scanasm.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. #ifdef LATER
  2. //////////////////////////////////////////////////////////////////////////////
  3. //
  4. // cubic approximation using four points on the curve
  5. //
  6. //////////////////////////////////////////////////////////////////////////////
  7. if (count > 0) {
  8. BYTE* pdest = pscan + xmin * 2;
  9. const float xscale = float(count);
  10. const float x1 = 0.25f;
  11. const float x2 = 0.9f;
  12. const float g = 1 / xscale;
  13. const float g2 = g * g;
  14. const float g3 = g2 * g;
  15. const float w0 = 1 / qw;
  16. const float w1 = 1 / (qw + dqwdx * xscale * x1);
  17. const float w2 = 1 / (qw + dqwdx * xscale * x2);
  18. const float w3 = 1 / (qw + dqwdx * xscale );
  19. const float bd = 1 / (x1 * x1 - x1);
  20. const float btop = (x1 * x1 * x1 - x1);
  21. const float q = btop * bd;
  22. const float ad = x2 * x2 * x2 - q * x2 * x2 + (q - 1) * x2;
  23. // u values
  24. const float u0 = w0 * uqw;
  25. const float u3 = w3 * (uqw + duqwdx * xscale);
  26. const float uscale = u3 - u0;
  27. const float quscale = 1 / uscale;
  28. const float u1 = quscale * (w1 * (uqw + duqwdx * xscale * x1) - u0);
  29. const float u2 = quscale * (w2 * (uqw + duqwdx * xscale * x2) - u0);
  30. const float ru = (u1 - x1) * bd;
  31. const float au = (u2 - ru * x2 * x2 + (ru - 1) * x2) * ad;
  32. const float bu = (u1 - au * btop - x1) * bd;
  33. const float cu = 1 - au - bu;
  34. const int dddu = MakeFixed(uscale * (au * 12 * g3 ));
  35. int ddu = MakeFixed(uscale * (au * 6 * g3 + bu * 2 * g2 ));
  36. int du = MakeFixed(uscale * (au * g3 + bu * g2 + cu * g));
  37. int u = MakeFixed(u0);
  38. // v values
  39. const float v0 = w0 * vqw;
  40. const float v3 = w3 * (vqw + dvqwdx * xscale);
  41. const float vscale = v3 - v0;
  42. const float qvscale = 1 / vscale;
  43. const float v1 = qvscale * (w1 * (vqw + dvqwdx * xscale * x1) - v0);
  44. const float v2 = qvscale * (w2 * (vqw + dvqwdx * xscale * x2) - v0);
  45. const float rv = (v1 - x1) * bd;
  46. const float av = (v2 - rv * x2 * x2 + (rv - 1) * x2) * ad;
  47. const float bv = (v1 - av * btop - x1) * bd;
  48. const float cv = 1 - av - bv;
  49. const int dddv = MakeFixed(vscale * (av * 12 * g3 ));
  50. int ddv = MakeFixed(vscale * (av * 6 * g3 + bv * 2 * g2 ));
  51. int dv = MakeFixed(vscale * (av * g3 + bv * g2 + cv * g));
  52. int v = MakeFixed(v0);
  53. // x loop
  54. for(; count > 0; count--) {
  55. //ZAssert(u >= 0);
  56. //ZAssert(v >= 0);
  57. DWORD index = ptexture[(v >> 16) * texturePitch + (u >> 16)];
  58. *(WORD*)pdest = pcolors[index];
  59. //*(WORD*)pdest += 0x4;
  60. // x++
  61. pdest += 2;
  62. u += du;
  63. du += ddu;
  64. ddu += dddu;
  65. v += dv;
  66. dv += ddv;
  67. ddv += dddv;
  68. }
  69. }
  70. //////////////////////////////////////////////////////////////////////////////
  71. //
  72. // quadradic approximation using three points on the curve
  73. //
  74. //////////////////////////////////////////////////////////////////////////////
  75. if (count > 0) {
  76. BYTE* pdest = pscan + xmin * 2;
  77. const float x2 = float(count);
  78. const float x1 = 0.5f * x2;
  79. const float w0 = 1 / qw;
  80. const float w1 = 1 / (qw + dqwdx * x1);
  81. const float w2 = 1 / (qw + dqwdx * x2);
  82. const float u0 = w0 * uqw;
  83. const float u1 = w1 * (uqw + duqwdx * x1) - u0;
  84. const float u2 = w2 * (uqw + duqwdx * x2) - u0;
  85. const float v0 = w0 * vqw;
  86. const float v1 = w1 * (vqw + dvqwdx * x1) - v0;
  87. const float v2 = w2 * (vqw + dvqwdx * x2) - v0;
  88. float d = x1 * x2 * (x2 - x1);
  89. float au = (u2 * x1 - u1 * x2) / d;
  90. float bu = (u1 - au * x1 * x1) / x1;
  91. const int ddu = MakeFixed(2 * au);
  92. int du = MakeFixed(au + bu);
  93. int u = MakeFixed(u0);
  94. float av = (v2 * x1 - v1 * x2) / d;
  95. float bv = (v1 - av * x1 * x1) / x1;
  96. const int ddv = MakeFixed(2 * av);
  97. int dv = MakeFixed(av + bv);
  98. int v = MakeFixed(v0);
  99. for(; count > 0; count--) {
  100. ZAssert(u >= 0);
  101. ZAssert(v >= 0);
  102. DWORD index = ptexture[(v >> 16) * texturePitch + (u >> 16)];
  103. *(WORD*)pdest = pcolors[index];
  104. //*(WORD*)pdest += 0x4;
  105. // x++
  106. pdest += 2;
  107. u += du;
  108. du += ddu;
  109. v += dv;
  110. dv += ddv;
  111. }
  112. }
  113. //////////////////////////////////////////////////////////////////////////////
  114. //
  115. // quadradic taylor series approximation
  116. //
  117. //////////////////////////////////////////////////////////////////////////////
  118. if (count > 0) {
  119. BYTE* pdest = pscan + xmin * 2;
  120. const float w = 1 / qw;
  121. const float w2 = w * w;
  122. const float w3 = w2 * w;
  123. const float dqw2 = dqwdx * dqwdx;
  124. const int ddu = MakeFixed(2 * dqw2 * uqw * w3 - duqwdx * dqwdx * w + duqwdx * dqw2 * w);
  125. int du = MakeFixed(duqwdx * w - uqw * dqwdx * w2) + ddu / 2;
  126. int u = MakeFixed(uqw * w);
  127. const int ddv = MakeFixed(2 * dqw2 * vqw * w3 - dvqwdx * dqwdx * w + dvqwdx * dqw2 * w);
  128. int dv = MakeFixed(dvqwdx * w - vqw * dqwdx * w2) + ddv / 2;
  129. int v = MakeFixed(vqw * w);
  130. for(; count > 0; count--) {
  131. ZAssert(u >= 0);
  132. ZAssert(v >= 0);
  133. DWORD index = ptexture[(v >> 16) * texturePitch + (u >> 16)];
  134. *(WORD*)pdest = pcolors[index];
  135. //*(WORD*)pdest += 0x4;
  136. // x++
  137. pdest += 2;
  138. u += du;
  139. du += ddu;
  140. v += dv;
  141. dv += ddv;
  142. }
  143. }
  144. //////////////////////////////////////////////////////////////////////////////
  145. //
  146. // divide per pixel
  147. //
  148. //////////////////////////////////////////////////////////////////////////////
  149. if (count > 0) {
  150. BYTE* pdest = pscan + xmin * 2;
  151. float qwSpan = qw;
  152. float uqwSpan = uqw;
  153. float vqwSpan = vqw;
  154. for(; count > 0; count--) {
  155. const float w = 1 / qwSpan;
  156. const int u = MakeFixed(uqwSpan * w);
  157. const int v = MakeFixed(vqwSpan * w);
  158. ZAssert(u >= 0);
  159. ZAssert(v >= 0);
  160. DWORD index = ptexture[(v>>16) * texturePitch + (u>>16)];
  161. *(WORD*)pdest = pcolors[index];
  162. //*(WORD*)pdest += 0x4;
  163. // x++
  164. qwSpan += dqwdx;
  165. uqwSpan += duqwdx;
  166. vqwSpan += dvqwdx;
  167. pdest += 2;
  168. }
  169. }
  170. //////////////////////////////////////////////////////////////////////////////
  171. //
  172. // piecewise linear approximation
  173. //
  174. //////////////////////////////////////////////////////////////////////////////
  175. if (count > 0) {
  176. BYTE* pdest = pscan + xmin * 2;
  177. float qwSpan = qw + dqwdx16;
  178. float uqwSpan = uqw + duqwdx16;
  179. float vqwSpan = vqw + dvqwdx16;
  180. float w = 1 / qwSpan;
  181. int u = MakeFixed(uqw * w);
  182. int v = MakeFixed(vqw * w);
  183. ZAssert(u >= 0);
  184. ZAssert(v >= 0);
  185. while (true) {
  186. float wNext = 1 / qwSpan;
  187. int uNext = MakeFixed(uqwSpan * wNext);
  188. int vNext = MakeFixed(vqwSpan * wNext);
  189. int du = (uNext - u) / 16;
  190. int dv = (vNext - v) / 16;
  191. int insideCount = count;
  192. if (insideCount > 16) {
  193. insideCount = 16;
  194. }
  195. for(; insideCount > 0; insideCount--) {
  196. DWORD index = ptexture[(v>>16) * texturePitch + (u>>16)];
  197. *(WORD*)pdest = pcolors[index];
  198. //*(WORD*)pdest += 0x4;
  199. // x++
  200. u += du;
  201. v += dv;
  202. pdest += 2;
  203. }
  204. count -= 16;
  205. if (count <= 0) break;
  206. // x += 16
  207. u = uNext;
  208. v = vNext;
  209. qwSpan += dqwdx16 ;
  210. uqwSpan += duqwdx16;
  211. vqwSpan += dvqwdx16;
  212. }
  213. }
  214. //////////////////////////////////////////////////////////////////////////////
  215. //
  216. // rgb texture
  217. //
  218. //////////////////////////////////////////////////////////////////////////////
  219. DWORD rTexture = colors[index].r;
  220. DWORD gTexture = colors[index].g;
  221. DWORD bTexture = colors[index].b;
  222. DWORD rFinal = (rTexture >> 16) & redMask;
  223. DWORD gFinal = (gTexture >> 16) & greenMask;
  224. DWORD bFinal = (bTexture >> 16);
  225. *(WORD*)pdest = (WORD)(rFinal | gFinal | bFinal);
  226. WORD word = *(WORD*)pdest;
  227. *(WORD*)pdest = (word << 5) + 0x1f;
  228. //////////////////////////////////////////////////////////////////////////////
  229. //
  230. // This routine doesn't support perspective correct textures
  231. //
  232. //////////////////////////////////////////////////////////////////////////////
  233. void ScanWindow::FillSubTriangle(
  234. float fymin,
  235. float fymax,
  236. float fxmin0,
  237. float fxmax0,
  238. float fxmin1,
  239. float fxmax1
  240. ) {
  241. const DWORD ymin = fymin;
  242. const DWORD ymax = fymax;
  243. const float qdy = 1 / (fymax - fymin);
  244. DWORD xmin = MakeFixed(fxmin0);
  245. DWORD xmax = MakeFixed(fxmax0);
  246. const int dxmin = MakeFixed((fxmin1 - fxmin0) * qdy);
  247. const int dxmax = MakeFixed((fxmax1 - fxmax0) * qdy);
  248. const DWORD dqwdx = MakeFixed(m_dqwdy + m_dqwdx * (fxmin1 - fxmin0) * qdy);
  249. const DWORD duqwdx = MakeFixed(m_duqwdy + m_duqwdx * (fxmin1 - fxmin0) * qdy);
  250. const DWORD dvqwdx = MakeFixed(m_dvqwdy + m_dvqwdx * (fxmin1 - fxmin0) * qdy);
  251. DWORD uqw = MakeFixed(m_uqw);
  252. DWORD vqw = MakeFixed(m_vqw);
  253. DWORD du = MakeFixed(m_duqwdx);
  254. DWORD dv = MakeFixed(m_dvqwdx);
  255. //
  256. // save members on stack
  257. //
  258. const WORD* pcolors = m_pcolors;
  259. const BYTE* ptexture = m_ptexture;
  260. const DWORD texturePitch = m_texturePitch;
  261. const DWORD pitch = m_pitch;
  262. //
  263. // pixel format
  264. //
  265. const DWORD redMask = 0x1f << 11;
  266. const DWORD greenMask = 0x3f << 5;
  267. const DWORD blueMask = 0x1f;
  268. //
  269. // fill the triangle
  270. //
  271. BYTE* pscan = m_pdata + ymin * m_pitch;
  272. if (true) {
  273. DWORD ycount = ymax - ymin;
  274. // eax - work
  275. // ebx - work
  276. //
  277. // ecx - u
  278. // edx - v
  279. // edi - pdest
  280. // esi - count
  281. // - ptexture
  282. // - pcolors
  283. // - texturePitch
  284. __asm {
  285. // for (DWORD y = ymin; y < ymax; y++) {
  286. // if (count > 0) {
  287. // BYTE* pdest = pscan + HIWORD(xmin) * 2;
  288. mov eax, xmin
  289. mov esi, xmax
  290. mov ecx, uqw
  291. mov edx, vqw
  292. mov edi, pscan
  293. jmp skipdelta
  294. labely:
  295. // uqw += duqwdx;
  296. // vqw += dvqwdx;
  297. // xmin += dxmin;
  298. // xmax += dxmax;
  299. // pscan += pitch;
  300. mov esi, xmax
  301. mov ebx, dxmax
  302. add esi, ebx
  303. mov xmax, esi
  304. mov eax, xmin
  305. mov ebx, dxmin
  306. add eax, ebx
  307. mov xmin, eax
  308. mov edi, pscan
  309. mov ebx, pitch
  310. add edi, ebx
  311. mov pscan, edi
  312. mov ecx, uqw
  313. mov ebx, duqwdx
  314. add ecx, ebx
  315. mov uqw, ecx
  316. mov edx, vqw
  317. mov ebx, dvqwdx
  318. add edx, ebx
  319. mov vqw, edx
  320. skipdelta:
  321. // int count = (HIWORD(xmax) - HIWORD(xmin)) * 2;
  322. // BYTE* pdest = pscan + HIWORD(xmin) * 2;
  323. shr esi, 10h
  324. shr eax, 10h
  325. sub esi, eax
  326. je nextscan
  327. lea edi, [edi + eax * 2]
  328. labelx:
  329. // DWORD index = ptexture[(v>>16) * texturePitch + (u>>16)];
  330. mov eax, ecx
  331. shr eax, 10h
  332. mov ebx, edx
  333. shr ebx, 10h
  334. add ebx, ptexture
  335. movsx eax, byte ptr [ebx + eax * 8]
  336. // *(WORD*)pdest = pcolors[index];
  337. mov ebx, pcolors
  338. mov ax, word ptr [ebx + eax * 2]
  339. mov word ptr [edi], ax
  340. // u += du;
  341. // v += dv;
  342. // pdest += 2;
  343. add ecx, du
  344. add edx, dv
  345. add edi, 2
  346. // count--
  347. dec esi
  348. jne labelx
  349. // ycount--
  350. nextscan:
  351. dec ycount
  352. jne labely
  353. }
  354. } else if (true) {
  355. for (DWORD y = ymin; y < ymax; y++) {
  356. int count = HIWORD(xmax) - HIWORD(xmin);
  357. if (count > 0) {
  358. BYTE* pdest = pscan + HIWORD(xmin) * 2;
  359. DWORD u = uqw;
  360. DWORD v = vqw;
  361. for (; count > 0; count--) {
  362. DWORD index = ptexture[(v>>16) * 8 /*texturePitch*/ + (u>>16)];
  363. *(WORD*)pdest = pcolors[index];
  364. // x++
  365. u += du;
  366. v += dv;
  367. pdest += 2;
  368. }
  369. }
  370. // y++
  371. uqw += duqwdx;
  372. vqw += dvqwdx;
  373. xmin += dxmin;
  374. xmax += dxmax;
  375. pscan += pitch;
  376. }
  377. }
  378. }
  379. #endif