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

3D/Files/!AUA_ray/source/c/engine

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

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

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

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

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

AUThreeD@aol.com

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

/* ANSI C includes */

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

/* OTHER includes */

#include "our_lib.h"

/* DEFINES */

#define WORLD_WIDTH 64 /* This is the number of walls across in our world */
#define WORLD_HEIGHT 64 /* This is the number of walls down in our world */
#define WALL_WIDTH 64 /* This is the width of each wall in pixels */
#define WALL_HEIGHT 64 /* This is the height of each wall in pixels */
#define WALL_NUMBER 20 /* This defines the number of walls allowed */
#define SCREEN_WIDTH 320 /* This is the width of the mode 13 screen */
#define SCREEN_HEIGHT 256 /* This is the height of the mode 13 screen */
#define CELL_X_SIZE 64 /* this is the size in units of each cell */
#define CELL_Y_SIZE 64 /* this is the size in units of each cell */
#define CELL_X_SIZE_FP 6 /* this is used in binary shifting */
#define CELL_Y_SIZE_FP 6 /* this is used in binary shifting */
#define FOUND_WALL 1 /* this flag is used to indicate when an intersection has be found */

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

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


/* GLOBAL variables */

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

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

char *screen_address; /* this will hold the base of the screen memory which we will manipulate. By altering values in the screen memory, we alter what appears on the screen. Note that this is of type "char *" because it holds the memory address of a byte array - the 256 colour mode 13 screen (well it will do!) */


/* these FLOATING point (urgh!) 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() */

float *tan_table,*inv_tan_table; /* pointers to tangent look_ups */
float *y_step,*x_step;           /* pointers to more complex look_ups */
float *inv_cos_table,            /* sin/cos tables (look_ups)    */
      *inv_sin_table;
float *cos_table;                /* cosinal look_up table    */


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

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

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

cos_table     = (float  *)malloc(sizeof(long) * (ANGLE_360+1));
inv_cos_table = (float  *)malloc(sizeof(float) * (ANGLE_360+1));
inv_sin_table = (float  *)malloc(sizeof(float) * (ANGLE_360+1));

/* generate them, their use is explained in the ray casting engine */

for(angt=ANGLE_0;angt<=ANGLE_360;angt++)
{
ang=angt;
rad_angle=(float)((3.272e-4) + ang * 2*3.141592654/ANGLE_360);

tan_table[ang]=(float)tan(rad_angle);
inv_tan_table[ang]=(float)(1/tan(rad_angle));
if(ang>=ANGLE_0 && ang<ANGLE_180)
{
y_step[ang]=(float)(fabs(tan(rad_angle) * CELL_Y_SIZE));
}
else
  y_step[ang]=(float)(-fabs(tan(rad_angle) * CELL_Y_SIZE));
if(ang>=ANGLE_90 && ang<ANGLE_270)
{
x_step[ang]=(float)(-fabs((1/tan(rad_angle)) * CELL_X_SIZE));
}
else
{
x_step[ang]=(float)(fabs((1/tan(rad_angle)) * CELL_X_SIZE));
}

inv_cos_table[ang]=(float)(1/cos(rad_angle));
inv_sin_table[ang]=(float)(1/sin(rad_angle));

}

/* the cosine table is used to get rid of the "fish bowl effect", explained in the ray caster */

for(ang=-ANGLE_30;ang<=ANGLE_30;ang++)
{
rad_angle=(float)((3.272e-4)+ ang * 2*3.141592654/ANGLE_360);
cos_table[ang+ANGLE_30]=(float)(13312/cos(rad_angle));

}
}

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

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


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

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

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

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

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

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

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

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


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

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

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

yi = (float)(tan_table[view_angle] * (x_bound - view_x)) +view_y;

/* 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 */
yi =(float)(tan_table[view_angle] * (x_bound - view_x)) +view_y;

/* and we also know that the x cell value will be minus, because as the ray moves to another cell, because the ray is going left, the value must be minus. */
next_x_cell = -1;

       }

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

/* SECTION 2 : Testing for further intersections */

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

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

yadd=y_step[view_angle];

/* 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);
cell_y = (int)yi>>CELL_X_SIZE_FP;

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

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

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

dist_x  = ( (yi - view_y) * inv_sin_table[view_angle]);
/* we also save the exact position of the intersection because we will need it later to add texture mapping. */
yi_save = (int)yi;
/* because the x ray has found a wall, we can stop casting */

xray=FOUND_WALL;

}
else
{
/* if not, we compute the next possible intersection */
yi +=yadd;
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 */

xadd=x_step[view_angle];

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

/* compute current cell to inspect */

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

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

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

/* save the exact intersection point, we will need it later */
xi_save = (int)xi;
/* STOP y casting in that case, a wall has been found. */
yray=FOUND_WALL;
}
else
{
/* if not, move the ray on */
xi+=xadd;
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. */

    if (dist_x < dist_y)

       {
/* make sure that no divide by zeros occur */
if(dist_x<1)dist_x=1;
/* 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! */

scale = cos_table[ray]/dist_x++;

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

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

       }
/* else the dist_y was nearer, everything from above applies */
    else
       {
/* avoid divide by zero */
if(dist_y<1)dist_y=1;

/* avoid fish bowl effect, see above */
scale = (int)cos_table[ray]/dist_y++;


/* set up variables for our sliver engine, see above */
variables[2]=(xi_save & 0x003f); /*notice that we use xi instead of yi_save*/
variables[3]=scale-1;
variables[4]=ray;
variables[6]=y_hit_type;

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

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

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

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



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

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

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

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

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

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

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

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

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

if(wall_number>=WALL_NUMBER)break;
}


}

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

void aua_world(void)
{

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

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

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

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

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

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

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

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

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

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

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

/* MAIN function */

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

  int key_press; /* this is used to confirm input of values */

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

printf("********** RAY CASTING DEMONSTRATION ***********\nPLEASE enter values for VIEWING X (200-3800 rcmd.), VIEWING Y (200-3800) and VIEWING_ANGLE (0-1920, where 1920=360 degrees etc...).\n\nThe program will take a screenshot of the rendered view, and store it inside the !AUARay application directory.\n\nThis early version is quite unstable, and is purely designed to give an example of how ray casting can be applied to C source code. Staying within the recommended coordinates is a wise move, and pay special attention to keeping the view point OUT of walls!\nIf you are using the program with the world file supplied, try 400,400,100\n************************************************\n");
scanf("%d %d %d",&view_x,&view_y,&view_angle);

/* confirm this is ok */

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

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

if(!key_press)exit(1);

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

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

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

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

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

printf("calling aua_tables() this could take a long time on some machines\n");
aua_tables();

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

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

/* call ourlib_changemode to switch to mode 13 */

ourlib_changemode(13);

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

screen_address=(char *)ourlib_findscreen();

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

aua_graphics();

/* NOW we can go to mode 13 again and call the ray caster function */

ourlib_changemode(13);
aua_raycaster(view_x,view_y,view_angle);

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

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

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 2f 2a 20 44  |our_lib.h"../* D|
000002b0  45 46 49 4e 45 53 20 2a  2f 0a 0a 23 64 65 66 69  |EFINES */..#defi|
000002c0  6e 65 20 57 4f 52 4c 44  5f 57 49 44 54 48 20 36  |ne WORLD_WIDTH 6|
000002d0  34 20 2f 2a 20 54 68 69  73 20 69 73 20 74 68 65  |4 /* This is the|
000002e0  20 6e 75 6d 62 65 72 20  6f 66 20 77 61 6c 6c 73  | number of walls|
000002f0  20 61 63 72 6f 73 73 20  69 6e 20 6f 75 72 20 77  | across in our w|
00000300  6f 72 6c 64 20 2a 2f 0a  23 64 65 66 69 6e 65 20  |orld */.#define |
00000310  57 4f 52 4c 44 5f 48 45  49 47 48 54 20 36 34 20  |WORLD_HEIGHT 64 |
00000320  2f 2a 20 54 68 69 73 20  69 73 20 74 68 65 20 6e  |/* This is the n|
00000330  75 6d 62 65 72 20 6f 66  20 77 61 6c 6c 73 20 64  |umber of walls d|
00000340  6f 77 6e 20 69 6e 20 6f  75 72 20 77 6f 72 6c 64  |own in our world|
00000350  20 2a 2f 0a 23 64 65 66  69 6e 65 20 57 41 4c 4c  | */.#define WALL|
00000360  5f 57 49 44 54 48 20 36  34 20 2f 2a 20 54 68 69  |_WIDTH 64 /* Thi|
00000370  73 20 69 73 20 74 68 65  20 77 69 64 74 68 20 6f  |s is the width o|
00000380  66 20 65 61 63 68 20 77  61 6c 6c 20 69 6e 20 70  |f each wall in p|
00000390  69 78 65 6c 73 20 2a 2f  0a 23 64 65 66 69 6e 65  |ixels */.#define|
000003a0  20 57 41 4c 4c 5f 48 45  49 47 48 54 20 36 34 20  | WALL_HEIGHT 64 |
000003b0  2f 2a 20 54 68 69 73 20  69 73 20 74 68 65 20 68  |/* This is the h|
000003c0  65 69 67 68 74 20 6f 66  20 65 61 63 68 20 77 61  |eight of each wa|
000003d0  6c 6c 20 69 6e 20 70 69  78 65 6c 73 20 2a 2f 0a  |ll in pixels */.|
000003e0  23 64 65 66 69 6e 65 20  57 41 4c 4c 5f 4e 55 4d  |#define WALL_NUM|
000003f0  42 45 52 20 32 30 20 2f  2a 20 54 68 69 73 20 64  |BER 20 /* This d|
00000400  65 66 69 6e 65 73 20 74  68 65 20 6e 75 6d 62 65  |efines the numbe|
00000410  72 20 6f 66 20 77 61 6c  6c 73 20 61 6c 6c 6f 77  |r of walls allow|
00000420  65 64 20 2a 2f 0a 23 64  65 66 69 6e 65 20 53 43  |ed */.#define SC|
00000430  52 45 45 4e 5f 57 49 44  54 48 20 33 32 30 20 2f  |REEN_WIDTH 320 /|
00000440  2a 20 54 68 69 73 20 69  73 20 74 68 65 20 77 69  |* This is the wi|
00000450  64 74 68 20 6f 66 20 74  68 65 20 6d 6f 64 65 20  |dth of the mode |
00000460  31 33 20 73 63 72 65 65  6e 20 2a 2f 0a 23 64 65  |13 screen */.#de|
00000470  66 69 6e 65 20 53 43 52  45 45 4e 5f 48 45 49 47  |fine SCREEN_HEIG|
00000480  48 54 20 32 35 36 20 2f  2a 20 54 68 69 73 20 69  |HT 256 /* This i|
00000490  73 20 74 68 65 20 68 65  69 67 68 74 20 6f 66 20  |s the height of |
000004a0  74 68 65 20 6d 6f 64 65  20 31 33 20 73 63 72 65  |the mode 13 scre|
000004b0  65 6e 20 2a 2f 0a 23 64  65 66 69 6e 65 20 43 45  |en */.#define CE|
000004c0  4c 4c 5f 58 5f 53 49 5a  45 20 36 34 20 2f 2a 20  |LL_X_SIZE 64 /* |
000004d0  74 68 69 73 20 69 73 20  74 68 65 20 73 69 7a 65  |this is the size|
000004e0  20 69 6e 20 75 6e 69 74  73 20 6f 66 20 65 61 63  | in units of eac|
000004f0  68 20 63 65 6c 6c 20 2a  2f 0a 23 64 65 66 69 6e  |h cell */.#defin|
00000500  65 20 43 45 4c 4c 5f 59  5f 53 49 5a 45 20 36 34  |e CELL_Y_SIZE 64|
00000510  20 2f 2a 20 74 68 69 73  20 69 73 20 74 68 65 20  | /* this is the |
00000520  73 69 7a 65 20 69 6e 20  75 6e 69 74 73 20 6f 66  |size in units of|
00000530  20 65 61 63 68 20 63 65  6c 6c 20 2a 2f 0a 23 64  | each cell */.#d|
00000540  65 66 69 6e 65 20 43 45  4c 4c 5f 58 5f 53 49 5a  |efine CELL_X_SIZ|
00000550  45 5f 46 50 20 36 20 2f  2a 20 74 68 69 73 20 69  |E_FP 6 /* this i|
00000560  73 20 75 73 65 64 20 69  6e 20 62 69 6e 61 72 79  |s used in binary|
00000570  20 73 68 69 66 74 69 6e  67 20 2a 2f 0a 23 64 65  | shifting */.#de|
00000580  66 69 6e 65 20 43 45 4c  4c 5f 59 5f 53 49 5a 45  |fine CELL_Y_SIZE|
00000590  5f 46 50 20 36 20 2f 2a  20 74 68 69 73 20 69 73  |_FP 6 /* this is|
000005a0  20 75 73 65 64 20 69 6e  20 62 69 6e 61 72 79 20  | used in binary |
000005b0  73 68 69 66 74 69 6e 67  20 2a 2f 0a 23 64 65 66  |shifting */.#def|
000005c0  69 6e 65 20 46 4f 55 4e  44 5f 57 41 4c 4c 20 31  |ine FOUND_WALL 1|
000005d0  20 2f 2a 20 74 68 69 73  20 66 6c 61 67 20 69 73  | /* this flag is|
000005e0  20 75 73 65 64 20 74 6f  20 69 6e 64 69 63 61 74  | used to indicat|
000005f0  65 20 77 68 65 6e 20 61  6e 20 69 6e 74 65 72 73  |e when an inters|
00000600  65 63 74 69 6f 6e 20 68  61 73 20 62 65 20 66 6f  |ection has be fo|
00000610  75 6e 64 20 2a 2f 0a 0a  2f 2a 20 74 68 65 73 65  |und */../* these|
00000620  20 64 65 66 69 6e 65 73  20 72 65 70 72 65 73 65  | defines represe|
00000630  6e 74 20 61 20 6e 65 77  20 66 69 78 65 64 20 70  |nt a new fixed p|
00000640  6f 69 6e 74 20 66 6f 72  6d 20 6f 66 20 61 6e 67  |oint form of ang|
00000650  6c 65 2d 63 6f 75 6e 74  69 6e 67 2e 20 42 61 73  |le-counting. Bas|
00000660  69 63 61 6c 6c 79 20 74  68 69 73 20 73 79 73 74  |ically this syst|
00000670  65 6d 20 69 73 20 75 73  65 64 20 74 6f 20 61 76  |em is used to av|
00000680  6f 69 64 20 75 73 69 6e  67 20 66 6c 6f 61 74 69  |oid using floati|
00000690  6e 67 20 70 6f 69 6e 74  20 72 61 64 69 61 6e 20  |ng point radian |
000006a0  61 6e 67 6c 65 73 2c 20  77 68 69 63 68 20 28 65  |angles, which (e|
000006b0  73 70 65 63 69 61 6c 6c  79 20 6f 6e 20 61 6e 20  |specially on an |
000006c0  41 63 6f 72 6e 29 20 74  61 6b 65 20 61 20 6c 6f  |Acorn) take a lo|
000006d0  6e 67 20 74 69 6d 65 2e  20 49 74 20 61 6c 73 6f  |ng time. It also|
000006e0  20 6d 61 6b 65 73 20 6c  6f 6f 6b 2d 75 70 20 74  | makes look-up t|
000006f0  61 62 6c 65 20 72 65 66  65 72 65 6e 63 69 6e 67  |able referencing|
00000700  20 61 20 6c 6f 74 20 65  61 73 69 65 72 2c 20 61  | a lot easier, a|
00000710  73 20 74 68 65 20 69 6e  64 65 78 20 68 61 73 20  |s the index has |
00000720  74 6f 20 62 65 20 61 6e  20 69 6e 74 65 67 65 72  |to be an integer|
00000730  20 61 6e 79 77 61 79 21  20 2a 2f 0a 0a 23 64 65  | anyway! */..#de|
00000740  66 69 6e 65 20 41 4e 47  4c 45 5f 30 20 30 0a 23  |fine ANGLE_0 0.#|
00000750  64 65 66 69 6e 65 20 41  4e 47 4c 45 5f 36 20 33  |define ANGLE_6 3|
00000760  30 0a 23 64 65 66 69 6e  65 20 41 4e 47 4c 45 5f  |0.#define ANGLE_|
00000770  33 30 20 31 36 30 0a 23  64 65 66 69 6e 65 20 41  |30 160.#define A|
00000780  4e 47 4c 45 5f 34 35 20  32 34 30 0a 23 64 65 66  |NGLE_45 240.#def|
00000790  69 6e 65 20 41 4e 47 4c  45 5f 36 30 20 33 32 30  |ine ANGLE_60 320|
000007a0  0a 23 64 65 66 69 6e 65  20 41 4e 47 4c 45 5f 39  |.#define ANGLE_9|
000007b0  30 20 34 38 30 0a 23 64  65 66 69 6e 65 20 41 4e  |0 480.#define AN|
000007c0  47 4c 45 5f 31 38 30 20  39 36 30 0a 23 64 65 66  |GLE_180 960.#def|
000007d0  69 6e 65 20 41 4e 47 4c  45 5f 32 32 35 20 31 32  |ine ANGLE_225 12|
000007e0  30 30 0a 23 64 65 66 69  6e 65 20 41 4e 47 4c 45  |00.#define ANGLE|
000007f0  5f 32 37 30 20 31 34 34  30 0a 23 64 65 66 69 6e  |_270 1440.#defin|
00000800  65 20 41 4e 47 4c 45 5f  33 36 30 20 31 39 32 30  |e ANGLE_360 1920|
00000810  0a 0a 0a 2f 2a 20 47 4c  4f 42 41 4c 20 76 61 72  |.../* GLOBAL var|
00000820  69 61 62 6c 65 73 20 2a  2f 0a 0a 63 68 61 72 20  |iables */..char |
00000830  77 6f 72 6c 64 5b 57 4f  52 4c 44 5f 48 45 49 47  |world[WORLD_HEIG|
00000840  48 54 2b 31 5d 5b 57 4f  52 4c 44 5f 57 49 44 54  |HT+1][WORLD_WIDT|
00000850  48 2b 31 5d 3b 2f 2a 20  54 68 69 73 20 68 6f 6c  |H+1];/* This hol|
00000860  64 73 20 6f 75 72 20 74  65 78 74 20 64 61 74 61  |ds our text data|
00000870  20 66 69 6c 65 20 2a 2f  0a 63 68 61 72 20 77 61  | file */.char wa|
00000880  6c 6c 73 5b 57 41 4c 4c  5f 4e 55 4d 42 45 52 2b  |lls[WALL_NUMBER+|
00000890  31 5d 5b 28 57 41 4c 4c  5f 57 49 44 54 48 2a 57  |1][(WALL_WIDTH*W|
000008a0  41 4c 4c 5f 48 45 49 47  48 54 29 2b 31 5d 3b 0a  |ALL_HEIGHT)+1];.|
000008b0  0a 2f 2a 20 54 68 69 73  20 68 6f 6c 64 73 20 74  |./* This holds t|
000008c0  68 65 20 77 61 6c 6c 20  67 72 61 70 68 69 63 73  |he wall graphics|
000008d0  20 69 6e 20 61 20 74 77  6f 20 64 69 6d 65 6e 73  | in a two dimens|
000008e0  69 6f 6e 61 6c 20 61 72  72 61 79 20 2a 2f 0a 2f  |ional array */./|
000008f0  2a 20 4e 6f 74 65 20 74  68 65 20 75 73 61 67 65  |* Note the usage|
00000900  20 6f 66 20 63 68 61 72  20 61 6e 64 20 6e 6f 74  | of char and not|
00000910  20 22 69 6e 74 22 20 69  6e 20 62 6f 74 68 20 63  | "int" in both c|
00000920  61 73 65 73 2e 20 54 68  69 73 20 69 73 20 62 65  |ases. This is be|
00000930  63 61 75 73 65 20 61 20  63 68 61 72 20 69 73 20  |cause a char is |
00000940  38 20 62 79 74 65 73 2c  20 77 68 69 63 68 20 67  |8 bytes, which g|
00000950  69 76 65 73 20 32 35 36  20 63 6f 6c 6f 75 72 73  |ives 256 colours|
00000960  20 28 75 73 65 64 20 69  6e 20 6f 75 72 20 4d 6f  | (used in our Mo|
00000970  64 65 20 31 33 20 73 63  72 65 65 6e 29 20 61 6e  |de 13 screen) an|
00000980  64 20 61 6c 73 6f 20 61  6e 20 69 6e 74 65 67 65  |d also an intege|
00000990  72 20 75 70 20 74 6f 20  32 35 36 2c 20 77 68 65  |r up to 256, whe|
000009a0  6e 20 6f 75 72 20 74 65  78 74 20 66 69 6c 65 20  |n our text file |
000009b0  64 6f 65 73 6e 27 74 20  67 6f 20 6f 76 65 72 20  |doesn't go over |
000009c0  39 20 69 6e 20 6e 75 6d  62 65 72 21 20 48 65 6e  |9 in number! Hen|
000009d0  63 65 20 74 68 65 72 65  20 69 73 20 6e 6f 20 6e  |ce there is no n|
000009e0  65 65 64 20 66 6f 72 20  61 6e 20 69 6e 74 20 61  |eed for an int a|
000009f0  72 72 61 79 20 69 6e 20  65 69 74 68 65 72 20 63  |rray in either c|
00000a00  61 73 65 2e 20 2a 2f 0a  0a 63 68 61 72 20 2a 73  |ase. */..char *s|
00000a10  63 72 65 65 6e 5f 61 64  64 72 65 73 73 3b 20 2f  |creen_address; /|
00000a20  2a 20 74 68 69 73 20 77  69 6c 6c 20 68 6f 6c 64  |* this will hold|
00000a30  20 74 68 65 20 62 61 73  65 20 6f 66 20 74 68 65  | the base of the|
00000a40  20 73 63 72 65 65 6e 20  6d 65 6d 6f 72 79 20 77  | screen memory w|
00000a50  68 69 63 68 20 77 65 20  77 69 6c 6c 20 6d 61 6e  |hich we will man|
00000a60  69 70 75 6c 61 74 65 2e  20 42 79 20 61 6c 74 65  |ipulate. By alte|
00000a70  72 69 6e 67 20 76 61 6c  75 65 73 20 69 6e 20 74  |ring values in t|
00000a80  68 65 20 73 63 72 65 65  6e 20 6d 65 6d 6f 72 79  |he screen memory|
00000a90  2c 20 77 65 20 61 6c 74  65 72 20 77 68 61 74 20  |, we alter what |
00000aa0  61 70 70 65 61 72 73 20  6f 6e 20 74 68 65 20 73  |appears on the s|
00000ab0  63 72 65 65 6e 2e 20 4e  6f 74 65 20 74 68 61 74  |creen. Note that|
00000ac0  20 74 68 69 73 20 69 73  20 6f 66 20 74 79 70 65  | this is of type|
00000ad0  20 22 63 68 61 72 20 2a  22 20 62 65 63 61 75 73  | "char *" becaus|
00000ae0  65 20 69 74 20 68 6f 6c  64 73 20 74 68 65 20 6d  |e it holds the m|
00000af0  65 6d 6f 72 79 20 61 64  64 72 65 73 73 20 6f 66  |emory address of|
00000b00  20 61 20 62 79 74 65 20  61 72 72 61 79 20 2d 20  | a byte array - |
00000b10  74 68 65 20 32 35 36 20  63 6f 6c 6f 75 72 20 6d  |the 256 colour m|
00000b20  6f 64 65 20 31 33 20 73  63 72 65 65 6e 20 28 77  |ode 13 screen (w|
00000b30  65 6c 6c 20 69 74 20 77  69 6c 6c 20 64 6f 21 29  |ell it will do!)|
00000b40  20 2a 2f 0a 0a 0a 2f 2a  20 74 68 65 73 65 20 46  | */.../* these F|
00000b50  4c 4f 41 54 49 4e 47 20  70 6f 69 6e 74 20 28 75  |LOATING point (u|
00000b60  72 67 68 21 29 20 70 6f  69 6e 74 65 72 73 20 70  |rgh!) pointers p|
00000b70  6f 69 6e 74 20 74 6f 20  6c 6f 6f 6b 2d 75 70 20  |oint to look-up |
00000b80  74 61 62 6c 65 73 20 75  73 65 64 20 69 6e 20 74  |tables used in t|
00000b90  68 65 20 72 61 79 20 63  61 73 74 69 6e 67 20 65  |he ray casting e|
00000ba0  6e 67 69 6e 65 2e 20 54  68 65 73 65 20 61 72 65  |ngine. These are|
00000bb0  20 65 78 70 6c 61 69 6e  65 64 20 6f 66 20 69 6e  | explained of in|
00000bc0  20 74 68 65 20 65 6e 67  69 6e 65 2c 20 62 75 74  | the engine, but|
00000bd0  20 74 68 65 20 6c 6f 6f  6b 2d 75 70 73 20 61 72  | the look-ups ar|
00000be0  65 20 67 65 6e 65 72 61  74 65 64 20 69 6e 20 61  |e generated in a|
00000bf0  75 61 5f 74 61 62 6c 65  73 28 29 20 2a 2f 0a 0a  |ua_tables() */..|
00000c00  66 6c 6f 61 74 20 2a 74  61 6e 5f 74 61 62 6c 65  |float *tan_table|
00000c10  2c 2a 69 6e 76 5f 74 61  6e 5f 74 61 62 6c 65 3b  |,*inv_tan_table;|
00000c20  20 2f 2a 20 70 6f 69 6e  74 65 72 73 20 74 6f 20  | /* pointers to |
00000c30  74 61 6e 67 65 6e 74 20  6c 6f 6f 6b 5f 75 70 73  |tangent look_ups|
00000c40  20 2a 2f 0a 66 6c 6f 61  74 20 2a 79 5f 73 74 65  | */.float *y_ste|
00000c50  70 2c 2a 78 5f 73 74 65  70 3b 20 20 20 20 20 20  |p,*x_step;      |
00000c60  20 20 20 20 20 2f 2a 20  70 6f 69 6e 74 65 72 73  |     /* pointers|
00000c70  20 74 6f 20 6d 6f 72 65  20 63 6f 6d 70 6c 65 78  | to more complex|
00000c80  20 6c 6f 6f 6b 5f 75 70  73 20 2a 2f 0a 66 6c 6f  | look_ups */.flo|
00000c90  61 74 20 2a 69 6e 76 5f  63 6f 73 5f 74 61 62 6c  |at *inv_cos_tabl|
00000ca0  65 2c 20 20 20 20 20 20  20 20 20 20 20 20 2f 2a  |e,            /*|
00000cb0  20 73 69 6e 2f 63 6f 73  20 74 61 62 6c 65 73 20  | sin/cos tables |
00000cc0  28 6c 6f 6f 6b 5f 75 70  73 29 20 20 20 20 2a 2f  |(look_ups)    */|
00000cd0  0a 20 20 20 20 20 20 2a  69 6e 76 5f 73 69 6e 5f  |.      *inv_sin_|
00000ce0  74 61 62 6c 65 3b 0a 66  6c 6f 61 74 20 2a 63 6f  |table;.float *co|
00000cf0  73 5f 74 61 62 6c 65 3b  20 20 20 20 20 20 20 20  |s_table;        |
00000d00  20 20 20 20 20 20 20 20  2f 2a 20 63 6f 73 69 6e  |        /* cosin|
00000d10  61 6c 20 6c 6f 6f 6b 5f  75 70 20 74 61 62 6c 65  |al look_up table|
00000d20  20 20 20 20 2a 2f 0a 0a  0a 2f 2a 20 46 55 4e 43  |    */.../* FUNC|
00000d30  54 49 4f 4e 20 64 65 66  69 6e 69 74 69 6f 6e 73  |TION definitions|
00000d40  20 2a 2f 0a 0a 2f 2a 20  74 68 69 73 20 66 75 6e  | */../* this fun|
00000d50  63 74 69 6f 6e 20 67 65  6e 65 72 61 74 65 73 20  |ction generates |
00000d60  4c 4f 4f 4b 20 55 50 20  74 61 62 6c 65 73 20 2d  |LOOK UP tables -|
00000d70  20 61 72 72 61 79 73 20  68 6f 6c 64 69 6e 67 20  | arrays holding |
00000d80  70 72 65 2d 63 61 6c 63  75 6c 61 74 65 64 20 74  |pre-calculated t|
00000d90  72 69 67 6f 6e 6f 6d 65  74 72 69 63 20 76 61 72  |rigonometric var|
00000da0  69 61 62 6c 65 73 20 75  73 65 64 20 69 6e 20 74  |iables used in t|
00000db0  68 65 20 72 61 79 20 63  61 73 74 69 6e 67 20 70  |he ray casting p|
00000dc0  72 6f 63 65 73 73 20 2a  2f 0a 0a 76 6f 69 64 20  |rocess */..void |
00000dd0  61 75 61 5f 74 61 62 6c  65 73 28 76 6f 69 64 29  |aua_tables(void)|
00000de0  0a 7b 0a 0a 69 6e 74 20  61 6e 67 2c 20 2f 2a 20  |.{..int ang, /* |
00000df0  74 68 69 73 20 69 73 20  75 73 65 64 20 74 6f 20  |this is used to |
00000e00  68 6f 6c 64 20 76 61 6c  75 65 73 20 77 68 69 6c  |hold values whil|
00000e10  65 20 6d 61 6b 69 6e 67  20 6c 6f 6f 6b 2d 75 70  |e making look-up|
00000e20  73 20 2a 2f 0a 20 20 20  20 61 6e 67 74 3b 20 2f  |s */.    angt; /|
00000e30  2a 20 73 61 6d 65 20 2a  2f 0a 0a 66 6c 6f 61 74  |* same */..float|
00000e40  20 72 61 64 5f 61 6e 67  6c 65 3b 20 2f 2a 20 74  | rad_angle; /* t|
00000e50  68 69 73 20 68 6f 6c 64  73 20 74 68 65 20 72 61  |his holds the ra|
00000e60  64 69 61 6e 73 20 65 71  75 69 76 61 6c 65 6e 74  |dians equivalent|
00000e70  20 6f 66 20 74 68 65 20  66 69 78 65 64 20 70 6f  | of the fixed po|
00000e80  69 6e 74 20 61 6e 67 6c  65 20 73 79 73 74 65 6d  |int angle system|
00000e90  20 28 30 2d 31 39 32 30  20 3d 20 30 2d 33 36 30  | (0-1920 = 0-360|
00000ea0  20 64 65 67 72 65 65 73  20 3d 20 30 2d 36 2e 77  | degrees = 0-6.w|
00000eb0  68 61 74 65 76 65 72 20  72 61 64 69 61 6e 73 20  |hatever radians |
00000ec0  2a 2f 0a 0a 2f 2a 20 64  79 6e 61 6d 69 63 61 6c  |*/../* dynamical|
00000ed0  6c 79 20 61 6c 6c 6f 63  61 74 65 64 20 61 64 65  |ly allocated ade|
00000ee0  71 75 61 74 65 20 6d 65  6d 6f 72 79 20 66 6f 72  |quate memory for|
00000ef0  20 74 68 65 20 6c 6f 6f  6b 2d 75 70 73 20 2a 2f  | the look-ups */|
00000f00  0a 74 61 6e 5f 74 61 62  6c 65 20 20 20 20 20 3d  |.tan_table     =|
00000f10  20 28 66 6c 6f 61 74 20  2a 29 6d 61 6c 6c 6f 63  | (float *)malloc|
00000f20  28 73 69 7a 65 6f 66 28  66 6c 6f 61 74 29 20 2a  |(sizeof(float) *|
00000f30  20 28 41 4e 47 4c 45 5f  33 36 30 2b 31 29 29 3b  | (ANGLE_360+1));|
00000f40  0a 69 6e 76 5f 74 61 6e  5f 74 61 62 6c 65 20 3d  |.inv_tan_table =|
00000f50  20 28 66 6c 6f 61 74 20  2a 29 6d 61 6c 6c 6f 63  | (float *)malloc|
00000f60  28 73 69 7a 65 6f 66 28  66 6c 6f 61 74 29 20 2a  |(sizeof(float) *|
00000f70  20 28 41 4e 47 4c 45 5f  33 36 30 2b 31 29 29 3b  | (ANGLE_360+1));|
00000f80  0a 0a 79 5f 73 74 65 70  20 20 20 20 20 20 20 20  |..y_step        |
00000f90  3d 20 28 66 6c 6f 61 74  20 2a 29 6d 61 6c 6c 6f  |= (float *)mallo|
00000fa0  63 28 73 69 7a 65 6f 66  28 66 6c 6f 61 74 29 20  |c(sizeof(float) |
00000fb0  2a 20 28 41 4e 47 4c 45  5f 33 36 30 2b 31 29 29  |* (ANGLE_360+1))|
00000fc0  3b 0a 78 5f 73 74 65 70  20 20 20 20 20 20 20 20  |;.x_step        |
00000fd0  3d 20 28 66 6c 6f 61 74  20 20 2a 29 6d 61 6c 6c  |= (float  *)mall|
00000fe0  6f 63 28 73 69 7a 65 6f  66 28 66 6c 6f 61 74 29  |oc(sizeof(float)|
00000ff0  20 2a 20 28 41 4e 47 4c  45 5f 33 36 30 2b 31 29  | * (ANGLE_360+1)|
00001000  29 3b 0a 0a 63 6f 73 5f  74 61 62 6c 65 20 20 20  |);..cos_table   |
00001010  20 20 3d 20 28 66 6c 6f  61 74 20 20 2a 29 6d 61  |  = (float  *)ma|
00001020  6c 6c 6f 63 28 73 69 7a  65 6f 66 28 6c 6f 6e 67  |lloc(sizeof(long|
00001030  29 20 2a 20 28 41 4e 47  4c 45 5f 33 36 30 2b 31  |) * (ANGLE_360+1|
00001040  29 29 3b 0a 69 6e 76 5f  63 6f 73 5f 74 61 62 6c  |));.inv_cos_tabl|
00001050  65 20 3d 20 28 66 6c 6f  61 74 20 20 2a 29 6d 61  |e = (float  *)ma|
00001060  6c 6c 6f 63 28 73 69 7a  65 6f 66 28 66 6c 6f 61  |lloc(sizeof(floa|
00001070  74 29 20 2a 20 28 41 4e  47 4c 45 5f 33 36 30 2b  |t) * (ANGLE_360+|
00001080  31 29 29 3b 0a 69 6e 76  5f 73 69 6e 5f 74 61 62  |1));.inv_sin_tab|
00001090  6c 65 20 3d 20 28 66 6c  6f 61 74 20 20 2a 29 6d  |le = (float  *)m|
000010a0  61 6c 6c 6f 63 28 73 69  7a 65 6f 66 28 66 6c 6f  |alloc(sizeof(flo|
000010b0  61 74 29 20 2a 20 28 41  4e 47 4c 45 5f 33 36 30  |at) * (ANGLE_360|
000010c0  2b 31 29 29 3b 0a 0a 2f  2a 20 67 65 6e 65 72 61  |+1));../* genera|
000010d0  74 65 20 74 68 65 6d 2c  20 74 68 65 69 72 20 75  |te them, their u|
000010e0  73 65 20 69 73 20 65 78  70 6c 61 69 6e 65 64 20  |se is explained |
000010f0  69 6e 20 74 68 65 20 72  61 79 20 63 61 73 74 69  |in the ray casti|
00001100  6e 67 20 65 6e 67 69 6e  65 20 2a 2f 0a 0a 66 6f  |ng engine */..fo|
00001110  72 28 61 6e 67 74 3d 41  4e 47 4c 45 5f 30 3b 61  |r(angt=ANGLE_0;a|
00001120  6e 67 74 3c 3d 41 4e 47  4c 45 5f 33 36 30 3b 61  |ngt<=ANGLE_360;a|
00001130  6e 67 74 2b 2b 29 0a 7b  0a 61 6e 67 3d 61 6e 67  |ngt++).{.ang=ang|
00001140  74 3b 0a 72 61 64 5f 61  6e 67 6c 65 3d 28 66 6c  |t;.rad_angle=(fl|
00001150  6f 61 74 29 28 28 33 2e  32 37 32 65 2d 34 29 20  |oat)((3.272e-4) |
00001160  2b 20 61 6e 67 20 2a 20  32 2a 33 2e 31 34 31 35  |+ ang * 2*3.1415|
00001170  39 32 36 35 34 2f 41 4e  47 4c 45 5f 33 36 30 29  |92654/ANGLE_360)|
00001180  3b 0a 0a 74 61 6e 5f 74  61 62 6c 65 5b 61 6e 67  |;..tan_table[ang|
00001190  5d 3d 28 66 6c 6f 61 74  29 74 61 6e 28 72 61 64  |]=(float)tan(rad|
000011a0  5f 61 6e 67 6c 65 29 3b  0a 69 6e 76 5f 74 61 6e  |_angle);.inv_tan|
000011b0  5f 74 61 62 6c 65 5b 61  6e 67 5d 3d 28 66 6c 6f  |_table[ang]=(flo|
000011c0  61 74 29 28 31 2f 74 61  6e 28 72 61 64 5f 61 6e  |at)(1/tan(rad_an|
000011d0  67 6c 65 29 29 3b 0a 69  66 28 61 6e 67 3e 3d 41  |gle));.if(ang>=A|
000011e0  4e 47 4c 45 5f 30 20 26  26 20 61 6e 67 3c 41 4e  |NGLE_0 && ang<AN|
000011f0  47 4c 45 5f 31 38 30 29  0a 7b 0a 79 5f 73 74 65  |GLE_180).{.y_ste|
00001200  70 5b 61 6e 67 5d 3d 28  66 6c 6f 61 74 29 28 66  |p[ang]=(float)(f|
00001210  61 62 73 28 74 61 6e 28  72 61 64 5f 61 6e 67 6c  |abs(tan(rad_angl|
00001220  65 29 20 2a 20 43 45 4c  4c 5f 59 5f 53 49 5a 45  |e) * CELL_Y_SIZE|
00001230  29 29 3b 0a 7d 0a 65 6c  73 65 0a 20 20 79 5f 73  |));.}.else.  y_s|
00001240  74 65 70 5b 61 6e 67 5d  3d 28 66 6c 6f 61 74 29  |tep[ang]=(float)|
00001250  28 2d 66 61 62 73 28 74  61 6e 28 72 61 64 5f 61  |(-fabs(tan(rad_a|
00001260  6e 67 6c 65 29 20 2a 20  43 45 4c 4c 5f 59 5f 53  |ngle) * CELL_Y_S|
00001270  49 5a 45 29 29 3b 0a 69  66 28 61 6e 67 3e 3d 41  |IZE));.if(ang>=A|
00001280  4e 47 4c 45 5f 39 30 20  26 26 20 61 6e 67 3c 41  |NGLE_90 && ang<A|
00001290  4e 47 4c 45 5f 32 37 30  29 0a 7b 0a 78 5f 73 74  |NGLE_270).{.x_st|
000012a0  65 70 5b 61 6e 67 5d 3d  28 66 6c 6f 61 74 29 28  |ep[ang]=(float)(|
000012b0  2d 66 61 62 73 28 28 31  2f 74 61 6e 28 72 61 64  |-fabs((1/tan(rad|
000012c0  5f 61 6e 67 6c 65 29 29  20 2a 20 43 45 4c 4c 5f  |_angle)) * CELL_|
000012d0  58 5f 53 49 5a 45 29 29  3b 0a 7d 0a 65 6c 73 65  |X_SIZE));.}.else|
000012e0  0a 7b 0a 78 5f 73 74 65  70 5b 61 6e 67 5d 3d 28  |.{.x_step[ang]=(|
000012f0  66 6c 6f 61 74 29 28 66  61 62 73 28 28 31 2f 74  |float)(fabs((1/t|
00001300  61 6e 28 72 61 64 5f 61  6e 67 6c 65 29 29 20 2a  |an(rad_angle)) *|
00001310  20 43 45 4c 4c 5f 58 5f  53 49 5a 45 29 29 3b 0a  | CELL_X_SIZE));.|
00001320  7d 0a 0a 69 6e 76 5f 63  6f 73 5f 74 61 62 6c 65  |}..inv_cos_table|
00001330  5b 61 6e 67 5d 3d 28 66  6c 6f 61 74 29 28 31 2f  |[ang]=(float)(1/|
00001340  63 6f 73 28 72 61 64 5f  61 6e 67 6c 65 29 29 3b  |cos(rad_angle));|
00001350  0a 69 6e 76 5f 73 69 6e  5f 74 61 62 6c 65 5b 61  |.inv_sin_table[a|
00001360  6e 67 5d 3d 28 66 6c 6f  61 74 29 28 31 2f 73 69  |ng]=(float)(1/si|
00001370  6e 28 72 61 64 5f 61 6e  67 6c 65 29 29 3b 0a 0a  |n(rad_angle));..|
00001380  7d 0a 0a 2f 2a 20 74 68  65 20 63 6f 73 69 6e 65  |}../* the cosine|
00001390  20 74 61 62 6c 65 20 69  73 20 75 73 65 64 20 74  | table is used t|
000013a0  6f 20 67 65 74 20 72 69  64 20 6f 66 20 74 68 65  |o get rid of the|
000013b0  20 22 66 69 73 68 20 62  6f 77 6c 20 65 66 66 65  | "fish bowl effe|
000013c0  63 74 22 2c 20 65 78 70  6c 61 69 6e 65 64 20 69  |ct", explained i|
000013d0  6e 20 74 68 65 20 72 61  79 20 63 61 73 74 65 72  |n the ray caster|
000013e0  20 2a 2f 0a 0a 66 6f 72  28 61 6e 67 3d 2d 41 4e  | */..for(ang=-AN|
000013f0  47 4c 45 5f 33 30 3b 61  6e 67 3c 3d 41 4e 47 4c  |GLE_30;ang<=ANGL|
00001400  45 5f 33 30 3b 61 6e 67  2b 2b 29 0a 7b 0a 72 61  |E_30;ang++).{.ra|
00001410  64 5f 61 6e 67 6c 65 3d  28 66 6c 6f 61 74 29 28  |d_angle=(float)(|
00001420  28 33 2e 32 37 32 65 2d  34 29 2b 20 61 6e 67 20  |(3.272e-4)+ ang |
00001430  2a 20 32 2a 33 2e 31 34  31 35 39 32 36 35 34 2f  |* 2*3.141592654/|
00001440  41 4e 47 4c 45 5f 33 36  30 29 3b 0a 63 6f 73 5f  |ANGLE_360);.cos_|
00001450  74 61 62 6c 65 5b 61 6e  67 2b 41 4e 47 4c 45 5f  |table[ang+ANGLE_|
00001460  33 30 5d 3d 28 66 6c 6f  61 74 29 28 31 33 33 31  |30]=(float)(1331|
00001470  32 2f 63 6f 73 28 72 61  64 5f 61 6e 67 6c 65 29  |2/cos(rad_angle)|
00001480  29 3b 0a 0a 7d 0a 7d 0a  0a 2f 2a 20 74 68 69 73  |);..}.}../* this|
00001490  20 66 75 6e 63 74 69 6f  6e 20 69 73 20 74 68 65  | function is the|
000014a0  20 68 65 61 72 74 20 6f  66 20 74 68 65 20 70 72  | heart of the pr|
000014b0  6f 67 72 61 6d 2c 20 74  68 65 20 65 6e 67 69 6e  |ogram, the engin|
000014c0  65 2c 20 74 6f 20 67 65  6e 65 72 61 74 65 20 74  |e, to generate t|
000014d0  68 65 20 66 69 72 73 74  20 70 65 72 73 6f 6e 20  |he first person |
000014e0  76 69 65 77 20 2a 2f 0a  76 6f 69 64 20 61 75 61  |view */.void aua|
000014f0  5f 72 61 79 63 61 73 74  65 72 28 69 6e 74 20 76  |_raycaster(int v|
00001500  69 65 77 5f 78 2c 69 6e  74 20 76 69 65 77 5f 79  |iew_x,int view_y|
00001510  2c 69 6e 74 20 76 69 65  77 5f 61 6e 67 6c 65 29  |,int view_angle)|
00001520  0a 7b 0a 2f 2a 20 72 65  6d 65 6d 62 65 72 20 74  |.{./* remember t|
00001530  68 61 74 20 77 65 20 61  72 65 20 74 68 69 6e 6b  |hat we are think|
00001540  69 6e 67 20 69 6e 20 32  2d 44 2c 20 6e 6f 74 20  |ing in 2-D, not |
00001550  69 6e 20 33 44 20 77 68  65 6e 20 77 65 20 64 69  |in 3D when we di|
00001560  73 63 75 73 73 20 69 64  65 61 73 2e 20 42 65 6c  |scuss ideas. Bel|
00001570  6f 77 20 64 6f 65 73 20  6e 6f 74 20 6d 65 61 6e  |ow does not mean|
00001580  20 22 61 20 66 6c 6f 6f  72 20 62 65 6c 6f 77 22  | "a floor below"|
00001590  2c 20 69 74 20 72 65 61  6c 6c 79 20 6d 65 61 6e  |, it really mean|
000015a0  73 20 22 62 65 68 69 6e  64 22 2c 20 62 75 74 20  |s "behind", but |
000015b0  77 65 20 73 61 79 20 62  65 6c 6f 77 20 62 65 63  |we say below bec|
000015c0  61 75 73 65 20 77 65 20  61 72 65 20 69 6d 61 67  |ause we are imag|
000015d0  69 6e 69 6e 67 20 6c 6f  6f 6b 69 6e 67 20 64 6f  |ining looking do|
000015e0  77 6e 20 6f 6e 20 74 68  65 20 76 69 65 77 20 70  |wn on the view p|
000015f0  6f 69 6e 74 20 74 6f 20  66 6f 72 6d 20 61 20 32  |oint to form a 2|
00001600  2d 44 20 70 6c 61 6e 20  2a 2f 0a 0a 2f 2a 20 74  |-D plan */../* t|
00001610  68 69 73 20 66 75 6e 63  74 69 6f 6e 2c 20 66 6f  |his function, fo|
00001620  72 20 65 61 63 68 20 63  6f 6c 75 6d 6e 20 6f 66  |r each column of|
00001630  20 74 68 65 20 33 32 30  20 70 69 78 65 6c 20 77  | the 320 pixel w|
00001640  69 64 74 68 20 4d 6f 64  65 20 31 33 20 73 63 72  |idth Mode 13 scr|
00001650  65 65 6e 2c 20 63 61 73  74 73 20 6f 75 74 20 74  |een, casts out t|
00001660  77 6f 20 72 61 79 73 2e  20 4f 6e 65 20 72 61 79  |wo rays. One ray|
00001670  20 6c 6f 6f 6b 73 20 66  6f 72 20 58 2c 20 68 6f  | looks for X, ho|
00001680  72 69 7a 6f 6e 74 61 6c  20 69 6e 74 65 72 73 65  |rizontal interse|
00001690  63 74 69 6f 6e 73 20 77  69 74 68 20 77 61 6c 6c  |ctions with wall|
000016a0  73 2c 20 61 6e 64 20 74  68 65 20 6f 74 68 65 72  |s, and the other|
000016b0  20 74 72 61 63 6b 73 20  69 6e 74 65 72 73 65 63  | tracks intersec|
000016c0  74 69 6f 6e 73 20 77 69  74 68 20 59 2c 20 76 65  |tions with Y, ve|
000016d0  72 74 69 63 61 6c 20 77  61 6c 6c 20 62 6f 75 6e  |rtical wall boun|
000016e0  64 61 72 69 65 73 2e 20  41 66 74 65 72 20 61 6c  |daries. After al|
000016f0  6c 2c 20 74 68 65 20 6f  6e 6c 79 20 74 69 6d 65  |l, the only time|
00001700  20 61 20 63 6f 6c 6c 69  73 69 6f 6e 20 63 6f 75  | a collision cou|
00001710  6c 64 20 6f 63 63 75 72  20 69 73 20 6f 6e 20 61  |ld occur is on a|
00001720  20 62 6f 75 6e 64 61 72  79 20 6f 66 20 61 20 63  | boundary of a c|
00001730  65 6c 6c 2c 20 61 73 20  74 68 65 20 77 61 6c 6c  |ell, as the wall|
00001740  20 66 69 6c 6c 73 20 75  70 20 74 68 65 20 65 6e  | fills up the en|
00001750  74 69 72 65 20 63 65 6c  6c 2e 20 45 78 70 65 63  |tire cell. Expec|
00001760  74 20 74 6f 20 73 65 65  20 6c 6f 74 73 20 6f 66  |t to see lots of|
00001770  20 36 34 27 73 2c 20 74  68 6f 75 67 68 20 72 65  | 64's, though re|
00001780  6d 65 6d 62 65 72 20 74  68 61 74 20 74 68 69 73  |member that this|
00001790  20 72 61 79 20 63 61 73  74 65 72 20 69 73 20 76  | ray caster is v|
000017a0  65 72 79 20 72 6f 75 74  69 6e 65 2c 20 61 6e 64  |ery routine, and|
000017b0  20 68 61 73 20 6e 6f 74  20 61 74 20 61 6c 6c 20  | has not at all |
000017c0  62 65 65 6e 20 70 75 74  20 74 68 72 6f 75 67 68  |been put through|
000017d0  20 6d 79 20 22 62 6f 78  20 6f 66 20 6d 61 67 69  | my "box of magi|
000017e0  63 22 2e 20 54 68 65 20  65 6e 67 69 6e 65 20 77  |c". The engine w|
000017f0  69 6c 6c 20 62 65 63 6f  6d 65 20 6d 75 63 68 20  |ill become much |
00001800  6d 6f 72 65 20 70 65 72  73 6f 6e 61 6c 69 73 65  |more personalise|
00001810  64 20 76 65 72 79 20 73  6f 6f 6e 21 20 2a 2f 0a  |d very soon! */.|
00001820  0a 0a 0a 69 6e 74 20 63  65 6c 6c 5f 78 2c 20 2f  |...int cell_x, /|
00001830  2a 20 75 73 65 64 20 74  6f 20 73 74 6f 72 65 20  |* used to store |
00001840  77 68 69 63 68 20 63 65  6c 6c 20 6f 66 20 74 68  |which cell of th|
00001850  65 20 77 61 6c 6c 73 20  64 61 74 61 20 74 68 65  |e walls data the|
00001860  20 72 61 79 20 69 73 20  69 6e 20 2a 2f 0a 63 65  | ray is in */.ce|
00001870  6c 6c 5f 79 2c 20 2f 2a  20 22 20 2a 2f 0a 63 61  |ll_y, /* " */.ca|
00001880  73 74 69 6e 67 3d 32 2c  20 2f 2a 20 75 73 65 64  |sting=2, /* used|
00001890  20 74 6f 20 73 74 6f 72  65 20 69 66 20 72 61 79  | to store if ray|
000018a0  20 63 61 73 74 69 6e 67  20 68 61 73 20 66 69 6e  | casting has fin|
000018b0  69 73 68 65 64 20 2a 2f  0a 78 5f 68 69 74 5f 74  |ished */.x_hit_t|
000018c0  79 70 65 2c 20 2f 2a 20  74 68 69 73 20 73 74 6f  |ype, /* this sto|
000018d0  72 65 73 20 74 68 65 20  77 61 6c 6c 20 74 79 70  |res the wall typ|
000018e0  65 20 68 69 74 20 62 79  20 74 68 65 20 78 20 63  |e hit by the x c|
000018f0  61 73 74 69 6e 67 20 72  61 79 20 2a 2f 0a 79 5f  |asting ray */.y_|
00001900  68 69 74 5f 74 79 70 65  2c 20 2f 2a 20 74 68 69  |hit_type, /* thi|
00001910  73 20 73 6f 74 72 65 73  20 74 68 65 20 77 61 6c  |s sotres the wal|
00001920  6c 20 74 79 70 65 20 28  6e 75 6d 62 65 72 29 20  |l type (number) |
00001930  68 69 74 20 62 79 20 74  68 65 20 79 20 72 61 79  |hit by the y ray|
00001940  20 2a 2f 0a 78 5f 62 6f  75 6e 64 2c 20 2f 2a 20  | */.x_bound, /* |
00001950  74 68 69 73 20 68 6f 6c  64 73 20 74 68 65 20 6e  |this holds the n|
00001960  65 78 74 20 78 20 62 6f  75 6e 64 61 72 79 20 66  |ext x boundary f|
00001970  6f 72 20 61 20 70 6f 73  73 69 62 6c 65 20 69 6e  |or a possible in|
00001980  74 65 72 73 65 63 74 69  6f 6e 20 2a 2f 0a 79 5f  |tersection */.y_|
00001990  62 6f 75 6e 64 2c 20 2f  2a 20 74 68 69 73 20 68  |bound, /* this h|
000019a0  6f 6c 64 73 20 74 68 65  20 6e 65 78 74 20 79 20  |olds the next y |
000019b0  62 6f 75 6e 64 61 72 79  20 66 6f 72 20 61 20 70  |boundary for a p|
000019c0  6f 73 73 69 62 6c 65 20  69 6e 74 65 72 73 65 63  |ossible intersec|
000019d0  74 69 6f 6e 20 2a 2f 0a  6e 65 78 74 5f 79 5f 63  |tion */.next_y_c|
000019e0  65 6c 6c 2c 20 2f 2a 20  74 68 69 73 20 69 73 20  |ell, /* this is |
000019f0  75 73 65 64 20 74 6f 20  66 69 67 75 72 65 20 6f  |used to figure o|
00001a00  75 74 20 74 68 65 20 71  75 61 64 72 61 6e 74 20  |ut the quadrant |
00001a10  6f 66 20 74 68 65 20 72  61 79 20 28 2b 2f 2d 29  |of the ray (+/-)|
00001a20  2a 2f 0a 6e 65 78 74 5f  78 5f 63 65 6c 6c 2c 20  |*/.next_x_cell, |
00001a30  2f 2a 20 22 20 2a 2f 0a  78 5f 64 65 6c 74 61 2c  |/* " */.x_delta,|
00001a40  20 2f 2a 20 74 68 69 73  20 69 73 20 2b 27 64 20  | /* this is +'d |
00001a50  74 6f 20 74 68 65 20 78  5f 62 6f 75 6e 64 20 76  |to the x_bound v|
00001a60  61 72 2e 20 74 6f 20 6d  6f 76 65 20 74 6f 20 74  |ar. to move to t|
00001a70  68 65 20 6e 65 78 74 20  62 6f 75 6e 64 61 72 79  |he next boundary|
00001a80  20 2a 2f 0a 79 5f 64 65  6c 74 61 2c 20 2f 2a 20  | */.y_delta, /* |
00001a90  74 68 69 73 20 69 73 20  2b 27 64 20 74 6f 20 74  |this is +'d to t|
00001aa0  68 65 20 79 5f 62 6f 75  6e 64 20 76 61 72 2e 20  |he y_bound var. |
00001ab0  74 6f 20 6d 6f 76 65 20  74 6f 20 74 68 65 20 6e  |to move to the n|
00001ac0  65 78 74 20 62 6f 75 6e  64 61 72 79 20 2a 2f 0a  |ext boundary */.|
00001ad0  78 69 5f 73 61 76 65 2c  20 2f 2a 20 74 68 69 73  |xi_save, /* this|
00001ae0  20 73 74 6f 72 65 73 20  77 68 65 72 65 20 74 68  | stores where th|
00001af0  65 20 78 20 63 61 73 74  69 6e 67 20 72 61 79 20  |e x casting ray |
00001b00  6d 61 64 65 20 69 74 73  20 69 6e 74 65 72 73 65  |made its interse|
00001b10  63 74 69 6f 6e 20 2a 2f  0a 79 69 5f 73 61 76 65  |ction */.yi_save|
00001b20  2c 20 2f 2a 20 74 68 69  73 20 73 74 6f 72 65 73  |, /* this stores|
00001b30  20 77 68 65 72 65 20 74  68 65 20 79 20 63 61 73  | where the y cas|
00001b40  74 69 6e 67 20 72 61 79  20 6d 61 64 65 20 69 74  |ting ray made it|
00001b50  73 20 69 6e 74 65 72 73  65 63 74 69 6f 6e 20 2a  |s intersection *|
00001b60  2f 0a 73 63 61 6c 65 2c  20 20 20 2f 2a 20 74 68  |/.scale,   /* th|
00001b70  69 73 20 73 74 6f 72 65  73 20 74 68 65 20 73 63  |is stores the sc|
00001b80  61 6c 65 20 6f 66 20 74  68 65 20 73 6c 69 76 65  |ale of the slive|
00001b90  72 20 74 6f 20 62 65 20  64 72 61 77 6e 20 69 6e  |r to be drawn in|
00001ba0  20 65 61 63 68 20 63 6f  6c 75 6d 6e 20 2a 2f 0a  | each column */.|
00001bb0  72 61 79 2c 20 2f 2a 20  74 68 69 73 20 73 74 6f  |ray, /* this sto|
00001bc0  72 65 73 20 74 68 65 20  72 61 79 20 6e 75 6d 62  |res the ray numb|
00001bd0  65 72 20 62 65 69 6e 67  20 63 61 73 74 20 6f 75  |er being cast ou|
00001be0  74 20 28 30 2d 33 32 30  29 2a 2f 0a 78 72 61 79  |t (0-320)*/.xray|
00001bf0  2c 20 2f 2a 20 74 68 69  73 20 66 6c 61 67 20 69  |, /* this flag i|
00001c00  73 20 75 73 65 64 20 74  6f 20 73 68 6f 77 20 69  |s used to show i|
00001c10  66 20 63 61 73 74 69 6e  67 20 69 73 20 6f 76 65  |f casting is ove|
00001c20  72 20 2a 2f 0a 79 72 61  79 2c 20 2f 2a 20 22 20  |r */.yray, /* " |
00001c30  2a 2f 0a 64 69 73 74 5f  78 2c 20 2f 2a 20 74 68  |*/.dist_x, /* th|
00001c40  69 73 20 68 6f 6c 64 73  20 74 68 65 20 64 69 73  |is holds the dis|
00001c50  74 61 6e 63 65 20 74 6f  20 74 68 65 20 78 20 69  |tance to the x i|
00001c60  6e 74 65 72 73 65 63 74  69 6f 6e 20 2a 2f 0a 64  |ntersection */.d|
00001c70  69 73 74 5f 79 3b 20 2f  2a 20 74 68 69 73 20 68  |ist_y; /* this h|
00001c80  6f 6c 64 73 20 74 68 65  20 64 69 73 74 61 6e 63  |olds the distanc|
00001c90  65 20 74 6f 20 74 68 65  20 79 20 69 6e 74 65 72  |e to the y inter|
00001ca0  73 65 63 74 69 6f 6e 20  2a 2f 0a 0a 66 6c 6f 61  |section */..floa|
00001cb0  74 20 78 69 2c 0a 20 20  20 20 20 20 79 69 2c 0a  |t xi,.      yi,.|
00001cc0  20 20 20 20 20 20 78 61  64 64 2c 0a 20 20 20 20  |      xadd,.    |
00001cd0  20 20 79 61 64 64 3b 20  2f 2a 20 74 68 65 73 65  |  yadd; /* these|
00001ce0  20 61 72 65 20 75 73 65  64 20 74 6f 20 61 63 63  | are used to acc|
00001cf0  75 72 61 74 65 6c 79 20  74 72 61 63 65 20 61 6e  |urately trace an|
00001d00  64 20 6d 6f 76 65 20 65  61 63 68 20 72 61 79 20  |d move each ray |
00001d10  2a 2f 0a 0a 0a 6c 6f 6e  67 20 76 61 72 69 61 62  |*/...long variab|
00001d20  6c 65 73 5b 38 5d 3b 20  2f 2a 20 74 68 69 73 20  |les[8]; /* this |
00001d30  69 73 20 75 73 65 64 20  74 6f 20 70 61 73 73 20  |is used to pass |
00001d40  76 61 72 69 61 62 6c 65  73 20 74 6f 20 61 20 73  |variables to a s|
00001d50  75 70 65 72 20 66 61 73  74 20 73 6c 69 76 65 72  |uper fast sliver|
00001d60  20 72 65 6e 64 65 72 20  2a 2f 0a 0a 2f 2a 20 66  | render */../* f|
00001d70  69 72 73 74 6c 79 2c 20  77 65 20 73 65 74 20 75  |irstly, we set u|
00001d80  70 20 74 68 65 20 76 61  72 69 61 62 6c 65 73 5b  |p the variables[|
00001d90  5d 20 77 65 20 61 6c 72  65 61 64 79 20 6b 6e 6f  |] we already kno|
00001da0  77 2c 20 73 75 63 68 20  61 73 20 73 63 72 65 65  |w, such as scree|
00001db0  6e 5f 61 64 64 72 65 73  73 2c 20 77 61 6c 6c 73  |n_address, walls|
00001dc0  20 61 6e 64 20 74 68 65  20 73 63 72 65 65 6e 20  | and the screen |
00001dd0  68 65 69 67 68 74 20 77  65 20 61 72 65 20 75 73  |height we are us|
00001de0  69 6e 67 2e 20 54 68 65  73 65 20 61 72 65 20 61  |ing. These are a|
00001df0  6c 6c 20 74 68 69 6e 67  73 20 77 68 69 63 68 20  |ll things which |
00001e00  6f 75 72 20 73 6c 69 76  65 72 20 72 65 6e 64 65  |our sliver rende|
00001e10  72 65 72 20 6e 65 65 64  73 20 74 6f 20 6b 6e 6f  |rer needs to kno|
00001e20  77 20 74 6f 20 70 6c 6f  74 20 69 74 73 20 63 6f  |w to plot its co|
00001e30  6c 75 6d 6e 20 2a 2f 0a  0a 76 61 72 69 61 62 6c  |lumn */..variabl|
00001e40  65 73 5b 30 5d 3d 28 63  68 61 72 20 2a 29 73 63  |es[0]=(char *)sc|
00001e50  72 65 65 6e 5f 61 64 64  72 65 73 73 3b 0a 76 61  |reen_address;.va|
00001e60  72 69 61 62 6c 65 73 5b  31 5d 3d 28 63 68 61 72  |riables[1]=(char|
00001e70  20 2a 29 77 61 6c 6c 73  3b 0a 76 61 72 69 61 62  | *)walls;.variab|
00001e80  6c 65 73 5b 35 5d 3d 53  43 52 45 45 4e 5f 48 45  |les[5]=SCREEN_HE|
00001e90  49 47 48 54 3b 0a 0a 2f  2a 20 6e 6f 77 20 77 65  |IGHT;../* now we|
00001ea0  20 67 65 74 20 64 6f 77  6e 20 74 6f 20 74 68 65  | get down to the|
00001eb0  20 6e 69 74 74 79 20 67  72 69 74 74 79 2e 20 48  | nitty gritty. H|
00001ec0  65 72 65 20 77 65 20 73  75 62 74 72 61 63 74 20  |ere we subtract |
00001ed0  33 30 20 64 65 67 72 65  65 73 20 66 72 6f 6d 20  |30 degrees from |
00001ee0  74 68 65 20 76 69 65 77  69 6e 67 20 61 6e 67 6c  |the viewing angl|
00001ef0  65 20 72 65 6d 65 6d 62  65 72 20 74 68 61 74 20  |e remember that |
00001f00  6f 75 72 20 46 4f 56 20  69 73 20 36 30 20 64 65  |our FOV is 60 de|
00001f10  67 72 65 65 73 20 77 68  69 63 68 20 6d 65 61 6e  |grees which mean|
00001f20  73 20 74 68 61 74 20 77  65 20 63 61 73 74 20 66  |s that we cast f|
00001f30  72 6f 6d 20 2d 33 30 20  74 6f 20 2b 33 30 20 2a  |rom -30 to +30 *|
00001f40  2f 0a 0a 69 66 20 28 20  28 76 69 65 77 5f 61 6e  |/..if ( (view_an|
00001f50  67 6c 65 2d 3d 41 4e 47  4c 45 5f 33 30 29 20 3c  |gle-=ANGLE_30) <|
00001f60  20 30 29 0a 20 20 20 7b  0a 20 20 20 2f 2a 20 74  | 0).   {.   /* t|
00001f70  68 69 73 20 65 6e 73 75  72 65 73 20 74 68 61 74  |his ensures that|
00001f80  20 77 65 20 64 6f 6e 27  74 20 67 6f 20 6f 76 65  | we don't go ove|
00001f90  72 20 6f 72 20 75 6e 64  65 72 20 30 2f 33 36 30  |r or under 0/360|
00001fa0  20 64 65 67 72 65 65 73  21 20 2a 2f 0a 20 20 20  | degrees! */.   |
00001fb0  76 69 65 77 5f 61 6e 67  6c 65 3d 41 4e 47 4c 45  |view_angle=ANGLE|
00001fc0  5f 33 36 30 20 2b 20 76  69 65 77 5f 61 6e 67 6c  |_360 + view_angl|
00001fd0  65 3b 0a 20 20 20 7d 0a  2f 2a 20 6e 6f 77 20 77  |e;.   }./* now w|
00001fe0  65 20 73 74 61 72 74 20  74 68 65 20 6d 61 69 6e  |e start the main|
00001ff0  20 6c 6f 6f 70 2c 20 73  74 61 72 74 20 61 74 20  | loop, start at |
00002000  74 68 65 20 72 69 67 68  74 20 6f 66 20 74 68 65  |the right of the|
00002010  20 73 63 72 65 65 6e 20  28 33 31 39 29 2c 20 61  | screen (319), a|
00002020  6e 64 20 63 61 73 74 20  65 61 63 68 20 63 6f 6c  |nd cast each col|
00002030  75 6d 6e 20 6f 6e 65 20  62 79 20 6f 6e 65 20 74  |umn one by one t|
00002040  6f 20 74 68 65 20 6c 65  66 74 20 2a 2f 0a 0a 66  |o the left */..f|
00002050  6f 72 20 28 72 61 79 3d  33 31 39 3b 20 72 61 79  |or (ray=319; ray|
00002060  3e 3d 30 3b 20 72 61 79  2d 2d 29 0a 20 20 20 20  |>=0; ray--).    |
00002070  7b 0a 2f 2a 20 66 6f 72  20 65 61 63 68 20 72 61  |{./* for each ra|
00002080  79 20 74 6f 20 62 65 20  63 61 73 74 20 77 65 20  |y to be cast we |
00002090  61 63 74 75 61 6c 6c 79  20 63 61 73 74 20 6f 75  |actually cast ou|
000020a0  74 20 74 77 6f 20 72 61  79 73 20 3a 20 6f 6e 65  |t two rays : one|
000020b0  20 74 6f 20 63 68 65 63  6b 20 66 6f 72 20 76 65  | to check for ve|
000020c0  72 74 69 63 61 6c 20 62  6f 75 6e 64 61 72 79 20  |rtical boundary |
000020d0  63 6f 6c 6c 69 73 69 6f  6e 73 20 61 6e 64 20 74  |collisions and t|
000020e0  68 65 20 6f 74 68 65 72  20 74 6f 20 63 68 65 63  |he other to chec|
000020f0  6b 20 66 6f 72 20 68 6f  72 69 7a 6f 6e 74 61 6c  |k for horizontal|
00002100  20 62 6f 75 6e 64 61 72  79 20 63 6f 6c 6c 69 73  | boundary collis|
00002110  69 6f 6e 73 2e 20 43 6f  6e 73 69 64 65 72 69 6e  |ions. Considerin|
00002120  67 20 74 68 61 74 20 77  61 6c 6c 73 20 66 69 6c  |g that walls fil|
00002130  6c 20 75 70 20 65 61 63  68 20 63 65 6c 6c 2c 20  |l up each cell, |
00002140  77 65 20 6e 65 65 64 20  6f 6e 6c 79 20 6c 6f 6f  |we need only loo|
00002150  6b 20 66 6f 72 20 69 6e  74 65 72 73 65 63 74 69  |k for intersecti|
00002160  6f 6e 73 20 6f 6e 20 74  68 65 20 62 6f 75 6e 64  |ons on the bound|
00002170  61 72 69 65 73 2e 20 57  65 20 68 61 76 65 20 74  |aries. We have t|
00002180  6f 20 70 65 72 66 6f 72  6d 20 73 65 70 65 72 61  |o perform sepera|
00002190  74 65 20 63 61 73 74 20  62 65 63 61 75 73 65 20  |te cast because |
000021a0  6a 75 73 74 20 63 61 73  74 69 6e 67 20 6f 6e 65  |just casting one|
000021b0  20 72 61 79 20 63 6f 6d  70 6c 69 63 61 74 65 73  | ray complicates|
000021c0  20 74 68 65 20 6d 61 74  74 65 72 20 61 6e 64 20  | the matter and |
000021d0  69 74 20 64 6f 65 73 6e  27 74 20 67 69 76 65 20  |it doesn't give |
000021e0  6d 75 63 68 20 73 70 65  65 64 20 69 6e 63 72 65  |much speed incre|
000021f0  61 73 65 2c 20 69 66 20  61 6e 79 2e 20 2a 2f 0a  |ase, if any. */.|
00002200  0a 2f 2a 20 53 45 43 54  49 4f 4e 20 31 20 3a 20  |./* SECTION 1 : |
00002210  43 41 4c 43 55 4c 41 54  49 4e 47 20 54 48 45 20  |CALCULATING THE |
00002220  46 49 52 53 54 20 58 20  61 6e 64 20 59 20 49 4e  |FIRST X and Y IN|
00002230  54 45 52 53 45 43 54 49  4f 4e 53 2a 2f 0a 2f 2a  |TERSECTIONS*/./*|
00002240  20 4f 6e 63 65 20 77 65  20 68 61 76 65 20 64 6f  | Once we have do|
00002250  6e 65 20 74 68 69 73 20  74 68 65 20 66 6f 6c 6c  |ne this the foll|
00002260  6f 77 69 6e 67 20 69 6e  74 65 72 73 65 63 74 69  |owing intersecti|
00002270  6f 6e 73 20 61 72 65 20  65 61 73 79 2a 2f 0a 0a  |ons are easy*/..|
00002280  0a 2f 2a 20 54 68 65 20  58 20 43 41 53 54 49 4e  |./* The X CASTIN|
00002290  47 20 52 41 59 20 3a 20  68 65 72 65 20 77 65 20  |G RAY : here we |
000022a0  74 65 73 74 20 74 6f 20  73 65 65 20 69 66 20 74  |test to see if t|
000022b0  68 65 20 61 6e 67 6c 65  20 6f 66 20 74 68 65 20  |he angle of the |
000022c0  72 61 79 20 69 73 20 66  61 63 69 6e 67 20 75 70  |ray is facing up|
000022d0  77 61 72 64 73 2e 20 57  65 20 6e 65 65 64 20 74  |wards. We need t|
000022e0  6f 20 6b 6e 6f 77 20 77  68 69 63 68 20 68 61 6c  |o know which hal|
000022f0  66 70 6c 61 6e 65 20 77  65 27 72 65 20 63 61 73  |fplane we're cas|
00002300  74 69 6e 67 20 66 72 6f  6d 20 72 65 6c 61 74 69  |ting from relati|
00002310  76 65 20 74 6f 20 74 68  65 20 79 2d 61 78 69 73  |ve to the y-axis|
00002320  2e 20 2a 2f 0a 0a 0a 20  69 66 20 28 76 69 65 77  |. */... if (view|
00002330  5f 61 6e 67 6c 65 20 3e  3d 20 41 4e 47 4c 45 5f  |_angle >= ANGLE_|
00002340  30 20 26 26 20 76 69 65  77 5f 61 6e 67 6c 65 20  |0 && view_angle |
00002350  3c 20 41 4e 47 4c 45 5f  31 38 30 29 0a 20 20 20  |< ANGLE_180).   |
00002360  20 20 20 20 7b 0a 2f 2a  20 69 66 20 73 6f 20 74  |    {./* if so t|
00002370  68 65 6e 20 77 65 20 61  73 73 69 67 6e 20 76 61  |hen we assign va|
00002380  72 69 61 62 6c 65 73 20  74 6f 20 74 68 61 74 20  |riables to that |
00002390  65 66 66 65 63 74 2e 20  57 65 20 6d 75 73 74 20  |effect. We must |
000023a0  63 6f 6d 70 75 74 65 20  74 68 65 20 66 69 72 73  |compute the firs|
000023b0  74 20 68 6f 72 69 7a 6f  6e 74 61 6c 20 6c 69 6e  |t horizontal lin|
000023c0  65 20 74 68 61 74 20 63  6f 75 6c 64 20 62 65 20  |e that could be |
000023d0  69 6e 74 65 72 73 65 63  74 65 64 20 77 69 74 68  |intersected with|
000023e0  20 74 68 65 20 72 61 79  2e 20 4e 6f 74 65 20 3a  | the ray. Note :|
000023f0  20 69 74 20 77 69 6c 6c  20 62 65 20 61 62 6f 76  | it will be abov|
00002400  65 20 74 68 65 20 76 69  65 77 65 72 2e 2a 2f 0a  |e the viewer.*/.|
00002410  0a 79 5f 62 6f 75 6e 64  20 3d 20 28 43 45 4c 4c  |.y_bound = (CELL|
00002420  5f 59 5f 53 49 5a 45 20  2b 20 28 76 69 65 77 5f  |_Y_SIZE + (view_|
00002430  79 20 26 20 30 78 66 66  63 30 29 29 3b 20 2f 2a  |y & 0xffc0)); /*|
00002440  20 74 68 69 73 20 6c 69  6e 65 20 69 73 20 6d 65  | this line is me|
00002450  72 65 6c 79 20 61 6e 20  6f 70 74 69 6d 69 7a 65  |rely an optimize|
00002460  64 20 76 65 72 73 69 6f  6e 20 6f 66 20 43 45 4c  |d version of CEL|
00002470  4c 5f 59 5f 53 49 5a 45  20 2b 20 28 76 69 65 77  |L_Y_SIZE + (view|
00002480  5f 79 20 25 20 36 34 29  2e 20 49 20 75 73 65 20  |_y % 64). I use |
00002490  69 74 20 6d 61 6e 79 20  74 69 6d 65 73 20 69 6e  |it many times in|
000024a0  20 74 68 69 73 20 65 6e  67 69 6e 65 2e 20 2a 2f  | this engine. */|
000024b0  0a 0a 79 5f 64 65 6c 74  61 20 3d 20 43 45 4c 4c  |..y_delta = CELL|
000024c0  5f 59 5f 53 49 5a 45 3b  20 2f 2a 20 74 68 69 73  |_Y_SIZE; /* this|
000024d0  20 6d 65 61 6e 73 20 74  68 61 74 20 66 6f 72 20  | means that for |
000024e0  65 76 65 72 79 20 6d 6f  76 65 6d 65 6e 74 20 6f  |every movement o|
000024f0  66 20 74 68 65 20 72 61  79 2c 20 74 68 65 20 79  |f the ray, the y|
00002500  20 62 6f 75 6e 64 61 72  79 20 6d 6f 76 65 73 20  | boundary moves |
00002510  75 70 20 6f 6e 65 20 63  65 6c 6c 2c 20 77 68 69  |up one cell, whi|
00002520  63 68 20 69 74 20 77 6f  75 6c 64 2e 20 49 74 20  |ch it would. It |
00002530  69 73 20 74 68 65 20 64  65 6c 74 61 20 74 6f 20  |is the delta to |
00002540  67 65 74 20 74 6f 20 74  68 65 20 6e 65 78 74 20  |get to the next |
00002550  68 6f 72 69 7a 6f 6e 74  61 6c 20 6c 69 6e 65 20  |horizontal line |
00002560  2a 2f 0a 0a 2f 2a 20 6e  65 78 74 20 77 65 20 75  |*/../* next we u|
00002570  73 65 20 74 68 65 20 69  6e 76 65 72 73 65 20 74  |se the inverse t|
00002580  61 6e 20 66 75 6e 63 74  69 6f 6e 20 74 6f 20 63  |an function to c|
00002590  61 6c 63 75 6c 61 74 65  20 74 68 65 20 69 6e 69  |alculate the ini|
000025a0  74 69 61 6c 20 70 6f 73  69 74 69 6f 6e 20 6f 66  |tial position of|
000025b0  20 74 68 65 20 78 20 62  6f 75 6e 64 61 72 79 20  | the x boundary |
000025c0  73 65 61 72 63 68 69 6e  67 20 72 61 79 20 6f 6e  |searching ray on|
000025d0  20 69 74 73 20 66 69 72  73 74 20 69 6e 74 65 72  | its first inter|
000025e0  73 65 63 74 69 6f 6e 2e  20 57 65 20 68 61 76 65  |section. We have|
000025f0  20 74 6f 20 75 73 65 20  74 61 6e 20 62 65 63 61  | to use tan beca|
00002600  75 73 65 20 69 74 20 69  73 20 72 65 6c 61 74 65  |use it is relate|
00002610  64 20 74 6f 20 73 6c 6f  70 65 73 20 2a 2f 0a 0a  |d to slopes */..|
00002620  78 69 20 3d 20 28 66 6c  6f 61 74 29 28 69 6e 76  |xi = (float)(inv|
00002630  5f 74 61 6e 5f 74 61 62  6c 65 5b 76 69 65 77 5f  |_tan_table[view_|
00002640  61 6e 67 6c 65 5d 20 2a  20 28 79 5f 62 6f 75 6e  |angle] * (y_boun|
00002650  64 20 2d 20 76 69 65 77  5f 79 29 29 20 2b 76 69  |d - view_y)) +vi|
00002660  65 77 5f 78 3b 0a 0a 0a  2f 2a 20 74 68 69 73 20  |ew_x;.../* this |
00002670  6d 65 61 6e 73 20 74 68  61 74 20 74 68 65 20 71  |means that the q|
00002680  75 61 64 72 61 6e 74 20  6f 66 20 74 68 65 20 72  |uadrant of the r|
00002690  61 79 20 69 73 20 6e 6f  74 20 6e 65 67 61 74 69  |ay is not negati|
000026a0  76 65 2c 20 74 68 61 74  20 69 73 20 74 68 65 20  |ve, that is the |
000026b0  6e 65 78 74 20 79 20 62  6f 75 6e 64 61 72 79 20  |next y boundary |
000026c0  77 69 6c 6c 20 61 70 70  65 61 72 20 61 62 6f 76  |will appear abov|
000026d0  65 20 74 68 65 20 76 69  65 77 20 70 6f 69 6e 74  |e the view point|
000026e0  20 61 6e 64 20 6e 6f 74  20 62 65 6c 6f 77 20 28  | and not below (|
000026f0  69 6e 20 74 65 72 6d 73  20 6f 66 20 6c 6f 6f 6b  |in terms of look|
00002700  69 6e 67 20 64 6f 77 6e  20 6f 6e 20 74 68 65 20  |ing down on the |
00002710  76 69 65 77 65 72 29 2e  20 54 68 69 73 20 69 73  |viewer). This is|
00002720  20 74 68 65 20 63 65 6c  6c 20 64 65 6c 74 61 20  | the cell delta |
00002730  2a 2f 0a 6e 65 78 74 5f  79 5f 63 65 6c 6c 20 3d  |*/.next_y_cell =|
00002740  20 30 3b 0a 0a 20 20 20  20 20 20 20 7d 0a 2f 2a  | 0;..       }./*|
00002750  20 69 66 20 74 68 65 20  76 69 65 77 69 6e 67 20  | if the viewing |
00002760  61 6e 67 6c 65 20 69 73  20 67 72 65 61 74 65 72  |angle is greater|
00002770  20 74 68 61 6e 20 31 38  30 20 64 65 67 72 65 65  | than 180 degree|
00002780  73 20 61 6e 64 20 6c 65  73 73 20 74 68 61 6e 20  |s and less than |
00002790  32 37 30 20 64 65 67 72  65 65 73 20 74 68 65 6e  |270 degrees then|
000027a0  20 77 65 20 68 61 76 65  20 74 6f 20 64 6f 20 6f  | we have to do o|
000027b0  74 68 65 72 20 63 61 6c  63 75 6c 61 74 69 6f 6e  |ther calculation|
000027c0  73 20 28 6c 6f 77 65 72  20 68 61 6c 66 20 70 6c  |s (lower half pl|
000027d0  61 6e 65 29 20 2a 2f 0a  20 20 20 20 65 6c 73 65  |ane) */.    else|
000027e0  0a 20 20 20 20 20 20 20  7b 0a 2f 2a 20 77 65 20  |.       {./* we |
000027f0  6b 6e 6f 77 20 74 68 61  74 20 62 65 63 61 75 73  |know that becaus|
00002800  65 20 74 68 65 20 76 69  65 77 69 6e 67 20 61 6e  |e the viewing an|
00002810  67 6c 65 20 69 73 20 64  6f 77 6e 77 61 72 64 73  |gle is downwards|
00002820  2c 20 73 6f 20 74 68 65  6e 20 74 68 65 20 68 6f  |, so then the ho|
00002830  72 69 7a 6f 6e 74 61 6c  20 69 6e 74 65 72 73 65  |rizontal interse|
00002840  63 74 69 6f 6e 20 68 61  73 20 74 6f 20 62 65 20  |ction has to be |
00002850  42 45 4c 4f 57 20 74 68  65 20 76 69 65 77 65 72  |BELOW the viewer|
00002860  20 2a 2f 0a 79 5f 62 6f  75 6e 64 20 3d 20 28 69  | */.y_bound = (i|
00002870  6e 74 29 28 76 69 65 77  5f 79 20 26 20 30 78 66  |nt)(view_y & 0xf|
00002880  66 63 30 29 3b 0a 0a 2f  2a 20 62 65 63 61 75 73  |fc0);../* becaus|
00002890  65 20 6f 66 20 74 68 69  73 20 77 65 20 61 6c 73  |e of this we als|
000028a0  6f 20 6b 6e 6f 77 20 74  68 61 74 20 74 68 65 20  |o know that the |
000028b0  6e 65 78 74 20 59 20 69  6e 74 65 72 73 65 63 74  |next Y intersect|
000028c0  69 6f 6e 73 20 77 69 6c  6c 20 62 65 20 61 20 63  |ions will be a c|
000028d0  65 6c 6c 20 62 65 6c 6f  77 20 65 61 63 68 20 6f  |ell below each o|
000028e0  74 68 65 72 2e 20 53 6f  20 74 68 65 20 64 65 6c  |ther. So the del|
000028f0  74 61 20 66 6f 72 20 65  61 63 68 20 68 6f 72 69  |ta for each hori|
00002900  7a 6f 6e 74 61 6c 20 69  6e 74 65 72 73 65 63 74  |zontal intersect|
00002910  69 6f 6e 20 77 69 6c 6c  20 62 65 20 61 20 63 65  |ion will be a ce|
00002920  6c 6c 20 62 65 6c 6f 77  20 20 74 68 65 20 6c 61  |ll below  the la|
00002930  73 74 20 2a 2f 0a 79 5f  64 65 6c 74 61 20 3d 20  |st */.y_delta = |
00002940  2d 43 45 4c 4c 5f 59 5f  53 49 5a 45 3b 0a 0a 2f  |-CELL_Y_SIZE;../|
00002950  2a 20 77 65 20 61 67 61  69 6e 20 75 73 65 20 74  |* we again use t|
00002960  68 65 20 74 61 6e 67 65  6e 74 20 66 75 6e 63 74  |he tangent funct|
00002970  69 6f 6e 2c 20 6a 75 73  74 20 61 73 20 62 65 66  |ion, just as bef|
00002980  6f 72 65 2c 20 74 6f 20  63 61 6c 63 75 6c 61 74  |ore, to calculat|
00002990  65 20 74 68 65 20 66 69  72 73 74 20 78 20 69 6e  |e the first x in|
000029a0  74 65 72 73 65 63 74 69  6f 6e 20 77 69 74 68 20  |tersection with |
000029b0  61 20 62 6f 75 6e 64 61  72 79 2e 20 2a 2f 0a 0a  |a boundary. */..|
000029c0  78 69 20 3d 20 28 66 6c  6f 61 74 29 28 69 6e 76  |xi = (float)(inv|
000029d0  5f 74 61 6e 5f 74 61 62  6c 65 5b 76 69 65 77 5f  |_tan_table[view_|
000029e0  61 6e 67 6c 65 5d 20 2a  20 28 79 5f 62 6f 75 6e  |angle] * (y_boun|
000029f0  64 20 2d 20 76 69 65 77  5f 79 29 29 20 2b 76 69  |d - view_y)) +vi|
00002a00  65 77 5f 78 3b 0a 0a 2f  2a 20 61 6e 64 20 77 65  |ew_x;../* and we|
00002a10  20 6b 6e 6f 77 20 61 6c  73 6f 20 74 68 61 74 20  | know also that |
00002a20  74 68 65 20 71 75 61 64  72 61 6e 74 20 69 73 20  |the quadrant is |
00002a30  62 65 6c 6f 77 20 74 68  65 20 70 6c 61 79 65 72  |below the player|
00002a40  2c 20 73 6f 20 74 68 65  20 63 65 6c 6c 20 79 20  |, so the cell y |
00002a50  64 65 6c 74 61 20 77 69  6c 6c 20 62 65 20 6e 65  |delta will be ne|
00002a60  67 61 74 69 76 65 20 2a  2f 0a 0a 6e 65 78 74 5f  |gative */..next_|
00002a70  79 5f 63 65 6c 6c 20 3d  20 2d 31 3b 0a 0a 20 20  |y_cell = -1;..  |
00002a80  20 20 20 20 20 7d 0a 2f  2a 20 59 20 52 41 59 20  |     }./* Y RAY |
00002a90  3a 20 77 65 20 64 6f 20  73 69 6d 69 6c 61 72 20  |: we do similar |
00002aa0  63 61 6c 63 75 6c 61 74  69 6f 6e 73 20 62 75 74  |calculations but|
00002ab0  20 74 68 69 73 20 74 69  6d 65 20 74 6f 20 63 61  | this time to ca|
00002ac0  6c 63 75 6c 61 74 65 20  74 68 65 20 66 69 72 73  |lculate the firs|
00002ad0  74 20 79 20 69 6e 74 65  72 73 65 63 74 69 6f 6e  |t y intersection|
00002ae0  73 20 2a 2f 0a 0a 2f 2a  20 77 65 20 74 65 73 74  |s */../* we test|
00002af0  20 74 6f 20 73 65 65 20  69 66 20 74 68 65 20 76  | to see if the v|
00002b00  69 65 77 20 61 6e 67 6c  65 20 69 73 20 77 69 74  |iew angle is wit|
00002b10  68 69 6e 20 74 68 65 20  76 65 72 74 69 63 61 6c  |hin the vertical|
00002b20  20 61 73 79 6d 70 74 6f  74 65 73 20 6f 66 20 33  | asymptotes of 3|
00002b30  36 30 20 64 65 67 72 65  65 73 2e 20 57 65 20 6e  |60 degrees. We n|
00002b40  65 65 64 20 74 6f 20 6b  6e 6f 77 20 77 68 69 63  |eed to know whic|
00002b50  68 20 68 61 6c 66 70 6c  61 6e 65 20 77 65 27 72  |h halfplane we'r|
00002b60  65 20 63 61 73 74 69 6e  67 20 66 72 6f 6d 20 72  |e casting from r|
00002b70  65 6c 61 74 69 76 65 20  74 6f 20 74 68 65 20 78  |elative to the x|
00002b80  2d 61 78 69 73 2e 20 2a  2f 0a 0a 69 66 20 28 76  |-axis. */..if (v|
00002b90  69 65 77 5f 61 6e 67 6c  65 20 3c 20 41 4e 47 4c  |iew_angle < ANGL|
00002ba0  45 5f 39 30 20 7c 7c 20  76 69 65 77 5f 61 6e 67  |E_90 || view_ang|
00002bb0  6c 65 20 3e 3d 20 41 4e  47 4c 45 5f 32 37 30 29  |le >= ANGLE_270)|
00002bc0  0a 20 20 20 20 20 20 20  7b 0a 2f 2a 20 77 65 20  |.       {./* we |
00002bd0  63 61 6e 20 64 65 64 75  63 65 20 63 65 72 74 61  |can deduce certa|
00002be0  69 6e 20 74 68 69 6e 67  73 2c 20 6a 75 73 74 20  |in things, just |
00002bf0  61 73 20 77 69 74 68 20  74 68 65 20 78 20 72 61  |as with the x ra|
00002c00  79 2e 20 57 65 20 6b 6e  6f 77 20 74 68 61 74 20  |y. We know that |
00002c10  62 65 63 61 75 73 65 20  74 68 65 20 76 69 65 77  |because the view|
00002c20  20 61 6e 67 6c 65 20 69  73 20 74 6f 20 74 68 65  | angle is to the|
00002c30  20 72 69 67 68 74 2c 20  74 68 65 20 6e 65 78 74  | right, the next|
00002c40  20 58 20 62 6f 75 6e 64  61 72 79 20 28 77 68 69  | X boundary (whi|
00002c50  63 68 20 69 73 20 63 6f  6e 73 74 61 6e 74 29 20  |ch is constant) |
00002c60  77 69 6c 6c 20 62 65 20  74 6f 20 74 68 65 20 52  |will be to the R|
00002c70  49 47 48 54 20 6f 66 20  74 68 65 20 76 69 65 77  |IGHT of the view|
00002c80  65 72 2e 20 2a 2f 0a 78  5f 62 6f 75 6e 64 20 3d  |er. */.x_bound =|
00002c90  20 28 69 6e 74 29 28 43  45 4c 4c 5f 58 5f 53 49  | (int)(CELL_X_SI|
00002ca0  5a 45 20 2b 20 28 76 69  65 77 5f 78 20 26 20 30  |ZE + (view_x & 0|
00002cb0  78 66 66 63 30 29 29 3b  0a 0a 2f 2a 20 6e 6f 74  |xffc0));../* not|
00002cc0  69 63 65 20 74 68 69 73  20 72 65 63 75 72 72 69  |ice this recurri|
00002cd0  6e 67 20 6f 70 74 69 6d  69 7a 61 74 69 6f 6e 20  |ng optimization |
00002ce0  6f 66 20 76 69 65 77 5f  78 20 25 20 36 34 20 2a  |of view_x % 64 *|
00002cf0  2f 0a 0a 2f 2a 20 61 6e  64 20 77 65 20 61 6c 73  |/../* and we als|
00002d00  6f 20 6b 6e 6f 77 20 74  68 61 74 20 65 61 63 68  |o know that each|
00002d10  20 76 65 72 74 69 63 61  6c 20 63 65 6c 6c 20 62  | vertical cell b|
00002d20  6f 75 6e 64 61 72 79 20  61 66 74 65 72 20 74 68  |oundary after th|
00002d30  65 20 66 69 72 73 74 20  77 69 6c 6c 20 62 65 20  |e first will be |
00002d40  61 20 63 65 6c 6c 27 73  20 77 69 64 74 68 20 61  |a cell's width a|
00002d50  77 61 79 20 2a 2f 0a 0a  78 5f 64 65 6c 74 61 20  |way */..x_delta |
00002d60  3d 20 43 45 4c 4c 5f 58  5f 53 49 5a 45 3b 0a 2f  |= CELL_X_SIZE;./|
00002d70  2a 20 74 68 69 73 20 74  69 6d 65 20 77 65 20 75  |* this time we u|
00002d80  73 65 20 74 68 65 20 74  61 6e 67 65 6e 74 20 66  |se the tangent f|
00002d90  75 6e 63 74 69 6f 6e 20  28 6e 6f 74 20 74 68 65  |unction (not the|
00002da0  20 69 6e 76 65 72 73 65  20 74 61 6e 29 20 74 6f  | inverse tan) to|
00002db0  20 63 61 6c 63 75 6c 61  74 65 20 77 68 65 72 65  | calculate where|
00002dc0  20 74 68 65 20 66 69 72  73 74 20 79 20 62 6f 75  | the first y bou|
00002dd0  6e 64 61 72 79 20 69 6e  74 65 72 73 65 63 74 69  |ndary intersecti|
00002de0  6f 6e 20 77 69 6c 6c 20  6f 63 63 75 72 29 2e 20  |on will occur). |
00002df0  2a 2f 0a 0a 79 69 20 3d  20 28 66 6c 6f 61 74 29  |*/..yi = (float)|
00002e00  28 74 61 6e 5f 74 61 62  6c 65 5b 76 69 65 77 5f  |(tan_table[view_|
00002e10  61 6e 67 6c 65 5d 20 2a  20 28 78 5f 62 6f 75 6e  |angle] * (x_boun|
00002e20  64 20 2d 20 76 69 65 77  5f 78 29 29 20 2b 76 69  |d - view_x)) +vi|
00002e30  65 77 5f 79 3b 0a 0a 2f  2a 20 61 6e 64 20 77 65  |ew_y;../* and we|
00002e40  20 6b 6e 6f 77 20 61 6c  73 6f 20 74 68 61 74 20  | know also that |
00002e50  62 65 63 61 75 73 65 20  74 68 65 20 76 69 65 77  |because the view|
00002e60  20 69 73 20 70 6f 73 69  74 69 76 65 2c 20 74 68  | is positive, th|
00002e70  65 20 6e 65 78 74 5f 78  5f 63 65 6c 6c 20 64 65  |e next_x_cell de|
00002e80  6c 74 61 20 64 6f 65 73  20 6e 6f 74 20 6e 65 65  |lta does not nee|
00002e90  64 20 74 6f 20 62 65 20  6e 65 67 61 74 69 76 65  |d to be negative|
00002ea0  20 2a 2f 0a 6e 65 78 74  5f 78 5f 63 65 6c 6c 20  | */.next_x_cell |
00002eb0  3d 20 30 3b 0a 0a 20 20  20 20 20 20 20 7d 0a 2f  |= 0;..       }./|
00002ec0  2a 20 6f 74 68 65 72 77  69 73 65 2c 20 69 66 20  |* otherwise, if |
00002ed0  74 68 65 20 76 69 65 77  69 6e 67 20 61 6e 67 6c  |the viewing angl|
00002ee0  65 20 69 73 20 74 6f 77  61 72 64 73 20 74 68 65  |e is towards the|
00002ef0  20 6f 74 68 65 72 20 64  69 72 65 63 74 69 6f 6e  | other direction|
00002f00  2e 2e 2e 2a 2f 0a 20 20  20 20 65 6c 73 65 0a 20  |...*/.    else. |
00002f10  20 20 20 20 20 20 7b 0a  2f 2a 20 77 65 20 6b 6e  |      {./* we kn|
00002f20  6f 77 20 74 68 61 74 20  74 68 65 20 66 69 72 73  |ow that the firs|
00002f30  74 20 78 20 62 6f 75 6e  64 61 72 79 20 63 61 6e  |t x boundary can|
00002f40  20 6f 63 63 75 72 20 6f  6e 6c 79 20 74 6f 20 74  | occur only to t|
00002f50  68 65 20 6c 65 66 74 20  6f 66 20 74 68 65 20 76  |he left of the v|
00002f60  69 65 77 65 72 20 62 65  63 61 75 73 65 20 74 68  |iewer because th|
00002f70  65 20 72 61 79 20 61 6e  67 6c 65 20 69 73 20 66  |e ray angle is f|
00002f80  61 63 69 6e 67 20 6c 65  66 74 2e 20 53 6f 20 77  |acing left. So w|
00002f90  65 20 63 61 6e 20 64 6f  20 76 69 65 77 5f 78 20  |e can do view_x |
00002fa0  25 20 36 34 20 74 6f 20  63 61 6c 63 75 6c 61 74  |% 64 to calculat|
00002fb0  65 20 74 68 65 20 66 69  72 73 74 20 76 65 72 74  |e the first vert|
00002fc0  69 63 61 6c 20 62 6f 75  6e 64 61 72 79 2c 20 74  |ical boundary, t|
00002fd0  68 69 73 20 73 68 6f 75  6c 64 20 62 65 20 62 65  |his should be be|
00002fe0  63 6f 6d 69 6e 67 20 6f  62 76 69 6f 75 73 20 2a  |coming obvious *|
00002ff0  2f 0a 78 5f 62 6f 75 6e  64 20 3d 20 28 69 6e 74  |/.x_bound = (int|
00003000  29 28 76 69 65 77 5f 78  20 26 20 30 78 66 66 63  |)(view_x & 0xffc|
00003010  30 29 3b 0a 0a 2f 2a 20  77 65 20 61 6c 73 6f 20  |0);../* we also |
00003020  6b 6e 6f 77 20 74 68 61  74 20 74 68 65 20 64 65  |know that the de|
00003030  6c 74 61 20 66 6f 72 20  74 68 65 20 63 65 6c 6c  |lta for the cell|
00003040  20 77 69 6c 6c 20 62 65  20 74 6f 20 74 68 65 20  | will be to the |
00003050  6c 65 66 74 2c 20 65 61  63 68 20 74 69 6d 65 20  |left, each time |
00003060  74 68 65 20 72 61 79 20  6d 6f 76 65 73 20 74 6f  |the ray moves to|
00003070  20 74 68 65 20 6e 65 78  74 20 62 6f 75 6e 64 61  | the next bounda|
00003080  72 79 20 74 68 65 20 6e  65 78 74 20 76 65 72 74  |ry the next vert|
00003090  69 63 61 6c 20 69 6e 74  65 72 73 65 63 74 69 6f  |ical intersectio|
000030a0  6e 20 77 69 6c 6c 20 62  65 20 61 20 63 65 6c 6c  |n will be a cell|
000030b0  20 74 6f 20 74 68 65 20  6c 65 66 74 20 74 68 61  | to the left tha|
000030c0  6e 20 74 68 65 20 6c 61  73 74 2e 20 2a 2f 0a 78  |n the last. */.x|
000030d0  5f 64 65 6c 74 61 20 3d  20 2d 43 45 4c 4c 5f 58  |_delta = -CELL_X|
000030e0  5f 53 49 5a 45 3b 0a 0a  2f 2a 20 77 65 20 75 73  |_SIZE;../* we us|
000030f0  65 20 74 68 65 20 74 61  6e 67 65 6e 74 61 6c 20  |e the tangental |
00003100  66 75 6e 63 74 69 6f 6e  20 61 67 61 69 6e 20 74  |function again t|
00003110  6f 20 63 61 6c 63 75 6c  61 74 65 20 74 68 65 20  |o calculate the |
00003120  70 6f 73 69 74 69 6f 6e  20 6f 6e 20 74 68 65 20  |position on the |
00003130  68 6f 72 69 7a 6f 6e 74  61 6c 20 69 6e 74 65 72  |horizontal inter|
00003140  73 65 63 74 69 6f 6e 73  20 2a 2f 0a 79 69 20 3d  |sections */.yi =|
00003150  28 66 6c 6f 61 74 29 28  74 61 6e 5f 74 61 62 6c  |(float)(tan_tabl|
00003160  65 5b 76 69 65 77 5f 61  6e 67 6c 65 5d 20 2a 20  |e[view_angle] * |
00003170  28 78 5f 62 6f 75 6e 64  20 2d 20 76 69 65 77 5f  |(x_bound - view_|
00003180  78 29 29 20 2b 76 69 65  77 5f 79 3b 0a 0a 2f 2a  |x)) +view_y;../*|
00003190  20 61 6e 64 20 77 65 20  61 6c 73 6f 20 6b 6e 6f  | and we also kno|
000031a0  77 20 74 68 61 74 20 74  68 65 20 78 20 63 65 6c  |w that the x cel|
000031b0  6c 20 76 61 6c 75 65 20  77 69 6c 6c 20 62 65 20  |l value will be |
000031c0  6d 69 6e 75 73 2c 20 62  65 63 61 75 73 65 20 61  |minus, because a|
000031d0  73 20 74 68 65 20 72 61  79 20 6d 6f 76 65 73 20  |s the ray moves |
000031e0  74 6f 20 61 6e 6f 74 68  65 72 20 63 65 6c 6c 2c  |to another cell,|
000031f0  20 62 65 63 61 75 73 65  20 74 68 65 20 72 61 79  | because the ray|
00003200  20 69 73 20 67 6f 69 6e  67 20 6c 65 66 74 2c 20  | is going left, |
00003210  74 68 65 20 76 61 6c 75  65 20 6d 75 73 74 20 62  |the value must b|
00003220  65 20 6d 69 6e 75 73 2e  20 2a 2f 0a 6e 65 78 74  |e minus. */.next|
00003230  5f 78 5f 63 65 6c 6c 20  3d 20 2d 31 3b 0a 0a 20  |_x_cell = -1;.. |
00003240  20 20 20 20 20 20 7d 0a  0a 2f 2a 20 4e 6f 77 20  |      }../* Now |
00003250  77 65 20 68 61 76 65 20  70 65 72 66 6f 72 6d 65  |we have performe|
00003260  64 20 74 68 65 20 73 6c  69 67 68 74 6c 79 20 74  |d the slightly t|
00003270  72 69 63 6b 79 20 74 61  73 6b 20 6f 66 20 74 68  |ricky task of th|
00003280  65 20 66 69 72 73 74 20  69 6e 74 65 72 73 65 63  |e first intersec|
00003290  74 69 6f 6e 73 2c 20 77  65 20 63 61 6e 20 6d 6f  |tions, we can mo|
000032a0  76 65 20 6f 6e 20 74 6f  20 63 61 6c 63 75 6c 61  |ve on to calcula|
000032b0  74 69 6e 67 20 74 68 65  20 6e 65 78 74 20 6f 6e  |ting the next on|
000032c0  65 73 2e 20 54 68 69 73  20 69 73 20 6d 6f 72 65  |es. This is more|
000032d0  20 73 69 6d 70 6c 65 2c  20 61 73 20 77 65 20 6b  | simple, as we k|
000032e0  6e 6f 77 20 74 68 61 74  20 74 68 65 20 69 6e 74  |now that the int|
000032f0  65 72 73 65 63 74 69 6f  6e 73 20 63 61 6e 20 6f  |ersections can o|
00003300  6e 6c 79 20 6f 63 63 75  72 20 61 74 20 63 65 6c  |nly occur at cel|
00003310  6c 20 62 6f 75 6e 64 61  72 69 65 73 2e 2a 2f 0a  |l boundaries.*/.|
00003320  0a 2f 2a 20 53 45 43 54  49 4f 4e 20 32 20 3a 20  |./* SECTION 2 : |
00003330  54 65 73 74 69 6e 67 20  66 6f 72 20 66 75 72 74  |Testing for furt|
00003340  68 65 72 20 69 6e 74 65  72 73 65 63 74 69 6f 6e  |her intersection|
00003350  73 20 2a 2f 0a 0a 2f 2a  20 74 68 65 73 65 20 66  |s */../* these f|
00003360  6c 61 67 73 20 73 74 6f  72 65 20 69 66 20 63 61  |lags store if ca|
00003370  73 74 69 6e 67 20 6f 66  20 62 6f 74 68 20 72 61  |sting of both ra|
00003380  79 73 20 69 73 20 63 6f  6d 70 6c 65 74 65 20 2a  |ys is complete *|
00003390  2f 0a 78 72 61 79 3d 79  72 61 79 3d 30 3b 0a 0a  |/.xray=yray=0;..|
000033a0  2f 2a 20 58 20 52 61 79  20 69 73 20 66 69 72 73  |/* X Ray is firs|
000033b0  74 20 2a 2f 0a 2f 2a 20  62 65 63 61 75 73 65 20  |t */./* because |
000033c0  77 65 20 61 72 65 20 74  65 73 74 69 6e 67 20 66  |we are testing f|
000033d0  6f 72 20 65 61 63 68 20  6e 65 78 74 20 69 6e 74  |or each next int|
000033e0  65 72 73 65 63 74 69 6f  6e 2c 20 77 65 20 63 61  |ersection, we ca|
000033f0  6e 20 66 69 67 75 72 65  20 6f 75 74 20 6d 6f 72  |n figure out mor|
00003400  65 20 65 61 73 69 6c 79  20 74 68 65 20 66 6f 6c  |e easily the fol|
00003410  6c 6f 77 69 6e 67 20 69  6e 74 65 72 73 65 63 74  |lowing intersect|
00003420  69 6f 6e 73 2e 20 2a 2f  0a 2f 2a 20 74 68 69 73  |ions. */./* this|
00003430  20 69 73 20 61 20 6c 6f  6f 6b 20 75 70 20 74 61  | is a look up ta|
00003440  62 6c 65 20 68 6f 6c 64  69 6e 67 20 74 68 65 20  |ble holding the |
00003450  6e 65 78 74 20 79 20 69  6e 74 65 72 63 65 70 74  |next y intercept|
00003460  73 2c 20 62 61 73 65 64  20 6f 6e 20 74 68 65 20  |s, based on the |
00003470  74 61 6e 67 65 6e 74 61  6c 20 66 75 6e 63 74 69  |tangental functi|
00003480  6f 6e 20 61 6e 64 20 74  68 65 20 73 69 7a 65 20  |on and the size |
00003490  6f 66 20 63 65 6c 6c 73  2e 20 42 61 73 69 63 61  |of cells. Basica|
000034a0  6c 6c 79 20 77 65 20 61  64 64 20 74 68 69 73 20  |lly we add this |
000034b0  74 6f 20 74 68 65 20 72  61 79 20 65 61 63 68 20  |to the ray each |
000034c0  74 69 6d 65 20 77 65 20  6d 6f 76 65 20 69 74 20  |time we move it |
000034d0  61 20 62 69 74 20 6d 6f  72 65 2c 20 73 65 61 72  |a bit more, sear|
000034e0  63 68 69 6e 67 20 66 6f  72 20 61 20 77 61 6c 6c  |ching for a wall|
000034f0  20 61 74 20 61 20 63 65  6c 6c 20 62 6f 75 6e 64  | at a cell bound|
00003500  61 72 79 20 2a 2f 0a 0a  79 61 64 64 3d 79 5f 73  |ary */..yadd=y_s|
00003510  74 65 70 5b 76 69 65 77  5f 61 6e 67 6c 65 5d 3b  |tep[view_angle];|
00003520  0a 0a 2f 2a 20 73 74 61  72 74 20 63 61 73 74 69  |../* start casti|
00003530  6e 67 20 74 68 65 20 78  20 72 61 79 20 2a 2f 0a  |ng the x ray */.|
00003540  77 68 69 6c 65 28 21 78  72 61 79 29 0a 7b 0a 2f  |while(!xray).{./|
00003550  2a 20 63 6f 6d 70 75 74  65 20 63 75 72 72 65 6e  |* compute curren|
00003560  74 20 63 65 6c 6c 20 70  6f 73 69 74 69 6f 6e 20  |t cell position |
00003570  6f 66 20 74 68 65 20 72  61 79 20 74 6f 20 69 6e  |of the ray to in|
00003580  73 70 65 63 74 2a 2f 0a  0a 63 65 6c 6c 5f 78 20  |spect*/..cell_x |
00003590  3d 20 28 20 28 78 5f 62  6f 75 6e 64 2b 6e 65 78  |= ( (x_bound+nex|
000035a0  74 5f 78 5f 63 65 6c 6c  29 20 3e 3e 20 43 45 4c  |t_x_cell) >> CEL|
000035b0  4c 5f 58 5f 53 49 5a 45  5f 46 50 29 3b 0a 63 65  |L_X_SIZE_FP);.ce|
000035c0  6c 6c 5f 79 20 3d 20 28  69 6e 74 29 79 69 3e 3e  |ll_y = (int)yi>>|
000035d0  43 45 4c 4c 5f 58 5f 53  49 5a 45 5f 46 50 3b 0a  |CELL_X_SIZE_FP;.|
000035e0  0a 2f 2a 20 62 6f 74 68  20 6f 66 20 74 68 65 20  |./* both of the |
000035f0  61 62 6f 76 65 20 65 78  61 6d 70 6c 65 73 20 75  |above examples u|
00003600  73 65 20 62 69 6e 61 72  79 20 73 68 69 66 74 69  |se binary shifti|
00003610  6e 67 20 74 6f 20 61 63  68 69 65 76 65 20 61 20  |ng to achieve a |
00003620  64 69 76 69 64 65 20 62  79 20 36 34 2e 20 43 65  |divide by 64. Ce|
00003630  6c 6c 5f 79 20 63 6f 6d  70 75 74 61 74 69 6f 6e  |ll_y computation|
00003640  20 75 73 65 73 20 69 64  65 6e 74 69 63 61 6c 20  | uses identical |
00003650  74 65 63 68 6e 69 71 75  65 73 20 74 6f 20 74 68  |techniques to th|
00003660  6f 73 65 20 63 6f 76 65  72 65 64 20 69 6e 20 74  |ose covered in t|
00003670  68 65 20 6d 61 67 61 7a  69 6e 65 2e 20 43 65 6c  |he magazine. Cel|
00003680  6c 5f 78 20 69 73 20 63  61 6c 63 75 6c 61 74 65  |l_x is calculate|
00003690  64 20 62 79 20 75 73 69  6e 67 20 74 68 65 20 78  |d by using the x|
000036a0  5f 62 6f 75 6e 64 20 61  6e 64 20 6e 65 78 74 5f  |_bound and next_|
000036b0  78 5f 63 65 6c 6c 20 76  61 6c 75 65 73 20 63 61  |x_cell values ca|
000036c0  6c 63 75 6c 61 74 65 64  20 62 65 66 6f 72 65 68  |lculated beforeh|
000036d0  61 6e 64 2e 20 2a 2f 0a  0a 69 66 28 63 65 6c 6c  |and. */..if(cell|
000036e0  5f 78 3c 30 29 63 65 6c  6c 5f 78 3d 30 3b 69 66  |_x<0)cell_x=0;if|
000036f0  28 63 65 6c 6c 5f 78 3e  36 33 29 63 65 6c 6c 5f  |(cell_x>63)cell_|
00003700  78 3d 36 33 3b 0a 69 66  28 63 65 6c 6c 5f 79 3c  |x=63;.if(cell_y<|
00003710  30 29 63 65 6c 6c 5f 79  3d 30 3b 69 66 28 63 65  |0)cell_y=0;if(ce|
00003720  6c 6c 5f 79 3e 36 33 29  63 65 6c 6c 5f 79 3d 36  |ll_y>63)cell_y=6|
00003730  33 3b 0a 2f 2a 20 74 68  65 73 65 20 73 69 6d 70  |3;./* these simp|
00003740  6c 65 20 6c 69 6e 65 73  20 65 6e 73 75 72 65 20  |le lines ensure |
00003750  74 68 61 74 20 74 68 65  20 72 61 79 20 64 6f 65  |that the ray doe|
00003760  73 6e 27 74 20 67 6f 20  6f 75 74 20 6f 66 20 74  |sn't go out of t|
00003770  68 65 20 77 6f 72 6c 64  2c 20 74 68 6f 75 67 68  |he world, though|
00003780  20 74 68 65 79 20 61 72  65 6e 27 74 20 72 65 61  | they aren't rea|
00003790  6c 6c 79 20 6e 65 65 64  65 64 2e 20 2a 2f 0a 0a  |lly needed. */..|
000037a0  2f 2a 20 77 65 20 6c 6f  6f 6b 20 75 70 20 69 6e  |/* we look up in|
000037b0  20 74 68 65 20 77 6f 72  6c 64 20 66 69 6c 65 20  | the world file |
000037c0  74 6f 20 73 65 65 20 69  66 20 74 68 65 72 65 20  |to see if there |
000037d0  69 73 20 61 20 77 61 6c  6c 20 61 74 20 74 68 65  |is a wall at the|
000037e0  20 69 6e 74 65 72 73 65  63 74 69 6f 6e 20 6f 66  | intersection of|
000037f0  20 6f 75 72 20 72 61 79  20 2a 2f 0a 69 66 20 28  | our ray */.if (|
00003800  28 78 5f 68 69 74 5f 74  79 70 65 20 3d 77 6f 72  |(x_hit_type =wor|
00003810  6c 64 5b 63 65 6c 6c 5f  79 5d 5b 63 65 6c 6c 5f  |ld[cell_y][cell_|
00003820  78 5d 29 21 3d 30 29 0a  7b 0a 2f 2a 20 69 66 20  |x])!=0).{./* if |
00003830  73 6f 20 77 65 20 63 61  6c 63 75 6c 61 74 65 20  |so we calculate |
00003840  74 68 65 20 64 69 73 74  61 6e 63 65 20 74 6f 20  |the distance to |
00003850  69 74 20 75 73 69 6e 67  20 74 68 65 20 6f 6c 64  |it using the old|
00003860  20 4f 2d 4c 65 76 65 6c  20 74 65 63 68 6e 69 71  | O-Level techniq|
00003870  75 65 20 6f 66 20 75 73  69 6e 67 20 73 69 6e 65  |ue of using sine|
00003880  20 61 6e 64 20 63 6f 73  69 6e 65 20 69 6e 73 74  | and cosine inst|
00003890  65 61 64 20 6f 66 20 64  6f 69 6e 67 20 74 68 65  |ead of doing the|
000038a0  20 73 74 61 6e 64 61 72  64 20 50 59 54 48 41 47  | standard PYTHAG|
000038b0  4f 52 41 53 20 74 65 63  68 6e 69 71 75 65 2e 2a  |ORAS technique.*|
000038c0  2f 0a 0a 64 69 73 74 5f  78 20 20 3d 20 28 20 28  |/..dist_x  = ( (|
000038d0  79 69 20 2d 20 76 69 65  77 5f 79 29 20 2a 20 69  |yi - view_y) * i|
000038e0  6e 76 5f 73 69 6e 5f 74  61 62 6c 65 5b 76 69 65  |nv_sin_table[vie|
000038f0  77 5f 61 6e 67 6c 65 5d  29 3b 0a 2f 2a 20 77 65  |w_angle]);./* we|
00003900  20 61 6c 73 6f 20 73 61  76 65 20 74 68 65 20 65  | also save the e|
00003910  78 61 63 74 20 70 6f 73  69 74 69 6f 6e 20 6f 66  |xact position of|
00003920  20 74 68 65 20 69 6e 74  65 72 73 65 63 74 69 6f  | the intersectio|
00003930  6e 20 62 65 63 61 75 73  65 20 77 65 20 77 69 6c  |n because we wil|
00003940  6c 20 6e 65 65 64 20 69  74 20 6c 61 74 65 72 20  |l need it later |
00003950  74 6f 20 61 64 64 20 74  65 78 74 75 72 65 20 6d  |to add texture m|
00003960  61 70 70 69 6e 67 2e 20  2a 2f 0a 79 69 5f 73 61  |apping. */.yi_sa|
00003970  76 65 20 3d 20 28 69 6e  74 29 79 69 3b 0a 2f 2a  |ve = (int)yi;./*|
00003980  20 62 65 63 61 75 73 65  20 74 68 65 20 78 20 72  | because the x r|
00003990  61 79 20 68 61 73 20 66  6f 75 6e 64 20 61 20 77  |ay has found a w|
000039a0  61 6c 6c 2c 20 77 65 20  63 61 6e 20 73 74 6f 70  |all, we can stop|
000039b0  20 63 61 73 74 69 6e 67  20 2a 2f 0a 0a 78 72 61  | casting */..xra|
000039c0  79 3d 46 4f 55 4e 44 5f  57 41 4c 4c 3b 0a 0a 7d  |y=FOUND_WALL;..}|
000039d0  0a 65 6c 73 65 0a 7b 0a  2f 2a 20 69 66 20 6e 6f  |.else.{./* if no|
000039e0  74 2c 20 77 65 20 63 6f  6d 70 75 74 65 20 74 68  |t, we compute th|
000039f0  65 20 6e 65 78 74 20 70  6f 73 73 69 62 6c 65 20  |e next possible |
00003a00  69 6e 74 65 72 73 65 63  74 69 6f 6e 20 2a 2f 0a  |intersection */.|
00003a10  79 69 20 2b 3d 79 61 64  64 3b 0a 78 5f 62 6f 75  |yi +=yadd;.x_bou|
00003a20  6e 64 20 2b 3d 20 78 5f  64 65 6c 74 61 3b 20 2f  |nd += x_delta; /|
00003a30  2a 20 61 6e 64 20 77 65  20 61 6c 73 6f 20 63 61  |* and we also ca|
00003a40  6c 63 75 6c 61 74 65 20  74 68 65 20 6e 65 78 74  |lculate the next|
00003a50  20 68 6f 72 69 7a 6f 6e  74 61 6c 20 62 6f 75 6e  | horizontal boun|
00003a60  64 61 72 79 2c 20 77 68  69 63 68 20 77 65 20 6b  |dary, which we k|
00003a70  6e 6f 77 20 77 69 6c 6c  20 62 65 20 78 5f 64 65  |now will be x_de|
00003a80  6c 74 61 20 61 77 61 79  2c 20 6e 6f 20 6e 65 65  |lta away, no nee|
00003a90  64 20 66 6f 72 20 63 6f  6d 70 6c 65 78 20 77 6f  |d for complex wo|
00003aa0  72 6b 69 6e 67 73 2e 20  2a 2f 0a 7d 0a 0a 7d 0a  |rkings. */.}..}.|
00003ab0  2f 2a 20 53 45 43 54 49  4f 4e 20 33 20 2a 2f 0a  |/* SECTION 3 */.|
00003ac0  2f 2a 20 57 45 20 4e 4f  57 20 64 6f 20 65 78 61  |/* WE NOW do exa|
00003ad0  63 74 6c 79 20 74 68 65  20 73 61 6d 65 20 62 75  |ctly the same bu|
00003ae0  74 20 66 6f 72 20 74 68  65 20 79 72 61 79 2c 20  |t for the yray, |
00003af0  77 65 20 63 61 73 74 20  69 74 20 6f 75 74 2c 20  |we cast it out, |
00003b00  63 68 65 63 6b 20 66 6f  72 20 61 20 77 61 6c 6c  |check for a wall|
00003b10  2c 20 69 66 20 74 68 65  72 65 20 69 73 20 6f 6e  |, if there is on|
00003b20  65 20 77 65 20 74 61 6b  65 20 74 68 65 20 64 69  |e we take the di|
00003b30  73 74 61 6e 63 65 20 74  6f 20 69 74 20 65 74 63  |stance to it etc|
00003b40  2c 20 69 66 20 6e 6f 74  2c 20 77 65 20 6d 6f 76  |, if not, we mov|
00003b50  65 20 20 74 68 65 20 72  61 79 20 75 6e 74 69 6c  |e  the ray until|
00003b60  20 61 20 77 61 6c 6c 20  69 74 20 66 6f 75 6e 64  | a wall it found|
00003b70  2e 20 2a 2f 0a 0a 2f 2a  20 6c 6f 6f 6b 20 75 70  |. */../* look up|
00003b80  20 74 68 65 20 76 61 6c  75 65 20 74 6f 20 61 64  | the value to ad|
00003b90  64 20 74 6f 20 74 68 65  20 72 61 79 20 65 61 63  |d to the ray eac|
00003ba0  68 20 74 69 6d 65 20 77  65 20 6d 6f 76 65 20 69  |h time we move i|
00003bb0  74 20 2a 2f 0a 0a 78 61  64 64 3d 78 5f 73 74 65  |t */..xadd=x_ste|
00003bc0  70 5b 76 69 65 77 5f 61  6e 67 6c 65 5d 3b 0a 0a  |p[view_angle];..|
00003bd0  2f 2a 20 73 74 61 72 74  20 63 61 73 74 69 6e 67  |/* start casting|
00003be0  20 74 68 65 20 72 61 79  20 2a 2f 0a 77 68 69 6c  | the ray */.whil|
00003bf0  65 28 21 79 72 61 79 29  0a 7b 0a 0a 2f 2a 20 63  |e(!yray).{../* c|
00003c00  6f 6d 70 75 74 65 20 63  75 72 72 65 6e 74 20 63  |ompute current c|
00003c10  65 6c 6c 20 74 6f 20 69  6e 73 70 65 63 74 20 2a  |ell to inspect *|
00003c20  2f 0a 0a 63 65 6c 6c 5f  78 20 3d 20 28 69 6e 74  |/..cell_x = (int|
00003c30  29 78 69 3e 3e 43 45 4c  4c 5f 59 5f 53 49 5a 45  |)xi>>CELL_Y_SIZE|
00003c40  5f 46 50 3b 0a 63 65 6c  6c 5f 79 20 3d 20 28 20  |_FP;.cell_y = ( |
00003c50  28 79 5f 62 6f 75 6e 64  20 2b 20 6e 65 78 74 5f  |(y_bound + next_|
00003c60  79 5f 63 65 6c 6c 29 20  3e 3e 20 43 45 4c 4c 5f  |y_cell) >> CELL_|
00003c70  59 5f 53 49 5a 45 5f 46  50 29 3b 0a 2f 2a 20 74  |Y_SIZE_FP);./* t|
00003c80  68 65 73 65 20 63 61 6c  63 75 6c 61 74 69 6f 6e  |hese calculation|
00003c90  73 20 77 6f 72 6b 20 6f  75 74 20 77 68 69 63 68  |s work out which|
00003ca0  20 63 65 6c 6c 73 20 74  68 65 20 72 61 79 20 69  | cells the ray i|
00003cb0  73 20 69 6e 2c 20 72 65  61 64 79 20 74 6f 20 63  |s in, ready to c|
00003cc0  68 65 63 6b 20 66 6f 72  20 77 61 6c 6c 73 20 69  |heck for walls i|
00003cd0  6e 20 74 68 65 20 77 6f  72 6c 64 5b 5d 5b 5d 20  |n the world[][] |
00003ce0  61 72 72 61 79 2e 20 54  68 65 79 20 62 6f 74 68  |array. They both|
00003cf0  20 75 73 65 20 62 69 6e  61 72 79 20 73 68 69 66  | use binary shif|
00003d00  74 69 6e 67 20 74 6f 20  70 65 72 66 6f 72 6d 20  |ting to perform |
00003d10  64 69 76 69 64 65 20 62  79 20 36 34 27 73 2e 20  |divide by 64's. |
00003d20  2a 2f 0a 0a 2f 2a 20 63  68 65 63 6b 20 74 68 61  |*/../* check tha|
00003d30  74 20 74 68 65 20 72 61  79 20 68 61 73 20 6e 6f  |t the ray has no|
00003d40  74 20 67 6f 6e 65 20 6f  75 74 20 6f 66 20 74 68  |t gone out of th|
00003d50  65 20 77 6f 72 6c 64 2c  20 74 68 6f 75 67 68 20  |e world, though |
00003d60  74 68 69 73 20 69 73 6e  27 74 20 72 65 61 6c 6c  |this isn't reall|
00003d70  79 20 6e 65 63 65 73 73  61 72 79 20 2a 2f 0a 69  |y necessary */.i|
00003d80  66 28 63 65 6c 6c 5f 78  3c 30 29 63 65 6c 6c 5f  |f(cell_x<0)cell_|
00003d90  78 3d 30 3b 69 66 28 63  65 6c 6c 5f 78 3e 36 33  |x=0;if(cell_x>63|
00003da0  29 63 65 6c 6c 5f 78 3d  36 33 3b 0a 69 66 28 63  |)cell_x=63;.if(c|
00003db0  65 6c 6c 5f 79 3c 30 29  63 65 6c 6c 5f 79 3d 30  |ell_y<0)cell_y=0|
00003dc0  3b 69 66 28 63 65 6c 6c  5f 79 3e 36 33 29 63 65  |;if(cell_y>63)ce|
00003dd0  6c 6c 5f 79 3d 36 33 3b  0a 0a 2f 2a 20 6c 6f 6f  |ll_y=63;../* loo|
00003de0  6b 20 61 6e 64 20 73 65  65 20 69 66 20 74 68 65  |k and see if the|
00003df0  72 65 20 69 73 20 61 20  77 61 6c 6c 20 61 74 20  |re is a wall at |
00003e00  74 68 65 20 63 75 72 72  65 6e 74 20 70 6f 69 6e  |the current poin|
00003e10  74 20 6f 66 20 69 6e 74  65 72 73 65 63 74 69 6f  |t of intersectio|
00003e20  6e 20 2a 2f 0a 69 66 20  28 28 79 5f 68 69 74 5f  |n */.if ((y_hit_|
00003e30  74 79 70 65 20 3d 20 77  6f 72 6c 64 5b 63 65 6c  |type = world[cel|
00003e40  6c 5f 79 5d 5b 63 65 6c  6c 5f 78 5d 29 21 3d 30  |l_y][cell_x])!=0|
00003e50  29 0a 7b 0a 2f 2a 20 55  73 65 20 74 68 65 20 6f  |).{./* Use the o|
00003e60  6c 64 20 4f 2d 4c 65 76  65 6c 20 74 72 69 61 6e  |ld O-Level trian|
00003e70  67 6c 65 20 6d 65 74 68  6f 64 20 6f 66 20 63 61  |gle method of ca|
00003e80  6c 75 6c 61 74 69 6e 67  20 64 69 73 74 61 6e 63  |lulating distanc|
00003e90  65 20 75 73 69 6e 67 20  63 6f 73 2c 20 72 61 74  |e using cos, rat|
00003ea0  68 65 72 20 74 68 61 6e  20 75 73 69 6e 67 20 50  |her than using P|
00003eb0  59 54 48 41 47 4f 52 41  53 2c 20 77 68 69 63 68  |YTHAGORAS, which|
00003ec0  20 69 73 20 73 6c 6f 77  65 72 20 62 65 63 61 75  | is slower becau|
00003ed0  73 65 20 69 74 20 75 73  65 73 20 61 20 73 71 75  |se it uses a squ|
00003ee0  61 72 65 20 72 6f 6f 74  21 20 2a 2f 0a 64 69 73  |are root! */.dis|
00003ef0  74 5f 79 20 20 3d 20 28  20 28 78 69 20 2d 20 76  |t_y  = ( (xi - v|
00003f00  69 65 77 5f 78 29 20 2a  20 69 6e 76 5f 63 6f 73  |iew_x) * inv_cos|
00003f10  5f 74 61 62 6c 65 5b 76  69 65 77 5f 61 6e 67 6c  |_table[view_angl|
00003f20  65 5d 20 29 3b 0a 0a 2f  2a 20 73 61 76 65 20 74  |e] );../* save t|
00003f30  68 65 20 65 78 61 63 74  20 69 6e 74 65 72 73 65  |he exact interse|
00003f40  63 74 69 6f 6e 20 70 6f  69 6e 74 2c 20 77 65 20  |ction point, we |
00003f50  77 69 6c 6c 20 6e 65 65  64 20 69 74 20 6c 61 74  |will need it lat|
00003f60  65 72 20 2a 2f 0a 78 69  5f 73 61 76 65 20 3d 20  |er */.xi_save = |
00003f70  28 69 6e 74 29 78 69 3b  0a 2f 2a 20 53 54 4f 50  |(int)xi;./* STOP|
00003f80  20 79 20 63 61 73 74 69  6e 67 20 69 6e 20 74 68  | y casting in th|
00003f90  61 74 20 63 61 73 65 2c  20 61 20 77 61 6c 6c 20  |at case, a wall |
00003fa0  68 61 73 20 62 65 65 6e  20 66 6f 75 6e 64 2e 20  |has been found. |
00003fb0  2a 2f 0a 79 72 61 79 3d  46 4f 55 4e 44 5f 57 41  |*/.yray=FOUND_WA|
00003fc0  4c 4c 3b 0a 7d 0a 65 6c  73 65 0a 7b 0a 2f 2a 20  |LL;.}.else.{./* |
00003fd0  69 66 20 6e 6f 74 2c 20  6d 6f 76 65 20 74 68 65  |if not, move the|
00003fe0  20 72 61 79 20 6f 6e 20  2a 2f 0a 78 69 2b 3d 78  | ray on */.xi+=x|
00003ff0  61 64 64 3b 0a 79 5f 62  6f 75 6e 64 20 2b 3d 20  |add;.y_bound += |
00004000  79 5f 64 65 6c 74 61 3b  20 2f 2a 20 61 6e 64 20  |y_delta; /* and |
00004010  6d 6f 76 65 20 74 6f 20  74 68 65 20 6e 65 78 74  |move to the next|
00004020  20 76 65 72 74 69 63 61  6c 20 62 6f 75 6e 64 61  | vertical bounda|
00004030  72 79 20 70 6f 73 69 74  69 6f 6e 20 2a 2f 0a 7d  |ry position */.}|
00004040  0a 0a 7d 0a 0a 2f 2a 20  53 45 43 54 49 4f 4e 20  |..}../* SECTION |
00004050  34 2a 2f 0a 2f 2a 20 42  6f 74 68 20 72 61 79 73  |4*/./* Both rays|
00004060  20 68 61 76 65 20 62 65  65 6e 20 63 61 73 74 2c  | have been cast,|
00004070  20 62 6f 74 68 20 72 61  79 73 20 68 61 76 65 20  | both rays have |
00004080  6d 65 74 20 61 20 77 61  6c 6c 2c 20 77 65 20 6e  |met a wall, we n|
00004090  6f 77 20 6e 65 65 64 20  74 6f 20 73 65 65 20 77  |ow need to see w|
000040a0  68 69 63 68 20 69 73 20  63 6c 6f 73 65 72 2c 20  |hich is closer, |
000040b0  61 6e 64 20 74 68 65 6e  20 70 6c 6f 74 20 69 74  |and then plot it|
000040c0  20 63 6f 72 72 65 63 74  6c 79 2e 20 2a 2f 0a 0a  | correctly. */..|
000040d0  2f 2a 20 66 69 6e 64 20  6f 75 74 20 77 68 69 63  |/* find out whic|
000040e0  68 20 77 61 6c 6c 20 28  78 20 6f 72 20 79 29 20  |h wall (x or y) |
000040f0  69 73 20 6e 65 61 72 65  72 20 74 68 65 20 76 69  |is nearer the vi|
00004100  65 77 65 72 2e 20 2a 2f  0a 0a 20 20 20 20 69 66  |ewer. */..    if|
00004110  20 28 64 69 73 74 5f 78  20 3c 20 64 69 73 74 5f  | (dist_x < dist_|
00004120  79 29 0a 0a 20 20 20 20  20 20 20 7b 0a 2f 2a 20  |y)..       {./* |
00004130  6d 61 6b 65 20 73 75 72  65 20 74 68 61 74 20 6e  |make sure that n|
00004140  6f 20 64 69 76 69 64 65  20 62 79 20 7a 65 72 6f  |o divide by zero|
00004150  73 20 6f 63 63 75 72 20  2a 2f 0a 69 66 28 64 69  |s occur */.if(di|
00004160  73 74 5f 78 3c 31 29 64  69 73 74 5f 78 3d 31 3b  |st_x<1)dist_x=1;|
00004170  0a 2f 2a 20 77 65 20 6e  65 65 64 20 74 6f 20 74  |./* we need to t|
00004180  61 6b 65 20 69 6e 74 6f  20 61 63 63 6f 75 6e 74  |ake into account|
00004190  20 68 65 72 65 2c 20 77  68 65 6e 20 63 6f 6d 70  | here, when comp|
000041a0  75 74 69 6e 67 20 74 68  65 20 73 63 61 6c 65 20  |uting the scale |
000041b0  6f 66 20 74 68 65 20 76  65 72 74 69 63 61 6c 20  |of the vertical |
000041c0  73 74 72 69 70 20 28 73  6c 69 76 65 72 29 20 74  |strip (sliver) t|
000041d0  6f 20 62 65 20 64 72 61  77 6e 2c 20 61 20 70 68  |o be drawn, a ph|
000041e0  65 6e 65 6d 65 6e 6f 6e  20 28 6f 66 20 73 6f 72  |enemenon (of sor|
000041f0  74 73 29 20 6b 6e 6f 77  6e 20 61 73 20 74 68 65  |ts) known as the|
00004200  20 22 66 69 73 68 20 62  6f 77 6c 20 65 66 66 65  | "fish bowl effe|
00004210  63 74 22 2e 20 54 68 69  73 20 69 73 20 63 61 75  |ct". This is cau|
00004220  73 65 64 20 62 79 20 6d  69 7a 69 6e 67 20 6f 66  |sed by mizing of|
00004230  20 63 61 72 74 65 73 69  61 6e 20 61 6e 64 20 70  | cartesian and p|
00004240  6f 6c 61 72 20 63 6f 6f  72 64 69 6e 61 74 65 73  |olar coordinates|
00004250  2e 20 54 6f 20 67 65 74  20 72 69 64 20 6f 66 20  |. To get rid of |
00004260  69 74 20 77 65 20 75 73  65 20 74 68 65 20 63 6f  |it we use the co|
00004270  73 69 6e 65 20 66 75 6e  63 74 69 6f 6e 2e 20 49  |sine function. I|
00004280  20 68 61 76 65 20 63 6f  6d 62 69 6e 65 64 20 6f  | have combined o|
00004290  74 68 65 72 20 6d 75 6c  74 69 70 6c 69 65 73 20  |ther multiplies |
000042a0  6f 66 20 61 20 76 65 72  74 69 63 61 6c 20 73 63  |of a vertical sc|
000042b0  61 6c 69 6e 67 20 66 61  63 74 6f 72 20 77 69 74  |aling factor wit|
000042c0  68 20 74 68 65 20 63 6f  73 69 6e 65 20 74 72 61  |h the cosine tra|
000042d0  6e 73 66 6f 72 6d 61 74  69 6f 6e 20 74 6f 20 73  |nsformation to s|
000042e0  61 76 65 20 74 69 6d 65  2e 20 41 6c 6c 20 77 65  |ave time. All we|
000042f0  20 65 76 65 6e 74 75 61  6c 6c 79 20 62 65 20 65  | eventually be e|
00004300  78 70 6c 61 69 6e 65 64  2e 20 59 6f 75 20 63 6f  |xplained. You co|
00004310  75 6c 64 20 72 65 70 6c  61 63 65 20 74 68 65 20  |uld replace the |
00004320  6c 69 6e 65 20 77 69 74  68 20 73 63 61 6c 65 3d  |line with scale=|
00004330  31 33 33 31 32 2f 64 69  73 74 5f 78 2b 2b 20 61  |13312/dist_x++ a|
00004340  6e 64 20 73 65 65 20 77  68 61 74 20 77 65 69 72  |nd see what weir|
00004350  64 20 72 65 73 75 6c 74  73 20 79 6f 75 20 67 65  |d results you ge|
00004360  74 21 20 2a 2f 0a 0a 73  63 61 6c 65 20 3d 20 63  |t! */..scale = c|
00004370  6f 73 5f 74 61 62 6c 65  5b 72 61 79 5d 2f 64 69  |os_table[ray]/di|
00004380  73 74 5f 78 2b 2b 3b 0a  0a 2f 2a 20 61 73 73 69  |st_x++;../* assi|
00004390  67 6e 20 74 68 65 20 76  61 72 69 61 62 6c 65 73  |gn the variables|
000043a0  20 77 65 20 6e 65 65 64  20 74 6f 20 74 68 65 20  | we need to the |
000043b0  76 61 72 69 61 62 6c 65  73 20 74 6f 20 62 65 20  |variables to be |
000043c0  70 61 73 73 65 64 20 74  6f 20 74 68 65 20 41 53  |passed to the AS|
000043d0  4d 20 73 6c 69 76 65 72  20 72 65 6e 64 65 72 65  |M sliver rendere|
000043e0  72 20 28 73 75 70 65 72  20 66 61 73 74 21 29 20  |r (super fast!) |
000043f0  2a 2f 0a 76 61 72 69 61  62 6c 65 73 5b 32 5d 3d  |*/.variables[2]=|
00004400  28 79 69 5f 73 61 76 65  20 26 20 30 78 30 30 33  |(yi_save & 0x003|
00004410  66 29 3b 20 2f 2a 20 74  68 69 73 20 77 6f 72 6b  |f); /* this work|
00004420  73 20 6f 75 74 20 74 68  65 20 63 6f 6c 75 6d 6e  |s out the column|
00004430  20 6f 66 20 74 68 65 20  77 61 6c 6c 20 74 6f 20  | of the wall to |
00004440  62 65 20 70 6c 6f 74 74  65 64 20 28 30 2d 36 34  |be plotted (0-64|
00004450  29 2c 20 62 79 20 63 61  6c 63 75 6c 61 74 69 6e  |), by calculatin|
00004460  67 20 77 68 65 72 65 20  61 62 6f 75 74 73 20 69  |g where abouts i|
00004470  6e 20 74 68 65 20 63 65  6c 6c 20 74 68 65 20 69  |n the cell the i|
00004480  6e 74 65 72 73 65 63 74  69 6f 6e 20 77 61 73 2c  |ntersection was,|
00004490  20 63 6f 76 65 72 65 64  20 69 6e 20 74 68 65 20  | covered in the |
000044a0  61 72 74 69 63 6c 65 2e  20 4e 6f 74 65 20 74 68  |article. Note th|
000044b0  65 20 6f 70 74 69 6d 69  7a 61 74 69 6f 6e 20 6f  |e optimization o|
000044c0  66 20 79 69 5f 73 61 76  65 20 25 20 36 34 20 2a  |f yi_save % 64 *|
000044d0  2f 0a 76 61 72 69 61 62  6c 65 73 5b 33 5d 3d 73  |/.variables[3]=s|
000044e0  63 61 6c 65 2d 31 3b 20  2f 2a 73 74 6f 72 65 73  |cale-1; /*stores|
000044f0  20 74 68 65 20 73 63 61  6c 65 20 6f 66 20 74 68  | the scale of th|
00004500  65 20 73 74 72 69 70 20  28 68 65 69 67 68 74 20  |e strip (height |
00004510  6f 66 20 69 74 29 2a 2f  0a 76 61 72 69 61 62 6c  |of it)*/.variabl|
00004520  65 73 5b 34 5d 3d 72 61  79 3b 20 2f 2a 20 77 65  |es[4]=ray; /* we|
00004530  20 75 73 65 20 72 61 79  20 61 73 20 74 68 65 20  | use ray as the |
00004540  78 20 70 6f 73 69 74 69  6f 6e 20 74 6f 20 70 6c  |x position to pl|
00004550  6f 74 20 74 6f 20 28 30  2d 33 31 39 29 2a 2f 0a  |ot to (0-319)*/.|
00004560  76 61 72 69 61 62 6c 65  73 5b 36 5d 3d 78 5f 68  |variables[6]=x_h|
00004570  69 74 5f 74 79 70 65 3b  20 2f 2a 20 66 69 6e 61  |it_type; /* fina|
00004580  6c 6c 79 20 77 65 20 73  74 6f 72 65 20 74 68 65  |lly we store the|
00004590  20 77 61 6c 6c 20 6e 75  6d 62 65 72 20 74 6f 20  | wall number to |
000045a0  70 6c 6f 74 20 2a 2f 0a  0a 2f 2a 20 61 6e 64 20  |plot */../* and |
000045b0  77 65 20 63 61 6c 6c 20  74 68 65 20 61 73 73 65  |we call the asse|
000045c0  6d 62 6c 65 72 20 66 75  6e 63 74 69 6f 6e 20 28  |mbler function (|
000045d0  65 78 70 6c 61 69 6e 65  64 20 61 74 20 61 20 6c  |explained at a l|
000045e0  61 74 65 72 20 64 61 74  65 29 2a 2f 0a 6f 75 72  |ater date)*/.our|
000045f0  6c 69 62 5f 73 6c 69 76  65 72 28 26 76 61 72 69  |lib_sliver(&vari|
00004600  61 62 6c 65 73 5b 30 5d  29 3b 0a 0a 20 20 20 20  |ables[0]);..    |
00004610  20 20 20 7d 0a 2f 2a 20  65 6c 73 65 20 74 68 65  |   }./* else the|
00004620  20 64 69 73 74 5f 79 20  77 61 73 20 6e 65 61 72  | dist_y was near|
00004630  65 72 2c 20 65 76 65 72  79 74 68 69 6e 67 20 66  |er, everything f|
00004640  72 6f 6d 20 61 62 6f 76  65 20 61 70 70 6c 69 65  |rom above applie|
00004650  73 20 2a 2f 0a 20 20 20  20 65 6c 73 65 0a 20 20  |s */.    else.  |
00004660  20 20 20 20 20 7b 0a 2f  2a 20 61 76 6f 69 64 20  |     {./* avoid |
00004670  64 69 76 69 64 65 20 62  79 20 7a 65 72 6f 20 2a  |divide by zero *|
00004680  2f 0a 69 66 28 64 69 73  74 5f 79 3c 31 29 64 69  |/.if(dist_y<1)di|
00004690  73 74 5f 79 3d 31 3b 0a  0a 2f 2a 20 61 76 6f 69  |st_y=1;../* avoi|
000046a0  64 20 66 69 73 68 20 62  6f 77 6c 20 65 66 66 65  |d fish bowl effe|
000046b0  63 74 2c 20 73 65 65 20  61 62 6f 76 65 20 2a 2f  |ct, see above */|
000046c0  0a 73 63 61 6c 65 20 3d  20 28 69 6e 74 29 63 6f  |.scale = (int)co|
000046d0  73 5f 74 61 62 6c 65 5b  72 61 79 5d 2f 64 69 73  |s_table[ray]/dis|
000046e0  74 5f 79 2b 2b 3b 0a 0a  0a 2f 2a 20 73 65 74 20  |t_y++;.../* set |
000046f0  75 70 20 76 61 72 69 61  62 6c 65 73 20 66 6f 72  |up variables for|
00004700  20 6f 75 72 20 73 6c 69  76 65 72 20 65 6e 67 69  | our sliver engi|
00004710  6e 65 2c 20 73 65 65 20  61 62 6f 76 65 20 2a 2f  |ne, see above */|
00004720  0a 76 61 72 69 61 62 6c  65 73 5b 32 5d 3d 28 78  |.variables[2]=(x|
00004730  69 5f 73 61 76 65 20 26  20 30 78 30 30 33 66 29  |i_save & 0x003f)|
00004740  3b 20 2f 2a 6e 6f 74 69  63 65 20 74 68 61 74 20  |; /*notice that |
00004750  77 65 20 75 73 65 20 78  69 20 69 6e 73 74 65 61  |we use xi instea|
00004760  64 20 6f 66 20 79 69 5f  73 61 76 65 2a 2f 0a 76  |d of yi_save*/.v|
00004770  61 72 69 61 62 6c 65 73  5b 33 5d 3d 73 63 61 6c  |ariables[3]=scal|
00004780  65 2d 31 3b 0a 76 61 72  69 61 62 6c 65 73 5b 34  |e-1;.variables[4|
00004790  5d 3d 72 61 79 3b 0a 76  61 72 69 61 62 6c 65 73  |]=ray;.variables|
000047a0  5b 36 5d 3d 79 5f 68 69  74 5f 74 79 70 65 3b 0a  |[6]=y_hit_type;.|
000047b0  0a 2f 2a 20 63 61 6c 6c  20 6f 75 72 20 73 6c 69  |./* call our sli|
000047c0  76 65 72 20 65 6e 67 69  6e 65 20 2a 2f 0a 6f 75  |ver engine */.ou|
000047d0  72 6c 69 62 5f 73 6c 69  76 65 72 28 26 76 61 72  |rlib_sliver(&var|
000047e0  69 61 62 6c 65 73 5b 30  5d 29 3b 0a 0a 20 20 20  |iables[0]);..   |
000047f0  20 20 20 20 7d 0a 2f 2a  20 74 68 69 73 20 72 61  |    }./* this ra|
00004800  79 20 68 61 73 20 62 65  65 6e 20 66 69 6e 69 73  |y has been finis|
00004810  68 65 64 2e 20 49 6e 63  72 65 61 73 65 20 74 68  |hed. Increase th|
00004820  65 20 61 6e 67 6c 65 20  6f 66 20 74 68 65 20 6e  |e angle of the n|
00004830  65 78 74 20 72 61 79 20  61 6e 64 20 73 74 61 72  |ext ray and star|
00004840  74 20 61 67 61 69 6e 21  20 2a 2f 0a 0a 20 20 20  |t again! */..   |
00004850  20 69 66 20 28 2b 2b 76  69 65 77 5f 61 6e 67 6c  | if (++view_angl|
00004860  65 3e 3d 41 4e 47 4c 45  5f 33 36 30 29 0a 20 20  |e>=ANGLE_360).  |
00004870  20 20 20 20 20 7b 0a 20  20 20 20 20 20 20 2f 2a  |     {.       /*|
00004880  20 74 68 69 73 20 65 6e  73 75 72 65 73 20 74 68  | this ensures th|
00004890  61 74 20 74 68 65 20 72  61 79 20 61 6e 67 6c 65  |at the ray angle|
000048a0  20 64 6f 65 73 6e 27 74  20 67 6f 20 6f 76 65 72  | doesn't go over|
000048b0  20 33 36 30 20 64 65 67  72 65 65 73 21 20 2a 2f  | 360 degrees! */|
000048c0  0a 20 20 20 20 20 20 20  76 69 65 77 5f 61 6e 67  |.       view_ang|
000048d0  6c 65 3d 30 3b 0a 0a 20  20 20 20 20 20 20 7d 0a  |le=0;..       }.|
000048e0  2f 2a 20 72 61 79 20 6c  6f 6f 70 20 2a 2f 0a 20  |/* ray loop */. |
000048f0  20 20 20 7d 0a 2f 2a 20  65 6e 64 20 72 61 79 20  |   }./* end ray |
00004900  63 61 73 74 65 72 20 65  6e 67 69 6e 65 20 2a 2f  |caster engine */|
00004910  0a 7d 0a 0a 0a 0a 2f 2a  20 74 68 69 73 20 66 75  |.}..../* this fu|
00004920  6e 63 74 69 6f 6e 20 67  72 61 62 73 20 61 6c 6c  |nction grabs all|
00004930  20 74 68 65 20 64 69 66  66 65 72 65 6e 74 20 77  | the different w|
00004940  61 6c 6c 73 20 66 72 6f  6d 20 61 20 73 69 6e 67  |alls from a sing|
00004950  6c 65 20 66 69 6c 65 20  2a 2f 0a 0a 76 6f 69 64  |le file */..void|
00004960  20 61 75 61 5f 67 72 61  70 68 69 63 73 28 76 6f  | aua_graphics(vo|
00004970  69 64 29 0a 7b 0a 69 6e  74 20 78 2c 20 2f 2a 20  |id).{.int x, /* |
00004980  74 68 69 73 20 69 73 20  75 73 65 64 20 74 6f 20  |this is used to |
00004990  73 74 6f 72 65 20 74 68  65 20 78 20 63 6f 6f 72  |store the x coor|
000049a0  64 69 6e 61 74 65 20 6f  66 20 61 20 70 6f 69 6e  |dinate of a poin|
000049b0  74 20 6f 6e 20 74 68 65  20 73 63 72 65 65 6e 20  |t on the screen |
000049c0  2a 2f 0a 20 20 20 20 79  2c 20 2f 2a 20 74 68 69  |*/.    y, /* thi|
000049d0  73 20 69 73 20 75 73 65  64 20 74 6f 20 73 74 6f  |s is used to sto|
000049e0  72 65 20 74 68 65 20 79  20 63 6f 6f 72 64 69 6e  |re the y coordin|
000049f0  61 74 65 20 6f 66 20 61  20 70 6f 69 6e 74 20 6f  |ate of a point o|
00004a00  6e 20 74 68 65 20 73 63  72 65 65 6e 20 2a 2f 0a  |n the screen */.|
00004a10  20 20 20 20 77 61 6c 6c  5f 6e 75 6d 62 65 72 3b  |    wall_number;|
00004a20  20 2f 2a 20 74 68 69 73  20 77 69 6c 6c 20 62 65  | /* this will be|
00004a30  20 75 73 65 64 20 74 6f  20 69 6e 64 65 78 20 74  | used to index t|
00004a40  68 65 20 77 61 6c 6c 73  5b 78 5d 5b 5d 20 63 68  |he walls[x][] ch|
00004a50  61 72 20 61 72 72 61 79  20 2a 2f 0a 0a 2f 2a 20  |ar array */../* |
00004a60  66 69 72 73 74 20 6f 66  20 61 6c 6c 20 77 65 20  |first of all we |
00004a70  67 65 74 20 74 68 65 20  67 72 61 70 68 69 63 73  |get the graphics|
00004a80  20 66 69 6c 65 20 3c 41  55 41 52 61 79 24 44 69  | file <AUARay$Di|
00004a90  72 3e 2e 67 72 61 70 68  69 63 73 20 6f 6e 74 6f  |r>.graphics onto|
00004aa0  20 74 68 65 20 73 63 72  65 65 6e 20 2a 2f 0a 0a  | the screen */..|
00004ab0  73 79 73 74 65 6d 28 22  2a 53 63 72 65 65 6e 4c  |system("*ScreenL|
00004ac0  6f 61 64 20 3c 41 55 41  52 61 79 24 44 69 72 3e  |oad <AUARay$Dir>|
00004ad0  2e 67 72 61 70 68 69 63  73 22 29 3b 0a 0a 2f 2a  |.graphics");../*|
00004ae0  20 6e 65 78 74 20 77 65  20 73 74 61 72 74 20 67  | next we start g|
00004af0  72 61 62 62 69 6e 67 20  65 61 63 68 20 74 69 6c  |rabbing each til|
00004b00  65 2c 20 36 34 20 78 20  36 34 20 70 69 78 65 6c  |e, 64 x 64 pixel|
00004b10  73 2c 20 69 6e 74 6f 20  74 68 65 20 77 61 6c 6c  |s, into the wall|
00004b20  73 5b 5d 5b 5d 20 61 72  72 61 79 20 2a 2f 0a 0a  |s[][] array */..|
00004b30  2f 2a 20 77 65 20 75 73  65 20 74 68 69 73 20 6c  |/* we use this l|
00004b40  61 72 67 65 20 66 6f 72  20 6c 6f 6f 70 20 61 74  |arge for loop at|
00004b50  20 74 68 65 20 6f 75 72  6c 69 62 5f 62 69 74 6d  | the ourlib_bitm|
00004b60  61 70 5f 67 72 61 62 20  66 75 6e 63 74 69 6f 6e  |ap_grab function|
00004b70  20 74 6f 20 69 6e 76 69  64 75 61 6c 6c 79 20 67  | to invidually g|
00004b80  72 61 62 20 65 61 63 68  20 74 69 6c 65 20 69 6e  |rab each tile in|
00004b90  74 6f 20 69 74 73 20 6f  77 6e 20 77 61 6c 6c 73  |to its own walls|
00004ba0  5b 78 5d 5b 5d 20 61 72  72 61 79 20 73 6c 6f 74  |[x][] array slot|
00004bb0  2c 20 6e 6f 74 65 20 74  68 61 74 20 77 65 20 43  |, note that we C|
00004bc0  41 4e 27 54 20 48 41 56  45 20 57 41 4c 4c 20 30  |AN'T HAVE WALL 0|
00004bd0  20 61 73 20 74 68 69 73  20 72 65 70 72 65 73 65  | as this represe|
00004be0  6e 74 73 20 61 20 67 61  70 20 69 6e 20 74 68 65  |nts a gap in the|
00004bf0  20 77 6f 72 6c 64 21 20  2a 2f 0a 0a 66 6f 72 28  | world! */..for(|
00004c00  77 61 6c 6c 5f 6e 75 6d  62 65 72 3d 31 2c 79 3d  |wall_number=1,y=|
00004c10  30 3b 79 3c 53 43 52 45  45 4e 5f 48 45 49 47 48  |0;y<SCREEN_HEIGH|
00004c20  54 3b 79 2b 3d 57 41 4c  4c 5f 48 45 49 47 48 54  |T;y+=WALL_HEIGHT|
00004c30  29 66 6f 72 28 78 3d 30  3b 78 3c 53 43 52 45 45  |)for(x=0;x<SCREE|
00004c40  4e 5f 57 49 44 54 48 3b  78 2b 3d 57 41 4c 4c 5f  |N_WIDTH;x+=WALL_|
00004c50  57 49 44 54 48 2c 77 61  6c 6c 5f 6e 75 6d 62 65  |WIDTH,wall_numbe|
00004c60  72 2b 2b 29 0a 7b 0a 2f  2a 20 74 68 69 73 20 63  |r++).{./* this c|
00004c70  61 6c 6c 73 20 74 68 65  20 66 75 6e 63 74 69 6f  |alls the functio|
00004c80  6e 20 6f 75 72 6c 69 62  5f 62 69 74 6d 61 70 5f  |n ourlib_bitmap_|
00004c90  67 72 61 62 20 28 49 20  73 61 69 64 20 69 74 20  |grab (I said it |
00004ca0  77 6f 75 6c 64 20 62 65  20 68 61 6e 64 79 21 29  |would be handy!)|
00004cb0  20 77 68 69 63 68 20 67  72 61 62 73 20 74 68 65  | which grabs the|
00004cc0  20 61 72 65 61 20 6f 66  20 73 63 72 65 65 6e 20  | area of screen |
00004cd0  6d 65 6d 6f 72 79 20 6d  61 72 6b 65 64 20 62 79  |memory marked by|
00004ce0  20 74 68 65 20 66 69 72  73 74 20 66 6f 75 72 20  | the first four |
00004cf0  70 61 72 61 6d 65 74 65  72 73 2c 20 73 74 6f 72  |parameters, stor|
00004d00  65 73 20 69 74 20 69 6e  20 74 68 65 20 62 79 74  |es it in the byt|
00004d10  65 20 61 72 72 61 79 20  70 6f 69 6e 74 65 72 20  |e array pointer |
00004d20  69 6e 20 70 61 72 61 6d  65 74 65 72 20 66 69 76  |in parameter fiv|
00004d30  65 2c 20 72 65 61 64 69  6e 67 20 69 74 20 61 6c  |e, reading it al|
00004d40  6c 20 66 72 6f 6d 20 74  68 65 20 73 63 72 65 65  |l from the scree|
00004d50  6e 20 70 6f 69 6e 74 65  64 20 74 6f 20 62 79 20  |n pointed to by |
00004d60  73 63 72 65 65 6e 5f 61  64 64 72 65 73 73 20 2a  |screen_address *|
00004d70  2f 0a 0a 6f 75 72 6c 69  62 5f 62 69 74 6d 61 70  |/..ourlib_bitmap|
00004d80  5f 67 72 61 62 28 78 2c  79 2c 78 2b 57 41 4c 4c  |_grab(x,y,x+WALL|
00004d90  5f 57 49 44 54 48 2d 31  2c 79 2b 57 41 4c 4c 5f  |_WIDTH-1,y+WALL_|
00004da0  48 45 49 47 48 54 2d 31  2c 26 77 61 6c 6c 73 5b  |HEIGHT-1,&walls[|
00004db0  77 61 6c 6c 5f 6e 75 6d  62 65 72 5d 5b 30 5d 2c  |wall_number][0],|
00004dc0  73 63 72 65 65 6e 5f 61  64 64 72 65 73 73 29 3b  |screen_address);|
00004dd0  0a 0a 2f 2a 20 74 68 69  73 20 6d 61 6b 65 73 20  |../* this makes |
00004de0  73 75 72 65 20 77 65 20  64 6f 6e 27 74 20 67 6f  |sure we don't go|
00004df0  20 6f 76 65 72 20 6f 75  72 20 6e 75 6d 62 65 72  | over our number|
00004e00  20 6f 66 20 77 61 6c 6c  73 20 6c 69 6d 69 74 20  | of walls limit |
00004e10  2a 2f 0a 0a 69 66 28 77  61 6c 6c 5f 6e 75 6d 62  |*/..if(wall_numb|
00004e20  65 72 3e 3d 57 41 4c 4c  5f 4e 55 4d 42 45 52 29  |er>=WALL_NUMBER)|
00004e30  62 72 65 61 6b 3b 0a 7d  0a 0a 0a 7d 0a 0a 2f 2a  |break;.}...}../*|
00004e40  20 74 68 69 73 20 66 75  6e 63 74 69 6f 6e 20 6c  | this function l|
00004e50  6f 61 64 73 20 69 6e 20  74 68 65 20 64 61 74 61  |oads in the data|
00004e60  20 66 72 6f 6d 20 6f 75  72 20 77 6f 72 6c 64 20  | from our world |
00004e70  74 65 78 74 20 66 69 6c  65 20 61 6e 64 20 73 74  |text file and st|
00004e80  6f 72 65 73 20 69 74 20  69 6e 20 74 68 65 20 77  |ores it in the w|
00004e90  6f 72 6c 64 5b 5d 5b 5d  20 61 72 72 61 79 20 2a  |orld[][] array *|
00004ea0  2f 0a 0a 76 6f 69 64 20  61 75 61 5f 77 6f 72 6c  |/..void aua_worl|
00004eb0  64 28 76 6f 69 64 29 0a  7b 0a 0a 46 49 4c 45 20  |d(void).{..FILE |
00004ec0  2a 77 6f 72 6c 64 5f 66  69 6c 65 3b 20 2f 2a 20  |*world_file; /* |
00004ed0  77 65 20 6e 65 65 64 20  61 20 66 69 6c 65 20 70  |we need a file p|
00004ee0  6f 69 6e 74 65 72 20 61  73 20 77 65 20 77 69 6c  |ointer as we wil|
00004ef0  6c 20 62 65 20 6c 6f 61  64 69 6e 67 20 69 6e 20  |l be loading in |
00004f00  74 65 78 74 20 2a 2f 0a  0a 69 6e 74 20 72 6f 77  |text */..int row|
00004f10  2c 20 2f 2a 20 74 68 69  73 20 77 69 6c 6c 20 62  |, /* this will b|
00004f20  65 20 75 73 65 64 20 74  6f 20 69 6e 64 65 78 20  |e used to index |
00004f30  74 68 65 20 77 6f 72 6c  64 5b 5d 5b 5d 20 61 72  |the world[][] ar|
00004f40  72 61 79 20 2a 2f 0a 20  20 20 20 63 6f 6c 75 6d  |ray */.    colum|
00004f50  6e 3b 20 2f 2a 20 74 68  69 73 20 77 69 6c 6c 20  |n; /* this will |
00004f60  62 65 20 75 73 65 64 20  74 6f 20 69 6e 64 65 78  |be used to index|
00004f70  20 74 68 65 20 77 6f 72  6c 64 5b 5d 5b 5d 20 61  | the world[][] a|
00004f80  72 72 61 79 20 2a 2f 0a  0a 63 68 61 72 20 63 68  |rray */..char ch|
00004f90  3b 20 2f 2a 20 74 68 69  73 20 69 73 20 75 73 65  |; /* this is use|
00004fa0  64 20 74 6f 20 73 74 6f  72 65 20 65 61 63 68 20  |d to store each |
00004fb0  6e 75 6d 62 65 72 20 61  73 20 69 74 20 69 73 20  |number as it is |
00004fc0  6c 6f 61 64 65 64 20 69  6e 20 2a 2f 0a 0a 2f 2a  |loaded in */../*|
00004fd0  20 6f 70 65 6e 20 74 68  65 20 77 6f 72 6c 64 20  | open the world |
00004fe0  66 69 6c 65 2c 20 69 66  20 69 74 20 69 73 20 6e  |file, if it is n|
00004ff0  6f 74 20 74 68 65 72 65  20 74 68 65 6e 20 65 78  |ot there then ex|
00005000  69 74 20 74 68 65 20 70  72 6f 67 72 61 6d 20 2a  |it the program *|
00005010  2f 0a 0a 69 66 28 21 28  77 6f 72 6c 64 5f 66 69  |/..if(!(world_fi|
00005020  6c 65 3d 66 6f 70 65 6e  28 22 3c 41 55 41 52 61  |le=fopen("<AUARa|
00005030  79 24 44 69 72 3e 2e 77  6f 72 6c 64 22 2c 22 72  |y$Dir>.world","r|
00005040  22 29 29 29 65 78 69 74  28 31 29 3b 0a 0a 2f 2a  |")))exit(1);../*|
00005050  20 74 68 69 73 20 70 72  6f 67 72 61 6d 20 6c 6f  | this program lo|
00005060  61 64 73 20 69 6e 20 74  68 65 20 64 61 74 61 20  |ads in the data |
00005070  66 72 6f 6d 20 74 68 65  20 77 6f 72 6c 64 20 66  |from the world f|
00005080  69 6c 65 2c 20 72 6f 77  20 62 79 20 72 6f 77 2c  |ile, row by row,|
00005090  20 63 6f 6c 75 6d 6e 20  62 79 20 63 6f 6c 75 6d  | column by colum|
000050a0  6e 20 75 73 69 6e 67 20  74 68 65 20 67 65 74 63  |n using the getc|
000050b0  28 29 20 41 4e 53 49 20  66 75 6e 63 74 69 6f 6e  |() ANSI function|
000050c0  20 2a 2f 0a 0a 66 6f 72  28 72 6f 77 3d 30 3b 72  | */..for(row=0;r|
000050d0  6f 77 3c 57 4f 52 4c 44  5f 48 45 49 47 48 54 3b  |ow<WORLD_HEIGHT;|
000050e0  72 6f 77 2b 2b 29 0a 7b  0a 66 6f 72 28 63 6f 6c  |row++).{.for(col|
000050f0  75 6d 6e 3d 30 3b 63 6f  6c 75 6d 6e 3c 57 4f 52  |umn=0;column<WOR|
00005100  4c 44 5f 57 49 44 54 48  3b 63 6f 6c 75 6d 6e 2b  |LD_WIDTH;column+|
00005110  2b 29 0a 7b 0a 77 68 69  6c 65 28 28 63 68 3d 67  |+).{.while((ch=g|
00005120  65 74 63 28 77 6f 72 6c  64 5f 66 69 6c 65 29 29  |etc(world_file))|
00005130  3d 3d 31 30 29 7b 7d 20  2f 2a 20 74 68 69 73 20  |==10){} /* this |
00005140  66 69 6c 74 65 72 73 20  6f 75 74 20 61 6e 79 20  |filters out any |
00005150  6d 65 73 73 2c 20 74 68  6f 75 67 68 20 6e 6f 74  |mess, though not|
00005160  20 6f 66 74 65 6e 20 75  73 65 64 21 20 2a 2f 0a  | often used! */.|
00005170  0a 69 66 28 63 68 3d 3d  27 20 27 29 63 68 3d 30  |.if(ch==' ')ch=0|
00005180  3b 20 2f 2a 74 68 69 73  20 65 6e 73 75 72 65 73  |; /*this ensures|
00005190  20 74 68 65 20 63 6f 72  72 65 63 74 20 76 61 6c  | the correct val|
000051a0  75 65 20 69 73 20 73 74  6f 72 65 64 2c 20 69 66  |ue is stored, if|
000051b0  20 74 68 65 72 65 20 69  73 20 61 20 67 61 70 20  | there is a gap |
000051c0  69 6e 20 74 68 65 20 66  69 6c 65 2c 20 74 68 69  |in the file, thi|
000051d0  73 20 6d 65 61 6e 73 20  61 20 73 70 61 63 65 20  |s means a space |
000051e0  69 6e 20 74 68 65 20 77  6f 72 6c 64 2c 20 61 20  |in the world, a |
000051f0  7a 65 72 6f 20 2a 2f 0a  65 6c 73 65 20 63 68 3d  |zero */.else ch=|
00005200  63 68 2d 27 30 27 3b 0a  0a 77 6f 72 6c 64 5b 28  |ch-'0';..world[(|
00005210  57 4f 52 4c 44 5f 48 45  49 47 48 54 2d 31 29 2d  |WORLD_HEIGHT-1)-|
00005220  72 6f 77 5d 5b 63 6f 6c  75 6d 6e 5d 3d 63 68 3b  |row][column]=ch;|
00005230  20 2f 2a 20 74 68 69 73  20 66 69 6e 61 6c 6c 79  | /* this finally|
00005240  20 73 74 6f 72 65 73 20  74 68 65 20 76 61 6c 75  | stores the valu|
00005250  65 20 69 6e 20 74 68 65  20 63 6f 72 72 65 63 74  |e in the correct|
00005260  20 70 6f 73 69 74 69 6f  6e 20 2a 2f 0a 0a 2f 2a  | position */../*|
00005270  70 72 69 6e 74 66 28 22  25 64 22 2c 63 68 29 3b  |printf("%d",ch);|
00005280  20 75 6e 63 6f 6d 6d 65  6e 74 20 74 68 69 73 20  | uncomment this |
00005290  6c 69 6e 65 20 74 6f 20  73 65 65 20 74 68 65 20  |line to see the |
000052a0  77 6f 72 6c 64 20 64 61  74 61 20 6c 6f 61 64 65  |world data loade|
000052b0  64 20 69 6e 20 2a 2f 0a  7d 0a 2f 2a 70 72 69 6e  |d in */.}./*prin|
000052c0  74 66 28 22 5c 6e 22 29  3b 20 75 6e 63 6f 6d 6d  |tf("\n"); uncomm|
000052d0  65 6e 74 20 74 68 69 73  20 6c 69 6e 65 20 74 6f  |ent this line to|
000052e0  20 73 65 65 20 74 68 65  20 77 6f 72 6c 64 20 64  | see the world d|
000052f0  61 74 61 20 6c 6f 61 64  65 64 20 69 6e 20 2a 2f  |ata loaded in */|
00005300  0a 7d 0a 0a 2f 2a 20 77  68 65 6e 20 61 6c 6c 20  |.}../* when all |
00005310  69 73 20 64 6f 6e 65 2c  20 63 6c 6f 73 65 20 74  |is done, close t|
00005320  68 65 20 66 69 6c 65 20  2a 2f 0a 66 63 6c 6f 73  |he file */.fclos|
00005330  65 28 77 6f 72 6c 64 5f  66 69 6c 65 29 3b 0a 7d  |e(world_file);.}|
00005340  0a 0a 2f 2a 20 4d 41 49  4e 20 66 75 6e 63 74 69  |../* MAIN functi|
00005350  6f 6e 20 2a 2f 0a 0a 76  6f 69 64 20 6d 61 69 6e  |on */..void main|
00005360  28 76 6f 69 64 29 0a 7b  0a 20 20 69 6e 74 20 76  |(void).{.  int v|
00005370  69 65 77 5f 78 2c 20 2f  2a 20 74 68 69 73 20 68  |iew_x, /* this h|
00005380  6f 6c 64 73 20 74 68 65  20 76 69 65 77 69 6e 67  |olds the viewing|
00005390  20 78 20 63 6f 6f 72 64  69 6e 61 74 65 20 2a 2f  | x coordinate */|
000053a0  0a 20 20 20 20 20 20 76  69 65 77 5f 79 2c 20 2f  |.      view_y, /|
000053b0  2a 20 74 68 69 73 20 68  6f 6c 64 73 20 74 68 65  |* this holds the|
000053c0  20 76 69 65 77 69 6e 67  20 79 20 63 6f 6f 72 64  | viewing y coord|
000053d0  69 6e 61 74 65 20 2a 2f  0a 20 20 20 20 20 20 76  |inate */.      v|
000053e0  69 65 77 5f 61 6e 67 6c  65 3b 20 2f 2a 20 74 68  |iew_angle; /* th|
000053f0  69 73 20 68 6f 6c 64 73  20 74 68 65 20 76 69 65  |is holds the vie|
00005400  77 69 6e 67 20 61 6e 67  6c 65 20 69 6e 20 66 69  |wing angle in fi|
00005410  78 65 64 20 75 6e 69 74  73 20 30 2d 31 39 32 30  |xed units 0-1920|
00005420  20 2a 2f 0a 0a 20 20 69  6e 74 20 6b 65 79 5f 70  | */..  int key_p|
00005430  72 65 73 73 3b 20 2f 2a  20 74 68 69 73 20 69 73  |ress; /* this is|
00005440  20 75 73 65 64 20 74 6f  20 63 6f 6e 66 69 72 6d  | used to confirm|
00005450  20 69 6e 70 75 74 20 6f  66 20 76 61 6c 75 65 73  | input of values|
00005460  20 2a 2f 0a 0a 2f 2a 20  66 69 72 73 74 2c 20 77  | */../* first, w|
00005470  65 20 6e 65 65 64 20 74  68 65 20 75 73 65 72 20  |e need the user |
00005480  74 6f 20 69 6e 70 75 74  20 76 61 6c 75 65 73 20  |to input values |
00005490  66 6f 72 20 76 69 65 77  5f 78 2c 76 69 65 77 5f  |for view_x,view_|
000054a0  79 20 61 6e 64 20 76 69  65 77 5f 61 6e 67 6c 65  |y and view_angle|
000054b0  2a 2f 0a 0a 70 72 69 6e  74 66 28 22 2a 2a 2a 2a  |*/..printf("****|
000054c0  2a 2a 2a 2a 2a 2a 20 52  41 59 20 43 41 53 54 49  |****** RAY CASTI|
000054d0  4e 47 20 44 45 4d 4f 4e  53 54 52 41 54 49 4f 4e  |NG DEMONSTRATION|
000054e0  20 2a 2a 2a 2a 2a 2a 2a  2a 2a 2a 2a 5c 6e 50 4c  | ***********\nPL|
000054f0  45 41 53 45 20 65 6e 74  65 72 20 76 61 6c 75 65  |EASE enter value|
00005500  73 20 66 6f 72 20 56 49  45 57 49 4e 47 20 58 20  |s for VIEWING X |
00005510  28 32 30 30 2d 33 38 30  30 20 72 63 6d 64 2e 29  |(200-3800 rcmd.)|
00005520  2c 20 56 49 45 57 49 4e  47 20 59 20 28 32 30 30  |, VIEWING Y (200|
00005530  2d 33 38 30 30 29 20 61  6e 64 20 56 49 45 57 49  |-3800) and VIEWI|
00005540  4e 47 5f 41 4e 47 4c 45  20 28 30 2d 31 39 32 30  |NG_ANGLE (0-1920|
00005550  2c 20 77 68 65 72 65 20  31 39 32 30 3d 33 36 30  |, where 1920=360|
00005560  20 64 65 67 72 65 65 73  20 65 74 63 2e 2e 2e 29  | degrees etc...)|
00005570  2e 5c 6e 5c 6e 54 68 65  20 70 72 6f 67 72 61 6d  |.\n\nThe program|
00005580  20 77 69 6c 6c 20 74 61  6b 65 20 61 20 73 63 72  | will take a scr|
00005590  65 65 6e 73 68 6f 74 20  6f 66 20 74 68 65 20 72  |eenshot of the r|
000055a0  65 6e 64 65 72 65 64 20  76 69 65 77 2c 20 61 6e  |endered view, an|
000055b0  64 20 73 74 6f 72 65 20  69 74 20 69 6e 73 69 64  |d store it insid|
000055c0  65 20 74 68 65 20 21 41  55 41 52 61 79 20 61 70  |e the !AUARay ap|
000055d0  70 6c 69 63 61 74 69 6f  6e 20 64 69 72 65 63 74  |plication direct|
000055e0  6f 72 79 2e 5c 6e 5c 6e  54 68 69 73 20 65 61 72  |ory.\n\nThis ear|
000055f0  6c 79 20 76 65 72 73 69  6f 6e 20 69 73 20 71 75  |ly version is qu|
00005600  69 74 65 20 75 6e 73 74  61 62 6c 65 2c 20 61 6e  |ite unstable, an|
00005610  64 20 69 73 20 70 75 72  65 6c 79 20 64 65 73 69  |d is purely desi|
00005620  67 6e 65 64 20 74 6f 20  67 69 76 65 20 61 6e 20  |gned to give an |
00005630  65 78 61 6d 70 6c 65 20  6f 66 20 68 6f 77 20 72  |example of how r|
00005640  61 79 20 63 61 73 74 69  6e 67 20 63 61 6e 20 62  |ay casting can b|
00005650  65 20 61 70 70 6c 69 65  64 20 74 6f 20 43 20 73  |e applied to C s|
00005660  6f 75 72 63 65 20 63 6f  64 65 2e 20 53 74 61 79  |ource code. Stay|
00005670  69 6e 67 20 77 69 74 68  69 6e 20 74 68 65 20 72  |ing within the r|
00005680  65 63 6f 6d 6d 65 6e 64  65 64 20 63 6f 6f 72 64  |ecommended coord|
00005690  69 6e 61 74 65 73 20 69  73 20 61 20 77 69 73 65  |inates is a wise|
000056a0  20 6d 6f 76 65 2c 20 61  6e 64 20 70 61 79 20 73  | move, and pay s|
000056b0  70 65 63 69 61 6c 20 61  74 74 65 6e 74 69 6f 6e  |pecial attention|
000056c0  20 74 6f 20 6b 65 65 70  69 6e 67 20 74 68 65 20  | to keeping the |
000056d0  76 69 65 77 20 70 6f 69  6e 74 20 4f 55 54 20 6f  |view point OUT o|
000056e0  66 20 77 61 6c 6c 73 21  5c 6e 49 66 20 79 6f 75  |f walls!\nIf you|
000056f0  20 61 72 65 20 75 73 69  6e 67 20 74 68 65 20 70  | are using the p|
00005700  72 6f 67 72 61 6d 20 77  69 74 68 20 74 68 65 20  |rogram with the |
00005710  77 6f 72 6c 64 20 66 69  6c 65 20 73 75 70 70 6c  |world file suppl|
00005720  69 65 64 2c 20 74 72 79  20 34 30 30 2c 34 30 30  |ied, try 400,400|
00005730  2c 31 30 30 5c 6e 2a 2a  2a 2a 2a 2a 2a 2a 2a 2a  |,100\n**********|
00005740  2a 2a 2a 2a 2a 2a 2a 2a  2a 2a 2a 2a 2a 2a 2a 2a  |****************|
*
00005760  2a 2a 2a 2a 2a 2a 5c 6e  22 29 3b 0a 73 63 61 6e  |******\n");.scan|
00005770  66 28 22 25 64 20 25 64  20 25 64 22 2c 26 76 69  |f("%d %d %d",&vi|
00005780  65 77 5f 78 2c 26 76 69  65 77 5f 79 2c 26 76 69  |ew_x,&view_y,&vi|
00005790  65 77 5f 61 6e 67 6c 65  29 3b 0a 0a 2f 2a 20 63  |ew_angle);../* c|
000057a0  6f 6e 66 69 72 6d 20 74  68 69 73 20 69 73 20 6f  |onfirm this is o|
000057b0  6b 20 2a 2f 0a 0a 70 72  69 6e 74 66 28 22 59 6f  |k */..printf("Yo|
000057c0  75 20 65 6e 74 65 72 65  64 20 25 64 20 25 64 20  |u entered %d %d |
000057d0  61 6e 64 20 25 64 20 50  72 65 73 73 20 30 20 74  |and %d Press 0 t|
000057e0  6f 20 71 75 69 74 20 61  6e 64 20 72 65 2d 65 6e  |o quit and re-en|
000057f0  74 65 72 20 6f 72 20 61  6e 79 20 6f 74 68 65 72  |ter or any other|
00005800  20 6e 75 6d 62 65 72 20  74 6f 20 63 6f 6e 74 69  | number to conti|
00005810  6e 75 65 2e 2e 2e 5c 6e  22 2c 76 69 65 77 5f 78  |nue...\n",view_x|
00005820  2c 76 69 65 77 5f 79 2c  76 69 65 77 5f 61 6e 67  |,view_y,view_ang|
00005830  6c 65 29 3b 0a 73 63 61  6e 66 28 22 25 64 22 2c  |le);.scanf("%d",|
00005840  26 6b 65 79 5f 70 72 65  73 73 29 3b 0a 0a 2f 2a  |&key_press);../*|
00005850  20 69 66 20 71 20 69 73  20 70 72 65 73 73 65 64  | if q is pressed|
00005860  20 74 68 65 6e 20 65 78  69 74 2c 20 65 6c 73 65  | then exit, else|
00005870  20 63 6f 6e 74 69 6e 75  65 20 2a 2f 0a 0a 69 66  | continue */..if|
00005880  28 21 6b 65 79 5f 70 72  65 73 73 29 65 78 69 74  |(!key_press)exit|
00005890  28 31 29 3b 0a 0a 2f 2a  20 6e 6f 77 20 77 65 20  |(1);../* now we |
000058a0  63 61 6c 6c 20 61 75 61  5f 77 6f 72 6c 64 20 74  |call aua_world t|
000058b0  6f 20 6c 6f 61 64 20 69  6e 20 74 68 65 20 74 65  |o load in the te|
000058c0  78 74 20 77 6f 72 6c 64  20 66 69 6c 65 20 77 68  |xt world file wh|
000058d0  69 63 68 20 64 65 66 69  6e 65 73 20 6f 75 72 20  |ich defines our |
000058e0  77 61 6c 6c 73 20 74 79  70 65 20 61 6e 64 20 6c  |walls type and l|
000058f0  61 79 6f 75 74 20 2a 2f  0a 0a 70 72 69 6e 74 66  |ayout */..printf|
00005900  28 22 6c 6f 61 64 69 6e  67 20 69 6e 20 74 65 78  |("loading in tex|
00005910  74 20 66 69 6c 65 20 3c  41 55 41 52 61 79 24 44  |t file <AUARay$D|
00005920  69 72 3e 2e 77 6f 72 6c  64 5c 6e 22 29 3b 0a 61  |ir>.world\n");.a|
00005930  75 61 5f 77 6f 72 6c 64  28 29 3b 0a 0a 2f 2a 20  |ua_world();../* |
00005940  63 68 65 63 6b 20 74 6f  20 73 65 65 20 69 66 20  |check to see if |
00005950  74 68 65 20 76 69 65 77  65 72 20 69 73 20 69 6e  |the viewer is in|
00005960  73 69 64 65 20 61 20 67  61 6d 65 20 63 65 6c 6c  |side a game cell|
00005970  20 57 41 4c 4c 2c 20 77  68 69 63 68 20 77 6f 75  | WALL, which wou|
00005980  6c 64 20 62 65 20 62 61  64 20 6e 65 77 73 21 20  |ld be bad news! |
00005990  2a 2f 0a 0a 69 66 28 77  6f 72 6c 64 5b 76 69 65  |*/..if(world[vie|
000059a0  77 5f 79 3e 3e 36 5d 5b  76 69 65 77 5f 78 3e 3e  |w_y>>6][view_x>>|
000059b0  36 5d 29 0a 7b 0a 20 20  70 72 69 6e 74 66 28 22  |6]).{.  printf("|
000059c0  42 61 64 20 63 6f 6f 72  64 69 6e 61 74 65 73 20  |Bad coordinates |
000059d0  67 69 76 65 6e 2c 20 76  69 65 77 65 72 20 69 73  |given, viewer is|
000059e0  20 49 4e 20 61 20 57 41  4c 4c 21 2c 20 65 78 69  | IN a WALL!, exi|
000059f0  74 69 6e 67 5c 6e 22 29  3b 0a 20 20 65 78 69 74  |ting\n");.  exit|
00005a00  28 31 29 3b 0a 7d 0a 0a  2f 2a 20 6e 6f 77 20 77  |(1);.}../* now w|
00005a10  65 20 63 61 6c 6c 20 61  75 61 5f 74 61 62 6c 65  |e call aua_table|
00005a20  73 20 74 6f 20 67 65 6e  65 72 61 74 65 20 73 6f  |s to generate so|
00005a30  6d 65 20 6c 6f 6f 6b 2d  75 70 20 74 61 62 6c 65  |me look-up table|
00005a40  73 20 66 6f 72 20 74 68  65 20 65 6e 67 69 6e 65  |s for the engine|
00005a50  20 74 6f 20 75 73 65 2c  20 6c 6f 6f 6b 2d 75 70  | to use, look-up|
00005a60  73 20 61 72 65 20 65 78  70 6c 61 69 6e 65 64 20  |s are explained |
00005a70  75 70 20 61 74 20 74 68  65 20 74 6f 70 20 6f 66  |up at the top of|
00005a80  20 74 68 65 20 66 69 6c  65 20 6e 65 78 74 20 74  | the file next t|
00005a90  6f 20 74 68 65 20 67 6c  6f 62 61 6c 20 76 61 72  |o the global var|
00005aa0  69 61 62 6c 65 73 20 2a  2f 0a 0a 70 72 69 6e 74  |iables */..print|
00005ab0  66 28 22 63 61 6c 6c 69  6e 67 20 61 75 61 5f 74  |f("calling aua_t|
00005ac0  61 62 6c 65 73 28 29 20  74 68 69 73 20 63 6f 75  |ables() this cou|
00005ad0  6c 64 20 74 61 6b 65 20  61 20 6c 6f 6e 67 20 74  |ld take a long t|
00005ae0  69 6d 65 20 6f 6e 20 73  6f 6d 65 20 6d 61 63 68  |ime on some mach|
00005af0  69 6e 65 73 5c 6e 22 29  3b 0a 61 75 61 5f 74 61  |ines\n");.aua_ta|
00005b00  62 6c 65 73 28 29 3b 0a  0a 2f 2a 20 61 6c 6c 20  |bles();../* all |
00005b10  69 73 20 64 6f 6e 65 20  69 6e 20 74 65 72 6d 73  |is done in terms|
00005b20  20 6f 66 20 69 6e 70 75  74 20 66 6f 72 20 6e 6f  | of input for no|
00005b30  77 2e 20 57 65 20 6e 65  65 64 20 74 6f 20 73 77  |w. We need to sw|
00005b40  69 74 63 68 20 74 6f 20  4d 6f 64 65 20 31 33 20  |itch to Mode 13 |
00005b50  2a 2f 0a 0a 70 72 69 6e  74 66 28 22 53 77 69 74  |*/..printf("Swit|
00005b60  63 68 69 6e 67 20 74 6f  20 4d 6f 64 65 20 31 33  |ching to Mode 13|
00005b70  5c 6e 22 29 3b 0a 0a 2f  2a 20 63 61 6c 6c 20 6f  |\n");../* call o|
00005b80  75 72 6c 69 62 5f 63 68  61 6e 67 65 6d 6f 64 65  |urlib_changemode|
00005b90  20 74 6f 20 73 77 69 74  63 68 20 74 6f 20 6d 6f  | to switch to mo|
00005ba0  64 65 20 31 33 20 2a 2f  0a 0a 6f 75 72 6c 69 62  |de 13 */..ourlib|
00005bb0  5f 63 68 61 6e 67 65 6d  6f 64 65 28 31 33 29 3b  |_changemode(13);|
00005bc0  0a 0a 2f 2a 20 63 61 6c  6c 20 6f 75 72 6c 69 62  |../* call ourlib|
00005bd0  5f 66 69 6e 64 73 63 72  65 65 6e 20 74 6f 20 67  |_findscreen to g|
00005be0  65 74 20 74 68 65 20 73  63 72 65 65 6e 20 62 61  |et the screen ba|
00005bf0  73 65 20 61 64 64 72 65  73 73 20 6f 66 20 6d 6f  |se address of mo|
00005c00  64 65 20 31 33 2c 20 20  77 69 74 68 6f 75 74 20  |de 13,  without |
00005c10  74 68 65 20 63 6f 72 72  65 63 74 20 61 64 64 72  |the correct addr|
00005c20  65 73 73 20 77 65 20 63  61 6e 27 74 20 64 72 61  |ess we can't dra|
00005c30  77 20 61 6e 79 74 68 69  6e 67 20 61 6e 64 20 74  |w anything and t|
00005c40  68 65 20 63 6f 6d 70 75  74 65 72 20 63 6f 75 6c  |he computer coul|
00005c50  64 20 63 72 61 73 68 20  2a 2f 0a 0a 73 63 72 65  |d crash */..scre|
00005c60  65 6e 5f 61 64 64 72 65  73 73 3d 28 63 68 61 72  |en_address=(char|
00005c70  20 2a 29 6f 75 72 6c 69  62 5f 66 69 6e 64 73 63  | *)ourlib_findsc|
00005c80  72 65 65 6e 28 29 3b 0a  0a 2f 2a 20 6e 6f 77 20  |reen();../* now |
00005c90  77 65 20 6e 65 65 64 20  74 6f 20 2a 73 63 72 65  |we need to *scre|
00005ca0  65 6e 6c 6f 61 64 20 6f  75 72 20 67 72 61 70 68  |enload our graph|
00005cb0  69 63 73 20 66 69 6c 65  2c 20 61 6e 64 20 67 72  |ics file, and gr|
00005cc0  61 62 20 65 61 63 68 20  69 6e 64 69 76 69 64 75  |ab each individu|
00005cd0  61 6c 20 77 61 6c 6c 20  67 72 61 70 68 69 63 20  |al wall graphic |
00005ce0  6f 6e 65 20 62 79 20 6f  6e 65 2c 20 74 68 65 20  |one by one, the |
00005cf0  66 75 6e 63 74 69 6f 6e  20 61 75 61 5f 67 72 61  |function aua_gra|
00005d00  70 68 69 63 73 20 64 6f  65 73 20 74 68 69 73 20  |phics does this |
00005d10  2a 2f 0a 0a 61 75 61 5f  67 72 61 70 68 69 63 73  |*/..aua_graphics|
00005d20  28 29 3b 0a 0a 2f 2a 20  4e 4f 57 20 77 65 20 63  |();../* NOW we c|
00005d30  61 6e 20 67 6f 20 74 6f  20 6d 6f 64 65 20 31 33  |an go to mode 13|
00005d40  20 61 67 61 69 6e 20 61  6e 64 20 63 61 6c 6c 20  | again and call |
00005d50  74 68 65 20 72 61 79 20  63 61 73 74 65 72 20 66  |the ray caster f|
00005d60  75 6e 63 74 69 6f 6e 20  2a 2f 0a 0a 6f 75 72 6c  |unction */..ourl|
00005d70  69 62 5f 63 68 61 6e 67  65 6d 6f 64 65 28 31 33  |ib_changemode(13|
00005d80  29 3b 0a 61 75 61 5f 72  61 79 63 61 73 74 65 72  |);.aua_raycaster|
00005d90  28 76 69 65 77 5f 78 2c  76 69 65 77 5f 79 2c 76  |(view_x,view_y,v|
00005da0  69 65 77 5f 61 6e 67 6c  65 29 3b 0a 0a 2f 2a 20  |iew_angle);../* |
00005db0  74 61 6b 65 20 61 20 73  63 72 65 65 6e 73 68 6f  |take a screensho|
00005dc0  74 2c 20 75 73 69 6e 67  20 2a 73 63 72 65 65 6e  |t, using *screen|
00005dd0  20 73 61 76 65 2c 20 61  6e 64 20 73 61 76 65 20  | save, and save |
00005de0  69 74 20 69 6e 73 69 64  65 20 74 68 65 20 64 69  |it inside the di|
00005df0  72 65 63 74 6f 72 79 20  2a 2f 0a 0a 73 79 73 74  |rectory */..syst|
00005e00  65 6d 28 22 2a 53 63 72  65 65 6e 53 61 76 65 20  |em("*ScreenSave |
00005e10  3c 41 55 41 52 61 79 24  44 69 72 3e 2e 73 63 72  |<AUARay$Dir>.scr|
00005e20  73 68 6f 74 22 29 3b 0a  7d 0a 0a                 |shot");.}..|
00005e2b