NTMAP.NEW 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990
  1. /*
  2. * $Source: f:/miner/source/texmap/rcs/ntmap.c $
  3. * $Revision: 1.61 $
  4. * $Author: jay $
  5. * $Date: 1996/03/12 20:15:58 $
  6. *
  7. * Start of conversion to new texture mapper.
  8. *
  9. * $Log: ntmap.c $
  10. * Revision 1.61 1996/03/12 20:15:58 jay
  11. * From JAY PATEL: changes for S3/Virge version
  12. *
  13. * Revision 1.60 1996/02/21 18:18:53 matt
  14. * From JOHN: changes to texture mapper, supposed to be slightly better & faster
  15. *
  16. * Revision 1.59 1996/02/12 11:11:37 jay
  17. * From JAY PATEL: code to add Diamond/S3 Virge support
  18. *
  19. * Revision 1.58 1996/01/24 16:37:28 champaign
  20. * From JOHN: texture mapper library cleaned up & optimized
  21. *
  22. * Revision 1.57 1995/11/28 10:40:24 matt
  23. * Allow screen heights up to 1024
  24. *
  25. * Revision 1.56 1995/08/21 18:06:20 matt
  26. * Allow screen height up to 768
  27. *
  28. * Revision 1.55 1995/07/17 11:04:00 matt
  29. * Added assert() for correct texture width
  30. *
  31. * Revision 1.54 1995/05/26 16:08:03 matt
  32. * Took out evil include of Descent main directory header file
  33. *
  34. * Revision 1.53 1995/04/18 14:36:14 matt
  35. * Moved window_clip vars to texmap library from Descent main source
  36. *
  37. * Revision 1.52 1995/03/14 15:13:06 john
  38. * Increased MAX_Y_Pointers to 480.
  39. *
  40. * Revision 1.51 1995/02/23 14:25:09 john
  41. * Added editor tmap.
  42. *
  43. * Revision 1.50 1995/02/20 18:22:58 john
  44. * Put all the externs in the assembly modules into tmap_inc.asm.
  45. * Also, moved all the C versions of the inner loops into a new module,
  46. * scanline.c.
  47. *
  48. * Revision 1.49 1995/02/20 17:09:11 john
  49. * Added code so that you can build the tmapper with no assembly!
  50. *
  51. * Revision 1.48 1995/01/06 11:11:30 mike
  52. * even when not in editor, have 400 lines in texture map scanline table.
  53. *
  54. * Revision 1.47 1994/12/15 16:43:25 matt
  55. * Took out code only needed by editor
  56. *
  57. * Revision 1.46 1994/12/09 22:35:37 mike
  58. * fix bug in before call to asm_tmap_scanline_per causing write of pixel onto past right border onto left.
  59. *
  60. * Revision 1.45 1994/12/06 16:31:06 mike
  61. * fix bug in asm_tmap_scanline_matt interface.
  62. *
  63. * Revision 1.44 1994/12/04 20:37:18 mike
  64. * *** empty log message ***
  65. *
  66. * Revision 1.43 1994/12/02 23:30:04 mike
  67. * optimizations.
  68. *
  69. * Revision 1.42 1994/11/30 00:57:43 mike
  70. * optimizations.
  71. *
  72. * Revision 1.41 1994/11/28 13:34:27 mike
  73. * optimizations.
  74. *
  75. * Revision 1.40 1994/11/28 01:30:01 mike
  76. * kill warning.
  77. *
  78. * Revision 1.39 1994/11/28 01:28:59 mike
  79. * optimizations.
  80. *
  81. * Revision 1.38 1994/11/21 14:08:07 john
  82. * Took out all multiple instead of divide code.
  83. *
  84. * Revision 1.37 1994/11/19 15:21:52 mike
  85. * rip out unused code.
  86. *
  87. * Revision 1.36 1994/11/14 11:42:51 mike
  88. * optimization.
  89. *
  90. * Revision 1.35 1994/11/12 16:41:36 mike
  91. * *** empty log message ***
  92. *
  93. * Revision 1.34 1994/11/10 21:28:41 mike
  94. * remove call to init_interface_vars_to_assembler.
  95. *
  96. * Revision 1.33 1994/11/10 11:08:59 mike
  97. * detail level stuff.
  98. *
  99. * Revision 1.32 1994/11/09 22:55:52 matt
  100. * Added variable Current_seg_depth for detail level optimization
  101. *
  102. * Revision 1.31 1994/11/09 19:57:31 john
  103. * Added texture rle caching.
  104. *
  105. * Revision 1.30 1994/11/09 19:54:48 mike
  106. * Call flat shader if Tmap_flat_flag set.
  107. *
  108. * Revision 1.29 1994/11/02 21:33:31 john
  109. * Added Burger Bill's optimization, ie.. 2 muls per 8 pixels.
  110. *
  111. * Revision 1.28 1994/11/02 11:32:16 john
  112. * Added code for c callable inner loop and code to
  113. * test dividing out z0.
  114. *
  115. * Revision 1.27 1994/10/28 20:54:32 matt
  116. * Added error checking
  117. *
  118. * Revision 1.26 1994/10/25 11:20:20 mike
  119. * fix bug in lighting overflow checking for one scanline tall linear texture maps.
  120. *
  121. * Revision 1.25 1994/08/03 15:40:33 mike
  122. * Prevent divide overflows, decrease occurrence of precision-caused glitches.
  123. *
  124. * Revision 1.24 1994/07/27 09:31:16 mike
  125. * Fix concave texture map problem, decrease occurrence of unimportant int 3.
  126. *
  127. * Revision 1.23 1994/06/17 12:23:31 mike
  128. * Support non-lighted texture maps.
  129. *
  130. * Revision 1.22 1994/06/11 08:10:24 mike
  131. * Fix mysterious hang bug, lighting value was out of range.
  132. *
  133. * Revision 1.21 1994/06/09 16:10:16 mike
  134. * Change SC2000 from constant to variable.
  135. *
  136. */
  137. #pragma off (unreferenced)
  138. static char rcsid[] = "$Id: ntmap.c 1.61 1996/03/12 20:15:58 jay Exp $";
  139. #pragma on (unreferenced)
  140. #define VESA 0
  141. #define NUM_TMAPS 16
  142. #define HEADLIGHT_LIGHTING 0
  143. #define WIREFRAME 0
  144. #define PERSPECTIVE 1
  145. #include <math.h>
  146. #include <limits.h>
  147. #include <stdio.h>
  148. #include <conio.h>
  149. #include <stdlib.h>
  150. #include "pa_enabl.h" //$$POLY_ACC
  151. #include "mono.h"
  152. #include "fix.h"
  153. #include "3d.h"
  154. #include "gr.h"
  155. #include "error.h"
  156. #include "key.h"
  157. #include "texmap.h"
  158. #include "texmapl.h"
  159. #include "rle.h"
  160. #include "scanline.h"
  161. #include "..\main\3dfx_des.h"
  162. #if defined(POLY_ACC)
  163. #include "poly_acc.h"
  164. #endif
  165. #define EDITOR_TMAP 1 //if in, include extra stuff
  166. #define F15_5 (F1_0*15 + F0_5)
  167. // 1 means enable special sc2000 code, else enable only for Descent
  168. #define SC2000K 0
  169. int SC2000 = SC2000K;
  170. // Temporary texture map, interface from Matt's 3d system to Mike's texture mapper.
  171. g3ds_tmap Tmap1;
  172. grs_bitmap Texmap_ptrs[NUM_TMAPS];
  173. grs_bitmap Texmap4_ptrs[NUM_TMAPS];
  174. fix Range_max=0; // debug, kill me
  175. int Interpolation_method=0; // 0 = choose best method
  176. int Lighting_on; // initialize to no lighting
  177. int Tmap_flat_flag = 0; // 1 = render texture maps as flat shaded polygons.
  178. int Current_seg_depth; // HACK INTERFACE: how far away the current segment (& thus texture) is
  179. int Max_perspective_depth;
  180. int Max_linear_depth;
  181. int Max_flat_depth;
  182. //variables for clipping the texture-mapper to screen region
  183. int Window_clip_left, Window_clip_bot, Window_clip_right, Window_clip_top;
  184. // These variables are the interface to assembler. They get set for each texture map, which is a real waste of time.
  185. // They should be set only when they change, which is generally when the window bounds change. And, even still, it's
  186. // a pretty bad interface.
  187. int bytes_per_row=-1;
  188. int write_buffer;
  189. int window_left;
  190. int window_right;
  191. int window_top;
  192. int window_bottom;
  193. int window_width;
  194. int window_height;
  195. uint dest_row_data;
  196. int loop_count;
  197. #define MAX_Y_POINTERS 1024
  198. int y_pointers[MAX_Y_POINTERS];
  199. #ifdef USE_SELECTORS
  200. short pixel_data_selector; // selector for current pixel data for texture mapper
  201. #endif
  202. fix fix_recip[FIX_RECIP_TABLE_SIZE];
  203. int Fix_recip_table_computed=0;
  204. fix fx_l, fx_u, fx_v, fx_z, fx_du_dx, fx_dv_dx, fx_dz_dx, fx_dl_dx;
  205. int fx_xleft, fx_xright, fx_y, fx_u_right, fx_v_right, fx_z_right;
  206. unsigned char * pixptr;
  207. int Transparency_on = 0;
  208. int dither_intensity_lighting = 0;
  209. ubyte * tmap_flat_cthru_table;
  210. ubyte tmap_flat_color;
  211. ubyte tmap_flat_shade_value;
  212. // F1_0/Z LOOKUP TABLE:
  213. // Sig bits... 10 looks fuzzy, but only uses 4K
  214. // 11 breaks up when close, but quite acceptable, Uses 8K
  215. // 12 looks good,except when very close. Can be used for game. Uses 16K. Recommended by John.
  216. #define DIVIDE_SIG_BITS 12
  217. #define Z_SHIFTER (30-DIVIDE_SIG_BITS)
  218. #define DIVIDE_TABLE_SIZE (1<<DIVIDE_SIG_BITS)
  219. ubyte divide_table_filled = 0;
  220. fix divide_table[1<<DIVIDE_SIG_BITS]; // Can use 16 bits if we divide by the greator of Z0 or Z1, instead of always Z0.
  221. void fill_divide_table()
  222. {
  223. int i;
  224. divide_table_filled = 1;
  225. divide_table[0]=f1_0;
  226. divide_table[1]=f1_0;
  227. for (i=2; i<DIVIDE_TABLE_SIZE; i++ ) {
  228. // entry[i] = 1.0 / i+0.5;
  229. divide_table[i] = fixdiv( F1_0*2, 2*i+1 );
  230. }
  231. }
  232. // -------------------------------------------------------------------------------------
  233. void init_fix_recip_table(void)
  234. {
  235. int i;
  236. fix_recip[0] = F1_0;
  237. for (i=1; i<FIX_RECIP_TABLE_SIZE; i++)
  238. fix_recip[i] = F1_0/i;
  239. Fix_recip_table_computed = 1;
  240. }
  241. // -------------------------------------------------------------------------------------
  242. // Initialize interface variables to assembler.
  243. // These things used to be constants. This routine is now (10/6/93) getting called for
  244. // every texture map. It should get called whenever the window changes, or, preferably,
  245. // not at all. I'm pretty sure these variables are only being used for range checking.
  246. void init_interface_vars_to_assembler(void)
  247. {
  248. grs_bitmap *bp;
  249. bp = &grd_curcanv->cv_bitmap;
  250. Assert(bp!=NULL);
  251. Assert(bp->bm_data!=NULL);
  252. Assert(bp->bm_h <= MAX_Y_POINTERS);
  253. // If bytes_per_row has changed, create new table of pointers.
  254. if (bytes_per_row != (int) bp->bm_rowsize) {
  255. int y_val, i;
  256. bytes_per_row = (int) bp->bm_rowsize;
  257. y_val = 0;
  258. for (i=0; i<MAX_Y_POINTERS; i++) {
  259. y_pointers[i] = y_val;
  260. y_val += bytes_per_row;
  261. }
  262. }
  263. write_buffer = (int) bp->bm_data;
  264. window_left = 0;
  265. window_right = (int) bp->bm_w-1;
  266. window_top = 0;
  267. window_bottom = (int) bp->bm_h-1;
  268. Window_clip_left = window_left;
  269. Window_clip_right = window_right;
  270. Window_clip_top = window_top;
  271. Window_clip_bot = window_bottom;
  272. window_width = bp->bm_w;
  273. window_height = bp->bm_h;
  274. if (!Fix_recip_table_computed)
  275. init_fix_recip_table();
  276. #if defined(POLY_ACC)
  277. pa_set_3d_offset(bp->bm_x, bp->bm_y);
  278. #endif
  279. if ( !divide_table_filled ) fill_divide_table();
  280. }
  281. // -------------------------------------------------------------------------------------
  282. // VARIABLES
  283. extern g3ds_tmap Tmap1;
  284. // -------------------------------------------------------------------------------------
  285. // Returns number preceding val modulo modulus.
  286. // prevmod(3,4) = 2
  287. // prevmod(0,4) = 3
  288. int prevmod(int val,int modulus)
  289. {
  290. if (val > 0)
  291. return val-1;
  292. else
  293. return modulus-1;
  294. // return (val + modulus - 1) % modulus;
  295. }
  296. // Returns number succeeding val modulo modulus.
  297. // succmod(3,4) = 0
  298. // succmod(0,4) = 1
  299. int succmod(int val,int modulus)
  300. {
  301. if (val < modulus-1)
  302. return val+1;
  303. else
  304. return 0;
  305. // return (val + 1) % modulus;
  306. }
  307. // -------------------------------------------------------------------------------------
  308. // Select topmost vertex (minimum y coordinate) and bottommost (maximum y coordinate) in
  309. // texture map. If either is part of a horizontal edge, then select leftmost vertex for
  310. // top, rightmost vertex for bottom.
  311. // Important: Vertex is selected with integer precision. So, if there are vertices at
  312. // (0.0,0.7) and (0.5,0.3), the first vertex is selected, because they y coordinates are
  313. // considered the same, so the smaller x is favored.
  314. // Parameters:
  315. // nv number of vertices
  316. // v3d pointer to 3d vertices containing u,v,x2d,y2d coordinates
  317. // Results in:
  318. // *min_y_ind
  319. // *max_y_ind
  320. // -------------------------------------------------------------------------------------
  321. void compute_y_bounds(g3ds_tmap *t, int *vlt, int *vlb, int *vrt, int *vrb,int *bottom_y_ind)
  322. {
  323. int i;
  324. int min_y,max_y;
  325. int min_y_ind;
  326. int original_vrt;
  327. fix min_x;
  328. // Scan all vertices, set min_y_ind to vertex with smallest y coordinate.
  329. min_y = f2i(t->verts[0].y2d);
  330. max_y = min_y;
  331. min_y_ind = 0;
  332. min_x = f2i(t->verts[0].x2d);
  333. *bottom_y_ind = 0;
  334. for (i=1; i<t->nv; i++) {
  335. if (f2i(t->verts[i].y2d) < min_y) {
  336. min_y = f2i(t->verts[i].y2d);
  337. min_y_ind = i;
  338. min_x = f2i(t->verts[i].x2d);
  339. } else if (f2i(t->verts[i].y2d) == min_y) {
  340. if (f2i(t->verts[i].x2d) < min_x) {
  341. min_y_ind = i;
  342. min_x = f2i(t->verts[i].x2d);
  343. }
  344. }
  345. if (f2i(t->verts[i].y2d) > max_y) {
  346. max_y = f2i(t->verts[i].y2d);
  347. *bottom_y_ind = i;
  348. }
  349. }
  350. //--removed mk, 11/27/94-- // Check for a non-upright-hourglass polygon and fix, if necessary, by bashing a y coordinate.
  351. //--removed mk, 11/27/94-- // min_y_ind = index of minimum y coordinate, *bottom_y_ind = index of maximum y coordinate
  352. //--removed mk, 11/27/94--{
  353. //--removed mk, 11/27/94-- int max_temp, min_temp;
  354. //--removed mk, 11/27/94--
  355. //--removed mk, 11/27/94-- max_temp = *bottom_y_ind;
  356. //--removed mk, 11/27/94-- if (*bottom_y_ind < min_y_ind)
  357. //--removed mk, 11/27/94-- max_temp += t->nv;
  358. //--removed mk, 11/27/94--
  359. //--removed mk, 11/27/94-- for (i=min_y_ind; i<max_temp; i++) {
  360. //--removed mk, 11/27/94-- if (f2i(t->verts[i%t->nv].y2d) > f2i(t->verts[(i+1)%t->nv].y2d)) {
  361. //--removed mk, 11/27/94-- Int3();
  362. //--removed mk, 11/27/94-- t->verts[(i+1)%t->nv].y2d = t->verts[i%t->nv].y2d;
  363. //--removed mk, 11/27/94-- }
  364. //--removed mk, 11/27/94-- }
  365. //--removed mk, 11/27/94--
  366. //--removed mk, 11/27/94-- min_temp = min_y_ind;
  367. //--removed mk, 11/27/94-- if (min_y_ind < *bottom_y_ind)
  368. //--removed mk, 11/27/94-- min_temp += t->nv;
  369. //--removed mk, 11/27/94--
  370. //--removed mk, 11/27/94-- for (i=*bottom_y_ind; i<min_temp; i++) {
  371. //--removed mk, 11/27/94-- if (f2i(t->verts[i%t->nv].y2d) < f2i(t->verts[(i+1)%t->nv].y2d)) {
  372. //--removed mk, 11/27/94-- Int3();
  373. //--removed mk, 11/27/94-- t->verts[(i+1)%t->nv].y2d = t->verts[i%t->nv].y2d;
  374. //--removed mk, 11/27/94-- }
  375. //--removed mk, 11/27/94-- }
  376. //--removed mk, 11/27/94--}
  377. // Set "vertex left top", etc. based on vertex with topmost y coordinate
  378. *vlt = min_y_ind;
  379. *vrt = *vlt;
  380. *vlb = prevmod(*vlt,t->nv);
  381. *vrb = succmod(*vrt,t->nv);
  382. // If right edge is horizontal, then advance along polygon bound until it no longer is or until all
  383. // vertices have been examined.
  384. // (Left edge cannot be horizontal, because *vlt is set to leftmost point with highest y coordinate.)
  385. original_vrt = *vrt;
  386. while (f2i(t->verts[*vrt].y2d) == f2i(t->verts[*vrb].y2d)) {
  387. if (succmod(*vrt,t->nv) == original_vrt) {
  388. break;
  389. }
  390. *vrt = succmod(*vrt,t->nv);
  391. *vrb = succmod(*vrt,t->nv);
  392. }
  393. }
  394. // -------------------------------------------------------------------------------------
  395. // Returns dx/dy given two vertices.
  396. // If dy == 0, returns 0.0
  397. // -------------------------------------------------------------------------------------
  398. //--fix compute_dx_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex)
  399. //--{
  400. //-- int dy;
  401. //--
  402. //-- // compute delta x with respect to y for any edge
  403. //-- dy = f2i(t->verts[bottom_vertex].y2d - t->verts[top_vertex].y2d) + 1;
  404. //-- if (dy)
  405. //-- return (t->verts[bottom_vertex].x2d - t->verts[top_vertex].x2d) / dy;
  406. //-- else
  407. //-- return 0;
  408. //--
  409. //--}
  410. fix compute_du_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  411. {
  412. return fixmul(t->verts[bottom_vertex].u - t->verts[top_vertex].u, recip_dy);
  413. }
  414. fix compute_dv_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  415. {
  416. return fixmul(t->verts[bottom_vertex].v - t->verts[top_vertex].v, recip_dy);
  417. }
  418. fix compute_dl_dy_lin(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  419. {
  420. return fixmul(t->verts[bottom_vertex].l - t->verts[top_vertex].l, recip_dy);
  421. }
  422. fix compute_dx_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  423. {
  424. return fixmul(t->verts[bottom_vertex].x2d - t->verts[top_vertex].x2d, recip_dy);
  425. }
  426. fix compute_du_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  427. {
  428. return fixmul(fixmul(t->verts[bottom_vertex].u,t->verts[bottom_vertex].z) - fixmul(t->verts[top_vertex].u,t->verts[top_vertex].z), recip_dy);
  429. }
  430. fix compute_dv_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  431. {
  432. return fixmul(fixmul(t->verts[bottom_vertex].v,t->verts[bottom_vertex].z) - fixmul(t->verts[top_vertex].v,t->verts[top_vertex].z), recip_dy);
  433. }
  434. fix compute_dz_dy(g3ds_tmap *t, int top_vertex,int bottom_vertex, fix recip_dy)
  435. {
  436. return fixmul(t->verts[bottom_vertex].z - t->verts[top_vertex].z, recip_dy);
  437. }
  438. int Skip_short_flag=0;
  439. // -------------------------------------------------------------------------------------
  440. // Texture map current scanline in perspective.
  441. // -------------------------------------------------------------------------------------
  442. int Do_vertical_scan=0;
  443. int Break_on_flat=0;
  444. // -------------------------------------------------------------------------------------
  445. // Render a texture map with lighting using perspective interpolation in inner and outer loops.
  446. // -------------------------------------------------------------------------------------
  447. void ntmap_outerloop_correct_lighted( g3ds_tmap *t )
  448. {
  449. #define LINEAR 0 // 0=Perspective, 1=Linear
  450. #define LIGHTING 1 // 0=No lighting, 1=Use lighting
  451. #ifdef NASM
  452. #define INNER_LOOP c_tmap_scanline_per // Function to be called when ready to draw.
  453. #else
  454. #define INNER_LOOP asm_tmap_scanline_per // Function to be called when ready to draw.
  455. #endif
  456. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  457. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  458. #include "ntmapout.h"
  459. }
  460. void ntmap_outerloop_correct_nolight( g3ds_tmap *t )
  461. {
  462. #define LINEAR 0 // 0=Perspective, 1=Linear
  463. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  464. #ifdef NASM
  465. #define INNER_LOOP c_tmap_scanline_per_nolight // Function to be called when ready to draw.
  466. #else
  467. #define INNER_LOOP asm_tmap_scanline_per // Function to be called when ready to draw.
  468. #endif
  469. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  470. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  471. #include "ntmapout.h"
  472. }
  473. extern void asm_tmap_scanline_llt();
  474. void ntmap_outerloop_lin_lighted_trans( g3ds_tmap *t )
  475. {
  476. #define LINEAR 1 // 0=Perspective, 1=Linear
  477. #define LIGHTING 1 // 0=No lighting, 1=Use lighting
  478. #ifdef NASM
  479. #define INNER_LOOP c_tmap_scanline_lin // Function to be called when ready to draw.
  480. #else
  481. #define INNER_LOOP asm_tmap_scanline_llt // Function to be called when ready to draw.
  482. #endif
  483. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  484. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  485. #include "ntmapout.h"
  486. }
  487. extern void asm_tmap_scanline_lln();
  488. void ntmap_outerloop_lin_lighted_notrans( g3ds_tmap *t )
  489. {
  490. #define LINEAR 1 // 0=Perspective, 1=Linear
  491. #define LIGHTING 1 // 0=No lighting, 1=Use lighting
  492. #ifdef NASM
  493. #define INNER_LOOP c_tmap_scanline_lin // Function to be called when ready to draw.
  494. #else
  495. #define INNER_LOOP asm_tmap_scanline_lln // Function to be called when ready to draw.
  496. #endif
  497. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  498. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  499. #include "ntmapout.h"
  500. }
  501. extern void asm_tmap_scanline_plt();
  502. void ntmap_outerloop_per_lighted_trans( g3ds_tmap *t )
  503. {
  504. #define LINEAR 0 // 0=Perspective, 1=Linear
  505. #define LIGHTING 1 // 0=No lighting, 1=Use lighting
  506. #ifdef NASM
  507. #define INNER_LOOP c_tmap_scanline_per // Function to be called when ready to draw.
  508. #else
  509. #define INNER_LOOP asm_tmap_scanline_plt // Function to be called when ready to draw.
  510. #endif
  511. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  512. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  513. #include "ntmapout.h"
  514. }
  515. extern void asm_tmap_scanline_pln();
  516. void ntmap_outerloop_per_lighted_notrans( g3ds_tmap *t )
  517. {
  518. #define LINEAR 0 // 0=Perspective, 1=Linear
  519. #define LIGHTING 1 // 0=No lighting, 1=Use lighting
  520. #ifdef NASM
  521. #define INNER_LOOP c_tmap_scanline_per // Function to be called when ready to draw.
  522. #else
  523. #define INNER_LOOP asm_tmap_scanline_pln // Function to be called when ready to draw.
  524. #endif
  525. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  526. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  527. #include "ntmapout.h"
  528. }
  529. extern void asm_tmap_scanline_lnt();
  530. void ntmap_outerloop_lin_nolight_trans( g3ds_tmap *t )
  531. {
  532. #define LINEAR 1 // 0=Perspective, 1=Linear
  533. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  534. #ifdef NASM
  535. #define INNER_LOOP c_tmap_scanline_lin_nolight // Function to be called when ready to draw.
  536. #else
  537. #define INNER_LOOP asm_tmap_scanline_lnt // Function to be called when ready to draw.
  538. #endif
  539. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  540. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  541. #include "ntmapout.h"
  542. }
  543. extern void asm_tmap_scanline_lnn();
  544. void ntmap_outerloop_lin_nolight_notrans( g3ds_tmap *t )
  545. {
  546. #define LINEAR 1 // 0=Perspective, 1=Linear
  547. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  548. #ifdef NASM
  549. #define INNER_LOOP c_tmap_scanline_lin_nolight // Function to be called when ready to draw.
  550. #else
  551. #define INNER_LOOP asm_tmap_scanline_lnn // Function to be called when ready to draw.
  552. #endif
  553. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  554. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  555. #include "ntmapout.h"
  556. }
  557. extern void asm_tmap_scanline_pnt();
  558. void ntmap_outerloop_per_nolight_trans( g3ds_tmap *t )
  559. {
  560. #define LINEAR 0 // 0=Perspective, 1=Linear
  561. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  562. #ifdef NASM
  563. #define INNER_LOOP c_tmap_scanline_per_nolight // Function to be called when ready to draw.
  564. #else
  565. #define INNER_LOOP asm_tmap_scanline_pnt // Function to be called when ready to draw.
  566. #endif
  567. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  568. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  569. #include "ntmapout.h"
  570. }
  571. extern void asm_tmap_scanline_pnn();
  572. void ntmap_outerloop_per_nolight_notrans( g3ds_tmap *t )
  573. {
  574. #define LINEAR 0 // 0=Perspective, 1=Linear
  575. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  576. #ifdef NASM
  577. #define INNER_LOOP c_tmap_scanline_per_nolight // Function to be called when ready to draw.
  578. #else
  579. #define INNER_LOOP asm_tmap_scanline_pnn // Function to be called when ready to draw.
  580. #endif
  581. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  582. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  583. #include "ntmapout.h"
  584. }
  585. extern void asm_tmap_scanline_editor();
  586. extern void c_tmap_scanline_editor();
  587. void ntmap_outerloop_editor( g3ds_tmap *t )
  588. {
  589. #define LINEAR 0 // 0=Perspective, 1=Linear
  590. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  591. #ifdef NASM
  592. #define INNER_LOOP c_tmap_scanline_editor // Function to be called when ready to draw.
  593. #else
  594. #define INNER_LOOP asm_tmap_scanline_editor // Function to be called when ready to draw.
  595. #endif
  596. #define CHECK_WINDOW 0 // Set to 1 to check window clip
  597. #define USE_UVS 1 // Set to 1 to enable U,V interpolation
  598. #include "ntmapout.h"
  599. }
  600. // -------------------------------------------------------------------------------------
  601. // Render a texture map.
  602. // Linear in outer loop, linear in inner loop.
  603. // -------------------------------------------------------------------------------------
  604. void texture_map_flat(g3ds_tmap *t)
  605. {
  606. #define LINEAR 1 // 0=Perspective, 1=Linear
  607. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  608. #ifdef NASM
  609. #define INNER_LOOP c_tmap_scanline_flat // Function to be called when ready to draw.
  610. #else
  611. #define INNER_LOOP asm_tmap_scanline_flat // Function to be called when ready to draw.
  612. #endif
  613. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  614. #define USE_UVS 0 // Set to 1 to enable U,V interpolation
  615. #include "ntmapout.h"
  616. }
  617. extern void asm_tmap_scanline_shaded(); // In tmapfade.asm
  618. void texture_map_flat_faded(g3ds_tmap *t)
  619. {
  620. #define LINEAR 1 // 0=Perspective, 1=Linear
  621. #define LIGHTING 0 // 0=No lighting, 1=Use lighting
  622. #ifdef NASM
  623. #define INNER_LOOP c_tmap_scanline_shaded // Function to be called when ready to draw.
  624. #else
  625. #define INNER_LOOP asm_tmap_scanline_shaded // Function to be called when ready to draw.
  626. #endif
  627. #define CHECK_WINDOW 1 // Set to 1 to check window clip
  628. #define USE_UVS 0 // Set to 1 to enable U,V interpolation
  629. #include "ntmapout.h"
  630. }
  631. // fix DivNum = F1_0*12;
  632. extern void draw_tmap_flat(grs_bitmap *bp,int nverts,g3s_point **vertbuf);
  633. // -------------------------------------------------------------------------------------
  634. // Interface from Matt's data structures to Mike's texture mapper.
  635. // -------------------------------------------------------------------------------------
  636. void draw_tmap(grs_bitmap *bp,int nverts,g3s_point **vertbuf)
  637. {
  638. int i;
  639. int lighting_mode = Lighting_on;
  640. int render_method;
  641. fix min_z;
  642. Assert(nverts <= MAX_TMAP_VERTS);
  643. Assert(bp->bm_w == 64);
  644. Assert(Lighting_on < 3);
  645. // If no transparency and seg depth is large, render as flat shaded.
  646. if ((Current_seg_depth > Max_linear_depth) && ((bp->bm_flags & 3) == 0)) {
  647. draw_tmap_flat(bp, nverts, vertbuf);
  648. return;
  649. }
  650. if ( bp->bm_flags & BM_FLAG_RLE )
  651. bp = rle_expand_texture( bp ); // Expand if rle'd
  652. Transparency_on = bp->bm_flags & BM_FLAG_TRANSPARENT;
  653. if (bp->bm_flags & BM_FLAG_NO_LIGHTING)
  654. lighting_mode = 0;
  655. pixptr = bp->bm_data;
  656. render_method = Interpolation_method;
  657. if (render_method==0) {
  658. if (Current_seg_depth > Max_perspective_depth)
  659. render_method = 1; // use linear
  660. else
  661. render_method = 2; // use perspective
  662. }
  663. // Setup texture map in Tmap1
  664. Tmap1.nv = nverts; // Initialize number of vertices
  665. for (i=0; i<nverts; i++) {
  666. g3ds_vertex *tvp = &Tmap1.verts[i];
  667. g3s_point *vp = vertbuf[i];
  668. tvp->x2d = vp->p3_sx;
  669. tvp->y2d = vp->p3_sy;
  670. tvp->u = vp->p3_u << 6; //* bp->bm_w;
  671. tvp->v = vp->p3_v << 6; //* bp->bm_h;
  672. // Perspective stuff:
  673. if ( render_method > 1 ) {
  674. //Check for overflow on fixdiv. Will overflow on vp->z <= something small. Allow only as low as 256.
  675. if (vp->p3_z < 256) {
  676. vp->p3_z = 256;
  677. // Int3(); // we would overflow if we divided!
  678. }
  679. tvp->z = vp->p3_z; //fixdiv(F1_0*12, vp->p3_z);
  680. if ( (i==0) || (tvp->z < min_z) )
  681. min_z = tvp->z;
  682. }
  683. // Lighting stuff:
  684. if (lighting_mode)
  685. tvp->l = vp->p3_l * NUM_LIGHTING_LEVELS;
  686. }
  687. // Calculate 1/Z for perspective
  688. if ( render_method > 1 ) {
  689. g3ds_vertex *tvp = Tmap1.verts;
  690. for (i=0; i<nverts; i++, tvp++) {
  691. tvp->z = fixdiv( min_z, tvp->z );
  692. // Z is now in the range 0-F1_0 (17 bits)
  693. // So, in the next line, we need to
  694. // scale Z down so that it fits in the available
  695. // number of significant bits (12 bits now). But, at the
  696. // same time, we're scaling it up by Z_SHIFTER amount so
  697. // that it use 30 bits for Z interpolation, which keeps the
  698. // dz_dx values from becoming so small that they go to zero.
  699. tvp->z <<= Z_SHIFTER-(17-DIVIDE_SIG_BITS);
  700. }
  701. }
  702. //old way:
  703. tvp->z = fixdiv(f1_0*12,tvp->z);
  704. // render_method:
  705. // 1 = linear, 2 = subdivided perspective, 3 = full perspective
  706. // lighting_mode:
  707. // 0 = no lighting, 1=lighting, 2=editor
  708. #ifndef __3DFX_NOT__
  709. if ( _3dfx_skip_ddraw )
  710. goto do_3dfx;
  711. #endif
  712. #if defined(POLY_ACC)
  713. switch (render_method)
  714. {
  715. /* obsolete 3/5/96.
  716. case 0: // choose best interpolation
  717. if (Current_seg_depth > Max_perspective_depth)
  718. pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 0); // linear
  719. else
  720. pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 1); // persp.
  721. break;
  722. */
  723. case 1: // linear interpolation
  724. pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 0, min_z); // linear
  725. break;
  726. case 2:
  727. case 3: // perspective every pixel interpolation
  728. pa_draw_tmap(bp, &Tmap1, Transparency_on, lighting_mode, 1, min_z); // persp.
  729. break;
  730. default:
  731. Assert(0); // Illegal value for Interpolation_method, must be 0,1,2,3
  732. }
  733. #else
  734. switch( lighting_mode ) {
  735. case 0:
  736. switch (render_method) {
  737. case 1: // linear interpolation
  738. if (Transparency_on)
  739. ntmap_outerloop_lin_nolight_trans(&Tmap1);
  740. else
  741. ntmap_outerloop_lin_nolight_notrans(&Tmap1);
  742. break;
  743. case 2: // subdivided perspective
  744. if (Transparency_on)
  745. ntmap_outerloop_per_nolight_trans( &Tmap1 );
  746. else
  747. ntmap_outerloop_per_nolight_notrans( &Tmap1 );
  748. break;
  749. case 3: // perspective every pixel interpolation
  750. ntmap_outerloop_correct_nolight( &Tmap1 );
  751. break;
  752. default:
  753. Assert(0); // Illegal value for Interpolation_method, must be 0,1,2,3
  754. }
  755. break;
  756. case 1:
  757. switch (render_method) {
  758. case 1: // linear interpolation
  759. if (Transparency_on)
  760. ntmap_outerloop_lin_lighted_trans(&Tmap1);
  761. else
  762. ntmap_outerloop_lin_lighted_notrans(&Tmap1);
  763. break;
  764. case 2: // subdivided perspective
  765. if (Transparency_on)
  766. ntmap_outerloop_per_lighted_trans( &Tmap1 );
  767. else
  768. ntmap_outerloop_per_lighted_notrans( &Tmap1 );
  769. break;
  770. case 3: // perspective every pixel interpolation
  771. ntmap_outerloop_correct_lighted( &Tmap1 );
  772. break;
  773. default:
  774. Assert(0); // Illegal value for Interpolation_method, must be 0,1,2,3
  775. }
  776. break;
  777. #ifdef EDITOR_TMAP
  778. case 2:
  779. ntmap_outerloop_editor( &Tmap1 );
  780. break;
  781. #endif
  782. }
  783. #endif //POLY_ACC
  784. #ifndef __3DFX_NOT__
  785. do_3dfx:
  786. if ( _3dfx_should_draw )
  787. {
  788. if ( Lighting_on )
  789. {
  790. guColorCombineFunction( GR_COLORCOMBINE_TEXTURE_TIMES_ITRGB );
  791. _3dfxDrawTmap( bp, &Tmap1 );
  792. }
  793. else
  794. {
  795. guColorCombineFunction( GR_COLORCOMBINE_DECAL_TEXTURE );
  796. _3dfxDrawTmap( bp, &Tmap1 );
  797. }
  798. }
  799. _3dfx_triangles_rendered_post_clip += Tmap1.nv - 2;
  800. #endif
  801. }
  802. #ifndef __3DFX_NOT__
  803. #define SNAP( a ) ( ( fix ) ( (a) & ( 0xFFFFF000L ) ) )
  804. void _3dfxDrawTmap( grs_bitmap *bp, g3ds_tmap *Tmap1 )
  805. {
  806. GrVertex a, b, c;
  807. int i;
  808. if ( _3dfx_no_texture )
  809. guColorCombineFunction( GR_COLORCOMBINE_ITRGB );
  810. a.r = a.g = a.b = Tmap1->verts[0].l * fix_to_rgb;
  811. a.tmuvtx[0].oow = a.oow = Tmap1->verts[0].z * fix_to_ooz;
  812. a.tmuvtx[0].sow = Tmap1->verts[0].u * fix_to_st * a.oow;
  813. a.tmuvtx[0].tow = Tmap1->verts[0].v * fix_to_st * a.oow;
  814. a.x = SNAP( Tmap1->verts[0].x2d ) * fix_to_float;
  815. a.y = SNAP( Tmap1->verts[0].y2d ) * fix_to_float;
  816. for ( i = 1; i < Tmap1->nv - 1; i++ )
  817. {
  818. extern void sst1InitCheckForHang( void );
  819. b.r = b.g = b.b = Tmap1->verts[i].l * fix_to_rgb;
  820. b.tmuvtx[0].oow = b.oow = Tmap1->verts[i].z * fix_to_ooz;
  821. b.tmuvtx[0].sow = Tmap1->verts[i].u * fix_to_st * b.oow;
  822. b.tmuvtx[0].tow = Tmap1->verts[i].v * fix_to_st * b.oow;
  823. b.x = SNAP( Tmap1->verts[i].x2d ) * fix_to_float;
  824. b.y = SNAP( Tmap1->verts[i].y2d ) * fix_to_float;
  825. c.r = c.g = c.b = Tmap1->verts[i+1].l * fix_to_rgb;
  826. c.tmuvtx[0].oow = c.oow = Tmap1->verts[i+1].z * fix_to_ooz;
  827. c.tmuvtx[0].sow = Tmap1->verts[i+1].u * fix_to_st * c.oow;
  828. c.tmuvtx[0].tow = Tmap1->verts[i+1].v * fix_to_st * c.oow;
  829. c.x = SNAP( Tmap1->verts[i+1].x2d ) * fix_to_float;
  830. c.y = SNAP( Tmap1->verts[i+1].y2d ) * fix_to_float;
  831. sst1InitCheckForHang();
  832. grDrawTriangle( &a, &b, &c );
  833. sst1InitCheckForHang();
  834. }
  835. }
  836. #endif