Annotation of src/build.txt, revision 1.1

1.1     ! root        1: BUILD engine Notes (7/20/95):
        !             2: 
        !             3: ���������������������������������������������������������������������������Ŀ
        !             4: �                        IMPORTANT ENGINE FUNCTIONS:                        �
        !             5: �����������������������������������������������������������������������������
        !             6: 
        !             7: initengine(char vidoption, long xdim, long ydim)
        !             8:        Sets up interrupt vectors for keyboard, and initializes many variables
        !             9:        for the BUILD engine.  You should call this once before any other
        !            10:        functions of the BUILD engine are used.
        !            11: 
        !            12:        vidoption can be anywhere from 0-6
        !            13:        xdim,ydim can be any mode x resolution if vidoption = 0
        !            14:        xdim,ydim can be any vesa resolution if vidoption = 1
        !            15:        xdim,ydim must be 320*200 for any other mode.
        !            16:                (see graphics mode selection in my setup program)
        !            17: uninitengine();
        !            18:                         Restores interrupt vectors for keyboard and timer, and frees
        !            19:                         buffers.  You should call this once at the end of the program
        !            20:                         before quitting to dos.
        !            21: loadboard(char *filename, long *posx, long *posy, long *posz, short *ang, short *cursectnum)
        !            22:                         Loads the given board file into memory for the BUILD engine.
        !            23:                         Returns -1 if file not found.  If no extension is given, .MAP will
        !            24:                         be appended to the filename.
        !            25: saveboard(char *filename, long *posx, long *posy, long *posz, short *ang, short *cursectnum)
        !            26:                         Saves the given board from memory inro the specified filename.
        !            27:                         Returns -1 if unable to save.  If no extension is given, .MAP will
        !            28:                         be appended to the filename.
        !            29: loadpics(char *filename);
        !            30:                         Loads the given artwork file into memory for the BUILD engine.
        !            31:                         Returns -1 if file not found.  If no extension is given, .ART will
        !            32:                         be appended to the filename.
        !            33: setgamemode();
        !            34:                         This function sets the video mode to 320*200*256color graphics.
        !            35:                         Since BUILD supports several different modes including mode x,
        !            36:                         mode 13h, and other special modes, I don't expect you to write
        !            37:                         any graphics output functions.  (Soon I have all the necessary
        !            38:                         functions)  If for some reason, you use your own graphics mode,
        !            39:                         you must call this function again before using the BUILD drawing
        !            40:                         functions.
        !            41: 
        !            42: drawrooms(long posx, long posy, long posz, short ang, long horiz, short cursectnum)
        !            43:                         This function draws the 3D screen to the current drawing page,
        !            44:                         which is not yet shown.  This way, you can overwrite some things
        !            45:                         over the 3D screen such as a gun.  Be sure to call the drawmasks()
        !            46:                         function soon after you call the drawrooms() function.  To view
        !            47:                         the screen, use the nextpage() function.  The nextpage() function
        !            48:                         should always be called sometime after each draw3dscreen()
        !            49:                         function.
        !            50: drawmasks();
        !            51:                         This function draws all the sprites and masked walls to the current
        !            52:                         drawing page which is not yet shown.  The reason I have the drawing
        !            53:                         split up into these 2 routines is so you can animate just the
        !            54:                         sprites that are about to be drawn instead of having to animate
        !            55:                         all the sprites on the whole board.  Drawrooms() prepares these
        !            56:                         variables:  spritex[], spritey[], spritepicnum[], thesprite[],
        !            57:                         and spritesortcnt.  Spritesortcnt is the number of sprites about
        !            58:                         to be drawn to the page.  To change the sprite's picnum, simply
        !            59:                         modify the spritepicnum array  If you want to change other parts
        !            60:                         of the sprite structure, then you can use the thesprite array to
        !            61:                         get an index to the actual sprite number.
        !            62: 
        !            63: engineinput();
        !            64:                         This function allows the engine to adjust your position depending
        !            65:                         on the status of the arrow keys, and other control keys.  It
        !            66:                         handles timing and clipping.
        !            67: nextpage();
        !            68:                         After a screen is prepared, use this function to view the screen.
        !            69: 
        !            70: draw2dscreen(long posxe, long posye, short ange, long zoome,
        !            71:                                 short gride)
        !            72:                         Draws the 2d screen - this function is a direct replacement
        !            73:                         for the drawrooms() and drawmasks() functions.  Be sure
        !            74:                         to call either qsetmode640350() or qsetmode640480()
        !            75:                         first.  When switching back to 3d mode, be sure to call
        !            76:                         qsetmode320200().
        !            77:                                IMPORTANT NOTES:
        !            78:                                1.  The overwritesprite function should only be called in
        !            79:                                         3D mode.  If you do this in 2D mode, junk will be
        !            80:                                         written to the 2D screen and a crash is possible.
        !            81:                                2.  When you switch back to 3D mode, you should call the
        !            82:                                         permanentwritesprite functions to draw the status bar,
        !            83:                                         or whatever else you have to draw.
        !            84:                                3.  You must call the nextpage() function in both 2D and
        !            85:                                         3D modes.
        !            86: qsetmode320200();
        !            87:                         Set to the game mode and load palette (320*200*256)
        !            88: qsetmode640350();
        !            89:                         Set to the 2D map mode #1 (640*350*16)
        !            90: qsetmode640480();
        !            91:                         Set to the 2D map mode #2 (640*480*16)
        !            92: 
        !            93: doanimations(long numtics);
        !            94:                This function animates anything you use setanimation for (like doors).
        !            95:        You should call it for every frame.  Pass the number of tics (lockspeed)
        !            96:        as a parameter to it to tell how much everything should animate.
        !            97: 
        !            98: kenchaintimer(void (__interrupt __far *datimerchainaddress)(),
        !            99:                                  short dachainpersecond)
        !           100:                This function makes the engine's timerhandler chain to another timer
        !           101:        handler at any specified interrupt rate.  This function forces IRQ0 to
        !           102:        point to my engine's timerhandler.  Clockspeed and totalclock will
        !           103:        be fixed at counting 120 per second regardless of the chaining interrupt
        !           104:        rate.  If you call this function with a NULL pointer, then the engine's
        !           105:        timerhandler will not chain anymore.
        !           106: 
        !           107:        Here's how you should structure your code if you use this function:
        !           108: 
        !           109:                main()
        !           110:                {
        !           111:                        initengine();
        !           112: 
        !           113:                        musicon();              //Turn music on after engine
        !           114:                        kenchaintimer(yourtimerhandleraddress,yourtimerrate);
        !           115:                                                                                        //When IRQ0 goes off, it will now go to
        !           116:                                                                                        //Ken's timer handler.  Then, Ken's timer
        !           117:                        (main loop)             //handler will make yourtimerhandler
        !           118:                                                                                        //interrupt yourtimerrate times per second
        !           119: 
        !           120:                        kenchaintimer(0,0);     //Stop chaining BEFORE music handler dies!
        !           121:                        musicoff();
        !           122: 
        !           123:                        uninitengine();
        !           124:                }
        !           125: 
        !           126: ���������������������������������������������������������������������������Ŀ
        !           127: �                           OTHER ENGINE FUNCTIONS:                         �
        !           128: �����������������������������������������������������������������������������
        !           129: 
        !           130: overwritesprite (long thex, long they, short tilenum,
        !           131:                                                 signed char shade, char orientation, char dapalnum)
        !           132: 
        !           133:                Use this function to draw any sprites that must be drawn to the screen
        !           134:        for every single frame, such as a gun or a menu system.
        !           135: 
        !           136:        If Bit 0 of orientation = 0: (thex, they) is top-left corner
        !           137:        If Bit 0 of orientation = 1: (thex, they) is middle
        !           138:        If Bit 1 of orientation = 0: no relation to viewing window
        !           139:        If Bit 1 of orientation = 1: scale and clip to viewing window
        !           140:        If Bit 2 of orientation = 0: normal
        !           141:        If Bit 2 of orientation = 1: 50/50 transluscent!
        !           142:        If Bit 3 of orientation = 0: normal
        !           143:        If Bit 3 of orientation = 1: x-flipped
        !           144:        If Bit 4 of orientation = 0: normal
        !           145:        If Bit 4 of orientation = 1: y-flipped
        !           146: 
        !           147:        * If it works at full screen, simply set bit 1 of orientation
        !           148:                                                 to 1, and it should automatically scale properly!
        !           149: 
        !           150:                         Use this function to write sprites over the 3d view.  For example,
        !           151:                         you can make a menu system with this function.  Be sure
        !           152:                         that you call this function for every single frame after the 3d
        !           153:                         view is drawn or else it will be flashed on for only 1 frame.
        !           154:                         If you want x and y to be the top left corner, set the orientation
        !           155:                         to 0.  If you want x and y to be the middle of the sprite, set the
        !           156:                         orientation to 1.  The reason I included the orienation = 1 option
        !           157:                         is so that if you want a sprite centered and the size of the tile
        !           158:                         changes, you don't need to recompile and guess where the new top
        !           159:                         left corner is.  Oh yeah, and I forget to mention that if shade is
        !           160:                         greater than 32, than overwritesprite does transluscence.  (Try it
        !           161:                         out!)  This function will clip the sprite to the startumost and
        !           162:                         startdmost arrays.  Dapalnum refers to a palette lookup list
        !           163:                         (normally 0).
        !           164: 
        !           165: rotatesprite(long sx, long sy, long z, short a, short picnum,
        !           166:                                 signed char dashade, char dapalnum, char dastat)
        !           167:        (sx, sy) is the center of the sprite to draw defined as
        !           168:                 screen coordinates shifted up by 16.
        !           169:        (z) is the zoom.  Normal size is 65536.
        !           170:                 Ex: 131072 is zoomed in 2X and 32768 is zoomed out 2X.
        !           171:        (a) is the angle (0 is straight up)
        !           172:        (picnum) is the tile number
        !           173:        if ((dastat&1) == 0) - no transluscence
        !           174:        if ((dastat&1) != 0) - transluscence
        !           175:        if ((dastat&2) == 0) - don't scale to viewing window
        !           176:        if ((dastat&2) != 0) - scale to viewing window
        !           177:        if ((dastat&4) == 0) - nuttin' special
        !           178:        if ((dastat&4) != 0) - x-flip image
        !           179:        if ((dastat&8) == 0) - clip to startumost/startdmost
        !           180:        if ((dastat&8) != 0) - don't clip to startumost/startdmost
        !           181: 
        !           182:                Ex: rotatesprite(160L<<16,100L<<16,65536,totalclock<<4,DEMOSIGN,2);
        !           183:                         This example will draw the DEMOSIGN tile in the center of the
        !           184:                         screen and rotate about once per second.
        !           185: 
        !           186: permanentwritesprite (long thex, long they, short tilenum, signed char shade,
        !           187:                                                         long cx1, long cy1, long cx2, long cy2, char dapalnum)
        !           188:                        - Added permanentwritesprite function for status bars or other
        !           189:                                  sections of the screen that will not be overwritten by the
        !           190:                                  engine.  The format of this function is like overwritesprite
        !           191:                                  except that the x and y are always top left corner, no
        !           192:                                  orientation variable, and no translucence.
        !           193:                                          The 4 last parameters (cx1, cy1) - (cx2, cy2) define a
        !           194:                                  rectangular clipping window of where permanentwritesprite
        !           195:                                  can draw to.   Dapalnum refers to a palette lookup list
        !           196:                                  (normally 0).
        !           197: 
        !           198: printext(long x, long y, char buffer[42], short tilenum, char invisiblecol);
        !           199:                         Use this function to print text anywhere on the screen from a font
        !           200:                         that you can create in EDITART.  Please see my example font in
        !           201:                         TILES.ART to see how I lay out the user-defined font.  X ranges
        !           202:                         from 0-319. Y ranges from 0-199.  The buffer is the string to
        !           203:                         print.  Tilenum specifies which font to use.  Invisiblecol tells
        !           204:                         printext what color to draw the transparent pixels.  If
        !           205:                         invisiblecol is 255 then the transpararent pixels are still
        !           206:                         transparent.
        !           207: printnum(long x, long y, long num, short tilenum, char invisiblecol);
        !           208:                         Printnum is a function call that will print a long integer (num)
        !           209:                         starting at top left corner x, y.  Please look at the documentation
        !           210:                         for printext, since internally, printnum simply prepares a buffer
        !           211:                         and calls the printext function.
        !           212: 
        !           213: setvmode(long videomode);
        !           214:                         If you look at the top of GAME.C, you will see something like this:
        !           215:                         #pragma aux setvmode =\...  This is how you do in-line assembler in
        !           216:                         WATCOM C.  All this function is doing is setting the video mode.
        !           217: showengineinfo();
        !           218:                         Use this function after setting to text mode to view some statics
        !           219:                         about the engine, such as frame rate.
        !           220: resettiming();
        !           221:                         Resets timing, such as setting totalclock = 0.  Also resets other
        !           222:                         timers.  This is for use with the showengineinfo function above.
        !           223: 
        !           224: ksqrt(long num);  returns (long)square root
        !           225:                         A square root function optimized for integers.  Use this function
        !           226:                         only if you want to.
        !           227: krand()
        !           228:                This simply returns a random number.  You can easily set the random
        !           229:        seed by externing the randomseed variable as a long.  This is useful
        !           230:        for keeping the random seed the same on multiple computers when playing
        !           231:        multi-player mode.
        !           232: 
        !           233: getangle(long xvect,long yvect);    returns (short)angle;
        !           234:                         Use this function call to determine the angle between two points.
        !           235:                         For example, if you want a monster to shoot a bullet towards you,
        !           236:                         you would get the bullet's angle this way:
        !           237:        sprite[bullet].ang = getangle(posx-sprite[monst].x,posy-sprite[monst].y);
        !           238: 
        !           239: lastwall(short point);
        !           240:                Use this function as a reverse function of wall[].point2.  In order
        !           241:        to save memory, my walls are only on a single linked list.
        !           242:        
        !           243: rotatepoint(long xpivot, long ypivot, long x, long y,
        !           244:                                short daang, long *x2, long *y2);
        !           245:                This function is a very convenient and fast math helper function.
        !           246:        Rotate points easily with this function without having to juggle your
        !           247:        cosines and sines.  Simply pass it: 
        !           248:                 
        !           249:                 Input:   1. Pivot point     (xpivot,ypivot)
        !           250:                                         2. Original point  (x,y)
        !           251:                                         3. Angle to rotate (0 = nothing, 512 = 90� CW, etc.)
        !           252:                 Output:  4. Rotated point   (*x2,*y2)
        !           253: 
        !           254: clipmove(long *x, long *y, long *z, short *sectnum, long xvect, long yvect,
        !           255:                        long walldist, long ceildist, long flordist, char cliptype)
        !           256:                Moves any object (x, y, z) in any direction at any velocity and will
        !           257:        make sure the object will stay a certain distance from walls (walldist)
        !           258:                 Pass the pointers of the starting position (x, y, z).  Then
        !           259:        pass the starting position's sector number as a pointer also.
        !           260:        Also these values will be modified accordingly.  Pass the
        !           261:        direction and velocity by using a vector (xvect, yvect).
        !           262:        If you don't fully understand these equations, please call me.
        !           263:                        xvect = velocity * cos(angle)
        !           264:                        yvect = velocity * sin(angle)
        !           265:                Walldist tells how close the object can get to a wall.  I use
        !           266:         128L as my default.  If you increase walldist all of a sudden
        !           267:         for a certain object, the object might leak through a wall, so
        !           268:         don't do that!
        !           269:                 If cliptype is 0, then the clipping is normal (Use 0 to clip you
        !           270:         and monsters).  If the cliptype is 1, then the object is clipped to
        !           271:         the same things that hitscan is clipped to (use 1 for all bullets).
        !           272: 
        !           273:          Clipmove can either return 0 (touched nothing)
        !           274:                                                                                  32768+wallnum (wall first touched)
        !           275:                                                                                  49152+spritenum (sprite first touched)
        !           276: 
        !           277: getzrange(long x, long y, long z, short sectnum,
        !           278:                                                long *ceilz, long *ceilhit,
        !           279:                                                long *florz, long *florhit,
        !           280:                                                long walldist, char cliptype)
        !           281: 
        !           282:                Use this in conjunction with clipmove.  This function will keep the
        !           283:        player from falling off cliffs when you're too close to the edge.  This
        !           284:        function finds the highest and lowest z coordinates that your clipping
        !           285:        BOX can get to.  It must search for all sectors (and sprites) that go
        !           286:        into your clipping box.  This method is better than using
        !           287:        sector[cursectnum].ceilingz and sector[cursectnum].floorz because this
        !           288:        searches the whole clipping box for objects, not just 1 point.
        !           289:                Pass x, y, z, sector normally.  Walldist can be 128.  Cliptype can be
        !           290:        0, 1, or 2. (just like movesprite and clipmove)  This function returns
        !           291:        the z extents in ceilz and florz. It will return the object hit in ceilhit
        !           292:        and florhit.
        !           293:          Ceilhit and florhit will also be either:
        !           294:                                                                                        16384+sector (sector first touched) or
        !           295:                                                                                        49152+spritenum (sprite first touched)
        !           296: 
        !           297: updatesector(long x, long y, &sectnum);
        !           298:        This function updates the sector number according to the x and y values
        !           299:        passed to it.  Be careful when you use this function with sprites because
        !           300:        remember that the sprite's sector number should not be modified directly.
        !           301:        If you want to update a sprite's sector, I recomment using the setsprite
        !           302:        function described below.
        !           303: 
        !           304: inside(long x, long y, short sectnum);
        !           305:        Tests to see whether the overhead point (x, y) is inside sector (sectnum)
        !           306:        Returns either 0 or 1, where 1 means it is inside, and 0 means it is not.
        !           307: 
        !           308: copytilepiece(long tilenume1, long sourcex1, long sourcey1,
        !           309:                                                                                long xsiz, long ysiz,
        !           310:                                  long tilenume2, long destx1, long desty1)
        !           311: 
        !           312:        This function simply copies any section of a source tile
        !           313:                to any part of a destination tile.  It will automatically
        !           314:                skip transparent pixels.  It will wrap-around in the
        !           315:                source but not the destination.  If for some reason
        !           316:                the destination tile gets removed from the cache, the
        !           317:                destination tile will be reset to original form.  This
        !           318:                is why I had to add this second function:
        !           319: 
        !           320: allocatepermanenttile(short tilenume, long xsiz, long ysiz)
        !           321:        This function allocates a place on the cache as permanent.
        !           322:                Right now, I reset the cache every time you call this
        !           323:                function so I would recommend calling this function
        !           324:                right after loadpics.
        !           325: 
        !           326: makepalookup(long palnum, char *remapbuf,
        !           327:                                 signed char r, signed char g, signed char b,
        !           328:                                 char dastat)
        !           329:        This function allows different shirt colors for sprites.  First prepare
        !           330:        remapbuf, which is a 256 byte buffer of chars which the colors to remap.
        !           331:        Palnum can be anywhere from 1-15.  Since 0 is where the normal palette is
        !           332:        stored, it is a bad idea to call this function with palnum=0.
        !           333:        In BUILD.H notice I added a new variable, spritepal[MAXSPRITES].
        !           334:        Usually the value of this is 0 for the default palette.  But if you
        !           335:        change it to the palnum in the code between drawrooms() and drawmasks
        !           336:        then the sprite will be drawn with that remapped palette.  The last 3
        !           337:        parameters are the color that the palette fades to as you get further
        !           338:        away.  This color is normally black (0,0,0).  White would be (63,63,63).
        !           339:        if ((dastat&1) == 0) then makepalookup will allocate & deallocate
        !           340:        the memory block for use but will not waste the time creating a palookup
        !           341:        table (assuming you will create one yourself)
        !           342: 
        !           343: copytilepiece(long walnume1, long x1, long y1, long xsiz, long ysiz,
        !           344:  long walnume2, long x2, long y2, char shadeoffs);
        !           345:        Copies section of tile 1 (walnume1) with top-left corner (x1,y1) and
        !           346:        rectangular size (xsiz, ysiz) to top-left corner (x2, y2) of tile 2
        !           347:        (walnume).  You can animate tiles with this function.  For example, with
        !           348:        this function, you can make a slot machine like in Ken's Labyrinth or an
        !           349:        electronic sign with text sliding from right to left.
        !           350: 
        !           351: loadtile(short tilenume);
        !           352:                This function will load the tile, tilenum, into the artwork cache.  A
        !           353:        tile is not in the cache if (waloff[tilenum] == -1).  If 
        !           354:        (waloff[tilenum] >= 0) then it is in the cache, and you don't need to call
        !           355:        this function.
        !           356: 
        !           357: precache();
        !           358:                This function will go through the tilenums of all sectors, walls, and
        !           359:        sprites and call loadtile() on them.  This function will not cache in some 
        !           360:        tiles of animations since their tilenums may not all be in the structures.
        !           361: 
        !           362: hitscan(long xstart, long ystart, long zstart, short startsectnum,
        !           363:                  long vectorx, long vectory, long vectorz,
        !           364:                  short *hitsect, short *hitwall, short *hitsprite,
        !           365:                  long *hitx, long *hity, long *hitz);
        !           366: 
        !           367:        Pass the starting 3D position:
        !           368:                  (xstart, ystart, zstart, startsectnum)
        !           369:        Then pass the 3D angle to shoot (defined as a 3D vector):
        !           370:                  (vectorx, vectory, vectorz)
        !           371:        Then set up the return values for the object hit:
        !           372:                  (hitsect, hitwall, hitsprite)
        !           373:        and the exact 3D point where the ray hits:
        !           374:                  (hitx, hity, hitz)
        !           375: 
        !           376:        How to determine what was hit:
        !           377:                * Hitsect is always equal to the sector that was hit (always >= 0).
        !           378: 
        !           379:                * If the ray hits a sprite then:
        !           380:                          hitsect = thesectornumber
        !           381:                          hitsprite = thespritenumber
        !           382:                          hitwall = -1
        !           383: 
        !           384:                 * If the ray hits a wall then:
        !           385:                          hitsect = thesectornumber
        !           386:                          hitsprite = -1
        !           387:                          hitwall = thewallnumber
        !           388: 
        !           389:                 * If the ray hits the ceiling of a sector then:
        !           390:                          hitsect = thesectornumber
        !           391:                          hitsprite = -1
        !           392:                          hitwall = -1
        !           393:                          vectorz < 0
        !           394:                          (If vectorz < 0 then you're shooting upward which means
        !           395:                                  that you couldn't have hit a floor)
        !           396: 
        !           397:                 * If the ray hits the floor of a sector then:
        !           398:                          hitsect = thesectornumber
        !           399:                          hitsprite = -1
        !           400:                          hitwall = -1
        !           401:                          vectorz > 0
        !           402:                          (If vectorz > 0 then you're shooting downard which means
        !           403:                                  that you couldn't have hit a ceiling)
        !           404: 
        !           405: neartag(long x, long y, long z, short sectnum, short ang,  //Starting position & angle
        !           406:                  short *neartagsector,   //Returns near sector if sector[].tag != 0
        !           407:                  short *neartagwall,     //Returns near wall if wall[].tag != 0
        !           408:                  short *neartagsprite,   //Returns near sprite if sprite[].tag != 0
        !           409:                  long *neartaghitdist,   //Returns actual distance to object (scale: 1024=largest grid size)
        !           410:                  long neartagrange,      //Choose maximum distance to scan (scale: 1024=largest grid size)
        !           411:                  char tagsearch)         //1-lotag only, 2-hitag only, 3-lotag&hitag
        !           412:                Neartag works sort of like hitscan, but is optimized to
        !           413:        scan only close objects and scan only objects with
        !           414:        tags != 0.  Neartag is perfect for the first line of your space bar code.
        !           415:        It will tell you what door you want to open or what switch you want to
        !           416:        flip.
        !           417: 
        !           418: cansee(long x1, long y1, long z1, short sectnum1,
        !           419:                 long x2, long y2, long z2, short sectnum2);  returns 0 or 1
        !           420:        This function determines whether or not two 3D points can "see" each
        !           421:        other or not.  All you do is pass it the coordinates of a 3D line defined
        !           422:        by two 3D points (with their respective sectors)  The function will return
        !           423:        a 1 if the points can see each other or a 0 if there is something blocking
        !           424:        the two points from seeing each other.  This is how I determine whether a
        !           425:        monster can see you or not. Try playing DOOM1.DAT to fully enjoy this
        !           426:        great function!
        !           427: 
        !           428: setanimation(long *animptr, long thegoal, long thevel);
        !           429:        This is a function for your convenience that will animate a long
        !           430:        variable, such as sector[].floorz for platforms, or sector[].ceilingz
        !           431:        for doors.  All you do is pass it the long pointer into memory, specifying
        !           432:        which long variable is to be animated; you also pass the goal (long value
        !           433:        to animate towards), and the velocity at which the variable is animated.
        !           434:        Velocity = 128 is a normal speed door.  You may also modify the animation
        !           435:        arrays directly if you wish:
        !           436: 
        !           437:        The animation arrays are as follows:
        !           438:                long *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
        !           439:                long animatevel[MAXANIMATES], animatecnt;
        !           440: 
        !           441: getanimationgoal(long animptr);
        !           442:        Check to see if a certain variable in memory is already being animated
        !           443:        by the engine.  If so, an index into the animation arrays is returned,
        !           444:        else -1 is returned.  This is function is useful when you are press
        !           445:        space bar near a door, and it is already animating, you simply want
        !           446:        to reverse its direction.
        !           447: 
        !           448: dragpoint(short wallnum, long newx, long newy);
        !           449:        This function will drag a point in the exact same way a point is dragged
        !           450:        in 2D EDIT MODE using the left mouse button.  Simply pass it which wall
        !           451:        to drag and then pass the new x and y coordinates for that point.
        !           452:        Please use this function because if you don't and try to drag points
        !           453:        yourself, I can guarantee that it won't work as well as mine and you
        !           454:        will get confused.  Note:  Every wall of course has 2 points.  When you
        !           455:        pass a wall number to this function, you are actually passing 1 point,
        !           456:        the left side of the wall (given that you are in the sector of that wall)
        !           457:        Got it?
        !           458: 
        !           459: nextsectorneighborz(short sectnum, long thez, short topbottom, short direction);
        !           460:        This function searches z-coordinates of neighboring sectors to find the
        !           461:        closest (next) ceiling starting at the given z-coordinate (thez).
        !           462:        For example, if you want to find the goal z-coordinate when opening a
        !           463:        door, you might want the door to stop at the next closest neighboring
        !           464:        ceiling z-coordinate.  You can get the z-coordinate this way:
        !           465: 
        !           466:                newz = sector[nextsectorneighborz(sectnum,startz,-1,-1)].ceilingz
        !           467: 
        !           468:        topbottom (3rd parameter)  -1 = search ceilings
        !           469:                                                                                 1 = search floors
        !           470:        direction (4th parameter)  -1 = search upwards
        !           471:                                                                                 1 = search downwards
        !           472: 
        !           473: screencapture(char *filename)
        !           474:        Capture the screen and save it as a .BMP file.  I don't know why my
        !           475:        .BMP format isn't compatible with other programs.
        !           476: 
        !           477: ���������������������������������������������������������������������������Ŀ
        !           478: �                             SPRITE FUNCTIONS:                             �
        !           479: �����������������������������������������������������������������������������
        !           480: 
        !           481: insertsprite(short sectnum, short statnum);   //returns (short)spritenum;
        !           482:        Whenever you insert a sprite, you must pass it the sector
        !           483:        number, and a status number (statnum).  The status number can be any
        !           484:        number from 0 to MAXSTATUS-1.  Insertsprite works like a memory
        !           485:        allocation function and returns the sprite number.
        !           486: 
        !           487: deletesprite(short spritenum);
        !           488:        Deletes the sprite.
        !           489: 
        !           490: changespritesect(short spritenum, short newsectnum);
        !           491:        Changes the sector of sprite (spritenum) to the
        !           492:        newsector (newsectnum).  This function may become
        !           493:        internal to the engine in the movesprite function.  But
        !           494:        this function is necessary since all the sectors have
        !           495:        their own doubly-linked lists of sprites.
        !           496: 
        !           497: changespritestat(short spritenum, short newstatnum);
        !           498:        Changes the status of sprite (spritenum) to status
        !           499:        (newstatus).  Newstatus can be any number from 0 to MAXSTATUS-1.
        !           500:        You can use this function to put a monster on a list of active sprites
        !           501:        when it first sees you.
        !           502: 
        !           503: setsprite(short spritenum, long newx, long newy, long newz);
        !           504:                This function simply sets the sprite's position to a specified
        !           505:        coordinate (newx, newy, newz) without any checking to see
        !           506:        whether the position is valid or not.  You could directly
        !           507:        modify the sprite[].x, sprite[].y, and sprite[].z values, but
        !           508:        if you use my function, the sprite is guaranteed to be in the
        !           509:        right sector.
        !           510: 
        !           511: movesprite(short spritenum, long xchange, long ychange, long zchange,
        !           512:                          long ceildist, long flordist, char cliptype, long numtics)
        !           513:                This function moves the sprite given by spritenum by the 3
        !           514:        increments, xchange, ychange, and zchange.  If cliptype is 0, then
        !           515:        the clipping is normal (Use 0 to clip you and monsters).  If the
        !           516:        cliptype is 1, then the object is clipped to the same things that
        !           517:        hitscan is clipped to (use 1 for all bullets).
        !           518:                Movesprite can either return 0 (touched nothing)
        !           519:                                                                                 16384+sectnum (ceiling/floor first touched)
        !           520:                                                                                 32768+wallnum (wall first touched)
        !           521:                                                                                 49152+spritenum (sprite first touched)
        !           522: 
        !           523: getspritescreencoord(short spritesortnum, long *scrx, long *scry)
        !           524:                This function returns the actual screen coordinates of a sprite.  It
        !           525:        is useful for locking on to a target.  Use this function between
        !           526:        drawrooms and drawmasks.  Note that spritesortnum is the index into the
        !           527:        spritesortcnt arrays, NOT the normal sprite arrays.  Scrx and scry are
        !           528:        actual screen coordinates ranging from 0-319 and 0-199 respectively.
        !           529: 
        !           530: ���������������������������������������������������������������������������Ŀ
        !           531: �                       MULTIPLAYER FUNCTIONS (multi.obj)                   �
        !           532: �����������������������������������������������������������������������������
        !           533: 
        !           534:        initmultiplayers(option[4],option[5]);
        !           535:                        Call this right after initengine.  Pass option[4] and option[5]
        !           536:                exactly the way I have it written here.  (option[4] is the COM1-COM4,
        !           537:                network option and option[5] is the com speed selection option)
        !           538: 
        !           539:        uninitmultiplayers();
        !           540:                        Call this right before uninitengine.
        !           541: 
        !           542:        sendlogon();
        !           543:                        Use this function after everything's initialized, but before you
        !           544:                go into the main game loop.  Right after you call sendlogon(), you
        !           545:                should run a loop that will wait until a specified number of players.
        !           546:                Here's some example code:
        !           547: 
        !           548:                sendlogon();
        !           549:                while (numplayers < waitplayers)
        !           550:                {
        !           551:                        getpackets();
        !           552:                }
        !           553:                screenpeek = myconnectindex;
        !           554: 
        !           555:                        Getpackets reserves the packet header range from 200-255.  If you
        !           556:                keep calling getpackets after sendlogon, the numplayers variable will
        !           557:                automatically be incremented when other people log on.
        !           558: 
        !           559:        sendlogoff();
        !           560:                        Call this before leaving, before uninitializing the multiplayer
        !           561:                code.
        !           562: 
        !           563:        sendpacket (short otherconnectindex, char *bufptr, short bufleng)
        !           564:                        For COM(modem) communications, the otherconnectindex doesn't matter.
        !           565:                        For network communcations, you can specify which computer to send
        !           566:                to by setting otherconnectindex to the proper index number.  You
        !           567:                can also do a broadcast by setting otherconnectindex to -1.
        !           568:                        Also pass the buffer and length parameters.
        !           569: 
        !           570:        short getpacket (short *otherconnectindex, char *bufptr) returns bufleng
        !           571:                        When using getpacket, first check the value it returns.
        !           572:                If the value is 0, then the buffer length is 0 which means there
        !           573:                are no packets available.  If the buffer length is greater than
        !           574:                0, then use that value as the length of the buffer.  Getpacket also
        !           575:                tells you what computer the message was received from -
        !           576:                (otherconnectindex).
        !           577: 
        !           578: ���������������������������������������������������������������������������Ŀ
        !           579: �                       DIGITIZED SOUND FUNCTIONS:                          �
        !           580: �����������������������������������������������������������������������������
        !           581: Note: If you want to write your own digitized sound driver, simply delete
        !           582:        these functions from GAME.C.
        !           583: 
        !           584: initsb();
        !           585:                         Initializes the digitized sound routines.  You need to call this
        !           586:                         only once at the beginning of the program.  Currently, the
        !           587:                         sample rate is 11,025 Hz.
        !           588: 
        !           589: wsay(char *filename, long freq, char volume);
        !           590:                         Play the sound file at the given frequency and volume.  If you
        !           591:                         set freq = 4096, the sound will play at normal frequency (given
        !           592:                         the sound was also recorded at 11025 Hz)  To play the sound an
        !           593:                         octave higher, for example, set freq = 8192.  Volume ranges from
        !           594:                         0 (silent) to 255 (full volume).  Ex: wsay("blowup.wav",4096L,255);
        !           595: 
        !           596: uninitsb();
        !           597:                         Turns the speaker off, so sounds don't continue playing while
        !           598:                         your back in DOS.
        !           599: 
        !           600: ���������������������������������������������������������������������������Ŀ
        !           601: �                            MUSIC FUNCTIONS:                               �
        !           602: �����������������������������������������������������������������������������
        !           603: Note: If you want to write your own music driver, simply delete these
        !           604:        functions from GAME.C.  The BUILD engine uses interrupt vector 0x8 (IRQ0)
        !           605:        and that may complicate things.  If you like my music, perhaps I can send
        !           606:        you my MIDI sequencer program (It requires MPU-401, and TSENG-ET4000 SVGA,
        !           607:        but could be standardized if there's enough demand).
        !           608: 
        !           609: loadmusic(char *filename);
        !           610:                         Loads the given song into memory.  Be sure INSTS.DAT is in the
        !           611:                         current directory.  If no extension is given, then .KSM will be
        !           612:                         appended to the filename.  You should use this function only when
        !           613:                         the music is off.
        !           614: musicon();
        !           615:                         Enable the playing of music.  Use this only after loadmusic has
        !           616:                         been called.
        !           617: musicoff();
        !           618:                         Disable the playing of music.  Be sure to call this before quitting
        !           619:                         to DOS.
        !           620: 
        !           621: ���������������������������������������������������������������������������ͻ
        !           622: ���������������������������������������������������������������������������͹
        !           623: ���������������������������������������������������������������������������͹
        !           624: ���������������������������������������������������������������������������͹
        !           625: ���������������������������������������������������������������������������͹
        !           626: ���������������������������������������������������������������������������͹
        !           627: ���������������������������������������������������������������������������͹
        !           628: ���������������������������������������������������������������������������͹
        !           629: ���������������������������������������������������������������������������͹
        !           630: ���������������������������������������������������������������������������ͼ
        !           631: 
        !           632: ���������������������������������������������������������������������������Ŀ
        !           633: �                       BUILD Revision History:                             �
        !           634: �����������������������������������������������������������������������������
        !           635: 2/6/94   - Added this revision thing.
        !           636:                        - Setup program.
        !           637:                        - A faster new mode for standard VGAs called chain mode.
        !           638: ������������������������������������������������������������������������������
        !           639: 2/8/94   - Fixed chain mode with groudraws.
        !           640:                        - Added sector joining in 2D EDIT MODE - press J on first sector.
        !           641:                                  Then press J again on sector to join with.  Attributes will be
        !           642:                                  taken from first sector.  Possible bugs.
        !           643:                        - Improved controls for slower computers.
        !           644:                        - Made timer interrupt rate 120/second instead of 240/second.
        !           645: ������������������������������������������������������������������������������
        !           646: 2/9/94   - Started to work on status bar in 2D EDIT MODE.
        !           647:                        - Added special optimization for the Western Digitial (Paradise)
        !           648:                                  chipset just like with TSENG ET4000.
        !           649: ������������������������������������������������������������������������������
        !           650: 2/10/94  - Added a door attribute to sectors.  To make a sector a door,
        !           651:                                  press "D" on the ceiling of the sector in 3D EDIT MODE.  For
        !           652:                                  the door to work, the ceiling of the door sector must be a
        !           653:                                  tiny bit lower than lowest neighboring ceiling.  To open/close
        !           654:                                  the door, you may press the space bar.  Note: Space Bar is also
        !           655:                                  used for copy and paste in 3D EDIT MODE.  You may have to go
        !           656:                                  into game mode to test out the doors for now.
        !           657:                        - Added a wall orientation attribute to walls.  This attribute is
        !           658:                                  used especially in conjunction with doors.  So far, you have
        !           659:                                  been working with walls that are start from the top.  For
        !           660:                                  example, if you hold down 2/8 on the keypad in 3D EDIT MODE,
        !           661:                                  the wall always starts from the top.  But for doors, you
        !           662:                                  sometimes need walls to start from the bottom.  To do this,
        !           663:                                  press "O" (for orientation) on the wall, and it will now
        !           664:                                  start from the bottom.
        !           665: ������������������������������������������������������������������������������
        !           666: 2/12/94  - Fixed some bugs for sprites.  Sprites don't disappear anymore.
        !           667:                                  Now you will pick up all sprites when running over them.
        !           668:                                  Monsters will not stop shooting anymore.
        !           669:                        - Made the sound blaster sounds have a 1-sound cache.  That is, if
        !           670:                                  the same sound is to be played several times in a row, it will
        !           671:                                  only be loaded once.
        !           672:                        - Added *.GIF format support to EDITART for 320*200 size images.
        !           673:                        - Changed the PASTE key in 3D EDIT MODE from Space bar to Left
        !           674:                                  Enter because the Space bar conflicted with opening doors.
        !           675:                        - Added music as an option in the setup program.  To run the music,
        !           676:                                  you need INSTS.DAT and a song file with a .KSM extension.
        !           677:                        - Split the editor from the game.
        !           678:                                  BUILD is now the map editor - you don't need BUILD.C anymore.
        !           679:                                  GAME is now the actual game that you will be programming.
        !           680:                                          I am giving you GAME.C to work with.  Its code is simpler
        !           681:                                          than before because there are no more editing function
        !           682:                                          calls in it.
        !           683:                        - Sprites move in a straight line now until they hit walls.  When
        !           684:                                  they hit walls, they pick a new angle to travel in.
        !           685:                        - Remember that tiny little guy with the "Al" on his shirt?
        !           686:                                  Next time you're in DOOM1.DAT, try shooting him.  Then look
        !           687:                                  at the code in GAME.C.
        !           688:                        - In EDITART, when you press, "u", you now select filenames with
        !           689:                                  the arrow keys and enter rather than having to type in
        !           690:                                  the exact filename.
        !           691:                        - Board maps now have extension .MAP and artwork files now have
        !           692:                                  extension .ART to help distinguish between the different types
        !           693:                                  of files.
        !           694: ������������������������������������������������������������������������������
        !           695: 2/22/94  - Fixed small bug with EDITART not loading right when names.h
        !           696:                                  existed with no names defined.
        !           697:                        - You can now edit new boards by typing:
        !           698:                                  BUILD <file that doesn't exist> like "BUILD NEWBOARD"
        !           699:                        - Added ALT-S in 2D EDIT Mode to change a whole white loop inside a
        !           700:                                  sector to a red loop.
        !           701:                        - When viewing the tiles (pressing "v") you can now use PGUP/PGDN.
        !           702:                        - Added a message bar in 2D EDIT Mode.
        !           703:                        - Added TAB and L.ALT-TAB keys to view all the attributes of a
        !           704:                                  sector, wall, or sprite (see above documentation).
        !           705:                        - Debugged and bullet-proofed ALT-S.
        !           706:                        - Fixed a bug that doesn't allow you to drag points with number
        !           707:                                  greater than 1023. (There can actually be 4096 walls and 1024
        !           708:                                  sectors, and 4096 sprites currently, an easy thing to increase)
        !           709:                        - Changed overwritesprite function paramaters.  If you are using it
        !           710:                                  in your c file, you must change it!  Now it looks like this:
        !           711: 
        !           712:                                          overwritesprite (long x, long y, short tilenum, char shade,
        !           713:                                                  char orientation);
        !           714: 
        !           715:                                  If orientation = 0: x and y are the top left corner.
        !           716:                                  If orientation = 1: x and y are the middle (like before).
        !           717:                        - Added permanentwritesprite function for status bars or other
        !           718:                                  sections of the screen that will not be overwritten by the
        !           719:                                  engine.  When using this function, you may want to modify the
        !           720:                                  STARTUMOST / STARTDMOST arrays. The format of this function is
        !           721:                                  like overwritesprite except that the x and y are always top
        !           722:                                  left corner, no orientation variable, and no translucence.
        !           723: 
        !           724:                                permanentwritesprite (long x, long y, short tilenum, char shade);
        !           725: 
        !           726:                        - Added an attribute to the printext and printnum functions.  Please
        !           727:                                  change these function if you use them in your program.  The
        !           728:                                  current formats are:
        !           729: 
        !           730:                                          printext(long x, long y, char buffer[42], short tilenum,
        !           731:                                                  char invisiblecol)
        !           732:                                          printnum(long x, long y, long num, short tilenum,
        !           733:                                                  char invisiblecol);
        !           734: 
        !           735:                         Invisiblecol tells printext what color to draw the transparent
        !           736:                         pixels.  If invisiblecol is 255 then the transpararent pixels are
        !           737:                         still transparent.
        !           738: ������������������������������������������������������������������������������
        !           739: 2/26/94  - Completely reprogrammed EDITART.
        !           740:          IMPORTANT: PLEASE RUN CONVART.EXE ON ALL ARTWORK FILES! (If you have not
        !           741:                                  already).  It will convert PICS.ART in the old format to
        !           742:                                  TILES.ART in the new format, so you may have to do some
        !           743:                                  renaming when converting artwork and also rename the loadpics
        !           744:                                  line in your C file.  BUILD WILL NOT RUN UNLESS YOU DO THIS!
        !           745:                                  With the new artwork file, the tiles can now be any size from
        !           746:                                  1*1 to 1024*240 and they no longer have to be powers of 2.
        !           747:                                  This feature allows parallaxing skies that are 1024 pixels wide
        !           748:                                  to cover all 360�, or 320 pixel wide status bars.  It can also
        !           749:                                  be used to display 320*200 title screens.
        !           750:                        - When pressing 'U' in EDITART, you can now change directories
        !           751:                                  and the current loading directory will be remembered.
        !           752:                        - When pressing 'U' in EDITART, you can press the mouse button to
        !           753:                                  readjust the size of the tile.
        !           754:                        - When pressing 'U' in EDITART, press ENTER for an automatic
        !           755:                                  palette conversion or press SPACE BAR for no conversion.
        !           756:                        - Walls that are Blocked ('B') in BUILD are now shown in pink.
        !           757:                                  If the wall does not show pink in your board, just press
        !           758:                                  'B' twice to permanently fix it.
        !           759:                        - Made smooshiness values easier to work with.  Hold down 5 on the
        !           760:                                  keypad with 2/4/6/8 to align the walls to multiples of the
        !           761:                                  tile that is used.  Also, when you do Tab and L.Enter for
        !           762:                                  Copy&Paste, the y-repeat values stay the same, and the
        !           763:                                  x-repeat values are adjusted so the pixels of the bitmaps
        !           764:                                  have a square-aspect ratio.
        !           765:                        - Added masked walls.  But since they don't quite work perfectly
        !           766:                                  yet, and they are extremely hard to edit now, so for now, just
        !           767:                                  enjoy the technologiy in DOOM1.MAP. Don't worry - you'll get
        !           768:                                  your hands on this soon!
        !           769:                        - Fixed the "earthquake" effect on really high walls.  The walls
        !           770:                                  will not move up and down, but the pixel fuzzyness bug is
        !           771:                                  still in there.
        !           772:                        - Put door variables and tile information into BUILD.H for you to
        !           773:                                  play around with.
        !           774:                        - Made walls, ceilings, and floors also work with the animation
        !           775:                                  attribute in EDITART.
        !           776: ������������������������������������������������������������������������������
        !           777: 3/2/94   - Made power of 2 size tiles work with ceilings & floors.
        !           778:                        - When using different size ceilings & floors, made an option in
        !           779:                                  3D EDIT MODE.  If you want a tile to be smooshed into the normal
        !           780:                                  64*64 area, press 'E' to unExpand the tile.
        !           781:                        - Groudraws now look more cubical than before. (But be careful of
        !           782:                                  crashing with them for now)
        !           783:                        - IMPORTANT: Changed the Board format.  If you tried running BUILD
        !           784:                                  before reading this, and it didn't work, shame on you!  You
        !           785:                                  should always look at the history section of BUILD.TXT first!
        !           786:                                  Since from now on, I am writing Board/Art converters, I am
        !           787:                                  giving you CONVMAP.EXE to convert maps.  You can type either:
        !           788:                                          C:\BUILD>convmap house.map
        !           789:                                  to convert an individual map or:
        !           790:                                          C:\BUILD>for %i in (*.map) do convmap %i
        !           791:                                  to convert all the maps in a directory.
        !           792: 
        !           793:                        - IMPORTANT: Sprites are now on 2 different sets of doubly-linked
        !           794:                                  lists. The big advantage of this method is that when sprites
        !           795:                                  are deleted, there can be holes in the sprite list with
        !           796:                                  no slow down.  Before I used to have linked lists for each
        !           797:                                  sector pointing to all the sprites in it.  Well, I have updated
        !           798:                                  that and added more linked lists that tell whether sprites
        !           799:                                  are active or inactive (not a fun thing to progam)  But not
        !           800:                                  to worry, you don't have to deal with changing the linked
        !           801:                                  lists, thanks to my very easy function calls.  YOU WILL
        !           802:                                  HAVE TO CHANGE YOUR CODE TO SUPPORT THE NEW LINKED LISTS.
        !           803:                                  You should know how to search through each list.  See BUILD.H
        !           804:                                  for a detailed description of how the linked lists work, and
        !           805:                                  see the top of this file for description of the new sprite
        !           806:                                  function calls.
        !           807: 
        !           808:                                          insertsprite(short sectnum, short statnum);
        !           809:                                          deletesprite(short spritenum);
        !           810:                                          changespritesect(short spritenum, short newsectnum);
        !           811:                                          changespritestat(short spritenum, short newstatnum);
        !           812: 
        !           813:                                  In your code, you will have to change the following:
        !           814:                                          firstsprite[spritenum]    -->  headspritesect[spritenum]
        !           815:                                          sprite[spritenum].point2  -->  nextspritesect[spritenum]
        !           816: 
        !           817:                                  Also, you should change the part of your main loop that scans
        !           818:                                          through all the active sprites to look more like this:
        !           819: 
        !           820: 
        !           821:                i = headspritestat[1];          //head of active sprite list
        !           822:                while (i != -1)
        !           823:                {
        !           824:                        nexti = nextspritestat[i];   //back up next sprite in case current
        !           825:                                                                                                  //one is deleted.
        !           826: 
        !           827:                        //your code goes here (use i as the sprite number)
        !           828: 
        !           829: spriteisdeletedskip:
        !           830:                        i = nexti;                   //go to next sprite
        !           831:                }
        !           832: 
        !           833: 
        !           834: 
        !           835:                        - Added tagging (naming) to any sector, sprite, or wall.  That means
        !           836:                                  you can change a tag in the BUILD editor by pressing T with the
        !           837:                                  mouse cursor on the highlighted sector.  And in GAME.C, you
        !           838:                                  can access the tag this way:
        !           839:                                          sector[sectnum].tag;
        !           840:                                          sprite[spritenum].tag;
        !           841:                                          wall[wallnum].tag;
        !           842:                                  Note: All 3 types of tags are long integers, but in BUILD.C
        !           843:                                          you can only make them short integers.  I am planning to
        !           844:                                          let you use the upper 16 bits of the tag byte as use for
        !           845:                                          you only.  (like permanently unreserved bits)
        !           846:                        - Added serial link.  But it doesn't work very well yet.  You
        !           847:                                  may have to try going into GAME several times before it works.
        !           848: ������������������������������������������������������������������������������
        !           849: 3/15/94  - Fixed maskable walls - now sort out with sprite better.  Easier
        !           850:                          to edit.  Simply press 'M' at a place where a maskable wall
        !           851:                          should be (like where you normally press 'B' for blocking)
        !           852:                        - Can flip walls, masked walls, and sprites x-wise by pressing
        !           853:                          'F' in 3D EDIT MODE.  Also, it is possible to save space in
        !           854:                          sprite rotations, by flipping it x-wise by programming one of
        !           855:                          the bits in sprite[].cstat.
        !           856:                        - A few other minor things, but I forgot what they were.
        !           857: ������������������������������������������������������������������������������
        !           858: 3/19/94  - Fixed one of the many crashing bugs.
        !           859:                                  For Duke Nukem III team:
        !           860:                                          CITY.MAP will not crash anymore with new version.  The
        !           861:                                          reason it crashed was because in your TILES.ART, you had
        !           862:                                          either ANMFD:0, ANMBK:0, or OSCI:0.  That caused a MOD 0
        !           863:                                          in my animation routine. I bullet-proofed that.  How about
        !           864:                                          fixing tiles #34, #112, or #114 in your TILES.ART.
        !           865:                        - Wrote divide by zero handler.  Now if there is a divide by zero,
        !           866:                                         BUILD goes back into text mode and fills the screen with
        !           867:                                         /0/0/0/0/..., then gives a DOS prompt. (In other words, you
        !           868:                                         don't have to type "MODE CO80" anymore for /0 crashes)
        !           869:                        - Optimized routines in assembly for 486's using my great new
        !           870:                                         Intel 32-bit optimizing techniques book that dad got for me.
        !           871:                        - Fixed ALT-S in BUILD so ANY white loop can be converted into a
        !           872:                                         red loop except for the 1 and only 1 outermost white loop.
        !           873:                        - FINALLY!  Splitsector bug is fixed!  You can now split a very
        !           874:                                         complicated sector with tons of sectors inside it or with
        !           875:                                         plenty of sprites.  Also sprites will not get deleted
        !           876:                                         spontaneously with split sector any more.
        !           877:                        - Ctrl-Enter in 3D EDIT MODE is like the normal Enter paste key,
        !           878:                                         but Ctrl-Enter pastes the attributes to an entire loop of
        !           879:                                         walls (if a wall is highlighted).
        !           880: ������������������������������������������������������������������������������
        !           881: 3/22/94  - Added doors that open left and right.  See sector[].tag #9 in the top
        !           882:                                         of this file for details - also look at my board, NUKELAND.MAP,
        !           883:                                         in BUILD to see how to make this type of door.
        !           884:                        - Increased the number of status lists.  You may recall my active /
        !           885:                                         inactive sprite lists called headspritestat, prevspritestat,
        !           886:                                         and nextspritestat.  Don't worry - you will NOT have to
        !           887:                                         change any of your code.  The only thing I changed is now
        !           888:                                         you can have 1024 different lists of sprites rather than just
        !           889:                                         2 lists if you want to use them.  For example, you might want
        !           890:                                         to run through all the brown monsters on the board.  Instead
        !           891:                                         of putting all different types of monsters on the active
        !           892:                                         list, it is faster to have a separate list just for brown
        !           893:                                         monsters.  Use your imagination!
        !           894: ������������������������������������������������������������������������������
        !           895: 3/31/94  - Fixed some palette problems with EDITART.  Now when you press 'P'
        !           896:                                         in 'U' mode, the palette of all the existing tiles are
        !           897:                                         converted to the new palette.  Also the text colors should
        !           898:                                         be similar colors on different palettes now.
        !           899:                        - Changed bit 0 of sprite[].cstat to the hitscan checking / ignoring
        !           900:                                         bit.  You should set this bit to 1 for monsters, 0 for
        !           901:                                         bullets, 0 for pick-upable objects like coins, and 1 for
        !           902:                                         objects like columns.  Right now, (Since it's not in the
        !           903:                                         BUILD editor), you must set these bits in your code right
        !           904:                                         after you load the board.
        !           905:                        - I did not document the neartagsector, neartagwall, and
        !           906:                                         neartagsprite very well, so if you don't know how to use
        !           907:                                         them alreay, please read on.  These 3 variables are modified
        !           908:                                         by the engine every time you call draw3dscreen().  These
        !           909:                                         variables are usually -1.  These variables will be >= 0 if
        !           910:                                         all of these cases are true:
        !           911:                                                 1.  You are looking at a wall, sprite, or sector.
        !           912:                                                 2.  You are close enough to the wall, sprite, or sector
        !           913:                                                          to be able to use the action key with it.
        !           914:                                                 3.  The tag of the wall, sprite, or sector is greater or
        !           915:                                                          equal to 1.
        !           916:                                         As you can see, neartagsector makes a perfect variable for
        !           917:                                         detecting whether or not you are opening a door.  You can
        !           918:                                         also use neartagwall for switches on walls.  Also, you can
        !           919:                                         use neartagsprite for sprites that are switches.
        !           920:                        - PROGRAMMERS: PLEASE MAKE THESE EASY CODE MODIFICATIONS:
        !           921:                                         I reversed the way variables are stored in BUILD.H.
        !           922:                                         Now the variables will be local to the ENGINE and externed
        !           923:                                         to GAME.  Before they were local to GAME and externed to the
        !           924:                                         engine.  All you have to do is this:
        !           925:                                                 1.  You can remove the #define MAIN if you want to.
        !           926:                                                 2.  Delete the externs declarations that I used to have
        !           927:                                                          in the beginning of GAME.C, because I put them in
        !           928:                                                          BUILD.H.  I will try not to put externs in the GAME
        !           929:                                                          in the future to save you the time of copying and
        !           930:                                                          pasting code.  Here is a list of externs I moved:
        !           931: 
        !           932:                                         EXTERN short neartagsector, neartagwall, neartagsprite;
        !           933:                                         EXTERN long *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
        !           934:                                         EXTERN long animatevel[MAXANIMATES], animatecnt;
        !           935:                                         EXTERN short tilesizx[MAXTILES], tilesizy[MAXTILES];
        !           936:                                         EXTERN long numtiles, picanm[MAXTILES], waloff[MAXTILES];
        !           937:                        - Added a global parallaxing sky type variable.  Now I have 3
        !           938:                                         different types of parallaxing skies.  Here they are:
        !           939: 
        !           940:                                 0 - Totally flat parallaxing sky.
        !           941:                                 1 - X-only stretching parallaxing sky (This is what DOOM uses).
        !           942:                                 2 - X- and Y- stretching parallaxing sky. (This is what BUILD
        !           943:                                                                                                                                                  uses by default)
        !           944:                                 A good place to set the parallaxing sky is right after you
        !           945:                                 call initengine().
        !           946:                        - Added local tile selection to the BUILD editor.  This means
        !           947:                                        that when you press V on a sprite, you will see only the
        !           948:                                        sprites that are on the level so far.  If you want to use
        !           949:                                        a sprite that is not already used on the current board, press
        !           950:                                        V again and you will be able to select from the huge list
        !           951:                                        that you are used to from before.  The local tile list will
        !           952:                                        be sorted according to how much each tile is used on the
        !           953:                                        current board.  Note that the local tile list will be
        !           954:                                        different depending where the mouse cursor was left when you
        !           955:                                        pressed V (or H).
        !           956: ������������������������������������������������������������������������������
        !           957: 4/4/94   - Changed the way ART files work.  YOU MUST READ THIS:
        !           958:                                        There are some two easy things that you must do 2 things before
        !           959:                                        you can use the new engine:
        !           960: 
        !           961:                                        1. Type CONVART1.EXE to convert your ARTWORK to the new
        !           962:                                        format.  (If I forgot to send this file to you, please call
        !           963:                                        and torture me.)   Now, instead of everything being stored
        !           964:                                        in one huge file, TILES.ART, I am splitting the artwork into
        !           965:                                        several files each holding 256 tiles in it.  This will allow
        !           966:                                        you to make infinitely large artwork files in EDITART.
        !           967: 
        !           968:                                        2. In GAME.C, you must change the line,
        !           969:                                                        loadpics("tiles.art");
        !           970:                                                to:
        !           971:                                                        loadpics("tiles000.art");
        !           972:                                                All you have to give loadpics is the first filename of your
        !           973:                                                artwork, and the engine will automatically know how to
        !           974:                                                modify the 3 digits at the end and load all the artwork
        !           975:                                                files properly.
        !           976: ������������������������������������������������������������������������������
        !           977: 4/5/94   - Fixed the "fuzzy" pixels on high walls.  Now you make walls as
        !           978:                                                high as skyscrapers, and when you look at it up close, the
        !           979:                                                pixels will still look like perfect rectangles.  Note: This
        !           980:                                                fix may require you to press 'O' in 3D EDIT MODE to put
        !           981:                                                your boards back to normal.
        !           982:                        - When you pressed ENTER on weird-sized tiles, sometimes in the old
        !           983:                                                version the pixels would not be square aspect ratio.  Now
        !           984:                                                when you press ENTER, they will be.
        !           985:                        - You can now set the starting position in 2D EDIT MODE with the
        !           986:                                                Scroll Lock key.  The starting position will look like a
        !           987:                                                brown arrow, and your current position will look like a
        !           988:                                                white arrow.  Now you don't have to keep returning to start
        !           989:                                                when you save your board.
        !           990:                        - Added some new things to the structures - guess what this means?
        !           991:                                                CONVMAP3!  THE NEW OBJ'S and BUILD will NOT work until you
        !           992:                                                                          run CONVMAP3. (Please call if I forgot to give
        !           993:                                                                                                                  you this file)
        !           994:                                                Notice that I added these things to the structures:
        !           995: 
        !           996:                                                sectortype:
        !           997:                                                        bit 2 of ceilingstat&floorstat:
        !           998:                                                                1 = North/South panning, 0 = East/West panning
        !           999:                                                        char ceilingpanning, floorpanning;
        !          1000:                                                walltype:
        !          1001:                                                        bit 6 of cstat
        !          1002:                                                                1 = Vertical panning, 0 = Horizontal panning
        !          1003:                                                        char panning;
        !          1004:                                                        short overpicnum;
        !          1005:                                                spritetype:
        !          1006:                                                        char *extra;
        !          1007: 
        !          1008:                                                Now an explanation of each:
        !          1009:                                                        To the sector structure, I added the capability to pan
        !          1010:                                                the floors and ceilings.  Usually ceilingpanning and
        !          1011:                                                floorpanning are set to 0.  For example, a good way to make
        !          1012:                                                an earthquake would be to randomly increment or decrement
        !          1013:                                                to panning values.  To allow you to pan the ceilings or
        !          1014:                                                floors at any of the standard 90 degree angles, I made
        !          1015:                                                bit 2 of sectortype's ceilingstat/floorstat byte choose
        !          1016:                                                whether the ceilingpanning/floorpanning byte should move
        !          1017:                                                the ceiling/floor North/South or East/West.
        !          1018:                                                        To the wall structure, I added panning also.  Bit 6
        !          1019:                                                of cstat and the panning values work in the same as the
        !          1020:                                                ceilings and floors.
        !          1021:                                                        To the sprite structure, I added only 1 variable.
        !          1022:                                                The "extra" pointer is intended for your use only, so you
        !          1023:                                                can have the sprite's structure extended if you so desire.
        !          1024: ������������������������������������������������������������������������������
        !          1025: 4/6/94   - In 2D EDIT MODE, you can now press ESC to get a message in the
        !          1026:                                                message bar that says this:
        !          1027: 
        !          1028:                                                (N)ew, (L)oad, (S)ave, (Q)uit
        !          1029: 
        !          1030:                                                And it all works too.  (Press ESC to cancel)
        !          1031:                                                Loading lets you select the file just like 'U' in EDITART.
        !          1032:                        - The old version of BUILD had the coordinate system all screwed
        !          1033:                                                up in 2D EDIT MODE.  I fixed this.  Included with
        !          1034:                                                CONVMAP3.EXE is a conversion utility that will make your
        !          1035:                                                boards have the same orientation as in the older BUILD
        !          1036:                                                editors.  If you don't care if the whole map gets rotated
        !          1037:                                                in the 2D editor, then press N.
        !          1038: ������������������������������������������������������������������������������
        !          1039: 4/7/94   - Changed the way Orientation works ('O' in 3D EDIT MODE)
        !          1040: 
        !          1041:                                  Now, when you draw a normal door in BUILD, you do NOT have to
        !          1042:                                  press 'O' everywhere to make the walls of the door move right.
        !          1043:                                  Now, the default is that everything moves right.  Here's a
        !          1044:                                  detailed description of how the new orientation works:
        !          1045: 
        !          1046:                                  For white lines (no neighboring sector):
        !          1047: 
        !          1048:                                          orientation = 0 (default) means picture is aligned with
        !          1049:                                                                         sector[].ceilingz.
        !          1050:                                          orientation = 1 means picture aligned with sector[].floorz.
        !          1051: 
        !          1052:                                  For red lines (has a neighboring sector):
        !          1053: 
        !          1054:                                                orientation = 0 (default) means picture is aligned with
        !          1055:                                                                        either the ceilingz or floorz of the next sector.
        !          1056:                                                orientation = 1 means picture aligned with
        !          1057:                                                                        sector[].ceilingz.
        !          1058: 
        !          1059:                                  Don't worry if you don't understand the detailed description.
        !          1060:                                  Just know that it's better this way.  I have included the
        !          1061:                                  proper conversions in CONVMAP3.EXE.
        !          1062:                        - Added wall&ceiling x-panning keys to the 3D EDIT MODE.  Press
        !          1063:                                  the , or . keys to pan a wall or ceiling left or right.  You
        !          1064:                                  can hold down the 5 key on the keypad to align at every eighth
        !          1065:                                  panning value.  (Just like with 2,4,6,8).
        !          1066:                        - Made TAB&ENTER in 3D EDIT MODE also copy the CSTAT byte of
        !          1067:                                  the wall's attributes.  This means that attributes such as
        !          1068:                                  the block attribute, 1-way wall attribute, orientation,
        !          1069:                                  and x-flipping attribute are also copied & pasted.
        !          1070:                        - Added a new function, cansee.
        !          1071: 
        !          1072:                                  cansee(long x1, long y1, long z1, short sectnum1,
        !          1073:                                                        long x2, long y2, long z2, short sectnum2)
        !          1074: 
        !          1075:                                  All you do is pass it the coordinates of a 3D line
        !          1076:                                                and the respective sectors of each point of the line.
        !          1077:                                                The function will return a 1 if the points can see each
        !          1078:                                                other or a 0 if there is something blocking the two points
        !          1079:                                                from seeing each other.  This is how I determine whether
        !          1080:                                                a monster can see you or not. Try playing DOOM1.DAT with
        !          1081:                                                digitized sound enabled to fully enjoy this great new
        !          1082:                                                function!
        !          1083: ������������������������������������������������������������������������������
        !          1084: 4/12/94   - Fixed HITSCAN function.  Since it works a little differently
        !          1085:                                        and the parameters are different, let me describe how the
        !          1086:                                        new hitscan works:
        !          1087: 
        !          1088:                         hitscan(long xstart, long ystart, long zstart, short startsectnum,
        !          1089:                                                long vectorx, long vectory, long vectorz,
        !          1090:                                                short *hitsect, short *hitwall, short *hitsprite,
        !          1091:                                                long *hitx, long *hity, long *hitz);
        !          1092: 
        !          1093:                                        Pass the starting 3D position:
        !          1094:                                                 (xstart, ystart, zstart, startsectnum)
        !          1095:                                        Then pass the 3D angle to shoot (defined as a 3D vector):
        !          1096:                                                 (vectorx, vectory, vectorz)
        !          1097:                                        Then set up the return values for the object hit:
        !          1098:                                                 (hitsect, hitwall, hitsprite)
        !          1099:                                        and the exact 3D point where the ray hits:
        !          1100:                                                 (hitx, hity, hitz)
        !          1101: 
        !          1102:                                        How to determine what was hit:
        !          1103:                                        * Hitsect is always equal to the sector that was hit
        !          1104:                                                 (always >= 0).
        !          1105: 
        !          1106:                                        * If the ray hits a sprite then:
        !          1107:                                                 hitsect = thesectornumber
        !          1108:                                                 hitsprite = thespritenumber
        !          1109:                                                 hitwall = -1
        !          1110: 
        !          1111:                                        * If the ray hits a wall then:
        !          1112:                                                 hitsect = thesectornumber
        !          1113:                                                 hitsprite = -1
        !          1114:                                                 hitwall = thewallnumber
        !          1115: 
        !          1116:                                        * If the ray hits the ceiling of a sector then:
        !          1117:                                                 hitsect = thesectornumber
        !          1118:                                                 hitsprite = -1
        !          1119:                                                 hitwall = -1
        !          1120:                                                 vectorz < 0
        !          1121:                                        (If vectorz < 0 then you're shooting upward which means
        !          1122:                                                 that you couldn't have hit a floor)
        !          1123: 
        !          1124:                                        * If the ray hits the floor of a sector then:
        !          1125:                                                 hitsect = thesectornumber
        !          1126:                                                 hitsprite = -1
        !          1127:                                                 hitwall = -1
        !          1128:                                                 vectorz > 0
        !          1129:                                        (If vectorz > 0 then you're shooting downard which means
        !          1130:                                                 that you couldn't have hit a ceiling)
        !          1131: 
        !          1132:                         - Added a position window to the bottom of the menu in 2D EDIT
        !          1133:                                  MODE.  It shows the posx, posy, and ang variables.
        !          1134: ������������������������������������������������������������������������������
        !          1135: 4/14/94   - Overwritesprite now clips to the startumost / startdmost arrays.
        !          1136:                                Now the only way to write to the status bar is with
        !          1137:                                the permanentwritesprite function.
        !          1138: 
        !          1139:                         - ATTENTION PROGRAMMERS! I Split draw3dscreen() into 2 separate
        !          1140:                                function calls.
        !          1141: 
        !          1142:                                old:  draw3dscreen();    //Draws walls, ceilings, floors, p-skies
        !          1143:                                                                                                 // groudraws, sprites, and masked walls.
        !          1144: 
        !          1145:                                new:  drawrooms();       //Draws walls, ceilings, floors, p-skies
        !          1146:                                                                                                 // and groudraws.
        !          1147:                                                drawmasks();       //Draws sprites and masked walls.
        !          1148: 
        !          1149:                                The reason I split draw3dscreen was so you could manipulate only
        !          1150:                                the sprites that the engine is going to draw to the screen
        !          1151:                                before the sprites are actually drawn.
        !          1152: 
        !          1153:                         - I think I may have fixed that darn sector line bug!  Before, the
        !          1154:                                bug usually appeared when you were on a (red) sector line where
        !          1155:                                the ceiling and floor of the sector were very far from each
        !          1156:                                other.  This overflowed some really high positive values into
        !          1157:                                the negative range and vice versa.
        !          1158: ������������������������������������������������������������������������������
        !          1159: 4/18/94   - Wall clipping now works much better! (You can still VERY RARELY
        !          1160:                                                                                                                         sneak through walls, however)
        !          1161:                                ATTENTION PROGRAMMERS:
        !          1162:                                        MOVESPRITE and CLIPMOVE have been changed.  They now look
        !          1163:                                like this:
        !          1164: 
        !          1165:                                        clipmove (long *x, long *y, long *z, short *sectnum,
        !          1166:                                                                 long xvect, long yvect, long walldist,
        !          1167:                                                                 char cliptype);
        !          1168: 
        !          1169:                                        movesprite(short spritenum,
        !          1170:                                                                  long xchange, long ychange, long zchange,
        !          1171:                                                                  long walldist, char cliptype);
        !          1172: 
        !          1173:                                To use the new clipmove:
        !          1174:                                        Pass the pointers of the starting position (x, y, z).  Then
        !          1175:                                pass the starting position's sector number as a pointer also.
        !          1176:                                Also these values will be modified accordingly.  Pass the
        !          1177:                                direction and velocity by using a vector (xvect, yvect).
        !          1178:                                If you don't fully understand these equations, please call me.
        !          1179:                                        xvect = velocity * cos(angle)
        !          1180:                                        yvect = velocity * sin(angle)
        !          1181:                                Walldist tells how close the object can get to a wall.  I use
        !          1182:                                128L as my default.  If you increase walldist all of a sudden
        !          1183:                                for a certain object, the object might leak through a wall, so
        !          1184:                                don't do that!
        !          1185: 
        !          1186:                                To use the new movesprite:
        !          1187:                                        Works like before, but you also pass walldist (How close the
        !          1188:                                sprite can get to a wall)
        !          1189: 
        !          1190:                         - New function for sprites:
        !          1191:                                 setsprite(short spritenum, long newx, long newy, long newz);
        !          1192: 
        !          1193:                                 This function simply sets the sprite's position to a specified
        !          1194:                                 coordinate (newx, newy, newz) without any checking to see
        !          1195:                                 whether the position is valid or not.  You could directly
        !          1196:                                 modify the sprite[].x, sprite[].y, and sprite[].z values, but
        !          1197:                                 if you use my function, the sprite is guaranteed to be in the
        !          1198:                                 right sector.
        !          1199: 
        !          1200:                         - You can now change the angle in 2D EDIT MODE with the
        !          1201:                                  < and > keys.  Move the mouse cursor to a sprite first.
        !          1202:                                  Hold down shift with the < and > to get more precise angles.
        !          1203:                         - You can now press 'B' on sprites in 3D EDIT MODE.  This in effect
        !          1204:                                  is xoring bit 0 of sprite[].cstat, which will not only be
        !          1205:                                  sensitive to hitscan, but will also block you from walking
        !          1206:                                  through the sprite.  Sprites with the 'B' attribute will
        !          1207:                                  appear pink in 2D EDIT MODE.
        !          1208:                         - You can now edit the Hi 16 bits of the tag in 2D EDIT MODE.
        !          1209:                                  Just like T and ALT-T, you press H and ALT-H to edit the high
        !          1210:                                  16-bits.  When a structure's attributes are displayed, the tag
        !          1211:                                  will be displayed as 2 unsigned shorts.  The first number
        !          1212:                                  represents the hi 16 bits and the second number represents the
        !          1213:                                  lo 16 bits.
        !          1214: ������������������������������������������������������������������������������
        !          1215: 4/23/94   - Added 'G' in Editart to GOTO a tile by typing in the tile number.
        !          1216:                         - Changed the way masking walls work a little bit.  Now the
        !          1217:                                  masking walls use the picture wall[].overpicnum rather than
        !          1218:                                  wall[].picnum.
        !          1219:                         - Made hitscan hit maskable walls.
        !          1220: ������������������������������������������������������������������������������
        !          1221: 4/24/94   - Made palette.dat support any number of shades up to 64.  There
        !          1222:                                        is no change to the palette.dat format.  The palette.dat
        !          1223:                                        format is:
        !          1224: 
        !          1225:                                                First the palette (768 bytes)  Values range from 0-63
        !          1226:                                                Then the lookup shades (256 * number_of_shades)  The
        !          1227:                                                        shades are stored in groups of 256 bytes.
        !          1228: 
        !          1229:                         - If you use Mark Dochtermann's palette program, then you can
        !          1230:                                        convert his data files (such as palette.pal and colormap.lmp)
        !          1231:                                        to my palette format, palette.dat, with my great Qbasic
        !          1232:                                        program, PALMP.BAS.  To run it, first copy the basic program
        !          1233:                                        into the same directory as the 2 source palette files are in.
        !          1234:                                        Then type: "QBASIC PALMP" and then press SHIFT+F5 (to run it).
        !          1235: 
        !          1236:                         - Added a global variable, HORIZ.  Horiz usually equals 100.
        !          1237:                                        Modifying horiz will move the whole screen up / down.  I
        !          1238:                                        added 2 keys, +/- in my own game.c to demonstrate this.  You
        !          1239:                                        can use this variable for looking up and down if you want.
        !          1240:                                        (Even though this is not "truly" looking up and down, if
        !          1241:                                        you're lucky, you might be able to fake out some people!)
        !          1242: 
        !          1243:                         - New Key in 3D EDIT MODE, the forward slash. Use / with the
        !          1244:                                        tile panning keys (, and .) to flip the horizontal / vertical
        !          1245:                                        orientation bits for walls, ceilings or floors.
        !          1246: ������������������������������������������������������������������������������
        !          1247: 4/28/94   - NEW BOARD VERSION!  You must run CONVMAP4.EXE on all your boards.
        !          1248:                                        Here's what I changed in the structures:
        !          1249: 
        !          1250:                                        Sectors:
        !          1251:                                                I got rid of:
        !          1252:                                                        char sector[].ceilingpanning, sector[].floorpanning;
        !          1253:                                                        sector[].ceilingstat/floorstat bit 2 zeroed out
        !          1254:                                                and added:
        !          1255:                                                        char sector[].ceilingxpanning, sector[].ceilingypanning;
        !          1256:                                                        char sector[].floorgxpanning, sector[].floorypanning;
        !          1257: 
        !          1258:                                        Walls:
        !          1259: 
        !          1260:                                                I got rid of:
        !          1261:                                                        char wall[].panning;
        !          1262:                                                        wall[].cstat bit 6 zeroed out
        !          1263:                                                and added:
        !          1264:                                                        char wall[].xpanning;
        !          1265:                                                        char wall[].ypanning;
        !          1266: 
        !          1267:                                        Sprites:
        !          1268: 
        !          1269:                                                I got rid of:
        !          1270:                                                        short sprite[].vel;
        !          1271:                                                and added:
        !          1272:                                                        short sprite[].xvel;
        !          1273:                                                        short sprite[].yvel;
        !          1274:                                                The reason I did this was so sprites could be moved in
        !          1275:                                                different directions than sprite[].ang.  Please make
        !          1276:                                                use of both xvel and yvel.  Here's the equation I would
        !          1277:                                                use to convert from the old to new.  For example:
        !          1278: 
        !          1279:                                                old:
        !          1280:                                                        sprite[i].vel = 256;
        !          1281:                                                new:
        !          1282:                                                        sprite[i].xvel = (sintable[(sprite[i].ang+512)&2047]>>6);
        !          1283:                                                        sprite[i].yvel = (sintable[sprite[i].ang&2047]>>6);
        !          1284: 
        !          1285:                                                The reason I am shifting the sines right by 6 is becuase
        !          1286:                                                        my sintable ranges from -16384 to 16384.  Dividing by
        !          1287:                                                        64 gives a maximum range of -256 to 256.
        !          1288: 
        !          1289:                                        CONVMAP4.EXE also attempts to convert the masked walls so
        !          1290:                                                overpicnum is the masked wall's picnum.
        !          1291: 
        !          1292:                         - Changed 3D EDIT MODE panning keys:
        !          1293:                                          Since panning is now all 4 directions, I got rid of the
        !          1294:                                  , and . keys and put the keys on the keypad using 2,4,6,8.
        !          1295:                                  Usually 2,4,6,8 are for x- and y-repeats, but if you hold
        !          1296:                                  down either shift key, then they act as x- and y- panning
        !          1297:                                  values.
        !          1298:                                          The / key now resets the panning values to 0.
        !          1299: 
        !          1300:                         - Please read the updated descriptions of how to make masking walls
        !          1301:                                        in the 3D EDIT MODE KEYS in the top of build.txt.  See
        !          1302:                                        the 'M' and 'Shift + M' keys.
        !          1303: 
        !          1304:                         - Also look at the top of this file for a description of dragpoint(), a
        !          1305:                                        great new function that makes it easy to morph sectors.
        !          1306: ������������������������������������������������������������������������������
        !          1307: 4/29/94   - Added some minor keys to 3D EDIT MODE.  Alt. +/- change the
        !          1308:                                        visibility variable.  It ranges from 5 (darkest) to 17
        !          1309:                                        (lightest) and it starts at 13.
        !          1310: 
        !          1311:                         - Made 1-way walls have more options.  Now, for example, you can
        !          1312:                                        make rectangular switches on walls.  Please look at my
        !          1313:                                        nukeland.map for an example of how to do switches.  (The
        !          1314:                                        switches are close to start - just go through the door and
        !          1315:                                        bear left.)
        !          1316: 
        !          1317:                        - For those who asked, here's how some sample bobbing code:
        !          1318:                                First, calculate the distance actually moved - because if you
        !          1319:                                        are not moving then you shouldn't bob:
        !          1320: 
        !          1321:                                                CODE:
        !          1322:                                        oposx = posx; oposy = posy;
        !          1323:                                        clipmove(&posx,&posy,&posz,&cursectnum,xvect,yvect,128L);
        !          1324:                                        dist = ksqrt((posx-oposx)*(posx-oposx)+(posy-oposy)*(posy-oposy));
        !          1325: 
        !          1326:                                Then modify the horizon value by multiplying the distance
        !          1327:                                        actually moved by a sine wave.  (default is horiz = 100).
        !          1328: 
        !          1329:                                                CODE:
        !          1330:                                        horiz = 100 + ((dist*sintable[(totalclock<<5)&2047])>>19);
        !          1331: 
        !          1332:                        - Remember that moving block in the slime in NUKELAND.MAP?  It
        !          1333:                                  works a lot better now.  I am now modifying the floor panning
        !          1334:                                  values to make the floor match up correctly with the block.
        !          1335: 
        !          1336:                        - Fixed the screen capturing (F12) to save captures as PCX files.
        !          1337:                                  This is for BUILD, GAME, and EDITART.
        !          1338: 
        !          1339:                        - Fixed bug in EDITART when you press 'U' on a blank tile.  It
        !          1340:                                  should not crash any more.
        !          1341: 
        !          1342:                        - Made Tab & Enter a little smarter in copying the right attributes
        !          1343:                                  to different types of objects.
        !          1344: 
        !          1345:                        - Added ceiling / floor 90� rotation attributes.  All 8
        !          1346:                                  rotations are possible. 3 bits have been added to both
        !          1347:                                  the sector[].ceilingstat and sector[].floorstat flags.
        !          1348:                                  If you look in BUILD.H, you will see the new flags
        !          1349:                                  descriptions.  You can use the 'F' key in 3D EDIT MODE on
        !          1350:                                  a ceiling or floor to change the rotation.
        !          1351: 
        !          1352: ������������������������������������������������������������������������������
        !          1353: 4/30/94  - ATTENTION PROGRAMMERS:
        !          1354:                                  I removed the function, getsector, and added a more expandable
        !          1355:                                  function, updatesector.  Also, updatesector is smart enough
        !          1356:                                  to check to see if you are in the same sector OR neighboring
        !          1357:                                  sectors first before going through every single sector.
        !          1358:                                  Getsector used to go though all the sectors every time you
        !          1359:                                  crossed a sector line.
        !          1360: 
        !          1361:                                  getsector();   (no arguments, returns nothing - REMOVED)
        !          1362:                                  * used to make sure that CURSECTNUM matched up with
        !          1363:                                         the right sector according to the POSX and POSY values.
        !          1364:                                         updatesector(posx,posy,&cursectnum);
        !          1365:                                  * the new way of writing getsector.  You can do a
        !          1366:                                         search&replace on your code.  Be careful when you use this
        !          1367:                                         function with sprites because remember that the sprite's
        !          1368:                                         sector number should not be modified directly.  For example,
        !          1369:                                         you might want to code it this way:
        !          1370: 
        !          1371:                                                  tempsectnum = sprite[i].sectnum;
        !          1372:                                                  updatesector(sprite[i].x,sprite[i].y,&tempsectnum);
        !          1373:                                                  if (tempsectnum != sprite[i].sectnum)
        !          1374:                                                          changespritesect(i,tempsectnum);
        !          1375: 
        !          1376:                                         Actually, I think the setsprite function is better for
        !          1377:                                         updating a sprite's sector number.
        !          1378: 
        !          1379:                        - Added swinging doors!  Look at NUKELAND.MAP in my GAME.EXE for
        !          1380:                                  an example.  For swinging doors, I used a new math-helper
        !          1381:                                  function, rotatepoint.
        !          1382: 
        !          1383:                                  rotatepoint(long xpivot, long ypivot,
        !          1384:                                                                  long x, long y,
        !          1385:                                                                  short deltaang,
        !          1386:                                                                  long *x2, long *y2);
        !          1387: 
        !          1388:                                  Rotatepoint will rotate point(x,y) around point(xpivot,ypivot)
        !          1389:                                  by the deltang value.  The resultant point will be s
        !          1390: 
        !          1391:                        - Fixed crashing bug in BUILD when a wall's tile doesn't exist.
        !          1392: ������������������������������������������������������������������������������
        !          1393: 5/02/94  - I improved the pre-level check on the swinging doors, so now
        !          1394:                                 you can have multiple doors in a sector that open any way.
        !          1395:                                 This is how I do my double swinging doors (demonstrated in
        !          1396:                                 NUKELAND.MAP)
        !          1397: 
        !          1398:                        - I added a revolving door!  See NUKELAND.MAP for an example.  (The
        !          1399:                                 revolving door is beyond the bouncing platforms in the slime
        !          1400:                                 pit)
        !          1401: 
        !          1402:                        - Fixed bug with joining sectors in 2D EDIT MODE.  The sprites
        !          1403:                                 don't get deleted any more.
        !          1404: ������������������������������������������������������������������������������
        !          1405: 5/04/94  - Optimized the masked walls.
        !          1406: 
        !          1407:                        - Cleaned up the sprite drawing code (and many bugs that that came
        !          1408:                                 along with it.)
        !          1409: ������������������������������������������������������������������������������
        !          1410: 5/05/94  - Made cylindrical walls with any number of points VERY easy to
        !          1411:                                  make in BUILD.  Here's how you do it:  Highlight a wall and
        !          1412:                                  press 'C' on it.  Then move the mouse to the proper position
        !          1413:                                  to make a nice circle.  You can press '+' or '-' to change
        !          1414:                                  the number of points on the circle.  Press 'C' again to cancel
        !          1415:                                  or press space bar to actually change the map.
        !          1416: ������������������������������������������������������������������������������
        !          1417: 5/07/94  - Made a fully-operational subway!  Look at subway.map.
        !          1418: 
        !          1419:                        - Made a new type of door - a sliding door where the door doesn't
        !          1420:                                  get "x-smooshed" when it is opened.  (See description of
        !          1421:                                  sector tag 16 & wall tag 6)
        !          1422: 
        !          1423:                        - Also note that I my first subroutine in game.c!  It is:
        !          1424:                                          operatesector(short dasector)
        !          1425:                                  All the door code is now in this function (with a few
        !          1426:                                  exceptions, such as parts of the swinging doors and revolving
        !          1427:                                  door)
        !          1428: ������������������������������������������������������������������������������
        !          1429: 5/08/94  - Made EDITART and BUILD support different tile sizes in 'V' mode.
        !          1430:                                  Here are the three possible sizes:
        !          1431:                                          0. 64*64 - 5*3 grid - views 15 tiles (old default)
        !          1432:                                          1. 32*32 - 10*6 grid - views 60 tiles (new default)
        !          1433:                                          2. 16*16 - 20*12 grid - views 240 tiles
        !          1434:                                  Press the '*' and '/' keys in 'V' mode if you want to change
        !          1435:                                          the grid resolution.
        !          1436: 
        !          1437:                        - Added/fixed up a new key in 3D EDIT MODE, the dot key (. or >)
        !          1438:                                 This key attempts to match up all the tiles along a wall.  It
        !          1439:                                 scans along the walls towards the right as long as the picture
        !          1440:                                 number of the next wall is the same as the original picture
        !          1441:                                 number.  Note that some walls may not work right, especially
        !          1442:                                 floor / ceiling steps.
        !          1443: 
        !          1444:                        - Made 2D EDIT MODE default to this when inserting sprites:
        !          1445:                                 1.  Sprite clipping = on for sprites taller than 32 pixels
        !          1446:                                 2.  Sprite clipping = off for sprites shorter than 32 pixels.
        !          1447: 
        !          1448:                        - Fixed sprite clipping with Z-coordinates
        !          1449: ������������������������������������������������������������������������������
        !          1450: 5/10/94  - Fixed some sprite dragging bugs
        !          1451: 
        !          1452:                        - Made neartag? maximum sensing distance a global variable called
        !          1453:                                  neartagdist.  See build.h.
        !          1454: ������������������������������������������������������������������������������
        !          1455: 5/11/94  - Added sector / groups of sectors selection.  When selecting
        !          1456:                                  sectors, hold down the right ALT key.  It works just like
        !          1457:                                  right shift.  You must completely surround any sector you
        !          1458:                                  wish to select.  Once selected, you can drag the mess of
        !          1459:                                  sectors with the mouse.  This is great for separating sectors
        !          1460:                                  from each other.
        !          1461: 
        !          1462:                        - Added sector duplication.  First select a bunch of sectors.  Then
        !          1463:                                  press the insert key. (with the select sectors flashing)  Then
        !          1464:                                  This duplication is like stamping.  So, you must drag
        !          1465:                                  the sector bunch somewhere else after stamping to see your
        !          1466:                                  great accomplishments.
        !          1467: ������������������������������������������������������������������������������
        !          1468: 5/12/94  - Added group-sector PGUP / PGDN.  Here's a neat trick that will
        !          1469:                                  let you move a whole section of a board up / down quickly.
        !          1470:                                  First you select a bunch of sectors with the right ALT key in
        !          1471:                                  2D mode.  Then flip to 3D mode and if you press PGUP / PGDN
        !          1472:                                  on any of the highlighted sectors, the rest of the highlighted
        !          1473:                                  sectors will move also.
        !          1474: 
        !          1475:                        - Added group-sector rotation.  Once you do a sector select (right
        !          1476:                                  ALT), you can press the , or . keys to rotate the selected
        !          1477:                                  sectors.  Hold down the shift key with the keys to get fine
        !          1478:                                  angle rotation (WARNING:  You will get distortion with fine
        !          1479:                                  angle rotation in this version)
        !          1480: 
        !          1481:                        - Added sector count and wall count information at the bottom of
        !          1482:                                  the 2D edit mode status bar.
        !          1483: 
        !          1484:                        - Fixed some stupid bug that you probably wouldn't have found if
        !          1485:                                  you made boards with BUILD for the rest of your life.
        !          1486: 
        !          1487:                        - You can now press 'B' to block / unblock a wall or sprite in
        !          1488:                                  2D edit mode.
        !          1489: 
        !          1490:                        - Made Ctrl-Shift Enter auto-shade a sector.  First make any
        !          1491:                                  wall of the loop as light as the lightest shade you want.
        !          1492:                                  Then make any other wall of the loop as dark as the darkest
        !          1493:                                  shade you want.  Finally press Ctrl-Shift Enter on the wall
        !          1494:                                  that should be lightest.  Now the loop should be smoothly
        !          1495:                                  shaded.  If it is not smoothly shaded, you may need to insert
        !          1496:                                  more points on the walls.
        !          1497: 
        !          1498:                        - Fixed my .PCX format bug.  My screen captures now load properly
        !          1499:                                 in Deluxe programs.
        !          1500: ������������������������������������������������������������������������������
        !          1501: 5/13/94  - Made my serial code in Game.c work better.  I fixed the bullet
        !          1502:                                 shooting and made all types of doors work.  Unfortunately, you
        !          1503:                                 still may have to run at slower COM speeds.
        !          1504: ������������������������������������������������������������������������������
        !          1505: 5/14/94  - Fixed deadly bug with sector copy & sprites.
        !          1506: 
        !          1507:                        - Added hitscan sensitivity bit.  It is bit 6 (64) of wall[].cstat.
        !          1508:                                 In 3D edit mode, you can press 'H' to toggle the bit.  (H used
        !          1509:                                 to be like 'V' for choosing height tile numbers for groudraws -
        !          1510:                                 I change the 'H' key to Alt-V since I don't think anybody was
        !          1511:                                 using it anyway)  By default, hitscan CAN go through maskable
        !          1512:                                 walls.  If a hitscan is set to not go through a maskable wall,
        !          1513:                                 The wall will appear BRIGHT pink in 2D edit mode.
        !          1514: ������������������������������������������������������������������������������
        !          1515: 5/15/94  - Made more subroutines in game.c and moved documentation from the
        !          1516:                                 end of game.c into this text file.   Added some more comments
        !          1517:                                 also.  Game.c is so much easier to read now!  The main loop is
        !          1518:                                 less than 50 lines long!
        !          1519: 
        !          1520:                        - Made some optimizations to my serial code now that everything
        !          1521:                                 is in functions.
        !          1522: 
        !          1523:                        - ATTENTION PROGRAMMERS:
        !          1524:                                 I added one new paramater (cliptype) to both the movesprite
        !          1525:                                         and clipmove functions.  If the new parameter is a 0, then
        !          1526:                                         the clipping is normal (Use 0 to clip you and monsters).
        !          1527:                                         If the new parameter is a 1, then the object is clipped to
        !          1528:                                         the same things that hitscan is clipped to (use 1 for all
        !          1529:                                         bullets).
        !          1530:                                 See the above documentation for a detailed description of the
        !          1531:                                         parameters.  (Remember that I moved the documentation from
        !          1532:                                         GAME.C into the middle BUILD.TXT)
        !          1533:                                 Finally, you can have sprites and bullets going where you
        !          1534:                                         want them to go!
        !          1535: ������������������������������������������������������������������������������
        !          1536: 5/18/94  - Added support for the Spaceplayer (6-degree of freedom Space ball)
        !          1537:                                  Try out the SETUP program now.
        !          1538: 
        !          1539:                        - Fixed some bugs with the 'E' key in 3D EDIT MODE.  As long as both
        !          1540:                                 dimensions of the tile are powers of 2, then the picture should
        !          1541:                                 be visible.  It should not be a solid color with a few weird
        !          1542:                                 lines any more.
        !          1543: 
        !          1544:                        - Fixed some bugs with the Z control in 3D EDIT MODE.  In normal
        !          1545:                                 operation,  BUILD attempts to keep your Z constant even if
        !          1546:                                 you cross sector lines.  Then I added a special new mode that
        !          1547:                                 locks your heightofffloor to a certain value.  You Z will
        !          1548:                                 change instantly if you cross sector lines.  To use this mode,
        !          1549:                                 press the Caps Lock key.  Press Caps Lock key again for normal
        !          1550:                                 operation.
        !          1551: 
        !          1552:                        - ATTENTION PROGRAMMERS!  I put all of engineinput into GAME.C
        !          1553:                                 This means you have absolutely total control of the Z's.  (The
        !          1554:                                 only thing left is some key code I still have in my timer
        !          1555:                                 handler)
        !          1556: 
        !          1557:                                 OK, now read carefully!  Here's how to convert to the new OBJ's:
        !          1558: 
        !          1559:                                 1. First of all, the Spaceball code is now also in game.c.
        !          1560:                                         A.  You will need to put this line in game.c:
        !          1561:                                                        include "spw_int.h"
        !          1562:                                         B.  And make sure to add spwint.obj your makefile.
        !          1563:                                 2. Heightoffceiling, heightofffloor, and gravity have been
        !          1564:                                         removed from BUILD.H.  If you still want to use them
        !          1565:                                         then you should defined them as globals in your own code.
        !          1566:                                 3. You should go through every single key of my gameinput()
        !          1567:                                         function in game.c and copy any code you want.
        !          1568: ������������������������������������������������������������������������������
        !          1569: 5/23/94  - GREAT NEW STUFF!
        !          1570: 
        !          1571:                                Be sure to check out GAME.EXE and try out these new keys!
        !          1572: 
        !          1573:                         Rt. Enter = Switch between 3D / 2D modes
        !          1574:                                Lt. +/- = Zoom in 2D mode
        !          1575: 
        !          1576:                                 Added 2D map display with auto-mapping!  The 2D maps use a
        !          1577:                                 higher resolution 16-color mode.  You have a choice of either
        !          1578:                                 using a 640*350*16 screen or a 640*480*16 screen with a 144-high
        !          1579:                                 status bar (remember that 640*480*16 cannot fit in 256K with 2
        !          1580:                                 screen pages so I have to cheat with a status bar).
        !          1581: 
        !          1582:                                         NEW FUNCTIONS:
        !          1583: 
        !          1584:                                 draw2dscreen(long posxe, long posye, short ange, long zoome,
        !          1585:                                                                  short gride)
        !          1586:                                         Draws the 2d screen - this function is a direct replacement
        !          1587:                                         for the drawrooms() and drawmasks() functions.  Be sure
        !          1588:                                         to call either qsetmode640350() or qsetmode640480()
        !          1589:                                         first.  When switching back to 3d mode, be sure to call
        !          1590:                                         qsetmode320200().
        !          1591: 
        !          1592:                                                 IMPORTANT NOTES:
        !          1593:                                                 1.  The overwritesprite function should only be called in
        !          1594:                                                          3D mode.  If you do this in 2D mode, junk will be
        !          1595:                                                          written to the 2D screen and a crash is possible.
        !          1596:                                                 2.  When you switch back to 3D mode, you should call the
        !          1597:                                                          permanentwritesprite functions to draw the status bar,
        !          1598:                                                          or whatever else you have to draw.
        !          1599:                                                 3.  You must call the nextpage() function in both 2D and
        !          1600:                                                          3D modes.
        !          1601: 
        !          1602:                                 qsetmode320200();
        !          1603:                                         Set to the game mode and load palette (320*200*256)
        !          1604:                                 qsetmode640350();
        !          1605:                                         Set to the 2D map mode #1 (640*350*16)
        !          1606:                                 qsetmode640480();
        !          1607:                                         Set to the 2D map mode #2 (640*480*16)
        !          1608: 
        !          1609:                                         NEW VARIABLES (see description in build.h):
        !          1610: 
        !          1611:                                 EXTERN char show2dwall[MAXWALLS>>3];
        !          1612:                                 EXTERN char show2dsprite[MAXSPRITES>>3];
        !          1613:                                 EXTERN char automapping;
        !          1614: 
        !          1615:                        - Added parallaxing floors!  Works like the parallaxing skies, but
        !          1616:                                  the other side.  In 3D EDIT MODE, press P on ceiling for
        !          1617:                                  parallaxing sky, or press P on floor for parallaxing floor.
        !          1618: 
        !          1619: ������������������������������������������������������������������������������
        !          1620: 5/24/94  - There is a new function that I forgot to document in the last
        !          1621:                                  version.  Oops!
        !          1622: 
        !          1623:                                         doanimations() is this function.
        !          1624:                                 It's not really new, but I split it off of the
        !          1625:                          drawrooms/drawmasks functions.  This function animates anything
        !          1626:                          that you use setanimation with.  Please stick it in your code
        !          1627:                          somewhere after you draw the screen.
        !          1628: ������������������������������������������������������������������������������
        !          1629: 5/26/94  - You can now do TRANSLUSCENT sprites!  I am using bit 1 of
        !          1630:                                  sprite[].cstat to detemine whether or not the sprite is
        !          1631:                                  transluscent or not.  In 3D EDIT MODE, you can press 'T' to
        !          1632:                                  toggle the transluscence bit.
        !          1633:                                          IMPORTANT:  Transluscence WILL NOT WORK until you run my
        !          1634:                                  TRANSPAL.EXE program.  On the command line, simply type:
        !          1635:                                          C:\BUILD>transpal [filename]
        !          1636:                                  If you do not specify a filename, the default will be
        !          1637:                                  palette.dat.  If your palette.dat file is now around 40K long,
        !          1638:                                  then you are ready for transluscence!
        !          1639: 
        !          1640:                        - Added TRANSLUSCENCE to masked walls.  See bit 7 of wall[].cstat.
        !          1641:                                  Press 'T' on wall to toggle the transluscence bit.
        !          1642: 
        !          1643:                        - In this BUILD update, I have collected many different palettes
        !          1644:                                 for comparison purposes.  Try running TRANSPAL.EXE on each of
        !          1645:                                 them and see for yourself which palettes work the best with
        !          1646:                                 transluscence!
        !          1647: 
        !          1648: ������������������������������������������������������������������������������
        !          1649: 5/29/94  - ATTENTION PROGRAMMERS:  I completely rewrote the neartag code.
        !          1650:                                 Here's what you have to do to convert your game.c files:
        !          1651: 
        !          1652:                                         1.  You should move the neartag variables that I used to
        !          1653:                                                  have in BUILD.H into your C code.
        !          1654:                                         2.  You must call the neartag function yourself if you want
        !          1655:                                                  to see if you're near a tagged object.  Neartag is NOT
        !          1656:                                                  automatically updated by the engine any more.
        !          1657:                                         3.  I highly recommend that you put your neartag function
        !          1658:                                                  call at the first line in your space bar code.  This way,
        !          1659:                                                  you can optimize the neartag calculations by only doing
        !          1660:                                                  them when you press the space bar.  (Exception:  For
        !          1661:                                                  ladders, I think you'll have to call neartag every single
        !          1662:                                                  frame)
        !          1663: 
        !          1664:                                          Here's a description of the new neartag function:
        !          1665:                                          Neartag works sort of like hitscan, but is optimized to
        !          1666:                                          scan only close objects and scan only objects with
        !          1667:                                          tags != 0.
        !          1668: 
        !          1669:                                 neartag(long x, long y, long z, short sectnum, short ang,  //Starting position & angle
        !          1670:                                                  short *neartagsector,   //Returns near sector if sector[].tag != 0
        !          1671:                                                  short *neartagwall,     //Returns near wall if wall[].tag != 0
        !          1672:                                                  short *neartagsprite,   //Returns near sprite if sprite[].tag != 0
        !          1673:                                                  long *neartaghitdist,   //Returns actual distance to object (scale: 1024=largest grid size)
        !          1674:                                                  long neartagrange)      //Choose maximum distance to scan (scale: 1024=largest grid size)
        !          1675: 
        !          1676: ������������������������������������������������������������������������������
        !          1677: 5/31/94  - Added a function to get a sprite's screen coordinates.  I put
        !          1678:                                  some sample code in my GAME in the analyzesprites function.
        !          1679:                                  Simply hold down the CAPS LOCK key in my GAME.EXE, and the
        !          1680:                                  screen will be centered around the sprite closest to the
        !          1681:                                  center of the screen.
        !          1682: 
        !          1683:                          Here's a new function in the engine I used to do this:
        !          1684: 
        !          1685:                         getspritescreencoord(short spritesortnum, long *scrx, long *scry)
        !          1686: 
        !          1687:                                  Note that spritesortnum is the index into the spritesortcnt
        !          1688:                         arrays, NOT the normal sprite arrays.  Scrx and scry are actual
        !          1689:                         screen coordinates ranging from 0-319 and 0-199 respectively.
        !          1690: ������������������������������������������������������������������������������
        !          1691: 6/6/94   - Made EDITART support sprite centering and animation speed.
        !          1692: 
        !          1693:                                  Now when you press 'A' in EDITART, the animation speed is
        !          1694:                                          actually saved to disk and runs the same speed in BUILD
        !          1695:                                          and your GAME.  Press + and - to change the animation speed.
        !          1696:                                          There are 16 different animation speeds.
        !          1697:                                                  (Speed is proportional to (totalclock>>animspeed))
        !          1698: 
        !          1699:                                  To center a sprite, press the weird ~` key (located just above
        !          1700:                                          the TAB key).  You will see some cross hairs.  Simply use
        !          1701:                                          the arrow keys to the desired position.
        !          1702: 
        !          1703:                                  For both the 'A' and ~` keys, you can press Enter to accept
        !          1704:                                          the new values or ESC to cancel.
        !          1705: 
        !          1706:                        - Added a variable to BUILD.H, lockclock.  Lockclock is to
        !          1707:                                  totalclock as lockspeed is to clockspeed.
        !          1708: ������������������������������������������������������������������������������
        !          1709: 6/7/94   - Made 3 different Z coordinate modes in BUILD.
        !          1710: 
        !          1711:                                Mode 0:  Game mode (default)
        !          1712:                                Mode 1:  Height lock mode
        !          1713:                                Mode 2:  Float mode
        !          1714: 
        !          1715:                          Press Caps Lock to switch between the 3 modes.
        !          1716:                          A and Z move up and down for all 3 modes.
        !          1717: ������������������������������������������������������������������������������
        !          1718: 6/10/94  - Added a new function that should solve all your sound problems.
        !          1719: 
        !          1720:                          kenchaintimer(void (__interrupt __far *datimerchainaddress)(),
        !          1721:                                          short dachainpersecond)
        !          1722: 
        !          1723:                          Please look at the IMPORTANT ENGINE FUNCTIONS section above for
        !          1724:                                  a full description.
        !          1725: ������������������������������������������������������������������������������
        !          1726: 6/20/94  - Got rid of the comsend / comgetchar functions.  Replaced them
        !          1727:                                  with sendpacket and getpacket.
        !          1728: 
        !          1729:                        - Added network support.
        !          1730: 
        !          1731:                        - Got rid of qsetmode320200(). Just replace it with setgamemode().
        !          1732:                                 The 2 are exactly the same.
        !          1733: 
        !          1734:                        - Got rid of clockspeed variables.  Just replace it with lockspeed.
        !          1735: 
        !          1736:                        - Adjusted my z directions of shooting depending on the horizon.
        !          1737:                                 You may want to readjust your code for this.
        !          1738: 
        !          1739:                        - You now pass the number of tics as a long to doanimations.
        !          1740:                                doanimations(long numtics);
        !          1741: 
        !          1742:                        - FIXED DEADLY BUG!  This may have been causing bigtime crash-city
        !          1743:                                bugs!  The problem was with show2dsprite and show2dwall.  In
        !          1744:                                my engine.c I forgot that they were BIT arrays, not BYTE arrays.
        !          1745:                                When I initialized the arrays to 0, I initialized 8 times the
        !          1746:                                length, possibly overwriting your precious data!  I initialize
        !          1747:                                these arrays in the initengine and loadboard functions.
        !          1748: 
        !          1749:                        - ATTENTION PROGRAMMERS:  In order to get rid of the posx, posy,
        !          1750:                                posz, ang, posz, and horiz variables from BUILD.H, I added some
        !          1751:                                parameters to a few functions.  YOU MUST REWRITE YOUR CODE
        !          1752:                                TO SUPPORT THESE:
        !          1753:                                        loadboard(char *filename, long *posx, long *posy, long *posz,
        !          1754:                                                                 short *ang, short *cursectnum)
        !          1755:                                        saveboard(char *filename, long *posx, long *posy, long *posz,
        !          1756:                                                                 short *ang, short *cursectnum)
        !          1757:                                        drawrooms(long posx, long posy, long posz,
        !          1758:                                                                 short ang, long horiz, short *cursectnum)
        !          1759: 
        !          1760:                          THESE VARIABLES SHOULD BE MOVED INTO GAME.C:
        !          1761:                                  long posx, posy, posz, horiz;
        !          1762:                                  short ang, cursectnum;
        !          1763:                                  long hvel;
        !          1764: ������������������������������������������������������������������������������
        !          1765: 6/22/94  - ATTENTION PROGRAMMERS:  Added 1 parameter to movesprite, the
        !          1766:                                  number of tics (such as lockspeed).
        !          1767: 
        !          1768:                          movesprite(short spritenum, long xchange, long ychange,
        !          1769:                                                         long zchange, long walldist,
        !          1770:                                                         char cliptype, long numtics)
        !          1771: 
        !          1772:                        - ATTENTION PROGRAMMERS:  At one time, I used to have 4 timing
        !          1773:                                  variable in the engine. (totalclock, clockspeed,
        !          1774:                                  lockclock, lockspeed).  I got rid of all of them except
        !          1775:                                  totalclock.  If you want to use the other 3 variables, you
        !          1776:                                  must simulate them yourself.  Here's how you do it:
        !          1777: 
        !          1778:                                  Step 1.  Define clockspeed, lockclock, and lockspeed as global
        !          1779:                                                          longs in your code.
        !          1780: 
        !          1781:                                  Step 2.  Be sure to zero out all 3 variables just before
        !          1782:                                                          starting to play each level.  (You could zero out
        !          1783:                                                          totalclock also.)
        !          1784: 
        !          1785:                                  Step 3.  Right after every time you call the nextpage()
        !          1786:                                                          function, insert this code line for line:
        !          1787: 
        !          1788:                                          lockspeed = totalclock-lockclock;
        !          1789:                                          lockclock += lockspeed;
        !          1790:                                          clockspeed = lockspeed;
        !          1791: 
        !          1792:                                  You really don't need clockspeed if you have lockspeed.
        !          1793:                                  You should replace all clockspeed's with lockspeed's.
        !          1794:                                  Before, I had both because both totalclock and clockspeed used
        !          1795:                                          to be incremented in the timer handler and could be changed
        !          1796:                                          at any time.
        !          1797: 
        !          1798:                        - I added my own optional random function, krand() which returns
        !          1799:                                  a pseudo-random number as a long from 0 to 65535.  Notice that
        !          1800:                          I put a randomseed variable in BUILD.H called randomseed.
        !          1801: 
        !          1802: ������������������������������������������������������������������������������
        !          1803: 6/24/94  - I just want to try to explain how all of my multiplayer code
        !          1804:                                  works.  Theory:  Think of the whole program as 2 functions:
        !          1805: 
        !          1806:                                          Function 1. Draw the screen (could be 2D / 3D)
        !          1807:                                          Function 2. Move things. (sprites, walls, sectors, and you!)
        !          1808: 
        !          1809:                                          My communications in GAME.C work on a MASTER/SLAVE
        !          1810:                                  system where it would be nice if the faster computer was the
        !          1811:                                  MASTER.  (Right now, the first computer in is the MASTER).
        !          1812:                                  The big trick to keeping everything in sync (and I do mean
        !          1813:                                  everything- even moving platforms, revolving doors, & subways)
        !          1814:                                  is to call function #2 with the exact same parameters as input
        !          1815:                                  on all computers the same number of times and in the same
        !          1816:                                  order.   Now this might seem like a lot of information but it
        !          1817:                                  really isn't!  Let me explain the role of the MASTER and SLAVE:
        !          1818: 
        !          1819:                                  The MASTER's job:
        !          1820:                                          1.  Read in own input changes
        !          1821:                                          2.  Read in any slave player input changes
        !          1822:                                                        (getpackets function - reads in foreign vel, svel,
        !          1823:                                                         angvel, & the bits)
        !          1824: 
        !          1825:                                          3.  Just before calling the movethings function, send the
        !          1826:                                                        input to the movethings function:
        !          1827:                                                  A.  Master's tic cnt (synctics)
        !          1828:                                                  B.  Every player's velocities (syncvel, svel, angvel)
        !          1829:                                                  C.  Every player's status bits (Space, Ctrl, Shift, etc.)
        !          1830:                                          4.  Call the movethings function
        !          1831:                                          5.  Draw screen
        !          1832: 
        !          1833:                                  The SLAVE's job:
        !          1834:                                          1.  Read in own input changes
        !          1835:                                          2.  Send own input changes to master.
        !          1836:                                          3.  Read in all master movethings input parameters and
        !          1837:                                                        call movethings function for each packet.  This may
        !          1838:                                                        mean calling the movethings function more than once
        !          1839:                                                        between calling the drawscreen functions. This is
        !          1840:                                                        waste, but it's the price you have to pay to keep
        !          1841:                                                        things in sync.
        !          1842:                                          4.  Draw screen
        !          1843: 
        !          1844: 
        !          1845:                                          You may ask how do monsters stay in sync even if you are
        !          1846:                                  not sending any monster information over the line.  The
        !          1847:                                  answer to this is simple.
        !          1848:                                          1.  You make sure that a random seed starts the same on
        !          1849:                                                        both computers.
        !          1850:                                          2.  Only call the rand() or krand() function in the
        !          1851:                                                        movethings function.
        !          1852: 
        !          1853:                                          Before you try my demo, I wanted to say that, I have
        !          1854:                                  ABSOLUTELY NO ERROR CORRECTION in my code at this point.  It
        !          1855:                                  is most certainly my next project.  For serial link, I would
        !          1856:                                  recommend a rate of about 14400 baud.  In the future, I think
        !          1857:                                  I can optimize the code enough to work at rates as low at 2400
        !          1858:                                  baud!  Let me explain how well certain setups should work
        !          1859:                                  without error correction:
        !          1860:                                          Ken's guesses on how badly it will crash WITH NO ERROR
        !          1861:                                  CORRECTION (Build the way it is now):
        !          1862: 
        !          1863:                                  1.  Serial link using 8250 chips - out of sync after 15
        !          1864:                                                        seconds because a few bytes were missed.
        !          1865:                                  2.  Serial link using 16550 chips - out of sync after 10
        !          1866:                                                        minutes because 16550 chips have a 16 byte FIFO and
        !          1867:                                                        therefore don't lose bytes as often as the 8250.
        !          1868:                                  3.  Modem - out of sync after less than 5 seconds.
        !          1869:                                  4.  Network - out of sync after 1 minute.  Networks love to
        !          1870:                                                        lose full packets here and there.
        !          1871: 
        !          1872:                                          I will be working on error correction for all of the above
        !          1873:                                  situations.  Any error correction techniques I use will be
        !          1874:                                  internal to the engine and completely transparent to you (so
        !          1875:                                  you can start coding now!)  If the demo actually works multi-
        !          1876:                                  player, then you may want to look at my GAME keys at the top
        !          1877:                                  of this file again.  There are some significant changes.
        !          1878: 
        !          1879:                                * I replaced the old COM functions section at the top of
        !          1880:                                        BUILD.TXT with a COMMUNICATIONS FUNCTIONS section.  Please
        !          1881:                                        look through it for descriptions of at least these 2
        !          1882:                                        functions:
        !          1883: 
        !          1884:                                  sendpacket(short otherconnectnum, char *bufptr, short bufleng)
        !          1885:                                  getpacket(short *otherconnectnum, char *bufptr)
        !          1886: 
        !          1887:                                * Another rule to keep in mind while testing: (as if there
        !          1888:                                        aren't enough already)  Always make sure you have the
        !          1889:                                        same EXE's and MAP'S or else the games will get out of sync.
        !          1890: 
        !          1891:                                * Connection numbers and Index numbers:
        !          1892:                                        For networks, each computer has a given connection number.
        !          1893:                                        Connection numbers range from 1 to 100.  Player number 1
        !          1894:                                        might have connection number 5 and player number 2 might have
        !          1895:                                        connection number 17.  Since a player's connection number
        !          1896:                                        can be anything between 1 and 100, I don't want you to
        !          1897:                                        allocate 100 of every variable such as posx[100].  My
        !          1898:                                        solution was to make index numbers.  So in this case:
        !          1899: 
        !          1900:                                                connectnum[0] = 5;  connectindex[5] = 0;
        !          1901:                                                connectnum[1] = 17; connectindex[17] = 1;
        !          1902: 
        !          1903:                                * Now I'll will describe some new variables at the top of GAME.C
        !          1904: 
        !          1905:                                        myconnectnum - connection number of your computer
        !          1906:                                        myconnectindex - index number of your computer
        !          1907:                                        masterconnectnum - connection number of the MASTER computer
        !          1908:                                        screenpeek - index number of which player's eyes you are
        !          1909:                                                                         looking through.
        !          1910:                                        numplayers - if numplayers >= 2 then multiplayer mode is
        !          1911:                                                                         enabled, else single player game.
        !          1912: 
        !          1913:                                        connecthead, connectpoint2[MAXPLAYERS] - These 2 variables
        !          1914:                                                form a linked list of all the index numbers.
        !          1915:                                                Here's some example code that traverses the list of
        !          1916:                                                players:
        !          1917: 
        !          1918:                                        p = connecthead;
        !          1919:                                        while (p != -1)
        !          1920:                                        {
        !          1921:                                                printf("Player index %d has connection number %d\n",p,connectnum[p]);
        !          1922:                                                p = connectpoint2[p];
        !          1923:                                        }
        !          1924: 
        !          1925:                                * These variables are used to record / playback a demo. (This
        !          1926:                                         is like POSCAPT.DAT, but with everything in sync!)  In my
        !          1927:                                         GAME, i single player mode, I have it so if you press the
        !          1928:                                         Left ENTER, then it will playback everything.  These are
        !          1929:                                         the only variables necessary to store a demo run:
        !          1930: 
        !          1931:                                                 static long reccnt;                //Number of frames
        !          1932:                                                 static short recsyncvel[16384];    //Vel for each frame
        !          1933:                                                 static short recsyncsvel[16384];   //Svel for each frame
        !          1934:                                                 static short recsyncangvel[16384]; //Angvel for each frame
        !          1935:                                                 static short recsyncbits[16384];   //Bits for each frame
        !          1936:                                                 static short recsynctics[16384];   //Tics for each frame
        !          1937: 
        !          1938:                                * These variables are used for communications syncing:
        !          1939: 
        !          1940:                                                 static short syncvel[MAXPLAYERS+1];    //Vel of each player
        !          1941:                                                 static short syncsvel[MAXPLAYERS+1];   //Svel of each player
        !          1942:                                                 static short syncangvel[MAXPLAYERS+1]; //Angvel of each player
        !          1943:                                                 static short syncbits[MAXPLAYERS+1];   //Bits for each player
        !          1944:                                                 static short synctics;                 //Number of tics of MASTER ONLY
        !          1945: 
        !          1946:                                * Unless I suddenly make BUILD a 6-degree of freedom engine
        !          1947:                                tomorrow, this should be the most difficult update in a long
        !          1948:                                time!  Good Luck in programming!  I'm sure I left a lot of
        !          1949:                                things out, so I'll be expecting plenty of phone calls!
        !          1950: ������������������������������������������������������������������������������
        !          1951: 6/27/94  - I scaled the vel, svel and angvel variabile down 1 bit so they
        !          1952:                          fit into a signed char.  (Before they ranged from -256 to 256)
        !          1953:                          Now they range from (-128 to 127).
        !          1954: ������������������������������������������������������������������������������
        !          1955: 6/28/94  - Optimized the size of my COM(modem)/network packets in game.c.
        !          1956:                          I made the tics into a char.  I also use some new buffers called
        !          1957:                          osyncvel, osyncsvel, osyncangvel, and osyncbits.  Now I send
        !          1958:                          extra byte with bit fields that tell whether I need to update
        !          1959:                          the syncvel, syncsvel, syncangvel, or syncbits variables.  If
        !          1960:                          the bit field of the extra byte is off then I don't send the
        !          1961:                          byte(s) it represents.  You can now play my GAME at 4800 baud.
        !          1962: 
        !          1963:                static signed char syncvel[MAXPLAYERS+1], osyncvel[MAXPLAYERS+1];
        !          1964:                static signed char syncsvel[MAXPLAYERS+1], osyncsvel[MAXPLAYERS+1];
        !          1965:                static signed char syncangvel[MAXPLAYERS+1], osyncangvel[MAXPLAYERS+1];
        !          1966:                static short syncbits[MAXPLAYERS+1], osyncbits[MAXPLAYERS+1];
        !          1967:                static unsigned char synctics;
        !          1968: 
        !          1969:                        - There was an crashing error with transluscence palette on low
        !          1970:                                  memory configurations.  When you exit the BUILD editor,
        !          1971:                                  you normally get some numbers like this.
        !          1972:                                          Memory status: 788979(788979) bytes
        !          1973:                                  If the first number (art memory cache size) was less than the
        !          1974:                                  second number (art file size), then the whole art file did
        !          1975:                                  not fit in memory.  The reason for the crashing was because
        !          1976:                                  loadpics() sucks all memory up to the size of the art file.
        !          1977:                                  The 64K transluscent palette is malloc'd when you call the
        !          1978:                                  setgamemode() function for the first time.  The was no memory
        !          1979:                                  left to allocate the palette.  I fixed this by making the
        !          1980:                                  transluscent palette take 64K of the art memory cache if
        !          1981:                                  it could not malloc the 64K.
        !          1982: 
        !          1983:                        - I programmed some error correction for the COM(modem).  Here is
        !          1984:                                 my new of Ken's guesses on how badly it will crash (assuming
        !          1985:                                 that it will always crash eventually.)  You will be seeing new
        !          1986:                                 and better correction methods in the future.
        !          1987: 
        !          1988:                                 ERROR CORRECTION METHOD #1:
        !          1989:                                  1.  Serial link using 8250 chips - out of sync after 5 minutes.
        !          1990:                                  2.  Serial link using 16550 chips - out of sync after 10 minutes.
        !          1991:                                  3.  Modem - out of sync after 3 minutes - try it!
        !          1992:                                  4.  Network - out of sync after 1 minute.  Networks love to
        !          1993:                                                        lose full packets here and there. (not changed)
        !          1994: ������������������������������������������������������������������������������
        !          1995: 6/29/94  - Added some code to my GAME.C that will let you type in messages
        !          1996:                                  and send them to all remote players.  Press Tab (or T for
        !          1997:                                  those people who play that other, very bad, game too much)
        !          1998:                                  to start typing in a message.  Press either Enter key to send
        !          1999:                                  the message to the other player.
        !          2000: ������������������������������������������������������������������������������
        !          2001: 6/30/94  - ATTENTION PROGRAMMERS:  I changed the values that clipmove and
        !          2002:                                  movesprite return!  Here's how they work now:
        !          2003:                                          If you did not hit anything, then they return 0.
        !          2004:                                          Movesprite only:  If the object hits a ceiling / floor
        !          2005:                                                  then movesprite returns 16384+(sectornum hit).
        !          2006:                                          If the first object you hit before sliding was a wall,
        !          2007:                                                  then they return the 32768+(wallnum hit).
        !          2008:                                          If the first object you hit before sliding was a sprite,
        !          2009:                                                  then they return the 49152+(spritenum hit).
        !          2010: 
        !          2011:                                  Be careful when adding these changes to your code since the
        !          2012:                                          return value are sort of reversed:
        !          2013: 
        !          2014:                          return values: � Hit nothing: � Hit something:
        !          2015:                          ���������������������������������������������������������
        !          2016:                          Old functions: �      1       �       0
        !          2017:                          ��������������������������������������������������������-
        !          2018:                                                                  �              �    16384+sectnum (Movesprite only)
        !          2019:                          New functions: �      0       � or 32768+wallnum
        !          2020:                                                                  �              � or 49152+spritenum
        !          2021: 
        !          2022: ������������������������������������������������������������������������������
        !          2023: 7/1/94   - Made getangle always return an angle from 0 to 2047.  Before I
        !          2024:                                  forgot to and it 2047 and sometimes the angle was negative.
        !          2025: 
        !          2026:                        - Made overwritesprite when using the centering option be sensitive
        !          2027:                                  to the Editart centering tool.  (The ~` key.)
        !          2028: 
        !          2029:                        - Made Ctrl+Rt.Shift highlight points on a loop rather than points
        !          2030:                                  inside a rectangle.
        !          2031: ������������������������������������������������������������������������������
        !          2032: 7/2/94   - Added some neat features to my GAME.C to make multi-player mode
        !          2033:                                  even more fun.  I added a portable bowling ball/bomb-thrower.
        !          2034:                                  kills instantly! (similar to rocket launcher)  I also added
        !          2035:                                  water fountains.  If you hold the space bar down on them,
        !          2036:                                  you slowly get more life.
        !          2037: 
        !          2038:                        - O.K.  I think I actually got the syncronization working perfectly
        !          2039:                                  for COM(modem) play.  I haven't had all day to test it out yet!
        !          2040:                                  (Still no error correction with networks)
        !          2041: 
        !          2042:                                  Here are some steps in playing over the modem:
        !          2043:                                          1.  Be sure that both people have the exact same version of
        !          2044:                                                                the EXEs, ART, and MAPs.
        !          2045:                                          2.  Then go into SETUP and set the COM port to the com port
        !          2046:                                                                of your modem.  Even though 9600 baud should work, I
        !          2047:                                                                would recommend going at 4800 baud because:
        !          2048:                                                                        A.  It works fine at 4800 baud so there is really
        !          2049:                                                                                 no need to go any faster.
        !          2050:                                                                        B.  Fewer errors over the modem so less time
        !          2051:                                                                                 spent re-sending packets.
        !          2052:                                          3.  Then type:   MODEM [mapname] (must be same mapname!)
        !          2053:                                                        This will bring you into my terminal program.  You can
        !          2054:                                                                set the modem initialization string in MODEM.BAT by
        !          2055:                                                                changing the first command line option of the TERM
        !          2056:                                                                line.  Please disable modem compression and
        !          2057:                                                                correction for least jerky play.  Then connect with
        !          2058:                                                                the other modem using various methods, such as one
        !          2059:                                                                person typing ATA and the other typing ATD or one
        !          2060:                                                                person typing ATS0=1 and the other typing
        !          2061:                                                                ATDT(phone #).
        !          2062:                                          4.  Wait through the beeps and buzzes until it says CONNECT
        !          2063:                                                                on the bottom window.
        !          2064:                                          5.  If you can now chat with each other then things are
        !          2065:                                                                going well.  When the first person presses ESC, both
        !          2066:                                                                computers will automatically quit to DOS and go right
        !          2067:                                                                into the GAME.
        !          2068:                                          6.  Play!
        !          2069: ������������������������������������������������������������������������������
        !          2070: 7/5/94   - Serial moder over COM(modem) should work perfectly now.
        !          2071: 
        !          2072:                        - Added scaredfallz to BUILD.H.  It is a global variable that
        !          2073:                                 tells monsters what height is too high to fall through.  You
        !          2074:                                 can set cliptype parameter to 2 for movesprite and clipmove.
        !          2075: ������������������������������������������������������������������������������
        !          2076: 7/6/94   - Fixed clipping bug that used to let you go through certain concave
        !          2077:                                 corners.
        !          2078: 
        !          2079:                        - Added new function which works well with clipmove.  Ever notice
        !          2080:                                 was when you're at the edge of a cliff and you go just a tiny
        !          2081:                                 bit over, you fall, but shouldn't yet?  Unlike what you have
        !          2082:                                 been doing, this new function finds the highest and lowest z
        !          2083:                                 coordinates that your clipping BOX can get to.  It must search
        !          2084:                                 for all sectors (and sprites) that go into your clipping box.
        !          2085:                                 Currently, you were searching the z's at the center point only
        !          2086:                                 by simply using the sector[].ceilingz and sector[].floorz
        !          2087:                                 variables.
        !          2088: 
        !          2089:                                 getzrange(long x, long y, long z, short sectnum,
        !          2090:                                                          long *ceilz, long *florz,
        !          2091:                                                          long walldist, char cliptype)
        !          2092: 
        !          2093:                                 Pass x, y, z, sector normally.  Walldist can be 128.  Cliptype
        !          2094:                                         can be 0, 1, or 2. (just like movesprite and clipmove)
        !          2095:                                         This function returnes the 2 z maxes in ceilz and florz.
        !          2096:                                         See GAME.C for an example.
        !          2097: 
        !          2098:                        - Fixed bug with weird vertical lines in transluscent masked walls
        !          2099:                                  in chain mode.
        !          2100: ������������������������������������������������������������������������������
        !          2101: 7/10/94  - Made screen capture (F12) work in 2D modes also.  It always
        !          2102:                                  saves to a 256 color PCX file.
        !          2103: 
        !          2104:                        - Made screen re-sizeable.  Use this easy new function to re-size
        !          2105:                                  the screen:
        !          2106: 
        !          2107:                                  setview(long scrx1, long scry1, long scrx2, long scry2);
        !          2108: 
        !          2109:                                  It is TOO easy to use.  You simply pass is the Upper-left hand
        !          2110:                          corner and the bottom-right corner in screen coordinates of the
        !          2111:                          rectangular region you want the engine to draw to.  The engine
        !          2112:                          automatically centers the horizon at the middle of the window and
        !          2113:                          scales everything properly.
        !          2114: 
        !          2115:                                  Notes:
        !          2116:                                          - Since the engine does extra scaling calculations for
        !          2117:                                                         window sizes that are not 320 pixels wide, I do not
        !          2118:                                                         recommend making the default mode with a window size
        !          2119:                                                         just under 320 pixels wide since the engine can
        !          2120:                                                         actually run a little slower. (such as 312-319
        !          2121:                                                         pixels wide)  Keep them 320 wide.
        !          2122:                                          - Feel free to modify the startumost / startdmost arrays
        !          2123:                                                         AFTER a setview call if you want weird window shapes.
        !          2124:                                                         Keep in mind that startumost[0] and startdmost[0] are
        !          2125:                                                         always refer to the left edge of the viewing window.
        !          2126:                                                         (NOT left edge of screen.)
        !          2127: ������������������������������������������������������������������������������
        !          2128: 7/19/94  - Finally got around to writing the number-of-tiles-per-file
        !          2129:                                  resizer.  Simply type rsizeart.  All instructions will be
        !          2130:                                  displayed when running the program before the actual
        !          2131:                                  conversion.
        !          2132: 
        !          2133:                        - Fixed a few bugs in Editart.  I hope I fixed those evil bugs that
        !          2134:                                  rarely come by.  I'm pretty sure I fixed the bug that made the
        !          2135:                                  screen go blank in 'V' mode, and the bug where a few pixels
        !          2136:                                  in the top left corners of tiles sometimes get overwritten.
        !          2137: 
        !          2138:                        - Added a key in Build 2D edit mode.  Press 'E' on a sprite to
        !          2139:                                  change its status list number.
        !          2140: 
        !          2141:                        - Fixed those lousy Editart subdirectory colors in 'U' for those
        !          2142:                                  teams with great color palettes, but don't have my ugly shade
        !          2143:                                  of pink.
        !          2144: 
        !          2145:                        - Fixed bug with non-200 high P-skies.  The p-skies are now (by
        !          2146:                                  default) centered on the horizon no matter what the height is.
        !          2147: 
        !          2148:                        - Added multiple size PCX and GIF support in Editart.  You can now
        !          2149:                                  load pictures up to 1024*256. (That's all that can fit in VGA
        !          2150:                                  video memory)  If you need to load a bigger picture than that,
        !          2151:                                  it will be chopped off at the bottom, but will still load the
        !          2152:                                  top piece.
        !          2153: 
        !          2154:                        - I know that I have introduced some wonderful new bugs with the
        !          2155:                                  sprite drawing.  I know why they're happening, but I am
        !          2156:                                  looking for a good solution so as to not make you change
        !          2157:                                  any code.  I will put another upload with these bugs fixed
        !          2158:                                  soon.
        !          2159: ������������������������������������������������������������������������������
        !          2160: 7/20/94  - Added TRUE ornamented walls.  Right now the actual ornamentation
        !          2161:                                  must be programmed by you with 2 simple functions:
        !          2162: 
        !          2163:                                  copytilepiece(long tilenume1, long sourcex1, long sourcey1,
        !          2164:                                                                                                                  long xsiz, long ysiz,
        !          2165:                                                                         long tilenume2, long destx1, long desty1)
        !          2166: 
        !          2167:                                  * This function simply copies any section of a source tile
        !          2168:                                                  to any part of a destination tile.  It will automatically
        !          2169:                                                  skip transparent pixels.  It will wrap-around in the
        !          2170:                                                  source but not the destination.  If for some reason
        !          2171:                                                  the destination tile gets removed from the cache, the
        !          2172:                                                  destination tile will be reset to original form.  This
        !          2173:                                                  is why I had to add this second function:
        !          2174: 
        !          2175:                                  allocatepermanenttile(short tilenume, long xsiz, long ysiz)
        !          2176: 
        !          2177:                                        * This function allocates a place on the cache as permanent.
        !          2178:                                                  Right now, I reset the cache every time you call this
        !          2179:                                                  function so I would recommend calling this function
        !          2180:                                                  right after loadpics.
        !          2181: 
        !          2182:                                  I have an example of both of these functions in GAME.C.  Try
        !          2183:                                          playing GAME DOOM1.MAP and go into the secret room with
        !          2184:                                          the pictures of Ken.  Shoot some walls there.  The pictures
        !          2185:                                          with Ken and the Explosion over it were done with
        !          2186:                                          copytilepiece and allocated permanently at tile 4095.  A
        !          2187:                                          good idea for allocating permanent tiles would be to start
        !          2188:                                          at 4095 and decrement.  You can also allocate a permanent
        !          2189:                                          tile over the original tile itself.
        !          2190: 
        !          2191:                        - Tile panning matching keys work a lot better.  They now work
        !          2192:                                  well with bottom steps.  Also, it works well with matching
        !          2193:                                  up windows.
        !          2194: ������������������������������������������������������������������������������
        !          2195: 7/25/94  - A week ago, I uploaded a version of BUILD which unfortunately
        !          2196:                                  had more bugs than the previous version.  This upload should
        !          2197:                                  have those bugs fixed - especially the sprite bugs. (I hope)
        !          2198: 
        !          2199:                        - I think I may actually have the sprite feet behind stairs bug
        !          2200:                                  working perfectly.
        !          2201: 
        !          2202:                        - The engine should now be even faster the before last week.  (A
        !          2203:                                  week ago, I temporarily changed the parallaxing sky algorithm,
        !          2204:                                  making the engine slower in those areas)
        !          2205: 
        !          2206:                        - Added a variable, parallaxyoffs in BUILD.H.  It defaults to 0.
        !          2207:                                  If you set it to 100, then all parallaxing skies will be
        !          2208:                                  properly moved 100 pixels higher.
        !          2209: 
        !          2210:                        - Fixed some weird drawing bug related to parallaxing skies and
        !          2211:                                  sprites.
        !          2212: ������������������������������������������������������������������������������
        !          2213: 7/26/94  - Made sprite's sectors dependent on the z coordinates in the BUILD
        !          2214:                                  editor.  (Helpful if you use overlapping in your maps)
        !          2215: ������������������������������������������������������������������������������
        !          2216: 7/29/94  - Made precache function.  Simply call:
        !          2217:                                        precache()        (no parameters)
        !          2218:                                  right after you call loadboard(?,?,...) and it will load
        !          2219:                                  all tiles in the current board into the cache.  Note that
        !          2220:                                  animations of sprites after the first one will not be
        !          2221:                                  precached.  I have included my precacheing code at the
        !          2222:                                  end of game.c for those interested in making the precaching
        !          2223:                                  fancy.
        !          2224: 
        !          2225:                        - Fixed bug in editart which made it sometimes save the art files
        !          2226:                                  and names.h in the wrong directory (the last directory you
        !          2227:                                  were in when you were in 'U' mode).  You may want to search
        !          2228:                                  your artwork directories to see if you were a victim of this
        !          2229:                                  bug.
        !          2230: ������������������������������������������������������������������������������
        !          2231: 7/30/94  - Made Ctrl-Enter paste parallaxing sky tiles to all neighboring
        !          2232:                                  parallaxing sky areas also.
        !          2233: ������������������������������������������������������������������������������
        !          2234: 7/31/94  - Fixed (most) crashing bugs - Doesn't even crash on the highest
        !          2235:                                  skyscrapers now!  Since I can never be SURE that the crashing
        !          2236:                                  is gone, I need you to test it for me - compare the number
        !          2237:                                  of times it crashes per second since the last version.  It
        !          2238:                                  should be much better.
        !          2239: 
        !          2240:                        - Fixed sector line bug!  Get close to a step, hold down Shift+Z
        !          2241:                                  and the edges of the step will NOT jitter like before AND you
        !          2242:                                  will not get random walls going through the screen.
        !          2243: ������������������������������������������������������������������������������
        !          2244: 8/1/94   - Got rid of the OLD transluscent stuff from overwritesprite and
        !          2245:                                  permanentwritesprite.  (Before it used the 8K shading table
        !          2246:                                  which didn't work very well)
        !          2247: 
        !          2248:                        - Added new true 50/50 transluscence option to overwritesprite.
        !          2249:                                  See bit 2 in the next comment.
        !          2250: 
        !          2251:                        - Fixed overwritesprite so it works with different screen sizes.
        !          2252:                                  You don't need to do any scaling calculations!  Should be
        !          2253:                                  compatible with old function.  Added new bit 1 to orientation
        !          2254:                                  parameter to determine whether or not the sprite should be
        !          2255:                                  scaled and clipped to the viewing window.
        !          2256: 
        !          2257:                                        overwritesprite (long thex, long they, short tilenum,
        !          2258:                                                                                                 signed char shade, char orientation)
        !          2259: 
        !          2260:                                        If Bit 0 of orientation = 0: (thex, they) is top-left corner
        !          2261:                                        If Bit 0 of orientation = 1: (thex, they) is middle
        !          2262:                                        If Bit 1 of orientation = 0: no relation to viewing window
        !          2263:                                        If Bit 1 of orientation = 1: scale and clip to viewing window
        !          2264:                                        If Bit 2 of orientation = 0: normal
        !          2265:                                        If Bit 2 of orientation = 1: 50/50 transluscent!
        !          2266: 
        !          2267:                                 * If it works at full screen, simply set bit 1 of orientation
        !          2268:                                                 to 1, and it should automatically scale properly!
        !          2269: 
        !          2270:                        - Made it so 2/4/6/8 keys in 3D EDIT MODE now only move the objects
        !          2271:                                  1 step rather than continuously, giving more control over the
        !          2272:                                  repeat/panning values of things.
        !          2273: 
        !          2274:                        - Made the / key not only reset the repeats of walls, but also for
        !          2275:                                  sprites.  It will set both repeats of the sprite to the default
        !          2276:                                  size of 64.  If you hold down shift with / on a sprite, it
        !          2277:                                  will give the sprite a square aspect ratio by setting the
        !          2278:                                  xrepeat to equal the yrepeat value.
        !          2279: ������������������������������������������������������������������������������
        !          2280: 8/2/94   - Doubled the board size from: (0 to 65536, 0 to 65536) to
        !          2281:                                  (-65536 to 65536, -65536 to 65536)  Notice that the grid in
        !          2282:                                  2D EDIT MODE is much bigger than before.  Since it is very easy
        !          2283:                                  to double the maximum board size, just tell me if you need
        !          2284:                                  a larger board.  The only bad thing about allowing larger
        !          2285:                                  boards is that the map designer is more likely to make some
        !          2286:                                  sectors too large and cause overflow bugs.  32 bits can only
        !          2287:                                  go so far you know!
        !          2288: 
        !          2289:                        - I think I MAY have fixed a bug in BUILD that used to make it crash
        !          2290:                                  when quitting.  It had something to do with the vertical grid
        !          2291:                                  lines in 2D EDIT MODE when zoomed way in around the upper left
        !          2292:                                  corner of the map (I think).
        !          2293: ������������������������������������������������������������������������������
        !          2294: 8/3/94   - Optimized Editart loading and saving.
        !          2295: 
        !          2296:                        - Made 'V' screen in Editart 320*400 instead of 320*200.
        !          2297: 
        !          2298:                        - Before I said I fixed the bug in EDITART where a few pixels in the
        !          2299:                                 top left corners of tiles sometimes got overwritten.  Well I
        !          2300:                                 lied.  This time I really fixed it.  (I hope)
        !          2301: ������������������������������������������������������������������������������
        !          2302: 8/7/94   - Made x&y repeats, x&y pannings easier to adjust.  It now works
        !          2303:                                 like the default keyboard handler.  It moves once when you
        !          2304:                                 first press the key.  A little later, it starts to move fast.
        !          2305: ������������������������������������������������������������������������������
        !          2306: 8/11/94  - Added great new sprite rotation function which works like
        !          2307:                                  overwritesprite (like 2DRAW sprites)
        !          2308: 
        !          2309:                                 rotatesprite(long sx, long sy, long z, short a, short picnum)
        !          2310: 
        !          2311:                                 (sx, sy) is the center of the sprite to draw defined as
        !          2312:                                          screen coordinates shifted up by 16.
        !          2313:                                 (z) is the zoom.  Normal size is 65536.
        !          2314:                                          Ex: 131072 is zoomed in 2X and 32768 is zoomed out 2X.
        !          2315:                                 (a) is the angle (0 is straight up)
        !          2316:                                 (picnum) is the tile number
        !          2317: 
        !          2318:                                 Ex: rotatesprite(160L<<16,100L<<16,65536,lockclock<<4,DEMOSIGN);
        !          2319:                                         This example will draw the DEMOSIGN tile in the center of the
        !          2320:                                         screen and rotate about once per second.
        !          2321: 
        !          2322:                                 Rotatesprite clips to the same area as overwritesprite but does
        !          2323:                                         not scale or do transluscence yet.
        !          2324: 
        !          2325:                        - Please look at the new permanentwritesprite documentation at the
        !          2326:                                  top of this file!
        !          2327: 
        !          2328:                        - Network should now work again - It now works great on my network
        !          2329:                                  with 3 players!  It may possibly also work with 4 or 5 players
        !          2330:                                  too, but I didn't feel like running between 2 rooms to test it!
        !          2331:                                  I never thought the day would come when I would get NET, COM,
        !          2332:                                  and MODEM all working respectably!
        !          2333: 
        !          2334:                        - Changed setup program so you can select 2, 3, 4, or 5 players in
        !          2335:                                  a network game. (The 5 is just to annoy people who like that
        !          2336:                                  other lousy game)
        !          2337: 
        !          2338:                        - ATTENTION BUILDERS!  Added TILE MOVING to EDITART!  For now, it
        !          2339:                                  will only work WITHIN THE SAME ART FILE.  Do the tile moving
        !          2340:                                  all in 'V' mode.  Here are the new keys in 'V' mode:
        !          2341: 
        !          2342:                                          To swap 2 tiles:
        !          2343:                                                  Simply press space bar on the first tile, then space
        !          2344:                                                          bar on the second.
        !          2345:                                          To swap a group of tiles:
        !          2346:                                                  Press 1 on the first tile, press 2 to remember the region
        !          2347:                                                          between where you pressed 1 and 2.  Press 3 at the
        !          2348:                                                          place to where you want to swap all the tiles.
        !          2349: 
        !          2350:                                  Don't forget that this is all SWAPPING, tiles will (should)
        !          2351:                                          NOT be overwritten using these keys.
        !          2352: 
        !          2353:                        - ATTENTION PROGRAMMERS!  Added ceildist and flordist parameters to
        !          2354:                                  both clipmove and movesprite.  I always had them all set to
        !          2355:                                  (4<<8) by default.
        !          2356: 
        !          2357:                                  clipmove(long *x, long *y, long *z, short *sectnum,
        !          2358:                                                                long xvect, long yvect,
        !          2359:                                                                long walldist, long ceildist, long flordist,
        !          2360:                                                                char cliptype)
        !          2361: 
        !          2362:                                  movesprite(short spritenum, long xchange, long ychange, long zchange,
        !          2363:                                                                 long walldist, long ceildist, long flordist,
        !          2364:                                                                 char cliptype, long numtics)
        !          2365: 
        !          2366:                        - Moved some com/network code from the getpackets function in game
        !          2367:                                  into the engine.
        !          2368: ������������������������������������������������������������������������������
        !          2369: 8/15/94  - Fixed some network initialization code and it now works with 4
        !          2370:                                  players.  (I tested it.)
        !          2371: ������������������������������������������������������������������������������
        !          2372: 8/16/94  - Added different shirt color support.  Here's how you do it:
        !          2373: 
        !          2374:                                allocatespritepalookup(long palnum, char *remapbuf)
        !          2375: 
        !          2376:                                See more documentation of allocatespritepalookup at the top of
        !          2377:                                        this file.
        !          2378: ������������������������������������������������������������������������������
        !          2379: 8/18/94  - I made it so you can redefine the keys in the setup program under
        !          2380:                                  the input devices menu.
        !          2381: 
        !          2382:                        - ATTENTION EVERYONE - for this new version, you MUST go into my
        !          2383:                                  new SETUP program, and SAVE CHANGES AND QUIT once.  The arrow
        !          2384:                                  key code will not work if you don't do this!  If you are
        !          2385:                                  one of those people who actually read BUILD.TXT, give yourself
        !          2386:                                  1 point.  I wonder who will get "caught" for not reading this!
        !          2387: ������������������������������������������������������������������������������
        !          2388: 8/22/94  - Added pixel height and wall length information to 2D EDIT MODE
        !          2389:                                  when you press Tab or Alt-Tab on a sector or wall.
        !          2390: 
        !          2391:                        - Now show the actual number of sprites in 2D EDIT MODE.
        !          2392: 
        !          2393:                        - Improved digitized sound routines.  Just thought I'd mention it.
        !          2394: 
        !          2395:                        - Added a "save As" feature to 2D EDIT MODE.
        !          2396: 
        !          2397:                        - Now show all lo and hi tags in 2D EDIT MODE on the map itself!
        !          2398:                                  Note that position of the sector tag's text is put at the
        !          2399:                                  average point of all the points of the sector, so if you have
        !          2400:                                  a weird shape tagged sector, the text might show up at an
        !          2401:                                  inconvenient place.
        !          2402: 
        !          2403:                        - You can turn the tag boxes on or off by pressing CTRL-T or by
        !          2404:                                  zooming out.
        !          2405: 
        !          2406:                        - ATTENTION EVERYONE - for the new BUILD.EXE and OBJ's, you will
        !          2407:                                  need to copy my new TABLES.DAT over your old one.  Also, you
        !          2408:                                  must go into SETUP and SAVE&QUIT.  I have split the TABLES.DAT
        !          2409:                                  file into 2 separate files.  They are:
        !          2410: 
        !          2411:                                  TABLES.DAT - 10880 bytes - sin tables, fonts, etc.
        !          2412:                                  SETUP.DAT  - 23 bytes    - (6 options) + (17 custom keys)
        !          2413: 
        !          2414:                                  The SETUP.DAT file is the only file SETUP.EXE accesses now.
        !          2415:                          This means that from now on, if I want to add something to
        !          2416:                          TABLES.DAT, you won't have to go into the setup program and reset
        !          2417:                          the options again.
        !          2418: ������������������������������������������������������������������������������
        !          2419: 8/24/94  - Relative alignment now fully works with ROTATION!  Relative
        !          2420:                                  alignment will allow ceilings and floors to align with the
        !          2421:                                  first 2 points of a sector.  This will relieve you of
        !          2422:                                  programming special ceiling and floor panning code for moving
        !          2423:                                  sectors.
        !          2424:                          In 3D EDIT MODE, simply press 'R' on a ceiling / floor to switch
        !          2425:                                  between relative alignment mode and normal mode.  Notice that
        !          2426:                                  bit 6 of both sector[].ceilingstat and sector[].floorstat are
        !          2427:                                  relative alignment bits.
        !          2428:                          I have an example of relative alignment in nukeland.map in the
        !          2429:                                  high blue room off the main octagonal room.  Also note that my
        !          2430:                                  subways and dragsectors now use relative alignment for panning.
        !          2431: ������������������������������������������������������������������������������
        !          2432: 8/25/94  - I added a new parameter to printext256 and printext16.  I need
        !          2433:                                  to document this stuff!
        !          2434: ������������������������������������������������������������������������������
        !          2435: 8/27/94  - Made it so you can't shrink sprites so much you can't grab them
        !          2436:                                  any more in 3D EDIT MODE.
        !          2437: 
        !          2438:                        - Added (G)oto feature into Build 'V' mode.  Simply press G, type
        !          2439:                                  the tile number and it will go there.
        !          2440: ������������������������������������������������������������������������������
        !          2441: 9/7/94   - Fixed relative alignment bugs I noticed.  My subway.map won't
        !          2442:                                  crash anymore and the relatively aligned ceilings and floors
        !          2443:                                  should not pan crazily anymore when looking from a far
        !          2444:                                  distance.
        !          2445: ������������������������������������������������������������������������������
        !          2446: 9/9/94   - ATTENTION PROGRAMMERS:  I added a new parameter to
        !          2447:                                  overwritesprite.  Dapalnum can be from 0-15 depending on
        !          2448:                                  what palette lookup table is being used.  Dapalnum is normally
        !          2449:                                  0.  Overwritesprite now looks like this:
        !          2450: 
        !          2451:                                  overwritesprite (long thex, long they, short tilenum,
        !          2452:                                                 signed char shade, char orientation, char dapalnum)
        !          2453: ������������������������������������������������������������������������������
        !          2454: 9/13/94   - ATTENTION PROGRAMMERS:  I changed the last parameter of drawrooms
        !          2455:                                  (sector number) to be passed as a value, NOT a pointer anymore.
        !          2456: 
        !          2457:                                  drawrooms(long daposx, long daposy, long daposz,
        !          2458:                                                          short daang, long dahoriz, short dacursectnum)
        !          2459: ������������������������������������������������������������������������������
        !          2460: 9/15/94   - ATTENTION PROGRAMMERS:  I took out the COM(modem)/network code
        !          2461:                                  from my engine.obj and put it into a separate .obj called
        !          2462:                                  multi.obj.  (I also removed the sound from my engine and stuck
        !          2463:                                  it in kdmeng.obj)  Please include it in your makefile.  Here is
        !          2464:                                  a list of ALL of the variables and functions you will need to
        !          2465:                                  know to program for multiple players:
        !          2466: 
        !          2467:                                  VARIABLES:  (You should extern these in your game.c)
        !          2468:                                          extern short numplayers, myconnectindex;
        !          2469:                                          extern short connecthead, connectpoint2[MAXPLAYERS];
        !          2470:                                          extern long *lastpacket2clock;
        !          2471: 
        !          2472:                                  FUNCTIONS:
        !          2473:                                          initmultiplayers(option[4],option[5]);
        !          2474:                                          uninitmultiplayers();
        !          2475: 
        !          2476:                                          sendlogon();
        !          2477:                                          sendlogoff();
        !          2478: 
        !          2479:                                          sendpacket(connecthead,tempbuf,j);
        !          2480:                                          sendpacket(-1,tempbuf,j);
        !          2481:                                          leng = getpacket(&otherconnectindex,tempbuf);
        !          2482: 
        !          2483:                                  Please see detailed descriptions of these functions at the top
        !          2484:                                          of this file.
        !          2485: 
        !          2486:                         - Multiplayer code is now MUCH cleaner!
        !          2487: 
        !          2488:                         - Please try my game on your networks again!  My game now works
        !          2489:                                        perfectly with 3 players on a network that used to crash at
        !          2490:                                        the DOS4GW prompt just a week ago!  My game needs only IPX,
        !          2491:                                        no server to run.
        !          2492: ������������������������������������������������������������������������������
        !          2493: 9/16/94   - ATTENTION PROGRAMMERS:  CONVMAP5!!!  YOU MUST RUN CONVMAP5 ON
        !          2494:                                        ALL OF YOUR MAPS IF YOU WANT THEM TO WORK WITH THE NEW
        !          2495:                                        BUILD.EXE OR OBJ'S!  Following are the exact changes I made
        !          2496:                                        to the new map format:
        !          2497: 
        !          2498:                                        * Added numextras
        !          2499:                                        * Added sector[].ceilingpal
        !          2500:                                        * Added sector[].floorpal
        !          2501:                                        * Added sector[].visibility
        !          2502:                                        * Split sector[].tag to sector[].lotag and sector[].hitag
        !          2503:                                        * Added sector[].extra
        !          2504:                                        * Expanded wall[].cstat to a short
        !          2505:                                        * Split wall[].tag to wall[].lotag and wall[].hitag
        !          2506:                                        * Added wall[].extra
        !          2507:                                        * Split sprite[].tag to sprite[].lotag and sprite[].hitag
        !          2508:                                        * Got rid of sprite[].extra (the void * mess)
        !          2509:                                        * Added sprite[].extra
        !          2510: 
        !          2511:                                        The only thing programmers have to worry about when converting
        !          2512:                                                are the tags.  I split them into lo and hi tags.
        !          2513:                                                (See BUILD.H for new structure formats)
        !          2514: 
        !          2515:                                        I got rid of the (void *)extra thing from the sprite
        !          2516:                                                structure.  I know I may have made some promises it
        !          2517:                                                wouldn't change and it was for your use only, but what
        !          2518:                                                can I say - it's not needed anymore (in other words,
        !          2519:                                                if you're already using it, TOUGH LUCK).  I have my
        !          2520:                                                own, new, method for extending sector, wall, or
        !          2521:                                                sprite structures.  You will be able to extend any
        !          2522:                                                structure as much as you want AND be able to edit it
        !          2523:                                                all in the BUILD editor to be saved in the permanent
        !          2524:                                                map format.  Notice I added a (short)extra to all 3
        !          2525:                                                main structures.  They default to -1.  But if they
        !          2526:                                                are >= 0 then they form a linked list out of the
        !          2527:                                                extra structure.   NOTE:  THIS EXTRA STUFF IS NOT
        !          2528:                                                PROGRAMMED YET!  I'm just mentioning it becuase the
        !          2529:                                                new map format has this extendability.  I'll try to
        !          2530:                                                get it done soon though.  (9/21/94) - Actually just
        !          2531:                                                ignore the fact that this paragraph ever existed.
        !          2532:                                                I'm just keeping it here for history purposes.
        !          2533: 
        !          2534:                         - Renamed my allocatespritepalookup function to makepalookup since
        !          2535:                                        it now also applies to walls, ceilings, floors, p-skies and
        !          2536:                                        masked walls.
        !          2537: ������������������������������������������������������������������������������
        !          2538: 9/20/94   - Added rotated sprites.  These new rotated sprites rotate in the
        !          2539:                                        same way as masked walls.  Sounds like a waste since the
        !          2540:                                        engine already has masked walls?  NOT AT ALL!  With rotated
        !          2541:                                        sprites, you can EASILY do TRUE ornamented walls FULLY inside
        !          2542:                                        the BUILD editor with even MORE versatility than that other
        !          2543:                                        game out there.  For example, you can place the ornamentation
        !          2544:                                        anywhere on the wall, with sizing control using 2,4,6,8 on the
        !          2545:                                        keypad, and even ornament with transluscence!  In 3D EDIT
        !          2546:                                        MODE, simply press 'R' on a sprite to make it a rotated
        !          2547:                                        sprite (Programmers see bit 4 of sprite[].cstat)
        !          2548: 
        !          2549:                         - Fixed crashing bug with sector (Rt. ALT) copy/paste in 2D EDIT
        !          2550:                                        MODE.
        !          2551: 
        !          2552:                         - You can now copy groups of sectors from 1 map to another!  Here's
        !          2553:                                        how you do it:
        !          2554: 
        !          2555:                                        Step 1:  Capture a bunch of sectors with the Rt. ALT selection
        !          2556:                                                                tool.
        !          2557:                                        Step 2:  With the sectors still highlighted, you can now load
        !          2558:                                                                another map and the highlighted sectors will
        !          2559:                                                                automatically be inserted into the new map.  (They
        !          2560:                                                                will still be highlighted)
        !          2561: ������������������������������������������������������������������������������
        !          2562: 9/21/94   - Fixed bug with cursectnum not always being right after loading
        !          2563:                                        the board.  I now check it and make sure it's right when
        !          2564:                                        saving in BUILD now.
        !          2565: 
        !          2566:                         - Added 'O' key in 2D/3D EDIT MODES.  It will push a rotated sprite
        !          2567:                                        backwards (using hitscan) into the first wall and
        !          2568:                                        automatically adjust the angle to make the sprite appear
        !          2569:                                        as if it was part of the wall.
        !          2570: 
        !          2571:                         - You can now press 'S' to insert a sprite in 3D EDIT MODE.  Press
        !          2572:                                        'S' on a ceiling or floor.
        !          2573: 
        !          2574:                         - You can now press delete to delete a sprite in 3D EDIT MODE.
        !          2575: ������������������������������������������������������������������������������
        !          2576: 9/22/94   - Programmed Nick & Peter's BUILD stub to their EXACT
        !          2577:                                        specifications.  See WSTUB.C for code & documentation.
        !          2578: ������������������������������������������������������������������������������
        !          2579: 9/27/94   - Fixed Rt. Alt block copying nextsector1 pointer bug.
        !          2580: ������������������������������������������������������������������������������
        !          2581: 9/29/94   - Added special bitmapped effect which I either call lava or
        !          2582:                                        boiling slime.  See my initlava and movelava functions
        !          2583:                                        inside GAME.C.
        !          2584: 
        !          2585:                         - I added a bit array call gotpic.  The engine will set the
        !          2586:                                        respective gotpic bit for each picnum drawn to the screen,
        !          2587:                                        including ceilings, floors, walls, sprites, masked walls -
        !          2588:                                        even overwritesprites, etc.   This array is mainly for
        !          2589:                                        making the game only calculate special bitmapped effects
        !          2590:                                        when that certain picnum is on the screen.
        !          2591: 
        !          2592:                                        Note 1:  The engine does NOT automatically clear the gotpic
        !          2593:                                                 bits for you.  If you want to test gotpic for a certain
        !          2594:                                                 picnum, you should clear it if you want to test it again.
        !          2595: 
        !          2596:                                        Note 2:  It is not necessary to use permanentwritesprite
        !          2597:                                                 for bitmapped special effects - after all, if you see it,
        !          2598:                                                 it MUST be in the cache.
        !          2599: 
        !          2600:                                        Added to BUILD.H:
        !          2601:                                                EXTERN char gotpic[MAXTILES>>3];
        !          2602: 
        !          2603:                                        Example code in GAME.C:
        !          2604:                                                if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0)  //test bit
        !          2605:                                                {
        !          2606:                                                        gotpic[SLIME>>3] &= ~(1<<(SLIME&7));     //clear bit
        !          2607: 
        !          2608:                                                        if (waloff[SLIME] != -1)                 //if in cache
        !          2609:                                                                movelava((char *)waloff[SLIME]);      //calculate!
        !          2610:                                                }
        !          2611: 
        !          2612:                         - Added what some people call gamma correction.  I think
        !          2613:                                        brightness is a better description though.
        !          2614: 
        !          2615:                                        setbrightness(char brightness);
        !          2616: 
        !          2617:                                        Simply call this function where brightness ranges from
        !          2618:                                 0 to 4.  Brightness defaults to 0.  Levels 1-4 are all brighter
        !          2619:                                 than 0.  If you switch between 2D & 3D modes, the engine will
        !          2620:                                 remember the current brightness level.
        !          2621: ������������������������������������������������������������������������������
        !          2622: 9/30/94   - Added a few keys to fake a multiplayer game all on 1 computer.
        !          2623:                                        In my game, press Insert to add a new player at the starting
        !          2624:                                        position, and Delete to delete the last player.  Press
        !          2625:                                        scroll lock to get control of the other players.  In the same
        !          2626:                                        way Lt. Enter lets you view other players, Scroll lock will
        !          2627:                                        let you control other players (single player game only)
        !          2628: ������������������������������������������������������������������������������
        !          2629: 10/2/94   - Moved all doanimations code from engine into game.c.  If you
        !          2630:                                        are using the doanimations code, here's exactly what you
        !          2631:                                        need to do to make it work with your code again:
        !          2632: 
        !          2633:                                Step 1:  Copy these 3 functions which you should find at
        !          2634:                                                        the end of my Game.c:
        !          2635: 
        !          2636:                                         doanimations(long numtics)
        !          2637:                                         getanimationgoal(long animptr)
        !          2638:                                         setanimation(long *animptr, long thegoal, long thevel)
        !          2639: 
        !          2640:                                Step 2:  Move these variables out of BUILD.H and into your
        !          2641:                                                        game.c:
        !          2642: 
        !          2643:                                 #define MAXANIMATES 512
        !          2644:                                 static long *animateptr[MAXANIMATES], animategoal[MAXANIMATES];
        !          2645:                                 static long animatevel[MAXANIMATES], animatecnt = 0;
        !          2646: 
        !          2647:                                 * If you copied my door code, you will probably have to convert
        !          2648:                                          some parameters to longs. (oops!)
        !          2649: 
        !          2650:                         - Got rid of printnum from the engine.  It is an outdated function.
        !          2651:                                        Use either printext256 or printext16 instead.
        !          2652: 
        !          2653:                         - Added y-flipping for both normal and rotated sprites.  (see bit
        !          2654:                                        3 of sprite[].cstat in BUILD.H.
        !          2655: 
        !          2656:                         - Added y-flipping for walls.  (see bit 8 of wall[].cstat in
        !          2657:                                        BUILD.H.
        !          2658: 
        !          2659:                         - Fixed bug with initialization of Master and Slave for
        !          2660:                                        COM(Modem) only.  If both computers went in at the same
        !          2661:                                        time, it used to sometimes think both were Masters.
        !          2662: ������������������������������������������������������������������������������
        !          2663: 10/4/94   - Alt-C in 3D EDIT MODE changes all picnums on the whole map
        !          2664:                                        from the picnum in tab to the picnum under the mouse cursor.
        !          2665: ������������������������������������������������������������������������������
        !          2666: 10/6/94   - Fixed y-flipping bug on walls and masked walls.
        !          2667: ������������������������������������������������������������������������������
        !          2668: 10/16/94  - Fixed bug in editart that didn't convert the maps right after
        !          2669:                                        swapping tiles.
        !          2670: 
        !          2671:                         - Added excellent function to my multi.obj.
        !          2672: 
        !          2673:                                        long getoutputcirclesize();
        !          2674:                                                This function returns the number of bytes that have not
        !          2675:                                        yet been copied.  If there are still more than say, 16 bytes,
        !          2676:                                        then you may be sending too many bytes per second.  This can
        !          2677:                                        happen if the frame rate of a computer is faster than the
        !          2678:                                        speed of the serial mode (Ex: Try 2400 baud with a Pentium 90!)
        !          2679:                                        this function will tell you how many bytes are left to copy
        !          2680:                                        In other words, if getoutputcirclesize() < 16 then it is safe
        !          2681:                                        to send a packet.  If you already have serial mode working
        !          2682:                                        all you have to do to update your code is to copy the lines
        !          2683:                                        in my sync() function the deal with the getoutputcirclesize
        !          2684:                                        function.  Everything else in sync() and getpackets() is
        !          2685:                                        pretty much the same.
        !          2686: 
        !          2687:                         - Programmed some example code in my game that will allow players
        !          2688:                                        to change masters and slaves during the game without losing
        !          2689:                                        sync.  Simply press 'M' in my multiplayer game, and that
        !          2690:                                        computer will become the master!  It is interesting how
        !          2691:                                        the frame rate and controllability changes.
        !          2692: ������������������������������������������������������������������������������
        !          2693: 10/31/94  - Added basic scripting to EDITART.  Don't expect it to be
        !          2694:                                        everything you ever dreamed of (yet).
        !          2695: 
        !          2696:                                Scripts are saved in a file called CAPFIL.TXT.  You can edit the
        !          2697:                                        text file, but be careful not to screw it up too badly (such
        !          2698:                                        as extra commas, spaces in weird places, etc.) since I am
        !          2699:                                        parsing it in EDITART.
        !          2700: 
        !          2701:                                Whenever you select a box in 'U' mode, a line will be appended to
        !          2702:                                        the CAPFIL.TXT file.
        !          2703: 
        !          2704:                                         WRITING THE CAPFIL.TXT FILE:
        !          2705:                                In 'U' mode, you can press 'O' instead of ENTER to select a tile.
        !          2706:                                        What 'O' does that is different from ENTER is that it takes
        !          2707:                                        the center point of the highlighted rectangle, and searches
        !          2708:                                        outward until a total rectangle of transparent pixels (255)
        !          2709:                                        is reached.  This is useful for grabbing sprites - not only
        !          2710:                                        will you not have fine adjust to the exact borders of a
        !          2711:                                        sprite now, but when you re-grab from the pcx's you can
        !          2712:                                        change the size of the sprite freely.
        !          2713: 
        !          2714:                                        READING THE CAPFIL.TXT FILE:
        !          2715:                                There are 2 ways to re-grab from the CAPFIL.TXT file.  If you
        !          2716:                                        press ALT-U in the main screen, everything will be re-grabbed.
        !          2717:                                        If you press ALT-U in 'V' mode, then you should first select
        !          2718:                                        the range by pressing '1' and '2' on the range boundaries.
        !          2719: 
        !          2720:                                Format of CAPFIL.TXT lines:
        !          2721:                                        Tile #, Full path/file name, x1, y1, xsize, ysize
        !          2722: 
        !          2723:                                        Note: If xsize and ysize are 0, then that means you did
        !          2724:                                        an 'O' grab and EDITART will search from point (x1, y1)
        !          2725:                                        when you do a re-grab.
        !          2726: 
        !          2727:                                Example CAPFIL.TXT file:
        !          2728:                                        31,D:\CAPTUR00.PCX,220,98,64,64
        !          2729:                                        110,D:\CAPTUR00.PCX,49,72,0,0
        !          2730: 
        !          2731:                                        The first line says that tile #31 is a 64*64 tile and the
        !          2732:                                        second line says that tile #110 is unknown size tile (grabbed
        !          2733:                                        with the 'O' key)
        !          2734: 
        !          2735:                                Note: You can only do 1 grab per tile with my scripting system.
        !          2736:                                        You may have done your parallaxing skies with several grabs.
        !          2737:                                        If so then try to make the tile into 1 large PCX and do 1
        !          2738:                                        grab.  (The largest grabbing size right now is 1024*256)
        !          2739: 
        !          2740:                        -------------------------------------------------------------------
        !          2741: 
        !          2742:                         - Made Editart's screen capture (F12) save to PCX's the exact size
        !          2743:                                        of the tile and not include the status bar at the bottom.  It
        !          2744:                                        will also save large tiles to large PCX's - Now it's easy and
        !          2745:                                        lossless to extract a tile from Editart!
        !          2746: 
        !          2747:                         - ATTENTION PROGRAMMES!  Added 2 new parameters to getzrange for
        !          2748:                                        returning the objects hit on top and bottom.  
        !          2749:                                        (sectors / sprites)  See my updated documentation at the top 
        !          2750:                                        of this file.
        !          2751: 
        !          2752:                         - Fixed clipping bugs with sprites near sector lines. (I hope)
        !          2753: 
        !          2754:                         - Got 3D Red-Blue glasses mode working for all VGA cards.  First
        !          2755:                                        set the graphics mode to red-blue mode in the setup program.
        !          2756:                                        The left eye is red and the right eye is blue.  There are
        !          2757:                                        4 keys that let you adjust the 3D view:
        !          2758:                                                          [,] = Adjust width between eyes (3D width)
        !          2759:                                          Shift [,] = Adjust width of parallax (2D width)
        !          2760: ������������������������������������������������������������������������������
        !          2761: 11/1/94   - Guess what?  I turned 19 today.  Doesn't that just suck.  Now,
        !          2762:                                        if you play my build game on my birthday, all the extemely
        !          2763:                                        evil and scary brown monsters will be replaced with super
        !          2764:                                        happy fun dogs that throw smiley red jelly coconuts at you.
        !          2765:                                        Also, my incredibly evil and scary music will be replaced
        !          2766:                                        with super happy music.  Actually this whole paragraph is
        !          2767:                                        a joke (except for the birthday part).
        !          2768: 
        !          2769:                         - Made centering work with rotated sprites.
        !          2770: 
        !          2771:                         - Fix centering with x and y flipped sprites.
        !          2772: 
        !          2773:                         - Rotated sprites now get chopped off by the ceiling or floor in
        !          2774:                                        the same way normal sprites get chopped.  Sprites do not get
        !          2775:                                        chopped if there is a parallaxing sky / floor.
        !          2776: 
        !          2777:                         - Made Shift + F12 is BUILD 2D mode inverse black and white.
        !          2778: 
        !          2779:                         - If SETUP.DAT is not found then default options are loaded
        !          2780:                                         instead of quitting to DOS.
        !          2781: 
        !          2782:                         - ATTENTION PROGRAMMERS!  Added 3 parameters to makepalookup that
        !          2783:                                         allow you to do FOG effects.  The first 2 parameters are the
        !          2784:                                         same as before.  The last 3 are the color that the palette
        !          2785:                                         fades to as you get further away.  Before, this color was
        !          2786:                                         always black (0,0,0).  White would be (63,63,63).
        !          2787: 
        !          2788:                                  makepalookup(long palnum, char *remapbuf,
        !          2789:                                                          char redvalue, char greenvalue, char bluevalue)
        !          2790: 
        !          2791:                         - ATTENTION PROGRAMMERS!  Moved 2 things into BUILD.H.  Please
        !          2792:                                        make sure to update it:
        !          2793: 
        !          2794:                                 #define MAXPALOOKUPS 256
        !          2795:                                         and
        !          2796:                                 EXTERN char *palookup[MAXPALOOKUPS];
        !          2797: 
        !          2798:                                 The palookup array is an array of pointers that point to the
        !          2799:                                 first byte of each 8K palette lookup table.  All 256 pointers
        !          2800:                                 are initialized to NULL by initengine() except for palookup[0]
        !          2801:                                 which is the default 8K palette.  This will allow you to modify
        !          2802:                                 the palette lookup table directly for non-snowy fading effects,
        !          2803:                                 etc.  Each palette lookup table has 32 shades.  Each shade has
        !          2804:                                 256 bytes.  Shade 0 is closest (actual palette brightness) and
        !          2805:                                 shade 31 is farthest (dark usually).  (256*32 = 8192 or 8K)
        !          2806: ������������������������������������������������������������������������������
        !          2807: 11/3/94   - Now show white lines in 'V' mode of EDITART at ART file tile
        !          2808:                                        boundaries.
        !          2809: 
        !          2810:                         - Added Insert and Delete commands to EDITART!  These Insert and
        !          2811:                                        Delete keys WILL shift all tiles after the one being inserted
        !          2812:                                        or deleted just like a regular text editor.  To insert or
        !          2813:                                        delete tiles, simply go the 'V' screen in EDITART and bang
        !          2814:                                        away!  Don't worry these keys are fully multi-tile file
        !          2815:                                        compatible (unlike swapping right now).
        !          2816:                                                You will notice that the white line boundaries that
        !          2817:                                        I just added will actually move if you press Insert or Delete.
        !          2818:                                        This changes the number of tiles per art file.  But that's
        !          2819:                                        ok.  If the art files ever get too unbalanced, you can run
        !          2820:                                        the RSIZEART.EXE utility to fix it.
        !          2821:                                                Ken's lesson of the day:  For the final release of your
        !          2822:                                        games, you only need 1 art file.  The reason I spent my time
        !          2823:                                        programming multiple art files was because of EDITART.
        !          2824:                                        Since EDITART need to READ & WRITE to the art files, it must
        !          2825:                                        hold a whole art file in memory at a time.  Since Build and
        !          2826:                                        Game only READ the art files, a caching system can be made
        !          2827:                                        and only 1 art file is necessary even for lo-memory systems.
        !          2828: ������������������������������������������������������������������������������
        !          2829: 11/4/94   - ATTENTION MAP DESIGNERS!  Added a long-awaited feature to BUILD
        !          2830:                                        which I call "loop joining".  Have you ever gotten this
        !          2831:                                        frustrating message in 2D EDIT MODE before?
        !          2832: 
        !          2833:                                                "You can't split sector by connecting different loops."
        !          2834: 
        !          2835:                                                Well, you're not going to see it any more because I fixed
        !          2836:                                        it!  Yup.  You can now split a sector along a line connecting
        !          2837:                                        different loops of the sector.
        !          2838: 
        !          2839:                                                Try this - Convert the sector on the left to the sector
        !          2840:                                        on the right:
        !          2841: 
        !          2842:                                                                                  Split #1         Split #2
        !          2843:                                        �������Ŀ        �������Ŀ        �������Ŀ
        !          2844:                                        � ���Ŀ �        � ���Ŀ �        � ���Ŀ �
        !          2845:                                        � �   � �        � �   � �        � �   � �
        !          2846:                                        � ����� �        � ����� �        � ����� �
        !          2847:                                        ���������        ���������        ���������
        !          2848:                                         (Given)        (Half done)        (Result)
        !          2849:                                        (1 sector)    (Still 1 sector)   (2 sectors)
        !          2850: 
        !          2851:                                                Before the only was to do this was to delete all the
        !          2852:                                        sectors and then redraw them again.
        !          2853: 
        !          2854:                                                I'm sure loop joining has its share of tricks, as most
        !          2855:                                        BUILD functions do, so you may want to spend some time just
        !          2856:                                        playing around with this new function.
        !          2857: 
        !          2858:                         - Removed my own profiler stuff - Hline calculations, etc. code.
        !          2859:                                        Watcom's sampler and profiler is much better anyway.
        !          2860: 
        !          2861:                         - Fixed neartag divide by zero bug with walls (I hope).
        !          2862:                                        Anyone calling neartag for every player per movethings?
        !          2863:                                        I would try not to - How much is that unnoticable extra 0.02
        !          2864:                                        frames per second worth to you anyway?
        !          2865: ������������������������������������������������������������������������������
        !          2866: 11/9/94   - Added new array to BUILD.H called gotsector.  It works a lot
        !          2867:                                        like the gotpic array, but this array determines which sectors
        !          2868:                                        were considered during the drawrooms function.  Note that
        !          2869:                                        gotsector, unlike gotpic IS cleared to 0 during every call
        !          2870:                                        to drawrooms.
        !          2871: 
        !          2872:                         - Fixed Editart 'U' mode mouse control bug.  I typed too fast this
        !          2873:                                        time.
        !          2874: 
        !          2875:                         - Fixed Build split sector bug of accidently deleting sprites.  It
        !          2876:                                        should not delete any sprites when splitting sectors now.
        !          2877: ������������������������������������������������������������������������������
        !          2878: 11/15/94  - ATTENTION PROGRAMMERS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        !          2879:                                        I moved ALL my timer code and arrow key code into GAME.C.
        !          2880:                                        Here are the exact instructions that you need to follow to
        !          2881:                                        upgrade your code to the new obj's:
        !          2882: 
        !          2883:                                        1.  From the end of my GAME.C, take the code from these 4
        !          2884:                                                 functions:
        !          2885: 
        !          2886:                                        ---> inittimer();
        !          2887:                                        ---> uninittimer();
        !          2888:                                        ---> void __interrupt __far timerhandler();
        !          2889:                                        ---> keytimerstuff();
        !          2890: 
        !          2891:                                        2.  After each initengine, call inittimer right AFTER:
        !          2892: 
        !          2893:                                                  initengine();
        !          2894:                                        ---> inittimer();
        !          2895: 
        !          2896:                                                 After each uninitengine, call uninittimer right BEFORE:
        !          2897: 
        !          2898:                                        ---> uninittimer();
        !          2899:                                                  uninitengine();
        !          2900: 
        !          2901:                                        3.  You may need to include this (if not already included):
        !          2902: 
        !          2903:                                        ---> #include <dos.h>
        !          2904: 
        !          2905:                                        4.  Add these 2 lines to declare the timerhandler:
        !          2906: 
        !          2907:                                        ---> void (__interrupt __far *oldtimerhandler)();
        !          2908:                                        ---> void __interrupt __far timerhandler(void);
        !          2909: 
        !          2910:                                        5.  Since BUILD.H NO LONGER has vel, svel, and angvel, you
        !          2911:                                                 must add the following line to your game:
        !          2912:                                                 (These variables are modified inside keytimerstuff())
        !          2913: 
        !          2914:                                        ---> static long vel, svel, angvel;
        !          2915: 
        !          2916:                                        6.  Let me list some variables that I recently removed from my
        !          2917:                                                 GAME.  This may or may not affect you:
        !          2918: 
        !          2919:                                                 oposx[], oposy[], oang[], etc.. - GONE!
        !          2920:                                                 lastpacket2clock - GONE!
        !          2921:                                                 lastsynctics - GONE!
        !          2922:                                                 drawscreen's smoothratio parameter & related code - GONE!
        !          2923:                                                 kenchaintimer - GONE! (Don't think anybody was using it
        !          2924:                                                         because it didn't solve sound compatibility problems)
        !          2925: ������������������������������������������������������������������������������
        !          2926: 11/16/94  - Made swinging door clipping work MUCH better!  It is much more
        !          2927:                                        difficult to "sneak" through the door now.  With the swinging
        !          2928:                                        door clipping working much better, I made it possible to open
        !          2929:                                        doors even if you are in the same sector as the door itself.
        !          2930:                                        Now you won't have to stand back a certain distance to open
        !          2931:                                        the doors.  (It is much less annoying this way)  Since neartag
        !          2932:                                        does not normally scan cursectnum's sector tags, you will
        !          2933:                                        need to check cursectnum's tags yourself (if you so desire)
        !          2934: 
        !          2935:                                        Example: (extracted from my GAME.C)
        !          2936: 
        !          2937:                                        neartag(posx[snum],posy[snum],posz[snum],cursectnum[snum],
        !          2938:                                                          ang[snum],&neartagsector,&neartagwall,&neartagsprite,
        !          2939:                                                          &neartaghitdist,1024L);
        !          2940:                                        if (neartagsector == -1)    //If no neartagsector found...
        !          2941:                                        {
        !          2942:                                                i = cursectnum[snum];    //Test current sector for tagging
        !          2943:                                                if ((sector[i].lotag|sector[i].hitag) != 0)
        !          2944:                                                        neartagsector = i;    //Cursectnum is the neartagsector!
        !          2945:                                        }
        !          2946: 
        !          2947:                         - Improved my gamma correction algorithm.  Since it now uses a new
        !          2948:                                        1K at the end of my TABLES.DAT, be sure to update all your
        !          2949:                                        TABLES.DAT files!  My new gamma correction supports 16 levels
        !          2950:                                        of brightness (0-15).  You need not change any code in your
        !          2951:                                        game if you already have gamma correction programmed.
        !          2952: ������������������������������������������������������������������������������
        !          2953: 11/17/94  - Made swinging door clipping code work even better.  The bug was:
        !          2954:                                        it only tested the clipping if you were in the same sector as
        !          2955:                                        the door.  So I put this handy little function in GAME.C which
        !          2956:                                        simply tests if 2 sectors are neighbors or not:
        !          2957:                                                testneighborsectors(short sect1, short sect2)
        !          2958:                                        Check it out!
        !          2959: 
        !          2960:                         - Rewrote my clipinsidebox function.  You probably don't use this
        !          2961:                                        function, but if you copied my swinging door code, then you
        !          2962:                                        will need to update this.  Clipinsidebox is used for clipping
        !          2963:                                        to determine whether a player or sprite is too close to a
        !          2964:                                        wall.
        !          2965: 
        !          2966:                                        clipinsidebox(long x, long y, short wallnum, long walldist)
        !          2967:                                                X and y are the position of the sprite or player.  Wallnum
        !          2968:                                        is the wall to test, and walldist is the fatness of the sprite
        !          2969:                                        or player (same as clipmove).  It returns a 1 if the sprite or
        !          2970:                                        player's clipping square intersects the wall or 0 if not.
        !          2971: 
        !          2972:                                        Example - You can test all 4 walls of a swinging door and make
        !          2973:                                                sure the door doesn't run you over:
        !          2974: 
        !          2975:                                        short swingwall[4];   //4 wall indeces of a swinging door
        !          2976:                                        for (i=0;i<4;i++)
        !          2977:                                                if (clipinsidebox(posx,posy,swingwall[i],128L) == 1)
        !          2978:                                                {
        !          2979:                                                        //Swinging door swung into player, so move door back to
        !          2980:                                                        //its old position / inverse swinging direction.
        !          2981: 
        !          2982:                                                        break;
        !          2983:                                                }
        !          2984: ������������������������������������������������������������������������������
        !          2985: 11/22/94  - Made build posx, posy, posz, ang, cursectnum, and horiz variables
        !          2986:                                        nonstatic.
        !          2987: 
        !          2988:                         - Made hi-res screen capture work.
        !          2989: 
        !          2990:                         - Fixed some of those evil view-clipping bugs with rotated sprites
        !          2991:                                        on red sector lines.  I think it should work with rotated
        !          2992:                                        sprites on horizontal or vertical red lines.  I'm not sure
        !          2993:                                        about weird angled lines.
        !          2994: ������������������������������������������������������������������������������
        !          2995: 11/23/94  - ATTENTION PROGRAMMERS:  Made parallaxing skies tileable in any
        !          2996:                                        equal size chunk where the chunk x size is a power of 2
        !          2997:                                        from 16-1024.  You can now make a 2048 wide parallaxing sky
        !          2998:                                        with 2 chunks of 1024 (gobble gobble).
        !          2999: 
        !          3000:                                        These lines were added to BUILD.H:
        !          3001: 
        !          3002:                                                #define MAXPSKYTILES 256
        !          3003:                                                EXTERN short pskyoff[MAXPSKYTILES], pskybits;
        !          3004: 
        !          3005:                                        pskyoff[MAXPSKYTILES] is an array of OFFSETS of each tile
        !          3006:                                                from the picnum of the parallaxing sky.
        !          3007: 
        !          3008:                                        pskybits is NOT the actual number of tiles, but the
        !          3009:                                                log (base 2) of the number of tiles.  Look at this table:
        !          3010: 
        !          3011:                                                  For 1 tile, pskybits = 0
        !          3012:                                                  For 2 tiles, pskybits = 1
        !          3013:                                                  For 4 tiles, pskybits = 2
        !          3014:                                                  For 8 tiles, pskybits = 3
        !          3015:                                                  For 16 tiles, pskybits = 4
        !          3016:                                                  etc.
        !          3017: 
        !          3018: 
        !          3019:                                        I know that most teams have a 1024 wide parallaxing sky that
        !          3020:                                                 wraps all the way around.  Don't worry - this is the
        !          3021:                                                 default now.  When initengine is called, the variables
        !          3022:                                                 default to this:
        !          3023: 
        !          3024:                                                pskyoff[0] = 0;
        !          3025:                                                pskybits = 0;
        !          3026: 
        !          3027:                                        You may have used a 512 wide parallaxing sky (like in my game)
        !          3028:                                                 that repeated every 180 degrees.  To make this work with
        !          3029:                                                 the new version, set these variables like this right after
        !          3030:                                                 initengine is called:
        !          3031: 
        !          3032:                                                 pskyoff[0] = 0;
        !          3033:                                                 pskyoff[1] = 0;
        !          3034:                                                 pskybits = 1;
        !          3035: 
        !          3036:                                                 Note that both pskyoff variables are 0 here.  This will
        !          3037:                                                 make the parallaxing sky repeat.
        !          3038: 
        !          3039:                                        With the new tiling, you can save memory by making small
        !          3040:                                                 chuck sizes, such as 64 or 128, and repeating certain
        !          3041:                                                 sections.
        !          3042: ������������������������������������������������������������������������������
        !          3043: 11/25/94  - Fixed some really stupid keyboard problem in Build.
        !          3044: ������������������������������������������������������������������������������
        !          3045: 11/29/94  - Added FLOOR SPRITES!!!  Here are some things that floor sprites
        !          3046:                                        can do for you:
        !          3047: 
        !          3048:                                 * Make bridges and balconies
        !          3049:                                 * Use them for ceiling and floor ornamentation
        !          3050:                                 * Use them in place of a rotating sector - modifying 1 angle
        !          3051:                                                is much faster than rotating tons of points.
        !          3052:                                 * Weapon such as a spinning saw blade or, of course, a smiley
        !          3053:                                                 red jelly coconut. (?)
        !          3054:                                 * How about a "walking" hole like in Ken's Labyrinth
        !          3055:                                 * You could throw a footstep on the floor every time you make a
        !          3056:                                                step.  The steps would go away after awhile.  Maybe if you
        !          3057:                                                step in mud, the next 16 or so footsteps will be plotted.
        !          3058:                                 * You could even fake radial shading with a transluscent floor
        !          3059:                                                sprite. (Transluscent floor sprites not yet programmed)
        !          3060: 
        !          3061:                                         Just imagine all the great stuff you can do with floor
        !          3062:                                 sprites combined with wall sprites!  I can't wait to see what
        !          3063:                                 you all come up with!
        !          3064: 
        !          3065:                          ��� To clear some confusion, and to shorten conversations, let
        !          3066:                          �      me give official names to my 3 kinds of sprites:
        !          3067:                          �
        !          3068:                          �        Normal stupid sprites             - "FACE SPRITES"
        !          3069:                          �        Rotated / masked wall sprites     - "WALL SPRITES"
        !          3070:                          �        New ceiling & floor sprites       - "FLOOR SPRITES"
        !          3071:                          �
        !          3072:                          �   Also let me clear up the 2 kinds of clipping:
        !          3073:                          �
        !          3074:                          �        Clipping when moving something    - "MOVEMENT CLIPPING"
        !          3075:                          ���      Clipping when drawing something   - "VIEW CLIPPING"
        !          3076: 
        !          3077:                                To make a floor sprite in BUILD, simply press 'R' on any
        !          3078:                                        sprite until it becomes a floor sprite.  The xrepeat and
        !          3079:                                        yrepeat values should work perfectly with floor sprites.
        !          3080:                                        Floor sprites can be rotated at any of 2048 degrees, using
        !          3081:                                        the sprite[].ang.  Press < / > for course angle adjustment
        !          3082:                                        or < / > with shift for fine angle adjustment.  Also, you
        !          3083:                                        can press 'F' on a floor sprite to flip it over like a
        !          3084:                                        mirror.  I am using another bit in sprite[].cstat to determine
        !          3085:                                        the type of sprite.  See the documentation in BUILD.H.
        !          3086: 
        !          3087:                                Now for the bad news:
        !          3088: 
        !          3089:                                        * Floor sprite textures have similar restrictions as normal
        !          3090:                                                ceilings and floors - both dimensions must be a power of 2.
        !          3091:                                                This will most likely not change.
        !          3092: 
        !          3093:                                And some known problems which I will have to fix:
        !          3094:                                        * Transluscence doesn't work yet
        !          3095:                                        * Sorting with other sprites
        !          3096:                                        * View clipping with walls
        !          3097:                                        * Doesn't work too well in hi-res mode
        !          3098: 
        !          3099:                                See NUKELAND.MAP for some examples of floor sprites.  I have both
        !          3100:                                        a bridge and a balcony on the level.  Please find them!
        !          3101:                                        Remember that floor sprites don't work in mode x or hi-res
        !          3102:                                        mode YET!
        !          3103: ������������������������������������������������������������������������������
        !          3104: 11/30/94  - Made WALL SPRITE and FLOOR SPRITE correctly do movement clipping.
        !          3105: ������������������������������������������������������������������������������
        !          3106: 12/1/94   - Made new map called BRIDGES.MAP.  It is excellent!  It has 3
        !          3107:                                        bridges all crossing each other.  Enjoy!
        !          3108: 
        !          3109:                         - For Editart, I added re-centering after delete and / to reset
        !          3110:                                        centering while in centering mode.
        !          3111: 
        !          3112:                         - Debugged more of the floor sprite stuff.
        !          3113: ������������������������������������������������������������������������������
        !          3114: 12/2/94   - Made transluscence with floor sprites work.  Check out my fake
        !          3115:                                        radial shading under the lights of SUBWAY.MAP.
        !          3116: 
        !          3117:                         - Optimized floor sprites in assembler.  Transluscent floor sprites
        !          3118:                                        are a bit slower than normal floor sprites.
        !          3119: ������������������������������������������������������������������������������
        !          3120: 12/6/94   - Made a special 1-way mode for WALL and FLOOR sprites 
        !          3121:                                        (not FACE sprites).  In BUILD 3D mode, you can press '1' on
        !          3122:                                        a wall or floor sprite to make it only draw if you are on
        !          3123:                                        1 side of it.  This method of back-face culling will not only
        !          3124:                                        make non-masking objects with thickness draw twice as fast,
        !          3125:                                        but will also make fewer drawing bugs due to sprite drawing
        !          3126:                                        order.  Try out my BRIDGES.MAP.  There's a new section at the
        !          3127:                                        top and it's not another "ugly Ken's face n' slime" room.
        !          3128: ������������������������������������������������������������������������������
        !          3129: 12/8/94   - Editart and Build now capture with capt#### rather than captur##
        !          3130:                                        allowing 10000 captured pictures.
        !          3131: ������������������������������������������������������������������������������
        !          3132: 12/23/94  - Increased Maximum number of walls to 8192.
        !          3133: ������������������������������������������������������������������������������
        !          3134: 12/28/94  - Made BUILD stub keys F5-F8 work in 3D mode also.  See top
        !          3135:                                        of BSTUB.C for full documentation of some new useful
        !          3136:                                        variables that can be used inside the stub:
        !          3137: 
        !          3138:                                                extern long qsetmode;
        !          3139:                                                extern short searchsector, searchwall, searchstat;
        !          3140: 
        !          3141:                                        In 3D mode, F5 and F6 do the exact same thing and F7 and F8
        !          3142:                                                do the exact same thing (you don't need the extra key to
        !          3143:                                                distinguish between sectors, walls and sprites, since the
        !          3144:                                                mouse cursor can only be on 1 of the 3 objects in 3D mode.
        !          3145: 
        !          3146:                                        Note:  Since F5-F8 are called in 3D mode, you must be sure
        !          3147:                                                NOT to use any 2D routines during those calls!  This means
        !          3148:                                                you will have to put the 3D/2D case check in all six
        !          3149:                                                subroutines:
        !          3150:                                                        ExtShowSectorData, ExtShowWallData, ExtShowSpriteData,
        !          3151:                                                        ExtEditSectorData, ExtEditWallData, ExtEditSpriteData
        !          3152: 
        !          3153:                         - KEN'S PROPOSAL (NOT YET DONE)  I am thinking of making a new
        !          3154:                                        (and maybe final) map format.  But before I do it, I am going
        !          3155:                                        to ask all of you for any suggestions on new fields to add to
        !          3156:                                        my 3 big structures (sector, wall, sprite):
        !          3157: 
        !          3158:                                        Here are a few things already on my list to add:
        !          3159: 
        !          3160:                                         * char sprite[].clipdist - THIS IS FOR SURE
        !          3161:                                                         This will be a sprite's clipping distance.  My default
        !          3162:                                                 walldist is 128.  With this field, you will finally be
        !          3163:                                                 able to make a unique fatness for each sprite with no
        !          3164:                                                 clipping bugs.  I will probably shift this field up 2-4
        !          3165:                                                 bits to give it a range of more than just 0-255.
        !          3166: 
        !          3167:                                         * char wall[].pal, sprite[].pal - PRETTY SURE
        !          3168:                                                         It should have been this way the whole time.  Currently
        !          3169:                                                 the wall's palookup number is sector[].floorpal.  While
        !          3170:                                                 it may save some memory, It has too many limitations.
        !          3171:                                                 I can make my map converter automatically convert all
        !          3172:                                                 walls of a sector to equal the sector[].floorpal so
        !          3173:                                                 don't worry about that type of conversion.  If I do
        !          3174:                                                 this, I can get rid of the spritepal[] hack.
        !          3175: 
        !          3176:                                         * I have decided that the sector[].extra, wall[].extra, and
        !          3177:                                                  sprite[].extra will remain in the structures as little
        !          3178:                                                  gifts for your use only.  That's right!  ALL YOURS!
        !          3179:                                                  ENJOY!!!
        !          3180: 
        !          3181:                                         * char sprite[].xoffset, sprite[].yoffset - NOT SURE YET
        !          3182:                                                         Some have asked for monster animations using the same 
        !          3183:                                                 frame at 2 different times of an animation sequence having 
        !          3184:                                                 different centers.
        !          3185:                                                         These will be signed chars.  I'm not sure whether to 
        !          3186:                                                 make these offsets as offsets to the centering information 
        !          3187:                                                 from Editart or just make them the absolute offsets where
        !          3188:                                                 Editart's data is the default offset.  I wonder if there's
        !          3189:                                                 a better way to do this without having to waste 8K.
        !          3190:                                         
        !          3191:                                         * Do I have your permission to remove nextsector2 and
        !          3192:                                                        nextwall2?  Anybody using them?  If so, can you use the
        !          3193:                                                        extra variable instead?  This will save 16K since both
        !          3194:                                                        are shorts.  (MAXWALLS*short + MAXWALLS*short = 16384)
        !          3195:                                                They were originally intended for 2 stories
        !          3196:                                                        but it would be totally ridiculous for me even to think
        !          3197:                                                        about programming that now.  Besides, you can use wall
        !          3198:                                                        and floor sprites to fake 2 story areas.  KEN PROMISE:
        !          3199:                                                        I will fix those darn view-clipping bugs eventually!
        !          3200: 
        !          3201: 
        !          3202:                                         Please send any comments/suggestions to my internet address
        !          3203:                                                 ([email protected])  I will consider each suggestion
        !          3204:                                                 carefully, because everything you suggest now won't have
        !          3205:                                                 to be an ugly hack like spritepal[] later.
        !          3206: ������������������������������������������������������������������������������
        !          3207: 1/1/95    - ����� ������ ���  �� ��   �� ��    �� ������ ������ ������ ��
        !          3208:                                ��    ��  �� ���� �� ��   �� �������� ��  �� ��  �� ��     ��
        !          3209:                                ��    ��  �� ������� ��� ��� �������� ������ ������ ������ ��
        !          3210:                                ��    ��  �� �� ����  �����  ��    �� ��  �� ��     ��  ��
        !          3211:                                ����� ������ ��  ���   ���   ��    �� ��  �� ��     ������ ��
        !          3212: 
        !          3213:                                CONVMAP6!  Here is what I changed in the structures:
        !          3214: 
        !          3215:                                        * Added wall[].pal, sprite[].pal
        !          3216:                                        * Added sprite[].clipdist
        !          3217:                                        * Expanded sprite[].cstat to a short
        !          3218:                                        * Added sprite[].xoffset, sprite[].yoffset
        !          3219:                                        * Removed wall[].nextsector2, wall[].nextwall2
        !          3220:                                        * Renamed wall[].nextsector1 to just wall[].nextsector
        !          3221:                                        * Renamed wall[].nextwall1 to just wall[].nextwall
        !          3222:                                        * Scrapped numextras and extratype structure - Don't confuse
        !          3223:                                                  this with sector[].extra, wall[].extra, sprite[].extra
        !          3224:                                                  which ARE in map version 6.
        !          3225: 
        !          3226:                                Probably the only change above that will affect programmers is
        !          3227:                                        getting rid of the '1' in wall[].nextsector1&wall[].nextwall1.
        !          3228:                                        All the following changes were possible because of the new
        !          3229:                                        map format.
        !          3230: 
        !          3231:                         - Got rid of the spritepal array in BUILD.H.  With my grea
        !          3232:                                        new map version 6, you can simply modify sprite[].pal!
        !          3233: 
        !          3234:                         - Made all .pal fields editable in 3D EDIT MODE.  Press ALT-P
        !          3235:                                        and simply edit the number as you would in 2D mode.
        !          3236: 
        !          3237:                         - Made sprite[].xoffset and sprite[].yoffset work as
        !          3238:                                        offsets to the offsets that are already in EDITART.
        !          3239:                                        Simple addition.  They should work for all 3 types
        !          3240:                                        of sprites.
        !          3241: 
        !          3242:                         - Made BUILD Tab&Enter also copy tags&extra if copying similar
        !          3243:                                        structures.  Also fixed some other attributes when
        !          3244:                                        copying between structure types.
        !          3245: 
        !          3246:                         - Made sprites highlighted with Rt. Shift duplicate and stamp
        !          3247:                                        when the insert key is pressed in 2D EDIT MODE.
        !          3248: 
        !          3249:                         - Made sprite[].clipdist work as the FACE SPRITE'S clipping
        !          3250:                                        fatness.  NOTE:  Sprite[].clipdist is shifted up 2 to
        !          3251:                                        allow a range from 0-1020, so if the sprite[].clipdist
        !          3252:                                        is set to 32, then the clipping radius is actually 128.
        !          3253: 
        !          3254:                         - Removed the walldist parameter from movesprite.  Movesprite
        !          3255:                                        now just uses the sprite[spritenum].clipdist field of
        !          3256:                                        whatever sprite is passed (shifted up 2).
        !          3257: 
        !          3258:                                movesprite(short spritenum, long xchange, long ychange,
        !          3259:                                                          long zchange, long ceildist, long flordist,
        !          3260:                                                          char cliptype, long numtics)
        !          3261: 
        !          3262:                                        If you use clipmove or getzrange, you should check that you
        !          3263:                                                are passing the correct walldist parameters.  I'm saying
        !          3264:                                                you may want to change some of the 128s to
        !          3265:                                                (sprite[spritenum].clipdist<<2).
        !          3266: ������������������������������������������������������������������������������
        !          3267: 1/3/95    - Made startumost[], startdmost[] into shorts.
        !          3268: 
        !          3269:                         - Optimized and fixed gamma correction in Stereo Red-Blue mode.
        !          3270: 
        !          3271:                         - Made weapons or anything using overwritesprite in Stereo Red-Blue
        !          3272:                                        mode be at screen depth.
        !          3273: ������������������������������������������������������������������������������
        !          3274: 1/4/95    - Not that anybody would care (except for some crazed mega-hackers)
        !          3275:                                        but I am just mentioning the fact that I did this:
        !          3276: 
        !          3277:                                        animateoffs(short tilenum, short fakevar);
        !          3278:                                                where fakevar is sectnum+0
        !          3279:                                                                                  or wallnum+16384
        !          3280:                                                                                  or spritenum+32768
        !          3281:                                                                                  or 49152 (just ignore-it's for rotatesprite)
        !          3282: 
        !          3283:                                        Also:  I changed one: "mov al, 0" instruction into an
        !          3284:                                                                                                 "xor al, al", a net savings of
        !          3285:                                                                                                 ONE LOUSY BYTE!  Let's not get TOO
        !          3286:                                                                                                 excited! (By the way, just kidding)
        !          3287: ������������������������������������������������������������������������������
        !          3288: 1/5/95    - Fixed the sprite centering with x-flipped FACE SPRITES.
        !          3289: 
        !          3290:                         - Found a bug with my swinging door clipping code.  There are 2
        !          3291:                                        types of swinging doors, forwards (opens CCW) and
        !          3292:                                        backwards (opens CW).  The bug was that you could sneak
        !          3293:                                        through a backwards door from the back side.  Well, I fixed
        !          3294:                                        it, so now I challenge you to sneak through my swinging doors
        !          3295:                                        now!  If you are using my swinging door code, please make
        !          3296:                                        these changes which you should find in my new GAME.C:
        !          3297: 
        !          3298:                                 1.  Changed declaration at beginning of GAME.C:
        !          3299:                                          static short swingwall[32][5];
        !          3300: 
        !          3301:                                 2.  Added new line in prepareboard:
        !          3302:                                          swingwall[swingcnt][4] = lastwall(swingwall[swingcnt][3]);
        !          3303: 
        !          3304:                                 3.  Modified some stuff in tagcode:
        !          3305:                                                         //swingangopendir is -1 if forwards, 1 is backwards
        !          3306:                                                 l = (swingangopendir[i] > 0);
        !          3307:                                                 for(k=l+3;k>=l;k--)
        !          3308:                                                         if...
        !          3309: 
        !          3310:                         - Here are some more functions that have been in the engine for
        !          3311:                                        a while, but I forgot to document...
        !          3312:                                                precache, loadtile, lastwall, rotatepoint
        !          3313:                                        They are now documented at the top of this file.
        !          3314: ������������������������������������������������������������������������������
        !          3315: 1/6/95    - Optimized loading/saving of maps by using fewer read/write calls.
        !          3316: ������������������������������������������������������������������������������
        !          3317: 1/14/95   - Fixed evil crashing bug that I accidently introduced in the
        !          3318:                                        1/3/95 version of Build.  This crashing bug happened mostly
        !          3319:                                        in tall rooms with lots of FACE SPRITES.  It used to crash
        !          3320:                                        very infrequently when you were standing almost exactly, but
        !          3321:                                        NOT on the same x & y coordinates of a FACE SPRITE where the
        !          3322:                                        z-distance was high.
        !          3323: ������������������������������������������������������������������������������
        !          3324: 1/15/95   - Fixed up network code so now you can miss 4 packets in row safely
        !          3325:                                        over the network rather than just 2.
        !          3326: ������������������������������������������������������������������������������
        !          3327: 1/16/95   - Added strafe left / strafe right keys to my SETUP.DAT file and
        !          3328:                                        char keys[19] array.  If you actually use my keys array for
        !          3329:                                        custom keys, here's what to do:  I inserted the new strafing
        !          3330:                                        keys at keys[12] & keys[13], so just add 2 to any keys with
        !          3331:                                        an index >= 12.
        !          3332: 
        !          3333:                         - Made the sprites in 2D EDIT MODE of Build highlight properly
        !          3334:                                        again.
        !          3335: 
        !          3336:                         - Added another parameter to permanentwritesprite, palookup number:
        !          3337: 
        !          3338:                                  permanentwritesprite(long thex, long they, short tilenum,
        !          3339:                                                                                          signed char shade, long cx1, long cy1,
        !          3340:                                                                                          long cx2, long cy2, char dapalnum);
        !          3341: ������������������������������������������������������������������������������
        !          3342: 1/17/95   - You can now select a bunch of sprites in 2D EDIT MODE with
        !          3343:                                        Rt. shift, then go to 3D mode and change the z's of all the
        !          3344:                                        highlighted sprites.
        !          3345: ������������������������������������������������������������������������������
        !          3346: 1/20/95   - Made Tab&Enter in 3D EDIT MODE copy .pal also whenever .shade is
        !          3347:                                        normally copied.  Shift+Enter will now copy just
        !          3348:                                        .pal and .shade.
        !          3349: ������������������������������������������������������������������������������
        !          3350: 1/21/95   - Made Splitsector work with overlapping better.
        !          3351: 
        !          3352:                         - In Editart 'U' mode, it now goes automatically to the PCX and
        !          3353:                                        coordinates of a tile if it is already in capfil.txt.
        !          3354: 
        !          3355:                         - In Editart, made capt????.PCX not get overwritten if they already
        !          3356:                                        exist.
        !          3357: 
        !          3358:                         - Fixed Build tab on masked walls.
        !          3359: 
        !          3360:                         - Made zmode and kensplayerheight variables public in BUILD/BSTUB
        !          3361:                                        so you can now compile BUILD to start out with your own
        !          3362:                                        preferred settings.  Kensplayerheight defaults to 32 and
        !          3363:                                        zmode defaults to 0.  You can over-ride these settings in
        !          3364:                                        the new ExtInit function.
        !          3365: 
        !          3366:                         - Made Editart tiles much easier to center by showing all tiles
        !          3367:                                        in the center of the screen instead of at the top-left corner.
        !          3368:                                        (Editart will not allow you to center tiles larger than
        !          3369:                                         320*200 right now)
        !          3370: 
        !          3371:                         - Made 'O' (optimize) key in Editart automatically preserve
        !          3372:                                        the centering information.
        !          3373: 
        !          3374:                         - ATTENTION BSTUB PROGRAMMERS!  Added ExtInit, ExtUnInit, and
        !          3375:                                        ExtCheckKeys to BSTUB.C.  Please just copy mine into your
        !          3376:                                        current BSTUB.  ExtInit and ExtUnInit are called only once.
        !          3377:                                        ExtInit is called before loadpics() and after initengine().
        !          3378:                                        ExtCheckKeys() is called just before nextpage in both 2D
        !          3379:                                        and 3D modes.  In 3D mode, you must call editinput inside
        !          3380:                                        ExtCheckKeys just like my example in BSTUB.
        !          3381: ������������������������������������������������������������������������������
        !          3382: 1/24/95   - Fixed vertical line chained mode bug with permanentwritesprites.
        !          3383: ������������������������������������������������������������������������������
        !          3384: 1/31/95   - Fixed parallaxing sky tiling bug.
        !          3385: ������������������������������������������������������������������������������
        !          3386: 2/1/95    - Fixed network crashing bug when call interrupt 0x1c.  You call
        !          3387:                                        this interrupt when you chain to the old timer handler.  Now
        !          3388: 
        !          3389:                         - Rewrote multiplayer code in game.c a bit.  Moved both sync()
        !          3390:                                        and getpackets() into the main program.  The master code and
        !          3391:                                        single player game code are now the same.  Slaves need to
        !          3392:                                        drawscreen and send packets only when a packet is received
        !          3393:                                        from the master.  Got rid of fake sync[MAXPLAYERS] slot by
        !          3394:                                        using a local sync buffers.  Rewrote checkmasterslaveswitch().
        !          3395:                                        If you don't get what I did, it doesn't matter because you
        !          3396:                                        already have working network code!
        !          3397: 
        !          3398:                         - Added new key in EDITART 'V' mode.  Press ALT-R to generate
        !          3399:                                        a tile frequency report.  It will scan all MAP files in the
        !          3400:                                        same directory as the ART files.  The frequency count will
        !          3401:                                        show up as text in the top-left corner of the boxes in
        !          3402:                                        'V' mode.  Press ALT-R again to turn off text.
        !          3403: 
        !          3404:                         - Perfected NCOPY!  Copies about 150K / second which is 10 times
        !          3405:                                        faster than a 115200bps serial cable.  Since NCOPY already
        !          3406:                                        links with multi.obj, it should not be too difficult to make
        !          3407:                                        joining work in the middle of a network game.  Please wait
        !          3408:                                        until I make some sample code for you!
        !          3409:                                                Receiver types:  NCOPY             (Ex: "NCOPY")
        !          3410:                                                Sender types:    NCOPY [filespec]  (Ex: "NCOPY *.ART")
        !          3411: 
        !          3412:                                        Ken's formula:
        !          3413:                                                NCOPY + Loading&Saving GAMES = joining in middle
        !          3414:                                                                                                                                 of network game!
        !          3415: 
        !          3416:                         - Made a DOOM to BUILD converter.  Right now it only converts
        !          3417:                                        ceilings, floors, and walls now, and some of the wall
        !          3418:                                        textures are screwed up.  Just because I converted some
        !          3419:                                        lousy stinkin' maps DOES NOT MEAN I AM GOING TO PROGRAM DOOM!
        !          3420:                                        Unfortunately, the converter is programmed in QuickBasic right
        !          3421:                                        now, it won't compile, and I didn't feel like putting up the
        !          3422:                                        7 MEG converted ART file up.  When I convert it to C, I'll
        !          3423:                                        upload it for all!
        !          3424: ������������������������������������������������������������������������������
        !          3425: 2/7/95    - Fixed overwritesprite bugs with translucence in chained mode
        !          3426:                                        and above top of screen.
        !          3427: 
        !          3428:                         - Made bit 3 of overwritesprite x-flip the picture if set.
        !          3429: 
        !          3430:                         - Optimized various parts of engine.
        !          3431: ������������������������������������������������������������������������������
        !          3432: 2/8/95    - Fixed shading of all sprite types so they match perfectly with
        !          3433:                                        their surroundings.  Floor sprites now shade in the exact same
        !          3434:                                        way as ceilings and floors.  (Before, the whole floor sprite
        !          3435:                                        had the same shade throughout)
        !          3436: ������������������������������������������������������������������������������
        !          3437: 2/9/95    - Started on loading and saving game code so I could give some
        !          3438:                                        sample code for joining network games, but none of it works
        !          3439:                                        yet, so just ignore it for now!
        !          3440: 
        !          3441:                         - Added frame rate in BSTUB.C.  It averages the last 16 frames.
        !          3442: ������������������������������������������������������������������������������
        !          3443: 2/16/95   - Added another bit to sprite[].cstat for y-centering control.  If
        !          3444:                                        bit 7 is set then the sprite's center will be the actual
        !          3445:                                        center rather then at the default position which is at the
        !          3446:                                        bottom of the sprite.  If you use this centering bit,
        !          3447:                                        you finally get "WYSIWYG" centering contol in EDITART.
        !          3448: ������������������������������������������������������������������������������
        !          3449: 2/24/95   - Made floor sprites now support any x size by a power of 2 y size.
        !          3450:                                        (That's better than before!)  These are the same restrictions
        !          3451:                                        on walls.
        !          3452: ������������������������������������������������������������������������������
        !          3453: 2/25/95   - Got loading / saving code to work with my game.  Press Ctrl-L to
        !          3454:                                  load game and Ctrl-S to save game.  Saved games are called
        !          3455:                                  SAVE0000.GAME and are about 300K.  Don't worry about the large
        !          3456:                                  sizes of the saved game files since they can be easily
        !          3457:                                  compressed to less than 50K.
        !          3458: ������������������������������������������������������������������������������
        !          3459: 2/26/95   - I Finally made my multiplayer code run with fast frame rates AND
        !          3460:                                        pefect controls on ALL computers of a multiplayer game.  I am
        !          3461:                                        now sending keystrokes of all computers at a constant rate of
        !          3462:                                        40 times per second.  All computers interpolate between frames
        !          3463:                                        to get screen frame rates of higher or lower than 40 fps
        !          3464:                                        (even in single player mode).
        !          3465: 
        !          3466:                                Here are the exact steps you will need to follow if you want to
        !          3467:                                        update your code:
        !          3468: 
        !          3469:                                        1.  WHAT'S THE FAKETIMERHANDLER()?
        !          3470: 
        !          3471:                                                         To send packets exactly 40 times a second, it would
        !          3472:                                                 sure be nice to send them right from the timer interrupt
        !          3473:                                                 handler.  Too bad network packets just won't get sent
        !          3474:                                                 from the interrupt handler.  (It may work from the
        !          3475:                                                 interrupt handler in Serial/Modem mode)  So the solution
        !          3476:                                                 is to make a "fake" timer handler that must be called
        !          3477:                                                 at least 40 times a second even on the slowest computer.
        !          3478:                                                 Throughout my engine, I call faketimerhandler().  If you
        !          3479:                                                 have any slow parts in your game code, you may want to
        !          3480:                                                 called faketimerhandler() also.
        !          3481:                                                         Besides the very first few lines, the rest of the code
        !          3482:                                                 was taken directly from my old sync and getpackets
        !          3483:                                                 functions.
        !          3484: 
        !          3485:                                        2. BYE BYE SYNCTICS!
        !          3486: 
        !          3487:                                                         Now that all computers are calling movethings a
        !          3488:                                                 constant number of times a second, you don't need any
        !          3489:                                                 synctics variables anymore.  You can convert all the
        !          3490:                                                 synctics variables to a define such as:
        !          3491:                                                         "#define TICSPERFRAME 3"
        !          3492:                                                 Doing this will guarantee that a game runs the same on
        !          3493:                                                 all speed computers.
        !          3494: 
        !          3495:                                        3. FRAME INTERPOLATION (optional):
        !          3496: 
        !          3497:                                                 static long ototalclock = 0, gotlastpacketclock = 0;
        !          3498:                                                 static long oposx[MAXPLAYERS], cposx[MAXPLAYERS];
        !          3499:                                                 static long oposy[MAXPLAYERS], cposy[MAXPLAYERS];
        !          3500:                                                 static long oposz[MAXPLAYERS], cposz[MAXPLAYERS];
        !          3501:                                                 static long ohoriz[MAXPLAYERS], choriz[MAXPLAYERS];
        !          3502:                                                 static long ozoom[MAXPLAYERS], czoom[MAXPLAYERS];
        !          3503:                                                 static short oang[MAXPLAYERS], cang[MAXPLAYERS];
        !          3504: 
        !          3505:                                                 Add to prepareboard:
        !          3506:                                                         for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3507:                                                         {
        !          3508:                                                                 oposx[i] = posx[i];
        !          3509:                                                                 oposy[i] = (etc.)
        !          3510:                                                         }
        !          3511:                                                         ototalclock = 0;
        !          3512:                                                         gotlastpacketclock = 0;
        !          3513: 
        !          3514:                                                 Even though you may be getting more than 40fps, you will
        !          3515:                                         only be seeing 40fps unless you interpolate between frames.
        !          3516:                                         The oposx[], etc. variables back up the last posx[], etc.
        !          3517:                                         variables so you can interpolate your actually drawing
        !          3518:                                         position as some fraction between the two.  This fraction
        !          3519:                                         is smoothratio.
        !          3520:                                                 See beginning of drawscreen code.  Here's where I actually
        !          3521:                                         calculate the interpolated position to draw the screen.
        !          3522: 
        !          3523:                                                for(i=connecthead;i>=0;i=connectpoint2[i])
        !          3524:                                                {
        !          3525:                                                        cposx[i] = oposx[i]+mulscale(posx[i]-oposx[i],smoothratio,16);
        !          3526:                                                        cposy[i] = oposy[i]+mulscale(posy[i]-oposy[i],smoothratio,16);
        !          3527:                                                        cposz[i] = oposz[i]+mulscale(posz[i]-oposz[i],smoothratio,16);
        !          3528:                                                        choriz[i] = ohoriz[i]+mulscale(horiz[i]-ohoriz[i],smoothratio,16);
        !          3529:                                                        czoom[i] = ozoom[i]+mulscale(zoom[i]-ozoom[i],smoothratio,16);
        !          3530:                                                        cang[i] = oang[i]+mulscale(((ang[i]+1024-oang[i])&2047)-1024,smoothratio,16);
        !          3531:                                                }
        !          3532: 
        !          3533:                                                Draw the screen using cposx[], etc. instead of posx[], etc.
        !          3534: 
        !          3535:                                                #pragma aux mulscale =\
        !          3536:                                                         "imul ebx",\
        !          3537:                                                         "shrd eax, edx, cl",\
        !          3538:                                                         parm [eax][ebx][ecx]\
        !          3539:                                                         modify [edx]\
        !          3540: 
        !          3541:                                                         It reads: eax = (eax*ebx)>>cl.  Unlike C, this will
        !          3542:                                                not overflow even if eax*ebx > 2^31, making full use of
        !          3543:                                                the 64-bit result of the imul instruction.
        !          3544: 
        !          3545:                                        4. MOVETHINGS FIFO:
        !          3546: 
        !          3547:                                                 static long movefifoplc, movefifoend;
        !          3548:                                                 static signed char baksyncvel[64][MAXPLAYERS];
        !          3549:                                                 static signed char baksyncsvel[64][MAXPLAYERS];
        !          3550:                                                 static signed char baksyncangvel[64][MAXPLAYERS];
        !          3551:                                                 static short baksyncbits[64][MAXPLAYERS];
        !          3552: 
        !          3553:                                                 Add to prepareboard: movefifoplc = 0; movefifoend = 0;
        !          3554: 
        !          3555:                                                 It is bad to call movethings inside faketimerhandler
        !          3556:                                         because you don't want things to move while you're drawing
        !          3557:                                         the screen.  To solve this, I made movethings just save
        !          3558:                                         away the parameters it was called with using a circular
        !          3559:                                         buffer, and when I'm actually ready to DO the movement code,
        !          3560:                                         I call domovethings.
        !          3561:                                                 Rename movethings to domovethings and see my new
        !          3562:                                         movethings.  This code is all for the fifo.
        !          3563: 
        !          3564:                                                Put this line in movethings:
        !          3565:                                                        gotlastpacketclock = totalclock;
        !          3566: 
        !          3567:                                                At the top of domovethings, copy my code for loading off
        !          3568:                                                        of the fifo.  Also set oposx[] = posx[], etc. here.
        !          3569: 
        !          3570:                                        5. You may want to add a global variable that controls whether
        !          3571:                                                  you are in continuous packet sending mode or not.  Only
        !          3572:                                                  in the main loop should ready2send be != 0.
        !          3573:                                                 static long ready2send = 0;
        !          3574: 
        !          3575:                                        6. The new main loop can be as short as this, with no case
        !          3576:                                                        checking for masters and slaves.
        !          3577: 
        !          3578:                                                ready2send = 1;
        !          3579:                                                while (keystatus[1] == 0)       //Main loop starts here
        !          3580:                                                {
        !          3581:                                                                //Actaully move everything here.
        !          3582:                                                        while (movefifoplc != movefifoend) domovethings();
        !          3583: 
        !          3584:                                                                //Second parameter is for frame interpolation,
        !          3585:                                                                //A fraction that ranges from 0-65536.
        !          3586:                                                        drawscreen(screenpeek,(totalclock-gotlastpacketclock)*(65536/TICSPERFRAME));
        !          3587:                                                }
        !          3588:                                                ready2send = 0;
        !          3589: ������������������������������������������������������������������������������
        !          3590: 3/6/95    - New key in BUILD.  Now when you use relative alignment mode on
        !          3591:                                        ceiling and floor textures, you can press Alt-F on the ceiling
        !          3592:                                        or floor to choose a new wall to align to.  It actually
        !          3593:                                        rotates the walls of a sector by 1.
        !          3594: 
        !          3595:                         - Fixed screen capture PCX saving bug in both EDITART and BUILD.
        !          3596: 
        !          3597:                         - Added a parameter to screencapture, a filename.
        !          3598:                                        screencapture(char *filename)
        !          3599:                                        Ex: screencapture("captxxxx.pcx");
        !          3600:                                        Please specify the full filename.  Screencapture will modify
        !          3601:                                        the 4 x's of the string to be a number starting at 0000.
        !          3602: ������������������������������������������������������������������������������
        !          3603: 3/8/95    - Made my rotatesprite function use Editart centering information.
        !          3604:                                        The center is the pivot point of rotation.
        !          3605: 
        !          3606:                         - Added y-flipping to overwritesprite.  See above documentation.
        !          3607: 
        !          3608:                         - Added 2 new parameters to rotatesprite, shade and pal
        !          3609: 
        !          3610:                                 rotatesprite (long sx, long sy, long z, short a,
        !          3611:                                                        short picnum, signed char shade, char pal);
        !          3612: 
        !          3613: ������������������������������������������������������������������������������
        !          3614: 3/10/95   - Fixed sprite showing through closed sectors bug.
        !          3615: 
        !          3616:                         - Made it possible to draw the overhead map in 3D mode by adding
        !          3617:                                  a line drawing function in 3D mode called drawline256.  It
        !          3618:                                  draws a line clipped to the viewing rectangle last set in
        !          3619:                                  setview().  Here are the parameters:
        !          3620: 
        !          3621:                                  drawline256(long x1, long y1, long x2, long y2, char col);
        !          3622: 
        !          3623:                                  Note:  The coordinates are all shifted up 12.
        !          3624:                                          Example: drawline256(0L,0L,319L<<12,199L<<12,31);
        !          3625: ������������������������������������������������������������������������������
        !          3626: 3/11/95   - Made drawline256 draw in a cleaner way, making use of the full
        !          3627:                                        12 bits of precision.
        !          3628: ������������������������������������������������������������������������������
        !          3629: 3/14/95   - Optimized / cleaned up parts of hitscan, neartag, cansee.
        !          3630:                                        Gee, I hope they all still work!
        !          3631: ������������������������������������������������������������������������������
        !          3632: 3/18/95   - I'm back in RI!
        !          3633: 
        !          3634:                         - Fixed recently added movesprite z parameter bug that may have
        !          3635:                                        done strange things with monsters, such as stuck in sectors
        !          3636:                                        I thought the following expression:  !(cstat&128)
        !          3637:                                        would be true if bit 7 was a 0, but I WAS WRONG!
        !          3638:                                        Get this straight:
        !          3639:                                                ! - logical NOT, returns 0 if != 0 else 1 (!2457=0, !0=1)
        !          3640:                                                ~ - bitwise NOT, xor's it with 0xffffffff (~0x5f=0xa0)
        !          3641: ������������������������������������������������������������������������������
        !          3642: 3/21/95   - Gave access to some more variables in BSTUB.
        !          3643: 
        !          3644:                         - Made clipmove return a valid sector even if you're not between
        !          3645:                                        its ceiling and floor.  If you use overlapping sectors,
        !          3646:                                        clipmove will find the sector closest to your z.
        !          3647: ������������������������������������������������������������������������������
        !          3648: 3/28/95   - Optimized transluscence for masked walls and wall sprites.
        !          3649: 
        !          3650:                         - Today is the day I declare my serial/modem error correction code
        !          3651:                                        perfect!  Sure, I may have bragged over and over again about
        !          3652:                                        how perfect my correction method is each time, but this time
        !          3653:                                        I mean it.  This is ship-it quality error correction.  The old
        !          3654:                                        method had a few dark, evil, and ugly bugs that sometimes
        !          3655:                                        totally screwed up bigtime.
        !          3656: ������������������������������������������������������������������������������
        !          3657: 4/5/95    - Got Master/Slave switching to stay in sync again with new
        !          3658:                                        multiplayer code.  Right after the master sends a packet
        !          3659:                                        where a switch is made, I disable the master from sending
        !          3660:                                        any more packets by setting ready2send to 0.  Ready2send
        !          3661:                                        will be set back to 1 only after the actual switch in
        !          3662:                                        checkmasterslaveswitch.  Here's what I added to movethings:
        !          3663: 
        !          3664:                                                  //Do this for Master/Slave switching
        !          3665:                                          for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i])
        !          3666:                                                  if (syncbits[i]&512) ready2send = 0;
        !          3667: ������������������������������������������������������������������������������
        !          3668: 4/10/95   - Optimized continuous setview calls between 2 different window
        !          3669:                                sizes.
        !          3670: 
        !          3671:                         - ATTENTION PROGRAMMERS:  Moved movesprite code into game.c.  It
        !          3672:                                  no longer exists in the engine.  It is a "cover-up" function
        !          3673:                                  and it should be yours.
        !          3674: 
        !          3675:                         - Added a circular keyboard buffer to my keyboard handler.  It is
        !          3676:                                  fully compatible with the keystatus arrays.  Use this buffer
        !          3677:                                  for typing in messages or cheat codes.  If you do not use this
        !          3678:                                  buffer (or you wrote your own interrupt handler), you will miss
        !          3679:                                  keys and it is very annoying.
        !          3680: 
        !          3681:                                  I added these variables to build.h:
        !          3682: 
        !          3683:                                  #define KEYFIFOSIZ 64
        !          3684:                                  EXTERN volatile char keyfifo[KEYFIFOSIZ],
        !          3685:                                                                                          keyfifoplc, keyfifoend;
        !          3686: 
        !          3687:                                  Every time a key is pressed and released, I add 2 bytes to the
        !          3688:                                  circular buffer.  The first byte is the scan code.  The second
        !          3689:                                  byte is a 1 for key pressed or 0 for key released.  You can
        !          3690:                                  ignore the key releases if you wish.  You must read 2 bytes at
        !          3691:                                  a time from this buffer.
        !          3692:                                          (scancode,keystat),(scancode,keystat),...
        !          3693: 
        !          3694:                                  Here's how you read the keyboard fifo:
        !          3695:                                                while (keyfifoplc != keyfifoend) //More characters to read
        !          3696:                                                {
        !          3697:                                                        ch = keyfifo[keyfifoplc];
        !          3698:                                                        keystate = keyfifo[(keyfifoplc+1)&(KEYFIFOSIZ-1)];
        !          3699:                                                                //Increment buffer pointer
        !          3700:                                                        keyfifoplc = ((keyfifoplc+2)&(KEYFIFOSIZ-1));
        !          3701: 
        !          3702:                                                        printf("Scancode: %d, status: %d\n",ch,keystate);
        !          3703:                                                }
        !          3704: 
        !          3705:                                  The interrupt handler does the same as above but writes and
        !          3706:                                          increments using keyfifoend as the index.
        !          3707:                                  You can easily clear the buffer this way:
        !          3708:                                          keyfifoplc = keyfifoend
        !          3709: 
        !          3710:                         - Made clipmove/getzrange not clip on the back side of a 1-sided
        !          3711:                                        wall/floor sprite.  It makes the clipping a little faster
        !          3712:                                        and seems to fix a few minor clipping bugs.  Don't get too
        !          3713:                                        excited.
        !          3714: 
        !          3715:                         - Fixed getzrange's ceilz/florz mismatch with floor sprites against
        !          3716:                                        normal ceilings and floors.
        !          3717: 
        !          3718:                         - Made Build default to y-centered centering mode when sprites
        !          3719:                                        are inserted (bit 7 of sprite[].cstat)
        !          3720: 
        !          3721:                         - Fixed clipmove bugs with y-centered centering mode.
        !          3722: 
        !          3723:                         - Made it so you don't get stuck sliding along multiple properly
        !          3724:                                        aligned wall/floor sprites.
        !          3725: 
        !          3726:                         - Please update to my new tables.dat.
        !          3727: ������������������������������������������������������������������������������
        !          3728: 4/11/95   - Optimized parts of clipmove / getzrange.  Is it faster?  Did I
        !          3729:                                        make more bugs?
        !          3730: 
        !          3731:                         - Made the movesprite code in GAME.C now use getzrange.  This
        !          3732:                                        allows sprites to walk on floor sprites and bombs roll across
        !          3733:                                        bridges.  I will include the original movesprite code that
        !          3734:                                        came from the engine in case you want to start with things
        !          3735:                                        the way they used to be.
        !          3736: 
        !          3737:                         - Made ornamentation in BUILD 3D mode much easier.  Now you can
        !          3738:                                         press 'S' to insert a sprite on walls (not just ceilings
        !          3739:                                         and floors).  When you insert a sprite on a wall, it will
        !          3740:                                         automatically be set to a wall sprite at the wall's angle.
        !          3741:                                         Also it will be 1-sided with blocking off (The optimal
        !          3742:                                         options for a decorative sprite on a wall).
        !          3743: 
        !          3744:                         - Added ALT-D to BUILD 3D mode.  It lets you type in clipdist
        !          3745:                                         for sprites.  It works in the same way as ALT-P for palookup
        !          3746:                                         changing.
        !          3747: 
        !          3748: ������������������������������������������������������������������������������
        !          3749: 4/15/95   - Fixed return value bug in setanimation and cleaned up these 3
        !          3750:                                functions:  doanimations, getanimationgoal, setanimation.
        !          3751:                                Since they are now in game.c, you will need to copy them to
        !          3752:                                update.
        !          3753: ������������������������������������������������������������������������������
        !          3754: 4/16/95   - Fixed hitscan not passing through loops bug.
        !          3755: 
        !          3756:                         - Fixed hitscan so it hits wall and floor sprites in the right
        !          3757:                                places.
        !          3758: 
        !          3759:                         - ATTENTION PROGRAMMERS!!!  Made bit 8 of sprite[].cstat the
        !          3760:                                hitscan clipping bit.  It works like the hitscan bit for walls.
        !          3761:                                Note that both the wall and sprite cstat variables now have
        !          3762:                                2 separate bits for clipping, where:
        !          3763:                                         1 is for use with the clipmove/getzrange function and
        !          3764:                                         1 is for use with the hitscan function only.
        !          3765:                                Before, hitscan used to use 1 bit for all sprite clipping.
        !          3766:                                In your maps, the sprite hitscan bits are all zeros.  That's bad!
        !          3767:                                To make things work like they used to, the sprite hitscan bit
        !          3768:                                must be set equal to the old sprite blocking bit.  So I was nice
        !          3769:                                enough to make a program, FIXSPRBT.EXE, which will do just that.
        !          3770: 
        !          3771:                                PLEASE RUN FIXSPRBT.EXE ON ALL YOUR MAPS.  You don't HAVE to
        !          3772:                                run it on all your maps since the map format hasn't changed, but
        !          3773:                                it will save you annoying attribute setting time if you do.
        !          3774: 
        !          3775:                         - Did a few things to make these blocking bits easier to edit:
        !          3776:                                Since H and ALT-H were already used, I made CTRL-H toggle the
        !          3777:                                hitscan bit for both walls and sprites in 2D mode.  B toggles
        !          3778:                                the blocking bit.  B also now sets the hitscan bit to its
        !          3779:                                default value when you press it.  For sprites, the hitscan bit
        !          3780:                                default is equal to the clipmove bit.  For walls, the hitscan
        !          3781:                                bit default is always 0.
        !          3782: 
        !          3783:                         - Added new map mode!  Check it out in my game.  I now have 3 map
        !          3784:                                modes.  Not that this really matters to you game programmers, but
        !          3785:                                this is how my game works:
        !          3786:                                                dimensionmode[snum] == 1   3D MODE + junky line map
        !          3787:                                                dimensionmode[snum] == 2   SUPER MAP!
        !          3788:                                                dimensionmode[snum] == 3   3D MODE
        !          3789: 
        !          3790:                                        I added show2dsector to BUILD.H which controls which works
        !          3791:                                        like the other show2d... bit arrays.  It tells which sectors
        !          3792:                                        to show.
        !          3793:                                                EXTERN char show2dsector[MAXSECTORS>>3];
        !          3794: 
        !          3795:                                        I rewrote parts of drawoverheadmap to accommodate this new
        !          3796:                                        mode - so it would be nice if you updated to my new code.
        !          3797: 
        !          3798:                                        Added a new function that clears full screen to a specified
        !          3799:                                        color:
        !          3800:                                                clearview(0L);
        !          3801: 
        !          3802:                                        Oh and did I forget to mention the big function!  Parameters
        !          3803:                                        are the exact same my drawoverheadmap function:
        !          3804:                                                drawmapview(cposx,cposy,czoom,cang);
        !          3805: 
        !          3806:                                        Note:  The new map mode right now is slowed down bigtime by
        !          3807:                                                the face sprites using the rotatesprite function.  The
        !          3808:                                                rotatesprite right now is using a worse than awful
        !          3809:                                                algorithm.  When I optimize rotatesprite, the frame rate
        !          3810:                                                of the new map mode will fly!
        !          3811: ������������������������������������������������������������������������������
        !          3812: 4/18/95   - Added default sprite cstat variable when you insert new sprites.
        !          3813:                                        Set it to 0 if you hate the new centering mode in ExtInit
        !          3814:                                                  or 128 if you like the new centering mode.
        !          3815:                                        Add this line to your Bstub if you wish:
        !          3816:                                                extern short defaultspritecstat;
        !          3817: 
        !          3818:                         - If a wall & sprite are same distance away using hitscan, hitscan
        !          3819:                                        now chooses the sprite.
        !          3820: 
        !          3821:                         - Optimized rotatesprite.
        !          3822: 
        !          3823:                         - ATTENTION PROGRAMMERS:  Added new paramater at end of
        !          3824:                                  rotatesprite:  A char where the first bit tells it to use
        !          3825:                                  transluscence mode or not.
        !          3826: 
        !          3827:                                  rotatesprite(long sx, long sy, long z, short a, short picnum,
        !          3828:                                                                         signed char dashade, char dapalnum, char dastat)
        !          3829: 
        !          3830:                                          if ((dastat&1) == 0) - no transluscence
        !          3831:                                          if ((dastat&1) != 0) - transluscence
        !          3832: 
        !          3833:                         - Cleaned up drawmapview further by making ALL floor sprite draw
        !          3834:                                        with the texture in the right place and made the polygon
        !          3835:                                        filling algorithm use higher screen coordinate precision.
        !          3836: ������������������������������������������������������������������������������
        !          3837: 4/19/95   - Added parameter to makepalookup:
        !          3838: 
        !          3839:                                makepalookup(long palnum, char *remapbuf,
        !          3840:                                                                 signed char r, signed char g, signed char b,
        !          3841:                                                                 char dastat)
        !          3842: 
        !          3843:                                if ((dastat&1) == 0) then makepalookup will allocate & deallocate
        !          3844:                                         the memory block for use but will not waste the time creating
        !          3845:                                         a palookup table (assuming you will create one yourself)
        !          3846:                                if ((dastat&1) != 0) then makepalookup will allocate & deallocate
        !          3847:                                         the memory block AND create a palookup table using the rgb
        !          3848:                                         values you pass.
        !          3849: 
        !          3850:                         - Made my ceiling&floor update the self-modified palookup pointers
        !          3851:                                        when palookup[sector[].?pal] changes, not just when
        !          3852:                                        sector[].?pal] changes.  Watching for changing pointers rather
        !          3853:                                        than changing indeces should solve the problem with screwy
        !          3854:                                        palookup selection for ceilings&floors.  Ignore what I said
        !          3855:                                        before.  You should now be able to change palookup pointers
        !          3856:                                        freely.
        !          3857: 
        !          3858:                         - Optimized relative alignment.  It should be the same speed as
        !          3859:                                        all other ceilings & floors now.
        !          3860: 
        !          3861:                         - Warning:  Since I added the new bit in sprite[].cstat, there are
        !          3862:                                        now 9 bits in use.  Make sure to treat it as a short.  In my
        !          3863:                                        code, I had some bugs where I did this:
        !          3864:                                        sprite[].cstat &= (255-4);  BAD!  Cstat's a short!  Please
        !          3865:                                        check your code and make sure you clear the bits this way:
        !          3866:                                        sprite[].cstat &= ~4;
        !          3867: ������������������������������������������������������������������������������
        !          3868: 4/21/95   - Fixed bug with flipping textures on ceilings & floors.  In
        !          3869:                                        BUIL0419.ZIP I had a bug whenever a ceiling or floor texture
        !          3870:                                        had bit 4 set.  It drew the texture backwards.  Well, I
        !          3871:                                        fixed it.  Hope you didn't "Build" on this bug!
        !          3872: ������������������������������������������������������������������������������
        !          3873: 4/22/95   - Fixed really really stupid hitscan returning sector < 0 bug.  If
        !          3874:                                        you were calling hitscan from the top-left triangular region
        !          3875:                                        of the board it stupidly returned a -1 for the sector.  Well,
        !          3876:                                        I fixed it.
        !          3877: 
        !          3878:                         - ATTENTION EVERYBODY!!!  Moved setup.dat loading from the engine
        !          3879:                                        into GAME.C and BSTUB.C.  If you copy this code from game.c
        !          3880:                                        into your game / bstub, they will work like it used to:
        !          3881: 
        !          3882:                                ----- NEW GLOBAL VARIABLES: -----
        !          3883: 
        !          3884:                                #define NUMOPTIONS 8
        !          3885:                                #define NUMKEYS 19
        !          3886:                                static long chainxres[4] = {256,320,360,400};
        !          3887:                                static long chainyres[11] = {200,240,256,270,300,350,
        !          3888:                                                                                                          360,400,480,512,540};
        !          3889:                                static long vesares[7][2] = {320,200,640,400,640,480,
        !          3890:                                                                                                          800,600,1024,768,
        !          3891:                                                                                                          1280,1024,1600,1200};
        !          3892:                                static char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0};
        !          3893:                                static char keys[NUMKEYS] =
        !          3894:                                {
        !          3895:                                        0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39,
        !          3896:                                        0x1e,0x2c,0xd1,0xc9,0x47,0x49,
        !          3897:                                        0x9c,0x1c,0xd,0xc,0xf,
        !          3898:                                };
        !          3899: 
        !          3900:                                ----- Put this where you call initengine -----
        !          3901: 
        !          3902:                                long fil;
        !          3903: 
        !          3904:                                if ((fil = open("setup.dat",O_BINARY|O_RDWR,S_IREAD)) != -1)
        !          3905:                                {
        !          3906:                                        read(fil,&option[0],NUMOPTIONS);
        !          3907:                                        read(fil,&keys[0],NUMKEYS);
        !          3908:                                        close(fil);
        !          3909:                                }
        !          3910:                                if (option[3] != 0) moustat = initmouse();
        !          3911: 
        !          3912:                                switch(option[0])
        !          3913:                                {
        !          3914:                                        case 0: initengine(0,chainxres[option[6]&15],chainyres[option[6]>>4]); break;
        !          3915:                                        case 1: initengine(1,vesares[option[6]&15][0],vesares[option[6]&15][1]); break;
        !          3916:                                        case 2: initengine(2,320L,200L); break;
        !          3917:                                        case 3: initengine(3,320L,200L); break;
        !          3918:                                        case 4: initengine(4,320L,200L); break;
        !          3919:                                        case 5: initengine(5,320L,200L); break;
        !          3920:                                        case 6: initengine(6,320L,200L); break;
        !          3921:                                }
        !          3922: 
        !          3923:                                ----- That's it! -----
        !          3924: 
        !          3925:                                Initengine now has 3 parameters:
        !          3926:                                        initengine(char davidoption, long daxdim, long daydim)
        !          3927:                                See revised initengine description at the top of this file.
        !          3928: 
        !          3929:                                Now that engine.c doesn't use setup.dat, you can use your
        !          3930:                                        own setup program.
        !          3931: 
        !          3932:                                Don't forget to update BSTUB!
        !          3933: 
        !          3934:                                NOTE!!!  While MY setup program allows you select many different
        !          3935:                                        video modes, no new modes are supported yet in BUILD!
        !          3936:                                        (It's on my list.)
        !          3937: 
        !          3938: 
        !          3939:                         - Fixed keyboard repeating.
        !          3940: ������������������������������������������������������������������������������
        !          3941: 4/26/95   - Hi-res now works in all modes!  The code I gave in the 4/22/95
        !          3942:                                        description is still perfectly valid, so please copy it if
        !          3943:                                        you haven't already looked at it.  Here are some important
        !          3944:                                        new variables I put in BUILD.H:
        !          3945: 
        !          3946:                                                EXTERN char vidoption;
        !          3947:                                                EXTERN long xdim, ydim, ylookup[MAXYDIM+1];
        !          3948: 
        !          3949:                                        Vidoption is simply the first parameter you pass to
        !          3950:                                        initengine.  Xdim and Ydim are the screen sizes you pass to
        !          3951:                                        initengine, such as 320*200 or 640*480.
        !          3952:                                        Ylookup is a lookup table that works like this:
        !          3953:                                                If (vidoption == 0) ylookup[i] = ((i*xdim)>>2);
        !          3954:                                                if (vidoption != 0) ylookup[i] = i*xdim;
        !          3955:                                        There is 1 exception:  If you are using a chained mode which
        !          3956:                                        can only fit only 1 viewing page, then the engine actually
        !          3957:                                        does a screen-buffer mode and blits to the chained screen
        !          3958:                                        so for this case, ylookup[i] = i*xdim.
        !          3959: 
        !          3960:                         - Added bit to the dastat parameter of rotatesprite.
        !          3961:                                  if ((dastat&2) != 0) - align to screen size so the gun or
        !          3962:                                  whatever is always over the same relative spot of the screen.
        !          3963:                                  Works like bit 2 of the flags parameter in overwritesprite.
        !          3964: 
        !          3965:                         - Added pixel writing and reading that will work in all BUILD
        !          3966:                                  graphics modes.  They work just like you think they should.
        !          3967: 
        !          3968:                                          plotpixel(long x, long y, char col);
        !          3969:                                          char getpixel(long x, long y);
        !          3970: 
        !          3971:                                  Please do not overuse these functions!  They are NOT intended
        !          3972:                                  for fast drawing!
        !          3973: 
        !          3974:                         - Changed tables.dat so parallaxing skies at high resolutions
        !          3975:                                  work accurately.
        !          3976: 
        !          3977:                         - I made bit 15 of sprite[].cstat the invisible bit.  If it is
        !          3978:                                set, then the sprite won't even be considered for sorting and
        !          3979:                                there is absolutely no speed loss due to its existence.  It is
        !          3980:                                faster to use this bit then manually set thesprite[] to -1.
        !          3981: 
        !          3982:                                Since drawrooms collects the list of sprites drawmasks is about
        !          3983:                                to sort, make sure the bit is set before drawrooms.  If you use
        !          3984:                                frame interpolation, you usually want to tell drawmasks somehow
        !          3985:                                to not draw yourself.  Before you used to use the
        !          3986:                                thesprite[] = -1 trick.  Now you do it like this:
        !          3987: 
        !          3988:                                        sprite[i].cstat |= 0x8000;        //Set invisible bit
        !          3989:                                        drawrooms(posx,posy,etc.);
        !          3990:                                        sprite[i].cstat &= ~0x8000;       //Restore invisible bit
        !          3991: 
        !          3992:                         - Fixed distance overflow bug (the one that showed garbage
        !          3993:                                        textures if a wall was really far away).
        !          3994: ������������������������������������������������������������������������������
        !          3995: 4/27/95   - Made an example board, MONWALK.MAP, where monsters walk along
        !          3996:                                        a bridge with no railing, onto a sector, and even up and down
        !          3997:                                        a stairway without falling off it.  If you shoot a brown so
        !          3998:                                        it's almost dead, it will turn transluscent.  If it's
        !          3999:                                        transluscent, it won't shoot bullets.  It is much easier to
        !          4000:                                        test the monsters' walking when they don't shoot!
        !          4001: 
        !          4002:                         - Try my new and improved fake network player mode!  Each fake
        !          4003:                                        network player now gets their own window.  Use insert and
        !          4004:                                        delete to add or remove players.  Use Scroll lock to switch
        !          4005:                                        which window you control.  If you have a Pentium, I would
        !          4006:                                        recommend trying this out in 640*480 mode.
        !          4007: 
        !          4008:                         - Noticed a bug with my movesprite code:
        !          4009:                                        For clipmove, I was getting the z-coordinate right, but for
        !          4010:                                        getzrange I forgot to subtract half the sprite's height if
        !          4011:                                        the sprite was using the real centered centering mode.
        !          4012: 
        !          4013:                                        These lines set daz to the actual center of sprite i no matter
        !          4014:                                                what centering mode is used:
        !          4015: 
        !          4016:                                        daz = sprite[i].z;
        !          4017:                                        if ((sprite[i].cstat&128) == 0)
        !          4018:                                                daz -= ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1);
        !          4019: ������������������������������������������������������������������������������
        !          4020: 4/28/95   - ATTENTION PROGRAMMERS!  When a tile is not in the cache:
        !          4021:                                  Before it used to be this:
        !          4022: 
        !          4023:                                          if (waloff[tilenum] == -1) loadtile(tilenum);
        !          4024:                                                  or
        !          4025:                                          if (waloff[tilenum] < 0) loadtile(tilenum);
        !          4026: 
        !          4027:                                  Now it's this:
        !          4028: 
        !          4029:                                          if (waloff[tilenum] == 0) loadtile(tilenum);
        !          4030: 
        !          4031:                                  PLEASE MODIFY YOUR CODE IF YOU USE WALOFF!
        !          4032: 
        !          4033:                                  Windows can allocate memory with addresses so high, they
        !          4034:                                          are negative.  That makes the (waloff[tilenum] < 0)
        !          4035:                                          method totally stupid and attempt to reload from disk
        !          4036:                                          the tile constantly!  I can think of 3 reasons why I
        !          4037:                                          originally designed my system in this fashion:
        !          4038:                                          mestupid, mestinx, and merottts.
        !          4039: 
        !          4040:                         - Fixed visibility for different screen sizes.
        !          4041: 
        !          4042:                         - ATTENTION PROGRAMMERS!  Now multiply by visibility rather than
        !          4043:                                        shift right by visiblity so you get a broader range of
        !          4044:                                        visibility.  If you want the visiblity to work like before,
        !          4045:                                        use this conversion table:
        !          4046: 
        !          4047:                                         Old visibility  New visibility
        !          4048:                                                                 8   ->  16384
        !          4049:                                                                 9   ->   8192
        !          4050:                                                                10   ->   4096
        !          4051:                                                                11   ->   2048
        !          4052:                                                                12   ->   1024
        !          4053:                                                                13   ->    512
        !          4054:                                                                14   ->    256
        !          4055:                                                                15   ->    128
        !          4056: 
        !          4057:                         - Made Alt-F make the selected wall the first wall of a sector.
        !          4058:                                        This is useful for quick relative alignment adjustments.
        !          4059:                                        Alt-F for 2D and 3D modes may not work for sectors with loops
        !          4060:                                        inside of them.
        !          4061: ������������������������������������������������������������������������������
        !          4062: 5/1/95   - Optimized horizontal line setup code from 9 multiplies to
        !          4063:                                  7 multiplies.
        !          4064: 
        !          4065:                        - Fixed dark vertical lines in parallaxing skies bug I recently
        !          4066:                                  introduced.
        !          4067: 
        !          4068:                        - Optimized horizontal line assembly code so it doesn't use the
        !          4069:                                  awful SHLD instruction any more.  This is a good speed
        !          4070:                                  improvement for Pentiums only.
        !          4071: ������������������������������������������������������������������������������
        !          4072: 5/2/95   - Added some code to my GAME.C which detects when a computer gets
        !          4073:                                  out of sync in a multiplayer game.  It's not as easy as you
        !          4074:                                  may think with all the faketimerhandler and fifo crap.  If
        !          4075:                                  you want to put this code in your game, search all areas in
        !          4076:                                  my code with the keyword "syncval".
        !          4077: 
        !          4078:                        - Fixed palookup crashing bug.
        !          4079: ������������������������������������������������������������������������������
        !          4080: 5/6/95   - Moved windowx1, windowy1, windowx2, windowy2 variables into
        !          4081:                                  BUILD.H.  They are the exact parameters you passed to the
        !          4082:                                  last setview call.  Please DO NOT modify them directly.
        !          4083:                                  Use setview to modify them.
        !          4084: ������������������������������������������������������������������������������
        !          4085: 5/10/95  - Fixed makepalookup bug when shading to non 0.
        !          4086: 
        !          4087:                        - Fixed palookup pointer setting bug.
        !          4088: 
        !          4089:                        - ATTENTION PROGRAMMERS!  I made a new cacheing system which allows
        !          4090:                                  any type of object to be allocated in my cache, such as
        !          4091:                                  artwork tiles and sounds or whatever else you may want to
        !          4092:                                  put on the cache.  This may or may not affect you.  If you
        !          4093:                                  haven't been hacking into my code, then you shouldn't have to
        !          4094:                                  change your code.  The cacheing routines have been moved into
        !          4095:                                  a separate module, cache1d.obj.  If you link engine.obj, then
        !          4096:                                  you must also link cache1d.obj.  Please update your makefiles.
        !          4097: 
        !          4098:                                  For anybody who may want to re-write my cacheing system, here's
        !          4099:                                          how it now works:  (I have only 3 functions in cache1d.obj
        !          4100:                                          right now, initcache, uninitcache, and allocache)
        !          4101: 
        !          4102:                                          Allocate a nice BIG buffer, like from 1MB-4MB and
        !          4103:                                  call initcache(long cachestart, long cachesize) where
        !          4104: 
        !          4105:                                                 cachestart = (long)(pointer to start of BIG buffer)
        !          4106:                                                 cachesize = length of BIG buffer
        !          4107: 
        !          4108:                                                 Ex: initcache(FP_OFF(pic),cachesize);
        !          4109: 
        !          4110:                                          Loadpics calls this function for you so you don't normally
        !          4111:                                                 need to call it.
        !          4112: 
        !          4113:                                  call allocache(long ptr, long siz) whenever you need to
        !          4114:                                          allocate a temporary buffer, where
        !          4115: 
        !          4116:                                          ptr = (long)(pointer to (4-byte pointer to thing))\
        !          4117:                                          siz = number of bytes
        !          4118: 
        !          4119:                                          Ex:  if (waloff[tilenume] == 0)
        !          4120:                                                                 allocache((long)&waloff[tilenume],walsiz[tilenume]);
        !          4121: 
        !          4122:                                          Allocache is totally tile independent.  To allocate a sound
        !          4123:                                                  on the cache, you can call allocache.
        !          4124: 
        !          4125:                                  There are 3 functions in the engine which help manage the
        !          4126:                                          cache for you: loadpics - calls initcache
        !          4127:                                                                                  loadtile - calls allocache
        !          4128:                                                                                  allocatepermanenttile - special function
        !          4129:                                                                                                                that allocates permanent memory
        !          4130:                                                                                                                from the cache.
        !          4131: 
        !          4132:                        - Fixed clipmove crashing bug when passing a sectnum < 0.  Whenever
        !          4133:                                  you moved in BUILD and you weren't in a valid sector, memory
        !          4134:                                  was getting trashed.
        !          4135: ������������������������������������������������������������������������������
        !          4136: 5/12/95  - Added ExtPreCheckKeys(void) to BSTUB.C.  It is called before
        !          4137:                                  drawrooms / drawmasks in 3D mode, whereas ExtCheckKeys(void)
        !          4138:                                  is called after drawrooms / drawmasks (and before nextpage).
        !          4139: 
        !          4140:                        - Added bit to flags of rotatesprite to allow x-flipping.  See
        !          4141:                                  updated documentation.
        !          4142: ������������������������������������������������������������������������������
        !          4143: 5/17/95  - Added aspect ratio for those weird modes like 320*400, etc.
        !          4144:                                  You could call setaspect to properly adjust a mode that is
        !          4145:                                          not exactly correct, or for special effect that stretch
        !          4146:                                          the screen.
        !          4147: 
        !          4148:                                  In ENGINE.OBJ, I added a function, setaspect(long daaspect),
        !          4149:                                          where you pass the Y/X aspect ratio scaled up 16 bits, so
        !          4150:                                          65536 would be normal.  You don't need to call this if you
        !          4151:                                          don't want to.  By default, in setview, I call setaspect
        !          4152:                                          with these parameters:
        !          4153: 
        !          4154:                                                  setaspect(divscale16(ydim*320,xdim*200));
        !          4155:                                                          (also written as:)
        !          4156:                                                  setaspect(((ydim*320)<<16)/(xdim*200));
        !          4157: 
        !          4158:                                          Note that in 320*200 mode the value passed would be 65536
        !          4159:                                                  which is a 1:1 aspect ratio.
        !          4160: 
        !          4161:                                  In BUILD.H, I added yxaspect and xyaspect.
        !          4162: 
        !          4163:                                          When you call setaspect(daaspect),
        !          4164: 
        !          4165:                                                 yxaspect = daaspect;
        !          4166:                                                 xyaspect = (1<<32) / yxaspect;   //reciprocal
        !          4167:                                                 and other internal variables, so DON'T MODIFY YXASPECT
        !          4168:                                                         AND XYASPECT DIRECTLY!
        !          4169: 
        !          4170:                                  Since drawmapview is also affect by the aspect ratio, you
        !          4171:                                          will need to make sure drawoverheadmap is affected so
        !          4172:                                          the map modes match up.  Please look at and copy my updated
        !          4173:                                          drawoverheadmap function into your GAME.C if you use it.
        !          4174: ������������������������������������������������������������������������������
        !          4175: 5/18/95  - Revised caching system so it supports locking.
        !          4176:                                  Here are the new parameters to allocache:
        !          4177: 
        !          4178:                                  allocache(long *bufptr, long bufsiz, char *lockptr)
        !          4179:                                          *bufptr = pointer to 4-byte pointer to buffer
        !          4180:                                          bufsiz = number of bytes to allocate
        !          4181:                                          *lockptr = pointer to 1-byte locking char.  1=locked, 0=not
        !          4182: 
        !          4183:                                  And uninitcache works a little differently too:
        !          4184:                                          Call uninitcache(0) to remove all UNLOCKED items or
        !          4185:                                          Call uninitcache(1) to remove ALL items.
        !          4186:                                                  After calling uninitcache, you do not need to call
        !          4187:                                          initcache to use the cache again.
        !          4188: ������������������������������������������������������������������������������
        !          4189: 5/21/95  - Made changespritesect and changespritestat return 0 instead of -1
        !          4190:                                  when changing to same value.
        !          4191: ������������������������������������������������������������������������������
        !          4192: 5/25/95  - Added relative visibility for sectors.  In 3D EDIT MODE, use
        !          4193:                                 ALT+(keyp.)+/- to change an individual sector's visibility.
        !          4194:                                 Press Shift in addition for fine visibility changine.  By
        !          4195:                                 default you change it by 16.  Press CTRL+ALT+(keyp.)+/- to
        !          4196:                                 change the global visibility. The global visibility is not
        !          4197:                                 saved in the map.
        !          4198: 
        !          4199:                        - Can now delete many sectors at a time.  Select sectors with the
        !          4200:                                 rt. Alt.  Then press Ctrl-delete on any highlighted sector to
        !          4201:                                 delete all the highlighted sectors.
        !          4202: 
        !          4203:                        - Fixed build sometimes not saving when quitting from 2D mode bug.
        !          4204: ������������������������������������������������������������������������������
        !          4205: 5/27/95  - Fixed bugs in network work that should make it miss packets
        !          4206:                                  much less often than before.
        !          4207: 
        !          4208:                        - Fixed bug in ncopy so it shouldn't halt or crash anymore.
        !          4209: 
        !          4210:                        - Added spritecstat[] the thesprite arrays.  Please use my
        !          4211:                                  thesprite arrays rather than modifying the sprite directly
        !          4212:                                  since hitscan and clipmove use bits 4 and 8 of sprite[].cstat.
        !          4213: 
        !          4214:                        - ATTENTION PROGRAMMERS:  Added 1 parameter to neartag that will
        !          4215:                                  allow you to search only lotags or only hitags.  See updated
        !          4216:                                  documentation above.
        !          4217: 
        !          4218:                          neartag (long xs, long ys, long zs, short sectnum, short ange,
        !          4219:                                  short *neartagsector, short *neartagwall, short *neartagsprite,
        !          4220:                                  long *neartaghitdist, long neartagrange, char tagsearch)
        !          4221: 
        !          4222:                                  If tagsearch = 1, neartag searches lotag only
        !          4223:                                  If tagsearch = 2, neartag searches hitag only
        !          4224:                                  If tagsearch = 3, neartag searches lotag&hitag
        !          4225: 
        !          4226:                                  Neartag used to always search both lotag&hitag.
        !          4227: ������������������������������������������������������������������������������
        !          4228: 5/30/95  - Added ExtAnalyzeSprites(void) to BSTUB and a spriteshade array
        !          4229:                                  to BUILD.H.
        !          4230: 
        !          4231:                        - Made circle drawing in 2D EDIT MODE work better at large sizes.
        !          4232: ������������������������������������������������������������������������������
        !          4233: 6/5/95   - Added shareware / registered artwork version control to EDITART.
        !          4234:                                  In 'V' mode, when you press ALT-R to get a report of tile
        !          4235:                                  frequencies of tiles on all the maps in the current directory,
        !          4236:                                  you can toggle the shareware/registered bit with the space bar.
        !          4237:                                  This bit is saved in the top bit of the picanm bits so it is
        !          4238:                                  stored permanently in the art file.  Press ALT-D in this mode
        !          4239:                                  to automatically delete all registered tiles.  Please before
        !          4240:                                  you do the deleting phase, copy all artwork to a temporary
        !          4241:                                  directory!!!  It is safe, however, the toggle the new bit in
        !          4242:                                  the full version.
        !          4243: ������������������������������������������������������������������������������
        !          4244: 6/7/95   - Made 3 main structures defined with typedef so struct prefix
        !          4245:                                  is no longer needed with sectortype, walltype, and spritetype.
        !          4246: 
        !          4247:                        - Added new function to engine:
        !          4248: 
        !          4249:                                 short sectorofwall(short dawall);
        !          4250: 
        !          4251:                                 It returns the sector of a given wall.  It is well optimized
        !          4252:                                         including sector[sector[].nextwall].nextsector if a red wall
        !          4253:                                         and a binary search on the sector[].wallptr's if it is a
        !          4254:                                         white wall.  On average, sectorofwall should have to scan
        !          4255:                                         through only 10 different sector indeces to find the right
        !          4256:                                         sector (not 1024!).
        !          4257: 
        !          4258:                        - ATTENTION PROGRAMMERS!  Made all the separate thesprite arrays
        !          4259:                                  into a single array of sprite structures call tsprite.  See
        !          4260:                                  BUILD.H!!!  This means:
        !          4261: 
        !          4262:                                          spritepicnum[i] is now tsprite[i].picnum
        !          4263:                                          spritex[i] is now tsprite[i].x
        !          4264:                                          spritey[i] is now tsprite[i].y
        !          4265:                                          spritez[i] is now tsprite[i].z
        !          4266:                                          spriteshade[i] is now tsprite[i].shade
        !          4267:                                          spritecstat[i] is now tsprite[i].cstat
        !          4268:                                          spritepal[i] is now tsprite[i].pal
        !          4269:                                          thesprite[i] is now tsprite[i].owner     <<<============
        !          4270: 
        !          4271:                                          Everything above is straight forward, except for thesprite,
        !          4272:                                                  which has been renamed to owner.
        !          4273: 
        !          4274:                                          All other tsprite parameters, such as .xrepeat, .yoffset,
        !          4275:                                                        etc.  can also be modified without changing the real
        !          4276:                                                        sprite structure so the game won't out of sync.
        !          4277: 
        !          4278:                        - Made tsprite[].statnum be a priority variable for sorting sprites
        !          4279:                                  that are the exact same distance from you.  I think higher
        !          4280:                                  means more in front.
        !          4281: 
        !          4282:                        - Made clipmove allow you to cross any red sector line when the z's
        !          4283:                                  of the next sector are farther apart.  This may solve clipping
        !          4284:                                  bugs such as when you're in water.  You may be able to remove
        !          4285:                                  some work-arounds you may have programmed previously.
        !          4286: 
        !          4287:                        - NEW FILE GROUPING SYSTEM!!!
        !          4288:                                          My system will first search for the stand-alone file in the
        !          4289:                                  directory.  If it doesn't find it, then it will search for it
        !          4290:                                  in the group file.  If it still doesn't find it then -1 city.
        !          4291:                                          Use KGROUP.EXE to create a grouped file from a lot of other
        !          4292:                                  files.  Type KGROUP [grouped filename][filespec][filespec][...]
        !          4293:                                  For example this line will create the new grouped file,
        !          4294:                                  stuff.dat, including all the following files specified:
        !          4295:                                          kgroup stuff.dat *.art *.map tables.dat palette.dat
        !          4296:                                  Feel free to make your own batch files.  If there is demand,
        !          4297:                                  I can make kgroup support appending, replacing, and extraction.
        !          4298: 
        !          4299:                                  Here is the file format of a grouped file:
        !          4300:                        �����������������������������������������������������������������Ŀ
        !          4301:                        �   12 bytes - File grouping ID                                   �
        !          4302:                        �    4 bytes - Number of files                                    �
        !          4303:                        �����������������������������������������������������������������Ĵ
        !          4304:                        �For each file: (16 bytes per file)                               �
        !          4305:                        �   12 bytes - Filename with extension (13th byte would be a 0)   �
        !          4306:                        �    4 bytes - Length of file                                     �
        !          4307:                        �����������������������������������������������������������������Ĵ
        !          4308:                        � Pure, raw file data, ordered just like you think it would be    �
        !          4309:                        �������������������������������������������������������������������
        !          4310:                                  There just couldn't be a simpler format.  This format is so
        !          4311:                                          hacker happy that when you view it in a hex editor, all the
        !          4312:                                          filenames line up perfectly since they're multiples of 16.
        !          4313:                                          Anybody who can't figure this out, of course, not only rots,
        !          4314:                                          but is probably one of those really stupid people who would
        !          4315:                                          actually "pay" to get the full version of a game.
        !          4316: 
        !          4317:                                  The engine currently supports grouping for:
        !          4318:                                                *.ART, *.MAP, TABLES.DAT and PALETTE.DAT.  If you want
        !          4319:                                  to group your own files, you will have to use my loading
        !          4320:                                  routines rather than the standard ones for those files.  My
        !          4321:                                  file routines are basically an extra layer around the standard
        !          4322:                                  lo-level functions.  Look at these 5 routines I currently
        !          4323:                                  support:
        !          4324: 
        !          4325:                                                                 Welcome to the K-routines!
        !          4326:                                                 open -> kopen4load(char *filename)
        !          4327:                                                 read -> kread(long handle, void *buffer, long leng)
        !          4328:                                                lseek -> klseek(long handle, long offset, long whence)
        !          4329:                                 filelength -> kfilelength(long handle)
        !          4330:                                                close -> kclose(long handle)
        !          4331: 
        !          4332:                                  Note that you only pass the filename to my kopen4load function.
        !          4333: 
        !          4334:                                  Here are 2 other routines that you MUST use, whether you like
        !          4335:                                          my file grouping system or not:
        !          4336: 
        !          4337:                                          initgroupfile(char *groupfilename)
        !          4338:                                                  Call this with the name of your grouped file before
        !          4339:                                          any possible file loading will the k-routines.  Note that
        !          4340:                                          tables.dat uses the k-routines and it is in initengine().
        !          4341:                                          Please don't give your grouped filename an extension that
        !          4342:                                          starts with W, ends with D, and has a vowel in between.
        !          4343:                                          And don't even bother to write your own file grouping
        !          4344:                                          system because even if you do, people still have to write
        !          4345:                                          their own new utilities to read the ART and MAP files.
        !          4346: 
        !          4347:                                          uninitgroupfile()
        !          4348:                                                  Call before quitting to DOS.
        !          4349:                ------------------------------------------------------
        !          4350:                        - ATTENTION PROGRAMMERS!  Changed kopen4load from:
        !          4351: 
        !          4352:                                kopen4load(char *filename)
        !          4353:                                        to:
        !          4354:                                kopen4load(char *filename, char searchfirst)
        !          4355: 
        !          4356:                                        where:
        !          4357:                                if searchfirst = 0 then search stand alone first then group file
        !          4358:                                if searchfirst = 1 then search group file only
        !          4359: ������������������������������������������������������������������������������
        !          4360: 6/12/95   - Tracked down an OUT OF SYNC bug with my multiplayer code!
        !          4361:                                        In my GAME.C, the way I had my sync arrays organized were
        !          4362:                                                wrong.  The problem was that if faketimerhandler was
        !          4363:                                                called during domovethings, the sync arrays may have been
        !          4364:                                                changed, getting the game out of sync.  The solution is
        !          4365:                                                to keep the sync arrays in domovethings totally separate
        !          4366:                                                from the sync arrays in faketimerhandler.  I split my sync
        !          4367:                                                arrays into 2 separate arrays, sync and fsync, where fsync
        !          4368:                                                and osync are for use BEFORE the FIFO only (such as
        !          4369:                                                faketimerhandler and getpackets), and sync is used AFTER
        !          4370:                                                the FIFO only (such as domovethings).  PLEASE SPLIT YOUR
        !          4371:                                                SYNC ARRAYS AS I DESCRIBED!
        !          4372: 
        !          4373:                         - The OUT OF SYNC message doesn't flicker any more.  See the
        !          4374:                                        section of code in GAME.C where I set syncstat.
        !          4375: 
        !          4376:                         - Fixed up a waitforeverybody function for network games which
        !          4377:                                        waits for everybody to be at a certain part of the game.
        !          4378:                                        Waitforeverybody also uses getpackets message number 5.
        !          4379: 
        !          4380:                         - Added new clipping function that will push players away from
        !          4381:                                        walls that are too close.  It solves A LOT of movement
        !          4382:                                        clipping problems.  It can be pretty darn slow if it detects
        !          4383:                                        that you're too close to a wall, so I'd recommend using it
        !          4384:                                        only for players.
        !          4385: 
        !          4386:                                        pushmove (long *x, long *y, long *z, short *sectnum,
        !          4387:                                          long walldist, long ceildist, long flordist, char cliptype)
        !          4388: 
        !          4389:                                        The parameters are exactly the same as clipmove but with no
        !          4390:                                                xvect or yvect.  Pushmove returns either a 0 or -1.  If
        !          4391:                                                it returns a -1, then that means that it could not push
        !          4392:                                                the player away from the offending wall after 256 tries.
        !          4393:                                                When this happens, then you should kill the player
        !          4394:                                                instantly, because this only happens when the player is
        !          4395:                                                getting smooshed.
        !          4396: ������������������������������������������������������������������������������
        !          4397: 6/13/95   - Made clipinsidebox and clipinsideboxline return 0 if line doesn't
        !          4398:                                        intersect box, 1 if line intersects box and center of box
        !          4399:                                        is in front of line, or 2 if line intersects box and center
        !          4400:                                        of box is behind line.
        !          4401: 
        !          4402:                         - Cansee should now work properly with overlapping.
        !          4403: ������������������������������������������������������������������������������
        !          4404: 6/19/95   - ATTENTION!  Remove work-arounds!!!  Found nasty getzrange bug.
        !          4405:                                        Getzrange used to let you fall through red sector line cracks
        !          4406:                                        when you were near more multiple red sector line sharing the
        !          4407:                                        same 2 sectors.  Sound familiar anybody?
        !          4408: 
        !          4409:                         - Made pushmove return the sector of whatever x and y end up in.
        !          4410: ������������������������������������������������������������������������������
        !          4411: 6/22/95   - I included cache1d.c renamed to cache1d.txt in this upload.
        !          4412: ������������������������������������������������������������������������������
        !          4413: 6/26/95   - Made face and wall sprites of clipmove, getzrange, hitscan, and
        !          4414:                                        neartag sensitive to the y-offset that you set in Editart.
        !          4415: 
        !          4416:                         - Made one sprite sorting case work perfectly:  where multiple
        !          4417:                                        sprites have the same x and y location (and priority).  The
        !          4418:                                        sorting still doesn't work perfectly, but this one case can
        !          4419:                                        solve many of the current sprite sorting bugs, such as
        !          4420:                                        inserting a floor sprite of blood below a dead body.
        !          4421: 
        !          4422:                         - Fixed some sprite drawing clipping bugs for wall and floor
        !          4423:                                        sprites.  Now, wall sprites and floor sprites should not
        !          4424:                                        show through walls, ceilings, or floors when they're not
        !          4425:                                        supposed to.  Also, I fixed a case where wall sprites
        !          4426:                                        disappeared when they happened to be between 2 white walls
        !          4427:                                        that clipped it.
        !          4428: ������������������������������������������������������������������������������
        !          4429: 6/27/95   - Fixed even more sprite drawing clipping bugs for wall sprites.
        !          4430: 
        !          4431:                         - BONUS!!!  Wall sprites now clip to white walls! (not red walls)
        !          4432:                                        If you ornament a wall, make sure that neither endpoint of the
        !          4433:                                        wall sprite is behind the wall or else it will get clipped.
        !          4434:                                        Please run lookatme.map from my game.exe which demonstrates
        !          4435:                                        some of the things you can do in build now without bugs.
        !          4436: ������������������������������������������������������������������������������
        !          4437: 6/30/95   - Made drawline256 clip with startumost/startdmost.
        !          4438: 
        !          4439:                         - Moved keyboard handler into GAME.C.  Here's what you need to do
        !          4440:                                        to use my keyboard handler (see my GAME.C):
        !          4441: 
        !          4442:                                        1.  Some global variables:
        !          4443: 
        !          4444:                                                         #define KEYFIFOSIZ 64
        !          4445:                                                         void (__interrupt __far *oldkeyhandler)();
        !          4446:                                                         void __interrupt __far keyhandler(void);
        !          4447:                                                         volatile char keystatus[256], keyfifo[KEYFIFOSIZ];
        !          4448:                                                         volatile char keyfifoplc, keyfifoend;
        !          4449:                                                         volatile char readch, oldreadch, extended, keytemp;
        !          4450: 
        !          4451:                                        2.  initkeys()
        !          4452: 
        !          4453:                                        3.  uninitkeys()
        !          4454: 
        !          4455:                                        4.  keyhandler()
        !          4456: 
        !          4457:                                        5.  Make sure to call initkeys and uninitkeys.  A good place
        !          4458:                                                        would be next to where you call inittimer / uninittimer.
        !          4459: 
        !          4460:                                        I didn't put my keyboard handler into BSTUB since I am using
        !          4461:                                keystatus throughout build.obj.  Besides I didn't want to anybody
        !          4462:                                too bad of a headache for one upload.
        !          4463: 
        !          4464:                         - Did you know that screencapture inverses black and white if you
        !          4465:                                        hold either shift key down?  This option is useful for
        !          4466:                                        printing out board maps.  Since I don't own the keyboard
        !          4467:                                        any more, I had to make screencapture take inverseit as the
        !          4468:                                        second parameter.
        !          4469: 
        !          4470:                                        screencapture(char *filename, char inverseit);
        !          4471: 
        !          4472:                          Ex: screencapture("captxxxx.pcx",keystatus[0x2a]|keystatus[0x36]);
        !          4473: 
        !          4474:                                        If (inverseit == 0) then nuttin' special
        !          4475:                                        If (inverseit == 1) then super-reverso blacko-whiteo mode!
        !          4476: 
        !          4477:                                        I also had to move the stereo adjustment keys into game.c
        !          4478:                                        Just search for the "stereo" keyword in GAME.C.  It'll take
        !          4479:                                        through all the necessary places.
        !          4480: ������������������������������������������������������������������������������
        !          4481: 7/5/95    - Moved my keytimerstuff from my timerhandler into getinput.
        !          4482:                                        (which is where it should be)
        !          4483: ������������������������������������������������������������������������������
        !          4484: 7/10/95   - Added a loadtilelockmode variable to BUILD.H.  It's a global
        !          4485:                                        variable that makes future loadtile calls allocate their
        !          4486:                                        buffers on the cache as unlocked (0-default) or locked (1).
        !          4487:                                        I decided to make this a global variable rather than a
        !          4488:                                        parameter to save some people from rewriting code.
        !          4489: 
        !          4490:                                        EXTERN char loadtilelockmode;
        !          4491: 
        !          4492:                         - Made my 2D EDIT MODE space bar code clear out new sectors and
        !          4493:                                        wall structures to 0. (except for the extras which are -1)
        !          4494: ������������������������������������������������������������������������������
        !          4495: 7/20/95   - I forgot to documenent rotatesprite bit 3, which controls
        !          4496:                                  whether or not the sprite will be clipped to the startumost
        !          4497:                                  /startdmost arrays.  If the bit is a 1, then the sprite will
        !          4498:                                  not be clipped.  This mode is useful for doing status bars
        !          4499:                                  at variable resolutions.  What you do is instead of calling
        !          4500:                                  permanentwritesprite, you call rotatesprite with the scaling
        !          4501:                                  bit and startumost/startdmost clipping bit off.  For non
        !          4502:                                  screen-buffer modes, be sure to call rotatesprite for each
        !          4503:                                  page of the mode.  Use the numpages variable in BUILD.H to
        !          4504:                                  get the number of video pages used.

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.