t3dlib10.cpp
上传用户:husern
上传日期:2018-01-20
资源大小:42486k
文件大小:1310k
源码类别:

游戏

开发平台:

Visual C++

  1. SWAP(tz1,tz2,temp);
  2. // set interpolation restart
  3. irestart = INTERP_RHS;
  4. } // end if
  5. } // end if
  6. else
  7. if (y0 < min_clip_y)
  8. {
  9. // compute all deltas
  10. // LHS
  11. dyl = (y1 - y0);
  12. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  13. dudyl = ((tu1 - tu0) << 0)/dyl;  
  14. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  15. dzdyl = ((tz1 - tz0) << 0)/dyl;  
  16. // RHS
  17. dyr = (y2 - y0);
  18. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  19. dudyr = ((tu2 - tu0) << 0)/dyr;  
  20. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  21. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  22. // compute overclip
  23. dy = (min_clip_y - y0);
  24. // computer new LHS starting values
  25. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  26. ul = dudyl*dy + (tu0 << 0);
  27. vl = dvdyl*dy + (tv0 << 0);
  28. zl = dzdyl*dy + (tz0 << 0);
  29. // compute new RHS starting values
  30. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  31. ur = dudyr*dy + (tu0 << 0);
  32. vr = dvdyr*dy + (tv0 << 0);
  33. zr = dzdyr*dy + (tz0 << 0);
  34. // compute new starting y
  35. ystart = min_clip_y;
  36. // test if we need swap to keep rendering left to right
  37. if (dxdyr < dxdyl)
  38. {
  39. SWAP(dxdyl,dxdyr,temp);
  40. SWAP(dudyl,dudyr,temp);
  41. SWAP(dvdyl,dvdyr,temp);
  42. SWAP(dzdyl,dzdyr,temp);
  43. SWAP(xl,xr,temp);
  44. SWAP(ul,ur,temp);
  45. SWAP(vl,vr,temp);
  46. SWAP(zl,zr,temp);
  47. SWAP(x1,x2,temp);
  48. SWAP(y1,y2,temp);
  49. SWAP(tu1,tu2,temp);
  50. SWAP(tv1,tv2,temp);
  51. SWAP(tz1,tz2,temp);
  52. // set interpolation restart
  53. irestart = INTERP_RHS;
  54. } // end if
  55. } // end if
  56. else
  57. {
  58. // no initial y clipping
  59. // compute all deltas
  60. // LHS
  61. dyl = (y1 - y0);
  62. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  63. dudyl = ((tu1 - tu0) << 0)/dyl;  
  64. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  65. dzdyl = ((tz1 - tz0) << 0)/dyl;   
  66. // RHS
  67. dyr = (y2 - y0);
  68. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dyr;
  69. dudyr = ((tu2 - tu0) << 0)/dyr;  
  70. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  71. dzdyr = ((tz2 - tz0) << 0)/dyr;  
  72. // no clipping y
  73. // set starting values
  74. xl = (x0 << FIXP16_SHIFT);
  75. xr = (x0 << FIXP16_SHIFT);
  76. ul = (tu0 << 0);
  77. vl = (tv0 << 0);
  78. zl = (tz0 << 0);
  79. ur = (tu0 << 0);
  80. vr = (tv0 << 0);
  81. zr = (tz0 << 0);
  82. // set starting y
  83. ystart = y0;
  84. // test if we need swap to keep rendering left to right
  85. if (dxdyr < dxdyl)
  86. {
  87. SWAP(dxdyl,dxdyr,temp);
  88. SWAP(dudyl,dudyr,temp);
  89. SWAP(dvdyl,dvdyr,temp);
  90. SWAP(dzdyl,dzdyr,temp);
  91. SWAP(xl,xr,temp);
  92. SWAP(ul,ur,temp);
  93. SWAP(vl,vr,temp);
  94. SWAP(zl,zr,temp);
  95. SWAP(x1,x2,temp);
  96. SWAP(y1,y2,temp);
  97. SWAP(tu1,tu2,temp);
  98. SWAP(tv1,tv2,temp);
  99. SWAP(tz1,tz2,temp);
  100. // set interpolation restart
  101. irestart = INTERP_RHS;
  102. } // end if
  103. } // end else
  104.     // test for horizontal clipping
  105. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  106. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  107. (x2 < min_clip_x) || (x2 > max_clip_x))
  108. {
  109.     // clip version
  110. // x clipping
  111. // point screen ptr to starting line
  112. screen_ptr = dest_buffer + (ystart * mem_pitch);
  113.     // point zbuffer to starting line
  114.     z_ptr = zbuffer + (ystart * zpitch);
  115. for (yi = ystart; yi < yend; yi++)
  116. {
  117. // compute span endpoints
  118. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  119. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  120. // compute starting points for u,v interpolants
  121. zi = zl + 0; // ????
  122. ui = ul + 0;
  123. vi = vl + 0;
  124. // compute u,v interpolants
  125. if ((dx = (xend - xstart))>0)
  126. {
  127. du = (ur - ul) / dx;
  128. dv = (vr - vl) / dx;
  129. dz = (zr - zl) / dx;
  130. } // end if
  131. else
  132. {
  133. du = (ur - ul) ;
  134. dv = (vr - vl) ;
  135. dz = (zr - zl);
  136. } // end else
  137. ///////////////////////////////////////////////////////////////////////
  138. // test for x clipping, LHS
  139. if (xstart < min_clip_x)
  140. {
  141. // compute x overlap
  142. dx = min_clip_x - xstart;
  143. // slide interpolants over
  144. ui+=dx*du;
  145. vi+=dx*dv;
  146. zi+=dx*dz;
  147. // set x to left clip edge
  148. xstart = min_clip_x;
  149. } // end if
  150. // test for x clipping RHS
  151. if (xend > max_clip_x)
  152. xend = max_clip_x;
  153. ///////////////////////////////////////////////////////////////////////
  154. // draw span
  155. for (xi=xstart; xi < xend; xi++)
  156. {
  157.             // test if z of current pixel is nearer than current z buffer value
  158.             if (zi > z_ptr[xi])
  159.                {
  160.        // write textel
  161.                screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  162.                                 alpha_table_src2[textmap[ ((ui << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) + 
  163.                                                           (((vi << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) << texture_shift2)]];
  164.                // update z-buffer
  165.                z_ptr[xi] = zi;           
  166.                } // end if
  167. // interpolate u,v,z
  168. ui+=du;
  169. vi+=dv;
  170. zi+=dz;
  171. } // end for xi
  172. // interpolate u,v,x along right and left edge
  173. xl+=dxdyl;
  174. ul+=dudyl;
  175. vl+=dvdyl;
  176. zl+=dzdyl;
  177. xr+=dxdyr;
  178. ur+=dudyr;
  179. vr+=dvdyr;
  180. zr+=dzdyr;
  181. // advance screen ptr
  182. screen_ptr+=mem_pitch;
  183.         // advance zbuffer ptr
  184.         z_ptr+=zpitch;
  185. // test for yi hitting second region, if so change interpolant
  186. if (yi==yrestart)
  187. {
  188.     // test interpolation side change flag
  189. if (irestart == INTERP_LHS)
  190. {
  191. // LHS
  192. dyl = (y2 - y1);
  193. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  194. dudyl = ((tu2 - tu1) << 0)/dyl;  
  195. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  196. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  197. // set starting values
  198. xl = (x1  << FIXP16_SHIFT);
  199. ul = (tu1 << 0);
  200. vl = (tv1 << 0);
  201. zl = (tz1 << 0);
  202. // interpolate down on LHS to even up
  203. xl+=dxdyl;
  204. ul+=dudyl;
  205. vl+=dvdyl;
  206. zl+=dzdyl;
  207. } // end if
  208. else
  209. {
  210. // RHS
  211. dyr = (y1 - y2);
  212. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  213. dudyr = ((tu1 - tu2) << 0)/dyr;  
  214. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  215. dzdyr = ((tz1 - tz2) << 0)/dyr;  
  216. // set starting values
  217. xr = (x2  << FIXP16_SHIFT);
  218. ur = (tu2 << 0);
  219. vr = (tv2 << 0);
  220. zr = (tz2 << 0);
  221. // interpolate down on RHS to even up
  222. xr+=dxdyr;
  223. ur+=dudyr;
  224. vr+=dvdyr;
  225. zr+=dzdyr;
  226. } // end else
  227. } // end if
  228. } // end for y
  229. } // end if
  230. else
  231. {
  232. // no x clipping
  233. // point screen ptr to starting line
  234. screen_ptr = dest_buffer + (ystart * mem_pitch);
  235.     // point zbuffer to starting line
  236.     z_ptr = zbuffer + (ystart * zpitch);
  237. for (yi = ystart; yi < yend; yi++)
  238. {
  239. // compute span endpoints
  240. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  241. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  242. // compute starting points for u,v interpolants
  243. zi = zl + 0; // ????
  244. ui = ul + 0;
  245. vi = vl + 0;
  246. // compute u,v interpolants
  247. if ((dx = (xend - xstart))>0)
  248. {
  249. du = (ur - ul) / dx;
  250. dv = (vr - vl) / dx;
  251. dz = (zr - zl) / dx;
  252. } // end if
  253. else
  254. {
  255. du = (ur - ul) ;
  256. dv = (vr - vl) ;
  257. dz = (zr - zl);
  258. } // end else
  259. // draw span
  260. for (xi=xstart; xi < xend; xi++)
  261. {
  262.             // test if z of current pixel is nearer than current z buffer value
  263.             if (zi > z_ptr[xi]) 
  264.                {
  265.        // write textel
  266.                screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  267.                                 alpha_table_src2[textmap[ ((ui << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) + 
  268.                                                           (((vi << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) << texture_shift2)]];
  269.                // update z-buffer
  270.                z_ptr[xi] = zi;           
  271.                } // end if
  272. // interpolate u,v
  273. ui+=du;
  274. vi+=dv;
  275. zi+=dz;
  276. } // end for xi
  277. // interpolate u,v,x along right and left edge
  278. xl+=dxdyl;
  279. ul+=dudyl;
  280. vl+=dvdyl;
  281. zl+=dzdyl;
  282. xr+=dxdyr;
  283. ur+=dudyr;
  284. vr+=dvdyr;
  285. zr+=dzdyr;
  286. // advance screen ptr
  287. screen_ptr+=mem_pitch;
  288.         // advance zbuffer ptr
  289.         z_ptr+=zpitch;
  290. // test for yi hitting second region, if so change interpolant
  291. if (yi==yrestart)
  292. {
  293. // test interpolation side change flag
  294. if (irestart == INTERP_LHS)
  295. {
  296. // LHS
  297. dyl = (y2 - y1);
  298. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  299. dudyl = ((tu2 - tu1) << 0)/dyl;  
  300. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  301. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  302. // set starting values
  303. xl = (x1  << FIXP16_SHIFT);
  304. ul = (tu1 << 0);
  305. vl = (tv1 << 0);
  306. zl = (tz1 << 0);
  307. // interpolate down on LHS to even up
  308. xl+=dxdyl;
  309. ul+=dudyl;
  310. vl+=dvdyl;
  311. zl+=dzdyl;
  312. } // end if
  313. else
  314. {
  315. // RHS
  316. dyr = (y1 - y2);
  317. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  318. dudyr = ((tu1 - tu2) << 0)/dyr;  
  319. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  320. dzdyr = ((tz1 - tz2) << 0)/dyr; 
  321. // set starting values
  322. xr = (x2  << FIXP16_SHIFT);
  323. ur = (tu2 << 0);
  324. vr = (tv2 << 0);
  325. zr = (tz2 << 0);
  326. // interpolate down on RHS to even up
  327. xr+=dxdyr;
  328. ur+=dudyr;
  329. vr+=dvdyr;
  330. zr+=dzdyr;
  331. } // end else
  332. } // end if
  333. } // end for y
  334.    } // end else
  335. } // end if
  336. } // end Draw_Textured_Perspective_Triangle_INVZB_Alpha16
  337. //////////////////////////////////////////////////////////////////////////////////////////
  338. void Draw_Textured_PerspectiveLP_Triangle_INVZB_Alpha16(POLYF4DV2_PTR face,  // ptr to face
  339.                                                    UCHAR *_dest_buffer, // pointer to video buffer
  340.                                                    int mem_pitch,       // bytes per line, 320, 640 etc.
  341.                                                    UCHAR *_zbuffer,     // pointer to z-buffer
  342.                                                    int zpitch,          // bytes per line of zbuffer
  343.                                                    int alpha)
  344. {
  345. // this function draws a textured triangle in 16-bit mode using a 1/z buffer and piecewise linear
  346. // perspective correct texture mappping, 1/z, u/z, v/z are interpolated down each edge then to draw
  347. // each span U and V are computed for each end point and the space is broken up into 32 pixel
  348. // spans where the correct U,V is computed at each point along the span, but linearly interpolated
  349. // across the span
  350. int v0=0,
  351.     v1=1,
  352. v2=2,
  353. temp=0,
  354. tri_type = TRI_TYPE_NONE,
  355. irestart = INTERP_LHS;
  356. int dx,dy,dyl,dyr,      // general deltas
  357.     u,v,z,
  358.     du,dv,dz,
  359.     xi,yi,              // the current interpolated x,y
  360. ui,vi,zi,           // the current interpolated u,v,z
  361. index_x,index_y,    // looping vars
  362. x,y,                // hold general x,y
  363. xstart,
  364. xend,
  365. ystart,
  366. yrestart,
  367. yend,
  368. xl,                 
  369. dxdyl,              
  370. xr,
  371. dxdyr,             
  372. dudyl,    
  373. ul,
  374. dvdyl,   
  375. vl,
  376. dzdyl,   
  377. zl,
  378. dudyr,
  379. ur,
  380. dvdyr,
  381. vr,
  382. dzdyr,
  383. zr;
  384. int ur2, ul2, vr2, vl2;
  385. int x0,y0,tu0,tv0,tz0,    // cached vertices
  386. x1,y1,tu1,tv1,tz1,
  387. x2,y2,tu2,tv2,tz2;
  388. USHORT *screen_ptr  = NULL,
  389.    *screen_line = NULL,
  390.    *textmap     = NULL,
  391.        *dest_buffer = (USHORT *)_dest_buffer;
  392. UINT  *z_ptr = NULL,
  393.       *zbuffer = (UINT *)_zbuffer;
  394. #ifdef DEBUG_ON
  395. // track rendering stats
  396.     debug_polys_rendered_per_frame++;
  397. #endif
  398. // extract texture map
  399. textmap = (USHORT *)face->texture->buffer;
  400. // extract base 2 of texture width
  401. int texture_shift2 = logbase2ofx[face->texture->width];
  402. // adjust memory pitch to words, divide by 2
  403. mem_pitch >>=1;
  404. // adjust zbuffer pitch for 32 bit alignment
  405. zpitch >>= 2;
  406. // apply fill convention to coordinates
  407. face->tvlist[0].x = (int)(face->tvlist[0].x+0.5);
  408. face->tvlist[0].y = (int)(face->tvlist[0].y+0.5);
  409. face->tvlist[1].x = (int)(face->tvlist[1].x+0.5);
  410. face->tvlist[1].y = (int)(face->tvlist[1].y+0.5);
  411. face->tvlist[2].x = (int)(face->tvlist[2].x+0.5);
  412. face->tvlist[2].y = (int)(face->tvlist[2].y+0.5);
  413. // first trivial clipping rejection tests 
  414. if (((face->tvlist[0].y < min_clip_y)  && 
  415.  (face->tvlist[1].y < min_clip_y)  &&
  416.  (face->tvlist[2].y < min_clip_y)) ||
  417. ((face->tvlist[0].y > max_clip_y)  && 
  418.  (face->tvlist[1].y > max_clip_y)  &&
  419.  (face->tvlist[2].y > max_clip_y)) ||
  420. ((face->tvlist[0].x < min_clip_x)  && 
  421.  (face->tvlist[1].x < min_clip_x)  &&
  422.  (face->tvlist[2].x < min_clip_x)) ||
  423. ((face->tvlist[0].x > max_clip_x)  && 
  424.  (face->tvlist[1].x > max_clip_x)  &&
  425.  (face->tvlist[2].x > max_clip_x)))
  426.    return;
  427. // sort vertices
  428. if (face->tvlist[v1].y < face->tvlist[v0].y) 
  429. {SWAP(v0,v1,temp);} 
  430. if (face->tvlist[v2].y < face->tvlist[v0].y) 
  431. {SWAP(v0,v2,temp);}
  432. if (face->tvlist[v2].y < face->tvlist[v1].y) 
  433. {SWAP(v1,v2,temp);}
  434. // now test for trivial flat sided cases
  435. if (FCMP(face->tvlist[v0].y, face->tvlist[v1].y) )
  436. // set triangle type
  437. tri_type = TRI_TYPE_FLAT_TOP;
  438. // sort vertices left to right
  439. if (face->tvlist[v1].x < face->tvlist[v0].x) 
  440. {SWAP(v0,v1,temp);}
  441. } // end if
  442. else
  443. // now test for trivial flat sided cases
  444. if (FCMP(face->tvlist[v1].y ,face->tvlist[v2].y))
  445. // set triangle type
  446. tri_type = TRI_TYPE_FLAT_BOTTOM;
  447. // sort vertices left to right
  448. if (face->tvlist[v2].x < face->tvlist[v1].x) 
  449. {SWAP(v1,v2,temp);}
  450. } // end if
  451. else
  452. {
  453. // must be a general triangle
  454. tri_type = TRI_TYPE_GENERAL;
  455. } // end else
  456. // extract vertices for processing, now that we have order
  457. x0  = (int)(face->tvlist[v0].x+0.0);
  458. y0  = (int)(face->tvlist[v0].y+0.0);
  459. tu0 = ((int)(face->tvlist[v0].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  460. tv0 = ((int)(face->tvlist[v0].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  461. tz0 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  462. x1  = (int)(face->tvlist[v1].x+0.0);
  463. y1  = (int)(face->tvlist[v1].y+0.0);
  464. tu1 = ((int)(face->tvlist[v1].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  465. tv1 = ((int)(face->tvlist[v1].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  466. tz1 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  467. x2  = (int)(face->tvlist[v2].x+0.0);
  468. y2  = (int)(face->tvlist[v2].y+0.0);
  469. tu2 = ((int)(face->tvlist[v2].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  470. tv2 = ((int)(face->tvlist[v2].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  471. tz2 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  472. // degenerate triangle
  473. if ( ((x0 == x1) && (x1 == x2)) || ((y0 ==  y1) && (y1 == y2)))
  474.    return;
  475. // assign both source1 and source2 alpha tables based on polygon alpha level
  476. USHORT *alpha_table_src1 = (USHORT *)&rgb_alpha_table[(NUM_ALPHA_LEVELS-1) - alpha][0];
  477. USHORT *alpha_table_src2 = (USHORT *)&rgb_alpha_table[alpha][0];
  478. // set interpolation restart value
  479. yrestart = y1;
  480. // what kind of triangle
  481. if (tri_type & TRI_TYPE_FLAT_MASK)
  482. {
  483. if (tri_type == TRI_TYPE_FLAT_TOP)
  484. {
  485. // compute all deltas
  486. dy = (y2 - y0);
  487. dxdyl = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  488. dudyl = ((tu2 - tu0) << 0)/dy;  
  489. dvdyl = ((tv2 - tv0) << 0)/dy;    
  490. dzdyl = ((tz2 - tz0) << 0)/dy;    
  491. dxdyr = ((x2 - x1)   << FIXP16_SHIFT)/dy;
  492. dudyr = ((tu2 - tu1) << 0)/dy;  
  493. dvdyr = ((tv2 - tv1) << 0)/dy;   
  494. dzdyr = ((tz2 - tz1) << 0)/dy;  
  495. // test for y clipping
  496. if (y0 < min_clip_y)
  497. {
  498. // compute overclip
  499. dy = (min_clip_y - y0);
  500. // computer new LHS starting values
  501. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  502. ul = dudyl*dy + (tu0 << 0);
  503. vl = dvdyl*dy + (tv0 << 0);
  504. zl = dzdyl*dy + (tz0 << 0);
  505. // compute new RHS starting values
  506. xr = dxdyr*dy + (x1  << FIXP16_SHIFT);
  507. ur = dudyr*dy + (tu1 << 0);
  508. vr = dvdyr*dy + (tv1 << 0);
  509. zr = dzdyr*dy + (tz1 << 0);
  510. // compute new starting y
  511. ystart = min_clip_y;
  512. } // end if
  513. else
  514. {
  515. // no clipping
  516. // set starting values
  517. xl = (x0 << FIXP16_SHIFT);
  518. xr = (x1 << FIXP16_SHIFT);
  519. ul = (tu0 << 0);
  520. vl = (tv0 << 0);
  521. zl = (tz0 << 0);
  522. ur = (tu1 << 0);
  523. vr = (tv1 << 0);
  524. zr = (tz1 << 0);
  525. // set starting y
  526. ystart = y0;
  527. } // end else
  528. } // end if flat top
  529. else
  530. {
  531. // must be flat bottom
  532. // compute all deltas
  533. dy = (y1 - y0);
  534. dxdyl = ((x1 - x0)   << FIXP16_SHIFT)/dy;
  535. dudyl = ((tu1 - tu0) << 0)/dy;  
  536. dvdyl = ((tv1 - tv0) << 0)/dy;    
  537. dzdyl = ((tz1 - tz0) << 0)/dy;   
  538. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  539. dudyr = ((tu2 - tu0) << 0)/dy;  
  540. dvdyr = ((tv2 - tv0) << 0)/dy;   
  541. dzdyr = ((tz2 - tz0) << 0)/dy;   
  542. // test for y clipping
  543. if (y0 < min_clip_y)
  544. {
  545. // compute overclip
  546. dy = (min_clip_y - y0);
  547. // computer new LHS starting values
  548. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  549. ul = dudyl*dy + (tu0 << 0);
  550. vl = dvdyl*dy + (tv0 << 0);
  551. zl = dzdyl*dy + (tz0 << 0);
  552. // compute new RHS starting values
  553. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  554. ur = dudyr*dy + (tu0 << 0);
  555. vr = dvdyr*dy + (tv0 << 0);
  556. zr = dzdyr*dy + (tz0 << 0);
  557. // compute new starting y
  558. ystart = min_clip_y;
  559. } // end if
  560. else
  561. {
  562. // no clipping
  563. // set starting values
  564. xl = (x0 << FIXP16_SHIFT);
  565. xr = (x0 << FIXP16_SHIFT);
  566. ul = (tu0 << 0);
  567. vl = (tv0 << 0);
  568. zl = (tz0 << 0);
  569. ur = (tu0 << 0);
  570. vr = (tv0 << 0);
  571. zr = (tz0 << 0);
  572. // set starting y
  573. ystart = y0;
  574. } // end else
  575. } // end else flat bottom
  576. // test for bottom clip, always
  577. if ((yend = y2) > max_clip_y)
  578. yend = max_clip_y;
  579.     // test for horizontal clipping
  580. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  581. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  582. (x2 < min_clip_x) || (x2 > max_clip_x))
  583. {
  584.     // clip version
  585. // point screen ptr to starting line
  586. screen_ptr = dest_buffer + (ystart * mem_pitch);
  587.     // point zbuffer to starting line
  588.     z_ptr = zbuffer + (ystart * zpitch);
  589. for (yi = ystart; yi < yend; yi++)
  590. {
  591. // compute span endpoints
  592. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  593. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  594.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  595.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  596.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  597.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  598. // compute starting points for u,v interpolants
  599. zi = zl + 0; // ????
  600. ui = ul2 + 0;
  601. vi = vl2 + 0;
  602. // compute u,v interpolants
  603. if ((dx = (xend - xstart))>0)
  604. {
  605. du = (ur2 - ul2) / dx;
  606. dv = (vr2 - vl2) / dx;
  607. dz = (zr - zl) / dx;
  608. } // end if
  609. else
  610. {
  611. du = (ur2 - ul2) ;
  612. dv = (vr2 - vl2) ;
  613. dz = (zr - zl);
  614. } // end else
  615. ///////////////////////////////////////////////////////////////////////
  616. // test for x clipping, LHS
  617. if (xstart < min_clip_x)
  618. {
  619. // compute x overlap
  620. dx = min_clip_x - xstart;
  621. // slide interpolants over
  622. ui+=dx*du;
  623. vi+=dx*dv;
  624. zi+=dx*dz;
  625. // reset vars
  626. xstart = min_clip_x;
  627. } // end if
  628. // test for x clipping RHS
  629. if (xend > max_clip_x)
  630. xend = max_clip_x;
  631. ///////////////////////////////////////////////////////////////////////
  632. // draw span
  633. for (xi=xstart; xi < xend; xi++)
  634. {
  635.             // test if z of current pixel is nearer than current z buffer value
  636.             if (zi > z_ptr[xi])
  637.                {
  638.        // write textel
  639.                screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  640.                                 alpha_table_src2[textmap[ (ui >> FIXP22_SHIFT) + 
  641.                                                           ((vi >> FIXP22_SHIFT) << texture_shift2)]];
  642.                // update z-buffer
  643.                z_ptr[xi] = zi;           
  644.                } // end if
  645. // interpolate u,v,z
  646. ui+=du;
  647. vi+=dv;
  648. zi+=dz;
  649. } // end for xi
  650. // interpolate u,v,x along right and left edge
  651. xl+=dxdyl;
  652. ul+=dudyl;
  653. vl+=dvdyl;
  654. zl+=dzdyl;
  655. xr+=dxdyr;
  656. ur+=dudyr;
  657. vr+=dvdyr;
  658. zr+=dzdyr;
  659.  
  660. // advance screen ptr
  661. screen_ptr+=mem_pitch;
  662.         // advance zbuffer ptr
  663.         z_ptr+=zpitch;
  664. } // end for y
  665. } // end if clip
  666. else
  667. {
  668. // non-clip version
  669. // point screen ptr to starting line
  670. screen_ptr = dest_buffer + (ystart * mem_pitch);
  671.     // point zbuffer to starting line
  672.     z_ptr = zbuffer + (ystart * zpitch);
  673. for (yi = ystart; yi < yend; yi++)
  674. {
  675. // compute span endpoints
  676. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  677. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  678.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  679.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  680.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  681.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  682. // compute starting points for u,v interpolants
  683. zi = zl + 0; // ????
  684. ui = ul2 + 0;
  685. vi = vl2 + 0;
  686. // compute u,v interpolants
  687. if ((dx = (xend - xstart))>0)
  688. {
  689. du = (ur2 - ul2) / dx;
  690. dv = (vr2 - vl2) / dx;
  691. dz = (zr - zl) / dx;
  692. } // end if
  693. else
  694. {
  695. du = (ur2 - ul2) ;
  696. dv = (vr2 - vl2) ;
  697. dz = (zr - zl);
  698. } // end else
  699. // draw span
  700. for (xi=xstart; xi < xend; xi++)
  701. {
  702.             // test if z of current pixel is nearer than current z buffer value
  703.             if (zi > z_ptr[xi])
  704.                {
  705.        // write textel
  706.                screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  707.                                 alpha_table_src2[textmap[ (ui >> FIXP22_SHIFT) + 
  708.                                                           ((vi >> FIXP22_SHIFT) << texture_shift2)]];
  709.                // update z-buffer
  710.                z_ptr[xi] = zi;           
  711.                } // end if
  712. // interpolate u,v,z
  713. ui+=du;
  714. vi+=dv;
  715. zi+=dz;
  716. } // end for xi
  717. // interpolate u,v,x along right and left edge
  718. xl+=dxdyl;
  719. ul+=dudyl;
  720. vl+=dvdyl;
  721. zl+=dzdyl;
  722. xr+=dxdyr;
  723. ur+=dudyr;
  724. vr+=dvdyr;
  725. zr+=dzdyr;
  726. // advance screen ptr
  727. screen_ptr+=mem_pitch;
  728.         // advance zbuffer ptr
  729.         z_ptr+=zpitch;
  730. } // end for y
  731. } // end if non-clipped
  732. } // end if
  733. else
  734. if (tri_type==TRI_TYPE_GENERAL)
  735. {
  736. // first test for bottom clip, always
  737. if ((yend = y2) > max_clip_y)
  738. yend = max_clip_y;
  739. // pre-test y clipping status
  740. if (y1 < min_clip_y)
  741. {
  742. // compute all deltas
  743. // LHS
  744. dyl = (y2 - y1);
  745. dxdyl = ((x2  - x1)  << FIXP16_SHIFT)/dyl;
  746. dudyl = ((tu2 - tu1) << 0)/dyl;  
  747. dvdyl = ((tv2 - tv1) << 0)/dyl;    
  748. dzdyl = ((tz2 - tz1) << 0)/dyl;  
  749. // RHS
  750. dyr = (y2 - y0);
  751. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  752. dudyr = ((tu2 - tu0) << 0)/dyr;  
  753. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  754. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  755. // compute overclip
  756. dyr = (min_clip_y - y0);
  757. dyl = (min_clip_y - y1);
  758. // computer new LHS starting values
  759. xl = dxdyl*dyl + (x1  << FIXP16_SHIFT);
  760. ul = dudyl*dyl + (tu1 << 0);
  761. vl = dvdyl*dyl + (tv1 << 0);
  762. zl = dzdyl*dyl + (tz1 << 0);
  763. // compute new RHS starting values
  764. xr = dxdyr*dyr + (x0  << FIXP16_SHIFT);
  765. ur = dudyr*dyr + (tu0 << 0);
  766. vr = dvdyr*dyr + (tv0 << 0);
  767. zr = dzdyr*dyr + (tz0 << 0);
  768. // compute new starting y
  769. ystart = min_clip_y;
  770. // test if we need swap to keep rendering left to right
  771. if (dxdyr > dxdyl)
  772. {
  773. SWAP(dxdyl,dxdyr,temp);
  774. SWAP(dudyl,dudyr,temp);
  775. SWAP(dvdyl,dvdyr,temp);
  776. SWAP(dzdyl,dzdyr,temp);
  777. SWAP(xl,xr,temp);
  778. SWAP(ul,ur,temp);
  779. SWAP(vl,vr,temp);
  780. SWAP(zl,zr,temp);
  781. SWAP(x1,x2,temp);
  782. SWAP(y1,y2,temp);
  783. SWAP(tu1,tu2,temp);
  784. SWAP(tv1,tv2,temp);
  785. SWAP(tz1,tz2,temp);
  786. // set interpolation restart
  787. irestart = INTERP_RHS;
  788. } // end if
  789. } // end if
  790. else
  791. if (y0 < min_clip_y)
  792. {
  793. // compute all deltas
  794. // LHS
  795. dyl = (y1 - y0);
  796. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  797. dudyl = ((tu1 - tu0) << 0)/dyl;  
  798. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  799. dzdyl = ((tz1 - tz0) << 0)/dyl;  
  800. // RHS
  801. dyr = (y2 - y0);
  802. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  803. dudyr = ((tu2 - tu0) << 0)/dyr;  
  804. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  805. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  806. // compute overclip
  807. dy = (min_clip_y - y0);
  808. // computer new LHS starting values
  809. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  810. ul = dudyl*dy + (tu0 << 0);
  811. vl = dvdyl*dy + (tv0 << 0);
  812. zl = dzdyl*dy + (tz0 << 0);
  813. // compute new RHS starting values
  814. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  815. ur = dudyr*dy + (tu0 << 0);
  816. vr = dvdyr*dy + (tv0 << 0);
  817. zr = dzdyr*dy + (tz0 << 0);
  818. // compute new starting y
  819. ystart = min_clip_y;
  820. // test if we need swap to keep rendering left to right
  821. if (dxdyr < dxdyl)
  822. {
  823. SWAP(dxdyl,dxdyr,temp);
  824. SWAP(dudyl,dudyr,temp);
  825. SWAP(dvdyl,dvdyr,temp);
  826. SWAP(dzdyl,dzdyr,temp);
  827. SWAP(xl,xr,temp);
  828. SWAP(ul,ur,temp);
  829. SWAP(vl,vr,temp);
  830. SWAP(zl,zr,temp);
  831. SWAP(x1,x2,temp);
  832. SWAP(y1,y2,temp);
  833. SWAP(tu1,tu2,temp);
  834. SWAP(tv1,tv2,temp);
  835. SWAP(tz1,tz2,temp);
  836. // set interpolation restart
  837. irestart = INTERP_RHS;
  838. } // end if
  839. } // end if
  840. else
  841. {
  842. // no initial y clipping
  843. // compute all deltas
  844. // LHS
  845. dyl = (y1 - y0);
  846. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  847. dudyl = ((tu1 - tu0) << 0)/dyl;  
  848. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  849. dzdyl = ((tz1 - tz0) << 0)/dyl;   
  850. // RHS
  851. dyr = (y2 - y0);
  852. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dyr;
  853. dudyr = ((tu2 - tu0) << 0)/dyr;  
  854. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  855. dzdyr = ((tz2 - tz0) << 0)/dyr;  
  856. // no clipping y
  857. // set starting values
  858. xl = (x0 << FIXP16_SHIFT);
  859. xr = (x0 << FIXP16_SHIFT);
  860. ul = (tu0 << 0);
  861. vl = (tv0 << 0);
  862. zl = (tz0 << 0);
  863. ur = (tu0 << 0);
  864. vr = (tv0 << 0);
  865. zr = (tz0 << 0);
  866. // set starting y
  867. ystart = y0;
  868. // test if we need swap to keep rendering left to right
  869. if (dxdyr < dxdyl)
  870. {
  871. SWAP(dxdyl,dxdyr,temp);
  872. SWAP(dudyl,dudyr,temp);
  873. SWAP(dvdyl,dvdyr,temp);
  874. SWAP(dzdyl,dzdyr,temp);
  875. SWAP(xl,xr,temp);
  876. SWAP(ul,ur,temp);
  877. SWAP(vl,vr,temp);
  878. SWAP(zl,zr,temp);
  879. SWAP(x1,x2,temp);
  880. SWAP(y1,y2,temp);
  881. SWAP(tu1,tu2,temp);
  882. SWAP(tv1,tv2,temp);
  883. SWAP(tz1,tz2,temp);
  884. // set interpolation restart
  885. irestart = INTERP_RHS;
  886. } // end if
  887. } // end else
  888.     // test for horizontal clipping
  889. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  890. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  891. (x2 < min_clip_x) || (x2 > max_clip_x))
  892. {
  893.     // clip version
  894. // x clipping
  895. // point screen ptr to starting line
  896. screen_ptr = dest_buffer + (ystart * mem_pitch);
  897.     // point zbuffer to starting line
  898.     z_ptr = zbuffer + (ystart * zpitch);
  899. for (yi = ystart; yi < yend; yi++)
  900. {
  901. // compute span endpoints
  902. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  903. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  904.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  905.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  906.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  907.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  908. // compute starting points for u,v interpolants
  909. zi = zl + 0; // ????
  910. ui = ul2 + 0;
  911. vi = vl2 + 0;
  912. // compute u,v interpolants
  913. if ((dx = (xend - xstart))>0)
  914. {
  915. du = (ur2 - ul2) / dx;
  916. dv = (vr2 - vl2) / dx;
  917. dz = (zr - zl) / dx;
  918. } // end if
  919. else
  920. {
  921. du = (ur2 - ul2) ;
  922. dv = (vr2 - vl2) ;
  923. dz = (zr - zl);
  924. } // end else
  925. ///////////////////////////////////////////////////////////////////////
  926. // test for x clipping, LHS
  927. if (xstart < min_clip_x)
  928. {
  929. // compute x overlap
  930. dx = min_clip_x - xstart;
  931. // slide interpolants over
  932. ui+=dx*du;
  933. vi+=dx*dv;
  934. zi+=dx*dz;
  935. // set x to left clip edge
  936. xstart = min_clip_x;
  937. } // end if
  938. // test for x clipping RHS
  939. if (xend > max_clip_x)
  940. xend = max_clip_x;
  941. ///////////////////////////////////////////////////////////////////////
  942. // draw span
  943. for (xi=xstart; xi < xend; xi++)
  944. {
  945.             // test if z of current pixel is nearer than current z buffer value
  946.             if (zi > z_ptr[xi])
  947.                {
  948.        // write textel
  949.                screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  950.                                 alpha_table_src2[textmap[ (ui >> FIXP22_SHIFT) + 
  951.                                                           ((vi >> FIXP22_SHIFT) << texture_shift2)]];
  952.                // update z-buffer
  953.                z_ptr[xi] = zi;           
  954.                } // end if
  955. // interpolate u,v,z
  956. ui+=du;
  957. vi+=dv;
  958. zi+=dz;
  959. } // end for xi
  960. // interpolate u,v,x along right and left edge
  961. xl+=dxdyl;
  962. ul+=dudyl;
  963. vl+=dvdyl;
  964. zl+=dzdyl;
  965. xr+=dxdyr;
  966. ur+=dudyr;
  967. vr+=dvdyr;
  968. zr+=dzdyr;
  969. // advance screen ptr
  970. screen_ptr+=mem_pitch;
  971.         // advance zbuffer ptr
  972.         z_ptr+=zpitch;
  973. // test for yi hitting second region, if so change interpolant
  974. if (yi==yrestart)
  975. {
  976.     // test interpolation side change flag
  977. if (irestart == INTERP_LHS)
  978. {
  979. // LHS
  980. dyl = (y2 - y1);
  981. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  982. dudyl = ((tu2 - tu1) << 0)/dyl;  
  983. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  984. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  985. // set starting values
  986. xl = (x1  << FIXP16_SHIFT);
  987. ul = (tu1 << 0);
  988. vl = (tv1 << 0);
  989. zl = (tz1 << 0);
  990. // interpolate down on LHS to even up
  991. xl+=dxdyl;
  992. ul+=dudyl;
  993. vl+=dvdyl;
  994. zl+=dzdyl;
  995. } // end if
  996. else
  997. {
  998. // RHS
  999. dyr = (y1 - y2);
  1000. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  1001. dudyr = ((tu1 - tu2) << 0)/dyr;  
  1002. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  1003. dzdyr = ((tz1 - tz2) << 0)/dyr;  
  1004. // set starting values
  1005. xr = (x2  << FIXP16_SHIFT);
  1006. ur = (tu2 << 0);
  1007. vr = (tv2 << 0);
  1008. zr = (tz2 << 0);
  1009. // interpolate down on RHS to even up
  1010. xr+=dxdyr;
  1011. ur+=dudyr;
  1012. vr+=dvdyr;
  1013. zr+=dzdyr;
  1014. } // end else
  1015. } // end if
  1016. } // end for y
  1017. } // end if
  1018. else
  1019. {
  1020. // no x clipping
  1021. // point screen ptr to starting line
  1022. screen_ptr = dest_buffer + (ystart * mem_pitch);
  1023.     // point zbuffer to starting line
  1024.     z_ptr = zbuffer + (ystart * zpitch);
  1025. for (yi = ystart; yi < yend; yi++)
  1026. {
  1027. // compute span endpoints
  1028. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1029. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1030.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  1031.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  1032.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  1033.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  1034. // compute starting points for u,v interpolants
  1035. zi = zl + 0; // ????
  1036. ui = ul2 + 0;
  1037. vi = vl2 + 0;
  1038. // compute u,v interpolants
  1039. if ((dx = (xend - xstart))>0)
  1040. {
  1041. du = (ur2 - ul2) / dx;
  1042. dv = (vr2 - vl2) / dx;
  1043. dz = (zr - zl) / dx;
  1044. } // end if
  1045. else
  1046. {
  1047. du = (ur2 - ul2) ;
  1048. dv = (vr2 - vl2) ;
  1049. dz = (zr - zl);
  1050. } // end else
  1051. // draw span
  1052. for (xi=xstart; xi < xend; xi++)
  1053. {
  1054.             // test if z of current pixel is nearer than current z buffer value
  1055.             if (zi > z_ptr[xi]) 
  1056.                {
  1057.        // write textel
  1058.                screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  1059.                                 alpha_table_src2[textmap[ (ui >> FIXP22_SHIFT) + 
  1060.                                                           ((vi >> FIXP22_SHIFT) << texture_shift2)]];
  1061.                // update z-buffer
  1062.                z_ptr[xi] = zi;           
  1063.                } // end if
  1064. // interpolate u,v
  1065. ui+=du;
  1066. vi+=dv;
  1067. zi+=dz;
  1068. } // end for xi
  1069. // interpolate u,v,x along right and left edge
  1070. xl+=dxdyl;
  1071. ul+=dudyl;
  1072. vl+=dvdyl;
  1073. zl+=dzdyl;
  1074. xr+=dxdyr;
  1075. ur+=dudyr;
  1076. vr+=dvdyr;
  1077. zr+=dzdyr;
  1078. // advance screen ptr
  1079. screen_ptr+=mem_pitch;
  1080.         // advance zbuffer ptr
  1081.         z_ptr+=zpitch;
  1082. // test for yi hitting second region, if so change interpolant
  1083. if (yi==yrestart)
  1084. {
  1085. // test interpolation side change flag
  1086. if (irestart == INTERP_LHS)
  1087. {
  1088. // LHS
  1089. dyl = (y2 - y1);
  1090. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  1091. dudyl = ((tu2 - tu1) << 0)/dyl;  
  1092. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  1093. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  1094. // set starting values
  1095. xl = (x1  << FIXP16_SHIFT);
  1096. ul = (tu1 << 0);
  1097. vl = (tv1 << 0);
  1098. zl = (tz1 << 0);
  1099. // interpolate down on LHS to even up
  1100. xl+=dxdyl;
  1101. ul+=dudyl;
  1102. vl+=dvdyl;
  1103. zl+=dzdyl;
  1104. } // end if
  1105. else
  1106. {
  1107. // RHS
  1108. dyr = (y1 - y2);
  1109. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  1110. dudyr = ((tu1 - tu2) << 0)/dyr;  
  1111. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  1112. dzdyr = ((tz1 - tz2) << 0)/dyr; 
  1113. // set starting values
  1114. xr = (x2  << FIXP16_SHIFT);
  1115. ur = (tu2 << 0);
  1116. vr = (tv2 << 0);
  1117. zr = (tz2 << 0);
  1118. // interpolate down on RHS to even up
  1119. xr+=dxdyr;
  1120. ur+=dudyr;
  1121. vr+=dvdyr;
  1122. zr+=dzdyr;
  1123. } // end else
  1124. } // end if
  1125. } // end for y
  1126.    } // end else
  1127. } // end if
  1128. } // end Draw_Textured_PerspectiveLP_Triangle_INVZB_Alpha16
  1129. //////////////////////////////////////////////////////////////////////////////////////////
  1130. void Draw_Textured_Perspective_Triangle_FSINVZB_Alpha16(POLYF4DV2_PTR face,  // ptr to face
  1131.                                                    UCHAR *_dest_buffer, // pointer to video buffer
  1132.                                                    int mem_pitch,       // bytes per line, 320, 640 etc.
  1133.                                                    UCHAR *_zbuffer,     // pointer to z-buffer
  1134.                                                    int zpitch,          // bytes per line of zbuffer
  1135.                                                    int alpha)
  1136. {
  1137. // this function draws a textured triangle in 16-bit mode using a 1/z buffer and piecewise linear
  1138. // perspective correct texture mappping, 1/z, u/z, v/z are interpolated down each edge then to draw
  1139. // each span U and V are computed for each end point and the space is broken up into 32 pixel
  1140. // spans where the correct U,V is computed at each point along the span, but linearly interpolated
  1141. // across the span
  1142. int v0=0,
  1143.     v1=1,
  1144. v2=2,
  1145. temp=0,
  1146. tri_type = TRI_TYPE_NONE,
  1147. irestart = INTERP_LHS;
  1148. int dx,dy,dyl,dyr,      // general deltas
  1149.     u,v,z,
  1150.     du,dv,dz,
  1151.     xi,yi,              // the current interpolated x,y
  1152. ui,vi,zi,           // the current interpolated u,v,z
  1153. index_x,index_y,    // looping vars
  1154. x,y,                // hold general x,y
  1155. xstart,
  1156. xend,
  1157. ystart,
  1158. yrestart,
  1159. yend,
  1160. xl,                 
  1161. dxdyl,              
  1162. xr,
  1163. dxdyr,             
  1164. dudyl,    
  1165. ul,
  1166. dvdyl,   
  1167. vl,
  1168. dzdyl,   
  1169. zl,
  1170. dudyr,
  1171. ur,
  1172. dvdyr,
  1173. vr,
  1174. dzdyr,
  1175. zr;
  1176. int x0,y0,tu0,tv0,tz0,    // cached vertices
  1177. x1,y1,tu1,tv1,tz1,
  1178. x2,y2,tu2,tv2,tz2;
  1179. USHORT *screen_ptr  = NULL,
  1180.    *screen_line = NULL,
  1181.    *textmap     = NULL,
  1182.        *dest_buffer = (USHORT *)_dest_buffer;
  1183. USHORT r_base, g_base, b_base,
  1184.        r_textel, g_textel, b_textel, textel;
  1185. UINT  *z_ptr = NULL,
  1186.       *zbuffer = (UINT *)_zbuffer;
  1187. #ifdef DEBUG_ON
  1188. // track rendering stats
  1189.     debug_polys_rendered_per_frame++;
  1190. #endif
  1191. // extract texture map
  1192. textmap = (USHORT *)face->texture->buffer;
  1193. // extract base 2 of texture width
  1194. int texture_shift2 = logbase2ofx[face->texture->width];
  1195. // adjust memory pitch to words, divide by 2
  1196. mem_pitch >>=1;
  1197. // adjust zbuffer pitch for 32 bit alignment
  1198. zpitch >>= 2;
  1199. // apply fill convention to coordinates
  1200. face->tvlist[0].x = (int)(face->tvlist[0].x+0.5);
  1201. face->tvlist[0].y = (int)(face->tvlist[0].y+0.5);
  1202. face->tvlist[1].x = (int)(face->tvlist[1].x+0.5);
  1203. face->tvlist[1].y = (int)(face->tvlist[1].y+0.5);
  1204. face->tvlist[2].x = (int)(face->tvlist[2].x+0.5);
  1205. face->tvlist[2].y = (int)(face->tvlist[2].y+0.5);
  1206. // first trivial clipping rejection tests 
  1207. if (((face->tvlist[0].y < min_clip_y)  && 
  1208.  (face->tvlist[1].y < min_clip_y)  &&
  1209.  (face->tvlist[2].y < min_clip_y)) ||
  1210. ((face->tvlist[0].y > max_clip_y)  && 
  1211.  (face->tvlist[1].y > max_clip_y)  &&
  1212.  (face->tvlist[2].y > max_clip_y)) ||
  1213. ((face->tvlist[0].x < min_clip_x)  && 
  1214.  (face->tvlist[1].x < min_clip_x)  &&
  1215.  (face->tvlist[2].x < min_clip_x)) ||
  1216. ((face->tvlist[0].x > max_clip_x)  && 
  1217.  (face->tvlist[1].x > max_clip_x)  &&
  1218.  (face->tvlist[2].x > max_clip_x)))
  1219.    return;
  1220. // sort vertices
  1221. if (face->tvlist[v1].y < face->tvlist[v0].y) 
  1222. {SWAP(v0,v1,temp);} 
  1223. if (face->tvlist[v2].y < face->tvlist[v0].y) 
  1224. {SWAP(v0,v2,temp);}
  1225. if (face->tvlist[v2].y < face->tvlist[v1].y) 
  1226. {SWAP(v1,v2,temp);}
  1227. // now test for trivial flat sided cases
  1228. if (FCMP(face->tvlist[v0].y, face->tvlist[v1].y) )
  1229. // set triangle type
  1230. tri_type = TRI_TYPE_FLAT_TOP;
  1231. // sort vertices left to right
  1232. if (face->tvlist[v1].x < face->tvlist[v0].x) 
  1233. {SWAP(v0,v1,temp);}
  1234. } // end if
  1235. else
  1236. // now test for trivial flat sided cases
  1237. if (FCMP(face->tvlist[v1].y ,face->tvlist[v2].y))
  1238. // set triangle type
  1239. tri_type = TRI_TYPE_FLAT_BOTTOM;
  1240. // sort vertices left to right
  1241. if (face->tvlist[v2].x < face->tvlist[v1].x) 
  1242. {SWAP(v1,v2,temp);}
  1243. } // end if
  1244. else
  1245. {
  1246. // must be a general triangle
  1247. tri_type = TRI_TYPE_GENERAL;
  1248. } // end else
  1249. // extract base color of lit poly, so we can modulate texture a bit
  1250. // for lighting
  1251. _RGB565FROM16BIT(face->lit_color[0], &r_base, &g_base, &b_base);
  1252. // extract vertices for processing, now that we have order
  1253. x0  = (int)(face->tvlist[v0].x+0.0);
  1254. y0  = (int)(face->tvlist[v0].y+0.0);
  1255. tu0 = ((int)(face->tvlist[v0].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  1256. tv0 = ((int)(face->tvlist[v0].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  1257. tz0 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  1258. x1  = (int)(face->tvlist[v1].x+0.0);
  1259. y1  = (int)(face->tvlist[v1].y+0.0);
  1260. tu1 = ((int)(face->tvlist[v1].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  1261. tv1 = ((int)(face->tvlist[v1].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  1262. tz1 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  1263. x2  = (int)(face->tvlist[v2].x+0.0);
  1264. y2  = (int)(face->tvlist[v2].y+0.0);
  1265. tu2 = ((int)(face->tvlist[v2].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  1266. tv2 = ((int)(face->tvlist[v2].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  1267. tz2 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  1268. // degenerate triangle
  1269. if ( ((x0 == x1) && (x1 == x2)) || ((y0 ==  y1) && (y1 == y2)))
  1270.    return;
  1271. // assign both source1 and source2 alpha tables based on polygon alpha level
  1272. USHORT *alpha_table_src1 = (USHORT *)&rgb_alpha_table[(NUM_ALPHA_LEVELS-1) - alpha][0];
  1273. USHORT *alpha_table_src2 = (USHORT *)&rgb_alpha_table[alpha][0];
  1274. // set interpolation restart value
  1275. yrestart = y1;
  1276. // what kind of triangle
  1277. if (tri_type & TRI_TYPE_FLAT_MASK)
  1278. {
  1279. if (tri_type == TRI_TYPE_FLAT_TOP)
  1280. {
  1281. // compute all deltas
  1282. dy = (y2 - y0);
  1283. dxdyl = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  1284. dudyl = ((tu2 - tu0) << 0)/dy;  
  1285. dvdyl = ((tv2 - tv0) << 0)/dy;    
  1286. dzdyl = ((tz2 - tz0) << 0)/dy;    
  1287. dxdyr = ((x2 - x1)   << FIXP16_SHIFT)/dy;
  1288. dudyr = ((tu2 - tu1) << 0)/dy;  
  1289. dvdyr = ((tv2 - tv1) << 0)/dy;   
  1290. dzdyr = ((tz2 - tz1) << 0)/dy;  
  1291. // test for y clipping
  1292. if (y0 < min_clip_y)
  1293. {
  1294. // compute overclip
  1295. dy = (min_clip_y - y0);
  1296. // computer new LHS starting values
  1297. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  1298. ul = dudyl*dy + (tu0 << 0);
  1299. vl = dvdyl*dy + (tv0 << 0);
  1300. zl = dzdyl*dy + (tz0 << 0);
  1301. // compute new RHS starting values
  1302. xr = dxdyr*dy + (x1  << FIXP16_SHIFT);
  1303. ur = dudyr*dy + (tu1 << 0);
  1304. vr = dvdyr*dy + (tv1 << 0);
  1305. zr = dzdyr*dy + (tz1 << 0);
  1306. // compute new starting y
  1307. ystart = min_clip_y;
  1308. } // end if
  1309. else
  1310. {
  1311. // no clipping
  1312. // set starting values
  1313. xl = (x0 << FIXP16_SHIFT);
  1314. xr = (x1 << FIXP16_SHIFT);
  1315. ul = (tu0 << 0);
  1316. vl = (tv0 << 0);
  1317. zl = (tz0 << 0);
  1318. ur = (tu1 << 0);
  1319. vr = (tv1 << 0);
  1320. zr = (tz1 << 0);
  1321. // set starting y
  1322. ystart = y0;
  1323. } // end else
  1324. } // end if flat top
  1325. else
  1326. {
  1327. // must be flat bottom
  1328. // compute all deltas
  1329. dy = (y1 - y0);
  1330. dxdyl = ((x1 - x0)   << FIXP16_SHIFT)/dy;
  1331. dudyl = ((tu1 - tu0) << 0)/dy;  
  1332. dvdyl = ((tv1 - tv0) << 0)/dy;    
  1333. dzdyl = ((tz1 - tz0) << 0)/dy;   
  1334. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  1335. dudyr = ((tu2 - tu0) << 0)/dy;  
  1336. dvdyr = ((tv2 - tv0) << 0)/dy;   
  1337. dzdyr = ((tz2 - tz0) << 0)/dy;   
  1338. // test for y clipping
  1339. if (y0 < min_clip_y)
  1340. {
  1341. // compute overclip
  1342. dy = (min_clip_y - y0);
  1343. // computer new LHS starting values
  1344. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  1345. ul = dudyl*dy + (tu0 << 0);
  1346. vl = dvdyl*dy + (tv0 << 0);
  1347. zl = dzdyl*dy + (tz0 << 0);
  1348. // compute new RHS starting values
  1349. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  1350. ur = dudyr*dy + (tu0 << 0);
  1351. vr = dvdyr*dy + (tv0 << 0);
  1352. zr = dzdyr*dy + (tz0 << 0);
  1353. // compute new starting y
  1354. ystart = min_clip_y;
  1355. } // end if
  1356. else
  1357. {
  1358. // no clipping
  1359. // set starting values
  1360. xl = (x0 << FIXP16_SHIFT);
  1361. xr = (x0 << FIXP16_SHIFT);
  1362. ul = (tu0 << 0);
  1363. vl = (tv0 << 0);
  1364. zl = (tz0 << 0);
  1365. ur = (tu0 << 0);
  1366. vr = (tv0 << 0);
  1367. zr = (tz0 << 0);
  1368. // set starting y
  1369. ystart = y0;
  1370. } // end else
  1371. } // end else flat bottom
  1372. // test for bottom clip, always
  1373. if ((yend = y2) > max_clip_y)
  1374. yend = max_clip_y;
  1375.     // test for horizontal clipping
  1376. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  1377. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  1378. (x2 < min_clip_x) || (x2 > max_clip_x))
  1379. {
  1380.     // clip version
  1381. // point screen ptr to starting line
  1382. screen_ptr = dest_buffer + (ystart * mem_pitch);
  1383.     // point zbuffer to starting line
  1384.     z_ptr = zbuffer + (ystart * zpitch);
  1385. for (yi = ystart; yi < yend; yi++)
  1386. {
  1387. // compute span endpoints
  1388. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1389. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1390. // compute starting points for u,v interpolants
  1391. zi = zl + 0; // ????
  1392. ui = ul + 0;
  1393. vi = vl + 0;
  1394. // compute u,v interpolants
  1395. if ((dx = (xend - xstart))>0)
  1396. {
  1397. du = (ur - ul) / dx;
  1398. dv = (vr - vl) / dx;
  1399. dz = (zr - zl) / dx;
  1400. } // end if
  1401. else
  1402. {
  1403. du = (ur - ul) ;
  1404. dv = (vr - vl) ;
  1405. dz = (zr - zl);
  1406. } // end else
  1407. ///////////////////////////////////////////////////////////////////////
  1408. // test for x clipping, LHS
  1409. if (xstart < min_clip_x)
  1410. {
  1411. // compute x overlap
  1412. dx = min_clip_x - xstart;
  1413. // slide interpolants over
  1414. ui+=dx*du;
  1415. vi+=dx*dv;
  1416. zi+=dx*dz;
  1417. // reset vars
  1418. xstart = min_clip_x;
  1419. } // end if
  1420. // test for x clipping RHS
  1421. if (xend > max_clip_x)
  1422. xend = max_clip_x;
  1423. ///////////////////////////////////////////////////////////////////////
  1424. // draw span
  1425. for (xi=xstart; xi < xend; xi++)
  1426. {
  1427.             // test if z of current pixel is nearer than current z buffer value
  1428.             if (zi > z_ptr[xi])
  1429.                {
  1430.    // write textel
  1431.        // get textel first
  1432.      textel = textmap[ ((ui << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) + ( ((vi << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) << texture_shift2)];
  1433.                // extract rgb components
  1434.                r_textel  = ((textel >> 11)       ); 
  1435.                g_textel  = ((textel >> 5)  & 0x3f); 
  1436.                b_textel =   (textel        & 0x1f);
  1437.                // modulate textel with lit background color
  1438.                r_textel*=r_base; 
  1439.                g_textel*=g_base;
  1440.                b_textel*=b_base;
  1441.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  1442.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  1443.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  1444.                // and they all cancel out for the most part, but we will need logical anding, we will do
  1445.                // it later when we optimize more...
  1446.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  1447.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  1448.                // update z-buffer
  1449.                z_ptr[xi] = zi;           
  1450.                } // end if
  1451. // interpolate u,v,z
  1452. ui+=du;
  1453. vi+=dv;
  1454. zi+=dz;
  1455. } // end for xi
  1456. // interpolate u,v,x along right and left edge
  1457. xl+=dxdyl;
  1458. ul+=dudyl;
  1459. vl+=dvdyl;
  1460. zl+=dzdyl;
  1461. xr+=dxdyr;
  1462. ur+=dudyr;
  1463. vr+=dvdyr;
  1464. zr+=dzdyr;
  1465.  
  1466. // advance screen ptr
  1467. screen_ptr+=mem_pitch;
  1468.         // advance zbuffer ptr
  1469.         z_ptr+=zpitch;
  1470. } // end for y
  1471. } // end if clip
  1472. else
  1473. {
  1474. // non-clip version
  1475. // point screen ptr to starting line
  1476. screen_ptr = dest_buffer + (ystart * mem_pitch);
  1477.     // point zbuffer to starting line
  1478.     z_ptr = zbuffer + (ystart * zpitch);
  1479. for (yi = ystart; yi < yend; yi++)
  1480. {
  1481. // compute span endpoints
  1482. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1483. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1484. // compute starting points for u,v interpolants
  1485. zi = zl + 0; // ????
  1486. ui = ul + 0;
  1487. vi = vl + 0;
  1488. // compute u,v interpolants
  1489. if ((dx = (xend - xstart))>0)
  1490. {
  1491. du = (ur - ul) / dx;
  1492. dv = (vr - vl) / dx;
  1493. dz = (zr - zl) / dx;
  1494. } // end if
  1495. else
  1496. {
  1497. du = (ur - ul) ;
  1498. dv = (vr - vl) ;
  1499. dz = (zr - zl);
  1500. } // end else
  1501. // draw span
  1502. for (xi=xstart; xi < xend; xi++)
  1503. {
  1504.             // test if z of current pixel is nearer than current z buffer value
  1505.             if (zi > z_ptr[xi])
  1506.                {
  1507.    // write textel
  1508.        // get textel first
  1509.      textel = textmap[ ((ui << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) + ( ((vi << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) << texture_shift2)];
  1510.                // extract rgb components
  1511.                r_textel  = ((textel >> 11)       ); 
  1512.                g_textel  = ((textel >> 5)  & 0x3f); 
  1513.                b_textel =   (textel        & 0x1f);
  1514.                // modulate textel with lit background color
  1515.                r_textel*=r_base; 
  1516.                g_textel*=g_base;
  1517.                b_textel*=b_base;
  1518.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  1519.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  1520.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  1521.                // and they all cancel out for the most part, but we will need logical anding, we will do
  1522.                // it later when we optimize more...
  1523.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  1524.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  1525.                // update z-buffer
  1526.                z_ptr[xi] = zi;           
  1527.                } // end if
  1528. // interpolate u,v,z
  1529. ui+=du;
  1530. vi+=dv;
  1531. zi+=dz;
  1532. } // end for xi
  1533. // interpolate u,v,x along right and left edge
  1534. xl+=dxdyl;
  1535. ul+=dudyl;
  1536. vl+=dvdyl;
  1537. zl+=dzdyl;
  1538. xr+=dxdyr;
  1539. ur+=dudyr;
  1540. vr+=dvdyr;
  1541. zr+=dzdyr;
  1542. // advance screen ptr
  1543. screen_ptr+=mem_pitch;
  1544.         // advance zbuffer ptr
  1545.         z_ptr+=zpitch;
  1546. } // end for y
  1547. } // end if non-clipped
  1548. } // end if
  1549. else
  1550. if (tri_type==TRI_TYPE_GENERAL)
  1551. {
  1552. // first test for bottom clip, always
  1553. if ((yend = y2) > max_clip_y)
  1554. yend = max_clip_y;
  1555. // pre-test y clipping status
  1556. if (y1 < min_clip_y)
  1557. {
  1558. // compute all deltas
  1559. // LHS
  1560. dyl = (y2 - y1);
  1561. dxdyl = ((x2  - x1)  << FIXP16_SHIFT)/dyl;
  1562. dudyl = ((tu2 - tu1) << 0)/dyl;  
  1563. dvdyl = ((tv2 - tv1) << 0)/dyl;    
  1564. dzdyl = ((tz2 - tz1) << 0)/dyl;  
  1565. // RHS
  1566. dyr = (y2 - y0);
  1567. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  1568. dudyr = ((tu2 - tu0) << 0)/dyr;  
  1569. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  1570. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  1571. // compute overclip
  1572. dyr = (min_clip_y - y0);
  1573. dyl = (min_clip_y - y1);
  1574. // computer new LHS starting values
  1575. xl = dxdyl*dyl + (x1  << FIXP16_SHIFT);
  1576. ul = dudyl*dyl + (tu1 << 0);
  1577. vl = dvdyl*dyl + (tv1 << 0);
  1578. zl = dzdyl*dyl + (tz1 << 0);
  1579. // compute new RHS starting values
  1580. xr = dxdyr*dyr + (x0  << FIXP16_SHIFT);
  1581. ur = dudyr*dyr + (tu0 << 0);
  1582. vr = dvdyr*dyr + (tv0 << 0);
  1583. zr = dzdyr*dyr + (tz0 << 0);
  1584. // compute new starting y
  1585. ystart = min_clip_y;
  1586. // test if we need swap to keep rendering left to right
  1587. if (dxdyr > dxdyl)
  1588. {
  1589. SWAP(dxdyl,dxdyr,temp);
  1590. SWAP(dudyl,dudyr,temp);
  1591. SWAP(dvdyl,dvdyr,temp);
  1592. SWAP(dzdyl,dzdyr,temp);
  1593. SWAP(xl,xr,temp);
  1594. SWAP(ul,ur,temp);
  1595. SWAP(vl,vr,temp);
  1596. SWAP(zl,zr,temp);
  1597. SWAP(x1,x2,temp);
  1598. SWAP(y1,y2,temp);
  1599. SWAP(tu1,tu2,temp);
  1600. SWAP(tv1,tv2,temp);
  1601. SWAP(tz1,tz2,temp);
  1602. // set interpolation restart
  1603. irestart = INTERP_RHS;
  1604. } // end if
  1605. } // end if
  1606. else
  1607. if (y0 < min_clip_y)
  1608. {
  1609. // compute all deltas
  1610. // LHS
  1611. dyl = (y1 - y0);
  1612. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  1613. dudyl = ((tu1 - tu0) << 0)/dyl;  
  1614. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  1615. dzdyl = ((tz1 - tz0) << 0)/dyl;  
  1616. // RHS
  1617. dyr = (y2 - y0);
  1618. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  1619. dudyr = ((tu2 - tu0) << 0)/dyr;  
  1620. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  1621. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  1622. // compute overclip
  1623. dy = (min_clip_y - y0);
  1624. // computer new LHS starting values
  1625. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  1626. ul = dudyl*dy + (tu0 << 0);
  1627. vl = dvdyl*dy + (tv0 << 0);
  1628. zl = dzdyl*dy + (tz0 << 0);
  1629. // compute new RHS starting values
  1630. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  1631. ur = dudyr*dy + (tu0 << 0);
  1632. vr = dvdyr*dy + (tv0 << 0);
  1633. zr = dzdyr*dy + (tz0 << 0);
  1634. // compute new starting y
  1635. ystart = min_clip_y;
  1636. // test if we need swap to keep rendering left to right
  1637. if (dxdyr < dxdyl)
  1638. {
  1639. SWAP(dxdyl,dxdyr,temp);
  1640. SWAP(dudyl,dudyr,temp);
  1641. SWAP(dvdyl,dvdyr,temp);
  1642. SWAP(dzdyl,dzdyr,temp);
  1643. SWAP(xl,xr,temp);
  1644. SWAP(ul,ur,temp);
  1645. SWAP(vl,vr,temp);
  1646. SWAP(zl,zr,temp);
  1647. SWAP(x1,x2,temp);
  1648. SWAP(y1,y2,temp);
  1649. SWAP(tu1,tu2,temp);
  1650. SWAP(tv1,tv2,temp);
  1651. SWAP(tz1,tz2,temp);
  1652. // set interpolation restart
  1653. irestart = INTERP_RHS;
  1654. } // end if
  1655. } // end if
  1656. else
  1657. {
  1658. // no initial y clipping
  1659. // compute all deltas
  1660. // LHS
  1661. dyl = (y1 - y0);
  1662. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  1663. dudyl = ((tu1 - tu0) << 0)/dyl;  
  1664. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  1665. dzdyl = ((tz1 - tz0) << 0)/dyl;   
  1666. // RHS
  1667. dyr = (y2 - y0);
  1668. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dyr;
  1669. dudyr = ((tu2 - tu0) << 0)/dyr;  
  1670. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  1671. dzdyr = ((tz2 - tz0) << 0)/dyr;  
  1672. // no clipping y
  1673. // set starting values
  1674. xl = (x0 << FIXP16_SHIFT);
  1675. xr = (x0 << FIXP16_SHIFT);
  1676. ul = (tu0 << 0);
  1677. vl = (tv0 << 0);
  1678. zl = (tz0 << 0);
  1679. ur = (tu0 << 0);
  1680. vr = (tv0 << 0);
  1681. zr = (tz0 << 0);
  1682. // set starting y
  1683. ystart = y0;
  1684. // test if we need swap to keep rendering left to right
  1685. if (dxdyr < dxdyl)
  1686. {
  1687. SWAP(dxdyl,dxdyr,temp);
  1688. SWAP(dudyl,dudyr,temp);
  1689. SWAP(dvdyl,dvdyr,temp);
  1690. SWAP(dzdyl,dzdyr,temp);
  1691. SWAP(xl,xr,temp);
  1692. SWAP(ul,ur,temp);
  1693. SWAP(vl,vr,temp);
  1694. SWAP(zl,zr,temp);
  1695. SWAP(x1,x2,temp);
  1696. SWAP(y1,y2,temp);
  1697. SWAP(tu1,tu2,temp);
  1698. SWAP(tv1,tv2,temp);
  1699. SWAP(tz1,tz2,temp);
  1700. // set interpolation restart
  1701. irestart = INTERP_RHS;
  1702. } // end if
  1703. } // end else
  1704.     // test for horizontal clipping
  1705. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  1706. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  1707. (x2 < min_clip_x) || (x2 > max_clip_x))
  1708. {
  1709.     // clip version
  1710. // x clipping
  1711. // point screen ptr to starting line
  1712. screen_ptr = dest_buffer + (ystart * mem_pitch);
  1713.     // point zbuffer to starting line
  1714.     z_ptr = zbuffer + (ystart * zpitch);
  1715. for (yi = ystart; yi < yend; yi++)
  1716. {
  1717. // compute span endpoints
  1718. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1719. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1720. // compute starting points for u,v interpolants
  1721. zi = zl + 0; // ????
  1722. ui = ul + 0;
  1723. vi = vl + 0;
  1724. // compute u,v interpolants
  1725. if ((dx = (xend - xstart))>0)
  1726. {
  1727. du = (ur - ul) / dx;
  1728. dv = (vr - vl) / dx;
  1729. dz = (zr - zl) / dx;
  1730. } // end if
  1731. else
  1732. {
  1733. du = (ur - ul) ;
  1734. dv = (vr - vl) ;
  1735. dz = (zr - zl);
  1736. } // end else
  1737. ///////////////////////////////////////////////////////////////////////
  1738. // test for x clipping, LHS
  1739. if (xstart < min_clip_x)
  1740. {
  1741. // compute x overlap
  1742. dx = min_clip_x - xstart;
  1743. // slide interpolants over
  1744. ui+=dx*du;
  1745. vi+=dx*dv;
  1746. zi+=dx*dz;
  1747. // set x to left clip edge
  1748. xstart = min_clip_x;
  1749. } // end if
  1750. // test for x clipping RHS
  1751. if (xend > max_clip_x)
  1752. xend = max_clip_x;
  1753. ///////////////////////////////////////////////////////////////////////
  1754. // draw span
  1755. for (xi=xstart; xi < xend; xi++)
  1756. {
  1757.             // test if z of current pixel is nearer than current z buffer value
  1758.             if (zi > z_ptr[xi])
  1759.                {
  1760.    // write textel
  1761.        // get textel first
  1762.      textel = textmap[ ((ui << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) + ( ((vi << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) << texture_shift2)];
  1763.                // extract rgb components
  1764.                r_textel  = ((textel >> 11)       ); 
  1765.                g_textel  = ((textel >> 5)  & 0x3f); 
  1766.                b_textel =   (textel        & 0x1f);
  1767.                // modulate textel with lit background color
  1768.                r_textel*=r_base; 
  1769.                g_textel*=g_base;
  1770.                b_textel*=b_base;
  1771.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  1772.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  1773.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  1774.                // and they all cancel out for the most part, but we will need logical anding, we will do
  1775.                // it later when we optimize more...
  1776.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  1777.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  1778.                // update z-buffer
  1779.                z_ptr[xi] = zi;           
  1780.                } // end if
  1781. // interpolate u,v,z
  1782. ui+=du;
  1783. vi+=dv;
  1784. zi+=dz;
  1785. } // end for xi
  1786. // interpolate u,v,x along right and left edge
  1787. xl+=dxdyl;
  1788. ul+=dudyl;
  1789. vl+=dvdyl;
  1790. zl+=dzdyl;
  1791. xr+=dxdyr;
  1792. ur+=dudyr;
  1793. vr+=dvdyr;
  1794. zr+=dzdyr;
  1795. // advance screen ptr
  1796. screen_ptr+=mem_pitch;
  1797.         // advance zbuffer ptr
  1798.         z_ptr+=zpitch;
  1799. // test for yi hitting second region, if so change interpolant
  1800. if (yi==yrestart)
  1801. {
  1802.     // test interpolation side change flag
  1803. if (irestart == INTERP_LHS)
  1804. {
  1805. // LHS
  1806. dyl = (y2 - y1);
  1807. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  1808. dudyl = ((tu2 - tu1) << 0)/dyl;  
  1809. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  1810. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  1811. // set starting values
  1812. xl = (x1  << FIXP16_SHIFT);
  1813. ul = (tu1 << 0);
  1814. vl = (tv1 << 0);
  1815. zl = (tz1 << 0);
  1816. // interpolate down on LHS to even up
  1817. xl+=dxdyl;
  1818. ul+=dudyl;
  1819. vl+=dvdyl;
  1820. zl+=dzdyl;
  1821. } // end if
  1822. else
  1823. {
  1824. // RHS
  1825. dyr = (y1 - y2);
  1826. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  1827. dudyr = ((tu1 - tu2) << 0)/dyr;  
  1828. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  1829. dzdyr = ((tz1 - tz2) << 0)/dyr;  
  1830. // set starting values
  1831. xr = (x2  << FIXP16_SHIFT);
  1832. ur = (tu2 << 0);
  1833. vr = (tv2 << 0);
  1834. zr = (tz2 << 0);
  1835. // interpolate down on RHS to even up
  1836. xr+=dxdyr;
  1837. ur+=dudyr;
  1838. vr+=dvdyr;
  1839. zr+=dzdyr;
  1840. } // end else
  1841. } // end if
  1842. } // end for y
  1843. } // end if
  1844. else
  1845. {
  1846. // no x clipping
  1847. // point screen ptr to starting line
  1848. screen_ptr = dest_buffer + (ystart * mem_pitch);
  1849.     // point zbuffer to starting line
  1850.     z_ptr = zbuffer + (ystart * zpitch);
  1851. for (yi = ystart; yi < yend; yi++)
  1852. {
  1853. // compute span endpoints
  1854. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1855. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  1856. // compute starting points for u,v interpolants
  1857. zi = zl + 0; // ????
  1858. ui = ul + 0;
  1859. vi = vl + 0;
  1860. // compute u,v interpolants
  1861. if ((dx = (xend - xstart))>0)
  1862. {
  1863. du = (ur - ul) / dx;
  1864. dv = (vr - vl) / dx;
  1865. dz = (zr - zl) / dx;
  1866. } // end if
  1867. else
  1868. {
  1869. du = (ur - ul) ;
  1870. dv = (vr - vl) ;
  1871. dz = (zr - zl);
  1872. } // end else
  1873. // draw span
  1874. for (xi=xstart; xi < xend; xi++)
  1875. {
  1876.             // test if z of current pixel is nearer than current z buffer value
  1877.             if (zi > z_ptr[xi])
  1878.                {
  1879.    // write textel
  1880.        // get textel first
  1881.      textel = textmap[ ((ui << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) + ( ((vi << (FIXP28_SHIFT - FIXP22_SHIFT)) / zi) << texture_shift2)];
  1882.                // extract rgb components
  1883.                r_textel  = ((textel >> 11)       ); 
  1884.                g_textel  = ((textel >> 5)  & 0x3f); 
  1885.                b_textel =   (textel        & 0x1f);
  1886.                // modulate textel with lit background color
  1887.                r_textel*=r_base; 
  1888.                g_textel*=g_base;
  1889.                b_textel*=b_base;
  1890.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  1891.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  1892.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  1893.                // and they all cancel out for the most part, but we will need logical anding, we will do
  1894.                // it later when we optimize more...
  1895.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  1896.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  1897.                // update z-buffer
  1898.                z_ptr[xi] = zi;           
  1899.                } // end if
  1900. // interpolate u,v
  1901. ui+=du;
  1902. vi+=dv;
  1903. zi+=dz;
  1904. } // end for xi
  1905. // interpolate u,v,x along right and left edge
  1906. xl+=dxdyl;
  1907. ul+=dudyl;
  1908. vl+=dvdyl;
  1909. zl+=dzdyl;
  1910. xr+=dxdyr;
  1911. ur+=dudyr;
  1912. vr+=dvdyr;
  1913. zr+=dzdyr;
  1914. // advance screen ptr
  1915. screen_ptr+=mem_pitch;
  1916.         // advance zbuffer ptr
  1917.         z_ptr+=zpitch;
  1918. // test for yi hitting second region, if so change interpolant
  1919. if (yi==yrestart)
  1920. {
  1921. // test interpolation side change flag
  1922. if (irestart == INTERP_LHS)
  1923. {
  1924. // LHS
  1925. dyl = (y2 - y1);
  1926. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  1927. dudyl = ((tu2 - tu1) << 0)/dyl;  
  1928. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  1929. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  1930. // set starting values
  1931. xl = (x1  << FIXP16_SHIFT);
  1932. ul = (tu1 << 0);
  1933. vl = (tv1 << 0);
  1934. zl = (tz1 << 0);
  1935. // interpolate down on LHS to even up
  1936. xl+=dxdyl;
  1937. ul+=dudyl;
  1938. vl+=dvdyl;
  1939. zl+=dzdyl;
  1940. } // end if
  1941. else
  1942. {
  1943. // RHS
  1944. dyr = (y1 - y2);
  1945. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  1946. dudyr = ((tu1 - tu2) << 0)/dyr;  
  1947. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  1948. dzdyr = ((tz1 - tz2) << 0)/dyr; 
  1949. // set starting values
  1950. xr = (x2  << FIXP16_SHIFT);
  1951. ur = (tu2 << 0);
  1952. vr = (tv2 << 0);
  1953. zr = (tz2 << 0);
  1954. // interpolate down on RHS to even up
  1955. xr+=dxdyr;
  1956. ur+=dudyr;
  1957. vr+=dvdyr;
  1958. zr+=dzdyr;
  1959. } // end else
  1960. } // end if
  1961. } // end for y
  1962.    } // end else
  1963. } // end if
  1964. } // end Draw_Textured_Perspective_Triangle_FSINVZB_Alpha16
  1965. //////////////////////////////////////////////////////////////////////////////////////////
  1966. void Draw_Textured_PerspectiveLP_Triangle_FSINVZB_Alpha16(POLYF4DV2_PTR face,  // ptr to face
  1967.                                                    UCHAR *_dest_buffer, // pointer to video buffer
  1968.                                                    int mem_pitch,       // bytes per line, 320, 640 etc.
  1969.                                                    UCHAR *_zbuffer,     // pointer to z-buffer
  1970.                                                    int zpitch,          // bytes per line of zbuffer
  1971.                                                    int alpha)
  1972. {
  1973. // this function draws a textured triangle in 16-bit mode using a 1/z buffer and piecewise linear
  1974. // perspective correct texture mappping, 1/z, u/z, v/z are interpolated down each edge then to draw
  1975. // each span U and V are computed for each end point and the space is broken up into 32 pixel
  1976. // spans where the correct U,V is computed at each point along the span, but linearly interpolated
  1977. // across the span
  1978. int v0=0,
  1979.     v1=1,
  1980. v2=2,
  1981. temp=0,
  1982. tri_type = TRI_TYPE_NONE,
  1983. irestart = INTERP_LHS;
  1984. int dx,dy,dyl,dyr,      // general deltas
  1985.     u,v,z,
  1986.     du,dv,dz,
  1987.     xi,yi,              // the current interpolated x,y
  1988. ui,vi,zi,           // the current interpolated u,v,z
  1989. index_x,index_y,    // looping vars
  1990. x,y,                // hold general x,y
  1991. xstart,
  1992. xend,
  1993. ystart,
  1994. yrestart,
  1995. yend,
  1996. xl,                 
  1997. dxdyl,              
  1998. xr,
  1999. dxdyr,             
  2000. dudyl,    
  2001. ul,
  2002. dvdyl,   
  2003. vl,
  2004. dzdyl,   
  2005. zl,
  2006. dudyr,
  2007. ur,
  2008. dvdyr,
  2009. vr,
  2010. dzdyr,
  2011. zr;
  2012. int x0,y0,tu0,tv0,tz0,    // cached vertices
  2013. x1,y1,tu1,tv1,tz1,
  2014. x2,y2,tu2,tv2,tz2;
  2015. int ur2, ul2, vr2, vl2;
  2016. USHORT *screen_ptr  = NULL,
  2017.    *screen_line = NULL,
  2018.    *textmap     = NULL,
  2019.        *dest_buffer = (USHORT *)_dest_buffer;
  2020. USHORT r_base, g_base, b_base,
  2021.        r_textel, g_textel, b_textel, textel;
  2022. UINT  *z_ptr = NULL,
  2023.       *zbuffer = (UINT *)_zbuffer;
  2024. #ifdef DEBUG_ON
  2025. // track rendering stats
  2026.     debug_polys_rendered_per_frame++;
  2027. #endif
  2028. // extract texture map
  2029. textmap = (USHORT *)face->texture->buffer;
  2030. // extract base 2 of texture width
  2031. int texture_shift2 = logbase2ofx[face->texture->width];
  2032. // adjust memory pitch to words, divide by 2
  2033. mem_pitch >>=1;
  2034. // adjust zbuffer pitch for 32 bit alignment
  2035. zpitch >>= 2;
  2036. // apply fill convention to coordinates
  2037. face->tvlist[0].x = (int)(face->tvlist[0].x+0.5);
  2038. face->tvlist[0].y = (int)(face->tvlist[0].y+0.5);
  2039. face->tvlist[1].x = (int)(face->tvlist[1].x+0.5);
  2040. face->tvlist[1].y = (int)(face->tvlist[1].y+0.5);
  2041. face->tvlist[2].x = (int)(face->tvlist[2].x+0.5);
  2042. face->tvlist[2].y = (int)(face->tvlist[2].y+0.5);
  2043. // first trivial clipping rejection tests 
  2044. if (((face->tvlist[0].y < min_clip_y)  && 
  2045.  (face->tvlist[1].y < min_clip_y)  &&
  2046.  (face->tvlist[2].y < min_clip_y)) ||
  2047. ((face->tvlist[0].y > max_clip_y)  && 
  2048.  (face->tvlist[1].y > max_clip_y)  &&
  2049.  (face->tvlist[2].y > max_clip_y)) ||
  2050. ((face->tvlist[0].x < min_clip_x)  && 
  2051.  (face->tvlist[1].x < min_clip_x)  &&
  2052.  (face->tvlist[2].x < min_clip_x)) ||
  2053. ((face->tvlist[0].x > max_clip_x)  && 
  2054.  (face->tvlist[1].x > max_clip_x)  &&
  2055.  (face->tvlist[2].x > max_clip_x)))
  2056.    return;
  2057. // sort vertices
  2058. if (face->tvlist[v1].y < face->tvlist[v0].y) 
  2059. {SWAP(v0,v1,temp);} 
  2060. if (face->tvlist[v2].y < face->tvlist[v0].y) 
  2061. {SWAP(v0,v2,temp);}
  2062. if (face->tvlist[v2].y < face->tvlist[v1].y) 
  2063. {SWAP(v1,v2,temp);}
  2064. // now test for trivial flat sided cases
  2065. if (FCMP(face->tvlist[v0].y, face->tvlist[v1].y) )
  2066. // set triangle type
  2067. tri_type = TRI_TYPE_FLAT_TOP;
  2068. // sort vertices left to right
  2069. if (face->tvlist[v1].x < face->tvlist[v0].x) 
  2070. {SWAP(v0,v1,temp);}
  2071. } // end if
  2072. else
  2073. // now test for trivial flat sided cases
  2074. if (FCMP(face->tvlist[v1].y ,face->tvlist[v2].y))
  2075. // set triangle type
  2076. tri_type = TRI_TYPE_FLAT_BOTTOM;
  2077. // sort vertices left to right
  2078. if (face->tvlist[v2].x < face->tvlist[v1].x) 
  2079. {SWAP(v1,v2,temp);}
  2080. } // end if
  2081. else
  2082. {
  2083. // must be a general triangle
  2084. tri_type = TRI_TYPE_GENERAL;
  2085. } // end else
  2086. // extract base color of lit poly, so we can modulate texture a bit
  2087. // for lighting
  2088. _RGB565FROM16BIT(face->lit_color[0], &r_base, &g_base, &b_base);
  2089. // extract vertices for processing, now that we have order
  2090. x0  = (int)(face->tvlist[v0].x+0.0);
  2091. y0  = (int)(face->tvlist[v0].y+0.0);
  2092. tu0 = ((int)(face->tvlist[v0].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  2093. tv0 = ((int)(face->tvlist[v0].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  2094. tz0 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  2095. x1  = (int)(face->tvlist[v1].x+0.0);
  2096. y1  = (int)(face->tvlist[v1].y+0.0);
  2097. tu1 = ((int)(face->tvlist[v1].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  2098. tv1 = ((int)(face->tvlist[v1].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  2099. tz1 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  2100. x2  = (int)(face->tvlist[v2].x+0.0);
  2101. y2  = (int)(face->tvlist[v2].y+0.0);
  2102. tu2 = ((int)(face->tvlist[v2].u0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  2103. tv2 = ((int)(face->tvlist[v2].v0+0.5) << FIXP22_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  2104. tz2 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  2105. // degenerate triangle
  2106. if ( ((x0 == x1) && (x1 == x2)) || ((y0 ==  y1) && (y1 == y2)))
  2107.    return;
  2108. // assign both source1 and source2 alpha tables based on polygon alpha level
  2109. USHORT *alpha_table_src1 = (USHORT *)&rgb_alpha_table[(NUM_ALPHA_LEVELS-1) - alpha][0];
  2110. USHORT *alpha_table_src2 = (USHORT *)&rgb_alpha_table[alpha][0];
  2111. // set interpolation restart value
  2112. yrestart = y1;
  2113. // what kind of triangle
  2114. if (tri_type & TRI_TYPE_FLAT_MASK)
  2115. {
  2116. if (tri_type == TRI_TYPE_FLAT_TOP)
  2117. {
  2118. // compute all deltas
  2119. dy = (y2 - y0);
  2120. dxdyl = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  2121. dudyl = ((tu2 - tu0) << 0)/dy;  
  2122. dvdyl = ((tv2 - tv0) << 0)/dy;    
  2123. dzdyl = ((tz2 - tz0) << 0)/dy;    
  2124. dxdyr = ((x2 - x1)   << FIXP16_SHIFT)/dy;
  2125. dudyr = ((tu2 - tu1) << 0)/dy;  
  2126. dvdyr = ((tv2 - tv1) << 0)/dy;   
  2127. dzdyr = ((tz2 - tz1) << 0)/dy;  
  2128. // test for y clipping
  2129. if (y0 < min_clip_y)
  2130. {
  2131. // compute overclip
  2132. dy = (min_clip_y - y0);
  2133. // computer new LHS starting values
  2134. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  2135. ul = dudyl*dy + (tu0 << 0);
  2136. vl = dvdyl*dy + (tv0 << 0);
  2137. zl = dzdyl*dy + (tz0 << 0);
  2138. // compute new RHS starting values
  2139. xr = dxdyr*dy + (x1  << FIXP16_SHIFT);
  2140. ur = dudyr*dy + (tu1 << 0);
  2141. vr = dvdyr*dy + (tv1 << 0);
  2142. zr = dzdyr*dy + (tz1 << 0);
  2143. // compute new starting y
  2144. ystart = min_clip_y;
  2145. } // end if
  2146. else
  2147. {
  2148. // no clipping
  2149. // set starting values
  2150. xl = (x0 << FIXP16_SHIFT);
  2151. xr = (x1 << FIXP16_SHIFT);
  2152. ul = (tu0 << 0);
  2153. vl = (tv0 << 0);
  2154. zl = (tz0 << 0);
  2155. ur = (tu1 << 0);
  2156. vr = (tv1 << 0);
  2157. zr = (tz1 << 0);
  2158. // set starting y
  2159. ystart = y0;
  2160. } // end else
  2161. } // end if flat top
  2162. else
  2163. {
  2164. // must be flat bottom
  2165. // compute all deltas
  2166. dy = (y1 - y0);
  2167. dxdyl = ((x1 - x0)   << FIXP16_SHIFT)/dy;
  2168. dudyl = ((tu1 - tu0) << 0)/dy;  
  2169. dvdyl = ((tv1 - tv0) << 0)/dy;    
  2170. dzdyl = ((tz1 - tz0) << 0)/dy;   
  2171. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  2172. dudyr = ((tu2 - tu0) << 0)/dy;  
  2173. dvdyr = ((tv2 - tv0) << 0)/dy;   
  2174. dzdyr = ((tz2 - tz0) << 0)/dy;   
  2175. // test for y clipping
  2176. if (y0 < min_clip_y)
  2177. {
  2178. // compute overclip
  2179. dy = (min_clip_y - y0);
  2180. // computer new LHS starting values
  2181. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  2182. ul = dudyl*dy + (tu0 << 0);
  2183. vl = dvdyl*dy + (tv0 << 0);
  2184. zl = dzdyl*dy + (tz0 << 0);
  2185. // compute new RHS starting values
  2186. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  2187. ur = dudyr*dy + (tu0 << 0);
  2188. vr = dvdyr*dy + (tv0 << 0);
  2189. zr = dzdyr*dy + (tz0 << 0);
  2190. // compute new starting y
  2191. ystart = min_clip_y;
  2192. } // end if
  2193. else
  2194. {
  2195. // no clipping
  2196. // set starting values
  2197. xl = (x0 << FIXP16_SHIFT);
  2198. xr = (x0 << FIXP16_SHIFT);
  2199. ul = (tu0 << 0);
  2200. vl = (tv0 << 0);
  2201. zl = (tz0 << 0);
  2202. ur = (tu0 << 0);
  2203. vr = (tv0 << 0);
  2204. zr = (tz0 << 0);
  2205. // set starting y
  2206. ystart = y0;
  2207. } // end else
  2208. } // end else flat bottom
  2209. // test for bottom clip, always
  2210. if ((yend = y2) > max_clip_y)
  2211. yend = max_clip_y;
  2212.     // test for horizontal clipping
  2213. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  2214. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  2215. (x2 < min_clip_x) || (x2 > max_clip_x))
  2216. {
  2217.     // clip version
  2218. // point screen ptr to starting line
  2219. screen_ptr = dest_buffer + (ystart * mem_pitch);
  2220.     // point zbuffer to starting line
  2221.     z_ptr = zbuffer + (ystart * zpitch);
  2222. for (yi = ystart; yi < yend; yi++)
  2223. {
  2224. // compute span endpoints
  2225. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2226. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2227.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2228.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2229.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2230.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2231. // compute starting points for u,v interpolants
  2232. zi = zl + 0; // ????
  2233. ui = ul2 + 0;
  2234. vi = vl2 + 0;
  2235. // compute u,v interpolants
  2236. if ((dx = (xend - xstart))>0)
  2237. {
  2238. du = (ur2 - ul2) / dx;
  2239. dv = (vr2 - vl2) / dx;
  2240. dz = (zr - zl) / dx;
  2241. } // end if
  2242. else
  2243. {
  2244. du = (ur2 - ul2) ;
  2245. dv = (vr2 - vl2) ;
  2246. dz = (zr - zl);
  2247. } // end else
  2248. ///////////////////////////////////////////////////////////////////////
  2249. // test for x clipping, LHS
  2250. if (xstart < min_clip_x)
  2251. {
  2252. // compute x overlap
  2253. dx = min_clip_x - xstart;
  2254. // slide interpolants over
  2255. ui+=dx*du;
  2256. vi+=dx*dv;
  2257. zi+=dx*dz;
  2258. // reset vars
  2259. xstart = min_clip_x;
  2260. } // end if
  2261. // test for x clipping RHS
  2262. if (xend > max_clip_x)
  2263. xend = max_clip_x;
  2264. ///////////////////////////////////////////////////////////////////////
  2265. // draw span
  2266. for (xi=xstart; xi < xend; xi++)
  2267. {
  2268.             // test if z of current pixel is nearer than current z buffer value
  2269.             if (zi > z_ptr[xi])
  2270.                {
  2271.    // write textel
  2272.        // get textel first
  2273.      textel = textmap[ (ui >> FIXP22_SHIFT) + ((vi >> FIXP22_SHIFT) << texture_shift2)];
  2274.                // extract rgb components
  2275.                r_textel  = ((textel >> 11)       ); 
  2276.                g_textel  = ((textel >> 5)  & 0x3f); 
  2277.                b_textel =   (textel        & 0x1f);
  2278.                // modulate textel with lit background color
  2279.                r_textel*=r_base; 
  2280.                g_textel*=g_base;
  2281.                b_textel*=b_base;
  2282.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  2283.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  2284.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  2285.                // and they all cancel out for the most part, but we will need logical anding, we will do
  2286.                // it later when we optimize more...
  2287.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  2288.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  2289.                // update z-buffer
  2290.                z_ptr[xi] = zi;           
  2291.                } // end if
  2292. // interpolate u,v,z
  2293. ui+=du;
  2294. vi+=dv;
  2295. zi+=dz;
  2296. } // end for xi
  2297. // interpolate u,v,x along right and left edge
  2298. xl+=dxdyl;
  2299. ul+=dudyl;
  2300. vl+=dvdyl;
  2301. zl+=dzdyl;
  2302. xr+=dxdyr;
  2303. ur+=dudyr;
  2304. vr+=dvdyr;
  2305. zr+=dzdyr;
  2306.  
  2307. // advance screen ptr
  2308. screen_ptr+=mem_pitch;
  2309.         // advance zbuffer ptr
  2310.         z_ptr+=zpitch;
  2311. } // end for y
  2312. } // end if clip
  2313. else
  2314. {
  2315. // non-clip version
  2316. // point screen ptr to starting line
  2317. screen_ptr = dest_buffer + (ystart * mem_pitch);
  2318.     // point zbuffer to starting line
  2319.     z_ptr = zbuffer + (ystart * zpitch);
  2320. for (yi = ystart; yi < yend; yi++)
  2321. {
  2322. // compute span endpoints
  2323. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2324. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2325.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2326.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2327.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2328.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2329. // compute starting points for u,v interpolants
  2330. zi = zl + 0; // ????
  2331. ui = ul2 + 0;
  2332. vi = vl2 + 0;
  2333. // compute u,v interpolants
  2334. if ((dx = (xend - xstart))>0)
  2335. {
  2336. du = (ur2 - ul2) / dx;
  2337. dv = (vr2 - vl2) / dx;
  2338. dz = (zr - zl) / dx;
  2339. } // end if
  2340. else
  2341. {
  2342. du = (ur2 - ul2) ;
  2343. dv = (vr2 - vl2) ;
  2344. dz = (zr - zl);
  2345. } // end else
  2346. // draw span
  2347. for (xi=xstart; xi < xend; xi++)
  2348. {
  2349.             // test if z of current pixel is nearer than current z buffer value
  2350.             if (zi > z_ptr[xi])
  2351.                {
  2352.    // write textel
  2353.        // get textel first
  2354.      textel = textmap[ (ui >> FIXP22_SHIFT) + ((vi >> FIXP22_SHIFT) << texture_shift2)];
  2355.                // extract rgb components
  2356.                r_textel  = ((textel >> 11)       ); 
  2357.                g_textel  = ((textel >> 5)  & 0x3f); 
  2358.                b_textel =   (textel        & 0x1f);
  2359.                // modulate textel with lit background color
  2360.                r_textel*=r_base; 
  2361.                g_textel*=g_base;
  2362.                b_textel*=b_base;
  2363.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  2364.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  2365.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  2366.                // and they all cancel out for the most part, but we will need logical anding, we will do
  2367.                // it later when we optimize more...
  2368.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  2369.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  2370.                // update z-buffer
  2371.                z_ptr[xi] = zi;           
  2372.                } // end if
  2373. // interpolate u,v,z
  2374. ui+=du;
  2375. vi+=dv;
  2376. zi+=dz;
  2377. } // end for xi
  2378. // interpolate u,v,x along right and left edge
  2379. xl+=dxdyl;
  2380. ul+=dudyl;
  2381. vl+=dvdyl;
  2382. zl+=dzdyl;
  2383. xr+=dxdyr;
  2384. ur+=dudyr;
  2385. vr+=dvdyr;
  2386. zr+=dzdyr;
  2387. // advance screen ptr
  2388. screen_ptr+=mem_pitch;
  2389.         // advance zbuffer ptr
  2390.         z_ptr+=zpitch;
  2391. } // end for y
  2392. } // end if non-clipped
  2393. } // end if
  2394. else
  2395. if (tri_type==TRI_TYPE_GENERAL)
  2396. {
  2397. // first test for bottom clip, always
  2398. if ((yend = y2) > max_clip_y)
  2399. yend = max_clip_y;
  2400. // pre-test y clipping status
  2401. if (y1 < min_clip_y)
  2402. {
  2403. // compute all deltas
  2404. // LHS
  2405. dyl = (y2 - y1);
  2406. dxdyl = ((x2  - x1)  << FIXP16_SHIFT)/dyl;
  2407. dudyl = ((tu2 - tu1) << 0)/dyl;  
  2408. dvdyl = ((tv2 - tv1) << 0)/dyl;    
  2409. dzdyl = ((tz2 - tz1) << 0)/dyl;  
  2410. // RHS
  2411. dyr = (y2 - y0);
  2412. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  2413. dudyr = ((tu2 - tu0) << 0)/dyr;  
  2414. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  2415. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  2416. // compute overclip
  2417. dyr = (min_clip_y - y0);
  2418. dyl = (min_clip_y - y1);
  2419. // computer new LHS starting values
  2420. xl = dxdyl*dyl + (x1  << FIXP16_SHIFT);
  2421. ul = dudyl*dyl + (tu1 << 0);
  2422. vl = dvdyl*dyl + (tv1 << 0);
  2423. zl = dzdyl*dyl + (tz1 << 0);
  2424. // compute new RHS starting values
  2425. xr = dxdyr*dyr + (x0  << FIXP16_SHIFT);
  2426. ur = dudyr*dyr + (tu0 << 0);
  2427. vr = dvdyr*dyr + (tv0 << 0);
  2428. zr = dzdyr*dyr + (tz0 << 0);
  2429. // compute new starting y
  2430. ystart = min_clip_y;
  2431. // test if we need swap to keep rendering left to right
  2432. if (dxdyr > dxdyl)
  2433. {
  2434. SWAP(dxdyl,dxdyr,temp);
  2435. SWAP(dudyl,dudyr,temp);
  2436. SWAP(dvdyl,dvdyr,temp);
  2437. SWAP(dzdyl,dzdyr,temp);
  2438. SWAP(xl,xr,temp);
  2439. SWAP(ul,ur,temp);
  2440. SWAP(vl,vr,temp);
  2441. SWAP(zl,zr,temp);
  2442. SWAP(x1,x2,temp);
  2443. SWAP(y1,y2,temp);
  2444. SWAP(tu1,tu2,temp);
  2445. SWAP(tv1,tv2,temp);
  2446. SWAP(tz1,tz2,temp);
  2447. // set interpolation restart
  2448. irestart = INTERP_RHS;
  2449. } // end if
  2450. } // end if
  2451. else
  2452. if (y0 < min_clip_y)
  2453. {
  2454. // compute all deltas
  2455. // LHS
  2456. dyl = (y1 - y0);
  2457. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  2458. dudyl = ((tu1 - tu0) << 0)/dyl;  
  2459. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  2460. dzdyl = ((tz1 - tz0) << 0)/dyl;  
  2461. // RHS
  2462. dyr = (y2 - y0);
  2463. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  2464. dudyr = ((tu2 - tu0) << 0)/dyr;  
  2465. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  2466. dzdyr = ((tz2 - tz0) << 0)/dyr;   
  2467. // compute overclip
  2468. dy = (min_clip_y - y0);
  2469. // computer new LHS starting values
  2470. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  2471. ul = dudyl*dy + (tu0 << 0);
  2472. vl = dvdyl*dy + (tv0 << 0);
  2473. zl = dzdyl*dy + (tz0 << 0);
  2474. // compute new RHS starting values
  2475. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  2476. ur = dudyr*dy + (tu0 << 0);
  2477. vr = dvdyr*dy + (tv0 << 0);
  2478. zr = dzdyr*dy + (tz0 << 0);
  2479. // compute new starting y
  2480. ystart = min_clip_y;
  2481. // test if we need swap to keep rendering left to right
  2482. if (dxdyr < dxdyl)
  2483. {
  2484. SWAP(dxdyl,dxdyr,temp);
  2485. SWAP(dudyl,dudyr,temp);
  2486. SWAP(dvdyl,dvdyr,temp);
  2487. SWAP(dzdyl,dzdyr,temp);
  2488. SWAP(xl,xr,temp);
  2489. SWAP(ul,ur,temp);
  2490. SWAP(vl,vr,temp);
  2491. SWAP(zl,zr,temp);
  2492. SWAP(x1,x2,temp);
  2493. SWAP(y1,y2,temp);
  2494. SWAP(tu1,tu2,temp);
  2495. SWAP(tv1,tv2,temp);
  2496. SWAP(tz1,tz2,temp);
  2497. // set interpolation restart
  2498. irestart = INTERP_RHS;
  2499. } // end if
  2500. } // end if
  2501. else
  2502. {
  2503. // no initial y clipping
  2504. // compute all deltas
  2505. // LHS
  2506. dyl = (y1 - y0);
  2507. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  2508. dudyl = ((tu1 - tu0) << 0)/dyl;  
  2509. dvdyl = ((tv1 - tv0) << 0)/dyl;    
  2510. dzdyl = ((tz1 - tz0) << 0)/dyl;   
  2511. // RHS
  2512. dyr = (y2 - y0);
  2513. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dyr;
  2514. dudyr = ((tu2 - tu0) << 0)/dyr;  
  2515. dvdyr = ((tv2 - tv0) << 0)/dyr;   
  2516. dzdyr = ((tz2 - tz0) << 0)/dyr;  
  2517. // no clipping y
  2518. // set starting values
  2519. xl = (x0 << FIXP16_SHIFT);
  2520. xr = (x0 << FIXP16_SHIFT);
  2521. ul = (tu0 << 0);
  2522. vl = (tv0 << 0);
  2523. zl = (tz0 << 0);
  2524. ur = (tu0 << 0);
  2525. vr = (tv0 << 0);
  2526. zr = (tz0 << 0);
  2527. // set starting y
  2528. ystart = y0;
  2529. // test if we need swap to keep rendering left to right
  2530. if (dxdyr < dxdyl)
  2531. {
  2532. SWAP(dxdyl,dxdyr,temp);
  2533. SWAP(dudyl,dudyr,temp);
  2534. SWAP(dvdyl,dvdyr,temp);
  2535. SWAP(dzdyl,dzdyr,temp);
  2536. SWAP(xl,xr,temp);
  2537. SWAP(ul,ur,temp);
  2538. SWAP(vl,vr,temp);
  2539. SWAP(zl,zr,temp);
  2540. SWAP(x1,x2,temp);
  2541. SWAP(y1,y2,temp);
  2542. SWAP(tu1,tu2,temp);
  2543. SWAP(tv1,tv2,temp);
  2544. SWAP(tz1,tz2,temp);
  2545. // set interpolation restart
  2546. irestart = INTERP_RHS;
  2547. } // end if
  2548. } // end else
  2549.     // test for horizontal clipping
  2550. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  2551. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  2552. (x2 < min_clip_x) || (x2 > max_clip_x))
  2553. {
  2554.     // clip version
  2555. // x clipping
  2556. // point screen ptr to starting line
  2557. screen_ptr = dest_buffer + (ystart * mem_pitch);
  2558.     // point zbuffer to starting line
  2559.     z_ptr = zbuffer + (ystart * zpitch);
  2560. for (yi = ystart; yi < yend; yi++)
  2561. {
  2562. // compute span endpoints
  2563. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2564. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2565.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2566.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2567.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2568.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2569. // compute starting points for u,v interpolants
  2570. zi = zl + 0; // ????
  2571. ui = ul2 + 0;
  2572. vi = vl2 + 0;
  2573. // compute u,v interpolants
  2574. if ((dx = (xend - xstart))>0)
  2575. {
  2576. du = (ur2 - ul2) / dx;
  2577. dv = (vr2 - vl2) / dx;
  2578. dz = (zr - zl) / dx;
  2579. } // end if
  2580. else
  2581. {
  2582. du = (ur2 - ul2) ;
  2583. dv = (vr2 - vl2) ;
  2584. dz = (zr - zl);
  2585. } // end else
  2586. ///////////////////////////////////////////////////////////////////////
  2587. // test for x clipping, LHS
  2588. if (xstart < min_clip_x)
  2589. {
  2590. // compute x overlap
  2591. dx = min_clip_x - xstart;
  2592. // slide interpolants over
  2593. ui+=dx*du;
  2594. vi+=dx*dv;
  2595. zi+=dx*dz;
  2596. // set x to left clip edge
  2597. xstart = min_clip_x;
  2598. } // end if
  2599. // test for x clipping RHS
  2600. if (xend > max_clip_x)
  2601. xend = max_clip_x;
  2602. ///////////////////////////////////////////////////////////////////////
  2603. // draw span
  2604. for (xi=xstart; xi < xend; xi++)
  2605. {
  2606.             // test if z of current pixel is nearer than current z buffer value
  2607.             if (zi > z_ptr[xi])
  2608.                {
  2609.    // write textel
  2610.        // get textel first
  2611.      textel = textmap[ (ui >> FIXP22_SHIFT) + ((vi >> FIXP22_SHIFT) << texture_shift2)];
  2612.                // extract rgb components
  2613.                r_textel  = ((textel >> 11)       ); 
  2614.                g_textel  = ((textel >> 5)  & 0x3f); 
  2615.                b_textel =   (textel        & 0x1f);
  2616.                // modulate textel with lit background color
  2617.                r_textel*=r_base; 
  2618.                g_textel*=g_base;
  2619.                b_textel*=b_base;
  2620.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  2621.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  2622.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  2623.                // and they all cancel out for the most part, but we will need logical anding, we will do
  2624.                // it later when we optimize more...
  2625.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  2626.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  2627.                // update z-buffer
  2628.                z_ptr[xi] = zi;           
  2629.                } // end if
  2630. // interpolate u,v,z
  2631. ui+=du;
  2632. vi+=dv;
  2633. zi+=dz;
  2634. } // end for xi
  2635. // interpolate u,v,x along right and left edge
  2636. xl+=dxdyl;
  2637. ul+=dudyl;
  2638. vl+=dvdyl;
  2639. zl+=dzdyl;
  2640. xr+=dxdyr;
  2641. ur+=dudyr;
  2642. vr+=dvdyr;
  2643. zr+=dzdyr;
  2644. // advance screen ptr
  2645. screen_ptr+=mem_pitch;
  2646.         // advance zbuffer ptr
  2647.         z_ptr+=zpitch;
  2648. // test for yi hitting second region, if so change interpolant
  2649. if (yi==yrestart)
  2650. {
  2651.     // test interpolation side change flag
  2652. if (irestart == INTERP_LHS)
  2653. {
  2654. // LHS
  2655. dyl = (y2 - y1);
  2656. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  2657. dudyl = ((tu2 - tu1) << 0)/dyl;  
  2658. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  2659. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  2660. // set starting values
  2661. xl = (x1  << FIXP16_SHIFT);
  2662. ul = (tu1 << 0);
  2663. vl = (tv1 << 0);
  2664. zl = (tz1 << 0);
  2665. // interpolate down on LHS to even up
  2666. xl+=dxdyl;
  2667. ul+=dudyl;
  2668. vl+=dvdyl;
  2669. zl+=dzdyl;
  2670. } // end if
  2671. else
  2672. {
  2673. // RHS
  2674. dyr = (y1 - y2);
  2675. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  2676. dudyr = ((tu1 - tu2) << 0)/dyr;  
  2677. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  2678. dzdyr = ((tz1 - tz2) << 0)/dyr;  
  2679. // set starting values
  2680. xr = (x2  << FIXP16_SHIFT);
  2681. ur = (tu2 << 0);
  2682. vr = (tv2 << 0);
  2683. zr = (tz2 << 0);
  2684. // interpolate down on RHS to even up
  2685. xr+=dxdyr;
  2686. ur+=dudyr;
  2687. vr+=dvdyr;
  2688. zr+=dzdyr;
  2689. } // end else
  2690. } // end if
  2691. } // end for y
  2692. } // end if
  2693. else
  2694. {
  2695. // no x clipping
  2696. // point screen ptr to starting line
  2697. screen_ptr = dest_buffer + (ystart * mem_pitch);
  2698.     // point zbuffer to starting line
  2699.     z_ptr = zbuffer + (ystart * zpitch);
  2700. for (yi = ystart; yi < yend; yi++)
  2701. {
  2702. // compute span endpoints
  2703. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2704. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  2705.         ul2 = ((ul << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2706.         ur2 = ((ur << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2707.         vl2 = ((vl << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zl >> 6) ) << 16;
  2708.         vr2 = ((vr << (FIXP28_SHIFT - FIXP22_SHIFT)) / (zr >> 6) ) << 16;
  2709. // compute starting points for u,v interpolants
  2710. zi = zl + 0; // ????
  2711. ui = ul2 + 0;
  2712. vi = vl2 + 0;
  2713. // compute u,v interpolants
  2714. if ((dx = (xend - xstart))>0)
  2715. {
  2716. du = (ur2 - ul2) / dx;
  2717. dv = (vr2 - vl2) / dx;
  2718. dz = (zr - zl) / dx;
  2719. } // end if
  2720. else
  2721. {
  2722. du = (ur2 - ul2) ;
  2723. dv = (vr2 - vl2) ;
  2724. dz = (zr - zl);
  2725. } // end else
  2726. // draw span
  2727. for (xi=xstart; xi < xend; xi++)
  2728. {
  2729.             // test if z of current pixel is nearer than current z buffer value
  2730.             if (zi > z_ptr[xi])
  2731.                {
  2732.    // write textel
  2733.        // get textel first
  2734.      textel = textmap[ (ui >> FIXP22_SHIFT) + ((vi >> FIXP22_SHIFT) << texture_shift2)];
  2735.                // extract rgb components
  2736.                r_textel  = ((textel >> 11)       ); 
  2737.                g_textel  = ((textel >> 5)  & 0x3f); 
  2738.                b_textel =   (textel        & 0x1f);
  2739.                // modulate textel with lit background color
  2740.                r_textel*=r_base; 
  2741.                g_textel*=g_base;
  2742.                b_textel*=b_base;
  2743.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  2744.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  2745.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  2746.                // and they all cancel out for the most part, but we will need logical anding, we will do
  2747.                // it later when we optimize more...
  2748.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  2749.                                 alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  2750.                // update z-buffer
  2751.                z_ptr[xi] = zi;           
  2752.                } // end if
  2753. // interpolate u,v
  2754. ui+=du;
  2755. vi+=dv;
  2756. zi+=dz;
  2757. } // end for xi
  2758. // interpolate u,v,x along right and left edge
  2759. xl+=dxdyl;
  2760. ul+=dudyl;
  2761. vl+=dvdyl;
  2762. zl+=dzdyl;
  2763. xr+=dxdyr;
  2764. ur+=dudyr;
  2765. vr+=dvdyr;
  2766. zr+=dzdyr;
  2767. // advance screen ptr
  2768. screen_ptr+=mem_pitch;
  2769.         // advance zbuffer ptr
  2770.         z_ptr+=zpitch;
  2771. // test for yi hitting second region, if so change interpolant
  2772. if (yi==yrestart)
  2773. {
  2774. // test interpolation side change flag
  2775. if (irestart == INTERP_LHS)
  2776. {
  2777. // LHS
  2778. dyl = (y2 - y1);
  2779. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  2780. dudyl = ((tu2 - tu1) << 0)/dyl;  
  2781. dvdyl = ((tv2 - tv1) << 0)/dyl;   
  2782. dzdyl = ((tz2 - tz1) << 0)/dyl;   
  2783. // set starting values
  2784. xl = (x1  << FIXP16_SHIFT);
  2785. ul = (tu1 << 0);
  2786. vl = (tv1 << 0);
  2787. zl = (tz1 << 0);
  2788. // interpolate down on LHS to even up
  2789. xl+=dxdyl;
  2790. ul+=dudyl;
  2791. vl+=dvdyl;
  2792. zl+=dzdyl;
  2793. } // end if
  2794. else
  2795. {
  2796. // RHS
  2797. dyr = (y1 - y2);
  2798. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  2799. dudyr = ((tu1 - tu2) << 0)/dyr;  
  2800. dvdyr = ((tv1 - tv2) << 0)/dyr;   
  2801. dzdyr = ((tz1 - tz2) << 0)/dyr; 
  2802. // set starting values
  2803. xr = (x2  << FIXP16_SHIFT);
  2804. ur = (tu2 << 0);
  2805. vr = (tv2 << 0);
  2806. zr = (tz2 << 0);
  2807. // interpolate down on RHS to even up
  2808. xr+=dxdyr;
  2809. ur+=dudyr;
  2810. vr+=dvdyr;
  2811. zr+=dzdyr;
  2812. } // end else
  2813. } // end if
  2814. } // end for y
  2815.    } // end else
  2816. } // end if
  2817. } // end Draw_Textured_PerspectiveLP_Triangle_FSINVZB_Alpha16
  2818. ///////////////////////////////////////////////////////////////////////////////
  2819. void Draw_Textured_TriangleFSINVZB_Alpha16(POLYF4DV2_PTR face, // ptr to face
  2820.                                  UCHAR *_dest_buffer,  // pointer to video buffer
  2821.                                  int mem_pitch,        // bytes per line, 320, 640 etc.
  2822.                                  UCHAR *_zbuffer,       // pointer to z-buffer
  2823.                                  int zpitch,           // bytes per line of zbuffer
  2824.                                  int alpha)
  2825. {
  2826. // this function draws a textured triangle in 16-bit mode with flat shading
  2827. int v0=0,
  2828.     v1=1,
  2829. v2=2,
  2830. temp=0,
  2831. tri_type = TRI_TYPE_NONE,
  2832. irestart = INTERP_LHS;
  2833. int dx,dy,dyl,dyr,      // general deltas
  2834.     u,v,z,
  2835.     du,dv,dz,
  2836.     xi,yi,              // the current interpolated x,y
  2837. ui,vi,zi,            // the current interpolated u,v,z
  2838. index_x,index_y,    // looping vars
  2839. x,y,                // hold general x,y
  2840. xstart,
  2841. xend,
  2842. ystart,
  2843. yrestart,
  2844. yend,
  2845. xl,                 
  2846. dxdyl,              
  2847. xr,
  2848. dxdyr,             
  2849. dudyl,    
  2850. ul,
  2851. dzdyl,    
  2852. zl,
  2853. dvdyl,   
  2854. vl,
  2855. dudyr,
  2856. ur,
  2857. dvdyr,
  2858. vr,
  2859. dzdyr,
  2860. zr;
  2861. USHORT r_base, g_base, b_base,
  2862.        r_textel, g_textel, b_textel, textel;
  2863. int x0,y0,tu0,tv0,tz0,    // cached vertices
  2864. x1,y1,tu1,tv1,tz1,
  2865. x2,y2,tu2,tv2,tz2;
  2866. USHORT *screen_ptr  = NULL,
  2867.    *screen_line = NULL,
  2868.    *textmap     = NULL,
  2869.        *dest_buffer = (USHORT *)_dest_buffer;
  2870. UINT  *z_ptr = NULL,
  2871.       *zbuffer = (UINT *)_zbuffer;
  2872. #ifdef DEBUG_ON
  2873. // track rendering stats
  2874.     debug_polys_rendered_per_frame++;
  2875. #endif
  2876. // extract texture map
  2877. textmap = (USHORT *)face->texture->buffer;
  2878. // extract base 2 of texture width
  2879. int texture_shift2 = logbase2ofx[face->texture->width];
  2880. // adjust memory pitch to words, divide by 2
  2881. mem_pitch >>=1;
  2882. // adjust zbuffer pitch for 32 bit alignment
  2883. zpitch >>= 2;
  2884. // apply fill convention to coordinates
  2885. face->tvlist[0].x = (int)(face->tvlist[0].x+0.5);
  2886. face->tvlist[0].y = (int)(face->tvlist[0].y+0.5);
  2887. face->tvlist[1].x = (int)(face->tvlist[1].x+0.5);
  2888. face->tvlist[1].y = (int)(face->tvlist[1].y+0.5);
  2889. face->tvlist[2].x = (int)(face->tvlist[2].x+0.5);
  2890. face->tvlist[2].y = (int)(face->tvlist[2].y+0.5);
  2891. // first trivial clipping rejection tests 
  2892. if (((face->tvlist[0].y < min_clip_y)  && 
  2893.  (face->tvlist[1].y < min_clip_y)  &&
  2894.  (face->tvlist[2].y < min_clip_y)) ||
  2895. ((face->tvlist[0].y > max_clip_y)  && 
  2896.  (face->tvlist[1].y > max_clip_y)  &&
  2897.  (face->tvlist[2].y > max_clip_y)) ||
  2898. ((face->tvlist[0].x < min_clip_x)  && 
  2899.  (face->tvlist[1].x < min_clip_x)  &&
  2900.  (face->tvlist[2].x < min_clip_x)) ||
  2901. ((face->tvlist[0].x > max_clip_x)  && 
  2902.  (face->tvlist[1].x > max_clip_x)  &&
  2903.  (face->tvlist[2].x > max_clip_x)))
  2904.    return;
  2905. // sort vertices
  2906. if (face->tvlist[v1].y < face->tvlist[v0].y) 
  2907. {SWAP(v0,v1,temp);} 
  2908. if (face->tvlist[v2].y < face->tvlist[v0].y) 
  2909. {SWAP(v0,v2,temp);}
  2910. if (face->tvlist[v2].y < face->tvlist[v1].y) 
  2911. {SWAP(v1,v2,temp);}
  2912. // now test for trivial flat sided cases
  2913. if (FCMP(face->tvlist[v0].y, face->tvlist[v1].y) )
  2914. // set triangle type
  2915. tri_type = TRI_TYPE_FLAT_TOP;
  2916. // sort vertices left to right
  2917. if (face->tvlist[v1].x < face->tvlist[v0].x) 
  2918. {SWAP(v0,v1,temp);}
  2919. } // end if
  2920. else
  2921. // now test for trivial flat sided cases
  2922. if (FCMP( face->tvlist[v1].y, face->tvlist[v2].y) )
  2923. // set triangle type
  2924. tri_type = TRI_TYPE_FLAT_BOTTOM;
  2925. // sort vertices left to right
  2926. if (face->tvlist[v2].x < face->tvlist[v1].x) 
  2927. {SWAP(v1,v2,temp);}
  2928. } // end if
  2929. else
  2930. {
  2931. // must be a general triangle
  2932. tri_type = TRI_TYPE_GENERAL;
  2933. } // end else
  2934. // extract base color of lit poly, so we can modulate texture a bit
  2935. // for lighting
  2936. _RGB565FROM16BIT(face->lit_color[0], &r_base, &g_base, &b_base);
  2937. // extract vertices for processing, now that we have order
  2938. x0  = (int)(face->tvlist[v0].x+0.0);
  2939. y0  = (int)(face->tvlist[v0].y+0.0);
  2940. tu0 = (int)(face->tvlist[v0].u0);
  2941. tv0 = (int)(face->tvlist[v0].v0);
  2942. tz0 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v0].z+0.5);
  2943. x1  = (int)(face->tvlist[v1].x+0.0);
  2944. y1  = (int)(face->tvlist[v1].y+0.0);
  2945. tu1 = (int)(face->tvlist[v1].u0);
  2946. tv1 = (int)(face->tvlist[v1].v0);
  2947. tz1 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v1].z+0.5);
  2948. x2  = (int)(face->tvlist[v2].x+0.0);
  2949. y2  = (int)(face->tvlist[v2].y+0.0);
  2950. tu2 = (int)(face->tvlist[v2].u0);
  2951. tv2 = (int)(face->tvlist[v2].v0);
  2952. tz2 = (1 << FIXP28_SHIFT) / (int)(face->tvlist[v2].z+0.5);
  2953. // degenerate triangle
  2954. if ( ((x0 == x1) && (x1 == x2)) || ((y0 ==  y1) && (y1 == y2)))
  2955.    return;
  2956. // assign both source1 and source2 alpha tables based on polygon alpha level
  2957. USHORT *alpha_table_src1 = (USHORT *)&rgb_alpha_table[(NUM_ALPHA_LEVELS-1) - alpha][0];
  2958. USHORT *alpha_table_src2 = (USHORT *)&rgb_alpha_table[alpha][0];
  2959. // set interpolation restart value
  2960. yrestart = y1;
  2961. // what kind of triangle
  2962. if (tri_type & TRI_TYPE_FLAT_MASK)
  2963. {
  2964. if (tri_type == TRI_TYPE_FLAT_TOP)
  2965. {
  2966. // compute all deltas
  2967. dy = (y2 - y0);
  2968. dxdyl = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  2969. dudyl = ((tu2 - tu0) << FIXP16_SHIFT)/dy;  
  2970. dvdyl = ((tv2 - tv0) << FIXP16_SHIFT)/dy;    
  2971. dzdyl = ((tz2 - tz0) << 0)/dy;    
  2972. dxdyr = ((x2 - x1)   << FIXP16_SHIFT)/dy;
  2973. dudyr = ((tu2 - tu1) << FIXP16_SHIFT)/dy;  
  2974. dvdyr = ((tv2 - tv1) << FIXP16_SHIFT)/dy;   
  2975. dzdyr = ((tz2 - tz1) << 0)/dy;   
  2976. // test for y clipping
  2977. if (y0 < min_clip_y)
  2978. {
  2979. // compute overclip
  2980. dy = (min_clip_y - y0);
  2981. // computer new LHS starting values
  2982. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  2983. ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
  2984. vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
  2985. zl = dzdyl*dy + (tz0 << 0);
  2986. // compute new RHS starting values
  2987. xr = dxdyr*dy + (x1  << FIXP16_SHIFT);
  2988. ur = dudyr*dy + (tu1 << FIXP16_SHIFT);
  2989. vr = dvdyr*dy + (tv1 << FIXP16_SHIFT);
  2990. zr = dzdyr*dy + (tz1 << 0);
  2991. // compute new starting y
  2992. ystart = min_clip_y;
  2993. } // end if
  2994. else
  2995. {
  2996. // no clipping
  2997. // set starting values
  2998. xl = (x0 << FIXP16_SHIFT);
  2999. xr = (x1 << FIXP16_SHIFT);
  3000. ul = (tu0 << FIXP16_SHIFT);
  3001. vl = (tv0 << FIXP16_SHIFT);
  3002. zl = (tz0 << 0);
  3003. ur = (tu1 << FIXP16_SHIFT);
  3004. vr = (tv1 << FIXP16_SHIFT);
  3005. zr = (tz1 << 0);
  3006. // set starting y
  3007. ystart = y0;
  3008. } // end else
  3009. } // end if flat top
  3010. else
  3011. {
  3012. // must be flat bottom
  3013. // compute all deltas
  3014. dy = (y1 - y0);
  3015. dxdyl = ((x1 - x0)   << FIXP16_SHIFT)/dy;
  3016. dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dy;  
  3017. dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dy;    
  3018. dzdyl = ((tz1 - tz0) << 0)/dy; 
  3019. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dy;
  3020. dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dy;  
  3021. dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dy;   
  3022. dzdyr = ((tz2 - tz0) << 0)/dy;   
  3023. // test for y clipping
  3024. if (y0 < min_clip_y)
  3025. {
  3026. // compute overclip
  3027. dy = (min_clip_y - y0);
  3028. // computer new LHS starting values
  3029. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  3030. ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
  3031. vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
  3032. zl = dzdyl*dy + (tz0 << 0);
  3033. // compute new RHS starting values
  3034. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  3035. ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
  3036. vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
  3037. zr = dzdyr*dy + (tz0 << 0);
  3038. // compute new starting y
  3039. ystart = min_clip_y;
  3040. } // end if
  3041. else
  3042. {
  3043. // no clipping
  3044. // set starting values
  3045. xl = (x0 << FIXP16_SHIFT);
  3046. xr = (x0 << FIXP16_SHIFT);
  3047. ul = (tu0 << FIXP16_SHIFT);
  3048. vl = (tv0 << FIXP16_SHIFT);
  3049. zl = (tz0 << 0);
  3050. ur = (tu0 << FIXP16_SHIFT);
  3051. vr = (tv0 << FIXP16_SHIFT);
  3052. zr = (tz0 << 0);
  3053. // set starting y
  3054. ystart = y0;
  3055. } // end else
  3056. } // end else flat bottom
  3057. // test for bottom clip, always
  3058. if ((yend = y2) > max_clip_y)
  3059. yend = max_clip_y;
  3060.     // test for horizontal clipping
  3061. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  3062. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  3063. (x2 < min_clip_x) || (x2 > max_clip_x))
  3064. {
  3065.     // clip version
  3066. // point screen ptr to starting line
  3067. screen_ptr = dest_buffer + (ystart * mem_pitch);
  3068.     // point zbuffer to starting line
  3069.     z_ptr = zbuffer + (ystart * zpitch);
  3070. for (yi = ystart; yi < yend; yi++)
  3071. {
  3072. // compute span endpoints
  3073. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3074. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3075. // compute starting points for u,v interpolants
  3076. ui = ul + FIXP16_ROUND_UP;
  3077. vi = vl + FIXP16_ROUND_UP;
  3078. zi = zl; //  + FIXP16_ROUND_UP; // ???
  3079. // compute u,v interpolants
  3080. if ((dx = (xend - xstart))>0)
  3081. {
  3082. du = (ur - ul)/dx;
  3083. dv = (vr - vl)/dx;
  3084. dz = (zr - zl)/dx;
  3085. } // end if
  3086. else
  3087. {
  3088. du = (ur - ul);
  3089. dv = (vr - vl);
  3090. dz = (zr - zl);
  3091. } // end else
  3092. ///////////////////////////////////////////////////////////////////////
  3093. // test for x clipping, LHS
  3094. if (xstart < min_clip_x)
  3095. {
  3096. // compute x overlap
  3097. dx = min_clip_x - xstart;
  3098. // slide interpolants over
  3099. ui+=dx*du;
  3100. vi+=dx*dv;
  3101. zi+=dx*dz;
  3102. // reset vars
  3103. xstart = min_clip_x;
  3104. } // end if
  3105. // test for x clipping RHS
  3106. if (xend > max_clip_x)
  3107. xend = max_clip_x;
  3108. ///////////////////////////////////////////////////////////////////////
  3109. // draw span
  3110. for (xi=xstart; xi < xend; xi++)
  3111. {
  3112.             // test if z of current pixel is nearer than current z buffer value
  3113.             if (zi > z_ptr[xi])
  3114.                {
  3115.    // write textel
  3116.        // get textel first
  3117.      textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
  3118.                // extract rgb components
  3119.                r_textel  = ((textel >> 11)       ); 
  3120.                g_textel  = ((textel >> 5)  & 0x3f); 
  3121.                b_textel =   (textel        & 0x1f);
  3122.                // modulate textel with lit background color
  3123.                r_textel*=r_base; 
  3124.                g_textel*=g_base;
  3125.                b_textel*=b_base;
  3126.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  3127.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  3128.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  3129.                // and they all cancel out for the most part, but we will need logical anding, we will do
  3130.                // it later when we optimize more...
  3131.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  3132.                              alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  3133.                // update z-buffer
  3134.                z_ptr[xi] = zi;           
  3135.                } // end if
  3136. // interpolate u,v,z
  3137. ui+=du;
  3138. vi+=dv;
  3139. zi+=dz;
  3140. } // end for xi
  3141. // interpolate u,v,x along right and left edge
  3142. xl+=dxdyl;
  3143. ul+=dudyl;
  3144. vl+=dvdyl;
  3145. zl+=dzdyl;
  3146. xr+=dxdyr;
  3147. ur+=dudyr;
  3148. vr+=dvdyr;
  3149. zr+=dzdyr;
  3150.  
  3151. // advance screen ptr
  3152. screen_ptr+=mem_pitch;
  3153.         // advance zbuffer ptr
  3154.         z_ptr+=zpitch;
  3155. } // end for y
  3156. } // end if clip
  3157. else
  3158. {
  3159. // non-clip version
  3160. // point screen ptr to starting line
  3161. screen_ptr = dest_buffer + (ystart * mem_pitch);
  3162.     // point zbuffer to starting line
  3163.     z_ptr = zbuffer + (ystart * zpitch);
  3164. for (yi = ystart; yi < yend; yi++)
  3165. {
  3166. // compute span endpoints
  3167. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3168. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3169. // compute starting points for u,v interpolants
  3170. ui = ul + FIXP16_ROUND_UP;
  3171. vi = vl + FIXP16_ROUND_UP;
  3172. zi = zl; //  + FIXP16_ROUND_UP; // ???
  3173. // compute u,v interpolants
  3174. if ((dx = (xend - xstart))>0)
  3175. {
  3176. du = (ur - ul)/dx;
  3177. dv = (vr - vl)/dx;
  3178. dz = (zr - zl)/dx;
  3179. } // end if
  3180. else
  3181. {
  3182. du = (ur - ul);
  3183. dv = (vr - vl);
  3184.             dz = (zr - zl);
  3185. } // end else
  3186. // draw span
  3187. for (xi=xstart; xi < xend; xi++)
  3188. {
  3189.             // test if z of current pixel is nearer than current z buffer value
  3190.             if (zi > z_ptr[xi])
  3191.                {
  3192.    // write textel
  3193.        // get textel first
  3194.      textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
  3195.                // extract rgb components
  3196.                r_textel  = ((textel >> 11)       ); 
  3197.                g_textel  = ((textel >> 5)  & 0x3f); 
  3198.                b_textel =   (textel        & 0x1f);
  3199.                // modulate textel with lit background color
  3200.                r_textel*=r_base; 
  3201.                g_textel*=g_base;
  3202.                b_textel*=b_base;
  3203.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  3204.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  3205.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  3206.                // and they all cancel out for the most part, but we will need logical anding, we will do
  3207.                // it later when we optimize more...
  3208.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  3209.                              alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  3210.                // update z-buffer
  3211.                z_ptr[xi] = zi;           
  3212.                } // end if
  3213. // interpolate u,v,z
  3214. ui+=du;
  3215. vi+=dv;
  3216.             zi+=dz;
  3217. } // end for xi
  3218. // interpolate u,v,x along right and left edge
  3219. xl+=dxdyl;
  3220. ul+=dudyl;
  3221. vl+=dvdyl;
  3222.     zl+=dzdyl;
  3223. xr+=dxdyr;
  3224. ur+=dudyr;
  3225. vr+=dvdyr;
  3226.         zr+=dzdyr;
  3227. // advance screen ptr
  3228. screen_ptr+=mem_pitch;
  3229.         // advance zbuffer ptr
  3230.         z_ptr+=zpitch;
  3231. } // end for y
  3232. } // end if non-clipped
  3233. } // end if
  3234. else
  3235. if (tri_type==TRI_TYPE_GENERAL)
  3236. {
  3237. // first test for bottom clip, always
  3238. if ((yend = y2) > max_clip_y)
  3239. yend = max_clip_y;
  3240. // pre-test y clipping status
  3241. if (y1 < min_clip_y)
  3242. {
  3243. // compute all deltas
  3244. // LHS
  3245. dyl = (y2 - y1);
  3246. dxdyl = ((x2  - x1)  << FIXP16_SHIFT)/dyl;
  3247. dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;  
  3248. dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;    
  3249.         dzdyl = ((tz2 - tz1) << 0)/dyl;    
  3250. // RHS
  3251. dyr = (y2 - y0);
  3252. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  3253. dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;  
  3254. dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;   
  3255.         dzdyr = ((tz2 - tz0) << 0)/dyr;   
  3256. // compute overclip
  3257. dyr = (min_clip_y - y0);
  3258. dyl = (min_clip_y - y1);
  3259. // computer new LHS starting values
  3260. xl = dxdyl*dyl + (x1  << FIXP16_SHIFT);
  3261. ul = dudyl*dyl + (tu1 << FIXP16_SHIFT);
  3262. vl = dvdyl*dyl + (tv1 << FIXP16_SHIFT);
  3263.         zl = dzdyl*dyl + (tz1 << 0);
  3264. // compute new RHS starting values
  3265. xr = dxdyr*dyr + (x0  << FIXP16_SHIFT);
  3266. ur = dudyr*dyr + (tu0 << FIXP16_SHIFT);
  3267. vr = dvdyr*dyr + (tv0 << FIXP16_SHIFT);
  3268.         zr = dzdyr*dyr + (tz0 << 0);
  3269. // compute new starting y
  3270. ystart = min_clip_y;
  3271. // test if we need swap to keep rendering left to right
  3272. if (dxdyr > dxdyl)
  3273. {
  3274. SWAP(dxdyl,dxdyr,temp);
  3275. SWAP(dudyl,dudyr,temp);
  3276. SWAP(dvdyl,dvdyr,temp);
  3277. SWAP(dzdyl,dzdyr,temp);
  3278. SWAP(xl,xr,temp);
  3279. SWAP(ul,ur,temp);
  3280. SWAP(vl,vr,temp);
  3281. SWAP(zl,zr,temp);
  3282. SWAP(x1,x2,temp);
  3283. SWAP(y1,y2,temp);
  3284. SWAP(tu1,tu2,temp);
  3285. SWAP(tv1,tv2,temp);
  3286. SWAP(tz1,tz2,temp);
  3287. // set interpolation restart
  3288. irestart = INTERP_RHS;
  3289. } // end if
  3290. } // end if
  3291. else
  3292. if (y0 < min_clip_y)
  3293. {
  3294. // compute all deltas
  3295. // LHS
  3296. dyl = (y1 - y0);
  3297. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  3298. dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;  
  3299. dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;    
  3300.         dzdyl = ((tz1 - tz0) << 0)/dyl;    
  3301. // RHS
  3302. dyr = (y2 - y0);
  3303. dxdyr = ((x2  - x0)  << FIXP16_SHIFT)/dyr;
  3304. dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;  
  3305. dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;   
  3306.         dzdyr = ((tz2 - tz0) << 0)/dyr;   
  3307. // compute overclip
  3308. dy = (min_clip_y - y0);
  3309. // computer new LHS starting values
  3310. xl = dxdyl*dy + (x0  << FIXP16_SHIFT);
  3311. ul = dudyl*dy + (tu0 << FIXP16_SHIFT);
  3312. vl = dvdyl*dy + (tv0 << FIXP16_SHIFT);
  3313.         zl = dzdyl*dy + (tz0 << 0);
  3314. // compute new RHS starting values
  3315. xr = dxdyr*dy + (x0  << FIXP16_SHIFT);
  3316. ur = dudyr*dy + (tu0 << FIXP16_SHIFT);
  3317. vr = dvdyr*dy + (tv0 << FIXP16_SHIFT);
  3318.         zr = dzdyr*dy + (tz0 << 0);
  3319. // compute new starting y
  3320. ystart = min_clip_y;
  3321. // test if we need swap to keep rendering left to right
  3322. if (dxdyr < dxdyl)
  3323. {
  3324. SWAP(dxdyl,dxdyr,temp);
  3325. SWAP(dudyl,dudyr,temp);
  3326. SWAP(dvdyl,dvdyr,temp);
  3327. SWAP(dzdyl,dzdyr,temp);
  3328. SWAP(xl,xr,temp);
  3329. SWAP(ul,ur,temp);
  3330. SWAP(vl,vr,temp);
  3331. SWAP(zl,zr,temp);
  3332. SWAP(x1,x2,temp);
  3333. SWAP(y1,y2,temp);
  3334. SWAP(tu1,tu2,temp);
  3335. SWAP(tv1,tv2,temp);
  3336. SWAP(tz1,tz2,temp);
  3337. // set interpolation restart
  3338. irestart = INTERP_RHS;
  3339. } // end if
  3340. } // end if
  3341. else
  3342. {
  3343. // no initial y clipping
  3344. // compute all deltas
  3345. // LHS
  3346. dyl = (y1 - y0);
  3347. dxdyl = ((x1  - x0)  << FIXP16_SHIFT)/dyl;
  3348. dudyl = ((tu1 - tu0) << FIXP16_SHIFT)/dyl;  
  3349. dvdyl = ((tv1 - tv0) << FIXP16_SHIFT)/dyl;    
  3350.         dzdyl = ((tz1 - tz0) << 0)/dyl;    
  3351. // RHS
  3352. dyr = (y2 - y0);
  3353. dxdyr = ((x2 - x0)   << FIXP16_SHIFT)/dyr;
  3354. dudyr = ((tu2 - tu0) << FIXP16_SHIFT)/dyr;  
  3355. dvdyr = ((tv2 - tv0) << FIXP16_SHIFT)/dyr;   
  3356.         dzdyr = ((tz2 - tz0) << 0)/dyr;   
  3357. // no clipping y
  3358. // set starting values
  3359. xl = (x0 << FIXP16_SHIFT);
  3360. xr = (x0 << FIXP16_SHIFT);
  3361. ul = (tu0 << FIXP16_SHIFT);
  3362. vl = (tv0 << FIXP16_SHIFT);
  3363.         zl = (tz0 << 0);
  3364. ur = (tu0 << FIXP16_SHIFT);
  3365. vr = (tv0 << FIXP16_SHIFT);
  3366.         zr = (tz0 << 0);
  3367. // set starting y
  3368. ystart = y0;
  3369. // test if we need swap to keep rendering left to right
  3370. if (dxdyr < dxdyl)
  3371. {
  3372. SWAP(dxdyl,dxdyr,temp);
  3373. SWAP(dudyl,dudyr,temp);
  3374. SWAP(dvdyl,dvdyr,temp);
  3375. SWAP(dzdyl,dzdyr,temp);
  3376. SWAP(xl,xr,temp);
  3377. SWAP(ul,ur,temp);
  3378. SWAP(vl,vr,temp);
  3379. SWAP(zl,zr,temp);
  3380. SWAP(x1,x2,temp);
  3381. SWAP(y1,y2,temp);
  3382. SWAP(tu1,tu2,temp);
  3383. SWAP(tv1,tv2,temp);
  3384. SWAP(tz1,tz2,temp);
  3385. // set interpolation restart
  3386. irestart = INTERP_RHS;
  3387. } // end if
  3388. } // end else
  3389.     // test for horizontal clipping
  3390. if ((x0 < min_clip_x) || (x0 > max_clip_x) ||
  3391. (x1 < min_clip_x) || (x1 > max_clip_x) ||
  3392. (x2 < min_clip_x) || (x2 > max_clip_x))
  3393. {
  3394.     // clip version
  3395. // x clipping
  3396. // point screen ptr to starting line
  3397. screen_ptr = dest_buffer + (ystart * mem_pitch);
  3398.     // point zbuffer to starting line
  3399.     z_ptr = zbuffer + (ystart * zpitch);
  3400. for (yi = ystart; yi < yend; yi++)
  3401. {
  3402. // compute span endpoints
  3403. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3404. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3405. // compute starting points for u,v interpolants
  3406. ui = ul + FIXP16_ROUND_UP;
  3407. vi = vl + FIXP16_ROUND_UP;
  3408.         zi = zl;// + FIXP16_ROUND_UP; // ???
  3409. // compute u,v interpolants
  3410. if ((dx = (xend - xstart))>0)
  3411. {
  3412. du = (ur - ul)/dx;
  3413. dv = (vr - vl)/dx;
  3414.             dz = (zr - zl)/dx;
  3415. } // end if
  3416. else
  3417. {
  3418. du = (ur - ul);
  3419. dv = (vr - vl);
  3420.             dz = (zr - zl);
  3421. } // end else
  3422. ///////////////////////////////////////////////////////////////////////
  3423. // test for x clipping, LHS
  3424. if (xstart < min_clip_x)
  3425. {
  3426. // compute x overlap
  3427. dx = min_clip_x - xstart;
  3428. // slide interpolants over
  3429. ui+=dx*du;
  3430. vi+=dx*dv;
  3431. zi+=dx*dz;
  3432. // set x to left clip edge
  3433. xstart = min_clip_x;
  3434. } // end if
  3435. // test for x clipping RHS
  3436. if (xend > max_clip_x)
  3437. xend = max_clip_x;
  3438. ///////////////////////////////////////////////////////////////////////
  3439. // draw span
  3440. for (xi=xstart; xi < xend; xi++)
  3441. {
  3442.             // test if z of current pixel is nearer than current z buffer value
  3443.             if (zi > z_ptr[xi])
  3444.                {
  3445.    // write textel
  3446.        // get textel first
  3447.      textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
  3448.                // extract rgb components
  3449.                r_textel  = ((textel >> 11)       ); 
  3450.                g_textel  = ((textel >> 5)  & 0x3f); 
  3451.                b_textel =   (textel        & 0x1f);
  3452.                // modulate textel with lit background color
  3453.                r_textel*=r_base; 
  3454.                g_textel*=g_base;
  3455.                b_textel*=b_base;
  3456.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  3457.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  3458.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  3459.                // and they all cancel out for the most part, but we will need logical anding, we will do
  3460.                // it later when we optimize more...
  3461.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  3462.                              alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  3463.                // update z-buffer
  3464.                z_ptr[xi] = zi;           
  3465.                } // end if
  3466. // interpolate u,v
  3467. ui+=du;
  3468. vi+=dv;
  3469.             zi+=dz;
  3470. } // end for xi
  3471. // interpolate u,v,x along right and left edge
  3472. xl+=dxdyl;
  3473. ul+=dudyl;
  3474. vl+=dvdyl;
  3475. zl+=dzdyl;
  3476. xr+=dxdyr;
  3477. ur+=dudyr;
  3478. vr+=dvdyr;
  3479. zr+=dzdyr;
  3480. // advance screen ptr
  3481. screen_ptr+=mem_pitch;
  3482.         // advance zbuffer ptr
  3483.         z_ptr+=zpitch;
  3484. // test for yi hitting second region, if so change interpolant
  3485. if (yi==yrestart)
  3486. {
  3487.       // test interpolation side change flag
  3488. if (irestart == INTERP_LHS)
  3489. {
  3490. // LHS
  3491. dyl = (y2 - y1);
  3492. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  3493. dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;  
  3494. dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;   
  3495. dzdyl = ((tz2 - tz1) << 0)/dyl;  
  3496. // set starting values
  3497. xl = (x1  << FIXP16_SHIFT);
  3498. ul = (tu1 << FIXP16_SHIFT);
  3499. vl = (tv1 << FIXP16_SHIFT);
  3500. zl = (tz1 << 0);
  3501. // interpolate down on LHS to even up
  3502. xl+=dxdyl;
  3503. ul+=dudyl;
  3504. vl+=dvdyl;
  3505. zl+=dzdyl;
  3506. } // end if
  3507. else
  3508. {
  3509. // RHS
  3510. dyr = (y1 - y2);
  3511. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  3512. dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;  
  3513. dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;   
  3514. dzdyr = ((tz1 - tz2) << 0)/dyr;   
  3515. // set starting values
  3516. xr = (x2  << FIXP16_SHIFT);
  3517. ur = (tu2 << FIXP16_SHIFT);
  3518. vr = (tv2 << FIXP16_SHIFT);
  3519. zr = (tz2 << 0);
  3520. // interpolate down on RHS to even up
  3521. xr+=dxdyr;
  3522. ur+=dudyr;
  3523. vr+=dvdyr;
  3524. zr+=dzdyr;
  3525. } // end else
  3526. } // end if
  3527. } // end for y
  3528. } // end if
  3529. else
  3530. {
  3531. // no x clipping
  3532. // point screen ptr to starting line
  3533. screen_ptr = dest_buffer + (ystart * mem_pitch);
  3534.     // point zbuffer to starting line
  3535.     z_ptr = zbuffer + (ystart * zpitch);
  3536. for (yi = ystart; yi < yend; yi++)
  3537. {
  3538. // compute span endpoints
  3539. xstart = ((xl + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3540. xend   = ((xr + FIXP16_ROUND_UP) >> FIXP16_SHIFT);
  3541. // compute starting points for u,v,z interpolants
  3542. ui = ul + FIXP16_ROUND_UP;
  3543. vi = vl + FIXP16_ROUND_UP;
  3544. zi = zl; //  + FIXP16_ROUND_UP; // ???
  3545. // compute u,v interpolants
  3546. if ((dx = (xend - xstart))>0)
  3547. {
  3548. du = (ur - ul)/dx;
  3549. dv = (vr - vl)/dx;
  3550.             dz = (zr - zl)/dx;
  3551. } // end if
  3552. else
  3553. {
  3554. du = (ur - ul);
  3555. dv = (vr - vl);
  3556.             dz = (zr - zl);
  3557. } // end else
  3558. // draw span
  3559. for (xi=xstart; xi < xend; xi++)
  3560. {
  3561.             // test if z of current pixel is nearer than current z buffer value
  3562.             if (zi > z_ptr[xi])
  3563.                {
  3564.    // write textel
  3565.        // get textel first
  3566.      textel = textmap[(ui >> FIXP16_SHIFT) + ((vi >> FIXP16_SHIFT) << texture_shift2)];
  3567.                // extract rgb components
  3568.                r_textel  = ((textel >> 11)       ); 
  3569.                g_textel  = ((textel >> 5)  & 0x3f); 
  3570.                b_textel =   (textel        & 0x1f);
  3571.                // modulate textel with lit background color
  3572.                r_textel*=r_base; 
  3573.                g_textel*=g_base;
  3574.                b_textel*=b_base;
  3575.                // finally write pixel, note that we did the math such that the results are r*32, g*64, b*32
  3576.                // hence we need to divide the results by 32,64,32 respetively, BUT since we need to shift
  3577.                // the results to fit into the destination 5.6.5 word, we can take advantage of the shifts
  3578.                // and they all cancel out for the most part, but we will need logical anding, we will do
  3579.                // it later when we optimize more...
  3580.               screen_ptr[xi] = alpha_table_src1[screen_ptr[xi]] + 
  3581.                              alpha_table_src2[((b_textel >> 5) + ((g_textel >> 6) << 5) + ((r_textel >> 5) << 11))];
  3582.                // update z-buffer
  3583.                z_ptr[xi] = zi;           
  3584.                } // end if
  3585. // interpolate u,v,z
  3586. ui+=du;
  3587. vi+=dv;
  3588.             zi+=dz;
  3589. } // end for xi
  3590. // interpolate u,v,x along right and left edge
  3591. xl+=dxdyl;
  3592. ul+=dudyl;
  3593. vl+=dvdyl;
  3594.         zl+=dzdyl;
  3595. xr+=dxdyr;
  3596. ur+=dudyr;
  3597. vr+=dvdyr;
  3598.         zr+=dzdyr;
  3599. // advance screen ptr
  3600. screen_ptr+=mem_pitch;
  3601.         // advance zbuffer ptr
  3602.         z_ptr+=zpitch;
  3603. // test for yi hitting second region, if so change interpolant
  3604. if (yi==yrestart)
  3605. {
  3606. // test interpolation side change flag
  3607. if (irestart == INTERP_LHS)
  3608. {
  3609. // LHS
  3610. dyl = (y2 - y1);
  3611. dxdyl = ((x2 - x1)   << FIXP16_SHIFT)/dyl;
  3612. dudyl = ((tu2 - tu1) << FIXP16_SHIFT)/dyl;  
  3613. dvdyl = ((tv2 - tv1) << FIXP16_SHIFT)/dyl;   
  3614. dzdyl = ((tz2 - tz1) << 0)/dyl; 
  3615. // set starting values
  3616. xl = (x1  << FIXP16_SHIFT);
  3617. ul = (tu1 << FIXP16_SHIFT);
  3618. vl = (tv1 << FIXP16_SHIFT);
  3619. zl = (tz1 << 0);
  3620. // interpolate down on LHS to even up
  3621. xl+=dxdyl;
  3622. ul+=dudyl;
  3623. vl+=dvdyl;
  3624. zl+=dzdyl;
  3625. } // end if
  3626. else
  3627. {
  3628. // RHS
  3629. dyr = (y1 - y2);
  3630. dxdyr = ((x1 - x2)   << FIXP16_SHIFT)/dyr;
  3631. dudyr = ((tu1 - tu2) << FIXP16_SHIFT)/dyr;  
  3632. dvdyr = ((tv1 - tv2) << FIXP16_SHIFT)/dyr;   
  3633. dzdyr = ((tz1 - tz2) << 0)/dyr;   
  3634. // set starting values
  3635. xr = (x2  << FIXP16_SHIFT);
  3636. ur = (tu2 << FIXP16_SHIFT);
  3637. vr = (tv2 << FIXP16_SHIFT);
  3638. zr = (tz2 << 0);
  3639. // interpolate down on RHS to even up
  3640. xr+=dxdyr;
  3641. ur+=dudyr;
  3642. vr+=dvdyr;
  3643. zr+=dzdyr;
  3644. } // end else
  3645. } // end if
  3646. } // end for y
  3647.    } // end else
  3648. } // end if
  3649. } // end Draw_Textured_TriangleFSINVZB_Alpha16
  3650. ////////////////////////////////////////////////////////////////////////////////
  3651. void Draw_Textured_TriangleGSINVZB_Alpha16(POLYF4DV2_PTR face,   // ptr to face
  3652.                                       UCHAR *_dest_buffer, // pointer to video buffer
  3653.                                       int mem_pitch,       // bytes per line, 320, 640 etc.
  3654.                                       UCHAR *_zbuffer,       // pointer to z-buffer
  3655.                                       int zpitch,          // bytes per line of zbuffer
  3656.                                       int alpha)
  3657. {
  3658. // this function draws a textured gouraud shaded polygon, and z bufferedbased on the affine texture mapper, 
  3659. // we simply interpolate the (R,G,B) values across the polygons along with the texture coordinates
  3660. // and then modulate to get the final color 
  3661. int v0=0,
  3662.     v1=1,
  3663. v2=2,
  3664. temp=0,
  3665. tri_type = TRI_TYPE_NONE,
  3666. irestart = INTERP_LHS;
  3667. int dx,dy,dyl,dyr,      // general deltas
  3668.     u,v,w,z, s,t,
  3669.     du,dv,dw,dz, ds, dt, 
  3670.     xi,yi,             // the current interpolated x,y
  3671. ui,vi,wi,zi, si, ti,    // the current interpolated u,v
  3672. index_x,index_y,    // looping vars
  3673. x,y,                // hold general x,y
  3674. xstart,
  3675. xend,
  3676. ystart,