Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

832 lines
24 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: mcdline.c
  3. *
  4. * Contains all of the line-rendering routines for the Millenium MCD driver.
  5. *
  6. * Copyright (c) 1996 Microsoft Corporation
  7. \**************************************************************************/
  8. #include "precomp.h"
  9. #include "mcdhw.h"
  10. #include "mcdutil.h"
  11. #include "mcdmath.h"
  12. //#undef CHECK_FIFO_FREE
  13. //#define CHECK_FIFO_FREE
  14. VOID FASTCALL __MCDRenderFlatLine(DEVRC *pRc, MCDVERTEX *a, MCDVERTEX *b, BOOL resetLine)
  15. {
  16. PDEV *ppdev = pRc->ppdev;
  17. BYTE *pjBase = ppdev->pjBase;
  18. ULONG clipNum;
  19. RECTL *pClip;
  20. MCDFLOAT invLength;
  21. MCDCOLOR *ac;
  22. LONG ix0, ix1, iy0, iy1;
  23. LONG idx, idy;
  24. LONG absIdx, absIdy;
  25. LONG x0frac, x1frac, y0frac, y1frac, totDist;
  26. LONG numPixels;
  27. LARGE_INTEGER idz, iZStart;
  28. LONG err;
  29. ULONG signs;
  30. ULONG adjust = 0;
  31. LONG majorInc;
  32. LONG minorInc;
  33. if ((clipNum = pRc->pEnumClip->c) > 1) {
  34. pClip = &pRc->pEnumClip->arcl[0];
  35. (*pRc->HWSetupClipRect)(pRc, pClip++);
  36. }
  37. x0frac = __MCD_VERTEX_FLOAT_FRACTION(a->windowCoord.x);
  38. y0frac = __MCD_VERTEX_FLOAT_FRACTION(a->windowCoord.y);
  39. ix0 = __MCD_VERTEX_FLOAT_TO_INT(a->windowCoord.x);
  40. iy0 = __MCD_VERTEX_FLOAT_TO_INT(a->windowCoord.y);
  41. x1frac = __MCD_VERTEX_FLOAT_FRACTION(b->windowCoord.x);
  42. y1frac = __MCD_VERTEX_FLOAT_FRACTION(b->windowCoord.y);
  43. ix1 = __MCD_VERTEX_FLOAT_TO_INT(b->windowCoord.x);
  44. iy1 = __MCD_VERTEX_FLOAT_TO_INT(b->windowCoord.y);
  45. absIdx = idx = ix1 - ix0;
  46. if (absIdx < 0)
  47. absIdx = -absIdx;
  48. absIdy = idy = iy1 - iy0;
  49. if (absIdy < 0)
  50. absIdy = -absIdy;
  51. if (absIdx > absIdy) {
  52. signs = sdydxl_MAJOR_X;
  53. if (idx > 0) {
  54. signs |= sdxl_ADD;
  55. if (pRc->privateEnables & __MCDENABLE_Z) {
  56. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  57. b->windowCoord.x - a->windowCoord.x,
  58. &invLength);
  59. }
  60. y0frac -= __MCD_VERTEX_FRAC_HALF;
  61. if (y0frac < 0) y0frac = -y0frac;
  62. totDist = y0frac + x0frac - __MCD_VERTEX_FRAC_ONE;
  63. if (totDist > 0) {
  64. ix0++;
  65. adjust++;
  66. }
  67. y1frac -= __MCD_VERTEX_FRAC_HALF;
  68. if (y1frac < 0) y1frac = -y1frac;
  69. totDist = y1frac + x1frac - __MCD_VERTEX_FRAC_ONE;
  70. if (totDist > 0) ix1++;
  71. numPixels = ix1 - ix0;
  72. } else {
  73. signs |= sdxl_SUB;
  74. if (pRc->privateEnables & __MCDENABLE_Z) {
  75. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  76. a->windowCoord.x - b->windowCoord.x,
  77. &invLength);
  78. }
  79. y0frac -= __MCD_VERTEX_FRAC_HALF;
  80. if (y0frac < 0) y0frac = -y0frac;
  81. totDist = y0frac - x0frac;
  82. if (totDist > 0) {
  83. ix0--;
  84. adjust++;
  85. }
  86. y1frac -= __MCD_VERTEX_FRAC_HALF;
  87. if (y1frac < 0) y1frac = -y1frac;
  88. totDist = y1frac - x1frac;
  89. if (totDist > 0) ix1--;
  90. numPixels = ix0 - ix1;
  91. }
  92. if (numPixels <= 0) {
  93. if (pRc->privateEnables & __MCDENABLE_Z)
  94. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  95. return;
  96. }
  97. majorInc = (absIdy << 1);
  98. minorInc = ((LONG)absIdy - (LONG)absIdx) << 1;
  99. if (idy < 0) {
  100. signs |= sdy_SUB;
  101. err = majorInc - (LONG)absIdx - 1;
  102. if (adjust) {
  103. if (err <= 0)
  104. err += majorInc;
  105. else {
  106. iy0--;
  107. err += minorInc;
  108. }
  109. }
  110. } else {
  111. signs |= sdy_ADD;
  112. err = majorInc - (LONG)absIdx;
  113. if (adjust) {
  114. if (err <= 0)
  115. err += majorInc;
  116. else {
  117. iy0++;
  118. err += minorInc;
  119. }
  120. }
  121. }
  122. } else {
  123. signs = sdydxl_MAJOR_Y;
  124. if (idy > 0) {
  125. signs |= sdy_ADD;
  126. if (pRc->privateEnables & __MCDENABLE_Z) {
  127. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  128. b->windowCoord.y - a->windowCoord.y,
  129. &invLength);
  130. }
  131. x0frac -= __MCD_VERTEX_FRAC_HALF;
  132. if (x0frac < 0) x0frac = -x0frac;
  133. totDist = y0frac + x0frac - __MCD_VERTEX_FRAC_ONE;
  134. if (totDist > 0) {
  135. iy0++;
  136. adjust++;
  137. }
  138. x1frac -= __MCD_VERTEX_FRAC_HALF;
  139. if (x1frac < 0) x1frac = -x1frac;
  140. totDist = y1frac + x1frac - __MCD_VERTEX_FRAC_ONE;
  141. if (totDist > 0) iy1++;
  142. numPixels = iy1 - iy0;
  143. } else {
  144. signs |= sdy_SUB;
  145. if (pRc->privateEnables & __MCDENABLE_Z) {
  146. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  147. a->windowCoord.y - b->windowCoord.y,
  148. &invLength);
  149. }
  150. x0frac -= __MCD_VERTEX_FRAC_HALF;
  151. if (x0frac < 0) x0frac = -x0frac;
  152. totDist = x0frac - y0frac;
  153. if (totDist > 0) {
  154. iy0--;
  155. adjust++;
  156. }
  157. x1frac -= __MCD_VERTEX_FRAC_HALF;
  158. if (x1frac < 0) x1frac = -x1frac;
  159. totDist = x1frac - y1frac;
  160. if (totDist > 0) iy1--;
  161. numPixels = iy0 - iy1;
  162. }
  163. if (numPixels <= 0) {
  164. if (pRc->privateEnables & __MCDENABLE_Z)
  165. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  166. return;
  167. }
  168. majorInc = (absIdx << 1);
  169. minorInc = ((LONG)absIdx - (LONG)absIdy) << 1;
  170. if (idx < 0) {
  171. signs |= sdxl_SUB;
  172. err = majorInc - (LONG)absIdy - 1;
  173. if (adjust) {
  174. if (err <= 0)
  175. err += majorInc;
  176. else {
  177. ix0--;
  178. err += minorInc;
  179. }
  180. }
  181. } else {
  182. signs |= sdxl_ADD;
  183. err = majorInc - (LONG)absIdy;
  184. if (adjust) {
  185. if (err <= 0)
  186. err += majorInc;
  187. else {
  188. ix0++;
  189. err += minorInc;
  190. }
  191. }
  192. }
  193. }
  194. if (pRc->privateEnables & __MCDENABLE_Z) {
  195. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 3+3+6);
  196. #if _X86_ && ASM_ACCEL
  197. _asm{
  198. mov ebx, b
  199. mov eax, a
  200. fld DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][ebx]
  201. fsub DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][eax] // dz len
  202. mov ebx, pRc
  203. fld DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][eax] // a.z dz len
  204. fxch ST(2) // len dz a.z
  205. fmulp ST(1), ST //+1 // dzL a.z
  206. fxch ST(1) // a.z dzL
  207. fmul DWORD PTR [OFFSET(DEVRC.zScale)][ebx] // azS dzL
  208. fxch ST(1) // dzL azS
  209. fmul DWORD PTR [OFFSET(DEVRC.zScale)][ebx] //+1 // dzLS azS
  210. fxch ST(1) // azS dzLS
  211. fistp iZStart
  212. fistp idz
  213. }
  214. #else
  215. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  216. idz.LowPart = FTOL((b->windowCoord.z - a->windowCoord.z) * invLength * pRc->zScale);
  217. iZStart.LowPart = FTOL(a->windowCoord.z * pRc->zScale);
  218. #endif
  219. CP_WRITE(pjBase, DWG_DR2, idz.LowPart);
  220. CP_WRITE(pjBase, DWG_DR3, idz.LowPart);
  221. CP_WRITE(pjBase, DWG_DR0, iZStart.LowPart);
  222. } else {
  223. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 3+6);
  224. }
  225. CP_WRITE(pjBase, DWG_AR0, majorInc);
  226. CP_WRITE(pjBase, DWG_AR1, err);
  227. CP_WRITE(pjBase, DWG_AR2, minorInc);
  228. CP_WRITE(pjBase, DWG_SGN, signs);
  229. CP_WRITE(pjBase, DWG_XDST, (ix0 + pRc->xOffset) & 0xffff);
  230. CP_WRITE(pjBase, DWG_YDSTLEN, ((iy0 + pRc->yOffset) << 16) | numPixels);
  231. #if _X86_ && ASM_ACCEL
  232. {
  233. LONG rTemp, gTemp, bTemp;
  234. _asm{
  235. mov eax, a
  236. mov ebx, pRc
  237. lea eax, [OFFSET(MCDVERTEX.colors) + eax]
  238. fld DWORD PTR [OFFSET(DEVRC.rScale)][ebx]
  239. fmul DWORD PTR [OFFSET(MCDCOLOR.r)][eax]
  240. fld DWORD PTR [OFFSET(DEVRC.gScale)][ebx]
  241. fmul DWORD PTR [OFFSET(MCDCOLOR.g)][eax]
  242. fld DWORD PTR [OFFSET(DEVRC.bScale)][ebx] // B G R
  243. fmul DWORD PTR [OFFSET(MCDCOLOR.b)][eax]
  244. fxch ST(2) // R G B
  245. fistp rTemp // G B
  246. fistp gTemp
  247. fistp bTemp
  248. }
  249. CP_WRITE(pjBase, DWG_DR4, rTemp);
  250. CP_WRITE(pjBase, DWG_DR8, gTemp);
  251. CP_START(pjBase, DWG_DR12, bTemp);
  252. }
  253. #else
  254. ac = &a->colors[0];
  255. CP_WRITE(pjBase, DWG_DR4, FTOL(ac->r * pRc->rScale));
  256. CP_WRITE(pjBase, DWG_DR8, FTOL(ac->g * pRc->gScale));
  257. CP_START(pjBase, DWG_DR12, FTOL(ac->b * pRc->bScale));
  258. #endif
  259. while (--clipNum) {
  260. (*pRc->HWSetupClipRect)(pRc, pClip++);
  261. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 4);
  262. CP_WRITE(pjBase, DWG_DR0, iZStart.LowPart);
  263. CP_WRITE(pjBase, DWG_AR1, err);
  264. CP_WRITE(pjBase, DWG_XDST, (ix0 + pRc->xOffset) & 0xffff);
  265. CP_START(pjBase, DWG_YDSTLEN, ((iy0 + pRc->yOffset) << 16) | numPixels);
  266. }
  267. }
  268. VOID FASTCALL __MCDRenderSmoothLine(DEVRC *pRc, MCDVERTEX *a, MCDVERTEX *b, BOOL resetLine)
  269. {
  270. PDEV *ppdev = pRc->ppdev;
  271. BYTE *pjBase = ppdev->pjBase;
  272. ULONG clipNum;
  273. RECTL *pClip;
  274. MCDFLOAT dr, dg, db;
  275. ULONG idr, idg, idb;
  276. LONG iRStart, iGStart, iBStart;
  277. MCDFLOAT length, invLength;
  278. MCDCOLOR *ac, *bc;
  279. LONG ix0, ix1, iy0, iy1;
  280. LONG idx, idy;
  281. LONG absIdx, absIdy;
  282. LONG x0frac, x1frac, y0frac, y1frac, totDist;
  283. LONG numPixels;
  284. LARGE_INTEGER idz, iZStart;
  285. LONG err;
  286. ULONG signs;
  287. ULONG adjust = 0;
  288. LONG majorInc;
  289. LONG minorInc;
  290. if ((clipNum = pRc->pEnumClip->c) > 1) {
  291. pClip = &pRc->pEnumClip->arcl[0];
  292. (*pRc->HWSetupClipRect)(pRc, pClip++);
  293. }
  294. x0frac = __MCD_VERTEX_FLOAT_FRACTION(a->windowCoord.x);
  295. y0frac = __MCD_VERTEX_FLOAT_FRACTION(a->windowCoord.y);
  296. ix0 = __MCD_VERTEX_FLOAT_TO_INT(a->windowCoord.x);
  297. iy0 = __MCD_VERTEX_FLOAT_TO_INT(a->windowCoord.y);
  298. x1frac = __MCD_VERTEX_FLOAT_FRACTION(b->windowCoord.x);
  299. y1frac = __MCD_VERTEX_FLOAT_FRACTION(b->windowCoord.y);
  300. ix1 = __MCD_VERTEX_FLOAT_TO_INT(b->windowCoord.x);
  301. iy1 = __MCD_VERTEX_FLOAT_TO_INT(b->windowCoord.y);
  302. absIdx = idx = ix1 - ix0;
  303. if (absIdx < 0)
  304. absIdx = -absIdx;
  305. absIdy = idy = iy1 - iy0;
  306. if (absIdy < 0)
  307. absIdy = -absIdy;
  308. if (absIdx > absIdy) {
  309. signs = sdydxl_MAJOR_X;
  310. if (idx > 0) {
  311. signs |= sdxl_ADD;
  312. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  313. b->windowCoord.x - a->windowCoord.x,
  314. &invLength);
  315. y0frac -= __MCD_VERTEX_FRAC_HALF;
  316. if (y0frac < 0) y0frac = -y0frac;
  317. totDist = y0frac + x0frac - __MCD_VERTEX_FRAC_ONE;
  318. if (totDist > 0) {
  319. ix0++;
  320. adjust++;
  321. }
  322. y1frac -= __MCD_VERTEX_FRAC_HALF;
  323. if (y1frac < 0) y1frac = -y1frac;
  324. totDist = y1frac + x1frac - __MCD_VERTEX_FRAC_ONE;
  325. if (totDist > 0) ix1++;
  326. numPixels = ix1 - ix0;
  327. } else {
  328. signs |= sdxl_SUB;
  329. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  330. a->windowCoord.x - b->windowCoord.x,
  331. &invLength);
  332. y0frac -= __MCD_VERTEX_FRAC_HALF;
  333. if (y0frac < 0) y0frac = -y0frac;
  334. totDist = y0frac - x0frac;
  335. if (totDist > 0) {
  336. ix0--;
  337. adjust++;
  338. }
  339. y1frac -= __MCD_VERTEX_FRAC_HALF;
  340. if (y1frac < 0) y1frac = -y1frac;
  341. totDist = y1frac - x1frac;
  342. if (totDist > 0) ix1--;
  343. numPixels = ix0 - ix1;
  344. }
  345. if (numPixels <= 0) {
  346. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  347. return;
  348. }
  349. if (numPixels == 1)
  350. goto shortLine;
  351. majorInc = (absIdy << 1);
  352. minorInc = ((LONG)absIdy - (LONG)absIdx) << 1;
  353. if (idy < 0) {
  354. signs |= sdy_SUB;
  355. err = majorInc - (LONG)absIdx - 1;
  356. if (adjust) {
  357. if (err <= 0)
  358. err += majorInc;
  359. else {
  360. iy0--;
  361. err += minorInc;
  362. }
  363. }
  364. } else {
  365. signs |= sdy_ADD;
  366. err = majorInc - (LONG)absIdx;
  367. if (adjust) {
  368. if (err <= 0)
  369. err += majorInc;
  370. else {
  371. iy0++;
  372. err += minorInc;
  373. }
  374. }
  375. }
  376. } else {
  377. signs = sdydxl_MAJOR_Y;
  378. if (idy > 0) {
  379. signs |= sdy_ADD;
  380. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  381. b->windowCoord.y - a->windowCoord.y,
  382. &invLength);
  383. x0frac -= __MCD_VERTEX_FRAC_HALF;
  384. if (x0frac < 0) x0frac = -x0frac;
  385. totDist = y0frac + x0frac - __MCD_VERTEX_FRAC_ONE;
  386. if (totDist > 0) {
  387. iy0++;
  388. adjust++;
  389. }
  390. x1frac -= __MCD_VERTEX_FRAC_HALF;
  391. if (x1frac < 0) x1frac = -x1frac;
  392. totDist = y1frac + x1frac - __MCD_VERTEX_FRAC_ONE;
  393. if (totDist > 0) iy1++;
  394. numPixels = iy1 - iy0;
  395. } else {
  396. signs |= sdy_SUB;
  397. __MCD_FLOAT_BEGIN_DIVIDE(__MCDONE,
  398. a->windowCoord.y - b->windowCoord.y,
  399. &invLength);
  400. x0frac -= __MCD_VERTEX_FRAC_HALF;
  401. if (x0frac < 0) x0frac = -x0frac;
  402. totDist = x0frac - y0frac;
  403. if (totDist > 0) {
  404. iy0--;
  405. adjust++;
  406. }
  407. x1frac -= __MCD_VERTEX_FRAC_HALF;
  408. if (x1frac < 0) x1frac = -x1frac;
  409. totDist = x1frac - y1frac;
  410. if (totDist > 0) iy1--;
  411. numPixels = iy0 - iy1;
  412. }
  413. if (numPixels <= 0) {
  414. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  415. return;
  416. }
  417. if (numPixels == 1)
  418. goto shortLine;
  419. majorInc = (absIdx << 1);
  420. minorInc = ((LONG)absIdx - (LONG)absIdy) << 1;
  421. if (idx < 0) {
  422. signs |= sdxl_SUB;
  423. err = majorInc - (LONG)absIdy - 1;
  424. if (adjust) {
  425. if (err <= 0)
  426. err += majorInc;
  427. else {
  428. ix0--;
  429. err += minorInc;
  430. }
  431. }
  432. } else {
  433. signs |= sdxl_ADD;
  434. err = majorInc - (LONG)absIdy;
  435. if (adjust) {
  436. if (err <= 0)
  437. err += majorInc;
  438. else {
  439. ix0++;
  440. err += minorInc;
  441. }
  442. }
  443. }
  444. }
  445. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  446. if (pRc->privateEnables & __MCDENABLE_Z) {
  447. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 18);
  448. #if _X86_ && ASM_ACCEL
  449. _asm{
  450. mov ebx, b
  451. mov eax, a
  452. fld DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][ebx]
  453. fsub DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][eax] // dz
  454. mov ebx, pRc
  455. fld DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][eax] // a.z dz
  456. fxch ST(1) // dz a.z
  457. fmul invLength //+1 // dzL
  458. fxch ST(1) // a.z dzL
  459. fmul DWORD PTR [OFFSET(DEVRC.zScale)][ebx] // azS dzL
  460. fxch ST(1) // dzL azS
  461. fmul DWORD PTR [OFFSET(DEVRC.zScale)][ebx] //+1 // dzLS azS
  462. fxch ST(1) // azS dzLS
  463. fistp iZStart
  464. fistp idz
  465. }
  466. #else
  467. idz.LowPart = FTOL((b->windowCoord.z - a->windowCoord.z) * invLength * pRc->zScale);
  468. iZStart.LowPart = FTOL(a->windowCoord.z * pRc->zScale);
  469. #endif
  470. CP_WRITE(pjBase, DWG_DR2, idz.LowPart);
  471. CP_WRITE(pjBase, DWG_DR3, idz.LowPart);
  472. CP_WRITE(pjBase, DWG_DR0, iZStart.LowPart);
  473. } else {
  474. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 15);
  475. }
  476. CP_WRITE(pjBase, DWG_AR0, majorInc);
  477. CP_WRITE(pjBase, DWG_AR1, err);
  478. CP_WRITE(pjBase, DWG_AR2, minorInc);
  479. CP_WRITE(pjBase, DWG_SGN, signs);
  480. CP_WRITE(pjBase, DWG_XDST, (ix0 + pRc->xOffset) & 0xffff);
  481. CP_WRITE(pjBase, DWG_YDSTLEN, ((iy0 + pRc->yOffset) << 16) | numPixels);
  482. #if _X86_ && ASM_ACCEL
  483. _asm{
  484. mov ebx, b
  485. mov eax, a
  486. mov edx, pRc
  487. lea ebx, [OFFSET(MCDVERTEX.colors) + ebx]
  488. lea eax, [OFFSET(MCDVERTEX.colors) + eax]
  489. fld DWORD PTR [OFFSET(MCDCOLOR.r)][ebx]
  490. fsub DWORD PTR [OFFSET(MCDCOLOR.r)][eax] // dr
  491. fld DWORD PTR [OFFSET(MCDCOLOR.g)][ebx]
  492. fsub DWORD PTR [OFFSET(MCDCOLOR.g)][eax] // dg dr
  493. fxch ST(1) // dr dg
  494. fmul invLength // drL dg
  495. fld DWORD PTR [OFFSET(MCDCOLOR.b)][ebx]
  496. fsub DWORD PTR [OFFSET(MCDCOLOR.b)][eax] // db drL dg
  497. fxch ST(2) // dg drL db
  498. fmul invLength // dgL drL db
  499. fxch ST(1) // drL dgL db
  500. fmul DWORD PTR [OFFSET(DEVRC.rScale)][edx] // drLS dgL db
  501. fxch ST(2) // db dgL drLS
  502. fmul invLength // dbL dgL drLS
  503. fxch ST(1) // dgL dbL drLS
  504. fmul DWORD PTR [OFFSET(DEVRC.gScale)][edx] // dgLS dbL drLS
  505. fxch ST(1) // dbL dgLS drLS
  506. fld DWORD PTR [OFFSET(MCDCOLOR.r)][eax]
  507. fmul DWORD PTR [OFFSET(DEVRC.rScale)][edx] // r dbL dgLS drLS
  508. fxch ST(1) // dbL r dgLS drLS
  509. fmul DWORD PTR [OFFSET(DEVRC.bScale)][edx] // dbLS r dgLS drLS
  510. fxch ST(1) // r dbLS dgLS drLS
  511. fld DWORD PTR [OFFSET(MCDCOLOR.g)][eax]
  512. fmul DWORD PTR [OFFSET(DEVRC.gScale)][edx] // g r dbLS dgLS drLS
  513. fld DWORD PTR [OFFSET(MCDCOLOR.b)][eax]
  514. fmul DWORD PTR [OFFSET(DEVRC.bScale)][edx] // b g r dbLS dgLS drLS
  515. fxch ST(2) // r g b dbLS dgLS drLS
  516. fistp iRStart
  517. fistp iGStart
  518. fistp iBStart
  519. fistp idb
  520. fistp idg
  521. fistp idr
  522. }
  523. #else
  524. ac = &a->colors[0];
  525. bc = &b->colors[0];
  526. dr = (bc->r - ac->r) * invLength * pRc->rScale;
  527. dg = (bc->g - ac->g) * invLength * pRc->gScale;
  528. db = (bc->b - ac->b) * invLength * pRc->bScale;
  529. iRStart = FTOL(ac->r * pRc->rScale);
  530. iGStart = FTOL(ac->g * pRc->gScale);
  531. iBStart = FTOL(ac->b * pRc->bScale);
  532. idr = FTOL(dr);
  533. idg = FTOL(dg);
  534. idb = FTOL(db);
  535. #endif
  536. CP_WRITE(pjBase, DWG_DR6, idr);
  537. CP_WRITE(pjBase, DWG_DR7, idr);
  538. CP_WRITE(pjBase, DWG_DR10, idg);
  539. CP_WRITE(pjBase, DWG_DR11, idg);
  540. CP_WRITE(pjBase, DWG_DR14, idb);
  541. CP_WRITE(pjBase, DWG_DR15, idb);
  542. CP_WRITE(pjBase, DWG_DR4, iRStart);
  543. CP_WRITE(pjBase, DWG_DR8, iGStart);
  544. CP_START(pjBase, DWG_DR12, iBStart);
  545. clipLine:
  546. while (--clipNum) {
  547. (*pRc->HWSetupClipRect)(pRc, pClip++);
  548. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 7);
  549. CP_WRITE(pjBase, DWG_DR4, iRStart);
  550. CP_WRITE(pjBase, DWG_DR8, iGStart);
  551. CP_WRITE(pjBase, DWG_DR12, iBStart);
  552. CP_WRITE(pjBase, DWG_DR0, iZStart.LowPart);
  553. CP_WRITE(pjBase, DWG_AR1, err);
  554. CP_WRITE(pjBase, DWG_XDST, (ix0 + pRc->xOffset) & 0xffff);
  555. CP_START(pjBase, DWG_YDSTLEN, ((iy0 + pRc->yOffset) << 16) | numPixels);
  556. }
  557. return;
  558. shortLine:
  559. __MCD_FLOAT_SIMPLE_END_DIVIDE(invLength);
  560. // all we will be drawing is a single pixel, so don't bother with
  561. // the color or z interpolants:
  562. if (pRc->privateEnables & __MCDENABLE_Z) {
  563. #if _X86_ && ASM_ACCEL
  564. _asm {
  565. mov ecx, a
  566. mov edx, pRc
  567. lea eax, [OFFSET(MCDVERTEX.colors) + ecx]
  568. fld DWORD PTR [OFFSET(DEVRC.rScale)][edx]
  569. fmul DWORD PTR [OFFSET(MCDCOLOR.r)][eax]
  570. fld DWORD PTR [OFFSET(DEVRC.gScale)][edx]
  571. fmul DWORD PTR [OFFSET(MCDCOLOR.g)][eax]
  572. fld DWORD PTR [OFFSET(DEVRC.bScale)][edx]
  573. fmul DWORD PTR [OFFSET(MCDCOLOR.b)][eax]
  574. fld DWORD PTR [OFFSET(MCDVERTEX.windowCoord.z)][ecx]
  575. fmul DWORD PTR [OFFSET(DEVRC.zScale)][edx] // z b g r
  576. fxch ST(3) // r b g z
  577. fistp iRStart
  578. fistp iBStart
  579. fistp iGStart
  580. fistp iZStart
  581. }
  582. #else
  583. ac = &a->colors[0];
  584. iRStart = FTOL(ac->r * pRc->rScale);
  585. iGStart = FTOL(ac->g * pRc->gScale);
  586. iBStart = FTOL(ac->b * pRc->bScale);
  587. iZStart.LowPart = FTOL(a->windowCoord.z * pRc->zScale);
  588. #endif
  589. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 6);
  590. CP_WRITE(pjBase, DWG_DR0, iZStart.LowPart);
  591. } else {
  592. #if _X86_ && ASM_ACCEL
  593. _asm{
  594. mov eax, a
  595. mov edx, pRc
  596. lea eax, [OFFSET(MCDVERTEX.colors) + eax]
  597. fld DWORD PTr [OFFSET(DEVRC.rScale)][edx]
  598. fmul DWORD PTR [OFFSET(MCDCOLOR.r)][eax]
  599. fld DWORD PTr [OFFSET(DEVRC.gScale)][edx]
  600. fmul DWORD PTR [OFFSET(MCDCOLOR.g)][eax]
  601. fld DWORD PTr [OFFSET(DEVRC.bScale)][edx] // b g r
  602. fmul DWORD PTR [OFFSET(MCDCOLOR.b)][eax]
  603. fxch ST(2) // r g b
  604. fistp iRStart
  605. fistp iGStart
  606. fistp iBStart
  607. }
  608. #else
  609. ac = &a->colors[0];
  610. iRStart = FTOL(ac->r * pRc->rScale);
  611. iGStart = FTOL(ac->g * pRc->gScale);
  612. iBStart = FTOL(ac->b * pRc->bScale);
  613. #endif
  614. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 5);
  615. }
  616. CP_WRITE(pjBase, DWG_XDST, (ix0 + pRc->xOffset) & 0xffff);
  617. CP_START(pjBase, DWG_YDSTLEN, ((iy0 + pRc->yOffset) << 16) + 1);
  618. CP_WRITE(pjBase, DWG_DR4, iRStart);
  619. CP_WRITE(pjBase, DWG_DR8, iGStart);
  620. CP_START(pjBase, DWG_DR12, iBStart);
  621. if (clipNum)
  622. goto clipLine;
  623. }
  624. VOID FASTCALL __MCDRenderGenLine(DEVRC *pRc, MCDVERTEX *pv1, MCDVERTEX *pv2, BOOL resetLine)
  625. {
  626. MCDBG_PRINT("__MCDRenderGenLine");
  627. }
  628. VOID FASTCALL __MCDRenderFlatFogLine(DEVRC *pRc, MCDVERTEX *pv1, MCDVERTEX *pv2, BOOL resetLine)
  629. {
  630. MCDCOLOR c1, c2;
  631. c1 = pv1->colors[0];
  632. c2 = pv2->colors[0];
  633. __MCDCalcFogColor(pRc, pv1, &pv1->colors[0], &c1);
  634. __MCDCalcFogColor(pRc, pv2, &pv2->colors[0], &c2);
  635. (*pRc->renderLineX)(pRc, pv1, pv2, resetLine);
  636. pv1->colors[0] = c1;
  637. pv2->colors[0] = c2;
  638. }
  639. VOID FASTCALL __MCDLineBegin(DEVRC *pRc)
  640. {
  641. BYTE *pjBase = ((PDEV *)pRc->ppdev)->pjBase;
  642. CHECK_FIFO_FREE(pjBase, pRc->cFifo, 1);
  643. CP_WRITE(pjBase, DWG_DWGCTL, pRc->hwLineFunc);
  644. }
  645. VOID FASTCALL __MCDLineEnd(DEVRC *pRc)
  646. {
  647. }