Home » Archimedes archive » Acorn User » AU 1997-06 B.adf » Features » 3D/!AUA_Ray/source/c/engine

3D/!AUA_Ray/source/c/engine

This website contains an archive of files for the Acorn Electron, BBC Micro, Acorn Archimedes, Commodore 16 and Commodore 64 computers, which Dominic Ford has rescued from his private collection of floppy disks and cassettes.

Some of these files were originally commercial releases in the 1980s and 1990s, but they are now widely available online. I assume that copyright over them is no longer being asserted. If you own the copyright and would like files to be removed, please contact me.

Tape/disk: Home » Archimedes archive » Acorn User » AU 1997-06 B.adf » Features
Filename: 3D/!AUA_Ray/source/c/engine
Read OK:
File size: 8716 bytes
Load address: 0000
Exec address: 0000
File contents
/*
   engine.c : Written by Greg Scott   1997
   for Acorn User, as part of the "Virtual
   Worlds" series.

   Usage of the source code is done at the
   owners risk, and Acorn User or the auth
   or hold no responsibility for damages.
*/

/* AUTHORS NOTE: A lot of the code in here is very complex, and can never be adequately explained. PLEASE PLEASE contact me for more assistance, it is much easier to address personal problems with the ideas than in general.

AUThreeD@aol.com

or contact the Acorn User offices and they will pass it on. Thank you. */

/* ANSI C includes */

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* OTHER includes */

#include "our_lib.h"


/* DEFINES */

#define WORLD_WIDTH 64 /* This is the number of walls across in our world */
#define WORLD_HEIGHT 64 /* This is the number of walls down in our world */
#define WALL_WIDTH 64 /* This is the width of each wall in pixels */
#define WALL_HEIGHT 64 /* This is the height of each wall in pixels */
#define WALL_NUMBER 20 /* This defines the number of walls allowed */
#define SCREEN_WIDTH 320 /* This is the width of the mode 13 screen */
#define SCREEN_HEIGHT 256 /* This is the height of the mode 13 screen */
#define CELL_X_SIZE 64 /* this is the size in units of each cell */
#define CELL_Y_SIZE 64 /* this is the size in units of each cell */
#define CELL_X_SIZE_FP 6 /* this is used in binary shifting */
#define CELL_Y_SIZE_FP 6 /* this is used in binary shifting */
#define FOUND_WALL 1 /* this flag is used to indicate when an intersection has be found */
#define MAX_DISTANCE 4000 /* this defines the largest distance a ray could travel in the world, used for look up tables */
#define STEP_LENGTH 15 /* this new define holds how far forward and backwards the viewpoint moves each time */
#define CLOSEST 50 /* this stores the closest a player can walk into a wall */

/* these next defines represent a new fixed point form of angle-counting. Basically this system is used to avoid using floating point radian angles, which (especially on an Acorn) take a long time. It also makes look-up table referencing a lot easier, as the index has to be an integer anyway! */

#define ANGLE_0 0
#define ANGLE_6 30
#define ANGLE_30 160
#define ANGLE_45 240
#define ANGLE_60 320
#define ANGLE_90 480
#define ANGLE_180 960
#define ANGLE_225 1200
#define ANGLE_270 1440
#define ANGLE_360 1920


/* GLOBAL variables */

char world[WORLD_HEIGHT+1][WORLD_WIDTH+1];/* This holds our text data file */
char walls[WALL_NUMBER+1][(WALL_WIDTH*WALL_HEIGHT)+1];

/* This holds the wall graphics in a two dimensional array */
/* Note the usage of char and not "int" in both cases. This is because a char is 8 bytes, which gives 256 colours (used in our Mode 13 screen) and also an integer up to 256, when our text file doesn't go over 9 in number! Hence there is no need for an int array in either case. */

char *screen_address; /* this will hold the base of the screen memory which we will manipulate. By altering values in the screen memory, we alter what appears on the screen. Note that this is of type "char *" because it holds the memory address of a byte array - the 256 colour mode 13 screen (well it will do!) */
char *screen_address_bank; /* this is another pointer to the other area of screen memory which we will be using for SCREEN BANKING - avoiding flickering of the screen during animating graphics */
char *screen_address_temp; /* this is a spare pointer for use during the switching of the two above values */

/* these new FIXED POINT INTEGER pointers point to look-up tables used in the ray casting engine. These are explained of in the engine, but the look-ups are generated in aua_tables() */

int *tan_table,*inv_tan_table; /* pointers to tangent look_ups */
int *y_step,*x_step;           /* pointers to more complex look_ups */
int *inv_cos_table,            /* sin/cos tables (look_ups)    */
    *inv_sin_table;
int *cos_table;                /* cosinal look_up table    */
int *recip_table;              /* reciprocal table used instead of a division
. See later */

int *dx_table,                 /* NEW FIXED POINT tables for moving the */
    *dy_table;                 /* view point very quickly */

/* FUNCTION definitions */

/* this function generates LOOK UP tables - arrays holding pre-calculated trigonometric variables used in the ray casting process */

void aua_tables(void)
{

int ang, /* this is used to hold values while making look-ups */
    angt; /* same */

float rad_angle; /* this holds the radians equivalent of the fixed point angle system (0-1920 = 0-360 degrees = 0-6.whatever radians. Next month I'll be changing the system so it becomes 0-1800 instead of 1920, this will allow a slightly smaller screen width, more like Wolfenstein, this will lead to an increase in frame rate. Yes! */

/* dynamically allocated adequate memory for the look-ups */
tan_table     = (int *)malloc(sizeof(int) * (ANGLE_360+1));
inv_tan_table = (int *)malloc(sizeof(int) * (ANGLE_360+1));

y_step        = (int *)malloc(sizeof(int) * (ANGLE_360+1));
x_step        = (int  *)malloc(sizeof(int) * (ANGLE_360+1));

cos_table     = (int  *)malloc(sizeof(int) * (ANGLE_360+1));
inv_cos_table = (int  *)malloc(sizeof(int) * (ANGLE_360+1));
inv_sin_table = (int  *)malloc(sizeof(int) * (ANGLE_360+1));
/* new table, for the engine, to avoid using a divide */
recip_table   = (int  *)malloc(sizeof(int) * (MAX_DISTANCE+1));
/* new tables for moving the view point */
dx_table      = (int  *)malloc(sizeof(int) * (ANGLE_360+1));
dy_table      = (int  *)malloc(sizeof(int) * (ANGLE_360+1));
/* generate them, their use is explained in the ray casting engine */

for(angt=ANGLE_0;angt<=ANGLE_360;angt++)
{
ang=angt;
/* this next line calculates the radian angle to pass to the trig. functions */
rad_angle=(float)((3.272e-4) + ang * 2*3.141592654/ANGLE_360);

tan_table[ang]=(int)(tan(rad_angle)*65536);
inv_tan_table[ang]=(int)((1/tan(rad_angle))*65536);
/* note tha above conversions to fixed point integers */

/* we do the same for these tables, but unfortunately at the asymptotes the numbers become awkwardly large to store in our fixed point representation. Instead of multiplying by 64 we do 8, to make sure that no overflow can occur at this stage. We only need to multiply by another 8 later in the engine, its okay */

if(ang>=ANGLE_0 && ang<ANGLE_180)
{
y_step[ang]=fabs( (8) * (tan_table[ang]) );
}
else
  y_step[ang]=-fabs( (8) * (tan_table[ang]) );

if(ang>=ANGLE_90 && ang<ANGLE_270)
{
x_step[ang]=-fabs( (8) * (inv_tan_table[ang]) );
}
else
{
x_step[ang]=fabs( (8) * (inv_tan_table[ang]) );
}

/* conversion to fixed point */
inv_cos_table[ang]=(int)((1/cos(rad_angle))*65536);
inv_sin_table[ang]=(int)((1/sin(rad_angle))*65536);

/* work out tables for moving the viewpoint */
dx_table[ang]=(int)(cos(6.28*ang/ANGLE_360)*STEP_LENGTH)*65536;
dy_table[ang]=(int)(sin(6.28*ang/ANGLE_360)*STEP_LENGTH)*65536;
}

/* the cosine table is used to get rid of the "fish bowl effect", explained in the ray caster. Basically we work out cosines for our own span of vision, from -30 degrees to +30 degrees. This means that as we scan from left to right, or vice versa, our rays of light are actually cast out in a cartesian, circular way. Our world is however square, polar, so we have to acknowledge the distortion caused by mixing cartesian and polar coordinates. In this look up we also have a bit of scaling in it, yet more time saving !!! */

for(ang=-ANGLE_30;ang<=ANGLE_30;ang++)
{
/* work out radians to pass to cosine function */
rad_angle=(float)((3.272e-4)+ ang * 2*3.141592654/ANGLE_360);

/*fixed point conversion */
cos_table[ang+ANGLE_30]=(int)(13312/(cos(rad_angle))*65536);
}

/* this creates a reciprocal table, so we don't have to use divides. Multiplying by the reciprocal of a number is the same as dividing by it: After all,

8 / 4 = 2 and 8 * 0.25 (1 over 4) = 2 - they produce the same result */

for(ang=1;ang<MAX_DISTANCE;ang++)
{
  /* it is still fixed point though */
  recip_table[ang]=(int)(1.0/(float)ang*65536);
}

}

/* this function is the heart of the program, the engine, to generate the first person view */
void aua_raycaster(int view_x,int view_y,int view_angle)
{
/* remember that we are thinking in 2-D, not in 3D when we discuss ideas. Below does not mean "a floor below", it really means "behind", but we say below because we are imagining looking down on the view point to form a 2-D plan */

/* this function, for each column of the 320 pixel width Mode 13 screen, casts out two rays. One ray looks for X, horizontal intersections with walls, and the other tracks intersections with Y, vertical wall boundaries. After all, the only time a collision could occur is on a boundary of a cell, as the wall fills up the entire cell. Expect to see lots of 64's, though remember that this ray caster is very routine, and has not at all been put through my "box of magic". The engine will become much more personalised very soon! */



int cell_x, /* used to store which cell of the walls data the ray is in */
cell_y, /* " */
casting=2, /* used to store if ray casting has finished */
x_hit_type, /* this stores the wall type hit by the x casting ray */
y_hit_type, /* this sotres the wall type (number) hit by the y ray */
x_bound, /* this holds the next x boundary for a possible intersection */
y_bound, /* this holds the next y boundary for a possible intersection */
next_y_cell, /* this is used to figure out the quadrant of the ray (+/-)*/
next_x_cell, /* " */
x_delta, /* this is +'d to the x_bound var. to move to the next boundary */
y_delta, /* this is +'d to the y_bound var. to move to the next boundary */
xi_save, /* this stores where the x casting ray made its intersection */
yi_save, /* this stores where the y casting ray made its intersection */
scale,   /* this stores the scale of the sliver to be drawn in each column */
ray, /* this stores the ray number being cast out (0-320)*/
xray, /* this flag is used to show if casting is over */
yray, /* " */
dist_x, /* this holds the distance to the x intersection */
dist_y; /* this holds the distance to the y intersection */

int xi,
      yi,
      xadd,
      yadd; /* these are used to accurately trace and move each ray */


int variables[8]; /* this is used to pass variables to a super fast sliver render */

/* firstly, we set up the variables[] we already know, such as screen_address, walls and the screen height we are using. These are all things which our sliver renderer needs to know to plot its column */

variables[0]=(char *)screen_address;
variables[1]=(char *)walls;
variables[5]=SCREEN_HEIGHT;

/* now we get down to the nitty gritty. Here we subtract 30 degrees from the viewing angle remember that our FOV is 60 degrees which means that we cast from -30 to +30 */

if ( (view_angle-=ANGLE_30) < 0)
   {
   /* this ensures that we don't go over or under 0/360 degrees! */
   view_angle=ANGLE_360 + view_angle;
   }
/* now we start the main loop, start at the right of the screen (319), and cast each column one by one to the left */

for (ray=319; ray>=0; ray--)
    {
/* for each ray to be cast we actually cast out two rays : one to check for vertical boundary collisions and the other to check for horizontal boundary collisions. Considering that walls fill up each cell, we need only look for intersections on the boundaries. We have to perform seperate cast because just casting one ray complicates the matter and it doesn't give much speed increase, if any. */

/* NEW LINE : We have to check to see if the viewing angle is at the asymptotes, unfortunately the fixed point system cannot store the values held at these angles, so we have to avoid their use. This is not very elegant I know, but it saves a lot of head aches and no one can tell we've done it! */

if(view_angle==ANGLE_0 || view_angle==ANGLE_90 || view_angle ==ANGLE_180 || view_angle==ANGLE_270)view_angle++;
/* SECTION 1 : CALCULATING THE FIRST X and Y INTERSECTIONS*/
/* Once we have done this the following intersections are easy*/


/* The X CASTING RAY : here we test to see if the angle of the ray is facing upwards. We need to know which halfplane we're casting from relative to the y-axis. */


 if (view_angle >= ANGLE_0 && view_angle < ANGLE_180)
       {
/* if so then we assign variables to that effect. We must compute the first horizontal line that could be intersected with the ray. Note : it will be above the viewer.*/

y_bound = (CELL_Y_SIZE + (view_y & 0xffc0)); /* this line is merely an optimized version of CELL_Y_SIZE + (view_y % 64). I use it many times in this engine. */

y_delta = CELL_Y_SIZE; /* this means that for every movement of the ray, the y boundary moves up one cell, which it would. It is the delta to get to the next horizontal line */

/* next we use the inverse tan function to calculate the initial position of the x boundary searching ray on its first intersection. We have to use tan because it is related to slopes */

/* NEW FIXED POINT CALCULATION of
xi = (float)(inv_tan_table[view_angle] * (y_bound - view_y)) +view_x; */

xi=((y_bound-view_y))*(inv_tan_table[view_angle]);
xi+=(view_x<<16);

/* this means that the quadrant of the ray is not negative, that is the next y boundary will appear above the view point and not below (in terms of looking down on the viewer). This is the cell delta */
next_y_cell = 0;

       }
/* if the viewing angle is greater than 180 degrees and less than 270 degrees then we have to do other calculations (lower half plane) */
    else
       {
/* we know that because the viewing angle is downwards, so then the horizontal intersection has to be BELOW the viewer */
y_bound = (int)(view_y & 0xffc0);

/* because of this we also know that the next Y intersections will be a cell below each other. So the delta for each horizontal intersection will be a cell below  the last */
y_delta = -CELL_Y_SIZE;

/* we again use the tangent function, just as before, to calculate the first x intersection with a boundary. */

/* NEW FIXED POINT, I won't show the old lines any more */

xi=((y_bound-view_y))*(inv_tan_table[view_angle]);
xi+=(view_x<<16);

/* and we know also that the quadrant is below the player, so the cell y delta will be negative */

next_y_cell = -1;

       }
/* Y RAY : we do similar calculations but this time to calculate the first y intersections */

/* we test to see if the view angle is within the vertical asymptotes of 360 degrees. We need to know which halfplane we're casting from relative to the x-axis. */

if (view_angle < ANGLE_90 || view_angle >= ANGLE_270)
       {
/* we can deduce certain things, just as with the x ray. We know that because the view angle is to the right, the next X boundary (which is constant) will be to the RIGHT of the viewer. */
x_bound = (int)(CELL_X_SIZE + (view_x & 0xffc0));

/* notice this recurring optimization of view_x % 64 */

/* and we also know that each vertical cell boundary after the first will be a cell's width away */

x_delta = CELL_X_SIZE;
/* this time we use the tangent function (not the inverse tan) to calculate where the first y boundary intersection will occur). */

/* NEW FIXED POINT */

yi=((x_bound - view_x))*(tan_table[view_angle]);
yi+=(view_y<<16);
/* and we know also that because the view is positive, the next_x_cell delta does not need to be negative */

next_x_cell = 0;

       }
/* otherwise, if the viewing angle is towards the other direction...*/
    else
       {
/* we know that the first x boundary can occur only to the left of the viewer because the ray angle is facing left. So we can do view_x % 64 to calculate the first vertical boundary, this should be becoming obvious */
x_bound = (int)(view_x & 0xffc0);

/* we also know that the delta for the cell will be to the left, each time the ray moves to the next boundary the next vertical intersection will be a cell to the left than the last. */
x_delta = -CELL_X_SIZE;

/* we use the tangental function again to calculate the position on the horizontal intersections */

/* NEW FIXED POINT */

yi=((x_bound - view_x))*(tan_table[view_angle]);
yi+=(view_y<<16);
/* and we also know that the x cell value will be minus, because as the ray moves to another cell, because the ray is going left, the value must be minus. */
next_x_cell = -1;

       }

/* Now we have performed the slightly tricky task of the first intersections, we can move on to calculating the next ones. This is more simple, as we know that the intersections can only occur at cell boundaries.*/

/* SECTION 2 : Testing for further intersections */

/* these flags store if casting of both rays is complete */
xray=yray=0;

/* X Ray is first */
/* because we are testing for each next intersection, we can figure out more easily the following intersections. */
/* this is a look up table holding the next y intercepts, based on the tangental function and the size of cells. Basically we add this to the ray each time we move it a bit more, searching for a wall at a cell boundary */

/* NEW FIXED POINT, note the shift 3 times to the left, the equivalent of a multiply by 8, this takes no time, and really I don't know why I've done it like this! It works. */

xadd=y_step[view_angle]<<3;

/* start casting the x ray */
while(!xray)
{
/* compute current cell position of the ray to inspect*/

cell_x = ( (x_bound+next_x_cell) >> CELL_X_SIZE_FP);
/* Note we have to shift not only by 6, but also by 16 to convert BACK to normal maths */
cell_y = (int)yi>>22;

/* both of the above examples use binary shifting to achieve a divide by 64. Cell_y computation uses identical techniques to those covered in the magazine. Cell_x is calculated by using the x_bound and next_x_cell values calculated beforehand. */

if(cell_x<0)cell_x=0;if(cell_x>63)cell_x=63;
if(cell_y<0)cell_y=0;if(cell_y>63)cell_y=63;
/* these simple lines ensure that the ray doesn't go out of the world, though they aren't really needed. */

/* we look up in the world file to see if there is a wall at the intersection of our ray */
if ((x_hit_type =world[cell_y][cell_x])!=0)
{
/* if so we calculate the distance to it using the old O-Level technique of using sine and cosine instead of doing the standard PYTHAGORAS technique.*/

/* NEW FIXED POINT calculation, notice that in this next line we have both a conversion TO fixed point (view_y) and also the check against over flow is very apparent, we share the accuracy. See the article for more details */

dist_x  = ( (yi - (view_y<<16))>>8) * (inv_sin_table[view_angle]>>8);
/* we also save the exact position of the intersection because we will need it later to add texture mapping. */

/* We save yi after converting it back to normal maths */

yi_save = (int)yi>>16;

/* because the x ray has found a wall, we can stop casting */
xray=FOUND_WALL;

}
else
{
/* if not, we compute the next possible intersection */
yi +=xadd; /* FIXED POINT ADDITION requires no extra work */
x_bound += x_delta; /* and we also calculate the next horizontal boundary, which we know will be x_delta away, no need for complex workings. */
}

}
/* SECTION 3 */
/* WE NOW do exactly the same but for the yray, we cast it out, check for a wall, if there is one we take the distance to it etc, if not, we move  the ray until a wall it found. */

/* look up the value to add to the ray each time we move it */

/* See above for more information, this is FIXED POINT remember */
yadd=x_step[view_angle]<<3;

/* start casting the ray */
while(!yray)
{

/* compute current cell to inspect */

/* Because XI IS IN FIXED POINT we have to not only divide by 64 but also we have to convert BACK to normal maths */

cell_x = (int)xi>>22;
cell_y = ( (y_bound + next_y_cell) >> CELL_Y_SIZE_FP);
/* these calculations work out which cells the ray is in, ready to check for walls in the world[][] array. They both use binary shifting to perform divide by 64's. */

/* check that the ray has not gone out of the world, though this isn't really necessary */
if(cell_x<0)cell_x=0;if(cell_x>63)cell_x=63;
if(cell_y<0)cell_y=0;if(cell_y>63)cell_y=63;

/* look and see if there is a wall at the current point of intersection */
if ((y_hit_type = world[cell_y][cell_x])!=0)
{
/* Use the old O-Level triangle method of calulating distance using cos, rather than using PYTHAGORAS, which is slower because it uses a square root! */
/* FIXED POINT calculation, just the same as the inv_sin calculation see above. */
dist_y  = ( (xi - (view_x<<16))>>8) * (inv_cos_table[view_angle]>>8);

/* save the exact intersection point, we will need it later */
/* Same as aobve, very simple conversion back from FIXED POINT to normal maths */
xi_save = (int)xi>>16;
/* STOP y casting in that case, a wall has been found. */
yray=FOUND_WALL;
}
else
{
/* if not, move the ray on */
xi+=yadd; /* AGAIN, no extra work is required for FIXED POINT ADDITION */
y_bound += y_delta; /* and move to the next vertical boundary position */
}

}

/* SECTION 4*/
/* Both rays have been cast, both rays have met a wall, we now need to see which is closer, and then plot it correctly. */

/* find out which wall (x or y) is nearer the viewer. */

/* we have altered this distance checking line to avoid minus distances being selected to draw, which produces large spikes on the screen! Again this is because of fixed point */

    if (dist_x < dist_y && dist_x>0 || dist_y<0)

       {


/* we need to take into account here, when computing the scale of the vertical strip (sliver) to be drawn, a phenemenon (of sorts) known as the "fish bowl effect". This is caused by mizing of cartesian and polar coordinates. To get rid of it we use the cosine function. I have combined other multiplies of a vertical scaling factor with the cosine transformation to save time. All we eventually be explained. You could replace the line with scale=13312/dist_x++ and see what weird results you get! */

/* NEW NEW NEW : We have fixed point here, and using the reciprocal table (see around) we don't have to do a length divide! Notice how we convert dist_x back to normal to index the recip_table array, and that all accuracy is lost with the cos_table, because all its figures are above zero (see aua_tables) and also that we actually convert the whole answer back to normal maths for scale */

scale = (int)( (cos_table[ray]>>16) * (recip_table[dist_x>>16]) >>16);

/* assign the variables we need to the variables to be passed to the ASM sliver renderer (super fast!) */
variables[2]=(yi_save & 0x003f); /* this works out the column of the wall to be plotted (0-64), by calculating where abouts in the cell the intersection was, covered in the article. Note the optimization of yi_save % 64 */
variables[3]=scale-1; /*stores the scale of the strip (height of it)*/
variables[4]=ray; /* we use ray as the x position to plot to (0-319)*/
variables[6]=x_hit_type; /* finally we store the wall number to plot */

/* and we call the assembler function (explained at a later date)*/
ourlib_sliver(&variables[0]);

       }
/* else the dist_y was nearer, everything from above applies */
    else
       {

/* avoid fish bowl effect and scale properly with FIXED POINT clever bits!, see above */
scale = (int)( (cos_table[ray]>>16) * (recip_table[dist_y>>16]) >> 16);


/* set up variables for our sliver engine, see above */
variables[2]=(xi_save & 0x003f); /*notice that we use xi instead of yi_save*/
variables[3]=scale-1;
variables[4]=ray;
/* notice we add one to the wall graphic selection, so the darker tile is used for added variation. See the article for more details of this sort of shading, if you want to call it that! */
variables[6]=y_hit_type+1;

/* call our sliver engine */
ourlib_sliver(&variables[0]);

       }
/* this ray has been finished. Increase the angle of the next ray and start again! */

    if (++view_angle>=ANGLE_360)
       {
       /* this ensures that the ray angle doesn't go over 360 degrees! */
       view_angle=0;

       }
/* ray loop */
    }
/* end ray caster engine */
}



/* this function grabs all the different walls from a single file */

void aua_graphics(void)
{
int x, /* this is used to store the x coordinate of a point on the screen */
    y, /* this is used to store the y coordinate of a point on the screen */
    wall_number; /* this will be used to index the walls[x][] char array */

/* first of all we get the graphics file <AUARay$Dir>.graphics onto the screen */

system("*ScreenLoad <AUARay$Dir>.graphics");

/* next we start grabbing each tile, 64 x 64 pixels, into the walls[][] array */

/* we use this large for loop at the ourlib_bitmap_grab function to invidually grab each tile into its own walls[x][] array slot, note that we CAN'T HAVE WALL 0 as this represents a gap in the world! */

for(wall_number=1,y=0;y<SCREEN_HEIGHT;y+=WALL_HEIGHT)for(x=0;x<SCREEN_WIDTH;x+=WALL_WIDTH,wall_number++)
{
/* this calls the function ourlib_bitmap_grab (I said it would be handy!) which grabs the area of screen memory marked by the first four parameters, stores it in the byte array pointer in parameter five, reading it all from the screen pointed to by screen_address */

ourlib_bitmap_grab(x,y,x+WALL_WIDTH-1,y+WALL_HEIGHT-1,&walls[wall_number][0],screen_address);

/* this makes sure we don't go over our number of walls limit */

if(wall_number>=WALL_NUMBER)break;
}


}

/* this function loads in the data from our world text file and stores it in the world[][] array */

void aua_world(void)
{

FILE *world_file; /* we need a file pointer as we will be loading in text */

int row, /* this will be used to index the world[][] array */
    column; /* this will be used to index the world[][] array */

char ch; /* this is used to store each number as it is loaded in */

/* open the world file, if it is not there then exit the program */

if(!(world_file=fopen("<AUARay$Dir>.world","r")))exit(1);

/* this program loads in the data from the world file, row by row, column by column using the getc() ANSI function */

for(row=0;row<WORLD_HEIGHT;row++)
{
for(column=0;column<WORLD_WIDTH;column++)
{
while((ch=getc(world_file))==10){} /* this filters out any mess, though not often used! */

if(ch==' ')ch=0; /*this ensures the correct value is stored, if there is a gap in the file, this means a space in the world, a zero */
else ch=ch-'0';

world[(WORLD_HEIGHT-1)-row][column]=ch; /* this finally stores the value in the correct position */

/*printf("%d",ch); uncomment this line to see the world data loaded in */
}
/*printf("\n"); uncomment this line to see the world data loaded in */
}

/* when all is done, close the file */
fclose(world_file);
}

/* NEWER MAIN function .
This function now incorporates the following (see article)

FIXED POINT LOOK-UPS for MOVEMENT of viewpoint!
SCREEN BANKING to avoid flicker!
COLOURED FLOOR AND CEILINGS!

All changes are commented */

void main(void)
{
  int view_x, /* this holds the viewing x coordinate */
      view_y, /* this holds the viewing y coordinate */
      view_angle; /* this holds the viewing angle in fixed units 0-1920 */

  int key_press, /* this is used to confirm input of values */
      done=0,    /* flag to indicate if the user wants to quit */
      dx,        /* movement variables for the viewer */
      dy,
      y_cell,    /* these NEW variables are used to store the player/viewer*/
      x_cell,    /* world positions, for calculating viewer hitting walls */
      y_sub_cell,
      x_sub_cell,
      time_start,
      time_finish, /* These last few variables are used to work out */
      frames=0;    /* the frames per sec. of the system, slow for now! */

 int temporary_variables[10]; /* this array can be used to pass parameters */

/* we'll assign those now, for clearing the screen (slowly) */

temporary_variables[1]=temporary_variables[2]=temporary_variables[5]=0;
temporary_variables[3]=320;temporary_variables[4]=256;

/* first, we need the user to input values for view_x,view_y and view_angle*/

printf("******* NEW, IMPROVED RAY CASTER *******\nThis month's ray caster involves SCREENBANKING, COLOURED FLOORS AND CEILINGS, FIXED POINT MATHS and MORE. It still runs at full screen, but next month will have an adjustable screen size to run much quicker. Next month's will go atleast 25 fps on a RPC 600. An assembler version is a possibility.\nPlease enter starting values for View_X, View_Y, Viewing angle. Make sure the view doesn't start in a wall!\n Use the cursor keys to move and Q to quit\n\n");
scanf("%d %d %d",&view_x,&view_y,&view_angle);

/* confirm this is ok */

printf("You entered %d %d and %d Press 0 to quit and re-enter or any other number to continue...\n",view_x,view_y,view_angle);
scanf("%d",&key_press);

/* if q is pressed then exit, else continue */

if(!key_press)exit(1);

/* now we call aua_world to load in the text world file which defines our walls type and layout */

printf("loading in text file <AUARay$Dir>.world\n");
aua_world();

/* check to see if the viewer is inside a game cell WALL, which would be bad news! */

if(world[view_y>>6][view_x>>6])
{
  printf("Bad coordinates given, viewer is IN a WALL!, exiting\n");
  exit(1);
}

/* now we call aua_tables to generate some look-up tables for the engine to use, look-ups are explained up at the top of the file next to the global variables */

printf("calling aua_tables() this could take a long time on some machines\n");
/* newer fixed point version */
aua_tables();

/* all is done in terms of input for now. We need to switch to Mode 13 */

printf("Switching to Mode 13\n");

/* call ourlib_changemode to switch to mode 13 */

ourlib_changemode(13);

/* call ourlib_findscreen to get the screen base address of mode 13,  without the correct address we can't draw anything and the computer could crash */

screen_address=(char *)ourlib_findscreen();

/* now we need to *screenload our graphics file, and grab each individual wall graphic one by one, the function aua_graphics does this */

aua_graphics();


/* NOW we call setup_screens, a small function which helps with banking */
/* With all the data loaded in we shall try and initiate SCREEN BANKS. First we change to MODE 15, so that screen memory becomes available for two times MODE 13 */

ourlib_setup_screens();
ourlib_changemode(15);

/* Now we switch to MODE 13, and get the first screen address */

ourlib_changemode(13);

screen_address=(char *)ourlib_findscreen();

/* Now we switch to the other screen bank and get the other screen address */

ourlib_simpleswitch();



screen_address_bank=(char *)ourlib_findscreen();

/* we shall clear the screen here */
temporary_variables[0]=screen_address_bank;
ourlib_colour_box(temporary_variables);

/* Switch back to the other screen */

ourlib_simpleswitch();



/* NOW we can call setup background, to tell the screen clearer the colour of the floor and ceilings we want. In LATER VERSIONS of the engine these sort of details will be called through the COMMAND LINE, so no source code changing will be necessary */

ourlib_setup_background(148,25);

/* NOW we can start the main loop, exitable only by pressing the Q key. Use the Cursors to move the viewpoint around */
/* We shall also take a reading to work out the frame rate of the system, slow for now */

ourlib_killcursor(); /* get rid of the cursor flashing away */
time_start=ourlib_gettime();

while(!done) /* the loop will continue until done */
{

 ourlib_fastclg_two(screen_address,SCREEN_WIDTH,SCREEN_HEIGHT); /* we call the floor/ceiling function to colour the whole screen */
/* then we call the ray caster to draw over it */
  aua_raycaster(view_x,view_y,view_angle);

/* reset the variables for moving the viewpoint */

dx=dy=0;

/* now we test for different key presses and take action accordingly */

if(ourlib_keydown(16)==255)done=1; /* if Q is pressed then quit */

/* LEFT */
if(ourlib_keydown(121)==255)
{
  if((view_angle-=ANGLE_6)<ANGLE_0)
  view_angle=ANGLE_360;
}

/*RIGHT */
if(ourlib_keydown(25)==255)
{
  if((view_angle+=ANGLE_6)>ANGLE_360)
  view_angle=ANGLE_0;
}
/* UP and DOWN */
if(ourlib_keydown(57)==255)
{
  dx=dx_table[view_angle];
  dy=dy_table[view_angle];
}

if(ourlib_keydown(41)==255)
{
  dx=-dx_table[view_angle];
  dy=-dy_table[view_angle];
}

/* NOW we need to move the player and recalculate the cell the viewer is in, and ALSO check to see if the player has hit a wall */

/* Watch for the conversions of fixed point and things */

/* Player X actually is in normal maths */
 view_x= (int)((view_x<<16)+dx)>>16;
 view_y= (int)((view_y<<16)+dy)>>16;

 x_cell = view_x/CELL_X_SIZE;
 y_cell = view_y/CELL_Y_SIZE;

 x_sub_cell = view_x % CELL_X_SIZE;
 y_sub_cell = view_y % CELL_Y_SIZE;

/* CHECK to see if player has walked into walls */
 if ((dx>>8)>0 ){
 if ((world[y_cell][x_cell+1] != 0)  && (x_sub_cell>(CELL_X_SIZE-CLOSEST)))
                {
                view_x-= (x_sub_cell-(CELL_X_SIZE-CLOSEST ));
                }
                }
 else
 {
 if ( (world[y_cell][x_cell-1] != 0)  && (x_sub_cell < (CLOSEST) ) )
                {
                view_x+= (CLOSEST-x_sub_cell) ;
                }
 }

 if ((dy>>8)>0 ){
 if ( (world[(y_cell+1)][x_cell] != 0)  &&
                (y_sub_cell > (CELL_Y_SIZE-CLOSEST ) ) )
                {
                view_y-= (y_sub_cell-(CELL_Y_SIZE-CLOSEST ));
                }
                }
 else
 {
 if ( (world[(y_cell-1)][x_cell] != 0)  && (y_sub_cell < (CLOSEST) ) )
                {
                view_y+= (CLOSEST-y_sub_cell);
                }
 }

/* PHEW! Now we can wait for a vysnc and then switch the views/banks over ot  produce flicker-free animation */

ourlib_waitvsync();
ourlib_simpleswitch();

/* We also have to switch the memory addresses around so our functions draw to the correct memory */

screen_address_temp=screen_address_bank;
screen_address_bank=screen_address;
screen_address=screen_address_temp;

/* add one to the frames count, we are counting the number of frames generated  */
frames++;
}
/* record the time stopped */

time_finish=ourlib_gettime();

/* take a screenshot, using *screen save, and save it inside the directory */

system("*ScreenSave <AUARay$Dir>.scrshot");

/* close down the screens using an ourlib function */

ourlib_closedown_screens();

/* change to mode 15 and bring back the cursor just in case */

ourlib_changemode(15);
ourlib_revivecursor();

/* print the calculation and other info. */
printf("******* FRAMES PER SECOND ********\n       %f\n\nNote that this program should be slow even on a RISC PC. Next month will include variable screen sizes so the program is a lot faster. Don't panic!\n\n",(float)frames/(float)((time_finish-time_start)/100));
}

00000000  2f 2a 0a 20 20 20 65 6e  67 69 6e 65 2e 63 20 3a  |/*.   engine.c :|
00000010  20 57 72 69 74 74 65 6e  20 62 79 20 47 72 65 67  | Written by Greg|
00000020  20 53 63 6f 74 74 20 20  20 31 39 39 37 0a 20 20  | Scott   1997.  |
00000030  20 66 6f 72 20 41 63 6f  72 6e 20 55 73 65 72 2c  | for Acorn User,|
00000040  20 61 73 20 70 61 72 74  20 6f 66 20 74 68 65 20  | as part of the |
00000050  22 56 69 72 74 75 61 6c  0a 20 20 20 57 6f 72 6c  |"Virtual.   Worl|
00000060  64 73 22 20 73 65 72 69  65 73 2e 0a 0a 20 20 20  |ds" series...   |
00000070  55 73 61 67 65 20 6f 66  20 74 68 65 20 73 6f 75  |Usage of the sou|
00000080  72 63 65 20 63 6f 64 65  20 69 73 20 64 6f 6e 65  |rce code is done|
00000090  20 61 74 20 74 68 65 0a  20 20 20 6f 77 6e 65 72  | at the.   owner|
000000a0  73 20 72 69 73 6b 2c 20  61 6e 64 20 41 63 6f 72  |s risk, and Acor|
000000b0  6e 20 55 73 65 72 20 6f  72 20 74 68 65 20 61 75  |n User or the au|
000000c0  74 68 0a 20 20 20 6f 72  20 68 6f 6c 64 20 6e 6f  |th.   or hold no|
000000d0  20 72 65 73 70 6f 6e 73  69 62 69 6c 69 74 79 20  | responsibility |
000000e0  66 6f 72 20 64 61 6d 61  67 65 73 2e 0a 2a 2f 0a  |for damages..*/.|
000000f0  0a 2f 2a 20 41 55 54 48  4f 52 53 20 4e 4f 54 45  |./* AUTHORS NOTE|
00000100  3a 20 41 20 6c 6f 74 20  6f 66 20 74 68 65 20 63  |: A lot of the c|
00000110  6f 64 65 20 69 6e 20 68  65 72 65 20 69 73 20 76  |ode in here is v|
00000120  65 72 79 20 63 6f 6d 70  6c 65 78 2c 20 61 6e 64  |ery complex, and|
00000130  20 63 61 6e 20 6e 65 76  65 72 20 62 65 20 61 64  | can never be ad|
00000140  65 71 75 61 74 65 6c 79  20 65 78 70 6c 61 69 6e  |equately explain|
00000150  65 64 2e 20 50 4c 45 41  53 45 20 50 4c 45 41 53  |ed. PLEASE PLEAS|
00000160  45 20 63 6f 6e 74 61 63  74 20 6d 65 20 66 6f 72  |E contact me for|
00000170  20 6d 6f 72 65 20 61 73  73 69 73 74 61 6e 63 65  | more assistance|
00000180  2c 20 69 74 20 69 73 20  6d 75 63 68 20 65 61 73  |, it is much eas|
00000190  69 65 72 20 74 6f 20 61  64 64 72 65 73 73 20 70  |ier to address p|
000001a0  65 72 73 6f 6e 61 6c 20  70 72 6f 62 6c 65 6d 73  |ersonal problems|
000001b0  20 77 69 74 68 20 74 68  65 20 69 64 65 61 73 20  | with the ideas |
000001c0  74 68 61 6e 20 69 6e 20  67 65 6e 65 72 61 6c 2e  |than in general.|
000001d0  0a 0a 41 55 54 68 72 65  65 44 40 61 6f 6c 2e 63  |..AUThreeD@aol.c|
000001e0  6f 6d 0a 0a 6f 72 20 63  6f 6e 74 61 63 74 20 74  |om..or contact t|
000001f0  68 65 20 41 63 6f 72 6e  20 55 73 65 72 20 6f 66  |he Acorn User of|
00000200  66 69 63 65 73 20 61 6e  64 20 74 68 65 79 20 77  |fices and they w|
00000210  69 6c 6c 20 70 61 73 73  20 69 74 20 6f 6e 2e 20  |ill pass it on. |
00000220  54 68 61 6e 6b 20 79 6f  75 2e 20 2a 2f 0a 0a 2f  |Thank you. */../|
00000230  2a 20 41 4e 53 49 20 43  20 69 6e 63 6c 75 64 65  |* ANSI C include|
00000240  73 20 2a 2f 0a 0a 23 69  6e 63 6c 75 64 65 20 3c  |s */..#include <|
00000250  73 74 64 69 6f 2e 68 3e  0a 23 69 6e 63 6c 75 64  |stdio.h>.#includ|
00000260  65 20 3c 73 74 64 6c 69  62 2e 68 3e 0a 23 69 6e  |e <stdlib.h>.#in|
00000270  63 6c 75 64 65 20 3c 6d  61 74 68 2e 68 3e 0a 0a  |clude <math.h>..|
00000280  2f 2a 20 4f 54 48 45 52  20 69 6e 63 6c 75 64 65  |/* OTHER include|
00000290  73 20 2a 2f 0a 0a 23 69  6e 63 6c 75 64 65 20 22  |s */..#include "|
000002a0  6f 75 72 5f 6c 69 62 2e  68 22 0a 0a 0a 2f 2a 20  |our_lib.h".../* |
000002b0  44 45 46 49 4e 45 53 20  2a 2f 0a 0a 23 64 65 66  |DEFINES */..#def|
000002c0  69 6e 65 20 57 4f 52 4c  44 5f 57 49 44 54 48 20  |ine WORLD_WIDTH |
000002d0  36 34 20 2f 2a 20 54 68  69 73 20 69 73 20 74 68  |64 /* This is th|
000002e0  65 20 6e 75 6d 62 65 72  20 6f 66 20 77 61 6c 6c  |e number of wall|
000002f0  73 20 61 63 72 6f 73 73  20 69 6e 20 6f 75 72 20  |s across in our |
00000300  77 6f 72 6c 64 20 2a 2f  0a 23 64 65 66 69 6e 65  |world */.#define|
00000310  20 57 4f 52 4c 44 5f 48  45 49 47 48 54 20 36 34  | WORLD_HEIGHT 64|
00000320  20 2f 2a 20 54 68 69 73  20 69 73 20 74 68 65 20  | /* This is the |
00000330  6e 75 6d 62 65 72 20 6f  66 20 77 61 6c 6c 73 20  |number of walls |
00000340  64 6f 77 6e 20 69 6e 20  6f 75 72 20 77 6f 72 6c  |down in our worl|
00000350  64 20 2a 2f 0a 23 64 65  66 69 6e 65 20 57 41 4c  |d */.#define WAL|
00000360  4c 5f 57 49 44 54 48 20  36 34 20 2f 2a 20 54 68  |L_WIDTH 64 /* Th|
00000370  69 73 20 69 73 20 74 68  65 20 77 69 64 74 68 20  |is is the width |
00000380  6f 66 20 65 61 63 68 20  77 61 6c 6c 20 69 6e 20  |of each wall in |
00000390  70 69 78 65 6c 73 20 2a  2f 0a 23 64 65 66 69 6e  |pixels */.#defin|
000003a0  65 20 57 41 4c 4c 5f 48  45 49 47 48 54 20 36 34  |e WALL_HEIGHT 64|
000003b0  20 2f 2a 20 54 68 69 73  20 69 73 20 74 68 65 20  | /* This is the |
000003c0  68 65 69 67 68 74 20 6f  66 20 65 61 63 68 20 77  |height of each w|
000003d0  61 6c 6c 20 69 6e 20 70  69 78 65 6c 73 20 2a 2f  |all in pixels */|
000003e0  0a 23 64 65 66 69 6e 65  20 57 41 4c 4c 5f 4e 55  |.#define WALL_NU|
000003f0  4d 42 45 52 20 32 30 20  2f 2a 20 54 68 69 73 20  |MBER 20 /* This |
00000400  64 65 66 69 6e 65 73 20  74 68 65 20 6e 75 6d 62  |defines the numb|
00000410  65 72 20 6f 66 20 77 61  6c 6c 73 20 61 6c 6c 6f  |er of walls allo|
00000420  77 65 64 20 2a 2f 0a 23  64 65 66 69 6e 65 20 53  |wed */.#define S|
00000430  43 52 45 45 4e 5f 57 49  44 54 48 20 33 32 30 20  |CREEN_WIDTH 320 |
00000440  2f 2a 20 54 68 69 73 20  69 73 20 74 68 65 20 77  |/* This is the w|
00000450  69 64 74 68 20 6f 66 20  74 68 65 20 6d 6f 64 65  |idth of the mode|
00000460  20 31 33 20 73 63 72 65  65 6e 20 2a 2f 0a 23 64  | 13 screen */.#d|
00000470  65 66 69 6e 65 20 53 43  52 45 45 4e 5f 48 45 49  |efine SCREEN_HEI|
00000480  47 48 54 20 32 35 36 20  2f 2a 20 54 68 69 73 20  |GHT 256 /* This |
00000490  69 73 20 74 68 65 20 68  65 69 67 68 74 20 6f 66  |is the height of|
000004a0  20 74 68 65 20 6d 6f 64  65 20 31 33 20 73 63 72  | the mode 13 scr|
000004b0  65 65 6e 20 2a 2f 0a 23  64 65 66 69 6e 65 20 43  |een */.#define C|
000004c0  45 4c 4c 5f 58 5f 53 49  5a 45 20 36 34 20 2f 2a  |ELL_X_SIZE 64 /*|
000004d0  20 74 68 69 73 20 69 73  20 74 68 65 20 73 69 7a  | this is the siz|
000004e0  65 20 69 6e 20 75 6e 69  74 73 20 6f 66 20 65 61  |e in units of ea|
000004f0  63 68 20 63 65 6c 6c 20  2a 2f 0a 23 64 65 66 69  |ch cell */.#defi|
00000500  6e 65 20 43 45 4c 4c 5f  59 5f 53 49 5a 45 20 36  |ne CELL_Y_SIZE 6|
00000510  34 20 2f 2a 20 74 68 69  73 20 69 73 20 74 68 65  |4 /* this is the|
00000520  20 73 69 7a 65 20 69 6e  20 75 6e 69 74 73 20 6f  | size in units o|
00000530  66 20 65 61 63 68 20 63  65 6c 6c 20 2a 2f 0a 23  |f each cell */.#|
00000540  64 65 66 69 6e 65 20 43  45 4c 4c 5f 58 5f 53 49  |define CELL_X_SI|
00000550  5a 45 5f 46 50 20 36 20  2f 2a 20 74 68 69 73 20  |ZE_FP 6 /* this |
00000560  69 73 20 75 73 65 64 20  69 6e 20 62 69 6e 61 72  |is used in binar|
00000570  79 20 73 68 69 66 74 69  6e 67 20 2a 2f 0a 23 64  |y shifting */.#d|
00000580  65 66 69 6e 65 20 43 45  4c 4c 5f 59 5f 53 49 5a  |efine CELL_Y_SIZ|
00000590  45 5f 46 50 20 36 20 2f  2a 20 74 68 69 73 20 69  |E_FP 6 /* this i|
000005a0  73 20 75 73 65 64 20 69  6e 20 62 69 6e 61 72 79  |s used in binary|
000005b0  20 73 68 69 66 74 69 6e  67 20 2a 2f 0a 23 64 65  | shifting */.#de|
000005c0  66 69 6e 65 20 46 4f 55  4e 44 5f 57 41 4c 4c 20  |fine FOUND_WALL |
000005d0  31 20 2f 2a 20 74 68 69  73 20 66 6c 61 67 20 69  |1 /* this flag i|
000005e0  73 20 75 73 65 64 20 74  6f 20 69 6e 64 69 63 61  |s used to indica|
000005f0  74 65 20 77 68 65 6e 20  61 6e 20 69 6e 74 65 72  |te when an inter|
00000600  73 65 63 74 69 6f 6e 20  68 61 73 20 62 65 20 66  |section has be f|
00000610  6f 75 6e 64 20 2a 2f 0a  23 64 65 66 69 6e 65 20  |ound */.#define |
00000620  4d 41 58 5f 44 49 53 54  41 4e 43 45 20 34 30 30  |MAX_DISTANCE 400|
00000630  30 20 2f 2a 20 74 68 69  73 20 64 65 66 69 6e 65  |0 /* this define|
00000640  73 20 74 68 65 20 6c 61  72 67 65 73 74 20 64 69  |s the largest di|
00000650  73 74 61 6e 63 65 20 61  20 72 61 79 20 63 6f 75  |stance a ray cou|
00000660  6c 64 20 74 72 61 76 65  6c 20 69 6e 20 74 68 65  |ld travel in the|
00000670  20 77 6f 72 6c 64 2c 20  75 73 65 64 20 66 6f 72  | world, used for|
00000680  20 6c 6f 6f 6b 20 75 70  20 74 61 62 6c 65 73 20  | look up tables |
00000690  2a 2f 0a 23 64 65 66 69  6e 65 20 53 54 45 50 5f  |*/.#define STEP_|
000006a0  4c 45 4e 47 54 48 20 31  35 20 2f 2a 20 74 68 69  |LENGTH 15 /* thi|
000006b0  73 20 6e 65 77 20 64 65  66 69 6e 65 20 68 6f 6c  |s new define hol|
000006c0  64 73 20 68 6f 77 20 66  61 72 20 66 6f 72 77 61  |ds how far forwa|
000006d0  72 64 20 61 6e 64 20 62  61 63 6b 77 61 72 64 73  |rd and backwards|
000006e0  20 74 68 65 20 76 69 65  77 70 6f 69 6e 74 20 6d  | the viewpoint m|
000006f0  6f 76 65 73 20 65 61 63  68 20 74 69 6d 65 20 2a  |oves each time *|
00000700  2f 0a 23 64 65 66 69 6e  65 20 43 4c 4f 53 45 53  |/.#define CLOSES|
00000710  54 20 35 30 20 2f 2a 20  74 68 69 73 20 73 74 6f  |T 50 /* this sto|
00000720  72 65 73 20 74 68 65 20  63 6c 6f 73 65 73 74 20  |res the closest |
00000730  61 20 70 6c 61 79 65 72  20 63 61 6e 20 77 61 6c  |a player can wal|
00000740  6b 20 69 6e 74 6f 20 61  20 77 61 6c 6c 20 2a 2f  |k into a wall */|
00000750  0a 0a 2f 2a 20 74 68 65  73 65 20 6e 65 78 74 20  |../* these next |
00000760  64 65 66 69 6e 65 73 20  72 65 70 72 65 73 65 6e  |defines represen|
00000770  74 20 61 20 6e 65 77 20  66 69 78 65 64 20 70 6f  |t a new fixed po|
00000780  69 6e 74 20 66 6f 72 6d  20 6f 66 20 61 6e 67 6c  |int form of angl|
00000790  65 2d 63 6f 75 6e 74 69  6e 67 2e 20 42 61 73 69  |e-counting. Basi|
000007a0  63 61 6c 6c 79 20 74 68  69 73 20 73 79 73 74 65  |cally this syste|
000007b0  6d 20 69 73 20 75 73 65  64 20 74 6f 20 61 76 6f  |m is used to avo|
000007c0  69 64 20 75 73 69 6e 67  20 66 6c 6f 61 74 69 6e  |id using floatin|
000007d0  67 20 70 6f 69 6e 74 20  72 61 64 69 61 6e 20 61  |g point radian a|
000007e0  6e 67 6c 65 73 2c 20 77  68 69 63 68 20 28 65 73  |ngles, which (es|
000007f0  70 65 63 69 61 6c 6c 79  20 6f 6e 20 61 6e 20 41  |pecially on an A|
00000800  63 6f 72 6e 29 20 74 61  6b 65 20 61 20 6c 6f 6e  |corn) take a lon|
00000810  67 20 74 69 6d 65 2e 20  49 74 20 61 6c 73 6f 20  |g time. It also |
00000820  6d 61 6b 65 73 20 6c 6f  6f 6b 2d 75 70 20 74 61  |makes look-up ta|
00000830  62 6c 65 20 72 65 66 65  72 65 6e 63 69 6e 67 20  |ble referencing |
00000840  61 20 6c 6f 74 20 65 61  73 69 65 72 2c 20 61 73  |a lot easier, as|
00000850  20 74 68 65 20 69 6e 64  65 78 20 68 61 73 20 74  | the index has t|
00000860  6f 20 62 65 20 61 6e 20  69 6e 74 65 67 65 72 20  |o be an integer |
00000870  61 6e 79 77 61 79 21 20  2a 2f 0a 0a 23 64 65 66  |anyway! */..#def|
00000880  69 6e 65 20 41 4e 47 4c  45 5f 30 20 30 0a 23 64  |ine ANGLE_0 0.#d|
00000890  65 66 69 6e 65 20 41 4e  47 4c 45 5f 36 20 33 30  |efine ANGLE_6 30|
000008a0  0a 23 64 65 66 69 6e 65  20 41 4e 47 4c 45 5f 33  |.#define ANGLE_3|
000008b0  30 20 31 36 30 0a 23 64  65 66 69 6e 65 20 41 4e  |0 160.#define AN|
000008c0  47 4c 45 5f 34 35 20 32  34 30 0a 23 64 65 66 69  |GLE_45 240.#defi|
000008d0  6e 65 20 41 4e 47 4c 45  5f 36 30 20 33 32 30 0a  |ne ANGLE_60 320.|
000008e0  23 64 65 66 69 6e 65 20  41 4e 47 4c 45 5f 39 30  |#define ANGLE_90|
000008f0  20 34 38 30 0a 23 64 65  66 69 6e 65 20 41 4e 47  | 480.#define ANG|
00000900  4c 45 5f 31 38 30 20 39  36 30 0a 23 64 65 66 69  |LE_180 960.#defi|
00000910  6e 65 20 41 4e 47 4c 45  5f 32 32 35 20 31 32 30  |ne ANGLE_225 120|
00000920  30 0a 23 64 65 66 69 6e  65 20 41 4e 47 4c 45 5f  |0.#define ANGLE_|
00000930  32 37 30 20 31 34 34 30  0a 23 64 65 66 69 6e 65  |270 1440.#define|
00000940  20 41 4e 47 4c 45 5f 33  36 30 20 31 39 32 30 0a  | ANGLE_360 1920.|
00000950  0a 0a 2f 2a 20 47 4c 4f  42 41 4c 20 76 61 72 69  |../* GLOBAL vari|
00000960  61 62 6c 65 73 20 2a 2f  0a 0a 63 68 61 72 20 77  |ables */..char w|
00000970  6f 72 6c 64 5b 57 4f 52  4c 44 5f 48 45 49 47 48  |orld[WORLD_HEIGH|
00000980  54 2b 31 5d 5b 57 4f 52  4c 44 5f 57 49 44 54 48  |T+1][WORLD_WIDTH|
00000990  2b 31 5d 3b 2f 2a 20 54  68 69 73 20 68 6f 6c 64  |+1];/* This hold|
000009a0  73 20 6f 75 72 20 74 65  78 74 20 64 61 74 61 20  |s our text data |
000009b0  66 69 6c 65 20 2a 2f 0a  63 68 61 72 20 77 61 6c  |file */.char wal|
000009c0  6c 73 5b 57 41 4c 4c 5f  4e 55 4d 42 45 52 2b 31  |ls[WALL_NUMBER+1|
000009d0  5d 5b 28 57 41 4c 4c 5f  57 49 44 54 48 2a 57 41  |][(WALL_WIDTH*WA|
000009e0  4c 4c 5f 48 45 49 47 48  54 29 2b 31 5d 3b 0a 0a  |LL_HEIGHT)+1];..|
000009f0  2f 2a 20 54 68 69 73 20  68 6f 6c 64 73 20 74 68  |/* This holds th|
00000a00  65 20 77 61 6c 6c 20 67  72 61 70 68 69 63 73 20  |e wall graphics |
00000a10  69 6e 20 61 20 74 77 6f  20 64 69 6d 65 6e 73 69  |in a two dimensi|
00000a20  6f 6e 61 6c 20 61 72 72  61 79 20 2a 2f 0a 2f 2a  |onal array */./*|
00000a30  20 4e 6f 74 65 20 74 68  65 20 75 73 61 67 65 20  | Note the usage |
00000a40  6f 66 20 63 68 61 72 20  61 6e 64 20 6e 6f 74 20  |of char and not |
00000a50  22 69 6e 74 22 20 69 6e  20 62 6f 74 68 20 63 61  |"int" in both ca|
00000a60  73 65 73 2e 20 54 68 69  73 20 69 73 20 62 65 63  |ses. This is bec|
00000a70  61 75 73 65 20 61 20 63  68 61 72 20 69 73 20 38  |ause a char is 8|
00000a80  20 62 79 74 65 73 2c 20  77 68 69 63 68 20 67 69  | bytes, which gi|
00000a90  76 65 73 20 32 35 36 20  63 6f 6c 6f 75 72 73 20  |ves 256 colours |
00000aa0  28 75 73 65 64 20 69 6e  20 6f 75 72 20 4d 6f 64  |(used in our Mod|
00000ab0  65 20 31 33 20 73 63 72  65 65 6e 29 20 61 6e 64  |e 13 screen) and|
00000ac0  20 61 6c 73 6f 20 61 6e  20 69 6e 74 65 67 65 72  | also an integer|
00000ad0  20 75 70 20 74 6f 20 32  35 36 2c 20 77 68 65 6e  | up to 256, when|
00000ae0  20 6f 75 72 20 74 65 78  74 20 66 69 6c 65 20 64  | our text file d|
00000af0  6f 65 73 6e 27 74 20 67  6f 20 6f 76 65 72 20 39  |oesn't go over 9|
00000b00  20 69 6e 20 6e 75 6d 62  65 72 21 20 48 65 6e 63  | in number! Henc|
00000b10  65 20 74 68 65 72 65 20  69 73 20 6e 6f 20 6e 65  |e there is no ne|
00000b20  65 64 20 66 6f 72 20 61  6e 20 69 6e 74 20 61 72  |ed for an int ar|
00000b30  72 61 79 20 69 6e 20 65  69 74 68 65 72 20 63 61  |ray in either ca|
00000b40  73 65 2e 20 2a 2f 0a 0a  63 68 61 72 20 2a 73 63  |se. */..char *sc|
00000b50  72 65 65 6e 5f 61 64 64  72 65 73 73 3b 20 2f 2a  |reen_address; /*|
00000b60  20 74 68 69 73 20 77 69  6c 6c 20 68 6f 6c 64 20  | this will hold |
00000b70  74 68 65 20 62 61 73 65  20 6f 66 20 74 68 65 20  |the base of the |
00000b80  73 63 72 65 65 6e 20 6d  65 6d 6f 72 79 20 77 68  |screen memory wh|
00000b90  69 63 68 20 77 65 20 77  69 6c 6c 20 6d 61 6e 69  |ich we will mani|
00000ba0  70 75 6c 61 74 65 2e 20  42 79 20 61 6c 74 65 72  |pulate. By alter|
00000bb0  69 6e 67 20 76 61 6c 75  65 73 20 69 6e 20 74 68  |ing values in th|
00000bc0  65 20 73 63 72 65 65 6e  20 6d 65 6d 6f 72 79 2c  |e screen memory,|
00000bd0  20 77 65 20 61 6c 74 65  72 20 77 68 61 74 20 61  | we alter what a|
00000be0  70 70 65 61 72 73 20 6f  6e 20 74 68 65 20 73 63  |ppears on the sc|
00000bf0  72 65 65 6e 2e 20 4e 6f  74 65 20 74 68 61 74 20  |reen. Note that |
00000c00  74 68 69 73 20 69 73 20  6f 66 20 74 79 70 65 20  |this is of type |
00000c10  22 63 68 61 72 20 2a 22  20 62 65 63 61 75 73 65  |"char *" because|
00000c20  20 69 74 20 68 6f 6c 64  73 20 74 68 65 20 6d 65  | it holds the me|
00000c30  6d 6f 72 79 20 61 64 64  72 65 73 73 20 6f 66 20  |mory address of |
00000c40  61 20 62 79 74 65 20 61  72 72 61 79 20 2d 20 74  |a byte array - t|
00000c50  68 65 20 32 35 36 20 63  6f 6c 6f 75 72 20 6d 6f  |he 256 colour mo|
00000c60  64 65 20 31 33 20 73 63  72 65 65 6e 20 28 77 65  |de 13 screen (we|
00000c70  6c 6c 20 69 74 20 77 69  6c 6c 20 64 6f 21 29 20  |ll it will do!) |
00000c80  2a 2f 0a 63 68 61 72 20  2a 73 63 72 65 65 6e 5f  |*/.char *screen_|
00000c90  61 64 64 72 65 73 73 5f  62 61 6e 6b 3b 20 2f 2a  |address_bank; /*|
00000ca0  20 74 68 69 73 20 69 73  20 61 6e 6f 74 68 65 72  | this is another|
00000cb0  20 70 6f 69 6e 74 65 72  20 74 6f 20 74 68 65 20  | pointer to the |
00000cc0  6f 74 68 65 72 20 61 72  65 61 20 6f 66 20 73 63  |other area of sc|
00000cd0  72 65 65 6e 20 6d 65 6d  6f 72 79 20 77 68 69 63  |reen memory whic|
00000ce0  68 20 77 65 20 77 69 6c  6c 20 62 65 20 75 73 69  |h we will be usi|
00000cf0  6e 67 20 66 6f 72 20 53  43 52 45 45 4e 20 42 41  |ng for SCREEN BA|
00000d00  4e 4b 49 4e 47 20 2d 20  61 76 6f 69 64 69 6e 67  |NKING - avoiding|
00000d10  20 66 6c 69 63 6b 65 72  69 6e 67 20 6f 66 20 74  | flickering of t|
00000d20  68 65 20 73 63 72 65 65  6e 20 64 75 72 69 6e 67  |he screen during|
00000d30  20 61 6e 69 6d 61 74 69  6e 67 20 67 72 61 70 68  | animating graph|
00000d40  69 63 73 20 2a 2f 0a 63  68 61 72 20 2a 73 63 72  |ics */.char *scr|
00000d50  65 65 6e 5f 61 64 64 72  65 73 73 5f 74 65 6d 70  |een_address_temp|
00000d60  3b 20 2f 2a 20 74 68 69  73 20 69 73 20 61 20 73  |; /* this is a s|
00000d70  70 61 72 65 20 70 6f 69  6e 74 65 72 20 66 6f 72  |pare pointer for|
00000d80  20 75 73 65 20 64 75 72  69 6e 67 20 74 68 65 20  | use during the |
00000d90  73 77 69 74 63 68 69 6e  67 20 6f 66 20 74 68 65  |switching of the|
00000da0  20 74 77 6f 20 61 62 6f  76 65 20 76 61 6c 75 65  | two above value|
00000db0  73 20 2a 2f 0a 0a 2f 2a  20 74 68 65 73 65 20 6e  |s */../* these n|
00000dc0  65 77 20 46 49 58 45 44  20 50 4f 49 4e 54 20 49  |ew FIXED POINT I|
00000dd0  4e 54 45 47 45 52 20 70  6f 69 6e 74 65 72 73 20  |NTEGER pointers |
00000de0  70 6f 69 6e 74 20 74 6f  20 6c 6f 6f 6b 2d 75 70  |point to look-up|
00000df0  20 74 61 62 6c 65 73 20  75 73 65 64 20 69 6e 20  | tables used in |
00000e00  74 68 65 20 72 61 79 20  63 61 73 74 69 6e 67 20  |the ray casting |
00000e10  65 6e 67 69 6e 65 2e 20  54 68 65 73 65 20 61 72  |engine. These ar|
00000e20  65 20 65 78 70 6c 61 69  6e 65 64 20 6f 66 20 69  |e explained of i|
00000e30  6e 20 74 68 65 20 65 6e  67 69 6e 65 2c 20 62 75  |n the engine, bu|
00000e40  74 20 74 68 65 20 6c 6f  6f 6b 2d 75 70 73 20 61  |t the look-ups a|
00000e50  72 65 20 67 65 6e 65 72  61 74 65 64 20 69 6e 20  |re generated in |
00000e60  61 75 61 5f 74 61 62 6c  65 73 28 29 20 2a 2f 0a  |aua_tables() */.|
00000e70  0a 69 6e 74 20 2a 74 61  6e 5f 74 61 62 6c 65 2c  |.int *tan_table,|
00000e80  2a 69 6e 76 5f 74 61 6e  5f 74 61 62 6c 65 3b 20  |*inv_tan_table; |
00000e90  2f 2a 20 70 6f 69 6e 74  65 72 73 20 74 6f 20 74  |/* pointers to t|
00000ea0  61 6e 67 65 6e 74 20 6c  6f 6f 6b 5f 75 70 73 20  |angent look_ups |
00000eb0  2a 2f 0a 69 6e 74 20 2a  79 5f 73 74 65 70 2c 2a  |*/.int *y_step,*|
00000ec0  78 5f 73 74 65 70 3b 20  20 20 20 20 20 20 20 20  |x_step;         |
00000ed0  20 20 2f 2a 20 70 6f 69  6e 74 65 72 73 20 74 6f  |  /* pointers to|
00000ee0  20 6d 6f 72 65 20 63 6f  6d 70 6c 65 78 20 6c 6f  | more complex lo|
00000ef0  6f 6b 5f 75 70 73 20 2a  2f 0a 69 6e 74 20 2a 69  |ok_ups */.int *i|
00000f00  6e 76 5f 63 6f 73 5f 74  61 62 6c 65 2c 20 20 20  |nv_cos_table,   |
00000f10  20 20 20 20 20 20 20 20  20 2f 2a 20 73 69 6e 2f  |         /* sin/|
00000f20  63 6f 73 20 74 61 62 6c  65 73 20 28 6c 6f 6f 6b  |cos tables (look|
00000f30  5f 75 70 73 29 20 20 20  20 2a 2f 0a 20 20 20 20  |_ups)    */.    |
00000f40  2a 69 6e 76 5f 73 69 6e  5f 74 61 62 6c 65 3b 0a  |*inv_sin_table;.|
00000f50  69 6e 74 20 2a 63 6f 73  5f 74 61 62 6c 65 3b 20  |int *cos_table; |
00000f60  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 2f  |               /|
00000f70  2a 20 63 6f 73 69 6e 61  6c 20 6c 6f 6f 6b 5f 75  |* cosinal look_u|
00000f80  70 20 74 61 62 6c 65 20  20 20 20 2a 2f 0a 69 6e  |p table    */.in|
00000f90  74 20 2a 72 65 63 69 70  5f 74 61 62 6c 65 3b 20  |t *recip_table; |
00000fa0  20 20 20 20 20 20 20 20  20 20 20 20 20 2f 2a 20  |             /* |
00000fb0  72 65 63 69 70 72 6f 63  61 6c 20 74 61 62 6c 65  |reciprocal table|
00000fc0  20 75 73 65 64 20 69 6e  73 74 65 61 64 20 6f 66  | used instead of|
00000fd0  20 61 20 64 69 76 69 73  69 6f 6e 0a 2e 20 53 65  | a division.. Se|
00000fe0  65 20 6c 61 74 65 72 20  2a 2f 0a 0a 69 6e 74 20  |e later */..int |
00000ff0  2a 64 78 5f 74 61 62 6c  65 2c 20 20 20 20 20 20  |*dx_table,      |
00001000  20 20 20 20 20 20 20 20  20 20 20 2f 2a 20 4e 45  |           /* NE|
00001010  57 20 46 49 58 45 44 20  50 4f 49 4e 54 20 74 61  |W FIXED POINT ta|
00001020  62 6c 65 73 20 66 6f 72  20 6d 6f 76 69 6e 67 20  |bles for moving |
00001030  74 68 65 20 2a 2f 0a 20  20 20 20 2a 64 79 5f 74  |the */.    *dy_t|
00001040  61 62 6c 65 3b 20 20 20  20 20 20 20 20 20 20 20  |able;           |
00001050  20 20 20 20 20 20 2f 2a  20 76 69 65 77 20 70 6f  |      /* view po|
00001060  69 6e 74 20 76 65 72 79  20 71 75 69 63 6b 6c 79  |int very quickly|
00001070  20 2a 2f 0a 0a 2f 2a 20  46 55 4e 43 54 49 4f 4e  | */../* FUNCTION|
00001080  20 64 65 66 69 6e 69 74  69 6f 6e 73 20 2a 2f 0a  | definitions */.|
00001090  0a 2f 2a 20 74 68 69 73  20 66 75 6e 63 74 69 6f  |./* this functio|
000010a0  6e 20 67 65 6e 65 72 61  74 65 73 20 4c 4f 4f 4b  |n generates LOOK|
000010b0  20 55 50 20 74 61 62 6c  65 73 20 2d 20 61 72 72  | UP tables - arr|
000010c0  61 79 73 20 68 6f 6c 64  69 6e 67 20 70 72 65 2d  |ays holding pre-|
000010d0  63 61 6c 63 75 6c 61 74  65 64 20 74 72 69 67 6f  |calculated trigo|
000010e0  6e 6f 6d 65 74 72 69 63  20 76 61 72 69 61 62 6c  |nometric variabl|
000010f0  65 73 20 75 73 65 64 20  69 6e 20 74 68 65 20 72  |es used in the r|
00001100  61 79 20 63 61 73 74 69  6e 67 20 70 72 6f 63 65  |ay casting proce|
00001110  73 73 20 2a 2f 0a 0a 76  6f 69 64 20 61 75 61 5f  |ss */..void aua_|
00001120  74 61 62 6c 65 73 28 76  6f 69 64 29 0a 7b 0a 0a  |tables(void).{..|
00001130  69 6e 74 20 61 6e 67 2c  20 2f 2a 20 74 68 69 73  |int ang, /* this|
00001140  20 69 73 20 75 73 65 64  20 74 6f 20 68 6f 6c 64  | is used to hold|
00001150  20 76 61 6c 75 65 73 20  77 68 69 6c 65 20 6d 61  | values while ma|
00001160  6b 69 6e 67 20 6c 6f 6f  6b 2d 75 70 73 20 2a 2f  |king look-ups */|
00001170  0a 20 20 20 20 61 6e 67  74 3b 20 2f 2a 20 73 61  |.    angt; /* sa|
00001180  6d 65 20 2a 2f 0a 0a 66  6c 6f 61 74 20 72 61 64  |me */..float rad|
00001190  5f 61 6e 67 6c 65 3b 20  2f 2a 20 74 68 69 73 20  |_angle; /* this |
000011a0  68 6f 6c 64 73 20 74 68  65 20 72 61 64 69 61 6e  |holds the radian|
000011b0  73 20 65 71 75 69 76 61  6c 65 6e 74 20 6f 66 20  |s equivalent of |
000011c0  74 68 65 20 66 69 78 65  64 20 70 6f 69 6e 74 20  |the fixed point |
000011d0  61 6e 67 6c 65 20 73 79  73 74 65 6d 20 28 30 2d  |angle system (0-|
000011e0  31 39 32 30 20 3d 20 30  2d 33 36 30 20 64 65 67  |1920 = 0-360 deg|
000011f0  72 65 65 73 20 3d 20 30  2d 36 2e 77 68 61 74 65  |rees = 0-6.whate|
00001200  76 65 72 20 72 61 64 69  61 6e 73 2e 20 4e 65 78  |ver radians. Nex|
00001210  74 20 6d 6f 6e 74 68 20  49 27 6c 6c 20 62 65 20  |t month I'll be |
00001220  63 68 61 6e 67 69 6e 67  20 74 68 65 20 73 79 73  |changing the sys|
00001230  74 65 6d 20 73 6f 20 69  74 20 62 65 63 6f 6d 65  |tem so it become|
00001240  73 20 30 2d 31 38 30 30  20 69 6e 73 74 65 61 64  |s 0-1800 instead|
00001250  20 6f 66 20 31 39 32 30  2c 20 74 68 69 73 20 77  | of 1920, this w|
00001260  69 6c 6c 20 61 6c 6c 6f  77 20 61 20 73 6c 69 67  |ill allow a slig|
00001270  68 74 6c 79 20 73 6d 61  6c 6c 65 72 20 73 63 72  |htly smaller scr|
00001280  65 65 6e 20 77 69 64 74  68 2c 20 6d 6f 72 65 20  |een width, more |
00001290  6c 69 6b 65 20 57 6f 6c  66 65 6e 73 74 65 69 6e  |like Wolfenstein|
000012a0  2c 20 74 68 69 73 20 77  69 6c 6c 20 6c 65 61 64  |, this will lead|
000012b0  20 74 6f 20 61 6e 20 69  6e 63 72 65 61 73 65 20  | to an increase |
000012c0  69 6e 20 66 72 61 6d 65  20 72 61 74 65 2e 20 59  |in frame rate. Y|
000012d0  65 73 21 20 2a 2f 0a 0a  2f 2a 20 64 79 6e 61 6d  |es! */../* dynam|
000012e0  69 63 61 6c 6c 79 20 61  6c 6c 6f 63 61 74 65 64  |ically allocated|
000012f0  20 61 64 65 71 75 61 74  65 20 6d 65 6d 6f 72 79  | adequate memory|
00001300  20 66 6f 72 20 74 68 65  20 6c 6f 6f 6b 2d 75 70  | for the look-up|
00001310  73 20 2a 2f 0a 74 61 6e  5f 74 61 62 6c 65 20 20  |s */.tan_table  |
00001320  20 20 20 3d 20 28 69 6e  74 20 2a 29 6d 61 6c 6c  |   = (int *)mall|
00001330  6f 63 28 73 69 7a 65 6f  66 28 69 6e 74 29 20 2a  |oc(sizeof(int) *|
00001340  20 28 41 4e 47 4c 45 5f  33 36 30 2b 31 29 29 3b  | (ANGLE_360+1));|
00001350  0a 69 6e 76 5f 74 61 6e  5f 74 61 62 6c 65 20 3d  |.inv_tan_table =|
00001360  20 28 69 6e 74 20 2a 29  6d 61 6c 6c 6f 63 28 73  | (int *)malloc(s|
00001370  69 7a 65 6f 66 28 69 6e  74 29 20 2a 20 28 41 4e  |izeof(int) * (AN|
00001380  47 4c 45 5f 33 36 30 2b  31 29 29 3b 0a 0a 79 5f  |GLE_360+1));..y_|
00001390  73 74 65 70 20 20 20 20  20 20 20 20 3d 20 28 69  |step        = (i|
000013a0  6e 74 20 2a 29 6d 61 6c  6c 6f 63 28 73 69 7a 65  |nt *)malloc(size|
000013b0  6f 66 28 69 6e 74 29 20  2a 20 28 41 4e 47 4c 45  |of(int) * (ANGLE|
000013c0  5f 33 36 30 2b 31 29 29  3b 0a 78 5f 73 74 65 70  |_360+1));.x_step|
000013d0  20 20 20 20 20 20 20 20  3d 20 28 69 6e 74 20 20  |        = (int  |
000013e0  2a 29 6d 61 6c 6c 6f 63  28 73 69 7a 65 6f 66 28  |*)malloc(sizeof(|
000013f0  69 6e 74 29 20 2a 20 28  41 4e 47 4c 45 5f 33 36  |int) * (ANGLE_36|
00001400  30 2b 31 29 29 3b 0a 0a  63 6f 73 5f 74 61 62 6c  |0+1));..cos_tabl|
00001410  65 20 20 20 20 20 3d 20  28 69 6e 74 20 20 2a 29  |e     = (int  *)|
00001420  6d 61 6c 6c 6f 63 28 73  69 7a 65 6f 66 28 69 6e  |malloc(sizeof(in|
00001430  74 29 20 2a 20 28 41 4e  47 4c 45 5f 33 36 30 2b  |t) * (ANGLE_360+|
00001440  31 29 29 3b 0a 69 6e 76  5f 63 6f 73 5f 74 61 62  |1));.inv_cos_tab|
00001450  6c 65 20 3d 20 28 69 6e  74 20 20 2a 29 6d 61 6c  |le = (int  *)mal|
00001460  6c 6f 63 28 73 69 7a 65  6f 66 28 69 6e 74 29 20  |loc(sizeof(int) |
00001470  2a 20 28 41 4e 47 4c 45  5f 33 36 30 2b 31 29 29  |* (ANGLE_360+1))|
00001480  3b 0a 69 6e 76 5f 73 69  6e 5f 74 61 62 6c 65 20  |;.inv_sin_table |
00001490  3d 20 28 69 6e 74 20 20  2a 29 6d 61 6c 6c 6f 63  |= (int  *)malloc|
000014a0  28 73 69 7a 65 6f 66 28  69 6e 74 29 20 2a 20 28  |(sizeof(int) * (|
000014b0  41 4e 47 4c 45 5f 33 36  30 2b 31 29 29 3b 0a 2f  |ANGLE_360+1));./|
000014c0  2a 20 6e 65 77 20 74 61  62 6c 65 2c 20 66 6f 72  |* new table, for|
000014d0  20 74 68 65 20 65 6e 67  69 6e 65 2c 20 74 6f 20  | the engine, to |
000014e0  61 76 6f 69 64 20 75 73  69 6e 67 20 61 20 64 69  |avoid using a di|
000014f0  76 69 64 65 20 2a 2f 0a  72 65 63 69 70 5f 74 61  |vide */.recip_ta|
00001500  62 6c 65 20 20 20 3d 20  28 69 6e 74 20 20 2a 29  |ble   = (int  *)|
00001510  6d 61 6c 6c 6f 63 28 73  69 7a 65 6f 66 28 69 6e  |malloc(sizeof(in|
00001520  74 29 20 2a 20 28 4d 41  58 5f 44 49 53 54 41 4e  |t) * (MAX_DISTAN|
00001530  43 45 2b 31 29 29 3b 0a  2f 2a 20 6e 65 77 20 74  |CE+1));./* new t|
00001540  61 62 6c 65 73 20 66 6f  72 20 6d 6f 76 69 6e 67  |ables for moving|
00001550  20 74 68 65 20 76 69 65  77 20 70 6f 69 6e 74 20  | the view point |
00001560  2a 2f 0a 64 78 5f 74 61  62 6c 65 20 20 20 20 20  |*/.dx_table     |
00001570  20 3d 20 28 69 6e 74 20  20 2a 29 6d 61 6c 6c 6f  | = (int  *)mallo|
00001580  63 28 73 69 7a 65 6f 66  28 69 6e 74 29 20 2a 20  |c(sizeof(int) * |
00001590  28 41 4e 47 4c 45 5f 33  36 30 2b 31 29 29 3b 0a  |(ANGLE_360+1));.|
000015a0  64 79 5f 74 61 62 6c 65  20 20 20 20 20 20 3d 20  |dy_table      = |
000015b0  28 69 6e 74 20 20 2a 29  6d 61 6c 6c 6f 63 28 73  |(int  *)malloc(s|
000015c0  69 7a 65 6f 66 28 69 6e  74 29 20 2a 20 28 41 4e  |izeof(int) * (AN|
000015d0  47 4c 45 5f 33 36 30 2b  31 29 29 3b 0a 2f 2a 20  |GLE_360+1));./* |
000015e0  67 65 6e 65 72 61 74 65  20 74 68 65 6d 2c 20 74  |generate them, t|
000015f0  68 65 69 72 20 75 73 65  20 69 73 20 65 78 70 6c  |heir use is expl|
00001600  61 69 6e 65 64 20 69 6e  20 74 68 65 20 72 61 79  |ained in the ray|
00001610  20 63 61 73 74 69 6e 67  20 65 6e 67 69 6e 65 20  | casting engine |
00001620  2a 2f 0a 0a 66 6f 72 28  61 6e 67 74 3d 41 4e 47  |*/..for(angt=ANG|
00001630  4c 45 5f 30 3b 61 6e 67  74 3c 3d 41 4e 47 4c 45  |LE_0;angt<=ANGLE|
00001640  5f 33 36 30 3b 61 6e 67  74 2b 2b 29 0a 7b 0a 61  |_360;angt++).{.a|
00001650  6e 67 3d 61 6e 67 74 3b  0a 2f 2a 20 74 68 69 73  |ng=angt;./* this|
00001660  20 6e 65 78 74 20 6c 69  6e 65 20 63 61 6c 63 75  | next line calcu|
00001670  6c 61 74 65 73 20 74 68  65 20 72 61 64 69 61 6e  |lates the radian|
00001680  20 61 6e 67 6c 65 20 74  6f 20 70 61 73 73 20 74  | angle to pass t|
00001690  6f 20 74 68 65 20 74 72  69 67 2e 20 66 75 6e 63  |o the trig. func|
000016a0  74 69 6f 6e 73 20 2a 2f  0a 72 61 64 5f 61 6e 67  |tions */.rad_ang|
000016b0  6c 65 3d 28 66 6c 6f 61  74 29 28 28 33 2e 32 37  |le=(float)((3.27|
000016c0  32 65 2d 34 29 20 2b 20  61 6e 67 20 2a 20 32 2a  |2e-4) + ang * 2*|
000016d0  33 2e 31 34 31 35 39 32  36 35 34 2f 41 4e 47 4c  |3.141592654/ANGL|
000016e0  45 5f 33 36 30 29 3b 0a  0a 74 61 6e 5f 74 61 62  |E_360);..tan_tab|
000016f0  6c 65 5b 61 6e 67 5d 3d  28 69 6e 74 29 28 74 61  |le[ang]=(int)(ta|
00001700  6e 28 72 61 64 5f 61 6e  67 6c 65 29 2a 36 35 35  |n(rad_angle)*655|
00001710  33 36 29 3b 0a 69 6e 76  5f 74 61 6e 5f 74 61 62  |36);.inv_tan_tab|
00001720  6c 65 5b 61 6e 67 5d 3d  28 69 6e 74 29 28 28 31  |le[ang]=(int)((1|
00001730  2f 74 61 6e 28 72 61 64  5f 61 6e 67 6c 65 29 29  |/tan(rad_angle))|
00001740  2a 36 35 35 33 36 29 3b  0a 2f 2a 20 6e 6f 74 65  |*65536);./* note|
00001750  20 74 68 61 20 61 62 6f  76 65 20 63 6f 6e 76 65  | tha above conve|
00001760  72 73 69 6f 6e 73 20 74  6f 20 66 69 78 65 64 20  |rsions to fixed |
00001770  70 6f 69 6e 74 20 69 6e  74 65 67 65 72 73 20 2a  |point integers *|
00001780  2f 0a 0a 2f 2a 20 77 65  20 64 6f 20 74 68 65 20  |/../* we do the |
00001790  73 61 6d 65 20 66 6f 72  20 74 68 65 73 65 20 74  |same for these t|
000017a0  61 62 6c 65 73 2c 20 62  75 74 20 75 6e 66 6f 72  |ables, but unfor|
000017b0  74 75 6e 61 74 65 6c 79  20 61 74 20 74 68 65 20  |tunately at the |
000017c0  61 73 79 6d 70 74 6f 74  65 73 20 74 68 65 20 6e  |asymptotes the n|
000017d0  75 6d 62 65 72 73 20 62  65 63 6f 6d 65 20 61 77  |umbers become aw|
000017e0  6b 77 61 72 64 6c 79 20  6c 61 72 67 65 20 74 6f  |kwardly large to|
000017f0  20 73 74 6f 72 65 20 69  6e 20 6f 75 72 20 66 69  | store in our fi|
00001800  78 65 64 20 70 6f 69 6e  74 20 72 65 70 72 65 73  |xed point repres|
00001810  65 6e 74 61 74 69 6f 6e  2e 20 49 6e 73 74 65 61  |entation. Instea|
00001820  64 20 6f 66 20 6d 75 6c  74 69 70 6c 79 69 6e 67  |d of multiplying|
00001830  20 62 79 20 36 34 20 77  65 20 64 6f 20 38 2c 20  | by 64 we do 8, |
00001840  74 6f 20 6d 61 6b 65 20  73 75 72 65 20 74 68 61  |to make sure tha|
00001850  74 20 6e 6f 20 6f 76 65  72 66 6c 6f 77 20 63 61  |t no overflow ca|
00001860  6e 20 6f 63 63 75 72 20  61 74 20 74 68 69 73 20  |n occur at this |
00001870  73 74 61 67 65 2e 20 57  65 20 6f 6e 6c 79 20 6e  |stage. We only n|
00001880  65 65 64 20 74 6f 20 6d  75 6c 74 69 70 6c 79 20  |eed to multiply |
00001890  62 79 20 61 6e 6f 74 68  65 72 20 38 20 6c 61 74  |by another 8 lat|
000018a0  65 72 20 69 6e 20 74 68  65 20 65 6e 67 69 6e 65  |er in the engine|
000018b0  2c 20 69 74 73 20 6f 6b  61 79 20 2a 2f 0a 0a 69  |, its okay */..i|
000018c0  66 28 61 6e 67 3e 3d 41  4e 47 4c 45 5f 30 20 26  |f(ang>=ANGLE_0 &|
000018d0  26 20 61 6e 67 3c 41 4e  47 4c 45 5f 31 38 30 29  |& ang<ANGLE_180)|
000018e0  0a 7b 0a 79 5f 73 74 65  70 5b 61 6e 67 5d 3d 66  |.{.y_step[ang]=f|
000018f0  61 62 73 28 20 28 38 29  20 2a 20 28 74 61 6e 5f  |abs( (8) * (tan_|
00001900  74 61 62 6c 65 5b 61 6e  67 5d 29 20 29 3b 0a 7d  |table[ang]) );.}|
00001910  0a 65 6c 73 65 0a 20 20  79 5f 73 74 65 70 5b 61  |.else.  y_step[a|
00001920  6e 67 5d 3d 2d 66 61 62  73 28 20 28 38 29 20 2a  |ng]=-fabs( (8) *|
00001930  20 28 74 61 6e 5f 74 61  62 6c 65 5b 61 6e 67 5d  | (tan_table[ang]|
00001940  29 20 29 3b 0a 0a 69 66  28 61 6e 67 3e 3d 41 4e  |) );..if(ang>=AN|
00001950  47 4c 45 5f 39 30 20 26  26 20 61 6e 67 3c 41 4e  |GLE_90 && ang<AN|
00001960  47 4c 45 5f 32 37 30 29  0a 7b 0a 78 5f 73 74 65  |GLE_270).{.x_ste|
00001970  70 5b 61 6e 67 5d 3d 2d  66 61 62 73 28 20 28 38  |p[ang]=-fabs( (8|
00001980  29 20 2a 20 28 69 6e 76  5f 74 61 6e 5f 74 61 62  |) * (inv_tan_tab|
00001990  6c 65 5b 61 6e 67 5d 29  20 29 3b 0a 7d 0a 65 6c  |le[ang]) );.}.el|
000019a0  73 65 0a 7b 0a 78 5f 73  74 65 70 5b 61 6e 67 5d  |se.{.x_step[ang]|
000019b0  3d 66 61 62 73 28 20 28  38 29 20 2a 20 28 69 6e  |=fabs( (8) * (in|
000019c0  76 5f 74 61 6e 5f 74 61  62 6c 65 5b 61 6e 67 5d  |v_tan_table[ang]|
000019d0  29 20 29 3b 0a 7d 0a 0a  2f 2a 20 63 6f 6e 76 65  |) );.}../* conve|
000019e0  72 73 69 6f 6e 20 74 6f  20 66 69 78 65 64 20 70  |rsion to fixed p|
000019f0  6f 69 6e 74 20 2a 2f 0a  69 6e 76 5f 63 6f 73 5f  |oint */.inv_cos_|
00001a00  74 61 62 6c 65 5b 61 6e  67 5d 3d 28 69 6e 74 29  |table[ang]=(int)|
00001a10  28 28 31 2f 63 6f 73 28  72 61 64 5f 61 6e 67 6c  |((1/cos(rad_angl|
00001a20  65 29 29 2a 36 35 35 33  36 29 3b 0a 69 6e 76 5f  |e))*65536);.inv_|
00001a30  73 69 6e 5f 74 61 62 6c  65 5b 61 6e 67 5d 3d 28  |sin_table[ang]=(|
00001a40  69 6e 74 29 28 28 31 2f  73 69 6e 28 72 61 64 5f  |int)((1/sin(rad_|
00001a50  61 6e 67 6c 65 29 29 2a  36 35 35 33 36 29 3b 0a  |angle))*65536);.|
00001a60  0a 2f 2a 20 77 6f 72 6b  20 6f 75 74 20 74 61 62  |./* work out tab|
00001a70  6c 65 73 20 66 6f 72 20  6d 6f 76 69 6e 67 20 74  |les for moving t|
00001a80  68 65 20 76 69 65 77 70  6f 69 6e 74 20 2a 2f 0a  |he viewpoint */.|
00001a90  64 78 5f 74 61 62 6c 65  5b 61 6e 67 5d 3d 28 69  |dx_table[ang]=(i|
00001aa0  6e 74 29 28 63 6f 73 28  36 2e 32 38 2a 61 6e 67  |nt)(cos(6.28*ang|
00001ab0  2f 41 4e 47 4c 45 5f 33  36 30 29 2a 53 54 45 50  |/ANGLE_360)*STEP|
00001ac0  5f 4c 45 4e 47 54 48 29  2a 36 35 35 33 36 3b 0a  |_LENGTH)*65536;.|
00001ad0  64 79 5f 74 61 62 6c 65  5b 61 6e 67 5d 3d 28 69  |dy_table[ang]=(i|
00001ae0  6e 74 29 28 73 69 6e 28  36 2e 32 38 2a 61 6e 67  |nt)(sin(6.28*ang|
00001af0  2f 41 4e 47 4c 45 5f 33  36 30 29 2a 53 54 45 50  |/ANGLE_360)*STEP|
00001b00  5f 4c 45 4e 47 54 48 29  2a 36 35 35 33 36 3b 0a  |_LENGTH)*65536;.|
00001b10  7d 0a 0a 2f 2a 20 74 68  65 20 63 6f 73 69 6e 65  |}../* the cosine|
00001b20  20 74 61 62 6c 65 20 69  73 20 75 73 65 64 20 74  | table is used t|
00001b30  6f 20 67 65 74 20 72 69  64 20 6f 66 20 74 68 65  |o get rid of the|
00001b40  20 22 66 69 73 68 20 62  6f 77 6c 20 65 66 66 65  | "fish bowl effe|
00001b50  63 74 22 2c 20 65 78 70  6c 61 69 6e 65 64 20 69  |ct", explained i|
00001b60  6e 20 74 68 65 20 72 61  79 20 63 61 73 74 65 72  |n the ray caster|
00001b70  2e 20 42 61 73 69 63 61  6c 6c 79 20 77 65 20 77  |. Basically we w|
00001b80  6f 72 6b 20 6f 75 74 20  63 6f 73 69 6e 65 73 20  |ork out cosines |
00001b90  66 6f 72 20 6f 75 72 20  6f 77 6e 20 73 70 61 6e  |for our own span|
00001ba0  20 6f 66 20 76 69 73 69  6f 6e 2c 20 66 72 6f 6d  | of vision, from|
00001bb0  20 2d 33 30 20 64 65 67  72 65 65 73 20 74 6f 20  | -30 degrees to |
00001bc0  2b 33 30 20 64 65 67 72  65 65 73 2e 20 54 68 69  |+30 degrees. Thi|
00001bd0  73 20 6d 65 61 6e 73 20  74 68 61 74 20 61 73 20  |s means that as |
00001be0  77 65 20 73 63 61 6e 20  66 72 6f 6d 20 6c 65 66  |we scan from lef|
00001bf0  74 20 74 6f 20 72 69 67  68 74 2c 20 6f 72 20 76  |t to right, or v|
00001c00  69 63 65 20 76 65 72 73  61 2c 20 6f 75 72 20 72  |ice versa, our r|
00001c10  61 79 73 20 6f 66 20 6c  69 67 68 74 20 61 72 65  |ays of light are|
00001c20  20 61 63 74 75 61 6c 6c  79 20 63 61 73 74 20 6f  | actually cast o|
00001c30  75 74 20 69 6e 20 61 20  63 61 72 74 65 73 69 61  |ut in a cartesia|
00001c40  6e 2c 20 63 69 72 63 75  6c 61 72 20 77 61 79 2e  |n, circular way.|
00001c50  20 4f 75 72 20 77 6f 72  6c 64 20 69 73 20 68 6f  | Our world is ho|
00001c60  77 65 76 65 72 20 73 71  75 61 72 65 2c 20 70 6f  |wever square, po|
00001c70  6c 61 72 2c 20 73 6f 20  77 65 20 68 61 76 65 20  |lar, so we have |
00001c80  74 6f 20 61 63 6b 6e 6f  77 6c 65 64 67 65 20 74  |to acknowledge t|
00001c90  68 65 20 64 69 73 74 6f  72 74 69 6f 6e 20 63 61  |he distortion ca|
00001ca0  75 73 65 64 20 62 79 20  6d 69 78 69 6e 67 20 63  |used by mixing c|
00001cb0  61 72 74 65 73 69 61 6e  20 61 6e 64 20 70 6f 6c  |artesian and pol|
00001cc0  61 72 20 63 6f 6f 72 64  69 6e 61 74 65 73 2e 20  |ar coordinates. |
00001cd0  49 6e 20 74 68 69 73 20  6c 6f 6f 6b 20 75 70 20  |In this look up |
00001ce0  77 65 20 61 6c 73 6f 20  68 61 76 65 20 61 20 62  |we also have a b|
00001cf0  69 74 20 6f 66 20 73 63  61 6c 69 6e 67 20 69 6e  |it of scaling in|
00001d00  20 69 74 2c 20 79 65 74  20 6d 6f 72 65 20 74 69  | it, yet more ti|
00001d10  6d 65 20 73 61 76 69 6e  67 20 21 21 21 20 2a 2f  |me saving !!! */|
00001d20  0a 0a 66 6f 72 28 61 6e  67 3d 2d 41 4e 47 4c 45  |..for(ang=-ANGLE|
00001d30  5f 33 30 3b 61 6e 67 3c  3d 41 4e 47 4c 45 5f 33  |_30;ang<=ANGLE_3|
00001d40  30 3b 61 6e 67 2b 2b 29  0a 7b 0a 2f 2a 20 77 6f  |0;ang++).{./* wo|
00001d50  72 6b 20 6f 75 74 20 72  61 64 69 61 6e 73 20 74  |rk out radians t|
00001d60  6f 20 70 61 73 73 20 74  6f 20 63 6f 73 69 6e 65  |o pass to cosine|
00001d70  20 66 75 6e 63 74 69 6f  6e 20 2a 2f 0a 72 61 64  | function */.rad|
00001d80  5f 61 6e 67 6c 65 3d 28  66 6c 6f 61 74 29 28 28  |_angle=(float)((|
00001d90  33 2e 32 37 32 65 2d 34  29 2b 20 61 6e 67 20 2a  |3.272e-4)+ ang *|
00001da0  20 32 2a 33 2e 31 34 31  35 39 32 36 35 34 2f 41  | 2*3.141592654/A|
00001db0  4e 47 4c 45 5f 33 36 30  29 3b 0a 0a 2f 2a 66 69  |NGLE_360);../*fi|
00001dc0  78 65 64 20 70 6f 69 6e  74 20 63 6f 6e 76 65 72  |xed point conver|
00001dd0  73 69 6f 6e 20 2a 2f 0a  63 6f 73 5f 74 61 62 6c  |sion */.cos_tabl|
00001de0  65 5b 61 6e 67 2b 41 4e  47 4c 45 5f 33 30 5d 3d  |e[ang+ANGLE_30]=|
00001df0  28 69 6e 74 29 28 31 33  33 31 32 2f 28 63 6f 73  |(int)(13312/(cos|
00001e00  28 72 61 64 5f 61 6e 67  6c 65 29 29 2a 36 35 35  |(rad_angle))*655|
00001e10  33 36 29 3b 0a 7d 0a 0a  2f 2a 20 74 68 69 73 20  |36);.}../* this |
00001e20  63 72 65 61 74 65 73 20  61 20 72 65 63 69 70 72  |creates a recipr|
00001e30  6f 63 61 6c 20 74 61 62  6c 65 2c 20 73 6f 20 77  |ocal table, so w|
00001e40  65 20 64 6f 6e 27 74 20  68 61 76 65 20 74 6f 20  |e don't have to |
00001e50  75 73 65 20 64 69 76 69  64 65 73 2e 20 4d 75 6c  |use divides. Mul|
00001e60  74 69 70 6c 79 69 6e 67  20 62 79 20 74 68 65 20  |tiplying by the |
00001e70  72 65 63 69 70 72 6f 63  61 6c 20 6f 66 20 61 20  |reciprocal of a |
00001e80  6e 75 6d 62 65 72 20 69  73 20 74 68 65 20 73 61  |number is the sa|
00001e90  6d 65 20 61 73 20 64 69  76 69 64 69 6e 67 20 62  |me as dividing b|
00001ea0  79 20 69 74 3a 20 41 66  74 65 72 20 61 6c 6c 2c  |y it: After all,|
00001eb0  0a 0a 38 20 2f 20 34 20  3d 20 32 20 61 6e 64 20  |..8 / 4 = 2 and |
00001ec0  38 20 2a 20 30 2e 32 35  20 28 31 20 6f 76 65 72  |8 * 0.25 (1 over|
00001ed0  20 34 29 20 3d 20 32 20  2d 20 74 68 65 79 20 70  | 4) = 2 - they p|
00001ee0  72 6f 64 75 63 65 20 74  68 65 20 73 61 6d 65 20  |roduce the same |
00001ef0  72 65 73 75 6c 74 20 2a  2f 0a 0a 66 6f 72 28 61  |result */..for(a|
00001f00  6e 67 3d 31 3b 61 6e 67  3c 4d 41 58 5f 44 49 53  |ng=1;ang<MAX_DIS|
00001f10  54 41 4e 43 45 3b 61 6e  67 2b 2b 29 0a 7b 0a 20  |TANCE;ang++).{. |
00001f20  20 2f 2a 20 69 74 20 69  73 20 73 74 69 6c 6c 20  | /* it is still |
00001f30  66 69 78 65 64 20 70 6f  69 6e 74 20 74 68 6f 75  |fixed point thou|
00001f40  67 68 20 2a 2f 0a 20 20  72 65 63 69 70 5f 74 61  |gh */.  recip_ta|
00001f50  62 6c 65 5b 61 6e 67 5d  3d 28 69 6e 74 29 28 31  |ble[ang]=(int)(1|
00001f60  2e 30 2f 28 66 6c 6f 61  74 29 61 6e 67 2a 36 35  |.0/(float)ang*65|
00001f70  35 33 36 29 3b 0a 7d 0a  0a 7d 0a 0a 2f 2a 20 74  |536);.}..}../* t|
00001f80  68 69 73 20 66 75 6e 63  74 69 6f 6e 20 69 73 20  |his function is |
00001f90  74 68 65 20 68 65 61 72  74 20 6f 66 20 74 68 65  |the heart of the|
00001fa0  20 70 72 6f 67 72 61 6d  2c 20 74 68 65 20 65 6e  | program, the en|
00001fb0  67 69 6e 65 2c 20 74 6f  20 67 65 6e 65 72 61 74  |gine, to generat|
00001fc0  65 20 74 68 65 20 66 69  72 73 74 20 70 65 72 73  |e the first pers|
00001fd0  6f 6e 20 76 69 65 77 20  2a 2f 0a 76 6f 69 64 20  |on view */.void |
00001fe0  61 75 61 5f 72 61 79 63  61 73 74 65 72 28 69 6e  |aua_raycaster(in|
00001ff0  74 20 76 69 65 77 5f 78  2c 69 6e 74 20 76 69 65  |t view_x,int vie|
00002000  77 5f 79 2c 69 6e 74 20  76 69 65 77 5f 61 6e 67  |w_y,int view_ang|
00002010  6c 65 29 0a 7b 0a 2f 2a  20 72 65 6d 65 6d 62 65  |le).{./* remembe|
00002020  72 20 74 68 61 74 20 77  65 20 61 72 65 20 74 68  |r that we are th|
00002030  69 6e 6b 69 6e 67 20 69  6e 20 32 2d 44 2c 20 6e  |inking in 2-D, n|
00002040  6f 74 20 69 6e 20 33 44  20 77 68 65 6e 20 77 65  |ot in 3D when we|
00002050  20 64 69 73 63 75 73 73  20 69 64 65 61 73 2e 20  | discuss ideas. |
00002060  42 65 6c 6f 77 20 64 6f  65 73 20 6e 6f 74 20 6d  |Below does not m|
00002070  65 61 6e 20 22 61 20 66  6c 6f 6f 72 20 62 65 6c  |ean "a floor bel|
00002080  6f 77 22 2c 20 69 74 20  72 65 61 6c 6c 79 20 6d  |ow", it really m|
00002090  65 61 6e 73 20 22 62 65  68 69 6e 64 22 2c 20 62  |eans "behind", b|
000020a0  75 74 20 77 65 20 73 61  79 20 62 65 6c 6f 77 20  |ut we say below |
000020b0  62 65 63 61 75 73 65 20  77 65 20 61 72 65 20 69  |because we are i|
000020c0  6d 61 67 69 6e 69 6e 67  20 6c 6f 6f 6b 69 6e 67  |magining looking|
000020d0  20 64 6f 77 6e 20 6f 6e  20 74 68 65 20 76 69 65  | down on the vie|
000020e0  77 20 70 6f 69 6e 74 20  74 6f 20 66 6f 72 6d 20  |w point to form |
000020f0  61 20 32 2d 44 20 70 6c  61 6e 20 2a 2f 0a 0a 2f  |a 2-D plan */../|
00002100  2a 20 74 68 69 73 20 66  75 6e 63 74 69 6f 6e 2c  |* this function,|
00002110  20 66 6f 72 20 65 61 63  68 20 63 6f 6c 75 6d 6e  | for each column|
00002120  20 6f 66 20 74 68 65 20  33 32 30 20 70 69 78 65  | of the 320 pixe|
00002130  6c 20 77 69 64 74 68 20  4d 6f 64 65 20 31 33 20  |l width Mode 13 |
00002140  73 63 72 65 65 6e 2c 20  63 61 73 74 73 20 6f 75  |screen, casts ou|
00002150  74 20 74 77 6f 20 72 61  79 73 2e 20 4f 6e 65 20  |t two rays. One |
00002160  72 61 79 20 6c 6f 6f 6b  73 20 66 6f 72 20 58 2c  |ray looks for X,|
00002170  20 68 6f 72 69 7a 6f 6e  74 61 6c 20 69 6e 74 65  | horizontal inte|
00002180  72 73 65 63 74 69 6f 6e  73 20 77 69 74 68 20 77  |rsections with w|
00002190  61 6c 6c 73 2c 20 61 6e  64 20 74 68 65 20 6f 74  |alls, and the ot|
000021a0  68 65 72 20 74 72 61 63  6b 73 20 69 6e 74 65 72  |her tracks inter|
000021b0  73 65 63 74 69 6f 6e 73  20 77 69 74 68 20 59 2c  |sections with Y,|
000021c0  20 76 65 72 74 69 63 61  6c 20 77 61 6c 6c 20 62  | vertical wall b|
000021d0  6f 75 6e 64 61 72 69 65  73 2e 20 41 66 74 65 72  |oundaries. After|
000021e0  20 61 6c 6c 2c 20 74 68  65 20 6f 6e 6c 79 20 74  | all, the only t|
000021f0  69 6d 65 20 61 20 63 6f  6c 6c 69 73 69 6f 6e 20  |ime a collision |
00002200  63 6f 75 6c 64 20 6f 63  63 75 72 20 69 73 20 6f  |could occur is o|
00002210  6e 20 61 20 62 6f 75 6e  64 61 72 79 20 6f 66 20  |n a boundary of |
00002220  61 20 63 65 6c 6c 2c 20  61 73 20 74 68 65 20 77  |a cell, as the w|
00002230  61 6c 6c 20 66 69 6c 6c  73 20 75 70 20 74 68 65  |all fills up the|
00002240  20 65 6e 74 69 72 65 20  63 65 6c 6c 2e 20 45 78  | entire cell. Ex|
00002250  70 65 63 74 20 74 6f 20  73 65 65 20 6c 6f 74 73  |pect to see lots|
00002260  20 6f 66 20 36 34 27 73  2c 20 74 68 6f 75 67 68  | of 64's, though|
00002270  20 72 65 6d 65 6d 62 65  72 20 74 68 61 74 20 74  | remember that t|
00002280  68 69 73 20 72 61 79 20  63 61 73 74 65 72 20 69  |his ray caster i|
00002290  73 20 76 65 72 79 20 72  6f 75 74 69 6e 65 2c 20  |s very routine, |
000022a0  61 6e 64 20 68 61 73 20  6e 6f 74 20 61 74 20 61  |and has not at a|
000022b0  6c 6c 20 62 65 65 6e 20  70 75 74 20 74 68 72 6f  |ll been put thro|
000022c0  75 67 68 20 6d 79 20 22  62 6f 78 20 6f 66 20 6d  |ugh my "box of m|
000022d0  61 67 69 63 22 2e 20 54  68 65 20 65 6e 67 69 6e  |agic". The engin|
000022e0  65 20 77 69 6c 6c 20 62  65 63 6f 6d 65 20 6d 75  |e will become mu|
000022f0  63 68 20 6d 6f 72 65 20  70 65 72 73 6f 6e 61 6c  |ch more personal|
00002300  69 73 65 64 20 76 65 72  79 20 73 6f 6f 6e 21 20  |ised very soon! |
00002310  2a 2f 0a 0a 0a 0a 69 6e  74 20 63 65 6c 6c 5f 78  |*/....int cell_x|
00002320  2c 20 2f 2a 20 75 73 65  64 20 74 6f 20 73 74 6f  |, /* used to sto|
00002330  72 65 20 77 68 69 63 68  20 63 65 6c 6c 20 6f 66  |re which cell of|
00002340  20 74 68 65 20 77 61 6c  6c 73 20 64 61 74 61 20  | the walls data |
00002350  74 68 65 20 72 61 79 20  69 73 20 69 6e 20 2a 2f  |the ray is in */|
00002360  0a 63 65 6c 6c 5f 79 2c  20 2f 2a 20 22 20 2a 2f  |.cell_y, /* " */|
00002370  0a 63 61 73 74 69 6e 67  3d 32 2c 20 2f 2a 20 75  |.casting=2, /* u|
00002380  73 65 64 20 74 6f 20 73  74 6f 72 65 20 69 66 20  |sed to store if |
00002390  72 61 79 20 63 61 73 74  69 6e 67 20 68 61 73 20  |ray casting has |
000023a0  66 69 6e 69 73 68 65 64  20 2a 2f 0a 78 5f 68 69  |finished */.x_hi|
000023b0  74 5f 74 79 70 65 2c 20  2f 2a 20 74 68 69 73 20  |t_type, /* this |
000023c0  73 74 6f 72 65 73 20 74  68 65 20 77 61 6c 6c 20  |stores the wall |
000023d0  74 79 70 65 20 68 69 74  20 62 79 20 74 68 65 20  |type hit by the |
000023e0  78 20 63 61 73 74 69 6e  67 20 72 61 79 20 2a 2f  |x casting ray */|
000023f0  0a 79 5f 68 69 74 5f 74  79 70 65 2c 20 2f 2a 20  |.y_hit_type, /* |
00002400  74 68 69 73 20 73 6f 74  72 65 73 20 74 68 65 20  |this sotres the |
00002410  77 61 6c 6c 20 74 79 70  65 20 28 6e 75 6d 62 65  |wall type (numbe|
00002420  72 29 20 68 69 74 20 62  79 20 74 68 65 20 79 20  |r) hit by the y |
00002430  72 61 79 20 2a 2f 0a 78  5f 62 6f 75 6e 64 2c 20  |ray */.x_bound, |
00002440  2f 2a 20 74 68 69 73 20  68 6f 6c 64 73 20 74 68  |/* this holds th|
00002450  65 20 6e 65 78 74 20 78  20 62 6f 75 6e 64 61 72  |e next x boundar|
00002460  79 20 66 6f 72 20 61 20  70 6f 73 73 69 62 6c 65  |y for a possible|
00002470  20 69 6e 74 65 72 73 65  63 74 69 6f 6e 20 2a 2f  | intersection */|
00002480  0a 79 5f 62 6f 75 6e 64  2c 20 2f 2a 20 74 68 69  |.y_bound, /* thi|
00002490  73 20 68 6f 6c 64 73 20  74 68 65 20 6e 65 78 74  |s holds the next|
000024a0  20 79 20 62 6f 75 6e 64  61 72 79 20 66 6f 72 20  | y boundary for |
000024b0  61 20 70 6f 73 73 69 62  6c 65 20 69 6e 74 65 72  |a possible inter|
000024c0  73 65 63 74 69 6f 6e 20  2a 2f 0a 6e 65 78 74 5f  |section */.next_|
000024d0  79 5f 63 65 6c 6c 2c 20  2f 2a 20 74 68 69 73 20  |y_cell, /* this |
000024e0  69 73 20 75 73 65 64 20  74 6f 20 66 69 67 75 72  |is used to figur|
000024f0  65 20 6f 75 74 20 74 68  65 20 71 75 61 64 72 61  |e out the quadra|
00002500  6e 74 20 6f 66 20 74 68  65 20 72 61 79 20 28 2b  |nt of the ray (+|
00002510  2f 2d 29 2a 2f 0a 6e 65  78 74 5f 78 5f 63 65 6c  |/-)*/.next_x_cel|
00002520  6c 2c 20 2f 2a 20 22 20  2a 2f 0a 78 5f 64 65 6c  |l, /* " */.x_del|
00002530  74 61 2c 20 2f 2a 20 74  68 69 73 20 69 73 20 2b  |ta, /* this is +|
00002540  27 64 20 74 6f 20 74 68  65 20 78 5f 62 6f 75 6e  |'d to the x_boun|
00002550  64 20 76 61 72 2e 20 74  6f 20 6d 6f 76 65 20 74  |d var. to move t|
00002560  6f 20 74 68 65 20 6e 65  78 74 20 62 6f 75 6e 64  |o the next bound|
00002570  61 72 79 20 2a 2f 0a 79  5f 64 65 6c 74 61 2c 20  |ary */.y_delta, |
00002580  2f 2a 20 74 68 69 73 20  69 73 20 2b 27 64 20 74  |/* this is +'d t|
00002590  6f 20 74 68 65 20 79 5f  62 6f 75 6e 64 20 76 61  |o the y_bound va|
000025a0  72 2e 20 74 6f 20 6d 6f  76 65 20 74 6f 20 74 68  |r. to move to th|
000025b0  65 20 6e 65 78 74 20 62  6f 75 6e 64 61 72 79 20  |e next boundary |
000025c0  2a 2f 0a 78 69 5f 73 61  76 65 2c 20 2f 2a 20 74  |*/.xi_save, /* t|
000025d0  68 69 73 20 73 74 6f 72  65 73 20 77 68 65 72 65  |his stores where|
000025e0  20 74 68 65 20 78 20 63  61 73 74 69 6e 67 20 72  | the x casting r|
000025f0  61 79 20 6d 61 64 65 20  69 74 73 20 69 6e 74 65  |ay made its inte|
00002600  72 73 65 63 74 69 6f 6e  20 2a 2f 0a 79 69 5f 73  |rsection */.yi_s|
00002610  61 76 65 2c 20 2f 2a 20  74 68 69 73 20 73 74 6f  |ave, /* this sto|
00002620  72 65 73 20 77 68 65 72  65 20 74 68 65 20 79 20  |res where the y |
00002630  63 61 73 74 69 6e 67 20  72 61 79 20 6d 61 64 65  |casting ray made|
00002640  20 69 74 73 20 69 6e 74  65 72 73 65 63 74 69 6f  | its intersectio|
00002650  6e 20 2a 2f 0a 73 63 61  6c 65 2c 20 20 20 2f 2a  |n */.scale,   /*|
00002660  20 74 68 69 73 20 73 74  6f 72 65 73 20 74 68 65  | this stores the|
00002670  20 73 63 61 6c 65 20 6f  66 20 74 68 65 20 73 6c  | scale of the sl|
00002680  69 76 65 72 20 74 6f 20  62 65 20 64 72 61 77 6e  |iver to be drawn|
00002690  20 69 6e 20 65 61 63 68  20 63 6f 6c 75 6d 6e 20  | in each column |
000026a0  2a 2f 0a 72 61 79 2c 20  2f 2a 20 74 68 69 73 20  |*/.ray, /* this |
000026b0  73 74 6f 72 65 73 20 74  68 65 20 72 61 79 20 6e  |stores the ray n|
000026c0  75 6d 62 65 72 20 62 65  69 6e 67 20 63 61 73 74  |umber being cast|
000026d0  20 6f 75 74 20 28 30 2d  33 32 30 29 2a 2f 0a 78  | out (0-320)*/.x|
000026e0  72 61 79 2c 20 2f 2a 20  74 68 69 73 20 66 6c 61  |ray, /* this fla|
000026f0  67 20 69 73 20 75 73 65  64 20 74 6f 20 73 68 6f  |g is used to sho|
00002700  77 20 69 66 20 63 61 73  74 69 6e 67 20 69 73 20  |w if casting is |
00002710  6f 76 65 72 20 2a 2f 0a  79 72 61 79 2c 20 2f 2a  |over */.yray, /*|
00002720  20 22 20 2a 2f 0a 64 69  73 74 5f 78 2c 20 2f 2a  | " */.dist_x, /*|
00002730  20 74 68 69 73 20 68 6f  6c 64 73 20 74 68 65 20  | this holds the |
00002740  64 69 73 74 61 6e 63 65  20 74 6f 20 74 68 65 20  |distance to the |
00002750  78 20 69 6e 74 65 72 73  65 63 74 69 6f 6e 20 2a  |x intersection *|
00002760  2f 0a 64 69 73 74 5f 79  3b 20 2f 2a 20 74 68 69  |/.dist_y; /* thi|
00002770  73 20 68 6f 6c 64 73 20  74 68 65 20 64 69 73 74  |s holds the dist|
00002780  61 6e 63 65 20 74 6f 20  74 68 65 20 79 20 69 6e  |ance to the y in|
00002790  74 65 72 73 65 63 74 69  6f 6e 20 2a 2f 0a 0a 69  |tersection */..i|
000027a0  6e 74 20 78 69 2c 0a 20  20 20 20 20 20 79 69 2c  |nt xi,.      yi,|
000027b0  0a 20 20 20 20 20 20 78  61 64 64 2c 0a 20 20 20  |.      xadd,.   |
000027c0  20 20 20 79 61 64 64 3b  20 2f 2a 20 74 68 65 73  |   yadd; /* thes|
000027d0  65 20 61 72 65 20 75 73  65 64 20 74 6f 20 61 63  |e are used to ac|
000027e0  63 75 72 61 74 65 6c 79  20 74 72 61 63 65 20 61  |curately trace a|
000027f0  6e 64 20 6d 6f 76 65 20  65 61 63 68 20 72 61 79  |nd move each ray|
00002800  20 2a 2f 0a 0a 0a 69 6e  74 20 76 61 72 69 61 62  | */...int variab|
00002810  6c 65 73 5b 38 5d 3b 20  2f 2a 20 74 68 69 73 20  |les[8]; /* this |
00002820  69 73 20 75 73 65 64 20  74 6f 20 70 61 73 73 20  |is used to pass |
00002830  76 61 72 69 61 62 6c 65  73 20 74 6f 20 61 20 73  |variables to a s|
00002840  75 70 65 72 20 66 61 73  74 20 73 6c 69 76 65 72  |uper fast sliver|
00002850  20 72 65 6e 64 65 72 20  2a 2f 0a 0a 2f 2a 20 66  | render */../* f|
00002860  69 72 73 74 6c 79 2c 20  77 65 20 73 65 74 20 75  |irstly, we set u|
00002870  70 20 74 68 65 20 76 61  72 69 61 62 6c 65 73 5b  |p the variables[|
00002880  5d 20 77 65 20 61 6c 72  65 61 64 79 20 6b 6e 6f  |] we already kno|
00002890  77 2c 20 73 75 63 68 20  61 73 20 73 63 72 65 65  |w, such as scree|
000028a0  6e 5f 61 64 64 72 65 73  73 2c 20 77 61 6c 6c 73  |n_address, walls|
000028b0  20 61 6e 64 20 74 68 65  20 73 63 72 65 65 6e 20  | and the screen |
000028c0  68 65 69 67 68 74 20 77  65 20 61 72 65 20 75 73  |height we are us|
000028d0  69 6e 67 2e 20 54 68 65  73 65 20 61 72 65 20 61  |ing. These are a|
000028e0  6c 6c 20 74 68 69 6e 67  73 20 77 68 69 63 68 20  |ll things which |
000028f0  6f 75 72 20 73 6c 69 76  65 72 20 72 65 6e 64 65  |our sliver rende|
00002900  72 65 72 20 6e 65 65 64  73 20 74 6f 20 6b 6e 6f  |rer needs to kno|
00002910  77 20 74 6f 20 70 6c 6f  74 20 69 74 73 20 63 6f  |w to plot its co|
00002920  6c 75 6d 6e 20 2a 2f 0a  0a 76 61 72 69 61 62 6c  |lumn */..variabl|
00002930  65 73 5b 30 5d 3d 28 63  68 61 72 20 2a 29 73 63  |es[0]=(char *)sc|
00002940  72 65 65 6e 5f 61 64 64  72 65 73 73 3b 0a 76 61  |reen_address;.va|
00002950  72 69 61 62 6c 65 73 5b  31 5d 3d 28 63 68 61 72  |riables[1]=(char|
00002960  20 2a 29 77 61 6c 6c 73  3b 0a 76 61 72 69 61 62  | *)walls;.variab|
00002970  6c 65 73 5b 35 5d 3d 53  43 52 45 45 4e 5f 48 45  |les[5]=SCREEN_HE|
00002980  49 47 48 54 3b 0a 0a 2f  2a 20 6e 6f 77 20 77 65  |IGHT;../* now we|
00002990  20 67 65 74 20 64 6f 77  6e 20 74 6f 20 74 68 65  | get down to the|
000029a0  20 6e 69 74 74 79 20 67  72 69 74 74 79 2e 20 48  | nitty gritty. H|
000029b0  65 72 65 20 77 65 20 73  75 62 74 72 61 63 74 20  |ere we subtract |
000029c0  33 30 20 64 65 67 72 65  65 73 20 66 72 6f 6d 20  |30 degrees from |
000029d0  74 68 65 20 76 69 65 77  69 6e 67 20 61 6e 67 6c  |the viewing angl|
000029e0  65 20 72 65 6d 65 6d 62  65 72 20 74 68 61 74 20  |e remember that |
000029f0  6f 75 72 20 46 4f 56 20  69 73 20 36 30 20 64 65  |our FOV is 60 de|
00002a00  67 72 65 65 73 20 77 68  69 63 68 20 6d 65 61 6e  |grees which mean|
00002a10  73 20 74 68 61 74 20 77  65 20 63 61 73 74 20 66  |s that we cast f|
00002a20  72 6f 6d 20 2d 33 30 20  74 6f 20 2b 33 30 20 2a  |rom -30 to +30 *|
00002a30  2f 0a 0a 69 66 20 28 20  28 76 69 65 77 5f 61 6e  |/..if ( (view_an|
00002a40  67 6c 65 2d 3d 41 4e 47  4c 45 5f 33 30 29 20 3c  |gle-=ANGLE_30) <|
00002a50  20 30 29 0a 20 20 20 7b  0a 20 20 20 2f 2a 20 74  | 0).   {.   /* t|
00002a60  68 69 73 20 65 6e 73 75  72 65 73 20 74 68 61 74  |his ensures that|
00002a70  20 77 65 20 64 6f 6e 27  74 20 67 6f 20 6f 76 65  | we don't go ove|
00002a80  72 20 6f 72 20 75 6e 64  65 72 20 30 2f 33 36 30  |r or under 0/360|
00002a90  20 64 65 67 72 65 65 73  21 20 2a 2f 0a 20 20 20  | degrees! */.   |
00002aa0  76 69 65 77 5f 61 6e 67  6c 65 3d 41 4e 47 4c 45  |view_angle=ANGLE|
00002ab0  5f 33 36 30 20 2b 20 76  69 65 77 5f 61 6e 67 6c  |_360 + view_angl|
00002ac0  65 3b 0a 20 20 20 7d 0a  2f 2a 20 6e 6f 77 20 77  |e;.   }./* now w|
00002ad0  65 20 73 74 61 72 74 20  74 68 65 20 6d 61 69 6e  |e start the main|
00002ae0  20 6c 6f 6f 70 2c 20 73  74 61 72 74 20 61 74 20  | loop, start at |
00002af0  74 68 65 20 72 69 67 68  74 20 6f 66 20 74 68 65  |the right of the|
00002b00  20 73 63 72 65 65 6e 20  28 33 31 39 29 2c 20 61  | screen (319), a|
00002b10  6e 64 20 63 61 73 74 20  65 61 63 68 20 63 6f 6c  |nd cast each col|
00002b20  75 6d 6e 20 6f 6e 65 20  62 79 20 6f 6e 65 20 74  |umn one by one t|
00002b30  6f 20 74 68 65 20 6c 65  66 74 20 2a 2f 0a 0a 66  |o the left */..f|
00002b40  6f 72 20 28 72 61 79 3d  33 31 39 3b 20 72 61 79  |or (ray=319; ray|
00002b50  3e 3d 30 3b 20 72 61 79  2d 2d 29 0a 20 20 20 20  |>=0; ray--).    |
00002b60  7b 0a 2f 2a 20 66 6f 72  20 65 61 63 68 20 72 61  |{./* for each ra|
00002b70  79 20 74 6f 20 62 65 20  63 61 73 74 20 77 65 20  |y to be cast we |
00002b80  61 63 74 75 61 6c 6c 79  20 63 61 73 74 20 6f 75  |actually cast ou|
00002b90  74 20 74 77 6f 20 72 61  79 73 20 3a 20 6f 6e 65  |t two rays : one|
00002ba0  20 74 6f 20 63 68 65 63  6b 20 66 6f 72 20 76 65  | to check for ve|
00002bb0  72 74 69 63 61 6c 20 62  6f 75 6e 64 61 72 79 20  |rtical boundary |
00002bc0  63 6f 6c 6c 69 73 69 6f  6e 73 20 61 6e 64 20 74  |collisions and t|
00002bd0  68 65 20 6f 74 68 65 72  20 74 6f 20 63 68 65 63  |he other to chec|
00002be0  6b 20 66 6f 72 20 68 6f  72 69 7a 6f 6e 74 61 6c  |k for horizontal|
00002bf0  20 62 6f 75 6e 64 61 72  79 20 63 6f 6c 6c 69 73  | boundary collis|
00002c00  69 6f 6e 73 2e 20 43 6f  6e 73 69 64 65 72 69 6e  |ions. Considerin|
00002c10  67 20 74 68 61 74 20 77  61 6c 6c 73 20 66 69 6c  |g that walls fil|
00002c20  6c 20 75 70 20 65 61 63  68 20 63 65 6c 6c 2c 20  |l up each cell, |
00002c30  77 65 20 6e 65 65 64 20  6f 6e 6c 79 20 6c 6f 6f  |we need only loo|
00002c40  6b 20 66 6f 72 20 69 6e  74 65 72 73 65 63 74 69  |k for intersecti|
00002c50  6f 6e 73 20 6f 6e 20 74  68 65 20 62 6f 75 6e 64  |ons on the bound|
00002c60  61 72 69 65 73 2e 20 57  65 20 68 61 76 65 20 74  |aries. We have t|
00002c70  6f 20 70 65 72 66 6f 72  6d 20 73 65 70 65 72 61  |o perform sepera|
00002c80  74 65 20 63 61 73 74 20  62 65 63 61 75 73 65 20  |te cast because |
00002c90  6a 75 73 74 20 63 61 73  74 69 6e 67 20 6f 6e 65  |just casting one|
00002ca0  20 72 61 79 20 63 6f 6d  70 6c 69 63 61 74 65 73  | ray complicates|
00002cb0  20 74 68 65 20 6d 61 74  74 65 72 20 61 6e 64 20  | the matter and |
00002cc0  69 74 20 64 6f 65 73 6e  27 74 20 67 69 76 65 20  |it doesn't give |
00002cd0  6d 75 63 68 20 73 70 65  65 64 20 69 6e 63 72 65  |much speed incre|
00002ce0  61 73 65 2c 20 69 66 20  61 6e 79 2e 20 2a 2f 0a  |ase, if any. */.|
00002cf0  0a 2f 2a 20 4e 45 57 20  4c 49 4e 45 20 3a 20 57  |./* NEW LINE : W|
00002d00  65 20 68 61 76 65 20 74  6f 20 63 68 65 63 6b 20  |e have to check |
00002d10  74 6f 20 73 65 65 20 69  66 20 74 68 65 20 76 69  |to see if the vi|
00002d20  65 77 69 6e 67 20 61 6e  67 6c 65 20 69 73 20 61  |ewing angle is a|
00002d30  74 20 74 68 65 20 61 73  79 6d 70 74 6f 74 65 73  |t the asymptotes|
00002d40  2c 20 75 6e 66 6f 72 74  75 6e 61 74 65 6c 79 20  |, unfortunately |
00002d50  74 68 65 20 66 69 78 65  64 20 70 6f 69 6e 74 20  |the fixed point |
00002d60  73 79 73 74 65 6d 20 63  61 6e 6e 6f 74 20 73 74  |system cannot st|
00002d70  6f 72 65 20 74 68 65 20  76 61 6c 75 65 73 20 68  |ore the values h|
00002d80  65 6c 64 20 61 74 20 74  68 65 73 65 20 61 6e 67  |eld at these ang|
00002d90  6c 65 73 2c 20 73 6f 20  77 65 20 68 61 76 65 20  |les, so we have |
00002da0  74 6f 20 61 76 6f 69 64  20 74 68 65 69 72 20 75  |to avoid their u|
00002db0  73 65 2e 20 54 68 69 73  20 69 73 20 6e 6f 74 20  |se. This is not |
00002dc0  76 65 72 79 20 65 6c 65  67 61 6e 74 20 49 20 6b  |very elegant I k|
00002dd0  6e 6f 77 2c 20 62 75 74  20 69 74 20 73 61 76 65  |now, but it save|
00002de0  73 20 61 20 6c 6f 74 20  6f 66 20 68 65 61 64 20  |s a lot of head |
00002df0  61 63 68 65 73 20 61 6e  64 20 6e 6f 20 6f 6e 65  |aches and no one|
00002e00  20 63 61 6e 20 74 65 6c  6c 20 77 65 27 76 65 20  | can tell we've |
00002e10  64 6f 6e 65 20 69 74 21  20 2a 2f 0a 0a 69 66 28  |done it! */..if(|
00002e20  76 69 65 77 5f 61 6e 67  6c 65 3d 3d 41 4e 47 4c  |view_angle==ANGL|
00002e30  45 5f 30 20 7c 7c 20 76  69 65 77 5f 61 6e 67 6c  |E_0 || view_angl|
00002e40  65 3d 3d 41 4e 47 4c 45  5f 39 30 20 7c 7c 20 76  |e==ANGLE_90 || v|
00002e50  69 65 77 5f 61 6e 67 6c  65 20 3d 3d 41 4e 47 4c  |iew_angle ==ANGL|
00002e60  45 5f 31 38 30 20 7c 7c  20 76 69 65 77 5f 61 6e  |E_180 || view_an|
00002e70  67 6c 65 3d 3d 41 4e 47  4c 45 5f 32 37 30 29 76  |gle==ANGLE_270)v|
00002e80  69 65 77 5f 61 6e 67 6c  65 2b 2b 3b 0a 2f 2a 20  |iew_angle++;./* |
00002e90  53 45 43 54 49 4f 4e 20  31 20 3a 20 43 41 4c 43  |SECTION 1 : CALC|
00002ea0  55 4c 41 54 49 4e 47 20  54 48 45 20 46 49 52 53  |ULATING THE FIRS|
00002eb0  54 20 58 20 61 6e 64 20  59 20 49 4e 54 45 52 53  |T X and Y INTERS|
00002ec0  45 43 54 49 4f 4e 53 2a  2f 0a 2f 2a 20 4f 6e 63  |ECTIONS*/./* Onc|
00002ed0  65 20 77 65 20 68 61 76  65 20 64 6f 6e 65 20 74  |e we have done t|
00002ee0  68 69 73 20 74 68 65 20  66 6f 6c 6c 6f 77 69 6e  |his the followin|
00002ef0  67 20 69 6e 74 65 72 73  65 63 74 69 6f 6e 73 20  |g intersections |
00002f00  61 72 65 20 65 61 73 79  2a 2f 0a 0a 0a 2f 2a 20  |are easy*/.../* |
00002f10  54 68 65 20 58 20 43 41  53 54 49 4e 47 20 52 41  |The X CASTING RA|
00002f20  59 20 3a 20 68 65 72 65  20 77 65 20 74 65 73 74  |Y : here we test|
00002f30  20 74 6f 20 73 65 65 20  69 66 20 74 68 65 20 61  | to see if the a|
00002f40  6e 67 6c 65 20 6f 66 20  74 68 65 20 72 61 79 20  |ngle of the ray |
00002f50  69 73 20 66 61 63 69 6e  67 20 75 70 77 61 72 64  |is facing upward|
00002f60  73 2e 20 57 65 20 6e 65  65 64 20 74 6f 20 6b 6e  |s. We need to kn|
00002f70  6f 77 20 77 68 69 63 68  20 68 61 6c 66 70 6c 61  |ow which halfpla|
00002f80  6e 65 20 77 65 27 72 65  20 63 61 73 74 69 6e 67  |ne we're casting|
00002f90  20 66 72 6f 6d 20 72 65  6c 61 74 69 76 65 20 74  | from relative t|
00002fa0  6f 20 74 68 65 20 79 2d  61 78 69 73 2e 20 2a 2f  |o the y-axis. */|
00002fb0  0a 0a 0a 20 69 66 20 28  76 69 65 77 5f 61 6e 67  |... if (view_ang|
00002fc0  6c 65 20 3e 3d 20 41 4e  47 4c 45 5f 30 20 26 26  |le >= ANGLE_0 &&|
00002fd0  20 76 69 65 77 5f 61 6e  67 6c 65 20 3c 20 41 4e  | view_angle < AN|
00002fe0  47 4c 45 5f 31 38 30 29  0a 20 20 20 20 20 20 20  |GLE_180).       |
00002ff0  7b 0a 2f 2a 20 69 66 20  73 6f 20 74 68 65 6e 20  |{./* if so then |
00003000  77 65 20 61 73 73 69 67  6e 20 76 61 72 69 61 62  |we assign variab|
00003010  6c 65 73 20 74 6f 20 74  68 61 74 20 65 66 66 65  |les to that effe|
00003020  63 74 2e 20 57 65 20 6d  75 73 74 20 63 6f 6d 70  |ct. We must comp|
00003030  75 74 65 20 74 68 65 20  66 69 72 73 74 20 68 6f  |ute the first ho|
00003040  72 69 7a 6f 6e 74 61 6c  20 6c 69 6e 65 20 74 68  |rizontal line th|
00003050  61 74 20 63 6f 75 6c 64  20 62 65 20 69 6e 74 65  |at could be inte|
00003060  72 73 65 63 74 65 64 20  77 69 74 68 20 74 68 65  |rsected with the|
00003070  20 72 61 79 2e 20 4e 6f  74 65 20 3a 20 69 74 20  | ray. Note : it |
00003080  77 69 6c 6c 20 62 65 20  61 62 6f 76 65 20 74 68  |will be above th|
00003090  65 20 76 69 65 77 65 72  2e 2a 2f 0a 0a 79 5f 62  |e viewer.*/..y_b|
000030a0  6f 75 6e 64 20 3d 20 28  43 45 4c 4c 5f 59 5f 53  |ound = (CELL_Y_S|
000030b0  49 5a 45 20 2b 20 28 76  69 65 77 5f 79 20 26 20  |IZE + (view_y & |
000030c0  30 78 66 66 63 30 29 29  3b 20 2f 2a 20 74 68 69  |0xffc0)); /* thi|
000030d0  73 20 6c 69 6e 65 20 69  73 20 6d 65 72 65 6c 79  |s line is merely|
000030e0  20 61 6e 20 6f 70 74 69  6d 69 7a 65 64 20 76 65  | an optimized ve|
000030f0  72 73 69 6f 6e 20 6f 66  20 43 45 4c 4c 5f 59 5f  |rsion of CELL_Y_|
00003100  53 49 5a 45 20 2b 20 28  76 69 65 77 5f 79 20 25  |SIZE + (view_y %|
00003110  20 36 34 29 2e 20 49 20  75 73 65 20 69 74 20 6d  | 64). I use it m|
00003120  61 6e 79 20 74 69 6d 65  73 20 69 6e 20 74 68 69  |any times in thi|
00003130  73 20 65 6e 67 69 6e 65  2e 20 2a 2f 0a 0a 79 5f  |s engine. */..y_|
00003140  64 65 6c 74 61 20 3d 20  43 45 4c 4c 5f 59 5f 53  |delta = CELL_Y_S|
00003150  49 5a 45 3b 20 2f 2a 20  74 68 69 73 20 6d 65 61  |IZE; /* this mea|
00003160  6e 73 20 74 68 61 74 20  66 6f 72 20 65 76 65 72  |ns that for ever|
00003170  79 20 6d 6f 76 65 6d 65  6e 74 20 6f 66 20 74 68  |y movement of th|
00003180  65 20 72 61 79 2c 20 74  68 65 20 79 20 62 6f 75  |e ray, the y bou|
00003190  6e 64 61 72 79 20 6d 6f  76 65 73 20 75 70 20 6f  |ndary moves up o|
000031a0  6e 65 20 63 65 6c 6c 2c  20 77 68 69 63 68 20 69  |ne cell, which i|
000031b0  74 20 77 6f 75 6c 64 2e  20 49 74 20 69 73 20 74  |t would. It is t|
000031c0  68 65 20 64 65 6c 74 61  20 74 6f 20 67 65 74 20  |he delta to get |
000031d0  74 6f 20 74 68 65 20 6e  65 78 74 20 68 6f 72 69  |to the next hori|
000031e0  7a 6f 6e 74 61 6c 20 6c  69 6e 65 20 2a 2f 0a 0a  |zontal line */..|
000031f0  2f 2a 20 6e 65 78 74 20  77 65 20 75 73 65 20 74  |/* next we use t|
00003200  68 65 20 69 6e 76 65 72  73 65 20 74 61 6e 20 66  |he inverse tan f|
00003210  75 6e 63 74 69 6f 6e 20  74 6f 20 63 61 6c 63 75  |unction to calcu|
00003220  6c 61 74 65 20 74 68 65  20 69 6e 69 74 69 61 6c  |late the initial|
00003230  20 70 6f 73 69 74 69 6f  6e 20 6f 66 20 74 68 65  | position of the|
00003240  20 78 20 62 6f 75 6e 64  61 72 79 20 73 65 61 72  | x boundary sear|
00003250  63 68 69 6e 67 20 72 61  79 20 6f 6e 20 69 74 73  |ching ray on its|
00003260  20 66 69 72 73 74 20 69  6e 74 65 72 73 65 63 74  | first intersect|
00003270  69 6f 6e 2e 20 57 65 20  68 61 76 65 20 74 6f 20  |ion. We have to |
00003280  75 73 65 20 74 61 6e 20  62 65 63 61 75 73 65 20  |use tan because |
00003290  69 74 20 69 73 20 72 65  6c 61 74 65 64 20 74 6f  |it is related to|
000032a0  20 73 6c 6f 70 65 73 20  2a 2f 0a 0a 2f 2a 20 4e  | slopes */../* N|
000032b0  45 57 20 46 49 58 45 44  20 50 4f 49 4e 54 20 43  |EW FIXED POINT C|
000032c0  41 4c 43 55 4c 41 54 49  4f 4e 20 6f 66 0a 78 69  |ALCULATION of.xi|
000032d0  20 3d 20 28 66 6c 6f 61  74 29 28 69 6e 76 5f 74  | = (float)(inv_t|
000032e0  61 6e 5f 74 61 62 6c 65  5b 76 69 65 77 5f 61 6e  |an_table[view_an|
000032f0  67 6c 65 5d 20 2a 20 28  79 5f 62 6f 75 6e 64 20  |gle] * (y_bound |
00003300  2d 20 76 69 65 77 5f 79  29 29 20 2b 76 69 65 77  |- view_y)) +view|
00003310  5f 78 3b 20 2a 2f 0a 0a  78 69 3d 28 28 79 5f 62  |_x; */..xi=((y_b|
00003320  6f 75 6e 64 2d 76 69 65  77 5f 79 29 29 2a 28 69  |ound-view_y))*(i|
00003330  6e 76 5f 74 61 6e 5f 74  61 62 6c 65 5b 76 69 65  |nv_tan_table[vie|
00003340  77 5f 61 6e 67 6c 65 5d  29 3b 0a 78 69 2b 3d 28  |w_angle]);.xi+=(|
00003350  76 69 65 77 5f 78 3c 3c  31 36 29 3b 0a 0a 2f 2a  |view_x<<16);../*|
00003360  20 74 68 69 73 20 6d 65  61 6e 73 20 74 68 61 74  | this means that|
00003370  20 74 68 65 20 71 75 61  64 72 61 6e 74 20 6f 66  | the quadrant of|
00003380  20 74 68 65 20 72 61 79  20 69 73 20 6e 6f 74 20  | the ray is not |
00003390  6e 65 67 61 74 69 76 65  2c 20 74 68 61 74 20 69  |negative, that i|
000033a0  73 20 74 68 65 20 6e 65  78 74 20 79 20 62 6f 75  |s the next y bou|
000033b0  6e 64 61 72 79 20 77 69  6c 6c 20 61 70 70 65 61  |ndary will appea|
000033c0  72 20 61 62 6f 76 65 20  74 68 65 20 76 69 65 77  |r above the view|
000033d0  20 70 6f 69 6e 74 20 61  6e 64 20 6e 6f 74 20 62  | point and not b|
000033e0  65 6c 6f 77 20 28 69 6e  20 74 65 72 6d 73 20 6f  |elow (in terms o|
000033f0  66 20 6c 6f 6f 6b 69 6e  67 20 64 6f 77 6e 20 6f  |f looking down o|
00003400  6e 20 74 68 65 20 76 69  65 77 65 72 29 2e 20 54  |n the viewer). T|
00003410  68 69 73 20 69 73 20 74  68 65 20 63 65 6c 6c 20  |his is the cell |
00003420  64 65 6c 74 61 20 2a 2f  0a 6e 65 78 74 5f 79 5f  |delta */.next_y_|
00003430  63 65 6c 6c 20 3d 20 30  3b 0a 0a 20 20 20 20 20  |cell = 0;..     |
00003440  20 20 7d 0a 2f 2a 20 69  66 20 74 68 65 20 76 69  |  }./* if the vi|
00003450  65 77 69 6e 67 20 61 6e  67 6c 65 20 69 73 20 67  |ewing angle is g|
00003460  72 65 61 74 65 72 20 74  68 61 6e 20 31 38 30 20  |reater than 180 |
00003470  64 65 67 72 65 65 73 20  61 6e 64 20 6c 65 73 73  |degrees and less|
00003480  20 74 68 61 6e 20 32 37  30 20 64 65 67 72 65 65  | than 270 degree|
00003490  73 20 74 68 65 6e 20 77  65 20 68 61 76 65 20 74  |s then we have t|
000034a0  6f 20 64 6f 20 6f 74 68  65 72 20 63 61 6c 63 75  |o do other calcu|
000034b0  6c 61 74 69 6f 6e 73 20  28 6c 6f 77 65 72 20 68  |lations (lower h|
000034c0  61 6c 66 20 70 6c 61 6e  65 29 20 2a 2f 0a 20 20  |alf plane) */.  |
000034d0  20 20 65 6c 73 65 0a 20  20 20 20 20 20 20 7b 0a  |  else.       {.|
000034e0  2f 2a 20 77 65 20 6b 6e  6f 77 20 74 68 61 74 20  |/* we know that |
000034f0  62 65 63 61 75 73 65 20  74 68 65 20 76 69 65 77  |because the view|
00003500  69 6e 67 20 61 6e 67 6c  65 20 69 73 20 64 6f 77  |ing angle is dow|
00003510  6e 77 61 72 64 73 2c 20  73 6f 20 74 68 65 6e 20  |nwards, so then |
00003520  74 68 65 20 68 6f 72 69  7a 6f 6e 74 61 6c 20 69  |the horizontal i|
00003530  6e 74 65 72 73 65 63 74  69 6f 6e 20 68 61 73 20  |ntersection has |
00003540  74 6f 20 62 65 20 42 45  4c 4f 57 20 74 68 65 20  |to be BELOW the |
00003550  76 69 65 77 65 72 20 2a  2f 0a 79 5f 62 6f 75 6e  |viewer */.y_boun|
00003560  64 20 3d 20 28 69 6e 74  29 28 76 69 65 77 5f 79  |d = (int)(view_y|
00003570  20 26 20 30 78 66 66 63  30 29 3b 0a 0a 2f 2a 20  | & 0xffc0);../* |
00003580  62 65 63 61 75 73 65 20  6f 66 20 74 68 69 73 20  |because of this |
00003590  77 65 20 61 6c 73 6f 20  6b 6e 6f 77 20 74 68 61  |we also know tha|
000035a0  74 20 74 68 65 20 6e 65  78 74 20 59 20 69 6e 74  |t the next Y int|
000035b0  65 72 73 65 63 74 69 6f  6e 73 20 77 69 6c 6c 20  |ersections will |
000035c0  62 65 20 61 20 63 65 6c  6c 20 62 65 6c 6f 77 20  |be a cell below |
000035d0  65 61 63 68 20 6f 74 68  65 72 2e 20 53 6f 20 74  |each other. So t|
000035e0  68 65 20 64 65 6c 74 61  20 66 6f 72 20 65 61 63  |he delta for eac|
000035f0  68 20 68 6f 72 69 7a 6f  6e 74 61 6c 20 69 6e 74  |h horizontal int|
00003600  65 72 73 65 63 74 69 6f  6e 20 77 69 6c 6c 20 62  |ersection will b|
00003610  65 20 61 20 63 65 6c 6c  20 62 65 6c 6f 77 20 20  |e a cell below  |
00003620  74 68 65 20 6c 61 73 74  20 2a 2f 0a 79 5f 64 65  |the last */.y_de|
00003630  6c 74 61 20 3d 20 2d 43  45 4c 4c 5f 59 5f 53 49  |lta = -CELL_Y_SI|
00003640  5a 45 3b 0a 0a 2f 2a 20  77 65 20 61 67 61 69 6e  |ZE;../* we again|
00003650  20 75 73 65 20 74 68 65  20 74 61 6e 67 65 6e 74  | use the tangent|
00003660  20 66 75 6e 63 74 69 6f  6e 2c 20 6a 75 73 74 20  | function, just |
00003670  61 73 20 62 65 66 6f 72  65 2c 20 74 6f 20 63 61  |as before, to ca|
00003680  6c 63 75 6c 61 74 65 20  74 68 65 20 66 69 72 73  |lculate the firs|
00003690  74 20 78 20 69 6e 74 65  72 73 65 63 74 69 6f 6e  |t x intersection|
000036a0  20 77 69 74 68 20 61 20  62 6f 75 6e 64 61 72 79  | with a boundary|
000036b0  2e 20 2a 2f 0a 0a 2f 2a  20 4e 45 57 20 46 49 58  |. */../* NEW FIX|
000036c0  45 44 20 50 4f 49 4e 54  2c 20 49 20 77 6f 6e 27  |ED POINT, I won'|
000036d0  74 20 73 68 6f 77 20 74  68 65 20 6f 6c 64 20 6c  |t show the old l|
000036e0  69 6e 65 73 20 61 6e 79  20 6d 6f 72 65 20 2a 2f  |ines any more */|
000036f0  0a 0a 78 69 3d 28 28 79  5f 62 6f 75 6e 64 2d 76  |..xi=((y_bound-v|
00003700  69 65 77 5f 79 29 29 2a  28 69 6e 76 5f 74 61 6e  |iew_y))*(inv_tan|
00003710  5f 74 61 62 6c 65 5b 76  69 65 77 5f 61 6e 67 6c  |_table[view_angl|
00003720  65 5d 29 3b 0a 78 69 2b  3d 28 76 69 65 77 5f 78  |e]);.xi+=(view_x|
00003730  3c 3c 31 36 29 3b 0a 0a  2f 2a 20 61 6e 64 20 77  |<<16);../* and w|
00003740  65 20 6b 6e 6f 77 20 61  6c 73 6f 20 74 68 61 74  |e know also that|
00003750  20 74 68 65 20 71 75 61  64 72 61 6e 74 20 69 73  | the quadrant is|
00003760  20 62 65 6c 6f 77 20 74  68 65 20 70 6c 61 79 65  | below the playe|
00003770  72 2c 20 73 6f 20 74 68  65 20 63 65 6c 6c 20 79  |r, so the cell y|
00003780  20 64 65 6c 74 61 20 77  69 6c 6c 20 62 65 20 6e  | delta will be n|
00003790  65 67 61 74 69 76 65 20  2a 2f 0a 0a 6e 65 78 74  |egative */..next|
000037a0  5f 79 5f 63 65 6c 6c 20  3d 20 2d 31 3b 0a 0a 20  |_y_cell = -1;.. |
000037b0  20 20 20 20 20 20 7d 0a  2f 2a 20 59 20 52 41 59  |      }./* Y RAY|
000037c0  20 3a 20 77 65 20 64 6f  20 73 69 6d 69 6c 61 72  | : we do similar|
000037d0  20 63 61 6c 63 75 6c 61  74 69 6f 6e 73 20 62 75  | calculations bu|
000037e0  74 20 74 68 69 73 20 74  69 6d 65 20 74 6f 20 63  |t this time to c|
000037f0  61 6c 63 75 6c 61 74 65  20 74 68 65 20 66 69 72  |alculate the fir|
00003800  73 74 20 79 20 69 6e 74  65 72 73 65 63 74 69 6f  |st y intersectio|
00003810  6e 73 20 2a 2f 0a 0a 2f  2a 20 77 65 20 74 65 73  |ns */../* we tes|
00003820  74 20 74 6f 20 73 65 65  20 69 66 20 74 68 65 20  |t to see if the |
00003830  76 69 65 77 20 61 6e 67  6c 65 20 69 73 20 77 69  |view angle is wi|
00003840  74 68 69 6e 20 74 68 65  20 76 65 72 74 69 63 61  |thin the vertica|
00003850  6c 20 61 73 79 6d 70 74  6f 74 65 73 20 6f 66 20  |l asymptotes of |
00003860  33 36 30 20 64 65 67 72  65 65 73 2e 20 57 65 20  |360 degrees. We |
00003870  6e 65 65 64 20 74 6f 20  6b 6e 6f 77 20 77 68 69  |need to know whi|
00003880  63 68 20 68 61 6c 66 70  6c 61 6e 65 20 77 65 27  |ch halfplane we'|
00003890  72 65 20 63 61 73 74 69  6e 67 20 66 72 6f 6d 20  |re casting from |
000038a0  72 65 6c 61 74 69 76 65  20 74 6f 20 74 68 65 20  |relative to the |
000038b0  78 2d 61 78 69 73 2e 20  2a 2f 0a 0a 69 66 20 28  |x-axis. */..if (|
000038c0  76 69 65 77 5f 61 6e 67  6c 65 20 3c 20 41 4e 47  |view_angle < ANG|
000038d0  4c 45 5f 39 30 20 7c 7c  20 76 69 65 77 5f 61 6e  |LE_90 || view_an|
000038e0  67 6c 65 20 3e 3d 20 41  4e 47 4c 45 5f 32 37 30  |gle >= ANGLE_270|
000038f0  29 0a 20 20 20 20 20 20  20 7b 0a 2f 2a 20 77 65  |).       {./* we|
00003900  20 63 61 6e 20 64 65 64  75 63 65 20 63 65 72 74  | can deduce cert|
00003910  61 69 6e 20 74 68 69 6e  67 73 2c 20 6a 75 73 74  |ain things, just|
00003920  20 61 73 20 77 69 74 68  20 74 68 65 20 78 20 72  | as with the x r|
00003930  61 79 2e 20 57 65 20 6b  6e 6f 77 20 74 68 61 74  |ay. We know that|
00003940  20 62 65 63 61 75 73 65  20 74 68 65 20 76 69 65  | because the vie|
00003950  77 20 61 6e 67 6c 65 20  69 73 20 74 6f 20 74 68  |w angle is to th|
00003960  65 20 72 69 67 68 74 2c  20 74 68 65 20 6e 65 78  |e right, the nex|
00003970  74 20 58 20 62 6f 75 6e  64 61 72 79 20 28 77 68  |t X boundary (wh|
00003980  69 63 68 20 69 73 20 63  6f 6e 73 74 61 6e 74 29  |ich is constant)|
00003990  20 77 69 6c 6c 20 62 65  20 74 6f 20 74 68 65 20  | will be to the |
000039a0  52 49 47 48 54 20 6f 66  20 74 68 65 20 76 69 65  |RIGHT of the vie|
000039b0  77 65 72 2e 20 2a 2f 0a  78 5f 62 6f 75 6e 64 20  |wer. */.x_bound |
000039c0  3d 20 28 69 6e 74 29 28  43 45 4c 4c 5f 58 5f 53  |= (int)(CELL_X_S|
000039d0  49 5a 45 20 2b 20 28 76  69 65 77 5f 78 20 26 20  |IZE + (view_x & |
000039e0  30 78 66 66 63 30 29 29  3b 0a 0a 2f 2a 20 6e 6f  |0xffc0));../* no|
000039f0  74 69 63 65 20 74 68 69  73 20 72 65 63 75 72 72  |tice this recurr|
00003a00  69 6e 67 20 6f 70 74 69  6d 69 7a 61 74 69 6f 6e  |ing optimization|
00003a10  20 6f 66 20 76 69 65 77  5f 78 20 25 20 36 34 20  | of view_x % 64 |
00003a20  2a 2f 0a 0a 2f 2a 20 61  6e 64 20 77 65 20 61 6c  |*/../* and we al|
00003a30  73 6f 20 6b 6e 6f 77 20  74 68 61 74 20 65 61 63  |so know that eac|
00003a40  68 20 76 65 72 74 69 63  61 6c 20 63 65 6c 6c 20  |h vertical cell |
00003a50  62 6f 75 6e 64 61 72 79  20 61 66 74 65 72 20 74  |boundary after t|
00003a60  68 65 20 66 69 72 73 74  20 77 69 6c 6c 20 62 65  |he first will be|
00003a70  20 61 20 63 65 6c 6c 27  73 20 77 69 64 74 68 20  | a cell's width |
00003a80  61 77 61 79 20 2a 2f 0a  0a 78 5f 64 65 6c 74 61  |away */..x_delta|
00003a90  20 3d 20 43 45 4c 4c 5f  58 5f 53 49 5a 45 3b 0a  | = CELL_X_SIZE;.|
00003aa0  2f 2a 20 74 68 69 73 20  74 69 6d 65 20 77 65 20  |/* this time we |
00003ab0  75 73 65 20 74 68 65 20  74 61 6e 67 65 6e 74 20  |use the tangent |
00003ac0  66 75 6e 63 74 69 6f 6e  20 28 6e 6f 74 20 74 68  |function (not th|
00003ad0  65 20 69 6e 76 65 72 73  65 20 74 61 6e 29 20 74  |e inverse tan) t|
00003ae0  6f 20 63 61 6c 63 75 6c  61 74 65 20 77 68 65 72  |o calculate wher|
00003af0  65 20 74 68 65 20 66 69  72 73 74 20 79 20 62 6f  |e the first y bo|
00003b00  75 6e 64 61 72 79 20 69  6e 74 65 72 73 65 63 74  |undary intersect|
00003b10  69 6f 6e 20 77 69 6c 6c  20 6f 63 63 75 72 29 2e  |ion will occur).|
00003b20  20 2a 2f 0a 0a 2f 2a 20  4e 45 57 20 46 49 58 45  | */../* NEW FIXE|
00003b30  44 20 50 4f 49 4e 54 20  2a 2f 0a 0a 79 69 3d 28  |D POINT */..yi=(|
00003b40  28 78 5f 62 6f 75 6e 64  20 2d 20 76 69 65 77 5f  |(x_bound - view_|
00003b50  78 29 29 2a 28 74 61 6e  5f 74 61 62 6c 65 5b 76  |x))*(tan_table[v|
00003b60  69 65 77 5f 61 6e 67 6c  65 5d 29 3b 0a 79 69 2b  |iew_angle]);.yi+|
00003b70  3d 28 76 69 65 77 5f 79  3c 3c 31 36 29 3b 0a 2f  |=(view_y<<16);./|
00003b80  2a 20 61 6e 64 20 77 65  20 6b 6e 6f 77 20 61 6c  |* and we know al|
00003b90  73 6f 20 74 68 61 74 20  62 65 63 61 75 73 65 20  |so that because |
00003ba0  74 68 65 20 76 69 65 77  20 69 73 20 70 6f 73 69  |the view is posi|
00003bb0  74 69 76 65 2c 20 74 68  65 20 6e 65 78 74 5f 78  |tive, the next_x|
00003bc0  5f 63 65 6c 6c 20 64 65  6c 74 61 20 64 6f 65 73  |_cell delta does|
00003bd0  20 6e 6f 74 20 6e 65 65  64 20 74 6f 20 62 65 20  | not need to be |
00003be0  6e 65 67 61 74 69 76 65  20 2a 2f 0a 0a 6e 65 78  |negative */..nex|
00003bf0  74 5f 78 5f 63 65 6c 6c  20 3d 20 30 3b 0a 0a 20  |t_x_cell = 0;.. |
00003c00  20 20 20 20 20 20 7d 0a  2f 2a 20 6f 74 68 65 72  |      }./* other|
00003c10  77 69 73 65 2c 20 69 66  20 74 68 65 20 76 69 65  |wise, if the vie|
00003c20  77 69 6e 67 20 61 6e 67  6c 65 20 69 73 20 74 6f  |wing angle is to|
00003c30  77 61 72 64 73 20 74 68  65 20 6f 74 68 65 72 20  |wards the other |
00003c40  64 69 72 65 63 74 69 6f  6e 2e 2e 2e 2a 2f 0a 20  |direction...*/. |
00003c50  20 20 20 65 6c 73 65 0a  20 20 20 20 20 20 20 7b  |   else.       {|
00003c60  0a 2f 2a 20 77 65 20 6b  6e 6f 77 20 74 68 61 74  |./* we know that|
00003c70  20 74 68 65 20 66 69 72  73 74 20 78 20 62 6f 75  | the first x bou|
00003c80  6e 64 61 72 79 20 63 61  6e 20 6f 63 63 75 72 20  |ndary can occur |
00003c90  6f 6e 6c 79 20 74 6f 20  74 68 65 20 6c 65 66 74  |only to the left|
00003ca0  20 6f 66 20 74 68 65 20  76 69 65 77 65 72 20 62  | of the viewer b|
00003cb0  65 63 61 75 73 65 20 74  68 65 20 72 61 79 20 61  |ecause the ray a|
00003cc0  6e 67 6c 65 20 69 73 20  66 61 63 69 6e 67 20 6c  |ngle is facing l|
00003cd0  65 66 74 2e 20 53 6f 20  77 65 20 63 61 6e 20 64  |eft. So we can d|
00003ce0  6f 20 76 69 65 77 5f 78  20 25 20 36 34 20 74 6f  |o view_x % 64 to|
00003cf0  20 63 61 6c 63 75 6c 61  74 65 20 74 68 65 20 66  | calculate the f|
00003d00  69 72 73 74 20 76 65 72  74 69 63 61 6c 20 62 6f  |irst vertical bo|
00003d10  75 6e 64 61 72 79 2c 20  74 68 69 73 20 73 68 6f  |undary, this sho|
00003d20  75 6c 64 20 62 65 20 62  65 63 6f 6d 69 6e 67 20  |uld be becoming |
00003d30  6f 62 76 69 6f 75 73 20  2a 2f 0a 78 5f 62 6f 75  |obvious */.x_bou|
00003d40  6e 64 20 3d 20 28 69 6e  74 29 28 76 69 65 77 5f  |nd = (int)(view_|
00003d50  78 20 26 20 30 78 66 66  63 30 29 3b 0a 0a 2f 2a  |x & 0xffc0);../*|
00003d60  20 77 65 20 61 6c 73 6f  20 6b 6e 6f 77 20 74 68  | we also know th|
00003d70  61 74 20 74 68 65 20 64  65 6c 74 61 20 66 6f 72  |at the delta for|
00003d80  20 74 68 65 20 63 65 6c  6c 20 77 69 6c 6c 20 62  | the cell will b|
00003d90  65 20 74 6f 20 74 68 65  20 6c 65 66 74 2c 20 65  |e to the left, e|
00003da0  61 63 68 20 74 69 6d 65  20 74 68 65 20 72 61 79  |ach time the ray|
00003db0  20 6d 6f 76 65 73 20 74  6f 20 74 68 65 20 6e 65  | moves to the ne|
00003dc0  78 74 20 62 6f 75 6e 64  61 72 79 20 74 68 65 20  |xt boundary the |
00003dd0  6e 65 78 74 20 76 65 72  74 69 63 61 6c 20 69 6e  |next vertical in|
00003de0  74 65 72 73 65 63 74 69  6f 6e 20 77 69 6c 6c 20  |tersection will |
00003df0  62 65 20 61 20 63 65 6c  6c 20 74 6f 20 74 68 65  |be a cell to the|
00003e00  20 6c 65 66 74 20 74 68  61 6e 20 74 68 65 20 6c  | left than the l|
00003e10  61 73 74 2e 20 2a 2f 0a  78 5f 64 65 6c 74 61 20  |ast. */.x_delta |
00003e20  3d 20 2d 43 45 4c 4c 5f  58 5f 53 49 5a 45 3b 0a  |= -CELL_X_SIZE;.|
00003e30  0a 2f 2a 20 77 65 20 75  73 65 20 74 68 65 20 74  |./* we use the t|
00003e40  61 6e 67 65 6e 74 61 6c  20 66 75 6e 63 74 69 6f  |angental functio|
00003e50  6e 20 61 67 61 69 6e 20  74 6f 20 63 61 6c 63 75  |n again to calcu|
00003e60  6c 61 74 65 20 74 68 65  20 70 6f 73 69 74 69 6f  |late the positio|
00003e70  6e 20 6f 6e 20 74 68 65  20 68 6f 72 69 7a 6f 6e  |n on the horizon|
00003e80  74 61 6c 20 69 6e 74 65  72 73 65 63 74 69 6f 6e  |tal intersection|
00003e90  73 20 2a 2f 0a 0a 2f 2a  20 4e 45 57 20 46 49 58  |s */../* NEW FIX|
00003ea0  45 44 20 50 4f 49 4e 54  20 2a 2f 0a 0a 79 69 3d  |ED POINT */..yi=|
00003eb0  28 28 78 5f 62 6f 75 6e  64 20 2d 20 76 69 65 77  |((x_bound - view|
00003ec0  5f 78 29 29 2a 28 74 61  6e 5f 74 61 62 6c 65 5b  |_x))*(tan_table[|
00003ed0  76 69 65 77 5f 61 6e 67  6c 65 5d 29 3b 0a 79 69  |view_angle]);.yi|
00003ee0  2b 3d 28 76 69 65 77 5f  79 3c 3c 31 36 29 3b 0a  |+=(view_y<<16);.|
00003ef0  2f 2a 20 61 6e 64 20 77  65 20 61 6c 73 6f 20 6b  |/* and we also k|
00003f00  6e 6f 77 20 74 68 61 74  20 74 68 65 20 78 20 63  |now that the x c|
00003f10  65 6c 6c 20 76 61 6c 75  65 20 77 69 6c 6c 20 62  |ell value will b|
00003f20  65 20 6d 69 6e 75 73 2c  20 62 65 63 61 75 73 65  |e minus, because|
00003f30  20 61 73 20 74 68 65 20  72 61 79 20 6d 6f 76 65  | as the ray move|
00003f40  73 20 74 6f 20 61 6e 6f  74 68 65 72 20 63 65 6c  |s to another cel|
00003f50  6c 2c 20 62 65 63 61 75  73 65 20 74 68 65 20 72  |l, because the r|
00003f60  61 79 20 69 73 20 67 6f  69 6e 67 20 6c 65 66 74  |ay is going left|
00003f70  2c 20 74 68 65 20 76 61  6c 75 65 20 6d 75 73 74  |, the value must|
00003f80  20 62 65 20 6d 69 6e 75  73 2e 20 2a 2f 0a 6e 65  | be minus. */.ne|
00003f90  78 74 5f 78 5f 63 65 6c  6c 20 3d 20 2d 31 3b 0a  |xt_x_cell = -1;.|
00003fa0  0a 20 20 20 20 20 20 20  7d 0a 0a 2f 2a 20 4e 6f  |.       }../* No|
00003fb0  77 20 77 65 20 68 61 76  65 20 70 65 72 66 6f 72  |w we have perfor|
00003fc0  6d 65 64 20 74 68 65 20  73 6c 69 67 68 74 6c 79  |med the slightly|
00003fd0  20 74 72 69 63 6b 79 20  74 61 73 6b 20 6f 66 20  | tricky task of |
00003fe0  74 68 65 20 66 69 72 73  74 20 69 6e 74 65 72 73  |the first inters|
00003ff0  65 63 74 69 6f 6e 73 2c  20 77 65 20 63 61 6e 20  |ections, we can |
00004000  6d 6f 76 65 20 6f 6e 20  74 6f 20 63 61 6c 63 75  |move on to calcu|
00004010  6c 61 74 69 6e 67 20 74  68 65 20 6e 65 78 74 20  |lating the next |
00004020  6f 6e 65 73 2e 20 54 68  69 73 20 69 73 20 6d 6f  |ones. This is mo|
00004030  72 65 20 73 69 6d 70 6c  65 2c 20 61 73 20 77 65  |re simple, as we|
00004040  20 6b 6e 6f 77 20 74 68  61 74 20 74 68 65 20 69  | know that the i|
00004050  6e 74 65 72 73 65 63 74  69 6f 6e 73 20 63 61 6e  |ntersections can|
00004060  20 6f 6e 6c 79 20 6f 63  63 75 72 20 61 74 20 63  | only occur at c|
00004070  65 6c 6c 20 62 6f 75 6e  64 61 72 69 65 73 2e 2a  |ell boundaries.*|
00004080  2f 0a 0a 2f 2a 20 53 45  43 54 49 4f 4e 20 32 20  |/../* SECTION 2 |
00004090  3a 20 54 65 73 74 69 6e  67 20 66 6f 72 20 66 75  |: Testing for fu|
000040a0  72 74 68 65 72 20 69 6e  74 65 72 73 65 63 74 69  |rther intersecti|
000040b0  6f 6e 73 20 2a 2f 0a 0a  2f 2a 20 74 68 65 73 65  |ons */../* these|
000040c0  20 66 6c 61 67 73 20 73  74 6f 72 65 20 69 66 20  | flags store if |
000040d0  63 61 73 74 69 6e 67 20  6f 66 20 62 6f 74 68 20  |casting of both |
000040e0  72 61 79 73 20 69 73 20  63 6f 6d 70 6c 65 74 65  |rays is complete|
000040f0  20 2a 2f 0a 78 72 61 79  3d 79 72 61 79 3d 30 3b  | */.xray=yray=0;|
00004100  0a 0a 2f 2a 20 58 20 52  61 79 20 69 73 20 66 69  |../* X Ray is fi|
00004110  72 73 74 20 2a 2f 0a 2f  2a 20 62 65 63 61 75 73  |rst */./* becaus|
00004120  65 20 77 65 20 61 72 65  20 74 65 73 74 69 6e 67  |e we are testing|
00004130  20 66 6f 72 20 65 61 63  68 20 6e 65 78 74 20 69  | for each next i|
00004140  6e 74 65 72 73 65 63 74  69 6f 6e 2c 20 77 65 20  |ntersection, we |
00004150  63 61 6e 20 66 69 67 75  72 65 20 6f 75 74 20 6d  |can figure out m|
00004160  6f 72 65 20 65 61 73 69  6c 79 20 74 68 65 20 66  |ore easily the f|
00004170  6f 6c 6c 6f 77 69 6e 67  20 69 6e 74 65 72 73 65  |ollowing interse|
00004180  63 74 69 6f 6e 73 2e 20  2a 2f 0a 2f 2a 20 74 68  |ctions. */./* th|
00004190  69 73 20 69 73 20 61 20  6c 6f 6f 6b 20 75 70 20  |is is a look up |
000041a0  74 61 62 6c 65 20 68 6f  6c 64 69 6e 67 20 74 68  |table holding th|
000041b0  65 20 6e 65 78 74 20 79  20 69 6e 74 65 72 63 65  |e next y interce|
000041c0  70 74 73 2c 20 62 61 73  65 64 20 6f 6e 20 74 68  |pts, based on th|
000041d0  65 20 74 61 6e 67 65 6e  74 61 6c 20 66 75 6e 63  |e tangental func|
000041e0  74 69 6f 6e 20 61 6e 64  20 74 68 65 20 73 69 7a  |tion and the siz|
000041f0  65 20 6f 66 20 63 65 6c  6c 73 2e 20 42 61 73 69  |e of cells. Basi|
00004200  63 61 6c 6c 79 20 77 65  20 61 64 64 20 74 68 69  |cally we add thi|
00004210  73 20 74 6f 20 74 68 65  20 72 61 79 20 65 61 63  |s to the ray eac|
00004220  68 20 74 69 6d 65 20 77  65 20 6d 6f 76 65 20 69  |h time we move i|
00004230  74 20 61 20 62 69 74 20  6d 6f 72 65 2c 20 73 65  |t a bit more, se|
00004240  61 72 63 68 69 6e 67 20  66 6f 72 20 61 20 77 61  |arching for a wa|
00004250  6c 6c 20 61 74 20 61 20  63 65 6c 6c 20 62 6f 75  |ll at a cell bou|
00004260  6e 64 61 72 79 20 2a 2f  0a 0a 2f 2a 20 4e 45 57  |ndary */../* NEW|
00004270  20 46 49 58 45 44 20 50  4f 49 4e 54 2c 20 6e 6f  | FIXED POINT, no|
00004280  74 65 20 74 68 65 20 73  68 69 66 74 20 33 20 74  |te the shift 3 t|
00004290  69 6d 65 73 20 74 6f 20  74 68 65 20 6c 65 66 74  |imes to the left|
000042a0  2c 20 74 68 65 20 65 71  75 69 76 61 6c 65 6e 74  |, the equivalent|
000042b0  20 6f 66 20 61 20 6d 75  6c 74 69 70 6c 79 20 62  | of a multiply b|
000042c0  79 20 38 2c 20 74 68 69  73 20 74 61 6b 65 73 20  |y 8, this takes |
000042d0  6e 6f 20 74 69 6d 65 2c  20 61 6e 64 20 72 65 61  |no time, and rea|
000042e0  6c 6c 79 20 49 20 64 6f  6e 27 74 20 6b 6e 6f 77  |lly I don't know|
000042f0  20 77 68 79 20 49 27 76  65 20 64 6f 6e 65 20 69  | why I've done i|
00004300  74 20 6c 69 6b 65 20 74  68 69 73 21 20 49 74 20  |t like this! It |
00004310  77 6f 72 6b 73 2e 20 2a  2f 0a 0a 78 61 64 64 3d  |works. */..xadd=|
00004320  79 5f 73 74 65 70 5b 76  69 65 77 5f 61 6e 67 6c  |y_step[view_angl|
00004330  65 5d 3c 3c 33 3b 0a 0a  2f 2a 20 73 74 61 72 74  |e]<<3;../* start|
00004340  20 63 61 73 74 69 6e 67  20 74 68 65 20 78 20 72  | casting the x r|
00004350  61 79 20 2a 2f 0a 77 68  69 6c 65 28 21 78 72 61  |ay */.while(!xra|
00004360  79 29 0a 7b 0a 2f 2a 20  63 6f 6d 70 75 74 65 20  |y).{./* compute |
00004370  63 75 72 72 65 6e 74 20  63 65 6c 6c 20 70 6f 73  |current cell pos|
00004380  69 74 69 6f 6e 20 6f 66  20 74 68 65 20 72 61 79  |ition of the ray|
00004390  20 74 6f 20 69 6e 73 70  65 63 74 2a 2f 0a 0a 63  | to inspect*/..c|
000043a0  65 6c 6c 5f 78 20 3d 20  28 20 28 78 5f 62 6f 75  |ell_x = ( (x_bou|
000043b0  6e 64 2b 6e 65 78 74 5f  78 5f 63 65 6c 6c 29 20  |nd+next_x_cell) |
000043c0  3e 3e 20 43 45 4c 4c 5f  58 5f 53 49 5a 45 5f 46  |>> CELL_X_SIZE_F|
000043d0  50 29 3b 0a 2f 2a 20 4e  6f 74 65 20 77 65 20 68  |P);./* Note we h|
000043e0  61 76 65 20 74 6f 20 73  68 69 66 74 20 6e 6f 74  |ave to shift not|
000043f0  20 6f 6e 6c 79 20 62 79  20 36 2c 20 62 75 74 20  | only by 6, but |
00004400  61 6c 73 6f 20 62 79 20  31 36 20 74 6f 20 63 6f  |also by 16 to co|
00004410  6e 76 65 72 74 20 42 41  43 4b 20 74 6f 20 6e 6f  |nvert BACK to no|
00004420  72 6d 61 6c 20 6d 61 74  68 73 20 2a 2f 0a 63 65  |rmal maths */.ce|
00004430  6c 6c 5f 79 20 3d 20 28  69 6e 74 29 79 69 3e 3e  |ll_y = (int)yi>>|
00004440  32 32 3b 0a 0a 2f 2a 20  62 6f 74 68 20 6f 66 20  |22;../* both of |
00004450  74 68 65 20 61 62 6f 76  65 20 65 78 61 6d 70 6c  |the above exampl|
00004460  65 73 20 75 73 65 20 62  69 6e 61 72 79 20 73 68  |es use binary sh|
00004470  69 66 74 69 6e 67 20 74  6f 20 61 63 68 69 65 76  |ifting to achiev|
00004480  65 20 61 20 64 69 76 69  64 65 20 62 79 20 36 34  |e a divide by 64|
00004490  2e 20 43 65 6c 6c 5f 79  20 63 6f 6d 70 75 74 61  |. Cell_y computa|
000044a0  74 69 6f 6e 20 75 73 65  73 20 69 64 65 6e 74 69  |tion uses identi|
000044b0  63 61 6c 20 74 65 63 68  6e 69 71 75 65 73 20 74  |cal techniques t|
000044c0  6f 20 74 68 6f 73 65 20  63 6f 76 65 72 65 64 20  |o those covered |
000044d0  69 6e 20 74 68 65 20 6d  61 67 61 7a 69 6e 65 2e  |in the magazine.|
000044e0  20 43 65 6c 6c 5f 78 20  69 73 20 63 61 6c 63 75  | Cell_x is calcu|
000044f0  6c 61 74 65 64 20 62 79  20 75 73 69 6e 67 20 74  |lated by using t|
00004500  68 65 20 78 5f 62 6f 75  6e 64 20 61 6e 64 20 6e  |he x_bound and n|
00004510  65 78 74 5f 78 5f 63 65  6c 6c 20 76 61 6c 75 65  |ext_x_cell value|
00004520  73 20 63 61 6c 63 75 6c  61 74 65 64 20 62 65 66  |s calculated bef|
00004530  6f 72 65 68 61 6e 64 2e  20 2a 2f 0a 0a 69 66 28  |orehand. */..if(|
00004540  63 65 6c 6c 5f 78 3c 30  29 63 65 6c 6c 5f 78 3d  |cell_x<0)cell_x=|
00004550  30 3b 69 66 28 63 65 6c  6c 5f 78 3e 36 33 29 63  |0;if(cell_x>63)c|
00004560  65 6c 6c 5f 78 3d 36 33  3b 0a 69 66 28 63 65 6c  |ell_x=63;.if(cel|
00004570  6c 5f 79 3c 30 29 63 65  6c 6c 5f 79 3d 30 3b 69  |l_y<0)cell_y=0;i|
00004580  66 28 63 65 6c 6c 5f 79  3e 36 33 29 63 65 6c 6c  |f(cell_y>63)cell|
00004590  5f 79 3d 36 33 3b 0a 2f  2a 20 74 68 65 73 65 20  |_y=63;./* these |
000045a0  73 69 6d 70 6c 65 20 6c  69 6e 65 73 20 65 6e 73  |simple lines ens|
000045b0  75 72 65 20 74 68 61 74  20 74 68 65 20 72 61 79  |ure that the ray|
000045c0  20 64 6f 65 73 6e 27 74  20 67 6f 20 6f 75 74 20  | doesn't go out |
000045d0  6f 66 20 74 68 65 20 77  6f 72 6c 64 2c 20 74 68  |of the world, th|
000045e0  6f 75 67 68 20 74 68 65  79 20 61 72 65 6e 27 74  |ough they aren't|
000045f0  20 72 65 61 6c 6c 79 20  6e 65 65 64 65 64 2e 20  | really needed. |
00004600  2a 2f 0a 0a 2f 2a 20 77  65 20 6c 6f 6f 6b 20 75  |*/../* we look u|
00004610  70 20 69 6e 20 74 68 65  20 77 6f 72 6c 64 20 66  |p in the world f|
00004620  69 6c 65 20 74 6f 20 73  65 65 20 69 66 20 74 68  |ile to see if th|
00004630  65 72 65 20 69 73 20 61  20 77 61 6c 6c 20 61 74  |ere is a wall at|
00004640  20 74 68 65 20 69 6e 74  65 72 73 65 63 74 69 6f  | the intersectio|
00004650  6e 20 6f 66 20 6f 75 72  20 72 61 79 20 2a 2f 0a  |n of our ray */.|
00004660  69 66 20 28 28 78 5f 68  69 74 5f 74 79 70 65 20  |if ((x_hit_type |
00004670  3d 77 6f 72 6c 64 5b 63  65 6c 6c 5f 79 5d 5b 63  |=world[cell_y][c|
00004680  65 6c 6c 5f 78 5d 29 21  3d 30 29 0a 7b 0a 2f 2a  |ell_x])!=0).{./*|
00004690  20 69 66 20 73 6f 20 77  65 20 63 61 6c 63 75 6c  | if so we calcul|
000046a0  61 74 65 20 74 68 65 20  64 69 73 74 61 6e 63 65  |ate the distance|
000046b0  20 74 6f 20 69 74 20 75  73 69 6e 67 20 74 68 65  | to it using the|
000046c0  20 6f 6c 64 20 4f 2d 4c  65 76 65 6c 20 74 65 63  | old O-Level tec|
000046d0  68 6e 69 71 75 65 20 6f  66 20 75 73 69 6e 67 20  |hnique of using |
000046e0  73 69 6e 65 20 61 6e 64  20 63 6f 73 69 6e 65 20  |sine and cosine |
000046f0  69 6e 73 74 65 61 64 20  6f 66 20 64 6f 69 6e 67  |instead of doing|
00004700  20 74 68 65 20 73 74 61  6e 64 61 72 64 20 50 59  | the standard PY|
00004710  54 48 41 47 4f 52 41 53  20 74 65 63 68 6e 69 71  |THAGORAS techniq|
00004720  75 65 2e 2a 2f 0a 0a 2f  2a 20 4e 45 57 20 46 49  |ue.*/../* NEW FI|
00004730  58 45 44 20 50 4f 49 4e  54 20 63 61 6c 63 75 6c  |XED POINT calcul|
00004740  61 74 69 6f 6e 2c 20 6e  6f 74 69 63 65 20 74 68  |ation, notice th|
00004750  61 74 20 69 6e 20 74 68  69 73 20 6e 65 78 74 20  |at in this next |
00004760  6c 69 6e 65 20 77 65 20  68 61 76 65 20 62 6f 74  |line we have bot|
00004770  68 20 61 20 63 6f 6e 76  65 72 73 69 6f 6e 20 54  |h a conversion T|
00004780  4f 20 66 69 78 65 64 20  70 6f 69 6e 74 20 28 76  |O fixed point (v|
00004790  69 65 77 5f 79 29 20 61  6e 64 20 61 6c 73 6f 20  |iew_y) and also |
000047a0  74 68 65 20 63 68 65 63  6b 20 61 67 61 69 6e 73  |the check agains|
000047b0  74 20 6f 76 65 72 20 66  6c 6f 77 20 69 73 20 76  |t over flow is v|
000047c0  65 72 79 20 61 70 70 61  72 65 6e 74 2c 20 77 65  |ery apparent, we|
000047d0  20 73 68 61 72 65 20 74  68 65 20 61 63 63 75 72  | share the accur|
000047e0  61 63 79 2e 20 53 65 65  20 74 68 65 20 61 72 74  |acy. See the art|
000047f0  69 63 6c 65 20 66 6f 72  20 6d 6f 72 65 20 64 65  |icle for more de|
00004800  74 61 69 6c 73 20 2a 2f  0a 0a 64 69 73 74 5f 78  |tails */..dist_x|
00004810  20 20 3d 20 28 20 28 79  69 20 2d 20 28 76 69 65  |  = ( (yi - (vie|
00004820  77 5f 79 3c 3c 31 36 29  29 3e 3e 38 29 20 2a 20  |w_y<<16))>>8) * |
00004830  28 69 6e 76 5f 73 69 6e  5f 74 61 62 6c 65 5b 76  |(inv_sin_table[v|
00004840  69 65 77 5f 61 6e 67 6c  65 5d 3e 3e 38 29 3b 0a  |iew_angle]>>8);.|
00004850  2f 2a 20 77 65 20 61 6c  73 6f 20 73 61 76 65 20  |/* we also save |
00004860  74 68 65 20 65 78 61 63  74 20 70 6f 73 69 74 69  |the exact positi|
00004870  6f 6e 20 6f 66 20 74 68  65 20 69 6e 74 65 72 73  |on of the inters|
00004880  65 63 74 69 6f 6e 20 62  65 63 61 75 73 65 20 77  |ection because w|
00004890  65 20 77 69 6c 6c 20 6e  65 65 64 20 69 74 20 6c  |e will need it l|
000048a0  61 74 65 72 20 74 6f 20  61 64 64 20 74 65 78 74  |ater to add text|
000048b0  75 72 65 20 6d 61 70 70  69 6e 67 2e 20 2a 2f 0a  |ure mapping. */.|
000048c0  0a 2f 2a 20 57 65 20 73  61 76 65 20 79 69 20 61  |./* We save yi a|
000048d0  66 74 65 72 20 63 6f 6e  76 65 72 74 69 6e 67 20  |fter converting |
000048e0  69 74 20 62 61 63 6b 20  74 6f 20 6e 6f 72 6d 61  |it back to norma|
000048f0  6c 20 6d 61 74 68 73 20  2a 2f 0a 0a 79 69 5f 73  |l maths */..yi_s|
00004900  61 76 65 20 3d 20 28 69  6e 74 29 79 69 3e 3e 31  |ave = (int)yi>>1|
00004910  36 3b 0a 0a 2f 2a 20 62  65 63 61 75 73 65 20 74  |6;../* because t|
00004920  68 65 20 78 20 72 61 79  20 68 61 73 20 66 6f 75  |he x ray has fou|
00004930  6e 64 20 61 20 77 61 6c  6c 2c 20 77 65 20 63 61  |nd a wall, we ca|
00004940  6e 20 73 74 6f 70 20 63  61 73 74 69 6e 67 20 2a  |n stop casting *|
00004950  2f 0a 78 72 61 79 3d 46  4f 55 4e 44 5f 57 41 4c  |/.xray=FOUND_WAL|
00004960  4c 3b 0a 0a 7d 0a 65 6c  73 65 0a 7b 0a 2f 2a 20  |L;..}.else.{./* |
00004970  69 66 20 6e 6f 74 2c 20  77 65 20 63 6f 6d 70 75  |if not, we compu|
00004980  74 65 20 74 68 65 20 6e  65 78 74 20 70 6f 73 73  |te the next poss|
00004990  69 62 6c 65 20 69 6e 74  65 72 73 65 63 74 69 6f  |ible intersectio|
000049a0  6e 20 2a 2f 0a 79 69 20  2b 3d 78 61 64 64 3b 20  |n */.yi +=xadd; |
000049b0  2f 2a 20 46 49 58 45 44  20 50 4f 49 4e 54 20 41  |/* FIXED POINT A|
000049c0  44 44 49 54 49 4f 4e 20  72 65 71 75 69 72 65 73  |DDITION requires|
000049d0  20 6e 6f 20 65 78 74 72  61 20 77 6f 72 6b 20 2a  | no extra work *|
000049e0  2f 0a 78 5f 62 6f 75 6e  64 20 2b 3d 20 78 5f 64  |/.x_bound += x_d|
000049f0  65 6c 74 61 3b 20 2f 2a  20 61 6e 64 20 77 65 20  |elta; /* and we |
00004a00  61 6c 73 6f 20 63 61 6c  63 75 6c 61 74 65 20 74  |also calculate t|
00004a10  68 65 20 6e 65 78 74 20  68 6f 72 69 7a 6f 6e 74  |he next horizont|
00004a20  61 6c 20 62 6f 75 6e 64  61 72 79 2c 20 77 68 69  |al boundary, whi|
00004a30  63 68 20 77 65 20 6b 6e  6f 77 20 77 69 6c 6c 20  |ch we know will |
00004a40  62 65 20 78 5f 64 65 6c  74 61 20 61 77 61 79 2c  |be x_delta away,|
00004a50  20 6e 6f 20 6e 65 65 64  20 66 6f 72 20 63 6f 6d  | no need for com|
00004a60  70 6c 65 78 20 77 6f 72  6b 69 6e 67 73 2e 20 2a  |plex workings. *|
00004a70  2f 0a 7d 0a 0a 7d 0a 2f  2a 20 53 45 43 54 49 4f  |/.}..}./* SECTIO|
00004a80  4e 20 33 20 2a 2f 0a 2f  2a 20 57 45 20 4e 4f 57  |N 3 */./* WE NOW|
00004a90  20 64 6f 20 65 78 61 63  74 6c 79 20 74 68 65 20  | do exactly the |
00004aa0  73 61 6d 65 20 62 75 74  20 66 6f 72 20 74 68 65  |same but for the|
00004ab0  20 79 72 61 79 2c 20 77  65 20 63 61 73 74 20 69  | yray, we cast i|
00004ac0  74 20 6f 75 74 2c 20 63  68 65 63 6b 20 66 6f 72  |t out, check for|
00004ad0  20 61 20 77 61 6c 6c 2c  20 69 66 20 74 68 65 72  | a wall, if ther|
00004ae0  65 20 69 73 20 6f 6e 65  20 77 65 20 74 61 6b 65  |e is one we take|
00004af0  20 74 68 65 20 64 69 73  74 61 6e 63 65 20 74 6f  | the distance to|
00004b00  20 69 74 20 65 74 63 2c  20 69 66 20 6e 6f 74 2c  | it etc, if not,|
00004b10  20 77 65 20 6d 6f 76 65  20 20 74 68 65 20 72 61  | we move  the ra|
00004b20  79 20 75 6e 74 69 6c 20  61 20 77 61 6c 6c 20 69  |y until a wall i|
00004b30  74 20 66 6f 75 6e 64 2e  20 2a 2f 0a 0a 2f 2a 20  |t found. */../* |
00004b40  6c 6f 6f 6b 20 75 70 20  74 68 65 20 76 61 6c 75  |look up the valu|
00004b50  65 20 74 6f 20 61 64 64  20 74 6f 20 74 68 65 20  |e to add to the |
00004b60  72 61 79 20 65 61 63 68  20 74 69 6d 65 20 77 65  |ray each time we|
00004b70  20 6d 6f 76 65 20 69 74  20 2a 2f 0a 0a 2f 2a 20  | move it */../* |
00004b80  53 65 65 20 61 62 6f 76  65 20 66 6f 72 20 6d 6f  |See above for mo|
00004b90  72 65 20 69 6e 66 6f 72  6d 61 74 69 6f 6e 2c 20  |re information, |
00004ba0  74 68 69 73 20 69 73 20  46 49 58 45 44 20 50 4f  |this is FIXED PO|
00004bb0  49 4e 54 20 72 65 6d 65  6d 62 65 72 20 2a 2f 0a  |INT remember */.|
00004bc0  79 61 64 64 3d 78 5f 73  74 65 70 5b 76 69 65 77  |yadd=x_step[view|
00004bd0  5f 61 6e 67 6c 65 5d 3c  3c 33 3b 0a 0a 2f 2a 20  |_angle]<<3;../* |
00004be0  73 74 61 72 74 20 63 61  73 74 69 6e 67 20 74 68  |start casting th|
00004bf0  65 20 72 61 79 20 2a 2f  0a 77 68 69 6c 65 28 21  |e ray */.while(!|
00004c00  79 72 61 79 29 0a 7b 0a  0a 2f 2a 20 63 6f 6d 70  |yray).{../* comp|
00004c10  75 74 65 20 63 75 72 72  65 6e 74 20 63 65 6c 6c  |ute current cell|
00004c20  20 74 6f 20 69 6e 73 70  65 63 74 20 2a 2f 0a 0a  | to inspect */..|
00004c30  2f 2a 20 42 65 63 61 75  73 65 20 58 49 20 49 53  |/* Because XI IS|
00004c40  20 49 4e 20 46 49 58 45  44 20 50 4f 49 4e 54 20  | IN FIXED POINT |
00004c50  77 65 20 68 61 76 65 20  74 6f 20 6e 6f 74 20 6f  |we have to not o|
00004c60  6e 6c 79 20 64 69 76 69  64 65 20 62 79 20 36 34  |nly divide by 64|
00004c70  20 62 75 74 20 61 6c 73  6f 20 77 65 20 68 61 76  | but also we hav|
00004c80  65 20 74 6f 20 63 6f 6e  76 65 72 74 20 42 41 43  |e to convert BAC|
00004c90  4b 20 74 6f 20 6e 6f 72  6d 61 6c 20 6d 61 74 68  |K to normal math|
00004ca0  73 20 2a 2f 0a 0a 63 65  6c 6c 5f 78 20 3d 20 28  |s */..cell_x = (|
00004cb0  69 6e 74 29 78 69 3e 3e  32 32 3b 0a 63 65 6c 6c  |int)xi>>22;.cell|
00004cc0  5f 79 20 3d 20 28 20 28  79 5f 62 6f 75 6e 64 20  |_y = ( (y_bound |
00004cd0  2b 20 6e 65 78 74 5f 79  5f 63 65 6c 6c 29 20 3e  |+ next_y_cell) >|
00004ce0  3e 20 43 45 4c 4c 5f 59  5f 53 49 5a 45 5f 46 50  |> CELL_Y_SIZE_FP|
00004cf0  29 3b 0a 2f 2a 20 74 68  65 73 65 20 63 61 6c 63  |);./* these calc|
00004d00  75 6c 61 74 69 6f 6e 73  20 77 6f 72 6b 20 6f 75  |ulations work ou|
00004d10  74 20 77 68 69 63 68 20  63 65 6c 6c 73 20 74 68  |t which cells th|
00004d20  65 20 72 61 79 20 69 73  20 69 6e 2c 20 72 65 61  |e ray is in, rea|
00004d30  64 79 20 74 6f 20 63 68  65 63 6b 20 66 6f 72 20  |dy to check for |
00004d40  77 61 6c 6c 73 20 69 6e  20 74 68 65 20 77 6f 72  |walls in the wor|
00004d50  6c 64 5b 5d 5b 5d 20 61  72 72 61 79 2e 20 54 68  |ld[][] array. Th|
00004d60  65 79 20 62 6f 74 68 20  75 73 65 20 62 69 6e 61  |ey both use bina|
00004d70  72 79 20 73 68 69 66 74  69 6e 67 20 74 6f 20 70  |ry shifting to p|
00004d80  65 72 66 6f 72 6d 20 64  69 76 69 64 65 20 62 79  |erform divide by|
00004d90  20 36 34 27 73 2e 20 2a  2f 0a 0a 2f 2a 20 63 68  | 64's. */../* ch|
00004da0  65 63 6b 20 74 68 61 74  20 74 68 65 20 72 61 79  |eck that the ray|
00004db0  20 68 61 73 20 6e 6f 74  20 67 6f 6e 65 20 6f 75  | has not gone ou|
00004dc0  74 20 6f 66 20 74 68 65  20 77 6f 72 6c 64 2c 20  |t of the world, |
00004dd0  74 68 6f 75 67 68 20 74  68 69 73 20 69 73 6e 27  |though this isn'|
00004de0  74 20 72 65 61 6c 6c 79  20 6e 65 63 65 73 73 61  |t really necessa|
00004df0  72 79 20 2a 2f 0a 69 66  28 63 65 6c 6c 5f 78 3c  |ry */.if(cell_x<|
00004e00  30 29 63 65 6c 6c 5f 78  3d 30 3b 69 66 28 63 65  |0)cell_x=0;if(ce|
00004e10  6c 6c 5f 78 3e 36 33 29  63 65 6c 6c 5f 78 3d 36  |ll_x>63)cell_x=6|
00004e20  33 3b 0a 69 66 28 63 65  6c 6c 5f 79 3c 30 29 63  |3;.if(cell_y<0)c|
00004e30  65 6c 6c 5f 79 3d 30 3b  69 66 28 63 65 6c 6c 5f  |ell_y=0;if(cell_|
00004e40  79 3e 36 33 29 63 65 6c  6c 5f 79 3d 36 33 3b 0a  |y>63)cell_y=63;.|
00004e50  0a 2f 2a 20 6c 6f 6f 6b  20 61 6e 64 20 73 65 65  |./* look and see|
00004e60  20 69 66 20 74 68 65 72  65 20 69 73 20 61 20 77  | if there is a w|
00004e70  61 6c 6c 20 61 74 20 74  68 65 20 63 75 72 72 65  |all at the curre|
00004e80  6e 74 20 70 6f 69 6e 74  20 6f 66 20 69 6e 74 65  |nt point of inte|
00004e90  72 73 65 63 74 69 6f 6e  20 2a 2f 0a 69 66 20 28  |rsection */.if (|
00004ea0  28 79 5f 68 69 74 5f 74  79 70 65 20 3d 20 77 6f  |(y_hit_type = wo|
00004eb0  72 6c 64 5b 63 65 6c 6c  5f 79 5d 5b 63 65 6c 6c  |rld[cell_y][cell|
00004ec0  5f 78 5d 29 21 3d 30 29  0a 7b 0a 2f 2a 20 55 73  |_x])!=0).{./* Us|
00004ed0  65 20 74 68 65 20 6f 6c  64 20 4f 2d 4c 65 76 65  |e the old O-Leve|
00004ee0  6c 20 74 72 69 61 6e 67  6c 65 20 6d 65 74 68 6f  |l triangle metho|
00004ef0  64 20 6f 66 20 63 61 6c  75 6c 61 74 69 6e 67 20  |d of calulating |
00004f00  64 69 73 74 61 6e 63 65  20 75 73 69 6e 67 20 63  |distance using c|
00004f10  6f 73 2c 20 72 61 74 68  65 72 20 74 68 61 6e 20  |os, rather than |
00004f20  75 73 69 6e 67 20 50 59  54 48 41 47 4f 52 41 53  |using PYTHAGORAS|
00004f30  2c 20 77 68 69 63 68 20  69 73 20 73 6c 6f 77 65  |, which is slowe|
00004f40  72 20 62 65 63 61 75 73  65 20 69 74 20 75 73 65  |r because it use|
00004f50  73 20 61 20 73 71 75 61  72 65 20 72 6f 6f 74 21  |s a square root!|
00004f60  20 2a 2f 0a 2f 2a 20 46  49 58 45 44 20 50 4f 49  | */./* FIXED POI|
00004f70  4e 54 20 63 61 6c 63 75  6c 61 74 69 6f 6e 2c 20  |NT calculation, |
00004f80  6a 75 73 74 20 74 68 65  20 73 61 6d 65 20 61 73  |just the same as|
00004f90  20 74 68 65 20 69 6e 76  5f 73 69 6e 20 63 61 6c  | the inv_sin cal|
00004fa0  63 75 6c 61 74 69 6f 6e  20 73 65 65 20 61 62 6f  |culation see abo|
00004fb0  76 65 2e 20 2a 2f 0a 64  69 73 74 5f 79 20 20 3d  |ve. */.dist_y  =|
00004fc0  20 28 20 28 78 69 20 2d  20 28 76 69 65 77 5f 78  | ( (xi - (view_x|
00004fd0  3c 3c 31 36 29 29 3e 3e  38 29 20 2a 20 28 69 6e  |<<16))>>8) * (in|
00004fe0  76 5f 63 6f 73 5f 74 61  62 6c 65 5b 76 69 65 77  |v_cos_table[view|
00004ff0  5f 61 6e 67 6c 65 5d 3e  3e 38 29 3b 0a 0a 2f 2a  |_angle]>>8);../*|
00005000  20 73 61 76 65 20 74 68  65 20 65 78 61 63 74 20  | save the exact |
00005010  69 6e 74 65 72 73 65 63  74 69 6f 6e 20 70 6f 69  |intersection poi|
00005020  6e 74 2c 20 77 65 20 77  69 6c 6c 20 6e 65 65 64  |nt, we will need|
00005030  20 69 74 20 6c 61 74 65  72 20 2a 2f 0a 2f 2a 20  | it later */./* |
00005040  53 61 6d 65 20 61 73 20  61 6f 62 76 65 2c 20 76  |Same as aobve, v|
00005050  65 72 79 20 73 69 6d 70  6c 65 20 63 6f 6e 76 65  |ery simple conve|
00005060  72 73 69 6f 6e 20 62 61  63 6b 20 66 72 6f 6d 20  |rsion back from |
00005070  46 49 58 45 44 20 50 4f  49 4e 54 20 74 6f 20 6e  |FIXED POINT to n|
00005080  6f 72 6d 61 6c 20 6d 61  74 68 73 20 2a 2f 0a 78  |ormal maths */.x|
00005090  69 5f 73 61 76 65 20 3d  20 28 69 6e 74 29 78 69  |i_save = (int)xi|
000050a0  3e 3e 31 36 3b 0a 2f 2a  20 53 54 4f 50 20 79 20  |>>16;./* STOP y |
000050b0  63 61 73 74 69 6e 67 20  69 6e 20 74 68 61 74 20  |casting in that |
000050c0  63 61 73 65 2c 20 61 20  77 61 6c 6c 20 68 61 73  |case, a wall has|
000050d0  20 62 65 65 6e 20 66 6f  75 6e 64 2e 20 2a 2f 0a  | been found. */.|
000050e0  79 72 61 79 3d 46 4f 55  4e 44 5f 57 41 4c 4c 3b  |yray=FOUND_WALL;|
000050f0  0a 7d 0a 65 6c 73 65 0a  7b 0a 2f 2a 20 69 66 20  |.}.else.{./* if |
00005100  6e 6f 74 2c 20 6d 6f 76  65 20 74 68 65 20 72 61  |not, move the ra|
00005110  79 20 6f 6e 20 2a 2f 0a  78 69 2b 3d 79 61 64 64  |y on */.xi+=yadd|
00005120  3b 20 2f 2a 20 41 47 41  49 4e 2c 20 6e 6f 20 65  |; /* AGAIN, no e|
00005130  78 74 72 61 20 77 6f 72  6b 20 69 73 20 72 65 71  |xtra work is req|
00005140  75 69 72 65 64 20 66 6f  72 20 46 49 58 45 44 20  |uired for FIXED |
00005150  50 4f 49 4e 54 20 41 44  44 49 54 49 4f 4e 20 2a  |POINT ADDITION *|
00005160  2f 0a 79 5f 62 6f 75 6e  64 20 2b 3d 20 79 5f 64  |/.y_bound += y_d|
00005170  65 6c 74 61 3b 20 2f 2a  20 61 6e 64 20 6d 6f 76  |elta; /* and mov|
00005180  65 20 74 6f 20 74 68 65  20 6e 65 78 74 20 76 65  |e to the next ve|
00005190  72 74 69 63 61 6c 20 62  6f 75 6e 64 61 72 79 20  |rtical boundary |
000051a0  70 6f 73 69 74 69 6f 6e  20 2a 2f 0a 7d 0a 0a 7d  |position */.}..}|
000051b0  0a 0a 2f 2a 20 53 45 43  54 49 4f 4e 20 34 2a 2f  |../* SECTION 4*/|
000051c0  0a 2f 2a 20 42 6f 74 68  20 72 61 79 73 20 68 61  |./* Both rays ha|
000051d0  76 65 20 62 65 65 6e 20  63 61 73 74 2c 20 62 6f  |ve been cast, bo|
000051e0  74 68 20 72 61 79 73 20  68 61 76 65 20 6d 65 74  |th rays have met|
000051f0  20 61 20 77 61 6c 6c 2c  20 77 65 20 6e 6f 77 20  | a wall, we now |
00005200  6e 65 65 64 20 74 6f 20  73 65 65 20 77 68 69 63  |need to see whic|
00005210  68 20 69 73 20 63 6c 6f  73 65 72 2c 20 61 6e 64  |h is closer, and|
00005220  20 74 68 65 6e 20 70 6c  6f 74 20 69 74 20 63 6f  | then plot it co|
00005230  72 72 65 63 74 6c 79 2e  20 2a 2f 0a 0a 2f 2a 20  |rrectly. */../* |
00005240  66 69 6e 64 20 6f 75 74  20 77 68 69 63 68 20 77  |find out which w|
00005250  61 6c 6c 20 28 78 20 6f  72 20 79 29 20 69 73 20  |all (x or y) is |
00005260  6e 65 61 72 65 72 20 74  68 65 20 76 69 65 77 65  |nearer the viewe|
00005270  72 2e 20 2a 2f 0a 0a 2f  2a 20 77 65 20 68 61 76  |r. */../* we hav|
00005280  65 20 61 6c 74 65 72 65  64 20 74 68 69 73 20 64  |e altered this d|
00005290  69 73 74 61 6e 63 65 20  63 68 65 63 6b 69 6e 67  |istance checking|
000052a0  20 6c 69 6e 65 20 74 6f  20 61 76 6f 69 64 20 6d  | line to avoid m|
000052b0  69 6e 75 73 20 64 69 73  74 61 6e 63 65 73 20 62  |inus distances b|
000052c0  65 69 6e 67 20 73 65 6c  65 63 74 65 64 20 74 6f  |eing selected to|
000052d0  20 64 72 61 77 2c 20 77  68 69 63 68 20 70 72 6f  | draw, which pro|
000052e0  64 75 63 65 73 20 6c 61  72 67 65 20 73 70 69 6b  |duces large spik|
000052f0  65 73 20 6f 6e 20 74 68  65 20 73 63 72 65 65 6e  |es on the screen|
00005300  21 20 41 67 61 69 6e 20  74 68 69 73 20 69 73 20  |! Again this is |
00005310  62 65 63 61 75 73 65 20  6f 66 20 66 69 78 65 64  |because of fixed|
00005320  20 70 6f 69 6e 74 20 2a  2f 0a 0a 20 20 20 20 69  | point */..    i|
00005330  66 20 28 64 69 73 74 5f  78 20 3c 20 64 69 73 74  |f (dist_x < dist|
00005340  5f 79 20 26 26 20 64 69  73 74 5f 78 3e 30 20 7c  |_y && dist_x>0 ||
00005350  7c 20 64 69 73 74 5f 79  3c 30 29 0a 0a 20 20 20  || dist_y<0)..   |
00005360  20 20 20 20 7b 0a 0a 0a  2f 2a 20 77 65 20 6e 65  |    {.../* we ne|
00005370  65 64 20 74 6f 20 74 61  6b 65 20 69 6e 74 6f 20  |ed to take into |
00005380  61 63 63 6f 75 6e 74 20  68 65 72 65 2c 20 77 68  |account here, wh|
00005390  65 6e 20 63 6f 6d 70 75  74 69 6e 67 20 74 68 65  |en computing the|
000053a0  20 73 63 61 6c 65 20 6f  66 20 74 68 65 20 76 65  | scale of the ve|
000053b0  72 74 69 63 61 6c 20 73  74 72 69 70 20 28 73 6c  |rtical strip (sl|
000053c0  69 76 65 72 29 20 74 6f  20 62 65 20 64 72 61 77  |iver) to be draw|
000053d0  6e 2c 20 61 20 70 68 65  6e 65 6d 65 6e 6f 6e 20  |n, a phenemenon |
000053e0  28 6f 66 20 73 6f 72 74  73 29 20 6b 6e 6f 77 6e  |(of sorts) known|
000053f0  20 61 73 20 74 68 65 20  22 66 69 73 68 20 62 6f  | as the "fish bo|
00005400  77 6c 20 65 66 66 65 63  74 22 2e 20 54 68 69 73  |wl effect". This|
00005410  20 69 73 20 63 61 75 73  65 64 20 62 79 20 6d 69  | is caused by mi|
00005420  7a 69 6e 67 20 6f 66 20  63 61 72 74 65 73 69 61  |zing of cartesia|
00005430  6e 20 61 6e 64 20 70 6f  6c 61 72 20 63 6f 6f 72  |n and polar coor|
00005440  64 69 6e 61 74 65 73 2e  20 54 6f 20 67 65 74 20  |dinates. To get |
00005450  72 69 64 20 6f 66 20 69  74 20 77 65 20 75 73 65  |rid of it we use|
00005460  20 74 68 65 20 63 6f 73  69 6e 65 20 66 75 6e 63  | the cosine func|
00005470  74 69 6f 6e 2e 20 49 20  68 61 76 65 20 63 6f 6d  |tion. I have com|
00005480  62 69 6e 65 64 20 6f 74  68 65 72 20 6d 75 6c 74  |bined other mult|
00005490  69 70 6c 69 65 73 20 6f  66 20 61 20 76 65 72 74  |iplies of a vert|
000054a0  69 63 61 6c 20 73 63 61  6c 69 6e 67 20 66 61 63  |ical scaling fac|
000054b0  74 6f 72 20 77 69 74 68  20 74 68 65 20 63 6f 73  |tor with the cos|
000054c0  69 6e 65 20 74 72 61 6e  73 66 6f 72 6d 61 74 69  |ine transformati|
000054d0  6f 6e 20 74 6f 20 73 61  76 65 20 74 69 6d 65 2e  |on to save time.|
000054e0  20 41 6c 6c 20 77 65 20  65 76 65 6e 74 75 61 6c  | All we eventual|
000054f0  6c 79 20 62 65 20 65 78  70 6c 61 69 6e 65 64 2e  |ly be explained.|
00005500  20 59 6f 75 20 63 6f 75  6c 64 20 72 65 70 6c 61  | You could repla|
00005510  63 65 20 74 68 65 20 6c  69 6e 65 20 77 69 74 68  |ce the line with|
00005520  20 73 63 61 6c 65 3d 31  33 33 31 32 2f 64 69 73  | scale=13312/dis|
00005530  74 5f 78 2b 2b 20 61 6e  64 20 73 65 65 20 77 68  |t_x++ and see wh|
00005540  61 74 20 77 65 69 72 64  20 72 65 73 75 6c 74 73  |at weird results|
00005550  20 79 6f 75 20 67 65 74  21 20 2a 2f 0a 0a 2f 2a  | you get! */../*|
00005560  20 4e 45 57 20 4e 45 57  20 4e 45 57 20 3a 20 57  | NEW NEW NEW : W|
00005570  65 20 68 61 76 65 20 66  69 78 65 64 20 70 6f 69  |e have fixed poi|
00005580  6e 74 20 68 65 72 65 2c  20 61 6e 64 20 75 73 69  |nt here, and usi|
00005590  6e 67 20 74 68 65 20 72  65 63 69 70 72 6f 63 61  |ng the reciproca|
000055a0  6c 20 74 61 62 6c 65 20  28 73 65 65 20 61 72 6f  |l table (see aro|
000055b0  75 6e 64 29 20 77 65 20  64 6f 6e 27 74 20 68 61  |und) we don't ha|
000055c0  76 65 20 74 6f 20 64 6f  20 61 20 6c 65 6e 67 74  |ve to do a lengt|
000055d0  68 20 64 69 76 69 64 65  21 20 4e 6f 74 69 63 65  |h divide! Notice|
000055e0  20 68 6f 77 20 77 65 20  63 6f 6e 76 65 72 74 20  | how we convert |
000055f0  64 69 73 74 5f 78 20 62  61 63 6b 20 74 6f 20 6e  |dist_x back to n|
00005600  6f 72 6d 61 6c 20 74 6f  20 69 6e 64 65 78 20 74  |ormal to index t|
00005610  68 65 20 72 65 63 69 70  5f 74 61 62 6c 65 20 61  |he recip_table a|
00005620  72 72 61 79 2c 20 61 6e  64 20 74 68 61 74 20 61  |rray, and that a|
00005630  6c 6c 20 61 63 63 75 72  61 63 79 20 69 73 20 6c  |ll accuracy is l|
00005640  6f 73 74 20 77 69 74 68  20 74 68 65 20 63 6f 73  |ost with the cos|
00005650  5f 74 61 62 6c 65 2c 20  62 65 63 61 75 73 65 20  |_table, because |
00005660  61 6c 6c 20 69 74 73 20  66 69 67 75 72 65 73 20  |all its figures |
00005670  61 72 65 20 61 62 6f 76  65 20 7a 65 72 6f 20 28  |are above zero (|
00005680  73 65 65 20 61 75 61 5f  74 61 62 6c 65 73 29 20  |see aua_tables) |
00005690  61 6e 64 20 61 6c 73 6f  20 74 68 61 74 20 77 65  |and also that we|
000056a0  20 61 63 74 75 61 6c 6c  79 20 63 6f 6e 76 65 72  | actually conver|
000056b0  74 20 74 68 65 20 77 68  6f 6c 65 20 61 6e 73 77  |t the whole answ|
000056c0  65 72 20 62 61 63 6b 20  74 6f 20 6e 6f 72 6d 61  |er back to norma|
000056d0  6c 20 6d 61 74 68 73 20  66 6f 72 20 73 63 61 6c  |l maths for scal|
000056e0  65 20 2a 2f 0a 0a 73 63  61 6c 65 20 3d 20 28 69  |e */..scale = (i|
000056f0  6e 74 29 28 20 28 63 6f  73 5f 74 61 62 6c 65 5b  |nt)( (cos_table[|
00005700  72 61 79 5d 3e 3e 31 36  29 20 2a 20 28 72 65 63  |ray]>>16) * (rec|
00005710  69 70 5f 74 61 62 6c 65  5b 64 69 73 74 5f 78 3e  |ip_table[dist_x>|
00005720  3e 31 36 5d 29 20 3e 3e  31 36 29 3b 0a 0a 2f 2a  |>16]) >>16);../*|
00005730  20 61 73 73 69 67 6e 20  74 68 65 20 76 61 72 69  | assign the vari|
00005740  61 62 6c 65 73 20 77 65  20 6e 65 65 64 20 74 6f  |ables we need to|
00005750  20 74 68 65 20 76 61 72  69 61 62 6c 65 73 20 74  | the variables t|
00005760  6f 20 62 65 20 70 61 73  73 65 64 20 74 6f 20 74  |o be passed to t|
00005770  68 65 20 41 53 4d 20 73  6c 69 76 65 72 20 72 65  |he ASM sliver re|
00005780  6e 64 65 72 65 72 20 28  73 75 70 65 72 20 66 61  |nderer (super fa|
00005790  73 74 21 29 20 2a 2f 0a  76 61 72 69 61 62 6c 65  |st!) */.variable|
000057a0  73 5b 32 5d 3d 28 79 69  5f 73 61 76 65 20 26 20  |s[2]=(yi_save & |
000057b0  30 78 30 30 33 66 29 3b  20 2f 2a 20 74 68 69 73  |0x003f); /* this|
000057c0  20 77 6f 72 6b 73 20 6f  75 74 20 74 68 65 20 63  | works out the c|
000057d0  6f 6c 75 6d 6e 20 6f 66  20 74 68 65 20 77 61 6c  |olumn of the wal|
000057e0  6c 20 74 6f 20 62 65 20  70 6c 6f 74 74 65 64 20  |l to be plotted |
000057f0  28 30 2d 36 34 29 2c 20  62 79 20 63 61 6c 63 75  |(0-64), by calcu|
00005800  6c 61 74 69 6e 67 20 77  68 65 72 65 20 61 62 6f  |lating where abo|
00005810  75 74 73 20 69 6e 20 74  68 65 20 63 65 6c 6c 20  |uts in the cell |
00005820  74 68 65 20 69 6e 74 65  72 73 65 63 74 69 6f 6e  |the intersection|
00005830  20 77 61 73 2c 20 63 6f  76 65 72 65 64 20 69 6e  | was, covered in|
00005840  20 74 68 65 20 61 72 74  69 63 6c 65 2e 20 4e 6f  | the article. No|
00005850  74 65 20 74 68 65 20 6f  70 74 69 6d 69 7a 61 74  |te the optimizat|
00005860  69 6f 6e 20 6f 66 20 79  69 5f 73 61 76 65 20 25  |ion of yi_save %|
00005870  20 36 34 20 2a 2f 0a 76  61 72 69 61 62 6c 65 73  | 64 */.variables|
00005880  5b 33 5d 3d 73 63 61 6c  65 2d 31 3b 20 2f 2a 73  |[3]=scale-1; /*s|
00005890  74 6f 72 65 73 20 74 68  65 20 73 63 61 6c 65 20  |tores the scale |
000058a0  6f 66 20 74 68 65 20 73  74 72 69 70 20 28 68 65  |of the strip (he|
000058b0  69 67 68 74 20 6f 66 20  69 74 29 2a 2f 0a 76 61  |ight of it)*/.va|
000058c0  72 69 61 62 6c 65 73 5b  34 5d 3d 72 61 79 3b 20  |riables[4]=ray; |
000058d0  2f 2a 20 77 65 20 75 73  65 20 72 61 79 20 61 73  |/* we use ray as|
000058e0  20 74 68 65 20 78 20 70  6f 73 69 74 69 6f 6e 20  | the x position |
000058f0  74 6f 20 70 6c 6f 74 20  74 6f 20 28 30 2d 33 31  |to plot to (0-31|
00005900  39 29 2a 2f 0a 76 61 72  69 61 62 6c 65 73 5b 36  |9)*/.variables[6|
00005910  5d 3d 78 5f 68 69 74 5f  74 79 70 65 3b 20 2f 2a  |]=x_hit_type; /*|
00005920  20 66 69 6e 61 6c 6c 79  20 77 65 20 73 74 6f 72  | finally we stor|
00005930  65 20 74 68 65 20 77 61  6c 6c 20 6e 75 6d 62 65  |e the wall numbe|
00005940  72 20 74 6f 20 70 6c 6f  74 20 2a 2f 0a 0a 2f 2a  |r to plot */../*|
00005950  20 61 6e 64 20 77 65 20  63 61 6c 6c 20 74 68 65  | and we call the|
00005960  20 61 73 73 65 6d 62 6c  65 72 20 66 75 6e 63 74  | assembler funct|
00005970  69 6f 6e 20 28 65 78 70  6c 61 69 6e 65 64 20 61  |ion (explained a|
00005980  74 20 61 20 6c 61 74 65  72 20 64 61 74 65 29 2a  |t a later date)*|
00005990  2f 0a 6f 75 72 6c 69 62  5f 73 6c 69 76 65 72 28  |/.ourlib_sliver(|
000059a0  26 76 61 72 69 61 62 6c  65 73 5b 30 5d 29 3b 0a  |&variables[0]);.|
000059b0  0a 20 20 20 20 20 20 20  7d 0a 2f 2a 20 65 6c 73  |.       }./* els|
000059c0  65 20 74 68 65 20 64 69  73 74 5f 79 20 77 61 73  |e the dist_y was|
000059d0  20 6e 65 61 72 65 72 2c  20 65 76 65 72 79 74 68  | nearer, everyth|
000059e0  69 6e 67 20 66 72 6f 6d  20 61 62 6f 76 65 20 61  |ing from above a|
000059f0  70 70 6c 69 65 73 20 2a  2f 0a 20 20 20 20 65 6c  |pplies */.    el|
00005a00  73 65 0a 20 20 20 20 20  20 20 7b 0a 0a 2f 2a 20  |se.       {../* |
00005a10  61 76 6f 69 64 20 66 69  73 68 20 62 6f 77 6c 20  |avoid fish bowl |
00005a20  65 66 66 65 63 74 20 61  6e 64 20 73 63 61 6c 65  |effect and scale|
00005a30  20 70 72 6f 70 65 72 6c  79 20 77 69 74 68 20 46  | properly with F|
00005a40  49 58 45 44 20 50 4f 49  4e 54 20 63 6c 65 76 65  |IXED POINT cleve|
00005a50  72 20 62 69 74 73 21 2c  20 73 65 65 20 61 62 6f  |r bits!, see abo|
00005a60  76 65 20 2a 2f 0a 73 63  61 6c 65 20 3d 20 28 69  |ve */.scale = (i|
00005a70  6e 74 29 28 20 28 63 6f  73 5f 74 61 62 6c 65 5b  |nt)( (cos_table[|
00005a80  72 61 79 5d 3e 3e 31 36  29 20 2a 20 28 72 65 63  |ray]>>16) * (rec|
00005a90  69 70 5f 74 61 62 6c 65  5b 64 69 73 74 5f 79 3e  |ip_table[dist_y>|
00005aa0  3e 31 36 5d 29 20 3e 3e  20 31 36 29 3b 0a 0a 0a  |>16]) >> 16);...|
00005ab0  2f 2a 20 73 65 74 20 75  70 20 76 61 72 69 61 62  |/* set up variab|
00005ac0  6c 65 73 20 66 6f 72 20  6f 75 72 20 73 6c 69 76  |les for our sliv|
00005ad0  65 72 20 65 6e 67 69 6e  65 2c 20 73 65 65 20 61  |er engine, see a|
00005ae0  62 6f 76 65 20 2a 2f 0a  76 61 72 69 61 62 6c 65  |bove */.variable|
00005af0  73 5b 32 5d 3d 28 78 69  5f 73 61 76 65 20 26 20  |s[2]=(xi_save & |
00005b00  30 78 30 30 33 66 29 3b  20 2f 2a 6e 6f 74 69 63  |0x003f); /*notic|
00005b10  65 20 74 68 61 74 20 77  65 20 75 73 65 20 78 69  |e that we use xi|
00005b20  20 69 6e 73 74 65 61 64  20 6f 66 20 79 69 5f 73  | instead of yi_s|
00005b30  61 76 65 2a 2f 0a 76 61  72 69 61 62 6c 65 73 5b  |ave*/.variables[|
00005b40  33 5d 3d 73 63 61 6c 65  2d 31 3b 0a 76 61 72 69  |3]=scale-1;.vari|
00005b50  61 62 6c 65 73 5b 34 5d  3d 72 61 79 3b 0a 2f 2a  |ables[4]=ray;./*|
00005b60  20 6e 6f 74 69 63 65 20  77 65 20 61 64 64 20 6f  | notice we add o|
00005b70  6e 65 20 74 6f 20 74 68  65 20 77 61 6c 6c 20 67  |ne to the wall g|
00005b80  72 61 70 68 69 63 20 73  65 6c 65 63 74 69 6f 6e  |raphic selection|
00005b90  2c 20 73 6f 20 74 68 65  20 64 61 72 6b 65 72 20  |, so the darker |
00005ba0  74 69 6c 65 20 69 73 20  75 73 65 64 20 66 6f 72  |tile is used for|
00005bb0  20 61 64 64 65 64 20 76  61 72 69 61 74 69 6f 6e  | added variation|
00005bc0  2e 20 53 65 65 20 74 68  65 20 61 72 74 69 63 6c  |. See the articl|
00005bd0  65 20 66 6f 72 20 6d 6f  72 65 20 64 65 74 61 69  |e for more detai|
00005be0  6c 73 20 6f 66 20 74 68  69 73 20 73 6f 72 74 20  |ls of this sort |
00005bf0  6f 66 20 73 68 61 64 69  6e 67 2c 20 69 66 20 79  |of shading, if y|
00005c00  6f 75 20 77 61 6e 74 20  74 6f 20 63 61 6c 6c 20  |ou want to call |
00005c10  69 74 20 74 68 61 74 21  20 2a 2f 0a 76 61 72 69  |it that! */.vari|
00005c20  61 62 6c 65 73 5b 36 5d  3d 79 5f 68 69 74 5f 74  |ables[6]=y_hit_t|
00005c30  79 70 65 2b 31 3b 0a 0a  2f 2a 20 63 61 6c 6c 20  |ype+1;../* call |
00005c40  6f 75 72 20 73 6c 69 76  65 72 20 65 6e 67 69 6e  |our sliver engin|
00005c50  65 20 2a 2f 0a 6f 75 72  6c 69 62 5f 73 6c 69 76  |e */.ourlib_sliv|
00005c60  65 72 28 26 76 61 72 69  61 62 6c 65 73 5b 30 5d  |er(&variables[0]|
00005c70  29 3b 0a 0a 20 20 20 20  20 20 20 7d 0a 2f 2a 20  |);..       }./* |
00005c80  74 68 69 73 20 72 61 79  20 68 61 73 20 62 65 65  |this ray has bee|
00005c90  6e 20 66 69 6e 69 73 68  65 64 2e 20 49 6e 63 72  |n finished. Incr|
00005ca0  65 61 73 65 20 74 68 65  20 61 6e 67 6c 65 20 6f  |ease the angle o|
00005cb0  66 20 74 68 65 20 6e 65  78 74 20 72 61 79 20 61  |f the next ray a|
00005cc0  6e 64 20 73 74 61 72 74  20 61 67 61 69 6e 21 20  |nd start again! |
00005cd0  2a 2f 0a 0a 20 20 20 20  69 66 20 28 2b 2b 76 69  |*/..    if (++vi|
00005ce0  65 77 5f 61 6e 67 6c 65  3e 3d 41 4e 47 4c 45 5f  |ew_angle>=ANGLE_|
00005cf0  33 36 30 29 0a 20 20 20  20 20 20 20 7b 0a 20 20  |360).       {.  |
00005d00  20 20 20 20 20 2f 2a 20  74 68 69 73 20 65 6e 73  |     /* this ens|
00005d10  75 72 65 73 20 74 68 61  74 20 74 68 65 20 72 61  |ures that the ra|
00005d20  79 20 61 6e 67 6c 65 20  64 6f 65 73 6e 27 74 20  |y angle doesn't |
00005d30  67 6f 20 6f 76 65 72 20  33 36 30 20 64 65 67 72  |go over 360 degr|
00005d40  65 65 73 21 20 2a 2f 0a  20 20 20 20 20 20 20 76  |ees! */.       v|
00005d50  69 65 77 5f 61 6e 67 6c  65 3d 30 3b 0a 0a 20 20  |iew_angle=0;..  |
00005d60  20 20 20 20 20 7d 0a 2f  2a 20 72 61 79 20 6c 6f  |     }./* ray lo|
00005d70  6f 70 20 2a 2f 0a 20 20  20 20 7d 0a 2f 2a 20 65  |op */.    }./* e|
00005d80  6e 64 20 72 61 79 20 63  61 73 74 65 72 20 65 6e  |nd ray caster en|
00005d90  67 69 6e 65 20 2a 2f 0a  7d 0a 0a 0a 0a 2f 2a 20  |gine */.}..../* |
00005da0  74 68 69 73 20 66 75 6e  63 74 69 6f 6e 20 67 72  |this function gr|
00005db0  61 62 73 20 61 6c 6c 20  74 68 65 20 64 69 66 66  |abs all the diff|
00005dc0  65 72 65 6e 74 20 77 61  6c 6c 73 20 66 72 6f 6d  |erent walls from|
00005dd0  20 61 20 73 69 6e 67 6c  65 20 66 69 6c 65 20 2a  | a single file *|
00005de0  2f 0a 0a 76 6f 69 64 20  61 75 61 5f 67 72 61 70  |/..void aua_grap|
00005df0  68 69 63 73 28 76 6f 69  64 29 0a 7b 0a 69 6e 74  |hics(void).{.int|
00005e00  20 78 2c 20 2f 2a 20 74  68 69 73 20 69 73 20 75  | x, /* this is u|
00005e10  73 65 64 20 74 6f 20 73  74 6f 72 65 20 74 68 65  |sed to store the|
00005e20  20 78 20 63 6f 6f 72 64  69 6e 61 74 65 20 6f 66  | x coordinate of|
00005e30  20 61 20 70 6f 69 6e 74  20 6f 6e 20 74 68 65 20  | a point on the |
00005e40  73 63 72 65 65 6e 20 2a  2f 0a 20 20 20 20 79 2c  |screen */.    y,|
00005e50  20 2f 2a 20 74 68 69 73  20 69 73 20 75 73 65 64  | /* this is used|
00005e60  20 74 6f 20 73 74 6f 72  65 20 74 68 65 20 79 20  | to store the y |
00005e70  63 6f 6f 72 64 69 6e 61  74 65 20 6f 66 20 61 20  |coordinate of a |
00005e80  70 6f 69 6e 74 20 6f 6e  20 74 68 65 20 73 63 72  |point on the scr|
00005e90  65 65 6e 20 2a 2f 0a 20  20 20 20 77 61 6c 6c 5f  |een */.    wall_|
00005ea0  6e 75 6d 62 65 72 3b 20  2f 2a 20 74 68 69 73 20  |number; /* this |
00005eb0  77 69 6c 6c 20 62 65 20  75 73 65 64 20 74 6f 20  |will be used to |
00005ec0  69 6e 64 65 78 20 74 68  65 20 77 61 6c 6c 73 5b  |index the walls[|
00005ed0  78 5d 5b 5d 20 63 68 61  72 20 61 72 72 61 79 20  |x][] char array |
00005ee0  2a 2f 0a 0a 2f 2a 20 66  69 72 73 74 20 6f 66 20  |*/../* first of |
00005ef0  61 6c 6c 20 77 65 20 67  65 74 20 74 68 65 20 67  |all we get the g|
00005f00  72 61 70 68 69 63 73 20  66 69 6c 65 20 3c 41 55  |raphics file <AU|
00005f10  41 52 61 79 24 44 69 72  3e 2e 67 72 61 70 68 69  |ARay$Dir>.graphi|
00005f20  63 73 20 6f 6e 74 6f 20  74 68 65 20 73 63 72 65  |cs onto the scre|
00005f30  65 6e 20 2a 2f 0a 0a 73  79 73 74 65 6d 28 22 2a  |en */..system("*|
00005f40  53 63 72 65 65 6e 4c 6f  61 64 20 3c 41 55 41 52  |ScreenLoad <AUAR|
00005f50  61 79 24 44 69 72 3e 2e  67 72 61 70 68 69 63 73  |ay$Dir>.graphics|
00005f60  22 29 3b 0a 0a 2f 2a 20  6e 65 78 74 20 77 65 20  |");../* next we |
00005f70  73 74 61 72 74 20 67 72  61 62 62 69 6e 67 20 65  |start grabbing e|
00005f80  61 63 68 20 74 69 6c 65  2c 20 36 34 20 78 20 36  |ach tile, 64 x 6|
00005f90  34 20 70 69 78 65 6c 73  2c 20 69 6e 74 6f 20 74  |4 pixels, into t|
00005fa0  68 65 20 77 61 6c 6c 73  5b 5d 5b 5d 20 61 72 72  |he walls[][] arr|
00005fb0  61 79 20 2a 2f 0a 0a 2f  2a 20 77 65 20 75 73 65  |ay */../* we use|
00005fc0  20 74 68 69 73 20 6c 61  72 67 65 20 66 6f 72 20  | this large for |
00005fd0  6c 6f 6f 70 20 61 74 20  74 68 65 20 6f 75 72 6c  |loop at the ourl|
00005fe0  69 62 5f 62 69 74 6d 61  70 5f 67 72 61 62 20 66  |ib_bitmap_grab f|
00005ff0  75 6e 63 74 69 6f 6e 20  74 6f 20 69 6e 76 69 64  |unction to invid|
00006000  75 61 6c 6c 79 20 67 72  61 62 20 65 61 63 68 20  |ually grab each |
00006010  74 69 6c 65 20 69 6e 74  6f 20 69 74 73 20 6f 77  |tile into its ow|
00006020  6e 20 77 61 6c 6c 73 5b  78 5d 5b 5d 20 61 72 72  |n walls[x][] arr|
00006030  61 79 20 73 6c 6f 74 2c  20 6e 6f 74 65 20 74 68  |ay slot, note th|
00006040  61 74 20 77 65 20 43 41  4e 27 54 20 48 41 56 45  |at we CAN'T HAVE|
00006050  20 57 41 4c 4c 20 30 20  61 73 20 74 68 69 73 20  | WALL 0 as this |
00006060  72 65 70 72 65 73 65 6e  74 73 20 61 20 67 61 70  |represents a gap|
00006070  20 69 6e 20 74 68 65 20  77 6f 72 6c 64 21 20 2a  | in the world! *|
00006080  2f 0a 0a 66 6f 72 28 77  61 6c 6c 5f 6e 75 6d 62  |/..for(wall_numb|
00006090  65 72 3d 31 2c 79 3d 30  3b 79 3c 53 43 52 45 45  |er=1,y=0;y<SCREE|
000060a0  4e 5f 48 45 49 47 48 54  3b 79 2b 3d 57 41 4c 4c  |N_HEIGHT;y+=WALL|
000060b0  5f 48 45 49 47 48 54 29  66 6f 72 28 78 3d 30 3b  |_HEIGHT)for(x=0;|
000060c0  78 3c 53 43 52 45 45 4e  5f 57 49 44 54 48 3b 78  |x<SCREEN_WIDTH;x|
000060d0  2b 3d 57 41 4c 4c 5f 57  49 44 54 48 2c 77 61 6c  |+=WALL_WIDTH,wal|
000060e0  6c 5f 6e 75 6d 62 65 72  2b 2b 29 0a 7b 0a 2f 2a  |l_number++).{./*|
000060f0  20 74 68 69 73 20 63 61  6c 6c 73 20 74 68 65 20  | this calls the |
00006100  66 75 6e 63 74 69 6f 6e  20 6f 75 72 6c 69 62 5f  |function ourlib_|
00006110  62 69 74 6d 61 70 5f 67  72 61 62 20 28 49 20 73  |bitmap_grab (I s|
00006120  61 69 64 20 69 74 20 77  6f 75 6c 64 20 62 65 20  |aid it would be |
00006130  68 61 6e 64 79 21 29 20  77 68 69 63 68 20 67 72  |handy!) which gr|
00006140  61 62 73 20 74 68 65 20  61 72 65 61 20 6f 66 20  |abs the area of |
00006150  73 63 72 65 65 6e 20 6d  65 6d 6f 72 79 20 6d 61  |screen memory ma|
00006160  72 6b 65 64 20 62 79 20  74 68 65 20 66 69 72 73  |rked by the firs|
00006170  74 20 66 6f 75 72 20 70  61 72 61 6d 65 74 65 72  |t four parameter|
00006180  73 2c 20 73 74 6f 72 65  73 20 69 74 20 69 6e 20  |s, stores it in |
00006190  74 68 65 20 62 79 74 65  20 61 72 72 61 79 20 70  |the byte array p|
000061a0  6f 69 6e 74 65 72 20 69  6e 20 70 61 72 61 6d 65  |ointer in parame|
000061b0  74 65 72 20 66 69 76 65  2c 20 72 65 61 64 69 6e  |ter five, readin|
000061c0  67 20 69 74 20 61 6c 6c  20 66 72 6f 6d 20 74 68  |g it all from th|
000061d0  65 20 73 63 72 65 65 6e  20 70 6f 69 6e 74 65 64  |e screen pointed|
000061e0  20 74 6f 20 62 79 20 73  63 72 65 65 6e 5f 61 64  | to by screen_ad|
000061f0  64 72 65 73 73 20 2a 2f  0a 0a 6f 75 72 6c 69 62  |dress */..ourlib|
00006200  5f 62 69 74 6d 61 70 5f  67 72 61 62 28 78 2c 79  |_bitmap_grab(x,y|
00006210  2c 78 2b 57 41 4c 4c 5f  57 49 44 54 48 2d 31 2c  |,x+WALL_WIDTH-1,|
00006220  79 2b 57 41 4c 4c 5f 48  45 49 47 48 54 2d 31 2c  |y+WALL_HEIGHT-1,|
00006230  26 77 61 6c 6c 73 5b 77  61 6c 6c 5f 6e 75 6d 62  |&walls[wall_numb|
00006240  65 72 5d 5b 30 5d 2c 73  63 72 65 65 6e 5f 61 64  |er][0],screen_ad|
00006250  64 72 65 73 73 29 3b 0a  0a 2f 2a 20 74 68 69 73  |dress);../* this|
00006260  20 6d 61 6b 65 73 20 73  75 72 65 20 77 65 20 64  | makes sure we d|
00006270  6f 6e 27 74 20 67 6f 20  6f 76 65 72 20 6f 75 72  |on't go over our|
00006280  20 6e 75 6d 62 65 72 20  6f 66 20 77 61 6c 6c 73  | number of walls|
00006290  20 6c 69 6d 69 74 20 2a  2f 0a 0a 69 66 28 77 61  | limit */..if(wa|
000062a0  6c 6c 5f 6e 75 6d 62 65  72 3e 3d 57 41 4c 4c 5f  |ll_number>=WALL_|
000062b0  4e 55 4d 42 45 52 29 62  72 65 61 6b 3b 0a 7d 0a  |NUMBER)break;.}.|
000062c0  0a 0a 7d 0a 0a 2f 2a 20  74 68 69 73 20 66 75 6e  |..}../* this fun|
000062d0  63 74 69 6f 6e 20 6c 6f  61 64 73 20 69 6e 20 74  |ction loads in t|
000062e0  68 65 20 64 61 74 61 20  66 72 6f 6d 20 6f 75 72  |he data from our|
000062f0  20 77 6f 72 6c 64 20 74  65 78 74 20 66 69 6c 65  | world text file|
00006300  20 61 6e 64 20 73 74 6f  72 65 73 20 69 74 20 69  | and stores it i|
00006310  6e 20 74 68 65 20 77 6f  72 6c 64 5b 5d 5b 5d 20  |n the world[][] |
00006320  61 72 72 61 79 20 2a 2f  0a 0a 76 6f 69 64 20 61  |array */..void a|
00006330  75 61 5f 77 6f 72 6c 64  28 76 6f 69 64 29 0a 7b  |ua_world(void).{|
00006340  0a 0a 46 49 4c 45 20 2a  77 6f 72 6c 64 5f 66 69  |..FILE *world_fi|
00006350  6c 65 3b 20 2f 2a 20 77  65 20 6e 65 65 64 20 61  |le; /* we need a|
00006360  20 66 69 6c 65 20 70 6f  69 6e 74 65 72 20 61 73  | file pointer as|
00006370  20 77 65 20 77 69 6c 6c  20 62 65 20 6c 6f 61 64  | we will be load|
00006380  69 6e 67 20 69 6e 20 74  65 78 74 20 2a 2f 0a 0a  |ing in text */..|
00006390  69 6e 74 20 72 6f 77 2c  20 2f 2a 20 74 68 69 73  |int row, /* this|
000063a0  20 77 69 6c 6c 20 62 65  20 75 73 65 64 20 74 6f  | will be used to|
000063b0  20 69 6e 64 65 78 20 74  68 65 20 77 6f 72 6c 64  | index the world|
000063c0  5b 5d 5b 5d 20 61 72 72  61 79 20 2a 2f 0a 20 20  |[][] array */.  |
000063d0  20 20 63 6f 6c 75 6d 6e  3b 20 2f 2a 20 74 68 69  |  column; /* thi|
000063e0  73 20 77 69 6c 6c 20 62  65 20 75 73 65 64 20 74  |s will be used t|
000063f0  6f 20 69 6e 64 65 78 20  74 68 65 20 77 6f 72 6c  |o index the worl|
00006400  64 5b 5d 5b 5d 20 61 72  72 61 79 20 2a 2f 0a 0a  |d[][] array */..|
00006410  63 68 61 72 20 63 68 3b  20 2f 2a 20 74 68 69 73  |char ch; /* this|
00006420  20 69 73 20 75 73 65 64  20 74 6f 20 73 74 6f 72  | is used to stor|
00006430  65 20 65 61 63 68 20 6e  75 6d 62 65 72 20 61 73  |e each number as|
00006440  20 69 74 20 69 73 20 6c  6f 61 64 65 64 20 69 6e  | it is loaded in|
00006450  20 2a 2f 0a 0a 2f 2a 20  6f 70 65 6e 20 74 68 65  | */../* open the|
00006460  20 77 6f 72 6c 64 20 66  69 6c 65 2c 20 69 66 20  | world file, if |
00006470  69 74 20 69 73 20 6e 6f  74 20 74 68 65 72 65 20  |it is not there |
00006480  74 68 65 6e 20 65 78 69  74 20 74 68 65 20 70 72  |then exit the pr|
00006490  6f 67 72 61 6d 20 2a 2f  0a 0a 69 66 28 21 28 77  |ogram */..if(!(w|
000064a0  6f 72 6c 64 5f 66 69 6c  65 3d 66 6f 70 65 6e 28  |orld_file=fopen(|
000064b0  22 3c 41 55 41 52 61 79  24 44 69 72 3e 2e 77 6f  |"<AUARay$Dir>.wo|
000064c0  72 6c 64 22 2c 22 72 22  29 29 29 65 78 69 74 28  |rld","r")))exit(|
000064d0  31 29 3b 0a 0a 2f 2a 20  74 68 69 73 20 70 72 6f  |1);../* this pro|
000064e0  67 72 61 6d 20 6c 6f 61  64 73 20 69 6e 20 74 68  |gram loads in th|
000064f0  65 20 64 61 74 61 20 66  72 6f 6d 20 74 68 65 20  |e data from the |
00006500  77 6f 72 6c 64 20 66 69  6c 65 2c 20 72 6f 77 20  |world file, row |
00006510  62 79 20 72 6f 77 2c 20  63 6f 6c 75 6d 6e 20 62  |by row, column b|
00006520  79 20 63 6f 6c 75 6d 6e  20 75 73 69 6e 67 20 74  |y column using t|
00006530  68 65 20 67 65 74 63 28  29 20 41 4e 53 49 20 66  |he getc() ANSI f|
00006540  75 6e 63 74 69 6f 6e 20  2a 2f 0a 0a 66 6f 72 28  |unction */..for(|
00006550  72 6f 77 3d 30 3b 72 6f  77 3c 57 4f 52 4c 44 5f  |row=0;row<WORLD_|
00006560  48 45 49 47 48 54 3b 72  6f 77 2b 2b 29 0a 7b 0a  |HEIGHT;row++).{.|
00006570  66 6f 72 28 63 6f 6c 75  6d 6e 3d 30 3b 63 6f 6c  |for(column=0;col|
00006580  75 6d 6e 3c 57 4f 52 4c  44 5f 57 49 44 54 48 3b  |umn<WORLD_WIDTH;|
00006590  63 6f 6c 75 6d 6e 2b 2b  29 0a 7b 0a 77 68 69 6c  |column++).{.whil|
000065a0  65 28 28 63 68 3d 67 65  74 63 28 77 6f 72 6c 64  |e((ch=getc(world|
000065b0  5f 66 69 6c 65 29 29 3d  3d 31 30 29 7b 7d 20 2f  |_file))==10){} /|
000065c0  2a 20 74 68 69 73 20 66  69 6c 74 65 72 73 20 6f  |* this filters o|
000065d0  75 74 20 61 6e 79 20 6d  65 73 73 2c 20 74 68 6f  |ut any mess, tho|
000065e0  75 67 68 20 6e 6f 74 20  6f 66 74 65 6e 20 75 73  |ugh not often us|
000065f0  65 64 21 20 2a 2f 0a 0a  69 66 28 63 68 3d 3d 27  |ed! */..if(ch=='|
00006600  20 27 29 63 68 3d 30 3b  20 2f 2a 74 68 69 73 20  | ')ch=0; /*this |
00006610  65 6e 73 75 72 65 73 20  74 68 65 20 63 6f 72 72  |ensures the corr|
00006620  65 63 74 20 76 61 6c 75  65 20 69 73 20 73 74 6f  |ect value is sto|
00006630  72 65 64 2c 20 69 66 20  74 68 65 72 65 20 69 73  |red, if there is|
00006640  20 61 20 67 61 70 20 69  6e 20 74 68 65 20 66 69  | a gap in the fi|
00006650  6c 65 2c 20 74 68 69 73  20 6d 65 61 6e 73 20 61  |le, this means a|
00006660  20 73 70 61 63 65 20 69  6e 20 74 68 65 20 77 6f  | space in the wo|
00006670  72 6c 64 2c 20 61 20 7a  65 72 6f 20 2a 2f 0a 65  |rld, a zero */.e|
00006680  6c 73 65 20 63 68 3d 63  68 2d 27 30 27 3b 0a 0a  |lse ch=ch-'0';..|
00006690  77 6f 72 6c 64 5b 28 57  4f 52 4c 44 5f 48 45 49  |world[(WORLD_HEI|
000066a0  47 48 54 2d 31 29 2d 72  6f 77 5d 5b 63 6f 6c 75  |GHT-1)-row][colu|
000066b0  6d 6e 5d 3d 63 68 3b 20  2f 2a 20 74 68 69 73 20  |mn]=ch; /* this |
000066c0  66 69 6e 61 6c 6c 79 20  73 74 6f 72 65 73 20 74  |finally stores t|
000066d0  68 65 20 76 61 6c 75 65  20 69 6e 20 74 68 65 20  |he value in the |
000066e0  63 6f 72 72 65 63 74 20  70 6f 73 69 74 69 6f 6e  |correct position|
000066f0  20 2a 2f 0a 0a 2f 2a 70  72 69 6e 74 66 28 22 25  | */../*printf("%|
00006700  64 22 2c 63 68 29 3b 20  75 6e 63 6f 6d 6d 65 6e  |d",ch); uncommen|
00006710  74 20 74 68 69 73 20 6c  69 6e 65 20 74 6f 20 73  |t this line to s|
00006720  65 65 20 74 68 65 20 77  6f 72 6c 64 20 64 61 74  |ee the world dat|
00006730  61 20 6c 6f 61 64 65 64  20 69 6e 20 2a 2f 0a 7d  |a loaded in */.}|
00006740  0a 2f 2a 70 72 69 6e 74  66 28 22 5c 6e 22 29 3b  |./*printf("\n");|
00006750  20 75 6e 63 6f 6d 6d 65  6e 74 20 74 68 69 73 20  | uncomment this |
00006760  6c 69 6e 65 20 74 6f 20  73 65 65 20 74 68 65 20  |line to see the |
00006770  77 6f 72 6c 64 20 64 61  74 61 20 6c 6f 61 64 65  |world data loade|
00006780  64 20 69 6e 20 2a 2f 0a  7d 0a 0a 2f 2a 20 77 68  |d in */.}../* wh|
00006790  65 6e 20 61 6c 6c 20 69  73 20 64 6f 6e 65 2c 20  |en all is done, |
000067a0  63 6c 6f 73 65 20 74 68  65 20 66 69 6c 65 20 2a  |close the file *|
000067b0  2f 0a 66 63 6c 6f 73 65  28 77 6f 72 6c 64 5f 66  |/.fclose(world_f|
000067c0  69 6c 65 29 3b 0a 7d 0a  0a 2f 2a 20 4e 45 57 45  |ile);.}../* NEWE|
000067d0  52 20 4d 41 49 4e 20 66  75 6e 63 74 69 6f 6e 20  |R MAIN function |
000067e0  2e 0a 54 68 69 73 20 66  75 6e 63 74 69 6f 6e 20  |..This function |
000067f0  6e 6f 77 20 69 6e 63 6f  72 70 6f 72 61 74 65 73  |now incorporates|
00006800  20 74 68 65 20 66 6f 6c  6c 6f 77 69 6e 67 20 28  | the following (|
00006810  73 65 65 20 61 72 74 69  63 6c 65 29 0a 0a 46 49  |see article)..FI|
00006820  58 45 44 20 50 4f 49 4e  54 20 4c 4f 4f 4b 2d 55  |XED POINT LOOK-U|
00006830  50 53 20 66 6f 72 20 4d  4f 56 45 4d 45 4e 54 20  |PS for MOVEMENT |
00006840  6f 66 20 76 69 65 77 70  6f 69 6e 74 21 0a 53 43  |of viewpoint!.SC|
00006850  52 45 45 4e 20 42 41 4e  4b 49 4e 47 20 74 6f 20  |REEN BANKING to |
00006860  61 76 6f 69 64 20 66 6c  69 63 6b 65 72 21 0a 43  |avoid flicker!.C|
00006870  4f 4c 4f 55 52 45 44 20  46 4c 4f 4f 52 20 41 4e  |OLOURED FLOOR AN|
00006880  44 20 43 45 49 4c 49 4e  47 53 21 0a 0a 41 6c 6c  |D CEILINGS!..All|
00006890  20 63 68 61 6e 67 65 73  20 61 72 65 20 63 6f 6d  | changes are com|
000068a0  6d 65 6e 74 65 64 20 2a  2f 0a 0a 76 6f 69 64 20  |mented */..void |
000068b0  6d 61 69 6e 28 76 6f 69  64 29 0a 7b 0a 20 20 69  |main(void).{.  i|
000068c0  6e 74 20 76 69 65 77 5f  78 2c 20 2f 2a 20 74 68  |nt view_x, /* th|
000068d0  69 73 20 68 6f 6c 64 73  20 74 68 65 20 76 69 65  |is holds the vie|
000068e0  77 69 6e 67 20 78 20 63  6f 6f 72 64 69 6e 61 74  |wing x coordinat|
000068f0  65 20 2a 2f 0a 20 20 20  20 20 20 76 69 65 77 5f  |e */.      view_|
00006900  79 2c 20 2f 2a 20 74 68  69 73 20 68 6f 6c 64 73  |y, /* this holds|
00006910  20 74 68 65 20 76 69 65  77 69 6e 67 20 79 20 63  | the viewing y c|
00006920  6f 6f 72 64 69 6e 61 74  65 20 2a 2f 0a 20 20 20  |oordinate */.   |
00006930  20 20 20 76 69 65 77 5f  61 6e 67 6c 65 3b 20 2f  |   view_angle; /|
00006940  2a 20 74 68 69 73 20 68  6f 6c 64 73 20 74 68 65  |* this holds the|
00006950  20 76 69 65 77 69 6e 67  20 61 6e 67 6c 65 20 69  | viewing angle i|
00006960  6e 20 66 69 78 65 64 20  75 6e 69 74 73 20 30 2d  |n fixed units 0-|
00006970  31 39 32 30 20 2a 2f 0a  0a 20 20 69 6e 74 20 6b  |1920 */..  int k|
00006980  65 79 5f 70 72 65 73 73  2c 20 2f 2a 20 74 68 69  |ey_press, /* thi|
00006990  73 20 69 73 20 75 73 65  64 20 74 6f 20 63 6f 6e  |s is used to con|
000069a0  66 69 72 6d 20 69 6e 70  75 74 20 6f 66 20 76 61  |firm input of va|
000069b0  6c 75 65 73 20 2a 2f 0a  20 20 20 20 20 20 64 6f  |lues */.      do|
000069c0  6e 65 3d 30 2c 20 20 20  20 2f 2a 20 66 6c 61 67  |ne=0,    /* flag|
000069d0  20 74 6f 20 69 6e 64 69  63 61 74 65 20 69 66 20  | to indicate if |
000069e0  74 68 65 20 75 73 65 72  20 77 61 6e 74 73 20 74  |the user wants t|
000069f0  6f 20 71 75 69 74 20 2a  2f 0a 20 20 20 20 20 20  |o quit */.      |
00006a00  64 78 2c 20 20 20 20 20  20 20 20 2f 2a 20 6d 6f  |dx,        /* mo|
00006a10  76 65 6d 65 6e 74 20 76  61 72 69 61 62 6c 65 73  |vement variables|
00006a20  20 66 6f 72 20 74 68 65  20 76 69 65 77 65 72 20  | for the viewer |
00006a30  2a 2f 0a 20 20 20 20 20  20 64 79 2c 0a 20 20 20  |*/.      dy,.   |
00006a40  20 20 20 79 5f 63 65 6c  6c 2c 20 20 20 20 2f 2a  |   y_cell,    /*|
00006a50  20 74 68 65 73 65 20 4e  45 57 20 76 61 72 69 61  | these NEW varia|
00006a60  62 6c 65 73 20 61 72 65  20 75 73 65 64 20 74 6f  |bles are used to|
00006a70  20 73 74 6f 72 65 20 74  68 65 20 70 6c 61 79 65  | store the playe|
00006a80  72 2f 76 69 65 77 65 72  2a 2f 0a 20 20 20 20 20  |r/viewer*/.     |
00006a90  20 78 5f 63 65 6c 6c 2c  20 20 20 20 2f 2a 20 77  | x_cell,    /* w|
00006aa0  6f 72 6c 64 20 70 6f 73  69 74 69 6f 6e 73 2c 20  |orld positions, |
00006ab0  66 6f 72 20 63 61 6c 63  75 6c 61 74 69 6e 67 20  |for calculating |
00006ac0  76 69 65 77 65 72 20 68  69 74 74 69 6e 67 20 77  |viewer hitting w|
00006ad0  61 6c 6c 73 20 2a 2f 0a  20 20 20 20 20 20 79 5f  |alls */.      y_|
00006ae0  73 75 62 5f 63 65 6c 6c  2c 0a 20 20 20 20 20 20  |sub_cell,.      |
00006af0  78 5f 73 75 62 5f 63 65  6c 6c 2c 0a 20 20 20 20  |x_sub_cell,.    |
00006b00  20 20 74 69 6d 65 5f 73  74 61 72 74 2c 0a 20 20  |  time_start,.  |
00006b10  20 20 20 20 74 69 6d 65  5f 66 69 6e 69 73 68 2c  |    time_finish,|
00006b20  20 2f 2a 20 54 68 65 73  65 20 6c 61 73 74 20 66  | /* These last f|
00006b30  65 77 20 76 61 72 69 61  62 6c 65 73 20 61 72 65  |ew variables are|
00006b40  20 75 73 65 64 20 74 6f  20 77 6f 72 6b 20 6f 75  | used to work ou|
00006b50  74 20 2a 2f 0a 20 20 20  20 20 20 66 72 61 6d 65  |t */.      frame|
00006b60  73 3d 30 3b 20 20 20 20  2f 2a 20 74 68 65 20 66  |s=0;    /* the f|
00006b70  72 61 6d 65 73 20 70 65  72 20 73 65 63 2e 20 6f  |rames per sec. o|
00006b80  66 20 74 68 65 20 73 79  73 74 65 6d 2c 20 73 6c  |f the system, sl|
00006b90  6f 77 20 66 6f 72 20 6e  6f 77 21 20 2a 2f 0a 0a  |ow for now! */..|
00006ba0  20 69 6e 74 20 74 65 6d  70 6f 72 61 72 79 5f 76  | int temporary_v|
00006bb0  61 72 69 61 62 6c 65 73  5b 31 30 5d 3b 20 2f 2a  |ariables[10]; /*|
00006bc0  20 74 68 69 73 20 61 72  72 61 79 20 63 61 6e 20  | this array can |
00006bd0  62 65 20 75 73 65 64 20  74 6f 20 70 61 73 73 20  |be used to pass |
00006be0  70 61 72 61 6d 65 74 65  72 73 20 2a 2f 0a 0a 2f  |parameters */../|
00006bf0  2a 20 77 65 27 6c 6c 20  61 73 73 69 67 6e 20 74  |* we'll assign t|
00006c00  68 6f 73 65 20 6e 6f 77  2c 20 66 6f 72 20 63 6c  |hose now, for cl|
00006c10  65 61 72 69 6e 67 20 74  68 65 20 73 63 72 65 65  |earing the scree|
00006c20  6e 20 28 73 6c 6f 77 6c  79 29 20 2a 2f 0a 0a 74  |n (slowly) */..t|
00006c30  65 6d 70 6f 72 61 72 79  5f 76 61 72 69 61 62 6c  |emporary_variabl|
00006c40  65 73 5b 31 5d 3d 74 65  6d 70 6f 72 61 72 79 5f  |es[1]=temporary_|
00006c50  76 61 72 69 61 62 6c 65  73 5b 32 5d 3d 74 65 6d  |variables[2]=tem|
00006c60  70 6f 72 61 72 79 5f 76  61 72 69 61 62 6c 65 73  |porary_variables|
00006c70  5b 35 5d 3d 30 3b 0a 74  65 6d 70 6f 72 61 72 79  |[5]=0;.temporary|
00006c80  5f 76 61 72 69 61 62 6c  65 73 5b 33 5d 3d 33 32  |_variables[3]=32|
00006c90  30 3b 74 65 6d 70 6f 72  61 72 79 5f 76 61 72 69  |0;temporary_vari|
00006ca0  61 62 6c 65 73 5b 34 5d  3d 32 35 36 3b 0a 0a 2f  |ables[4]=256;../|
00006cb0  2a 20 66 69 72 73 74 2c  20 77 65 20 6e 65 65 64  |* first, we need|
00006cc0  20 74 68 65 20 75 73 65  72 20 74 6f 20 69 6e 70  | the user to inp|
00006cd0  75 74 20 76 61 6c 75 65  73 20 66 6f 72 20 76 69  |ut values for vi|
00006ce0  65 77 5f 78 2c 76 69 65  77 5f 79 20 61 6e 64 20  |ew_x,view_y and |
00006cf0  76 69 65 77 5f 61 6e 67  6c 65 2a 2f 0a 0a 70 72  |view_angle*/..pr|
00006d00  69 6e 74 66 28 22 2a 2a  2a 2a 2a 2a 2a 20 4e 45  |intf("******* NE|
00006d10  57 2c 20 49 4d 50 52 4f  56 45 44 20 52 41 59 20  |W, IMPROVED RAY |
00006d20  43 41 53 54 45 52 20 2a  2a 2a 2a 2a 2a 2a 5c 6e  |CASTER *******\n|
00006d30  54 68 69 73 20 6d 6f 6e  74 68 27 73 20 72 61 79  |This month's ray|
00006d40  20 63 61 73 74 65 72 20  69 6e 76 6f 6c 76 65 73  | caster involves|
00006d50  20 53 43 52 45 45 4e 42  41 4e 4b 49 4e 47 2c 20  | SCREENBANKING, |
00006d60  43 4f 4c 4f 55 52 45 44  20 46 4c 4f 4f 52 53 20  |COLOURED FLOORS |
00006d70  41 4e 44 20 43 45 49 4c  49 4e 47 53 2c 20 46 49  |AND CEILINGS, FI|
00006d80  58 45 44 20 50 4f 49 4e  54 20 4d 41 54 48 53 20  |XED POINT MATHS |
00006d90  61 6e 64 20 4d 4f 52 45  2e 20 49 74 20 73 74 69  |and MORE. It sti|
00006da0  6c 6c 20 72 75 6e 73 20  61 74 20 66 75 6c 6c 20  |ll runs at full |
00006db0  73 63 72 65 65 6e 2c 20  62 75 74 20 6e 65 78 74  |screen, but next|
00006dc0  20 6d 6f 6e 74 68 20 77  69 6c 6c 20 68 61 76 65  | month will have|
00006dd0  20 61 6e 20 61 64 6a 75  73 74 61 62 6c 65 20 73  | an adjustable s|
00006de0  63 72 65 65 6e 20 73 69  7a 65 20 74 6f 20 72 75  |creen size to ru|
00006df0  6e 20 6d 75 63 68 20 71  75 69 63 6b 65 72 2e 20  |n much quicker. |
00006e00  4e 65 78 74 20 6d 6f 6e  74 68 27 73 20 77 69 6c  |Next month's wil|
00006e10  6c 20 67 6f 20 61 74 6c  65 61 73 74 20 32 35 20  |l go atleast 25 |
00006e20  66 70 73 20 6f 6e 20 61  20 52 50 43 20 36 30 30  |fps on a RPC 600|
00006e30  2e 20 41 6e 20 61 73 73  65 6d 62 6c 65 72 20 76  |. An assembler v|
00006e40  65 72 73 69 6f 6e 20 69  73 20 61 20 70 6f 73 73  |ersion is a poss|
00006e50  69 62 69 6c 69 74 79 2e  5c 6e 50 6c 65 61 73 65  |ibility.\nPlease|
00006e60  20 65 6e 74 65 72 20 73  74 61 72 74 69 6e 67 20  | enter starting |
00006e70  76 61 6c 75 65 73 20 66  6f 72 20 56 69 65 77 5f  |values for View_|
00006e80  58 2c 20 56 69 65 77 5f  59 2c 20 56 69 65 77 69  |X, View_Y, Viewi|
00006e90  6e 67 20 61 6e 67 6c 65  2e 20 4d 61 6b 65 20 73  |ng angle. Make s|
00006ea0  75 72 65 20 74 68 65 20  76 69 65 77 20 64 6f 65  |ure the view doe|
00006eb0  73 6e 27 74 20 73 74 61  72 74 20 69 6e 20 61 20  |sn't start in a |
00006ec0  77 61 6c 6c 21 5c 6e 20  55 73 65 20 74 68 65 20  |wall!\n Use the |
00006ed0  63 75 72 73 6f 72 20 6b  65 79 73 20 74 6f 20 6d  |cursor keys to m|
00006ee0  6f 76 65 20 61 6e 64 20  51 20 74 6f 20 71 75 69  |ove and Q to qui|
00006ef0  74 5c 6e 5c 6e 22 29 3b  0a 73 63 61 6e 66 28 22  |t\n\n");.scanf("|
00006f00  25 64 20 25 64 20 25 64  22 2c 26 76 69 65 77 5f  |%d %d %d",&view_|
00006f10  78 2c 26 76 69 65 77 5f  79 2c 26 76 69 65 77 5f  |x,&view_y,&view_|
00006f20  61 6e 67 6c 65 29 3b 0a  0a 2f 2a 20 63 6f 6e 66  |angle);../* conf|
00006f30  69 72 6d 20 74 68 69 73  20 69 73 20 6f 6b 20 2a  |irm this is ok *|
00006f40  2f 0a 0a 70 72 69 6e 74  66 28 22 59 6f 75 20 65  |/..printf("You e|
00006f50  6e 74 65 72 65 64 20 25  64 20 25 64 20 61 6e 64  |ntered %d %d and|
00006f60  20 25 64 20 50 72 65 73  73 20 30 20 74 6f 20 71  | %d Press 0 to q|
00006f70  75 69 74 20 61 6e 64 20  72 65 2d 65 6e 74 65 72  |uit and re-enter|
00006f80  20 6f 72 20 61 6e 79 20  6f 74 68 65 72 20 6e 75  | or any other nu|
00006f90  6d 62 65 72 20 74 6f 20  63 6f 6e 74 69 6e 75 65  |mber to continue|
00006fa0  2e 2e 2e 5c 6e 22 2c 76  69 65 77 5f 78 2c 76 69  |...\n",view_x,vi|
00006fb0  65 77 5f 79 2c 76 69 65  77 5f 61 6e 67 6c 65 29  |ew_y,view_angle)|
00006fc0  3b 0a 73 63 61 6e 66 28  22 25 64 22 2c 26 6b 65  |;.scanf("%d",&ke|
00006fd0  79 5f 70 72 65 73 73 29  3b 0a 0a 2f 2a 20 69 66  |y_press);../* if|
00006fe0  20 71 20 69 73 20 70 72  65 73 73 65 64 20 74 68  | q is pressed th|
00006ff0  65 6e 20 65 78 69 74 2c  20 65 6c 73 65 20 63 6f  |en exit, else co|
00007000  6e 74 69 6e 75 65 20 2a  2f 0a 0a 69 66 28 21 6b  |ntinue */..if(!k|
00007010  65 79 5f 70 72 65 73 73  29 65 78 69 74 28 31 29  |ey_press)exit(1)|
00007020  3b 0a 0a 2f 2a 20 6e 6f  77 20 77 65 20 63 61 6c  |;../* now we cal|
00007030  6c 20 61 75 61 5f 77 6f  72 6c 64 20 74 6f 20 6c  |l aua_world to l|
00007040  6f 61 64 20 69 6e 20 74  68 65 20 74 65 78 74 20  |oad in the text |
00007050  77 6f 72 6c 64 20 66 69  6c 65 20 77 68 69 63 68  |world file which|
00007060  20 64 65 66 69 6e 65 73  20 6f 75 72 20 77 61 6c  | defines our wal|
00007070  6c 73 20 74 79 70 65 20  61 6e 64 20 6c 61 79 6f  |ls type and layo|
00007080  75 74 20 2a 2f 0a 0a 70  72 69 6e 74 66 28 22 6c  |ut */..printf("l|
00007090  6f 61 64 69 6e 67 20 69  6e 20 74 65 78 74 20 66  |oading in text f|
000070a0  69 6c 65 20 3c 41 55 41  52 61 79 24 44 69 72 3e  |ile <AUARay$Dir>|
000070b0  2e 77 6f 72 6c 64 5c 6e  22 29 3b 0a 61 75 61 5f  |.world\n");.aua_|
000070c0  77 6f 72 6c 64 28 29 3b  0a 0a 2f 2a 20 63 68 65  |world();../* che|
000070d0  63 6b 20 74 6f 20 73 65  65 20 69 66 20 74 68 65  |ck to see if the|
000070e0  20 76 69 65 77 65 72 20  69 73 20 69 6e 73 69 64  | viewer is insid|
000070f0  65 20 61 20 67 61 6d 65  20 63 65 6c 6c 20 57 41  |e a game cell WA|
00007100  4c 4c 2c 20 77 68 69 63  68 20 77 6f 75 6c 64 20  |LL, which would |
00007110  62 65 20 62 61 64 20 6e  65 77 73 21 20 2a 2f 0a  |be bad news! */.|
00007120  0a 69 66 28 77 6f 72 6c  64 5b 76 69 65 77 5f 79  |.if(world[view_y|
00007130  3e 3e 36 5d 5b 76 69 65  77 5f 78 3e 3e 36 5d 29  |>>6][view_x>>6])|
00007140  0a 7b 0a 20 20 70 72 69  6e 74 66 28 22 42 61 64  |.{.  printf("Bad|
00007150  20 63 6f 6f 72 64 69 6e  61 74 65 73 20 67 69 76  | coordinates giv|
00007160  65 6e 2c 20 76 69 65 77  65 72 20 69 73 20 49 4e  |en, viewer is IN|
00007170  20 61 20 57 41 4c 4c 21  2c 20 65 78 69 74 69 6e  | a WALL!, exitin|
00007180  67 5c 6e 22 29 3b 0a 20  20 65 78 69 74 28 31 29  |g\n");.  exit(1)|
00007190  3b 0a 7d 0a 0a 2f 2a 20  6e 6f 77 20 77 65 20 63  |;.}../* now we c|
000071a0  61 6c 6c 20 61 75 61 5f  74 61 62 6c 65 73 20 74  |all aua_tables t|
000071b0  6f 20 67 65 6e 65 72 61  74 65 20 73 6f 6d 65 20  |o generate some |
000071c0  6c 6f 6f 6b 2d 75 70 20  74 61 62 6c 65 73 20 66  |look-up tables f|
000071d0  6f 72 20 74 68 65 20 65  6e 67 69 6e 65 20 74 6f  |or the engine to|
000071e0  20 75 73 65 2c 20 6c 6f  6f 6b 2d 75 70 73 20 61  | use, look-ups a|
000071f0  72 65 20 65 78 70 6c 61  69 6e 65 64 20 75 70 20  |re explained up |
00007200  61 74 20 74 68 65 20 74  6f 70 20 6f 66 20 74 68  |at the top of th|
00007210  65 20 66 69 6c 65 20 6e  65 78 74 20 74 6f 20 74  |e file next to t|
00007220  68 65 20 67 6c 6f 62 61  6c 20 76 61 72 69 61 62  |he global variab|
00007230  6c 65 73 20 2a 2f 0a 0a  70 72 69 6e 74 66 28 22  |les */..printf("|
00007240  63 61 6c 6c 69 6e 67 20  61 75 61 5f 74 61 62 6c  |calling aua_tabl|
00007250  65 73 28 29 20 74 68 69  73 20 63 6f 75 6c 64 20  |es() this could |
00007260  74 61 6b 65 20 61 20 6c  6f 6e 67 20 74 69 6d 65  |take a long time|
00007270  20 6f 6e 20 73 6f 6d 65  20 6d 61 63 68 69 6e 65  | on some machine|
00007280  73 5c 6e 22 29 3b 0a 2f  2a 20 6e 65 77 65 72 20  |s\n");./* newer |
00007290  66 69 78 65 64 20 70 6f  69 6e 74 20 76 65 72 73  |fixed point vers|
000072a0  69 6f 6e 20 2a 2f 0a 61  75 61 5f 74 61 62 6c 65  |ion */.aua_table|
000072b0  73 28 29 3b 0a 0a 2f 2a  20 61 6c 6c 20 69 73 20  |s();../* all is |
000072c0  64 6f 6e 65 20 69 6e 20  74 65 72 6d 73 20 6f 66  |done in terms of|
000072d0  20 69 6e 70 75 74 20 66  6f 72 20 6e 6f 77 2e 20  | input for now. |
000072e0  57 65 20 6e 65 65 64 20  74 6f 20 73 77 69 74 63  |We need to switc|
000072f0  68 20 74 6f 20 4d 6f 64  65 20 31 33 20 2a 2f 0a  |h to Mode 13 */.|
00007300  0a 70 72 69 6e 74 66 28  22 53 77 69 74 63 68 69  |.printf("Switchi|
00007310  6e 67 20 74 6f 20 4d 6f  64 65 20 31 33 5c 6e 22  |ng to Mode 13\n"|
00007320  29 3b 0a 0a 2f 2a 20 63  61 6c 6c 20 6f 75 72 6c  |);../* call ourl|
00007330  69 62 5f 63 68 61 6e 67  65 6d 6f 64 65 20 74 6f  |ib_changemode to|
00007340  20 73 77 69 74 63 68 20  74 6f 20 6d 6f 64 65 20  | switch to mode |
00007350  31 33 20 2a 2f 0a 0a 6f  75 72 6c 69 62 5f 63 68  |13 */..ourlib_ch|
00007360  61 6e 67 65 6d 6f 64 65  28 31 33 29 3b 0a 0a 2f  |angemode(13);../|
00007370  2a 20 63 61 6c 6c 20 6f  75 72 6c 69 62 5f 66 69  |* call ourlib_fi|
00007380  6e 64 73 63 72 65 65 6e  20 74 6f 20 67 65 74 20  |ndscreen to get |
00007390  74 68 65 20 73 63 72 65  65 6e 20 62 61 73 65 20  |the screen base |
000073a0  61 64 64 72 65 73 73 20  6f 66 20 6d 6f 64 65 20  |address of mode |
000073b0  31 33 2c 20 20 77 69 74  68 6f 75 74 20 74 68 65  |13,  without the|
000073c0  20 63 6f 72 72 65 63 74  20 61 64 64 72 65 73 73  | correct address|
000073d0  20 77 65 20 63 61 6e 27  74 20 64 72 61 77 20 61  | we can't draw a|
000073e0  6e 79 74 68 69 6e 67 20  61 6e 64 20 74 68 65 20  |nything and the |
000073f0  63 6f 6d 70 75 74 65 72  20 63 6f 75 6c 64 20 63  |computer could c|
00007400  72 61 73 68 20 2a 2f 0a  0a 73 63 72 65 65 6e 5f  |rash */..screen_|
00007410  61 64 64 72 65 73 73 3d  28 63 68 61 72 20 2a 29  |address=(char *)|
00007420  6f 75 72 6c 69 62 5f 66  69 6e 64 73 63 72 65 65  |ourlib_findscree|
00007430  6e 28 29 3b 0a 0a 2f 2a  20 6e 6f 77 20 77 65 20  |n();../* now we |
00007440  6e 65 65 64 20 74 6f 20  2a 73 63 72 65 65 6e 6c  |need to *screenl|
00007450  6f 61 64 20 6f 75 72 20  67 72 61 70 68 69 63 73  |oad our graphics|
00007460  20 66 69 6c 65 2c 20 61  6e 64 20 67 72 61 62 20  | file, and grab |
00007470  65 61 63 68 20 69 6e 64  69 76 69 64 75 61 6c 20  |each individual |
00007480  77 61 6c 6c 20 67 72 61  70 68 69 63 20 6f 6e 65  |wall graphic one|
00007490  20 62 79 20 6f 6e 65 2c  20 74 68 65 20 66 75 6e  | by one, the fun|
000074a0  63 74 69 6f 6e 20 61 75  61 5f 67 72 61 70 68 69  |ction aua_graphi|
000074b0  63 73 20 64 6f 65 73 20  74 68 69 73 20 2a 2f 0a  |cs does this */.|
000074c0  0a 61 75 61 5f 67 72 61  70 68 69 63 73 28 29 3b  |.aua_graphics();|
000074d0  0a 0a 0a 2f 2a 20 4e 4f  57 20 77 65 20 63 61 6c  |.../* NOW we cal|
000074e0  6c 20 73 65 74 75 70 5f  73 63 72 65 65 6e 73 2c  |l setup_screens,|
000074f0  20 61 20 73 6d 61 6c 6c  20 66 75 6e 63 74 69 6f  | a small functio|
00007500  6e 20 77 68 69 63 68 20  68 65 6c 70 73 20 77 69  |n which helps wi|
00007510  74 68 20 62 61 6e 6b 69  6e 67 20 2a 2f 0a 2f 2a  |th banking */./*|
00007520  20 57 69 74 68 20 61 6c  6c 20 74 68 65 20 64 61  | With all the da|
00007530  74 61 20 6c 6f 61 64 65  64 20 69 6e 20 77 65 20  |ta loaded in we |
00007540  73 68 61 6c 6c 20 74 72  79 20 61 6e 64 20 69 6e  |shall try and in|
00007550  69 74 69 61 74 65 20 53  43 52 45 45 4e 20 42 41  |itiate SCREEN BA|
00007560  4e 4b 53 2e 20 46 69 72  73 74 20 77 65 20 63 68  |NKS. First we ch|
00007570  61 6e 67 65 20 74 6f 20  4d 4f 44 45 20 31 35 2c  |ange to MODE 15,|
00007580  20 73 6f 20 74 68 61 74  20 73 63 72 65 65 6e 20  | so that screen |
00007590  6d 65 6d 6f 72 79 20 62  65 63 6f 6d 65 73 20 61  |memory becomes a|
000075a0  76 61 69 6c 61 62 6c 65  20 66 6f 72 20 74 77 6f  |vailable for two|
000075b0  20 74 69 6d 65 73 20 4d  4f 44 45 20 31 33 20 2a  | times MODE 13 *|
000075c0  2f 0a 0a 6f 75 72 6c 69  62 5f 73 65 74 75 70 5f  |/..ourlib_setup_|
000075d0  73 63 72 65 65 6e 73 28  29 3b 0a 6f 75 72 6c 69  |screens();.ourli|
000075e0  62 5f 63 68 61 6e 67 65  6d 6f 64 65 28 31 35 29  |b_changemode(15)|
000075f0  3b 0a 0a 2f 2a 20 4e 6f  77 20 77 65 20 73 77 69  |;../* Now we swi|
00007600  74 63 68 20 74 6f 20 4d  4f 44 45 20 31 33 2c 20  |tch to MODE 13, |
00007610  61 6e 64 20 67 65 74 20  74 68 65 20 66 69 72 73  |and get the firs|
00007620  74 20 73 63 72 65 65 6e  20 61 64 64 72 65 73 73  |t screen address|
00007630  20 2a 2f 0a 0a 6f 75 72  6c 69 62 5f 63 68 61 6e  | */..ourlib_chan|
00007640  67 65 6d 6f 64 65 28 31  33 29 3b 0a 0a 73 63 72  |gemode(13);..scr|
00007650  65 65 6e 5f 61 64 64 72  65 73 73 3d 28 63 68 61  |een_address=(cha|
00007660  72 20 2a 29 6f 75 72 6c  69 62 5f 66 69 6e 64 73  |r *)ourlib_finds|
00007670  63 72 65 65 6e 28 29 3b  0a 0a 2f 2a 20 4e 6f 77  |creen();../* Now|
00007680  20 77 65 20 73 77 69 74  63 68 20 74 6f 20 74 68  | we switch to th|
00007690  65 20 6f 74 68 65 72 20  73 63 72 65 65 6e 20 62  |e other screen b|
000076a0  61 6e 6b 20 61 6e 64 20  67 65 74 20 74 68 65 20  |ank and get the |
000076b0  6f 74 68 65 72 20 73 63  72 65 65 6e 20 61 64 64  |other screen add|
000076c0  72 65 73 73 20 2a 2f 0a  0a 6f 75 72 6c 69 62 5f  |ress */..ourlib_|
000076d0  73 69 6d 70 6c 65 73 77  69 74 63 68 28 29 3b 0a  |simpleswitch();.|
000076e0  0a 0a 0a 73 63 72 65 65  6e 5f 61 64 64 72 65 73  |...screen_addres|
000076f0  73 5f 62 61 6e 6b 3d 28  63 68 61 72 20 2a 29 6f  |s_bank=(char *)o|
00007700  75 72 6c 69 62 5f 66 69  6e 64 73 63 72 65 65 6e  |urlib_findscreen|
00007710  28 29 3b 0a 0a 2f 2a 20  77 65 20 73 68 61 6c 6c  |();../* we shall|
00007720  20 63 6c 65 61 72 20 74  68 65 20 73 63 72 65 65  | clear the scree|
00007730  6e 20 68 65 72 65 20 2a  2f 0a 74 65 6d 70 6f 72  |n here */.tempor|
00007740  61 72 79 5f 76 61 72 69  61 62 6c 65 73 5b 30 5d  |ary_variables[0]|
00007750  3d 73 63 72 65 65 6e 5f  61 64 64 72 65 73 73 5f  |=screen_address_|
00007760  62 61 6e 6b 3b 0a 6f 75  72 6c 69 62 5f 63 6f 6c  |bank;.ourlib_col|
00007770  6f 75 72 5f 62 6f 78 28  74 65 6d 70 6f 72 61 72  |our_box(temporar|
00007780  79 5f 76 61 72 69 61 62  6c 65 73 29 3b 0a 0a 2f  |y_variables);../|
00007790  2a 20 53 77 69 74 63 68  20 62 61 63 6b 20 74 6f  |* Switch back to|
000077a0  20 74 68 65 20 6f 74 68  65 72 20 73 63 72 65 65  | the other scree|
000077b0  6e 20 2a 2f 0a 0a 6f 75  72 6c 69 62 5f 73 69 6d  |n */..ourlib_sim|
000077c0  70 6c 65 73 77 69 74 63  68 28 29 3b 0a 0a 0a 0a  |pleswitch();....|
000077d0  2f 2a 20 4e 4f 57 20 77  65 20 63 61 6e 20 63 61  |/* NOW we can ca|
000077e0  6c 6c 20 73 65 74 75 70  20 62 61 63 6b 67 72 6f  |ll setup backgro|
000077f0  75 6e 64 2c 20 74 6f 20  74 65 6c 6c 20 74 68 65  |und, to tell the|
00007800  20 73 63 72 65 65 6e 20  63 6c 65 61 72 65 72 20  | screen clearer |
00007810  74 68 65 20 63 6f 6c 6f  75 72 20 6f 66 20 74 68  |the colour of th|
00007820  65 20 66 6c 6f 6f 72 20  61 6e 64 20 63 65 69 6c  |e floor and ceil|
00007830  69 6e 67 73 20 77 65 20  77 61 6e 74 2e 20 49 6e  |ings we want. In|
00007840  20 4c 41 54 45 52 20 56  45 52 53 49 4f 4e 53 20  | LATER VERSIONS |
00007850  6f 66 20 74 68 65 20 65  6e 67 69 6e 65 20 74 68  |of the engine th|
00007860  65 73 65 20 73 6f 72 74  20 6f 66 20 64 65 74 61  |ese sort of deta|
00007870  69 6c 73 20 77 69 6c 6c  20 62 65 20 63 61 6c 6c  |ils will be call|
00007880  65 64 20 74 68 72 6f 75  67 68 20 74 68 65 20 43  |ed through the C|
00007890  4f 4d 4d 41 4e 44 20 4c  49 4e 45 2c 20 73 6f 20  |OMMAND LINE, so |
000078a0  6e 6f 20 73 6f 75 72 63  65 20 63 6f 64 65 20 63  |no source code c|
000078b0  68 61 6e 67 69 6e 67 20  77 69 6c 6c 20 62 65 20  |hanging will be |
000078c0  6e 65 63 65 73 73 61 72  79 20 2a 2f 0a 0a 6f 75  |necessary */..ou|
000078d0  72 6c 69 62 5f 73 65 74  75 70 5f 62 61 63 6b 67  |rlib_setup_backg|
000078e0  72 6f 75 6e 64 28 31 34  38 2c 32 35 29 3b 0a 0a  |round(148,25);..|
000078f0  2f 2a 20 4e 4f 57 20 77  65 20 63 61 6e 20 73 74  |/* NOW we can st|
00007900  61 72 74 20 74 68 65 20  6d 61 69 6e 20 6c 6f 6f  |art the main loo|
00007910  70 2c 20 65 78 69 74 61  62 6c 65 20 6f 6e 6c 79  |p, exitable only|
00007920  20 62 79 20 70 72 65 73  73 69 6e 67 20 74 68 65  | by pressing the|
00007930  20 51 20 6b 65 79 2e 20  55 73 65 20 74 68 65 20  | Q key. Use the |
00007940  43 75 72 73 6f 72 73 20  74 6f 20 6d 6f 76 65 20  |Cursors to move |
00007950  74 68 65 20 76 69 65 77  70 6f 69 6e 74 20 61 72  |the viewpoint ar|
00007960  6f 75 6e 64 20 2a 2f 0a  2f 2a 20 57 65 20 73 68  |ound */./* We sh|
00007970  61 6c 6c 20 61 6c 73 6f  20 74 61 6b 65 20 61 20  |all also take a |
00007980  72 65 61 64 69 6e 67 20  74 6f 20 77 6f 72 6b 20  |reading to work |
00007990  6f 75 74 20 74 68 65 20  66 72 61 6d 65 20 72 61  |out the frame ra|
000079a0  74 65 20 6f 66 20 74 68  65 20 73 79 73 74 65 6d  |te of the system|
000079b0  2c 20 73 6c 6f 77 20 66  6f 72 20 6e 6f 77 20 2a  |, slow for now *|
000079c0  2f 0a 0a 6f 75 72 6c 69  62 5f 6b 69 6c 6c 63 75  |/..ourlib_killcu|
000079d0  72 73 6f 72 28 29 3b 20  2f 2a 20 67 65 74 20 72  |rsor(); /* get r|
000079e0  69 64 20 6f 66 20 74 68  65 20 63 75 72 73 6f 72  |id of the cursor|
000079f0  20 66 6c 61 73 68 69 6e  67 20 61 77 61 79 20 2a  | flashing away *|
00007a00  2f 0a 74 69 6d 65 5f 73  74 61 72 74 3d 6f 75 72  |/.time_start=our|
00007a10  6c 69 62 5f 67 65 74 74  69 6d 65 28 29 3b 0a 0a  |lib_gettime();..|
00007a20  77 68 69 6c 65 28 21 64  6f 6e 65 29 20 2f 2a 20  |while(!done) /* |
00007a30  74 68 65 20 6c 6f 6f 70  20 77 69 6c 6c 20 63 6f  |the loop will co|
00007a40  6e 74 69 6e 75 65 20 75  6e 74 69 6c 20 64 6f 6e  |ntinue until don|
00007a50  65 20 2a 2f 0a 7b 0a 0a  20 6f 75 72 6c 69 62 5f  |e */.{.. ourlib_|
00007a60  66 61 73 74 63 6c 67 5f  74 77 6f 28 73 63 72 65  |fastclg_two(scre|
00007a70  65 6e 5f 61 64 64 72 65  73 73 2c 53 43 52 45 45  |en_address,SCREE|
00007a80  4e 5f 57 49 44 54 48 2c  53 43 52 45 45 4e 5f 48  |N_WIDTH,SCREEN_H|
00007a90  45 49 47 48 54 29 3b 20  2f 2a 20 77 65 20 63 61  |EIGHT); /* we ca|
00007aa0  6c 6c 20 74 68 65 20 66  6c 6f 6f 72 2f 63 65 69  |ll the floor/cei|
00007ab0  6c 69 6e 67 20 66 75 6e  63 74 69 6f 6e 20 74 6f  |ling function to|
00007ac0  20 63 6f 6c 6f 75 72 20  74 68 65 20 77 68 6f 6c  | colour the whol|
00007ad0  65 20 73 63 72 65 65 6e  20 2a 2f 0a 2f 2a 20 74  |e screen */./* t|
00007ae0  68 65 6e 20 77 65 20 63  61 6c 6c 20 74 68 65 20  |hen we call the |
00007af0  72 61 79 20 63 61 73 74  65 72 20 74 6f 20 64 72  |ray caster to dr|
00007b00  61 77 20 6f 76 65 72 20  69 74 20 2a 2f 0a 20 20  |aw over it */.  |
00007b10  61 75 61 5f 72 61 79 63  61 73 74 65 72 28 76 69  |aua_raycaster(vi|
00007b20  65 77 5f 78 2c 76 69 65  77 5f 79 2c 76 69 65 77  |ew_x,view_y,view|
00007b30  5f 61 6e 67 6c 65 29 3b  0a 0a 2f 2a 20 72 65 73  |_angle);../* res|
00007b40  65 74 20 74 68 65 20 76  61 72 69 61 62 6c 65 73  |et the variables|
00007b50  20 66 6f 72 20 6d 6f 76  69 6e 67 20 74 68 65 20  | for moving the |
00007b60  76 69 65 77 70 6f 69 6e  74 20 2a 2f 0a 0a 64 78  |viewpoint */..dx|
00007b70  3d 64 79 3d 30 3b 0a 0a  2f 2a 20 6e 6f 77 20 77  |=dy=0;../* now w|
00007b80  65 20 74 65 73 74 20 66  6f 72 20 64 69 66 66 65  |e test for diffe|
00007b90  72 65 6e 74 20 6b 65 79  20 70 72 65 73 73 65 73  |rent key presses|
00007ba0  20 61 6e 64 20 74 61 6b  65 20 61 63 74 69 6f 6e  | and take action|
00007bb0  20 61 63 63 6f 72 64 69  6e 67 6c 79 20 2a 2f 0a  | accordingly */.|
00007bc0  0a 69 66 28 6f 75 72 6c  69 62 5f 6b 65 79 64 6f  |.if(ourlib_keydo|
00007bd0  77 6e 28 31 36 29 3d 3d  32 35 35 29 64 6f 6e 65  |wn(16)==255)done|
00007be0  3d 31 3b 20 2f 2a 20 69  66 20 51 20 69 73 20 70  |=1; /* if Q is p|
00007bf0  72 65 73 73 65 64 20 74  68 65 6e 20 71 75 69 74  |ressed then quit|
00007c00  20 2a 2f 0a 0a 2f 2a 20  4c 45 46 54 20 2a 2f 0a  | */../* LEFT */.|
00007c10  69 66 28 6f 75 72 6c 69  62 5f 6b 65 79 64 6f 77  |if(ourlib_keydow|
00007c20  6e 28 31 32 31 29 3d 3d  32 35 35 29 0a 7b 0a 20  |n(121)==255).{. |
00007c30  20 69 66 28 28 76 69 65  77 5f 61 6e 67 6c 65 2d  | if((view_angle-|
00007c40  3d 41 4e 47 4c 45 5f 36  29 3c 41 4e 47 4c 45 5f  |=ANGLE_6)<ANGLE_|
00007c50  30 29 0a 20 20 76 69 65  77 5f 61 6e 67 6c 65 3d  |0).  view_angle=|
00007c60  41 4e 47 4c 45 5f 33 36  30 3b 0a 7d 0a 0a 2f 2a  |ANGLE_360;.}../*|
00007c70  52 49 47 48 54 20 2a 2f  0a 69 66 28 6f 75 72 6c  |RIGHT */.if(ourl|
00007c80  69 62 5f 6b 65 79 64 6f  77 6e 28 32 35 29 3d 3d  |ib_keydown(25)==|
00007c90  32 35 35 29 0a 7b 0a 20  20 69 66 28 28 76 69 65  |255).{.  if((vie|
00007ca0  77 5f 61 6e 67 6c 65 2b  3d 41 4e 47 4c 45 5f 36  |w_angle+=ANGLE_6|
00007cb0  29 3e 41 4e 47 4c 45 5f  33 36 30 29 0a 20 20 76  |)>ANGLE_360).  v|
00007cc0  69 65 77 5f 61 6e 67 6c  65 3d 41 4e 47 4c 45 5f  |iew_angle=ANGLE_|
00007cd0  30 3b 0a 7d 0a 2f 2a 20  55 50 20 61 6e 64 20 44  |0;.}./* UP and D|
00007ce0  4f 57 4e 20 2a 2f 0a 69  66 28 6f 75 72 6c 69 62  |OWN */.if(ourlib|
00007cf0  5f 6b 65 79 64 6f 77 6e  28 35 37 29 3d 3d 32 35  |_keydown(57)==25|
00007d00  35 29 0a 7b 0a 20 20 64  78 3d 64 78 5f 74 61 62  |5).{.  dx=dx_tab|
00007d10  6c 65 5b 76 69 65 77 5f  61 6e 67 6c 65 5d 3b 0a  |le[view_angle];.|
00007d20  20 20 64 79 3d 64 79 5f  74 61 62 6c 65 5b 76 69  |  dy=dy_table[vi|
00007d30  65 77 5f 61 6e 67 6c 65  5d 3b 0a 7d 0a 0a 69 66  |ew_angle];.}..if|
00007d40  28 6f 75 72 6c 69 62 5f  6b 65 79 64 6f 77 6e 28  |(ourlib_keydown(|
00007d50  34 31 29 3d 3d 32 35 35  29 0a 7b 0a 20 20 64 78  |41)==255).{.  dx|
00007d60  3d 2d 64 78 5f 74 61 62  6c 65 5b 76 69 65 77 5f  |=-dx_table[view_|
00007d70  61 6e 67 6c 65 5d 3b 0a  20 20 64 79 3d 2d 64 79  |angle];.  dy=-dy|
00007d80  5f 74 61 62 6c 65 5b 76  69 65 77 5f 61 6e 67 6c  |_table[view_angl|
00007d90  65 5d 3b 0a 7d 0a 0a 2f  2a 20 4e 4f 57 20 77 65  |e];.}../* NOW we|
00007da0  20 6e 65 65 64 20 74 6f  20 6d 6f 76 65 20 74 68  | need to move th|
00007db0  65 20 70 6c 61 79 65 72  20 61 6e 64 20 72 65 63  |e player and rec|
00007dc0  61 6c 63 75 6c 61 74 65  20 74 68 65 20 63 65 6c  |alculate the cel|
00007dd0  6c 20 74 68 65 20 76 69  65 77 65 72 20 69 73 20  |l the viewer is |
00007de0  69 6e 2c 20 61 6e 64 20  41 4c 53 4f 20 63 68 65  |in, and ALSO che|
00007df0  63 6b 20 74 6f 20 73 65  65 20 69 66 20 74 68 65  |ck to see if the|
00007e00  20 70 6c 61 79 65 72 20  68 61 73 20 68 69 74 20  | player has hit |
00007e10  61 20 77 61 6c 6c 20 2a  2f 0a 0a 2f 2a 20 57 61  |a wall */../* Wa|
00007e20  74 63 68 20 66 6f 72 20  74 68 65 20 63 6f 6e 76  |tch for the conv|
00007e30  65 72 73 69 6f 6e 73 20  6f 66 20 66 69 78 65 64  |ersions of fixed|
00007e40  20 70 6f 69 6e 74 20 61  6e 64 20 74 68 69 6e 67  | point and thing|
00007e50  73 20 2a 2f 0a 0a 2f 2a  20 50 6c 61 79 65 72 20  |s */../* Player |
00007e60  58 20 61 63 74 75 61 6c  6c 79 20 69 73 20 69 6e  |X actually is in|
00007e70  20 6e 6f 72 6d 61 6c 20  6d 61 74 68 73 20 2a 2f  | normal maths */|
00007e80  0a 20 76 69 65 77 5f 78  3d 20 28 69 6e 74 29 28  |. view_x= (int)(|
00007e90  28 76 69 65 77 5f 78 3c  3c 31 36 29 2b 64 78 29  |(view_x<<16)+dx)|
00007ea0  3e 3e 31 36 3b 0a 20 76  69 65 77 5f 79 3d 20 28  |>>16;. view_y= (|
00007eb0  69 6e 74 29 28 28 76 69  65 77 5f 79 3c 3c 31 36  |int)((view_y<<16|
00007ec0  29 2b 64 79 29 3e 3e 31  36 3b 0a 0a 20 78 5f 63  |)+dy)>>16;.. x_c|
00007ed0  65 6c 6c 20 3d 20 76 69  65 77 5f 78 2f 43 45 4c  |ell = view_x/CEL|
00007ee0  4c 5f 58 5f 53 49 5a 45  3b 0a 20 79 5f 63 65 6c  |L_X_SIZE;. y_cel|
00007ef0  6c 20 3d 20 76 69 65 77  5f 79 2f 43 45 4c 4c 5f  |l = view_y/CELL_|
00007f00  59 5f 53 49 5a 45 3b 0a  0a 20 78 5f 73 75 62 5f  |Y_SIZE;.. x_sub_|
00007f10  63 65 6c 6c 20 3d 20 76  69 65 77 5f 78 20 25 20  |cell = view_x % |
00007f20  43 45 4c 4c 5f 58 5f 53  49 5a 45 3b 0a 20 79 5f  |CELL_X_SIZE;. y_|
00007f30  73 75 62 5f 63 65 6c 6c  20 3d 20 76 69 65 77 5f  |sub_cell = view_|
00007f40  79 20 25 20 43 45 4c 4c  5f 59 5f 53 49 5a 45 3b  |y % CELL_Y_SIZE;|
00007f50  0a 0a 2f 2a 20 43 48 45  43 4b 20 74 6f 20 73 65  |../* CHECK to se|
00007f60  65 20 69 66 20 70 6c 61  79 65 72 20 68 61 73 20  |e if player has |
00007f70  77 61 6c 6b 65 64 20 69  6e 74 6f 20 77 61 6c 6c  |walked into wall|
00007f80  73 20 2a 2f 0a 20 69 66  20 28 28 64 78 3e 3e 38  |s */. if ((dx>>8|
00007f90  29 3e 30 20 29 7b 0a 20  69 66 20 28 28 77 6f 72  |)>0 ){. if ((wor|
00007fa0  6c 64 5b 79 5f 63 65 6c  6c 5d 5b 78 5f 63 65 6c  |ld[y_cell][x_cel|
00007fb0  6c 2b 31 5d 20 21 3d 20  30 29 20 20 26 26 20 28  |l+1] != 0)  && (|
00007fc0  78 5f 73 75 62 5f 63 65  6c 6c 3e 28 43 45 4c 4c  |x_sub_cell>(CELL|
00007fd0  5f 58 5f 53 49 5a 45 2d  43 4c 4f 53 45 53 54 29  |_X_SIZE-CLOSEST)|
00007fe0  29 29 0a 20 20 20 20 20  20 20 20 20 20 20 20 20  |)).             |
00007ff0  20 20 20 7b 0a 20 20 20  20 20 20 20 20 20 20 20  |   {.           |
00008000  20 20 20 20 20 76 69 65  77 5f 78 2d 3d 20 28 78  |     view_x-= (x|
00008010  5f 73 75 62 5f 63 65 6c  6c 2d 28 43 45 4c 4c 5f  |_sub_cell-(CELL_|
00008020  58 5f 53 49 5a 45 2d 43  4c 4f 53 45 53 54 20 29  |X_SIZE-CLOSEST )|
00008030  29 3b 0a 20 20 20 20 20  20 20 20 20 20 20 20 20  |);.             |
00008040  20 20 20 7d 0a 20 20 20  20 20 20 20 20 20 20 20  |   }.           |
00008050  20 20 20 20 20 7d 0a 20  65 6c 73 65 0a 20 7b 0a  |     }. else. {.|
00008060  20 69 66 20 28 20 28 77  6f 72 6c 64 5b 79 5f 63  | if ( (world[y_c|
00008070  65 6c 6c 5d 5b 78 5f 63  65 6c 6c 2d 31 5d 20 21  |ell][x_cell-1] !|
00008080  3d 20 30 29 20 20 26 26  20 28 78 5f 73 75 62 5f  |= 0)  && (x_sub_|
00008090  63 65 6c 6c 20 3c 20 28  43 4c 4f 53 45 53 54 29  |cell < (CLOSEST)|
000080a0  20 29 20 29 0a 20 20 20  20 20 20 20 20 20 20 20  | ) ).           |
000080b0  20 20 20 20 20 7b 0a 20  20 20 20 20 20 20 20 20  |     {.         |
000080c0  20 20 20 20 20 20 20 76  69 65 77 5f 78 2b 3d 20  |       view_x+= |
000080d0  28 43 4c 4f 53 45 53 54  2d 78 5f 73 75 62 5f 63  |(CLOSEST-x_sub_c|
000080e0  65 6c 6c 29 20 3b 0a 20  20 20 20 20 20 20 20 20  |ell) ;.         |
000080f0  20 20 20 20 20 20 20 7d  0a 20 7d 0a 0a 20 69 66  |       }. }.. if|
00008100  20 28 28 64 79 3e 3e 38  29 3e 30 20 29 7b 0a 20  | ((dy>>8)>0 ){. |
00008110  69 66 20 28 20 28 77 6f  72 6c 64 5b 28 79 5f 63  |if ( (world[(y_c|
00008120  65 6c 6c 2b 31 29 5d 5b  78 5f 63 65 6c 6c 5d 20  |ell+1)][x_cell] |
00008130  21 3d 20 30 29 20 20 26  26 0a 20 20 20 20 20 20  |!= 0)  &&.      |
00008140  20 20 20 20 20 20 20 20  20 20 28 79 5f 73 75 62  |          (y_sub|
00008150  5f 63 65 6c 6c 20 3e 20  28 43 45 4c 4c 5f 59 5f  |_cell > (CELL_Y_|
00008160  53 49 5a 45 2d 43 4c 4f  53 45 53 54 20 29 20 29  |SIZE-CLOSEST ) )|
00008170  20 29 0a 20 20 20 20 20  20 20 20 20 20 20 20 20  | ).             |
00008180  20 20 20 7b 0a 20 20 20  20 20 20 20 20 20 20 20  |   {.           |
00008190  20 20 20 20 20 76 69 65  77 5f 79 2d 3d 20 28 79  |     view_y-= (y|
000081a0  5f 73 75 62 5f 63 65 6c  6c 2d 28 43 45 4c 4c 5f  |_sub_cell-(CELL_|
000081b0  59 5f 53 49 5a 45 2d 43  4c 4f 53 45 53 54 20 29  |Y_SIZE-CLOSEST )|
000081c0  29 3b 0a 20 20 20 20 20  20 20 20 20 20 20 20 20  |);.             |
000081d0  20 20 20 7d 0a 20 20 20  20 20 20 20 20 20 20 20  |   }.           |
000081e0  20 20 20 20 20 7d 0a 20  65 6c 73 65 0a 20 7b 0a  |     }. else. {.|
000081f0  20 69 66 20 28 20 28 77  6f 72 6c 64 5b 28 79 5f  | if ( (world[(y_|
00008200  63 65 6c 6c 2d 31 29 5d  5b 78 5f 63 65 6c 6c 5d  |cell-1)][x_cell]|
00008210  20 21 3d 20 30 29 20 20  26 26 20 28 79 5f 73 75  | != 0)  && (y_su|
00008220  62 5f 63 65 6c 6c 20 3c  20 28 43 4c 4f 53 45 53  |b_cell < (CLOSES|
00008230  54 29 20 29 20 29 0a 20  20 20 20 20 20 20 20 20  |T) ) ).         |
00008240  20 20 20 20 20 20 20 7b  0a 20 20 20 20 20 20 20  |       {.       |
00008250  20 20 20 20 20 20 20 20  20 76 69 65 77 5f 79 2b  |         view_y+|
00008260  3d 20 28 43 4c 4f 53 45  53 54 2d 79 5f 73 75 62  |= (CLOSEST-y_sub|
00008270  5f 63 65 6c 6c 29 3b 0a  20 20 20 20 20 20 20 20  |_cell);.        |
00008280  20 20 20 20 20 20 20 20  7d 0a 20 7d 0a 0a 2f 2a  |        }. }../*|
00008290  20 50 48 45 57 21 20 4e  6f 77 20 77 65 20 63 61  | PHEW! Now we ca|
000082a0  6e 20 77 61 69 74 20 66  6f 72 20 61 20 76 79 73  |n wait for a vys|
000082b0  6e 63 20 61 6e 64 20 74  68 65 6e 20 73 77 69 74  |nc and then swit|
000082c0  63 68 20 74 68 65 20 76  69 65 77 73 2f 62 61 6e  |ch the views/ban|
000082d0  6b 73 20 6f 76 65 72 20  6f 74 20 20 70 72 6f 64  |ks over ot  prod|
000082e0  75 63 65 20 66 6c 69 63  6b 65 72 2d 66 72 65 65  |uce flicker-free|
000082f0  20 61 6e 69 6d 61 74 69  6f 6e 20 2a 2f 0a 0a 6f  | animation */..o|
00008300  75 72 6c 69 62 5f 77 61  69 74 76 73 79 6e 63 28  |urlib_waitvsync(|
00008310  29 3b 0a 6f 75 72 6c 69  62 5f 73 69 6d 70 6c 65  |);.ourlib_simple|
00008320  73 77 69 74 63 68 28 29  3b 0a 0a 2f 2a 20 57 65  |switch();../* We|
00008330  20 61 6c 73 6f 20 68 61  76 65 20 74 6f 20 73 77  | also have to sw|
00008340  69 74 63 68 20 74 68 65  20 6d 65 6d 6f 72 79 20  |itch the memory |
00008350  61 64 64 72 65 73 73 65  73 20 61 72 6f 75 6e 64  |addresses around|
00008360  20 73 6f 20 6f 75 72 20  66 75 6e 63 74 69 6f 6e  | so our function|
00008370  73 20 64 72 61 77 20 74  6f 20 74 68 65 20 63 6f  |s draw to the co|
00008380  72 72 65 63 74 20 6d 65  6d 6f 72 79 20 2a 2f 0a  |rrect memory */.|
00008390  0a 73 63 72 65 65 6e 5f  61 64 64 72 65 73 73 5f  |.screen_address_|
000083a0  74 65 6d 70 3d 73 63 72  65 65 6e 5f 61 64 64 72  |temp=screen_addr|
000083b0  65 73 73 5f 62 61 6e 6b  3b 0a 73 63 72 65 65 6e  |ess_bank;.screen|
000083c0  5f 61 64 64 72 65 73 73  5f 62 61 6e 6b 3d 73 63  |_address_bank=sc|
000083d0  72 65 65 6e 5f 61 64 64  72 65 73 73 3b 0a 73 63  |reen_address;.sc|
000083e0  72 65 65 6e 5f 61 64 64  72 65 73 73 3d 73 63 72  |reen_address=scr|
000083f0  65 65 6e 5f 61 64 64 72  65 73 73 5f 74 65 6d 70  |een_address_temp|
00008400  3b 0a 0a 2f 2a 20 61 64  64 20 6f 6e 65 20 74 6f  |;../* add one to|
00008410  20 74 68 65 20 66 72 61  6d 65 73 20 63 6f 75 6e  | the frames coun|
00008420  74 2c 20 77 65 20 61 72  65 20 63 6f 75 6e 74 69  |t, we are counti|
00008430  6e 67 20 74 68 65 20 6e  75 6d 62 65 72 20 6f 66  |ng the number of|
00008440  20 66 72 61 6d 65 73 20  67 65 6e 65 72 61 74 65  | frames generate|
00008450  64 20 20 2a 2f 0a 66 72  61 6d 65 73 2b 2b 3b 0a  |d  */.frames++;.|
00008460  7d 0a 2f 2a 20 72 65 63  6f 72 64 20 74 68 65 20  |}./* record the |
00008470  74 69 6d 65 20 73 74 6f  70 70 65 64 20 2a 2f 0a  |time stopped */.|
00008480  0a 74 69 6d 65 5f 66 69  6e 69 73 68 3d 6f 75 72  |.time_finish=our|
00008490  6c 69 62 5f 67 65 74 74  69 6d 65 28 29 3b 0a 0a  |lib_gettime();..|
000084a0  2f 2a 20 74 61 6b 65 20  61 20 73 63 72 65 65 6e  |/* take a screen|
000084b0  73 68 6f 74 2c 20 75 73  69 6e 67 20 2a 73 63 72  |shot, using *scr|
000084c0  65 65 6e 20 73 61 76 65  2c 20 61 6e 64 20 73 61  |een save, and sa|
000084d0  76 65 20 69 74 20 69 6e  73 69 64 65 20 74 68 65  |ve it inside the|
000084e0  20 64 69 72 65 63 74 6f  72 79 20 2a 2f 0a 0a 73  | directory */..s|
000084f0  79 73 74 65 6d 28 22 2a  53 63 72 65 65 6e 53 61  |ystem("*ScreenSa|
00008500  76 65 20 3c 41 55 41 52  61 79 24 44 69 72 3e 2e  |ve <AUARay$Dir>.|
00008510  73 63 72 73 68 6f 74 22  29 3b 0a 0a 2f 2a 20 63  |scrshot");../* c|
00008520  6c 6f 73 65 20 64 6f 77  6e 20 74 68 65 20 73 63  |lose down the sc|
00008530  72 65 65 6e 73 20 75 73  69 6e 67 20 61 6e 20 6f  |reens using an o|
00008540  75 72 6c 69 62 20 66 75  6e 63 74 69 6f 6e 20 2a  |urlib function *|
00008550  2f 0a 0a 6f 75 72 6c 69  62 5f 63 6c 6f 73 65 64  |/..ourlib_closed|
00008560  6f 77 6e 5f 73 63 72 65  65 6e 73 28 29 3b 0a 0a  |own_screens();..|
00008570  2f 2a 20 63 68 61 6e 67  65 20 74 6f 20 6d 6f 64  |/* change to mod|
00008580  65 20 31 35 20 61 6e 64  20 62 72 69 6e 67 20 62  |e 15 and bring b|
00008590  61 63 6b 20 74 68 65 20  63 75 72 73 6f 72 20 6a  |ack the cursor j|
000085a0  75 73 74 20 69 6e 20 63  61 73 65 20 2a 2f 0a 0a  |ust in case */..|
000085b0  6f 75 72 6c 69 62 5f 63  68 61 6e 67 65 6d 6f 64  |ourlib_changemod|
000085c0  65 28 31 35 29 3b 0a 6f  75 72 6c 69 62 5f 72 65  |e(15);.ourlib_re|
000085d0  76 69 76 65 63 75 72 73  6f 72 28 29 3b 0a 0a 2f  |vivecursor();../|
000085e0  2a 20 70 72 69 6e 74 20  74 68 65 20 63 61 6c 63  |* print the calc|
000085f0  75 6c 61 74 69 6f 6e 20  61 6e 64 20 6f 74 68 65  |ulation and othe|
00008600  72 20 69 6e 66 6f 2e 20  2a 2f 0a 70 72 69 6e 74  |r info. */.print|
00008610  66 28 22 2a 2a 2a 2a 2a  2a 2a 20 46 52 41 4d 45  |f("******* FRAME|
00008620  53 20 50 45 52 20 53 45  43 4f 4e 44 20 2a 2a 2a  |S PER SECOND ***|
00008630  2a 2a 2a 2a 2a 5c 6e 20  20 20 20 20 20 20 25 66  |*****\n       %f|
00008640  5c 6e 5c 6e 4e 6f 74 65  20 74 68 61 74 20 74 68  |\n\nNote that th|
00008650  69 73 20 70 72 6f 67 72  61 6d 20 73 68 6f 75 6c  |is program shoul|
00008660  64 20 62 65 20 73 6c 6f  77 20 65 76 65 6e 20 6f  |d be slow even o|
00008670  6e 20 61 20 52 49 53 43  20 50 43 2e 20 4e 65 78  |n a RISC PC. Nex|
00008680  74 20 6d 6f 6e 74 68 20  77 69 6c 6c 20 69 6e 63  |t month will inc|
00008690  6c 75 64 65 20 76 61 72  69 61 62 6c 65 20 73 63  |lude variable sc|
000086a0  72 65 65 6e 20 73 69 7a  65 73 20 73 6f 20 74 68  |reen sizes so th|
000086b0  65 20 70 72 6f 67 72 61  6d 20 69 73 20 61 20 6c  |e program is a l|
000086c0  6f 74 20 66 61 73 74 65  72 2e 20 44 6f 6e 27 74  |ot faster. Don't|
000086d0  20 70 61 6e 69 63 21 5c  6e 5c 6e 22 2c 28 66 6c  | panic!\n\n",(fl|
000086e0  6f 61 74 29 66 72 61 6d  65 73 2f 28 66 6c 6f 61  |oat)frames/(floa|
000086f0  74 29 28 28 74 69 6d 65  5f 66 69 6e 69 73 68 2d  |t)((time_finish-|
00008700  74 69 6d 65 5f 73 74 61  72 74 29 2f 31 30 30 29  |time_start)/100)|
00008710  29 3b 0a 7d 0a 0a                                 |);.}..|
00008716