Leaked source code of windows server 2003
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.

1567 lines
33 KiB

  1. ;---------------------------Module-Header------------------------------;
  2. ; Module Name: texspan.asm
  3. ;
  4. ; Include file for "body" of texture routines.
  5. ;
  6. ; Created: 011/15/1995
  7. ; Author: Otto Berkes [ottob]
  8. ;
  9. ; Copyright (c) 1995 Microsoft Corporation
  10. ;----------------------------------------------------------------------;
  11. rMask = ((1 SHL rBits) - 1) SHL rShift
  12. gMask = ((1 SHL gBits) - 1) SHL gShift
  13. bMask = ((1 SHL bBits) - 1) SHL bShift
  14. if REPLACE
  15. rRightShiftAdj = 16 - (rShift + rBits)
  16. gRightShiftAdj = 16 - (gShift + gBits)
  17. bRightShiftAdj = 16 - (bShift + bBits)
  18. else
  19. rRightShiftAdj = 16 - (rShift)
  20. gRightShiftAdj = 16 - (gShift)
  21. bRightShiftAdj = 16 - (bShift)
  22. endif
  23. TMASK_SUBDIV equ [esi].GENGC_tMaskSubDiv
  24. TSHIFT_SUBDIV equ [esi].GENGC_tShiftSubDiv
  25. if FAST_REPLACE
  26. TEXPALETTE equ [esi].GENGC_texImageReplace
  27. if (PALETTE_ONLY)
  28. TEXIMAGE equ [esi].GENGC_texImage
  29. else
  30. TEXIMAGE equ [esi].GENGC_texImageReplace
  31. endif
  32. if PALETTE_ONLY
  33. TEX_BPP_LOG2 = 0
  34. elseif (BPP eq 8)
  35. TEX_BPP_LOG2 = 0
  36. else
  37. TEX_BPP_LOG2 = 1
  38. endif
  39. else
  40. TEXPALETTE equ [esi].GENGC_texPalette
  41. TEXIMAGE equ [esi].GENGC_texImage
  42. if PALETTE_ONLY
  43. TEX_BPP_LOG2 = 0
  44. else
  45. TEX_BPP_LOG2 = 2
  46. endif
  47. endif
  48. ;;
  49. ;;
  50. ;; Macros for alpha modulation, and alpha reads
  51. ;;
  52. ;;
  53. ALPHAMODULATE MACRO
  54. mov ah, [esi].GENGC_aAccum+2
  55. mov al, [edx+3]
  56. and eax, 0ffffh
  57. mov ch, _gbMulTable[eax]
  58. mov [esi].GENGC_aDisplay, ch
  59. ENDM
  60. ALPHANOMODULATE MACRO
  61. mov ch, [edx+3]
  62. mov [esi].GENGC_aDisplay, ch
  63. ENDM
  64. ;; There are AGIs and other nasties in the alpha-read code. There's
  65. ;; not much we can really do, unfortunately...
  66. if (BPP eq 8)
  67. ALPHAREAD MACRO
  68. xor eax, eax
  69. mov al, [ebx]
  70. mov ebx, [esi].GENGC_pInvTranslateVector
  71. mov cl, 0ffh
  72. mov al, [ebx+eax]
  73. mov ebx, eax
  74. and ebx, rMask
  75. sub cl, ch
  76. shl ebx, gBits + bBits
  77. mov bh, cl
  78. mov ch, _gbMulTable[ebx]
  79. mov ebx, eax
  80. mov [esi].GENGC_rDisplay, ch
  81. and ebx, gMask
  82. shl ebx, bBits
  83. mov bh, cl
  84. mov ch, _gbMulTable[ebx]
  85. mov ebx, eax
  86. mov [esi].GENGC_gDisplay, ch
  87. and ebx, bMask
  88. mov bh, cl
  89. mov ch, _gbMulTable[ebx]
  90. mov [esi].GENGC_bDisplay, ch
  91. ENDM
  92. endif
  93. if (BPP eq 16)
  94. ALPHAREAD MACRO
  95. mov ax, [ebx]
  96. mov cl, 0ffh
  97. mov ebx, eax
  98. and ebx, rMask
  99. sub cl, ch
  100. shr ebx, rShift - (8 - rBits)
  101. mov bh, cl
  102. mov ch, _gbMulTable[ebx]
  103. mov ebx, eax
  104. mov [esi].GENGC_rDisplay, ch
  105. and ebx, gMask
  106. shr ebx, gShift - (8 - gBits)
  107. mov bh, cl
  108. mov ch, _gbMulTable[ebx]
  109. mov ebx, eax
  110. mov [esi].GENGC_gDisplay, ch
  111. and ebx, bMask
  112. shl ebx, (8 - bBits)
  113. mov bh, cl
  114. mov ch, _gbMulTable[ebx]
  115. mov [esi].GENGC_bDisplay, ch
  116. ENDM
  117. elseif (BPP eq 32)
  118. ALPHAREAD MACRO
  119. xor eax, eax
  120. mov cl, 0ffh
  121. mov al, [ebx+2]
  122. sub cl, ch
  123. mov ah, cl
  124. mov al, _gbMulTable[eax]
  125. mov [esi].GENGC_rDisplay, al
  126. mov al, [ebx+1]
  127. mov ah, cl
  128. mov al, _gbMulTable[eax]
  129. mov [esi].GENGC_gDisplay, al
  130. mov al, [ebx]
  131. mov ah, cl
  132. mov al, _gbMulTable[eax]
  133. mov [esi].GENGC_bDisplay, al
  134. ENDM
  135. endif
  136. ;;
  137. ;;
  138. ;; Macros for advancing a single pixel unit
  139. ;;
  140. ;;
  141. if (BPP eq 8)
  142. PIXADVANCE MACRO var
  143. inc var
  144. ENDM
  145. elseif (BPP eq 16)
  146. PIXADVANCE MACRO var
  147. add var, (BPP / 8)
  148. ENDM
  149. else
  150. PIXADVANCE MACRO var
  151. add var, [esi].GENGC_bytesPerPixel
  152. ENDM
  153. endif
  154. if (BPP le 16)
  155. PIXADVANCE2 MACRO var1, var2
  156. lea var1, [var2 + (BPP / 8)]
  157. ENDM
  158. else
  159. PIXADVANCE2 MACRO var1, var2
  160. mov var1, var2
  161. add var1, [esi].GENGC_bytesPerPixel
  162. ENDM
  163. endif
  164. ;;
  165. ;;
  166. ;; Macros for advancing the accumulators if the z-buffer test fails:
  167. ;;
  168. ;;
  169. if FAST_REPLACE
  170. ZBUFFER_FAIL_ADVANCE MACRO
  171. mov ecx, [esi].GENGC_zAccum ;U
  172. mov eax, [esi].GENGC_SPAN_dz ; V
  173. mov ebx, [esi].GENGC_pixAccum ;U
  174. add edi, 2 ; V
  175. add ecx, eax ;U
  176. PIXADVANCE ebx ; V
  177. sub ebp, 010001h ;U
  178. mov [esi].GENGC_zAccum, ecx ; V
  179. mov [esi].GENGC_pixAccum, ebx ;U
  180. jl doSubDiv ; V
  181. test ebp, 08000h ;U
  182. je loopTopNoDiv ; V
  183. jmp spanExit
  184. ENDM
  185. elseif REPLACE
  186. ZBUFFER_FAIL_ADVANCE MACRO
  187. mov ecx, [esi].GENGC_zAccum ;U
  188. mov eax, [esi].GENGC_SPAN_dz ; V
  189. add edi, 2 ;U
  190. add ecx, eax ; V
  191. mov eax, [esi].GENGC_ditherAccum ;U
  192. mov ebx, [esi].GENGC_pixAccum ; V
  193. ror eax, 8 ;U
  194. mov [esi].GENGC_zAccum, ecx ; V
  195. PIXADVANCE ebx ;U
  196. sub ebp, 010001h ; V
  197. mov [esi].GENGC_pixAccum, ebx ;U
  198. mov [esi].GENGC_ditherAccum, eax ; V
  199. jl doSubDiv ;U
  200. test ebp, 08000h ; V
  201. je loopTopNoDiv ;U
  202. jmp spanExit ; V
  203. ENDM
  204. elseif FLAT_SHADING
  205. ZBUFFER_FAIL_ADVANCE MACRO
  206. mov ecx, [esi].GENGC_zAccum ;U
  207. mov eax, [esi].GENGC_SPAN_dz ; V
  208. add edi, 2 ;U
  209. add ecx, eax ; V
  210. mov ebx, [esi].GENGC_pixAccum ;U
  211. mov eax, [esi].GENGC_ditherAccum ; V
  212. mov [esi].GENGC_zAccum, ecx ;U
  213. PIXADVANCE ebx ; V
  214. ror eax, 8 ;U
  215. sub ebp, 010001h ; V
  216. mov [esi].GENGC_pixAccum, ebx ;U
  217. mov [esi].GENGC_ditherAccum, eax ; V
  218. jl doSubDiv ;U
  219. test ebp, 08000h ; V
  220. je loopTopNoDiv ;U
  221. jmp spanExit
  222. ENDM
  223. elseif SMOOTH_SHADING
  224. ZBUFFER_FAIL_ADVANCE MACRO
  225. mov ecx, [esi].GENGC_zAccum ;U
  226. mov eax, [esi].GENGC_SPAN_dz ; V
  227. add edi, 2 ;U
  228. add ecx, eax ; V
  229. mov eax, [esi].GENGC_rAccum ;U
  230. mov [esi].GENGC_zAccum, ecx ; V
  231. mov ebx, [esi].GENGC_SPAN_dr ;U
  232. mov ecx, [esi].GENGC_gAccum ; V
  233. add eax, ebx ;U
  234. mov edx, [esi].GENGC_SPAN_dg ; V
  235. mov [esi].GENGC_rAccum, eax ;U
  236. add ecx, edx ; V
  237. mov eax, [esi].GENGC_bAccum ;U
  238. mov ebx, [esi].GENGC_SPAN_db ; V
  239. mov [esi].GENGC_gAccum, ecx ;U
  240. add ebx, eax ; V
  241. mov eax, [esi].GENGC_ditherAccum ;U
  242. mov [esi].GENGC_bAccum, ebx ; V
  243. ror eax, 8 ;U
  244. if ALPHA
  245. mov ecx, [esi].GENGC_aAccum
  246. endif
  247. mov ebx, [esi].GENGC_pixAccum ;U
  248. if ALPHA
  249. add ecx, [esi].GENGC_SPAN_da
  250. endif
  251. PIXADVANCE ebx ;U
  252. if ALPHA
  253. mov [esi].GENGC_aAccum, ecx
  254. endif
  255. mov [esi].GENGC_pixAccum, ebx ; V
  256. sub ebp, 010001h ;U
  257. mov [esi].GENGC_ditherAccum, eax ; V
  258. jl doSubDiv ;U
  259. test ebp, 08000h ; V
  260. je loopTopNoDiv ;U
  261. jmp spanExit ; V
  262. ENDM
  263. endif
  264. ;;----------------------------------------------------------------------
  265. ;;
  266. ;; This is the start of the texture routine. Kick off the divide, and use
  267. ;; the dead time to set up all of the accumulators and other variables.
  268. ;;
  269. ;;----------------------------------------------------------------------
  270. ZBUFFER_EARLY_OUT = 1
  271. if ZBUFFER
  272. push ebx ;U
  273. push esi ; V
  274. push edi ;U
  275. push ebp ; V
  276. if ZBUFFER_EARLY_OUT
  277. mov edi, [ecx].GENGC_SPAN_zbuf ;U
  278. mov esi, [ecx].GENGC_SPAN_z ; V
  279. mov edx, [ecx].GENGC_SPAN_length ;U
  280. mov ebp, [ecx].GENGC_SPAN_dz ; V
  281. @zLoop:
  282. mov ebx, esi ;U
  283. mov eax, [edi] ; V
  284. shr ebx, 16 ;U
  285. and eax, 0ffffh ; V
  286. cmp ebx, eax ;U
  287. if ZCMP_L
  288. jl @zFirstWrite ; V
  289. else
  290. jle @zFirstWrite ; V
  291. endif
  292. add edi, 2 ;U
  293. add esi, ebp ; V
  294. dec edx ;U
  295. jne @zLoop ; V
  296. pop ebp
  297. pop edi
  298. pop esi
  299. pop ebx
  300. ret 0
  301. @zFirstWrite:
  302. endif ;; ZBUFFER_EARLY_OUT
  303. endif ;; ZBUFFER
  304. ;;
  305. ;; Start the divide:
  306. ;;
  307. mov eax, [ecx].GENGC_flags
  308. fld DWORD PTR [ecx].GENGC_SPAN_qw ;qwAccum
  309. fld DWORD PTR [ecx].GENGC_SPAN_qw ;qwAccum qwAccum
  310. test eax, GEN_TEXTURE_ORTHO
  311. jne @f
  312. fdivr __One ;1/qw qwAccum
  313. @@:
  314. ;;
  315. ;; Save the registers that we need to:
  316. ;;
  317. if ZBUFFER
  318. else
  319. push ebx ;U
  320. push esi ; V
  321. push edi ;U
  322. push ebp ; V
  323. endif
  324. mov esi, ecx ;U
  325. ;;
  326. ;; Set up accumulators:
  327. ;;
  328. if FAST_REPLACE
  329. if ZBUFFER
  330. mov eax, [esi].GENGC_SPAN_z ; V
  331. endif
  332. mov ebx, [esi].GENGC_SPAN_s ;U
  333. mov ecx, [esi].GENGC_SPAN_t ; V
  334. if ZBUFFER
  335. mov [esi].GENGC_zAccum, eax ;U
  336. endif
  337. mov [esi].GENGC_sAccum, ebx ; V
  338. mov [esi].GENGC_tAccum, ecx ;U
  339. mov ebx, [esi].GENGC_SPAN_qw ; V
  340. mov eax, [esi].GENGC_SPAN_y ;U
  341. mov [esi].GENGC_qwAccum, ebx ; V
  342. mov edx, [esi].GENGC_SPAN_ppix ;U
  343. mov edi, [esi].GENGC_flags ; V
  344. mov ebx, [esi].GENGC_SPAN_x ;U
  345. test edi, SURFACE_TYPE_DIB ; V
  346. jne @f ;U
  347. mov edx, [esi].GENGC_ColorsBits ; V
  348. jmp short @pixAccumDone
  349. @@:
  350. if (BPP eq 8)
  351. add edx, ebx ;U
  352. elseif (BPP eq 16)
  353. lea edx, [edx + 2*ebx]
  354. else
  355. lea edx, [edx + 4*ebx]
  356. cmp [esi].GENGC_bpp, 32
  357. je @f
  358. sub edx, ebx
  359. @@:
  360. endif
  361. @pixAccumDone:
  362. test edi, GEN_TEXTURE_ORTHO ; V
  363. mov ebp, [esi].GENGC_SPAN_length ;U
  364. je @f ; V
  365. else
  366. if REPLACE
  367. else
  368. ;; Handle RGB accumulators
  369. if FLAT_SHADING
  370. mov eax, [ecx].GENGC_SPAN_r ;U
  371. mov ebx, [ecx].GENGC_SPAN_g ; V
  372. shr eax, rBits ;U
  373. mov ecx, [esi].GENGC_SPAN_b ; V
  374. shr ebx, gBits ;U
  375. and eax, 0ff00h ; V
  376. shr ecx, bBits ;U
  377. and ebx, 0ff00h ; V
  378. and ecx, 0ff00h ;U
  379. mov [esi].GENGC_rAccum, eax ; V
  380. mov [esi].GENGC_gAccum, ebx ;U
  381. mov [esi].GENGC_bAccum, ecx ; V
  382. else
  383. mov eax, [ecx].GENGC_SPAN_r ;U
  384. mov ebx, [ecx].GENGC_SPAN_g ; V
  385. mov ecx, [esi].GENGC_SPAN_b ;U
  386. mov [esi].GENGC_rAccum, eax ; V
  387. mov [esi].GENGC_gAccum, ebx ;U
  388. mov [esi].GENGC_bAccum, ecx ; V
  389. endif ;; FLAT_SHADING
  390. endif ;; NOT REPLACE
  391. if ZBUFFER
  392. mov eax, [esi].GENGC_SPAN_z ; V
  393. endif
  394. mov ebx, [esi].GENGC_SPAN_s ;U
  395. mov ecx, [esi].GENGC_SPAN_t ; V
  396. if ZBUFFER
  397. mov [esi].GENGC_zAccum, eax ;U
  398. endif
  399. mov [esi].GENGC_sAccum, ebx ; V
  400. mov [esi].GENGC_tAccum, ecx ;U
  401. mov ebx, [esi].GENGC_SPAN_qw ; V
  402. mov eax, [esi].GENGC_SPAN_y ;U
  403. mov [esi].GENGC_qwAccum, ebx ; V
  404. and eax, 03h ;U
  405. mov ecx, [esi].GENGC_SPAN_x ; V
  406. lea eax, [eax*4 + offset dither0] ;U
  407. lea ecx, [ecx*8] ; V
  408. mov edx, [esi].GENGC_SPAN_ppix ;U
  409. mov edi, [esi].GENGC_flags ; V
  410. mov ebx, [esi].GENGC_SPAN_x ;U
  411. test edi, SURFACE_TYPE_DIB ; V
  412. jne @f ;U
  413. mov edx, [esi].GENGC_ColorsBits ; V
  414. jmp short @pixAccumDone
  415. @@:
  416. if (BPP eq 8)
  417. add edx, ebx ;U
  418. elseif (BPP eq 16)
  419. lea edx, [edx + 2*ebx]
  420. else
  421. lea edx, [edx + 4*ebx]
  422. cmp [esi].GENGC_bpp, 32
  423. je @f
  424. sub edx, ebx
  425. @@:
  426. endif
  427. @pixAccumDone:
  428. mov eax, [eax] ; V
  429. and ecx, 018h ;U
  430. test edi, GEN_TEXTURE_ORTHO ; V
  431. mov ebp, [esi].GENGC_SPAN_length ;U
  432. je @f ; V
  433. endif
  434. mov edi, [esi].GENGC_sAccum ; V
  435. mov ebx, [esi].GENGC_tAccum ;U
  436. mov DWORD PTR [esi].GENGC_sResult, edi ; V
  437. mov DWORD PTR [esi].GENGC_tResult, ebx ;U
  438. mov edi, [esi].GENGC_flags ; V
  439. jmp short @stResultDone1 ;U
  440. ;;
  441. ;; Kick off the next divide:
  442. ;;
  443. @@:
  444. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  445. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  446. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  447. fmulp ST(2), ST ; s/qw t/qw qwAccum
  448. fistp QWORD PTR [esi].GENGC_sResult ; t/qw qwAccum
  449. fistp QWORD PTR [esi].GENGC_tResult ; qwAccum
  450. fadd DWORD PTR [esi].GENGC_qwStepX ; qwAccum
  451. fld ST(0) ; qwAccum qwAccum
  452. fdivr __One ; 1/qw qwAccum
  453. @stResultDone1:
  454. ror eax, cl ;UV (4)
  455. add ebp, 070000h ;U
  456. mov [esi].GENGC_ditherAccum, eax ; V
  457. dec ebp ;U
  458. mov [esi].GENGC_pixAccum, edx ; V
  459. mov eax, [esi].GENGC_sAccum ;U
  460. mov ebx, [esi].GENGC_tAccum ; V
  461. add eax, [esi].GENGC_sStepX ;U
  462. add ebx, [esi].GENGC_tStepX ; V
  463. mov [esi].GENGC_sAccum, eax ;U
  464. mov [esi].GENGC_tAccum, ebx ; V
  465. mov eax, [esi].GENGC_sResult ;U
  466. mov ebx, [esi].GENGC_tResult ; V
  467. mov cl, TSHIFT_SUBDIV ;U
  468. sar ebx, cl ;UV (4)
  469. and ebx, NOT 7 ;U
  470. if ALPHA
  471. mov ecx, [esi].GENGC_SPAN_a
  472. endif
  473. test edi, GEN_TEXTURE_ORTHO ; V
  474. mov [esi].GENGC_tResult, ebx ;U
  475. if ALPHA
  476. mov [esi].GENGC_aAccum, ecx
  477. endif
  478. je @f
  479. mov ecx, [esi].GENGC_sAccum ; V
  480. mov edx, [esi].GENGC_tAccum ;U
  481. mov DWORD PTR [esi].GENGC_sResultNew, ecx ; V
  482. mov DWORD PTR [esi].GENGC_tResultNew, edx ;U
  483. jmp short @stResultDone2 ; V
  484. @@:
  485. ;; We may have to burn some cycles here...
  486. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  487. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  488. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  489. fmulp ST(2), ST ; s/qw t/qw qwAccum
  490. fistp QWORD PTR [esi].GENGC_sResultNew; t/qw qwAccum
  491. fistp QWORD PTR [esi].GENGC_tResultNew; qwAccum
  492. fadd DWORD PTR [esi].GENGC_qwStepX ; qwAccum
  493. @stResultDone2:
  494. mov cl, TSHIFT_SUBDIV ;U
  495. mov edx, [esi].GENGC_tResultNew ; V
  496. sar edx, cl ;UV (4)
  497. and edx, NOT 7 ;U
  498. mov ecx, [esi].GENGC_sResultNew ; V
  499. mov [esi].GENGC_tResultNew, edx ;U
  500. sub ecx, eax ; V
  501. sar ecx, 3 ;U
  502. sub edx, ebx ; V
  503. sar edx, 3 ;U
  504. mov [esi].GENGC_subDs, ecx ; V
  505. mov [esi].GENGC_subDt, edx ;U
  506. mov eax, [esi].GENGC_flags ; V
  507. mov edi, [esi].GENGC_SPAN_zbuf ;U
  508. loopTop:
  509. ;;
  510. ;; This is the start of the outer loop. We come back here on each
  511. ;; subdivision. The key thing is to kick off the next divide:
  512. ;;
  513. test eax, GEN_TEXTURE_ORTHO ; V
  514. jne @f ;U
  515. fld ST(0) ; qwAccum qwAccum
  516. fadd DWORD PTR [esi].GENGC_qwStepX ; qwAccum+ qwAccum
  517. fxch ST(1) ; qwAccum qwAccum+
  518. fdivr __One ; 1/qw qwAccum+ -- let the divide rip!
  519. @@:
  520. loopTopNoDiv:
  521. ;;
  522. ;; This is the start of the inner loop. This is where the pixel-level
  523. ;; work happens:
  524. ;;
  525. ;;
  526. ;; First, do z-buffering is enabled:
  527. ;;
  528. if ZBUFFER
  529. mov eax, [edi] ;U
  530. mov ebx, [esi].GENGC_zAccum ; V
  531. shr ebx, 16 ;U
  532. and eax, 0ffffh ; V
  533. cmp ebx, eax ;U
  534. if ZCMP_L
  535. jl @zWrite ; V
  536. else
  537. jle @zWrite ; V
  538. endif
  539. ZBUFFER_FAIL_ADVANCE
  540. @zWrite:
  541. mov [edi], bx ;UV
  542. endif ;;ZBUFFER
  543. ;;
  544. ;; Now, get pointer to current texel value in EDX. There are two cases,
  545. ;; one if there is a palette-lookup, and one if we index straight into
  546. ;; the texture.
  547. ;;
  548. if PALETTE_ENABLED
  549. mov ecx, TEXPALETTE ;U
  550. mov eax, TMASK_SUBDIV ; V
  551. test ecx, ecx ;U
  552. je @noPalette ; V
  553. mov edx, [esi].GENGC_tResult ; V
  554. mov ebx, [esi].GENGC_sResult ;U
  555. and edx, eax ; V
  556. mov eax, [esi].GENGC_sMask ;U
  557. and ebx, eax ; V
  558. shr edx, 6 ;U
  559. mov eax, DWORD PTR [esi].GENGC_sResult ; V
  560. shr ebx, 16 ;U
  561. mov ecx, TEXIMAGE ; V
  562. add edx, ecx ;U
  563. add eax, [esi].GENGC_subDs ; V
  564. mov ecx, DWORD PTR [esi].GENGC_tResult ;U
  565. add edx, ebx ; V
  566. add ecx, [esi].GENGC_subDt ;U
  567. mov DWORD PTR [esi].GENGC_sResult, eax ; V
  568. xor eax, eax ;U
  569. mov ebx, TEXPALETTE ; V
  570. mov DWORD PTR [esi].GENGC_tResult, ecx ;U
  571. mov al, [edx] ; V
  572. lea edx, [ebx+4*eax] ;U
  573. jmp short @paletteDone ; V
  574. @noPalette:
  575. endif ;;PALETTE_ENABLED
  576. mov eax, TMASK_SUBDIV ;U
  577. mov edx, [esi].GENGC_tResult ; V
  578. mov ebx, [esi].GENGC_sResult ;U
  579. and edx, eax ; V
  580. shr edx, (6-TEX_BPP_LOG2) ;U
  581. mov ecx, [esi].GENGC_sMask ; V
  582. and ebx, ecx ;U
  583. mov eax, DWORD PTR [esi].GENGC_sResult ; V
  584. shr ebx, (16-TEX_BPP_LOG2) ;U
  585. mov ecx, [esi].GENGC_subDs ; V
  586. add eax, ecx ;U
  587. add edx, ebx ; V
  588. mov ecx, TEXIMAGE ;U
  589. mov ebx, [esi].GENGC_subDt ; V
  590. add edx, ecx ;U
  591. mov ecx, DWORD PTR [esi].GENGC_tResult ; V
  592. add ecx, ebx ;U
  593. mov DWORD PTR [esi].GENGC_sResult, eax ; V
  594. mov DWORD PTR [esi].GENGC_tResult, ecx ;U
  595. if (PALETTE_ONLY)
  596. mov al, [edx] ; V
  597. and eax, 0ffh ;U
  598. mov ebx, TEXPALETTE ; V
  599. lea edx, [ebx+4*eax] ;U
  600. endif
  601. @paletteDone:
  602. ;;
  603. ;; We are now ready to handle each of the 4 basic modes on a case-by-case
  604. ;; basis. We will generally try to adhere to the following register
  605. ;; usage:
  606. ;; eax - red
  607. ;; ebx - green
  608. ;; ecx - blue
  609. ;; ebx, edx - framebuffer pointers
  610. ;;
  611. if FAST_REPLACE
  612. ;;----------------------------------------------------------------------
  613. ;;
  614. ;; ** Replace mode (compressed)
  615. ;;
  616. ;;----------------------------------------------------------------------
  617. if ALPHA
  618. cmp BYTE PTR [edx+3], 0ffh ;U
  619. je @noAlpha ; V
  620. mov ebx, [esi].GENGC_pixAccum ;U ;; get ready to do read
  621. cmp BYTE PTR [edx+3], 0 ; V
  622. jne @alphaRead ;U
  623. ;; Alpha is 0 in the texture, so just increment all the accumulators
  624. if ZBUFFER
  625. mov ecx, [esi].GENGC_zAccum ;U
  626. add edi, 2 ; V
  627. add ecx, [esi].GENGC_SPAN_dz ;U
  628. endif
  629. PIXADVANCE ebx ;U
  630. if ZBUFFER
  631. mov [esi].GENGC_zAccum, ecx ;U
  632. endif
  633. ror eax, 8 ; V
  634. sub ebp, 010001h ;U
  635. mov [esi].GENGC_pixAccum, ebx ; V
  636. mov [esi].GENGC_ditherAccum, eax ;U
  637. ;; Finish incrementing all of our accumulators
  638. jl doSubDiv ; V
  639. test ebp, 08000h ;U
  640. je loopTopNoDiv ; V
  641. jmp spanExit
  642. @alphaRead:
  643. ;;
  644. ;; Get pixel value and calculate total effect with alpha
  645. ;;
  646. ;; To make this easy on ourselves, we'll use the uncompressed palette
  647. ;; to do the alpha modulation:
  648. ALPHANOMODULATE
  649. sub edx, [esi].GENGC_texImageReplace
  650. add edx, [esi].GENGC_texPalette
  651. ALPHAREAD
  652. mov al, [edx+2] ;U get texel value
  653. mov ah, [esi].GENGC_aDisplay
  654. mov bl, [edx+1] ;U
  655. mov bh, [esi].GENGC_aDisplay
  656. mov cl, [edx] ; V
  657. mov ch, [esi].GENGC_aDisplay
  658. and eax, 0ffffh
  659. and ebx, 0ffffh
  660. and ecx, 0ffffh
  661. mov ah, _gbMulTable[eax]
  662. mov bh, _gbMulTable[ebx]
  663. mov ch, _gbMulTable[ecx]
  664. add ah, [esi].GENGC_rDisplay
  665. add bh, [esi].GENGC_gDisplay
  666. add ch, [esi].GENGC_bDisplay
  667. if (BPP eq 32)
  668. shl eax, -rRightShiftAdj
  669. else
  670. shr eax, rRightShiftAdj ;U
  671. endif
  672. mov edx, [esi].GENGC_pixAccum ; V
  673. shr ebx, gRightShiftAdj ;U
  674. and eax, rMask ; V
  675. shr ecx, bRightShiftAdj ;U
  676. and ebx, gMask ; V
  677. and ecx, bMask ;U
  678. or eax, ebx ; V
  679. or eax, ecx ;U
  680. PIXADVANCE2 ebx, edx ; V
  681. if ZBUFFER
  682. mov ecx, [esi].GENGC_zAccum ; V
  683. add edi, 2 ;U
  684. add ecx, [esi].GENGC_SPAN_dz ; V
  685. endif
  686. mov [esi].GENGC_pixAccum, ebx ;U
  687. if ZBUFFER
  688. mov [esi].GENGC_zAccum, ecx ;U
  689. endif
  690. if (BPP eq 8)
  691. sub ebp, 010001h ; V
  692. mov al, [esi].GENGC_xlatPalette[eax];U ;; AGI without z-buffering
  693. mov [edx], al ;U
  694. elseif (BPP eq 16)
  695. sub ebp, 010001h
  696. mov [edx], ax
  697. else
  698. mov [edx], ax
  699. shr eax, 16
  700. sub ebp, 010001h
  701. mov [edx+2], al
  702. endif
  703. ;; Finish the loop:
  704. jl doSubDiv ; V
  705. test ebp, 08000h ;U
  706. je loopTopNoDiv ; V
  707. jmp spanExit
  708. endif ;;ALPHA
  709. @noAlpha:
  710. mov ebx, [esi].GENGC_pixAccum ;U
  711. if (BPP eq 8)
  712. mov al, [edx] ; V get texel value
  713. elseif (BPP eq 16)
  714. mov ax, [edx]
  715. else
  716. mov eax, [edx]
  717. endif
  718. PIXADVANCE2 ecx, ebx ;U
  719. if ZBUFFER
  720. mov edx, [esi].GENGC_zAccum ; V
  721. add edi, 2 ;U
  722. add edx, [esi].GENGC_SPAN_dz ; V
  723. mov [esi].GENGC_zAccum, edx ;U
  724. endif
  725. mov [esi].GENGC_pixAccum, ecx ; V
  726. if (BPP eq 8)
  727. sub ebp, 010001h ;U
  728. mov [ebx], al ; V
  729. elseif (BPP eq 16)
  730. sub ebp, 010001h
  731. mov [ebx], ax
  732. else
  733. mov [ebx], ax
  734. shr eax, 16
  735. sub ebp, 010001h
  736. mov [ebx+2], al
  737. endif
  738. ;; Finish incrementing all of our accumulators
  739. jl doSubDiv ;U
  740. test ebp, 08000h ; V
  741. je loopTopNoDiv ;U
  742. jmp spanExit
  743. elseif REPLACE
  744. ;;----------------------------------------------------------------------
  745. ;;
  746. ;; ** Replace mode (non-compressed)
  747. ;;
  748. ;;----------------------------------------------------------------------
  749. if ALPHA
  750. cmp BYTE PTR [edx+3], 0ffh ;U
  751. je @noAlpha ; V
  752. mov ebx, [esi].GENGC_pixAccum ;U ;; get ready to do read
  753. cmp BYTE PTR [edx+3], 0 ; V
  754. jne @alphaRead ;U
  755. ;; Alpha is 0 in the texture, so just increment all the accumulators
  756. if ZBUFFER
  757. mov ecx, [esi].GENGC_zAccum ;U
  758. add edi, 2 ; V
  759. add ecx, [esi].GENGC_SPAN_dz ;U
  760. endif
  761. mov eax, [esi].GENGC_ditherAccum ; V
  762. if ZBUFFER
  763. mov [esi].GENGC_zAccum, ecx ;U
  764. endif
  765. PIXADVANCE ebx ;U
  766. ror eax, 8 ; V
  767. sub ebp, 010001h ;U
  768. mov [esi].GENGC_pixAccum, ebx ; V
  769. mov [esi].GENGC_ditherAccum, eax ;U
  770. ;; Finish incrementing all of our accumulators
  771. jl doSubDiv ; V
  772. test ebp, 08000h ;U
  773. je loopTopNoDiv ; V
  774. jmp spanExit
  775. @alphaRead:
  776. ;;
  777. ;; Get pixel value and calculate total effect with alpha
  778. ;;
  779. ALPHANOMODULATE
  780. ALPHAREAD
  781. mov al, [edx+2] ;U get texel value
  782. mov ah, [esi].GENGC_aDisplay
  783. mov bl, [edx+1] ;U
  784. mov bh, [esi].GENGC_aDisplay
  785. mov cl, [edx] ; V
  786. mov ch, [esi].GENGC_aDisplay
  787. and eax, 0ffffh
  788. and ebx, 0ffffh
  789. and ecx, 0ffffh
  790. mov ah, _gbMulTable[eax]
  791. mov bh, _gbMulTable[ebx]
  792. mov ch, _gbMulTable[ecx]
  793. add ah, [esi].GENGC_rDisplay
  794. add bh, [esi].GENGC_gDisplay
  795. add ch, [esi].GENGC_bDisplay
  796. if (BPP eq 32)
  797. shl eax, -rRightShiftAdj
  798. else
  799. shr eax, rRightShiftAdj ;U
  800. endif
  801. mov edx, [esi].GENGC_pixAccum ; V
  802. shr ebx, gRightShiftAdj ;U
  803. and eax, rMask ; V
  804. shr ecx, bRightShiftAdj ;U
  805. and ebx, gMask ; V
  806. and ecx, bMask ;U
  807. or eax, ebx ; V
  808. or eax, ecx ;U
  809. PIXADVANCE2 ebx, edx ; V
  810. if ZBUFFER
  811. mov ecx, [esi].GENGC_zAccum ; V
  812. add edi, 2 ;U
  813. add ecx, [esi].GENGC_SPAN_dz ; V
  814. endif
  815. mov [esi].GENGC_pixAccum, ebx ;U
  816. if ZBUFFER
  817. mov [esi].GENGC_zAccum, ecx ;U
  818. endif
  819. if (BPP eq 8)
  820. sub ebp, 010001h ; V
  821. mov al, [esi].GENGC_xlatPalette[eax];U ;; AGI without z-buffering
  822. mov [edx], al ;U
  823. elseif (BPP eq 16)
  824. sub ebp, 010001h
  825. mov [edx], ax
  826. else
  827. mov [edx], ax
  828. shr eax, 16
  829. sub ebp, 010001h
  830. mov [edx+2], al
  831. endif
  832. ;; Finish the loop:
  833. jl doSubDiv ; V
  834. test ebp, 08000h ;U
  835. je loopTopNoDiv ; V
  836. jmp spanExit
  837. endif ;;ALPHA
  838. @noAlpha:
  839. mov ah, [edx+2] ;U get texel value
  840. mov bh, [edx+1] ; V
  841. if (BPP eq 32)
  842. shl eax, -rRightShiftAdj
  843. else
  844. shr eax, rRightShiftAdj ;U
  845. endif
  846. mov ch, [edx] ; V
  847. shr ebx, gRightShiftAdj ;U
  848. and eax, rMask ; V
  849. shr ecx, bRightShiftAdj ;U
  850. and ebx, gMask ; V
  851. or eax, ebx ;U
  852. and ecx, bMask ; V
  853. mov edx, [esi].GENGC_pixAccum ;U
  854. or eax, ecx ; V
  855. PIXADVANCE2 ebx, edx ;U
  856. if ZBUFFER
  857. mov ecx, [esi].GENGC_zAccum ; V
  858. add edi, 2 ;U
  859. add ecx, [esi].GENGC_SPAN_dz ; V
  860. mov [esi].GENGC_zAccum, ecx ;U
  861. endif
  862. if (BPP eq 8)
  863. sub ebp, 010001h ; V
  864. mov [esi].GENGC_pixAccum, ebx ;U
  865. mov al, [esi].GENGC_xlatPalette[eax]; V
  866. mov [edx], al ;U
  867. elseif (BPP eq 16)
  868. sub ebp, 010001h
  869. mov [esi].GENGC_pixAccum, ebx
  870. mov [edx], ax
  871. else
  872. mov [edx], ax
  873. shr eax, 16
  874. mov [esi].GENGC_pixAccum, ebx
  875. sub ebp, 010001h
  876. mov [edx+2], al
  877. endif
  878. ;; Finish the loop:
  879. jl doSubDiv ; V
  880. test ebp, 08000h ;U
  881. je loopTopNoDiv ; V
  882. jmp spanExit
  883. elseif FLAT_SHADING
  884. ;;----------------------------------------------------------------------
  885. ;;
  886. ;; ** Flat shading
  887. ;;
  888. ;;----------------------------------------------------------------------
  889. if ALPHA
  890. mov ebx, [esi].GENGC_pixAccum ;; get ready to do read
  891. cmp BYTE PTR [edx+3], 0
  892. jne @alphaRead
  893. ;; Alpha is 0 in the texture, so just increment all the accumulators
  894. if ZBUFFER
  895. mov ecx, [esi].GENGC_zAccum
  896. mov eax, [esi].GENGC_SPAN_dz
  897. add edi, 2
  898. add ecx, eax
  899. endif
  900. mov eax, [esi].GENGC_ditherAccum
  901. if ZBUFFER
  902. mov [esi].GENGC_zAccum, ecx
  903. endif
  904. ror eax, 8 ;U
  905. PIXADVANCE ebx ; V
  906. sub ebp, 010001h ;U
  907. mov [esi].GENGC_pixAccum, ebx ; V
  908. mov [esi].GENGC_ditherAccum, eax ;U
  909. ;; Finish incrementing all of our accumulators
  910. jl doSubDiv ; V
  911. test ebp, 08000h ;U
  912. je loopTopNoDiv ; V
  913. jmp spanExit
  914. @alphaRead:
  915. cmp BYTE PTR [edx+3], 0ffh
  916. jne @doAlpha
  917. cmp BYTE PTR [esi].GENGC_aAccum+2, 0ffh
  918. jne @doAlpha
  919. ;; Set mix color to 1, 0, 0, 0
  920. mov DWORD PTR [esi].GENGC_rDisplay, 0ff000000h
  921. jmp short @doneAlpha
  922. ;;
  923. ;; Get pixel value and calculate total effect with alpha
  924. ;;
  925. @doAlpha:
  926. ALPHAMODULATE
  927. ALPHAREAD
  928. @doneAlpha:
  929. endif ;;ALPHA
  930. mov ebx, [edx] ;U
  931. mov ecx, ebx ; V
  932. shr ebx, 16 ;U
  933. mov edx, ecx ; V
  934. shr ecx, 8 ;U
  935. mov eax, [esi].GENGC_rAccum ; V
  936. and ebx, 0ffh ;U
  937. and ecx, 0ffh ; V
  938. or ebx, eax ;U
  939. mov eax, [esi].GENGC_gAccum ; V
  940. and edx, 0ffh ;U
  941. or ecx, eax ; V
  942. mov eax, [esi].GENGC_bAccum ;U
  943. or edx, eax ; V
  944. mov ebx, DWORD PTR _gbMulTable[ebx] ;U
  945. mov ecx, DWORD PTR _gbMulTable[ecx] ; V
  946. mov edx, DWORD PTR _gbMulTable[edx] ;U
  947. if ALPHA
  948. mov bh, [esi].GENGC_aDisplay
  949. mov ch, bh
  950. mov dh, bh
  951. and ebx, 0ffffh
  952. and ecx, 0ffffh
  953. and edx, 0ffffh
  954. mov bl, _gbMulTable[ebx]
  955. mov cl, _gbMulTable[ecx]
  956. mov dl, _gbMulTable[edx]
  957. add bl, [esi].GENGC_rDisplay
  958. add cl, [esi].GENGC_gDisplay
  959. add dl, [esi].GENGC_bDisplay
  960. endif
  961. ;; do the dithering
  962. shl ebx, (rBits+8) ;U
  963. mov eax, [esi].GENGC_ditherAccum ; V
  964. shl ecx, (gBits+8) ;U
  965. and eax, 0f800h ; V
  966. shl edx, (bBits+8) ;U
  967. add ebx, eax ; V
  968. add ecx, eax ;U
  969. add edx, eax ; V
  970. ;;
  971. ;; Compose the final pixel:
  972. ;;
  973. if (BPP eq 32)
  974. shl ebx, -rRightShiftAdj
  975. else
  976. shr ebx, rRightShiftAdj ;U
  977. endif
  978. mov eax, [esi].GENGC_ditherAccum ; V
  979. ror eax, 8 ;U
  980. and ebx, rMask ; V
  981. shr ecx, gRightShiftAdj ;U
  982. mov [esi].GENGC_ditherAccum, eax ; V
  983. shr edx, bRightShiftAdj ;U
  984. and ecx, gMask ; V
  985. or ebx, ecx ;U
  986. and edx, bMask ; V
  987. or ebx, edx ;U
  988. ;;
  989. ;; Advance the frame buffer pointer:
  990. ;;
  991. mov ecx, [esi].GENGC_pixAccum ; V
  992. mov edx, ecx ;U
  993. if (BPP le 16)
  994. add ecx, (BPP / 8) ; V
  995. else
  996. add ecx, [esi].GENGC_bytesPerPixel ; V
  997. endif
  998. mov [esi].GENGC_pixAccum, ecx ;U
  999. ;;
  1000. ;; A good time to start incrementing all of our accumulators:
  1001. ;;
  1002. if ZBUFFER
  1003. mov ecx, [esi].GENGC_zAccum ; V
  1004. mov eax, [esi].GENGC_SPAN_dz ;U
  1005. add ecx, eax ; V
  1006. add edi, 2 ;U
  1007. mov [esi].GENGC_zAccum, ecx ; V
  1008. endif
  1009. ;;
  1010. ;; Write the pixel into the frame buffer
  1011. ;;
  1012. if (BPP eq 8)
  1013. mov al, [esi].GENGC_xlatPalette[ebx]; V
  1014. sub ebp, 010001h ;U
  1015. mov [edx], al ; V
  1016. elseif (BPP eq 16)
  1017. sub ebp, 010001h
  1018. mov [edx], bx
  1019. else
  1020. mov [edx], bx
  1021. shr ebx, 16
  1022. sub ebp, 010001h
  1023. mov [edx+2], bl
  1024. endif
  1025. ;; Finish incrementing all of our accumulators
  1026. jl doSubDiv ;U
  1027. test ebp, 08000h ; V
  1028. je loopTopNoDiv ;U
  1029. elseif SMOOTH_SHADING
  1030. ;;----------------------------------------------------------------------
  1031. ;;
  1032. ;; ** Smooth shading
  1033. ;;
  1034. ;;----------------------------------------------------------------------
  1035. if ALPHA
  1036. mov ebx, [esi].GENGC_pixAccum ;; get ready to do read
  1037. cmp BYTE PTR [edx+3], 0
  1038. jne @alphaRead
  1039. ;; Alpha is 0 in the texture, so just increment all the accumulators
  1040. if ZBUFFER
  1041. mov ecx, [esi].GENGC_zAccum
  1042. mov eax, [esi].GENGC_SPAN_dz
  1043. add eax, ecx
  1044. add edi, 2
  1045. mov [esi].GENGC_zAccum, eax
  1046. endif
  1047. mov eax, [esi].GENGC_rAccum
  1048. mov ebx, [esi].GENGC_gAccum
  1049. mov ecx, [esi].GENGC_bAccum
  1050. add eax, [esi].GENGC_SPAN_dr
  1051. add ebx, [esi].GENGC_SPAN_dg
  1052. add ecx, [esi].GENGC_SPAN_db
  1053. mov [esi].GENGC_rAccum, eax
  1054. mov [esi].GENGC_gAccum, ebx
  1055. mov [esi].GENGC_bAccum, ecx
  1056. mov eax, [esi].GENGC_ditherAccum
  1057. mov ecx, [esi].GENGC_aAccum
  1058. ror eax, 8
  1059. mov ebx, [esi].GENGC_pixAccum
  1060. add ecx, [esi].GENGC_SPAN_da
  1061. PIXADVANCE ebx
  1062. mov [esi].GENGC_aAccum, ecx
  1063. mov [esi].GENGC_pixAccum, ebx
  1064. sub ebp, 010001h
  1065. mov [esi].GENGC_ditherAccum, eax
  1066. ;; Finish incrementing all of our accumulators
  1067. jl doSubDiv ;U
  1068. test ebp, 08000h ; V
  1069. je loopTopNoDiv ;U
  1070. jmp spanExit
  1071. @alphaRead:
  1072. cmp BYTE PTR [edx+3], 0ffh
  1073. jne @doAlpha
  1074. cmp BYTE PTR [esi].GENGC_aAccum+2, 0ffh
  1075. jne @doAlpha
  1076. ;; Set mix color to 1, 0, 0, 0
  1077. mov DWORD PTR [esi].GENGC_rDisplay, 0ff000000h
  1078. jmp short @doneAlpha
  1079. ;;
  1080. ;; Get pixel value and calculate total effect with alpha
  1081. ;;
  1082. @doAlpha:
  1083. ALPHAMODULATE
  1084. ALPHAREAD
  1085. @doneAlpha:
  1086. endif ;;ALPHA
  1087. mov ebx, [esi].GENGC_rAccum ;U
  1088. mov eax, [edx] ; V
  1089. shr ebx, rBits ;U
  1090. and eax, 0ff0000h ; V
  1091. shr eax, 16 ;U
  1092. mov ecx, [esi].GENGC_gAccum ; V
  1093. shr ecx, gBits ;U
  1094. and ebx, 0ff00h ; V
  1095. or ebx, eax ;U
  1096. mov eax, [edx] ; V
  1097. shr eax, 8 ;U
  1098. mov edx, [edx] ; V
  1099. and eax, 0ffh ;U
  1100. and ecx, 0ff00h ; V
  1101. or ecx, eax ;U
  1102. mov eax, [esi].GENGC_bAccum ; V
  1103. shr eax, bBits ;U
  1104. and edx, 0ffh ; V
  1105. and eax, 0ff00h ;U
  1106. mov ebx, DWORD PTR _gbMulTable[ebx] ; V get multiplied 8-bit R value
  1107. or edx, eax ;U
  1108. mov ecx, DWORD PTR _gbMulTable[ecx] ; V get multiplied 8-bit G value
  1109. mov eax, [esi].GENGC_ditherAccum ;U
  1110. mov edx, DWORD PTR _gbMulTable[edx] ; V get multiplied 8-bit B value
  1111. if ALPHA
  1112. mov bh, [esi].GENGC_aDisplay
  1113. mov ch, bh
  1114. mov dh, bh
  1115. and ebx, 0ffffh
  1116. and ecx, 0ffffh
  1117. and edx, 0ffffh
  1118. mov bl, _gbMulTable[ebx]
  1119. mov cl, _gbMulTable[ecx]
  1120. mov dl, _gbMulTable[edx]
  1121. add bl, [esi].GENGC_rDisplay
  1122. add cl, [esi].GENGC_gDisplay
  1123. add dl, [esi].GENGC_bDisplay
  1124. endif
  1125. shl ebx, (rBits+8) ;U
  1126. and eax, 0f800h ; V
  1127. shl ecx, (gBits+8) ;U
  1128. add ebx, eax ; V
  1129. shl edx, (bBits+8) ;U
  1130. add ecx, eax ; V
  1131. if (BPP eq 32)
  1132. shl ebx, -rRightShiftAdj
  1133. else
  1134. shr ebx, rRightShiftAdj ;U
  1135. endif
  1136. add edx, eax ; V
  1137. shr ecx, gRightShiftAdj ;U
  1138. and ebx, rMask ; V
  1139. shr edx, bRightShiftAdj ;U
  1140. and ecx, gMask ; V
  1141. or ebx, ecx ;U
  1142. and edx, bMask ; V
  1143. or ebx, edx ;U
  1144. ;;
  1145. ;; A good time to start incrementing all of our accumulators
  1146. ;;
  1147. if ZBUFFER
  1148. mov ecx, [esi].GENGC_zAccum ; V
  1149. mov eax, [esi].GENGC_SPAN_dz ;U
  1150. add eax, ecx ; V
  1151. add edi, 2 ;U
  1152. mov [esi].GENGC_zAccum, eax ; V
  1153. endif
  1154. mov eax, [esi].GENGC_rAccum ;U
  1155. mov ecx, [esi].GENGC_SPAN_dr ; V
  1156. mov edx, [esi].GENGC_gAccum ;U
  1157. add eax, ecx ; V
  1158. mov ecx, [esi].GENGC_SPAN_dg ;U
  1159. mov [esi].GENGC_rAccum, eax ; V
  1160. add edx, ecx ;U
  1161. mov eax, [esi].GENGC_bAccum ; V
  1162. mov ecx, [esi].GENGC_SPAN_db ;U
  1163. add eax, ecx ; V
  1164. mov [esi].GENGC_gAccum, edx ;U
  1165. mov [esi].GENGC_bAccum, eax ; V
  1166. mov eax, [esi].GENGC_ditherAccum ;U
  1167. mov ecx, [esi].GENGC_pixAccum ; V
  1168. ror eax, 8 ;U
  1169. mov edx, ecx ; V
  1170. if (BPP le 16)
  1171. add ecx, (BPP / 8) ;U
  1172. else
  1173. add ecx, [esi].GENGC_bytesPerPixel ;U
  1174. endif
  1175. mov [esi].GENGC_ditherAccum, eax ; V
  1176. mov [esi].GENGC_pixAccum, ecx ;U
  1177. if ALPHA
  1178. mov ecx, [esi].GENGC_aAccum
  1179. add ecx, [esi].GENGC_SPAN_da
  1180. mov [esi].GENGC_aAccum, ecx
  1181. endif
  1182. if (BPP eq 8)
  1183. mov al, [esi].GENGC_xlatPalette[ebx]; V
  1184. sub ebp, 010001h ;U
  1185. mov [edx], al ; V
  1186. elseif (BPP eq 16)
  1187. sub ebp, 010001h
  1188. mov [edx], bx
  1189. else
  1190. mov [edx], bx
  1191. shr ebx, 16
  1192. sub ebp, 010001h
  1193. mov [edx+2], bl
  1194. endif
  1195. ;; Finish incrementing all of our accumulators
  1196. jl doSubDiv ;U
  1197. test ebp, 08000h ; V
  1198. je loopTopNoDiv ;U
  1199. endif ;;SMOOTH_SHADING
  1200. ;;
  1201. ;; This is the exit point. We need to pop the unused floating-point
  1202. ;; registers off the stack, and return:
  1203. ;;
  1204. spanExit:
  1205. fstp ST(0)
  1206. fstp ST(0)
  1207. pop ebp
  1208. pop edi
  1209. pop esi
  1210. pop ebx
  1211. ret 0
  1212. ;;
  1213. ;; This is the subdivision code. After the required number of steps, the
  1214. ;; routine will jump here to calculate the next set of interpolants based
  1215. ;; on subdivision:
  1216. ;;
  1217. doSubDiv:
  1218. add ebp, 080000h
  1219. mov ecx, [esi].GENGC_flags
  1220. ;;
  1221. ;; Increment the big S and T steps:
  1222. ;;
  1223. mov edx, [esi].GENGC_sAccum
  1224. test ebp, 08000h
  1225. jne short spanExit
  1226. mov ebx, [esi].GENGC_tAccum
  1227. add edx, [esi].GENGC_sStepX
  1228. add ebx, [esi].GENGC_tStepX
  1229. mov [esi].GENGC_sAccum, edx
  1230. mov [esi].GENGC_tAccum, ebx
  1231. mov eax, [esi].GENGC_sResultNew
  1232. mov ebx, [esi].GENGC_tResultNew
  1233. test ecx, GEN_TEXTURE_ORTHO
  1234. je @f
  1235. mov ecx, DWORD PTR [esi].GENGC_tAccum
  1236. mov DWORD PTR [esi].GENGC_sResultNew, edx
  1237. mov DWORD PTR [esi].GENGC_tResultNew, ecx
  1238. jmp short @stResultDone3
  1239. ;;
  1240. ;; Do the floating-point computation for perspective:
  1241. ;;
  1242. @@:
  1243. fild DWORD PTR [esi].GENGC_sAccum ; s 1/qw qwAccum
  1244. fmul ST, ST(1) ; s/qw 1/qw qwAccum
  1245. fild DWORD PTr [esi].GENGC_tAccum ; t s/qw 1/qw qwAccum
  1246. fmulp ST(2), ST ; s/qw t/qw qwAccum
  1247. fistp QWORD PTR [esi].GENGC_sResultNew; t/qw qwAccum
  1248. fistp QWORD PTR [esi].GENGC_tResultNew; qwAccum
  1249. @stResultDone3:
  1250. ;;
  1251. ;; Now, calculate the per-pixel deltas:
  1252. ;;
  1253. mov cl, TSHIFT_SUBDIV ;U
  1254. mov edx, [esi].GENGC_tResultNew ; V
  1255. sar edx, cl ;UV (4)
  1256. mov ecx, [esi].GENGC_sResultNew ;U
  1257. and edx, NOT 7 ; V
  1258. sub ecx, eax ;U
  1259. mov [esi].GENGC_tResultNew, edx ; V
  1260. sar ecx, 3 ;U
  1261. sub edx, ebx ; V
  1262. sar edx, 3 ;U
  1263. mov [esi].GENGC_subDs, ecx ; V
  1264. mov [esi].GENGC_subDt, edx ;U
  1265. mov [esi].GENGC_sResult, eax ; V
  1266. mov [esi].GENGC_tResult, ebx ;U
  1267. mov eax, [esi].GENGC_flags ; V
  1268. jmp loopTop ;U