ENGINE.H 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524
  1. #ifndef __ENGINE_H
  2. #define __ENGINE_H
  3. #include <stddef.h>
  4. #include "typedefs.h"
  5. #define kMaxSectors 1024
  6. #define kMaxWalls 8192
  7. #define kMaxSprites 4096
  8. #define kMaxTiles 4096
  9. #define kMaxStatus 1024
  10. #define kMaxViewSprites 1024
  11. #define MAXXDIM 1600 // 640
  12. #define MAXYDIM 1200 // 480
  13. #define MAXPALOOKUPS 256
  14. #define kMaxSkyTiles 256
  15. // Hit definitions
  16. #define kHitTypeMask 0xE000
  17. #define kHitIndexMask 0x1FFF
  18. #define kHitFloor 0x4000
  19. #define kHitSector 0x4000
  20. #define kHitCeiling 0x6000
  21. #define kHitWall 0x8000
  22. #define kHitSprite 0xC000
  23. // SearchStat definitions
  24. #define SS_CUSTOM -2
  25. #define SS_ALL -1
  26. #define SS_WALL 0
  27. #define SS_CEILING 1
  28. #define SS_FLOOR 2
  29. #define SS_SPRITE 3
  30. #define SS_MASKED 4
  31. #define SS_FLATSPRITE 5
  32. #define SS_SECTOR 6
  33. // Shade definitions
  34. #define kMinShade 127
  35. #define kMaxShade -128
  36. /***********************************************************************
  37. * Structures and typedefs
  38. **********************************************************************/
  39. struct SECTOR
  40. {
  41. short wallptr;
  42. short wallnum;
  43. long ceilingz;
  44. long floorz;
  45. ushort ceilingstat;
  46. ushort floorstat;
  47. sshort ceilingpicnum;
  48. sshort ceilingslope;
  49. schar ceilingshade;
  50. uchar ceilingpal;
  51. uchar ceilingxpanning, ceilingypanning;
  52. sshort floorpicnum;
  53. sshort floorslope;
  54. schar floorshade;
  55. uchar floorpal;
  56. uchar floorxpanning, floorypanning;
  57. uchar visibility;
  58. uchar filler;
  59. ushort type;
  60. short hitag;
  61. short extra;
  62. };
  63. //cstat, bit 0: 1 = parallaxed, 0 = not "P"
  64. // bit 1: 1 = sloped, 0 = not
  65. // bit 2: 1 = swap texture x&y, 0 = not "F"
  66. // bit 3: 1 = texture smoosh, 0 = not "E"
  67. // bit 4: 1 = texture x-flip "F"
  68. // bit 5: 1 = texture y-flip "F"
  69. // bit 6: 1 = Rel-aligned to 1st wall "R"
  70. // bit 15: 1 = Force sprite to floor shade "L" (floorstat only: primarily used in shaded/parallaxed areas)
  71. enum {
  72. kSectorParallax = 0x01,
  73. kSectorSloped = 0x02,
  74. kSectorSwapXY = 0x04,
  75. kSectorExpand = 0x08,
  76. kSectorFlipX = 0x10,
  77. kSectorFlipY = 0x20,
  78. kSectorFlipMask = 0x34,
  79. kSectorRelAlign = 0x40,
  80. kSectorFloorShade = 0x8000
  81. };
  82. struct WALL
  83. {
  84. long x, y;
  85. short point2; // right vertex of wall
  86. short nextwall; // wall on other side (-1 if single sided)
  87. short nextsector; // sector on other side (-1 if single sided)
  88. ushort cstat;
  89. short picnum, overpicnum;
  90. schar shade;
  91. uchar pal, xrepeat, yrepeat, xpanning, ypanning;
  92. ushort type;
  93. short hitag, extra;
  94. };
  95. /* wall cstat bits
  96. bit 0: 1 = Blocking wall (use with clipmove, egetzrange) "B"
  97. bit 1: 1 = bottoms of walls swapped, 0 = not "2"
  98. bit 2: 1 = align picture on bottom (for doors), 0 = top "O"
  99. bit 3: 1 = x-flipped, 0 = normal "F"
  100. bit 4: 1 = masking wall, 0 = not "M"
  101. bit 5: 1 = 1-way wall, 0 = not "1"
  102. bit 6: 1 = Blocking wall (use with hitscan) "H"
  103. bit 7: 1 = Transluscent, 0 = not "T"
  104. bit 8: 1 = y-flipped, 0 = normal "F"
  105. bit 9: 1 = 1 = Reverse translucent table)
  106. bit 14-15: 00 = normal
  107. 01 = move with vector
  108. 10 = move opposite vector
  109. 11 = undefined
  110. */
  111. enum {
  112. kWallBlocking = 0x0001,
  113. kWallBottomSwap = 0x0002,
  114. kWallBottomOrg = 0x0004,
  115. kWallOutsideOrg = 0x0004,
  116. kWallFlipX = 0x0008,
  117. kWallMasked = 0x0010,
  118. kWallOneWay = 0x0020,
  119. kWallHitscan = 0x0040,
  120. kWallTranslucent = 0x0080,
  121. kWallFlipY = 0x0100,
  122. kWallFlipMask = 0x0108,
  123. kWallTranslucentR = 0x0200,
  124. kWallMapSecret = 0x0400,
  125. kWallMapNever = 0x0800,
  126. kWallMapAlways = 0x1000,
  127. kWallMoveMask = 0xC000,
  128. kWallMoveNone = 0x0000,
  129. kWallMoveForward = 0x4000,
  130. kWallMoveBackward = 0x8000,
  131. };
  132. /*******************************************************************************
  133. Texture alignment notes:
  134. For single sided walls, the alignment bit (bit 2) specifies whether the texture
  135. is pegged at the top (clear) or the bottom (set). For two sided walls, the bit
  136. determines whether the texture is pegged at the floor and ceiling of the inside
  137. sector (clear), or the ceiling of the outside/facing sector (set).
  138. *******************************************************************************/
  139. struct SPRITE
  140. {
  141. long x, y, z;
  142. ushort cstat;
  143. sshort picnum;
  144. schar shade;
  145. uchar pal, clipdist;
  146. uchar filler;
  147. uchar xrepeat, yrepeat;
  148. schar xoffset, yoffset;
  149. short sectnum, statnum;
  150. short ang;
  151. short owner;
  152. short xvel, yvel, zvel;
  153. short type;
  154. ushort flags;
  155. short extra;
  156. };
  157. /* SPRITE cstat bits
  158. cstat, bit 0: 1 = Blocking sprite (use with clipmove, getzrange) "B"
  159. bit 1: 1 = 50/50 transluscence, 0 = normal "T"
  160. bit 2: 1 = x-flipped, 0 = normal "F"
  161. bit 3: 1 = y-flipped, 0 = normal "F"
  162. bits 4-5: 00 = FACE sprite (default) "R"
  163. 01 = WALL sprite (like masked walls)
  164. 10 = FLOOR sprite (parallel to ceilings&floors)
  165. 11 = SPIN sprite (face sprite that can spin 2draw style - not done yet)
  166. bit 6: 1 = 1-sided sprite, 0 = normal "1"
  167. bit 7: 1 = Real centered centering, 0 = foot center "C"
  168. bit 8: 1 = Blocking sprite (use with hitscan) "H"
  169. bit 9: 1 = Reverse translucence
  170. bit 10: reserved
  171. bit 11: reserved
  172. bit 12: reserved
  173. bit 13: reserved
  174. bit 14: reserved
  175. bit 15: Force invisible sprite
  176. */
  177. enum {
  178. kSpriteBlocking = 0x0001,
  179. kSpriteTranslucent = 0x0002,
  180. kSpriteFlipX = 0x0004,
  181. kSpriteFlipY = 0x0008,
  182. kSpriteFace = 0x0000,
  183. kSpriteWall = 0x0010,
  184. kSpriteFloor = 0x0020,
  185. kSpriteSpin = 0x0030,
  186. kSpriteRMask = 0x0030,
  187. kSpriteOneSided = 0x0040,
  188. kSpriteOriginAlign = 0x0080,
  189. kSpriteHitscan = 0x0100,
  190. kSpriteTranslucentR = 0x0200,
  191. kSpriteMapSecret = 0x0400,
  192. kSpriteMapNever = 0x0800,
  193. kSpriteMapAlways = 0x1000,
  194. kSpriteMoveMask = 0x6000,
  195. kSpriteMoveNone = 0x0000,
  196. kSpriteMoveForward = 0x2000,
  197. kSpriteMoveFloor = 0x2000,
  198. kSpriteMoveReverse = 0x4000,
  199. kSpriteMoveCeiling = 0x4000,
  200. kSpriteInvisible = 0x8000,
  201. };
  202. // SPRITE flag attributes
  203. enum {
  204. kAttrMove = 0x0001, // is affected by movement physics
  205. kAttrGravity = 0x0002, // is affected by gravity
  206. kAttrFalling = 0x0004, // in z motion
  207. kAttrSmoke = 0x0100, // receives tsprite smoke/steam
  208. kAttrBloodSpray = 0x0200, // receives tsprite blood spray
  209. };
  210. #pragma pack(1);
  211. struct RGB6 {
  212. uchar r,g,b;
  213. };
  214. #pragma pack;
  215. #ifdef __cplusplus
  216. extern "C" {
  217. #endif
  218. /***********************************************************************
  219. * Engine global variables
  220. **********************************************************************/
  221. //static int artfil;
  222. /* DOS handle for currently open art file. */
  223. //static char artfilename[];
  224. /* Name of art file, i.e., "TILES000.ART" */
  225. //static int artfilnum;
  226. /* Number of the currently open art file. */
  227. extern long artsize;
  228. /* The total size in bytes of all the tile pieces. Ken's engine will try to
  229. allocate a cache this large. */
  230. extern long artversion;
  231. /* The current art version is now 1. If artversion is not 1 then
  232. either it's the wrong art version or something is wrong. */
  233. extern long asm1, asm2, asm3, asm4;
  234. /* These are temporary holding registers for the interface from Ken's C code to
  235. his assembly code. I guess he isn't using Watcom's parameter passing scheme. */
  236. extern char automapping;
  237. /* Set to 1 to automatically mark seen walls and sprites to appear in the map
  238. */
  239. extern char britable[16][64];
  240. /* Ken's gamma table */
  241. extern short bunchfirst[];
  242. /* Used internally by drawrooms(). Used as indexes into thewall[] */
  243. extern short bunchlast[];
  244. /* Used internally by drawrooms() */
  245. extern short capturecount;
  246. /* Increments each time a screen capture is done. Use to sequentially number
  247. capture files. */
  248. extern int chainnumpages, chainsiz;
  249. extern uchar *chainplace;
  250. //extern short cliplist[];
  251. /* used by getcliplines() */
  252. // static short clipnum;
  253. /* used by getcliplines() */
  254. // static short clipobjectval[];
  255. /* used by getcliplines() */
  256. // static short clipsectnum;
  257. /* used by getcliplines() */
  258. // static short clipsectorlist[];
  259. /* used by getcliplines() */
  260. // static long clipx1[], clipx2[], clipy1[], clipy2[];
  261. /* used by getcliplines() */
  262. extern long cosglobalang;
  263. /* temporary holder for a cos value */
  264. extern char curbrightness;
  265. /* The current brightness level (0 - 4) */
  266. extern char curpag;
  267. /* used for VESA mode */
  268. extern long dahorizbak;
  269. /* copy of horiz value passed to drawrooms() saved for internal use */
  270. extern short dmost[MAXXDIM];
  271. /* at the beginning of each drawing cycle, startdmost[] gets copied to dmost[] */
  272. extern long dplc[];
  273. extern long dwall[];
  274. extern short editstatus;
  275. /* Set by build. Alters behavior of certain engine features */
  276. extern BYTE *frameplace;
  277. /* location of the virtual frame buffer for page 0 */
  278. extern short globalang;
  279. extern long globalbufplc;
  280. extern short globalcursectnum;
  281. extern long globalhoriz;
  282. extern short globalorientation;
  283. extern long globalpal;
  284. extern long globalpalwritten;
  285. extern short globalpicnum;
  286. extern long globalposx;
  287. extern long globalposy;
  288. extern long globalposz;
  289. extern char globalshade;
  290. extern short globalshiftval;
  291. extern long globalx1;
  292. extern long globalx2;
  293. extern long globalxpanning;
  294. extern char globalxshift;
  295. extern long globaly1;
  296. extern long globaly2;
  297. extern long globalypanning;
  298. extern long globalyscale;
  299. extern char globalyshift;
  300. extern long globalzd;
  301. extern long globalzx;
  302. extern BYTE gotpic[kMaxTiles >> 3];
  303. /* A bitmapped array of flags for each tile. The engine will set the respective
  304. gotpic bit for each picnum drawn to the screen, including ceilings, floors,
  305. walls, sprites, masked walls - even overwritesprites, etc. This array is
  306. mainly for making the game only calculate special bitmapped effects when that
  307. certain picnum is on the screen. */
  308. extern BYTE gotsector[kMaxSectors >> 3];
  309. /* It works a lot like the gotpic array, but this array determines which
  310. sectors were considered during the drawrooms function. Note that gotsector,
  311. unlike gotpic IS cleared to 0 during every call to drawrooms. */
  312. extern short headspritesect[kMaxSectors+1];
  313. /* list starting with headspritesect[kMaxSectors] is unused sprites. */
  314. extern short headspritestat[kMaxStatus+1];
  315. /* list starting with headspritestat[kMaxSectors] is unused sprites. */
  316. extern short highlightcnt;
  317. /* number of points to be highlighted in 2d mode */
  318. extern hitcnt;
  319. /* not used. size unknown */
  320. // static short hitwalls[];
  321. extern long lastx[];
  322. /* used internally to sychronize floor and ceiling drawing with walls */
  323. extern short linehighlight;
  324. /* wall to be highlighted in 2d mode */
  325. //static long localtileend;
  326. /* Localtileend is the tile number of the last tile in this art file. */
  327. //static long localtilestart;
  328. /* tile number of the first tile in this art file */
  329. extern long lplc[];
  330. extern long lwall[];
  331. extern long mapversion;
  332. /* version of currently loaded board. Should be 5 */
  333. extern short maskwall[];
  334. /* list of walls to be drawn in drawmasks(). Value is used as index to
  335. thewall[] and thesector[] */
  336. extern short maskwallcnt;
  337. /* number of walls to be drawn in drawmasks() */
  338. extern short nextspritesect[kMaxSprites];
  339. extern short nextspritestat[kMaxSprites];
  340. extern short numbunches;
  341. extern long numframes;
  342. /* The number of times the draw3dscreen function was called since the engine
  343. was initialized. This helps to determine frame rate. (Frame rate = numframes
  344. * 120 / totalclock.) */
  345. extern short numhits;
  346. extern short numpalookups;
  347. /* number of levels used for depth cueing. Normally 32, but determined by
  348. palette.dat */
  349. extern long numpages;
  350. extern short numscans;
  351. extern short numsectors;
  352. /* the total number of existing sectors. Modified every time you call the
  353. loadboard function. */
  354. //static long numtilefiles;
  355. extern long numtiles;
  356. /* the number of tiles found TILES.DAT. */
  357. extern short numwalls;
  358. /* the total number of existing walls. Modified every time you call the
  359. loadboard function. */
  360. extern short p2[];
  361. /* used internally for wall drawing. Creates a linked list of references to
  362. thewall[] */
  363. extern long page;
  364. /* number of the page being rendered */
  365. extern long pageoffset;
  366. /* offset of the active page (in pixels) */
  367. extern RGB6 palette[256];
  368. extern char paletteloaded;
  369. /* Set to 1 after the palette has been loaded. */
  370. extern uchar *palookup[MAXPALOOKUPS];
  371. /* The palookup array is an array of pointers that point to the first byte of
  372. each 8K palette lookup table. All 256 pointers are initialized to NULL by
  373. initengine() except for palookup[0] which is the default 8K palette. This will
  374. allow you to modify the palette lookup table directly for non-snowy fading
  375. effects, etc. Each palette lookup table has 32 shades. Each shade has 256
  376. bytes. Shade 0 is closest (actual palette brightness) and shade 31 is farthest
  377. (dark usually). (256*32 = 8192 or 8K) */
  378. extern long parallaxscale;
  379. /* Controls the ratio at which the parallaxing skies scroll in relation to the
  380. horizon. Default is 65536. With lower values, you don't need as much artwork
  381. and can look higher. */
  382. extern char parallaxtype;
  383. /* 0 = Totally flat parallaxing sky. 1 = X-only stretching parallaxing sky
  384. (This is what DOOM uses). 2 = X and Y stretching parallaxing sky. */
  385. extern long parallaxyoffs;
  386. /* It defaults to 0. If you set it to 100, then all parallaxing skies will be
  387. properly moved 100 pixels higher. */
  388. extern short pskyoff[kMaxSkyTiles];
  389. extern short pskybits;
  390. /* pskyoff[kMaxSkyTiles] is an array of OFFSETS of each tile from the
  391. picnum of the parallaxing sky. pskybits is NOT the actual number of tiles,
  392. but the log (base 2) of the number of tiles. Look at this table:
  393. For 1 tile, pskybits = 0
  394. For 2 tiles, pskybits = 1
  395. For 4 tiles, pskybits = 2
  396. For 8 tiles, pskybits = 3
  397. For 16 tiles, pskybits = 4, etc.
  398. Most teams have a 1024 wide parallaxing sky that wraps all the way around.
  399. Don't worry - this is the default now. When initengine is called, the
  400. variables default to this: pskyoff[0] = 0; pskybits = 0;
  401. You may have used a 512 wide parallaxing sky (like in my game) that repeated
  402. every 180 degrees. To make this work with the new version, set these
  403. variables like this right after initengine is called:
  404. pskyoff[0] = 0;
  405. pskyoff[1] = 0;
  406. pskybits = 1;
  407. Note that both pskyoff variables are 0 here. This will make the parallaxing
  408. sky repeat. With the new tiling, you can save memory by making small chuck
  409. sizes, such as 64 or 128, and repeating certain sections.
  410. */
  411. extern char pcxheader[];
  412. /* Ken's doesn't use a structure for the pcx header */
  413. extern uchar *pic;
  414. /* Pointer to a large buffer used for the tile cache. Wall offsets are pointers
  415. to locations within this block. */
  416. extern struct PICANM {
  417. unsigned frames : 5; // number of frames - 1
  418. unsigned update : 1; // this came from upper bit of frames
  419. unsigned type : 2; // 0 = none, 1 = Oscil, 2 = Frwd, 3 = Bkwd
  420. signed xcenter : 8;
  421. signed ycenter : 8;
  422. unsigned speed : 4; // (clock >> speed) determines rate
  423. unsigned view : 3;
  424. unsigned registered : 1;
  425. } picanm[kMaxTiles];
  426. /* Upper 4 bits: y size shift; lower 4 bits: x size shift */
  427. extern uchar picsiz[kMaxTiles];
  428. extern short pointhighlight;
  429. /* point to be highlighted in 2d mode */
  430. extern posfil;
  431. /* not used */
  432. extern short prevspritesect[kMaxSprites];
  433. extern short prevspritestat[kMaxSprites];
  434. extern long qsetmode;
  435. /* number of scanlines for current mode (480, 350, 200). Can be use to
  436. determine current display mode */
  437. extern short radarang[];
  438. extern short radarang2[];
  439. /* table of angles used for sweeping across the screen */
  440. extern long randomseed;
  441. extern long rx1[];
  442. /* Used for wall drawing */
  443. extern long rx2[];
  444. /* Used for wall drawing */
  445. extern long ry1[];
  446. /* Used for wall drawing */
  447. extern long ry2[];
  448. /* Used for wall drawing */
  449. //static BYTE *screen;
  450. /* same as frameplace */
  451. extern short searchit;
  452. extern short searchsector;
  453. extern short searchstat;
  454. /* Indicates the type of object being pointed to in 3d mode in the editor.
  455. When searchstat == 0, it's wall searchwall; searchstat == 1, it's ceiling of
  456. searchsector; searchstat == 2, it's floor of searchsector; searchstat == 3,
  457. it's sprite in searchwall; searchstat == 4, it's masked wall in searchwall. */
  458. extern short searchwall;
  459. extern long searchx;
  460. extern long searchy;
  461. extern SECTOR sector[kMaxSectors];
  462. // static short sectorborder[];
  463. // static short sectorbordercnt;
  464. extern BYTE show2dsprite[kMaxSprites>>3];
  465. /* These variables are for auto-mapping with the draw2dscreen function. When
  466. you load a new board, these bits are all set to 0 - since you haven't mapped
  467. out anything yet. Note that these arrays are bit-mapped. If you want
  468. draw2dscreen() to show sprite #54 then you say:
  469. spritenum = 54;
  470. show2dsprite[spritenum>>3] |= (1<<(spritenum&7));
  471. And if you want draw2dscreen() to not show sprite #54 then you say:
  472. spritenum = 54;
  473. show2dsprite[spritenum>>3] &= ~(1<<(spritenum&7));
  474. */
  475. extern BYTE show2dwall[kMaxWalls>>3];
  476. extern BYTE show2dsector[kMaxSectors>>3];
  477. extern char showinvisibility;
  478. /* If you set this to 1, then all sprites with the invisible bit set will be
  479. shown. This is useful for editing invisiblie sprites. */
  480. extern long singlobalang;
  481. extern short sintable[2048];
  482. /* sin table in 2:14 format
  483. If you plan to use sintable, 2 identities you may want to keep in mind are:
  484. sintable[ang&2047] = sin(ang * (3.141592/1024)) * 16383
  485. sintable[(ang+512)&2047] = cos(ang * (3.141592/1024)) * 16383
  486. */
  487. extern char smalltextfont[1024];
  488. extern short smost[];
  489. extern short smostcnt;
  490. extern short smoststart[];
  491. extern short smostwall[];
  492. extern short smostwallcnt;
  493. extern SPRITE sprite[kMaxSprites];
  494. extern long spritesortcnt;
  495. extern long sqrtable[2048];
  496. extern short startang;
  497. /* not used */
  498. extern short startdmost[MAXXDIM];
  499. /* array of the lowest y-coordinates on each column that the engine is allowed
  500. to write to. You need to set it only once. */
  501. extern long startposx, startposy, startposz;
  502. /* not used */
  503. extern short startsectnum;
  504. /* not used */
  505. extern short startumost[MAXXDIM];
  506. /* array of the highest y-coordinates on each column that the engine is allowed
  507. to write to. You need to set it only once. */
  508. extern long stereofps;
  509. extern char stereopage;
  510. extern long stereopixelwidth;
  511. extern long stereowidth;
  512. extern long swall[];
  513. extern long swplc[];
  514. extern char tablesloaded;
  515. /* set to 1 when tables have been loaded. Duh. */
  516. extern long takernum;
  517. /* Reflects the current activity of the engine; tracked for time statistics in
  518. timetakercount[] */
  519. extern short tantable[2048];
  520. /* not used */
  521. extern char textfont[1024];
  522. extern short thesector[];
  523. /* list of sector ids for masked walls to be drawn in drawmasks() */
  524. extern short thewall[];
  525. /* list of wall ids for masked walls to be drawn in drawmasks() */
  526. extern char tilefilenum[];
  527. /* list of art file numbers which contain each tile */
  528. extern long tilefileoffs[];
  529. /* offset of the tile within the art file. */
  530. extern short tilesizx[kMaxTiles];
  531. /* simply the x-dimension of the tile number. */
  532. extern short tilesizy[kMaxTiles];
  533. /* simply the y-dimension of the tile number. */
  534. extern char timenames[][20];
  535. /* text strings for each of the time statistic engine activities */
  536. extern long timetakercount[];
  537. /* Used to track engine statistics. Each array element contains the total
  538. ticks for each activity. */
  539. extern volatile long totalclock;
  540. /* TOTALCLOCK - When the engine is initialized, TOTALCLOCK is set to zero. It
  541. is up to the game timer code to update totalclock. The timing value in
  542. totalclock is used to synchronize tile animations. */
  543. extern long totalclocklock;
  544. /* Gets set to totalclock at the beginning of drawrooms(). */
  545. extern uchar *transluc;
  546. /* table (256 * 256) for combining translucent colors */
  547. extern char tsengdriver;
  548. /* not used */
  549. extern SPRITE tsprite[kMaxSprites];
  550. extern short umost[MAXXDIM];
  551. /* at the beginning of each drawing cycle, startumost[] gets copied to umost[] */
  552. extern long uplc[];
  553. extern long uwall[];
  554. extern char vesapageshift;
  555. /* used for page flipping in VESA mode */
  556. extern char vgapal16[48];
  557. /* REG 16 color palette used for writing 16 color screen captures to PCX files */
  558. extern long viewoffset;
  559. /* Linear offset of the upper left of the 3d view window */
  560. extern long visibility;
  561. /* for special effects such as a gun shooting. A value from 5 to around 15.
  562. 13 is normal, the lower the number, the darker. */
  563. extern long parallaxvisibility;
  564. /* visibility value for parallaxed skies */
  565. extern WALL wall[kMaxWalls];
  566. /* This is the list of all the walls. */
  567. extern BYTE *waloff[kMaxTiles];
  568. /* pointers to the raw bitmap data for each tile. */
  569. extern long windowx1, windowx2, windowy1, windowy2;
  570. /* Window coordinates passed to setview(). */
  571. extern long xb1[];
  572. /* Used internally for wall drawing */
  573. extern long xb2[];
  574. /* Used internally for wall drawing */
  575. extern long xdimen;
  576. /* Width of the 3d view window */
  577. extern long xdimenoffs;
  578. /* x offset of the 3d view window. Not used. */
  579. extern long xdimenscale;
  580. /* (xdimen << 16) / 320 */
  581. extern long xdimscale;
  582. /* (320 << 16) / xdimen */
  583. extern long yb1[];
  584. /* Used internally for wall drawing */
  585. extern long yb2[];
  586. /* Used internally for wall drawing */
  587. //extern long ybot;
  588. extern long ydim16;
  589. /* clip y max for 16 color drawing. Also determines whether drawing takes
  590. place on the 2d map or on the status bar. */
  591. extern long ydimen;
  592. /* Height of the 3d view window */
  593. //extern long ytop;
  594. extern char vidoption;
  595. /* Vidoption is simply the first parameter you pass to initengine. Xdim and
  596. Ydim are the screen sizes you pass to initengine, such as 320*200 or 640*480.
  597. Ylookup is a lookup table that works like this: If (vidoption == 0) ylookup[i]
  598. = ((i*xdim)>>2); if (vidoption != 0) ylookup[i] = i*xdim; There is 1 exception:
  599. If you are using a chained mode which can only fit only 1 viewing page, then
  600. the engine actually does a screen-buffer mode and blits to the chained screen
  601. so for this case, ylookup[i] = i*xdim. */
  602. extern long xdim, ydim, ylookup[MAXYDIM+1];
  603. extern long yxaspect, xyaspect;
  604. /***********************************************************************
  605. * Engine functions
  606. **********************************************************************/
  607. int addboxlinum( short nSector, short nWall );
  608. /* Called internally by scansector(). */
  609. void alignceilslope(short sectnum, long x, long y, long z);
  610. void alignflorslope(short sectnum, long x, long y, long z);
  611. /*These functions will align a slope to a given (x, y, z) point. It will make
  612. the slope pass through the point. The function will do nothing if the point is
  613. collinear to the first wall of the sector. */
  614. void allocache(long *bufptr, long bufsiz, char *lockptr);
  615. /* Called internally by loadtile() */
  616. ulong allocatepermanenttile( short tilenume, long xsiz, long ysiz );
  617. /* This function allocates a place on the cache as permanent. Right now, I
  618. reset the cache every time you call this function so I would recommend calling
  619. this function right after loadpics. Returns a pointer to the tile bitmap or 0
  620. on failure. */
  621. short animateoffs( short nTile, ushort nInfo );
  622. /* Returns the current frame for the animating tile based on totalclocklock.
  623. nInfo is used to identify what type of object is being animated.
  624. nInfo is nSector, nWall | 0x4000, nSprite | 0x8000, or 0xC000 (just ignore-it's
  625. for rotatesprite) */
  626. int bunchfront( short, short );
  627. /* Used internally by drawrooms() */
  628. long calcksqrt( long );
  629. /* Used internally to create sqrtable[] */
  630. void calcwalls( short );
  631. /* Used internally by drawrooms() */
  632. BOOL cansee( long x1, long y1, long z1, short sectnum1, long x2, long y2, long z2, short sectnum2 );
  633. /* This function determines whether or not two 3D points can "see" each other
  634. or not. All you do is pass it the coordinates of a 3D line defined by two 3D
  635. points (with their respective sectors) The function will return a 1 if the
  636. points can see each other or a 0 if there is something blocking the two points
  637. from seeing each other. This is how I determine whether a monster can see you
  638. or not. Try playing DOOM1.DAT to fully enjoy this great function! */
  639. void ceilscan( long, long, short );
  640. /* Used internally by calcwalls() */
  641. int changespritesect(short spritenum, short newsectnum);
  642. /* Changes the sector of sprite (spritenum) to the newsector (newsectnum).
  643. This function may become internal to the engine in the movesprite function.
  644. But this function is necessary since all the sectors have their own
  645. doubly-linked lists of sprites. Returns -1 if sector doesn't change. */
  646. int changespritestat(short spritenum, short newstatnum);
  647. /* Changes the status of sprite (spritenum) to status newstatus). Newstatus
  648. can be any number from 0 to kMaxStatus-1. You can use this function to put a
  649. monster on a list of active sprites when it first sees you. Returns -1 is
  650. statnum doesn't change. */
  651. void clear2dscreen( void );
  652. /* Clears the drawing page in 16 color mode */
  653. extern void clearview(int nColor);
  654. /* clears the view to the specified color */
  655. unsigned clipinsidebox(long x, long y, short wallnum, long walldist);
  656. /* Clipinsidebox is used for clipping to determine whether a player or sprite
  657. is too close to a wall. X and y are the position of the sprite or player.
  658. Wallnum is the wall to test, and walldist is the fatness of the sprite or
  659. player (same as clipmove). It returns a 1 if the sprite or player's clipping
  660. square intersects the wall or 0 if not. */
  661. unsigned clipmove( long *x, long *y, long *z, short *sectnum, long xvect, long yvect,
  662. long walldist, long ceildist, long flordist, char cliptype );
  663. /* Moves any object (x, y, z) in any direction at any velocity and will make
  664. sure the object will stay a certain distance from walls (walldist). Pass the
  665. pointers of the starting position (x, y, z, and sectnum.) These values will be
  666. modified accordingly. Pass the direction and velocity by using a vector xvect,
  667. yvect). Walldist tells how close the object can get to a wall. If you
  668. increase walldist for a certain object, the object might leak through a wall,
  669. so don't do that! If cliptype is 0, then the clipping is normal (Use 0 to clip
  670. you and monsters). If the cliptype is 1, then the object is clipped to the
  671. same things that hitscan is clipped to (use 1 for all bullets).
  672. Clipmove can either return 0 (touched nothing), 0x8000 + wallnum (wall first
  673. touched), 0xC000 + spritenum (sprite first touched).
  674. Clipmove uses getceilzofslope and getflorzofslope when checking for overlapping. */
  675. void completemirror( void );
  676. /* called after preparemirror, drawrooms, viewProcessSprites and drawmasks in mirrorDraw() */
  677. void copytilepiece( long tilenume1, long sourcex1, long sourcey1,
  678. long xsiz, long ysiz, long tilenume2, long destx1, long desty1 );
  679. /* This function simply copies any section of a source tile to any part of a
  680. destination tile. It will automatically skip transparent pixels. It will
  681. wrap-around in the source but not the destination. If for some reason the
  682. destination tile gets removed from the cache, the destination tile will be
  683. reset to original form. Use allocatepermanenttile() to prevent the tile from
  684. being purged. */
  685. void deletesprite( short nSprite );
  686. /* Deletes the sprite. */
  687. void deletespritesect( short nSprite );
  688. /* Remove the sprite from the sector linked list. Called by deletesprite() */
  689. void deletespritestat( short nSprite );
  690. /* Remove the sprite from the status linked list. Called by deletesprite() */
  691. void dragpoint( short wallnum, long newx, long newy );
  692. /* This function will drag a point in the exact same way a point is dragged in
  693. 2D EDIT MODE using the left mouse button. Simply pass it which wall to drag
  694. and then pass the new x and y coordinates for that point. Please use this
  695. function because if you try to drag points yourself, I can guarantee that it
  696. won't work as well as mine and you will get confused. Note: Every wall of
  697. course has 2 points. When you pass a wall number to this function, you are
  698. actually passing 1 point, the left side of the wall given that you are in the
  699. sector of that wall) Got it? */
  700. void draw2dgrid( long x, long y, short ang, long zoom, short grid );
  701. /* Draws the grid on the 2d screen. Used internally by draw2dscreen() */
  702. int drawoverheadmap(long cposx, long cposy, long czoom, short cang);
  703. int drawmapview(long cposx, long cposy, long czoom, short cang);
  704. void draw2dscreen( long x, long y, short ang, long zoom, short grid );
  705. /* Draws the 2d screen - this function is a direct replacement for the
  706. drawrooms() and drawmasks() functions. Be sure to call either qsetmode640350()
  707. or qsetmode640480() first. When switching back to 3d mode, be sure to call
  708. setgamemode(). IMPORTANT NOTES: 1. The overwritesprite function should
  709. only be called in 3D mode. If you do this in 2D mode, junk will be written to
  710. the 2D screen and a crash is possible. 2. When you switch back to 3D mode,
  711. you should call the permanentwritesprite functions to draw the status bar, or
  712. whatever else you have to draw. 3. You must call the nextpage() function in
  713. both 2D and 3D modes. */
  714. void drawalls( short );
  715. /* Used internally by drawrooms() */
  716. void drawline16(long x1, long y1, long x2, long y2, char nColor);
  717. void drawline256(long x1, long y1, long x2, long y2, char nColor);
  718. void drawmasks( void );
  719. /* This function draws all the sprites and masked walls to the current drawing
  720. page which is not yet shown. The reason I have the drawing split up into these
  721. 2 routines is so you can animate just the sprites that are about to be drawn
  722. instead of having to animate all the sprites on the whole board. Drawrooms()
  723. prepares these variables: spritex[], spritey[], spritepicnum[], thesprite[],
  724. and spritesortcnt. Spritesortcnt is the number of sprites about to be drawn to
  725. the page. To change the sprite's picnum, simply modify the spritepicnum array
  726. If you want to change other parts of the sprite structure, then you can use the
  727. thesprite array to get an index to the actual sprite number. */
  728. void drawmaskwall( short index );
  729. /* Draws the masked wall referenced in maskwall[index]. */
  730. void drawrooms( long posx, long posy, long posz, short ang, long horiz,
  731. short cursectnum );
  732. /* This function draws the 3D screen to the current drawing page, which is not
  733. yet shown. This way, you can overwrite some things over the 3D screen such as
  734. a gun. Be sure to call the drawmasks() function soon after you call the
  735. drawrooms() function. To view the screen, use the nextpage() function. The
  736. nextpage() function should always be called sometime after each draw3dscreen()
  737. function. */
  738. void drawsprite( long x, long y, short nTile, short nSprite, char pal);
  739. /* Draw the specified sprite to the 3d screen. Called internally by
  740. drawmasks(). */
  741. void faketimerhandler( void );
  742. /* Called at various places in engine. Must be supplied externally. */
  743. void florscan( long xb1, long xb2, short );
  744. /* Called internally by calcwalls() */
  745. short getangle( long xvect, long yvect );
  746. /* returns (short)angle; Use this function call to determine the angle between
  747. two points. For example, if you want a monster to shoot a bullet towards you,
  748. you would get the bullet's angle this way: sprite[bullet].ang = getangle(posx
  749. - sprite[monst].x, posy - sprite[monst].y); */
  750. long getceilzofslope(short sectnum, long x, long y);
  751. long getflorzofslope(short sectnum, long x, long y);
  752. void getzsofslope(short sectnum, long x, long y, long *ceilz, long *florz);
  753. /* Returns the z coordinate of the ceiling/floor at that x, y location. If the
  754. sector doesn't have a ceiling/floor slope then it immediately returns the
  755. sector[].floorz or sector[].ceilingz so it's not that slow. You may want to
  756. check for slopes yourself ceilingstat&2/floorstat&2 if you think the overhead
  757. of calling these functions are too slow. */
  758. void getcliplines( long x, long y, long z, long newX, long newY, short sectnum,
  759. long walldist, long ceildist, long floordist, char cliptype);
  760. /* generates a list of clip areas for clipmove */
  761. void getmousevalues( short *xMickeys, short *yMickeys, short *buttons );
  762. /* Retrieves mouse info using int 33h, 0Bh and int 33h, 05h */
  763. int getpalookup(long nVis, long nShade);
  764. unsigned getpixel16( long offset );
  765. /* retrieves pixel color addressed by linear pixel number. Weird. Used by
  766. screencapture(). */
  767. void getzrange( long x, long y, long z, short sectnum,
  768. long *ceilZ, long *ceilHit, long *floorZ, long *floorHit,
  769. long walldist, char cliptype );
  770. /* Determines the vertical range for an area. Use this in conjunction with
  771. clipmove. This function will keep the player from falling off cliffs when
  772. you're too close to the edge. This function finds the highest and lowest z
  773. coordinates that your clipping BOX can get to. It must search for all sectors
  774. (and sprites) that go into your clipping box. This method is better than using
  775. sector[].ceilingz and sector[].floorz because this searches the whole clipping
  776. box for objects, not just 1 point. Pass x, y, z, sector normally. Walldist
  777. can be 128. Cliptype can be 0, 1, or 2. (just like movesprite and clipmove)
  778. This function returns the z extents in ceilZ and floorZ. It will return the
  779. object hit in ceilHit and floorHit. CeilHit and floorHit will also be either:
  780. 0x4000 | sector (sector first touched) or 0xC000 | spritenum (sprite first
  781. touched) */
  782. void grouvline( long, long, long, short );
  783. /* used internally by calcwalls() */
  784. void hitscan( long xstart, long ystart, long zstart, short startsectnum,
  785. long vectorx, long vectory, long vectorz, short *hitsect,
  786. short *hitwall, short *hitsprite, long *hitx, long *hity, long *hitz );
  787. /* Pass the starting 3D position: (xstart, ystart, zstart, startsectnum) Then
  788. pass the 3D angle to shoot (defined as a 3D vector): (vectorx, vectory,
  789. vectorz) Then set up the return values for the object hit: (hitsect, hitwall,
  790. hitsprite) and the exact 3D point where the ray hits: (hitx, hity, hitz)
  791. How to determine what was hit:
  792. Hitsect is always equal to the sector that was hit (always >= 0).
  793. If the ray hits a sprite then:
  794. hitsect = thesectornumber
  795. hitsprite = thespritenumber
  796. hitwall = -1
  797. If the ray hits a wall then:
  798. hitsect = thesectornumber
  799. hitsprite = -1
  800. hitwall = thewallnumber
  801. If the ray hits the ceiling of a sector then:
  802. hitsect = thesectornumber
  803. hitsprite = -1
  804. hitwall = -1
  805. vectorz < 0 (If vectorz < 0 then you're shooting upward which means
  806. that you couldn't have hit a floor)
  807. If the ray hits the floor of a sector then:
  808. hitsect = thesectornumber
  809. hitsprite = -1
  810. hitwall = -1
  811. vectorz > 0 (If vectorz > 0 then you're shooting downward which means
  812. that you couldn't have hit a ceiling)
  813. */
  814. void hline( long, long, long, short );
  815. /* used internally by ceilscan() and floorscan() */
  816. void initcache(long cachestart, long cachesize);
  817. /* clears all but permanent tiles from the cache */
  818. void initengine( int vidoption, int xdim, int ydim );
  819. /* Sets up interrupt vectors for keyboard, and initializes many variables for
  820. the BUILD engine. You should call this once before any other functions of the
  821. BUILD engine are used. vidoption can be anywhere from 0-6 xdim,ydim can be any
  822. mode x resolution if vidoption = 0 xdim,ydim can be any vesa resolution if
  823. vidoption = 1 xdim,ydim must be 320*200 for any other mode. (see graphics mode
  824. selection in my setup program) */
  825. void initkeys( void );
  826. unsigned initmouse();
  827. void initspritelists( void );
  828. /* Called internally by loadboard(). Creates the linked sector and status
  829. lists based on the sprite sectnum and statnum fields. */
  830. short insertsprite(short sectnum, short statnum);
  831. /* Returns spritenum. Whenever you insert a sprite, you must pass it
  832. the sector number, and a status number (statnum). The status number can be any
  833. number from 0 to kMaxStatus-1. Insertsprite works like a memory allocation
  834. function and returns the sprite number. */
  835. short insertspritesect( short sectnum );
  836. /* Called internally by insertsprite(). Adds a sprite to the sector linked
  837. list. Returns spritenum. */
  838. short insertspritestat( short statnum );
  839. /* Called internally by insertsprite(). Adds a sprite to the status linked
  840. list. Returns spritenum. */
  841. unsigned inside( long x, long y, short sectnum );
  842. /* Tests to see whether the overhead point (x, y) is inside sector (sectnum)
  843. Returns either 0 or 1, where 1 means it is inside, and 0 means it is not. */
  844. void keepaway( long *, long *, long, short );
  845. /* Called internally by clipmove(). */
  846. void __interrupt __far keyhandler( void );
  847. /* Ken's keyboard interrupt routine. */
  848. void * kmalloc( size_t size );
  849. void kfree( void * ptr );
  850. /* Ken's replaceable memory handling functions, that just call malloc and free. */
  851. unsigned krand( void );
  852. /* This simply returns a random number. You can easily set the random seed by
  853. externing the randomseed variable as a long. This is useful for keeping the
  854. random seed the same on multiple computers when playing multi-player mode.
  855. Note: this random number routine is extremely simplistic and can very easily
  856. generate patterns. Use rand() instead. */
  857. ushort ksqrt( long num );
  858. /* returns square root. A square root function optimized for integers. Use
  859. this function only if you want to. */
  860. short lastwall( short nWall );
  861. /* Returns the number of the wall whose .point2 equals nWall. Returns nWall if
  862. no previous wall is found. */
  863. BOOL lintersect( long x, long y, long z, long dx, long dy, long dz, long xc,
  864. long yc, long xd, long yd, long *xint, long *yint, long *zint);
  865. /* Determines if and where and if the line segment specified by origin (x,y,z)
  866. and magnitude (dx,dy,dz) intersects with line segment CD. If the lines
  867. intersect, returns TRUE and sets x, y, and z to the point of intersection. */
  868. int loadboard( char *filename, long *posx, long *posy, long *posz, short *ang,
  869. short *cursectnum );
  870. /* Loads the given board file into memory for the BUILD engine. Returns -1 if
  871. file not found. If no extension is given, .MAP will be appended to the
  872. filename. */
  873. void loadpalette( void );
  874. /* Loads "PALETTE.DAT". Gets palette, color lookup tables, and transparency
  875. table. */
  876. int loadpics( char *filename );
  877. /* Loads the given artwork file into memory for the BUILD engine. Returns -1
  878. if file not found. If no extension is given, .ART will be appended to the
  879. filename. */
  880. void loadredbluepalette( void );
  881. /* Loads special red/blue palette for stereo vision */
  882. void loadtables( void );
  883. /* Reads "TABLES.DAT" and "SETUP.DAT". Builds sqrtable[], loads sintable[],
  884. tantable[], radarang[], * textfont, smalltextfont, and setup options. */
  885. void loadtile( short nTile );
  886. /* Loads the specified tile into the cache. Called internally when
  887. waloff[nTile] == NULL */
  888. void makepalookup( long palnum, char *remapbuf, char red, char green, char blue, char stat );
  889. /* This function allows different shirt colors for sprites. First prepare
  890. remapbuf, which is a 256 byte buffer of chars which the colors to remap.
  891. Palnum can be anywhere from 1-15. Since 0 is where the normal palette is
  892. stored, it is a bad idea to call this function with palnum = 0. The last 3
  893. parameters are the color that the palette fades to as you get further away.
  894. This color is normally black 0,0,0). White would be (63,63,63). This allows
  895. you to do fog and other effects.
  896. if ((stat&1) == 0) then makepalookup will allocate & deallocate the memory block
  897. for use but will not waste the time creating a palookup table (assuming you will
  898. create one yourself)
  899. if ((dastat&1) != 0) then makepalookup will allocate & deallocate the memory
  900. block AND create a palookup table using the rgb values you pass.*/
  901. void makeradarang( long width );
  902. /* Builds the radarang2[] array */
  903. void maskwallscan( long xb1, long xb2, long *uwall, long *dwall,
  904. long *swall, long *lwall );
  905. /* Draws the masked wall. Called by drawmaskwall() */
  906. unsigned movesprite(short spritenum, long dx, long dy, long dz,
  907. long ceildist, long flordist, char cliptype, long numtics);
  908. /* This function moves the sprite given by spritenum by the 3 increments, dx,
  909. dy, and dz. Walldist tells how close the object can get to a wall. I use 128L
  910. as my default. If you increase walldist all of a sudden for a certain object,
  911. the object might leak through a wall, so don't do that! If cliptype is 0, then
  912. the clipping is normal (Use 0 to clip you and monsters). If the cliptype is 1,
  913. then the object is clipped to the same things that hitscan is clipped to (use 1
  914. for all bullets). Movesprite can either return 0 (touched nothing),
  915. kHitFloor | nSector (floor hit), kHitCeiling | nSector (ceiling hit),
  916. kHitWall | nWall (wall hit), or kHitSprite | nSprite (sprite hit).
  917. */
  918. void neartag(
  919. long x, long y, long z, short sectnum, // Starting position
  920. short ang, //Starting angle
  921. short *neartagsector, //Returns near sector if sector[].tag != 0
  922. short *neartagwall, //Returns near wall if wall[].tag != 0
  923. short *neartagsprite, //Returns near sprite if sprite[].tag != 0
  924. long *neartaghitdist, //Returns actual distance to object (scale: 1024=largest grid size)
  925. long tagrange, //Choose maximum distance to scan (scale: 1024=largest grid size)
  926. char tagsearch ); //1=lotag, 2=hitag, 3=lotag and hitag
  927. /* Neartag works sort of like hitscan, but is optimized to scan only close
  928. objects and scan only objects with tags != 0. Neartag is perfect for the first
  929. line of your space bar code. It will tell you what door you want to open or
  930. what switch you want to flip. */
  931. void nextpage( void );
  932. /* After a screen is prepared, use this function to view the screen. */
  933. int nextsectorneighborz( short sectnum, long thez, short topbottom, short direction );
  934. /* This function searches z-coordinates of neighboring sectors to find the
  935. closest (next) ceiling starting at the given z-coordinate (thez). For example,
  936. if you want to find the goal z-coordinate when opening a door, you might want
  937. the door to stop at the next closest neighboring ceiling z-coordinate. You can
  938. get the z-coordinate this way:
  939. newz = sector[nextsectorneighborz(sectnum,startz,-1,-1)].ceilingz
  940. topbottom = -1: search ceilings
  941. 1: search floors
  942. direction = -1: search upwards
  943. 1: search downwards
  944. */
  945. enum {
  946. kOrientNormal = 0,
  947. kOrientMiddle = 0x01,
  948. kOrientScale = 0x02,
  949. kOrientTranslucent = 0x04,
  950. kOrientXFlip = 0x08,
  951. kOrientYFlip = 0x10,
  952. };
  953. //void overwritesprite(long x, long y, short nTile, signed char shade,
  954. // char orientation, char nPal );
  955. /* Use this function to draw any sprites that must be drawn to the screen for
  956. every single frame, such as a gun or a menu system.
  957. Bit 0 (1) of orientation = 0: (x, y) is top-left corner
  958. Bit 0 (1) of orientation = 1: (x, y) is middle
  959. Bit 1 (2) of orientation = 0: no relation to viewing window
  960. Bit 1 (2) of orientation = 1: scale and clip to viewing window
  961. Bit 2 (4) of orientation = 0: normal
  962. Bit 2 (4) of orientation = 1: 50/50 transluscent!
  963. Bit 3 (8) of orientation = 0: normal
  964. Bit 3 (8) of orientation = 1: x-flipped
  965. Bit 4 (16) of orientation = 0: normal
  966. Bit 4 (16) of orientation = 1: y-flipped
  967. If it works at full screen, simply set bit 1 of orientation to 1, and it should
  968. automatically scale properly!
  969. Use this function to write sprites over the 3d view. For example, you can make
  970. a menu system with this function. Be sure that you call this function for
  971. every single frame after the 3d view is drawn or else it will be flashed on for
  972. only 1 frame. If you want x and y to be the top left corner, set the
  973. orientation to 0. If you want x and y to be the middle of the sprite, set the
  974. orientation to 1. The reason I included the orienation = 1 option is so that
  975. if you want a sprite centered and the size of the tile changes, you don't need
  976. to recompile and guess where the new top left corner is. This function will
  977. clip the sprite to the startumost and startdmost arrays. nPal refers to a
  978. palette lookup list (normally 0). */
  979. void plotpixel(long x, long y, uchar hue);
  980. uchar getpixel(long x, long y);
  981. void precache( void );
  982. /* Load all tiles used in the current map into the cache */
  983. void preparemirror( long x, long y, long z, short ang, long horiz,
  984. short wallnum, short sectnum, long *tx, long *ty, short *tang );
  985. /* called before drawrooms, viewProcessSprites, drawmasks and completemirror in mirrorDraw() */
  986. void printext16(int x, int y, short nForeColor, short nBackColor, char *text, char nFont);
  987. /* color -1 is transparent, nFont 0=8*8, 1=3*5 */
  988. void printext256(int x, int y, short nForeColor, short nBackColor, char *text, char nFont);
  989. /* color -1 is transparent, nFont 0=8*8, 1=3*5 */
  990. void printext( long x, long y, char buffer[42], short tilenum, char invisiblecol );
  991. /* Use this function to print text anywhere on the screen from a font that you
  992. can create in EDITART. Please see my example font in TILES.ART to see how I
  993. lay out the user-defined font. X ranges from 0-319. Y ranges from 0-199. The
  994. buffer is the string to print. Tilenum specifies which font to use.
  995. Invisiblecol tells printext what color to draw the transparent pixels. If
  996. invisiblecol is 255 then the transpararent pixels are still transparent. */
  997. void printmessage16(char *);
  998. void printmessage256(char *);
  999. /* quick way to display message in the top right of status bar in 2d mode */
  1000. void __interrupt __far printscreeninterrupt( void );
  1001. /* Gets called when the PrScr key is pressed, Currently passes it to INT 5 */
  1002. void qsetmode640350( void );
  1003. /* Set to the 2D map mode #1 (640*350*16) */
  1004. void qsetmode640480( void );
  1005. /* Set to the 2D map mode #2 (640*480*16) */
  1006. int raytrace( long, long, long, long, long *, long * );
  1007. /* Used internally by clipmove(). */
  1008. void resettiming( void );
  1009. /* Resets timing, such as setting totalclock = 0. Also resets other timers.
  1010. This is for use with the showengineinfo */
  1011. int rintersect( int x, int y, int z, int dx, int dy, int dz, int xc,
  1012. int yc, int xd, int yd, int *xint, int *yint, int *zint);
  1013. /* Determines if and where and if the ray specified by origin (x,y,z) and
  1014. magnitude (dx,dy,dz) intersects with line segment CD. If the lines intersect,
  1015. returns 1 and sets x, y, and z to the point of intersection. */
  1016. void rotatepoint( long xpivot, long ypivot, long x, long y, short dAng,
  1017. long *newX, long *newY );
  1018. /* Rotatepoint will rotate point(x,y) around point(xpivot,ypivot) by the
  1019. dAng value. The resultant point will be s */
  1020. enum {
  1021. kRotateNormal = 0,
  1022. kRotateTranslucent = 0x01,
  1023. kRotateScale = 0x02,
  1024. kRotateYFlip = 0x04,
  1025. kRotateUnclipped = 0x08,
  1026. kRotateStatus = 0x0A,
  1027. kRotateCorner = 0x10,
  1028. kRotateTranslucentR = 0x20,
  1029. kRotateNoMask = 0x40,
  1030. kRotateAllPages = 0x80,
  1031. };
  1032. void rotatesprite(long sx, long sy, long zoom, short ang,
  1033. short picnum, schar shade, char pal, char flags,
  1034. long cx1, long cy1, long cx2, long cy2);
  1035. /*
  1036. (sx, sy) is the center of the sprite to draw defined as
  1037. screen coordinates shifted up by 16.
  1038. (zoom) is the zoom in 16:16 format. Normal zoom is 65536.
  1039. (ang) is the angle (0 is straight up)
  1040. (picnum) is the tile number
  1041. (shade) is 0 normally but can be any standard shade
  1042. (pal) is the palookup number from 0-255.
  1043. flags & 0x01: Translucence
  1044. flags & 0x02: Scale to viewing window
  1045. flags & 0x04: Y flip
  1046. flags & 0x08: Don't clip to startumost/startdmost.
  1047. flags & 0x10: Position by top left corner instead of origin
  1048. flags & 0x20: Translucence using reverse translucency values
  1049. flags & 0x40: Don't check for mask color (faster)
  1050. flags & 0x80: Write sprite successively to all pages
  1051. Auto-scale mode (kRotateScale) will automatically scale from 320*200
  1052. resolution coordinates to the clipping window passed (cx1, cy1, cx2, cy2).
  1053. In auto-scale mode, don't pre-scale the (sx, sy) coordinates. Simply pass
  1054. (sx, sy) as if the resolution was 320*200 even though it may be different.
  1055. This means that you shouldn't use xdim or ydim to get (sx, sy).
  1056. (cx1, cy1, cx2, cy2) - The clipping window. These coordinates are never
  1057. scaled, not even in auto-scale mode. Usually you should pass them as
  1058. (windowx1,windowy1,windowx2,windowy2) for things scaled to the viewing
  1059. window or (0L,0L,xdim-1L,ydim-1L) for things scaled to full screen.
  1060. Probably the only time you wouldn't follow this rule is if you program a
  1061. non-scaled tiled background function.
  1062. Note: As a special case, if both (flags & 2) && (flags & 8) then
  1063. rotatesprite will scale to the full screen (0,0,xdim-1,ydim-1) rather than
  1064. setview's viewing window. (windowx1,windowy1,etc.) This case is useful
  1065. for status bars, etc.
  1066. */
  1067. int saveboard( char *filename, long *posx, long *posy, long *posz, short *ang,
  1068. short *cursectnum );
  1069. /* Saves the given board from memory inro the specified filename. Returns -1
  1070. if unable to save. If no extension is given, .MAP will be appended to the
  1071. filename. */
  1072. void scansector( short nSector );
  1073. /* Used internally by drawrooms() and drawalls(). */
  1074. void screencapture(char *filename);
  1075. /* Capture the screen and save it as a .BMP file. I don't know why my .BMP
  1076. format isn't compatible with other programs. */
  1077. short sectorofwall(short nWall);
  1078. /* Returns the sector index for a given wall. */
  1079. void setaspect( long xRange, int aspectRatio );
  1080. /* Parameter aspectRatio is a 16:16 fraction that is pixWidth/pixHeight. Note
  1081. you will need to pass in the reciprical fraction if you use 4/3 * ydim/xdim.
  1082. For a standard 90ø 320*200 screen, xRange and aspectRatio are 65536. For
  1083. square aspect ratio at 320*400, set aspectRatio to 131072. Since xRange is
  1084. actually zoom, you must modify the aspect ratio inversely if you only want to
  1085. change the viewing angle. */
  1086. void setbrightness(char brightness, char *pal);
  1087. /* Simply call this function where brightness ranges from 0 to 4. Brightness
  1088. defaults to 0. Levels 1-4 are all brighter than 0. If you switch between 2D &
  1089. 3D modes, the engine will remember the current brightness level. */
  1090. void setgamemode( void );
  1091. /* This function sets the video mode to 320*200*256color graphics. Since BUILD
  1092. supports several different modes including mode x, mode 13h, and other special
  1093. modes, I don't expect you to write any graphics output functions. Soon I have
  1094. all the necessary functions) If for some reason, you use your own graphics
  1095. mode, you must call this function again before using the BUILD drawing
  1096. functions. */
  1097. void setsprite(short spritenum, long newx, long newy, long newz);
  1098. /* This function simply sets the sprite's position to a specified coordinate
  1099. newx, newy, newz) without any checking to see whether the position is
  1100. valid or not. You could directly modify the sprite[].x, sprite[].y, and
  1101. sprite[].z values, but if you use my function, the sprite is guaranteed to
  1102. be in the right sector. */
  1103. void setverts( long, long, long, long, long, long );
  1104. /* Used internally by stereoinit() */
  1105. void setvesamode( long mode );
  1106. /* Initializes hires VESA 3d mode */
  1107. void setview( long x1, long y1, long x2, long y2 );
  1108. /* Change the size of the 3d view window */
  1109. void setviewtotile( short tile, long x, long y );
  1110. void setviewback( void );
  1111. /* */
  1112. void showengineinfo( void );
  1113. /* Use this function after setting to text mode to view some statistics about
  1114. the engine, such as frame rate. */
  1115. int spritewallfront( short nSprite, short nWall );
  1116. /* determines z order of sprites and masked walls. Used internally by
  1117. drawmasks(). */
  1118. void stereoblit( int page, int screen );
  1119. /* flips pages in stereo view mode */
  1120. void stereoinit( void );
  1121. /* initializes stereo view mode */
  1122. void transmaskvline( long );
  1123. /* Used internally by transmaskwallscan(). */
  1124. void transmaskwallscan( long xb1, long xb2 );
  1125. /* Called by drawmaskwall() for walls that are translucent. */
  1126. void uninitcache( int );
  1127. void uninitengine( void );
  1128. /* Restores interrupt vectors for keyboard and timer, and frees buffers. You
  1129. should call this once at the end of the program before quitting to dos. */
  1130. void uninitkeys( void );
  1131. void updatesector( long x, long y, short *sectnum );
  1132. /* This function updates the sector number according to the x and y values
  1133. passed to it. Be careful when you use this function with sprites because
  1134. remember that the sprite's sector number should not be modified directly. If
  1135. you want to update a sprite's sector, I recomment using setsprite(). */
  1136. int wallfront( short nWall1, short nWall2);
  1137. /* determines wall z order */
  1138. int wallmost( long *, long, long );
  1139. /* used internally in calcwalls() */
  1140. void wallscan( long xb1, long xb2, long *uwall, long *dwall, long *swplc, long *lplc );
  1141. /* Draws walls. Called internally by calcwalls(). */
  1142. void __interrupt __far zerohandler( void );
  1143. /* Ken's spiffy divide by zero handler. Obsolete. */
  1144. /***********************************************************************
  1145. * Assembly helper functions
  1146. **********************************************************************/
  1147. void fixtransluscence( void * );
  1148. /* Fixup self modifying assembly to point to the current translucence table */
  1149. void setpalookupaddress( void *);
  1150. /* Fixup self modifying assembly to point to the current palookup table */
  1151. void setupvlineasm(int shift);
  1152. #pragma aux setupvlineasm parm [eax];
  1153. void setupmvlineasm(int shift);
  1154. #pragma aux setupmvlineasm parm [eax];
  1155. extern long vplce[4]; // this is the v coordinate
  1156. extern long vince[4]; // this is the dv coordinate
  1157. extern BYTE *palookupoffse[4]; // this is the pointer to the 256 byte subtable
  1158. extern BYTE *bufplce[4]; // this is the pointer to the texture
  1159. long vlineasm1(long dv, BYTE *pal, long count, long v, BYTE *source, BYTE *dest);
  1160. #pragma aux vlineasm1 parm [eax][ebx][ecx][edx][esi][edi];
  1161. long mvlineasm1(long vinc, BYTE *pal, long, long vplc, BYTE *source, BYTE *dest);
  1162. #pragma aux mvlineasm1 parm [eax][ebx][ecx][edx][esi][edi];
  1163. long vlineasm4(long count, BYTE *dest);
  1164. #pragma aux vlineasm4 parm [ecx][edi] modify [eax ebx ecx edx esi edi];
  1165. long mvlineasm4(long count, BYTE *dest);
  1166. #pragma aux mvlineasm4 parm [ecx][edi] modify [eax ebx ecx edx esi edi];
  1167. #ifdef __cplusplus
  1168. }
  1169. #endif
  1170. #endif /* __ENGINE_H */