diff --git a/polymer/build/doc/build.txt b/polymer/build/doc/build.txt new file mode 100644 index 000000000..d4fa220fa --- /dev/null +++ b/polymer/build/doc/build.txt @@ -0,0 +1,5081 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. + +BUILD engine Notes (8/14/95): + +BUILD programmed by Ken Silverman + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ GAME KEYS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + ESC = Quit + Mouse = Movement + Arrows = Movement + Lt. Enter = Single-player: Play back game. + Multi-player: View from other player's eyes. + Rt. Enter = Switch between 3D / 2D modes + Lt. +/- = Zoom in 2D mode + A/Z = Move up and down + Left-Ctrl = Shoot + 1/2 = Select weapon +Left-Shift = Run + T = Reset Timing (sets totalclock = 0) + V = Change visibility. In BUILD.H there is a visiblity variable. + It is initialized to 13. It can range from around 8 (darker) + to about 15 (lighter). + P = Change parallaxing sky mode. (0, 1, and 2 (Default = 2) + F12 = Screen capture (saves image as a *.BMP file, starting as file + name CAPTUR00.BMP and incrementing by 1 each time F12 is + pressed. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ BUILD EDITOR INTRODUCTION: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +There are 2 modes in the BUILD editor: + 3D EDIT MODE (Same as PLAY MODE but with a mouse cursor) + 2D EDIT MODE (The overhead map of the board with an arrow showing your + position and angle and a mouse cursor) + +It is essential that you use both editor modes: + + Use the 3D EDIT MODE to change the attributes of a sector, wall, or sprite + such as: + + Tile number - Tells which picture in the artwork file goes on the + object. Press V to change. + Shade - The shade of the object. Press -/+ to change. + Repeating - The "smooshiness" of a wall. Also for sprites. Press + keypad 2,4,6,8 to change. + Panning - The starting offset into the tile graphics. Press + Shift + keypad 2,4,6,8 to change. + Height - For ceilings, floors, and sprites. Press PGUP or PGDN + to change. + and there are a few other special attributes. + + Use the 2D EDIT MODE to add, delete, or change the shape of sectors. + + To switch between the two EDIT MODES, press the keypad enter key. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ 3D EDIT MODE KEYS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + ESC = Quit +keypad ENTER = Flip to the 2D overhead editor + + Mouse = Move mouse cursor + Arrows = Move you in the appropriate directions + Caps Lock = There are 3 different Z coordinate modes in BUILD. + Mode 0: Game mode (default) + Mode 1: Height lock mode + Mode 2: Float mode + Press Caps Lock to switch between the 3 modes. + A and Z move up and down for all 3 modes. + + +Note: For the following keys, it is important to move the mouse cursor to +the right position before using them. Also, if you hold down the first mouse +button, then the item under the mouse cursor will be locked as the +highlighted object while the button is held down. This is useful for the +PGUP/DN keys, when different objects come into view even without moving your +coordinates or the mouse cursor. + There are 4 basic types of objects that can be worked with in this part +of the editor: WALLS, CEILINGS, FLOORS, and SPRITES. + + PGUP/DN = Raise or Lower a ceiling or floor. (If a wall is selected, + the ceiling of that sector will move) Also, if you did a + sector highlight in 2D EDIT MODE, you can raise / lower + multiple sectors at a time. +Ctrl-PGUP/DN = For sprites only, puts sprites exactly on the floor or exactly + on the ceiling. + + V = Tile selection - use arrow keys to move around. Press ENTER + to change the object to the highlighted piece of artwork, or + press ESC to cancel without changes made. + ALT-V = Height selection - works just like V, but this selects the + groudraw height map. + +2,4,6,8 (keypad) = Repeat values (smooshiness of the sizes of pixels) - + think of these keys as arrow keys controlling the bottom + right corner of the bitmap. Normally, this is used for walls + and sprites. If you select a floor or ceiling, all the walls + in that sector will be affected. Perhaps this can be used + to make sprites grow and shrink as they get healthy or hurt. +Shift + +2,4,6,8 (keypad) = Panning values (offset into the tile) - These keys are + useful when the you want a long wall to look continuous when + they normally would not look continuous. + / = Use this key to reset the panning values (if you're lost!) + 5 (keypad) = If you hold down this key down in addition to the 2,4,6,8 + keys (keypad),the values will align at multiples of 8. + .> = This key attempts to match up all the tiles along a wall. It + scans along the walls towards the right as long as the picture + number of the next wall is the same as the original picture + number. Note that some walls may not work right, especially + floor / ceiling steps. + + F = Flip an object. For sprites and walls, this flips the object + x-wise. For ceilings and floors, the objects are flipped in + 8 possible ways. Just keep pressing 'F' to go through + the 8 ways. + ALT-F = When you use relative alignment mode on ceiling and floor + textures, you can press Alt-F on the ceiling or floor to + choose a new wall to align to. It actually rotates the walls + of a sector by 1. + O = Wall orientation (whether it starts from the top or bottom) + Normally, walls are oriented from the top. For example, if + you hold down 2/8 on the keypad in 3D EDIT MODE, the wall + always starts from the top. Orientation works differently + for white lines and red lines, so if a wall doesn't look + right, just press 'O' anyway to see if it get fixed. + +COPY & PASTE + TAB = COPY. Copy the attibutes of the highlighted objects into a + temporary place. The attributes it remembers are: + tile, shade, x-repeat, y-repeat, and cstat values. + Left ENTER = PASTE. Paste the stored attributes over the highlighted + object. Whenever you press ENTER, the y-repeat values stay + the same, and the x-repeat values are adjusted so the pixels + of the bitmaps have a square-aspect ratio. +Ctrl+L.ENTER = Left ENTER with the ctrl key will paste the attribtues to + every wall in a loop (if a wall is highlighted). +Shft+L.ENTER = Left ENTER with the shift key also pressed copies the shade + only. +Ctrl+Shft+L.ENTER = Auto-shade a sector. First make any wall of the loop + as light as the lightest shade you want. Then make any other + wall of the loop as dark as the darkest shade you want. + Finally press Ctrl-Shift Enter on the wall that should be + lightest. Now the loop should be smoothly shaded. If it + is not smoothly shaded, you may need to insert more points + on the walls. + +SECTOR FLAGS: + + P = Make the ceiling of the given sector have a Parallaxing sky + or just a normal ceiling. + G = Make the floor of the given sector have a Groudraw + (floor with height mapping). I do not recommend using this + attribute very extensively yet. (See the H key for selecting + the height map) + E = An option for ceilings and floors. If for some reason, you + want a tile to be smooshed into the normal 64*64 area, press + E to unExpand the tile. Press E again, and the tile will be + expanded, so the pixel size is the same as the normal 64*64 + ceiling/floor. + R = Relative alignment - switch between relative alignment mode + and normal mode. Allows floor / ceiling textures to align + to the first 2 points of a sector. Textures will rotate/pan + with moving sectors properly. Notice that bit 6 of both + sector[].ceilingstat and sector[].floorstat are relative + alignment bits. + +WALL FLAGS: + + B = Make an invisible wall, such as a window, block you from + going through. Since the wall is invisible, you can also + highlight the ceiling right above the window or floor + right below the window. You can block either the front or + the back of the window. If you block the back only, you + will be able to go onto the window sill. + T = Press to make a maskable wall 50/50 transluscent. Press T + again to put the masked wall back to normal mode. + M = Make a maskable wall. Press in the same place you press 'B'. + The masking wall takes all its attributes from the front of + the wall, so it must have the same repeat, panning, and cstat + values as the walls above or below it (if you have a step). + The masking picture number is stored in overpicnum. Also, + the masking walls is also automatically added the the other + side of the wall, with the picture flipped. (see the 'F' + key descripte above) + Shift + M = Make a maskable wall just like 'M' described above, but only + on the front side. + + 1 = Make a 1-way wall. + 2 = Some walls have two different sections. One step on the + ceiling and one step on the floor. Normally they always + have the same attributes. It is possible though, to give + both the top and bottom different attributes by pressing 2 on + that wall. 2 simply makes the bottom wall's attributes + separately editable. Press 2 on either the top or bottom + wall. + O = Wall orientation (whether it starts from the top or bottom) + Normally, walls are oriented from the top. For example, if + you hold down 2/8 on the keypad in 3D EDIT MODE, the wall + always starts from the top. Orientation works differently + for white lines and red lines, so if a wall doesn't look + right, just press 'O' anyway to see if it get fixed. + H = Toggle hitscan pass through bit. Default is pass through. + +SPRITE FLAGS: + + B = When the mouse cursor is on a sprite, this makes a sprite + block you from walking through. Also makes the sprite + sensitive to hitscan. Sprites with the 'B' attribute will + appear pink in 2D EDIT MODE + T = Press to make a sprite 50/50 transluscent. Press T again + to put sprite back to normal mode. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ 2D EDIT MODE KEYS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + ESC = Show a menu that says, "(N)ew, (L)oad, (S)ave, (Q)uit" + Press ESC again to cancel the menu. + keypad ENTER = Flip back to the 3D edit mode + + Mouse = Move mouse cursor + Left mouse button = If you hold down the left mouse button, you can drag + existing points. To drag multiple points you can use + the right shift key to first select a rectangular + region of points to highlight, then just drag any of + the highlighted points and the rest move with it. +Right mouse button = Moves the player's positions to the mouse cursor. + This is useful when you accidently get stuck somewhere + in the board, or when you need to edit some part of + a sector that is hard to access. + Right Shift = Select a bunch of points for use with dragging around. + Selects all points inside a box. (Use the left mouse + button to drag) + Ctrl+Right Shift = Select a bunch of points for use with dragging around. + Selects all points on a loop. (Use the left mouse + button to drag) + Right Alt = Select a bunch of sectors for either duplication or + dragging around. (see left mouse button for + dragging and the insert key for duplication). + + Arrows = Move player position in the appropriate directions. + The player will be clipped. To jump to a different part + of the board, use the right mouse button. + Space = Press the space bar when drawing new sectors. There + are several ways of drawing new sectors. The following + three ways of drawing sectors can all be done by only + using the space bar. The computer is smart enough to + decide which method you are using. + + 1. Drawing a FULL LOOP - that is, whenever the new + sector meets the old sector, draw over that line + again. In full loop mode the new sector must not + already be in another sector. The loop is done + when you press the space bar at the first point + again. + 2. SPLITTING a sector - press space bar to draw points + at which you want to split a sector. The computer + knows you are done splitting when you end at + another point that's on the edge of the sector you + are splitting. + 3. Drawing a sector COMPLETELY INSIDE another sector. + (for example, columns) To do this, just press space + bar at every point in the loop. The loop is done + when you press the space bar at the first point + again. + Backspace = When plotting points with the space bar, you can use + backspace to get rid of the last point plotted. You + can press the backspace to get rid of all the points + if you didn't want to start a sector at all. + + Insert = Inserts a new point at the midpoint of the highlighted + line. Then you can drag the point to wherever you like. + (If you insert on a red line, the point will be inserted + on both sides of the sector line.) + If a bunch of sectors are selected (see right ALT) then + instead of inserted points, the selected sector bunch + will be duplicated (stamped). Don't forget to drag + the selected sectors after stamping. + + Delete = Use this to delete sprites (blue circles). To delete + points of a sector border, don't press delete. Instead, + drag the point into one of its 2 neighbor points on the + sector. This is easist done if grid locking is on + (mouse cursor is pink). If 2 neighbor points are equal, + one will automatically be deleted. + Right Ctrl-Delete = This deletes the whole sector that the mouse cursor is + in. Note the right ctrl for protection. + (Note: to delete a point of a sector, just drag that point into the next + point and it will automatically be deleted. You should do this with + grid-locking on) + J = Use to join two neighboring sectors. Press J when mouse + cursor is over the first sector. Then press J again + when the mouse cursor is over the neighboring sector. + The attributes of the combined sector will be taken from + the first sector selected. + ALT-S = When you have a white loop inside a sector, you can + press ALT-S on it (highlight any of its lines) to turn + the whole loop red. + S = Places a sprite at the location under the mouse cursor. + A sprite looks like a blue circle in the overhead map. + + B = Blocks / unblocks you from going through a wall or + sprites. A blocked wall or sprite will appear pink + in 2D EDIT MODE. See the description for 'B' in + the 3D EDIT MODE section for more details. + + C = Turn a line into a circle defined by short line + segments. First press 'C' on a highlighted wall. Then + move the mouse to the right place and press '+' or '-' + if you want to change the number of points on the + circle. Press 'C' again to cancel the circle drawing or + press the Space bar to actually change the map. + +/- = Increase / Decrease the number of points on the circle. + + T = Type in a LO-tag for a sector. Move the mouse cursor to + the inside of a sector that you want to tag first. + ALT-T = Just like 'T' but for walls and sprites. + H = Type in a HI-tag for a sector. Move the mouse cursor to + the inside of a sector that you want to tag first. + ALT-H = Just like 'H' but for walls and sprites. + E = Change a sprite's status list number. + < and > = Changes angle of sprite. Move the mouse cursor to a + sprite first. You can hold down shift with the < and > + to get more precise angles. If you did a sector + highlight, then the selected sector will be rotated + instead. + CTRL-T = Turn tag boxes on/off. + + TAB = Move the mouse cursor to the inside of a sector that you + you want to see the attributes of. It will show them + at the bottom of the status bar. To clear it, press + TAB again at somewhere in the board that is not part + of any sector. This is a useful key for debugging. + ALT-TAB = Works just like TAB, but here, you can see the + attributes of highlighted walls or sprites. For red + lines, the side the mouse cursor is on the line affects + which line is highlighted, since red lines are actually + defined as 2 walls (1 wall for each sector). + + Scroll Lock = Set starting position (brown arrow) to your current + position (white arrow). + + A,Z = Zoom in and out. This is useful for choosing whether + you want to edit finely or not. + G = Change grid resolution. The grid resolution cycles + through this sequence: + (off, 1x, 2x, 4x (default), 8x, 16x) + L = Turns grid locking on or off. If the mouse cursor is + pink then grid locking is on. If it is white then + grid locking is off. There is no grid locking + if the grid is turned off. Also, grid locking will + lock to nearby points. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ EDITART KEYS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + ---- Keys you will need to know if you want to select from a section of + a 320*200*256 picture file (.BMP and .PCX only) and put it into the BUILD + engine. + + U - Use this to import a section of a 320*200*256 .BMP, .PCX, or .GIF. + ³ Enter - Convert the image that is inside the rectangular selection + ³ rectangle to the BUILD palette. + ³ Space - Convert the image that is inside the rectangular selection + ³ rectangle without remapping the palette. + ³ P - If in the picture selecting screen (after pressing U and loading + ³ the picture), you press P, then the palette of BUILD can be + ÀÄÄ replaced by the palette of the displayed picture. + PGUP/PGDN - Select tile to edit (4096 tile maximum right now). + G - GOTO a tile by typing in the tile number. + S - Re-size tile. The X and Y sizes can be any unsigned short integer. + X ranges from 0 to 1024, and Y ranges from 0 to 240. + Delete - short cut key to set both the X and Y sizes to 0. + +,- Change the animation setting. (Default: NoAnm = 0.) + To change the animation type, press - when the value is 0. + Ex: If you want an object to have 4 tiles of animation, you can + animate it in 4 different sequences: (0 is the current tile) + NoAnm=4 sequence: 0,0,0,0,0,0,0,0,0,0,0,... (no animation) + Oscis=4 sequence: 0,1,2,3,2,1,0,1,2,3,2,... (oscillate) + AnmFD=4 sequence: 0,1,2,3,0,1,2,3,0,1,2,... (forwards) + AnmBK=4 sequence: 0,-1,-2,-3,0,-1,-2,-3,... (backwards) + A - Set the animation speed of the tile. Press + and - to change the + animation speed. There are 16 different animation speeds. The + animation speed set here set the speed for BUILD and your GAME also. + (Speed is proportional to (totalclock>>animspeed)) + ~' - This key (located just above the TAB key) allows you to center a + sprite. Simply use the arrow keys to get to the desired position. + N - Name a tile. Naming a tile simply changes the #define statement in + NAMES.H. You should include NAMES.H when compiling so you can easily + refer to sprites by name rather than by number. + O - Optimize the size of an individual piece of artwork. Use this for + tiles with invisible pixels on the sides. + V - View and select a tile to edit. + ³ Space - To swap 2 tiles simply press space bar on the first tile, + ³ then space bar on the second. + ³ 1,2,3 - To swap a group of tiles, press 1 on the first tile, + ³ press 2 to remember the region between where you pressed + ³ 1 and 2. Press 3 at the place to where you want to swap + ÀÄÄ all the tiles. +ALT+U- Re-grab artwork from original pictures according to the CAPFIL.TXT + file. If you press ALT-U in the main screen, everything will be + re-grabbed. If you press ALT-U in 'V' mode, then you should first + select the range by pressing '1' and '2' on the range boundaries. +ALT+R- Generate a Tile frequency report by scanning all maps in directory. + Use in 'V' mode only. +F12 - Screen capture (saves image as a *.BMP file, starting as file + name CAPTUR00.BMP and incrementing by 1 each time F12 is + pressed. + + ESC - Quit. + + + + ---- Extra features: (if you actually want to do the artwork in EDITART + or if you want to touch-up some imported art.) + + C - Change all pixels on the tile having the same color under the + graphics cursor to to selected color. + Arrows / Mouse - Move graphics cursor. + Shift + Arrows - Select color. (on bottom right corner of screen) + Space - Plot a pixel with the selected color. + T - Turn drawing trail on / off. + Tab - Select the color under the graphics cursor. + BACKSPACE - Set the color to color 255 (transparent color). + F - Floodfill a region with the current color and with the current + color as a boundary. + M,P - Use M to back up a tile into a temporary buffer in memory and P + to restore it. It may be wise to press M before a floodfill (F) + (because sometimes you miss encapsulating the region by 1 pixel, + and the whole picture gets killed, etc...) + J - Randomly plots dots of current color over any pixels having the + same color as the color under the tile cursor. + [ - Random antialias of colors in color band under graphics cursor. + ] - Non-random antialias of colors in color band under graphics cursor. + ; - 3-Dimentionalize an image. Makes colors in different rows of the + color bar either appear to stick out or stick in to the wall. + ' - 3-Dimentionalize the other way. + R - Rotate the tile in a specified direction. + + 1 - Mark the first corner of a rectangle for a copy/paste operation. + 2 - Mark the other corner of a rectangle for a copy/paste operation. + 3 - Paste the selected rectangle (Note: You must press 1 and 2 in that + order first before pressing 3. Pretty simple 1-2-3 for copy&paste) + + 4 - Flip the copied rectangular region x-wise. + 5 - Flip the copied rectangular region y-wise. + 6 - Swap the x and y coordinates of the copied rectangular region. + + ,.<> - Change the shade of the selected region. + \ - Move the cursor to the center or the tile. + | - Get the coordinates of the cursor. + +ÉÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍ» +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÈÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊͼ + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ IMPORTANT ENGINE FUNCTIONS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +initengine(char vidoption, long xdim, long ydim) + Sets up interrupt vectors for keyboard, and initializes many variables + for the BUILD engine. You should call this once before any other + functions of the BUILD engine are used. + + vidoption can be anywhere from 0-6 + xdim,ydim can be any mode x resolution if vidoption = 0 + xdim,ydim can be any vesa resolution if vidoption = 1 + xdim,ydim must be 320*200 for any other mode. + (see graphics mode selection in my setup program) +uninitengine(); + Restores interrupt vectors for keyboard and timer, and frees + buffers. You should call this once at the end of the program + before quitting to dos. +loadboard(char *filename, long *posx, long *posy, long *posz, short *ang, short *cursectnum) + Loads the given board file into memory for the BUILD engine. + Returns -1 if file not found. If no extension is given, .MAP will + be appended to the filename. +saveboard(char *filename, long *posx, long *posy, long *posz, short *ang, short *cursectnum) + Saves the given board from memory inro the specified filename. + Returns -1 if unable to save. If no extension is given, .MAP will + be appended to the filename. +loadpics(char *filename); + Loads the given artwork file into memory for the BUILD engine. + Returns -1 if file not found. If no extension is given, .ART will + be appended to the filename. +setgamemode(); + This function sets the video mode to 320*200*256color graphics. + Since BUILD supports several different modes including mode x, + mode 13h, and other special modes, I don't expect you to write + any graphics output functions. (Soon I have all the necessary + functions) If for some reason, you use your own graphics mode, + you must call this function again before using the BUILD drawing + functions. + +drawrooms(long posx, long posy, long posz, short ang, long horiz, short cursectnum) + This function draws the 3D screen to the current drawing page, + which is not yet shown. This way, you can overwrite some things + over the 3D screen such as a gun. Be sure to call the drawmasks() + function soon after you call the drawrooms() function. To view + the screen, use the nextpage() function. The nextpage() function + should always be called sometime after each draw3dscreen() + function. +drawmasks(); + This function draws all the sprites and masked walls to the current + drawing page which is not yet shown. The reason I have the drawing + split up into these 2 routines is so you can animate just the + sprites that are about to be drawn instead of having to animate + all the sprites on the whole board. Drawrooms() prepares these + variables: spritex[], spritey[], spritepicnum[], thesprite[], + and spritesortcnt. Spritesortcnt is the number of sprites about + to be drawn to the page. To change the sprite's picnum, simply + modify the spritepicnum array If you want to change other parts + of the sprite structure, then you can use the thesprite array to + get an index to the actual sprite number. + +engineinput(); + This function allows the engine to adjust your position depending + on the status of the arrow keys, and other control keys. It + handles timing and clipping. +nextpage(); + After a screen is prepared, use this function to view the screen. + +draw2dscreen(long posxe, long posye, short ange, long zoome, + short gride) + Draws the 2d screen - this function is a direct replacement + for the drawrooms() and drawmasks() functions. Be sure + to call either qsetmode640350() or qsetmode640480() + first. When switching back to 3d mode, be sure to call + qsetmode320200(). + IMPORTANT NOTES: + 1. The overwritesprite function should only be called in + 3D mode. If you do this in 2D mode, junk will be + written to the 2D screen and a crash is possible. + 2. When you switch back to 3D mode, you should call the + permanentwritesprite functions to draw the status bar, + or whatever else you have to draw. + 3. You must call the nextpage() function in both 2D and + 3D modes. +qsetmode320200(); + Set to the game mode and load palette (320*200*256) +qsetmode640350(); + Set to the 2D map mode #1 (640*350*16) +qsetmode640480(); + Set to the 2D map mode #2 (640*480*16) + +doanimations(long numtics); + This function animates anything you use setanimation for (like doors). + You should call it for every frame. Pass the number of tics (lockspeed) + as a parameter to it to tell how much everything should animate. + +kenchaintimer(void (__interrupt __far *datimerchainaddress)(), + short dachainpersecond) + This function makes the engine's timerhandler chain to another timer + handler at any specified interrupt rate. This function forces IRQ0 to + point to my engine's timerhandler. Clockspeed and totalclock will + be fixed at counting 120 per second regardless of the chaining interrupt + rate. If you call this function with a NULL pointer, then the engine's + timerhandler will not chain anymore. + + Here's how you should structure your code if you use this function: + + main() + { + initengine(); + + musicon(); //Turn music on after engine + kenchaintimer(yourtimerhandleraddress,yourtimerrate); + //When IRQ0 goes off, it will now go to + //Ken's timer handler. Then, Ken's timer + (main loop) //handler will make yourtimerhandler + //interrupt yourtimerrate times per second + + kenchaintimer(0,0); //Stop chaining BEFORE music handler dies! + musicoff(); + + uninitengine(); + } + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ OTHER ENGINE FUNCTIONS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +overwritesprite (long thex, long they, short tilenum, + signed char shade, char orientation, char dapalnum) + + Use this function to draw any sprites that must be drawn to the screen + for every single frame, such as a gun or a menu system. + + If Bit 0 of orientation = 0: (thex, they) is top-left corner + If Bit 0 of orientation = 1: (thex, they) is middle + If Bit 1 of orientation = 0: no relation to viewing window + If Bit 1 of orientation = 1: scale and clip to viewing window + If Bit 2 of orientation = 0: normal + If Bit 2 of orientation = 1: 50/50 transluscent! + If Bit 3 of orientation = 0: normal + If Bit 3 of orientation = 1: x-flipped + If Bit 4 of orientation = 0: normal + If Bit 4 of orientation = 1: y-flipped + + * If it works at full screen, simply set bit 1 of orientation + to 1, and it should automatically scale properly! + + Use this function to write sprites over the 3d view. For example, + you can make a menu system with this function. Be sure + that you call this function for every single frame after the 3d + view is drawn or else it will be flashed on for only 1 frame. + If you want x and y to be the top left corner, set the orientation + to 0. If you want x and y to be the middle of the sprite, set the + orientation to 1. The reason I included the orienation = 1 option + is so that if you want a sprite centered and the size of the tile + changes, you don't need to recompile and guess where the new top + left corner is. Oh yeah, and I forget to mention that if shade is + greater than 32, than overwritesprite does transluscence. (Try it + out!) This function will clip the sprite to the startumost and + startdmost arrays. Dapalnum refers to a palette lookup list + (normally 0). + +rotatesprite (long sx, long sy, long z, short a, short picnum, + signed char dashade, char dapalnum, char dastat, + long cx1, long cy1, long cx2, long cy2) + (sx, sy) is the center of the sprite to draw defined as + screen coordinates shifted up by 16. + (z) is the zoom. Normal zoom is 65536. + Ex: 131072 is zoomed in 2X and 32768 is zoomed out 2X. + (a) is the angle (0 is straight up) + (picnum) is the tile number + (dashade) is 0 normally but can be any standard shade up to 31 or 63. + (dapalnum) can be from 0-255. + if ((dastat&1) == 0) - no transluscence + if ((dastat&1) != 0) - transluscence + if ((dastat&2) == 0) - don't scale to setview's viewing window + if ((dastat&2) != 0) - scale to setview's viewing window (windowx1,etc.) + if ((dastat&4) == 0) - nuttin' special + if ((dastat&4) != 0) - y-flip image + if ((dastat&8) == 0) - clip to startumost/startdmost + if ((dastat&8) != 0) - don't clip to startumost/startdmost + if ((dastat&16) == 0) - use Editart center as point passed + if ((dastat&16) != 0) - force point passed to be top-left corner + if ((dastat&32) == 0) - nuttin' special + if ((dastat&32) != 0) - use reverse transluscence + if ((dastat&64) == 0) - masked drawing (check 255's) (slower) + if ((dastat&64) != 0) - draw everything (don't check 255's) (faster) + + Note: As a special case, if both ((dastat&2) != 0) and ((dastat&8) != 0) + then rotatesprite will scale to the full screen (0,0,xdim-1,ydim-1) + rather than setview's viewing window. (windowx1,windowy1,etc.) This + case is useful for status bars, etc. + + Ex: rotatesprite(160L<<16,100L<<16,65536,totalclock<<4, + DEMOSIGN,2,50L,50L,270L,150L); + This example will draw the DEMOSIGN tile in the center of the + screen and rotate about once per second. The sprite will only + get drawn inside the rectangle from (50,50) to (270,150) + +permanentwritesprite (long thex, long they, short tilenum, signed char shade, + long cx1, long cy1, long cx2, long cy2, char dapalnum) + - Added permanentwritesprite function for status bars or other + sections of the screen that will not be overwritten by the + engine. The format of this function is like overwritesprite + except that the x and y are always top left corner, no + orientation variable, and no translucence. + The 4 last parameters (cx1, cy1) - (cx2, cy2) define a + rectangular clipping window of where permanentwritesprite + can draw to. Dapalnum refers to a palette lookup list + (normally 0). + +printext(long x, long y, char buffer[42], short tilenum, char invisiblecol); + Use this function to print text anywhere on the screen from a font + that you can create in EDITART. Please see my example font in + TILES.ART to see how I lay out the user-defined font. X ranges + from 0-319. Y ranges from 0-199. The buffer is the string to + print. Tilenum specifies which font to use. Invisiblecol tells + printext what color to draw the transparent pixels. If + invisiblecol is 255 then the transpararent pixels are still + transparent. +printnum(long x, long y, long num, short tilenum, char invisiblecol); + Printnum is a function call that will print a long integer (num) + starting at top left corner x, y. Please look at the documentation + for printext, since internally, printnum simply prepares a buffer + and calls the printext function. + +setvmode(long videomode); + If you look at the top of GAME.C, you will see something like this: + #pragma aux setvmode =\... This is how you do in-line assembler in + WATCOM C. All this function is doing is setting the video mode. +showengineinfo(); + Use this function after setting to text mode to view some statics + about the engine, such as frame rate. +resettiming(); + Resets timing, such as setting totalclock = 0. Also resets other + timers. This is for use with the showengineinfo function above. + +ksqrt(long num); returns (long)square root + A square root function optimized for integers. Use this function + only if you want to. +krand() + This simply returns a random number. You can easily set the random + seed by externing the randomseed variable as a long. This is useful + for keeping the random seed the same on multiple computers when playing + multi-player mode. + +getangle(long xvect,long yvect); returns (short)angle; + Use this function call to determine the angle between two points. + For example, if you want a monster to shoot a bullet towards you, + you would get the bullet's angle this way: + sprite[bullet].ang = getangle(posx-sprite[monst].x,posy-sprite[monst].y); + +lastwall(short point); + Use this function as a reverse function of wall[].point2. In order + to save memory, my walls are only on a single linked list. + +rotatepoint(long xpivot, long ypivot, long x, long y, + short daang, long *x2, long *y2); + This function is a very convenient and fast math helper function. + Rotate points easily with this function without having to juggle your + cosines and sines. Simply pass it: + + Input: 1. Pivot point (xpivot,ypivot) + 2. Original point (x,y) + 3. Angle to rotate (0 = nothing, 512 = 90ø CW, etc.) + Output: 4. Rotated point (*x2,*y2) + +clipmove(long *x, long *y, long *z, short *sectnum, long xvect, long yvect, + long walldist, long ceildist, long flordist, char cliptype) + Moves any object (x, y, z) in any direction at any velocity and will + make sure the object will stay a certain distance from walls (walldist) + Pass the pointers of the starting position (x, y, z). Then + pass the starting position's sector number as a pointer also. + Also these values will be modified accordingly. Pass the + direction and velocity by using a vector (xvect, yvect). + If you don't fully understand these equations, please call me. + xvect = velocity * cos(angle) + yvect = velocity * sin(angle) + Walldist tells how close the object can get to a wall. I use + 128L as my default. If you increase walldist all of a sudden + for a certain object, the object might leak through a wall, so + don't do that! + If cliptype is 0, then the clipping is normal (Use 0 to clip you + and monsters). If the cliptype is 1, then the object is clipped to + the same things that hitscan is clipped to (use 1 for all bullets). + + Clipmove can either return 0 (touched nothing) + 32768+wallnum (wall first touched) + 49152+spritenum (sprite first touched) + +getzrange(long x, long y, long z, short sectnum, + long *ceilz, long *ceilhit, + long *florz, long *florhit, + long walldist, char cliptype) + + Use this in conjunction with clipmove. This function will keep the + player from falling off cliffs when you're too close to the edge. This + function finds the highest and lowest z coordinates that your clipping + BOX can get to. It must search for all sectors (and sprites) that go + into your clipping box. This method is better than using + sector[cursectnum].ceilingz and sector[cursectnum].floorz because this + searches the whole clipping box for objects, not just 1 point. + Pass x, y, z, sector normally. Walldist can be 128. Cliptype can be + 0, 1, or 2. (just like movesprite and clipmove) This function returns + the z extents in ceilz and florz. It will return the object hit in ceilhit + and florhit. + Ceilhit and florhit will also be either: + 16384+sector (sector first touched) or + 49152+spritenum (sprite first touched) + +updatesector(long x, long y, §num); + This function updates the sector number according to the x and y values + passed to it. Be careful when you use this function with sprites because + remember that the sprite's sector number should not be modified directly. + If you want to update a sprite's sector, I recomment using the setsprite + function described below. + +inside(long x, long y, short sectnum); + Tests to see whether the overhead point (x, y) is inside sector (sectnum) + Returns either 0 or 1, where 1 means it is inside, and 0 means it is not. + +copytilepiece(long tilenume1, long sourcex1, long sourcey1, + long xsiz, long ysiz, + long tilenume2, long destx1, long desty1) + + This function simply copies any section of a source tile + to any part of a destination tile. It will automatically + skip transparent pixels. It will wrap-around in the + source but not the destination. If for some reason + the destination tile gets removed from the cache, the + destination tile will be reset to original form. This + is why I had to add this second function: + +allocatepermanenttile(short tilenume, long xsiz, long ysiz) + This function allocates a place on the cache as permanent. + Right now, I reset the cache every time you call this + function so I would recommend calling this function + right after loadpics. + +makepalookup(long palnum, char *remapbuf, + signed char r, signed char g, signed char b, + char dastat) + This function allows different shirt colors for sprites. First prepare + remapbuf, which is a 256 byte buffer of chars which the colors to remap. + Palnum can be anywhere from 1-15. Since 0 is where the normal palette is + stored, it is a bad idea to call this function with palnum=0. + In BUILD.H notice I added a new variable, spritepal[MAXSPRITES]. + Usually the value of this is 0 for the default palette. But if you + change it to the palnum in the code between drawrooms() and drawmasks + then the sprite will be drawn with that remapped palette. The last 3 + parameters are the color that the palette fades to as you get further + away. This color is normally black (0,0,0). White would be (63,63,63). + if ((dastat&1) == 0) then makepalookup will allocate & deallocate + the memory block for use but will not waste the time creating a palookup + table (assuming you will create one yourself) + +copytilepiece(long walnume1, long x1, long y1, long xsiz, long ysiz, + long walnume2, long x2, long y2, char shadeoffs); + Copies section of tile 1 (walnume1) with top-left corner (x1,y1) and + rectangular size (xsiz, ysiz) to top-left corner (x2, y2) of tile 2 + (walnume). You can animate tiles with this function. For example, with + this function, you can make a slot machine like in Ken's Labyrinth or an + electronic sign with text sliding from right to left. + +loadtile(short tilenume); + This function will load the tile, tilenum, into the artwork cache. A + tile is not in the cache if (waloff[tilenum] == -1). If + (waloff[tilenum] >= 0) then it is in the cache, and you don't need to call + this function. + +precache(); + This function will go through the tilenums of all sectors, walls, and + sprites and call loadtile() on them. This function will not cache in some + tiles of animations since their tilenums may not all be in the structures. + +hitscan(long xstart, long ystart, long zstart, short startsectnum, + long vectorx, long vectory, long vectorz, + short *hitsect, short *hitwall, short *hitsprite, + long *hitx, long *hity, long *hitz); + + Pass the starting 3D position: + (xstart, ystart, zstart, startsectnum) + Then pass the 3D angle to shoot (defined as a 3D vector): + (vectorx, vectory, vectorz) + Then set up the return values for the object hit: + (hitsect, hitwall, hitsprite) + and the exact 3D point where the ray hits: + (hitx, hity, hitz) + + How to determine what was hit: + * Hitsect is always equal to the sector that was hit (always >= 0). + + * If the ray hits a sprite then: + hitsect = thesectornumber + hitsprite = thespritenumber + hitwall = -1 + + * If the ray hits a wall then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = thewallnumber + + * If the ray hits the ceiling of a sector then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = -1 + vectorz < 0 + (If vectorz < 0 then you're shooting upward which means + that you couldn't have hit a floor) + + * If the ray hits the floor of a sector then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = -1 + vectorz > 0 + (If vectorz > 0 then you're shooting downard which means + that you couldn't have hit a ceiling) + +neartag(long x, long y, long z, short sectnum, short ang, //Starting position & angle + short *neartagsector, //Returns near sector if sector[].tag != 0 + short *neartagwall, //Returns near wall if wall[].tag != 0 + short *neartagsprite, //Returns near sprite if sprite[].tag != 0 + long *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size) + long neartagrange, //Choose maximum distance to scan (scale: 1024=largest grid size) + char tagsearch) //1-lotag only, 2-hitag only, 3-lotag&hitag + Neartag works sort of like hitscan, but is optimized to + scan only close objects and scan only objects with + tags != 0. Neartag is perfect for the first line of your space bar code. + It will tell you what door you want to open or what switch you want to + flip. + +cansee(long x1, long y1, long z1, short sectnum1, + long x2, long y2, long z2, short sectnum2); returns 0 or 1 + This function determines whether or not two 3D points can "see" each + other or not. All you do is pass it the coordinates of a 3D line defined + by two 3D points (with their respective sectors) The function will return + a 1 if the points can see each other or a 0 if there is something blocking + the two points from seeing each other. This is how I determine whether a + monster can see you or not. Try playing DOOM1.DAT to fully enjoy this + great function! + +setanimation(long *animptr, long thegoal, long thevel); + This is a function for your convenience that will animate a long + variable, such as sector[].floorz for platforms, or sector[].ceilingz + for doors. All you do is pass it the long pointer into memory, specifying + which long variable is to be animated; you also pass the goal (long value + to animate towards), and the velocity at which the variable is animated. + Velocity = 128 is a normal speed door. You may also modify the animation + arrays directly if you wish: + + The animation arrays are as follows: + long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; + long animatevel[MAXANIMATES], animatecnt; + +getanimationgoal(long animptr); + Check to see if a certain variable in memory is already being animated + by the engine. If so, an index into the animation arrays is returned, + else -1 is returned. This is function is useful when you are press + space bar near a door, and it is already animating, you simply want + to reverse its direction. + +dragpoint(short wallnum, long newx, long newy); + This function will drag a point in the exact same way a point is dragged + in 2D EDIT MODE using the left mouse button. Simply pass it which wall + to drag and then pass the new x and y coordinates for that point. + Please use this function because if you don't and try to drag points + yourself, I can guarantee that it won't work as well as mine and you + will get confused. Note: Every wall of course has 2 points. When you + pass a wall number to this function, you are actually passing 1 point, + the left side of the wall (given that you are in the sector of that wall) + Got it? + +nextsectorneighborz(short sectnum, long thez, short topbottom, short direction); + This function searches z-coordinates of neighboring sectors to find the + closest (next) ceiling starting at the given z-coordinate (thez). + For example, if you want to find the goal z-coordinate when opening a + door, you might want the door to stop at the next closest neighboring + ceiling z-coordinate. You can get the z-coordinate this way: + + newz = sector[nextsectorneighborz(sectnum,startz,-1,-1)].ceilingz + + topbottom (3rd parameter) -1 = search ceilings + 1 = search floors + direction (4th parameter) -1 = search upwards + 1 = search downwards + +screencapture(char *filename) + Capture the screen and save it as a .BMP file. I don't know why my + .BMP format isn't compatible with other programs. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ SPRITE FUNCTIONS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + +insertsprite(short sectnum, short statnum); //returns (short)spritenum; + Whenever you insert a sprite, you must pass it the sector + number, and a status number (statnum). The status number can be any + number from 0 to MAXSTATUS-1. Insertsprite works like a memory + allocation function and returns the sprite number. + +deletesprite(short spritenum); + Deletes the sprite. + +changespritesect(short spritenum, short newsectnum); + Changes the sector of sprite (spritenum) to the + newsector (newsectnum). This function may become + internal to the engine in the movesprite function. But + this function is necessary since all the sectors have + their own doubly-linked lists of sprites. + +changespritestat(short spritenum, short newstatnum); + Changes the status of sprite (spritenum) to status + (newstatus). Newstatus can be any number from 0 to MAXSTATUS-1. + You can use this function to put a monster on a list of active sprites + when it first sees you. + +setsprite(short spritenum, long newx, long newy, long newz); + This function simply sets the sprite's position to a specified + coordinate (newx, newy, newz) without any checking to see + whether the position is valid or not. You could directly + modify the sprite[].x, sprite[].y, and sprite[].z values, but + if you use my function, the sprite is guaranteed to be in the + right sector. + +movesprite(short spritenum, long xchange, long ychange, long zchange, + long ceildist, long flordist, char cliptype, long numtics) + This function moves the sprite given by spritenum by the 3 + increments, xchange, ychange, and zchange. If cliptype is 0, then + the clipping is normal (Use 0 to clip you and monsters). If the + cliptype is 1, then the object is clipped to the same things that + hitscan is clipped to (use 1 for all bullets). + Movesprite can either return 0 (touched nothing) + 16384+sectnum (ceiling/floor first touched) + 32768+wallnum (wall first touched) + 49152+spritenum (sprite first touched) + +getspritescreencoord(short spritesortnum, long *scrx, long *scry) + This function returns the actual screen coordinates of a sprite. It + is useful for locking on to a target. Use this function between + drawrooms and drawmasks. Note that spritesortnum is the index into the + spritesortcnt arrays, NOT the normal sprite arrays. Scrx and scry are + actual screen coordinates ranging from 0-319 and 0-199 respectively. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ MULTIPLAYER FUNCTIONS (multi.obj) ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + + initmultiplayers(char option[4], char option[5], char priority); + Call this right after initengine. Pass option[4] and option[5] + exactly the way I have it written here. (option[4] is the COM1-COM4, + network option and option[5] is the com speed selection option) + Priority can be used to decide who becomes master. Lower is more + towards the master. + + uninitmultiplayers(); + Call this right before uninitengine. + + sendlogon(); + Use this function after everything's initialized, but before you + go into the main game loop. Right after you call sendlogon(), you + should run a loop that will wait until a specified number of players. + Here's some example code: + + sendlogon(); + while (numplayers < waitplayers) + { + getpackets(); + } + screenpeek = myconnectindex; + + Getpackets reserves the packet header range from 200-255. If you + keep calling getpackets after sendlogon, the numplayers variable will + automatically be incremented when other people log on. + + sendlogoff(); + Call this before leaving, before uninitializing the multiplayer + code. + + sendpacket (short otherconnectindex, char *bufptr, short bufleng) + For COM(modem) communications, the otherconnectindex doesn't matter. + For network communcations, you can specify which computer to send + to by setting otherconnectindex to the proper index number. You + can also do a broadcast by setting otherconnectindex to -1. + Also pass the buffer and length parameters. + + short getpacket (short *otherconnectindex, char *bufptr) returns bufleng + When using getpacket, first check the value it returns. + If the value is 0, then the buffer length is 0 which means there + are no packets available. If the buffer length is greater than + 0, then use that value as the length of the buffer. Getpacket also + tells you what computer the message was received from - + (otherconnectindex). + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ DIGITIZED SOUND FUNCTIONS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +Note: If you want to write your own digitized sound driver, simply delete + these functions from GAME.C. + +initsb(); + Initializes the digitized sound routines. You need to call this + only once at the beginning of the program. Currently, the + sample rate is 11,025 Hz. + +wsay(char *filename, long freq, char volume); + Play the sound file at the given frequency and volume. If you + set freq = 4096, the sound will play at normal frequency (given + the sound was also recorded at 11025 Hz) To play the sound an + octave higher, for example, set freq = 8192. Volume ranges from + 0 (silent) to 255 (full volume). Ex: wsay("blowup.wav",4096L,255); + +uninitsb(); + Turns the speaker off, so sounds don't continue playing while + your back in DOS. + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ MUSIC FUNCTIONS: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +Note: If you want to write your own music driver, simply delete these + functions from GAME.C. The BUILD engine uses interrupt vector 0x8 (IRQ0) + and that may complicate things. If you like my music, perhaps I can send + you my MIDI sequencer program (It requires MPU-401, and TSENG-ET4000 SVGA, + but could be standardized if there's enough demand). + +loadmusic(char *filename); + Loads the given song into memory. Be sure INSTS.DAT is in the + current directory. If no extension is given, then .KSM will be + appended to the filename. You should use this function only when + the music is off. +musicon(); + Enable the playing of music. Use this only after loadmusic has + been called. +musicoff(); + Disable the playing of music. Be sure to call this before quitting + to DOS. + +ÉÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍËÍ» +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÌÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎÍÎ͹ +ÈÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊÍÊͼ + +ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ +³ BUILD Revision History: ³ +ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ +2/6/94 - Added this revision thing. + - Setup program. + - A faster new mode for standard VGAs called chain mode. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/8/94 - Fixed chain mode with groudraws. + - Added sector joining in 2D EDIT MODE - press J on first sector. + Then press J again on sector to join with. Attributes will be + taken from first sector. Possible bugs. + - Improved controls for slower computers. + - Made timer interrupt rate 120/second instead of 240/second. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/9/94 - Started to work on status bar in 2D EDIT MODE. + - Added special optimization for the Western Digitial (Paradise) + chipset just like with TSENG ET4000. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/10/94 - Added a door attribute to sectors. To make a sector a door, + press "D" on the ceiling of the sector in 3D EDIT MODE. For + the door to work, the ceiling of the door sector must be a + tiny bit lower than lowest neighboring ceiling. To open/close + the door, you may press the space bar. Note: Space Bar is also + used for copy and paste in 3D EDIT MODE. You may have to go + into game mode to test out the doors for now. + - Added a wall orientation attribute to walls. This attribute is + used especially in conjunction with doors. So far, you have + been working with walls that are start from the top. For + example, if you hold down 2/8 on the keypad in 3D EDIT MODE, + the wall always starts from the top. But for doors, you + sometimes need walls to start from the bottom. To do this, + press "O" (for orientation) on the wall, and it will now + start from the bottom. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/12/94 - Fixed some bugs for sprites. Sprites don't disappear anymore. + Now you will pick up all sprites when running over them. + Monsters will not stop shooting anymore. + - Made the sound blaster sounds have a 1-sound cache. That is, if + the same sound is to be played several times in a row, it will + only be loaded once. + - Added *.GIF format support to EDITART for 320*200 size images. + - Changed the PASTE key in 3D EDIT MODE from Space bar to Left + Enter because the Space bar conflicted with opening doors. + - Added music as an option in the setup program. To run the music, + you need INSTS.DAT and a song file with a .KSM extension. + - Split the editor from the game. + BUILD is now the map editor - you don't need BUILD.C anymore. + GAME is now the actual game that you will be programming. + I am giving you GAME.C to work with. Its code is simpler + than before because there are no more editing function + calls in it. + - Sprites move in a straight line now until they hit walls. When + they hit walls, they pick a new angle to travel in. + - Remember that tiny little guy with the "Al" on his shirt? + Next time you're in DOOM1.DAT, try shooting him. Then look + at the code in GAME.C. + - In EDITART, when you press, "u", you now select filenames with + the arrow keys and enter rather than having to type in + the exact filename. + - Board maps now have extension .MAP and artwork files now have + extension .ART to help distinguish between the different types + of files. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/22/94 - Fixed small bug with EDITART not loading right when names.h + existed with no names defined. + - You can now edit new boards by typing: + BUILD like "BUILD NEWBOARD" + - Added ALT-S in 2D EDIT Mode to change a whole white loop inside a + sector to a red loop. + - When viewing the tiles (pressing "v") you can now use PGUP/PGDN. + - Added a message bar in 2D EDIT Mode. + - Added TAB and L.ALT-TAB keys to view all the attributes of a + sector, wall, or sprite (see above documentation). + - Debugged and bullet-proofed ALT-S. + - Fixed a bug that doesn't allow you to drag points with number + greater than 1023. (There can actually be 4096 walls and 1024 + sectors, and 4096 sprites currently, an easy thing to increase) + - Changed overwritesprite function paramaters. If you are using it + in your c file, you must change it! Now it looks like this: + + overwritesprite (long x, long y, short tilenum, char shade, + char orientation); + + If orientation = 0: x and y are the top left corner. + If orientation = 1: x and y are the middle (like before). + - Added permanentwritesprite function for status bars or other + sections of the screen that will not be overwritten by the + engine. When using this function, you may want to modify the + STARTUMOST / STARTDMOST arrays. The format of this function is + like overwritesprite except that the x and y are always top + left corner, no orientation variable, and no translucence. + + permanentwritesprite (long x, long y, short tilenum, char shade); + + - Added an attribute to the printext and printnum functions. Please + change these function if you use them in your program. The + current formats are: + + printext(long x, long y, char buffer[42], short tilenum, + char invisiblecol) + printnum(long x, long y, long num, short tilenum, + char invisiblecol); + + Invisiblecol tells printext what color to draw the transparent + pixels. If invisiblecol is 255 then the transpararent pixels are + still transparent. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/26/94 - Completely reprogrammed EDITART. + IMPORTANT: PLEASE RUN CONVART.EXE ON ALL ARTWORK FILES! (If you have not + already). It will convert PICS.ART in the old format to + TILES.ART in the new format, so you may have to do some + renaming when converting artwork and also rename the loadpics + line in your C file. BUILD WILL NOT RUN UNLESS YOU DO THIS! + With the new artwork file, the tiles can now be any size from + 1*1 to 1024*240 and they no longer have to be powers of 2. + This feature allows parallaxing skies that are 1024 pixels wide + to cover all 360ø, or 320 pixel wide status bars. It can also + be used to display 320*200 title screens. + - When pressing 'U' in EDITART, you can now change directories + and the current loading directory will be remembered. + - When pressing 'U' in EDITART, you can press the mouse button to + readjust the size of the tile. + - When pressing 'U' in EDITART, press ENTER for an automatic + palette conversion or press SPACE BAR for no conversion. + - Walls that are Blocked ('B') in BUILD are now shown in pink. + If the wall does not show pink in your board, just press + 'B' twice to permanently fix it. + - Made smooshiness values easier to work with. Hold down 5 on the + keypad with 2/4/6/8 to align the walls to multiples of the + tile that is used. Also, when you do Tab and L.Enter for + Copy&Paste, the y-repeat values stay the same, and the + x-repeat values are adjusted so the pixels of the bitmaps + have a square-aspect ratio. + - Added masked walls. But since they don't quite work perfectly + yet, and they are extremely hard to edit now, so for now, just + enjoy the technologiy in DOOM1.MAP. Don't worry - you'll get + your hands on this soon! + - Fixed the "earthquake" effect on really high walls. The walls + will not move up and down, but the pixel fuzzyness bug is + still in there. + - Put door variables and tile information into BUILD.H for you to + play around with. + - Made walls, ceilings, and floors also work with the animation + attribute in EDITART. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/2/94 - Made power of 2 size tiles work with ceilings & floors. + - When using different size ceilings & floors, made an option in + 3D EDIT MODE. If you want a tile to be smooshed into the normal + 64*64 area, press 'E' to unExpand the tile. + - Groudraws now look more cubical than before. (But be careful of + crashing with them for now) + - IMPORTANT: Changed the Board format. If you tried running BUILD + before reading this, and it didn't work, shame on you! You + should always look at the history section of BUILD.TXT first! + Since from now on, I am writing Board/Art converters, I am + giving you CONVMAP.EXE to convert maps. You can type either: + C:\BUILD>convmap house.map + to convert an individual map or: + C:\BUILD>for %i in (*.map) do convmap %i + to convert all the maps in a directory. + + - IMPORTANT: Sprites are now on 2 different sets of doubly-linked + lists. The big advantage of this method is that when sprites + are deleted, there can be holes in the sprite list with + no slow down. Before I used to have linked lists for each + sector pointing to all the sprites in it. Well, I have updated + that and added more linked lists that tell whether sprites + are active or inactive (not a fun thing to progam) But not + to worry, you don't have to deal with changing the linked + lists, thanks to my very easy function calls. YOU WILL + HAVE TO CHANGE YOUR CODE TO SUPPORT THE NEW LINKED LISTS. + You should know how to search through each list. See BUILD.H + for a detailed description of how the linked lists work, and + see the top of this file for description of the new sprite + function calls. + + insertsprite(short sectnum, short statnum); + deletesprite(short spritenum); + changespritesect(short spritenum, short newsectnum); + changespritestat(short spritenum, short newstatnum); + + In your code, you will have to change the following: + firstsprite[spritenum] --> headspritesect[spritenum] + sprite[spritenum].point2 --> nextspritesect[spritenum] + + Also, you should change the part of your main loop that scans + through all the active sprites to look more like this: + + + i = headspritestat[1]; //head of active sprite list + while (i != -1) + { + nexti = nextspritestat[i]; //back up next sprite in case current + //one is deleted. + + //your code goes here (use i as the sprite number) + +spriteisdeletedskip: + i = nexti; //go to next sprite + } + + + + - Added tagging (naming) to any sector, sprite, or wall. That means + you can change a tag in the BUILD editor by pressing T with the + mouse cursor on the highlighted sector. And in GAME.C, you + can access the tag this way: + sector[sectnum].tag; + sprite[spritenum].tag; + wall[wallnum].tag; + Note: All 3 types of tags are long integers, but in BUILD.C + you can only make them short integers. I am planning to + let you use the upper 16 bits of the tag byte as use for + you only. (like permanently unreserved bits) + - Added serial link. But it doesn't work very well yet. You + may have to try going into GAME several times before it works. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/15/94 - Fixed maskable walls - now sort out with sprite better. Easier + to edit. Simply press 'M' at a place where a maskable wall + should be (like where you normally press 'B' for blocking) + - Can flip walls, masked walls, and sprites x-wise by pressing + 'F' in 3D EDIT MODE. Also, it is possible to save space in + sprite rotations, by flipping it x-wise by programming one of + the bits in sprite[].cstat. + - A few other minor things, but I forgot what they were. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/19/94 - Fixed one of the many crashing bugs. + For Duke Nukem III team: + CITY.MAP will not crash anymore with new version. The + reason it crashed was because in your TILES.ART, you had + either ANMFD:0, ANMBK:0, or OSCI:0. That caused a MOD 0 + in my animation routine. I bullet-proofed that. How about + fixing tiles #34, #112, or #114 in your TILES.ART. + - Wrote divide by zero handler. Now if there is a divide by zero, + BUILD goes back into text mode and fills the screen with + /0/0/0/0/..., then gives a DOS prompt. (In other words, you + don't have to type "MODE CO80" anymore for /0 crashes) + - Optimized routines in assembly for 486's using my great new + Intel 32-bit optimizing techniques book that dad got for me. + - Fixed ALT-S in BUILD so ANY white loop can be converted into a + red loop except for the 1 and only 1 outermost white loop. + - FINALLY! Splitsector bug is fixed! You can now split a very + complicated sector with tons of sectors inside it or with + plenty of sprites. Also sprites will not get deleted + spontaneously with split sector any more. + - Ctrl-Enter in 3D EDIT MODE is like the normal Enter paste key, + but Ctrl-Enter pastes the attributes to an entire loop of + walls (if a wall is highlighted). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/22/94 - Added doors that open left and right. See sector[].tag #9 in the top + of this file for details - also look at my board, NUKELAND.MAP, + in BUILD to see how to make this type of door. + - Increased the number of status lists. You may recall my active / + inactive sprite lists called headspritestat, prevspritestat, + and nextspritestat. Don't worry - you will NOT have to + change any of your code. The only thing I changed is now + you can have 1024 different lists of sprites rather than just + 2 lists if you want to use them. For example, you might want + to run through all the brown monsters on the board. Instead + of putting all different types of monsters on the active + list, it is faster to have a separate list just for brown + monsters. Use your imagination! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/31/94 - Fixed some palette problems with EDITART. Now when you press 'P' + in 'U' mode, the palette of all the existing tiles are + converted to the new palette. Also the text colors should + be similar colors on different palettes now. + - Changed bit 0 of sprite[].cstat to the hitscan checking / ignoring + bit. You should set this bit to 1 for monsters, 0 for + bullets, 0 for pick-upable objects like coins, and 1 for + objects like columns. Right now, (Since it's not in the + BUILD editor), you must set these bits in your code right + after you load the board. + - I did not document the neartagsector, neartagwall, and + neartagsprite very well, so if you don't know how to use + them alreay, please read on. These 3 variables are modified + by the engine every time you call draw3dscreen(). These + variables are usually -1. These variables will be >= 0 if + all of these cases are true: + 1. You are looking at a wall, sprite, or sector. + 2. You are close enough to the wall, sprite, or sector + to be able to use the action key with it. + 3. The tag of the wall, sprite, or sector is greater or + equal to 1. + As you can see, neartagsector makes a perfect variable for + detecting whether or not you are opening a door. You can + also use neartagwall for switches on walls. Also, you can + use neartagsprite for sprites that are switches. + - PROGRAMMERS: PLEASE MAKE THESE EASY CODE MODIFICATIONS: + I reversed the way variables are stored in BUILD.H. + Now the variables will be local to the ENGINE and externed + to GAME. Before they were local to GAME and externed to the + engine. All you have to do is this: + 1. You can remove the #define MAIN if you want to. + 2. Delete the externs declarations that I used to have + in the beginning of GAME.C, because I put them in + BUILD.H. I will try not to put externs in the GAME + in the future to save you the time of copying and + pasting code. Here is a list of externs I moved: + + EXTERN short neartagsector, neartagwall, neartagsprite; + EXTERN long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; + EXTERN long animatevel[MAXANIMATES], animatecnt; + EXTERN short tilesizx[MAXTILES], tilesizy[MAXTILES]; + EXTERN long numtiles, picanm[MAXTILES], waloff[MAXTILES]; + - Added a global parallaxing sky type variable. Now I have 3 + different types of parallaxing skies. Here they are: + + 0 - Totally flat parallaxing sky. + 1 - X-only stretching parallaxing sky (This is what DOOM uses). + 2 - X- and Y- stretching parallaxing sky. (This is what BUILD + uses by default) + A good place to set the parallaxing sky is right after you + call initengine(). + - Added local tile selection to the BUILD editor. This means + that when you press V on a sprite, you will see only the + sprites that are on the level so far. If you want to use + a sprite that is not already used on the current board, press + V again and you will be able to select from the huge list + that you are used to from before. The local tile list will + be sorted according to how much each tile is used on the + current board. Note that the local tile list will be + different depending where the mouse cursor was left when you + pressed V (or H). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/4/94 - Changed the way ART files work. YOU MUST READ THIS: + There are some two easy things that you must do 2 things before + you can use the new engine: + + 1. Type CONVART1.EXE to convert your ARTWORK to the new + format. (If I forgot to send this file to you, please call + and torture me.) Now, instead of everything being stored + in one huge file, TILES.ART, I am splitting the artwork into + several files each holding 256 tiles in it. This will allow + you to make infinitely large artwork files in EDITART. + + 2. In GAME.C, you must change the line, + loadpics("tiles.art"); + to: + loadpics("tiles000.art"); + All you have to give loadpics is the first filename of your + artwork, and the engine will automatically know how to + modify the 3 digits at the end and load all the artwork + files properly. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/5/94 - Fixed the "fuzzy" pixels on high walls. Now you make walls as + high as skyscrapers, and when you look at it up close, the + pixels will still look like perfect rectangles. Note: This + fix may require you to press 'O' in 3D EDIT MODE to put + your boards back to normal. + - When you pressed ENTER on weird-sized tiles, sometimes in the old + version the pixels would not be square aspect ratio. Now + when you press ENTER, they will be. + - You can now set the starting position in 2D EDIT MODE with the + Scroll Lock key. The starting position will look like a + brown arrow, and your current position will look like a + white arrow. Now you don't have to keep returning to start + when you save your board. + - Added some new things to the structures - guess what this means? + CONVMAP3! THE NEW OBJ'S and BUILD will NOT work until you + run CONVMAP3. (Please call if I forgot to give + you this file) + Notice that I added these things to the structures: + + sectortype: + bit 2 of ceilingstat&floorstat: + 1 = North/South panning, 0 = East/West panning + char ceilingpanning, floorpanning; + walltype: + bit 6 of cstat + 1 = Vertical panning, 0 = Horizontal panning + char panning; + short overpicnum; + spritetype: + char *extra; + + Now an explanation of each: + To the sector structure, I added the capability to pan + the floors and ceilings. Usually ceilingpanning and + floorpanning are set to 0. For example, a good way to make + an earthquake would be to randomly increment or decrement + to panning values. To allow you to pan the ceilings or + floors at any of the standard 90 degree angles, I made + bit 2 of sectortype's ceilingstat/floorstat byte choose + whether the ceilingpanning/floorpanning byte should move + the ceiling/floor North/South or East/West. + To the wall structure, I added panning also. Bit 6 + of cstat and the panning values work in the same as the + ceilings and floors. + To the sprite structure, I added only 1 variable. + The "extra" pointer is intended for your use only, so you + can have the sprite's structure extended if you so desire. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/6/94 - In 2D EDIT MODE, you can now press ESC to get a message in the + message bar that says this: + + (N)ew, (L)oad, (S)ave, (Q)uit + + And it all works too. (Press ESC to cancel) + Loading lets you select the file just like 'U' in EDITART. + - The old version of BUILD had the coordinate system all screwed + up in 2D EDIT MODE. I fixed this. Included with + CONVMAP3.EXE is a conversion utility that will make your + boards have the same orientation as in the older BUILD + editors. If you don't care if the whole map gets rotated + in the 2D editor, then press N. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/7/94 - Changed the way Orientation works ('O' in 3D EDIT MODE) + + Now, when you draw a normal door in BUILD, you do NOT have to + press 'O' everywhere to make the walls of the door move right. + Now, the default is that everything moves right. Here's a + detailed description of how the new orientation works: + + For white lines (no neighboring sector): + + orientation = 0 (default) means picture is aligned with + sector[].ceilingz. + orientation = 1 means picture aligned with sector[].floorz. + + For red lines (has a neighboring sector): + + orientation = 0 (default) means picture is aligned with + either the ceilingz or floorz of the next sector. + orientation = 1 means picture aligned with + sector[].ceilingz. + + Don't worry if you don't understand the detailed description. + Just know that it's better this way. I have included the + proper conversions in CONVMAP3.EXE. + - Added wall&ceiling x-panning keys to the 3D EDIT MODE. Press + the , or . keys to pan a wall or ceiling left or right. You + can hold down the 5 key on the keypad to align at every eighth + panning value. (Just like with 2,4,6,8). + - Made TAB&ENTER in 3D EDIT MODE also copy the CSTAT byte of + the wall's attributes. This means that attributes such as + the block attribute, 1-way wall attribute, orientation, + and x-flipping attribute are also copied & pasted. + - Added a new function, cansee. + + cansee(long x1, long y1, long z1, short sectnum1, + long x2, long y2, long z2, short sectnum2) + + All you do is pass it the coordinates of a 3D line + and the respective sectors of each point of the line. + The function will return a 1 if the points can see each + other or a 0 if there is something blocking the two points + from seeing each other. This is how I determine whether + a monster can see you or not. Try playing DOOM1.DAT with + digitized sound enabled to fully enjoy this great new + function! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/12/94 - Fixed HITSCAN function. Since it works a little differently + and the parameters are different, let me describe how the + new hitscan works: + + hitscan(long xstart, long ystart, long zstart, short startsectnum, + long vectorx, long vectory, long vectorz, + short *hitsect, short *hitwall, short *hitsprite, + long *hitx, long *hity, long *hitz); + + Pass the starting 3D position: + (xstart, ystart, zstart, startsectnum) + Then pass the 3D angle to shoot (defined as a 3D vector): + (vectorx, vectory, vectorz) + Then set up the return values for the object hit: + (hitsect, hitwall, hitsprite) + and the exact 3D point where the ray hits: + (hitx, hity, hitz) + + How to determine what was hit: + * Hitsect is always equal to the sector that was hit + (always >= 0). + + * If the ray hits a sprite then: + hitsect = thesectornumber + hitsprite = thespritenumber + hitwall = -1 + + * If the ray hits a wall then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = thewallnumber + + * If the ray hits the ceiling of a sector then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = -1 + vectorz < 0 + (If vectorz < 0 then you're shooting upward which means + that you couldn't have hit a floor) + + * If the ray hits the floor of a sector then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = -1 + vectorz > 0 + (If vectorz > 0 then you're shooting downard which means + that you couldn't have hit a ceiling) + + - Added a position window to the bottom of the menu in 2D EDIT + MODE. It shows the posx, posy, and ang variables. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/14/94 - Overwritesprite now clips to the startumost / startdmost arrays. + Now the only way to write to the status bar is with + the permanentwritesprite function. + + - ATTENTION PROGRAMMERS! I Split draw3dscreen() into 2 separate + function calls. + + old: draw3dscreen(); //Draws walls, ceilings, floors, p-skies + // groudraws, sprites, and masked walls. + + new: drawrooms(); //Draws walls, ceilings, floors, p-skies + // and groudraws. + drawmasks(); //Draws sprites and masked walls. + + The reason I split draw3dscreen was so you could manipulate only + the sprites that the engine is going to draw to the screen + before the sprites are actually drawn. + + - I think I may have fixed that darn sector line bug! Before, the + bug usually appeared when you were on a (red) sector line where + the ceiling and floor of the sector were very far from each + other. This overflowed some really high positive values into + the negative range and vice versa. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/18/94 - Wall clipping now works much better! (You can still VERY RARELY + sneak through walls, however) + ATTENTION PROGRAMMERS: + MOVESPRITE and CLIPMOVE have been changed. They now look + like this: + + clipmove (long *x, long *y, long *z, short *sectnum, + long xvect, long yvect, long walldist, + char cliptype); + + movesprite(short spritenum, + long xchange, long ychange, long zchange, + long walldist, char cliptype); + + To use the new clipmove: + Pass the pointers of the starting position (x, y, z). Then + pass the starting position's sector number as a pointer also. + Also these values will be modified accordingly. Pass the + direction and velocity by using a vector (xvect, yvect). + If you don't fully understand these equations, please call me. + xvect = velocity * cos(angle) + yvect = velocity * sin(angle) + Walldist tells how close the object can get to a wall. I use + 128L as my default. If you increase walldist all of a sudden + for a certain object, the object might leak through a wall, so + don't do that! + + To use the new movesprite: + Works like before, but you also pass walldist (How close the + sprite can get to a wall) + + - New function for sprites: + setsprite(short spritenum, long newx, long newy, long newz); + + This function simply sets the sprite's position to a specified + coordinate (newx, newy, newz) without any checking to see + whether the position is valid or not. You could directly + modify the sprite[].x, sprite[].y, and sprite[].z values, but + if you use my function, the sprite is guaranteed to be in the + right sector. + + - You can now change the angle in 2D EDIT MODE with the + < and > keys. Move the mouse cursor to a sprite first. + Hold down shift with the < and > to get more precise angles. + - You can now press 'B' on sprites in 3D EDIT MODE. This in effect + is xoring bit 0 of sprite[].cstat, which will not only be + sensitive to hitscan, but will also block you from walking + through the sprite. Sprites with the 'B' attribute will + appear pink in 2D EDIT MODE. + - You can now edit the Hi 16 bits of the tag in 2D EDIT MODE. + Just like T and ALT-T, you press H and ALT-H to edit the high + 16-bits. When a structure's attributes are displayed, the tag + will be displayed as 2 unsigned shorts. The first number + represents the hi 16 bits and the second number represents the + lo 16 bits. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/23/94 - Added 'G' in Editart to GOTO a tile by typing in the tile number. + - Changed the way masking walls work a little bit. Now the + masking walls use the picture wall[].overpicnum rather than + wall[].picnum. + - Made hitscan hit maskable walls. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/24/94 - Made palette.dat support any number of shades up to 64. There + is no change to the palette.dat format. The palette.dat + format is: + + First the palette (768 bytes) Values range from 0-63 + Then the lookup shades (256 * number_of_shades) The + shades are stored in groups of 256 bytes. + + - If you use Mark Dochtermann's palette program, then you can + convert his data files (such as palette.pal and colormap.lmp) + to my palette format, palette.dat, with my great Qbasic + program, PALMP.BAS. To run it, first copy the basic program + into the same directory as the 2 source palette files are in. + Then type: "QBASIC PALMP" and then press SHIFT+F5 (to run it). + + - Added a global variable, HORIZ. Horiz usually equals 100. + Modifying horiz will move the whole screen up / down. I + added 2 keys, +/- in my own game.c to demonstrate this. You + can use this variable for looking up and down if you want. + (Even though this is not "truly" looking up and down, if + you're lucky, you might be able to fake out some people!) + + - New Key in 3D EDIT MODE, the forward slash. Use / with the + tile panning keys (, and .) to flip the horizontal / vertical + orientation bits for walls, ceilings or floors. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/28/94 - NEW BOARD VERSION! You must run CONVMAP4.EXE on all your boards. + Here's what I changed in the structures: + + Sectors: + I got rid of: + char sector[].ceilingpanning, sector[].floorpanning; + sector[].ceilingstat/floorstat bit 2 zeroed out + and added: + char sector[].ceilingxpanning, sector[].ceilingypanning; + char sector[].floorgxpanning, sector[].floorypanning; + + Walls: + + I got rid of: + char wall[].panning; + wall[].cstat bit 6 zeroed out + and added: + char wall[].xpanning; + char wall[].ypanning; + + Sprites: + + I got rid of: + short sprite[].vel; + and added: + short sprite[].xvel; + short sprite[].yvel; + The reason I did this was so sprites could be moved in + different directions than sprite[].ang. Please make + use of both xvel and yvel. Here's the equation I would + use to convert from the old to new. For example: + + old: + sprite[i].vel = 256; + new: + sprite[i].xvel = (sintable[(sprite[i].ang+512)&2047]>>6); + sprite[i].yvel = (sintable[sprite[i].ang&2047]>>6); + + The reason I am shifting the sines right by 6 is becuase + my sintable ranges from -16384 to 16384. Dividing by + 64 gives a maximum range of -256 to 256. + + CONVMAP4.EXE also attempts to convert the masked walls so + overpicnum is the masked wall's picnum. + + - Changed 3D EDIT MODE panning keys: + Since panning is now all 4 directions, I got rid of the + , and . keys and put the keys on the keypad using 2,4,6,8. + Usually 2,4,6,8 are for x- and y-repeats, but if you hold + down either shift key, then they act as x- and y- panning + values. + The / key now resets the panning values to 0. + + - Please read the updated descriptions of how to make masking walls + in the 3D EDIT MODE KEYS in the top of build.txt. See + the 'M' and 'Shift + M' keys. + + - Also look at the top of this file for a description of dragpoint(), a + great new function that makes it easy to morph sectors. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/29/94 - Added some minor keys to 3D EDIT MODE. Alt. +/- change the + visibility variable. It ranges from 5 (darkest) to 17 + (lightest) and it starts at 13. + + - Made 1-way walls have more options. Now, for example, you can + make rectangular switches on walls. Please look at my + nukeland.map for an example of how to do switches. (The + switches are close to start - just go through the door and + bear left.) + + - For those who asked, here's how some sample bobbing code: + First, calculate the distance actually moved - because if you + are not moving then you shouldn't bob: + + CODE: + oposx = posx; oposy = posy; + clipmove(&posx,&posy,&posz,&cursectnum,xvect,yvect,128L); + dist = ksqrt((posx-oposx)*(posx-oposx)+(posy-oposy)*(posy-oposy)); + + Then modify the horizon value by multiplying the distance + actually moved by a sine wave. (default is horiz = 100). + + CODE: + horiz = 100 + ((dist*sintable[(totalclock<<5)&2047])>>19); + + - Remember that moving block in the slime in NUKELAND.MAP? It + works a lot better now. I am now modifying the floor panning + values to make the floor match up correctly with the block. + + - Fixed the screen capturing (F12) to save captures as PCX files. + This is for BUILD, GAME, and EDITART. + + - Fixed bug in EDITART when you press 'U' on a blank tile. It + should not crash any more. + + - Made Tab & Enter a little smarter in copying the right attributes + to different types of objects. + + - Added ceiling / floor 90ø rotation attributes. All 8 + rotations are possible. 3 bits have been added to both + the sector[].ceilingstat and sector[].floorstat flags. + If you look in BUILD.H, you will see the new flags + descriptions. You can use the 'F' key in 3D EDIT MODE on + a ceiling or floor to change the rotation. + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/30/94 - ATTENTION PROGRAMMERS: + I removed the function, getsector, and added a more expandable + function, updatesector. Also, updatesector is smart enough + to check to see if you are in the same sector OR neighboring + sectors first before going through every single sector. + Getsector used to go though all the sectors every time you + crossed a sector line. + + getsector(); (no arguments, returns nothing - REMOVED) + * used to make sure that CURSECTNUM matched up with + the right sector according to the POSX and POSY values. + updatesector(posx,posy,&cursectnum); + * the new way of writing getsector. You can do a + search&replace on your code. Be careful when you use this + function with sprites because remember that the sprite's + sector number should not be modified directly. For example, + you might want to code it this way: + + tempsectnum = sprite[i].sectnum; + updatesector(sprite[i].x,sprite[i].y,&tempsectnum); + if (tempsectnum != sprite[i].sectnum) + changespritesect(i,tempsectnum); + + Actually, I think the setsprite function is better for + updating a sprite's sector number. + + - Added swinging doors! Look at NUKELAND.MAP in my GAME.EXE for + an example. For swinging doors, I used a new math-helper + function, rotatepoint. + + rotatepoint(long xpivot, long ypivot, + long x, long y, + short deltaang, + long *x2, long *y2); + + Rotatepoint will rotate point(x,y) around point(xpivot,ypivot) + by the deltang value. The resultant point will be s + + - Fixed crashing bug in BUILD when a wall's tile doesn't exist. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/02/94 - I improved the pre-level check on the swinging doors, so now + you can have multiple doors in a sector that open any way. + This is how I do my double swinging doors (demonstrated in + NUKELAND.MAP) + + - I added a revolving door! See NUKELAND.MAP for an example. (The + revolving door is beyond the bouncing platforms in the slime + pit) + + - Fixed bug with joining sectors in 2D EDIT MODE. The sprites + don't get deleted any more. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/04/94 - Optimized the masked walls. + + - Cleaned up the sprite drawing code (and many bugs that that came + along with it.) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/05/94 - Made cylindrical walls with any number of points VERY easy to + make in BUILD. Here's how you do it: Highlight a wall and + press 'C' on it. Then move the mouse to the proper position + to make a nice circle. You can press '+' or '-' to change + the number of points on the circle. Press 'C' again to cancel + or press space bar to actually change the map. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/07/94 - Made a fully-operational subway! Look at subway.map. + + - Made a new type of door - a sliding door where the door doesn't + get "x-smooshed" when it is opened. (See description of + sector tag 16 & wall tag 6) + + - Also note that I my first subroutine in game.c! It is: + operatesector(short dasector) + All the door code is now in this function (with a few + exceptions, such as parts of the swinging doors and revolving + door) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/08/94 - Made EDITART and BUILD support different tile sizes in 'V' mode. + Here are the three possible sizes: + 0. 64*64 - 5*3 grid - views 15 tiles (old default) + 1. 32*32 - 10*6 grid - views 60 tiles (new default) + 2. 16*16 - 20*12 grid - views 240 tiles + Press the '*' and '/' keys in 'V' mode if you want to change + the grid resolution. + + - Added/fixed up a new key in 3D EDIT MODE, the dot key (. or >) + This key attempts to match up all the tiles along a wall. It + scans along the walls towards the right as long as the picture + number of the next wall is the same as the original picture + number. Note that some walls may not work right, especially + floor / ceiling steps. + + - Made 2D EDIT MODE default to this when inserting sprites: + 1. Sprite clipping = on for sprites taller than 32 pixels + 2. Sprite clipping = off for sprites shorter than 32 pixels. + + - Fixed sprite clipping with Z-coordinates +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/10/94 - Fixed some sprite dragging bugs + + - Made neartag? maximum sensing distance a global variable called + neartagdist. See build.h. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/11/94 - Added sector / groups of sectors selection. When selecting + sectors, hold down the right ALT key. It works just like + right shift. You must completely surround any sector you + wish to select. Once selected, you can drag the mess of + sectors with the mouse. This is great for separating sectors + from each other. + + - Added sector duplication. First select a bunch of sectors. Then + press the insert key. (with the select sectors flashing) Then + This duplication is like stamping. So, you must drag + the sector bunch somewhere else after stamping to see your + great accomplishments. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/12/94 - Added group-sector PGUP / PGDN. Here's a neat trick that will + let you move a whole section of a board up / down quickly. + First you select a bunch of sectors with the right ALT key in + 2D mode. Then flip to 3D mode and if you press PGUP / PGDN + on any of the highlighted sectors, the rest of the highlighted + sectors will move also. + + - Added group-sector rotation. Once you do a sector select (right + ALT), you can press the , or . keys to rotate the selected + sectors. Hold down the shift key with the keys to get fine + angle rotation (WARNING: You will get distortion with fine + angle rotation in this version) + + - Added sector count and wall count information at the bottom of + the 2D edit mode status bar. + + - Fixed some stupid bug that you probably wouldn't have found if + you made boards with BUILD for the rest of your life. + + - You can now press 'B' to block / unblock a wall or sprite in + 2D edit mode. + + - Made Ctrl-Shift Enter auto-shade a sector. First make any + wall of the loop as light as the lightest shade you want. + Then make any other wall of the loop as dark as the darkest + shade you want. Finally press Ctrl-Shift Enter on the wall + that should be lightest. Now the loop should be smoothly + shaded. If it is not smoothly shaded, you may need to insert + more points on the walls. + + - Fixed my .PCX format bug. My screen captures now load properly + in Deluxe programs. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/13/94 - Made my serial code in Game.c work better. I fixed the bullet + shooting and made all types of doors work. Unfortunately, you + still may have to run at slower COM speeds. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/14/94 - Fixed deadly bug with sector copy & sprites. + + - Added hitscan sensitivity bit. It is bit 6 (64) of wall[].cstat. + In 3D edit mode, you can press 'H' to toggle the bit. (H used + to be like 'V' for choosing height tile numbers for groudraws - + I change the 'H' key to Alt-V since I don't think anybody was + using it anyway) By default, hitscan CAN go through maskable + walls. If a hitscan is set to not go through a maskable wall, + The wall will appear BRIGHT pink in 2D edit mode. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/15/94 - Made more subroutines in game.c and moved documentation from the + end of game.c into this text file. Added some more comments + also. Game.c is so much easier to read now! The main loop is + less than 50 lines long! + + - Made some optimizations to my serial code now that everything + is in functions. + + - ATTENTION PROGRAMMERS: + I added one new paramater (cliptype) to both the movesprite + and clipmove functions. If the new parameter is a 0, then + the clipping is normal (Use 0 to clip you and monsters). + If the new parameter is a 1, then the object is clipped to + the same things that hitscan is clipped to (use 1 for all + bullets). + See the above documentation for a detailed description of the + parameters. (Remember that I moved the documentation from + GAME.C into the middle BUILD.TXT) + Finally, you can have sprites and bullets going where you + want them to go! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/18/94 - Added support for the Spaceplayer (6-degree of freedom Space ball) + Try out the SETUP program now. + + - Fixed some bugs with the 'E' key in 3D EDIT MODE. As long as both + dimensions of the tile are powers of 2, then the picture should + be visible. It should not be a solid color with a few weird + lines any more. + + - Fixed some bugs with the Z control in 3D EDIT MODE. In normal + operation, BUILD attempts to keep your Z constant even if + you cross sector lines. Then I added a special new mode that + locks your heightofffloor to a certain value. You Z will + change instantly if you cross sector lines. To use this mode, + press the Caps Lock key. Press Caps Lock key again for normal + operation. + + - ATTENTION PROGRAMMERS! I put all of engineinput into GAME.C + This means you have absolutely total control of the Z's. (The + only thing left is some key code I still have in my timer + handler) + + OK, now read carefully! Here's how to convert to the new OBJ's: + + 1. First of all, the Spaceball code is now also in game.c. + A. You will need to put this line in game.c: + include "spw_int.h" + B. And make sure to add spwint.obj your makefile. + 2. Heightoffceiling, heightofffloor, and gravity have been + removed from BUILD.H. If you still want to use them + then you should defined them as globals in your own code. + 3. You should go through every single key of my gameinput() + function in game.c and copy any code you want. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/23/94 - GREAT NEW STUFF! + + Be sure to check out GAME.EXE and try out these new keys! + + Rt. Enter = Switch between 3D / 2D modes + Lt. +/- = Zoom in 2D mode + + Added 2D map display with auto-mapping! The 2D maps use a + higher resolution 16-color mode. You have a choice of either + using a 640*350*16 screen or a 640*480*16 screen with a 144-high + status bar (remember that 640*480*16 cannot fit in 256K with 2 + screen pages so I have to cheat with a status bar). + + NEW FUNCTIONS: + + draw2dscreen(long posxe, long posye, short ange, long zoome, + short gride) + Draws the 2d screen - this function is a direct replacement + for the drawrooms() and drawmasks() functions. Be sure + to call either qsetmode640350() or qsetmode640480() + first. When switching back to 3d mode, be sure to call + qsetmode320200(). + + IMPORTANT NOTES: + 1. The overwritesprite function should only be called in + 3D mode. If you do this in 2D mode, junk will be + written to the 2D screen and a crash is possible. + 2. When you switch back to 3D mode, you should call the + permanentwritesprite functions to draw the status bar, + or whatever else you have to draw. + 3. You must call the nextpage() function in both 2D and + 3D modes. + + qsetmode320200(); + Set to the game mode and load palette (320*200*256) + qsetmode640350(); + Set to the 2D map mode #1 (640*350*16) + qsetmode640480(); + Set to the 2D map mode #2 (640*480*16) + + NEW VARIABLES (see description in build.h): + + EXTERN char show2dwall[MAXWALLS>>3]; + EXTERN char show2dsprite[MAXSPRITES>>3]; + EXTERN char automapping; + + - Added parallaxing floors! Works like the parallaxing skies, but + the other side. In 3D EDIT MODE, press P on ceiling for + parallaxing sky, or press P on floor for parallaxing floor. + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/24/94 - There is a new function that I forgot to document in the last + version. Oops! + + doanimations() is this function. + It's not really new, but I split it off of the + drawrooms/drawmasks functions. This function animates anything + that you use setanimation with. Please stick it in your code + somewhere after you draw the screen. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/26/94 - You can now do TRANSLUSCENT sprites! I am using bit 1 of + sprite[].cstat to detemine whether or not the sprite is + transluscent or not. In 3D EDIT MODE, you can press 'T' to + toggle the transluscence bit. + IMPORTANT: Transluscence WILL NOT WORK until you run my + TRANSPAL.EXE program. On the command line, simply type: + C:\BUILD>transpal [filename] + If you do not specify a filename, the default will be + palette.dat. If your palette.dat file is now around 40K long, + then you are ready for transluscence! + + - Added TRANSLUSCENCE to masked walls. See bit 7 of wall[].cstat. + Press 'T' on wall to toggle the transluscence bit. + + - In this BUILD update, I have collected many different palettes + for comparison purposes. Try running TRANSPAL.EXE on each of + them and see for yourself which palettes work the best with + transluscence! + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/29/94 - ATTENTION PROGRAMMERS: I completely rewrote the neartag code. + Here's what you have to do to convert your game.c files: + + 1. You should move the neartag variables that I used to + have in BUILD.H into your C code. + 2. You must call the neartag function yourself if you want + to see if you're near a tagged object. Neartag is NOT + automatically updated by the engine any more. + 3. I highly recommend that you put your neartag function + call at the first line in your space bar code. This way, + you can optimize the neartag calculations by only doing + them when you press the space bar. (Exception: For + ladders, I think you'll have to call neartag every single + frame) + + Here's a description of the new neartag function: + Neartag works sort of like hitscan, but is optimized to + scan only close objects and scan only objects with + tags != 0. + + neartag(long x, long y, long z, short sectnum, short ang, //Starting position & angle + short *neartagsector, //Returns near sector if sector[].tag != 0 + short *neartagwall, //Returns near wall if wall[].tag != 0 + short *neartagsprite, //Returns near sprite if sprite[].tag != 0 + long *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size) + long neartagrange) //Choose maximum distance to scan (scale: 1024=largest grid size) + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/31/94 - Added a function to get a sprite's screen coordinates. I put + some sample code in my GAME in the analyzesprites function. + Simply hold down the CAPS LOCK key in my GAME.EXE, and the + screen will be centered around the sprite closest to the + center of the screen. + + Here's a new function in the engine I used to do this: + + getspritescreencoord(short spritesortnum, long *scrx, long *scry) + + Note that spritesortnum is the index into the spritesortcnt + arrays, NOT the normal sprite arrays. Scrx and scry are actual + screen coordinates ranging from 0-319 and 0-199 respectively. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/6/94 - Made EDITART support sprite centering and animation speed. + + Now when you press 'A' in EDITART, the animation speed is + actually saved to disk and runs the same speed in BUILD + and your GAME. Press + and - to change the animation speed. + There are 16 different animation speeds. + (Speed is proportional to (totalclock>>animspeed)) + + To center a sprite, press the weird ~` key (located just above + the TAB key). You will see some cross hairs. Simply use + the arrow keys to the desired position. + + For both the 'A' and ~` keys, you can press Enter to accept + the new values or ESC to cancel. + + - Added a variable to BUILD.H, lockclock. Lockclock is to + totalclock as lockspeed is to clockspeed. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/7/94 - Made 3 different Z coordinate modes in BUILD. + + Mode 0: Game mode (default) + Mode 1: Height lock mode + Mode 2: Float mode + + Press Caps Lock to switch between the 3 modes. + A and Z move up and down for all 3 modes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/10/94 - Added a new function that should solve all your sound problems. + + kenchaintimer(void (__interrupt __far *datimerchainaddress)(), + short dachainpersecond) + + Please look at the IMPORTANT ENGINE FUNCTIONS section above for + a full description. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/20/94 - Got rid of the comsend / comgetchar functions. Replaced them + with sendpacket and getpacket. + + - Added network support. + + - Got rid of qsetmode320200(). Just replace it with setgamemode(). + The 2 are exactly the same. + + - Got rid of clockspeed variables. Just replace it with lockspeed. + + - Adjusted my z directions of shooting depending on the horizon. + You may want to readjust your code for this. + + - You now pass the number of tics as a long to doanimations. + doanimations(long numtics); + + - FIXED DEADLY BUG! This may have been causing bigtime crash-city + bugs! The problem was with show2dsprite and show2dwall. In + my engine.c I forgot that they were BIT arrays, not BYTE arrays. + When I initialized the arrays to 0, I initialized 8 times the + length, possibly overwriting your precious data! I initialize + these arrays in the initengine and loadboard functions. + + - ATTENTION PROGRAMMERS: In order to get rid of the posx, posy, + posz, ang, posz, and horiz variables from BUILD.H, I added some + parameters to a few functions. YOU MUST REWRITE YOUR CODE + TO SUPPORT THESE: + loadboard(char *filename, long *posx, long *posy, long *posz, + short *ang, short *cursectnum) + saveboard(char *filename, long *posx, long *posy, long *posz, + short *ang, short *cursectnum) + drawrooms(long posx, long posy, long posz, + short ang, long horiz, short *cursectnum) + + THESE VARIABLES SHOULD BE MOVED INTO GAME.C: + long posx, posy, posz, horiz; + short ang, cursectnum; + long hvel; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/22/94 - ATTENTION PROGRAMMERS: Added 1 parameter to movesprite, the + number of tics (such as lockspeed). + + movesprite(short spritenum, long xchange, long ychange, + long zchange, long walldist, + char cliptype, long numtics) + + - ATTENTION PROGRAMMERS: At one time, I used to have 4 timing + variable in the engine. (totalclock, clockspeed, + lockclock, lockspeed). I got rid of all of them except + totalclock. If you want to use the other 3 variables, you + must simulate them yourself. Here's how you do it: + + Step 1. Define clockspeed, lockclock, and lockspeed as global + longs in your code. + + Step 2. Be sure to zero out all 3 variables just before + starting to play each level. (You could zero out + totalclock also.) + + Step 3. Right after every time you call the nextpage() + function, insert this code line for line: + + lockspeed = totalclock-lockclock; + lockclock += lockspeed; + clockspeed = lockspeed; + + You really don't need clockspeed if you have lockspeed. + You should replace all clockspeed's with lockspeed's. + Before, I had both because both totalclock and clockspeed used + to be incremented in the timer handler and could be changed + at any time. + + - I added my own optional random function, krand() which returns + a pseudo-random number as a long from 0 to 65535. Notice that + I put a randomseed variable in BUILD.H called randomseed. + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/24/94 - I just want to try to explain how all of my multiplayer code + works. Theory: Think of the whole program as 2 functions: + + Function 1. Draw the screen (could be 2D / 3D) + Function 2. Move things. (sprites, walls, sectors, and you!) + + My communications in GAME.C work on a MASTER/SLAVE + system where it would be nice if the faster computer was the + MASTER. (Right now, the first computer in is the MASTER). + The big trick to keeping everything in sync (and I do mean + everything- even moving platforms, revolving doors, & subways) + is to call function #2 with the exact same parameters as input + on all computers the same number of times and in the same + order. Now this might seem like a lot of information but it + really isn't! Let me explain the role of the MASTER and SLAVE: + + The MASTER's job: + 1. Read in own input changes + 2. Read in any slave player input changes + (getpackets function - reads in foreign vel, svel, + angvel, & the bits) + + 3. Just before calling the movethings function, send the + input to the movethings function: + A. Master's tic cnt (synctics) + B. Every player's velocities (syncvel, svel, angvel) + C. Every player's status bits (Space, Ctrl, Shift, etc.) + 4. Call the movethings function + 5. Draw screen + + The SLAVE's job: + 1. Read in own input changes + 2. Send own input changes to master. + 3. Read in all master movethings input parameters and + call movethings function for each packet. This may + mean calling the movethings function more than once + between calling the drawscreen functions. This is + waste, but it's the price you have to pay to keep + things in sync. + 4. Draw screen + + + You may ask how do monsters stay in sync even if you are + not sending any monster information over the line. The + answer to this is simple. + 1. You make sure that a random seed starts the same on + both computers. + 2. Only call the rand() or krand() function in the + movethings function. + + Before you try my demo, I wanted to say that, I have + ABSOLUTELY NO ERROR CORRECTION in my code at this point. It + is most certainly my next project. For serial link, I would + recommend a rate of about 14400 baud. In the future, I think + I can optimize the code enough to work at rates as low at 2400 + baud! Let me explain how well certain setups should work + without error correction: + Ken's guesses on how badly it will crash WITH NO ERROR + CORRECTION (Build the way it is now): + + 1. Serial link using 8250 chips - out of sync after 15 + seconds because a few bytes were missed. + 2. Serial link using 16550 chips - out of sync after 10 + minutes because 16550 chips have a 16 byte FIFO and + therefore don't lose bytes as often as the 8250. + 3. Modem - out of sync after less than 5 seconds. + 4. Network - out of sync after 1 minute. Networks love to + lose full packets here and there. + + I will be working on error correction for all of the above + situations. Any error correction techniques I use will be + internal to the engine and completely transparent to you (so + you can start coding now!) If the demo actually works multi- + player, then you may want to look at my GAME keys at the top + of this file again. There are some significant changes. + + * I replaced the old COM functions section at the top of + BUILD.TXT with a COMMUNICATIONS FUNCTIONS section. Please + look through it for descriptions of at least these 2 + functions: + + sendpacket(short otherconnectnum, char *bufptr, short bufleng) + getpacket(short *otherconnectnum, char *bufptr) + + * Another rule to keep in mind while testing: (as if there + aren't enough already) Always make sure you have the + same EXE's and MAP'S or else the games will get out of sync. + + * Connection numbers and Index numbers: + For networks, each computer has a given connection number. + Connection numbers range from 1 to 100. Player number 1 + might have connection number 5 and player number 2 might have + connection number 17. Since a player's connection number + can be anything between 1 and 100, I don't want you to + allocate 100 of every variable such as posx[100]. My + solution was to make index numbers. So in this case: + + connectnum[0] = 5; connectindex[5] = 0; + connectnum[1] = 17; connectindex[17] = 1; + + * Now I'll will describe some new variables at the top of GAME.C + + myconnectnum - connection number of your computer + myconnectindex - index number of your computer + masterconnectnum - connection number of the MASTER computer + screenpeek - index number of which player's eyes you are + looking through. + numplayers - if numplayers >= 2 then multiplayer mode is + enabled, else single player game. + + connecthead, connectpoint2[MAXPLAYERS] - These 2 variables + form a linked list of all the index numbers. + Here's some example code that traverses the list of + players: + + p = connecthead; + while (p != -1) + { + printf("Player index %d has connection number %d\n",p,connectnum[p]); + p = connectpoint2[p]; + } + + * These variables are used to record / playback a demo. (This + is like POSCAPT.DAT, but with everything in sync!) In my + GAME, i single player mode, I have it so if you press the + Left ENTER, then it will playback everything. These are + the only variables necessary to store a demo run: + + static long reccnt; //Number of frames + static short recsyncvel[16384]; //Vel for each frame + static short recsyncsvel[16384]; //Svel for each frame + static short recsyncangvel[16384]; //Angvel for each frame + static short recsyncbits[16384]; //Bits for each frame + static short recsynctics[16384]; //Tics for each frame + + * These variables are used for communications syncing: + + static short syncvel[MAXPLAYERS+1]; //Vel of each player + static short syncsvel[MAXPLAYERS+1]; //Svel of each player + static short syncangvel[MAXPLAYERS+1]; //Angvel of each player + static short syncbits[MAXPLAYERS+1]; //Bits for each player + static short synctics; //Number of tics of MASTER ONLY + + * Unless I suddenly make BUILD a 6-degree of freedom engine + tomorrow, this should be the most difficult update in a long + time! Good Luck in programming! I'm sure I left a lot of + things out, so I'll be expecting plenty of phone calls! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/27/94 - I scaled the vel, svel and angvel variabile down 1 bit so they + fit into a signed char. (Before they ranged from -256 to 256) + Now they range from (-128 to 127). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/28/94 - Optimized the size of my COM(modem)/network packets in game.c. + I made the tics into a char. I also use some new buffers called + osyncvel, osyncsvel, osyncangvel, and osyncbits. Now I send + extra byte with bit fields that tell whether I need to update + the syncvel, syncsvel, syncangvel, or syncbits variables. If + the bit field of the extra byte is off then I don't send the + byte(s) it represents. You can now play my GAME at 4800 baud. + + static signed char syncvel[MAXPLAYERS+1], osyncvel[MAXPLAYERS+1]; + static signed char syncsvel[MAXPLAYERS+1], osyncsvel[MAXPLAYERS+1]; + static signed char syncangvel[MAXPLAYERS+1], osyncangvel[MAXPLAYERS+1]; + static short syncbits[MAXPLAYERS+1], osyncbits[MAXPLAYERS+1]; + static unsigned char synctics; + + - There was an crashing error with transluscence palette on low + memory configurations. When you exit the BUILD editor, + you normally get some numbers like this. + Memory status: 788979(788979) bytes + If the first number (art memory cache size) was less than the + second number (art file size), then the whole art file did + not fit in memory. The reason for the crashing was because + loadpics() sucks all memory up to the size of the art file. + The 64K transluscent palette is malloc'd when you call the + setgamemode() function for the first time. The was no memory + left to allocate the palette. I fixed this by making the + transluscent palette take 64K of the art memory cache if + it could not malloc the 64K. + + - I programmed some error correction for the COM(modem). Here is + my new of Ken's guesses on how badly it will crash (assuming + that it will always crash eventually.) You will be seeing new + and better correction methods in the future. + + ERROR CORRECTION METHOD #1: + 1. Serial link using 8250 chips - out of sync after 5 minutes. + 2. Serial link using 16550 chips - out of sync after 10 minutes. + 3. Modem - out of sync after 3 minutes - try it! + 4. Network - out of sync after 1 minute. Networks love to + lose full packets here and there. (not changed) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/29/94 - Added some code to my GAME.C that will let you type in messages + and send them to all remote players. Press Tab (or T for + those people who play that other, very bad, game too much) + to start typing in a message. Press either Enter key to send + the message to the other player. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/30/94 - ATTENTION PROGRAMMERS: I changed the values that clipmove and + movesprite return! Here's how they work now: + If you did not hit anything, then they return 0. + Movesprite only: If the object hits a ceiling / floor + then movesprite returns 16384+(sectornum hit). + If the first object you hit before sliding was a wall, + then they return the 32768+(wallnum hit). + If the first object you hit before sliding was a sprite, + then they return the 49152+(spritenum hit). + + Be careful when adding these changes to your code since the + return value are sort of reversed: + + return values: º Hit nothing: ³ Hit something: + ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÎÍÍÍÍÍÍÍÍÍÍÍÍÍÍØÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ + Old functions: º 1 ³ 0 + ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ×ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ- + º ³ 16384+sectnum (Movesprite only) + New functions: º 0 ³ or 32768+wallnum + º ³ or 49152+spritenum + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/1/94 - Made getangle always return an angle from 0 to 2047. Before I + forgot to and it 2047 and sometimes the angle was negative. + + - Made overwritesprite when using the centering option be sensitive + to the Editart centering tool. (The ~` key.) + + - Made Ctrl+Rt.Shift highlight points on a loop rather than points + inside a rectangle. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/2/94 - Added some neat features to my GAME.C to make multi-player mode + even more fun. I added a portable bowling ball/bomb-thrower. + kills instantly! (similar to rocket launcher) I also added + water fountains. If you hold the space bar down on them, + you slowly get more life. + + - O.K. I think I actually got the syncronization working perfectly + for COM(modem) play. I haven't had all day to test it out yet! + (Still no error correction with networks) + + Here are some steps in playing over the modem: + 1. Be sure that both people have the exact same version of + the EXEs, ART, and MAPs. + 2. Then go into SETUP and set the COM port to the com port + of your modem. Even though 9600 baud should work, I + would recommend going at 4800 baud because: + A. It works fine at 4800 baud so there is really + no need to go any faster. + B. Fewer errors over the modem so less time + spent re-sending packets. + 3. Then type: MODEM [mapname] (must be same mapname!) + This will bring you into my terminal program. You can + set the modem initialization string in MODEM.BAT by + changing the first command line option of the TERM + line. Please disable modem compression and + correction for least jerky play. Then connect with + the other modem using various methods, such as one + person typing ATA and the other typing ATD or one + person typing ATS0=1 and the other typing + ATDT(phone #). + 4. Wait through the beeps and buzzes until it says CONNECT + on the bottom window. + 5. If you can now chat with each other then things are + going well. When the first person presses ESC, both + computers will automatically quit to DOS and go right + into the GAME. + 6. Play! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/5/94 - Serial moder over COM(modem) should work perfectly now. + + - Added scaredfallz to BUILD.H. It is a global variable that + tells monsters what height is too high to fall through. You + can set cliptype parameter to 2 for movesprite and clipmove. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/6/94 - Fixed clipping bug that used to let you go through certain concave + corners. + + - Added new function which works well with clipmove. Ever notice + was when you're at the edge of a cliff and you go just a tiny + bit over, you fall, but shouldn't yet? Unlike what you have + been doing, this new function finds the highest and lowest z + coordinates that your clipping BOX can get to. It must search + for all sectors (and sprites) that go into your clipping box. + Currently, you were searching the z's at the center point only + by simply using the sector[].ceilingz and sector[].floorz + variables. + + getzrange(long x, long y, long z, short sectnum, + long *ceilz, long *florz, + long walldist, char cliptype) + + Pass x, y, z, sector normally. Walldist can be 128. Cliptype + can be 0, 1, or 2. (just like movesprite and clipmove) + This function returnes the 2 z maxes in ceilz and florz. + See GAME.C for an example. + + - Fixed bug with weird vertical lines in transluscent masked walls + in chain mode. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/10/94 - Made screen capture (F12) work in 2D modes also. It always + saves to a 256 color PCX file. + + - Made screen re-sizeable. Use this easy new function to re-size + the screen: + + setview(long scrx1, long scry1, long scrx2, long scry2); + + It is TOO easy to use. You simply pass is the Upper-left hand + corner and the bottom-right corner in screen coordinates of the + rectangular region you want the engine to draw to. The engine + automatically centers the horizon at the middle of the window and + scales everything properly. + + Notes: + - Since the engine does extra scaling calculations for + window sizes that are not 320 pixels wide, I do not + recommend making the default mode with a window size + just under 320 pixels wide since the engine can + actually run a little slower. (such as 312-319 + pixels wide) Keep them 320 wide. + - Feel free to modify the startumost / startdmost arrays + AFTER a setview call if you want weird window shapes. + Keep in mind that startumost[0] and startdmost[0] are + always refer to the left edge of the viewing window. + (NOT left edge of screen.) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/19/94 - Finally got around to writing the number-of-tiles-per-file + resizer. Simply type rsizeart. All instructions will be + displayed when running the program before the actual + conversion. + + - Fixed a few bugs in Editart. I hope I fixed those evil bugs that + rarely come by. I'm pretty sure I fixed the bug that made the + screen go blank in 'V' mode, and the bug where a few pixels + in the top left corners of tiles sometimes get overwritten. + + - Added a key in Build 2D edit mode. Press 'E' on a sprite to + change its status list number. + + - Fixed those lousy Editart subdirectory colors in 'U' for those + teams with great color palettes, but don't have my ugly shade + of pink. + + - Fixed bug with non-200 high P-skies. The p-skies are now (by + default) centered on the horizon no matter what the height is. + + - Added multiple size PCX and GIF support in Editart. You can now + load pictures up to 1024*256. (That's all that can fit in VGA + video memory) If you need to load a bigger picture than that, + it will be chopped off at the bottom, but will still load the + top piece. + + - I know that I have introduced some wonderful new bugs with the + sprite drawing. I know why they're happening, but I am + looking for a good solution so as to not make you change + any code. I will put another upload with these bugs fixed + soon. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/20/94 - Added TRUE ornamented walls. Right now the actual ornamentation + must be programmed by you with 2 simple functions: + + copytilepiece(long tilenume1, long sourcex1, long sourcey1, + long xsiz, long ysiz, + long tilenume2, long destx1, long desty1) + + * This function simply copies any section of a source tile + to any part of a destination tile. It will automatically + skip transparent pixels. It will wrap-around in the + source but not the destination. If for some reason + the destination tile gets removed from the cache, the + destination tile will be reset to original form. This + is why I had to add this second function: + + allocatepermanenttile(short tilenume, long xsiz, long ysiz) + + * This function allocates a place on the cache as permanent. + Right now, I reset the cache every time you call this + function so I would recommend calling this function + right after loadpics. + + I have an example of both of these functions in GAME.C. Try + playing GAME DOOM1.MAP and go into the secret room with + the pictures of Ken. Shoot some walls there. The pictures + with Ken and the Explosion over it were done with + copytilepiece and allocated permanently at tile 4095. A + good idea for allocating permanent tiles would be to start + at 4095 and decrement. You can also allocate a permanent + tile over the original tile itself. + + - Tile panning matching keys work a lot better. They now work + well with bottom steps. Also, it works well with matching + up windows. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/25/94 - A week ago, I uploaded a version of BUILD which unfortunately + had more bugs than the previous version. This upload should + have those bugs fixed - especially the sprite bugs. (I hope) + + - I think I may actually have the sprite feet behind stairs bug + working perfectly. + + - The engine should now be even faster the before last week. (A + week ago, I temporarily changed the parallaxing sky algorithm, + making the engine slower in those areas) + + - Added a variable, parallaxyoffs in BUILD.H. It defaults to 0. + If you set it to 100, then all parallaxing skies will be + properly moved 100 pixels higher. + + - Fixed some weird drawing bug related to parallaxing skies and + sprites. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/26/94 - Made sprite's sectors dependent on the z coordinates in the BUILD + editor. (Helpful if you use overlapping in your maps) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/29/94 - Made precache function. Simply call: + precache() (no parameters) + right after you call loadboard(?,?,...) and it will load + all tiles in the current board into the cache. Note that + animations of sprites after the first one will not be + precached. I have included my precacheing code at the + end of game.c for those interested in making the precaching + fancy. + + - Fixed bug in editart which made it sometimes save the art files + and names.h in the wrong directory (the last directory you + were in when you were in 'U' mode). You may want to search + your artwork directories to see if you were a victim of this + bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/30/94 - Made Ctrl-Enter paste parallaxing sky tiles to all neighboring + parallaxing sky areas also. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/31/94 - Fixed (most) crashing bugs - Doesn't even crash on the highest + skyscrapers now! Since I can never be SURE that the crashing + is gone, I need you to test it for me - compare the number + of times it crashes per second since the last version. It + should be much better. + + - Fixed sector line bug! Get close to a step, hold down Shift+Z + and the edges of the step will NOT jitter like before AND you + will not get random walls going through the screen. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/1/94 - Got rid of the OLD transluscent stuff from overwritesprite and + permanentwritesprite. (Before it used the 8K shading table + which didn't work very well) + + - Added new true 50/50 transluscence option to overwritesprite. + See bit 2 in the next comment. + + - Fixed overwritesprite so it works with different screen sizes. + You don't need to do any scaling calculations! Should be + compatible with old function. Added new bit 1 to orientation + parameter to determine whether or not the sprite should be + scaled and clipped to the viewing window. + + overwritesprite (long thex, long they, short tilenum, + signed char shade, char orientation) + + If Bit 0 of orientation = 0: (thex, they) is top-left corner + If Bit 0 of orientation = 1: (thex, they) is middle + If Bit 1 of orientation = 0: no relation to viewing window + If Bit 1 of orientation = 1: scale and clip to viewing window + If Bit 2 of orientation = 0: normal + If Bit 2 of orientation = 1: 50/50 transluscent! + + * If it works at full screen, simply set bit 1 of orientation + to 1, and it should automatically scale properly! + + - Made it so 2/4/6/8 keys in 3D EDIT MODE now only move the objects + 1 step rather than continuously, giving more control over the + repeat/panning values of things. + + - Made the / key not only reset the repeats of walls, but also for + sprites. It will set both repeats of the sprite to the default + size of 64. If you hold down shift with / on a sprite, it + will give the sprite a square aspect ratio by setting the + xrepeat to equal the yrepeat value. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/2/94 - Doubled the board size from: (0 to 65536, 0 to 65536) to + (-65536 to 65536, -65536 to 65536) Notice that the grid in + 2D EDIT MODE is much bigger than before. Since it is very easy + to double the maximum board size, just tell me if you need + a larger board. The only bad thing about allowing larger + boards is that the map designer is more likely to make some + sectors too large and cause overflow bugs. 32 bits can only + go so far you know! + + - I think I MAY have fixed a bug in BUILD that used to make it crash + when quitting. It had something to do with the vertical grid + lines in 2D EDIT MODE when zoomed way in around the upper left + corner of the map (I think). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/3/94 - Optimized Editart loading and saving. + + - Made 'V' screen in Editart 320*400 instead of 320*200. + + - Before I said I fixed the bug in EDITART where a few pixels in the + top left corners of tiles sometimes got overwritten. Well I + lied. This time I really fixed it. (I hope) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/7/94 - Made x&y repeats, x&y pannings easier to adjust. It now works + like the default keyboard handler. It moves once when you + first press the key. A little later, it starts to move fast. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/11/94 - Added great new sprite rotation function which works like + overwritesprite (like 2DRAW sprites) + + rotatesprite(long sx, long sy, long z, short a, short picnum) + + (sx, sy) is the center of the sprite to draw defined as + screen coordinates shifted up by 16. + (z) is the zoom. Normal size is 65536. + Ex: 131072 is zoomed in 2X and 32768 is zoomed out 2X. + (a) is the angle (0 is straight up) + (picnum) is the tile number + + Ex: rotatesprite(160L<<16,100L<<16,65536,lockclock<<4,DEMOSIGN); + This example will draw the DEMOSIGN tile in the center of the + screen and rotate about once per second. + + Rotatesprite clips to the same area as overwritesprite but does + not scale or do transluscence yet. + + - Please look at the new permanentwritesprite documentation at the + top of this file! + + - Network should now work again - It now works great on my network + with 3 players! It may possibly also work with 4 or 5 players + too, but I didn't feel like running between 2 rooms to test it! + I never thought the day would come when I would get NET, COM, + and MODEM all working respectably! + + - Changed setup program so you can select 2, 3, 4, or 5 players in + a network game. (The 5 is just to annoy people who like that + other lousy game) + + - ATTENTION BUILDERS! Added TILE MOVING to EDITART! For now, it + will only work WITHIN THE SAME ART FILE. Do the tile moving + all in 'V' mode. Here are the new keys in 'V' mode: + + To swap 2 tiles: + Simply press space bar on the first tile, then space + bar on the second. + To swap a group of tiles: + Press 1 on the first tile, press 2 to remember the region + between where you pressed 1 and 2. Press 3 at the + place to where you want to swap all the tiles. + + Don't forget that this is all SWAPPING, tiles will (should) + NOT be overwritten using these keys. + + - ATTENTION PROGRAMMERS! Added ceildist and flordist parameters to + both clipmove and movesprite. I always had them all set to + (4<<8) by default. + + clipmove(long *x, long *y, long *z, short *sectnum, + long xvect, long yvect, + long walldist, long ceildist, long flordist, + char cliptype) + + movesprite(short spritenum, long xchange, long ychange, long zchange, + long walldist, long ceildist, long flordist, + char cliptype, long numtics) + + - Moved some com/network code from the getpackets function in game + into the engine. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/15/94 - Fixed some network initialization code and it now works with 4 + players. (I tested it.) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/16/94 - Added different shirt color support. Here's how you do it: + + allocatespritepalookup(long palnum, char *remapbuf) + + See more documentation of allocatespritepalookup at the top of + this file. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/18/94 - I made it so you can redefine the keys in the setup program under + the input devices menu. + + - ATTENTION EVERYONE - for this new version, you MUST go into my + new SETUP program, and SAVE CHANGES AND QUIT once. The arrow + key code will not work if you don't do this! If you are + one of those people who actually read BUILD.TXT, give yourself + 1 point. I wonder who will get "caught" for not reading this! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/22/94 - Added pixel height and wall length information to 2D EDIT MODE + when you press Tab or Alt-Tab on a sector or wall. + + - Now show the actual number of sprites in 2D EDIT MODE. + + - Improved digitized sound routines. Just thought I'd mention it. + + - Added a "save As" feature to 2D EDIT MODE. + + - Now show all lo and hi tags in 2D EDIT MODE on the map itself! + Note that position of the sector tag's text is put at the + average point of all the points of the sector, so if you have + a weird shape tagged sector, the text might show up at an + inconvenient place. + + - You can turn the tag boxes on or off by pressing CTRL-T or by + zooming out. + + - ATTENTION EVERYONE - for the new BUILD.EXE and OBJ's, you will + need to copy my new TABLES.DAT over your old one. Also, you + must go into SETUP and SAVE&QUIT. I have split the TABLES.DAT + file into 2 separate files. They are: + + TABLES.DAT - 10880 bytes - sin tables, fonts, etc. + SETUP.DAT - 23 bytes - (6 options) + (17 custom keys) + + The SETUP.DAT file is the only file SETUP.EXE accesses now. + This means that from now on, if I want to add something to + TABLES.DAT, you won't have to go into the setup program and reset + the options again. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/24/94 - Relative alignment now fully works with ROTATION! Relative + alignment will allow ceilings and floors to align with the + first 2 points of a sector. This will relieve you of + programming special ceiling and floor panning code for moving + sectors. + In 3D EDIT MODE, simply press 'R' on a ceiling / floor to switch + between relative alignment mode and normal mode. Notice that + bit 6 of both sector[].ceilingstat and sector[].floorstat are + relative alignment bits. + I have an example of relative alignment in nukeland.map in the + high blue room off the main octagonal room. Also note that my + subways and dragsectors now use relative alignment for panning. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/25/94 - I added a new parameter to printext256 and printext16. I need + to document this stuff! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/27/94 - Made it so you can't shrink sprites so much you can't grab them + any more in 3D EDIT MODE. + + - Added (G)oto feature into Build 'V' mode. Simply press G, type + the tile number and it will go there. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/7/94 - Fixed relative alignment bugs I noticed. My subway.map won't + crash anymore and the relatively aligned ceilings and floors + should not pan crazily anymore when looking from a far + distance. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/9/94 - ATTENTION PROGRAMMERS: I added a new parameter to + overwritesprite. Dapalnum can be from 0-15 depending on + what palette lookup table is being used. Dapalnum is normally + 0. Overwritesprite now looks like this: + + overwritesprite (long thex, long they, short tilenum, + signed char shade, char orientation, char dapalnum) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/13/94 - ATTENTION PROGRAMMERS: I changed the last parameter of drawrooms + (sector number) to be passed as a value, NOT a pointer anymore. + + drawrooms(long daposx, long daposy, long daposz, + short daang, long dahoriz, short dacursectnum) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/15/94 - ATTENTION PROGRAMMERS: I took out the COM(modem)/network code + from my engine.obj and put it into a separate .obj called + multi.obj. (I also removed the sound from my engine and stuck + it in kdmeng.obj) Please include it in your makefile. Here is + a list of ALL of the variables and functions you will need to + know to program for multiple players: + + VARIABLES: (You should extern these in your game.c) + extern short numplayers, myconnectindex; + extern short connecthead, connectpoint2[MAXPLAYERS]; + extern long *lastpacket2clock; + + FUNCTIONS: + initmultiplayers(option[4],option[5]); + uninitmultiplayers(); + + sendlogon(); + sendlogoff(); + + sendpacket(connecthead,tempbuf,j); + sendpacket(-1,tempbuf,j); + leng = getpacket(&otherconnectindex,tempbuf); + + Please see detailed descriptions of these functions at the top + of this file. + + - Multiplayer code is now MUCH cleaner! + + - Please try my game on your networks again! My game now works + perfectly with 3 players on a network that used to crash at + the DOS4GW prompt just a week ago! My game needs only IPX, + no server to run. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/16/94 - ATTENTION PROGRAMMERS: CONVMAP5!!! YOU MUST RUN CONVMAP5 ON + ALL OF YOUR MAPS IF YOU WANT THEM TO WORK WITH THE NEW + BUILD.EXE OR OBJ'S! Following are the exact changes I made + to the new map format: + + * Added numextras + * Added sector[].ceilingpal + * Added sector[].floorpal + * Added sector[].visibility + * Split sector[].tag to sector[].lotag and sector[].hitag + * Added sector[].extra + * Expanded wall[].cstat to a short + * Split wall[].tag to wall[].lotag and wall[].hitag + * Added wall[].extra + * Split sprite[].tag to sprite[].lotag and sprite[].hitag + * Got rid of sprite[].extra (the void * mess) + * Added sprite[].extra + + The only thing programmers have to worry about when converting + are the tags. I split them into lo and hi tags. + (See BUILD.H for new structure formats) + + I got rid of the (void *)extra thing from the sprite + structure. I know I may have made some promises it + wouldn't change and it was for your use only, but what + can I say - it's not needed anymore (in other words, + if you're already using it, TOUGH LUCK). I have my + own, new, method for extending sector, wall, or + sprite structures. You will be able to extend any + structure as much as you want AND be able to edit it + all in the BUILD editor to be saved in the permanent + map format. Notice I added a (short)extra to all 3 + main structures. They default to -1. But if they + are >= 0 then they form a linked list out of the + extra structure. NOTE: THIS EXTRA STUFF IS NOT + PROGRAMMED YET! I'm just mentioning it becuase the + new map format has this extendability. I'll try to + get it done soon though. (9/21/94) - Actually just + ignore the fact that this paragraph ever existed. + I'm just keeping it here for history purposes. + + - Renamed my allocatespritepalookup function to makepalookup since + it now also applies to walls, ceilings, floors, p-skies and + masked walls. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/20/94 - Added rotated sprites. These new rotated sprites rotate in the + same way as masked walls. Sounds like a waste since the + engine already has masked walls? NOT AT ALL! With rotated + sprites, you can EASILY do TRUE ornamented walls FULLY inside + the BUILD editor with even MORE versatility than that other + game out there. For example, you can place the ornamentation + anywhere on the wall, with sizing control using 2,4,6,8 on the + keypad, and even ornament with transluscence! In 3D EDIT + MODE, simply press 'R' on a sprite to make it a rotated + sprite (Programmers see bit 4 of sprite[].cstat) + + - Fixed crashing bug with sector (Rt. ALT) copy/paste in 2D EDIT + MODE. + + - You can now copy groups of sectors from 1 map to another! Here's + how you do it: + + Step 1: Capture a bunch of sectors with the Rt. ALT selection + tool. + Step 2: With the sectors still highlighted, you can now load + another map and the highlighted sectors will + automatically be inserted into the new map. (They + will still be highlighted) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/21/94 - Fixed bug with cursectnum not always being right after loading + the board. I now check it and make sure it's right when + saving in BUILD now. + + - Added 'O' key in 2D/3D EDIT MODES. It will push a rotated sprite + backwards (using hitscan) into the first wall and + automatically adjust the angle to make the sprite appear + as if it was part of the wall. + + - You can now press 'S' to insert a sprite in 3D EDIT MODE. Press + 'S' on a ceiling or floor. + + - You can now press delete to delete a sprite in 3D EDIT MODE. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/22/94 - Programmed Nick & Peter's BUILD stub to their EXACT + specifications. See WSTUB.C for code & documentation. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/27/94 - Fixed Rt. Alt block copying nextsector1 pointer bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/29/94 - Added special bitmapped effect which I either call lava or + boiling slime. See my initlava and movelava functions + inside GAME.C. + + - I added a bit array call gotpic. The engine will set the + respective gotpic bit for each picnum drawn to the screen, + including ceilings, floors, walls, sprites, masked walls - + even overwritesprites, etc. This array is mainly for + making the game only calculate special bitmapped effects + when that certain picnum is on the screen. + + Note 1: The engine does NOT automatically clear the gotpic + bits for you. If you want to test gotpic for a certain + picnum, you should clear it if you want to test it again. + + Note 2: It is not necessary to use permanentwritesprite + for bitmapped special effects - after all, if you see it, + it MUST be in the cache. + + Added to BUILD.H: + EXTERN char gotpic[MAXTILES>>3]; + + Example code in GAME.C: + if ((gotpic[SLIME>>3]&(1<<(SLIME&7))) > 0) //test bit + { + gotpic[SLIME>>3] &= ~(1<<(SLIME&7)); //clear bit + + if (waloff[SLIME] != -1) //if in cache + movelava((char *)waloff[SLIME]); //calculate! + } + + - Added what some people call gamma correction. I think + brightness is a better description though. + + setbrightness(char brightness); + + Simply call this function where brightness ranges from + 0 to 4. Brightness defaults to 0. Levels 1-4 are all brighter + than 0. If you switch between 2D & 3D modes, the engine will + remember the current brightness level. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/30/94 - Added a few keys to fake a multiplayer game all on 1 computer. + In my game, press Insert to add a new player at the starting + position, and Delete to delete the last player. Press + scroll lock to get control of the other players. In the same + way Lt. Enter lets you view other players, Scroll lock will + let you control other players (single player game only) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/2/94 - Moved all doanimations code from engine into game.c. If you + are using the doanimations code, here's exactly what you + need to do to make it work with your code again: + + Step 1: Copy these 3 functions which you should find at + the end of my Game.c: + + doanimations(long numtics) + getanimationgoal(long animptr) + setanimation(long *animptr, long thegoal, long thevel) + + Step 2: Move these variables out of BUILD.H and into your + game.c: + + #define MAXANIMATES 512 + static long *animateptr[MAXANIMATES], animategoal[MAXANIMATES]; + static long animatevel[MAXANIMATES], animatecnt = 0; + + * If you copied my door code, you will probably have to convert + some parameters to longs. (oops!) + + - Got rid of printnum from the engine. It is an outdated function. + Use either printext256 or printext16 instead. + + - Added y-flipping for both normal and rotated sprites. (see bit + 3 of sprite[].cstat in BUILD.H. + + - Added y-flipping for walls. (see bit 8 of wall[].cstat in + BUILD.H. + + - Fixed bug with initialization of Master and Slave for + COM(Modem) only. If both computers went in at the same + time, it used to sometimes think both were Masters. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/4/94 - Alt-C in 3D EDIT MODE changes all picnums on the whole map + from the picnum in tab to the picnum under the mouse cursor. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/6/94 - Fixed y-flipping bug on walls and masked walls. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/16/94 - Fixed bug in editart that didn't convert the maps right after + swapping tiles. + + - Added excellent function to my multi.obj. + + long getoutputcirclesize(); + This function returns the number of bytes that have not + yet been copied. If there are still more than say, 16 bytes, + then you may be sending too many bytes per second. This can + happen if the frame rate of a computer is faster than the + speed of the serial mode (Ex: Try 2400 baud with a Pentium 90!) + this function will tell you how many bytes are left to copy + In other words, if getoutputcirclesize() < 16 then it is safe + to send a packet. If you already have serial mode working + all you have to do to update your code is to copy the lines + in my sync() function the deal with the getoutputcirclesize + function. Everything else in sync() and getpackets() is + pretty much the same. + + - Programmed some example code in my game that will allow players + to change masters and slaves during the game without losing + sync. Simply press 'M' in my multiplayer game, and that + computer will become the master! It is interesting how + the frame rate and controllability changes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/31/94 - Added basic scripting to EDITART. Don't expect it to be + everything you ever dreamed of (yet). + + Scripts are saved in a file called CAPFIL.TXT. You can edit the + text file, but be careful not to screw it up too badly (such + as extra commas, spaces in weird places, etc.) since I am + parsing it in EDITART. + + Whenever you select a box in 'U' mode, a line will be appended to + the CAPFIL.TXT file. + + WRITING THE CAPFIL.TXT FILE: + In 'U' mode, you can press 'O' instead of ENTER to select a tile. + What 'O' does that is different from ENTER is that it takes + the center point of the highlighted rectangle, and searches + outward until a total rectangle of transparent pixels (255) + is reached. This is useful for grabbing sprites - not only + will you not have fine adjust to the exact borders of a + sprite now, but when you re-grab from the pcx's you can + change the size of the sprite freely. + + READING THE CAPFIL.TXT FILE: + There are 2 ways to re-grab from the CAPFIL.TXT file. If you + press ALT-U in the main screen, everything will be re-grabbed. + If you press ALT-U in 'V' mode, then you should first select + the range by pressing '1' and '2' on the range boundaries. + + Format of CAPFIL.TXT lines: + Tile #, Full path/file name, x1, y1, xsize, ysize + + Note: If xsize and ysize are 0, then that means you did + an 'O' grab and EDITART will search from point (x1, y1) + when you do a re-grab. + + Example CAPFIL.TXT file: + 31,D:\CAPTUR00.PCX,220,98,64,64 + 110,D:\CAPTUR00.PCX,49,72,0,0 + + The first line says that tile #31 is a 64*64 tile and the + second line says that tile #110 is unknown size tile (grabbed + with the 'O' key) + + Note: You can only do 1 grab per tile with my scripting system. + You may have done your parallaxing skies with several grabs. + If so then try to make the tile into 1 large PCX and do 1 + grab. (The largest grabbing size right now is 1024*256) + + ------------------------------------------------------------------- + + - Made Editart's screen capture (F12) save to PCX's the exact size + of the tile and not include the status bar at the bottom. It + will also save large tiles to large PCX's - Now it's easy and + lossless to extract a tile from Editart! + + - ATTENTION PROGRAMMES! Added 2 new parameters to getzrange for + returning the objects hit on top and bottom. + (sectors / sprites) See my updated documentation at the top + of this file. + + - Fixed clipping bugs with sprites near sector lines. (I hope) + + - Got 3D Red-Blue glasses mode working for all VGA cards. First + set the graphics mode to red-blue mode in the setup program. + The left eye is red and the right eye is blue. There are + 4 keys that let you adjust the 3D view: + [,] = Adjust width between eyes (3D width) + Shift [,] = Adjust width of parallax (2D width) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/1/94 - Guess what? I turned 19 today. Doesn't that just suck. Now, + if you play my build game on my birthday, all the extemely + evil and scary brown monsters will be replaced with super + happy fun dogs that throw smiley red jelly coconuts at you. + Also, my incredibly evil and scary music will be replaced + with super happy music. Actually this whole paragraph is + a joke (except for the birthday part). + + - Made centering work with rotated sprites. + + - Fix centering with x and y flipped sprites. + + - Rotated sprites now get chopped off by the ceiling or floor in + the same way normal sprites get chopped. Sprites do not get + chopped if there is a parallaxing sky / floor. + + - Made Shift + F12 is BUILD 2D mode inverse black and white. + + - If SETUP.DAT is not found then default options are loaded + instead of quitting to DOS. + + - ATTENTION PROGRAMMERS! Added 3 parameters to makepalookup that + allow you to do FOG effects. The first 2 parameters are the + same as before. The last 3 are the color that the palette + fades to as you get further away. Before, this color was + always black (0,0,0). White would be (63,63,63). + + makepalookup(long palnum, char *remapbuf, + char redvalue, char greenvalue, char bluevalue) + + - ATTENTION PROGRAMMERS! Moved 2 things into BUILD.H. Please + make sure to update it: + + #define MAXPALOOKUPS 256 + and + EXTERN char *palookup[MAXPALOOKUPS]; + + The palookup array is an array of pointers that point to the + first byte of each 8K palette lookup table. All 256 pointers + are initialized to NULL by initengine() except for palookup[0] + which is the default 8K palette. This will allow you to modify + the palette lookup table directly for non-snowy fading effects, + etc. Each palette lookup table has 32 shades. Each shade has + 256 bytes. Shade 0 is closest (actual palette brightness) and + shade 31 is farthest (dark usually). (256*32 = 8192 or 8K) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/3/94 - Now show white lines in 'V' mode of EDITART at ART file tile + boundaries. + + - Added Insert and Delete commands to EDITART! These Insert and + Delete keys WILL shift all tiles after the one being inserted + or deleted just like a regular text editor. To insert or + delete tiles, simply go the 'V' screen in EDITART and bang + away! Don't worry these keys are fully multi-tile file + compatible (unlike swapping right now). + You will notice that the white line boundaries that + I just added will actually move if you press Insert or Delete. + This changes the number of tiles per art file. But that's + ok. If the art files ever get too unbalanced, you can run + the RSIZEART.EXE utility to fix it. + Ken's lesson of the day: For the final release of your + games, you only need 1 art file. The reason I spent my time + programming multiple art files was because of EDITART. + Since EDITART need to READ & WRITE to the art files, it must + hold a whole art file in memory at a time. Since Build and + Game only READ the art files, a caching system can be made + and only 1 art file is necessary even for lo-memory systems. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/4/94 - ATTENTION MAP DESIGNERS! Added a long-awaited feature to BUILD + which I call "loop joining". Have you ever gotten this + frustrating message in 2D EDIT MODE before? + + "You can't split sector by connecting different loops." + + Well, you're not going to see it any more because I fixed + it! Yup. You can now split a sector along a line connecting + different loops of the sector. + + Try this - Convert the sector on the left to the sector + on the right: + + Split #1 Split #2 + ÚÄÄÄÄÄÄÄ¿ ÚÄÄÄÂÄÄÄ¿ ÚÄÄÄÂÄÄÄ¿ + ³ ÚÄÄÄ¿ ³ ³ ÚÄÁÄ¿ ³ ³ ÚÄÁÄ¿ ³ + ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ ³ + ³ ÀÄÄÄÙ ³ ³ ÀÄÄÄÙ ³ ³ ÀÄÂÄÙ ³ + ÀÄÄÄÄÄÄÄÙ ÀÄÄÄÄÄÄÄÙ ÀÄÄÄÁÄÄÄÙ + (Given) (Half done) (Result) + (1 sector) (Still 1 sector) (2 sectors) + + Before the only was to do this was to delete all the + sectors and then redraw them again. + + I'm sure loop joining has its share of tricks, as most + BUILD functions do, so you may want to spend some time just + playing around with this new function. + + - Removed my own profiler stuff - Hline calculations, etc. code. + Watcom's sampler and profiler is much better anyway. + + - Fixed neartag divide by zero bug with walls (I hope). + Anyone calling neartag for every player per movethings? + I would try not to - How much is that unnoticable extra 0.02 + frames per second worth to you anyway? +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/9/94 - Added new array to BUILD.H called gotsector. It works a lot + like the gotpic array, but this array determines which sectors + were considered during the drawrooms function. Note that + gotsector, unlike gotpic IS cleared to 0 during every call + to drawrooms. + + - Fixed Editart 'U' mode mouse control bug. I typed too fast this + time. + + - Fixed Build split sector bug of accidently deleting sprites. It + should not delete any sprites when splitting sectors now. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/15/94 - ATTENTION PROGRAMMERS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + I moved ALL my timer code and arrow key code into GAME.C. + Here are the exact instructions that you need to follow to + upgrade your code to the new obj's: + + 1. From the end of my GAME.C, take the code from these 4 + functions: + + ---> inittimer(); + ---> uninittimer(); + ---> void __interrupt __far timerhandler(); + ---> keytimerstuff(); + + 2. After each initengine, call inittimer right AFTER: + + initengine(); + ---> inittimer(); + + After each uninitengine, call uninittimer right BEFORE: + + ---> uninittimer(); + uninitengine(); + + 3. You may need to include this (if not already included): + + ---> #include + + 4. Add these 2 lines to declare the timerhandler: + + ---> void (__interrupt __far *oldtimerhandler)(); + ---> void __interrupt __far timerhandler(void); + + 5. Since BUILD.H NO LONGER has vel, svel, and angvel, you + must add the following line to your game: + (These variables are modified inside keytimerstuff()) + + ---> static long vel, svel, angvel; + + 6. Let me list some variables that I recently removed from my + GAME. This may or may not affect you: + + oposx[], oposy[], oang[], etc.. - GONE! + lastpacket2clock - GONE! + lastsynctics - GONE! + drawscreen's smoothratio parameter & related code - GONE! + kenchaintimer - GONE! (Don't think anybody was using it + because it didn't solve sound compatibility problems) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/16/94 - Made swinging door clipping work MUCH better! It is much more + difficult to "sneak" through the door now. With the swinging + door clipping working much better, I made it possible to open + doors even if you are in the same sector as the door itself. + Now you won't have to stand back a certain distance to open + the doors. (It is much less annoying this way) Since neartag + does not normally scan cursectnum's sector tags, you will + need to check cursectnum's tags yourself (if you so desire) + + Example: (extracted from my GAME.C) + + neartag(posx[snum],posy[snum],posz[snum],cursectnum[snum], + ang[snum],&neartagsector,&neartagwall,&neartagsprite, + &neartaghitdist,1024L); + if (neartagsector == -1) //If no neartagsector found... + { + i = cursectnum[snum]; //Test current sector for tagging + if ((sector[i].lotag|sector[i].hitag) != 0) + neartagsector = i; //Cursectnum is the neartagsector! + } + + - Improved my gamma correction algorithm. Since it now uses a new + 1K at the end of my TABLES.DAT, be sure to update all your + TABLES.DAT files! My new gamma correction supports 16 levels + of brightness (0-15). You need not change any code in your + game if you already have gamma correction programmed. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/17/94 - Made swinging door clipping code work even better. The bug was: + it only tested the clipping if you were in the same sector as + the door. So I put this handy little function in GAME.C which + simply tests if 2 sectors are neighbors or not: + testneighborsectors(short sect1, short sect2) + Check it out! + + - Rewrote my clipinsidebox function. You probably don't use this + function, but if you copied my swinging door code, then you + will need to update this. Clipinsidebox is used for clipping + to determine whether a player or sprite is too close to a + wall. + + clipinsidebox(long x, long y, short wallnum, long walldist) + X and y are the position of the sprite or player. Wallnum + is the wall to test, and walldist is the fatness of the sprite + or player (same as clipmove). It returns a 1 if the sprite or + player's clipping square intersects the wall or 0 if not. + + Example - You can test all 4 walls of a swinging door and make + sure the door doesn't run you over: + + short swingwall[4]; //4 wall indeces of a swinging door + for (i=0;i<4;i++) + if (clipinsidebox(posx,posy,swingwall[i],128L) == 1) + { + //Swinging door swung into player, so move door back to + //its old position / inverse swinging direction. + + break; + } +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/22/94 - Made build posx, posy, posz, ang, cursectnum, and horiz variables + nonstatic. + + - Made hi-res screen capture work. + + - Fixed some of those evil view-clipping bugs with rotated sprites + on red sector lines. I think it should work with rotated + sprites on horizontal or vertical red lines. I'm not sure + about weird angled lines. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/23/94 - ATTENTION PROGRAMMERS: Made parallaxing skies tileable in any + equal size chunk where the chunk x size is a power of 2 + from 16-1024. You can now make a 2048 wide parallaxing sky + with 2 chunks of 1024 (gobble gobble). + + These lines were added to BUILD.H: + + #define MAXPSKYTILES 256 + EXTERN short pskyoff[MAXPSKYTILES], pskybits; + + pskyoff[MAXPSKYTILES] is an array of OFFSETS of each tile + from the picnum of the parallaxing sky. + + pskybits is NOT the actual number of tiles, but the + log (base 2) of the number of tiles. Look at this table: + + For 1 tile, pskybits = 0 + For 2 tiles, pskybits = 1 + For 4 tiles, pskybits = 2 + For 8 tiles, pskybits = 3 + For 16 tiles, pskybits = 4 + etc. + + + I know that most teams have a 1024 wide parallaxing sky that + wraps all the way around. Don't worry - this is the + default now. When initengine is called, the variables + default to this: + + pskyoff[0] = 0; + pskybits = 0; + + You may have used a 512 wide parallaxing sky (like in my game) + that repeated every 180 degrees. To make this work with + the new version, set these variables like this right after + initengine is called: + + pskyoff[0] = 0; + pskyoff[1] = 0; + pskybits = 1; + + Note that both pskyoff variables are 0 here. This will + make the parallaxing sky repeat. + + With the new tiling, you can save memory by making small + chuck sizes, such as 64 or 128, and repeating certain + sections. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/25/94 - Fixed some really stupid keyboard problem in Build. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/29/94 - Added FLOOR SPRITES!!! Here are some things that floor sprites + can do for you: + + * Make bridges and balconies + * Use them for ceiling and floor ornamentation + * Use them in place of a rotating sector - modifying 1 angle + is much faster than rotating tons of points. + * Weapon such as a spinning saw blade or, of course, a smiley + red jelly coconut. (?) + * How about a "walking" hole like in Ken's Labyrinth + * You could throw a footstep on the floor every time you make a + step. The steps would go away after awhile. Maybe if you + step in mud, the next 16 or so footsteps will be plotted. + * You could even fake radial shading with a transluscent floor + sprite. (Transluscent floor sprites not yet programmed) + + Just imagine all the great stuff you can do with floor + sprites combined with wall sprites! I can't wait to see what + you all come up with! + + ÚÄÄ To clear some confusion, and to shorten conversations, let + ³ me give official names to my 3 kinds of sprites: + ³ + ³ Normal stupid sprites - "FACE SPRITES" + ³ Rotated / masked wall sprites - "WALL SPRITES" + ³ New ceiling & floor sprites - "FLOOR SPRITES" + ³ + ³ Also let me clear up the 2 kinds of clipping: + ³ + ³ Clipping when moving something - "MOVEMENT CLIPPING" + ÀÄÄ Clipping when drawing something - "VIEW CLIPPING" + + To make a floor sprite in BUILD, simply press 'R' on any + sprite until it becomes a floor sprite. The xrepeat and + yrepeat values should work perfectly with floor sprites. + Floor sprites can be rotated at any of 2048 degrees, using + the sprite[].ang. Press < / > for course angle adjustment + or < / > with shift for fine angle adjustment. Also, you + can press 'F' on a floor sprite to flip it over like a + mirror. I am using another bit in sprite[].cstat to determine + the type of sprite. See the documentation in BUILD.H. + + Now for the bad news: + + * Floor sprite textures have similar restrictions as normal + ceilings and floors - both dimensions must be a power of 2. + This will most likely not change. + + And some known problems which I will have to fix: + * Transluscence doesn't work yet + * Sorting with other sprites + * View clipping with walls + * Doesn't work too well in hi-res mode + + See NUKELAND.MAP for some examples of floor sprites. I have both + a bridge and a balcony on the level. Please find them! + Remember that floor sprites don't work in mode x or hi-res + mode YET! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/30/94 - Made WALL SPRITE and FLOOR SPRITE correctly do movement clipping. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/1/94 - Made new map called BRIDGES.MAP. It is excellent! It has 3 + bridges all crossing each other. Enjoy! + + - For Editart, I added re-centering after delete and / to reset + centering while in centering mode. + + - Debugged more of the floor sprite stuff. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/2/94 - Made transluscence with floor sprites work. Check out my fake + radial shading under the lights of SUBWAY.MAP. + + - Optimized floor sprites in assembler. Transluscent floor sprites + are a bit slower than normal floor sprites. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/6/94 - Made a special 1-way mode for WALL and FLOOR sprites + (not FACE sprites). In BUILD 3D mode, you can press '1' on + a wall or floor sprite to make it only draw if you are on + 1 side of it. This method of back-face culling will not only + make non-masking objects with thickness draw twice as fast, + but will also make fewer drawing bugs due to sprite drawing + order. Try out my BRIDGES.MAP. There's a new section at the + top and it's not another "ugly Ken's face n' slime" room. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/8/94 - Editart and Build now capture with capt#### rather than captur## + allowing 10000 captured pictures. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/23/94 - Increased Maximum number of walls to 8192. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/28/94 - Made BUILD stub keys F5-F8 work in 3D mode also. See top + of BSTUB.C for full documentation of some new useful + variables that can be used inside the stub: + + extern long qsetmode; + extern short searchsector, searchwall, searchstat; + + In 3D mode, F5 and F6 do the exact same thing and F7 and F8 + do the exact same thing (you don't need the extra key to + distinguish between sectors, walls and sprites, since the + mouse cursor can only be on 1 of the 3 objects in 3D mode. + + Note: Since F5-F8 are called in 3D mode, you must be sure + NOT to use any 2D routines during those calls! This means + you will have to put the 3D/2D case check in all six + subroutines: + ExtShowSectorData, ExtShowWallData, ExtShowSpriteData, + ExtEditSectorData, ExtEditWallData, ExtEditSpriteData + + - KEN'S PROPOSAL (NOT YET DONE) I am thinking of making a new + (and maybe final) map format. But before I do it, I am going + to ask all of you for any suggestions on new fields to add to + my 3 big structures (sector, wall, sprite): + + Here are a few things already on my list to add: + + * char sprite[].clipdist - THIS IS FOR SURE + This will be a sprite's clipping distance. My default + walldist is 128. With this field, you will finally be + able to make a unique fatness for each sprite with no + clipping bugs. I will probably shift this field up 2-4 + bits to give it a range of more than just 0-255. + + * char wall[].pal, sprite[].pal - PRETTY SURE + It should have been this way the whole time. Currently + the wall's palookup number is sector[].floorpal. While + it may save some memory, It has too many limitations. + I can make my map converter automatically convert all + walls of a sector to equal the sector[].floorpal so + don't worry about that type of conversion. If I do + this, I can get rid of the spritepal[] hack. + + * I have decided that the sector[].extra, wall[].extra, and + sprite[].extra will remain in the structures as little + gifts for your use only. That's right! ALL YOURS! + ENJOY!!! + + * char sprite[].xoffset, sprite[].yoffset - NOT SURE YET + Some have asked for monster animations using the same + frame at 2 different times of an animation sequence having + different centers. + These will be signed chars. I'm not sure whether to + make these offsets as offsets to the centering information + from Editart or just make them the absolute offsets where + Editart's data is the default offset. I wonder if there's + a better way to do this without having to waste 8K. + + * Do I have your permission to remove nextsector2 and + nextwall2? Anybody using them? If so, can you use the + extra variable instead? This will save 16K since both + are shorts. (MAXWALLS*short + MAXWALLS*short = 16384) + They were originally intended for 2 stories + but it would be totally ridiculous for me even to think + about programming that now. Besides, you can use wall + and floor sprites to fake 2 story areas. KEN PROMISE: + I will fix those darn view-clipping bugs eventually! + + + Please send any comments/suggestions to my internet address + (kjs@lems.brown.edu) I will consider each suggestion + carefully, because everything you suggest now won't have + to be an ugly hack like spritepal[] later. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/1/95 - ÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÜ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛ + ÛÛ ÛÛ ÛÛ ÛÛÛÜ ÛÛ ÛÛ ÛÛ ÛÛÛÜÜÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ + ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛ ÛÛÜ ÜÛÛ ÛÛßÛÛßÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛ + ÛÛ ÛÛ ÛÛ ÛÛ ßÛÛÛ ÛÛÛÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ + ÛÛÛÛÛ ÛÛÛÛÛÛ ÛÛ ßÛÛ ßÛß ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛ ÛÛ + + CONVMAP6! Here is what I changed in the structures: + + * Added wall[].pal, sprite[].pal + * Added sprite[].clipdist + * Expanded sprite[].cstat to a short + * Added sprite[].xoffset, sprite[].yoffset + * Removed wall[].nextsector2, wall[].nextwall2 + * Renamed wall[].nextsector1 to just wall[].nextsector + * Renamed wall[].nextwall1 to just wall[].nextwall + * Scrapped numextras and extratype structure - Don't confuse + this with sector[].extra, wall[].extra, sprite[].extra + which ARE in map version 6. + + Probably the only change above that will affect programmers is + getting rid of the '1' in wall[].nextsector1&wall[].nextwall1. + All the following changes were possible because of the new + map format. + + - Got rid of the spritepal array in BUILD.H. With my grea + new map version 6, you can simply modify sprite[].pal! + + - Made all .pal fields editable in 3D EDIT MODE. Press ALT-P + and simply edit the number as you would in 2D mode. + + - Made sprite[].xoffset and sprite[].yoffset work as + offsets to the offsets that are already in EDITART. + Simple addition. They should work for all 3 types + of sprites. + + - Made BUILD Tab&Enter also copy tags&extra if copying similar + structures. Also fixed some other attributes when + copying between structure types. + + - Made sprites highlighted with Rt. Shift duplicate and stamp + when the insert key is pressed in 2D EDIT MODE. + + - Made sprite[].clipdist work as the FACE SPRITE'S clipping + fatness. NOTE: Sprite[].clipdist is shifted up 2 to + allow a range from 0-1020, so if the sprite[].clipdist + is set to 32, then the clipping radius is actually 128. + + - Removed the walldist parameter from movesprite. Movesprite + now just uses the sprite[spritenum].clipdist field of + whatever sprite is passed (shifted up 2). + + movesprite(short spritenum, long xchange, long ychange, + long zchange, long ceildist, long flordist, + char cliptype, long numtics) + + If you use clipmove or getzrange, you should check that you + are passing the correct walldist parameters. I'm saying + you may want to change some of the 128s to + (sprite[spritenum].clipdist<<2). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/3/95 - Made startumost[], startdmost[] into shorts. + + - Optimized and fixed gamma correction in Stereo Red-Blue mode. + + - Made weapons or anything using overwritesprite in Stereo Red-Blue + mode be at screen depth. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/4/95 - Not that anybody would care (except for some crazed mega-hackers) + but I am just mentioning the fact that I did this: + + animateoffs(short tilenum, short fakevar); + where fakevar is sectnum+0 + or wallnum+16384 + or spritenum+32768 + or 49152 (just ignore-it's for rotatesprite) + + Also: I changed one: "mov al, 0" instruction into an + "xor al, al", a net savings of + ONE LOUSY BYTE! Let's not get TOO + excited! (By the way, just kidding) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/5/95 - Fixed the sprite centering with x-flipped FACE SPRITES. + + - Found a bug with my swinging door clipping code. There are 2 + types of swinging doors, forwards (opens CCW) and + backwards (opens CW). The bug was that you could sneak + through a backwards door from the back side. Well, I fixed + it, so now I challenge you to sneak through my swinging doors + now! If you are using my swinging door code, please make + these changes which you should find in my new GAME.C: + + 1. Changed declaration at beginning of GAME.C: + static short swingwall[32][5]; + + 2. Added new line in prepareboard: + swingwall[swingcnt][4] = lastwall(swingwall[swingcnt][3]); + + 3. Modified some stuff in tagcode: + //swingangopendir is -1 if forwards, 1 is backwards + l = (swingangopendir[i] > 0); + for(k=l+3;k>=l;k--) + if... + + - Here are some more functions that have been in the engine for + a while, but I forgot to document... + precache, loadtile, lastwall, rotatepoint + They are now documented at the top of this file. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/6/95 - Optimized loading/saving of maps by using fewer read/write calls. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/14/95 - Fixed evil crashing bug that I accidently introduced in the + 1/3/95 version of Build. This crashing bug happened mostly + in tall rooms with lots of FACE SPRITES. It used to crash + very infrequently when you were standing almost exactly, but + NOT on the same x & y coordinates of a FACE SPRITE where the + z-distance was high. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/15/95 - Fixed up network code so now you can miss 4 packets in row safely + over the network rather than just 2. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/16/95 - Added strafe left / strafe right keys to my SETUP.DAT file and + char keys[19] array. If you actually use my keys array for + custom keys, here's what to do: I inserted the new strafing + keys at keys[12] & keys[13], so just add 2 to any keys with + an index >= 12. + + - Made the sprites in 2D EDIT MODE of Build highlight properly + again. + + - Added another parameter to permanentwritesprite, palookup number: + + permanentwritesprite(long thex, long they, short tilenum, + signed char shade, long cx1, long cy1, + long cx2, long cy2, char dapalnum); +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/17/95 - You can now select a bunch of sprites in 2D EDIT MODE with + Rt. shift, then go to 3D mode and change the z's of all the + highlighted sprites. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/20/95 - Made Tab&Enter in 3D EDIT MODE copy .pal also whenever .shade is + normally copied. Shift+Enter will now copy just + .pal and .shade. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/21/95 - Made Splitsector work with overlapping better. + + - In Editart 'U' mode, it now goes automatically to the PCX and + coordinates of a tile if it is already in capfil.txt. + + - In Editart, made capt????.PCX not get overwritten if they already + exist. + + - Fixed Build tab on masked walls. + + - Made zmode and kensplayerheight variables public in BUILD/BSTUB + so you can now compile BUILD to start out with your own + preferred settings. Kensplayerheight defaults to 32 and + zmode defaults to 0. You can over-ride these settings in + the new ExtInit function. + + - Made Editart tiles much easier to center by showing all tiles + in the center of the screen instead of at the top-left corner. + (Editart will not allow you to center tiles larger than + 320*200 right now) + + - Made 'O' (optimize) key in Editart automatically preserve + the centering information. + + - ATTENTION BSTUB PROGRAMMERS! Added ExtInit, ExtUnInit, and + ExtCheckKeys to BSTUB.C. Please just copy mine into your + current BSTUB. ExtInit and ExtUnInit are called only once. + ExtInit is called before loadpics() and after initengine(). + ExtCheckKeys() is called just before nextpage in both 2D + and 3D modes. In 3D mode, you must call editinput inside + ExtCheckKeys just like my example in BSTUB. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/24/95 - Fixed vertical line chained mode bug with permanentwritesprites. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/31/95 - Fixed parallaxing sky tiling bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/1/95 - Fixed network crashing bug when call interrupt 0x1c. You call + this interrupt when you chain to the old timer handler. Now + + - Rewrote multiplayer code in game.c a bit. Moved both sync() + and getpackets() into the main program. The master code and + single player game code are now the same. Slaves need to + drawscreen and send packets only when a packet is received + from the master. Got rid of fake sync[MAXPLAYERS] slot by + using a local sync buffers. Rewrote checkmasterslaveswitch(). + If you don't get what I did, it doesn't matter because you + already have working network code! + + - Added new key in EDITART 'V' mode. Press ALT-R to generate + a tile frequency report. It will scan all MAP files in the + same directory as the ART files. The frequency count will + show up as text in the top-left corner of the boxes in + 'V' mode. Press ALT-R again to turn off text. + + - Perfected NCOPY! Copies about 150K / second which is 10 times + faster than a 115200bps serial cable. Since NCOPY already + links with multi.obj, it should not be too difficult to make + joining work in the middle of a network game. Please wait + until I make some sample code for you! + Receiver types: NCOPY (Ex: "NCOPY") + Sender types: NCOPY [filespec] (Ex: "NCOPY *.ART") + + Ken's formula: + NCOPY + Loading&Saving GAMES = joining in middle + of network game! + + - Made a DOOM to BUILD converter. Right now it only converts + ceilings, floors, and walls now, and some of the wall + textures are screwed up. Just because I converted some + lousy stinkin' maps DOES NOT MEAN I AM GOING TO PROGRAM DOOM! + Unfortunately, the converter is programmed in QuickBasic right + now, it won't compile, and I didn't feel like putting up the + 7 MEG converted ART file up. When I convert it to C, I'll + upload it for all! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/7/95 - Fixed overwritesprite bugs with translucence in chained mode + and above top of screen. + + - Made bit 3 of overwritesprite x-flip the picture if set. + + - Optimized various parts of engine. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/8/95 - Fixed shading of all sprite types so they match perfectly with + their surroundings. Floor sprites now shade in the exact same + way as ceilings and floors. (Before, the whole floor sprite + had the same shade throughout) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/9/95 - Started on loading and saving game code so I could give some + sample code for joining network games, but none of it works + yet, so just ignore it for now! + + - Added frame rate in BSTUB.C. It averages the last 16 frames. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/16/95 - Added another bit to sprite[].cstat for y-centering control. If + bit 7 is set then the sprite's center will be the actual + center rather then at the default position which is at the + bottom of the sprite. If you use this centering bit, + you finally get "WYSIWYG" centering contol in EDITART. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/24/95 - Made floor sprites now support any x size by a power of 2 y size. + (That's better than before!) These are the same restrictions + on walls. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/25/95 - Got loading / saving code to work with my game. Press Ctrl-L to + load game and Ctrl-S to save game. Saved games are called + SAVE0000.GAME and are about 300K. Don't worry about the large + sizes of the saved game files since they can be easily + compressed to less than 50K. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/26/95 - I Finally made my multiplayer code run with fast frame rates AND + pefect controls on ALL computers of a multiplayer game. I am + now sending keystrokes of all computers at a constant rate of + 40 times per second. All computers interpolate between frames + to get screen frame rates of higher or lower than 40 fps + (even in single player mode). + + Here are the exact steps you will need to follow if you want to + update your code: + + 1. WHAT'S THE FAKETIMERHANDLER()? + + To send packets exactly 40 times a second, it would + sure be nice to send them right from the timer interrupt + handler. Too bad network packets just won't get sent + from the interrupt handler. (It may work from the + interrupt handler in Serial/Modem mode) So the solution + is to make a "fake" timer handler that must be called + at least 40 times a second even on the slowest computer. + Throughout my engine, I call faketimerhandler(). If you + have any slow parts in your game code, you may want to + called faketimerhandler() also. + Besides the very first few lines, the rest of the code + was taken directly from my old sync and getpackets + functions. + + 2. BYE BYE SYNCTICS! + + Now that all computers are calling movethings a + constant number of times a second, you don't need any + synctics variables anymore. You can convert all the + synctics variables to a define such as: + "#define TICSPERFRAME 3" + Doing this will guarantee that a game runs the same on + all speed computers. + + 3. FRAME INTERPOLATION (optional): + + static long ototalclock = 0, gotlastpacketclock = 0; + static long oposx[MAXPLAYERS], cposx[MAXPLAYERS]; + static long oposy[MAXPLAYERS], cposy[MAXPLAYERS]; + static long oposz[MAXPLAYERS], cposz[MAXPLAYERS]; + static long ohoriz[MAXPLAYERS], choriz[MAXPLAYERS]; + static long ozoom[MAXPLAYERS], czoom[MAXPLAYERS]; + static short oang[MAXPLAYERS], cang[MAXPLAYERS]; + + Add to prepareboard: + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + oposx[i] = posx[i]; + oposy[i] = (etc.) + } + ototalclock = 0; + gotlastpacketclock = 0; + + Even though you may be getting more than 40fps, you will + only be seeing 40fps unless you interpolate between frames. + The oposx[], etc. variables back up the last posx[], etc. + variables so you can interpolate your actually drawing + position as some fraction between the two. This fraction + is smoothratio. + See beginning of drawscreen code. Here's where I actually + calculate the interpolated position to draw the screen. + + for(i=connecthead;i>=0;i=connectpoint2[i]) + { + cposx[i] = oposx[i]+mulscale(posx[i]-oposx[i],smoothratio,16); + cposy[i] = oposy[i]+mulscale(posy[i]-oposy[i],smoothratio,16); + cposz[i] = oposz[i]+mulscale(posz[i]-oposz[i],smoothratio,16); + choriz[i] = ohoriz[i]+mulscale(horiz[i]-ohoriz[i],smoothratio,16); + czoom[i] = ozoom[i]+mulscale(zoom[i]-ozoom[i],smoothratio,16); + cang[i] = oang[i]+mulscale(((ang[i]+1024-oang[i])&2047)-1024,smoothratio,16); + } + + Draw the screen using cposx[], etc. instead of posx[], etc. + + #pragma aux mulscale =\ + "imul ebx",\ + "shrd eax, edx, cl",\ + parm [eax][ebx][ecx]\ + modify [edx]\ + + It reads: eax = (eax*ebx)>>cl. Unlike C, this will + not overflow even if eax*ebx > 2^31, making full use of + the 64-bit result of the imul instruction. + + 4. MOVETHINGS FIFO: + + static long movefifoplc, movefifoend; + static signed char baksyncvel[64][MAXPLAYERS]; + static signed char baksyncsvel[64][MAXPLAYERS]; + static signed char baksyncangvel[64][MAXPLAYERS]; + static short baksyncbits[64][MAXPLAYERS]; + + Add to prepareboard: movefifoplc = 0; movefifoend = 0; + + It is bad to call movethings inside faketimerhandler + because you don't want things to move while you're drawing + the screen. To solve this, I made movethings just save + away the parameters it was called with using a circular + buffer, and when I'm actually ready to DO the movement code, + I call domovethings. + Rename movethings to domovethings and see my new + movethings. This code is all for the fifo. + + Put this line in movethings: + gotlastpacketclock = totalclock; + + At the top of domovethings, copy my code for loading off + of the fifo. Also set oposx[] = posx[], etc. here. + + 5. You may want to add a global variable that controls whether + you are in continuous packet sending mode or not. Only + in the main loop should ready2send be != 0. + static long ready2send = 0; + + 6. The new main loop can be as short as this, with no case + checking for masters and slaves. + + ready2send = 1; + while (keystatus[1] == 0) //Main loop starts here + { + //Actaully move everything here. + while (movefifoplc != movefifoend) domovethings(); + + //Second parameter is for frame interpolation, + //A fraction that ranges from 0-65536. + drawscreen(screenpeek,(totalclock-gotlastpacketclock)*(65536/TICSPERFRAME)); + } + ready2send = 0; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/6/95 - New key in BUILD. Now when you use relative alignment mode on + ceiling and floor textures, you can press Alt-F on the ceiling + or floor to choose a new wall to align to. It actually + rotates the walls of a sector by 1. + + - Fixed screen capture PCX saving bug in both EDITART and BUILD. + + - Added a parameter to screencapture, a filename. + screencapture(char *filename) + Ex: screencapture("captxxxx.pcx"); + Please specify the full filename. Screencapture will modify + the 4 x's of the string to be a number starting at 0000. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/8/95 - Made my rotatesprite function use Editart centering information. + The center is the pivot point of rotation. + + - Added y-flipping to overwritesprite. See above documentation. + + - Added 2 new parameters to rotatesprite, shade and pal + + rotatesprite (long sx, long sy, long z, short a, + short picnum, signed char shade, char pal); + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/10/95 - Fixed sprite showing through closed sectors bug. + + - Made it possible to draw the overhead map in 3D mode by adding + a line drawing function in 3D mode called drawline256. It + draws a line clipped to the viewing rectangle last set in + setview(). Here are the parameters: + + drawline256(long x1, long y1, long x2, long y2, char col); + + Note: The coordinates are all shifted up 12. + Example: drawline256(0L,0L,319L<<12,199L<<12,31); +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/11/95 - Made drawline256 draw in a cleaner way, making use of the full + 12 bits of precision. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/14/95 - Optimized / cleaned up parts of hitscan, neartag, cansee. + Gee, I hope they all still work! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/18/95 - I'm back in RI! + + - Fixed recently added movesprite z parameter bug that may have + done strange things with monsters, such as stuck in sectors + I thought the following expression: !(cstat&128) + would be true if bit 7 was a 0, but I WAS WRONG! + Get this straight: + ! - logical NOT, returns 0 if != 0 else 1 (!2457=0, !0=1) + ~ - bitwise NOT, xor's it with 0xffffffff (~0x5f=0xa0) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/21/95 - Gave access to some more variables in BSTUB. + + - Made clipmove return a valid sector even if you're not between + its ceiling and floor. If you use overlapping sectors, + clipmove will find the sector closest to your z. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/28/95 - Optimized transluscence for masked walls and wall sprites. + + - Today is the day I declare my serial/modem error correction code + perfect! Sure, I may have bragged over and over again about + how perfect my correction method is each time, but this time + I mean it. This is ship-it quality error correction. The old + method had a few dark, evil, and ugly bugs that sometimes + totally screwed up bigtime. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/5/95 - Got Master/Slave switching to stay in sync again with new + multiplayer code. Right after the master sends a packet + where a switch is made, I disable the master from sending + any more packets by setting ready2send to 0. Ready2send + will be set back to 1 only after the actual switch in + checkmasterslaveswitch. Here's what I added to movethings: + + //Do this for Master/Slave switching + for(i=connectpoint2[connecthead];i>=0;i=connectpoint2[i]) + if (syncbits[i]&512) ready2send = 0; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/10/95 - Optimized continuous setview calls between 2 different window + sizes. + + - ATTENTION PROGRAMMERS: Moved movesprite code into game.c. It + no longer exists in the engine. It is a "cover-up" function + and it should be yours. + + - Added a circular keyboard buffer to my keyboard handler. It is + fully compatible with the keystatus arrays. Use this buffer + for typing in messages or cheat codes. If you do not use this + buffer (or you wrote your own interrupt handler), you will miss + keys and it is very annoying. + + I added these variables to build.h: + + #define KEYFIFOSIZ 64 + EXTERN volatile char keyfifo[KEYFIFOSIZ], + keyfifoplc, keyfifoend; + + Every time a key is pressed and released, I add 2 bytes to the + circular buffer. The first byte is the scan code. The second + byte is a 1 for key pressed or 0 for key released. You can + ignore the key releases if you wish. You must read 2 bytes at + a time from this buffer. + (scancode,keystat),(scancode,keystat),... + + Here's how you read the keyboard fifo: + while (keyfifoplc != keyfifoend) //More characters to read + { + ch = keyfifo[keyfifoplc]; + keystate = keyfifo[(keyfifoplc+1)&(KEYFIFOSIZ-1)]; + //Increment buffer pointer + keyfifoplc = ((keyfifoplc+2)&(KEYFIFOSIZ-1)); + + printf("Scancode: %d, status: %d\n",ch,keystate); + } + + The interrupt handler does the same as above but writes and + increments using keyfifoend as the index. + You can easily clear the buffer this way: + keyfifoplc = keyfifoend + + - Made clipmove/getzrange not clip on the back side of a 1-sided + wall/floor sprite. It makes the clipping a little faster + and seems to fix a few minor clipping bugs. Don't get too + excited. + + - Fixed getzrange's ceilz/florz mismatch with floor sprites against + normal ceilings and floors. + + - Made Build default to y-centered centering mode when sprites + are inserted (bit 7 of sprite[].cstat) + + - Fixed clipmove bugs with y-centered centering mode. + + - Made it so you don't get stuck sliding along multiple properly + aligned wall/floor sprites. + + - Please update to my new tables.dat. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/11/95 - Optimized parts of clipmove / getzrange. Is it faster? Did I + make more bugs? + + - Made the movesprite code in GAME.C now use getzrange. This + allows sprites to walk on floor sprites and bombs roll across + bridges. I will include the original movesprite code that + came from the engine in case you want to start with things + the way they used to be. + + - Made ornamentation in BUILD 3D mode much easier. Now you can + press 'S' to insert a sprite on walls (not just ceilings + and floors). When you insert a sprite on a wall, it will + automatically be set to a wall sprite at the wall's angle. + Also it will be 1-sided with blocking off (The optimal + options for a decorative sprite on a wall). + + - Added ALT-D to BUILD 3D mode. It lets you type in clipdist + for sprites. It works in the same way as ALT-P for palookup + changing. + +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/15/95 - Fixed return value bug in setanimation and cleaned up these 3 + functions: doanimations, getanimationgoal, setanimation. + Since they are now in game.c, you will need to copy them to + update. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/16/95 - Fixed hitscan not passing through loops bug. + + - Fixed hitscan so it hits wall and floor sprites in the right + places. + + - ATTENTION PROGRAMMERS!!! Made bit 8 of sprite[].cstat the + hitscan clipping bit. It works like the hitscan bit for walls. + Note that both the wall and sprite cstat variables now have + 2 separate bits for clipping, where: + 1 is for use with the clipmove/getzrange function and + 1 is for use with the hitscan function only. + Before, hitscan used to use 1 bit for all sprite clipping. + In your maps, the sprite hitscan bits are all zeros. That's bad! + To make things work like they used to, the sprite hitscan bit + must be set equal to the old sprite blocking bit. So I was nice + enough to make a program, FIXSPRBT.EXE, which will do just that. + + PLEASE RUN FIXSPRBT.EXE ON ALL YOUR MAPS. You don't HAVE to + run it on all your maps since the map format hasn't changed, but + it will save you annoying attribute setting time if you do. + + - Did a few things to make these blocking bits easier to edit: + Since H and ALT-H were already used, I made CTRL-H toggle the + hitscan bit for both walls and sprites in 2D mode. B toggles + the blocking bit. B also now sets the hitscan bit to its + default value when you press it. For sprites, the hitscan bit + default is equal to the clipmove bit. For walls, the hitscan + bit default is always 0. + + - Added new map mode! Check it out in my game. I now have 3 map + modes. Not that this really matters to you game programmers, but + this is how my game works: + dimensionmode[snum] == 1 3D MODE + junky line map + dimensionmode[snum] == 2 SUPER MAP! + dimensionmode[snum] == 3 3D MODE + + I added show2dsector to BUILD.H which controls which works + like the other show2d... bit arrays. It tells which sectors + to show. + EXTERN char show2dsector[MAXSECTORS>>3]; + + I rewrote parts of drawoverheadmap to accommodate this new + mode - so it would be nice if you updated to my new code. + + Added a new function that clears full screen to a specified + color: + clearview(0L); + + Oh and did I forget to mention the big function! Parameters + are the exact same my drawoverheadmap function: + drawmapview(cposx,cposy,czoom,cang); + + Note: The new map mode right now is slowed down bigtime by + the face sprites using the rotatesprite function. The + rotatesprite right now is using a worse than awful + algorithm. When I optimize rotatesprite, the frame rate + of the new map mode will fly! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/18/95 - Added default sprite cstat variable when you insert new sprites. + Set it to 0 if you hate the new centering mode in ExtInit + or 128 if you like the new centering mode. + Add this line to your Bstub if you wish: + extern short defaultspritecstat; + + - If a wall & sprite are same distance away using hitscan, hitscan + now chooses the sprite. + + - Optimized rotatesprite. + + - ATTENTION PROGRAMMERS: Added new paramater at end of + rotatesprite: A char where the first bit tells it to use + transluscence mode or not. + + rotatesprite(long sx, long sy, long z, short a, short picnum, + signed char dashade, char dapalnum, char dastat) + + if ((dastat&1) == 0) - no transluscence + if ((dastat&1) != 0) - transluscence + + - Cleaned up drawmapview further by making ALL floor sprite draw + with the texture in the right place and made the polygon + filling algorithm use higher screen coordinate precision. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/19/95 - Added parameter to makepalookup: + + makepalookup(long palnum, char *remapbuf, + signed char r, signed char g, signed char b, + char dastat) + + if ((dastat&1) == 0) then makepalookup will allocate & deallocate + the memory block for use but will not waste the time creating + a palookup table (assuming you will create one yourself) + if ((dastat&1) != 0) then makepalookup will allocate & deallocate + the memory block AND create a palookup table using the rgb + values you pass. + + - Made my ceiling&floor update the self-modified palookup pointers + when palookup[sector[].?pal] changes, not just when + sector[].?pal] changes. Watching for changing pointers rather + than changing indeces should solve the problem with screwy + palookup selection for ceilings&floors. Ignore what I said + before. You should now be able to change palookup pointers + freely. + + - Optimized relative alignment. It should be the same speed as + all other ceilings & floors now. + + - Warning: Since I added the new bit in sprite[].cstat, there are + now 9 bits in use. Make sure to treat it as a short. In my + code, I had some bugs where I did this: + sprite[].cstat &= (255-4); BAD! Cstat's a short! Please + check your code and make sure you clear the bits this way: + sprite[].cstat &= ~4; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/21/95 - Fixed bug with flipping textures on ceilings & floors. In + BUIL0419.ZIP I had a bug whenever a ceiling or floor texture + had bit 4 set. It drew the texture backwards. Well, I + fixed it. Hope you didn't "Build" on this bug! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/22/95 - Fixed really really stupid hitscan returning sector < 0 bug. If + you were calling hitscan from the top-left triangular region + of the board it stupidly returned a -1 for the sector. Well, + I fixed it. + + - ATTENTION EVERYBODY!!! Moved setup.dat loading from the engine + into GAME.C and BSTUB.C. If you copy this code from game.c + into your game / bstub, they will work like it used to: + + ----- NEW GLOBAL VARIABLES: ----- + + #define NUMOPTIONS 8 + #define NUMKEYS 19 + static long chainxres[4] = {256,320,360,400}; + static long chainyres[11] = {200,240,256,270,300,350, + 360,400,480,512,540}; + static long vesares[7][2] = {320,200,640,400,640,480, + 800,600,1024,768, + 1280,1024,1600,1200}; + static char option[NUMOPTIONS] = {0,0,0,0,0,0,1,0}; + static char keys[NUMKEYS] = + { + 0xc8,0xd0,0xcb,0xcd,0x2a,0x9d,0x1d,0x39, + 0x1e,0x2c,0xd1,0xc9,0x47,0x49, + 0x9c,0x1c,0xd,0xc,0xf, + }; + + ----- Put this where you call initengine ----- + + long fil; + + if ((fil = open("setup.dat",O_BINARY|O_RDWR,S_IREAD)) != -1) + { + read(fil,&option[0],NUMOPTIONS); + read(fil,&keys[0],NUMKEYS); + close(fil); + } + if (option[3] != 0) moustat = initmouse(); + + switch(option[0]) + { + case 0: initengine(0,chainxres[option[6]&15],chainyres[option[6]>>4]); break; + case 1: initengine(1,vesares[option[6]&15][0],vesares[option[6]&15][1]); break; + case 2: initengine(2,320L,200L); break; + case 3: initengine(3,320L,200L); break; + case 4: initengine(4,320L,200L); break; + case 5: initengine(5,320L,200L); break; + case 6: initengine(6,320L,200L); break; + } + + ----- That's it! ----- + + Initengine now has 3 parameters: + initengine(char davidoption, long daxdim, long daydim) + See revised initengine description at the top of this file. + + Now that engine.c doesn't use setup.dat, you can use your + own setup program. + + Don't forget to update BSTUB! + + NOTE!!! While MY setup program allows you select many different + video modes, no new modes are supported yet in BUILD! + (It's on my list.) + + + - Fixed keyboard repeating. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/26/95 - Hi-res now works in all modes! The code I gave in the 4/22/95 + description is still perfectly valid, so please copy it if + you haven't already looked at it. Here are some important + new variables I put in BUILD.H: + + EXTERN char vidoption; + EXTERN long xdim, ydim, ylookup[MAXYDIM+1]; + + Vidoption is simply the first parameter you pass to + initengine. Xdim and Ydim are the screen sizes you pass to + initengine, such as 320*200 or 640*480. + Ylookup is a lookup table that works like this: + If (vidoption == 0) ylookup[i] = ((i*xdim)>>2); + if (vidoption != 0) ylookup[i] = i*xdim; + There is 1 exception: If you are using a chained mode which + can only fit only 1 viewing page, then the engine actually + does a screen-buffer mode and blits to the chained screen + so for this case, ylookup[i] = i*xdim. + + - Added bit to the dastat parameter of rotatesprite. + if ((dastat&2) != 0) - align to screen size so the gun or + whatever is always over the same relative spot of the screen. + Works like bit 2 of the flags parameter in overwritesprite. + + - Added pixel writing and reading that will work in all BUILD + graphics modes. They work just like you think they should. + + plotpixel(long x, long y, char col); + char getpixel(long x, long y); + + Please do not overuse these functions! They are NOT intended + for fast drawing! + + - Changed tables.dat so parallaxing skies at high resolutions + work accurately. + + - I made bit 15 of sprite[].cstat the invisible bit. If it is + set, then the sprite won't even be considered for sorting and + there is absolutely no speed loss due to its existence. It is + faster to use this bit then manually set thesprite[] to -1. + + Since drawrooms collects the list of sprites drawmasks is about + to sort, make sure the bit is set before drawrooms. If you use + frame interpolation, you usually want to tell drawmasks somehow + to not draw yourself. Before you used to use the + thesprite[] = -1 trick. Now you do it like this: + + sprite[i].cstat |= 0x8000; //Set invisible bit + drawrooms(posx,posy,etc.); + sprite[i].cstat &= ~0x8000; //Restore invisible bit + + - Fixed distance overflow bug (the one that showed garbage + textures if a wall was really far away). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/27/95 - Made an example board, MONWALK.MAP, where monsters walk along + a bridge with no railing, onto a sector, and even up and down + a stairway without falling off it. If you shoot a brown so + it's almost dead, it will turn transluscent. If it's + transluscent, it won't shoot bullets. It is much easier to + test the monsters' walking when they don't shoot! + + - Try my new and improved fake network player mode! Each fake + network player now gets their own window. Use insert and + delete to add or remove players. Use Scroll lock to switch + which window you control. If you have a Pentium, I would + recommend trying this out in 640*480 mode. + + - Noticed a bug with my movesprite code: + For clipmove, I was getting the z-coordinate right, but for + getzrange I forgot to subtract half the sprite's height if + the sprite was using the real centered centering mode. + + These lines set daz to the actual center of sprite i no matter + what centering mode is used: + + daz = sprite[i].z; + if ((sprite[i].cstat&128) == 0) + daz -= ((tilesizy[sprite[i].picnum]*sprite[i].yrepeat)<<1); +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/28/95 - ATTENTION PROGRAMMERS! When a tile is not in the cache: + Before it used to be this: + + if (waloff[tilenum] == -1) loadtile(tilenum); + or + if (waloff[tilenum] < 0) loadtile(tilenum); + + Now it's this: + + if (waloff[tilenum] == 0) loadtile(tilenum); + + PLEASE MODIFY YOUR CODE IF YOU USE WALOFF! + + Windows can allocate memory with addresses so high, they + are negative. That makes the (waloff[tilenum] < 0) + method totally stupid and attempt to reload from disk + the tile constantly! I can think of 3 reasons why I + originally designed my system in this fashion: + mestupid, mestinx, and merottts. + + - Fixed visibility for different screen sizes. + + - ATTENTION PROGRAMMERS! Now multiply by visibility rather than + shift right by visiblity so you get a broader range of + visibility. If you want the visiblity to work like before, + use this conversion table: + + Old visibility New visibility + 8 -> 16384 + 9 -> 8192 + 10 -> 4096 + 11 -> 2048 + 12 -> 1024 + 13 -> 512 + 14 -> 256 + 15 -> 128 + + - Made Alt-F make the selected wall the first wall of a sector. + This is useful for quick relative alignment adjustments. + Alt-F for 2D and 3D modes may not work for sectors with loops + inside of them. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/1/95 - Optimized horizontal line setup code from 9 multiplies to + 7 multiplies. + + - Fixed dark vertical lines in parallaxing skies bug I recently + introduced. + + - Optimized horizontal line assembly code so it doesn't use the + awful SHLD instruction any more. This is a good speed + improvement for Pentiums only. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/2/95 - Added some code to my GAME.C which detects when a computer gets + out of sync in a multiplayer game. It's not as easy as you + may think with all the faketimerhandler and fifo crap. If + you want to put this code in your game, search all areas in + my code with the keyword "syncval". + + - Fixed palookup crashing bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/6/95 - Moved windowx1, windowy1, windowx2, windowy2 variables into + BUILD.H. They are the exact parameters you passed to the + last setview call. Please DO NOT modify them directly. + Use setview to modify them. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/10/95 - Fixed makepalookup bug when shading to non 0. + + - Fixed palookup pointer setting bug. + + - ATTENTION PROGRAMMERS! I made a new cacheing system which allows + any type of object to be allocated in my cache, such as + artwork tiles and sounds or whatever else you may want to + put on the cache. This may or may not affect you. If you + haven't been hacking into my code, then you shouldn't have to + change your code. The cacheing routines have been moved into + a separate module, cache1d.obj. If you link engine.obj, then + you must also link cache1d.obj. Please update your makefiles. + + For anybody who may want to re-write my cacheing system, here's + how it now works: (I have only 3 functions in cache1d.obj + right now, initcache, uninitcache, and allocache) + + Allocate a nice BIG buffer, like from 1MB-4MB and + call initcache(long cachestart, long cachesize) where + + cachestart = (long)(pointer to start of BIG buffer) + cachesize = length of BIG buffer + + Ex: initcache(FP_OFF(pic),cachesize); + + Loadpics calls this function for you so you don't normally + need to call it. + + call allocache(long ptr, long siz) whenever you need to + allocate a temporary buffer, where + + ptr = (long)(pointer to (4-byte pointer to thing))\ + siz = number of bytes + + Ex: if (waloff[tilenume] == 0) + allocache((long)&waloff[tilenume],walsiz[tilenume]); + + Allocache is totally tile independent. To allocate a sound + on the cache, you can call allocache. + + There are 3 functions in the engine which help manage the + cache for you: loadpics - calls initcache + loadtile - calls allocache + allocatepermanenttile - special function + that allocates permanent memory + from the cache. + + - Fixed clipmove crashing bug when passing a sectnum < 0. Whenever + you moved in BUILD and you weren't in a valid sector, memory + was getting trashed. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/12/95 - Added ExtPreCheckKeys(void) to BSTUB.C. It is called before + drawrooms / drawmasks in 3D mode, whereas ExtCheckKeys(void) + is called after drawrooms / drawmasks (and before nextpage). + + - Added bit to flags of rotatesprite to allow x-flipping. See + updated documentation. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/17/95 - Added aspect ratio for those weird modes like 320*400, etc. + You could call setaspect to properly adjust a mode that is + not exactly correct, or for special effect that stretch + the screen. + + In ENGINE.OBJ, I added a function, setaspect(long daaspect), + where you pass the Y/X aspect ratio scaled up 16 bits, so + 65536 would be normal. You don't need to call this if you + don't want to. By default, in setview, I call setaspect + with these parameters: + + setaspect(divscale16(ydim*320,xdim*200)); + (also written as:) + setaspect(((ydim*320)<<16)/(xdim*200)); + + Note that in 320*200 mode the value passed would be 65536 + which is a 1:1 aspect ratio. + + In BUILD.H, I added yxaspect and xyaspect. + + When you call setaspect(daaspect), + + yxaspect = daaspect; + xyaspect = (1<<32) / yxaspect; //reciprocal + and other internal variables, so DON'T MODIFY YXASPECT + AND XYASPECT DIRECTLY! + + Since drawmapview is also affect by the aspect ratio, you + will need to make sure drawoverheadmap is affected so + the map modes match up. Please look at and copy my updated + drawoverheadmap function into your GAME.C if you use it. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/18/95 - Revised caching system so it supports locking. + Here are the new parameters to allocache: + + allocache(long *bufptr, long bufsiz, char *lockptr) + *bufptr = pointer to 4-byte pointer to buffer + bufsiz = number of bytes to allocate + *lockptr = pointer to 1-byte locking char. 1=locked, 0=not + + And uninitcache works a little differently too: + Call uninitcache(0) to remove all UNLOCKED items or + Call uninitcache(1) to remove ALL items. + After calling uninitcache, you do not need to call + initcache to use the cache again. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/21/95 - Made changespritesect and changespritestat return 0 instead of -1 + when changing to same value. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/25/95 - Added relative visibility for sectors. In 3D EDIT MODE, use + ALT+(keyp.)+/- to change an individual sector's visibility. + Press Shift in addition for fine visibility changine. By + default you change it by 16. Press CTRL+ALT+(keyp.)+/- to + change the global visibility. The global visibility is not + saved in the map. + + - Can now delete many sectors at a time. Select sectors with the + rt. Alt. Then press Ctrl-delete on any highlighted sector to + delete all the highlighted sectors. + + - Fixed build sometimes not saving when quitting from 2D mode bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/27/95 - Fixed bugs in network work that should make it miss packets + much less often than before. + + - Fixed bug in ncopy so it shouldn't halt or crash anymore. + + - Added spritecstat[] the thesprite arrays. Please use my + thesprite arrays rather than modifying the sprite directly + since hitscan and clipmove use bits 4 and 8 of sprite[].cstat. + + - ATTENTION PROGRAMMERS: Added 1 parameter to neartag that will + allow you to search only lotags or only hitags. See updated + documentation above. + + neartag (long xs, long ys, long zs, short sectnum, short ange, + short *neartagsector, short *neartagwall, short *neartagsprite, + long *neartaghitdist, long neartagrange, char tagsearch) + + If tagsearch = 1, neartag searches lotag only + If tagsearch = 2, neartag searches hitag only + If tagsearch = 3, neartag searches lotag&hitag + + Neartag used to always search both lotag&hitag. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/30/95 - Added ExtAnalyzeSprites(void) to BSTUB and a spriteshade array + to BUILD.H. + + - Made circle drawing in 2D EDIT MODE work better at large sizes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/5/95 - Added shareware / registered artwork version control to EDITART. + In 'V' mode, when you press ALT-R to get a report of tile + frequencies of tiles on all the maps in the current directory, + you can toggle the shareware/registered bit with the space bar. + This bit is saved in the top bit of the picanm bits so it is + stored permanently in the art file. Press ALT-D in this mode + to automatically delete all registered tiles. Please before + you do the deleting phase, copy all artwork to a temporary + directory!!! It is safe, however, the toggle the new bit in + the full version. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/7/95 - Made 3 main structures defined with typedef so struct prefix + is no longer needed with sectortype, walltype, and spritetype. + + - Added new function to engine: + + short sectorofwall(short dawall); + + It returns the sector of a given wall. It is well optimized + including sector[sector[].nextwall].nextsector if a red wall + and a binary search on the sector[].wallptr's if it is a + white wall. On average, sectorofwall should have to scan + through only 10 different sector indeces to find the right + sector (not 1024!). + + - ATTENTION PROGRAMMERS! Made all the separate thesprite arrays + into a single array of sprite structures call tsprite. See + BUILD.H!!! This means: + + spritepicnum[i] is now tsprite[i].picnum + spritex[i] is now tsprite[i].x + spritey[i] is now tsprite[i].y + spritez[i] is now tsprite[i].z + spriteshade[i] is now tsprite[i].shade + spritecstat[i] is now tsprite[i].cstat + spritepal[i] is now tsprite[i].pal + thesprite[i] is now tsprite[i].owner <<<============ + + Everything above is straight forward, except for thesprite, + which has been renamed to owner. + + All other tsprite parameters, such as .xrepeat, .yoffset, + etc. can also be modified without changing the real + sprite structure so the game won't out of sync. + + - Made tsprite[].statnum be a priority variable for sorting sprites + that are the exact same distance from you. I think higher + means more in front. + + - Made clipmove allow you to cross any red sector line when the z's + of the next sector are farther apart. This may solve clipping + bugs such as when you're in water. You may be able to remove + some work-arounds you may have programmed previously. + + - NEW FILE GROUPING SYSTEM!!! + My system will first search for the stand-alone file in the + directory. If it doesn't find it, then it will search for it + in the group file. If it still doesn't find it then -1 city. + Use KGROUP.EXE to create a grouped file from a lot of other + files. Type KGROUP [grouped filename][filespec][filespec][...] + For example this line will create the new grouped file, + stuff.dat, including all the following files specified: + kgroup stuff.dat *.art *.map tables.dat palette.dat + Feel free to make your own batch files. If there is demand, + I can make kgroup support appending, replacing, and extraction. + + Here is the file format of a grouped file: + ÚÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ + ³ 12 bytes - File grouping ID ³ + ³ 4 bytes - Number of files ³ + ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ + ³For each file: (16 bytes per file) ³ + ³ 12 bytes - Filename with extension (13th byte would be a 0) ³ + ³ 4 bytes - Length of file ³ + ÃÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ´ + ³ Pure, raw file data, ordered just like you think it would be ³ + ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ + There just couldn't be a simpler format. This format is so + hacker happy that when you view it in a hex editor, all the + filenames line up perfectly since they're multiples of 16. + Anybody who can't figure this out, of course, not only rots, + but is probably one of those really stupid people who would + actually "pay" to get the full version of a game. + + The engine currently supports grouping for: + *.ART, *.MAP, TABLES.DAT and PALETTE.DAT. If you want + to group your own files, you will have to use my loading + routines rather than the standard ones for those files. My + file routines are basically an extra layer around the standard + lo-level functions. Look at these 5 routines I currently + support: + + Welcome to the K-routines! + open -> kopen4load(char *filename) + read -> kread(long handle, void *buffer, long leng) + lseek -> klseek(long handle, long offset, long whence) + filelength -> kfilelength(long handle) + close -> kclose(long handle) + + Note that you only pass the filename to my kopen4load function. + + Here are 2 other routines that you MUST use, whether you like + my file grouping system or not: + + initgroupfile(char *groupfilename) + Call this with the name of your grouped file before + any possible file loading will the k-routines. Note that + tables.dat uses the k-routines and it is in initengine(). + Please don't give your grouped filename an extension that + starts with W, ends with D, and has a vowel in between. + And don't even bother to write your own file grouping + system because even if you do, people still have to write + their own new utilities to read the ART and MAP files. + + uninitgroupfile() + Call before quitting to DOS. + ------------------------------------------------------ + - ATTENTION PROGRAMMERS! Changed kopen4load from: + + kopen4load(char *filename) + to: + kopen4load(char *filename, char searchfirst) + + where: + if searchfirst = 0 then search stand alone first then group file + if searchfirst = 1 then search group file only +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/12/95 - Tracked down an OUT OF SYNC bug with my multiplayer code! + In my GAME.C, the way I had my sync arrays organized were + wrong. The problem was that if faketimerhandler was + called during domovethings, the sync arrays may have been + changed, getting the game out of sync. The solution is + to keep the sync arrays in domovethings totally separate + from the sync arrays in faketimerhandler. I split my sync + arrays into 2 separate arrays, sync and fsync, where fsync + and osync are for use BEFORE the FIFO only (such as + faketimerhandler and getpackets), and sync is used AFTER + the FIFO only (such as domovethings). PLEASE SPLIT YOUR + SYNC ARRAYS AS I DESCRIBED! + + - The OUT OF SYNC message doesn't flicker any more. See the + section of code in GAME.C where I set syncstat. + + - Fixed up a waitforeverybody function for network games which + waits for everybody to be at a certain part of the game. + Waitforeverybody also uses getpackets message number 5. + + - Added new clipping function that will push players away from + walls that are too close. It solves A LOT of movement + clipping problems. It can be pretty darn slow if it detects + that you're too close to a wall, so I'd recommend using it + only for players. + + pushmove (long *x, long *y, long *z, short *sectnum, + long walldist, long ceildist, long flordist, char cliptype) + + The parameters are exactly the same as clipmove but with no + xvect or yvect. Pushmove returns either a 0 or -1. If + it returns a -1, then that means that it could not push + the player away from the offending wall after 256 tries. + When this happens, then you should kill the player + instantly, because this only happens when the player is + getting smooshed. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/13/95 - Made clipinsidebox and clipinsideboxline return 0 if line doesn't + intersect box, 1 if line intersects box and center of box + is in front of line, or 2 if line intersects box and center + of box is behind line. + + - Cansee should now work properly with overlapping. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/19/95 - ATTENTION! Remove work-arounds!!! Found nasty getzrange bug. + Getzrange used to let you fall through red sector line cracks + when you were near more multiple red sector line sharing the + same 2 sectors. Sound familiar anybody? + + - Made pushmove return the sector of whatever x and y end up in. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/22/95 - I included cache1d.c renamed to cache1d.txt in this upload. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/26/95 - Made face and wall sprites of clipmove, getzrange, hitscan, and + neartag sensitive to the y-offset that you set in Editart. + + - Made one sprite sorting case work perfectly: where multiple + sprites have the same x and y location (and priority). The + sorting still doesn't work perfectly, but this one case can + solve many of the current sprite sorting bugs, such as + inserting a floor sprite of blood below a dead body. + + - Fixed some sprite drawing clipping bugs for wall and floor + sprites. Now, wall sprites and floor sprites should not + show through walls, ceilings, or floors when they're not + supposed to. Also, I fixed a case where wall sprites + disappeared when they happened to be between 2 white walls + that clipped it. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/27/95 - Fixed even more sprite drawing clipping bugs for wall sprites. + + - BONUS!!! Wall sprites now clip to white walls! (not red walls) + If you ornament a wall, make sure that neither endpoint of the + wall sprite is behind the wall or else it will get clipped. + Please run lookatme.map from my game.exe which demonstrates + some of the things you can do in build now without bugs. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/30/95 - Made drawline256 clip with startumost/startdmost. + + - Moved keyboard handler into GAME.C. Here's what you need to do + to use my keyboard handler (see my GAME.C): + + 1. Some global variables: + + #define KEYFIFOSIZ 64 + void (__interrupt __far *oldkeyhandler)(); + void __interrupt __far keyhandler(void); + volatile char keystatus[256], keyfifo[KEYFIFOSIZ]; + volatile char keyfifoplc, keyfifoend; + volatile char readch, oldreadch, extended, keytemp; + + 2. initkeys() + + 3. uninitkeys() + + 4. keyhandler() + + 5. Make sure to call initkeys and uninitkeys. A good place + would be next to where you call inittimer / uninittimer. + + I didn't put my keyboard handler into BSTUB since I am using + keystatus throughout build.obj. Besides I didn't want to anybody + too bad of a headache for one upload. + + - Did you know that screencapture inverses black and white if you + hold either shift key down? This option is useful for + printing out board maps. Since I don't own the keyboard + any more, I had to make screencapture take inverseit as the + second parameter. + + screencapture(char *filename, char inverseit); + + Ex: screencapture("captxxxx.pcx",keystatus[0x2a]|keystatus[0x36]); + + If (inverseit == 0) then nuttin' special + If (inverseit == 1) then super-reverso blacko-whiteo mode! + + I also had to move the stereo adjustment keys into game.c + Just search for the "stereo" keyword in GAME.C. It'll take + through all the necessary places. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/5/95 - Moved my keytimerstuff from my timerhandler into getinput. + (which is where it should be) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/10/95 - Added a loadtilelockmode variable to BUILD.H. It's a global + variable that makes future loadtile calls allocate their + buffers on the cache as unlocked (0-default) or locked (1). + I decided to make this a global variable rather than a + parameter to save some people from rewriting code. + + EXTERN char loadtilelockmode; + + - Made my 2D EDIT MODE space bar code clear out new sectors and + wall structures to 0. (except for the extras which are -1) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/20/95 - I forgot to documenent rotatesprite bit 3, which controls + whether or not the sprite will be clipped to the startumost + /startdmost arrays. If the bit is a 1, then the sprite will + not be clipped. This mode is useful for doing status bars + at variable resolutions. What you do is instead of calling + permanentwritesprite, you call rotatesprite with the scaling + bit and startumost/startdmost clipping bit off. For non + screen-buffer modes, be sure to call rotatesprite for each + page of the mode. Use the numpages variable in BUILD.H to + get the number of video pages used. + + - Added clipping box parameters to rotatesprite: Here is the + prototype now: + + rotatesprite (long sx, long sy, long z, short a, short picnum, + signed char dashade, char dapalnum, char dastat, + long cx1, long cy1, long cx2, long cy2) + + For your information, rotatesprite used to choose default + clipping box sizes using this code: + + if ((dastat&8) == 0) + { //0,0,xdim-1,ydim-1 + cx1 = windowx1; cy1 = windowy1; + cx2 = windowx2; cy2 = windowy2; + } + else + { + cx1 = 0; cy1 = 0; + cx2 = xdim-1; cy2 = ydim-1; + } + + Now both permanentwritesprite and overwrite can both be + replaced with rotatesprite which now does everything. + To replace permanentwritesprite, you must make sure to + draw to all the pages in numpages. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/27/95 - Fixed recently introduced build 3D mode bug when you press the + L.ENTER key on a blank map. Also made sectorofwall return -1 + if an invalid wall is passed to it. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/28/95 - Added a function to my game that shows only the local area of + the map by scanning through the nextsectors of walls and + setting the show2dsector, show2dwall, and show2dsprite + arrays properly. You should call this function any time + (show2dsector[cursectnum>>3] & (1<<(cursectnum&7))) == 0) + That means it's not showing the sector you're currently + in. You should also manipulate show2dsprite any time you + insert or warp a sprite. + + - You know the one thing in my engine that doesn't work in chained + mode? Well I fixed it! + + - Fixed a bug which made it print out of sync when it really + wasn't (This bug probably only affecting my game.) In + getsyncstat, I was calling updatecrc16() with things other + than chars, making it index invalid parts of the crctable + array. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/30/95 - Reduced some overhead memory: + * Removed walsiz[] array. (16K saved). If you ACTUALLY used + this array, you can multiply tilesizx[]*tilesizy[] instead. + * Made sqr table from longs to shorts with same precision. + * Removed tantable. (4K saved) + * Reduced internal constant, MAXWALLSB, from 4096 to 2048 + (96K saved). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/1/95 - Added another bit to rotatesprite for top-left corner mode and + made documentation of the stat bits more clear. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/3/95 - Fixed a bug with rotatesprite so it now scales perfectly to the + full screen view when enabling bits 2 and 8 of the stat field. + This means that with rotatesprite, you can easily get your + status bars, etc., to work at any resolution. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/4/95 - New Doom->Build update! You can now convert doors and lots of + other weird things. Fixed more conversion bugs. Sprites now + convert properly in doom-artwork mode. You can now convert + PWADS. + + - Added some wacky aspect ratio keys to 3D EDIT MODE of BUILD. + Use Rt.Ctrl Rt.Alt Lt.- or Rt.Ctrl Rt.Alt Lt.= to select. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/12/95 - Added parameter to initmultiplayers to allow who becomes + master at the start of a multiplayer game. + + - Added parallaxyscale variable to BUILD.H which control the ratio + at which the parallaxing skies scroll in relation to the + horizon. Default is 65536. With lower values, you don't + need as much artwork and can look higher, but I like 65536 + because it is the correct projection. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/13/95 - Had MAJOR bug with my searchmap function. If you use it, please + re-copy from my game.c +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/14/95 - Fixed some EVIL bugs with Rt.ALT sector copying. It shouldn't + screw up your maps anymore! And if you have maps that were + screwed up with it, you can try my new map correcting key, + L.Ctrl+L.Shift+L.Enter. This key will not affect an already + perfect map. However it can SOMETIMES clean up a map that + was screwed up. I take no responsibility if it screws up + your map even more, so please check them before saving! diff --git a/polymer/build/doc/build2.txt b/polymer/build/doc/build2.txt new file mode 100644 index 000000000..2f5819acc --- /dev/null +++ b/polymer/build/doc/build2.txt @@ -0,0 +1,1655 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. + +BUILD engine Notes (7/24/96): + +BUILD programmed by Ken Silverman + +BUILD.TXT CONTINUED... (BUILD.TXT WAS GETTING TOO BIG!!!) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/12/95 - Added parameter to initmultiplayers to allow who becomes + master at the start of a multiplayer game. + + - Added parallaxyscale variable to BUILD.H which control the ratio + at which the parallaxing skies scroll in relation to the + horizon. Default is 65536. With lower values, you don't + need as much artwork and can look higher, but I like 65536 + because it is the correct projection. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/13/95 - Had MAJOR bug with my searchmap function. If you use it, please + re-copy from my game.c +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/14/95 - Fixed some EVIL bugs with Rt.ALT sector copying. It shouldn't + screw up your maps anymore! And if you have maps that were + screwed up with it, you can try my new map correcting key, + L.Ctrl+L.Shift+L.Enter. This key will not affect an already + perfect map. However it can SOMETIMES clean up a map that + was screwed up. I take no responsibility if it screws up + your map even more, so please check them before saving! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/16/95 - Added error correction to mmulti.obj. Mmulti.obj is like + multi.obj but it is made to work with Mark's real mode + multiplayer driver that he calls COMMIT. + + + MMULTI.OBJ vs. MULTI.OBJ: + * initmultiplayers is the same, but the parameters are ignored + * uninitmultiplayers can be called but does nothing. + * sendlogon can be called but does nothing. + * sendlogoff sends packet 255 to everybody else. It does not + need to be called any more. + * sendpacket and getpacket are the same. + * connecthead, connectpoint2[], numplayers, myconnectindex + are the same. They can be externed just like before. + * getoutputcirclesize always returns 0. It is not needed. + * setsocket does nothing. The socket is now in commit.dat. + * crctable can still be externed. + * syncstate can still be externed but is not used. + * Do not use the option[4] variable. Initmultiplayers will + always return a valid number in numplayers from 1-16. + + + You can link mmulti.obj in place of multi.obj and use + commit.dat as the setup file for multiplayer options. + + There are 2 ways you can run your game through commit: + 1. Set the launch name (usually game.exe) in commit.dat + and type something like "commit map01 /asdf" + 2. Type "commit launch game map01 /asdf". This method + is easier if you want to use the debugger with commit + since you won't have to change commit.dat constantly. + Ex: "commit launch wd /tr=rsi game map01 /asdf" + + I have not tested mmulti.obj with my BUILD game yet because + I have been using 2DRAW as my test program. I may put up a + new version of mmulti.obj with better error correction for + extremely error-prone lines soon. + + - Kgroup can now accept a parameter as a filename with a list of + files to be put into the group file. + Ex: "kgroup @filelist.txt" +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/18/95 - Found a way to greatly reduce slave "hitching" on multiplayer + games for faketimerhandler style communications. It's pretty + simple. + + Step 1: In the beginning of faketimerhandler, change + + ototalclock = totalclock; + TO: + ototalclock += TICSPERFRAME; + + This makes the timing of the game more constant and to + never miss ticks. I should have done this in the first + place all along. + + Step 2: In getpackets, (for slaves only) count the number of + times movethings is called. Normally, movethings should + be called exactly once for every time getpackets is called + inside faketimerhandler. The hitching is because + movethings is called in a 0-2-0-2-0-2 cycle instead of the + standard 1-1-1-1-1-1 cycle. This happens because the + timers of the 2 computers are aligning in such a way that + the slave is receiving the master's packets at nearly the + same time as it calls getpackets. To correct the problem, + if movethings is called an even number of times, I randomly + add or subtract (TICSPERFRAME>>1) to ototalclock. Throw + this code at the end of getpackets: + + Beginning of getpackets: + movecnt = 0; + + Where slave receives buffer in getpackets, next to movethings: + movecnt++; + + End of getpackets: + if ((myconnectindex != connecthead) && ((movecnt&1) == 0)) + { + if (rand()&1) ototalclock += (TICSPERFRAME>>1); + else ototalclock -= (TICSPERFRAME>>1); + } + + - Found a way to interpolate anything using the doanimations + code for faketimerhandler style multiplayer games. It's not + as hard as I thought it would be (and it doesn't waste too + much memory!) To smooth out doanimations, since there's no + temporary variables that can be thrown away like with tsprite, + the current doanimations positions must be backed up at the + beginning of drawscreen and restored at the end of drawscreen. + If you want smooth up&down doors, do this: + + Global declaration: + static long oanimateval[MAXANIMATES]; + + Beginning of drawscreen: + for(i=animatecnt-1;i>=0;i--) + { + oanimateval[i] = *animateptr[i]; //Backup doanimations interpolation + + j = *animateptr[i]; + if (j < animategoal[i]) + j = min(j+animatevel[i]*(totalclock-gotlastpacketclock),animategoal[i]); + else + j = max(j-animatevel[i]*(totalclock-gotlastpacketclock),animategoal[i]); + + *animateptr[i] = j; + } + + End of drawscreen: + //Restore doanimations interpolation + for(i=animatecnt-1;i>=0;i--) *animateptr[i] = oanimateval[i]; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/19/95 - Added global invisibility variable. Initengine sets it to 0 + by default. If you set global invisibility to 1, then + all sprites with the invisible bit set (sprite[].cstat&0x8000) + will be shown. This is useful for editing invisiblie sprites. + + - Made the hitscan blocking bit for sprites be the bit checked + when using cliptype 1 instead of the blocking bit. Before + I was accidently using the clipmove blocking bit on sprites + with cliptype 1. I should have done it this way in the first + place. I hope you haven't "built" around this bug too much! + Here's how everything works now: + + Clipmove blocking bits: + Which bits: + wall[].cstat & 1 + sprite[].cstat & 1 + Used in these cases: + clipmove when cliptype = 0 + getzrange when cliptype = 0 + + Hitscan blocking bits: + Which bits: + wall[].cstat & 64 + sprite[].cstat & 256 + Used in these cases: + clipmove when cliptype = 1 + getzrange when cliptype = 1 + hitscan always +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/20/95 - Reduced some overhead memory by combining 2 large internal + arrays which were used in different parts of the engine. + This is a total savings of about 90K. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/24/95 - Changed the way 'E' mode works on ceiling and floor textures. + 64*64 and 128*128 textures are the same as before so I think + this won't screw up your existing maps. (But I can never be + sure) Now, 'E' mode always smooshes the texture size by 2 for + any size texture. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/29/95 - ÜÛÛÛÛÛÛÜ ÛÛ ÜÛÛÛÛÛÛÜ ÜÛÛÛÛÛÛÜ ÜÛÛÛÛÛÛÜ ÜÛÛÛÛÛÛÜ ÛÛ ÛÛ ÛÛ + ÛÛ ÛÛ ÛÛß ßÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ ÛÛ + ßÛÛÛÛÛÛÜ ÛÛ ÛÛ ÛÛ ÛÛÛÛÛÛÛß ÛÛÛÛÛÛ ßÛÛÛÛÛÛÜ ÛÛ ÛÛ ÛÛ + ÛÛ ÛÛ ÛÛÜ ÜÛÛ ÛÛ ÛÛ ÛÛ ßß ßß ßß + ßÛÛÛÛÛÛß ßÛÛÛÛÛÛÛ ßÛÛÛÛÛÛß ÛÛ ßÛÛÛÛÛÛß ßÛÛÛÛÛÛß ÛÛ ÛÛ ÛÛ + + New 3D EDIT MODE BUILD keys: + Press [ or ] on a ceiling or floor to change the slope. + Shift + [ or ] on a ceiling or floor to adjust finely. + Press / to reset a ceiling or floor to slope 0. + Use Alt-F in either 2D or 3D mode to change the slope's hinge. + + Sector fields used for slopes: + The useless groudraw fields, ceilingheinum and floorheinum, + are now being used as the slope value. They are treated + as signed shorts, where 0 is slope 0, of course. To enable + slope mode, you must also set bit 1 of the ceilingstat or + floorstat bits. + + Known bugs: + There are still a few bugs that I haven't gotten around to + fixing yet. They're not necessarily hard to fix - it's just + that there are a lot of little things that need to be updated + (on my part). + + - Hitscan does not hit slopes correctly. + - Rare divide overflow bug in my wallmost function only when + you're very close to a red sector line of a slope. + - Relative alignment for slopes not yet programmed. Relative + alignment for slopes will allow square aspect ratio for all + slopes of slopes. + - ALT-F code with passing loops would be nice. + - Visibility not implemented for slopes yet. + - Sometimes an annoying tiny wall is drawn at sector lines. + + Don't call me to tell me about these bugs. I know about them. + And if I didn't list your favorite bug of the day, it will + probably be brought up by the 2 internal teams now working + with BUILD. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/4/95 - Made ALT-F select any wall of a sector, even crossing loops. + In 3D mode, ALT-F now sets the selected wall directly to the + first wall. + + - Fixes related to slopes: + * Relative alignment now works. Use relative alignment on high + slopes if you don't like the way the texture is stretched + out. + * Flipping now works + * Panning now works + * Fixed seams for SOME (not all) slope borders + + - My wonderful divide overflow bugs in wallmost aren't quite as + rare as they used to be. Wait a minute - I thought I was + supposed to document bug fixes here! This is what you get + for wanting BUILD tonight. As soon as I fix these darn + divide bugs, I'll put up a new version. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/5/95 - Fixed all known divide overflow bugs related to wallmost. I + haven't gotten a divide overflow yet in the last few hours, + but that doesn't guarantee that you'll never get one. Take a + look at GROULAND. It has a cool new cylindrical tunnel. On + the other side of the level is my house in Rhode Island. + + Known bugs with slopes now: + - Hitscan does not hit slopes correctly. + - Visibility not implemented for slopes yet. + - Clipmove will not allow you to walk off high sloped cliffs. + + - Also, I noticed a rare sprite drawing clipping bug. I + don't know if this is new or not. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/7/95 - Fixed an exception 0xe bug by using tsprite[MAXSPRITESONSCREEN-2] + instead of tsprite[MAXSPRITESONSCREEN-1]. I don't understand + why this fixed it so I expect that it will come back to haunt + me. Oh happy day. :( + + - I forgot to document 2 new and useful functions in the engine: + + long getceilzofslope(short sectnum, long x, long y); and + long getflorzofslope(short sectnum, long x, long y); + + Returns the z coordinate of the ceiling/floor at that x, y + location. If the sector doesn't have a ceiling/floor slope + then it immediately returns the sector[].floorz or + sector[].ceilingz so it's not that slow. You may want to + check for slopes yourself ceilingstat&2/floorstat&2 if you + think the overhead of calling these functions are too slow. + + - Made clipmove use getceilzofslope and getflorzofslope when + checking for overlapping. + + - Cleaned up mirror code for non-chained modes a little bit. The + mirrors should no longer have a stay line on the right anymore + for these modes. + + - Added Chain-Buffer mode. See my new SETUP.EXE. Chain-Buffer + is a combination of the chain and screen buffer modes - a + buffered chain mode. This mode is faster than standard chain + mode when a lot of screen memory is being read, for example + when you use transluscence or mirrors. Also, Chain-Buffer + mode is cleaner than screen-buffer mode since you don't see + memory being copied to the screen. Unfortunately, in most + cases, Chain-Buffer is the slowest of all modes. Actually, + Chain-Buffer mode sucks. There is a use for this mode, + however! In the future, I may make some kind of chain mode + automatically switch into chain-buffer mode for extra speed + when there is a large area of transluscence, etc. + + ATTENTION PROGRAMMERS: Here is the new order of modes that + initengine accepts: + + 0 = Chain mode + 1 = Chain-Buffer mode + 2 = Screen-Buffer/VESA mode + 3 = TSENG mode + 4 = Paradise mode + 5 = S3 + 6 = Crystal Eyes mode + 7 = Red-Blue mode +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/9/95 - Fixed visibility for face sprites in high resolution modes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/14/95 - Added a new bunch of graphics modes using the new VESA 2.0 linear + buffer. (I replaced the useless chain-buffer mode with VESA + 2.0 modes) See my new SETUP. Since most cards only support + VESA 1.2 right now, you will probably need a VESA 2.0 driver. + I have been using the UniVBE(tm) 5.1 from SciTech Software + (ftp: ftp.scitechsoft.com, www: http://www.scitechsoft.com) + Note that since I inserted the new modes between chained mode + and screen buffer mode, you will need to update your setup + program and fix your initengine calls. + + - Programmed a LRU/MRU-style cacheing system. It should be fully + compatible with the old cache1d except for the locking byte. + The locking byte would be better described as a priority byte. + Priority byte: + + 0 - non-cached memory, you NEVER set the byte to 0! + 1-199 - cached unlocked memory + 200-255 - cached locked memory + + When the cacheing system needs to remove a memory block, it + will try to remove the FEWEST number of SMALLEST blocks with + the LOWEST priority. + + Note: Never set the priority byte to a 0! Let the cacheing + system do that for you. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/15/95 - Optimized hitscan a little and made it work with slopes. + + - Made some internal things in the build editor work better with + sprites on slopes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/16/95 - Note: Initengine now only does memory allocation for the + graphics modes. The ylookup table is calculated in + setgamemode since with VESA, I don't know certain + variables such as bytesperline until the mode is + actually set. + + - Cansee should now work with slopes properly. + + - Added a new function which is a combination of the + getceilzofslope and getflorzofslope functions. Whenever you + need both the ceiling and floor, it is more optimal to call + this function instead. The parameters are just like the other + functions except the ceiling and floor are returned through + pointers instead of a return value. + + getzsofslope(short sectnum, long x, long y, + long *ceilz, long *florz); + + - Fixed recently introduced hitscan divide overflow bug. + + - Fixed a sprite drawing clipping bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/17/95 - ATTENTION PROGRAMMERS: I moved the sprite shading code from + the engine into GAME/BSTUB. If you want sprites to shade + like they used to, be sure to copy the code I recently added + to the end of analyzesprites in GAME.C or ExtAnalyzeSprites + in BSTUB.C. + + - Added 2 new interesting functions to the engine to make moving + slope programming easier. These functions will align a slope + to a given (x, y, z) point. It will make the slope pass + through the point. The function will do nothing if the point + is collinear to the first wall of the sector. + + alignceilslope(short sectnum, long x, long y, long z); + and + alignflorslope(short sectnum, long x, long y, long z); +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/18/95 - Kgroup will now work with subdirectories. + + - ATTENTION PROGRAMMERS: I have not done this yet, but I am + planning on doing a new map version! Before I do it, I + want to give you a chance to give me any suggestions you may + have. The only changes I am planning on, besides re-arranging + the structures for better alignment is to give the slopes some + more bits precision. This may limit slopes to a maximum slope + of 4 (almost 76ø) which is still extremely high. Here are the + new structures that I am proposing: + + //40 bytes + typedef struct + { + long ceilingz, floorz; + unsigned short wallptr, wallnum; + short ceilingstat, floorstat; + short ceilingpicnum, ceilingheinum; + signed char ceilingshade; + char ceilingpal, ceilingxpanning, ceilingypanning; + short floorpicnum, floorheinum; + signed char floorshade; + char floorpal, floorxpanning, floorypanning; + char visibility, filler; + short lotag, hitag, extra; + } sectortype; + + //32 bytes + typedef struct + { + long x, y; + short point2, nextwall, nextsector, cstat; + short picnum, overpicnum; + signed char shade; + char pal, xrepeat, yrepeat, xpanning, ypanning; + short lotag, hitag, extra; + } walltype; + + //44 bytes + typedef struct + { + long x, y, z; + short cstat, picnum; + signed char shade; + char pal, clipdist, filler; + unsigned char xrepeat, yrepeat; + signed char xoffset, yoffset; + short sectnum, statnum; + short ang, owner, xvel, yvel, zvel; + short lotag, hitag, extra; + } spritetype; + + Note that I am adding 1 byte of filler to the sprite structure + (4K more) and 3 bytes of filler to the sector structure + (3K more). (If I'm a nice guy, one of those bytes may even + be use for fog. (DOH!)) + + - Fixed another wonderful hitscan divide bug. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/22/95 - Optimized slopes. On a 486-66 w/ local bus in VESA 2.0 320*200 + mode, a full screen slope was optimized from 24fps to 35fps! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/25/95 - Re-optimized some more assembly. + + - ATTENTION EVERYONE! CONVMAP7! You know what this means. Just + type "convmap7 *.map" and you'll be back in business. P.S. + enjoy the newly aligned structures! + + - ATTENTION PROGRAMMERS! New TRANSPAL! You can now use 2 levels + of transluscence by using just a single 64K transluscent + buffer, such as 33/67 and 67/33 transluscence. I changed the + format of palette.dat, so please run TRANSPAL before you try + running the game with the new OBJS! If you don't, the palette + tables will be screwed up. + + Old PALETTE.DAT: + 768 bytes - VGA palette + numshades*256 bytes - palookup[0] table + 32640 bytes- transluscent palette (smaller from symmetry) + + The way I used to get numshades (fun): + numshades = ((filelength-32640-768)>>8) + + New PALETTE.DAT: + 768 - VGA palette + 2 - numshades + numshades*256 - palookup[0] table + 65536 - transluscent table + + To keep things less confusing, could you all use a + transluscent constant >= 128. For example, I used 170 on + my PALETTE.DAT. + + + READ THIS! New bits added to things: + Bit 5 of rotatesprite, bit 9 of both sprite[].cstat + and bit 9 of wall[].cstat are now used for reverse + transluscence. + + - Added super-cool new feature to 2D EDIT MODE (that should have + been there from the start). Try inserting some points! + + - ATTENTION PROGRAMMERS! Removed overwritesprite. Use + rotatesprite instead. I don't want to support a function that + can totally be done with another better function. I will + eventually optimize rotatesprite for 90ø cases so it's even + faster than the current overwritesprite. If you're too lazy + to convert right now, then you can use this overwritesprite + stub function: + +overwritesprite (long thex, long they, short tilenum, + signed char shade, char stat, char dapalnum) +{ + rotatesprite(thex<<16,they<<16,65536L,(stat&8)<<7,tilenum,shade,dapalnum, + ((stat&1^1)<<4)+(stat&2)+((stat&4)>>2)+((stat&16)>>2)^((stat&8)>>1), + windowx1,windowy1,windowx2,windowy2); +} + + - Fixed the rotatesprite centerting bug in y-flipping mode. Oh + by the way, you know how I originally said the flipping bit + was x? Well, I screwed it up. It was actually y-flipping all + along. + + - This one's for hackers (N&P/Qs) In the engine, I call + getpalookup every time I need a pointer to a 256-byte + palookup table. One big limitation right now is that each + bunch of 256-byte tables has a limit of 64K because a shade + is being returned, not a 4-byte pointer. This means you + could have a maximum of 8 shades, with 8 fogs per palookup. + It's not as expandable as I originally intended since this is + a speed-critical function. It is called EVERY single time a + line is drawn - probably called 50 times more often than + faketimerhandler. + + #pragma aux bound32 =\ + "test eax, 0ffffffe0h",\ + "jz endit",\ + "cmp eax, 80000000h",\ + "sbb eax, eax",\ + "and eax, 31",\ + "endit:",\ + parm [eax]\ + + getpalookup(long davis, long dashade) + { + return(bound32(dashade+(davis>>8))); + } + + This is just a start. Eventually I hope to use some kind of + lookup table, such as: palookup = palptr[davis][dashade], + but I couldn't think of a good way to make the array small + enough for what people need. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/26/95 - Fixed drawmapview so it actually clips to the rectangular window + properly. It does not clip to startumost/startdmost so you + should call a rotatesprite to draw the status bar every frame + if it is not rectangular. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/30/95 - Fixed recently introduced mirror bug. + + - Fixed rotatesprite x-positioning bug in scale mode for weird + resolutions. + + - Fixed tilting for pure chained modes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/2/95 - Changed setbrightness call: + + setbrightness(char dabrightness, char *dapal) + dabrightness is gamma level(0-15) + dapal is pointer to standard VGA 768 byte palette. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/3/95 - Fixed flicker in UNIVBE modes. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/6/95 - Added a global visibility variable to BUILD.H specific for + p-skies called parallaxvisibility. Now you can do lightning + effects without modifying the visibility for everything. + + - Really fixed the drawmapview window clipping this time. + + - Made my clearview function clip to the viewing window since it + is usually used just before the drawmapview function. + + - You can now use bit 6 (64) to tell rotatesprite whether or not + the tile has transparent regions or not. If there are no + transparent regions, then it would be faster to set this bit + because it doesn't have to check for color 255 at every pixel. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/11/95 - Back in RI! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/13/95 - Cleaned up setup program by having only 1 VESA menu for all + possible VESA modes. The engine will now auto-detect whether + or not your computer supports VESA 2.0. The screen buffer + menu now only supports 320*200. (I noticed that Mark's setup + program doesn't list 320*400 mode even though it is supported + by my game and UNIVBE. 320*400 is considered by some people + the next best mode after 320*200 and 640*480. You have my + permission to annoy him.) + + - I bought UNIVBE by credit card for $28! When you buy UNIVBE, + you don't have to struggle with beeps or date changing - and + it loads instantly. I try not to use TSR's whenever possible, + but I found that UNIVBE is worth wasting 8K. I don't think my + computer has ever crashed due to something related to UNIVBE. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/17/95 - Found an easy way to interpolate everything for faketimerhandler + in my game, including swinging doors, revolving doors, and + other moving sectors. My doanimations interpolation now uses + these functions instead. Check them out in my GAME: + + setinterpolation(long *posptr); //Call when door starts + stopinterpolation(long *posptr); //Call when door stops + updateinterpolations(); //Call at start of domovethings + dointerpolations() //Call at start of drawscreen + restoreinterpolations() //Call at end of drawscreen + + Call setinterpolation with a pointer to the long variable + being interpolated. If an object stops moving, you can + speed things up by calling stopinterpolation. For things + that always move, you can call setinterpolation in pre-map + and don't stopinterpolation for those things. Don't forget + to set numinterpolations to 0 in premap whenever changing + levels in the game. + + - Optimized lava. You can re-copy my code if you want. + + - Added auto screen-buffering mode for linear VESA modes. (In + case you didn't know, reading video memory can be 10 times + slower than reading non-video memory.) Auto-buffering + means that if the engine detects that more than 1/8th of the + screen has transluscence or mirrors, then it will switch into + a screen-buffering mode. Screen-buffer mode in linear VESA + not only will still have smooth page flipping, but will be + faster than standard screen buffer mode on some video cards + just because it's linear memory. (That's a good thing) + + - Optimized screen buffer modes so they copy only the viewing + window instead of the whole screen from non-video memory to + video memory. If a permanent sprite is written, as a special + case, it will copy the whole screen - but this doesn't affect + you. Me and my engine babble. + + - Moved the printext function out of the engine and into my game. + Use printext16/printext256 instead. + + - I tried removing chain mode twice and it didn't improve the frame + rates of the other modes at all. So it stays! If you don't + like it, then don't include it in your setup program. + + - Made allocatepermanenttile return 0 instead of -1 if something + bad happens. My GAME.C was crashing in windows with a memory + error because I was assuming all memory pointers were + positive. Please make sure your code will work if an + allocation function returns a negative pointer (Windows often + returns negative pointers). +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/19/95 - Tried to make pushmove work with face sprites, but it kept making + the player die too much. Also it presented some interesting + new problems, such as: You get pushed by your own bullets + that you just shot - and get this - if you don't temporarily + set yourself to non-blocking you kill yourself because you're + inside you're own sprite! So I have decided to comment out + this code for now. + + - Fixed hitscan bug with ceiling slopes. + + - ATTENTION PROGRAMMERS!!! PERMANENTWRITESPRITE was removed from + the engine and be put into my game as an emulated function. + If you still use permanentwritesprite, get the emulated + function out of my GAME.C. + + Drawing permanent areas is now easier than ever!!! Simply + call rotatesprite with bit 3 (&8) set or the + permanentwritesprite stub call, and the engine now + automatically takes care of copying the permanent region + to all necessary pages in the future. It even keeps track + of whether the call was before or after drawrooms! + I am using an internal fifo to back up the parameters for each + rotatesprite call. It can support up to 512 calls per + page right now. This number can get reached quicker than + you think, especially if you use fonts with shadows behind + each character. Permanentwritespritetile could also go + over the limit in hi-res modes since each tile is considered + a separate call. + I optimized out the case where an older rotatesprite region gets + completely covered by a newer rotatesprite region with bit 6 + (&64 for non-masking) set. Currently this has a few + limitations - such as the x, y, zoom, and ang must be the same + right now to knock out an older rotatesprite. + + - I corrected an off-by 1 error in my GAME.C for window size + calculations. I simply used more precision. Ex: + * changing (xdim>>1)-(screensize>>1) to ((xdim-screensize)>>1) + * using the scale function instead of a separate mul & div. + By the way, if you haven't already, please stick your screen + re-sizing code BEFORE drawrooms. It will make the screen + re-size update more responsively and you're less likely to get + drawing bugs. + + - Future plans for possible rotatesprite optimizations: + 1. Angle is 0, 512, 1024, 1536 + 2. Bit 6 (&64) is set for non-masking mode + 3. tilesizy[tilenum] is a power of 2 + 4. If coincidentally, x=34562, y=34682, and zoom=67275 +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/20/95 - Fixed vertical line shading bugs when looking at walls at harsh + angles. + + - Made masked walls clip to slopes properly. TRY IT! + (hope you didn't "BUILD" on this bug!) + + - Fixed overflow and precision bugs with extremely long walls. + I even got the chance to optimize out a multiply in the + wallmost clipping code! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/25/95 - Now absolutely everything in my game is being interpolated + for smooth play - including subways! No interpolation + disable variable exists any more. The setinterpolation + function is really easy to use. Try it! + + - Programmed VISIBILITY for slopes!!!!! On my P-100, the slopes + are almost as fast as they used to be. You can now start + adjusting the shades of slopes. + + - The shading lines on ceilings and floors now match to the shading + lines on walls. Before they didn't match. (oops). + + + - For those of you who want to program their own palette functions, + using my gamma correction lookup table, here's the code: + + extern char britable[16][64]; + + koutp(0x3c8,0); + for(i=0;i<768;i++) + koutp(0x3c9,britable[curbrightness][palette[i]]); + + If you use this code, don't bother calling setbrightness any + more. The only bad thing about programming this yourself + is that you lose support for red-blue glasses mode. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/26/95 - Added support for VESA 2.0 protected mode extensions. With the + protected mode extensions, the page-flipping is less likely to + flicker, if at all. This is because the retrace timing isn't + screwed up as badly as if it had to switch to real mode. + + - Fixed a weird buffer bug in my GAME.C. I was using tempbuf in + faketimerhandler/getpackets for sending packets. I was also + using tempbuf in many other places, such as my printext + function. Unfortunately, since rotatesprite is now called + for each character, faketimerhandler would sometimes get + called and the rest of the word got screwed up. Please make + sure you are not sharing any buffers in faketimerhandler / + getpackets with the rest of your code. + + - Fixed a bug for linear VESA modes. Now, the screen will update + properly when calling rotatesprite and nextpage for the first + time before any drawrooms calls. This used to not work right + at my "waiting for other players" code in this mode. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/27/95 - Did you notice I fixed some of the weird cases with slope drawing + in the last upload? I fixed things like when a ceiling of + one sector is partially below the floor of another, etc. + + - Fixed precision of shading lines on slopes. + + - Fixed visibility overflow when slopes are near horizons. This + means you won't see ugly bright pixels any more when you're + looking at a slope at an extremely sharp angle. + + - Fixed a bug in BUILD 3D EDIT MODE with slopes. Now when you + press '/' on a ceiling or floor slope, it stays straight + until you press [ or ] on it again. Before, sometimes the + ceiling would stupidly get sloped again if you pressed [ or ] + on the floor and vice versa. + + - Removed some unnecessary sounds from my game. This doesn't + really affect you people out there. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/30/95 - Fixed recently screwed up p-sky tiling. + + - Made Editart work with map version 7 for tile sorting and the + Alt-R command. Alt-R does not scan the heinum's of sectors + any more, and only adds in the overpicnum if a masked or + 1-way wall is actually defined on the map. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/31/95 - Fixed a bug with my slopalookup array. It was sometimes writing + up to 3 bytes after the end of the array. + + - Fixed recently screwed up p-sky tiling for real this time. + + - Permanentwritesprite is out of my game. Here it is just in case + I will need it again for future reference. + + permanentwritesprite (long thex, long they, short tilenum, + signed char shade, long cx1, long cy1, + long cx2, long cy2, char dapalnum) + { + rotatesprite(thex<<16,they<<16,65536L,0,tilenum,shade, + dapalnum,8+16,cx1,cy1,cx2,cy2); + } +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/1/95 - Guess what? I turned 20 today. This means I'm no longer a + teenage programming genius. Doesn't that just suck. If you + guys don't get a game out by the next time my age plus + plusses, I'm going to get really p-skied off and kill some + people. That would be bad. (When I say killing, I mean + virtual killing in the entertaining game of Ken-Build + in which a fun time is always had by all.) So put on your + happy fun smiles and work out all those rotatesprites, + fsyncsyncvel.bits, and interpolation fifos before it's + ototalclock! + + - Optimized the NON-MASKING cases of rotatesprite for + NON-(un)CHAINED modes. This means that low detail modes, + status bars, and permanent background tiles are now drawn + about as fast as they're ever going to be drawn! Try the + F5 key in my game to compare frame rates if you want. I have + not optimized guns and stuff yet. That's next on my list. + + - Made the engine call new internal functions, kmalloc and kfree, + instead of malloc or free. Unless you're a hacker and wrote + your own memory manager (like N&P/Qs) you can just ignore + this message. + void *kmalloc(size_t size) { return(malloc(size)); } + void kfree(void *buffer) { free(buffer); } + + - Supposedly fixed the new rotatesprite and linear vesa crashing + bugs. Since I'm not totally sure that I fixed the problems, + all I can do is hope that I don't get too many phone calls! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/4/95 - Did some neat optimizations that will make the drawing code + faster, especially in hi-res modes, but I'm sure nobody cares. + Instead I'm probably just going to get 10 totally different + bug report stories. So I'll be talking to you soon! + + - Fixed stupid bugs in cansee. If the 2 objects were in the same + place, sometimes it returned 1 even if it couldn't see you. + I made 2 fixes: + This one to fix overlapping: + + if ((xs == xe) && (ys == ye)) return(sects == secte); + + And I removed the early out return(1) optimization - I + put this after the big loop instead: + + for(i=danum-1;i>=0;i--) + if (clipsectorlist[i] == secte) return(1); +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/7/95 - Optimized the awful shld's out of my divscale's in pragmas.h. + You can update to the new pragmas.h if you actually use it. + + - Remember the lovely horizontal lines on top of face sprites. + Well you won't be seeing them any more. At least the case + I trapped works better than before. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/8/95 - Made krand generate better random seeds. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/9/95 - ATTENTION PROGRAMMERS! Moved part of stat bit 3 of rotatesprite + to bit 7. Have you noticed that your menu code was kind of + screwy in modes where numpages > 1? This is because I made + rotatesprite automatically copy to all pages whenever the + "don't clip to startmost's bit" (bit 3 or +8) was set in + the stat bit of rotatesprite. To give you more control, I + moved the auto copy to all pages bit to bit 7 and left bit 3 + as the don't clip to startmosts bit. If you want your code + to work the same as the last update of BUILD, simply go + through all your rotatesprite calls and add 128 in addition + to the stat bit whenever you were adding 8 before. See the + revised rotatesprite documentation: + +rotatesprite (long sx, long sy, long z, short a, short picnum, + signed char dashade, char dapalnum, char dastat, + long cx1, long cy1, long cx2, long cy2) + + (sx, sy) is the center of the sprite to draw defined as screen coordinates + shifted up by 16. In auto-scale mode, be sure that (sx, sy) is using + a 320*200 size screen even though the real resolution may be different. + (z) is the zoom. Normal zoom is 65536. > is zoomed in, < is zoomed out. + (a) is the angle (0 is straight up) + (picnum) is the tile number + (dashade) is shade number + (dapalnum) is the palookup number + + if ((dastat&1) != 0) - transluscence + if ((dastat&2) != 0) - auto-scale mode + Auto-scale mode will automatically scale from 320*200 resolution + coordinates to the clipping window passed (cx1, cy1, cx2, cy2). In + auto-scale mode, don't pre-scale the (sx, sy) coordinates. Simply pass + (sx, sy) as if the resolution was 320*200 even though it may be + different. This means that you shouldn't use xdim or ydim to get + (sx, sy). + if ((dastat&4) != 0) - y-flip image + if ((dastat&8) != 0) - don't clip to startumost/startdmost + if ((dastat&16) == 0) - use Editart center as point passed + if ((dastat&16) != 0) - force point passed to be top-left corner + if ((dastat&32) != 0) - use reverse transluscence + if ((dastat&64) == 0) - masked drawing (check 255's) (slower) + if ((dastat&64) != 0) - draw everything (don't check 255's) (faster) + if ((dastat&128) != 0) - automatically draws to all pages as they come + + (cx1, cy1, cx2, cy2) - The clipping window. These coordinates are never + scaled, not even in auto-scale mode. Usually you should pass them as + (windowx1,windowy1,windowx2,windowy2) for things scaled to the viewing + window or (0L,0L,xdim-1L,ydim-1L) for things scaled to full screen. + Probably the only time you wouldn't follow this rule is if you program + a non-scaled tiled background function. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +11/21/95 - Optimized cansee - before it was checking each red wall 2 times + as much as it needed to. Now it only checks the side facing + the first object passed to cansee. Since this optimization + is only 1 line, I don't think I messed anything up this time. + + - Made cansee not pass through 1-way walls. This means that the + order of points passed to cansee could give you different + results, but only for 1-way walls. + + - FIXED CRASHING AND PRECISION ON HIGH SLOPES!!! Try it for the + first time again! The bug was: In wallmost, if a slope's + line was getting clipped by both the top and bottom of the + screen, the x-intercept of the bottom was calculated wrong. + And if you were real lucky, if the x-intercept could have been + so wrong that a loop would happily overwrite random chunks of + memory. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/1/95 - In my GAME.C, made tilting zoom in smoothly as it rotates to + hide the ugly corners. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/4/95 - Made some more optimizations to rotatesprite - added more cases + for removing things from the permanent list early, such as: + any full screen rotatesprite with 64 knocks everything else + off the list, and any rotatesprites with zoom=65536,ang=0, + stat&64 will knock out anything totally under its rectangle. + These optimizations seemed to actually fix some bugs. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/10/95 - Well, well, well. It has now been 2 years since you know what + was released and Apogee still hasn't put out a (real) Build + game. Trivia of the year: Did you know that the first Build + game was originally scheduled to be released a month before + Doom was to be released? Maybe I should rename the "Build" + engine to the "ROTTT" engine because it's probably just going + to rot on my hard drive for another year until all the games + just get cancelled. PROVE ME WRONG! + + - Added selectable viewing angles - not locked at 90ø anymore! + Try playing around with the ( ) - = keys on the main keyboard + in my new BSTUB.C. See the example code in BSTUB for setaspect. + Use the setaspect function to control both the viewing range + angle and the y/x aspect ratio. + + setaspect(long daxrange, long daaspect) + + For a standard 90ø 320*200 screen, daxrange and daaspect are + 65536. For square aspect ratio at 320*400, set daaspect + to 131072. Since daxrange is actually zoom, you must + modify the aspect ratio inversely if you only want to + change the viewing angle. + + ATTENTION EVERYONE! To make parallaxing skies work with larger + than 90ø viewing ranges, I had to change some things around + in TABLES.DAT. Don't forget to update to the new one! The + new one is smaller because I removed a useless array. + + - Improved red-blue glasses mode by fixing some palette problems + and removing the overlap problem on the right side of the + screen. It still has some things wrong with it though. + + - Perfected screen tilting by using the new setaspect function. It + now tilts all 360ø smoothly with no zoom change and with no + ugly corners. This is possible only because you can now set + the viewing angle higher than 90ø. + + - Fixed a flicker bug with permanent rotatesprites in multi-page + modes. When rotatesprite was called because drawrooms in a + multipage mode, the rotatesprites were being called in the + wrong order from the fifo for the first page. Note that + before, the auto-knock out feature sometimes hid the problem. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/11/95 - Made EDITART work with the new TABLES.DAT. + + - Upgraded to Watcom 10.5. The engine is now about 1K larger, + and 0.0000001% faster. + + - Added some interesting compression routines to cache1d.obj, + dfread and dfwrite. These functions take the same parameters + as fread and fwrite respectively. These functions are useful + for loading/saving games or for recording demos. + + Note: Since these functions need to allocate 118K off of my LRU + cacheing system, you must not call them before + initcache(loadpics) is called. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/18/95 - Made rotatesprite use getpalookup to get the palette shade. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/31/95 - Cleaned up KGROUP.EXE and wrote a KEXTRACT.EXE utility. With + KEXTRACT, you can extract any files from a group file. + Note that in KGROUP, DOS handles the ? and * wildcards whereas + in KEXTRACT, I had to program the wildcards myself for finding + files inside the group file. The following combinations + should work: *.*, *.map, game.*, tiles???.art, *.k?? + + - NEW NETWORK METHODS! TRY MY GAME IN MULTIPLAYER MODE! MODEM! + + SUMMARY: Lag Time: ZERO! That's right Z.E.R.O. (0) + Smoothness: Perfect on ALL computers! + + My new network code builds upon everything you've already + programed with faketimerhandler, getpackets, movethings, and + domovethings, so you don't need to throw away any of that + great stuff. There are actually 2 totally separate things I + did to improve the multiplayer performance. First I added a + new network mode which sends packets in a different way (this + is way Doom actually does it) Then I found a way to reduce + lag-time to 0 with perfect smoothness. (Doom does NOT do + this, but G&S like it anyway for some reason.) I will first + describe the new network mode: + + ------------------------------------------------------------- + 1. First, let me describe the new network mode. Instead of + a master/slave system, every computer sends its own controls + to every other. You are currently using the master/slave + system which sends 2(n-1) packets per frame where n is the + number of players. My new network mode sends n(n-1) packets + per frame and treats every player evenly. See the chart + below of packets per frame: + + 2(n-1) method: n(n-1) method: + 2 players 2 2 + 3 players 4 6 + 4 players 6 12 + 5 players 8 20 (OUCH!) + 6 players 10 30 (OUCH!) + 7 players 12 42 (OUCH!) + 8 players 14 56 (OUCH!) + + + You may be asking why I am bothering you with this new + network method if it sends more packets then the old one? + I'll explain: With the old network method, slaves had to + wait for their packets to take 2 trips before they could move, + whereas with the new method the packets need to take only 1 + trip. Also with the new method the players are treated + evenly. For 2 players, the new network method is definitly + the mode of choice since it sends the same number of packets + AND the packets can be smaller since each computer only needs + to send its own controls to the other computer, not everyone's + controls (good for modem play). It's up to you what your + break even point is before you switch into the old network + method. I recommend: 1-4 New, 5+ Old. + Now let me explain how the new method REALLY works. Since + every computer must call the movement code in the same order + to stay in sync, all computers must wait until every packet + is received for that frame before it can actually go into + the movement code. You could say that all the computers are + half-slaves. Your computer should always be ahead of the + other computers. If you are player 0, the packets you + currently have might look like this: + + Chart for Player 0: + + Player 0 Player 1 Player 2 + Tic 0: GOTMINE------GOT--------GOT------> MOVE! + Tic 1: GOTMINE------GOT--------GOT------> MOVE! + Tic 2: GOTMINE--X WAITING... GOT CAN'T MOVE! + Tic 3: GOTMINE WAITING... WAITING... CAN'T MOVE! + Tic 4: GOTMINE WAITING... WAITING... CAN'T MOVE! + + As soon as player 0 receives player 1's next packet, + player 0 can call domovethings for tic 2. + One interesting complication of the new network method is + the timing. If for some reason player 0 sends packets faster + than player 1, then player 1 will have no lag and player 0 + will start with twice the normal lag which will increase + until bad things happen. See this chart: + + Player 0's side: | Player 1's side: + Player 0: Player 1: | Player 0: Player 1: + Tic 5: GOTMINE GOT (MOVE) | GOT GOTMINE (MOVE) + Tic 6: GOTMINE WAITING | GOT GOTMINE (MOVE) + Tic 7: GOTMINE WAITING | GOT GOTMINE (MOVE) + Tic 8: GOTMINE WAITING | GOT GOTMINE (MOVE) + Tic 9: GOTMINE WAITING | GOT GOTMINE (MOVE) + | GOT + | GOT + | GOT + + This can be corrected by sending a byte which tells the + other computer how many packets behind it is. You want the + other computer to be a little behind. Player 0's packet + delta in this case would be 4. Player 1's would be -3. + + Another interesting thing about this network method is + that a slave's packet cannot be skipped like in the + master/slave system. + + The actual code for everything described above is already + in my GAME.C and working perfectly. Go through the file + searching for the keyword, "networkmode". If it is non-zero, + that's the new mode. Look mainly at the section inside + faketimerhandler and case 17 of getpackets. + + (I've talked about "2(n-1)" and "n(n-1)" networking modes. + Believe it or not, it's possible to do a network mode as + low as an "n" mode. I haven't done it due to some + inherent problems. I'd be impressed if you can figure out + how this one works) + ------------------------------------------------------------- + 2. Now I'll type about the "KLAG-0 Technology" I promised you. + + The secret to life is, " + NO CARRIER + + Why do you have to wait for another computer to tell you + when to move when you already know where you want to go? + So I added a fake set of variables that simulate + where the player's x, y, z, and ang variables will be after + it does sync crap with other computers. I added a function + called fakedomovethings which is called in the same fashion + that domovethings would be called in a 1-player game. + Fakedomovethings modifies ONLY the fake x, y, z, and ang + variables. It is a shadow of the processinput function. It + only needs the parts of processinput that modify the position + of player[myconnectindex]. If it modifies real variables, + the game will get out of sync. + Sometimes the fake variables can get out of sync with the + real variables. This can happen if you walk into another + player or anything else that moves. This doesn't happen too + often though and when it does, there are things that you can + do to smooth out the jump to the right position. This brings + me to my other new function: fakedomovethingscorrect. + The easy way to correct the player's position in a smooth + way is to say something like: fakex += ((realx-fakex)>>3); + This would effectively move the player 1/8th of the way closer + to the real position. The problem with this method is that + the realx and fakex are not sampled at the same time, + therefore creating more error than isn't any. + So instead of comparing your fake position with where the + real position was a few tics ago, I chose to compare both + of them a few tics ago. FIFO time! To do this, I am keeping + a fifo of the new fake positions and comparing the positions + as the real positions come. Now that they're being compared + at the same tic, correction will only occur when you've truly + run into a moving object. + ------------------------------------------------------------- + I hope all this was as much fun for you to read as it was for + me to type. If you don't understand it, then I was probably + just trying to confuse you with all the possible word + combinations I could come up with that contain the letters in: + "fake", "sync", and "fifo". +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/6/96 - Made RT.SHIFT highlighting in build.obj not pick up non-existent + sprites in the selection rectangle. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/9/96 - Fixed a rare hitscan overflow bug for sectors that had a + ceiling&floor z-difference of more than 400000 z-units. + (About 20 stories tall) +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/15/96 - Changed something in rotatesprite so that status bars could be + clipped easily by using the clipping parameters. (I never + knew this didn't work until now) This change will only affect + your code if you were using bits 2+8 and the clipping window + was something other than the standard (0,0,xdim-1,ydim-1). + + - Improved fakedomovethingscorrect. Before when there was an + error, I was adding the difference into the current + position. This method conflicted with pushmove - where + sometimes it never fully corrected the position leaving you + stuck behind a wall. Now I make your position the position + it would have been if it had predicted the right position + several ticks ago. In other words, I set the my... variables + to the real, older position then call fakedomovethings for + every tic from the time of the real, older position up to + the current time. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/19/96 - Added snow reduction code to setpalette. It takes about 4 ms + to set a full palette. I write during the horizontal retrace + period to save time. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/23/96 - Added hack to loadboard to make it load a board only from the + group file if the last character of the filename is a 255. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +1/25/96 - Fixed a stupid bug in UNIVBE segmented modes so it doesn't + flicker anymore. Why didn't you guys tell me about this + sooner! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/1/96 - Optimized cansee according to Peter's suggestions. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/2/96 - Made setview calls not mess up the stereo vision variables. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/5/96 - ATTENTIONS ALL PROGRAMMERS!!! If you use use any VGA registers + (such as 0x3da, or 0x3c6 - 0x3c9), you will need to re-code + those sections of code. Please make your BSTUB's work with + this too! + + 1. If you use register 0x3da, limitrate, or qlimitrate, you + will need to do a special check to see whether or not the + video mode is VGA register compatible. If you do not + check this, then the computer may lock up because register + 0x3da simply doesn't change on certain video cards. + Unless you know the code won't be called in VESA mode, you + need to perform this check. Here's an example of how you + can do this check: + + Instead of calling limitrate (or your own 0x3da function): + limitrate(); + Do this: + //extern char vgacompatible; + if ((vidoption != 1) || (vgacompatible == 1)) limitrate(); + + 2. You must now use my function to set or get any palette + registers. This means that the keywords "3c7", "3c8", + and "3c9" should not even exist in your code. I really + didn't want to force you to use my palette functions, but + since VESA 2.0 supports non VGA compatible cards, you must + do it this way. If you use setbrightness for all of your + palette setting, then you can ignore this. Note that the + palette format here is VESA's palette format, which is + different than my other palette control functions. It's + 4 bytes and RGB are backwards. Here are the function + prototypes: + + VBE_setPalette(long palstart, long palnum, char *dapal); + VBE_getPalette(long palstart, long palnum, char *dapal); + palstart is the offset of the first palette to set + palnum is the number of the palette entries to set + dapal is a pointer to the palette buffer. The palette + buffer must be in this format: + char Blue, Green, Red, reserved; + I think this format stinks, but since VESA 2.0 uses + it, the code will run fastest if the buffer is not + copied. You can make your own cover up function if + you don't like this format. + + This example sets up a wasteful gray scale palette: + + char mypalette[1024]; + for(i=0;i<256;i++) + { + mypalette[i*4+0] = (i>>2); //Blue + mypalette[i*4+1] = (i>>2); //Green + mypalette[i*4+2] = (i>>2); //Red + mypalette[i*4+3] = 0; //reserved + } + VBE_setPalette(0,256,mypalette); +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/7/96 - Did some minor optimizations to functions that use cliptype. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/9/96 - ATTENTION PROGRAMMERS!!! There is no such thing as a cliptype + anymore! Instead you use clipmasks. Clipmasks are much better + because it gives you full control of which bits are used to + test whether or not a sprite or wall will block things. + + Let me refresh your memory on how cliptypes used to work: + For CLIPMOVE, PUSHMOVE, and GETZRANGE: + If (cliptype == 0) these bits were the blocking bits: + (wall[].cstat&1), (sprite[].cstat&1) + If (cliptype == 1) these bits were the blocking bits: + (wall[].cstat&64), (sprite[].cstat&256) + For HITSCAN, cliptype was not passed and assumed to be 1: + (wall[].cstat&64), (sprite[].cstat&256) + + Note that I added these 2 defines in BUILD.H: + #define CLIPMASK0 (((1L)<<16)+1L) + #define CLIPMASK1 (((256L)<<16)+64L) + + In order to make clipmasks work, I had to change the parameters + to these 4 important functions. CLIPMOVE, PUSHMOVE, GETZRANGE, + and HITSCAN. For CLIPMOVE, PUSHMOVE, and GETZRANGE, I simply + made the cliptype from a char to a long. For HITSCAN, I had to + add the clipmask parameter at the end. Here are the new function + prototypes: + +clipmove (long *x, long *y, long *z, short *sectnum, long xvect, long yvect, + long walldist, long ceildist, long flordist, unsigned long clipmask) + +pushmove (long *x, long *y, long *z, short *sectnum, + long walldist, long ceildist, long flordist, unsigned long clipmask) + +getzrange (long x, long y, long z, short sectnum, + long *ceilz, long *ceilhit, long *florz, long *florhit, + long walldist, unsigned long clipmask) + +hitscan (long xs, long ys, long zs, short sectnum, long vx, long vy, long vz, + short *hitsect, short *hitwall, short *hitsprite, + long *hitx, long *hity, long *hitz, unsigned long clipmask) + + You should convert your source code using these rules: + * For CLIPMOVE, PUSHMOVE, and GETZRANGE, look at the last + parameter. If it is a 0, then change it to say CLIPMASK0. + If it is a 1, then change it to say CLIPMASK1. + + * For HITSCAN, add a new parameter that says CLIPMASK1. + + * If you have your own movesprite function, then you will + need to make the cliptype parameter into a long variable. + + - If you want to set a range for hitscan, or optimize its + performance, you can now extern these 2 variables from + the engine. You can set them just before you call hitscan. + If you DO choose to screw around with these variables, then + you must set them before EVERY hitscan in your code. + I have them defaulting to a really high number, totally out + of range of the map, but not high enough for a subtraction + to overflow it. These variables are used in hitscan only + to compare whether the new hit is closer then the last one. + + long hitscangoalx = (1<<29)-1, hitscangoaly = (1<<29)-1; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/13/96 - Fixed a bug in clipmove that showed up in the latest upload + related to sector searching. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/18/96 - Re-wrote waitforeverybody / case 250 of getpackets, so the slave + sends acknowledge packets in a better way. Before there was + a possibility of a slave sending an invalid acknowledge + packet if the last packet received was not 250. + + - ATTENTION PROGRAMMERS! Setgamemode now returns -1 if the mode + is invalid or 0 if it is valid. Since the engine no longer + quits to DOS from an invalid video mode, you must program the + -1 case or else the computer will probably lock up! +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +3/5/96 - Solved tile index corruption bug in EDITART. After looking at + the latest art files I have from you, It looks like SW has + this problem, but DUKE and BLOOD seem ok. Let me explain: + In Editart 'V' mode (with no tile report), when you use + INSERT or DELETE, it very quickly moves all tiles after the + cursor forward or back 1. With multiple art files, this + operation would be very slow, since I'd have to load and + save every art file after the current one. But I figured + out a way to still keep it fast - instead of reading and + writing all the later art files, I instead changed just the + headers that tell which tile indeces the art files start and + end with. This works nice when you have 1 big art file, or + only 1 person using EDITART to change stuff. + Unfortunately, some of you have been passing around + individual art files and this is where the problem comes in. + If either person used INSERT of DELETE in 'V' mode and passed + an individual art file to another person, the headers could + possibly conflict and cause strange lockups or crashes in + EDITART, BUILD, or GAME. + So I fixed the problem by making EDITART only change the + CURRENT art file. Insert mode will now delete the last + tile in the CURRENT art file, so be careful that the last + tile in the CURRENT art file is blank. Delete will now + insert a blank tile at the end of the CURRENT art file. + If your ART files are already corrupt, you can run + RSIZEART.EXE and agree on a number of tiles per file. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +4/27/96 - Fixed a bug where rotatesprite seemed to clip the tile + to the viewing window even though stat&8 (don't clip + to startumosts/startdmosts) was set. The problem was + actually related to an optimization in the VESA blitting + code that copies only the screen if it thinks nothing + was drawn outside of the viewing window. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/15/96 - I must have added a whole bunch of unnoticable optimizations + since the last time I typed stuff into this file, but since + I didn't keeping track of it, I couldn't tell you what they + were off hand. + + - I added support for the 'new' Crystal Eyes in such a way where + you don't have to mess with the timer. I use the real-time + clock (IRQ8) in order to avoid conflicts. Crystal Eyes mode + works only in VESA 2.0 modes with at least 4 pages. The nice + thing about this mode is that you can switch in and out of + it easily during the game. There are 2 very simple functions + and 3 variables you can extern. To use Crystal Eyes mode, + simply call initstereo(). Initstereo should be called after + setgamemode and the palette is loaded into the VGA. To + return back to normal mode, simply call uninitstereo(). + Here's what the code would look like: + + extern long stereomode, stereowidth, stereopixelwidth; + + if (KEYTOTOGGLESTEREOMODE) + { + KEYTOTOGGLESTEREOMODE = 0; + if (stereomode == 0) + initstereo(); + else + uninitstereo(); + } + + Notes: + * The following 2 variables can be changed any time, and + should always be >= 0. + + stereowidth: distance between left and right eyes + stereopixelwidth: parallax - pan offset in pixels between + left & right screens + + * initstereo automatically sets stereomode to nonzero and + uninitstereo automatically sets stereomode to 0. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/5/96 - Made cache1d.obj support up to 4 group files at the same time. + To use multiple group files, simply call initgroupfile again. + You need to uninitgroupfile only once. This is useful if + users want to add their own .ART, .VOC, or other files and + distribute it all in one file without telling people they + need to back up stuff. For example: + + Beginning of program: + initgroupfile("duke3d.grp"); + if (usergroupfile) + initgroupfile(usergroufile); + + End of program: + uninitgroupfile(); + + Here's the order cache1d will search for a file when + kopen4load is called. Remember that the second parameter + to kopen4load is the searchfirst parameter. If you set + this variable to non-zero, you can tell kopen4load to search + the main group file only. This is useful if invalid user + files are detected. + + if (searchfirst == 0) + { + 1. Look for it as a stand-alone file + 2. Look for it in the 4th group file (user group file) + 3. Look for it in the 3rd group file (user group file) + 4. Look for it in the 2nd group file (user group file) + } + 5. Look for it in the 1st groupfile ("duke3d.grp") + 6. If file still not found, return -1 + + - Fixed a stupid bug with choosing the side of a red line in BUILD + 2D edit mode. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +7/24/96 - Increased MAXTILES to 6144. Fixed some scrolling errors related + to MAXTILES in 'V' mode of EDITART and BUILD. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +8/20/96 - Made it possible to safely default to NORMAL mode 320*200 when + VESA is not supported or found. Check out the beginning of + my setup3dscreen function. It shows how you can offer the + player a choice of quitting to DOS or continuing in NORMAL + mode. It is very annoying when setting up multiplayer games + when the game always quits to DOS because somebody forgot + to load their VESA driver. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/6/96 - Moved internal function, setfirstwall, in BUILD.OBJ into + ENGINE.OBJ because it can be useful to game programmers. + This function sets the first wall of a sector to be the + wall index passed. This function is useful for setting + the hinge wall for slopes or relative alignment. (ALT-F + uses this function) Here's the function: + + setfirstwall(short sectnum, short newfirstwall) + + - Added a variable, clipmoveboxtracenum, to ENGINE.OBJ which can + be externed. As a special case, if you set it to 1 just + before calling clipmove, then clipmove will return when it + first hits a wall - in other words, the (x,y,z) that clipmove + returns will be before any sliding calculations occur. Be + sure to set clipmoveboxtracenum back to 3 after calling + clipmove. + + This is how it is defined in ENGINE.OBJ: + long clipmoveboxtracenum = 3; + + Example of calling clipmove with no sliding: + clipmoveboxtracenum = 1; + i = clipmove(...); + clipmoveboxtracenum = 3; +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +9/25/96 - Removed support for specially optimized TSENG, Paradise, and S3 + modes. If you want the engine to run as fast on these cards, + get Scitech Software's latest Vesa 2.0 driver. + + - ATTENTION PROGRAMMERS! Added video mode changing during the game. + I moved the option, xdim, and ydim parameters from initengine + into the setgamemode function. + + Here are the updated prototypes for the 2 functions: + initengine(); + setgamemode(char newvidoption, long newxdim, long newydim); + + You are free to call setgamemode as often as you like. If you + have very low memory, it's possible that the call will fail + and quit to DOS with one of those awful CACHE SPACE ALL LOCKED + UP messages. + + Note: When updating your code, be careful to not rely on + vidoption, xdim, of ydim being valid until your first + setgamemode call. If you're not careful with this, you may + get a divide by zero or something. I had a bug in my GAME.C + where I was calling setview between initengine and + setgamemode. I had to move setview after setgamemode. + + - Added function to the engine that returns all valid VESA modes. + + getvalidvesamodes(); + + This function prepares the list of valid VESA modes in these + new variables which I put in BUILD.H. This function needs to + only be called once, but it doesn't hurt to call it multiple + times since I have a flag that checks if it has already been + called. + + EXTERN long validmodecnt; + EXTERN short validmode[256]; + EXTERN long validmodexdim[256], validmodeydim[256]; + + validmodecnt - number of available 256 color VESA modes. + validmode[] - array of vesa mode numbers (640*480 is 0x101, etc.) + validmodexdim[] - array of x dimensions for each mode + validmodeydim[] - array of y dimensions for each mode + + In my GAME.C, I have code that cycles through all VESA modes + and screen buffer mode when you press F4. Search for the + keyword "//F4" to find it. + + Note: Be careful when you call setgamemode! Be sure that it + is not called inside any function of sub-function of + faketimerhandler because this would be in the middle of the + drawing code. Actually, the safest place to call setgamemode is + right after nextpage in your main drawing loop. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +12/13/96 - Fixed the nasty caching bug first found in the Plutonium version + of Duke3D. I was using copybuf when I should have been using + copybufbyte. + + - Made the '>' key in 3D EDIT MODE not lock up any more for + textures that have non power of 2 tilesizy's. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +2/12/97 - Optimized mirror code so it x-flips only the bounding rectangle + (x AND y). Actually calculates left & right boundaries instead + of using the horizontal line checking stuff which didn't really + work all the time anyway. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +5/22/97 - Frank noticed a divide overflow in clippoly when drawmapview was + in hi-res mode. -fixed by lowered precision from 16 to 12 + bits. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +6/2/97 - Added support for the Nuvision 3D-Spex stereo glasses. I renamed + initstereo to setstereo and got rid of uninitstereo. Here's + complete documentation for all of the new stereo glasses stuff: + + setstereo(0); //Set to default normal non-stereo mode + setstereo(1); //Use Stereographics Simuleyes (white line code) + setstereo(2); //Use Nuvision 3-D Spex stereo (uses LPT1) + + //You can extern these 2 variables from the engine to add + //your own stereo adjustment code + extern long stereowidth = 23040; + extern long stereopixelwidth = 28; + + It would be nice to allow the adjustment of these variables + inside the game, but if you're too lazy, it would be nice to + have some way of modifying it. + Please do not extern stereomode any more since I use it now + to uninit the old mode automatically. Use your own current + stereo mode variable. +ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ +10/4/97 - I have upgraded to Watcom 11.0. The only changes I had to make + in the engine were some "#pragma push" and "#pragma pop" + calls in BUILD.H since the default structure packing alignment + was moved from 1 to 8. The sector, wall, and sprite structures + are already aligned well and must remain the same for .MAP + files to remain compatible. + + - Increase MAXTILES for all utilities (EDITART,BUILD,GAME,etc.) to + 9216 for Xatrix. + + You may have some initial bugs with EDITART when you add new + tiles for the first time. I haven't touched the code in years + and I'm afraid if I did, I'd mess it up more. One bug I know + of is this: Let's say you have 256 tiles per art file, and + then you add 1 silly tile way up at picnum=8500. When you + save and quit, your directory may look like this: + + TILES000.ART + TILES001.ART + TILES002.ART + TILES029.ART + + When you load EDITART again, that 1 tile will not appear unless + you kind of mess with it and scroll around for a while. This + is because EDITART loads TILES###.ART files until 1 is not + found, meaning that it will stop when it doesn't find + TILES003.ART. There are probably some other nasty bugs like + this. To get around it, you could add 1 tile to the next file, + save and quit. Or you could use RSIZEART.EXE to make 1 huge + ART file, add 1 tile way up high (if you have enough memory), + and then run RSIZEART.EXE again to 256 tiles per file or + whatever you like. Remember that the ART files need to be split + in such a way that each individual .ART file must fit in + memory, or else EDITART will crash. + + - It's time I document how you can add voxels to the Build engine. + The code is not the cleanest, but at least it works. First + you must load each voxel into memory using the qloadkvx + function. You specify the filename of the .KVX file and an + index that you want to use to reference the voxel. You can + pack .KVX files in a .GRP file if you want. The index must + be in this range: 0 <= index < MAXVOXELS where MAXVOXELS is + currently 512. This index works sort of like a picnum, but I + have a totally separate array for these indeces so you don't + need to mess with your art file at all. Since qloadkvx + allocates memory off of my cacheing system, you must call it + after loadpics which allocates all memory. + + Function parameters: + void qloadkvx(long voxindex, char *filename) + + loadpics("tiles000.art"); + qloadkvx(0L,"voxel000.kvx"); + qloadkvx(1L,"voxel001.kvx"); + + Now to actually display the voxel, you need to set the + (sprite[?].cstat&48) to equal 48 like this: + sprite[?].cstat |= 48; + I have no special collision code for voxels. They are simply + treated as face sprites. + + If ((sprite[?].cstat&48) == 48) + You should set the sprite[?].picnum to equal the VOXEL + index of the voxel that you passed to qloadkvx. If you don't + do this you will see nothing. To handle this index remapping + it is a good idea to make some array like this: + short picnumtovox[MAXTILES]; + and save the array in some file (or in the .GRP file) + + Many other fields of the sprite structure also affect voxels, + such as: ang, shade, pal, xrepeat, yrepeat. + + Note: To view voxels in the Build editor, you will need to do + the same qloadkvx calls in your BSTUB.C. + + And now a warning: Voxels tend to draw the fastest when + they are tall and thin. For example, a telephone poll + would work just great. They slow down very quickly as + you add detail. This is why you don't see any large + voxels in SW and Blood. + + - Something you should know about this version of the engine: + Over the summer, I got a lot of pressure from GT to add + MMX support to the Build engine, so I bought a Pentium II. + I messed around with the code quite a bit and discovered + that MMX really didn't help at all. In fact, in some ways + it made the code slower. The problem is that the inner + loops of Build are already optimized really well. I have + found that MMX is useful only because it gives you extra + registers. Unfortunately, the Build loops don't need extra + registers since they aren't very complex. + Now there are 2 major differences between an old Pentium and + a Pentium II. A Pentium II is like a Pentium PRO with MMX. + So I tried to optimize Build for Pentium PRO's. I was + actually able to get about a 50% speed increase mostly due + to avoiding those awful partial stalls. But there are + SEVERAL catches: + + 1. First of all, you need to enable WRITE-COMBINING for + video memory to get all this extra speed. One popular + program which does this is FASTVID. You should be able + to find it easily on the net. If you do not enable + WRITE-COMBINING, the engine actually runs SLOWER than + the original version! Unfortunately, neither DOS nor + WINDOWS 95 enable WRITE-COMBINING by default, so you need to + load a driver. Even worse, if you're in WINDOWS 95, the + program which enables WRITE-COMBINING will crash because + you can only set the PPRO registers in Priviledge Level 0. + You can still enable WRITE-COMBINING in WINDOWS 95, but you + have to run the program in your AUTOEXEC.BAT file. I wish + you all good luck on getting the average user to be able + to accomplish this feat. Quake has the same problem. + You'll find the same thing in their documentation. + + 2. The second catch is that my code tries to auto-detect + whether you have a Pentium, Pentium MMX, Pentium PRO, of + Pentium II. Of course this means, that if you don't have + an Intel processor, it's possible that the auto-detect code + may crash. I haven't had the opportunity to test this + myself. And since I can never guarantee it will always work + I made a way for you to disable the new code altogether + should this happen. Here's how you disable the new code + in the Build engine: + + extern long dommxoverlay; //(from engine.obj) + + Before you first call initengine, set dommxoverlay = 0; + + The default is dommxoverlay = 1 and it will run the code. diff --git a/polymer/build/doc/buildinf.txt b/polymer/build/doc/buildinf.txt new file mode 100644 index 000000000..06f00bd75 --- /dev/null +++ b/polymer/build/doc/buildinf.txt @@ -0,0 +1,882 @@ +// "Build Engine & Tools" Copyright (c) 1993-1997 Ken Silverman +// Ken Silverman's official web site: "http://www.advsys.net/ken" +// See the included license file "BUILDLIC.TXT" for license info. + +Build information to get you started: + +The first half of this file explains the .ART, .MAP, and PALETTE.DAT formats. +The second half has documentation about every BUILD engine function, what it + does, and what the parameters are. + +-Ken S. + +------------------------------------------------------------------------------ +Documentation on Ken's .ART file format by Ken Silverman + + I am documenting my ART format to allow you to program your own custom +art utilites if you so desire. I am still planning on writing the script +system. + + All art files must have xxxxx###.ART. When loading an art file you +should keep trying to open new xxxxx###'s, incrementing the number, until +an art file is not found. + + +1. long artversion; + + The first 4 bytes in the art format are the version number. The current + current art version is now 1. If artversion is not 1 then either it's the + wrong art version or something is wrong. + +2. long numtiles; + + Numtiles is not really used anymore. I wouldn't trust it. Actually + when I originally planning art version 1 many months ago, I thought I + would need this variable, but it turned it is was unnecessary. To get + the number of tiles, you should search all art files, and check the + localtilestart and localtileend values for each file. + +3. long localtilestart; + + Localtilestart is the tile number of the first tile in this art file. + +4. long localtileend; + + Localtileend is the tile number of the last tile in this art file. + Note: Localtileend CAN be higher than the last used slot in an art + file. + + Example: If you chose 256 tiles per art file: + TILES000.ART -> localtilestart = 0, localtileend = 255 + TILES001.ART -> localtilestart = 256, localtileend = 511 + TILES002.ART -> localtilestart = 512, localtileend = 767 + TILES003.ART -> localtilestart = 768, localtileend = 1023 + +5. short tilesizx[localtileend-localtilestart+1]; + + This is an array of shorts of all the x dimensions of the tiles + in this art file. If you chose 256 tiles per art file then + [localtileend-localtilestart+1] should equal 256. + +6. short tilesizy[localtileend-localtilestart+1]; + + This is an array of shorts of all the y dimensions. + +7. long picanm[localtileend-localtilestart+1]; + + This array of longs stores a few attributes for each tile that you + can set inside EDITART. You probably won't be touching this array, but + I'll document it anyway. + + Bit: |31 24|23 16|15 8|7 0| + ----------------------------------------------------------------- + | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | + ----------------------------------------------------------------- + | Anim. | Signed char | Signed char | | Animate | + | Speed | Y-center | X-center | | number | + --------| offset | offset | |------------ + --------------------------------| ------------ + | Animate type:| + | 00 - NoAnm | + | 01 - Oscil | + | 10 - AnmFd | + | 11 - AnmBk | + ---------------- + You probably recognize these: + Animate speed - EDITART key: 'A', + and - to adjust + Signed char x&y offset - EDITART key: '`', Arrows to adjust + Animate number&type - EDITART key: +/- on keypad + +8. After the picanm's, the rest of the file is straight-forward rectangular + art data. You must go through the tilesizx and tilesizy arrays to find + where the artwork is actually stored in this file. + + Note: The tiles are stored in the opposite coordinate system than + the screen memory is stored. Example on a 4*4 file: + + Offsets: + ----------------- + | 0 | 4 | 8 |12 | + ----------------- + | 1 | 5 | 9 |13 | + ----------------- + | 2 | 6 |10 |14 | + ----------------- + | 3 | 7 |11 |15 | + ----------------- + + + +---------------------------------------------------------------------------- + If you wish to display the artwork, you will also need to load your +palette. To load the palette, simply read the first 768 bytes of your +palette.dat and write it directly to the video card - like this: + + Example: + long i, fil; + + fil = open("palette.dat",O_BINARY|O_RDWR,S_IREAD); + read(fil,&palette[0],768); + close(fil); + + outp(0x3c8,0); + for(i=0;i<768;i++) + outp(0x3c9,palette[i]); +------------------------------------------------------------------------------ + +Packet format for DUKE3D (specifically for network mode 1, n(n-1) mode): + +Example bunch of packets: +A B C D E F G H I J K L M N... O +--------------------------------------------------------------------- +d9 00 d9 11 01 00 - - - - - - - - - - 4f 16 31 +da 00 da 11 01 00 - - - - - - - - - - b2 b7 9d +db 00 db 11 01 00 - - - - - - - - - - b1 24 62 +dc 00 dc 11 01 00 - - - - - - - - - - ca 1d 58 +dd 00 dd 11 01 00 - - - - - - - - - - a9 94 14 +de 00 de 11 01 05 00 00 - - 03 00 - - - - c5 50 b9 +df 00 df 11 01 0f a1 ff fe 09 00 00 26 - - - e2 88 6f +e0 00 e0 11 01 04 - - - - fd ff - - - - 77 51 d7 +e1 00 e1 11 01 03 1f 00 ff 09 - - - - - - ac 14 b7 +e2 00 e2 11 01 0b 9c 00 fb 09 - - 24 - - - f8 6c 22 + +GAME sends fields D-N +MMULTI adds fields A-C and O for error correction. + +A: Packet count sending modulo 256 +B: Error state. Usually 0. To request a resend, bit 0 is set. In order + to catch up on networks, sending many packets is bad, so 2 packets + are sent in 1 IPX packet. To send 2 packets in 1 packet, bit 1 is set. + In special cases, this value may be different. +C: Packet count receiving modulo 256 + +D: Message header byte. These are all the possible values currently. You + are probably only interested in case 17. Note that fields E-N apply + to case 17 only. + 0: send movement info from master to slave (network mode 0 only) + 1: send movement info from slave to master (network mode 0 only) + 4: user-typed messages + 5: Re-start level with given parameters + 6: Send player name + 7: Play Remote Ridicule sound + 8: Re-start level with given parameters for a user map + 17: send movement info to everybody else (network mode 1 only) + 250: Wait for Everybody (Don't start until everybody's done loading) + 255: Player quit to DOS + +E: Timing byte used to calculate lag time. This prevents the 2 computer's + timers from drifting apart. + +F: Bits field byte. Fields G-M are sent only when certain bits + in this byte are set. + +G: X momentum update (2 bytes). Sent only if ((F&1) != 0) + +H: Y momentum update (2 bytes). Sent only if ((F&2) != 0) + +I: Angle momentum update (2 bytes). Sent only if ((F&4) != 0) + +J: The states of 8 different keys (1 byte). Sent only if ((F&8) != 0) +K: The states of 8 different keys (1 byte). Sent only if ((F&16) != 0) +L: The states of 8 different keys (1 byte). Sent only if ((F&32) != 0) +M: The states of 8 different keys (1 byte). Sent only if ((F&64) != 0) + +N: Sync checking byte. Useful for debugging programming errors. Can be a + variable number of bytes. Actual number of sync checking bytes is + calculated by length of the whole packet minus the rest of the bytes sent. + +O: CRC-16 + +------------------------------------------------------------------------------ +| @@@@@@@@@@@ @@@ @@@ @@@@@@@@@ @@@ @@@@@@@@@ | +| @@@@@@@@@@@@@ @@@ @@@ @@@@@@@@@ @@@ @@@@@@@@@@@ | +| @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@@@ | +| @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@@ | +| @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ | +| @@@@@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@ | +| @@@@@@@@@@@@@ @@@ @@@ @@@ @@@ @@@ @@@ | +| @@@ @@@@ @@@ @@@ @@@ @@@ @@@ @@@ | +| @@@ @@@ @@@ @@@ @@@ @@@ @@@ @@@@ | +| @@@ @@@@ @@@@ @@@@ @@@ @@@ @@@ @@@@@ | +| @@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@@@ | +| @@@@@@@@@@@ @@@@@@@ @@@@@@@@@ @@@@@@@@@@@@ @@@@@@@@@ | +| | +| M A P F O R M A T ! | +------------------------------------------------------------------------------ + +Here is Ken's documentation on the COMPLETE BUILD map format: +BUILD engine and editor programmed completely by Ken Silverman + +Here's how you should read a BUILD map file: +{ + fil = open(???); + + //Load map version number (current version is 7L) + read(fil,&mapversion,4); + + //Load starting position + read(fil,posx,4); + read(fil,posy,4); + read(fil,posz,4); //Note: Z coordinates are all shifted up 4 + read(fil,ang,2); //All angles are from 0-2047, clockwise + read(fil,cursectnum,2); //Sector of starting point + + //Load all sectors (see sector structure described below) + read(fil,&numsectors,2); + read(fil,§or[0],sizeof(sectortype)*numsectors); + + //Load all walls (see wall structure described below) + read(fil,&numwalls,2); + read(fil,&wall[0],sizeof(walltype)*numwalls); + + //Load all sprites (see sprite structure described below) + read(fil,&numsprites,2); + read(fil,&sprite[0],sizeof(spritetype)*numsprites); + + close(fil); +} + + ------------------------------------------------------------- + | @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@@ @@@@@@@ @@@@@@@ @@@@@@@ | + | @@ @@ @@ @@ @@ @@ @@ @@@ @@ | + | @@@@@@@ @@@@@ @@ @@ @@ @@ @@@@@@@ @@@@@@@ | + | @@ @@ @@ @@ @@ @@ @@ @@@ @@ | + | @@@@@@@ @@@@@@@ @@@@@@@ @@ @@@@@@@ @@ @@ @@@@@@@ | + ------------------------------------------------------------- + + //sizeof(sectortype) = 40 +typedef struct +{ + short wallptr, wallnum; + long ceilingz, floorz; + short ceilingstat, floorstat; + short ceilingpicnum, ceilingheinum; + signed char ceilingshade; + char ceilingpal, ceilingxpanning, ceilingypanning; + short floorpicnum, floorheinum; + signed char floorshade; + char floorpal, floorxpanning, floorypanning; + char visibility, filler; + short lotag, hitag, extra; +} sectortype; +sectortype sector[1024]; + +wallptr - index to first wall of sector +wallnum - number of walls in sector +z's - z coordinate (height) of ceiling / floor at first point of sector +stat's + bit 0: 1 = parallaxing, 0 = not "P" + bit 1: 1 = sloped, 0 = not + bit 2: 1 = swap x&y, 0 = not "F" + bit 3: 1 = double smooshiness "E" + bit 4: 1 = x-flip "F" + bit 5: 1 = y-flip "F" + bit 6: 1 = Align texture to first wall of sector "R" + bits 7-15: reserved +picnum's - texture index into art file +heinum's - slope value (rise/run) (0-parallel to floor, 4096-45 degrees) +shade's - shade offset of ceiling/floor +pal's - palette lookup table number (0 - use standard colors) +panning's - used to align textures or to do texture panning +visibility - determines how fast an area changes shade relative to distance +filler - useless byte to make structure aligned +lotag, hitag, extra - These variables used by the game programmer only + + + ----------------------------------------------- + | @@ @@ @@@@@@@@ @@ @@ @@@@@@@ | + | @@ @@ @@ @@ @@ @@ @@ | + | @@ @@ @@ @@@@@@@@ @@ @@ @@@@@@@ | + | @@ @@@@ @@ @@ @@ @@ @@ @@ | + | @@@ @@@@ @@ @@ @@@@@@@ @@@@@@@ @@@@@@@ | + ----------------------------------------------| + + //sizeof(walltype) = 32 +typedef struct +{ + long x, y; + short point2, nextwall, nextsector, cstat; + short picnum, overpicnum; + signed char shade; + char pal, xrepeat, yrepeat, xpanning, ypanning; + short lotag, hitag, extra; +} walltype; +walltype wall[8192]; + +x, y: Coordinate of left side of wall, get right side from next wall's left side +point2: Index to next wall on the right (always in the same sector) +nextwall: Index to wall on other side of wall (-1 if there is no sector) +nextsector: Index to sector on other side of wall (-1 if there is no sector) +cstat: + bit 0: 1 = Blocking wall (use with clipmove, getzrange) "B" + bit 1: 1 = bottoms of invisible walls swapped, 0 = not "2" + bit 2: 1 = align picture on bottom (for doors), 0 = top "O" + bit 3: 1 = x-flipped, 0 = normal "F" + bit 4: 1 = masking wall, 0 = not "M" + bit 5: 1 = 1-way wall, 0 = not "1" + bit 6: 1 = Blocking wall (use with hitscan / cliptype 1) "H" + bit 7: 1 = Transluscence, 0 = not "T" + bit 8: 1 = y-flipped, 0 = normal "F" + bit 9: 1 = Transluscence reversing, 0 = normal "T" + bits 10-15: reserved +picnum - texture index into art file +overpicnum - texture index into art file for masked walls / 1-way walls +shade - shade offset of wall +pal - palette lookup table number (0 - use standard colors) +repeat's - used to change the size of pixels (stretch textures) +pannings - used to align textures or to do texture panning +lotag, hitag, extra - These variables used by the game programmer only + + ------------------------------------------------------------- + | @@@@@@@ @@@@@@@ @@@@@@@ @@@@@@ @@@@@@@@ @@@@@@@ @@@@@@@ | + | @@ @@ @@ @@ @@@ @@ @@ @@ @@ | + | @@@@@@@ @@@@@@@ @@@@@@@ @@ @@ @@@@@ @@@@@@@ | + | @@ @@ @@ @@ @@ @@ @@ @@ | + | @@@@@@@ @@ @@ @@ @@@@@@ @@ @@@@@@@ @@@@@@@ | + ------------------------------------------------------------- + + //sizeof(spritetype) = 44 +typedef struct +{ + long x, y, z; + short cstat, picnum; + signed char shade; + char pal, clipdist, filler; + unsigned char xrepeat, yrepeat; + signed char xoffset, yoffset; + short sectnum, statnum; + short ang, owner, xvel, yvel, zvel; + short lotag, hitag, extra; +} spritetype; +spritetype sprite[4096]; +x, y, z - position of sprite - can be defined at center bottom or center +cstat: + bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B" + bit 1: 1 = transluscence, 0 = normal "T" + bit 2: 1 = x-flipped, 0 = normal "F" + bit 3: 1 = y-flipped, 0 = normal "F" + bits 5-4: 00 = FACE sprite (default) "R" + 01 = WALL sprite (like masked walls) + 10 = FLOOR sprite (parallel to ceilings&floors) + bit 6: 1 = 1-sided sprite, 0 = normal "1" + bit 7: 1 = Real centered centering, 0 = foot center "C" + bit 8: 1 = Blocking sprite (use with hitscan / cliptype 1) "H" + bit 9: 1 = Transluscence reversing, 0 = normal "T" + bits 10-14: reserved + bit 15: 1 = Invisible sprite, 0 = not invisible +picnum - texture index into art file +shade - shade offset of sprite +pal - palette lookup table number (0 - use standard colors) +clipdist - the size of the movement clipping square (face sprites only) +filler - useless byte to make structure aligned +repeat's - used to change the size of pixels (stretch textures) +offset's - used to center the animation of sprites +sectnum - current sector of sprite +statnum - current status of sprite (inactive/monster/bullet, etc.) + +ang - angle the sprite is facing +owner, xvel, yvel, zvel, lotag, hitag, extra - These variables used by the + game programmer only +------------------------------------------------------------------------------ + + + + +----------------------------------------------------------------------------- +| IMPORTANT ENGINE FUNCTIONS: | +----------------------------------------------------------------------------- + +initengine() + Initializes many variables for the BUILD engine. You should call this + once before any other functions of the BUILD engine are used. + +uninitengine(); + Frees buffers. You should call this once at the end of the program + before quitting to dos. + +loadboard(char *filename, long *posx, long *posy, long *posz, short *ang, short *cursectnum) +saveboard(char *filename, long *posx, long *posy, long *posz, short *ang, short *cursectnum) + Loads/saves the given board file from memory. Returns -1 if file not + found. If no extension is given, .MAP will be appended to the filename. + +loadpics(char *filename); + Loads the given artwork file into memory for the BUILD engine. + Returns -1 if file not found. If no extension is given, .ART will + be appended to the filename. + +loadtile(short tilenum) + Loads a given tile number from disk into memory if it is not already in + memory. This function calls allocache internally. A tile is not in the + cache if (waloff[tilenum] == 0) + +----------------------------------------------------------------------------- +| SCREEN STATUS FUNCTIONS: | +----------------------------------------------------------------------------- + +setgamemode(char vidoption, long xdim, long ydim); + This function sets the video mode to 320*200*256color graphics. + Since BUILD supports several different modes including mode x, + mode 13h, and other special modes, I don't expect you to write + any graphics output functions. (Soon I have all the necessary + functions) If for some reason, you use your own graphics mode, + you must call this function again before using the BUILD drawing + functions. + + vidoption can be anywhere from 0-6 + xdim,ydim can be any vesa resolution if vidoption = 1 + xdim,ydim must be 320*200 for any other mode. + (see graphics mode selection in my setup program) + +setview(long x1, long y1, long x2, long y2) + Sets the viewing window to a given rectangle of the screen. + Example: For full screen 320*200, call like this: setview(0L,0L,319L,199L); + +nextpage(); + This function flips to the next video page. After a screen is prepared, + use this function to view the screen. + +----------------------------------------------------------------------------- +| DRAWING FUNCTIONS: | +----------------------------------------------------------------------------- + +drawrooms(long posx, long posy, long posz, short ang, long horiz, short cursectnum) + This function draws the 3D screen to the current drawing page, + which is not yet shown. This way, you can overwrite some things + over the 3D screen such as a gun. Be sure to call the drawmasks() + function soon after you call the drawrooms() function. To view + the screen, use the nextpage() function. The nextpage() function + should always be called sometime after each draw3dscreen() + function. + +drawmasks(); + This function draws all the sprites and masked walls to the current + drawing page which is not yet shown. The reason I have the drawing + split up into these 2 routines is so you can animate just the + sprites that are about to be drawn instead of having to animate + all the sprites on the whole board. Drawrooms() prepares these + variables: spritex[], spritey[], spritepicnum[], thesprite[], + and spritesortcnt. Spritesortcnt is the number of sprites about + to be drawn to the page. To change the sprite's picnum, simply + modify the spritepicnum array If you want to change other parts + of the sprite structure, then you can use the thesprite array to + get an index to the actual sprite number. + +clearview(long col) + Clears the current video page to the given color + +clearallviews(long col) + Clears all video pages to the given color + +drawmapview (long x, long y, long zoom, short ang) + Draws the 2-D texturized map at the given position into the viewing window. + +rotatesprite (long sx, long sy, long z, short a, short picnum, + signed char dashade, char dapalnum, char dastat, + long cx1, long cy1, long cx2, long cy2) + (sx, sy) is the center of the sprite to draw defined as + screen coordinates shifted up by 16. + (z) is the zoom. Normal zoom is 65536. + Ex: 131072 is zoomed in 2X and 32768 is zoomed out 2X. + (a) is the angle (0 is straight up) + (picnum) is the tile number + (dashade) is 0 normally but can be any standard shade up to 31 or 63. + (dapalnum) can be from 0-255. + if ((dastat&1) == 0) - no transluscence + if ((dastat&1) != 0) - transluscence + if ((dastat&2) == 0) - don't scale to setview's viewing window + if ((dastat&2) != 0) - scale to setview's viewing window (windowx1,etc.) + if ((dastat&4) == 0) - nuttin' special + if ((dastat&4) != 0) - y-flip image + if ((dastat&8) == 0) - clip to startumost/startdmost + if ((dastat&8) != 0) - don't clip to startumost/startdmost + if ((dastat&16) == 0) - use Editart center as point passed + if ((dastat&16) != 0) - force point passed to be top-left corner + if ((dastat&32) == 0) - nuttin' special + if ((dastat&32) != 0) - use reverse transluscence + if ((dastat&64) == 0) - masked drawing (check 255's) (slower) + if ((dastat&64) != 0) - draw everything (don't check 255's) (faster) + if ((dastat&128) == 0) - nuttin' special + if ((dastat&128) != 0) - automatically draw to all video pages + + Note: As a special case, if both ((dastat&2) != 0) and ((dastat&8) != 0) + then rotatesprite will scale to the full screen (0,0,xdim-1,ydim-1) + rather than setview's viewing window. (windowx1,windowy1,etc.) This + case is useful for status bars, etc. + + Ex: rotatesprite(160L<<16,100L<<16,65536,totalclock<<4, + DEMOSIGN,2,50L,50L,270L,150L); + This example will draw the DEMOSIGN tile in the center of the + screen and rotate about once per second. The sprite will only + get drawn inside the rectangle from (50,50) to (270,150) + +drawline256(long x1, long y1, long x2, long y2, char col) + Draws a solid line from (x1,y1) to (x2,y2) with color (col) + For this function, screen coordinates are all shifted up 16 for precision. + +printext256(long xpos, long ypos, short col, short backcol, + char *message, char fontsize) + Draws a text message to the screen. + (xpos,ypos) - position of top left corner + col - color of text + backcol - background color, if -1, then background is transparent + message - text message + fontsize - 0 - 8*8 font + 1 - 4*6 font + +----------------------------------------------------------------------------- +| MOVEMENT COLLISION FUNCTIONS: | +----------------------------------------------------------------------------- + +clipmove(long *x, long *y, long *z, short *sectnum, long xvect, long yvect, + long walldist, long ceildist, long flordist, unsigned long cliptype) + Moves any object (x, y, z) in any direction at any velocity and will + make sure the object will stay a certain distance from walls (walldist) + Pass the pointers of the starting position (x, y, z). Then + pass the starting position's sector number as a pointer also. + Also these values will be modified accordingly. Pass the + direction and velocity by using a vector (xvect, yvect). + If you don't fully understand these equations, please call me. + xvect = velocity * cos(angle) + yvect = velocity * sin(angle) + Walldist tells how close the object can get to a wall. I use + 128L as my default. If you increase walldist all of a sudden + for a certain object, the object might leak through a wall, so + don't do that! + Cliptype is a mask that tells whether the object should be clipped + to or not. The lower 16 bits are anded with wall[].cstat and the higher + 16 bits are anded with sprite[].cstat. + + Clipmove can either return 0 (touched nothing) + 32768+wallnum (wall first touched) + 49152+spritenum (sprite first touched) + +pushmove (long *x, long *y, long *z, short *sectnum, + long walldist, long ceildist, long flordist, unsigned long cliptype) + This function makes sure a player or monster (defined by x, y, z, sectnum) + is not too close to a wall. If it is, then it attempts to push it away. + If after 256 tries, it is unable to push it away, it returns -1, in which + case the thing should gib. + +getzrange(long x, long y, long z, short sectnum, + long *ceilz, long *ceilhit, + long *florz, long *florhit, + long walldist, unsigned long cliptype) + + Use this in conjunction with clipmove. This function will keep the + player from falling off cliffs when you're too close to the edge. This + function finds the highest and lowest z coordinates that your clipping + BOX can get to. It must search for all sectors (and sprites) that go + into your clipping box. This method is better than using + sector[cursectnum].ceilingz and sector[cursectnum].floorz because this + searches the whole clipping box for objects, not just 1 point. + Pass x, y, z, sector normally. Walldist can be 128. Cliptype is + defined the same way as it is for clipmove. This function returns the + z extents in ceilz and florz. It will return the object hit in ceilhit + and florhit. Ceilhit and florhit will also be either: + 16384+sector (sector first touched) or + 49152+spritenum (sprite first touched) + +hitscan(long xstart, long ystart, long zstart, short startsectnum, + long vectorx, long vectory, long vectorz, + short *hitsect, short *hitwall, short *hitsprite, + long *hitx, long *hity, long *hitz); + + Pass the starting 3D position: + (xstart, ystart, zstart, startsectnum) + Then pass the 3D angle to shoot (defined as a 3D vector): + (vectorx, vectory, vectorz) + Then set up the return values for the object hit: + (hitsect, hitwall, hitsprite) + and the exact 3D point where the ray hits: + (hitx, hity, hitz) + + How to determine what was hit: + * Hitsect is always equal to the sector that was hit (always >= 0). + + * If the ray hits a sprite then: + hitsect = thesectornumber + hitsprite = thespritenumber + hitwall = -1 + + * If the ray hits a wall then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = thewallnumber + + * If the ray hits the ceiling of a sector then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = -1 + vectorz < 0 + (If vectorz < 0 then you're shooting upward which means + that you couldn't have hit a floor) + + * If the ray hits the floor of a sector then: + hitsect = thesectornumber + hitsprite = -1 + hitwall = -1 + vectorz > 0 + (If vectorz > 0 then you're shooting downard which means + that you couldn't have hit a ceiling) + +neartag(long x, long y, long z, short sectnum, short ang, //Starting position & angle + short *neartagsector, //Returns near sector if sector[].tag != 0 + short *neartagwall, //Returns near wall if wall[].tag != 0 + short *neartagsprite, //Returns near sprite if sprite[].tag != 0 + long *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size) + long neartagrange, //Choose maximum distance to scan (scale: 1024=largest grid size) + char tagsearch) //1-lotag only, 2-hitag only, 3-lotag&hitag + Neartag works sort of like hitscan, but is optimized to + scan only close objects and scan only objects with + tags != 0. Neartag is perfect for the first line of your space bar code. + It will tell you what door you want to open or what switch you want to + flip. + +cansee(long x1, long y1, long z1, short sectnum1, + long x2, long y2, long z2, short sectnum2); returns 0 or 1 + This function determines whether or not two 3D points can "see" each + other or not. All you do is pass it the coordinates of a 3D line defined + by two 3D points (with their respective sectors) The function will return + a 1 if the points can see each other or a 0 if there is something blocking + the two points from seeing each other. This is how I determine whether a + monster can see you or not. Try playing DOOM1.DAT to fully enjoy this + great function! + +updatesector(long x, long y, §num); + This function updates the sector number according to the x and y values + passed to it. Be careful when you use this function with sprites because + remember that the sprite's sector number should not be modified directly. + If you want to update a sprite's sector, I recomment using the setsprite + function described below. + +inside(long x, long y, short sectnum); + Tests to see whether the overhead point (x, y) is inside sector (sectnum) + Returns either 0 or 1, where 1 means it is inside, and 0 means it is not. + +clipinsidebox(long x, long y, short wallnum, long walldist) + Returns TRUE only if the given line (wallnum) intersects the square with + center (x,y) and radius, walldist. + +dragpoint(short wallnum, long newx, long newy); + This function will drag a point in the exact same way a point is dragged + in 2D EDIT MODE using the left mouse button. Simply pass it which wall + to drag and then pass the new x and y coordinates for that point. + Please use this function because if you don't and try to drag points + yourself, I can guarantee that it won't work as well as mine and you + will get confused. Note: Every wall of course has 2 points. When you + pass a wall number to this function, you are actually passing 1 point, + the left side of the wall (given that you are in the sector of that wall) + Got it? + +----------------------------------------------------------------------------- +| MATH HELPER FUNCTIONS: | +----------------------------------------------------------------------------- + +krand() + Random number function - returns numbers from 0-65535 + +ksqrt(long num) + Returns the integer square root of the number. + +getangle(long xvect, long yvect) + Gets the angle of a vector (xvect,yvect) + These are 2048 possible angles starting from the right, going clockwise + +rotatepoint(long xpivot, long ypivot, long x, long y, + short daang, long *x2, long *y2); + This function is a very convenient and fast math helper function. + Rotate points easily with this function without having to juggle your + cosines and sines. Simply pass it: + + Input: 1. Pivot point (xpivot,ypivot) + 2. Original point (x,y) + 3. Angle to rotate (0 = nothing, 512 = 90ø CW, etc.) + Output: 4. Rotated point (*x2,*y2) + +lastwall(short point); + Use this function as a reverse function of wall[].point2. In order + to save memory, my walls are only on a single linked list. + +nextsectorneighborz(short sectnum, long thez, short topbottom, short direction) + This function is used to tell where elevators should stop. It searches + nearby sectors for the next closest ceilingz or floorz it should stop at. + sectnum - elevator sector + thez - current z to start search from + topbottom - search ceilingz's/floorz's only + direction - search upwards/downwards + +getceilzofslope(short sectnum, long x, long y) +getflorzofslope(short sectnum, long x, long y) +getzsofslope(short sectnum, long x, long y, long *ceilz, long *florz) + These 3 functions get the height of a ceiling and/or floor in a sector + at any (x,y) location. Use getzsofslope only if you need both the ceiling + and floor. + +alignceilslope(short sectnum, long x, long y, long z) +alignflorslope(short sectnum, long x, long y, long z) + Given a sector and assuming it's first wall is the pivot wall of the slope, + this function makes the slope pass through the x,y,z point. One use of + this function is used for sin-wave floors. + +----------------------------------------------------------------------------- +| SPRITE FUNCTIONS: | +----------------------------------------------------------------------------- + +insertsprite(short sectnum, short statnum); //returns (short)spritenum; + Whenever you insert a sprite, you must pass it the sector + number, and a status number (statnum). The status number can be any + number from 0 to MAXSTATUS-1. Insertsprite works like a memory + allocation function and returns the sprite number. + +deletesprite(short spritenum); + Deletes the sprite. + +changespritesect(short spritenum, short newsectnum); + Changes the sector of sprite (spritenum) to the + newsector (newsectnum). This function may become + internal to the engine in the movesprite function. But + this function is necessary since all the sectors have + their own doubly-linked lists of sprites. + +changespritestat(short spritenum, short newstatnum); + Changes the status of sprite (spritenum) to status + (newstatus). Newstatus can be any number from 0 to MAXSTATUS-1. + You can use this function to put a monster on a list of active sprites + when it first sees you. + +setsprite(short spritenum, long newx, long newy, long newz); + This function simply sets the sprite's position to a specified + coordinate (newx, newy, newz) without any checking to see + whether the position is valid or not. You could directly + modify the sprite[].x, sprite[].y, and sprite[].z values, but + if you use my function, the sprite is guaranteed to be in the + right sector. + +----------------------------------------------------------------------------- +| CACHE FUNCTIONS: | +----------------------------------------------------------------------------- +initcache(long dacachestart, long dacachesize) + First allocate a really large buffer (as large as possible), then pass off + the memory bufer the initcache + dacachestart: 32-bit offset in memory of start of cache + dacachesize: number of bytes that were allocated for the cache to use + +allocache (long *bufptr, long bufsiz, char *lockptr) + *bufptr = pointer to 4-byte pointer to buffer. This + allows allocache to remove previously allocated things + from the cache safely by setting the 4-byte pointer to 0. + bufsiz = number of bytes to allocate + *lockptr = pointer to locking char which tells whether + the region can be removed or not. If *lockptr = 0 then + the region is not locked else its locked. + +----------------------------------------------------------------------------- +| GROUP FILE FUNCTIONS: | +----------------------------------------------------------------------------- +initgroupfile(char *filename) + Tells the engine what the group file name is. + You should call this before any of the following group file functions. +uninitgroupfile() + Frees buffers. You should call this once at the end of the program + before quitting to dos. + +kopen4load(char *filename, char searchfirst) + Open a file. First tries to open a stand alone file. Then searches for + it in the group file. If searchfirst is nonzero, it will check the group + file only. + +kread(long handle, void *buffer, long leng) +klseek(long handle, long offset, long whence) +kfilelength(long handle) +kclose(long handle) + These 4 functions simply shadow the dos file functions - they + can do file I/O on the group file in addition to stand-along files. + +----------------------------------------------------------------------------- +| COMMUNICATIONS FUNCTIONS: | +----------------------------------------------------------------------------- + Much of the following code is to keep compatibity with older network code: + +initmultiplayers(char damultioption, char dacomrateoption, char dapriority) + The parameters are ignored - just pass 3 0's +uninitmultiplayers() Does nothing + +sendpacket(long other, char *bufptr, long messleng) + other - who to send the packet to + bufptr - pointer to message to send + messleng - length of message +short getpacket (short *other, char *bufptr) + returns the number of bytes of the packet received, 0 if no packet + other - who the packet was received from + bufptr - pointer to message that was received + +sendlogon() Does nothing +sendlogoff() + Sends a packet to everyone else where the + first byte is 255, and the + second byte is myconnectindex + +getoutputcirclesize() Does nothing - just a stub function, returns 0 +setsocket(short newsocket) Does nothing + +flushpackets() + Clears all packet buffers +genericmultifunction(long other, char *bufptr, long messleng, long command) + Passes a buffer to the commit driver. This command provides a gateway + for game programmer to access COMMIT directly. + +----------------------------------------------------------------------------- +| PALETTE FUNCTIONS: | +----------------------------------------------------------------------------- +VBE_setPalette(long start, long num, char *palettebuffer) +VBE_getPalette(long start, long num, char *palettebuffer) + Set (num) palette palette entries starting at (start) + palette entries are in a 4-byte format in this order: + 0: Blue (0-63) + 1: Green (0-63) + 2: Red (0-63) + 3: Reserved + +makepalookup(long palnum, char *remapbuf, + signed char r, signed char g, signed char b, + char dastat) + This function allows different shirt colors for sprites. First prepare + remapbuf, which is a 256 byte buffer of chars which the colors to remap. + Palnum can be anywhere from 1-15. Since 0 is where the normal palette is + stored, it is a bad idea to call this function with palnum=0. + In BUILD.H notice I added a new variable, spritepal[MAXSPRITES]. + Usually the value of this is 0 for the default palette. But if you + change it to the palnum in the code between drawrooms() and drawmasks + then the sprite will be drawn with that remapped palette. The last 3 + parameters are the color that the palette fades to as you get further + away. This color is normally black (0,0,0). White would be (63,63,63). + if ((dastat&1) == 0) then makepalookup will allocate & deallocate + the memory block for use but will not waste the time creating a palookup + table (assuming you will create one yourself) + +setbrightness(char gammalevel, char *dapal) + Use this function to adjust for gamma correction. + Gammalevel - ranges from 0-15, 0 is darkest, 15 brightest. Default: 0 + dapal: standard VGA palette (768 bytes) + +------------------------------------------------------------------------------ +| This document brought to you by: | +| | +| @@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@ @@@@@@ | +| @@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@@@@@ @@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@@ @@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@@@ @@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@ @@@@@@@@@@@@@ @@@@@@ | +| @@@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@ @@@@@@@ @@@@@@ | +| @@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@ @@@@@@@ @@@@@@ | +| @@@@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@@@ @@@@@@@ @@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@ @@@@@@ @@@@@@@@@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@ @@@@@@ @@@@@@@@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@ @@@@@@ @@@@@@@@@@@ | +| @@@@@@ @@@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@@ | +| @@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@@ | +| @@@@@@ @@@@@@ @@@@@@@@@@@@@@@@@@ @@@@@@ @@@@@@@@ | +| | +| Ken Silverman of East Greenwich, RI USA | +------------------------------------------------------------------------------