Home » Archimedes archive » Acorn User » AU 1997-07 A.adf » Features » 3D/!AU_Attack/source/c/engine

3D/!AU_Attack/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-07 A.adf » Features
Filename: 3D/!AU_Attack/source/c/engine
Read OK:
File size: 927F 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 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 */

/* NEW use of ANGLES variables, they are now not defines but are inputted by the command line at the beginning of main()*/

int ANGLE_0,ANGLE_6,ANGLE_30,ANGLE_90,ANGLE_180,ANGLE_270,ANGLE_360;

int VERTICAL_SCALE;
int SCREEN_HEIGHT,SCREEN_WIDTH;
/*
#define ANGLE_0 0
#define ANGLE_6 30
#define ANGLE_30 160
#define ANGLE_90 480
#define ANGLE_270 1440
#define ANGLE_360 1920
#define ANGLE_180 960*/
/* GLOBAL variables */

char world[WORLD_HEIGHT+1][WORLD_WIDTH+1];/* This holds our text data file */
char objects[WORLD_HEIGHT+1][WORLD_WIDTH+1]; /* NEW object array (as world)*/
char walls[WALL_NUMBER+1][(WALL_WIDTH*WALL_HEIGHT)+1];
char objgraphics[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 20 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 */
     /* used to store scale values of each sliver*/
/* 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)(VERTICAL_SCALE/(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[5]; /* this is used to pass variables to a super fast sliver render */

int xtrans_dist, /* these NEW TRANSPARENT variables are used for windows */
    ytrans_dist, /* each one will be used later to draw transparent walls*/
    xtrans_col,
    ytrans_col,
    xtrans_type,
    ytrans_type,
    xtrans_done,/* these last two are used as flags to mark if a transpar-*/
    ytrans_done;/*ency has been found or not */

/* 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[2]=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=SCREEN_WIDTH-1; 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=xtrans_done=ytrans_done=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)
{
 /* or any (extra or different) tile value you wish */
if(x_hit_type==9 || x_hit_type==7){
  /*THEN THE WALL IS TRANSPARENT!!!*/
 xtrans_dist=((yi-(view_y<<16))>>8)*(inv_sin_table[view_angle]>>8);
 xtrans_type=x_hit_type;
 xtrans_col=((int)(yi>>16) & 0x003f);
 xtrans_done=FOUND_WALL;
/* we record all required details then continue */
                 }

else
{
/* 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;

}
}

{
/* 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)
{
if(y_hit_type==9 || y_hit_type==7){
  /*THEN THE WALL IS TRANSPARENT!!!*/
ytrans_dist=((xi-(view_x<<16))>>8)*(inv_cos_table[view_angle]>>8);
ytrans_type=y_hit_type;
ytrans_col=((int)(xi>>16) & 0x003f);
ytrans_done=FOUND_WALL;
}
/* we record all required details then continue */

else
{



/* 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;
}
}

{
/* 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[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[1]=&walls[x_hit_type][(yi_save & 0x003f)];

/* 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[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[1]=&walls[y_hit_type+1][(xi_save & 0x003f)];

/* 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! */

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

       }
/* it is here that we draw the overlaying transparent wall */
if(xtrans_done && xtrans_dist<dist_y)
{
  scale=(int)((cos_table[ray]>>16) * (recip_table[xtrans_dist>>16])>>16);
  variables[3]=scale-1;
  variables[4]=ray;
  variables[1]=&walls[xtrans_type][xtrans_col];

/* now call our special function which treats color 0 as a mask */

ourlib_sliver_mask(variables);

}
else if(ytrans_done && ytrans_dist<dist_x)
{
  scale=(int)((cos_table[ray]>>16) * (recip_table[ytrans_dist>>16])>>16);
  variables[3]=scale-1;
  variables[4]=ray;
  variables[1]=&walls[ytrans_type+1][ytrans_col];

/* now call our special function which treats color 0 as a mask */

ourlib_sliver_mask(variables);

}




/* 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 */
/* objects*/
}



/* 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! */

ourlib_killcursor(); /* get rid of cursor first */

for(wall_number=1,y=0;y<256/*SCREEN_HEIGHT*/;y+=WALL_HEIGHT)for(x=0;x<320/*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;
}

/* new stuff load in objects separately */
/* see above for comments (its identical) */
system("*ScreenLoad <AURay$Dir>.Objgraphic");
ourlib_killcursor();

for(wall_number=1,y=0;y<256/*SCREEN_HEIGHT*/;y+=WALL_HEIGHT)for(x=0;x<320/*SCREEN_WIDTH*/;x+=WALL_WIDTH,wall_number++)
{
ourlib_bitmap_grab(x,y,x+63,y+63,&objgraphics[wall_number][0],screen_address);
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';

/* this new line will (should!) convert letters into their appropriate number */

if(ch>16)ch-=6;

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);

/* new part to load in object data, see above for comments */

if(!(world_file=fopen("<AUARay$Dir>.objworld","r"))) exit(1);
for(row=0;row<WORLD_HEIGHT;row++)
{
  for(column=0;column<WORLD_WIDTH;column++)
  {
  while((ch=getc(world_file))==10){}
  if(ch==' ')ch=0;
  else ch=ch-'0';
  if(ch>16)ch-=6;
  objects[(WORLD_HEIGHT-1)-row][column]=ch;
  }
}
fclose(world_file);

}


/* NEWER MAIN function .

All changes are commented */

void main(int argc,char *argv[])
{
  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! */
      door_x,
      door_y;      /* These new variables will be used for door things */

/* NEW system of passing, we use the standard argc and argv to supply parameters to the engine. FIRST we must extract them:*/

/* check that correct number of parameters have been passed */

if(argc!=8)
{
/* quit if not */
printf("Error: Incorrect number of parameters passed. _Exiting\n"); exit(1);
/* "beep" (on most machines)*/ putchar('\a');
}
/* use atoi to get it right */
/* INPUT ALL VALUES FROM COMMAND LINE using ATOI and then work out needed*/
/* angle values for the ray casting engine. */
view_x=atoi(argv[1]);view_y=atoi(argv[2]);view_angle=atoi(argv[3]);
SCREEN_WIDTH=atoi(argv[4]);SCREEN_HEIGHT=atoi(argv[5]);
ANGLE_360=atoi(argv[6]);ANGLE_180=ANGLE_360/2;ANGLE_90=ANGLE_180/2;
ANGLE_6=(int)ANGLE_360/60;ANGLE_30=(int)ANGLE_90/3;ANGLE_0=0;
ANGLE_270=ANGLE_90*3;VERTICAL_SCALE=atoi(argv[7]);
/* DONE. Now continue as normal with the program */


/* 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();
/* NEW LOAD TITLE SCREEN */
system("*ScreenLoad <AUARay$Dir>.title");ourlib_killcursor();
ourlib_wait(200);
/*ourlib_screen_dissolve(screen_address,81920); USE IF WANTED */

/* THEN WAIT THEN SCREENDISSOLVE OUT, see above */

/* 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);
ourlib_killcursor();
/*os_clg();*/
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();
ourlib_slowclear(screen_address_bank,81920,0);
ourlib_killcursor();
/* 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.*/

ourlib_setup_background(208,45);

/* 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 */

/* NEW ADJUSTING LINES : we add an offset to both screen memory areas in order to centre the image in the middle of the screen no matter what size */

screen_address+=(320-SCREEN_WIDTH)>>1;
screen_address_bank+=(320-SCREEN_WIDTH)>>1;

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;

/* NEW OPTIMIZED VERSIONS OF MOVING THE PLAYER */

 x_cell = view_x>>6;
 y_cell = view_y>>6;

 x_sub_cell = view_x & 0x003f;
 y_sub_cell = view_y & 0x003f;

/* 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);
                }
 }



/* NEW DOOR code. A "probe" is sent out in front of the player, if a door tile is found near it then the block is destroyed. */

if(ourlib_keydown(98)==255)
{
/* Use similar techniques to above to find door */

dx=dx_table[view_angle];
dy=dy_table[view_angle];

/* Calculate door x and y, it is in normal maths */
 door_x= (int)((view_x<<16)+(dx<<3))>>16;
 door_y= (int)((view_y<<16)+(dy<<3))>>16;

/* NEW OPTIMIZED VERSIONS OF FINDIN DOORS */
/* now find the cell we are looking in with the standard equation */

 x_cell = (int)door_x>>6;
 y_cell = (int)door_y>>6;

/* Check if a doors is present */

if(world[y_cell][x_cell]==7 /* OR WHATEVER YOU LIKE */)
{
world[y_cell][x_cell]=0; /* or alternatively do what you like */
}
}




/* 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",(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 43  |wed */.#define C|
00000430  45 4c 4c 5f 58 5f 53 49  5a 45 20 36 34 20 2f 2a  |ELL_X_SIZE 64 /*|
00000440  20 74 68 69 73 20 69 73  20 74 68 65 20 73 69 7a  | this is the siz|
00000450  65 20 69 6e 20 75 6e 69  74 73 20 6f 66 20 65 61  |e in units of ea|
00000460  63 68 20 63 65 6c 6c 20  2a 2f 0a 23 64 65 66 69  |ch cell */.#defi|
00000470  6e 65 20 43 45 4c 4c 5f  59 5f 53 49 5a 45 20 36  |ne CELL_Y_SIZE 6|
00000480  34 20 2f 2a 20 74 68 69  73 20 69 73 20 74 68 65  |4 /* this is the|
00000490  20 73 69 7a 65 20 69 6e  20 75 6e 69 74 73 20 6f  | size in units o|
000004a0  66 20 65 61 63 68 20 63  65 6c 6c 20 2a 2f 0a 23  |f each cell */.#|
000004b0  64 65 66 69 6e 65 20 43  45 4c 4c 5f 58 5f 53 49  |define CELL_X_SI|
000004c0  5a 45 5f 46 50 20 36 20  2f 2a 20 74 68 69 73 20  |ZE_FP 6 /* this |
000004d0  69 73 20 75 73 65 64 20  69 6e 20 62 69 6e 61 72  |is used in binar|
000004e0  79 20 73 68 69 66 74 69  6e 67 20 2a 2f 0a 23 64  |y shifting */.#d|
000004f0  65 66 69 6e 65 20 43 45  4c 4c 5f 59 5f 53 49 5a  |efine CELL_Y_SIZ|
00000500  45 5f 46 50 20 36 20 2f  2a 20 74 68 69 73 20 69  |E_FP 6 /* this i|
00000510  73 20 75 73 65 64 20 69  6e 20 62 69 6e 61 72 79  |s used in binary|
00000520  20 73 68 69 66 74 69 6e  67 20 2a 2f 0a 23 64 65  | shifting */.#de|
00000530  66 69 6e 65 20 46 4f 55  4e 44 5f 57 41 4c 4c 20  |fine FOUND_WALL |
00000540  31 20 2f 2a 20 74 68 69  73 20 66 6c 61 67 20 69  |1 /* this flag i|
00000550  73 20 75 73 65 64 20 74  6f 20 69 6e 64 69 63 61  |s used to indica|
00000560  74 65 20 77 68 65 6e 20  61 6e 20 69 6e 74 65 72  |te when an inter|
00000570  73 65 63 74 69 6f 6e 20  68 61 73 20 62 65 20 66  |section has be f|
00000580  6f 75 6e 64 20 2a 2f 0a  23 64 65 66 69 6e 65 20  |ound */.#define |
00000590  4d 41 58 5f 44 49 53 54  41 4e 43 45 20 34 30 30  |MAX_DISTANCE 400|
000005a0  30 20 2f 2a 20 74 68 69  73 20 64 65 66 69 6e 65  |0 /* this define|
000005b0  73 20 74 68 65 20 6c 61  72 67 65 73 74 20 64 69  |s the largest di|
000005c0  73 74 61 6e 63 65 20 61  20 72 61 79 20 63 6f 75  |stance a ray cou|
000005d0  6c 64 20 74 72 61 76 65  6c 20 69 6e 20 74 68 65  |ld travel in the|
000005e0  20 77 6f 72 6c 64 2c 20  75 73 65 64 20 66 6f 72  | world, used for|
000005f0  20 6c 6f 6f 6b 20 75 70  20 74 61 62 6c 65 73 20  | look up tables |
00000600  2a 2f 0a 23 64 65 66 69  6e 65 20 53 54 45 50 5f  |*/.#define STEP_|
00000610  4c 45 4e 47 54 48 20 31  35 20 2f 2a 20 74 68 69  |LENGTH 15 /* thi|
00000620  73 20 6e 65 77 20 64 65  66 69 6e 65 20 68 6f 6c  |s new define hol|
00000630  64 73 20 68 6f 77 20 66  61 72 20 66 6f 72 77 61  |ds how far forwa|
00000640  72 64 20 61 6e 64 20 62  61 63 6b 77 61 72 64 73  |rd and backwards|
00000650  20 74 68 65 20 76 69 65  77 70 6f 69 6e 74 20 6d  | the viewpoint m|
00000660  6f 76 65 73 20 65 61 63  68 20 74 69 6d 65 20 2a  |oves each time *|
00000670  2f 0a 23 64 65 66 69 6e  65 20 43 4c 4f 53 45 53  |/.#define CLOSES|
00000680  54 20 35 30 20 2f 2a 20  74 68 69 73 20 73 74 6f  |T 50 /* this sto|
00000690  72 65 73 20 74 68 65 20  63 6c 6f 73 65 73 74 20  |res the closest |
000006a0  61 20 70 6c 61 79 65 72  20 63 61 6e 20 77 61 6c  |a player can wal|
000006b0  6b 20 69 6e 74 6f 20 61  20 77 61 6c 6c 20 2a 2f  |k into a wall */|
000006c0  0a 0a 2f 2a 20 4e 45 57  20 75 73 65 20 6f 66 20  |../* NEW use of |
000006d0  41 4e 47 4c 45 53 20 76  61 72 69 61 62 6c 65 73  |ANGLES variables|
000006e0  2c 20 74 68 65 79 20 61  72 65 20 6e 6f 77 20 6e  |, they are now n|
000006f0  6f 74 20 64 65 66 69 6e  65 73 20 62 75 74 20 61  |ot defines but a|
00000700  72 65 20 69 6e 70 75 74  74 65 64 20 62 79 20 74  |re inputted by t|
00000710  68 65 20 63 6f 6d 6d 61  6e 64 20 6c 69 6e 65 20  |he command line |
00000720  61 74 20 74 68 65 20 62  65 67 69 6e 6e 69 6e 67  |at the beginning|
00000730  20 6f 66 20 6d 61 69 6e  28 29 2a 2f 0a 0a 69 6e  | of main()*/..in|
00000740  74 20 41 4e 47 4c 45 5f  30 2c 41 4e 47 4c 45 5f  |t ANGLE_0,ANGLE_|
00000750  36 2c 41 4e 47 4c 45 5f  33 30 2c 41 4e 47 4c 45  |6,ANGLE_30,ANGLE|
00000760  5f 39 30 2c 41 4e 47 4c  45 5f 31 38 30 2c 41 4e  |_90,ANGLE_180,AN|
00000770  47 4c 45 5f 32 37 30 2c  41 4e 47 4c 45 5f 33 36  |GLE_270,ANGLE_36|
00000780  30 3b 0a 0a 69 6e 74 20  56 45 52 54 49 43 41 4c  |0;..int VERTICAL|
00000790  5f 53 43 41 4c 45 3b 0a  69 6e 74 20 53 43 52 45  |_SCALE;.int SCRE|
000007a0  45 4e 5f 48 45 49 47 48  54 2c 53 43 52 45 45 4e  |EN_HEIGHT,SCREEN|
000007b0  5f 57 49 44 54 48 3b 0a  2f 2a 0a 23 64 65 66 69  |_WIDTH;./*.#defi|
000007c0  6e 65 20 41 4e 47 4c 45  5f 30 20 30 0a 23 64 65  |ne ANGLE_0 0.#de|
000007d0  66 69 6e 65 20 41 4e 47  4c 45 5f 36 20 33 30 0a  |fine ANGLE_6 30.|
000007e0  23 64 65 66 69 6e 65 20  41 4e 47 4c 45 5f 33 30  |#define ANGLE_30|
000007f0  20 31 36 30 0a 23 64 65  66 69 6e 65 20 41 4e 47  | 160.#define ANG|
00000800  4c 45 5f 39 30 20 34 38  30 0a 23 64 65 66 69 6e  |LE_90 480.#defin|
00000810  65 20 41 4e 47 4c 45 5f  32 37 30 20 31 34 34 30  |e ANGLE_270 1440|
00000820  0a 23 64 65 66 69 6e 65  20 41 4e 47 4c 45 5f 33  |.#define ANGLE_3|
00000830  36 30 20 31 39 32 30 0a  23 64 65 66 69 6e 65 20  |60 1920.#define |
00000840  41 4e 47 4c 45 5f 31 38  30 20 39 36 30 2a 2f 0a  |ANGLE_180 960*/.|
00000850  2f 2a 20 47 4c 4f 42 41  4c 20 76 61 72 69 61 62  |/* GLOBAL variab|
00000860  6c 65 73 20 2a 2f 0a 0a  63 68 61 72 20 77 6f 72  |les */..char wor|
00000870  6c 64 5b 57 4f 52 4c 44  5f 48 45 49 47 48 54 2b  |ld[WORLD_HEIGHT+|
00000880  31 5d 5b 57 4f 52 4c 44  5f 57 49 44 54 48 2b 31  |1][WORLD_WIDTH+1|
00000890  5d 3b 2f 2a 20 54 68 69  73 20 68 6f 6c 64 73 20  |];/* This holds |
000008a0  6f 75 72 20 74 65 78 74  20 64 61 74 61 20 66 69  |our text data fi|
000008b0  6c 65 20 2a 2f 0a 63 68  61 72 20 6f 62 6a 65 63  |le */.char objec|
000008c0  74 73 5b 57 4f 52 4c 44  5f 48 45 49 47 48 54 2b  |ts[WORLD_HEIGHT+|
000008d0  31 5d 5b 57 4f 52 4c 44  5f 57 49 44 54 48 2b 31  |1][WORLD_WIDTH+1|
000008e0  5d 3b 20 2f 2a 20 4e 45  57 20 6f 62 6a 65 63 74  |]; /* NEW object|
000008f0  20 61 72 72 61 79 20 28  61 73 20 77 6f 72 6c 64  | array (as world|
00000900  29 2a 2f 0a 63 68 61 72  20 77 61 6c 6c 73 5b 57  |)*/.char walls[W|
00000910  41 4c 4c 5f 4e 55 4d 42  45 52 2b 31 5d 5b 28 57  |ALL_NUMBER+1][(W|
00000920  41 4c 4c 5f 57 49 44 54  48 2a 57 41 4c 4c 5f 48  |ALL_WIDTH*WALL_H|
00000930  45 49 47 48 54 29 2b 31  5d 3b 0a 63 68 61 72 20  |EIGHT)+1];.char |
00000940  6f 62 6a 67 72 61 70 68  69 63 73 5b 57 41 4c 4c  |objgraphics[WALL|
00000950  5f 4e 55 4d 42 45 52 2b  31 5d 5b 28 57 41 4c 4c  |_NUMBER+1][(WALL|
00000960  5f 57 49 44 54 48 2a 57  41 4c 4c 5f 48 45 49 47  |_WIDTH*WALL_HEIG|
00000970  48 54 29 2b 31 5d 3b 0a  2f 2a 20 54 68 69 73 20  |HT)+1];./* This |
00000980  68 6f 6c 64 73 20 74 68  65 20 77 61 6c 6c 20 67  |holds the wall g|
00000990  72 61 70 68 69 63 73 20  69 6e 20 61 20 74 77 6f  |raphics in a two|
000009a0  20 64 69 6d 65 6e 73 69  6f 6e 61 6c 20 61 72 72  | dimensional arr|
000009b0  61 79 20 2a 2f 0a 2f 2a  20 4e 6f 74 65 20 74 68  |ay */./* Note th|
000009c0  65 20 75 73 61 67 65 20  6f 66 20 63 68 61 72 20  |e usage of char |
000009d0  61 6e 64 20 6e 6f 74 20  22 69 6e 74 22 20 69 6e  |and not "int" in|
000009e0  20 62 6f 74 68 20 63 61  73 65 73 2e 20 54 68 69  | both cases. Thi|
000009f0  73 20 69 73 20 62 65 63  61 75 73 65 20 61 20 63  |s is because a c|
00000a00  68 61 72 20 69 73 20 38  20 62 79 74 65 73 2c 20  |har is 8 bytes, |
00000a10  77 68 69 63 68 20 67 69  76 65 73 20 32 35 36 20  |which gives 256 |
00000a20  63 6f 6c 6f 75 72 73 20  28 75 73 65 64 20 69 6e  |colours (used in|
00000a30  20 6f 75 72 20 4d 6f 64  65 20 31 33 20 73 63 72  | our Mode 13 scr|
00000a40  65 65 6e 29 20 61 6e 64  20 61 6c 73 6f 20 61 6e  |een) and also an|
00000a50  20 69 6e 74 65 67 65 72  20 75 70 20 74 6f 20 32  | integer up to 2|
00000a60  35 36 2c 20 77 68 65 6e  20 6f 75 72 20 74 65 78  |56, when our tex|
00000a70  74 20 66 69 6c 65 20 64  6f 65 73 6e 27 74 20 67  |t file doesn't g|
00000a80  6f 20 6f 76 65 72 20 32  30 20 69 6e 20 6e 75 6d  |o over 20 in num|
00000a90  62 65 72 21 20 48 65 6e  63 65 20 74 68 65 72 65  |ber! Hence there|
00000aa0  20 69 73 20 6e 6f 20 6e  65 65 64 20 66 6f 72 20  | is no need for |
00000ab0  61 6e 20 69 6e 74 20 61  72 72 61 79 20 69 6e 20  |an int array in |
00000ac0  65 69 74 68 65 72 20 63  61 73 65 2e 20 2a 2f 0a  |either case. */.|
00000ad0  0a 63 68 61 72 20 2a 73  63 72 65 65 6e 5f 61 64  |.char *screen_ad|
00000ae0  64 72 65 73 73 3b 20 2f  2a 20 74 68 69 73 20 77  |dress; /* this w|
00000af0  69 6c 6c 20 68 6f 6c 64  20 74 68 65 20 62 61 73  |ill hold the bas|
00000b00  65 20 6f 66 20 74 68 65  20 73 63 72 65 65 6e 20  |e of the screen |
00000b10  6d 65 6d 6f 72 79 20 77  68 69 63 68 20 77 65 20  |memory which we |
00000b20  77 69 6c 6c 20 6d 61 6e  69 70 75 6c 61 74 65 2e  |will manipulate.|
00000b30  20 42 79 20 61 6c 74 65  72 69 6e 67 20 76 61 6c  | By altering val|
00000b40  75 65 73 20 69 6e 20 74  68 65 20 73 63 72 65 65  |ues in the scree|
00000b50  6e 20 6d 65 6d 6f 72 79  2c 20 77 65 20 61 6c 74  |n memory, we alt|
00000b60  65 72 20 77 68 61 74 20  61 70 70 65 61 72 73 20  |er what appears |
00000b70  6f 6e 20 74 68 65 20 73  63 72 65 65 6e 2e 20 4e  |on the screen. N|
00000b80  6f 74 65 20 74 68 61 74  20 74 68 69 73 20 69 73  |ote that this is|
00000b90  20 6f 66 20 74 79 70 65  20 22 63 68 61 72 20 2a  | of type "char *|
00000ba0  22 20 62 65 63 61 75 73  65 20 69 74 20 68 6f 6c  |" because it hol|
00000bb0  64 73 20 74 68 65 20 6d  65 6d 6f 72 79 20 61 64  |ds the memory ad|
00000bc0  64 72 65 73 73 20 6f 66  20 61 20 62 79 74 65 20  |dress of a byte |
00000bd0  61 72 72 61 79 20 2d 20  74 68 65 20 32 35 36 20  |array - the 256 |
00000be0  63 6f 6c 6f 75 72 20 6d  6f 64 65 20 31 33 20 73  |colour mode 13 s|
00000bf0  63 72 65 65 6e 20 28 77  65 6c 6c 20 69 74 20 77  |creen (well it w|
00000c00  69 6c 6c 20 64 6f 21 29  20 2a 2f 0a 63 68 61 72  |ill do!) */.char|
00000c10  20 2a 73 63 72 65 65 6e  5f 61 64 64 72 65 73 73  | *screen_address|
00000c20  5f 62 61 6e 6b 3b 20 2f  2a 20 74 68 69 73 20 69  |_bank; /* this i|
00000c30  73 20 61 6e 6f 74 68 65  72 20 70 6f 69 6e 74 65  |s another pointe|
00000c40  72 20 74 6f 20 74 68 65  20 6f 74 68 65 72 20 61  |r to the other a|
00000c50  72 65 61 20 6f 66 20 73  63 72 65 65 6e 20 6d 65  |rea of screen me|
00000c60  6d 6f 72 79 20 77 68 69  63 68 20 77 65 20 77 69  |mory which we wi|
00000c70  6c 6c 20 62 65 20 75 73  69 6e 67 20 66 6f 72 20  |ll be using for |
00000c80  53 43 52 45 45 4e 20 42  41 4e 4b 49 4e 47 20 2d  |SCREEN BANKING -|
00000c90  20 61 76 6f 69 64 69 6e  67 20 66 6c 69 63 6b 65  | avoiding flicke|
00000ca0  72 69 6e 67 20 6f 66 20  74 68 65 20 73 63 72 65  |ring of the scre|
00000cb0  65 6e 20 64 75 72 69 6e  67 20 61 6e 69 6d 61 74  |en during animat|
00000cc0  69 6e 67 20 67 72 61 70  68 69 63 73 20 2a 2f 0a  |ing graphics */.|
00000cd0  63 68 61 72 20 2a 73 63  72 65 65 6e 5f 61 64 64  |char *screen_add|
00000ce0  72 65 73 73 5f 74 65 6d  70 3b 20 2f 2a 20 74 68  |ress_temp; /* th|
00000cf0  69 73 20 69 73 20 61 20  73 70 61 72 65 20 70 6f  |is is a spare po|
00000d00  69 6e 74 65 72 20 66 6f  72 20 75 73 65 20 64 75  |inter for use du|
00000d10  72 69 6e 67 20 74 68 65  20 73 77 69 74 63 68 69  |ring the switchi|
00000d20  6e 67 20 6f 66 20 74 68  65 20 74 77 6f 20 61 62  |ng of the two ab|
00000d30  6f 76 65 20 76 61 6c 75  65 73 20 2a 2f 0a 0a 2f  |ove values */../|
00000d40  2a 20 74 68 65 73 65 20  6e 65 77 20 46 49 58 45  |* these new FIXE|
00000d50  44 20 50 4f 49 4e 54 20  49 4e 54 45 47 45 52 20  |D POINT INTEGER |
00000d60  70 6f 69 6e 74 65 72 73  20 70 6f 69 6e 74 20 74  |pointers point t|
00000d70  6f 20 6c 6f 6f 6b 2d 75  70 20 74 61 62 6c 65 73  |o look-up tables|
00000d80  20 75 73 65 64 20 69 6e  20 74 68 65 20 72 61 79  | used in the ray|
00000d90  20 63 61 73 74 69 6e 67  20 65 6e 67 69 6e 65 2e  | casting engine.|
00000da0  20 54 68 65 73 65 20 61  72 65 20 65 78 70 6c 61  | These are expla|
00000db0  69 6e 65 64 20 6f 66 20  69 6e 20 74 68 65 20 65  |ined of in the e|
00000dc0  6e 67 69 6e 65 2c 20 62  75 74 20 74 68 65 20 6c  |ngine, but the l|
00000dd0  6f 6f 6b 2d 75 70 73 20  61 72 65 20 67 65 6e 65  |ook-ups are gene|
00000de0  72 61 74 65 64 20 69 6e  20 61 75 61 5f 74 61 62  |rated in aua_tab|
00000df0  6c 65 73 28 29 20 2a 2f  0a 0a 69 6e 74 20 2a 74  |les() */..int *t|
00000e00  61 6e 5f 74 61 62 6c 65  2c 2a 69 6e 76 5f 74 61  |an_table,*inv_ta|
00000e10  6e 5f 74 61 62 6c 65 3b  20 2f 2a 20 70 6f 69 6e  |n_table; /* poin|
00000e20  74 65 72 73 20 74 6f 20  74 61 6e 67 65 6e 74 20  |ters to tangent |
00000e30  6c 6f 6f 6b 5f 75 70 73  20 2a 2f 0a 69 6e 74 20  |look_ups */.int |
00000e40  2a 79 5f 73 74 65 70 2c  2a 78 5f 73 74 65 70 3b  |*y_step,*x_step;|
00000e50  20 20 20 20 20 20 20 20  20 20 20 2f 2a 20 70 6f  |           /* po|
00000e60  69 6e 74 65 72 73 20 74  6f 20 6d 6f 72 65 20 63  |inters to more c|
00000e70  6f 6d 70 6c 65 78 20 6c  6f 6f 6b 5f 75 70 73 20  |omplex look_ups |
00000e80  2a 2f 0a 69 6e 74 20 2a  69 6e 76 5f 63 6f 73 5f  |*/.int *inv_cos_|
00000e90  74 61 62 6c 65 2c 20 20  20 20 20 20 20 20 20 20  |table,          |
00000ea0  20 20 2f 2a 20 73 69 6e  2f 63 6f 73 20 74 61 62  |  /* sin/cos tab|
00000eb0  6c 65 73 20 28 6c 6f 6f  6b 5f 75 70 73 29 20 20  |les (look_ups)  |
00000ec0  20 20 2a 2f 0a 20 20 20  20 2a 69 6e 76 5f 73 69  |  */.    *inv_si|
00000ed0  6e 5f 74 61 62 6c 65 3b  0a 69 6e 74 20 2a 63 6f  |n_table;.int *co|
00000ee0  73 5f 74 61 62 6c 65 3b  20 20 20 20 20 20 20 20  |s_table;        |
00000ef0  20 20 20 20 20 20 20 20  2f 2a 20 63 6f 73 69 6e  |        /* cosin|
00000f00  61 6c 20 6c 6f 6f 6b 5f  75 70 20 74 61 62 6c 65  |al look_up table|
00000f10  20 20 20 20 2a 2f 0a 69  6e 74 20 2a 72 65 63 69  |    */.int *reci|
00000f20  70 5f 74 61 62 6c 65 3b  20 20 20 20 20 20 20 20  |p_table;        |
00000f30  20 20 20 20 20 20 2f 2a  20 72 65 63 69 70 72 6f  |      /* recipro|
00000f40  63 61 6c 20 74 61 62 6c  65 20 75 73 65 64 20 69  |cal table used i|
00000f50  6e 73 74 65 61 64 20 6f  66 20 61 20 64 69 76 69  |nstead of a divi|
00000f60  73 69 6f 6e 0a 2e 20 53  65 65 20 6c 61 74 65 72  |sion.. See later|
00000f70  20 2a 2f 0a 0a 69 6e 74  20 2a 64 78 5f 74 61 62  | */..int *dx_tab|
00000f80  6c 65 2c 20 20 20 20 20  20 20 20 20 20 20 20 20  |le,             |
00000f90  20 20 20 20 2f 2a 20 4e  45 57 20 46 49 58 45 44  |    /* NEW FIXED|
00000fa0  20 50 4f 49 4e 54 20 74  61 62 6c 65 73 20 66 6f  | POINT tables fo|
00000fb0  72 20 6d 6f 76 69 6e 67  20 74 68 65 20 2a 2f 0a  |r moving the */.|
00000fc0  20 20 20 20 2a 64 79 5f  74 61 62 6c 65 3b 20 20  |    *dy_table;  |
00000fd0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 2f  |               /|
00000fe0  2a 20 76 69 65 77 20 70  6f 69 6e 74 20 76 65 72  |* view point ver|
00000ff0  79 20 71 75 69 63 6b 6c  79 20 2a 2f 0a 20 20 20  |y quickly */.   |
00001000  20 20 2f 2a 20 75 73 65  64 20 74 6f 20 73 74 6f  |  /* used to sto|
00001010  72 65 20 73 63 61 6c 65  20 76 61 6c 75 65 73 20  |re scale values |
00001020  6f 66 20 65 61 63 68 20  73 6c 69 76 65 72 2a 2f  |of each sliver*/|
00001030  0a 2f 2a 20 46 55 4e 43  54 49 4f 4e 20 64 65 66  |./* FUNCTION def|
00001040  69 6e 69 74 69 6f 6e 73  20 2a 2f 0a 0a 2f 2a 20  |initions */../* |
00001050  74 68 69 73 20 66 75 6e  63 74 69 6f 6e 20 67 65  |this function ge|
00001060  6e 65 72 61 74 65 73 20  4c 4f 4f 4b 20 55 50 20  |nerates LOOK UP |
00001070  74 61 62 6c 65 73 20 2d  20 61 72 72 61 79 73 20  |tables - arrays |
00001080  68 6f 6c 64 69 6e 67 20  70 72 65 2d 63 61 6c 63  |holding pre-calc|
00001090  75 6c 61 74 65 64 20 74  72 69 67 6f 6e 6f 6d 65  |ulated trigonome|
000010a0  74 72 69 63 20 76 61 72  69 61 62 6c 65 73 20 75  |tric variables u|
000010b0  73 65 64 20 69 6e 20 74  68 65 20 72 61 79 20 63  |sed in the ray c|
000010c0  61 73 74 69 6e 67 20 70  72 6f 63 65 73 73 20 2a  |asting process *|
000010d0  2f 0a 0a 76 6f 69 64 20  61 75 61 5f 74 61 62 6c  |/..void aua_tabl|
000010e0  65 73 28 76 6f 69 64 29  0a 7b 0a 0a 69 6e 74 20  |es(void).{..int |
000010f0  61 6e 67 2c 20 2f 2a 20  74 68 69 73 20 69 73 20  |ang, /* this is |
00001100  75 73 65 64 20 74 6f 20  68 6f 6c 64 20 76 61 6c  |used to hold val|
00001110  75 65 73 20 77 68 69 6c  65 20 6d 61 6b 69 6e 67  |ues while making|
00001120  20 6c 6f 6f 6b 2d 75 70  73 20 2a 2f 0a 20 20 20  | look-ups */.   |
00001130  20 61 6e 67 74 3b 20 2f  2a 20 73 61 6d 65 20 2a  | angt; /* same *|
00001140  2f 0a 0a 66 6c 6f 61 74  20 72 61 64 5f 61 6e 67  |/..float rad_ang|
00001150  6c 65 3b 20 2f 2a 20 74  68 69 73 20 68 6f 6c 64  |le; /* this hold|
00001160  73 20 74 68 65 20 72 61  64 69 61 6e 73 20 65 71  |s the radians eq|
00001170  75 69 76 61 6c 65 6e 74  20 6f 66 20 74 68 65 20  |uivalent of the |
00001180  66 69 78 65 64 20 70 6f  69 6e 74 20 61 6e 67 6c  |fixed point angl|
00001190  65 20 73 79 73 74 65 6d  20 28 30 2d 31 39 32 30  |e system (0-1920|
000011a0  20 3d 20 30 2d 33 36 30  20 64 65 67 72 65 65 73  | = 0-360 degrees|
000011b0  20 3d 20 30 2d 36 2e 77  68 61 74 65 76 65 72 20  | = 0-6.whatever |
000011c0  72 61 64 69 61 6e 73 2e  20 4e 65 78 74 20 6d 6f  |radians. Next mo|
000011d0  6e 74 68 20 49 27 6c 6c  20 62 65 20 63 68 61 6e  |nth I'll be chan|
000011e0  67 69 6e 67 20 74 68 65  20 73 79 73 74 65 6d 20  |ging the system |
000011f0  73 6f 20 69 74 20 62 65  63 6f 6d 65 73 20 30 2d  |so it becomes 0-|
00001200  31 38 30 30 20 69 6e 73  74 65 61 64 20 6f 66 20  |1800 instead of |
00001210  31 39 32 30 2c 20 74 68  69 73 20 77 69 6c 6c 20  |1920, this will |
00001220  61 6c 6c 6f 77 20 61 20  73 6c 69 67 68 74 6c 79  |allow a slightly|
00001230  20 73 6d 61 6c 6c 65 72  20 73 63 72 65 65 6e 20  | smaller screen |
00001240  77 69 64 74 68 2c 20 6d  6f 72 65 20 6c 69 6b 65  |width, more like|
00001250  20 57 6f 6c 66 65 6e 73  74 65 69 6e 2c 20 74 68  | Wolfenstein, th|
00001260  69 73 20 77 69 6c 6c 20  6c 65 61 64 20 74 6f 20  |is will lead to |
00001270  61 6e 20 69 6e 63 72 65  61 73 65 20 69 6e 20 66  |an increase in f|
00001280  72 61 6d 65 20 72 61 74  65 2e 20 59 65 73 21 20  |rame rate. Yes! |
00001290  2a 2f 0a 0a 2f 2a 20 64  79 6e 61 6d 69 63 61 6c  |*/../* dynamical|
000012a0  6c 79 20 61 6c 6c 6f 63  61 74 65 64 20 61 64 65  |ly allocated ade|
000012b0  71 75 61 74 65 20 6d 65  6d 6f 72 79 20 66 6f 72  |quate memory for|
000012c0  20 74 68 65 20 6c 6f 6f  6b 2d 75 70 73 20 2a 2f  | the look-ups */|
000012d0  0a 74 61 6e 5f 74 61 62  6c 65 20 20 20 20 20 3d  |.tan_table     =|
000012e0  20 28 69 6e 74 20 2a 29  6d 61 6c 6c 6f 63 28 73  | (int *)malloc(s|
000012f0  69 7a 65 6f 66 28 69 6e  74 29 20 2a 20 28 41 4e  |izeof(int) * (AN|
00001300  47 4c 45 5f 33 36 30 2b  31 29 29 3b 0a 69 6e 76  |GLE_360+1));.inv|
00001310  5f 74 61 6e 5f 74 61 62  6c 65 20 3d 20 28 69 6e  |_tan_table = (in|
00001320  74 20 2a 29 6d 61 6c 6c  6f 63 28 73 69 7a 65 6f  |t *)malloc(sizeo|
00001330  66 28 69 6e 74 29 20 2a  20 28 41 4e 47 4c 45 5f  |f(int) * (ANGLE_|
00001340  33 36 30 2b 31 29 29 3b  0a 0a 79 5f 73 74 65 70  |360+1));..y_step|
00001350  20 20 20 20 20 20 20 20  3d 20 28 69 6e 74 20 2a  |        = (int *|
00001360  29 6d 61 6c 6c 6f 63 28  73 69 7a 65 6f 66 28 69  |)malloc(sizeof(i|
00001370  6e 74 29 20 2a 20 28 41  4e 47 4c 45 5f 33 36 30  |nt) * (ANGLE_360|
00001380  2b 31 29 29 3b 0a 78 5f  73 74 65 70 20 20 20 20  |+1));.x_step    |
00001390  20 20 20 20 3d 20 28 69  6e 74 20 20 2a 29 6d 61  |    = (int  *)ma|
000013a0  6c 6c 6f 63 28 73 69 7a  65 6f 66 28 69 6e 74 29  |lloc(sizeof(int)|
000013b0  20 2a 20 28 41 4e 47 4c  45 5f 33 36 30 2b 31 29  | * (ANGLE_360+1)|
000013c0  29 3b 0a 0a 63 6f 73 5f  74 61 62 6c 65 20 20 20  |);..cos_table   |
000013d0  20 20 3d 20 28 69 6e 74  20 20 2a 29 6d 61 6c 6c  |  = (int  *)mall|
000013e0  6f 63 28 73 69 7a 65 6f  66 28 69 6e 74 29 20 2a  |oc(sizeof(int) *|
000013f0  20 28 41 4e 47 4c 45 5f  33 36 30 2b 31 29 29 3b  | (ANGLE_360+1));|
00001400  0a 69 6e 76 5f 63 6f 73  5f 74 61 62 6c 65 20 3d  |.inv_cos_table =|
00001410  20 28 69 6e 74 20 20 2a  29 6d 61 6c 6c 6f 63 28  | (int  *)malloc(|
00001420  73 69 7a 65 6f 66 28 69  6e 74 29 20 2a 20 28 41  |sizeof(int) * (A|
00001430  4e 47 4c 45 5f 33 36 30  2b 31 29 29 3b 0a 69 6e  |NGLE_360+1));.in|
00001440  76 5f 73 69 6e 5f 74 61  62 6c 65 20 3d 20 28 69  |v_sin_table = (i|
00001450  6e 74 20 20 2a 29 6d 61  6c 6c 6f 63 28 73 69 7a  |nt  *)malloc(siz|
00001460  65 6f 66 28 69 6e 74 29  20 2a 20 28 41 4e 47 4c  |eof(int) * (ANGL|
00001470  45 5f 33 36 30 2b 31 29  29 3b 0a 2f 2a 20 6e 65  |E_360+1));./* ne|
00001480  77 20 74 61 62 6c 65 2c  20 66 6f 72 20 74 68 65  |w table, for the|
00001490  20 65 6e 67 69 6e 65 2c  20 74 6f 20 61 76 6f 69  | engine, to avoi|
000014a0  64 20 75 73 69 6e 67 20  61 20 64 69 76 69 64 65  |d using a divide|
000014b0  20 2a 2f 0a 72 65 63 69  70 5f 74 61 62 6c 65 20  | */.recip_table |
000014c0  20 20 3d 20 28 69 6e 74  20 20 2a 29 6d 61 6c 6c  |  = (int  *)mall|
000014d0  6f 63 28 73 69 7a 65 6f  66 28 69 6e 74 29 20 2a  |oc(sizeof(int) *|
000014e0  20 28 4d 41 58 5f 44 49  53 54 41 4e 43 45 2b 31  | (MAX_DISTANCE+1|
000014f0  29 29 3b 0a 2f 2a 20 6e  65 77 20 74 61 62 6c 65  |));./* new table|
00001500  73 20 66 6f 72 20 6d 6f  76 69 6e 67 20 74 68 65  |s for moving the|
00001510  20 76 69 65 77 20 70 6f  69 6e 74 20 2a 2f 0a 64  | view point */.d|
00001520  78 5f 74 61 62 6c 65 20  20 20 20 20 20 3d 20 28  |x_table      = (|
00001530  69 6e 74 20 20 2a 29 6d  61 6c 6c 6f 63 28 73 69  |int  *)malloc(si|
00001540  7a 65 6f 66 28 69 6e 74  29 20 2a 20 28 41 4e 47  |zeof(int) * (ANG|
00001550  4c 45 5f 33 36 30 2b 31  29 29 3b 0a 64 79 5f 74  |LE_360+1));.dy_t|
00001560  61 62 6c 65 20 20 20 20  20 20 3d 20 28 69 6e 74  |able      = (int|
00001570  20 20 2a 29 6d 61 6c 6c  6f 63 28 73 69 7a 65 6f  |  *)malloc(sizeo|
00001580  66 28 69 6e 74 29 20 2a  20 28 41 4e 47 4c 45 5f  |f(int) * (ANGLE_|
00001590  33 36 30 2b 31 29 29 3b  0a 2f 2a 20 67 65 6e 65  |360+1));./* gene|
000015a0  72 61 74 65 20 74 68 65  6d 2c 20 74 68 65 69 72  |rate them, their|
000015b0  20 75 73 65 20 69 73 20  65 78 70 6c 61 69 6e 65  | use is explaine|
000015c0  64 20 69 6e 20 74 68 65  20 72 61 79 20 63 61 73  |d in the ray cas|
000015d0  74 69 6e 67 20 65 6e 67  69 6e 65 20 2a 2f 0a 0a  |ting engine */..|
000015e0  66 6f 72 28 61 6e 67 74  3d 41 4e 47 4c 45 5f 30  |for(angt=ANGLE_0|
000015f0  3b 61 6e 67 74 3c 3d 41  4e 47 4c 45 5f 33 36 30  |;angt<=ANGLE_360|
00001600  3b 61 6e 67 74 2b 2b 29  0a 7b 0a 61 6e 67 3d 61  |;angt++).{.ang=a|
00001610  6e 67 74 3b 0a 2f 2a 20  74 68 69 73 20 6e 65 78  |ngt;./* this nex|
00001620  74 20 6c 69 6e 65 20 63  61 6c 63 75 6c 61 74 65  |t line calculate|
00001630  73 20 74 68 65 20 72 61  64 69 61 6e 20 61 6e 67  |s the radian ang|
00001640  6c 65 20 74 6f 20 70 61  73 73 20 74 6f 20 74 68  |le to pass to th|
00001650  65 20 74 72 69 67 2e 20  66 75 6e 63 74 69 6f 6e  |e trig. function|
00001660  73 20 2a 2f 0a 72 61 64  5f 61 6e 67 6c 65 3d 28  |s */.rad_angle=(|
00001670  66 6c 6f 61 74 29 28 28  33 2e 32 37 32 65 2d 34  |float)((3.272e-4|
00001680  29 20 2b 20 61 6e 67 20  2a 20 32 2a 33 2e 31 34  |) + ang * 2*3.14|
00001690  31 35 39 32 36 35 34 2f  41 4e 47 4c 45 5f 33 36  |1592654/ANGLE_36|
000016a0  30 29 3b 0a 0a 74 61 6e  5f 74 61 62 6c 65 5b 61  |0);..tan_table[a|
000016b0  6e 67 5d 3d 28 69 6e 74  29 28 74 61 6e 28 72 61  |ng]=(int)(tan(ra|
000016c0  64 5f 61 6e 67 6c 65 29  2a 36 35 35 33 36 29 3b  |d_angle)*65536);|
000016d0  0a 69 6e 76 5f 74 61 6e  5f 74 61 62 6c 65 5b 61  |.inv_tan_table[a|
000016e0  6e 67 5d 3d 28 69 6e 74  29 28 28 31 2f 74 61 6e  |ng]=(int)((1/tan|
000016f0  28 72 61 64 5f 61 6e 67  6c 65 29 29 2a 36 35 35  |(rad_angle))*655|
00001700  33 36 29 3b 0a 2f 2a 20  6e 6f 74 65 20 74 68 61  |36);./* note tha|
00001710  20 61 62 6f 76 65 20 63  6f 6e 76 65 72 73 69 6f  | above conversio|
00001720  6e 73 20 74 6f 20 66 69  78 65 64 20 70 6f 69 6e  |ns to fixed poin|
00001730  74 20 69 6e 74 65 67 65  72 73 20 2a 2f 0a 0a 2f  |t integers */../|
00001740  2a 20 77 65 20 64 6f 20  74 68 65 20 73 61 6d 65  |* we do the same|
00001750  20 66 6f 72 20 74 68 65  73 65 20 74 61 62 6c 65  | for these table|
00001760  73 2c 20 62 75 74 20 75  6e 66 6f 72 74 75 6e 61  |s, but unfortuna|
00001770  74 65 6c 79 20 61 74 20  74 68 65 20 61 73 79 6d  |tely at the asym|
00001780  70 74 6f 74 65 73 20 74  68 65 20 6e 75 6d 62 65  |ptotes the numbe|
00001790  72 73 20 62 65 63 6f 6d  65 20 61 77 6b 77 61 72  |rs become awkwar|
000017a0  64 6c 79 20 6c 61 72 67  65 20 74 6f 20 73 74 6f  |dly large to sto|
000017b0  72 65 20 69 6e 20 6f 75  72 20 66 69 78 65 64 20  |re in our fixed |
000017c0  70 6f 69 6e 74 20 72 65  70 72 65 73 65 6e 74 61  |point representa|
000017d0  74 69 6f 6e 2e 20 49 6e  73 74 65 61 64 20 6f 66  |tion. Instead of|
000017e0  20 6d 75 6c 74 69 70 6c  79 69 6e 67 20 62 79 20  | multiplying by |
000017f0  36 34 20 77 65 20 64 6f  20 38 2c 20 74 6f 20 6d  |64 we do 8, to m|
00001800  61 6b 65 20 73 75 72 65  20 74 68 61 74 20 6e 6f  |ake sure that no|
00001810  20 6f 76 65 72 66 6c 6f  77 20 63 61 6e 20 6f 63  | overflow can oc|
00001820  63 75 72 20 61 74 20 74  68 69 73 20 73 74 61 67  |cur at this stag|
00001830  65 2e 20 57 65 20 6f 6e  6c 79 20 6e 65 65 64 20  |e. We only need |
00001840  74 6f 20 6d 75 6c 74 69  70 6c 79 20 62 79 20 61  |to multiply by a|
00001850  6e 6f 74 68 65 72 20 38  20 6c 61 74 65 72 20 69  |nother 8 later i|
00001860  6e 20 74 68 65 20 65 6e  67 69 6e 65 2c 20 69 74  |n the engine, it|
00001870  73 20 6f 6b 61 79 20 2a  2f 0a 0a 69 66 28 61 6e  |s okay */..if(an|
00001880  67 3e 3d 41 4e 47 4c 45  5f 30 20 26 26 20 61 6e  |g>=ANGLE_0 && an|
00001890  67 3c 41 4e 47 4c 45 5f  31 38 30 29 0a 7b 0a 79  |g<ANGLE_180).{.y|
000018a0  5f 73 74 65 70 5b 61 6e  67 5d 3d 66 61 62 73 28  |_step[ang]=fabs(|
000018b0  20 28 38 29 20 2a 20 28  74 61 6e 5f 74 61 62 6c  | (8) * (tan_tabl|
000018c0  65 5b 61 6e 67 5d 29 20  29 3b 0a 7d 0a 65 6c 73  |e[ang]) );.}.els|
000018d0  65 0a 20 20 79 5f 73 74  65 70 5b 61 6e 67 5d 3d  |e.  y_step[ang]=|
000018e0  2d 66 61 62 73 28 20 28  38 29 20 2a 20 28 74 61  |-fabs( (8) * (ta|
000018f0  6e 5f 74 61 62 6c 65 5b  61 6e 67 5d 29 20 29 3b  |n_table[ang]) );|
00001900  0a 0a 69 66 28 61 6e 67  3e 3d 41 4e 47 4c 45 5f  |..if(ang>=ANGLE_|
00001910  39 30 20 26 26 20 61 6e  67 3c 41 4e 47 4c 45 5f  |90 && ang<ANGLE_|
00001920  32 37 30 29 0a 7b 0a 78  5f 73 74 65 70 5b 61 6e  |270).{.x_step[an|
00001930  67 5d 3d 2d 66 61 62 73  28 20 28 38 29 20 2a 20  |g]=-fabs( (8) * |
00001940  28 69 6e 76 5f 74 61 6e  5f 74 61 62 6c 65 5b 61  |(inv_tan_table[a|
00001950  6e 67 5d 29 20 29 3b 0a  7d 0a 65 6c 73 65 0a 7b  |ng]) );.}.else.{|
00001960  0a 78 5f 73 74 65 70 5b  61 6e 67 5d 3d 66 61 62  |.x_step[ang]=fab|
00001970  73 28 20 28 38 29 20 2a  20 28 69 6e 76 5f 74 61  |s( (8) * (inv_ta|
00001980  6e 5f 74 61 62 6c 65 5b  61 6e 67 5d 29 20 29 3b  |n_table[ang]) );|
00001990  0a 7d 0a 0a 2f 2a 20 63  6f 6e 76 65 72 73 69 6f  |.}../* conversio|
000019a0  6e 20 74 6f 20 66 69 78  65 64 20 70 6f 69 6e 74  |n to fixed point|
000019b0  20 2a 2f 0a 69 6e 76 5f  63 6f 73 5f 74 61 62 6c  | */.inv_cos_tabl|
000019c0  65 5b 61 6e 67 5d 3d 28  69 6e 74 29 28 28 31 2f  |e[ang]=(int)((1/|
000019d0  63 6f 73 28 72 61 64 5f  61 6e 67 6c 65 29 29 2a  |cos(rad_angle))*|
000019e0  36 35 35 33 36 29 3b 0a  69 6e 76 5f 73 69 6e 5f  |65536);.inv_sin_|
000019f0  74 61 62 6c 65 5b 61 6e  67 5d 3d 28 69 6e 74 29  |table[ang]=(int)|
00001a00  28 28 31 2f 73 69 6e 28  72 61 64 5f 61 6e 67 6c  |((1/sin(rad_angl|
00001a10  65 29 29 2a 36 35 35 33  36 29 3b 0a 0a 2f 2a 20  |e))*65536);../* |
00001a20  77 6f 72 6b 20 6f 75 74  20 74 61 62 6c 65 73 20  |work out tables |
00001a30  66 6f 72 20 6d 6f 76 69  6e 67 20 74 68 65 20 76  |for moving the v|
00001a40  69 65 77 70 6f 69 6e 74  20 2a 2f 0a 64 78 5f 74  |iewpoint */.dx_t|
00001a50  61 62 6c 65 5b 61 6e 67  5d 3d 28 69 6e 74 29 28  |able[ang]=(int)(|
00001a60  63 6f 73 28 36 2e 32 38  2a 61 6e 67 2f 41 4e 47  |cos(6.28*ang/ANG|
00001a70  4c 45 5f 33 36 30 29 2a  53 54 45 50 5f 4c 45 4e  |LE_360)*STEP_LEN|
00001a80  47 54 48 29 2a 36 35 35  33 36 3b 0a 64 79 5f 74  |GTH)*65536;.dy_t|
00001a90  61 62 6c 65 5b 61 6e 67  5d 3d 28 69 6e 74 29 28  |able[ang]=(int)(|
00001aa0  73 69 6e 28 36 2e 32 38  2a 61 6e 67 2f 41 4e 47  |sin(6.28*ang/ANG|
00001ab0  4c 45 5f 33 36 30 29 2a  53 54 45 50 5f 4c 45 4e  |LE_360)*STEP_LEN|
00001ac0  47 54 48 29 2a 36 35 35  33 36 3b 0a 7d 0a 0a 2f  |GTH)*65536;.}../|
00001ad0  2a 20 74 68 65 20 63 6f  73 69 6e 65 20 74 61 62  |* the cosine tab|
00001ae0  6c 65 20 69 73 20 75 73  65 64 20 74 6f 20 67 65  |le is used to ge|
00001af0  74 20 72 69 64 20 6f 66  20 74 68 65 20 22 66 69  |t rid of the "fi|
00001b00  73 68 20 62 6f 77 6c 20  65 66 66 65 63 74 22 2c  |sh bowl effect",|
00001b10  20 65 78 70 6c 61 69 6e  65 64 20 69 6e 20 74 68  | explained in th|
00001b20  65 20 72 61 79 20 63 61  73 74 65 72 2e 20 42 61  |e ray caster. Ba|
00001b30  73 69 63 61 6c 6c 79 20  77 65 20 77 6f 72 6b 20  |sically we work |
00001b40  6f 75 74 20 63 6f 73 69  6e 65 73 20 66 6f 72 20  |out cosines for |
00001b50  6f 75 72 20 6f 77 6e 20  73 70 61 6e 20 6f 66 20  |our own span of |
00001b60  76 69 73 69 6f 6e 2c 20  66 72 6f 6d 20 2d 33 30  |vision, from -30|
00001b70  20 64 65 67 72 65 65 73  20 74 6f 20 2b 33 30 20  | degrees to +30 |
00001b80  64 65 67 72 65 65 73 2e  20 54 68 69 73 20 6d 65  |degrees. This me|
00001b90  61 6e 73 20 74 68 61 74  20 61 73 20 77 65 20 73  |ans that as we s|
00001ba0  63 61 6e 20 66 72 6f 6d  20 6c 65 66 74 20 74 6f  |can from left to|
00001bb0  20 72 69 67 68 74 2c 20  6f 72 20 76 69 63 65 20  | right, or vice |
00001bc0  76 65 72 73 61 2c 20 6f  75 72 20 72 61 79 73 20  |versa, our rays |
00001bd0  6f 66 20 6c 69 67 68 74  20 61 72 65 20 61 63 74  |of light are act|
00001be0  75 61 6c 6c 79 20 63 61  73 74 20 6f 75 74 20 69  |ually cast out i|
00001bf0  6e 20 61 20 63 61 72 74  65 73 69 61 6e 2c 20 63  |n a cartesian, c|
00001c00  69 72 63 75 6c 61 72 20  77 61 79 2e 20 4f 75 72  |ircular way. Our|
00001c10  20 77 6f 72 6c 64 20 69  73 20 68 6f 77 65 76 65  | world is howeve|
00001c20  72 20 73 71 75 61 72 65  2c 20 70 6f 6c 61 72 2c  |r square, polar,|
00001c30  20 73 6f 20 77 65 20 68  61 76 65 20 74 6f 20 61  | so we have to a|
00001c40  63 6b 6e 6f 77 6c 65 64  67 65 20 74 68 65 20 64  |cknowledge the d|
00001c50  69 73 74 6f 72 74 69 6f  6e 20 63 61 75 73 65 64  |istortion caused|
00001c60  20 62 79 20 6d 69 78 69  6e 67 20 63 61 72 74 65  | by mixing carte|
00001c70  73 69 61 6e 20 61 6e 64  20 70 6f 6c 61 72 20 63  |sian and polar c|
00001c80  6f 6f 72 64 69 6e 61 74  65 73 2e 20 49 6e 20 74  |oordinates. In t|
00001c90  68 69 73 20 6c 6f 6f 6b  20 75 70 20 77 65 20 61  |his look up we a|
00001ca0  6c 73 6f 20 68 61 76 65  20 61 20 62 69 74 20 6f  |lso have a bit o|
00001cb0  66 20 73 63 61 6c 69 6e  67 20 69 6e 20 69 74 2c  |f scaling in it,|
00001cc0  20 79 65 74 20 6d 6f 72  65 20 74 69 6d 65 20 73  | yet more time s|
00001cd0  61 76 69 6e 67 20 21 21  21 20 2a 2f 0a 0a 66 6f  |aving !!! */..fo|
00001ce0  72 28 61 6e 67 3d 2d 41  4e 47 4c 45 5f 33 30 3b  |r(ang=-ANGLE_30;|
00001cf0  61 6e 67 3c 3d 41 4e 47  4c 45 5f 33 30 3b 61 6e  |ang<=ANGLE_30;an|
00001d00  67 2b 2b 29 0a 7b 0a 2f  2a 20 77 6f 72 6b 20 6f  |g++).{./* work o|
00001d10  75 74 20 72 61 64 69 61  6e 73 20 74 6f 20 70 61  |ut radians to pa|
00001d20  73 73 20 74 6f 20 63 6f  73 69 6e 65 20 66 75 6e  |ss to cosine fun|
00001d30  63 74 69 6f 6e 20 2a 2f  0a 72 61 64 5f 61 6e 67  |ction */.rad_ang|
00001d40  6c 65 3d 28 66 6c 6f 61  74 29 28 28 33 2e 32 37  |le=(float)((3.27|
00001d50  32 65 2d 34 29 2b 20 61  6e 67 20 2a 20 32 2a 33  |2e-4)+ ang * 2*3|
00001d60  2e 31 34 31 35 39 32 36  35 34 2f 41 4e 47 4c 45  |.141592654/ANGLE|
00001d70  5f 33 36 30 29 3b 0a 0a  2f 2a 66 69 78 65 64 20  |_360);../*fixed |
00001d80  70 6f 69 6e 74 20 63 6f  6e 76 65 72 73 69 6f 6e  |point conversion|
00001d90  20 2a 2f 0a 63 6f 73 5f  74 61 62 6c 65 5b 61 6e  | */.cos_table[an|
00001da0  67 2b 41 4e 47 4c 45 5f  33 30 5d 3d 28 69 6e 74  |g+ANGLE_30]=(int|
00001db0  29 28 56 45 52 54 49 43  41 4c 5f 53 43 41 4c 45  |)(VERTICAL_SCALE|
00001dc0  2f 28 63 6f 73 28 72 61  64 5f 61 6e 67 6c 65 29  |/(cos(rad_angle)|
00001dd0  29 2a 36 35 35 33 36 29  3b 0a 7d 0a 0a 2f 2a 20  |)*65536);.}../* |
00001de0  74 68 69 73 20 63 72 65  61 74 65 73 20 61 20 72  |this creates a r|
00001df0  65 63 69 70 72 6f 63 61  6c 20 74 61 62 6c 65 2c  |eciprocal table,|
00001e00  20 73 6f 20 77 65 20 64  6f 6e 27 74 20 68 61 76  | so we don't hav|
00001e10  65 20 74 6f 20 75 73 65  20 64 69 76 69 64 65 73  |e to use divides|
00001e20  2e 20 4d 75 6c 74 69 70  6c 79 69 6e 67 20 62 79  |. Multiplying by|
00001e30  20 74 68 65 20 72 65 63  69 70 72 6f 63 61 6c 20  | the reciprocal |
00001e40  6f 66 20 61 20 6e 75 6d  62 65 72 20 69 73 20 74  |of a number is t|
00001e50  68 65 20 73 61 6d 65 20  61 73 20 64 69 76 69 64  |he same as divid|
00001e60  69 6e 67 20 62 79 20 69  74 3a 20 41 66 74 65 72  |ing by it: After|
00001e70  20 61 6c 6c 2c 0a 0a 38  20 2f 20 34 20 3d 20 32  | all,..8 / 4 = 2|
00001e80  20 61 6e 64 20 38 20 2a  20 30 2e 32 35 20 28 31  | and 8 * 0.25 (1|
00001e90  20 6f 76 65 72 20 34 29  20 3d 20 32 20 2d 20 74  | over 4) = 2 - t|
00001ea0  68 65 79 20 70 72 6f 64  75 63 65 20 74 68 65 20  |hey produce the |
00001eb0  73 61 6d 65 20 72 65 73  75 6c 74 20 2a 2f 0a 0a  |same result */..|
00001ec0  66 6f 72 28 61 6e 67 3d  31 3b 61 6e 67 3c 4d 41  |for(ang=1;ang<MA|
00001ed0  58 5f 44 49 53 54 41 4e  43 45 3b 61 6e 67 2b 2b  |X_DISTANCE;ang++|
00001ee0  29 0a 7b 0a 20 20 2f 2a  20 69 74 20 69 73 20 73  |).{.  /* it is s|
00001ef0  74 69 6c 6c 20 66 69 78  65 64 20 70 6f 69 6e 74  |till fixed point|
00001f00  20 74 68 6f 75 67 68 20  2a 2f 0a 20 20 72 65 63  | though */.  rec|
00001f10  69 70 5f 74 61 62 6c 65  5b 61 6e 67 5d 3d 28 69  |ip_table[ang]=(i|
00001f20  6e 74 29 28 31 2e 30 2f  28 66 6c 6f 61 74 29 61  |nt)(1.0/(float)a|
00001f30  6e 67 2a 36 35 35 33 36  29 3b 0a 7d 0a 0a 7d 0a  |ng*65536);.}..}.|
00001f40  0a 2f 2a 20 74 68 69 73  20 66 75 6e 63 74 69 6f  |./* this functio|
00001f50  6e 20 69 73 20 74 68 65  20 68 65 61 72 74 20 6f  |n is the heart o|
00001f60  66 20 74 68 65 20 70 72  6f 67 72 61 6d 2c 20 74  |f the program, t|
00001f70  68 65 20 65 6e 67 69 6e  65 2c 20 74 6f 20 67 65  |he engine, to ge|
00001f80  6e 65 72 61 74 65 20 74  68 65 20 66 69 72 73 74  |nerate the first|
00001f90  20 70 65 72 73 6f 6e 20  76 69 65 77 20 2a 2f 0a  | person view */.|
00001fa0  76 6f 69 64 20 61 75 61  5f 72 61 79 63 61 73 74  |void aua_raycast|
00001fb0  65 72 28 69 6e 74 20 76  69 65 77 5f 78 2c 69 6e  |er(int view_x,in|
00001fc0  74 20 76 69 65 77 5f 79  2c 69 6e 74 20 76 69 65  |t view_y,int vie|
00001fd0  77 5f 61 6e 67 6c 65 29  0a 7b 0a 2f 2a 20 72 65  |w_angle).{./* re|
00001fe0  6d 65 6d 62 65 72 20 74  68 61 74 20 77 65 20 61  |member that we a|
00001ff0  72 65 20 74 68 69 6e 6b  69 6e 67 20 69 6e 20 32  |re thinking in 2|
00002000  2d 44 2c 20 6e 6f 74 20  69 6e 20 33 44 20 77 68  |-D, not in 3D wh|
00002010  65 6e 20 77 65 20 64 69  73 63 75 73 73 20 69 64  |en we discuss id|
00002020  65 61 73 2e 20 42 65 6c  6f 77 20 64 6f 65 73 20  |eas. Below does |
00002030  6e 6f 74 20 6d 65 61 6e  20 22 61 20 66 6c 6f 6f  |not mean "a floo|
00002040  72 20 62 65 6c 6f 77 22  2c 20 69 74 20 72 65 61  |r below", it rea|
00002050  6c 6c 79 20 6d 65 61 6e  73 20 22 62 65 68 69 6e  |lly means "behin|
00002060  64 22 2c 20 62 75 74 20  77 65 20 73 61 79 20 62  |d", but we say b|
00002070  65 6c 6f 77 20 62 65 63  61 75 73 65 20 77 65 20  |elow because we |
00002080  61 72 65 20 69 6d 61 67  69 6e 69 6e 67 20 6c 6f  |are imagining lo|
00002090  6f 6b 69 6e 67 20 64 6f  77 6e 20 6f 6e 20 74 68  |oking down on th|
000020a0  65 20 76 69 65 77 20 70  6f 69 6e 74 20 74 6f 20  |e view point to |
000020b0  66 6f 72 6d 20 61 20 32  2d 44 20 70 6c 61 6e 20  |form a 2-D plan |
000020c0  2a 2f 0a 0a 2f 2a 20 74  68 69 73 20 66 75 6e 63  |*/../* this func|
000020d0  74 69 6f 6e 2c 20 66 6f  72 20 65 61 63 68 20 63  |tion, for each c|
000020e0  6f 6c 75 6d 6e 20 6f 66  20 74 68 65 20 33 32 30  |olumn of the 320|
000020f0  20 70 69 78 65 6c 20 77  69 64 74 68 20 4d 6f 64  | pixel width Mod|
00002100  65 20 31 33 20 73 63 72  65 65 6e 2c 20 63 61 73  |e 13 screen, cas|
00002110  74 73 20 6f 75 74 20 74  77 6f 20 72 61 79 73 2e  |ts out two rays.|
00002120  20 4f 6e 65 20 72 61 79  20 6c 6f 6f 6b 73 20 66  | One ray looks f|
00002130  6f 72 20 58 2c 20 68 6f  72 69 7a 6f 6e 74 61 6c  |or X, horizontal|
00002140  20 69 6e 74 65 72 73 65  63 74 69 6f 6e 73 20 77  | intersections w|
00002150  69 74 68 20 77 61 6c 6c  73 2c 20 61 6e 64 20 74  |ith walls, and t|
00002160  68 65 20 6f 74 68 65 72  20 74 72 61 63 6b 73 20  |he other tracks |
00002170  69 6e 74 65 72 73 65 63  74 69 6f 6e 73 20 77 69  |intersections wi|
00002180  74 68 20 59 2c 20 76 65  72 74 69 63 61 6c 20 77  |th Y, vertical w|
00002190  61 6c 6c 20 62 6f 75 6e  64 61 72 69 65 73 2e 20  |all boundaries. |
000021a0  41 66 74 65 72 20 61 6c  6c 2c 20 74 68 65 20 6f  |After all, the o|
000021b0  6e 6c 79 20 74 69 6d 65  20 61 20 63 6f 6c 6c 69  |nly time a colli|
000021c0  73 69 6f 6e 20 63 6f 75  6c 64 20 6f 63 63 75 72  |sion could occur|
000021d0  20 69 73 20 6f 6e 20 61  20 62 6f 75 6e 64 61 72  | is on a boundar|
000021e0  79 20 6f 66 20 61 20 63  65 6c 6c 2c 20 61 73 20  |y of a cell, as |
000021f0  74 68 65 20 77 61 6c 6c  20 66 69 6c 6c 73 20 75  |the wall fills u|
00002200  70 20 74 68 65 20 65 6e  74 69 72 65 20 63 65 6c  |p the entire cel|
00002210  6c 2e 20 45 78 70 65 63  74 20 74 6f 20 73 65 65  |l. Expect to see|
00002220  20 6c 6f 74 73 20 6f 66  20 36 34 27 73 2c 20 74  | lots of 64's, t|
00002230  68 6f 75 67 68 20 72 65  6d 65 6d 62 65 72 20 74  |hough remember t|
00002240  68 61 74 20 74 68 69 73  20 72 61 79 20 63 61 73  |hat this ray cas|
00002250  74 65 72 20 69 73 20 76  65 72 79 20 72 6f 75 74  |ter is very rout|
00002260  69 6e 65 2c 20 61 6e 64  20 68 61 73 20 6e 6f 74  |ine, and has not|
00002270  20 61 74 20 61 6c 6c 20  62 65 65 6e 20 70 75 74  | at all been put|
00002280  20 74 68 72 6f 75 67 68  20 6d 79 20 22 62 6f 78  | through my "box|
00002290  20 6f 66 20 6d 61 67 69  63 22 2e 20 54 68 65 20  | of magic". The |
000022a0  65 6e 67 69 6e 65 20 77  69 6c 6c 20 62 65 63 6f  |engine will beco|
000022b0  6d 65 20 6d 75 63 68 20  6d 6f 72 65 20 70 65 72  |me much more per|
000022c0  73 6f 6e 61 6c 69 73 65  64 20 76 65 72 79 20 73  |sonalised very s|
000022d0  6f 6f 6e 21 20 2a 2f 0a  0a 0a 0a 69 6e 74 20 63  |oon! */....int c|
000022e0  65 6c 6c 5f 78 2c 20 2f  2a 20 75 73 65 64 20 74  |ell_x, /* used t|
000022f0  6f 20 73 74 6f 72 65 20  77 68 69 63 68 20 63 65  |o store which ce|
00002300  6c 6c 20 6f 66 20 74 68  65 20 77 61 6c 6c 73 20  |ll of the walls |
00002310  64 61 74 61 20 74 68 65  20 72 61 79 20 69 73 20  |data the ray is |
00002320  69 6e 20 2a 2f 0a 63 65  6c 6c 5f 79 2c 20 2f 2a  |in */.cell_y, /*|
00002330  20 22 20 2a 2f 0a 63 61  73 74 69 6e 67 3d 32 2c  | " */.casting=2,|
00002340  20 2f 2a 20 75 73 65 64  20 74 6f 20 73 74 6f 72  | /* used to stor|
00002350  65 20 69 66 20 72 61 79  20 63 61 73 74 69 6e 67  |e if ray casting|
00002360  20 68 61 73 20 66 69 6e  69 73 68 65 64 20 2a 2f  | has finished */|
00002370  0a 78 5f 68 69 74 5f 74  79 70 65 2c 20 2f 2a 20  |.x_hit_type, /* |
00002380  74 68 69 73 20 73 74 6f  72 65 73 20 74 68 65 20  |this stores the |
00002390  77 61 6c 6c 20 74 79 70  65 20 68 69 74 20 62 79  |wall type hit by|
000023a0  20 74 68 65 20 78 20 63  61 73 74 69 6e 67 20 72  | the x casting r|
000023b0  61 79 20 2a 2f 0a 79 5f  68 69 74 5f 74 79 70 65  |ay */.y_hit_type|
000023c0  2c 20 2f 2a 20 74 68 69  73 20 73 6f 74 72 65 73  |, /* this sotres|
000023d0  20 74 68 65 20 77 61 6c  6c 20 74 79 70 65 20 28  | the wall type (|
000023e0  6e 75 6d 62 65 72 29 20  68 69 74 20 62 79 20 74  |number) hit by t|
000023f0  68 65 20 79 20 72 61 79  20 2a 2f 0a 78 5f 62 6f  |he y ray */.x_bo|
00002400  75 6e 64 2c 20 2f 2a 20  74 68 69 73 20 68 6f 6c  |und, /* this hol|
00002410  64 73 20 74 68 65 20 6e  65 78 74 20 78 20 62 6f  |ds the next x bo|
00002420  75 6e 64 61 72 79 20 66  6f 72 20 61 20 70 6f 73  |undary for a pos|
00002430  73 69 62 6c 65 20 69 6e  74 65 72 73 65 63 74 69  |sible intersecti|
00002440  6f 6e 20 2a 2f 0a 79 5f  62 6f 75 6e 64 2c 20 2f  |on */.y_bound, /|
00002450  2a 20 74 68 69 73 20 68  6f 6c 64 73 20 74 68 65  |* this holds the|
00002460  20 6e 65 78 74 20 79 20  62 6f 75 6e 64 61 72 79  | next y boundary|
00002470  20 66 6f 72 20 61 20 70  6f 73 73 69 62 6c 65 20  | for a possible |
00002480  69 6e 74 65 72 73 65 63  74 69 6f 6e 20 2a 2f 0a  |intersection */.|
00002490  6e 65 78 74 5f 79 5f 63  65 6c 6c 2c 20 2f 2a 20  |next_y_cell, /* |
000024a0  74 68 69 73 20 69 73 20  75 73 65 64 20 74 6f 20  |this is used to |
000024b0  66 69 67 75 72 65 20 6f  75 74 20 74 68 65 20 71  |figure out the q|
000024c0  75 61 64 72 61 6e 74 20  6f 66 20 74 68 65 20 72  |uadrant of the r|
000024d0  61 79 20 28 2b 2f 2d 29  2a 2f 0a 6e 65 78 74 5f  |ay (+/-)*/.next_|
000024e0  78 5f 63 65 6c 6c 2c 20  2f 2a 20 22 20 2a 2f 0a  |x_cell, /* " */.|
000024f0  78 5f 64 65 6c 74 61 2c  20 2f 2a 20 74 68 69 73  |x_delta, /* this|
00002500  20 69 73 20 2b 27 64 20  74 6f 20 74 68 65 20 78  | is +'d to the x|
00002510  5f 62 6f 75 6e 64 20 76  61 72 2e 20 74 6f 20 6d  |_bound var. to m|
00002520  6f 76 65 20 74 6f 20 74  68 65 20 6e 65 78 74 20  |ove to the next |
00002530  62 6f 75 6e 64 61 72 79  20 2a 2f 0a 79 5f 64 65  |boundary */.y_de|
00002540  6c 74 61 2c 20 2f 2a 20  74 68 69 73 20 69 73 20  |lta, /* this is |
00002550  2b 27 64 20 74 6f 20 74  68 65 20 79 5f 62 6f 75  |+'d to the y_bou|
00002560  6e 64 20 76 61 72 2e 20  74 6f 20 6d 6f 76 65 20  |nd var. to move |
00002570  74 6f 20 74 68 65 20 6e  65 78 74 20 62 6f 75 6e  |to the next boun|
00002580  64 61 72 79 20 2a 2f 0a  78 69 5f 73 61 76 65 2c  |dary */.xi_save,|
00002590  20 2f 2a 20 74 68 69 73  20 73 74 6f 72 65 73 20  | /* this stores |
000025a0  77 68 65 72 65 20 74 68  65 20 78 20 63 61 73 74  |where the x cast|
000025b0  69 6e 67 20 72 61 79 20  6d 61 64 65 20 69 74 73  |ing ray made its|
000025c0  20 69 6e 74 65 72 73 65  63 74 69 6f 6e 20 2a 2f  | intersection */|
000025d0  0a 79 69 5f 73 61 76 65  2c 20 2f 2a 20 74 68 69  |.yi_save, /* thi|
000025e0  73 20 73 74 6f 72 65 73  20 77 68 65 72 65 20 74  |s stores where t|
000025f0  68 65 20 79 20 63 61 73  74 69 6e 67 20 72 61 79  |he y casting ray|
00002600  20 6d 61 64 65 20 69 74  73 20 69 6e 74 65 72 73  | made its inters|
00002610  65 63 74 69 6f 6e 20 2a  2f 0a 73 63 61 6c 65 2c  |ection */.scale,|
00002620  20 20 20 2f 2a 20 74 68  69 73 20 73 74 6f 72 65  |   /* this store|
00002630  73 20 74 68 65 20 73 63  61 6c 65 20 6f 66 20 74  |s the scale of t|
00002640  68 65 20 73 6c 69 76 65  72 20 74 6f 20 62 65 20  |he sliver to be |
00002650  64 72 61 77 6e 20 69 6e  20 65 61 63 68 20 63 6f  |drawn in each co|
00002660  6c 75 6d 6e 20 2a 2f 0a  72 61 79 2c 20 2f 2a 20  |lumn */.ray, /* |
00002670  74 68 69 73 20 73 74 6f  72 65 73 20 74 68 65 20  |this stores the |
00002680  72 61 79 20 6e 75 6d 62  65 72 20 62 65 69 6e 67  |ray number being|
00002690  20 63 61 73 74 20 6f 75  74 20 28 30 2d 33 32 30  | cast out (0-320|
000026a0  29 2a 2f 0a 78 72 61 79  2c 20 2f 2a 20 74 68 69  |)*/.xray, /* thi|
000026b0  73 20 66 6c 61 67 20 69  73 20 75 73 65 64 20 74  |s flag is used t|
000026c0  6f 20 73 68 6f 77 20 69  66 20 63 61 73 74 69 6e  |o show if castin|
000026d0  67 20 69 73 20 6f 76 65  72 20 2a 2f 0a 79 72 61  |g is over */.yra|
000026e0  79 2c 20 2f 2a 20 22 20  2a 2f 0a 64 69 73 74 5f  |y, /* " */.dist_|
000026f0  78 2c 20 2f 2a 20 74 68  69 73 20 68 6f 6c 64 73  |x, /* this holds|
00002700  20 74 68 65 20 64 69 73  74 61 6e 63 65 20 74 6f  | the distance to|
00002710  20 74 68 65 20 78 20 69  6e 74 65 72 73 65 63 74  | the x intersect|
00002720  69 6f 6e 20 2a 2f 0a 64  69 73 74 5f 79 3b 20 2f  |ion */.dist_y; /|
00002730  2a 20 74 68 69 73 20 68  6f 6c 64 73 20 74 68 65  |* this holds the|
00002740  20 64 69 73 74 61 6e 63  65 20 74 6f 20 74 68 65  | distance to the|
00002750  20 79 20 69 6e 74 65 72  73 65 63 74 69 6f 6e 20  | y intersection |
00002760  2a 2f 0a 0a 69 6e 74 20  78 69 2c 0a 20 20 20 20  |*/..int xi,.    |
00002770  20 20 79 69 2c 0a 20 20  20 20 20 20 78 61 64 64  |  yi,.      xadd|
00002780  2c 0a 20 20 20 20 20 20  79 61 64 64 3b 20 2f 2a  |,.      yadd; /*|
00002790  20 74 68 65 73 65 20 61  72 65 20 75 73 65 64 20  | these are used |
000027a0  74 6f 20 61 63 63 75 72  61 74 65 6c 79 20 74 72  |to accurately tr|
000027b0  61 63 65 20 61 6e 64 20  6d 6f 76 65 20 65 61 63  |ace and move eac|
000027c0  68 20 72 61 79 20 2a 2f  0a 0a 0a 69 6e 74 20 76  |h ray */...int v|
000027d0  61 72 69 61 62 6c 65 73  5b 35 5d 3b 20 2f 2a 20  |ariables[5]; /* |
000027e0  74 68 69 73 20 69 73 20  75 73 65 64 20 74 6f 20  |this is used to |
000027f0  70 61 73 73 20 76 61 72  69 61 62 6c 65 73 20 74  |pass variables t|
00002800  6f 20 61 20 73 75 70 65  72 20 66 61 73 74 20 73  |o a super fast s|
00002810  6c 69 76 65 72 20 72 65  6e 64 65 72 20 2a 2f 0a  |liver render */.|
00002820  0a 69 6e 74 20 78 74 72  61 6e 73 5f 64 69 73 74  |.int xtrans_dist|
00002830  2c 20 2f 2a 20 74 68 65  73 65 20 4e 45 57 20 54  |, /* these NEW T|
00002840  52 41 4e 53 50 41 52 45  4e 54 20 76 61 72 69 61  |RANSPARENT varia|
00002850  62 6c 65 73 20 61 72 65  20 75 73 65 64 20 66 6f  |bles are used fo|
00002860  72 20 77 69 6e 64 6f 77  73 20 2a 2f 0a 20 20 20  |r windows */.   |
00002870  20 79 74 72 61 6e 73 5f  64 69 73 74 2c 20 2f 2a  | ytrans_dist, /*|
00002880  20 65 61 63 68 20 6f 6e  65 20 77 69 6c 6c 20 62  | each one will b|
00002890  65 20 75 73 65 64 20 6c  61 74 65 72 20 74 6f 20  |e used later to |
000028a0  64 72 61 77 20 74 72 61  6e 73 70 61 72 65 6e 74  |draw transparent|
000028b0  20 77 61 6c 6c 73 2a 2f  0a 20 20 20 20 78 74 72  | walls*/.    xtr|
000028c0  61 6e 73 5f 63 6f 6c 2c  0a 20 20 20 20 79 74 72  |ans_col,.    ytr|
000028d0  61 6e 73 5f 63 6f 6c 2c  0a 20 20 20 20 78 74 72  |ans_col,.    xtr|
000028e0  61 6e 73 5f 74 79 70 65  2c 0a 20 20 20 20 79 74  |ans_type,.    yt|
000028f0  72 61 6e 73 5f 74 79 70  65 2c 0a 20 20 20 20 78  |rans_type,.    x|
00002900  74 72 61 6e 73 5f 64 6f  6e 65 2c 2f 2a 20 74 68  |trans_done,/* th|
00002910  65 73 65 20 6c 61 73 74  20 74 77 6f 20 61 72 65  |ese last two are|
00002920  20 75 73 65 64 20 61 73  20 66 6c 61 67 73 20 74  | used as flags t|
00002930  6f 20 6d 61 72 6b 20 69  66 20 61 20 74 72 61 6e  |o mark if a tran|
00002940  73 70 61 72 2d 2a 2f 0a  20 20 20 20 79 74 72 61  |spar-*/.    ytra|
00002950  6e 73 5f 64 6f 6e 65 3b  2f 2a 65 6e 63 79 20 68  |ns_done;/*ency h|
00002960  61 73 20 62 65 65 6e 20  66 6f 75 6e 64 20 6f 72  |as been found or|
00002970  20 6e 6f 74 20 2a 2f 0a  0a 2f 2a 20 66 69 72 73  | not */../* firs|
00002980  74 6c 79 2c 20 77 65 20  73 65 74 20 75 70 20 74  |tly, we set up t|
00002990  68 65 20 76 61 72 69 61  62 6c 65 73 5b 5d 20 77  |he variables[] w|
000029a0  65 20 61 6c 72 65 61 64  79 20 6b 6e 6f 77 2c 20  |e already know, |
000029b0  73 75 63 68 20 61 73 20  73 63 72 65 65 6e 5f 61  |such as screen_a|
000029c0  64 64 72 65 73 73 2c 20  77 61 6c 6c 73 20 61 6e  |ddress, walls an|
000029d0  64 20 74 68 65 20 73 63  72 65 65 6e 20 68 65 69  |d the screen hei|
000029e0  67 68 74 20 77 65 20 61  72 65 20 75 73 69 6e 67  |ght we are using|
000029f0  2e 20 54 68 65 73 65 20  61 72 65 20 61 6c 6c 20  |. These are all |
00002a00  74 68 69 6e 67 73 20 77  68 69 63 68 20 6f 75 72  |things which our|
00002a10  20 73 6c 69 76 65 72 20  72 65 6e 64 65 72 65 72  | sliver renderer|
00002a20  20 6e 65 65 64 73 20 74  6f 20 6b 6e 6f 77 20 74  | needs to know t|
00002a30  6f 20 70 6c 6f 74 20 69  74 73 20 63 6f 6c 75 6d  |o plot its colum|
00002a40  6e 20 2a 2f 0a 0a 76 61  72 69 61 62 6c 65 73 5b  |n */..variables[|
00002a50  30 5d 3d 28 63 68 61 72  20 2a 29 73 63 72 65 65  |0]=(char *)scree|
00002a60  6e 5f 61 64 64 72 65 73  73 3b 0a 76 61 72 69 61  |n_address;.varia|
00002a70  62 6c 65 73 5b 32 5d 3d  53 43 52 45 45 4e 5f 48  |bles[2]=SCREEN_H|
00002a80  45 49 47 48 54 3b 0a 0a  2f 2a 20 6e 6f 77 20 77  |EIGHT;../* now w|
00002a90  65 20 67 65 74 20 64 6f  77 6e 20 74 6f 20 74 68  |e get down to th|
00002aa0  65 20 6e 69 74 74 79 20  67 72 69 74 74 79 2e 20  |e nitty gritty. |
00002ab0  48 65 72 65 20 77 65 20  73 75 62 74 72 61 63 74  |Here we subtract|
00002ac0  20 33 30 20 64 65 67 72  65 65 73 20 66 72 6f 6d  | 30 degrees from|
00002ad0  20 74 68 65 20 76 69 65  77 69 6e 67 20 61 6e 67  | the viewing ang|
00002ae0  6c 65 20 72 65 6d 65 6d  62 65 72 20 74 68 61 74  |le remember that|
00002af0  20 6f 75 72 20 46 4f 56  20 69 73 20 36 30 20 64  | our FOV is 60 d|
00002b00  65 67 72 65 65 73 20 77  68 69 63 68 20 6d 65 61  |egrees which mea|
00002b10  6e 73 20 74 68 61 74 20  77 65 20 63 61 73 74 20  |ns that we cast |
00002b20  66 72 6f 6d 20 2d 33 30  20 74 6f 20 2b 33 30 20  |from -30 to +30 |
00002b30  2a 2f 0a 0a 69 66 20 28  20 28 76 69 65 77 5f 61  |*/..if ( (view_a|
00002b40  6e 67 6c 65 2d 3d 41 4e  47 4c 45 5f 33 30 29 20  |ngle-=ANGLE_30) |
00002b50  3c 20 30 29 0a 20 20 20  7b 0a 20 20 20 2f 2a 20  |< 0).   {.   /* |
00002b60  74 68 69 73 20 65 6e 73  75 72 65 73 20 74 68 61  |this ensures tha|
00002b70  74 20 77 65 20 64 6f 6e  27 74 20 67 6f 20 6f 76  |t we don't go ov|
00002b80  65 72 20 6f 72 20 75 6e  64 65 72 20 30 2f 33 36  |er or under 0/36|
00002b90  30 20 64 65 67 72 65 65  73 21 20 2a 2f 0a 20 20  |0 degrees! */.  |
00002ba0  20 76 69 65 77 5f 61 6e  67 6c 65 3d 41 4e 47 4c  | view_angle=ANGL|
00002bb0  45 5f 33 36 30 20 2b 20  76 69 65 77 5f 61 6e 67  |E_360 + view_ang|
00002bc0  6c 65 3b 0a 20 20 20 7d  0a 2f 2a 20 6e 6f 77 20  |le;.   }./* now |
00002bd0  77 65 20 73 74 61 72 74  20 74 68 65 20 6d 61 69  |we start the mai|
00002be0  6e 20 6c 6f 6f 70 2c 20  73 74 61 72 74 20 61 74  |n loop, start at|
00002bf0  20 74 68 65 20 72 69 67  68 74 20 6f 66 20 74 68  | the right of th|
00002c00  65 20 73 63 72 65 65 6e  20 28 33 31 39 29 2c 20  |e screen (319), |
00002c10  61 6e 64 20 63 61 73 74  20 65 61 63 68 20 63 6f  |and cast each co|
00002c20  6c 75 6d 6e 20 6f 6e 65  20 62 79 20 6f 6e 65 20  |lumn one by one |
00002c30  74 6f 20 74 68 65 20 6c  65 66 74 20 2a 2f 0a 0a  |to the left */..|
00002c40  66 6f 72 20 28 72 61 79  3d 53 43 52 45 45 4e 5f  |for (ray=SCREEN_|
00002c50  57 49 44 54 48 2d 31 3b  20 72 61 79 3e 3d 30 3b  |WIDTH-1; ray>=0;|
00002c60  20 72 61 79 2d 2d 29 0a  20 20 20 20 7b 0a 2f 2a  | ray--).    {./*|
00002c70  20 66 6f 72 20 65 61 63  68 20 72 61 79 20 74 6f  | for each ray to|
00002c80  20 62 65 20 63 61 73 74  20 77 65 20 61 63 74 75  | be cast we actu|
00002c90  61 6c 6c 79 20 63 61 73  74 20 6f 75 74 20 74 77  |ally cast out tw|
00002ca0  6f 20 72 61 79 73 20 3a  20 6f 6e 65 20 74 6f 20  |o rays : one to |
00002cb0  63 68 65 63 6b 20 66 6f  72 20 76 65 72 74 69 63  |check for vertic|
00002cc0  61 6c 20 62 6f 75 6e 64  61 72 79 20 63 6f 6c 6c  |al boundary coll|
00002cd0  69 73 69 6f 6e 73 20 61  6e 64 20 74 68 65 20 6f  |isions and the o|
00002ce0  74 68 65 72 20 74 6f 20  63 68 65 63 6b 20 66 6f  |ther to check fo|
00002cf0  72 20 68 6f 72 69 7a 6f  6e 74 61 6c 20 62 6f 75  |r horizontal bou|
00002d00  6e 64 61 72 79 20 63 6f  6c 6c 69 73 69 6f 6e 73  |ndary collisions|
00002d10  2e 20 43 6f 6e 73 69 64  65 72 69 6e 67 20 74 68  |. Considering th|
00002d20  61 74 20 77 61 6c 6c 73  20 66 69 6c 6c 20 75 70  |at walls fill up|
00002d30  20 65 61 63 68 20 63 65  6c 6c 2c 20 77 65 20 6e  | each cell, we n|
00002d40  65 65 64 20 6f 6e 6c 79  20 6c 6f 6f 6b 20 66 6f  |eed only look fo|
00002d50  72 20 69 6e 74 65 72 73  65 63 74 69 6f 6e 73 20  |r intersections |
00002d60  6f 6e 20 74 68 65 20 62  6f 75 6e 64 61 72 69 65  |on the boundarie|
00002d70  73 2e 20 57 65 20 68 61  76 65 20 74 6f 20 70 65  |s. We have to pe|
00002d80  72 66 6f 72 6d 20 73 65  70 65 72 61 74 65 20 63  |rform seperate c|
00002d90  61 73 74 20 62 65 63 61  75 73 65 20 6a 75 73 74  |ast because just|
00002da0  20 63 61 73 74 69 6e 67  20 6f 6e 65 20 72 61 79  | casting one ray|
00002db0  20 63 6f 6d 70 6c 69 63  61 74 65 73 20 74 68 65  | complicates the|
00002dc0  20 6d 61 74 74 65 72 20  61 6e 64 20 69 74 20 64  | matter and it d|
00002dd0  6f 65 73 6e 27 74 20 67  69 76 65 20 6d 75 63 68  |oesn't give much|
00002de0  20 73 70 65 65 64 20 69  6e 63 72 65 61 73 65 2c  | speed increase,|
00002df0  20 69 66 20 61 6e 79 2e  20 2a 2f 0a 0a 2f 2a 20  | if any. */../* |
00002e00  4e 45 57 20 4c 49 4e 45  20 3a 20 57 65 20 68 61  |NEW LINE : We ha|
00002e10  76 65 20 74 6f 20 63 68  65 63 6b 20 74 6f 20 73  |ve to check to s|
00002e20  65 65 20 69 66 20 74 68  65 20 76 69 65 77 69 6e  |ee if the viewin|
00002e30  67 20 61 6e 67 6c 65 20  69 73 20 61 74 20 74 68  |g angle is at th|
00002e40  65 20 61 73 79 6d 70 74  6f 74 65 73 2c 20 75 6e  |e asymptotes, un|
00002e50  66 6f 72 74 75 6e 61 74  65 6c 79 20 74 68 65 20  |fortunately the |
00002e60  66 69 78 65 64 20 70 6f  69 6e 74 20 73 79 73 74  |fixed point syst|
00002e70  65 6d 20 63 61 6e 6e 6f  74 20 73 74 6f 72 65 20  |em cannot store |
00002e80  74 68 65 20 76 61 6c 75  65 73 20 68 65 6c 64 20  |the values held |
00002e90  61 74 20 74 68 65 73 65  20 61 6e 67 6c 65 73 2c  |at these angles,|
00002ea0  20 73 6f 20 77 65 20 68  61 76 65 20 74 6f 20 61  | so we have to a|
00002eb0  76 6f 69 64 20 74 68 65  69 72 20 75 73 65 2e 20  |void their use. |
00002ec0  54 68 69 73 20 69 73 20  6e 6f 74 20 76 65 72 79  |This is not very|
00002ed0  20 65 6c 65 67 61 6e 74  20 49 20 6b 6e 6f 77 2c  | elegant I know,|
00002ee0  20 62 75 74 20 69 74 20  73 61 76 65 73 20 61 20  | but it saves a |
00002ef0  6c 6f 74 20 6f 66 20 68  65 61 64 20 61 63 68 65  |lot of head ache|
00002f00  73 20 61 6e 64 20 6e 6f  20 6f 6e 65 20 63 61 6e  |s and no one can|
00002f10  20 74 65 6c 6c 20 77 65  27 76 65 20 64 6f 6e 65  | tell we've done|
00002f20  20 69 74 21 20 2a 2f 0a  0a 69 66 28 76 69 65 77  | it! */..if(view|
00002f30  5f 61 6e 67 6c 65 3d 3d  41 4e 47 4c 45 5f 30 20  |_angle==ANGLE_0 |
00002f40  7c 7c 20 76 69 65 77 5f  61 6e 67 6c 65 3d 3d 41  ||| view_angle==A|
00002f50  4e 47 4c 45 5f 39 30 20  7c 7c 20 76 69 65 77 5f  |NGLE_90 || view_|
00002f60  61 6e 67 6c 65 20 3d 3d  41 4e 47 4c 45 5f 31 38  |angle ==ANGLE_18|
00002f70  30 20 7c 7c 20 76 69 65  77 5f 61 6e 67 6c 65 3d  |0 || view_angle=|
00002f80  3d 41 4e 47 4c 45 5f 32  37 30 29 76 69 65 77 5f  |=ANGLE_270)view_|
00002f90  61 6e 67 6c 65 2b 2b 3b  0a 2f 2a 20 53 45 43 54  |angle++;./* SECT|
00002fa0  49 4f 4e 20 31 20 3a 20  43 41 4c 43 55 4c 41 54  |ION 1 : CALCULAT|
00002fb0  49 4e 47 20 54 48 45 20  46 49 52 53 54 20 58 20  |ING THE FIRST X |
00002fc0  61 6e 64 20 59 20 49 4e  54 45 52 53 45 43 54 49  |and Y INTERSECTI|
00002fd0  4f 4e 53 2a 2f 0a 2f 2a  20 4f 6e 63 65 20 77 65  |ONS*/./* Once we|
00002fe0  20 68 61 76 65 20 64 6f  6e 65 20 74 68 69 73 20  | have done this |
00002ff0  74 68 65 20 66 6f 6c 6c  6f 77 69 6e 67 20 69 6e  |the following in|
00003000  74 65 72 73 65 63 74 69  6f 6e 73 20 61 72 65 20  |tersections are |
00003010  65 61 73 79 2a 2f 0a 0a  0a 2f 2a 20 54 68 65 20  |easy*/.../* The |
00003020  58 20 43 41 53 54 49 4e  47 20 52 41 59 20 3a 20  |X CASTING RAY : |
00003030  68 65 72 65 20 77 65 20  74 65 73 74 20 74 6f 20  |here we test to |
00003040  73 65 65 20 69 66 20 74  68 65 20 61 6e 67 6c 65  |see if the angle|
00003050  20 6f 66 20 74 68 65 20  72 61 79 20 69 73 20 66  | of the ray is f|
00003060  61 63 69 6e 67 20 75 70  77 61 72 64 73 2e 20 57  |acing upwards. W|
00003070  65 20 6e 65 65 64 20 74  6f 20 6b 6e 6f 77 20 77  |e need to know w|
00003080  68 69 63 68 20 68 61 6c  66 70 6c 61 6e 65 20 77  |hich halfplane w|
00003090  65 27 72 65 20 63 61 73  74 69 6e 67 20 66 72 6f  |e're casting fro|
000030a0  6d 20 72 65 6c 61 74 69  76 65 20 74 6f 20 74 68  |m relative to th|
000030b0  65 20 79 2d 61 78 69 73  2e 20 2a 2f 0a 0a 0a 20  |e y-axis. */... |
000030c0  69 66 20 28 76 69 65 77  5f 61 6e 67 6c 65 20 3e  |if (view_angle >|
000030d0  3d 20 41 4e 47 4c 45 5f  30 20 26 26 20 76 69 65  |= ANGLE_0 && vie|
000030e0  77 5f 61 6e 67 6c 65 20  3c 20 41 4e 47 4c 45 5f  |w_angle < ANGLE_|
000030f0  31 38 30 29 0a 20 20 20  20 20 20 20 7b 0a 2f 2a  |180).       {./*|
00003100  20 69 66 20 73 6f 20 74  68 65 6e 20 77 65 20 61  | if so then we a|
00003110  73 73 69 67 6e 20 76 61  72 69 61 62 6c 65 73 20  |ssign variables |
00003120  74 6f 20 74 68 61 74 20  65 66 66 65 63 74 2e 20  |to that effect. |
00003130  57 65 20 6d 75 73 74 20  63 6f 6d 70 75 74 65 20  |We must compute |
00003140  74 68 65 20 66 69 72 73  74 20 68 6f 72 69 7a 6f  |the first horizo|
00003150  6e 74 61 6c 20 6c 69 6e  65 20 74 68 61 74 20 63  |ntal line that c|
00003160  6f 75 6c 64 20 62 65 20  69 6e 74 65 72 73 65 63  |ould be intersec|
00003170  74 65 64 20 77 69 74 68  20 74 68 65 20 72 61 79  |ted with the ray|
00003180  2e 20 4e 6f 74 65 20 3a  20 69 74 20 77 69 6c 6c  |. Note : it will|
00003190  20 62 65 20 61 62 6f 76  65 20 74 68 65 20 76 69  | be above the vi|
000031a0  65 77 65 72 2e 2a 2f 0a  0a 79 5f 62 6f 75 6e 64  |ewer.*/..y_bound|
000031b0  20 3d 20 28 43 45 4c 4c  5f 59 5f 53 49 5a 45 20  | = (CELL_Y_SIZE |
000031c0  2b 20 28 76 69 65 77 5f  79 20 26 20 30 78 66 66  |+ (view_y & 0xff|
000031d0  63 30 29 29 3b 20 2f 2a  20 74 68 69 73 20 6c 69  |c0)); /* this li|
000031e0  6e 65 20 69 73 20 6d 65  72 65 6c 79 20 61 6e 20  |ne is merely an |
000031f0  6f 70 74 69 6d 69 7a 65  64 20 76 65 72 73 69 6f  |optimized versio|
00003200  6e 20 6f 66 20 43 45 4c  4c 5f 59 5f 53 49 5a 45  |n of CELL_Y_SIZE|
00003210  20 2b 20 28 76 69 65 77  5f 79 20 25 20 36 34 29  | + (view_y % 64)|
00003220  2e 20 49 20 75 73 65 20  69 74 20 6d 61 6e 79 20  |. I use it many |
00003230  74 69 6d 65 73 20 69 6e  20 74 68 69 73 20 65 6e  |times in this en|
00003240  67 69 6e 65 2e 20 2a 2f  0a 0a 79 5f 64 65 6c 74  |gine. */..y_delt|
00003250  61 20 3d 20 43 45 4c 4c  5f 59 5f 53 49 5a 45 3b  |a = CELL_Y_SIZE;|
00003260  20 2f 2a 20 74 68 69 73  20 6d 65 61 6e 73 20 74  | /* this means t|
00003270  68 61 74 20 66 6f 72 20  65 76 65 72 79 20 6d 6f  |hat for every mo|
00003280  76 65 6d 65 6e 74 20 6f  66 20 74 68 65 20 72 61  |vement of the ra|
00003290  79 2c 20 74 68 65 20 79  20 62 6f 75 6e 64 61 72  |y, the y boundar|
000032a0  79 20 6d 6f 76 65 73 20  75 70 20 6f 6e 65 20 63  |y moves up one c|
000032b0  65 6c 6c 2c 20 77 68 69  63 68 20 69 74 20 77 6f  |ell, which it wo|
000032c0  75 6c 64 2e 20 49 74 20  69 73 20 74 68 65 20 64  |uld. It is the d|
000032d0  65 6c 74 61 20 74 6f 20  67 65 74 20 74 6f 20 74  |elta to get to t|
000032e0  68 65 20 6e 65 78 74 20  68 6f 72 69 7a 6f 6e 74  |he next horizont|
000032f0  61 6c 20 6c 69 6e 65 20  2a 2f 0a 0a 2f 2a 20 6e  |al line */../* n|
00003300  65 78 74 20 77 65 20 75  73 65 20 74 68 65 20 69  |ext we use the i|
00003310  6e 76 65 72 73 65 20 74  61 6e 20 66 75 6e 63 74  |nverse tan funct|
00003320  69 6f 6e 20 74 6f 20 63  61 6c 63 75 6c 61 74 65  |ion to calculate|
00003330  20 74 68 65 20 69 6e 69  74 69 61 6c 20 70 6f 73  | the initial pos|
00003340  69 74 69 6f 6e 20 6f 66  20 74 68 65 20 78 20 62  |ition of the x b|
00003350  6f 75 6e 64 61 72 79 20  73 65 61 72 63 68 69 6e  |oundary searchin|
00003360  67 20 72 61 79 20 6f 6e  20 69 74 73 20 66 69 72  |g ray on its fir|
00003370  73 74 20 69 6e 74 65 72  73 65 63 74 69 6f 6e 2e  |st intersection.|
00003380  20 57 65 20 68 61 76 65  20 74 6f 20 75 73 65 20  | We have to use |
00003390  74 61 6e 20 62 65 63 61  75 73 65 20 69 74 20 69  |tan because it i|
000033a0  73 20 72 65 6c 61 74 65  64 20 74 6f 20 73 6c 6f  |s related to slo|
000033b0  70 65 73 20 2a 2f 0a 0a  2f 2a 20 4e 45 57 20 46  |pes */../* NEW F|
000033c0  49 58 45 44 20 50 4f 49  4e 54 20 43 41 4c 43 55  |IXED POINT CALCU|
000033d0  4c 41 54 49 4f 4e 20 6f  66 0a 78 69 20 3d 20 28  |LATION of.xi = (|
000033e0  66 6c 6f 61 74 29 28 69  6e 76 5f 74 61 6e 5f 74  |float)(inv_tan_t|
000033f0  61 62 6c 65 5b 76 69 65  77 5f 61 6e 67 6c 65 5d  |able[view_angle]|
00003400  20 2a 20 28 79 5f 62 6f  75 6e 64 20 2d 20 76 69  | * (y_bound - vi|
00003410  65 77 5f 79 29 29 20 2b  76 69 65 77 5f 78 3b 20  |ew_y)) +view_x; |
00003420  2a 2f 0a 0a 78 69 3d 28  28 79 5f 62 6f 75 6e 64  |*/..xi=((y_bound|
00003430  2d 76 69 65 77 5f 79 29  29 2a 28 69 6e 76 5f 74  |-view_y))*(inv_t|
00003440  61 6e 5f 74 61 62 6c 65  5b 76 69 65 77 5f 61 6e  |an_table[view_an|
00003450  67 6c 65 5d 29 3b 0a 78  69 2b 3d 28 76 69 65 77  |gle]);.xi+=(view|
00003460  5f 78 3c 3c 31 36 29 3b  0a 0a 2f 2a 20 74 68 69  |_x<<16);../* thi|
00003470  73 20 6d 65 61 6e 73 20  74 68 61 74 20 74 68 65  |s means that the|
00003480  20 71 75 61 64 72 61 6e  74 20 6f 66 20 74 68 65  | quadrant of the|
00003490  20 72 61 79 20 69 73 20  6e 6f 74 20 6e 65 67 61  | ray is not nega|
000034a0  74 69 76 65 2c 20 74 68  61 74 20 69 73 20 74 68  |tive, that is th|
000034b0  65 20 6e 65 78 74 20 79  20 62 6f 75 6e 64 61 72  |e next y boundar|
000034c0  79 20 77 69 6c 6c 20 61  70 70 65 61 72 20 61 62  |y will appear ab|
000034d0  6f 76 65 20 74 68 65 20  76 69 65 77 20 70 6f 69  |ove the view poi|
000034e0  6e 74 20 61 6e 64 20 6e  6f 74 20 62 65 6c 6f 77  |nt and not below|
000034f0  20 28 69 6e 20 74 65 72  6d 73 20 6f 66 20 6c 6f  | (in terms of lo|
00003500  6f 6b 69 6e 67 20 64 6f  77 6e 20 6f 6e 20 74 68  |oking down on th|
00003510  65 20 76 69 65 77 65 72  29 2e 20 54 68 69 73 20  |e viewer). This |
00003520  69 73 20 74 68 65 20 63  65 6c 6c 20 64 65 6c 74  |is the cell delt|
00003530  61 20 2a 2f 0a 6e 65 78  74 5f 79 5f 63 65 6c 6c  |a */.next_y_cell|
00003540  20 3d 20 30 3b 0a 0a 20  20 20 20 20 20 20 7d 0a  | = 0;..       }.|
00003550  2f 2a 20 69 66 20 74 68  65 20 76 69 65 77 69 6e  |/* if the viewin|
00003560  67 20 61 6e 67 6c 65 20  69 73 20 67 72 65 61 74  |g angle is great|
00003570  65 72 20 74 68 61 6e 20  31 38 30 20 64 65 67 72  |er than 180 degr|
00003580  65 65 73 20 61 6e 64 20  6c 65 73 73 20 74 68 61  |ees and less tha|
00003590  6e 20 32 37 30 20 64 65  67 72 65 65 73 20 74 68  |n 270 degrees th|
000035a0  65 6e 20 77 65 20 68 61  76 65 20 74 6f 20 64 6f  |en we have to do|
000035b0  20 6f 74 68 65 72 20 63  61 6c 63 75 6c 61 74 69  | other calculati|
000035c0  6f 6e 73 20 28 6c 6f 77  65 72 20 68 61 6c 66 20  |ons (lower half |
000035d0  70 6c 61 6e 65 29 20 2a  2f 0a 20 20 20 20 65 6c  |plane) */.    el|
000035e0  73 65 0a 20 20 20 20 20  20 20 7b 0a 2f 2a 20 77  |se.       {./* w|
000035f0  65 20 6b 6e 6f 77 20 74  68 61 74 20 62 65 63 61  |e know that beca|
00003600  75 73 65 20 74 68 65 20  76 69 65 77 69 6e 67 20  |use the viewing |
00003610  61 6e 67 6c 65 20 69 73  20 64 6f 77 6e 77 61 72  |angle is downwar|
00003620  64 73 2c 20 73 6f 20 74  68 65 6e 20 74 68 65 20  |ds, so then the |
00003630  68 6f 72 69 7a 6f 6e 74  61 6c 20 69 6e 74 65 72  |horizontal inter|
00003640  73 65 63 74 69 6f 6e 20  68 61 73 20 74 6f 20 62  |section has to b|
00003650  65 20 42 45 4c 4f 57 20  74 68 65 20 76 69 65 77  |e BELOW the view|
00003660  65 72 20 2a 2f 0a 79 5f  62 6f 75 6e 64 20 3d 20  |er */.y_bound = |
00003670  28 69 6e 74 29 28 76 69  65 77 5f 79 20 26 20 30  |(int)(view_y & 0|
00003680  78 66 66 63 30 29 3b 0a  0a 2f 2a 20 62 65 63 61  |xffc0);../* beca|
00003690  75 73 65 20 6f 66 20 74  68 69 73 20 77 65 20 61  |use of this we a|
000036a0  6c 73 6f 20 6b 6e 6f 77  20 74 68 61 74 20 74 68  |lso know that th|
000036b0  65 20 6e 65 78 74 20 59  20 69 6e 74 65 72 73 65  |e next Y interse|
000036c0  63 74 69 6f 6e 73 20 77  69 6c 6c 20 62 65 20 61  |ctions will be a|
000036d0  20 63 65 6c 6c 20 62 65  6c 6f 77 20 65 61 63 68  | cell below each|
000036e0  20 6f 74 68 65 72 2e 20  53 6f 20 74 68 65 20 64  | other. So the d|
000036f0  65 6c 74 61 20 66 6f 72  20 65 61 63 68 20 68 6f  |elta for each ho|
00003700  72 69 7a 6f 6e 74 61 6c  20 69 6e 74 65 72 73 65  |rizontal interse|
00003710  63 74 69 6f 6e 20 77 69  6c 6c 20 62 65 20 61 20  |ction will be a |
00003720  63 65 6c 6c 20 62 65 6c  6f 77 20 20 74 68 65 20  |cell below  the |
00003730  6c 61 73 74 20 2a 2f 0a  79 5f 64 65 6c 74 61 20  |last */.y_delta |
00003740  3d 20 2d 43 45 4c 4c 5f  59 5f 53 49 5a 45 3b 0a  |= -CELL_Y_SIZE;.|
00003750  0a 2f 2a 20 77 65 20 61  67 61 69 6e 20 75 73 65  |./* we again use|
00003760  20 74 68 65 20 74 61 6e  67 65 6e 74 20 66 75 6e  | the tangent fun|
00003770  63 74 69 6f 6e 2c 20 6a  75 73 74 20 61 73 20 62  |ction, just as b|
00003780  65 66 6f 72 65 2c 20 74  6f 20 63 61 6c 63 75 6c  |efore, to calcul|
00003790  61 74 65 20 74 68 65 20  66 69 72 73 74 20 78 20  |ate the first x |
000037a0  69 6e 74 65 72 73 65 63  74 69 6f 6e 20 77 69 74  |intersection wit|
000037b0  68 20 61 20 62 6f 75 6e  64 61 72 79 2e 20 2a 2f  |h a boundary. */|
000037c0  0a 0a 2f 2a 20 4e 45 57  20 46 49 58 45 44 20 50  |../* NEW FIXED P|
000037d0  4f 49 4e 54 2c 20 49 20  77 6f 6e 27 74 20 73 68  |OINT, I won't sh|
000037e0  6f 77 20 74 68 65 20 6f  6c 64 20 6c 69 6e 65 73  |ow the old lines|
000037f0  20 61 6e 79 20 6d 6f 72  65 20 2a 2f 0a 0a 78 69  | any more */..xi|
00003800  3d 28 28 79 5f 62 6f 75  6e 64 2d 76 69 65 77 5f  |=((y_bound-view_|
00003810  79 29 29 2a 28 69 6e 76  5f 74 61 6e 5f 74 61 62  |y))*(inv_tan_tab|
00003820  6c 65 5b 76 69 65 77 5f  61 6e 67 6c 65 5d 29 3b  |le[view_angle]);|
00003830  0a 78 69 2b 3d 28 76 69  65 77 5f 78 3c 3c 31 36  |.xi+=(view_x<<16|
00003840  29 3b 0a 0a 2f 2a 20 61  6e 64 20 77 65 20 6b 6e  |);../* and we kn|
00003850  6f 77 20 61 6c 73 6f 20  74 68 61 74 20 74 68 65  |ow also that the|
00003860  20 71 75 61 64 72 61 6e  74 20 69 73 20 62 65 6c  | quadrant is bel|
00003870  6f 77 20 74 68 65 20 70  6c 61 79 65 72 2c 20 73  |ow the player, s|
00003880  6f 20 74 68 65 20 63 65  6c 6c 20 79 20 64 65 6c  |o the cell y del|
00003890  74 61 20 77 69 6c 6c 20  62 65 20 6e 65 67 61 74  |ta will be negat|
000038a0  69 76 65 20 2a 2f 0a 0a  6e 65 78 74 5f 79 5f 63  |ive */..next_y_c|
000038b0  65 6c 6c 20 3d 20 2d 31  3b 0a 0a 20 20 20 20 20  |ell = -1;..     |
000038c0  20 20 7d 0a 2f 2a 20 59  20 52 41 59 20 3a 20 77  |  }./* Y RAY : w|
000038d0  65 20 64 6f 20 73 69 6d  69 6c 61 72 20 63 61 6c  |e do similar cal|
000038e0  63 75 6c 61 74 69 6f 6e  73 20 62 75 74 20 74 68  |culations but th|
000038f0  69 73 20 74 69 6d 65 20  74 6f 20 63 61 6c 63 75  |is time to calcu|
00003900  6c 61 74 65 20 74 68 65  20 66 69 72 73 74 20 79  |late the first y|
00003910  20 69 6e 74 65 72 73 65  63 74 69 6f 6e 73 20 2a  | intersections *|
00003920  2f 0a 0a 2f 2a 20 77 65  20 74 65 73 74 20 74 6f  |/../* we test to|
00003930  20 73 65 65 20 69 66 20  74 68 65 20 76 69 65 77  | see if the view|
00003940  20 61 6e 67 6c 65 20 69  73 20 77 69 74 68 69 6e  | angle is within|
00003950  20 74 68 65 20 76 65 72  74 69 63 61 6c 20 61 73  | the vertical as|
00003960  79 6d 70 74 6f 74 65 73  20 6f 66 20 33 36 30 20  |ymptotes of 360 |
00003970  64 65 67 72 65 65 73 2e  20 57 65 20 6e 65 65 64  |degrees. We need|
00003980  20 74 6f 20 6b 6e 6f 77  20 77 68 69 63 68 20 68  | to know which h|
00003990  61 6c 66 70 6c 61 6e 65  20 77 65 27 72 65 20 63  |alfplane we're c|
000039a0  61 73 74 69 6e 67 20 66  72 6f 6d 20 72 65 6c 61  |asting from rela|
000039b0  74 69 76 65 20 74 6f 20  74 68 65 20 78 2d 61 78  |tive to the x-ax|
000039c0  69 73 2e 20 2a 2f 0a 0a  69 66 20 28 76 69 65 77  |is. */..if (view|
000039d0  5f 61 6e 67 6c 65 20 3c  20 41 4e 47 4c 45 5f 39  |_angle < ANGLE_9|
000039e0  30 20 7c 7c 20 76 69 65  77 5f 61 6e 67 6c 65 20  |0 || view_angle |
000039f0  3e 3d 20 41 4e 47 4c 45  5f 32 37 30 29 0a 20 20  |>= ANGLE_270).  |
00003a00  20 20 20 20 20 7b 0a 2f  2a 20 77 65 20 63 61 6e  |     {./* we can|
00003a10  20 64 65 64 75 63 65 20  63 65 72 74 61 69 6e 20  | deduce certain |
00003a20  74 68 69 6e 67 73 2c 20  6a 75 73 74 20 61 73 20  |things, just as |
00003a30  77 69 74 68 20 74 68 65  20 78 20 72 61 79 2e 20  |with the x ray. |
00003a40  57 65 20 6b 6e 6f 77 20  74 68 61 74 20 62 65 63  |We know that bec|
00003a50  61 75 73 65 20 74 68 65  20 76 69 65 77 20 61 6e  |ause the view an|
00003a60  67 6c 65 20 69 73 20 74  6f 20 74 68 65 20 72 69  |gle is to the ri|
00003a70  67 68 74 2c 20 74 68 65  20 6e 65 78 74 20 58 20  |ght, the next X |
00003a80  62 6f 75 6e 64 61 72 79  20 28 77 68 69 63 68 20  |boundary (which |
00003a90  69 73 20 63 6f 6e 73 74  61 6e 74 29 20 77 69 6c  |is constant) wil|
00003aa0  6c 20 62 65 20 74 6f 20  74 68 65 20 52 49 47 48  |l be to the RIGH|
00003ab0  54 20 6f 66 20 74 68 65  20 76 69 65 77 65 72 2e  |T of the viewer.|
00003ac0  20 2a 2f 0a 78 5f 62 6f  75 6e 64 20 3d 20 28 69  | */.x_bound = (i|
00003ad0  6e 74 29 28 43 45 4c 4c  5f 58 5f 53 49 5a 45 20  |nt)(CELL_X_SIZE |
00003ae0  2b 20 28 76 69 65 77 5f  78 20 26 20 30 78 66 66  |+ (view_x & 0xff|
00003af0  63 30 29 29 3b 0a 0a 2f  2a 20 6e 6f 74 69 63 65  |c0));../* notice|
00003b00  20 74 68 69 73 20 72 65  63 75 72 72 69 6e 67 20  | this recurring |
00003b10  6f 70 74 69 6d 69 7a 61  74 69 6f 6e 20 6f 66 20  |optimization of |
00003b20  76 69 65 77 5f 78 20 25  20 36 34 20 2a 2f 0a 0a  |view_x % 64 */..|
00003b30  2f 2a 20 61 6e 64 20 77  65 20 61 6c 73 6f 20 6b  |/* and we also k|
00003b40  6e 6f 77 20 74 68 61 74  20 65 61 63 68 20 76 65  |now that each ve|
00003b50  72 74 69 63 61 6c 20 63  65 6c 6c 20 62 6f 75 6e  |rtical cell boun|
00003b60  64 61 72 79 20 61 66 74  65 72 20 74 68 65 20 66  |dary after the f|
00003b70  69 72 73 74 20 77 69 6c  6c 20 62 65 20 61 20 63  |irst will be a c|
00003b80  65 6c 6c 27 73 20 77 69  64 74 68 20 61 77 61 79  |ell's width away|
00003b90  20 2a 2f 0a 0a 78 5f 64  65 6c 74 61 20 3d 20 43  | */..x_delta = C|
00003ba0  45 4c 4c 5f 58 5f 53 49  5a 45 3b 0a 2f 2a 20 74  |ELL_X_SIZE;./* t|
00003bb0  68 69 73 20 74 69 6d 65  20 77 65 20 75 73 65 20  |his time we use |
00003bc0  74 68 65 20 74 61 6e 67  65 6e 74 20 66 75 6e 63  |the tangent func|
00003bd0  74 69 6f 6e 20 28 6e 6f  74 20 74 68 65 20 69 6e  |tion (not the in|
00003be0  76 65 72 73 65 20 74 61  6e 29 20 74 6f 20 63 61  |verse tan) to ca|
00003bf0  6c 63 75 6c 61 74 65 20  77 68 65 72 65 20 74 68  |lculate where th|
00003c00  65 20 66 69 72 73 74 20  79 20 62 6f 75 6e 64 61  |e first y bounda|
00003c10  72 79 20 69 6e 74 65 72  73 65 63 74 69 6f 6e 20  |ry intersection |
00003c20  77 69 6c 6c 20 6f 63 63  75 72 29 2e 20 2a 2f 0a  |will occur). */.|
00003c30  0a 2f 2a 20 4e 45 57 20  46 49 58 45 44 20 50 4f  |./* NEW FIXED PO|
00003c40  49 4e 54 20 2a 2f 0a 0a  79 69 3d 28 28 78 5f 62  |INT */..yi=((x_b|
00003c50  6f 75 6e 64 20 2d 20 76  69 65 77 5f 78 29 29 2a  |ound - view_x))*|
00003c60  28 74 61 6e 5f 74 61 62  6c 65 5b 76 69 65 77 5f  |(tan_table[view_|
00003c70  61 6e 67 6c 65 5d 29 3b  0a 79 69 2b 3d 28 76 69  |angle]);.yi+=(vi|
00003c80  65 77 5f 79 3c 3c 31 36  29 3b 0a 2f 2a 20 61 6e  |ew_y<<16);./* an|
00003c90  64 20 77 65 20 6b 6e 6f  77 20 61 6c 73 6f 20 74  |d we know also t|
00003ca0  68 61 74 20 62 65 63 61  75 73 65 20 74 68 65 20  |hat because the |
00003cb0  76 69 65 77 20 69 73 20  70 6f 73 69 74 69 76 65  |view is positive|
00003cc0  2c 20 74 68 65 20 6e 65  78 74 5f 78 5f 63 65 6c  |, the next_x_cel|
00003cd0  6c 20 64 65 6c 74 61 20  64 6f 65 73 20 6e 6f 74  |l delta does not|
00003ce0  20 6e 65 65 64 20 74 6f  20 62 65 20 6e 65 67 61  | need to be nega|
00003cf0  74 69 76 65 20 2a 2f 0a  0a 6e 65 78 74 5f 78 5f  |tive */..next_x_|
00003d00  63 65 6c 6c 20 3d 20 30  3b 0a 0a 20 20 20 20 20  |cell = 0;..     |
00003d10  20 20 7d 0a 2f 2a 20 6f  74 68 65 72 77 69 73 65  |  }./* otherwise|
00003d20  2c 20 69 66 20 74 68 65  20 76 69 65 77 69 6e 67  |, if the viewing|
00003d30  20 61 6e 67 6c 65 20 69  73 20 74 6f 77 61 72 64  | angle is toward|
00003d40  73 20 74 68 65 20 6f 74  68 65 72 20 64 69 72 65  |s the other dire|
00003d50  63 74 69 6f 6e 2e 2e 2e  2a 2f 0a 20 20 20 20 65  |ction...*/.    e|
00003d60  6c 73 65 0a 20 20 20 20  20 20 20 7b 0a 2f 2a 20  |lse.       {./* |
00003d70  77 65 20 6b 6e 6f 77 20  74 68 61 74 20 74 68 65  |we know that the|
00003d80  20 66 69 72 73 74 20 78  20 62 6f 75 6e 64 61 72  | first x boundar|
00003d90  79 20 63 61 6e 20 6f 63  63 75 72 20 6f 6e 6c 79  |y can occur only|
00003da0  20 74 6f 20 74 68 65 20  6c 65 66 74 20 6f 66 20  | to the left of |
00003db0  74 68 65 20 76 69 65 77  65 72 20 62 65 63 61 75  |the viewer becau|
00003dc0  73 65 20 74 68 65 20 72  61 79 20 61 6e 67 6c 65  |se the ray angle|
00003dd0  20 69 73 20 66 61 63 69  6e 67 20 6c 65 66 74 2e  | is facing left.|
00003de0  20 53 6f 20 77 65 20 63  61 6e 20 64 6f 20 76 69  | So we can do vi|
00003df0  65 77 5f 78 20 25 20 36  34 20 74 6f 20 63 61 6c  |ew_x % 64 to cal|
00003e00  63 75 6c 61 74 65 20 74  68 65 20 66 69 72 73 74  |culate the first|
00003e10  20 76 65 72 74 69 63 61  6c 20 62 6f 75 6e 64 61  | vertical bounda|
00003e20  72 79 2c 20 74 68 69 73  20 73 68 6f 75 6c 64 20  |ry, this should |
00003e30  62 65 20 62 65 63 6f 6d  69 6e 67 20 6f 62 76 69  |be becoming obvi|
00003e40  6f 75 73 20 2a 2f 0a 78  5f 62 6f 75 6e 64 20 3d  |ous */.x_bound =|
00003e50  20 28 69 6e 74 29 28 76  69 65 77 5f 78 20 26 20  | (int)(view_x & |
00003e60  30 78 66 66 63 30 29 3b  0a 0a 2f 2a 20 77 65 20  |0xffc0);../* we |
00003e70  61 6c 73 6f 20 6b 6e 6f  77 20 74 68 61 74 20 74  |also know that t|
00003e80  68 65 20 64 65 6c 74 61  20 66 6f 72 20 74 68 65  |he delta for the|
00003e90  20 63 65 6c 6c 20 77 69  6c 6c 20 62 65 20 74 6f  | cell will be to|
00003ea0  20 74 68 65 20 6c 65 66  74 2c 20 65 61 63 68 20  | the left, each |
00003eb0  74 69 6d 65 20 74 68 65  20 72 61 79 20 6d 6f 76  |time the ray mov|
00003ec0  65 73 20 74 6f 20 74 68  65 20 6e 65 78 74 20 62  |es to the next b|
00003ed0  6f 75 6e 64 61 72 79 20  74 68 65 20 6e 65 78 74  |oundary the next|
00003ee0  20 76 65 72 74 69 63 61  6c 20 69 6e 74 65 72 73  | vertical inters|
00003ef0  65 63 74 69 6f 6e 20 77  69 6c 6c 20 62 65 20 61  |ection will be a|
00003f00  20 63 65 6c 6c 20 74 6f  20 74 68 65 20 6c 65 66  | cell to the lef|
00003f10  74 20 74 68 61 6e 20 74  68 65 20 6c 61 73 74 2e  |t than the last.|
00003f20  20 2a 2f 0a 78 5f 64 65  6c 74 61 20 3d 20 2d 43  | */.x_delta = -C|
00003f30  45 4c 4c 5f 58 5f 53 49  5a 45 3b 0a 0a 2f 2a 20  |ELL_X_SIZE;../* |
00003f40  77 65 20 75 73 65 20 74  68 65 20 74 61 6e 67 65  |we use the tange|
00003f50  6e 74 61 6c 20 66 75 6e  63 74 69 6f 6e 20 61 67  |ntal function ag|
00003f60  61 69 6e 20 74 6f 20 63  61 6c 63 75 6c 61 74 65  |ain to calculate|
00003f70  20 74 68 65 20 70 6f 73  69 74 69 6f 6e 20 6f 6e  | the position on|
00003f80  20 74 68 65 20 68 6f 72  69 7a 6f 6e 74 61 6c 20  | the horizontal |
00003f90  69 6e 74 65 72 73 65 63  74 69 6f 6e 73 20 2a 2f  |intersections */|
00003fa0  0a 0a 2f 2a 20 4e 45 57  20 46 49 58 45 44 20 50  |../* NEW FIXED P|
00003fb0  4f 49 4e 54 20 2a 2f 0a  0a 79 69 3d 28 28 78 5f  |OINT */..yi=((x_|
00003fc0  62 6f 75 6e 64 20 2d 20  76 69 65 77 5f 78 29 29  |bound - view_x))|
00003fd0  2a 28 74 61 6e 5f 74 61  62 6c 65 5b 76 69 65 77  |*(tan_table[view|
00003fe0  5f 61 6e 67 6c 65 5d 29  3b 0a 79 69 2b 3d 28 76  |_angle]);.yi+=(v|
00003ff0  69 65 77 5f 79 3c 3c 31  36 29 3b 0a 2f 2a 20 61  |iew_y<<16);./* a|
00004000  6e 64 20 77 65 20 61 6c  73 6f 20 6b 6e 6f 77 20  |nd we also know |
00004010  74 68 61 74 20 74 68 65  20 78 20 63 65 6c 6c 20  |that the x cell |
00004020  76 61 6c 75 65 20 77 69  6c 6c 20 62 65 20 6d 69  |value will be mi|
00004030  6e 75 73 2c 20 62 65 63  61 75 73 65 20 61 73 20  |nus, because as |
00004040  74 68 65 20 72 61 79 20  6d 6f 76 65 73 20 74 6f  |the ray moves to|
00004050  20 61 6e 6f 74 68 65 72  20 63 65 6c 6c 2c 20 62  | another cell, b|
00004060  65 63 61 75 73 65 20 74  68 65 20 72 61 79 20 69  |ecause the ray i|
00004070  73 20 67 6f 69 6e 67 20  6c 65 66 74 2c 20 74 68  |s going left, th|
00004080  65 20 76 61 6c 75 65 20  6d 75 73 74 20 62 65 20  |e value must be |
00004090  6d 69 6e 75 73 2e 20 2a  2f 0a 6e 65 78 74 5f 78  |minus. */.next_x|
000040a0  5f 63 65 6c 6c 20 3d 20  2d 31 3b 0a 0a 20 20 20  |_cell = -1;..   |
000040b0  20 20 20 20 7d 0a 0a 2f  2a 20 4e 6f 77 20 77 65  |    }../* Now we|
000040c0  20 68 61 76 65 20 70 65  72 66 6f 72 6d 65 64 20  | have performed |
000040d0  74 68 65 20 73 6c 69 67  68 74 6c 79 20 74 72 69  |the slightly tri|
000040e0  63 6b 79 20 74 61 73 6b  20 6f 66 20 74 68 65 20  |cky task of the |
000040f0  66 69 72 73 74 20 69 6e  74 65 72 73 65 63 74 69  |first intersecti|
00004100  6f 6e 73 2c 20 77 65 20  63 61 6e 20 6d 6f 76 65  |ons, we can move|
00004110  20 6f 6e 20 74 6f 20 63  61 6c 63 75 6c 61 74 69  | on to calculati|
00004120  6e 67 20 74 68 65 20 6e  65 78 74 20 6f 6e 65 73  |ng the next ones|
00004130  2e 20 54 68 69 73 20 69  73 20 6d 6f 72 65 20 73  |. This is more s|
00004140  69 6d 70 6c 65 2c 20 61  73 20 77 65 20 6b 6e 6f  |imple, as we kno|
00004150  77 20 74 68 61 74 20 74  68 65 20 69 6e 74 65 72  |w that the inter|
00004160  73 65 63 74 69 6f 6e 73  20 63 61 6e 20 6f 6e 6c  |sections can onl|
00004170  79 20 6f 63 63 75 72 20  61 74 20 63 65 6c 6c 20  |y occur at cell |
00004180  62 6f 75 6e 64 61 72 69  65 73 2e 2a 2f 0a 0a 2f  |boundaries.*/../|
00004190  2a 20 53 45 43 54 49 4f  4e 20 32 20 3a 20 54 65  |* SECTION 2 : Te|
000041a0  73 74 69 6e 67 20 66 6f  72 20 66 75 72 74 68 65  |sting for furthe|
000041b0  72 20 69 6e 74 65 72 73  65 63 74 69 6f 6e 73 20  |r intersections |
000041c0  2a 2f 0a 0a 2f 2a 20 74  68 65 73 65 20 66 6c 61  |*/../* these fla|
000041d0  67 73 20 73 74 6f 72 65  20 69 66 20 63 61 73 74  |gs store if cast|
000041e0  69 6e 67 20 6f 66 20 62  6f 74 68 20 72 61 79 73  |ing of both rays|
000041f0  20 69 73 20 63 6f 6d 70  6c 65 74 65 20 2a 2f 0a  | is complete */.|
00004200  78 72 61 79 3d 79 72 61  79 3d 78 74 72 61 6e 73  |xray=yray=xtrans|
00004210  5f 64 6f 6e 65 3d 79 74  72 61 6e 73 5f 64 6f 6e  |_done=ytrans_don|
00004220  65 3d 30 3b 0a 0a 2f 2a  20 58 20 52 61 79 20 69  |e=0;../* X Ray i|
00004230  73 20 66 69 72 73 74 20  2a 2f 0a 2f 2a 20 62 65  |s first */./* be|
00004240  63 61 75 73 65 20 77 65  20 61 72 65 20 74 65 73  |cause we are tes|
00004250  74 69 6e 67 20 66 6f 72  20 65 61 63 68 20 6e 65  |ting for each ne|
00004260  78 74 20 69 6e 74 65 72  73 65 63 74 69 6f 6e 2c  |xt intersection,|
00004270  20 77 65 20 63 61 6e 20  66 69 67 75 72 65 20 6f  | we can figure o|
00004280  75 74 20 6d 6f 72 65 20  65 61 73 69 6c 79 20 74  |ut more easily t|
00004290  68 65 20 66 6f 6c 6c 6f  77 69 6e 67 20 69 6e 74  |he following int|
000042a0  65 72 73 65 63 74 69 6f  6e 73 2e 20 2a 2f 0a 2f  |ersections. */./|
000042b0  2a 20 74 68 69 73 20 69  73 20 61 20 6c 6f 6f 6b  |* this is a look|
000042c0  20 75 70 20 74 61 62 6c  65 20 68 6f 6c 64 69 6e  | up table holdin|
000042d0  67 20 74 68 65 20 6e 65  78 74 20 79 20 69 6e 74  |g the next y int|
000042e0  65 72 63 65 70 74 73 2c  20 62 61 73 65 64 20 6f  |ercepts, based o|
000042f0  6e 20 74 68 65 20 74 61  6e 67 65 6e 74 61 6c 20  |n the tangental |
00004300  66 75 6e 63 74 69 6f 6e  20 61 6e 64 20 74 68 65  |function and the|
00004310  20 73 69 7a 65 20 6f 66  20 63 65 6c 6c 73 2e 20  | size of cells. |
00004320  42 61 73 69 63 61 6c 6c  79 20 77 65 20 61 64 64  |Basically we add|
00004330  20 74 68 69 73 20 74 6f  20 74 68 65 20 72 61 79  | this to the ray|
00004340  20 65 61 63 68 20 74 69  6d 65 20 77 65 20 6d 6f  | each time we mo|
00004350  76 65 20 69 74 20 61 20  62 69 74 20 6d 6f 72 65  |ve it a bit more|
00004360  2c 20 73 65 61 72 63 68  69 6e 67 20 66 6f 72 20  |, searching for |
00004370  61 20 77 61 6c 6c 20 61  74 20 61 20 63 65 6c 6c  |a wall at a cell|
00004380  20 62 6f 75 6e 64 61 72  79 20 2a 2f 0a 0a 2f 2a  | boundary */../*|
00004390  20 4e 45 57 20 46 49 58  45 44 20 50 4f 49 4e 54  | NEW FIXED POINT|
000043a0  2c 20 6e 6f 74 65 20 74  68 65 20 73 68 69 66 74  |, note the shift|
000043b0  20 33 20 74 69 6d 65 73  20 74 6f 20 74 68 65 20  | 3 times to the |
000043c0  6c 65 66 74 2c 20 74 68  65 20 65 71 75 69 76 61  |left, the equiva|
000043d0  6c 65 6e 74 20 6f 66 20  61 20 6d 75 6c 74 69 70  |lent of a multip|
000043e0  6c 79 20 62 79 20 38 2c  20 74 68 69 73 20 74 61  |ly by 8, this ta|
000043f0  6b 65 73 20 6e 6f 20 74  69 6d 65 2c 20 61 6e 64  |kes no time, and|
00004400  20 72 65 61 6c 6c 79 20  49 20 64 6f 6e 27 74 20  | really I don't |
00004410  6b 6e 6f 77 20 77 68 79  20 49 27 76 65 20 64 6f  |know why I've do|
00004420  6e 65 20 69 74 20 6c 69  6b 65 20 74 68 69 73 21  |ne it like this!|
00004430  20 49 74 20 77 6f 72 6b  73 2e 20 2a 2f 0a 0a 78  | It works. */..x|
00004440  61 64 64 3d 79 5f 73 74  65 70 5b 76 69 65 77 5f  |add=y_step[view_|
00004450  61 6e 67 6c 65 5d 3c 3c  33 3b 0a 0a 2f 2a 20 73  |angle]<<3;../* s|
00004460  74 61 72 74 20 63 61 73  74 69 6e 67 20 74 68 65  |tart casting the|
00004470  20 78 20 72 61 79 20 2a  2f 0a 77 68 69 6c 65 28  | x ray */.while(|
00004480  21 78 72 61 79 29 0a 7b  0a 2f 2a 20 63 6f 6d 70  |!xray).{./* comp|
00004490  75 74 65 20 63 75 72 72  65 6e 74 20 63 65 6c 6c  |ute current cell|
000044a0  20 70 6f 73 69 74 69 6f  6e 20 6f 66 20 74 68 65  | position of the|
000044b0  20 72 61 79 20 74 6f 20  69 6e 73 70 65 63 74 2a  | ray to inspect*|
000044c0  2f 0a 0a 63 65 6c 6c 5f  78 20 3d 20 28 20 28 78  |/..cell_x = ( (x|
000044d0  5f 62 6f 75 6e 64 2b 6e  65 78 74 5f 78 5f 63 65  |_bound+next_x_ce|
000044e0  6c 6c 29 20 3e 3e 20 43  45 4c 4c 5f 58 5f 53 49  |ll) >> CELL_X_SI|
000044f0  5a 45 5f 46 50 29 3b 0a  2f 2a 20 4e 6f 74 65 20  |ZE_FP);./* Note |
00004500  77 65 20 68 61 76 65 20  74 6f 20 73 68 69 66 74  |we have to shift|
00004510  20 6e 6f 74 20 6f 6e 6c  79 20 62 79 20 36 2c 20  | not only by 6, |
00004520  62 75 74 20 61 6c 73 6f  20 62 79 20 31 36 20 74  |but also by 16 t|
00004530  6f 20 63 6f 6e 76 65 72  74 20 42 41 43 4b 20 74  |o convert BACK t|
00004540  6f 20 6e 6f 72 6d 61 6c  20 6d 61 74 68 73 20 2a  |o normal maths *|
00004550  2f 0a 63 65 6c 6c 5f 79  20 3d 20 28 69 6e 74 29  |/.cell_y = (int)|
00004560  79 69 3e 3e 32 32 3b 0a  0a 2f 2a 20 62 6f 74 68  |yi>>22;../* both|
00004570  20 6f 66 20 74 68 65 20  61 62 6f 76 65 20 65 78  | of the above ex|
00004580  61 6d 70 6c 65 73 20 75  73 65 20 62 69 6e 61 72  |amples use binar|
00004590  79 20 73 68 69 66 74 69  6e 67 20 74 6f 20 61 63  |y shifting to ac|
000045a0  68 69 65 76 65 20 61 20  64 69 76 69 64 65 20 62  |hieve a divide b|
000045b0  79 20 36 34 2e 20 43 65  6c 6c 5f 79 20 63 6f 6d  |y 64. Cell_y com|
000045c0  70 75 74 61 74 69 6f 6e  20 75 73 65 73 20 69 64  |putation uses id|
000045d0  65 6e 74 69 63 61 6c 20  74 65 63 68 6e 69 71 75  |entical techniqu|
000045e0  65 73 20 74 6f 20 74 68  6f 73 65 20 63 6f 76 65  |es to those cove|
000045f0  72 65 64 20 69 6e 20 74  68 65 20 6d 61 67 61 7a  |red in the magaz|
00004600  69 6e 65 2e 20 43 65 6c  6c 5f 78 20 69 73 20 63  |ine. Cell_x is c|
00004610  61 6c 63 75 6c 61 74 65  64 20 62 79 20 75 73 69  |alculated by usi|
00004620  6e 67 20 74 68 65 20 78  5f 62 6f 75 6e 64 20 61  |ng the x_bound a|
00004630  6e 64 20 6e 65 78 74 5f  78 5f 63 65 6c 6c 20 76  |nd next_x_cell v|
00004640  61 6c 75 65 73 20 63 61  6c 63 75 6c 61 74 65 64  |alues calculated|
00004650  20 62 65 66 6f 72 65 68  61 6e 64 2e 20 2a 2f 0a  | beforehand. */.|
00004660  0a 69 66 28 63 65 6c 6c  5f 78 3c 30 29 63 65 6c  |.if(cell_x<0)cel|
00004670  6c 5f 78 3d 30 3b 69 66  28 63 65 6c 6c 5f 78 3e  |l_x=0;if(cell_x>|
00004680  36 33 29 63 65 6c 6c 5f  78 3d 36 33 3b 0a 69 66  |63)cell_x=63;.if|
00004690  28 63 65 6c 6c 5f 79 3c  30 29 63 65 6c 6c 5f 79  |(cell_y<0)cell_y|
000046a0  3d 30 3b 69 66 28 63 65  6c 6c 5f 79 3e 36 33 29  |=0;if(cell_y>63)|
000046b0  63 65 6c 6c 5f 79 3d 36  33 3b 0a 2f 2a 20 74 68  |cell_y=63;./* th|
000046c0  65 73 65 20 73 69 6d 70  6c 65 20 6c 69 6e 65 73  |ese simple lines|
000046d0  20 65 6e 73 75 72 65 20  74 68 61 74 20 74 68 65  | ensure that the|
000046e0  20 72 61 79 20 64 6f 65  73 6e 27 74 20 67 6f 20  | ray doesn't go |
000046f0  6f 75 74 20 6f 66 20 74  68 65 20 77 6f 72 6c 64  |out of the world|
00004700  2c 20 74 68 6f 75 67 68  20 74 68 65 79 20 61 72  |, though they ar|
00004710  65 6e 27 74 20 72 65 61  6c 6c 79 20 6e 65 65 64  |en't really need|
00004720  65 64 2e 20 2a 2f 0a 0a  2f 2a 20 77 65 20 6c 6f  |ed. */../* we lo|
00004730  6f 6b 20 75 70 20 69 6e  20 74 68 65 20 77 6f 72  |ok up in the wor|
00004740  6c 64 20 66 69 6c 65 20  74 6f 20 73 65 65 20 69  |ld file to see i|
00004750  66 20 74 68 65 72 65 20  69 73 20 61 20 77 61 6c  |f there is a wal|
00004760  6c 20 61 74 20 74 68 65  20 69 6e 74 65 72 73 65  |l at the interse|
00004770  63 74 69 6f 6e 20 6f 66  20 6f 75 72 20 72 61 79  |ction of our ray|
00004780  20 2a 2f 0a 69 66 20 28  28 78 5f 68 69 74 5f 74  | */.if ((x_hit_t|
00004790  79 70 65 20 3d 77 6f 72  6c 64 5b 63 65 6c 6c 5f  |ype =world[cell_|
000047a0  79 5d 5b 63 65 6c 6c 5f  78 5d 29 21 3d 30 29 0a  |y][cell_x])!=0).|
000047b0  7b 0a 20 2f 2a 20 6f 72  20 61 6e 79 20 28 65 78  |{. /* or any (ex|
000047c0  74 72 61 20 6f 72 20 64  69 66 66 65 72 65 6e 74  |tra or different|
000047d0  29 20 74 69 6c 65 20 76  61 6c 75 65 20 79 6f 75  |) tile value you|
000047e0  20 77 69 73 68 20 2a 2f  0a 69 66 28 78 5f 68 69  | wish */.if(x_hi|
000047f0  74 5f 74 79 70 65 3d 3d  39 20 7c 7c 20 78 5f 68  |t_type==9 || x_h|
00004800  69 74 5f 74 79 70 65 3d  3d 37 29 7b 0a 20 20 2f  |it_type==7){.  /|
00004810  2a 54 48 45 4e 20 54 48  45 20 57 41 4c 4c 20 49  |*THEN THE WALL I|
00004820  53 20 54 52 41 4e 53 50  41 52 45 4e 54 21 21 21  |S TRANSPARENT!!!|
00004830  2a 2f 0a 20 78 74 72 61  6e 73 5f 64 69 73 74 3d  |*/. xtrans_dist=|
00004840  28 28 79 69 2d 28 76 69  65 77 5f 79 3c 3c 31 36  |((yi-(view_y<<16|
00004850  29 29 3e 3e 38 29 2a 28  69 6e 76 5f 73 69 6e 5f  |))>>8)*(inv_sin_|
00004860  74 61 62 6c 65 5b 76 69  65 77 5f 61 6e 67 6c 65  |table[view_angle|
00004870  5d 3e 3e 38 29 3b 0a 20  78 74 72 61 6e 73 5f 74  |]>>8);. xtrans_t|
00004880  79 70 65 3d 78 5f 68 69  74 5f 74 79 70 65 3b 0a  |ype=x_hit_type;.|
00004890  20 78 74 72 61 6e 73 5f  63 6f 6c 3d 28 28 69 6e  | xtrans_col=((in|
000048a0  74 29 28 79 69 3e 3e 31  36 29 20 26 20 30 78 30  |t)(yi>>16) & 0x0|
000048b0  30 33 66 29 3b 0a 20 78  74 72 61 6e 73 5f 64 6f  |03f);. xtrans_do|
000048c0  6e 65 3d 46 4f 55 4e 44  5f 57 41 4c 4c 3b 0a 2f  |ne=FOUND_WALL;./|
000048d0  2a 20 77 65 20 72 65 63  6f 72 64 20 61 6c 6c 20  |* we record all |
000048e0  72 65 71 75 69 72 65 64  20 64 65 74 61 69 6c 73  |required details|
000048f0  20 74 68 65 6e 20 63 6f  6e 74 69 6e 75 65 20 2a  | then continue *|
00004900  2f 0a 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |/.              |
00004910  20 20 20 7d 0a 0a 65 6c  73 65 0a 7b 0a 2f 2a 20  |   }..else.{./* |
00004920  69 66 20 73 6f 20 77 65  20 63 61 6c 63 75 6c 61  |if so we calcula|
00004930  74 65 20 74 68 65 20 64  69 73 74 61 6e 63 65 20  |te the distance |
00004940  74 6f 20 69 74 20 75 73  69 6e 67 20 74 68 65 20  |to it using the |
00004950  6f 6c 64 20 4f 2d 4c 65  76 65 6c 20 74 65 63 68  |old O-Level tech|
00004960  6e 69 71 75 65 20 6f 66  20 75 73 69 6e 67 20 73  |nique of using s|
00004970  69 6e 65 20 61 6e 64 20  63 6f 73 69 6e 65 20 69  |ine and cosine i|
00004980  6e 73 74 65 61 64 20 6f  66 20 64 6f 69 6e 67 20  |nstead of doing |
00004990  74 68 65 20 73 74 61 6e  64 61 72 64 20 50 59 54  |the standard PYT|
000049a0  48 41 47 4f 52 41 53 20  74 65 63 68 6e 69 71 75  |HAGORAS techniqu|
000049b0  65 2e 2a 2f 0a 0a 2f 2a  20 4e 45 57 20 46 49 58  |e.*/../* NEW FIX|
000049c0  45 44 20 50 4f 49 4e 54  20 63 61 6c 63 75 6c 61  |ED POINT calcula|
000049d0  74 69 6f 6e 2c 20 6e 6f  74 69 63 65 20 74 68 61  |tion, notice tha|
000049e0  74 20 69 6e 20 74 68 69  73 20 6e 65 78 74 20 6c  |t in this next l|
000049f0  69 6e 65 20 77 65 20 68  61 76 65 20 62 6f 74 68  |ine we have both|
00004a00  20 61 20 63 6f 6e 76 65  72 73 69 6f 6e 20 54 4f  | a conversion TO|
00004a10  20 66 69 78 65 64 20 70  6f 69 6e 74 20 28 76 69  | fixed point (vi|
00004a20  65 77 5f 79 29 20 61 6e  64 20 61 6c 73 6f 20 74  |ew_y) and also t|
00004a30  68 65 20 63 68 65 63 6b  20 61 67 61 69 6e 73 74  |he check against|
00004a40  20 6f 76 65 72 20 66 6c  6f 77 20 69 73 20 76 65  | over flow is ve|
00004a50  72 79 20 61 70 70 61 72  65 6e 74 2c 20 77 65 20  |ry apparent, we |
00004a60  73 68 61 72 65 20 74 68  65 20 61 63 63 75 72 61  |share the accura|
00004a70  63 79 2e 20 53 65 65 20  74 68 65 20 61 72 74 69  |cy. See the arti|
00004a80  63 6c 65 20 66 6f 72 20  6d 6f 72 65 20 64 65 74  |cle for more det|
00004a90  61 69 6c 73 20 2a 2f 0a  0a 64 69 73 74 5f 78 20  |ails */..dist_x |
00004aa0  20 3d 20 28 20 28 79 69  20 2d 20 28 76 69 65 77  | = ( (yi - (view|
00004ab0  5f 79 3c 3c 31 36 29 29  3e 3e 38 29 20 2a 20 28  |_y<<16))>>8) * (|
00004ac0  69 6e 76 5f 73 69 6e 5f  74 61 62 6c 65 5b 76 69  |inv_sin_table[vi|
00004ad0  65 77 5f 61 6e 67 6c 65  5d 3e 3e 38 29 3b 0a 2f  |ew_angle]>>8);./|
00004ae0  2a 20 77 65 20 61 6c 73  6f 20 73 61 76 65 20 74  |* we also save t|
00004af0  68 65 20 65 78 61 63 74  20 70 6f 73 69 74 69 6f  |he exact positio|
00004b00  6e 20 6f 66 20 74 68 65  20 69 6e 74 65 72 73 65  |n of the interse|
00004b10  63 74 69 6f 6e 20 62 65  63 61 75 73 65 20 77 65  |ction because we|
00004b20  20 77 69 6c 6c 20 6e 65  65 64 20 69 74 20 6c 61  | will need it la|
00004b30  74 65 72 20 74 6f 20 61  64 64 20 74 65 78 74 75  |ter to add textu|
00004b40  72 65 20 6d 61 70 70 69  6e 67 2e 20 2a 2f 0a 0a  |re mapping. */..|
00004b50  2f 2a 20 57 65 20 73 61  76 65 20 79 69 20 61 66  |/* We save yi af|
00004b60  74 65 72 20 63 6f 6e 76  65 72 74 69 6e 67 20 69  |ter converting i|
00004b70  74 20 62 61 63 6b 20 74  6f 20 6e 6f 72 6d 61 6c  |t back to normal|
00004b80  20 6d 61 74 68 73 20 2a  2f 0a 0a 79 69 5f 73 61  | maths */..yi_sa|
00004b90  76 65 20 3d 20 28 69 6e  74 29 79 69 3e 3e 31 36  |ve = (int)yi>>16|
00004ba0  3b 0a 0a 2f 2a 20 62 65  63 61 75 73 65 20 74 68  |;../* because th|
00004bb0  65 20 78 20 72 61 79 20  68 61 73 20 66 6f 75 6e  |e x ray has foun|
00004bc0  64 20 61 20 77 61 6c 6c  2c 20 77 65 20 63 61 6e  |d a wall, we can|
00004bd0  20 73 74 6f 70 20 63 61  73 74 69 6e 67 20 2a 2f  | stop casting */|
00004be0  0a 78 72 61 79 3d 46 4f  55 4e 44 5f 57 41 4c 4c  |.xray=FOUND_WALL|
00004bf0  3b 0a 0a 7d 0a 7d 0a 0a  7b 0a 2f 2a 20 69 66 20  |;..}.}..{./* if |
00004c00  6e 6f 74 2c 20 77 65 20  63 6f 6d 70 75 74 65 20  |not, we compute |
00004c10  74 68 65 20 6e 65 78 74  20 70 6f 73 73 69 62 6c  |the next possibl|
00004c20  65 20 69 6e 74 65 72 73  65 63 74 69 6f 6e 20 2a  |e intersection *|
00004c30  2f 0a 79 69 20 2b 3d 78  61 64 64 3b 20 2f 2a 20  |/.yi +=xadd; /* |
00004c40  46 49 58 45 44 20 50 4f  49 4e 54 20 41 44 44 49  |FIXED POINT ADDI|
00004c50  54 49 4f 4e 20 72 65 71  75 69 72 65 73 20 6e 6f  |TION requires no|
00004c60  20 65 78 74 72 61 20 77  6f 72 6b 20 2a 2f 0a 78  | extra work */.x|
00004c70  5f 62 6f 75 6e 64 20 2b  3d 20 78 5f 64 65 6c 74  |_bound += x_delt|
00004c80  61 3b 20 2f 2a 20 61 6e  64 20 77 65 20 61 6c 73  |a; /* and we als|
00004c90  6f 20 63 61 6c 63 75 6c  61 74 65 20 74 68 65 20  |o calculate the |
00004ca0  6e 65 78 74 20 68 6f 72  69 7a 6f 6e 74 61 6c 20  |next horizontal |
00004cb0  62 6f 75 6e 64 61 72 79  2c 20 77 68 69 63 68 20  |boundary, which |
00004cc0  77 65 20 6b 6e 6f 77 20  77 69 6c 6c 20 62 65 20  |we know will be |
00004cd0  78 5f 64 65 6c 74 61 20  61 77 61 79 2c 20 6e 6f  |x_delta away, no|
00004ce0  20 6e 65 65 64 20 66 6f  72 20 63 6f 6d 70 6c 65  | need for comple|
00004cf0  78 20 77 6f 72 6b 69 6e  67 73 2e 20 2a 2f 0a 7d  |x workings. */.}|
00004d00  0a 0a 7d 0a 2f 2a 20 53  45 43 54 49 4f 4e 20 33  |..}./* SECTION 3|
00004d10  20 2a 2f 0a 2f 2a 20 57  45 20 4e 4f 57 20 64 6f  | */./* WE NOW do|
00004d20  20 65 78 61 63 74 6c 79  20 74 68 65 20 73 61 6d  | exactly the sam|
00004d30  65 20 62 75 74 20 66 6f  72 20 74 68 65 20 79 72  |e but for the yr|
00004d40  61 79 2c 20 77 65 20 63  61 73 74 20 69 74 20 6f  |ay, we cast it o|
00004d50  75 74 2c 20 63 68 65 63  6b 20 66 6f 72 20 61 20  |ut, check for a |
00004d60  77 61 6c 6c 2c 20 69 66  20 74 68 65 72 65 20 69  |wall, if there i|
00004d70  73 20 6f 6e 65 20 77 65  20 74 61 6b 65 20 74 68  |s one we take th|
00004d80  65 20 64 69 73 74 61 6e  63 65 20 74 6f 20 69 74  |e distance to it|
00004d90  20 65 74 63 2c 20 69 66  20 6e 6f 74 2c 20 77 65  | etc, if not, we|
00004da0  20 6d 6f 76 65 20 20 74  68 65 20 72 61 79 20 75  | move  the ray u|
00004db0  6e 74 69 6c 20 61 20 77  61 6c 6c 20 69 74 20 66  |ntil a wall it f|
00004dc0  6f 75 6e 64 2e 20 2a 2f  0a 0a 2f 2a 20 6c 6f 6f  |ound. */../* loo|
00004dd0  6b 20 75 70 20 74 68 65  20 76 61 6c 75 65 20 74  |k up the value t|
00004de0  6f 20 61 64 64 20 74 6f  20 74 68 65 20 72 61 79  |o add to the ray|
00004df0  20 65 61 63 68 20 74 69  6d 65 20 77 65 20 6d 6f  | each time we mo|
00004e00  76 65 20 69 74 20 2a 2f  0a 0a 2f 2a 20 53 65 65  |ve it */../* See|
00004e10  20 61 62 6f 76 65 20 66  6f 72 20 6d 6f 72 65 20  | above for more |
00004e20  69 6e 66 6f 72 6d 61 74  69 6f 6e 2c 20 74 68 69  |information, thi|
00004e30  73 20 69 73 20 46 49 58  45 44 20 50 4f 49 4e 54  |s is FIXED POINT|
00004e40  20 72 65 6d 65 6d 62 65  72 20 2a 2f 0a 79 61 64  | remember */.yad|
00004e50  64 3d 78 5f 73 74 65 70  5b 76 69 65 77 5f 61 6e  |d=x_step[view_an|
00004e60  67 6c 65 5d 3c 3c 33 3b  0a 0a 2f 2a 20 73 74 61  |gle]<<3;../* sta|
00004e70  72 74 20 63 61 73 74 69  6e 67 20 74 68 65 20 72  |rt casting the r|
00004e80  61 79 20 2a 2f 0a 77 68  69 6c 65 28 21 79 72 61  |ay */.while(!yra|
00004e90  79 29 0a 7b 0a 0a 2f 2a  20 63 6f 6d 70 75 74 65  |y).{../* compute|
00004ea0  20 63 75 72 72 65 6e 74  20 63 65 6c 6c 20 74 6f  | current cell to|
00004eb0  20 69 6e 73 70 65 63 74  20 2a 2f 0a 0a 2f 2a 20  | inspect */../* |
00004ec0  42 65 63 61 75 73 65 20  58 49 20 49 53 20 49 4e  |Because XI IS IN|
00004ed0  20 46 49 58 45 44 20 50  4f 49 4e 54 20 77 65 20  | FIXED POINT we |
00004ee0  68 61 76 65 20 74 6f 20  6e 6f 74 20 6f 6e 6c 79  |have to not only|
00004ef0  20 64 69 76 69 64 65 20  62 79 20 36 34 20 62 75  | divide by 64 bu|
00004f00  74 20 61 6c 73 6f 20 77  65 20 68 61 76 65 20 74  |t also we have t|
00004f10  6f 20 63 6f 6e 76 65 72  74 20 42 41 43 4b 20 74  |o convert BACK t|
00004f20  6f 20 6e 6f 72 6d 61 6c  20 6d 61 74 68 73 20 2a  |o normal maths *|
00004f30  2f 0a 0a 63 65 6c 6c 5f  78 20 3d 20 28 69 6e 74  |/..cell_x = (int|
00004f40  29 78 69 3e 3e 32 32 3b  0a 63 65 6c 6c 5f 79 20  |)xi>>22;.cell_y |
00004f50  3d 20 28 20 28 79 5f 62  6f 75 6e 64 20 2b 20 6e  |= ( (y_bound + n|
00004f60  65 78 74 5f 79 5f 63 65  6c 6c 29 20 3e 3e 20 43  |ext_y_cell) >> C|
00004f70  45 4c 4c 5f 59 5f 53 49  5a 45 5f 46 50 29 3b 0a  |ELL_Y_SIZE_FP);.|
00004f80  2f 2a 20 74 68 65 73 65  20 63 61 6c 63 75 6c 61  |/* these calcula|
00004f90  74 69 6f 6e 73 20 77 6f  72 6b 20 6f 75 74 20 77  |tions work out w|
00004fa0  68 69 63 68 20 63 65 6c  6c 73 20 74 68 65 20 72  |hich cells the r|
00004fb0  61 79 20 69 73 20 69 6e  2c 20 72 65 61 64 79 20  |ay is in, ready |
00004fc0  74 6f 20 63 68 65 63 6b  20 66 6f 72 20 77 61 6c  |to check for wal|
00004fd0  6c 73 20 69 6e 20 74 68  65 20 77 6f 72 6c 64 5b  |ls in the world[|
00004fe0  5d 5b 5d 20 61 72 72 61  79 2e 20 54 68 65 79 20  |][] array. They |
00004ff0  62 6f 74 68 20 75 73 65  20 62 69 6e 61 72 79 20  |both use binary |
00005000  73 68 69 66 74 69 6e 67  20 74 6f 20 70 65 72 66  |shifting to perf|
00005010  6f 72 6d 20 64 69 76 69  64 65 20 62 79 20 36 34  |orm divide by 64|
00005020  27 73 2e 20 2a 2f 0a 0a  2f 2a 20 63 68 65 63 6b  |'s. */../* check|
00005030  20 74 68 61 74 20 74 68  65 20 72 61 79 20 68 61  | that the ray ha|
00005040  73 20 6e 6f 74 20 67 6f  6e 65 20 6f 75 74 20 6f  |s not gone out o|
00005050  66 20 74 68 65 20 77 6f  72 6c 64 2c 20 74 68 6f  |f the world, tho|
00005060  75 67 68 20 74 68 69 73  20 69 73 6e 27 74 20 72  |ugh this isn't r|
00005070  65 61 6c 6c 79 20 6e 65  63 65 73 73 61 72 79 20  |eally necessary |
00005080  2a 2f 0a 69 66 28 63 65  6c 6c 5f 78 3c 30 29 63  |*/.if(cell_x<0)c|
00005090  65 6c 6c 5f 78 3d 30 3b  69 66 28 63 65 6c 6c 5f  |ell_x=0;if(cell_|
000050a0  78 3e 36 33 29 63 65 6c  6c 5f 78 3d 36 33 3b 0a  |x>63)cell_x=63;.|
000050b0  69 66 28 63 65 6c 6c 5f  79 3c 30 29 63 65 6c 6c  |if(cell_y<0)cell|
000050c0  5f 79 3d 30 3b 69 66 28  63 65 6c 6c 5f 79 3e 36  |_y=0;if(cell_y>6|
000050d0  33 29 63 65 6c 6c 5f 79  3d 36 33 3b 0a 0a 2f 2a  |3)cell_y=63;../*|
000050e0  20 6c 6f 6f 6b 20 61 6e  64 20 73 65 65 20 69 66  | look and see if|
000050f0  20 74 68 65 72 65 20 69  73 20 61 20 77 61 6c 6c  | there is a wall|
00005100  20 61 74 20 74 68 65 20  63 75 72 72 65 6e 74 20  | at the current |
00005110  70 6f 69 6e 74 20 6f 66  20 69 6e 74 65 72 73 65  |point of interse|
00005120  63 74 69 6f 6e 20 2a 2f  0a 69 66 20 28 28 79 5f  |ction */.if ((y_|
00005130  68 69 74 5f 74 79 70 65  20 3d 20 77 6f 72 6c 64  |hit_type = world|
00005140  5b 63 65 6c 6c 5f 79 5d  5b 63 65 6c 6c 5f 78 5d  |[cell_y][cell_x]|
00005150  29 21 3d 30 29 0a 7b 0a  69 66 28 79 5f 68 69 74  |)!=0).{.if(y_hit|
00005160  5f 74 79 70 65 3d 3d 39  20 7c 7c 20 79 5f 68 69  |_type==9 || y_hi|
00005170  74 5f 74 79 70 65 3d 3d  37 29 7b 0a 20 20 2f 2a  |t_type==7){.  /*|
00005180  54 48 45 4e 20 54 48 45  20 57 41 4c 4c 20 49 53  |THEN THE WALL IS|
00005190  20 54 52 41 4e 53 50 41  52 45 4e 54 21 21 21 2a  | TRANSPARENT!!!*|
000051a0  2f 0a 79 74 72 61 6e 73  5f 64 69 73 74 3d 28 28  |/.ytrans_dist=((|
000051b0  78 69 2d 28 76 69 65 77  5f 78 3c 3c 31 36 29 29  |xi-(view_x<<16))|
000051c0  3e 3e 38 29 2a 28 69 6e  76 5f 63 6f 73 5f 74 61  |>>8)*(inv_cos_ta|
000051d0  62 6c 65 5b 76 69 65 77  5f 61 6e 67 6c 65 5d 3e  |ble[view_angle]>|
000051e0  3e 38 29 3b 0a 79 74 72  61 6e 73 5f 74 79 70 65  |>8);.ytrans_type|
000051f0  3d 79 5f 68 69 74 5f 74  79 70 65 3b 0a 79 74 72  |=y_hit_type;.ytr|
00005200  61 6e 73 5f 63 6f 6c 3d  28 28 69 6e 74 29 28 78  |ans_col=((int)(x|
00005210  69 3e 3e 31 36 29 20 26  20 30 78 30 30 33 66 29  |i>>16) & 0x003f)|
00005220  3b 0a 79 74 72 61 6e 73  5f 64 6f 6e 65 3d 46 4f  |;.ytrans_done=FO|
00005230  55 4e 44 5f 57 41 4c 4c  3b 0a 7d 0a 2f 2a 20 77  |UND_WALL;.}./* w|
00005240  65 20 72 65 63 6f 72 64  20 61 6c 6c 20 72 65 71  |e record all req|
00005250  75 69 72 65 64 20 64 65  74 61 69 6c 73 20 74 68  |uired details th|
00005260  65 6e 20 63 6f 6e 74 69  6e 75 65 20 2a 2f 0a 0a  |en continue */..|
00005270  65 6c 73 65 0a 7b 0a 0a  0a 0a 2f 2a 20 55 73 65  |else.{..../* Use|
00005280  20 74 68 65 20 6f 6c 64  20 4f 2d 4c 65 76 65 6c  | the old O-Level|
00005290  20 74 72 69 61 6e 67 6c  65 20 6d 65 74 68 6f 64  | triangle method|
000052a0  20 6f 66 20 63 61 6c 75  6c 61 74 69 6e 67 20 64  | of calulating d|
000052b0  69 73 74 61 6e 63 65 20  75 73 69 6e 67 20 63 6f  |istance using co|
000052c0  73 2c 20 72 61 74 68 65  72 20 74 68 61 6e 20 75  |s, rather than u|
000052d0  73 69 6e 67 20 50 59 54  48 41 47 4f 52 41 53 2c  |sing PYTHAGORAS,|
000052e0  20 77 68 69 63 68 20 69  73 20 73 6c 6f 77 65 72  | which is slower|
000052f0  20 62 65 63 61 75 73 65  20 69 74 20 75 73 65 73  | because it uses|
00005300  20 61 20 73 71 75 61 72  65 20 72 6f 6f 74 21 20  | a square root! |
00005310  2a 2f 0a 2f 2a 20 46 49  58 45 44 20 50 4f 49 4e  |*/./* FIXED POIN|
00005320  54 20 63 61 6c 63 75 6c  61 74 69 6f 6e 2c 20 6a  |T calculation, j|
00005330  75 73 74 20 74 68 65 20  73 61 6d 65 20 61 73 20  |ust the same as |
00005340  74 68 65 20 69 6e 76 5f  73 69 6e 20 63 61 6c 63  |the inv_sin calc|
00005350  75 6c 61 74 69 6f 6e 20  73 65 65 20 61 62 6f 76  |ulation see abov|
00005360  65 2e 20 2a 2f 0a 64 69  73 74 5f 79 20 20 3d 20  |e. */.dist_y  = |
00005370  28 20 28 78 69 20 2d 20  28 76 69 65 77 5f 78 3c  |( (xi - (view_x<|
00005380  3c 31 36 29 29 3e 3e 38  29 20 2a 20 28 69 6e 76  |<16))>>8) * (inv|
00005390  5f 63 6f 73 5f 74 61 62  6c 65 5b 76 69 65 77 5f  |_cos_table[view_|
000053a0  61 6e 67 6c 65 5d 3e 3e  38 29 3b 0a 0a 2f 2a 20  |angle]>>8);../* |
000053b0  73 61 76 65 20 74 68 65  20 65 78 61 63 74 20 69  |save the exact i|
000053c0  6e 74 65 72 73 65 63 74  69 6f 6e 20 70 6f 69 6e  |ntersection poin|
000053d0  74 2c 20 77 65 20 77 69  6c 6c 20 6e 65 65 64 20  |t, we will need |
000053e0  69 74 20 6c 61 74 65 72  20 2a 2f 0a 2f 2a 20 53  |it later */./* S|
000053f0  61 6d 65 20 61 73 20 61  6f 62 76 65 2c 20 76 65  |ame as aobve, ve|
00005400  72 79 20 73 69 6d 70 6c  65 20 63 6f 6e 76 65 72  |ry simple conver|
00005410  73 69 6f 6e 20 62 61 63  6b 20 66 72 6f 6d 20 46  |sion back from F|
00005420  49 58 45 44 20 50 4f 49  4e 54 20 74 6f 20 6e 6f  |IXED POINT to no|
00005430  72 6d 61 6c 20 6d 61 74  68 73 20 2a 2f 0a 78 69  |rmal maths */.xi|
00005440  5f 73 61 76 65 20 3d 20  28 69 6e 74 29 78 69 3e  |_save = (int)xi>|
00005450  3e 31 36 3b 0a 2f 2a 20  53 54 4f 50 20 79 20 63  |>16;./* STOP y c|
00005460  61 73 74 69 6e 67 20 69  6e 20 74 68 61 74 20 63  |asting in that c|
00005470  61 73 65 2c 20 61 20 77  61 6c 6c 20 68 61 73 20  |ase, a wall has |
00005480  62 65 65 6e 20 66 6f 75  6e 64 2e 20 2a 2f 0a 79  |been found. */.y|
00005490  72 61 79 3d 46 4f 55 4e  44 5f 57 41 4c 4c 3b 0a  |ray=FOUND_WALL;.|
000054a0  7d 0a 7d 0a 0a 7b 0a 2f  2a 20 69 66 20 6e 6f 74  |}.}..{./* if not|
000054b0  2c 20 6d 6f 76 65 20 74  68 65 20 72 61 79 20 6f  |, move the ray o|
000054c0  6e 20 2a 2f 0a 78 69 2b  3d 79 61 64 64 3b 20 2f  |n */.xi+=yadd; /|
000054d0  2a 20 41 47 41 49 4e 2c  20 6e 6f 20 65 78 74 72  |* AGAIN, no extr|
000054e0  61 20 77 6f 72 6b 20 69  73 20 72 65 71 75 69 72  |a work is requir|
000054f0  65 64 20 66 6f 72 20 46  49 58 45 44 20 50 4f 49  |ed for FIXED POI|
00005500  4e 54 20 41 44 44 49 54  49 4f 4e 20 2a 2f 0a 79  |NT ADDITION */.y|
00005510  5f 62 6f 75 6e 64 20 2b  3d 20 79 5f 64 65 6c 74  |_bound += y_delt|
00005520  61 3b 20 2f 2a 20 61 6e  64 20 6d 6f 76 65 20 74  |a; /* and move t|
00005530  6f 20 74 68 65 20 6e 65  78 74 20 76 65 72 74 69  |o the next verti|
00005540  63 61 6c 20 62 6f 75 6e  64 61 72 79 20 70 6f 73  |cal boundary pos|
00005550  69 74 69 6f 6e 20 2a 2f  0a 7d 0a 0a 7d 0a 0a 2f  |ition */.}..}../|
00005560  2a 20 53 45 43 54 49 4f  4e 20 34 2a 2f 0a 2f 2a  |* SECTION 4*/./*|
00005570  20 42 6f 74 68 20 72 61  79 73 20 68 61 76 65 20  | Both rays have |
00005580  62 65 65 6e 20 63 61 73  74 2c 20 62 6f 74 68 20  |been cast, both |
00005590  72 61 79 73 20 68 61 76  65 20 6d 65 74 20 61 20  |rays have met a |
000055a0  77 61 6c 6c 2c 20 77 65  20 6e 6f 77 20 6e 65 65  |wall, we now nee|
000055b0  64 20 74 6f 20 73 65 65  20 77 68 69 63 68 20 69  |d to see which i|
000055c0  73 20 63 6c 6f 73 65 72  2c 20 61 6e 64 20 74 68  |s closer, and th|
000055d0  65 6e 20 70 6c 6f 74 20  69 74 20 63 6f 72 72 65  |en plot it corre|
000055e0  63 74 6c 79 2e 20 2a 2f  0a 0a 2f 2a 20 66 69 6e  |ctly. */../* fin|
000055f0  64 20 6f 75 74 20 77 68  69 63 68 20 77 61 6c 6c  |d out which wall|
00005600  20 28 78 20 6f 72 20 79  29 20 69 73 20 6e 65 61  | (x or y) is nea|
00005610  72 65 72 20 74 68 65 20  76 69 65 77 65 72 2e 20  |rer the viewer. |
00005620  2a 2f 0a 0a 2f 2a 20 77  65 20 68 61 76 65 20 61  |*/../* we have a|
00005630  6c 74 65 72 65 64 20 74  68 69 73 20 64 69 73 74  |ltered this dist|
00005640  61 6e 63 65 20 63 68 65  63 6b 69 6e 67 20 6c 69  |ance checking li|
00005650  6e 65 20 74 6f 20 61 76  6f 69 64 20 6d 69 6e 75  |ne to avoid minu|
00005660  73 20 64 69 73 74 61 6e  63 65 73 20 62 65 69 6e  |s distances bein|
00005670  67 20 73 65 6c 65 63 74  65 64 20 74 6f 20 64 72  |g selected to dr|
00005680  61 77 2c 20 77 68 69 63  68 20 70 72 6f 64 75 63  |aw, which produc|
00005690  65 73 20 6c 61 72 67 65  20 73 70 69 6b 65 73 20  |es large spikes |
000056a0  6f 6e 20 74 68 65 20 73  63 72 65 65 6e 21 20 41  |on the screen! A|
000056b0  67 61 69 6e 20 74 68 69  73 20 69 73 20 62 65 63  |gain this is bec|
000056c0  61 75 73 65 20 6f 66 20  66 69 78 65 64 20 70 6f  |ause of fixed po|
000056d0  69 6e 74 20 2a 2f 0a 0a  20 20 20 20 69 66 20 28  |int */..    if (|
000056e0  64 69 73 74 5f 78 20 3c  20 64 69 73 74 5f 79 20  |dist_x < dist_y |
000056f0  26 26 20 64 69 73 74 5f  78 3e 30 20 7c 7c 20 64  |&& dist_x>0 || d|
00005700  69 73 74 5f 79 3c 30 29  0a 0a 20 20 20 20 20 20  |ist_y<0)..      |
00005710  20 7b 0a 0a 0a 2f 2a 20  77 65 20 6e 65 65 64 20  | {.../* we need |
00005720  74 6f 20 74 61 6b 65 20  69 6e 74 6f 20 61 63 63  |to take into acc|
00005730  6f 75 6e 74 20 68 65 72  65 2c 20 77 68 65 6e 20  |ount here, when |
00005740  63 6f 6d 70 75 74 69 6e  67 20 74 68 65 20 73 63  |computing the sc|
00005750  61 6c 65 20 6f 66 20 74  68 65 20 76 65 72 74 69  |ale of the verti|
00005760  63 61 6c 20 73 74 72 69  70 20 28 73 6c 69 76 65  |cal strip (slive|
00005770  72 29 20 74 6f 20 62 65  20 64 72 61 77 6e 2c 20  |r) to be drawn, |
00005780  61 20 70 68 65 6e 65 6d  65 6e 6f 6e 20 28 6f 66  |a phenemenon (of|
00005790  20 73 6f 72 74 73 29 20  6b 6e 6f 77 6e 20 61 73  | sorts) known as|
000057a0  20 74 68 65 20 22 66 69  73 68 20 62 6f 77 6c 20  | the "fish bowl |
000057b0  65 66 66 65 63 74 22 2e  20 54 68 69 73 20 69 73  |effect". This is|
000057c0  20 63 61 75 73 65 64 20  62 79 20 6d 69 7a 69 6e  | caused by mizin|
000057d0  67 20 6f 66 20 63 61 72  74 65 73 69 61 6e 20 61  |g of cartesian a|
000057e0  6e 64 20 70 6f 6c 61 72  20 63 6f 6f 72 64 69 6e  |nd polar coordin|
000057f0  61 74 65 73 2e 20 54 6f  20 67 65 74 20 72 69 64  |ates. To get rid|
00005800  20 6f 66 20 69 74 20 77  65 20 75 73 65 20 74 68  | of it we use th|
00005810  65 20 63 6f 73 69 6e 65  20 66 75 6e 63 74 69 6f  |e cosine functio|
00005820  6e 2e 20 49 20 68 61 76  65 20 63 6f 6d 62 69 6e  |n. I have combin|
00005830  65 64 20 6f 74 68 65 72  20 6d 75 6c 74 69 70 6c  |ed other multipl|
00005840  69 65 73 20 6f 66 20 61  20 76 65 72 74 69 63 61  |ies of a vertica|
00005850  6c 20 73 63 61 6c 69 6e  67 20 66 61 63 74 6f 72  |l scaling factor|
00005860  20 77 69 74 68 20 74 68  65 20 63 6f 73 69 6e 65  | with the cosine|
00005870  20 74 72 61 6e 73 66 6f  72 6d 61 74 69 6f 6e 20  | transformation |
00005880  74 6f 20 73 61 76 65 20  74 69 6d 65 2e 20 41 6c  |to save time. Al|
00005890  6c 20 77 65 20 65 76 65  6e 74 75 61 6c 6c 79 20  |l we eventually |
000058a0  62 65 20 65 78 70 6c 61  69 6e 65 64 2e 20 59 6f  |be explained. Yo|
000058b0  75 20 63 6f 75 6c 64 20  72 65 70 6c 61 63 65 20  |u could replace |
000058c0  74 68 65 20 6c 69 6e 65  20 77 69 74 68 20 73 63  |the line with sc|
000058d0  61 6c 65 3d 31 33 33 31  32 2f 64 69 73 74 5f 78  |ale=13312/dist_x|
000058e0  2b 2b 20 61 6e 64 20 73  65 65 20 77 68 61 74 20  |++ and see what |
000058f0  77 65 69 72 64 20 72 65  73 75 6c 74 73 20 79 6f  |weird results yo|
00005900  75 20 67 65 74 21 20 2a  2f 0a 0a 2f 2a 20 4e 45  |u get! */../* NE|
00005910  57 20 4e 45 57 20 4e 45  57 20 3a 20 57 65 20 68  |W NEW NEW : We h|
00005920  61 76 65 20 66 69 78 65  64 20 70 6f 69 6e 74 20  |ave fixed point |
00005930  68 65 72 65 2c 20 61 6e  64 20 75 73 69 6e 67 20  |here, and using |
00005940  74 68 65 20 72 65 63 69  70 72 6f 63 61 6c 20 74  |the reciprocal t|
00005950  61 62 6c 65 20 28 73 65  65 20 61 72 6f 75 6e 64  |able (see around|
00005960  29 20 77 65 20 64 6f 6e  27 74 20 68 61 76 65 20  |) we don't have |
00005970  74 6f 20 64 6f 20 61 20  6c 65 6e 67 74 68 20 64  |to do a length d|
00005980  69 76 69 64 65 21 20 4e  6f 74 69 63 65 20 68 6f  |ivide! Notice ho|
00005990  77 20 77 65 20 63 6f 6e  76 65 72 74 20 64 69 73  |w we convert dis|
000059a0  74 5f 78 20 62 61 63 6b  20 74 6f 20 6e 6f 72 6d  |t_x back to norm|
000059b0  61 6c 20 74 6f 20 69 6e  64 65 78 20 74 68 65 20  |al to index the |
000059c0  72 65 63 69 70 5f 74 61  62 6c 65 20 61 72 72 61  |recip_table arra|
000059d0  79 2c 20 61 6e 64 20 74  68 61 74 20 61 6c 6c 20  |y, and that all |
000059e0  61 63 63 75 72 61 63 79  20 69 73 20 6c 6f 73 74  |accuracy is lost|
000059f0  20 77 69 74 68 20 74 68  65 20 63 6f 73 5f 74 61  | with the cos_ta|
00005a00  62 6c 65 2c 20 62 65 63  61 75 73 65 20 61 6c 6c  |ble, because all|
00005a10  20 69 74 73 20 66 69 67  75 72 65 73 20 61 72 65  | its figures are|
00005a20  20 61 62 6f 76 65 20 7a  65 72 6f 20 28 73 65 65  | above zero (see|
00005a30  20 61 75 61 5f 74 61 62  6c 65 73 29 20 61 6e 64  | aua_tables) and|
00005a40  20 61 6c 73 6f 20 74 68  61 74 20 77 65 20 61 63  | also that we ac|
00005a50  74 75 61 6c 6c 79 20 63  6f 6e 76 65 72 74 20 74  |tually convert t|
00005a60  68 65 20 77 68 6f 6c 65  20 61 6e 73 77 65 72 20  |he whole answer |
00005a70  62 61 63 6b 20 74 6f 20  6e 6f 72 6d 61 6c 20 6d  |back to normal m|
00005a80  61 74 68 73 20 66 6f 72  20 73 63 61 6c 65 20 2a  |aths for scale *|
00005a90  2f 0a 0a 73 63 61 6c 65  20 3d 20 28 69 6e 74 29  |/..scale = (int)|
00005aa0  28 20 28 63 6f 73 5f 74  61 62 6c 65 5b 72 61 79  |( (cos_table[ray|
00005ab0  5d 3e 3e 31 36 29 20 2a  20 28 72 65 63 69 70 5f  |]>>16) * (recip_|
00005ac0  74 61 62 6c 65 5b 64 69  73 74 5f 78 3e 3e 31 36  |table[dist_x>>16|
00005ad0  5d 29 20 3e 3e 31 36 29  3b 0a 0a 2f 2a 20 61 73  |]) >>16);../* as|
00005ae0  73 69 67 6e 20 74 68 65  20 76 61 72 69 61 62 6c  |sign the variabl|
00005af0  65 73 20 77 65 20 6e 65  65 64 20 74 6f 20 74 68  |es we need to th|
00005b00  65 20 76 61 72 69 61 62  6c 65 73 20 74 6f 20 62  |e variables to b|
00005b10  65 20 70 61 73 73 65 64  20 74 6f 20 74 68 65 20  |e passed to the |
00005b20  41 53 4d 20 73 6c 69 76  65 72 20 72 65 6e 64 65  |ASM sliver rende|
00005b30  72 65 72 20 28 73 75 70  65 72 20 66 61 73 74 21  |rer (super fast!|
00005b40  29 20 2a 2f 0a 0a 76 61  72 69 61 62 6c 65 73 5b  |) */..variables[|
00005b50  33 5d 3d 73 63 61 6c 65  2d 31 3b 20 2f 2a 73 74  |3]=scale-1; /*st|
00005b60  6f 72 65 73 20 74 68 65  20 73 63 61 6c 65 20 6f  |ores the scale o|
00005b70  66 20 74 68 65 20 73 74  72 69 70 20 28 68 65 69  |f the strip (hei|
00005b80  67 68 74 20 6f 66 20 69  74 29 2a 2f 0a 76 61 72  |ght of it)*/.var|
00005b90  69 61 62 6c 65 73 5b 34  5d 3d 72 61 79 3b 20 2f  |iables[4]=ray; /|
00005ba0  2a 20 77 65 20 75 73 65  20 72 61 79 20 61 73 20  |* we use ray as |
00005bb0  74 68 65 20 78 20 70 6f  73 69 74 69 6f 6e 20 74  |the x position t|
00005bc0  6f 20 70 6c 6f 74 20 74  6f 20 28 30 2d 33 31 39  |o plot to (0-319|
00005bd0  29 2a 2f 0a 76 61 72 69  61 62 6c 65 73 5b 31 5d  |)*/.variables[1]|
00005be0  3d 26 77 61 6c 6c 73 5b  78 5f 68 69 74 5f 74 79  |=&walls[x_hit_ty|
00005bf0  70 65 5d 5b 28 79 69 5f  73 61 76 65 20 26 20 30  |pe][(yi_save & 0|
00005c00  78 30 30 33 66 29 5d 3b  0a 0a 2f 2a 20 61 6e 64  |x003f)];../* and|
00005c10  20 77 65 20 63 61 6c 6c  20 74 68 65 20 61 73 73  | we call the ass|
00005c20  65 6d 62 6c 65 72 20 66  75 6e 63 74 69 6f 6e 20  |embler function |
00005c30  28 65 78 70 6c 61 69 6e  65 64 20 61 74 20 61 20  |(explained at a |
00005c40  6c 61 74 65 72 20 64 61  74 65 29 2a 2f 0a 6f 75  |later date)*/.ou|
00005c50  72 6c 69 62 5f 73 6c 69  76 65 72 28 26 76 61 72  |rlib_sliver(&var|
00005c60  69 61 62 6c 65 73 5b 30  5d 29 3b 0a 0a 20 20 20  |iables[0]);..   |
00005c70  20 20 20 20 7d 0a 2f 2a  20 65 6c 73 65 20 74 68  |    }./* else th|
00005c80  65 20 64 69 73 74 5f 79  20 77 61 73 20 6e 65 61  |e dist_y was nea|
00005c90  72 65 72 2c 20 65 76 65  72 79 74 68 69 6e 67 20  |rer, everything |
00005ca0  66 72 6f 6d 20 61 62 6f  76 65 20 61 70 70 6c 69  |from above appli|
00005cb0  65 73 20 2a 2f 0a 20 20  20 20 65 6c 73 65 0a 20  |es */.    else. |
00005cc0  20 20 20 20 20 20 7b 0a  0a 2f 2a 20 61 76 6f 69  |      {../* avoi|
00005cd0  64 20 66 69 73 68 20 62  6f 77 6c 20 65 66 66 65  |d fish bowl effe|
00005ce0  63 74 20 61 6e 64 20 73  63 61 6c 65 20 70 72 6f  |ct and scale pro|
00005cf0  70 65 72 6c 79 20 77 69  74 68 20 46 49 58 45 44  |perly with FIXED|
00005d00  20 50 4f 49 4e 54 20 63  6c 65 76 65 72 20 62 69  | POINT clever bi|
00005d10  74 73 21 2c 20 73 65 65  20 61 62 6f 76 65 20 2a  |ts!, see above *|
00005d20  2f 0a 73 63 61 6c 65 20  3d 20 28 69 6e 74 29 28  |/.scale = (int)(|
00005d30  20 28 63 6f 73 5f 74 61  62 6c 65 5b 72 61 79 5d  | (cos_table[ray]|
00005d40  3e 3e 31 36 29 20 2a 20  28 72 65 63 69 70 5f 74  |>>16) * (recip_t|
00005d50  61 62 6c 65 5b 64 69 73  74 5f 79 3e 3e 31 36 5d  |able[dist_y>>16]|
00005d60  29 20 3e 3e 20 31 36 29  3b 0a 0a 0a 2f 2a 20 73  |) >> 16);.../* s|
00005d70  65 74 20 75 70 20 76 61  72 69 61 62 6c 65 73 20  |et up variables |
00005d80  66 6f 72 20 6f 75 72 20  73 6c 69 76 65 72 20 65  |for our sliver e|
00005d90  6e 67 69 6e 65 2c 20 73  65 65 20 61 62 6f 76 65  |ngine, see above|
00005da0  20 2a 2f 0a 0a 76 61 72  69 61 62 6c 65 73 5b 33  | */..variables[3|
00005db0  5d 3d 73 63 61 6c 65 2d  31 3b 20 2f 2a 73 74 6f  |]=scale-1; /*sto|
00005dc0  72 65 73 20 74 68 65 20  73 63 61 6c 65 20 6f 66  |res the scale of|
00005dd0  20 74 68 65 20 73 74 72  69 70 20 28 68 65 69 67  | the strip (heig|
00005de0  68 74 20 6f 66 20 69 74  29 2a 2f 0a 76 61 72 69  |ht of it)*/.vari|
00005df0  61 62 6c 65 73 5b 34 5d  3d 72 61 79 3b 20 2f 2a  |ables[4]=ray; /*|
00005e00  20 77 65 20 75 73 65 20  72 61 79 20 61 73 20 74  | we use ray as t|
00005e10  68 65 20 78 20 70 6f 73  69 74 69 6f 6e 20 74 6f  |he x position to|
00005e20  20 70 6c 6f 74 20 74 6f  20 28 30 2d 33 31 39 29  | plot to (0-319)|
00005e30  2a 2f 0a 76 61 72 69 61  62 6c 65 73 5b 31 5d 3d  |*/.variables[1]=|
00005e40  26 77 61 6c 6c 73 5b 79  5f 68 69 74 5f 74 79 70  |&walls[y_hit_typ|
00005e50  65 2b 31 5d 5b 28 78 69  5f 73 61 76 65 20 26 20  |e+1][(xi_save & |
00005e60  30 78 30 30 33 66 29 5d  3b 0a 0a 2f 2a 20 6e 6f  |0x003f)];../* no|
00005e70  74 69 63 65 20 77 65 20  61 64 64 20 6f 6e 65 20  |tice we add one |
00005e80  74 6f 20 74 68 65 20 77  61 6c 6c 20 67 72 61 70  |to the wall grap|
00005e90  68 69 63 20 73 65 6c 65  63 74 69 6f 6e 2c 20 73  |hic selection, s|
00005ea0  6f 20 74 68 65 20 64 61  72 6b 65 72 20 74 69 6c  |o the darker til|
00005eb0  65 20 69 73 20 75 73 65  64 20 66 6f 72 20 61 64  |e is used for ad|
00005ec0  64 65 64 20 76 61 72 69  61 74 69 6f 6e 2e 20 53  |ded variation. S|
00005ed0  65 65 20 74 68 65 20 61  72 74 69 63 6c 65 20 66  |ee the article f|
00005ee0  6f 72 20 6d 6f 72 65 20  64 65 74 61 69 6c 73 20  |or more details |
00005ef0  6f 66 20 74 68 69 73 20  73 6f 72 74 20 6f 66 20  |of this sort of |
00005f00  73 68 61 64 69 6e 67 2c  20 69 66 20 79 6f 75 20  |shading, if you |
00005f10  77 61 6e 74 20 74 6f 20  63 61 6c 6c 20 69 74 20  |want to call it |
00005f20  74 68 61 74 21 20 2a 2f  0a 0a 2f 2a 20 63 61 6c  |that! */../* cal|
00005f30  6c 20 6f 75 72 20 73 6c  69 76 65 72 20 65 6e 67  |l our sliver eng|
00005f40  69 6e 65 20 2a 2f 0a 6f  75 72 6c 69 62 5f 73 6c  |ine */.ourlib_sl|
00005f50  69 76 65 72 28 26 76 61  72 69 61 62 6c 65 73 5b  |iver(&variables[|
00005f60  30 5d 29 3b 0a 0a 20 20  20 20 20 20 20 7d 0a 2f  |0]);..       }./|
00005f70  2a 20 69 74 20 69 73 20  68 65 72 65 20 74 68 61  |* it is here tha|
00005f80  74 20 77 65 20 64 72 61  77 20 74 68 65 20 6f 76  |t we draw the ov|
00005f90  65 72 6c 61 79 69 6e 67  20 74 72 61 6e 73 70 61  |erlaying transpa|
00005fa0  72 65 6e 74 20 77 61 6c  6c 20 2a 2f 0a 69 66 28  |rent wall */.if(|
00005fb0  78 74 72 61 6e 73 5f 64  6f 6e 65 20 26 26 20 78  |xtrans_done && x|
00005fc0  74 72 61 6e 73 5f 64 69  73 74 3c 64 69 73 74 5f  |trans_dist<dist_|
00005fd0  79 29 0a 7b 0a 20 20 73  63 61 6c 65 3d 28 69 6e  |y).{.  scale=(in|
00005fe0  74 29 28 28 63 6f 73 5f  74 61 62 6c 65 5b 72 61  |t)((cos_table[ra|
00005ff0  79 5d 3e 3e 31 36 29 20  2a 20 28 72 65 63 69 70  |y]>>16) * (recip|
00006000  5f 74 61 62 6c 65 5b 78  74 72 61 6e 73 5f 64 69  |_table[xtrans_di|
00006010  73 74 3e 3e 31 36 5d 29  3e 3e 31 36 29 3b 0a 20  |st>>16])>>16);. |
00006020  20 76 61 72 69 61 62 6c  65 73 5b 33 5d 3d 73 63  | variables[3]=sc|
00006030  61 6c 65 2d 31 3b 0a 20  20 76 61 72 69 61 62 6c  |ale-1;.  variabl|
00006040  65 73 5b 34 5d 3d 72 61  79 3b 0a 20 20 76 61 72  |es[4]=ray;.  var|
00006050  69 61 62 6c 65 73 5b 31  5d 3d 26 77 61 6c 6c 73  |iables[1]=&walls|
00006060  5b 78 74 72 61 6e 73 5f  74 79 70 65 5d 5b 78 74  |[xtrans_type][xt|
00006070  72 61 6e 73 5f 63 6f 6c  5d 3b 0a 0a 2f 2a 20 6e  |rans_col];../* n|
00006080  6f 77 20 63 61 6c 6c 20  6f 75 72 20 73 70 65 63  |ow call our spec|
00006090  69 61 6c 20 66 75 6e 63  74 69 6f 6e 20 77 68 69  |ial function whi|
000060a0  63 68 20 74 72 65 61 74  73 20 63 6f 6c 6f 72 20  |ch treats color |
000060b0  30 20 61 73 20 61 20 6d  61 73 6b 20 2a 2f 0a 0a  |0 as a mask */..|
000060c0  6f 75 72 6c 69 62 5f 73  6c 69 76 65 72 5f 6d 61  |ourlib_sliver_ma|
000060d0  73 6b 28 76 61 72 69 61  62 6c 65 73 29 3b 0a 0a  |sk(variables);..|
000060e0  7d 0a 65 6c 73 65 20 69  66 28 79 74 72 61 6e 73  |}.else if(ytrans|
000060f0  5f 64 6f 6e 65 20 26 26  20 79 74 72 61 6e 73 5f  |_done && ytrans_|
00006100  64 69 73 74 3c 64 69 73  74 5f 78 29 0a 7b 0a 20  |dist<dist_x).{. |
00006110  20 73 63 61 6c 65 3d 28  69 6e 74 29 28 28 63 6f  | scale=(int)((co|
00006120  73 5f 74 61 62 6c 65 5b  72 61 79 5d 3e 3e 31 36  |s_table[ray]>>16|
00006130  29 20 2a 20 28 72 65 63  69 70 5f 74 61 62 6c 65  |) * (recip_table|
00006140  5b 79 74 72 61 6e 73 5f  64 69 73 74 3e 3e 31 36  |[ytrans_dist>>16|
00006150  5d 29 3e 3e 31 36 29 3b  0a 20 20 76 61 72 69 61  |])>>16);.  varia|
00006160  62 6c 65 73 5b 33 5d 3d  73 63 61 6c 65 2d 31 3b  |bles[3]=scale-1;|
00006170  0a 20 20 76 61 72 69 61  62 6c 65 73 5b 34 5d 3d  |.  variables[4]=|
00006180  72 61 79 3b 0a 20 20 76  61 72 69 61 62 6c 65 73  |ray;.  variables|
00006190  5b 31 5d 3d 26 77 61 6c  6c 73 5b 79 74 72 61 6e  |[1]=&walls[ytran|
000061a0  73 5f 74 79 70 65 2b 31  5d 5b 79 74 72 61 6e 73  |s_type+1][ytrans|
000061b0  5f 63 6f 6c 5d 3b 0a 0a  2f 2a 20 6e 6f 77 20 63  |_col];../* now c|
000061c0  61 6c 6c 20 6f 75 72 20  73 70 65 63 69 61 6c 20  |all our special |
000061d0  66 75 6e 63 74 69 6f 6e  20 77 68 69 63 68 20 74  |function which t|
000061e0  72 65 61 74 73 20 63 6f  6c 6f 72 20 30 20 61 73  |reats color 0 as|
000061f0  20 61 20 6d 61 73 6b 20  2a 2f 0a 0a 6f 75 72 6c  | a mask */..ourl|
00006200  69 62 5f 73 6c 69 76 65  72 5f 6d 61 73 6b 28 76  |ib_sliver_mask(v|
00006210  61 72 69 61 62 6c 65 73  29 3b 0a 0a 7d 0a 0a 0a  |ariables);..}...|
00006220  0a 0a 2f 2a 20 74 68 69  73 20 72 61 79 20 68 61  |../* this ray ha|
00006230  73 20 62 65 65 6e 20 66  69 6e 69 73 68 65 64 2e  |s been finished.|
00006240  20 49 6e 63 72 65 61 73  65 20 74 68 65 20 61 6e  | Increase the an|
00006250  67 6c 65 20 6f 66 20 74  68 65 20 6e 65 78 74 20  |gle of the next |
00006260  72 61 79 20 61 6e 64 20  73 74 61 72 74 20 61 67  |ray and start ag|
00006270  61 69 6e 21 20 2a 2f 0a  0a 20 20 20 20 69 66 20  |ain! */..    if |
00006280  28 2b 2b 76 69 65 77 5f  61 6e 67 6c 65 3e 3d 41  |(++view_angle>=A|
00006290  4e 47 4c 45 5f 33 36 30  29 0a 20 20 20 20 20 20  |NGLE_360).      |
000062a0  20 7b 0a 20 20 20 20 20  20 20 2f 2a 20 74 68 69  | {.       /* thi|
000062b0  73 20 65 6e 73 75 72 65  73 20 74 68 61 74 20 74  |s ensures that t|
000062c0  68 65 20 72 61 79 20 61  6e 67 6c 65 20 64 6f 65  |he ray angle doe|
000062d0  73 6e 27 74 20 67 6f 20  6f 76 65 72 20 33 36 30  |sn't go over 360|
000062e0  20 64 65 67 72 65 65 73  21 20 2a 2f 0a 20 20 20  | degrees! */.   |
000062f0  20 20 20 20 76 69 65 77  5f 61 6e 67 6c 65 3d 30  |    view_angle=0|
00006300  3b 0a 0a 20 20 20 20 20  20 20 7d 0a 2f 2a 20 72  |;..       }./* r|
00006310  61 79 20 6c 6f 6f 70 20  2a 2f 0a 20 20 20 20 7d  |ay loop */.    }|
00006320  0a 2f 2a 20 65 6e 64 20  72 61 79 20 63 61 73 74  |./* end ray cast|
00006330  65 72 20 65 6e 67 69 6e  65 20 2a 2f 0a 2f 2a 20  |er engine */./* |
00006340  6f 62 6a 65 63 74 73 2a  2f 0a 7d 0a 0a 0a 0a 2f  |objects*/.}..../|
00006350  2a 20 74 68 69 73 20 66  75 6e 63 74 69 6f 6e 20  |* this function |
00006360  67 72 61 62 73 20 61 6c  6c 20 74 68 65 20 64 69  |grabs all the di|
00006370  66 66 65 72 65 6e 74 20  77 61 6c 6c 73 20 66 72  |fferent walls fr|
00006380  6f 6d 20 61 20 73 69 6e  67 6c 65 20 66 69 6c 65  |om a single file|
00006390  20 2a 2f 0a 0a 76 6f 69  64 20 61 75 61 5f 67 72  | */..void aua_gr|
000063a0  61 70 68 69 63 73 28 76  6f 69 64 29 0a 7b 0a 69  |aphics(void).{.i|
000063b0  6e 74 20 78 2c 20 2f 2a  20 74 68 69 73 20 69 73  |nt x, /* this is|
000063c0  20 75 73 65 64 20 74 6f  20 73 74 6f 72 65 20 74  | used to store t|
000063d0  68 65 20 78 20 63 6f 6f  72 64 69 6e 61 74 65 20  |he x coordinate |
000063e0  6f 66 20 61 20 70 6f 69  6e 74 20 6f 6e 20 74 68  |of a point on th|
000063f0  65 20 73 63 72 65 65 6e  20 2a 2f 0a 20 20 20 20  |e screen */.    |
00006400  79 2c 20 2f 2a 20 74 68  69 73 20 69 73 20 75 73  |y, /* this is us|
00006410  65 64 20 74 6f 20 73 74  6f 72 65 20 74 68 65 20  |ed to store the |
00006420  79 20 63 6f 6f 72 64 69  6e 61 74 65 20 6f 66 20  |y coordinate of |
00006430  61 20 70 6f 69 6e 74 20  6f 6e 20 74 68 65 20 73  |a point on the s|
00006440  63 72 65 65 6e 20 2a 2f  0a 20 20 20 20 77 61 6c  |creen */.    wal|
00006450  6c 5f 6e 75 6d 62 65 72  3b 20 2f 2a 20 74 68 69  |l_number; /* thi|
00006460  73 20 77 69 6c 6c 20 62  65 20 75 73 65 64 20 74  |s will be used t|
00006470  6f 20 69 6e 64 65 78 20  74 68 65 20 77 61 6c 6c  |o index the wall|
00006480  73 5b 78 5d 5b 5d 20 63  68 61 72 20 61 72 72 61  |s[x][] char arra|
00006490  79 20 2a 2f 0a 0a 2f 2a  20 66 69 72 73 74 20 6f  |y */../* first o|
000064a0  66 20 61 6c 6c 20 77 65  20 67 65 74 20 74 68 65  |f all we get the|
000064b0  20 67 72 61 70 68 69 63  73 20 66 69 6c 65 20 3c  | graphics file <|
000064c0  41 55 41 52 61 79 24 44  69 72 3e 2e 67 72 61 70  |AUARay$Dir>.grap|
000064d0  68 69 63 73 20 6f 6e 74  6f 20 74 68 65 20 73 63  |hics onto the sc|
000064e0  72 65 65 6e 20 2a 2f 0a  0a 73 79 73 74 65 6d 28  |reen */..system(|
000064f0  22 2a 53 63 72 65 65 6e  4c 6f 61 64 20 3c 41 55  |"*ScreenLoad <AU|
00006500  41 52 61 79 24 44 69 72  3e 2e 67 72 61 70 68 69  |ARay$Dir>.graphi|
00006510  63 73 22 29 3b 0a 0a 2f  2a 20 6e 65 78 74 20 77  |cs");../* next w|
00006520  65 20 73 74 61 72 74 20  67 72 61 62 62 69 6e 67  |e start grabbing|
00006530  20 65 61 63 68 20 74 69  6c 65 2c 20 36 34 20 78  | each tile, 64 x|
00006540  20 36 34 20 70 69 78 65  6c 73 2c 20 69 6e 74 6f  | 64 pixels, into|
00006550  20 74 68 65 20 77 61 6c  6c 73 5b 5d 5b 5d 20 61  | the walls[][] a|
00006560  72 72 61 79 20 2a 2f 0a  0a 2f 2a 20 77 65 20 75  |rray */../* we u|
00006570  73 65 20 74 68 69 73 20  6c 61 72 67 65 20 66 6f  |se this large fo|
00006580  72 20 6c 6f 6f 70 20 61  74 20 74 68 65 20 6f 75  |r loop at the ou|
00006590  72 6c 69 62 5f 62 69 74  6d 61 70 5f 67 72 61 62  |rlib_bitmap_grab|
000065a0  20 66 75 6e 63 74 69 6f  6e 20 74 6f 20 69 6e 76  | function to inv|
000065b0  69 64 75 61 6c 6c 79 20  67 72 61 62 20 65 61 63  |idually grab eac|
000065c0  68 20 74 69 6c 65 20 69  6e 74 6f 20 69 74 73 20  |h tile into its |
000065d0  6f 77 6e 20 77 61 6c 6c  73 5b 78 5d 5b 5d 20 61  |own walls[x][] a|
000065e0  72 72 61 79 20 73 6c 6f  74 2c 20 6e 6f 74 65 20  |rray slot, note |
000065f0  74 68 61 74 20 77 65 20  43 41 4e 27 54 20 48 41  |that we CAN'T HA|
00006600  56 45 20 57 41 4c 4c 20  30 20 61 73 20 74 68 69  |VE WALL 0 as thi|
00006610  73 20 72 65 70 72 65 73  65 6e 74 73 20 61 20 67  |s represents a g|
00006620  61 70 20 69 6e 20 74 68  65 20 77 6f 72 6c 64 21  |ap in the world!|
00006630  20 2a 2f 0a 0a 6f 75 72  6c 69 62 5f 6b 69 6c 6c  | */..ourlib_kill|
00006640  63 75 72 73 6f 72 28 29  3b 20 2f 2a 20 67 65 74  |cursor(); /* get|
00006650  20 72 69 64 20 6f 66 20  63 75 72 73 6f 72 20 66  | rid of cursor f|
00006660  69 72 73 74 20 2a 2f 0a  0a 66 6f 72 28 77 61 6c  |irst */..for(wal|
00006670  6c 5f 6e 75 6d 62 65 72  3d 31 2c 79 3d 30 3b 79  |l_number=1,y=0;y|
00006680  3c 32 35 36 2f 2a 53 43  52 45 45 4e 5f 48 45 49  |<256/*SCREEN_HEI|
00006690  47 48 54 2a 2f 3b 79 2b  3d 57 41 4c 4c 5f 48 45  |GHT*/;y+=WALL_HE|
000066a0  49 47 48 54 29 66 6f 72  28 78 3d 30 3b 78 3c 33  |IGHT)for(x=0;x<3|
000066b0  32 30 2f 2a 53 43 52 45  45 4e 5f 57 49 44 54 48  |20/*SCREEN_WIDTH|
000066c0  2a 2f 3b 78 2b 3d 57 41  4c 4c 5f 57 49 44 54 48  |*/;x+=WALL_WIDTH|
000066d0  2c 77 61 6c 6c 5f 6e 75  6d 62 65 72 2b 2b 29 0a  |,wall_number++).|
000066e0  7b 0a 2f 2a 20 74 68 69  73 20 63 61 6c 6c 73 20  |{./* this calls |
000066f0  74 68 65 20 66 75 6e 63  74 69 6f 6e 20 6f 75 72  |the function our|
00006700  6c 69 62 5f 62 69 74 6d  61 70 5f 67 72 61 62 20  |lib_bitmap_grab |
00006710  28 49 20 73 61 69 64 20  69 74 20 77 6f 75 6c 64  |(I said it would|
00006720  20 62 65 20 68 61 6e 64  79 21 29 20 77 68 69 63  | be handy!) whic|
00006730  68 20 67 72 61 62 73 20  74 68 65 20 61 72 65 61  |h grabs the area|
00006740  20 6f 66 20 73 63 72 65  65 6e 20 6d 65 6d 6f 72  | of screen memor|
00006750  79 20 6d 61 72 6b 65 64  20 62 79 20 74 68 65 20  |y marked by the |
00006760  66 69 72 73 74 20 66 6f  75 72 20 70 61 72 61 6d  |first four param|
00006770  65 74 65 72 73 2c 20 73  74 6f 72 65 73 20 69 74  |eters, stores it|
00006780  20 69 6e 20 74 68 65 20  62 79 74 65 20 61 72 72  | in the byte arr|
00006790  61 79 20 70 6f 69 6e 74  65 72 20 69 6e 20 70 61  |ay pointer in pa|
000067a0  72 61 6d 65 74 65 72 20  66 69 76 65 2c 20 72 65  |rameter five, re|
000067b0  61 64 69 6e 67 20 69 74  20 61 6c 6c 20 66 72 6f  |ading it all fro|
000067c0  6d 20 74 68 65 20 73 63  72 65 65 6e 20 70 6f 69  |m the screen poi|
000067d0  6e 74 65 64 20 74 6f 20  62 79 20 73 63 72 65 65  |nted to by scree|
000067e0  6e 5f 61 64 64 72 65 73  73 20 2a 2f 0a 0a 6f 75  |n_address */..ou|
000067f0  72 6c 69 62 5f 62 69 74  6d 61 70 5f 67 72 61 62  |rlib_bitmap_grab|
00006800  28 78 2c 79 2c 78 2b 57  41 4c 4c 5f 57 49 44 54  |(x,y,x+WALL_WIDT|
00006810  48 2d 31 2c 79 2b 57 41  4c 4c 5f 48 45 49 47 48  |H-1,y+WALL_HEIGH|
00006820  54 2d 31 2c 26 77 61 6c  6c 73 5b 77 61 6c 6c 5f  |T-1,&walls[wall_|
00006830  6e 75 6d 62 65 72 5d 5b  30 5d 2c 73 63 72 65 65  |number][0],scree|
00006840  6e 5f 61 64 64 72 65 73  73 29 3b 0a 0a 2f 2a 20  |n_address);../* |
00006850  74 68 69 73 20 6d 61 6b  65 73 20 73 75 72 65 20  |this makes sure |
00006860  77 65 20 64 6f 6e 27 74  20 67 6f 20 6f 76 65 72  |we don't go over|
00006870  20 6f 75 72 20 6e 75 6d  62 65 72 20 6f 66 20 77  | our number of w|
00006880  61 6c 6c 73 20 6c 69 6d  69 74 20 2a 2f 0a 0a 69  |alls limit */..i|
00006890  66 28 77 61 6c 6c 5f 6e  75 6d 62 65 72 3e 3d 57  |f(wall_number>=W|
000068a0  41 4c 4c 5f 4e 55 4d 42  45 52 29 62 72 65 61 6b  |ALL_NUMBER)break|
000068b0  3b 0a 7d 0a 0a 2f 2a 20  6e 65 77 20 73 74 75 66  |;.}../* new stuf|
000068c0  66 20 6c 6f 61 64 20 69  6e 20 6f 62 6a 65 63 74  |f load in object|
000068d0  73 20 73 65 70 61 72 61  74 65 6c 79 20 2a 2f 0a  |s separately */.|
000068e0  2f 2a 20 73 65 65 20 61  62 6f 76 65 20 66 6f 72  |/* see above for|
000068f0  20 63 6f 6d 6d 65 6e 74  73 20 28 69 74 73 20 69  | comments (its i|
00006900  64 65 6e 74 69 63 61 6c  29 20 2a 2f 0a 73 79 73  |dentical) */.sys|
00006910  74 65 6d 28 22 2a 53 63  72 65 65 6e 4c 6f 61 64  |tem("*ScreenLoad|
00006920  20 3c 41 55 52 61 79 24  44 69 72 3e 2e 4f 62 6a  | <AURay$Dir>.Obj|
00006930  67 72 61 70 68 69 63 22  29 3b 0a 6f 75 72 6c 69  |graphic");.ourli|
00006940  62 5f 6b 69 6c 6c 63 75  72 73 6f 72 28 29 3b 0a  |b_killcursor();.|
00006950  0a 66 6f 72 28 77 61 6c  6c 5f 6e 75 6d 62 65 72  |.for(wall_number|
00006960  3d 31 2c 79 3d 30 3b 79  3c 32 35 36 2f 2a 53 43  |=1,y=0;y<256/*SC|
00006970  52 45 45 4e 5f 48 45 49  47 48 54 2a 2f 3b 79 2b  |REEN_HEIGHT*/;y+|
00006980  3d 57 41 4c 4c 5f 48 45  49 47 48 54 29 66 6f 72  |=WALL_HEIGHT)for|
00006990  28 78 3d 30 3b 78 3c 33  32 30 2f 2a 53 43 52 45  |(x=0;x<320/*SCRE|
000069a0  45 4e 5f 57 49 44 54 48  2a 2f 3b 78 2b 3d 57 41  |EN_WIDTH*/;x+=WA|
000069b0  4c 4c 5f 57 49 44 54 48  2c 77 61 6c 6c 5f 6e 75  |LL_WIDTH,wall_nu|
000069c0  6d 62 65 72 2b 2b 29 0a  7b 0a 6f 75 72 6c 69 62  |mber++).{.ourlib|
000069d0  5f 62 69 74 6d 61 70 5f  67 72 61 62 28 78 2c 79  |_bitmap_grab(x,y|
000069e0  2c 78 2b 36 33 2c 79 2b  36 33 2c 26 6f 62 6a 67  |,x+63,y+63,&objg|
000069f0  72 61 70 68 69 63 73 5b  77 61 6c 6c 5f 6e 75 6d  |raphics[wall_num|
00006a00  62 65 72 5d 5b 30 5d 2c  73 63 72 65 65 6e 5f 61  |ber][0],screen_a|
00006a10  64 64 72 65 73 73 29 3b  0a 69 66 28 77 61 6c 6c  |ddress);.if(wall|
00006a20  5f 6e 75 6d 62 65 72 3e  57 41 4c 4c 5f 4e 55 4d  |_number>WALL_NUM|
00006a30  42 45 52 29 62 72 65 61  6b 3b 0a 7d 0a 0a 0a 7d  |BER)break;.}...}|
00006a40  0a 0a 2f 2a 20 74 68 69  73 20 66 75 6e 63 74 69  |../* this functi|
00006a50  6f 6e 20 6c 6f 61 64 73  20 69 6e 20 74 68 65 20  |on loads in the |
00006a60  64 61 74 61 20 66 72 6f  6d 20 6f 75 72 20 77 6f  |data from our wo|
00006a70  72 6c 64 20 74 65 78 74  20 66 69 6c 65 20 61 6e  |rld text file an|
00006a80  64 20 73 74 6f 72 65 73  20 69 74 20 69 6e 20 74  |d stores it in t|
00006a90  68 65 20 77 6f 72 6c 64  5b 5d 5b 5d 20 61 72 72  |he world[][] arr|
00006aa0  61 79 20 2a 2f 0a 0a 76  6f 69 64 20 61 75 61 5f  |ay */..void aua_|
00006ab0  77 6f 72 6c 64 28 76 6f  69 64 29 0a 7b 0a 0a 46  |world(void).{..F|
00006ac0  49 4c 45 20 2a 77 6f 72  6c 64 5f 66 69 6c 65 3b  |ILE *world_file;|
00006ad0  20 2f 2a 20 77 65 20 6e  65 65 64 20 61 20 66 69  | /* we need a fi|
00006ae0  6c 65 20 70 6f 69 6e 74  65 72 20 61 73 20 77 65  |le pointer as we|
00006af0  20 77 69 6c 6c 20 62 65  20 6c 6f 61 64 69 6e 67  | will be loading|
00006b00  20 69 6e 20 74 65 78 74  20 2a 2f 0a 0a 69 6e 74  | in text */..int|
00006b10  20 72 6f 77 2c 20 2f 2a  20 74 68 69 73 20 77 69  | row, /* this wi|
00006b20  6c 6c 20 62 65 20 75 73  65 64 20 74 6f 20 69 6e  |ll be used to in|
00006b30  64 65 78 20 74 68 65 20  77 6f 72 6c 64 5b 5d 5b  |dex the world[][|
00006b40  5d 20 61 72 72 61 79 20  2a 2f 0a 20 20 20 20 63  |] array */.    c|
00006b50  6f 6c 75 6d 6e 3b 20 2f  2a 20 74 68 69 73 20 77  |olumn; /* this w|
00006b60  69 6c 6c 20 62 65 20 75  73 65 64 20 74 6f 20 69  |ill be used to i|
00006b70  6e 64 65 78 20 74 68 65  20 77 6f 72 6c 64 5b 5d  |ndex the world[]|
00006b80  5b 5d 20 61 72 72 61 79  20 2a 2f 0a 0a 63 68 61  |[] array */..cha|
00006b90  72 20 63 68 3b 20 2f 2a  20 74 68 69 73 20 69 73  |r ch; /* this is|
00006ba0  20 75 73 65 64 20 74 6f  20 73 74 6f 72 65 20 65  | used to store e|
00006bb0  61 63 68 20 6e 75 6d 62  65 72 20 61 73 20 69 74  |ach number as it|
00006bc0  20 69 73 20 6c 6f 61 64  65 64 20 69 6e 20 2a 2f  | is loaded in */|
00006bd0  0a 0a 2f 2a 20 6f 70 65  6e 20 74 68 65 20 77 6f  |../* open the wo|
00006be0  72 6c 64 20 66 69 6c 65  2c 20 69 66 20 69 74 20  |rld file, if it |
00006bf0  69 73 20 6e 6f 74 20 74  68 65 72 65 20 74 68 65  |is not there the|
00006c00  6e 20 65 78 69 74 20 74  68 65 20 70 72 6f 67 72  |n exit the progr|
00006c10  61 6d 20 2a 2f 0a 0a 69  66 28 21 28 77 6f 72 6c  |am */..if(!(worl|
00006c20  64 5f 66 69 6c 65 3d 66  6f 70 65 6e 28 22 3c 41  |d_file=fopen("<A|
00006c30  55 41 52 61 79 24 44 69  72 3e 2e 77 6f 72 6c 64  |UARay$Dir>.world|
00006c40  22 2c 22 72 22 29 29 29  65 78 69 74 28 31 29 3b  |","r")))exit(1);|
00006c50  0a 0a 2f 2a 20 74 68 69  73 20 70 72 6f 67 72 61  |../* this progra|
00006c60  6d 20 6c 6f 61 64 73 20  69 6e 20 74 68 65 20 64  |m loads in the d|
00006c70  61 74 61 20 66 72 6f 6d  20 74 68 65 20 77 6f 72  |ata from the wor|
00006c80  6c 64 20 66 69 6c 65 2c  20 72 6f 77 20 62 79 20  |ld file, row by |
00006c90  72 6f 77 2c 20 63 6f 6c  75 6d 6e 20 62 79 20 63  |row, column by c|
00006ca0  6f 6c 75 6d 6e 20 75 73  69 6e 67 20 74 68 65 20  |olumn using the |
00006cb0  67 65 74 63 28 29 20 41  4e 53 49 20 66 75 6e 63  |getc() ANSI func|
00006cc0  74 69 6f 6e 20 2a 2f 0a  0a 66 6f 72 28 72 6f 77  |tion */..for(row|
00006cd0  3d 30 3b 72 6f 77 3c 57  4f 52 4c 44 5f 48 45 49  |=0;row<WORLD_HEI|
00006ce0  47 48 54 3b 72 6f 77 2b  2b 29 0a 7b 0a 66 6f 72  |GHT;row++).{.for|
00006cf0  28 63 6f 6c 75 6d 6e 3d  30 3b 63 6f 6c 75 6d 6e  |(column=0;column|
00006d00  3c 57 4f 52 4c 44 5f 57  49 44 54 48 3b 63 6f 6c  |<WORLD_WIDTH;col|
00006d10  75 6d 6e 2b 2b 29 0a 7b  0a 77 68 69 6c 65 28 28  |umn++).{.while((|
00006d20  63 68 3d 67 65 74 63 28  77 6f 72 6c 64 5f 66 69  |ch=getc(world_fi|
00006d30  6c 65 29 29 3d 3d 31 30  29 7b 7d 20 2f 2a 20 74  |le))==10){} /* t|
00006d40  68 69 73 20 66 69 6c 74  65 72 73 20 6f 75 74 20  |his filters out |
00006d50  61 6e 79 20 6d 65 73 73  2c 20 74 68 6f 75 67 68  |any mess, though|
00006d60  20 6e 6f 74 20 6f 66 74  65 6e 20 75 73 65 64 21  | not often used!|
00006d70  20 2a 2f 0a 0a 69 66 28  63 68 3d 3d 27 20 27 29  | */..if(ch==' ')|
00006d80  63 68 3d 30 3b 20 2f 2a  74 68 69 73 20 65 6e 73  |ch=0; /*this ens|
00006d90  75 72 65 73 20 74 68 65  20 63 6f 72 72 65 63 74  |ures the correct|
00006da0  20 76 61 6c 75 65 20 69  73 20 73 74 6f 72 65 64  | value is stored|
00006db0  2c 20 69 66 20 74 68 65  72 65 20 69 73 20 61 20  |, if there is a |
00006dc0  67 61 70 20 69 6e 20 74  68 65 20 66 69 6c 65 2c  |gap in the file,|
00006dd0  20 74 68 69 73 20 6d 65  61 6e 73 20 61 20 73 70  | this means a sp|
00006de0  61 63 65 20 69 6e 20 74  68 65 20 77 6f 72 6c 64  |ace in the world|
00006df0  2c 20 61 20 7a 65 72 6f  20 2a 2f 0a 65 6c 73 65  |, a zero */.else|
00006e00  20 63 68 3d 63 68 2d 27  30 27 3b 0a 0a 2f 2a 20  | ch=ch-'0';../* |
00006e10  74 68 69 73 20 6e 65 77  20 6c 69 6e 65 20 77 69  |this new line wi|
00006e20  6c 6c 20 28 73 68 6f 75  6c 64 21 29 20 63 6f 6e  |ll (should!) con|
00006e30  76 65 72 74 20 6c 65 74  74 65 72 73 20 69 6e 74  |vert letters int|
00006e40  6f 20 74 68 65 69 72 20  61 70 70 72 6f 70 72 69  |o their appropri|
00006e50  61 74 65 20 6e 75 6d 62  65 72 20 2a 2f 0a 0a 69  |ate number */..i|
00006e60  66 28 63 68 3e 31 36 29  63 68 2d 3d 36 3b 0a 0a  |f(ch>16)ch-=6;..|
00006e70  77 6f 72 6c 64 5b 28 57  4f 52 4c 44 5f 48 45 49  |world[(WORLD_HEI|
00006e80  47 48 54 2d 31 29 2d 72  6f 77 5d 5b 63 6f 6c 75  |GHT-1)-row][colu|
00006e90  6d 6e 5d 3d 63 68 3b 20  2f 2a 20 74 68 69 73 20  |mn]=ch; /* this |
00006ea0  66 69 6e 61 6c 6c 79 20  73 74 6f 72 65 73 20 74  |finally stores t|
00006eb0  68 65 20 76 61 6c 75 65  20 69 6e 20 74 68 65 20  |he value in the |
00006ec0  63 6f 72 72 65 63 74 20  70 6f 73 69 74 69 6f 6e  |correct position|
00006ed0  20 2a 2f 0a 0a 2f 2a 70  72 69 6e 74 66 28 22 25  | */../*printf("%|
00006ee0  64 22 2c 63 68 29 3b 20  75 6e 63 6f 6d 6d 65 6e  |d",ch); uncommen|
00006ef0  74 20 74 68 69 73 20 6c  69 6e 65 20 74 6f 20 73  |t this line to s|
00006f00  65 65 20 74 68 65 20 77  6f 72 6c 64 20 64 61 74  |ee the world dat|
00006f10  61 20 6c 6f 61 64 65 64  20 69 6e 20 2a 2f 0a 7d  |a loaded in */.}|
00006f20  0a 2f 2a 70 72 69 6e 74  66 28 22 5c 6e 22 29 3b  |./*printf("\n");|
00006f30  20 75 6e 63 6f 6d 6d 65  6e 74 20 74 68 69 73 20  | uncomment this |
00006f40  6c 69 6e 65 20 74 6f 20  73 65 65 20 74 68 65 20  |line to see the |
00006f50  77 6f 72 6c 64 20 64 61  74 61 20 6c 6f 61 64 65  |world data loade|
00006f60  64 20 69 6e 20 2a 2f 0a  7d 0a 0a 2f 2a 20 77 68  |d in */.}../* wh|
00006f70  65 6e 20 61 6c 6c 20 69  73 20 64 6f 6e 65 2c 20  |en all is done, |
00006f80  63 6c 6f 73 65 20 74 68  65 20 66 69 6c 65 20 2a  |close the file *|
00006f90  2f 0a 66 63 6c 6f 73 65  28 77 6f 72 6c 64 5f 66  |/.fclose(world_f|
00006fa0  69 6c 65 29 3b 0a 0a 2f  2a 20 6e 65 77 20 70 61  |ile);../* new pa|
00006fb0  72 74 20 74 6f 20 6c 6f  61 64 20 69 6e 20 6f 62  |rt to load in ob|
00006fc0  6a 65 63 74 20 64 61 74  61 2c 20 73 65 65 20 61  |ject data, see a|
00006fd0  62 6f 76 65 20 66 6f 72  20 63 6f 6d 6d 65 6e 74  |bove for comment|
00006fe0  73 20 2a 2f 0a 0a 69 66  28 21 28 77 6f 72 6c 64  |s */..if(!(world|
00006ff0  5f 66 69 6c 65 3d 66 6f  70 65 6e 28 22 3c 41 55  |_file=fopen("<AU|
00007000  41 52 61 79 24 44 69 72  3e 2e 6f 62 6a 77 6f 72  |ARay$Dir>.objwor|
00007010  6c 64 22 2c 22 72 22 29  29 29 20 65 78 69 74 28  |ld","r"))) exit(|
00007020  31 29 3b 0a 66 6f 72 28  72 6f 77 3d 30 3b 72 6f  |1);.for(row=0;ro|
00007030  77 3c 57 4f 52 4c 44 5f  48 45 49 47 48 54 3b 72  |w<WORLD_HEIGHT;r|
00007040  6f 77 2b 2b 29 0a 7b 0a  20 20 66 6f 72 28 63 6f  |ow++).{.  for(co|
00007050  6c 75 6d 6e 3d 30 3b 63  6f 6c 75 6d 6e 3c 57 4f  |lumn=0;column<WO|
00007060  52 4c 44 5f 57 49 44 54  48 3b 63 6f 6c 75 6d 6e  |RLD_WIDTH;column|
00007070  2b 2b 29 0a 20 20 7b 0a  20 20 77 68 69 6c 65 28  |++).  {.  while(|
00007080  28 63 68 3d 67 65 74 63  28 77 6f 72 6c 64 5f 66  |(ch=getc(world_f|
00007090  69 6c 65 29 29 3d 3d 31  30 29 7b 7d 0a 20 20 69  |ile))==10){}.  i|
000070a0  66 28 63 68 3d 3d 27 20  27 29 63 68 3d 30 3b 0a  |f(ch==' ')ch=0;.|
000070b0  20 20 65 6c 73 65 20 63  68 3d 63 68 2d 27 30 27  |  else ch=ch-'0'|
000070c0  3b 0a 20 20 69 66 28 63  68 3e 31 36 29 63 68 2d  |;.  if(ch>16)ch-|
000070d0  3d 36 3b 0a 20 20 6f 62  6a 65 63 74 73 5b 28 57  |=6;.  objects[(W|
000070e0  4f 52 4c 44 5f 48 45 49  47 48 54 2d 31 29 2d 72  |ORLD_HEIGHT-1)-r|
000070f0  6f 77 5d 5b 63 6f 6c 75  6d 6e 5d 3d 63 68 3b 0a  |ow][column]=ch;.|
00007100  20 20 7d 0a 7d 0a 66 63  6c 6f 73 65 28 77 6f 72  |  }.}.fclose(wor|
00007110  6c 64 5f 66 69 6c 65 29  3b 0a 0a 7d 0a 0a 0a 2f  |ld_file);..}.../|
00007120  2a 20 4e 45 57 45 52 20  4d 41 49 4e 20 66 75 6e  |* NEWER MAIN fun|
00007130  63 74 69 6f 6e 20 2e 0a  0a 41 6c 6c 20 63 68 61  |ction ...All cha|
00007140  6e 67 65 73 20 61 72 65  20 63 6f 6d 6d 65 6e 74  |nges are comment|
00007150  65 64 20 2a 2f 0a 0a 76  6f 69 64 20 6d 61 69 6e  |ed */..void main|
00007160  28 69 6e 74 20 61 72 67  63 2c 63 68 61 72 20 2a  |(int argc,char *|
00007170  61 72 67 76 5b 5d 29 0a  7b 0a 20 20 69 6e 74 20  |argv[]).{.  int |
00007180  76 69 65 77 5f 78 2c 20  2f 2a 20 74 68 69 73 20  |view_x, /* this |
00007190  68 6f 6c 64 73 20 74 68  65 20 76 69 65 77 69 6e  |holds the viewin|
000071a0  67 20 78 20 63 6f 6f 72  64 69 6e 61 74 65 20 2a  |g x coordinate *|
000071b0  2f 0a 20 20 20 20 20 20  76 69 65 77 5f 79 2c 20  |/.      view_y, |
000071c0  2f 2a 20 74 68 69 73 20  68 6f 6c 64 73 20 74 68  |/* this holds th|
000071d0  65 20 76 69 65 77 69 6e  67 20 79 20 63 6f 6f 72  |e viewing y coor|
000071e0  64 69 6e 61 74 65 20 2a  2f 0a 20 20 20 20 20 20  |dinate */.      |
000071f0  76 69 65 77 5f 61 6e 67  6c 65 3b 20 2f 2a 20 74  |view_angle; /* t|
00007200  68 69 73 20 68 6f 6c 64  73 20 74 68 65 20 76 69  |his holds the vi|
00007210  65 77 69 6e 67 20 61 6e  67 6c 65 20 69 6e 20 66  |ewing angle in f|
00007220  69 78 65 64 20 75 6e 69  74 73 20 30 2d 31 39 32  |ixed units 0-192|
00007230  30 20 2a 2f 0a 0a 20 20  69 6e 74 20 6b 65 79 5f  |0 */..  int key_|
00007240  70 72 65 73 73 2c 20 2f  2a 20 74 68 69 73 20 69  |press, /* this i|
00007250  73 20 75 73 65 64 20 74  6f 20 63 6f 6e 66 69 72  |s used to confir|
00007260  6d 20 69 6e 70 75 74 20  6f 66 20 76 61 6c 75 65  |m input of value|
00007270  73 20 2a 2f 0a 20 20 20  20 20 20 64 6f 6e 65 3d  |s */.      done=|
00007280  30 2c 20 20 20 20 2f 2a  20 66 6c 61 67 20 74 6f  |0,    /* flag to|
00007290  20 69 6e 64 69 63 61 74  65 20 69 66 20 74 68 65  | indicate if the|
000072a0  20 75 73 65 72 20 77 61  6e 74 73 20 74 6f 20 71  | user wants to q|
000072b0  75 69 74 20 2a 2f 0a 20  20 20 20 20 20 64 78 2c  |uit */.      dx,|
000072c0  20 20 20 20 20 20 20 20  2f 2a 20 6d 6f 76 65 6d  |        /* movem|
000072d0  65 6e 74 20 76 61 72 69  61 62 6c 65 73 20 66 6f  |ent variables fo|
000072e0  72 20 74 68 65 20 76 69  65 77 65 72 20 2a 2f 0a  |r the viewer */.|
000072f0  20 20 20 20 20 20 64 79  2c 0a 20 20 20 20 20 20  |      dy,.      |
00007300  79 5f 63 65 6c 6c 2c 20  20 20 20 2f 2a 20 74 68  |y_cell,    /* th|
00007310  65 73 65 20 4e 45 57 20  76 61 72 69 61 62 6c 65  |ese NEW variable|
00007320  73 20 61 72 65 20 75 73  65 64 20 74 6f 20 73 74  |s are used to st|
00007330  6f 72 65 20 74 68 65 20  70 6c 61 79 65 72 2f 76  |ore the player/v|
00007340  69 65 77 65 72 2a 2f 0a  20 20 20 20 20 20 78 5f  |iewer*/.      x_|
00007350  63 65 6c 6c 2c 20 20 20  20 2f 2a 20 77 6f 72 6c  |cell,    /* worl|
00007360  64 20 70 6f 73 69 74 69  6f 6e 73 2c 20 66 6f 72  |d positions, for|
00007370  20 63 61 6c 63 75 6c 61  74 69 6e 67 20 76 69 65  | calculating vie|
00007380  77 65 72 20 68 69 74 74  69 6e 67 20 77 61 6c 6c  |wer hitting wall|
00007390  73 20 2a 2f 0a 20 20 20  20 20 20 79 5f 73 75 62  |s */.      y_sub|
000073a0  5f 63 65 6c 6c 2c 0a 20  20 20 20 20 20 78 5f 73  |_cell,.      x_s|
000073b0  75 62 5f 63 65 6c 6c 2c  0a 20 20 20 20 20 20 74  |ub_cell,.      t|
000073c0  69 6d 65 5f 73 74 61 72  74 2c 0a 20 20 20 20 20  |ime_start,.     |
000073d0  20 74 69 6d 65 5f 66 69  6e 69 73 68 2c 20 2f 2a  | time_finish, /*|
000073e0  20 54 68 65 73 65 20 6c  61 73 74 20 66 65 77 20  | These last few |
000073f0  76 61 72 69 61 62 6c 65  73 20 61 72 65 20 75 73  |variables are us|
00007400  65 64 20 74 6f 20 77 6f  72 6b 20 6f 75 74 20 2a  |ed to work out *|
00007410  2f 0a 20 20 20 20 20 20  66 72 61 6d 65 73 3d 30  |/.      frames=0|
00007420  2c 20 20 20 20 2f 2a 20  74 68 65 20 66 72 61 6d  |,    /* the fram|
00007430  65 73 20 70 65 72 20 73  65 63 2e 20 6f 66 20 74  |es per sec. of t|
00007440  68 65 20 73 79 73 74 65  6d 2c 20 73 6c 6f 77 20  |he system, slow |
00007450  66 6f 72 20 6e 6f 77 21  20 2a 2f 0a 20 20 20 20  |for now! */.    |
00007460  20 20 64 6f 6f 72 5f 78  2c 0a 20 20 20 20 20 20  |  door_x,.      |
00007470  64 6f 6f 72 5f 79 3b 20  20 20 20 20 20 2f 2a 20  |door_y;      /* |
00007480  54 68 65 73 65 20 6e 65  77 20 76 61 72 69 61 62  |These new variab|
00007490  6c 65 73 20 77 69 6c 6c  20 62 65 20 75 73 65 64  |les will be used|
000074a0  20 66 6f 72 20 64 6f 6f  72 20 74 68 69 6e 67 73  | for door things|
000074b0  20 2a 2f 0a 0a 2f 2a 20  4e 45 57 20 73 79 73 74  | */../* NEW syst|
000074c0  65 6d 20 6f 66 20 70 61  73 73 69 6e 67 2c 20 77  |em of passing, w|
000074d0  65 20 75 73 65 20 74 68  65 20 73 74 61 6e 64 61  |e use the standa|
000074e0  72 64 20 61 72 67 63 20  61 6e 64 20 61 72 67 76  |rd argc and argv|
000074f0  20 74 6f 20 73 75 70 70  6c 79 20 70 61 72 61 6d  | to supply param|
00007500  65 74 65 72 73 20 74 6f  20 74 68 65 20 65 6e 67  |eters to the eng|
00007510  69 6e 65 2e 20 46 49 52  53 54 20 77 65 20 6d 75  |ine. FIRST we mu|
00007520  73 74 20 65 78 74 72 61  63 74 20 74 68 65 6d 3a  |st extract them:|
00007530  2a 2f 0a 0a 2f 2a 20 63  68 65 63 6b 20 74 68 61  |*/../* check tha|
00007540  74 20 63 6f 72 72 65 63  74 20 6e 75 6d 62 65 72  |t correct number|
00007550  20 6f 66 20 70 61 72 61  6d 65 74 65 72 73 20 68  | of parameters h|
00007560  61 76 65 20 62 65 65 6e  20 70 61 73 73 65 64 20  |ave been passed |
00007570  2a 2f 0a 0a 69 66 28 61  72 67 63 21 3d 38 29 0a  |*/..if(argc!=8).|
00007580  7b 0a 2f 2a 20 71 75 69  74 20 69 66 20 6e 6f 74  |{./* quit if not|
00007590  20 2a 2f 0a 70 72 69 6e  74 66 28 22 45 72 72 6f  | */.printf("Erro|
000075a0  72 3a 20 49 6e 63 6f 72  72 65 63 74 20 6e 75 6d  |r: Incorrect num|
000075b0  62 65 72 20 6f 66 20 70  61 72 61 6d 65 74 65 72  |ber of parameter|
000075c0  73 20 70 61 73 73 65 64  2e 20 5f 45 78 69 74 69  |s passed. _Exiti|
000075d0  6e 67 5c 6e 22 29 3b 20  65 78 69 74 28 31 29 3b  |ng\n"); exit(1);|
000075e0  0a 2f 2a 20 22 62 65 65  70 22 20 28 6f 6e 20 6d  |./* "beep" (on m|
000075f0  6f 73 74 20 6d 61 63 68  69 6e 65 73 29 2a 2f 20  |ost machines)*/ |
00007600  70 75 74 63 68 61 72 28  27 5c 61 27 29 3b 0a 7d  |putchar('\a');.}|
00007610  0a 2f 2a 20 75 73 65 20  61 74 6f 69 20 74 6f 20  |./* use atoi to |
00007620  67 65 74 20 69 74 20 72  69 67 68 74 20 2a 2f 0a  |get it right */.|
00007630  2f 2a 20 49 4e 50 55 54  20 41 4c 4c 20 56 41 4c  |/* INPUT ALL VAL|
00007640  55 45 53 20 46 52 4f 4d  20 43 4f 4d 4d 41 4e 44  |UES FROM COMMAND|
00007650  20 4c 49 4e 45 20 75 73  69 6e 67 20 41 54 4f 49  | LINE using ATOI|
00007660  20 61 6e 64 20 74 68 65  6e 20 77 6f 72 6b 20 6f  | and then work o|
00007670  75 74 20 6e 65 65 64 65  64 2a 2f 0a 2f 2a 20 61  |ut needed*/./* a|
00007680  6e 67 6c 65 20 76 61 6c  75 65 73 20 66 6f 72 20  |ngle values for |
00007690  74 68 65 20 72 61 79 20  63 61 73 74 69 6e 67 20  |the ray casting |
000076a0  65 6e 67 69 6e 65 2e 20  2a 2f 0a 76 69 65 77 5f  |engine. */.view_|
000076b0  78 3d 61 74 6f 69 28 61  72 67 76 5b 31 5d 29 3b  |x=atoi(argv[1]);|
000076c0  76 69 65 77 5f 79 3d 61  74 6f 69 28 61 72 67 76  |view_y=atoi(argv|
000076d0  5b 32 5d 29 3b 76 69 65  77 5f 61 6e 67 6c 65 3d  |[2]);view_angle=|
000076e0  61 74 6f 69 28 61 72 67  76 5b 33 5d 29 3b 0a 53  |atoi(argv[3]);.S|
000076f0  43 52 45 45 4e 5f 57 49  44 54 48 3d 61 74 6f 69  |CREEN_WIDTH=atoi|
00007700  28 61 72 67 76 5b 34 5d  29 3b 53 43 52 45 45 4e  |(argv[4]);SCREEN|
00007710  5f 48 45 49 47 48 54 3d  61 74 6f 69 28 61 72 67  |_HEIGHT=atoi(arg|
00007720  76 5b 35 5d 29 3b 0a 41  4e 47 4c 45 5f 33 36 30  |v[5]);.ANGLE_360|
00007730  3d 61 74 6f 69 28 61 72  67 76 5b 36 5d 29 3b 41  |=atoi(argv[6]);A|
00007740  4e 47 4c 45 5f 31 38 30  3d 41 4e 47 4c 45 5f 33  |NGLE_180=ANGLE_3|
00007750  36 30 2f 32 3b 41 4e 47  4c 45 5f 39 30 3d 41 4e  |60/2;ANGLE_90=AN|
00007760  47 4c 45 5f 31 38 30 2f  32 3b 0a 41 4e 47 4c 45  |GLE_180/2;.ANGLE|
00007770  5f 36 3d 28 69 6e 74 29  41 4e 47 4c 45 5f 33 36  |_6=(int)ANGLE_36|
00007780  30 2f 36 30 3b 41 4e 47  4c 45 5f 33 30 3d 28 69  |0/60;ANGLE_30=(i|
00007790  6e 74 29 41 4e 47 4c 45  5f 39 30 2f 33 3b 41 4e  |nt)ANGLE_90/3;AN|
000077a0  47 4c 45 5f 30 3d 30 3b  0a 41 4e 47 4c 45 5f 32  |GLE_0=0;.ANGLE_2|
000077b0  37 30 3d 41 4e 47 4c 45  5f 39 30 2a 33 3b 56 45  |70=ANGLE_90*3;VE|
000077c0  52 54 49 43 41 4c 5f 53  43 41 4c 45 3d 61 74 6f  |RTICAL_SCALE=ato|
000077d0  69 28 61 72 67 76 5b 37  5d 29 3b 0a 2f 2a 20 44  |i(argv[7]);./* D|
000077e0  4f 4e 45 2e 20 4e 6f 77  20 63 6f 6e 74 69 6e 75  |ONE. Now continu|
000077f0  65 20 61 73 20 6e 6f 72  6d 61 6c 20 77 69 74 68  |e as normal with|
00007800  20 74 68 65 20 70 72 6f  67 72 61 6d 20 2a 2f 0a  | the program */.|
00007810  0a 0a 2f 2a 20 6e 6f 77  20 77 65 20 63 61 6c 6c  |../* now we call|
00007820  20 61 75 61 5f 77 6f 72  6c 64 20 74 6f 20 6c 6f  | aua_world to lo|
00007830  61 64 20 69 6e 20 74 68  65 20 74 65 78 74 20 77  |ad in the text w|
00007840  6f 72 6c 64 20 66 69 6c  65 20 77 68 69 63 68 20  |orld file which |
00007850  64 65 66 69 6e 65 73 20  6f 75 72 20 77 61 6c 6c  |defines our wall|
00007860  73 20 74 79 70 65 20 61  6e 64 20 6c 61 79 6f 75  |s type and layou|
00007870  74 20 2a 2f 0a 0a 70 72  69 6e 74 66 28 22 6c 6f  |t */..printf("lo|
00007880  61 64 69 6e 67 20 69 6e  20 74 65 78 74 20 66 69  |ading in text fi|
00007890  6c 65 20 3c 41 55 41 52  61 79 24 44 69 72 3e 2e  |le <AUARay$Dir>.|
000078a0  77 6f 72 6c 64 5c 6e 22  29 3b 0a 61 75 61 5f 77  |world\n");.aua_w|
000078b0  6f 72 6c 64 28 29 3b 0a  0a 2f 2a 20 63 68 65 63  |orld();../* chec|
000078c0  6b 20 74 6f 20 73 65 65  20 69 66 20 74 68 65 20  |k to see if the |
000078d0  76 69 65 77 65 72 20 69  73 20 69 6e 73 69 64 65  |viewer is inside|
000078e0  20 61 20 67 61 6d 65 20  63 65 6c 6c 20 57 41 4c  | a game cell WAL|
000078f0  4c 2c 20 77 68 69 63 68  20 77 6f 75 6c 64 20 62  |L, which would b|
00007900  65 20 62 61 64 20 6e 65  77 73 21 20 2a 2f 0a 0a  |e bad news! */..|
00007910  69 66 28 77 6f 72 6c 64  5b 76 69 65 77 5f 79 3e  |if(world[view_y>|
00007920  3e 36 5d 5b 76 69 65 77  5f 78 3e 3e 36 5d 29 0a  |>6][view_x>>6]).|
00007930  7b 0a 20 20 70 72 69 6e  74 66 28 22 42 61 64 20  |{.  printf("Bad |
00007940  63 6f 6f 72 64 69 6e 61  74 65 73 20 67 69 76 65  |coordinates give|
00007950  6e 2c 20 76 69 65 77 65  72 20 69 73 20 49 4e 20  |n, viewer is IN |
00007960  61 20 57 41 4c 4c 21 2c  20 65 78 69 74 69 6e 67  |a WALL!, exiting|
00007970  5c 6e 22 29 3b 0a 20 20  65 78 69 74 28 31 29 3b  |\n");.  exit(1);|
00007980  0a 7d 0a 0a 2f 2a 20 6e  6f 77 20 77 65 20 63 61  |.}../* now we ca|
00007990  6c 6c 20 61 75 61 5f 74  61 62 6c 65 73 20 74 6f  |ll aua_tables to|
000079a0  20 67 65 6e 65 72 61 74  65 20 73 6f 6d 65 20 6c  | generate some l|
000079b0  6f 6f 6b 2d 75 70 20 74  61 62 6c 65 73 20 66 6f  |ook-up tables fo|
000079c0  72 20 74 68 65 20 65 6e  67 69 6e 65 20 74 6f 20  |r the engine to |
000079d0  75 73 65 2c 20 6c 6f 6f  6b 2d 75 70 73 20 61 72  |use, look-ups ar|
000079e0  65 20 65 78 70 6c 61 69  6e 65 64 20 75 70 20 61  |e explained up a|
000079f0  74 20 74 68 65 20 74 6f  70 20 6f 66 20 74 68 65  |t the top of the|
00007a00  20 66 69 6c 65 20 6e 65  78 74 20 74 6f 20 74 68  | file next to th|
00007a10  65 20 67 6c 6f 62 61 6c  20 76 61 72 69 61 62 6c  |e global variabl|
00007a20  65 73 20 2a 2f 0a 0a 70  72 69 6e 74 66 28 22 63  |es */..printf("c|
00007a30  61 6c 6c 69 6e 67 20 61  75 61 5f 74 61 62 6c 65  |alling aua_table|
00007a40  73 28 29 20 74 68 69 73  20 63 6f 75 6c 64 20 74  |s() this could t|
00007a50  61 6b 65 20 61 20 6c 6f  6e 67 20 74 69 6d 65 20  |ake a long time |
00007a60  6f 6e 20 73 6f 6d 65 20  6d 61 63 68 69 6e 65 73  |on some machines|
00007a70  5c 6e 22 29 3b 0a 2f 2a  20 6e 65 77 65 72 20 66  |\n");./* newer f|
00007a80  69 78 65 64 20 70 6f 69  6e 74 20 76 65 72 73 69  |ixed point versi|
00007a90  6f 6e 20 2a 2f 0a 61 75  61 5f 74 61 62 6c 65 73  |on */.aua_tables|
00007aa0  28 29 3b 0a 0a 2f 2a 20  61 6c 6c 20 69 73 20 64  |();../* all is d|
00007ab0  6f 6e 65 20 69 6e 20 74  65 72 6d 73 20 6f 66 20  |one in terms of |
00007ac0  69 6e 70 75 74 20 66 6f  72 20 6e 6f 77 2e 20 57  |input for now. W|
00007ad0  65 20 6e 65 65 64 20 74  6f 20 73 77 69 74 63 68  |e need to switch|
00007ae0  20 74 6f 20 4d 6f 64 65  20 31 33 20 2a 2f 0a 0a  | to Mode 13 */..|
00007af0  70 72 69 6e 74 66 28 22  53 77 69 74 63 68 69 6e  |printf("Switchin|
00007b00  67 20 74 6f 20 4d 6f 64  65 20 31 33 5c 6e 22 29  |g to Mode 13\n")|
00007b10  3b 0a 0a 2f 2a 20 63 61  6c 6c 20 6f 75 72 6c 69  |;../* call ourli|
00007b20  62 5f 63 68 61 6e 67 65  6d 6f 64 65 20 74 6f 20  |b_changemode to |
00007b30  73 77 69 74 63 68 20 74  6f 20 6d 6f 64 65 20 31  |switch to mode 1|
00007b40  33 20 2a 2f 0a 0a 6f 75  72 6c 69 62 5f 63 68 61  |3 */..ourlib_cha|
00007b50  6e 67 65 6d 6f 64 65 28  31 33 29 3b 0a 0a 2f 2a  |ngemode(13);../*|
00007b60  20 63 61 6c 6c 20 6f 75  72 6c 69 62 5f 66 69 6e  | call ourlib_fin|
00007b70  64 73 63 72 65 65 6e 20  74 6f 20 67 65 74 20 74  |dscreen to get t|
00007b80  68 65 20 73 63 72 65 65  6e 20 62 61 73 65 20 61  |he screen base a|
00007b90  64 64 72 65 73 73 20 6f  66 20 6d 6f 64 65 20 31  |ddress of mode 1|
00007ba0  33 2c 20 20 77 69 74 68  6f 75 74 20 74 68 65 20  |3,  without the |
00007bb0  63 6f 72 72 65 63 74 20  61 64 64 72 65 73 73 20  |correct address |
00007bc0  77 65 20 63 61 6e 27 74  20 64 72 61 77 20 61 6e  |we can't draw an|
00007bd0  79 74 68 69 6e 67 20 61  6e 64 20 74 68 65 20 63  |ything and the c|
00007be0  6f 6d 70 75 74 65 72 20  63 6f 75 6c 64 20 63 72  |omputer could cr|
00007bf0  61 73 68 20 2a 2f 0a 0a  73 63 72 65 65 6e 5f 61  |ash */..screen_a|
00007c00  64 64 72 65 73 73 3d 28  63 68 61 72 20 2a 29 6f  |ddress=(char *)o|
00007c10  75 72 6c 69 62 5f 66 69  6e 64 73 63 72 65 65 6e  |urlib_findscreen|
00007c20  28 29 3b 0a 2f 2a 20 4e  45 57 20 4c 4f 41 44 20  |();./* NEW LOAD |
00007c30  54 49 54 4c 45 20 53 43  52 45 45 4e 20 2a 2f 0a  |TITLE SCREEN */.|
00007c40  73 79 73 74 65 6d 28 22  2a 53 63 72 65 65 6e 4c  |system("*ScreenL|
00007c50  6f 61 64 20 3c 41 55 41  52 61 79 24 44 69 72 3e  |oad <AUARay$Dir>|
00007c60  2e 74 69 74 6c 65 22 29  3b 6f 75 72 6c 69 62 5f  |.title");ourlib_|
00007c70  6b 69 6c 6c 63 75 72 73  6f 72 28 29 3b 0a 6f 75  |killcursor();.ou|
00007c80  72 6c 69 62 5f 77 61 69  74 28 32 30 30 29 3b 0a  |rlib_wait(200);.|
00007c90  2f 2a 6f 75 72 6c 69 62  5f 73 63 72 65 65 6e 5f  |/*ourlib_screen_|
00007ca0  64 69 73 73 6f 6c 76 65  28 73 63 72 65 65 6e 5f  |dissolve(screen_|
00007cb0  61 64 64 72 65 73 73 2c  38 31 39 32 30 29 3b 20  |address,81920); |
00007cc0  55 53 45 20 49 46 20 57  41 4e 54 45 44 20 2a 2f  |USE IF WANTED */|
00007cd0  0a 0a 2f 2a 20 54 48 45  4e 20 57 41 49 54 20 54  |../* THEN WAIT T|
00007ce0  48 45 4e 20 53 43 52 45  45 4e 44 49 53 53 4f 4c  |HEN SCREENDISSOL|
00007cf0  56 45 20 4f 55 54 2c 20  73 65 65 20 61 62 6f 76  |VE OUT, see abov|
00007d00  65 20 2a 2f 0a 0a 2f 2a  20 6e 6f 77 20 77 65 20  |e */../* now we |
00007d10  6e 65 65 64 20 74 6f 20  2a 73 63 72 65 65 6e 6c  |need to *screenl|
00007d20  6f 61 64 20 6f 75 72 20  67 72 61 70 68 69 63 73  |oad our graphics|
00007d30  20 66 69 6c 65 2c 20 61  6e 64 20 67 72 61 62 20  | file, and grab |
00007d40  65 61 63 68 20 69 6e 64  69 76 69 64 75 61 6c 20  |each individual |
00007d50  77 61 6c 6c 20 67 72 61  70 68 69 63 20 6f 6e 65  |wall graphic one|
00007d60  20 62 79 20 6f 6e 65 2c  20 74 68 65 20 66 75 6e  | by one, the fun|
00007d70  63 74 69 6f 6e 20 61 75  61 5f 67 72 61 70 68 69  |ction aua_graphi|
00007d80  63 73 20 64 6f 65 73 20  74 68 69 73 20 2a 2f 0a  |cs does this */.|
00007d90  0a 61 75 61 5f 67 72 61  70 68 69 63 73 28 29 3b  |.aua_graphics();|
00007da0  0a 0a 0a 2f 2a 20 4e 4f  57 20 77 65 20 63 61 6c  |.../* NOW we cal|
00007db0  6c 20 73 65 74 75 70 5f  73 63 72 65 65 6e 73 2c  |l setup_screens,|
00007dc0  20 61 20 73 6d 61 6c 6c  20 66 75 6e 63 74 69 6f  | a small functio|
00007dd0  6e 20 77 68 69 63 68 20  68 65 6c 70 73 20 77 69  |n which helps wi|
00007de0  74 68 20 62 61 6e 6b 69  6e 67 20 2a 2f 0a 2f 2a  |th banking */./*|
00007df0  20 57 69 74 68 20 61 6c  6c 20 74 68 65 20 64 61  | With all the da|
00007e00  74 61 20 6c 6f 61 64 65  64 20 69 6e 20 77 65 20  |ta loaded in we |
00007e10  73 68 61 6c 6c 20 74 72  79 20 61 6e 64 20 69 6e  |shall try and in|
00007e20  69 74 69 61 74 65 20 53  43 52 45 45 4e 20 42 41  |itiate SCREEN BA|
00007e30  4e 4b 53 2e 20 46 69 72  73 74 20 77 65 20 63 68  |NKS. First we ch|
00007e40  61 6e 67 65 20 74 6f 20  4d 4f 44 45 20 31 35 2c  |ange to MODE 15,|
00007e50  20 73 6f 20 74 68 61 74  20 73 63 72 65 65 6e 20  | so that screen |
00007e60  6d 65 6d 6f 72 79 20 62  65 63 6f 6d 65 73 20 61  |memory becomes a|
00007e70  76 61 69 6c 61 62 6c 65  20 66 6f 72 20 74 77 6f  |vailable for two|
00007e80  20 74 69 6d 65 73 20 4d  4f 44 45 20 31 33 20 2a  | times MODE 13 *|
00007e90  2f 0a 0a 6f 75 72 6c 69  62 5f 73 65 74 75 70 5f  |/..ourlib_setup_|
00007ea0  73 63 72 65 65 6e 73 28  29 3b 0a 6f 75 72 6c 69  |screens();.ourli|
00007eb0  62 5f 63 68 61 6e 67 65  6d 6f 64 65 28 31 35 29  |b_changemode(15)|
00007ec0  3b 0a 0a 2f 2a 20 4e 6f  77 20 77 65 20 73 77 69  |;../* Now we swi|
00007ed0  74 63 68 20 74 6f 20 4d  4f 44 45 20 31 33 2c 20  |tch to MODE 13, |
00007ee0  61 6e 64 20 67 65 74 20  74 68 65 20 66 69 72 73  |and get the firs|
00007ef0  74 20 73 63 72 65 65 6e  20 61 64 64 72 65 73 73  |t screen address|
00007f00  20 2a 2f 0a 0a 6f 75 72  6c 69 62 5f 63 68 61 6e  | */..ourlib_chan|
00007f10  67 65 6d 6f 64 65 28 31  33 29 3b 0a 6f 75 72 6c  |gemode(13);.ourl|
00007f20  69 62 5f 6b 69 6c 6c 63  75 72 73 6f 72 28 29 3b  |ib_killcursor();|
00007f30  0a 2f 2a 6f 73 5f 63 6c  67 28 29 3b 2a 2f 0a 73  |./*os_clg();*/.s|
00007f40  63 72 65 65 6e 5f 61 64  64 72 65 73 73 3d 28 63  |creen_address=(c|
00007f50  68 61 72 20 2a 29 6f 75  72 6c 69 62 5f 66 69 6e  |har *)ourlib_fin|
00007f60  64 73 63 72 65 65 6e 28  29 3b 0a 0a 2f 2a 20 4e  |dscreen();../* N|
00007f70  6f 77 20 77 65 20 73 77  69 74 63 68 20 74 6f 20  |ow we switch to |
00007f80  74 68 65 20 6f 74 68 65  72 20 73 63 72 65 65 6e  |the other screen|
00007f90  20 62 61 6e 6b 20 61 6e  64 20 67 65 74 20 74 68  | bank and get th|
00007fa0  65 20 6f 74 68 65 72 20  73 63 72 65 65 6e 20 61  |e other screen a|
00007fb0  64 64 72 65 73 73 20 2a  2f 0a 0a 6f 75 72 6c 69  |ddress */..ourli|
00007fc0  62 5f 73 69 6d 70 6c 65  73 77 69 74 63 68 28 29  |b_simpleswitch()|
00007fd0  3b 0a 0a 73 63 72 65 65  6e 5f 61 64 64 72 65 73  |;..screen_addres|
00007fe0  73 5f 62 61 6e 6b 3d 28  63 68 61 72 20 2a 29 6f  |s_bank=(char *)o|
00007ff0  75 72 6c 69 62 5f 66 69  6e 64 73 63 72 65 65 6e  |urlib_findscreen|
00008000  28 29 3b 0a 6f 75 72 6c  69 62 5f 73 6c 6f 77 63  |();.ourlib_slowc|
00008010  6c 65 61 72 28 73 63 72  65 65 6e 5f 61 64 64 72  |lear(screen_addr|
00008020  65 73 73 5f 62 61 6e 6b  2c 38 31 39 32 30 2c 30  |ess_bank,81920,0|
00008030  29 3b 0a 6f 75 72 6c 69  62 5f 6b 69 6c 6c 63 75  |);.ourlib_killcu|
00008040  72 73 6f 72 28 29 3b 0a  2f 2a 20 53 77 69 74 63  |rsor();./* Switc|
00008050  68 20 62 61 63 6b 20 74  6f 20 74 68 65 20 6f 74  |h back to the ot|
00008060  68 65 72 20 73 63 72 65  65 6e 20 2a 2f 0a 0a 6f  |her screen */..o|
00008070  75 72 6c 69 62 5f 73 69  6d 70 6c 65 73 77 69 74  |urlib_simpleswit|
00008080  63 68 28 29 3b 0a 0a 2f  2a 20 4e 4f 57 20 77 65  |ch();../* NOW we|
00008090  20 63 61 6e 20 63 61 6c  6c 20 73 65 74 75 70 20  | can call setup |
000080a0  62 61 63 6b 67 72 6f 75  6e 64 2c 20 74 6f 20 74  |background, to t|
000080b0  65 6c 6c 20 74 68 65 20  73 63 72 65 65 6e 20 63  |ell the screen c|
000080c0  6c 65 61 72 65 72 20 74  68 65 20 63 6f 6c 6f 75  |learer the colou|
000080d0  72 20 6f 66 20 74 68 65  20 66 6c 6f 6f 72 20 61  |r of the floor a|
000080e0  6e 64 20 63 65 69 6c 69  6e 67 73 20 77 65 20 77  |nd ceilings we w|
000080f0  61 6e 74 2e 2a 2f 0a 0a  6f 75 72 6c 69 62 5f 73  |ant.*/..ourlib_s|
00008100  65 74 75 70 5f 62 61 63  6b 67 72 6f 75 6e 64 28  |etup_background(|
00008110  32 30 38 2c 34 35 29 3b  0a 0a 2f 2a 20 4e 4f 57  |208,45);../* NOW|
00008120  20 77 65 20 63 61 6e 20  73 74 61 72 74 20 74 68  | we can start th|
00008130  65 20 6d 61 69 6e 20 6c  6f 6f 70 2c 20 65 78 69  |e main loop, exi|
00008140  74 61 62 6c 65 20 6f 6e  6c 79 20 62 79 20 70 72  |table only by pr|
00008150  65 73 73 69 6e 67 20 74  68 65 20 51 20 6b 65 79  |essing the Q key|
00008160  2e 20 55 73 65 20 74 68  65 20 43 75 72 73 6f 72  |. Use the Cursor|
00008170  73 20 74 6f 20 6d 6f 76  65 20 74 68 65 20 76 69  |s to move the vi|
00008180  65 77 70 6f 69 6e 74 20  61 72 6f 75 6e 64 20 2a  |ewpoint around *|
00008190  2f 0a 2f 2a 20 57 65 20  73 68 61 6c 6c 20 61 6c  |/./* We shall al|
000081a0  73 6f 20 74 61 6b 65 20  61 20 72 65 61 64 69 6e  |so take a readin|
000081b0  67 20 74 6f 20 77 6f 72  6b 20 6f 75 74 20 74 68  |g to work out th|
000081c0  65 20 66 72 61 6d 65 20  72 61 74 65 20 6f 66 20  |e frame rate of |
000081d0  74 68 65 20 73 79 73 74  65 6d 2c 20 73 6c 6f 77  |the system, slow|
000081e0  20 66 6f 72 20 6e 6f 77  20 2a 2f 0a 0a 2f 2a 20  | for now */../* |
000081f0  4e 45 57 20 41 44 4a 55  53 54 49 4e 47 20 4c 49  |NEW ADJUSTING LI|
00008200  4e 45 53 20 3a 20 77 65  20 61 64 64 20 61 6e 20  |NES : we add an |
00008210  6f 66 66 73 65 74 20 74  6f 20 62 6f 74 68 20 73  |offset to both s|
00008220  63 72 65 65 6e 20 6d 65  6d 6f 72 79 20 61 72 65  |creen memory are|
00008230  61 73 20 69 6e 20 6f 72  64 65 72 20 74 6f 20 63  |as in order to c|
00008240  65 6e 74 72 65 20 74 68  65 20 69 6d 61 67 65 20  |entre the image |
00008250  69 6e 20 74 68 65 20 6d  69 64 64 6c 65 20 6f 66  |in the middle of|
00008260  20 74 68 65 20 73 63 72  65 65 6e 20 6e 6f 20 6d  | the screen no m|
00008270  61 74 74 65 72 20 77 68  61 74 20 73 69 7a 65 20  |atter what size |
00008280  2a 2f 0a 0a 73 63 72 65  65 6e 5f 61 64 64 72 65  |*/..screen_addre|
00008290  73 73 2b 3d 28 33 32 30  2d 53 43 52 45 45 4e 5f  |ss+=(320-SCREEN_|
000082a0  57 49 44 54 48 29 3e 3e  31 3b 0a 73 63 72 65 65  |WIDTH)>>1;.scree|
000082b0  6e 5f 61 64 64 72 65 73  73 5f 62 61 6e 6b 2b 3d  |n_address_bank+=|
000082c0  28 33 32 30 2d 53 43 52  45 45 4e 5f 57 49 44 54  |(320-SCREEN_WIDT|
000082d0  48 29 3e 3e 31 3b 0a 0a  6f 75 72 6c 69 62 5f 6b  |H)>>1;..ourlib_k|
000082e0  69 6c 6c 63 75 72 73 6f  72 28 29 3b 20 2f 2a 20  |illcursor(); /* |
000082f0  67 65 74 20 72 69 64 20  6f 66 20 74 68 65 20 63  |get rid of the c|
00008300  75 72 73 6f 72 20 66 6c  61 73 68 69 6e 67 20 61  |ursor flashing a|
00008310  77 61 79 20 2a 2f 0a 74  69 6d 65 5f 73 74 61 72  |way */.time_star|
00008320  74 3d 6f 75 72 6c 69 62  5f 67 65 74 74 69 6d 65  |t=ourlib_gettime|
00008330  28 29 3b 0a 0a 77 68 69  6c 65 28 21 64 6f 6e 65  |();..while(!done|
00008340  29 20 2f 2a 20 74 68 65  20 6c 6f 6f 70 20 77 69  |) /* the loop wi|
00008350  6c 6c 20 63 6f 6e 74 69  6e 75 65 20 75 6e 74 69  |ll continue unti|
00008360  6c 20 64 6f 6e 65 20 2a  2f 0a 7b 0a 0a 20 6f 75  |l done */.{.. ou|
00008370  72 6c 69 62 5f 66 61 73  74 63 6c 67 5f 74 77 6f  |rlib_fastclg_two|
00008380  28 73 63 72 65 65 6e 5f  61 64 64 72 65 73 73 2c  |(screen_address,|
00008390  53 43 52 45 45 4e 5f 57  49 44 54 48 2c 53 43 52  |SCREEN_WIDTH,SCR|
000083a0  45 45 4e 5f 48 45 49 47  48 54 29 3b 20 2f 2a 20  |EEN_HEIGHT); /* |
000083b0  77 65 20 63 61 6c 6c 20  74 68 65 20 66 6c 6f 6f  |we call the floo|
000083c0  72 2f 63 65 69 6c 69 6e  67 20 66 75 6e 63 74 69  |r/ceiling functi|
000083d0  6f 6e 20 74 6f 20 63 6f  6c 6f 75 72 20 74 68 65  |on to colour the|
000083e0  20 77 68 6f 6c 65 20 73  63 72 65 65 6e 20 2a 2f  | whole screen */|
000083f0  0a 2f 2a 20 74 68 65 6e  20 77 65 20 63 61 6c 6c  |./* then we call|
00008400  20 74 68 65 20 72 61 79  20 63 61 73 74 65 72 20  | the ray caster |
00008410  74 6f 20 64 72 61 77 20  6f 76 65 72 20 69 74 20  |to draw over it |
00008420  2a 2f 0a 20 20 61 75 61  5f 72 61 79 63 61 73 74  |*/.  aua_raycast|
00008430  65 72 28 76 69 65 77 5f  78 2c 76 69 65 77 5f 79  |er(view_x,view_y|
00008440  2c 76 69 65 77 5f 61 6e  67 6c 65 29 3b 0a 0a 2f  |,view_angle);../|
00008450  2a 20 72 65 73 65 74 20  74 68 65 20 76 61 72 69  |* reset the vari|
00008460  61 62 6c 65 73 20 66 6f  72 20 6d 6f 76 69 6e 67  |ables for moving|
00008470  20 74 68 65 20 76 69 65  77 70 6f 69 6e 74 20 2a  | the viewpoint *|
00008480  2f 0a 0a 64 78 3d 64 79  3d 30 3b 0a 0a 2f 2a 20  |/..dx=dy=0;../* |
00008490  6e 6f 77 20 77 65 20 74  65 73 74 20 66 6f 72 20  |now we test for |
000084a0  64 69 66 66 65 72 65 6e  74 20 6b 65 79 20 70 72  |different key pr|
000084b0  65 73 73 65 73 20 61 6e  64 20 74 61 6b 65 20 61  |esses and take a|
000084c0  63 74 69 6f 6e 20 61 63  63 6f 72 64 69 6e 67 6c  |ction accordingl|
000084d0  79 20 2a 2f 0a 0a 69 66  28 6f 75 72 6c 69 62 5f  |y */..if(ourlib_|
000084e0  6b 65 79 64 6f 77 6e 28  31 36 29 3d 3d 32 35 35  |keydown(16)==255|
000084f0  29 64 6f 6e 65 3d 31 3b  20 2f 2a 20 69 66 20 51  |)done=1; /* if Q|
00008500  20 69 73 20 70 72 65 73  73 65 64 20 74 68 65 6e  | is pressed then|
00008510  20 71 75 69 74 20 2a 2f  0a 0a 2f 2a 20 4c 45 46  | quit */../* LEF|
00008520  54 20 2a 2f 0a 69 66 28  6f 75 72 6c 69 62 5f 6b  |T */.if(ourlib_k|
00008530  65 79 64 6f 77 6e 28 31  32 31 29 3d 3d 32 35 35  |eydown(121)==255|
00008540  29 0a 7b 0a 20 20 69 66  28 28 76 69 65 77 5f 61  |).{.  if((view_a|
00008550  6e 67 6c 65 2d 3d 41 4e  47 4c 45 5f 36 29 3c 41  |ngle-=ANGLE_6)<A|
00008560  4e 47 4c 45 5f 30 29 0a  20 20 76 69 65 77 5f 61  |NGLE_0).  view_a|
00008570  6e 67 6c 65 3d 41 4e 47  4c 45 5f 33 36 30 3b 0a  |ngle=ANGLE_360;.|
00008580  7d 0a 0a 2f 2a 52 49 47  48 54 20 2a 2f 0a 69 66  |}../*RIGHT */.if|
00008590  28 6f 75 72 6c 69 62 5f  6b 65 79 64 6f 77 6e 28  |(ourlib_keydown(|
000085a0  32 35 29 3d 3d 32 35 35  29 0a 7b 0a 20 20 69 66  |25)==255).{.  if|
000085b0  28 28 76 69 65 77 5f 61  6e 67 6c 65 2b 3d 41 4e  |((view_angle+=AN|
000085c0  47 4c 45 5f 36 29 3e 41  4e 47 4c 45 5f 33 36 30  |GLE_6)>ANGLE_360|
000085d0  29 0a 20 20 76 69 65 77  5f 61 6e 67 6c 65 3d 41  |).  view_angle=A|
000085e0  4e 47 4c 45 5f 30 3b 0a  7d 0a 2f 2a 20 55 50 20  |NGLE_0;.}./* UP |
000085f0  61 6e 64 20 44 4f 57 4e  20 2a 2f 0a 69 66 28 6f  |and DOWN */.if(o|
00008600  75 72 6c 69 62 5f 6b 65  79 64 6f 77 6e 28 35 37  |urlib_keydown(57|
00008610  29 3d 3d 32 35 35 29 0a  7b 0a 20 20 64 78 3d 64  |)==255).{.  dx=d|
00008620  78 5f 74 61 62 6c 65 5b  76 69 65 77 5f 61 6e 67  |x_table[view_ang|
00008630  6c 65 5d 3b 0a 20 20 64  79 3d 64 79 5f 74 61 62  |le];.  dy=dy_tab|
00008640  6c 65 5b 76 69 65 77 5f  61 6e 67 6c 65 5d 3b 0a  |le[view_angle];.|
00008650  7d 0a 0a 69 66 28 6f 75  72 6c 69 62 5f 6b 65 79  |}..if(ourlib_key|
00008660  64 6f 77 6e 28 34 31 29  3d 3d 32 35 35 29 0a 7b  |down(41)==255).{|
00008670  0a 0a 20 20 64 78 3d 2d  64 78 5f 74 61 62 6c 65  |..  dx=-dx_table|
00008680  5b 76 69 65 77 5f 61 6e  67 6c 65 5d 3b 0a 20 20  |[view_angle];.  |
00008690  64 79 3d 2d 64 79 5f 74  61 62 6c 65 5b 76 69 65  |dy=-dy_table[vie|
000086a0  77 5f 61 6e 67 6c 65 5d  3b 0a 7d 0a 0a 2f 2a 20  |w_angle];.}../* |
000086b0  4e 4f 57 20 77 65 20 6e  65 65 64 20 74 6f 20 6d  |NOW we need to m|
000086c0  6f 76 65 20 74 68 65 20  70 6c 61 79 65 72 20 61  |ove the player a|
000086d0  6e 64 20 72 65 63 61 6c  63 75 6c 61 74 65 20 74  |nd recalculate t|
000086e0  68 65 20 63 65 6c 6c 20  74 68 65 20 76 69 65 77  |he cell the view|
000086f0  65 72 20 69 73 20 69 6e  2c 20 61 6e 64 20 41 4c  |er is in, and AL|
00008700  53 4f 20 63 68 65 63 6b  20 74 6f 20 73 65 65 20  |SO check to see |
00008710  69 66 20 74 68 65 20 70  6c 61 79 65 72 20 68 61  |if the player ha|
00008720  73 20 68 69 74 20 61 20  77 61 6c 6c 20 2a 2f 0a  |s hit a wall */.|
00008730  0a 2f 2a 20 57 61 74 63  68 20 66 6f 72 20 74 68  |./* Watch for th|
00008740  65 20 63 6f 6e 76 65 72  73 69 6f 6e 73 20 6f 66  |e conversions of|
00008750  20 66 69 78 65 64 20 70  6f 69 6e 74 20 61 6e 64  | fixed point and|
00008760  20 74 68 69 6e 67 73 20  2a 2f 0a 0a 2f 2a 20 50  | things */../* P|
00008770  6c 61 79 65 72 20 58 20  61 63 74 75 61 6c 6c 79  |layer X actually|
00008780  20 69 73 20 69 6e 20 6e  6f 72 6d 61 6c 20 6d 61  | is in normal ma|
00008790  74 68 73 20 2a 2f 0a 20  76 69 65 77 5f 78 3d 20  |ths */. view_x= |
000087a0  28 69 6e 74 29 28 28 76  69 65 77 5f 78 3c 3c 31  |(int)((view_x<<1|
000087b0  36 29 2b 64 78 29 3e 3e  31 36 3b 0a 20 76 69 65  |6)+dx)>>16;. vie|
000087c0  77 5f 79 3d 20 28 69 6e  74 29 28 28 76 69 65 77  |w_y= (int)((view|
000087d0  5f 79 3c 3c 31 36 29 2b  64 79 29 3e 3e 31 36 3b  |_y<<16)+dy)>>16;|
000087e0  0a 0a 2f 2a 20 4e 45 57  20 4f 50 54 49 4d 49 5a  |../* NEW OPTIMIZ|
000087f0  45 44 20 56 45 52 53 49  4f 4e 53 20 4f 46 20 4d  |ED VERSIONS OF M|
00008800  4f 56 49 4e 47 20 54 48  45 20 50 4c 41 59 45 52  |OVING THE PLAYER|
00008810  20 2a 2f 0a 0a 20 78 5f  63 65 6c 6c 20 3d 20 76  | */.. x_cell = v|
00008820  69 65 77 5f 78 3e 3e 36  3b 0a 20 79 5f 63 65 6c  |iew_x>>6;. y_cel|
00008830  6c 20 3d 20 76 69 65 77  5f 79 3e 3e 36 3b 0a 0a  |l = view_y>>6;..|
00008840  20 78 5f 73 75 62 5f 63  65 6c 6c 20 3d 20 76 69  | x_sub_cell = vi|
00008850  65 77 5f 78 20 26 20 30  78 30 30 33 66 3b 0a 20  |ew_x & 0x003f;. |
00008860  79 5f 73 75 62 5f 63 65  6c 6c 20 3d 20 76 69 65  |y_sub_cell = vie|
00008870  77 5f 79 20 26 20 30 78  30 30 33 66 3b 0a 0a 2f  |w_y & 0x003f;../|
00008880  2a 20 43 48 45 43 4b 20  74 6f 20 73 65 65 20 69  |* CHECK to see i|
00008890  66 20 70 6c 61 79 65 72  20 68 61 73 20 77 61 6c  |f player has wal|
000088a0  6b 65 64 20 69 6e 74 6f  20 77 61 6c 6c 73 20 2a  |ked into walls *|
000088b0  2f 0a 20 69 66 20 28 28  64 78 3e 3e 38 29 3e 30  |/. if ((dx>>8)>0|
000088c0  20 29 7b 0a 20 69 66 20  28 28 77 6f 72 6c 64 5b  | ){. if ((world[|
000088d0  79 5f 63 65 6c 6c 5d 5b  78 5f 63 65 6c 6c 2b 31  |y_cell][x_cell+1|
000088e0  5d 20 21 3d 20 30 29 20  20 26 26 20 28 78 5f 73  |] != 0)  && (x_s|
000088f0  75 62 5f 63 65 6c 6c 3e  28 43 45 4c 4c 5f 58 5f  |ub_cell>(CELL_X_|
00008900  53 49 5a 45 2d 43 4c 4f  53 45 53 54 29 29 29 0a  |SIZE-CLOSEST))).|
00008910  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00008920  7b 0a 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |{.              |
00008930  20 20 76 69 65 77 5f 78  2d 3d 20 28 78 5f 73 75  |  view_x-= (x_su|
00008940  62 5f 63 65 6c 6c 2d 28  43 45 4c 4c 5f 58 5f 53  |b_cell-(CELL_X_S|
00008950  49 5a 45 2d 43 4c 4f 53  45 53 54 20 29 29 3b 0a  |IZE-CLOSEST ));.|
00008960  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00008970  7d 0a 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |}.              |
00008980  20 20 7d 0a 20 65 6c 73  65 0a 20 7b 0a 20 69 66  |  }. else. {. if|
00008990  20 28 20 28 77 6f 72 6c  64 5b 79 5f 63 65 6c 6c  | ( (world[y_cell|
000089a0  5d 5b 78 5f 63 65 6c 6c  2d 31 5d 20 21 3d 20 30  |][x_cell-1] != 0|
000089b0  29 20 20 26 26 20 28 78  5f 73 75 62 5f 63 65 6c  |)  && (x_sub_cel|
000089c0  6c 20 3c 20 28 43 4c 4f  53 45 53 54 29 20 29 20  |l < (CLOSEST) ) |
000089d0  29 0a 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |).              |
000089e0  20 20 7b 0a 20 20 20 20  20 20 20 20 20 20 20 20  |  {.            |
000089f0  20 20 20 20 76 69 65 77  5f 78 2b 3d 20 28 43 4c  |    view_x+= (CL|
00008a00  4f 53 45 53 54 2d 78 5f  73 75 62 5f 63 65 6c 6c  |OSEST-x_sub_cell|
00008a10  29 20 3b 0a 20 20 20 20  20 20 20 20 20 20 20 20  |) ;.            |
00008a20  20 20 20 20 7d 0a 20 7d  0a 0a 20 69 66 20 28 28  |    }. }.. if ((|
00008a30  64 79 3e 3e 38 29 3e 30  20 29 7b 0a 20 69 66 20  |dy>>8)>0 ){. if |
00008a40  28 20 28 77 6f 72 6c 64  5b 28 79 5f 63 65 6c 6c  |( (world[(y_cell|
00008a50  2b 31 29 5d 5b 78 5f 63  65 6c 6c 5d 20 21 3d 20  |+1)][x_cell] != |
00008a60  30 29 20 20 26 26 0a 20  20 20 20 20 20 20 20 20  |0)  &&.         |
00008a70  20 20 20 20 20 20 20 28  79 5f 73 75 62 5f 63 65  |       (y_sub_ce|
00008a80  6c 6c 20 3e 20 28 43 45  4c 4c 5f 59 5f 53 49 5a  |ll > (CELL_Y_SIZ|
00008a90  45 2d 43 4c 4f 53 45 53  54 20 29 20 29 20 29 0a  |E-CLOSEST ) ) ).|
00008aa0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00008ab0  7b 0a 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |{.              |
00008ac0  20 20 76 69 65 77 5f 79  2d 3d 20 28 79 5f 73 75  |  view_y-= (y_su|
00008ad0  62 5f 63 65 6c 6c 2d 28  43 45 4c 4c 5f 59 5f 53  |b_cell-(CELL_Y_S|
00008ae0  49 5a 45 2d 43 4c 4f 53  45 53 54 20 29 29 3b 0a  |IZE-CLOSEST ));.|
00008af0  20 20 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |                |
00008b00  7d 0a 20 20 20 20 20 20  20 20 20 20 20 20 20 20  |}.              |
00008b10  20 20 7d 0a 20 65 6c 73  65 0a 20 7b 0a 20 69 66  |  }. else. {. if|
00008b20  20 28 20 28 77 6f 72 6c  64 5b 28 79 5f 63 65 6c  | ( (world[(y_cel|
00008b30  6c 2d 31 29 5d 5b 78 5f  63 65 6c 6c 5d 20 21 3d  |l-1)][x_cell] !=|
00008b40  20 30 29 20 20 26 26 20  28 79 5f 73 75 62 5f 63  | 0)  && (y_sub_c|
00008b50  65 6c 6c 20 3c 20 28 43  4c 4f 53 45 53 54 29 20  |ell < (CLOSEST) |
00008b60  29 20 29 0a 20 20 20 20  20 20 20 20 20 20 20 20  |) ).            |
00008b70  20 20 20 20 7b 0a 20 20  20 20 20 20 20 20 20 20  |    {.          |
00008b80  20 20 20 20 20 20 76 69  65 77 5f 79 2b 3d 20 28  |      view_y+= (|
00008b90  43 4c 4f 53 45 53 54 2d  79 5f 73 75 62 5f 63 65  |CLOSEST-y_sub_ce|
00008ba0  6c 6c 29 3b 0a 20 20 20  20 20 20 20 20 20 20 20  |ll);.           |
00008bb0  20 20 20 20 20 7d 0a 20  7d 0a 0a 0a 0a 2f 2a 20  |     }. }..../* |
00008bc0  4e 45 57 20 44 4f 4f 52  20 63 6f 64 65 2e 20 41  |NEW DOOR code. A|
00008bd0  20 22 70 72 6f 62 65 22  20 69 73 20 73 65 6e 74  | "probe" is sent|
00008be0  20 6f 75 74 20 69 6e 20  66 72 6f 6e 74 20 6f 66  | out in front of|
00008bf0  20 74 68 65 20 70 6c 61  79 65 72 2c 20 69 66 20  | the player, if |
00008c00  61 20 64 6f 6f 72 20 74  69 6c 65 20 69 73 20 66  |a door tile is f|
00008c10  6f 75 6e 64 20 6e 65 61  72 20 69 74 20 74 68 65  |ound near it the|
00008c20  6e 20 74 68 65 20 62 6c  6f 63 6b 20 69 73 20 64  |n the block is d|
00008c30  65 73 74 72 6f 79 65 64  2e 20 2a 2f 0a 0a 69 66  |estroyed. */..if|
00008c40  28 6f 75 72 6c 69 62 5f  6b 65 79 64 6f 77 6e 28  |(ourlib_keydown(|
00008c50  39 38 29 3d 3d 32 35 35  29 0a 7b 0a 2f 2a 20 55  |98)==255).{./* U|
00008c60  73 65 20 73 69 6d 69 6c  61 72 20 74 65 63 68 6e  |se similar techn|
00008c70  69 71 75 65 73 20 74 6f  20 61 62 6f 76 65 20 74  |iques to above t|
00008c80  6f 20 66 69 6e 64 20 64  6f 6f 72 20 2a 2f 0a 0a  |o find door */..|
00008c90  64 78 3d 64 78 5f 74 61  62 6c 65 5b 76 69 65 77  |dx=dx_table[view|
00008ca0  5f 61 6e 67 6c 65 5d 3b  0a 64 79 3d 64 79 5f 74  |_angle];.dy=dy_t|
00008cb0  61 62 6c 65 5b 76 69 65  77 5f 61 6e 67 6c 65 5d  |able[view_angle]|
00008cc0  3b 0a 0a 2f 2a 20 43 61  6c 63 75 6c 61 74 65 20  |;../* Calculate |
00008cd0  64 6f 6f 72 20 78 20 61  6e 64 20 79 2c 20 69 74  |door x and y, it|
00008ce0  20 69 73 20 69 6e 20 6e  6f 72 6d 61 6c 20 6d 61  | is in normal ma|
00008cf0  74 68 73 20 2a 2f 0a 20  64 6f 6f 72 5f 78 3d 20  |ths */. door_x= |
00008d00  28 69 6e 74 29 28 28 76  69 65 77 5f 78 3c 3c 31  |(int)((view_x<<1|
00008d10  36 29 2b 28 64 78 3c 3c  33 29 29 3e 3e 31 36 3b  |6)+(dx<<3))>>16;|
00008d20  0a 20 64 6f 6f 72 5f 79  3d 20 28 69 6e 74 29 28  |. door_y= (int)(|
00008d30  28 76 69 65 77 5f 79 3c  3c 31 36 29 2b 28 64 79  |(view_y<<16)+(dy|
00008d40  3c 3c 33 29 29 3e 3e 31  36 3b 0a 0a 2f 2a 20 4e  |<<3))>>16;../* N|
00008d50  45 57 20 4f 50 54 49 4d  49 5a 45 44 20 56 45 52  |EW OPTIMIZED VER|
00008d60  53 49 4f 4e 53 20 4f 46  20 46 49 4e 44 49 4e 20  |SIONS OF FINDIN |
00008d70  44 4f 4f 52 53 20 2a 2f  0a 2f 2a 20 6e 6f 77 20  |DOORS */./* now |
00008d80  66 69 6e 64 20 74 68 65  20 63 65 6c 6c 20 77 65  |find the cell we|
00008d90  20 61 72 65 20 6c 6f 6f  6b 69 6e 67 20 69 6e 20  | are looking in |
00008da0  77 69 74 68 20 74 68 65  20 73 74 61 6e 64 61 72  |with the standar|
00008db0  64 20 65 71 75 61 74 69  6f 6e 20 2a 2f 0a 0a 20  |d equation */.. |
00008dc0  78 5f 63 65 6c 6c 20 3d  20 28 69 6e 74 29 64 6f  |x_cell = (int)do|
00008dd0  6f 72 5f 78 3e 3e 36 3b  0a 20 79 5f 63 65 6c 6c  |or_x>>6;. y_cell|
00008de0  20 3d 20 28 69 6e 74 29  64 6f 6f 72 5f 79 3e 3e  | = (int)door_y>>|
00008df0  36 3b 0a 0a 2f 2a 20 43  68 65 63 6b 20 69 66 20  |6;../* Check if |
00008e00  61 20 64 6f 6f 72 73 20  69 73 20 70 72 65 73 65  |a doors is prese|
00008e10  6e 74 20 2a 2f 0a 0a 69  66 28 77 6f 72 6c 64 5b  |nt */..if(world[|
00008e20  79 5f 63 65 6c 6c 5d 5b  78 5f 63 65 6c 6c 5d 3d  |y_cell][x_cell]=|
00008e30  3d 37 20 2f 2a 20 4f 52  20 57 48 41 54 45 56 45  |=7 /* OR WHATEVE|
00008e40  52 20 59 4f 55 20 4c 49  4b 45 20 2a 2f 29 0a 7b  |R YOU LIKE */).{|
00008e50  0a 77 6f 72 6c 64 5b 79  5f 63 65 6c 6c 5d 5b 78  |.world[y_cell][x|
00008e60  5f 63 65 6c 6c 5d 3d 30  3b 20 2f 2a 20 6f 72 20  |_cell]=0; /* or |
00008e70  61 6c 74 65 72 6e 61 74  69 76 65 6c 79 20 64 6f  |alternatively do|
00008e80  20 77 68 61 74 20 79 6f  75 20 6c 69 6b 65 20 2a  | what you like *|
00008e90  2f 0a 7d 0a 7d 0a 0a 0a  0a 0a 2f 2a 20 50 48 45  |/.}.}...../* PHE|
00008ea0  57 21 20 4e 6f 77 20 77  65 20 63 61 6e 20 77 61  |W! Now we can wa|
00008eb0  69 74 20 66 6f 72 20 61  20 76 79 73 6e 63 20 61  |it for a vysnc a|
00008ec0  6e 64 20 74 68 65 6e 20  73 77 69 74 63 68 20 74  |nd then switch t|
00008ed0  68 65 20 76 69 65 77 73  2f 62 61 6e 6b 73 20 6f  |he views/banks o|
00008ee0  76 65 72 20 6f 74 20 20  70 72 6f 64 75 63 65 20  |ver ot  produce |
00008ef0  66 6c 69 63 6b 65 72 2d  66 72 65 65 20 61 6e 69  |flicker-free ani|
00008f00  6d 61 74 69 6f 6e 20 2a  2f 0a 6f 75 72 6c 69 62  |mation */.ourlib|
00008f10  5f 77 61 69 74 76 73 79  6e 63 28 29 3b 0a 6f 75  |_waitvsync();.ou|
00008f20  72 6c 69 62 5f 73 69 6d  70 6c 65 73 77 69 74 63  |rlib_simpleswitc|
00008f30  68 28 29 3b 0a 0a 2f 2a  20 57 65 20 61 6c 73 6f  |h();../* We also|
00008f40  20 68 61 76 65 20 74 6f  20 73 77 69 74 63 68 20  | have to switch |
00008f50  74 68 65 20 6d 65 6d 6f  72 79 20 61 64 64 72 65  |the memory addre|
00008f60  73 73 65 73 20 61 72 6f  75 6e 64 20 73 6f 20 6f  |sses around so o|
00008f70  75 72 20 66 75 6e 63 74  69 6f 6e 73 20 64 72 61  |ur functions dra|
00008f80  77 20 74 6f 20 74 68 65  20 63 6f 72 72 65 63 74  |w to the correct|
00008f90  20 6d 65 6d 6f 72 79 20  2a 2f 0a 0a 73 63 72 65  | memory */..scre|
00008fa0  65 6e 5f 61 64 64 72 65  73 73 5f 74 65 6d 70 3d  |en_address_temp=|
00008fb0  73 63 72 65 65 6e 5f 61  64 64 72 65 73 73 5f 62  |screen_address_b|
00008fc0  61 6e 6b 3b 0a 73 63 72  65 65 6e 5f 61 64 64 72  |ank;.screen_addr|
00008fd0  65 73 73 5f 62 61 6e 6b  3d 73 63 72 65 65 6e 5f  |ess_bank=screen_|
00008fe0  61 64 64 72 65 73 73 3b  0a 73 63 72 65 65 6e 5f  |address;.screen_|
00008ff0  61 64 64 72 65 73 73 3d  73 63 72 65 65 6e 5f 61  |address=screen_a|
00009000  64 64 72 65 73 73 5f 74  65 6d 70 3b 0a 0a 2f 2a  |ddress_temp;../*|
00009010  20 61 64 64 20 6f 6e 65  20 74 6f 20 74 68 65 20  | add one to the |
00009020  66 72 61 6d 65 73 20 63  6f 75 6e 74 2c 20 77 65  |frames count, we|
00009030  20 61 72 65 20 63 6f 75  6e 74 69 6e 67 20 74 68  | are counting th|
00009040  65 20 6e 75 6d 62 65 72  20 6f 66 20 66 72 61 6d  |e number of fram|
00009050  65 73 20 67 65 6e 65 72  61 74 65 64 20 20 2a 2f  |es generated  */|
00009060  0a 66 72 61 6d 65 73 2b  2b 3b 0a 7d 0a 2f 2a 20  |.frames++;.}./* |
00009070  72 65 63 6f 72 64 20 74  68 65 20 74 69 6d 65 20  |record the time |
00009080  73 74 6f 70 70 65 64 20  2a 2f 0a 0a 74 69 6d 65  |stopped */..time|
00009090  5f 66 69 6e 69 73 68 3d  6f 75 72 6c 69 62 5f 67  |_finish=ourlib_g|
000090a0  65 74 74 69 6d 65 28 29  3b 0a 0a 2f 2a 20 74 61  |ettime();../* ta|
000090b0  6b 65 20 61 20 73 63 72  65 65 6e 73 68 6f 74 2c  |ke a screenshot,|
000090c0  20 75 73 69 6e 67 20 2a  73 63 72 65 65 6e 20 73  | using *screen s|
000090d0  61 76 65 2c 20 61 6e 64  20 73 61 76 65 20 69 74  |ave, and save it|
000090e0  20 69 6e 73 69 64 65 20  74 68 65 20 64 69 72 65  | inside the dire|
000090f0  63 74 6f 72 79 20 2a 2f  0a 0a 73 79 73 74 65 6d  |ctory */..system|
00009100  28 22 2a 53 63 72 65 65  6e 53 61 76 65 20 3c 41  |("*ScreenSave <A|
00009110  55 41 52 61 79 24 44 69  72 3e 2e 73 63 72 73 68  |UARay$Dir>.scrsh|
00009120  6f 74 22 29 3b 0a 0a 2f  2a 20 63 6c 6f 73 65 20  |ot");../* close |
00009130  64 6f 77 6e 20 74 68 65  20 73 63 72 65 65 6e 73  |down the screens|
00009140  20 75 73 69 6e 67 20 61  6e 20 6f 75 72 6c 69 62  | using an ourlib|
00009150  20 66 75 6e 63 74 69 6f  6e 20 2a 2f 0a 0a 6f 75  | function */..ou|
00009160  72 6c 69 62 5f 63 6c 6f  73 65 64 6f 77 6e 5f 73  |rlib_closedown_s|
00009170  63 72 65 65 6e 73 28 29  3b 0a 0a 2f 2a 20 63 68  |creens();../* ch|
00009180  61 6e 67 65 20 74 6f 20  6d 6f 64 65 20 31 35 20  |ange to mode 15 |
00009190  61 6e 64 20 62 72 69 6e  67 20 62 61 63 6b 20 74  |and bring back t|
000091a0  68 65 20 63 75 72 73 6f  72 20 6a 75 73 74 20 69  |he cursor just i|
000091b0  6e 20 63 61 73 65 20 2a  2f 0a 0a 6f 75 72 6c 69  |n case */..ourli|
000091c0  62 5f 63 68 61 6e 67 65  6d 6f 64 65 28 31 35 29  |b_changemode(15)|
000091d0  3b 0a 6f 75 72 6c 69 62  5f 72 65 76 69 76 65 63  |;.ourlib_revivec|
000091e0  75 72 73 6f 72 28 29 3b  0a 0a 2f 2a 20 70 72 69  |ursor();../* pri|
000091f0  6e 74 20 74 68 65 20 63  61 6c 63 75 6c 61 74 69  |nt the calculati|
00009200  6f 6e 20 61 6e 64 20 6f  74 68 65 72 20 69 6e 66  |on and other inf|
00009210  6f 2e 20 2a 2f 0a 70 72  69 6e 74 66 28 22 2a 2a  |o. */.printf("**|
00009220  2a 2a 2a 2a 2a 20 46 52  41 4d 45 53 20 50 45 52  |***** FRAMES PER|
00009230  20 53 45 43 4f 4e 44 20  2a 2a 2a 2a 2a 2a 2a 2a  | SECOND ********|
00009240  5c 6e 25 66 22 2c 28 66  6c 6f 61 74 29 66 72 61  |\n%f",(float)fra|
00009250  6d 65 73 2f 28 66 6c 6f  61 74 29 28 28 74 69 6d  |mes/(float)((tim|
00009260  65 5f 66 69 6e 69 73 68  2d 74 69 6d 65 5f 73 74  |e_finish-time_st|
00009270  61 72 74 29 2f 31 30 30  29 29 3b 0a 7d 0a 0a     |art)/100));.}..|
0000927f