|
|
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, §num); ! 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.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.