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