r_polyse.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
  1. /*
  2. Copyright (C) 1997-2001 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. // d_polyset.c: routines for drawing sets of polygons sharing the same
  16. // texture (used for Alias models)
  17. #include "r_local.h"
  18. int rand1k[] = {
  19. #include "rand1k.h"
  20. };
  21. #define MASK_1K 0x3FF
  22. int rand1k_index = 0;
  23. // TODO: put in span spilling to shrink list size
  24. // !!! if this is changed, it must be changed in d_polysa.s too !!!
  25. #define DPS_MAXSPANS MAXHEIGHT+1
  26. // 1 extra for spanpackage that marks end
  27. // !!! if this is changed, it must be changed in asm_draw.h too !!!
  28. typedef struct {
  29. void *pdest;
  30. short *pz;
  31. int count;
  32. byte *ptex;
  33. int sfrac, tfrac, light, zi;
  34. } spanpackage_t;
  35. typedef struct {
  36. int isflattop;
  37. int numleftedges;
  38. int *pleftedgevert0;
  39. int *pleftedgevert1;
  40. int *pleftedgevert2;
  41. int numrightedges;
  42. int *prightedgevert0;
  43. int *prightedgevert1;
  44. int *prightedgevert2;
  45. } edgetable;
  46. aliastriangleparms_t aliastriangleparms;
  47. int r_p0[6], r_p1[6], r_p2[6];
  48. byte *d_pcolormap;
  49. int d_aflatcolor;
  50. int d_xdenom;
  51. edgetable *pedgetable;
  52. edgetable edgetables[12] = {
  53. {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2 },
  54. {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL},
  55. {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL},
  56. {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0 },
  57. {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL},
  58. {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL},
  59. {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1 },
  60. {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL},
  61. {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL},
  62. {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL},
  63. {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL},
  64. {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL},
  65. };
  66. // FIXME: some of these can become statics
  67. int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole;
  68. int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy;
  69. int r_zistepx, r_zistepy;
  70. int d_aspancount, d_countextrastep;
  71. spanpackage_t *a_spans;
  72. spanpackage_t *d_pedgespanpackage;
  73. static int ystart;
  74. byte *d_pdest, *d_ptex;
  75. short *d_pz;
  76. int d_sfrac, d_tfrac, d_light, d_zi;
  77. int d_ptexextrastep, d_sfracextrastep;
  78. int d_tfracextrastep, d_lightextrastep, d_pdestextrastep;
  79. int d_lightbasestep, d_pdestbasestep, d_ptexbasestep;
  80. int d_sfracbasestep, d_tfracbasestep;
  81. int d_ziextrastep, d_zibasestep;
  82. int d_pzextrastep, d_pzbasestep;
  83. typedef struct {
  84. int quotient;
  85. int remainder;
  86. } adivtab_t;
  87. static adivtab_t adivtab[32*32] = {
  88. #include "adivtab.h"
  89. };
  90. byte *skintable[MAX_LBM_HEIGHT];
  91. int skinwidth;
  92. byte *skinstart;
  93. void (*d_pdrawspans)(spanpackage_t *pspanpackage);
  94. void R_PolysetDrawSpans8_33 (spanpackage_t *pspanpackage);
  95. void R_PolysetDrawSpans8_66 (spanpackage_t *pspanpackage);
  96. void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage);
  97. void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage);
  98. void R_PolysetCalcGradients (int skinwidth);
  99. void R_DrawNonSubdiv (void);
  100. void R_PolysetSetEdgeTable (void);
  101. void R_RasterizeAliasPolySmooth (void);
  102. void R_PolysetScanLeftEdge(int height);
  103. void R_PolysetScanLeftEdge_C(int height);
  104. // ======================
  105. // PGM
  106. // 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
  107. byte iractive = 0;
  108. byte irtable[256] = { 79, 78, 77, 76, 75, 74, 73, 72, // black/white
  109. 71, 70, 69, 68, 67, 66, 65, 64,
  110. 64, 65, 66, 67, 68, 69, 70, 71, // dark taupe
  111. 72, 73, 74, 75, 76, 77, 78, 79,
  112. 64, 65, 66, 67, 68, 69, 70, 71, // slate grey
  113. 72, 73, 74, 75, 76, 77, 78, 79,
  114. 208, 208, 208, 208, 208, 208, 208, 208, // unused?'
  115. 64, 66, 68, 70, 72, 74, 76, 78, // dark yellow
  116. 64, 65, 66, 67, 68, 69, 70, 71, // dark red
  117. 72, 73, 74, 75, 76, 77, 78, 79,
  118. 64, 65, 66, 67, 68, 69, 70, 71, // grey/tan
  119. 72, 73, 74, 75, 76, 77, 78, 79,
  120. 64, 66, 68, 70, 72, 74, 76, 78, // chocolate
  121. 68, 67, 66, 65, 64, 65, 66, 67, // mauve / teal
  122. 68, 69, 70, 71, 72, 73, 74, 75,
  123. 76, 76, 77, 77, 78, 78, 79, 79,
  124. 64, 65, 66, 67, 68, 69, 70, 71, // more mauve
  125. 72, 73, 74, 75, 76, 77, 78, 79,
  126. 64, 65, 66, 67, 68, 69, 70, 71, // olive
  127. 72, 73, 74, 75, 76, 77, 78, 79,
  128. 64, 65, 66, 67, 68, 69, 70, 71, // maroon
  129. 72, 73, 74, 75, 76, 77, 78, 79,
  130. 64, 65, 66, 67, 68, 69, 70, 71, // sky blue
  131. 72, 73, 74, 75, 76, 77, 78, 79,
  132. 64, 65, 66, 67, 68, 69, 70, 71, // olive again
  133. 72, 73, 74, 75, 76, 77, 78, 79,
  134. 64, 65, 66, 67, 68, 69, 70, 71, // nuclear green
  135. 64, 65, 66, 67, 68, 69, 70, 71, // bright yellow
  136. 64, 65, 66, 67, 68, 69, 70, 71, // fire colors
  137. 72, 73, 74, 75, 76, 77, 78, 79,
  138. 208, 208, 64, 64, 70, 71, 72, 64, // mishmash1
  139. 66, 68, 70, 64, 65, 66, 67, 68}; // mishmash2
  140. // PGM
  141. // ======================
  142. /*
  143. ================
  144. R_PolysetUpdateTables
  145. ================
  146. */
  147. void R_PolysetUpdateTables (void)
  148. {
  149. int i;
  150. byte *s;
  151. if (r_affinetridesc.skinwidth != skinwidth ||
  152. r_affinetridesc.pskin != skinstart)
  153. {
  154. skinwidth = r_affinetridesc.skinwidth;
  155. skinstart = r_affinetridesc.pskin;
  156. s = skinstart;
  157. for (i=0 ; i<MAX_LBM_HEIGHT ; i++, s+=skinwidth)
  158. skintable[i] = s;
  159. }
  160. }
  161. /*
  162. ================
  163. R_DrawTriangle
  164. ================
  165. */
  166. void R_DrawTriangle( void )
  167. {
  168. spanpackage_t spans[DPS_MAXSPANS];
  169. int dv1_ab, dv0_ac;
  170. int dv0_ab, dv1_ac;
  171. /*
  172. d_xdenom = ( aliastriangleparms.a->v[1] - aliastriangleparms.b->v[1] ) * ( aliastriangleparms.a->v[0] - aliastriangleparms.c->v[0] ) -
  173. ( aliastriangleparms.a->v[0] - aliastriangleparms.b->v[0] ) * ( aliastriangleparms.a->v[1] - aliastriangleparms.c->v[1] );
  174. */
  175. dv0_ab = aliastriangleparms.a->u - aliastriangleparms.b->u;
  176. dv1_ab = aliastriangleparms.a->v - aliastriangleparms.b->v;
  177. if ( !( dv0_ab | dv1_ab ) )
  178. return;
  179. dv0_ac = aliastriangleparms.a->u - aliastriangleparms.c->u;
  180. dv1_ac = aliastriangleparms.a->v - aliastriangleparms.c->v;
  181. if ( !( dv0_ac | dv1_ac ) )
  182. return;
  183. d_xdenom = ( dv0_ac * dv1_ab ) - ( dv0_ab * dv1_ac );
  184. if ( d_xdenom < 0 )
  185. {
  186. a_spans = spans;
  187. r_p0[0] = aliastriangleparms.a->u; // u
  188. r_p0[1] = aliastriangleparms.a->v; // v
  189. r_p0[2] = aliastriangleparms.a->s; // s
  190. r_p0[3] = aliastriangleparms.a->t; // t
  191. r_p0[4] = aliastriangleparms.a->l; // light
  192. r_p0[5] = aliastriangleparms.a->zi; // iz
  193. r_p1[0] = aliastriangleparms.b->u;
  194. r_p1[1] = aliastriangleparms.b->v;
  195. r_p1[2] = aliastriangleparms.b->s;
  196. r_p1[3] = aliastriangleparms.b->t;
  197. r_p1[4] = aliastriangleparms.b->l;
  198. r_p1[5] = aliastriangleparms.b->zi;
  199. r_p2[0] = aliastriangleparms.c->u;
  200. r_p2[1] = aliastriangleparms.c->v;
  201. r_p2[2] = aliastriangleparms.c->s;
  202. r_p2[3] = aliastriangleparms.c->t;
  203. r_p2[4] = aliastriangleparms.c->l;
  204. r_p2[5] = aliastriangleparms.c->zi;
  205. R_PolysetSetEdgeTable ();
  206. R_RasterizeAliasPolySmooth ();
  207. }
  208. }
  209. /*
  210. ===================
  211. R_PolysetScanLeftEdge_C
  212. ====================
  213. */
  214. void R_PolysetScanLeftEdge_C(int height)
  215. {
  216. do
  217. {
  218. d_pedgespanpackage->pdest = d_pdest;
  219. d_pedgespanpackage->pz = d_pz;
  220. d_pedgespanpackage->count = d_aspancount;
  221. d_pedgespanpackage->ptex = d_ptex;
  222. d_pedgespanpackage->sfrac = d_sfrac;
  223. d_pedgespanpackage->tfrac = d_tfrac;
  224. // FIXME: need to clamp l, s, t, at both ends?
  225. d_pedgespanpackage->light = d_light;
  226. d_pedgespanpackage->zi = d_zi;
  227. d_pedgespanpackage++;
  228. errorterm += erroradjustup;
  229. if (errorterm >= 0)
  230. {
  231. d_pdest += d_pdestextrastep;
  232. d_pz += d_pzextrastep;
  233. d_aspancount += d_countextrastep;
  234. d_ptex += d_ptexextrastep;
  235. d_sfrac += d_sfracextrastep;
  236. d_ptex += d_sfrac >> 16;
  237. d_sfrac &= 0xFFFF;
  238. d_tfrac += d_tfracextrastep;
  239. if (d_tfrac & 0x10000)
  240. {
  241. d_ptex += r_affinetridesc.skinwidth;
  242. d_tfrac &= 0xFFFF;
  243. }
  244. d_light += d_lightextrastep;
  245. d_zi += d_ziextrastep;
  246. errorterm -= erroradjustdown;
  247. }
  248. else
  249. {
  250. d_pdest += d_pdestbasestep;
  251. d_pz += d_pzbasestep;
  252. d_aspancount += ubasestep;
  253. d_ptex += d_ptexbasestep;
  254. d_sfrac += d_sfracbasestep;
  255. d_ptex += d_sfrac >> 16;
  256. d_sfrac &= 0xFFFF;
  257. d_tfrac += d_tfracbasestep;
  258. if (d_tfrac & 0x10000)
  259. {
  260. d_ptex += r_affinetridesc.skinwidth;
  261. d_tfrac &= 0xFFFF;
  262. }
  263. d_light += d_lightbasestep;
  264. d_zi += d_zibasestep;
  265. }
  266. } while (--height);
  267. }
  268. /*
  269. ===================
  270. FloorDivMod
  271. Returns mathematically correct (floor-based) quotient and remainder for
  272. numer and denom, both of which should contain no fractional part. The
  273. quotient must fit in 32 bits.
  274. FIXME: GET RID OF THIS! (FloorDivMod)
  275. ====================
  276. */
  277. void FloorDivMod (float numer, float denom, int *quotient,
  278. int *rem)
  279. {
  280. int q, r;
  281. float x;
  282. if (numer >= 0.0)
  283. {
  284. x = floor(numer / denom);
  285. q = (int)x;
  286. r = (int)floor(numer - (x * denom));
  287. }
  288. else
  289. {
  290. //
  291. // perform operations with positive values, and fix mod to make floor-based
  292. //
  293. x = floor(-numer / denom);
  294. q = -(int)x;
  295. r = (int)floor(-numer - (x * denom));
  296. if (r != 0)
  297. {
  298. q--;
  299. r = (int)denom - r;
  300. }
  301. }
  302. *quotient = q;
  303. *rem = r;
  304. }
  305. /*
  306. ===================
  307. R_PolysetSetUpForLineScan
  308. ====================
  309. */
  310. void R_PolysetSetUpForLineScan(fixed8_t startvertu, fixed8_t startvertv,
  311. fixed8_t endvertu, fixed8_t endvertv)
  312. {
  313. float dm, dn;
  314. int tm, tn;
  315. adivtab_t *ptemp;
  316. // TODO: implement x86 version
  317. errorterm = -1;
  318. tm = endvertu - startvertu;
  319. tn = endvertv - startvertv;
  320. if (((tm <= 16) && (tm >= -15)) &&
  321. ((tn <= 16) && (tn >= -15)))
  322. {
  323. ptemp = &adivtab[((tm+15) << 5) + (tn+15)];
  324. ubasestep = ptemp->quotient;
  325. erroradjustup = ptemp->remainder;
  326. erroradjustdown = tn;
  327. }
  328. else
  329. {
  330. dm = tm;
  331. dn = tn;
  332. FloorDivMod (dm, dn, &ubasestep, &erroradjustup);
  333. erroradjustdown = dn;
  334. }
  335. }
  336. /*
  337. ================
  338. R_PolysetCalcGradients
  339. ================
  340. */
  341. #if id386 && !defined __linux__
  342. void R_PolysetCalcGradients( int skinwidth )
  343. {
  344. static float xstepdenominv, ystepdenominv, t0, t1;
  345. static float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
  346. static float one = 1.0F, negative_one = -1.0F;
  347. static unsigned long t0_int, t1_int;
  348. extern unsigned long fpu_sp24_ceil_cw, fpu_ceil_cw, fpu_chop_cw;
  349. /*
  350. p00_minus_p20 = r_p0[0] - r_p2[0];
  351. p01_minus_p21 = r_p0[1] - r_p2[1];
  352. p10_minus_p20 = r_p1[0] - r_p2[0];
  353. p11_minus_p21 = r_p1[1] - r_p2[1];
  354. */
  355. __asm mov eax, dword ptr [r_p0+0]
  356. __asm mov ebx, dword ptr [r_p0+4]
  357. __asm sub eax, dword ptr [r_p2+0]
  358. __asm sub ebx, dword ptr [r_p2+4]
  359. __asm mov p00_minus_p20, eax
  360. __asm mov p01_minus_p21, ebx
  361. __asm fild dword ptr p00_minus_p20
  362. __asm fild dword ptr p01_minus_p21
  363. __asm mov eax, dword ptr [r_p1+0]
  364. __asm mov ebx, dword ptr [r_p1+4]
  365. __asm sub eax, dword ptr [r_p2+0]
  366. __asm sub ebx, dword ptr [r_p2+4]
  367. __asm fstp p01_minus_p21
  368. __asm fstp p00_minus_p20
  369. __asm mov p10_minus_p20, eax
  370. __asm mov p11_minus_p21, ebx
  371. __asm fild dword ptr p10_minus_p20
  372. __asm fild dword ptr p11_minus_p21
  373. __asm fstp p11_minus_p21
  374. __asm fstp p10_minus_p20
  375. /*
  376. xstepdenominv = 1.0 / (float)d_xdenom;
  377. ystepdenominv = -xstepdenominv;
  378. */
  379. /*
  380. ** put FPU in single precision ceil mode
  381. */
  382. __asm fldcw word ptr [fpu_sp24_ceil_cw]
  383. // __asm fldcw word ptr [fpu_ceil_cw]
  384. __asm fild dword ptr d_xdenom ; d_xdenom
  385. __asm fdivr one ; 1 / d_xdenom
  386. __asm fst xstepdenominv ;
  387. __asm fmul negative_one ; -( 1 / d_xdenom )
  388. // ceil () for light so positive steps are exaggerated, negative steps
  389. // diminished, pushing us away from underflow toward overflow. Underflow is
  390. // very visible, overflow is very unlikely, because of ambient lighting
  391. /*
  392. t0 = r_p0[4] - r_p2[4];
  393. t1 = r_p1[4] - r_p2[4];
  394. r_lstepx = (int)
  395. ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
  396. r_lstepy = (int)
  397. ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
  398. */
  399. __asm mov eax, dword ptr [r_p0+16]
  400. __asm mov ebx, dword ptr [r_p1+16]
  401. __asm sub eax, dword ptr [r_p2+16]
  402. __asm sub ebx, dword ptr [r_p2+16]
  403. __asm fstp ystepdenominv ; (empty)
  404. __asm mov t0_int, eax
  405. __asm mov t1_int, ebx
  406. __asm fild t0_int ; t0
  407. __asm fild t1_int ; t1 | t0
  408. __asm fxch st(1) ; t0 | t1
  409. __asm fstp t0 ; t1
  410. __asm fst t1 ; t1
  411. __asm fmul p01_minus_p21 ; t1 * p01_minus_p21
  412. __asm fld t0 ; t0 | t1 * p01_minus_p21
  413. __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21
  414. __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  415. __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  416. __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  417. __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  418. __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
  419. __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  420. __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  421. __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
  422. __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
  423. __asm fxch st(1)
  424. __asm fmul ystepdenominv ; r_lstepy | r_lstepx
  425. __asm fxch st(1) ; r_lstepx | r_lstepy
  426. __asm fistp dword ptr [r_lstepx]
  427. __asm fistp dword ptr [r_lstepy]
  428. /*
  429. ** put FPU back into extended precision chop mode
  430. */
  431. __asm fldcw word ptr [fpu_chop_cw]
  432. /*
  433. t0 = r_p0[2] - r_p2[2];
  434. t1 = r_p1[2] - r_p2[2];
  435. r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  436. xstepdenominv);
  437. r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
  438. ystepdenominv);
  439. */
  440. __asm mov eax, dword ptr [r_p0+8]
  441. __asm mov ebx, dword ptr [r_p1+8]
  442. __asm sub eax, dword ptr [r_p2+8]
  443. __asm sub ebx, dword ptr [r_p2+8]
  444. __asm mov t0_int, eax
  445. __asm mov t1_int, ebx
  446. __asm fild t0_int ; t0
  447. __asm fild t1_int ; t1 | t0
  448. __asm fxch st(1) ; t0 | t1
  449. __asm fstp t0 ; t1
  450. __asm fst t1 ; (empty)
  451. __asm fmul p01_minus_p21 ; t1 * p01_minus_p21
  452. __asm fld t0 ; t0 | t1 * p01_minus_p21
  453. __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21
  454. __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  455. __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  456. __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  457. __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  458. __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
  459. __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  460. __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  461. __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
  462. __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
  463. __asm fxch st(1)
  464. __asm fmul ystepdenominv ; r_lstepy | r_lstepx
  465. __asm fxch st(1) ; r_lstepx | r_lstepy
  466. __asm fistp dword ptr [r_sstepx]
  467. __asm fistp dword ptr [r_sstepy]
  468. /*
  469. t0 = r_p0[3] - r_p2[3];
  470. t1 = r_p1[3] - r_p2[3];
  471. r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  472. xstepdenominv);
  473. r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  474. ystepdenominv);
  475. */
  476. __asm mov eax, dword ptr [r_p0+12]
  477. __asm mov ebx, dword ptr [r_p1+12]
  478. __asm sub eax, dword ptr [r_p2+12]
  479. __asm sub ebx, dword ptr [r_p2+12]
  480. __asm mov t0_int, eax
  481. __asm mov t1_int, ebx
  482. __asm fild t0_int ; t0
  483. __asm fild t1_int ; t1 | t0
  484. __asm fxch st(1) ; t0 | t1
  485. __asm fstp t0 ; t1
  486. __asm fst t1 ; (empty)
  487. __asm fmul p01_minus_p21 ; t1 * p01_minus_p21
  488. __asm fld t0 ; t0 | t1 * p01_minus_p21
  489. __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21
  490. __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  491. __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  492. __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  493. __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  494. __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
  495. __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  496. __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  497. __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
  498. __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
  499. __asm fxch st(1)
  500. __asm fmul ystepdenominv ; r_lstepy | r_lstepx
  501. __asm fxch st(1) ; r_lstepx | r_lstepy
  502. __asm fistp dword ptr [r_tstepx]
  503. __asm fistp dword ptr [r_tstepy]
  504. /*
  505. t0 = r_p0[5] - r_p2[5];
  506. t1 = r_p1[5] - r_p2[5];
  507. r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  508. xstepdenominv);
  509. r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  510. ystepdenominv);
  511. */
  512. __asm mov eax, dword ptr [r_p0+20]
  513. __asm mov ebx, dword ptr [r_p1+20]
  514. __asm sub eax, dword ptr [r_p2+20]
  515. __asm sub ebx, dword ptr [r_p2+20]
  516. __asm mov t0_int, eax
  517. __asm mov t1_int, ebx
  518. __asm fild t0_int ; t0
  519. __asm fild t1_int ; t1 | t0
  520. __asm fxch st(1) ; t0 | t1
  521. __asm fstp t0 ; t1
  522. __asm fst t1 ; (empty)
  523. __asm fmul p01_minus_p21 ; t1 * p01_minus_p21
  524. __asm fld t0 ; t0 | t1 * p01_minus_p21
  525. __asm fmul p11_minus_p21 ; t0 * p11_minus_p21 | t1 * p01_minus_p21
  526. __asm fld t1 ; t1 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  527. __asm fmul p00_minus_p20 ; t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  528. __asm fld t0 ; t0 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  529. __asm fmul p10_minus_p20 ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t0 * p11_minus_p21 | t1 * p01_minus_p21
  530. __asm fxch st(2) ; t0 * p11_minus_p21 | t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21
  531. __asm fsubp st(3), st ; t0 * p10_minus_p20 | t1 * p00_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  532. __asm fsubrp st(1), st ; t1 * p00_minus_p20 - t0 * p10_minus_p20 | t1 * p01_minus_p21 - t0 * p11_minus_p21
  533. __asm fxch st(1) ; t1 * p01_minus_p21 - t0 * p11_minus_p21 | t1 * p00_minus_p20 - t0 * p10_minus_p20
  534. __asm fmul xstepdenominv ; r_lstepx | t1 * p00_minus_p20 - t0 * p10_minus_p20
  535. __asm fxch st(1)
  536. __asm fmul ystepdenominv ; r_lstepy | r_lstepx
  537. __asm fxch st(1) ; r_lstepx | r_lstepy
  538. __asm fistp dword ptr [r_zistepx]
  539. __asm fistp dword ptr [r_zistepy]
  540. /*
  541. #if id386ALIAS
  542. a_sstepxfrac = r_sstepx << 16;
  543. a_tstepxfrac = r_tstepx << 16;
  544. #else
  545. a_sstepxfrac = r_sstepx & 0xFFFF;
  546. a_tstepxfrac = r_tstepx & 0xFFFF;
  547. #endif
  548. */
  549. __asm mov eax, d_pdrawspans
  550. __asm cmp eax, offset R_PolysetDrawSpans8_Opaque
  551. __asm mov eax, r_sstepx
  552. __asm mov ebx, r_tstepx
  553. __asm jne translucent
  554. //#if id386ALIAS
  555. __asm shl eax, 16
  556. __asm shl ebx, 16
  557. __asm jmp done_with_steps
  558. //#else
  559. translucent:
  560. __asm and eax, 0ffffh
  561. __asm and ebx, 0ffffh
  562. //#endif
  563. done_with_steps:
  564. __asm mov a_sstepxfrac, eax
  565. __asm mov a_tstepxfrac, ebx
  566. /*
  567. a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
  568. */
  569. __asm mov ebx, r_tstepx
  570. __asm mov ecx, r_sstepx
  571. __asm sar ebx, 16
  572. __asm mov eax, skinwidth
  573. __asm mul ebx
  574. __asm sar ecx, 16
  575. __asm add eax, ecx
  576. __asm mov a_ststepxwhole, eax
  577. }
  578. #else
  579. void R_PolysetCalcGradients (int skinwidth)
  580. {
  581. float xstepdenominv, ystepdenominv, t0, t1;
  582. float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20;
  583. p00_minus_p20 = r_p0[0] - r_p2[0];
  584. p01_minus_p21 = r_p0[1] - r_p2[1];
  585. p10_minus_p20 = r_p1[0] - r_p2[0];
  586. p11_minus_p21 = r_p1[1] - r_p2[1];
  587. xstepdenominv = 1.0 / (float)d_xdenom;
  588. ystepdenominv = -xstepdenominv;
  589. // ceil () for light so positive steps are exaggerated, negative steps
  590. // diminished, pushing us away from underflow toward overflow. Underflow is
  591. // very visible, overflow is very unlikely, because of ambient lighting
  592. t0 = r_p0[4] - r_p2[4];
  593. t1 = r_p1[4] - r_p2[4];
  594. r_lstepx = (int)
  595. ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv);
  596. r_lstepy = (int)
  597. ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv);
  598. t0 = r_p0[2] - r_p2[2];
  599. t1 = r_p1[2] - r_p2[2];
  600. r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  601. xstepdenominv);
  602. r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) *
  603. ystepdenominv);
  604. t0 = r_p0[3] - r_p2[3];
  605. t1 = r_p1[3] - r_p2[3];
  606. r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  607. xstepdenominv);
  608. r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  609. ystepdenominv);
  610. t0 = r_p0[5] - r_p2[5];
  611. t1 = r_p1[5] - r_p2[5];
  612. r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) *
  613. xstepdenominv);
  614. r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) *
  615. ystepdenominv);
  616. //#if id386ALIAS
  617. #if id386
  618. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  619. {
  620. a_sstepxfrac = r_sstepx << 16;
  621. a_tstepxfrac = r_tstepx << 16;
  622. }
  623. else
  624. #endif
  625. {
  626. //#else
  627. a_sstepxfrac = r_sstepx & 0xFFFF;
  628. a_tstepxfrac = r_tstepx & 0xFFFF;
  629. }
  630. //#endif
  631. a_ststepxwhole = skinwidth * (r_tstepx >> 16) + (r_sstepx >> 16);
  632. }
  633. #endif
  634. /*
  635. ================
  636. R_PolysetDrawThreshSpans8
  637. Random fizzle fade rasterizer
  638. ================
  639. */
  640. void R_PolysetDrawThreshSpans8 (spanpackage_t *pspanpackage)
  641. {
  642. int lcount;
  643. byte *lpdest;
  644. byte *lptex;
  645. int lsfrac, ltfrac;
  646. int llight;
  647. int lzi;
  648. short *lpz;
  649. do
  650. {
  651. lcount = d_aspancount - pspanpackage->count;
  652. errorterm += erroradjustup;
  653. if (errorterm >= 0)
  654. {
  655. d_aspancount += d_countextrastep;
  656. errorterm -= erroradjustdown;
  657. }
  658. else
  659. {
  660. d_aspancount += ubasestep;
  661. }
  662. if (lcount)
  663. {
  664. lpdest = pspanpackage->pdest;
  665. lptex = pspanpackage->ptex;
  666. lpz = pspanpackage->pz;
  667. lsfrac = pspanpackage->sfrac;
  668. ltfrac = pspanpackage->tfrac;
  669. llight = pspanpackage->light;
  670. lzi = pspanpackage->zi;
  671. do
  672. {
  673. if ((lzi >> 16) >= *lpz)
  674. {
  675. rand1k_index = (rand1k_index + 1) & MASK_1K;
  676. if (rand1k[rand1k_index] <= r_affinetridesc.vis_thresh)
  677. {
  678. *lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
  679. *lpz = lzi >> 16;
  680. }
  681. }
  682. lpdest++;
  683. lzi += r_zistepx;
  684. lpz++;
  685. llight += r_lstepx;
  686. lptex += a_ststepxwhole;
  687. lsfrac += a_sstepxfrac;
  688. lptex += lsfrac >> 16;
  689. lsfrac &= 0xFFFF;
  690. ltfrac += a_tstepxfrac;
  691. if (ltfrac & 0x10000)
  692. {
  693. lptex += r_affinetridesc.skinwidth;
  694. ltfrac &= 0xFFFF;
  695. }
  696. } while (--lcount);
  697. }
  698. pspanpackage++;
  699. } while (pspanpackage->count != -999999);
  700. }
  701. /*
  702. ================
  703. R_PolysetDrawSpans8
  704. ================
  705. */
  706. void R_PolysetDrawSpans8_33( spanpackage_t *pspanpackage)
  707. {
  708. int lcount;
  709. byte *lpdest;
  710. byte *lptex;
  711. int lsfrac, ltfrac;
  712. int llight;
  713. int lzi;
  714. short *lpz;
  715. do
  716. {
  717. lcount = d_aspancount - pspanpackage->count;
  718. errorterm += erroradjustup;
  719. if (errorterm >= 0)
  720. {
  721. d_aspancount += d_countextrastep;
  722. errorterm -= erroradjustdown;
  723. }
  724. else
  725. {
  726. d_aspancount += ubasestep;
  727. }
  728. if (lcount)
  729. {
  730. lpdest = pspanpackage->pdest;
  731. lptex = pspanpackage->ptex;
  732. lpz = pspanpackage->pz;
  733. lsfrac = pspanpackage->sfrac;
  734. ltfrac = pspanpackage->tfrac;
  735. llight = pspanpackage->light;
  736. lzi = pspanpackage->zi;
  737. do
  738. {
  739. if ((lzi >> 16) >= *lpz)
  740. {
  741. int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
  742. *lpdest = vid.alphamap[temp+ *lpdest*256];
  743. }
  744. lpdest++;
  745. lzi += r_zistepx;
  746. lpz++;
  747. llight += r_lstepx;
  748. lptex += a_ststepxwhole;
  749. lsfrac += a_sstepxfrac;
  750. lptex += lsfrac >> 16;
  751. lsfrac &= 0xFFFF;
  752. ltfrac += a_tstepxfrac;
  753. if (ltfrac & 0x10000)
  754. {
  755. lptex += r_affinetridesc.skinwidth;
  756. ltfrac &= 0xFFFF;
  757. }
  758. } while (--lcount);
  759. }
  760. pspanpackage++;
  761. } while (pspanpackage->count != -999999);
  762. }
  763. void R_PolysetDrawSpansConstant8_33( spanpackage_t *pspanpackage)
  764. {
  765. int lcount;
  766. byte *lpdest;
  767. int lzi;
  768. short *lpz;
  769. do
  770. {
  771. lcount = d_aspancount - pspanpackage->count;
  772. errorterm += erroradjustup;
  773. if (errorterm >= 0)
  774. {
  775. d_aspancount += d_countextrastep;
  776. errorterm -= erroradjustdown;
  777. }
  778. else
  779. {
  780. d_aspancount += ubasestep;
  781. }
  782. if (lcount)
  783. {
  784. lpdest = pspanpackage->pdest;
  785. lpz = pspanpackage->pz;
  786. lzi = pspanpackage->zi;
  787. do
  788. {
  789. if ((lzi >> 16) >= *lpz)
  790. {
  791. *lpdest = vid.alphamap[r_aliasblendcolor + *lpdest*256];
  792. }
  793. lpdest++;
  794. lzi += r_zistepx;
  795. lpz++;
  796. } while (--lcount);
  797. }
  798. pspanpackage++;
  799. } while (pspanpackage->count != -999999);
  800. }
  801. void R_PolysetDrawSpans8_66(spanpackage_t *pspanpackage)
  802. {
  803. int lcount;
  804. byte *lpdest;
  805. byte *lptex;
  806. int lsfrac, ltfrac;
  807. int llight;
  808. int lzi;
  809. short *lpz;
  810. do
  811. {
  812. lcount = d_aspancount - pspanpackage->count;
  813. errorterm += erroradjustup;
  814. if (errorterm >= 0)
  815. {
  816. d_aspancount += d_countextrastep;
  817. errorterm -= erroradjustdown;
  818. }
  819. else
  820. {
  821. d_aspancount += ubasestep;
  822. }
  823. if (lcount)
  824. {
  825. lpdest = pspanpackage->pdest;
  826. lptex = pspanpackage->ptex;
  827. lpz = pspanpackage->pz;
  828. lsfrac = pspanpackage->sfrac;
  829. ltfrac = pspanpackage->tfrac;
  830. llight = pspanpackage->light;
  831. lzi = pspanpackage->zi;
  832. do
  833. {
  834. if ((lzi >> 16) >= *lpz)
  835. {
  836. int temp = vid.colormap[*lptex + ( llight & 0xFF00 )];
  837. *lpdest = vid.alphamap[temp*256 + *lpdest];
  838. *lpz = lzi >> 16;
  839. }
  840. lpdest++;
  841. lzi += r_zistepx;
  842. lpz++;
  843. llight += r_lstepx;
  844. lptex += a_ststepxwhole;
  845. lsfrac += a_sstepxfrac;
  846. lptex += lsfrac >> 16;
  847. lsfrac &= 0xFFFF;
  848. ltfrac += a_tstepxfrac;
  849. if (ltfrac & 0x10000)
  850. {
  851. lptex += r_affinetridesc.skinwidth;
  852. ltfrac &= 0xFFFF;
  853. }
  854. } while (--lcount);
  855. }
  856. pspanpackage++;
  857. } while (pspanpackage->count != -999999);
  858. }
  859. void R_PolysetDrawSpansConstant8_66( spanpackage_t *pspanpackage)
  860. {
  861. int lcount;
  862. byte *lpdest;
  863. int lzi;
  864. short *lpz;
  865. do
  866. {
  867. lcount = d_aspancount - pspanpackage->count;
  868. errorterm += erroradjustup;
  869. if (errorterm >= 0)
  870. {
  871. d_aspancount += d_countextrastep;
  872. errorterm -= erroradjustdown;
  873. }
  874. else
  875. {
  876. d_aspancount += ubasestep;
  877. }
  878. if (lcount)
  879. {
  880. lpdest = pspanpackage->pdest;
  881. lpz = pspanpackage->pz;
  882. lzi = pspanpackage->zi;
  883. do
  884. {
  885. if ((lzi >> 16) >= *lpz)
  886. {
  887. *lpdest = vid.alphamap[r_aliasblendcolor*256 + *lpdest];
  888. }
  889. lpdest++;
  890. lzi += r_zistepx;
  891. lpz++;
  892. } while (--lcount);
  893. }
  894. pspanpackage++;
  895. } while (pspanpackage->count != -999999);
  896. }
  897. #if !id386
  898. void R_PolysetDrawSpans8_Opaque (spanpackage_t *pspanpackage)
  899. {
  900. int lcount;
  901. do
  902. {
  903. lcount = d_aspancount - pspanpackage->count;
  904. errorterm += erroradjustup;
  905. if (errorterm >= 0)
  906. {
  907. d_aspancount += d_countextrastep;
  908. errorterm -= erroradjustdown;
  909. }
  910. else
  911. {
  912. d_aspancount += ubasestep;
  913. }
  914. if (lcount)
  915. {
  916. int lsfrac, ltfrac;
  917. byte *lpdest;
  918. byte *lptex;
  919. int llight;
  920. int lzi;
  921. short *lpz;
  922. lpdest = pspanpackage->pdest;
  923. lptex = pspanpackage->ptex;
  924. lpz = pspanpackage->pz;
  925. lsfrac = pspanpackage->sfrac;
  926. ltfrac = pspanpackage->tfrac;
  927. llight = pspanpackage->light;
  928. lzi = pspanpackage->zi;
  929. do
  930. {
  931. if ((lzi >> 16) >= *lpz)
  932. {
  933. //PGM
  934. if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
  935. *lpdest = ((byte *)vid.colormap)[irtable[*lptex]];
  936. else
  937. *lpdest = ((byte *)vid.colormap)[*lptex + (llight & 0xFF00)];
  938. //PGM
  939. *lpz = lzi >> 16;
  940. }
  941. lpdest++;
  942. lzi += r_zistepx;
  943. lpz++;
  944. llight += r_lstepx;
  945. lptex += a_ststepxwhole;
  946. lsfrac += a_sstepxfrac;
  947. lptex += lsfrac >> 16;
  948. lsfrac &= 0xFFFF;
  949. ltfrac += a_tstepxfrac;
  950. if (ltfrac & 0x10000)
  951. {
  952. lptex += r_affinetridesc.skinwidth;
  953. ltfrac &= 0xFFFF;
  954. }
  955. } while (--lcount);
  956. }
  957. pspanpackage++;
  958. } while (pspanpackage->count != -999999);
  959. }
  960. #endif
  961. /*
  962. ================
  963. R_PolysetFillSpans8
  964. ================
  965. */
  966. void R_PolysetFillSpans8 (spanpackage_t *pspanpackage)
  967. {
  968. int color;
  969. // FIXME: do z buffering
  970. color = d_aflatcolor++;
  971. while (1)
  972. {
  973. int lcount;
  974. byte *lpdest;
  975. lcount = pspanpackage->count;
  976. if (lcount == -1)
  977. return;
  978. if (lcount)
  979. {
  980. lpdest = pspanpackage->pdest;
  981. do
  982. {
  983. *lpdest++ = color;
  984. } while (--lcount);
  985. }
  986. pspanpackage++;
  987. }
  988. }
  989. /*
  990. ================
  991. R_RasterizeAliasPolySmooth
  992. ================
  993. */
  994. void R_RasterizeAliasPolySmooth (void)
  995. {
  996. int initialleftheight, initialrightheight;
  997. int *plefttop, *prighttop, *pleftbottom, *prightbottom;
  998. int working_lstepx, originalcount;
  999. plefttop = pedgetable->pleftedgevert0;
  1000. prighttop = pedgetable->prightedgevert0;
  1001. pleftbottom = pedgetable->pleftedgevert1;
  1002. prightbottom = pedgetable->prightedgevert1;
  1003. initialleftheight = pleftbottom[1] - plefttop[1];
  1004. initialrightheight = prightbottom[1] - prighttop[1];
  1005. //
  1006. // set the s, t, and light gradients, which are consistent across the triangle
  1007. // because being a triangle, things are affine
  1008. //
  1009. R_PolysetCalcGradients (r_affinetridesc.skinwidth);
  1010. //
  1011. // rasterize the polygon
  1012. //
  1013. //
  1014. // scan out the top (and possibly only) part of the left edge
  1015. //
  1016. d_pedgespanpackage = a_spans;
  1017. ystart = plefttop[1];
  1018. d_aspancount = plefttop[0] - prighttop[0];
  1019. d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
  1020. (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
  1021. //#if id386ALIAS
  1022. #if id386
  1023. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1024. {
  1025. d_sfrac = (plefttop[2] & 0xFFFF) << 16;
  1026. d_tfrac = (plefttop[3] & 0xFFFF) << 16;
  1027. }
  1028. //#else
  1029. else
  1030. #endif
  1031. {
  1032. d_sfrac = plefttop[2] & 0xFFFF;
  1033. d_tfrac = plefttop[3] & 0xFFFF;
  1034. }
  1035. //#endif
  1036. d_light = plefttop[4];
  1037. d_zi = plefttop[5];
  1038. d_pdest = (byte *)d_viewbuffer +
  1039. ystart * r_screenwidth + plefttop[0];
  1040. d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
  1041. if (initialleftheight == 1)
  1042. {
  1043. d_pedgespanpackage->pdest = d_pdest;
  1044. d_pedgespanpackage->pz = d_pz;
  1045. d_pedgespanpackage->count = d_aspancount;
  1046. d_pedgespanpackage->ptex = d_ptex;
  1047. d_pedgespanpackage->sfrac = d_sfrac;
  1048. d_pedgespanpackage->tfrac = d_tfrac;
  1049. // FIXME: need to clamp l, s, t, at both ends?
  1050. d_pedgespanpackage->light = d_light;
  1051. d_pedgespanpackage->zi = d_zi;
  1052. d_pedgespanpackage++;
  1053. }
  1054. else
  1055. {
  1056. R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
  1057. pleftbottom[0], pleftbottom[1]);
  1058. //#if id386ALIAS
  1059. #if id386
  1060. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1061. {
  1062. d_pzbasestep = (d_zwidth + ubasestep) << 1;
  1063. d_pzextrastep = d_pzbasestep + 2;
  1064. }
  1065. //#else
  1066. else
  1067. #endif
  1068. {
  1069. d_pzbasestep = d_zwidth + ubasestep;
  1070. d_pzextrastep = d_pzbasestep + 1;
  1071. }
  1072. //#endif
  1073. d_pdestbasestep = r_screenwidth + ubasestep;
  1074. d_pdestextrastep = d_pdestbasestep + 1;
  1075. // TODO: can reuse partial expressions here
  1076. // for negative steps in x along left edge, bias toward overflow rather than
  1077. // underflow (sort of turning the floor () we did in the gradient calcs into
  1078. // ceil (), but plus a little bit)
  1079. if (ubasestep < 0)
  1080. working_lstepx = r_lstepx - 1;
  1081. else
  1082. working_lstepx = r_lstepx;
  1083. d_countextrastep = ubasestep + 1;
  1084. d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
  1085. ((r_tstepy + r_tstepx * ubasestep) >> 16) *
  1086. r_affinetridesc.skinwidth;
  1087. //#if id386ALIAS
  1088. #if id386
  1089. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1090. {
  1091. d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
  1092. d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
  1093. }
  1094. else
  1095. #endif
  1096. {
  1097. //#else
  1098. d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
  1099. d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
  1100. }
  1101. //#endif
  1102. d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
  1103. d_zibasestep = r_zistepy + r_zistepx * ubasestep;
  1104. d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
  1105. ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
  1106. r_affinetridesc.skinwidth;
  1107. //#if id386ALIAS
  1108. #if id386
  1109. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1110. {
  1111. d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) << 16;
  1112. d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) << 16;
  1113. }
  1114. else
  1115. #endif
  1116. {
  1117. //#else
  1118. d_sfracextrastep = (r_sstepy + r_sstepx*d_countextrastep) & 0xFFFF;
  1119. d_tfracextrastep = (r_tstepy + r_tstepx*d_countextrastep) & 0xFFFF;
  1120. }
  1121. //#endif
  1122. d_lightextrastep = d_lightbasestep + working_lstepx;
  1123. d_ziextrastep = d_zibasestep + r_zistepx;
  1124. #if id386
  1125. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1126. {
  1127. R_PolysetScanLeftEdge (initialleftheight);
  1128. }
  1129. else
  1130. #endif
  1131. {
  1132. R_PolysetScanLeftEdge_C(initialleftheight);
  1133. }
  1134. }
  1135. //
  1136. // scan out the bottom part of the left edge, if it exists
  1137. //
  1138. if (pedgetable->numleftedges == 2)
  1139. {
  1140. int height;
  1141. plefttop = pleftbottom;
  1142. pleftbottom = pedgetable->pleftedgevert2;
  1143. height = pleftbottom[1] - plefttop[1];
  1144. // TODO: make this a function; modularize this function in general
  1145. ystart = plefttop[1];
  1146. d_aspancount = plefttop[0] - prighttop[0];
  1147. d_ptex = (byte *)r_affinetridesc.pskin + (plefttop[2] >> 16) +
  1148. (plefttop[3] >> 16) * r_affinetridesc.skinwidth;
  1149. d_sfrac = 0;
  1150. d_tfrac = 0;
  1151. d_light = plefttop[4];
  1152. d_zi = plefttop[5];
  1153. d_pdest = (byte *)d_viewbuffer + ystart * r_screenwidth + plefttop[0];
  1154. d_pz = d_pzbuffer + ystart * d_zwidth + plefttop[0];
  1155. if (height == 1)
  1156. {
  1157. d_pedgespanpackage->pdest = d_pdest;
  1158. d_pedgespanpackage->pz = d_pz;
  1159. d_pedgespanpackage->count = d_aspancount;
  1160. d_pedgespanpackage->ptex = d_ptex;
  1161. d_pedgespanpackage->sfrac = d_sfrac;
  1162. d_pedgespanpackage->tfrac = d_tfrac;
  1163. // FIXME: need to clamp l, s, t, at both ends?
  1164. d_pedgespanpackage->light = d_light;
  1165. d_pedgespanpackage->zi = d_zi;
  1166. d_pedgespanpackage++;
  1167. }
  1168. else
  1169. {
  1170. R_PolysetSetUpForLineScan(plefttop[0], plefttop[1],
  1171. pleftbottom[0], pleftbottom[1]);
  1172. d_pdestbasestep = r_screenwidth + ubasestep;
  1173. d_pdestextrastep = d_pdestbasestep + 1;
  1174. //#if id386ALIAS
  1175. #if id386
  1176. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1177. {
  1178. d_pzbasestep = (d_zwidth + ubasestep) << 1;
  1179. d_pzextrastep = d_pzbasestep + 2;
  1180. }
  1181. //#else
  1182. else
  1183. #endif
  1184. {
  1185. d_pzbasestep = d_zwidth + ubasestep;
  1186. d_pzextrastep = d_pzbasestep + 1;
  1187. }
  1188. //#endif
  1189. if (ubasestep < 0)
  1190. working_lstepx = r_lstepx - 1;
  1191. else
  1192. working_lstepx = r_lstepx;
  1193. d_countextrastep = ubasestep + 1;
  1194. d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> 16) +
  1195. ((r_tstepy + r_tstepx * ubasestep) >> 16) *
  1196. r_affinetridesc.skinwidth;
  1197. //#if id386ALIAS
  1198. #if id386
  1199. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1200. {
  1201. d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) << 16;
  1202. d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) << 16;
  1203. }
  1204. //#else
  1205. else
  1206. #endif
  1207. {
  1208. d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF;
  1209. d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF;
  1210. }
  1211. //#endif
  1212. d_lightbasestep = r_lstepy + working_lstepx * ubasestep;
  1213. d_zibasestep = r_zistepy + r_zistepx * ubasestep;
  1214. d_ptexextrastep = ((r_sstepy + r_sstepx * d_countextrastep) >> 16) +
  1215. ((r_tstepy + r_tstepx * d_countextrastep) >> 16) *
  1216. r_affinetridesc.skinwidth;
  1217. //#if id386ALIAS
  1218. #if id386
  1219. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1220. {
  1221. d_sfracextrastep = ((r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF)<<16;
  1222. d_tfracextrastep = ((r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF)<<16;
  1223. }
  1224. else
  1225. #endif
  1226. //#endif
  1227. {
  1228. d_sfracextrastep = (r_sstepy+r_sstepx*d_countextrastep) & 0xFFFF;
  1229. d_tfracextrastep = (r_tstepy+r_tstepx*d_countextrastep) & 0xFFFF;
  1230. }
  1231. //#endif
  1232. d_lightextrastep = d_lightbasestep + working_lstepx;
  1233. d_ziextrastep = d_zibasestep + r_zistepx;
  1234. #if id386
  1235. if ( d_pdrawspans == R_PolysetDrawSpans8_Opaque )
  1236. {
  1237. R_PolysetScanLeftEdge (height);
  1238. }
  1239. else
  1240. #endif
  1241. {
  1242. R_PolysetScanLeftEdge_C(height);
  1243. }
  1244. }
  1245. }
  1246. // scan out the top (and possibly only) part of the right edge, updating the
  1247. // count field
  1248. d_pedgespanpackage = a_spans;
  1249. R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
  1250. prightbottom[0], prightbottom[1]);
  1251. d_aspancount = 0;
  1252. d_countextrastep = ubasestep + 1;
  1253. originalcount = a_spans[initialrightheight].count;
  1254. a_spans[initialrightheight].count = -999999; // mark end of the spanpackages
  1255. (*d_pdrawspans) (a_spans);
  1256. // scan out the bottom part of the right edge, if it exists
  1257. if (pedgetable->numrightedges == 2)
  1258. {
  1259. int height;
  1260. spanpackage_t *pstart;
  1261. pstart = a_spans + initialrightheight;
  1262. pstart->count = originalcount;
  1263. d_aspancount = prightbottom[0] - prighttop[0];
  1264. prighttop = prightbottom;
  1265. prightbottom = pedgetable->prightedgevert2;
  1266. height = prightbottom[1] - prighttop[1];
  1267. R_PolysetSetUpForLineScan(prighttop[0], prighttop[1],
  1268. prightbottom[0], prightbottom[1]);
  1269. d_countextrastep = ubasestep + 1;
  1270. a_spans[initialrightheight + height].count = -999999;
  1271. // mark end of the spanpackages
  1272. (*d_pdrawspans) (pstart);
  1273. }
  1274. }
  1275. /*
  1276. ================
  1277. R_PolysetSetEdgeTable
  1278. ================
  1279. */
  1280. void R_PolysetSetEdgeTable (void)
  1281. {
  1282. int edgetableindex;
  1283. edgetableindex = 0; // assume the vertices are already in
  1284. // top to bottom order
  1285. //
  1286. // determine which edges are right & left, and the order in which
  1287. // to rasterize them
  1288. //
  1289. if (r_p0[1] >= r_p1[1])
  1290. {
  1291. if (r_p0[1] == r_p1[1])
  1292. {
  1293. if (r_p0[1] < r_p2[1])
  1294. pedgetable = &edgetables[2];
  1295. else
  1296. pedgetable = &edgetables[5];
  1297. return;
  1298. }
  1299. else
  1300. {
  1301. edgetableindex = 1;
  1302. }
  1303. }
  1304. if (r_p0[1] == r_p2[1])
  1305. {
  1306. if (edgetableindex)
  1307. pedgetable = &edgetables[8];
  1308. else
  1309. pedgetable = &edgetables[9];
  1310. return;
  1311. }
  1312. else if (r_p1[1] == r_p2[1])
  1313. {
  1314. if (edgetableindex)
  1315. pedgetable = &edgetables[10];
  1316. else
  1317. pedgetable = &edgetables[11];
  1318. return;
  1319. }
  1320. if (r_p0[1] > r_p2[1])
  1321. edgetableindex += 2;
  1322. if (r_p1[1] > r_p2[1])
  1323. edgetableindex += 4;
  1324. pedgetable = &edgetables[edgetableindex];
  1325. }