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.

4010 lines
122 KiB

  1. include(`m4hdr.mh')dnl
  2. dnl
  3. dnl New masm does not like string FCOMI
  4. dnl
  5. define(`FCOMI', `FCOMXX')dnl
  6. ; $Id: rmfillf5.asm,v 1.8 1995/10/13 14:56:45 james Exp $
  7. ;
  8. ; Copyright (c) RenderMorphics Ltd. 1993, 1994, 1995
  9. ; Version 1.0beta2
  10. ;
  11. ; All rights reserved.
  12. ;
  13. ; This file contains private, unpublished information and may not be
  14. ; copied in part or in whole without express permission of
  15. ; RenderMorphics Ltd.
  16. ;
  17. ; Interface: Floating point
  18. ; Internal: Floating point, fixed point
  19. ; CPU: Intel Pentium, no MMX
  20. ; This module does ramp triangle fills in 8, 16 bits, undithered, no
  21. ; transparency. It can produce these 12 functions, according to the
  22. ; flags we're compiled with.
  23. ; RENDER_FLAT RENDER_TEXTURE DEPTH
  24. ; RLDDIR8FTriangle 1 0 8
  25. ; RLDDIR8GTriangle 0 0 8
  26. ; RLDDIR8FTTriangle 1 1 8
  27. ; RLDDIR8GTTriangle 0 1 8
  28. ; RLDDIR8FPTriangle 1 2 8
  29. ; RLDDIR8GPTriangle 0 2 8
  30. ; RLDDIR16FTriangle 1 0 16
  31. ; RLDDIR16GTriangle 0 0 16
  32. ; RLDDIR16FTTriangle 1 1 16
  33. ; RLDDIR16GTTriangle 0 1 16
  34. ; RLDDIR16FPTriangle 1 2 16
  35. ; RLDDIR16GPTriangle 0 2 16
  36. ; The other controlling flag is OTHER_SEG. When this is set
  37. ; to one we do extra time-consuming work to draw pixels in a far away
  38. ; segment.
  39. ; This is generally only needed when compiling for Windows 3.1.
  40. ; (NB: all these variables default to 0 if undefined).
  41. ; .radix 16
  42. .486p
  43. ; General environment equ s that do not change between versions of ramp fill
  44. ; routines
  45. D3D equ 1
  46. NT equ 1
  47. MICROSOFT_NT equ 1
  48. STACK_CALL equ 1
  49. ; equ s that generate different required routines
  50. RENDER_Z equ d_z
  51. DEPTH equ d_depth
  52. RENDER_GOURAUD equ d_gouraud
  53. RENDER_TEXTURE equ d_tex
  54. RENDER_TRANS equ d_trans
  55. if DEPTH eq 8
  56. NAME ramp8
  57. else
  58. NAME ramp16
  59. endif
  60. include equates.asm
  61. include macros.asm
  62. include offsets.asm
  63. ;************************************************************************
  64. WANT_DOUBLE_FILLSPAN equ 0 ; Double pixel fillspan
  65. WANT_SUB_FILLSPAN equ 0 ; Soubroutine fillspan
  66. WANT_SUB_FILL_INIT equ 1 ; Subroutine FILL_INIT
  67. WANT_RECIPROCAL_MULTIPLY equ 1 ; Replace (x/y) with (x*(1/y))
  68. ifndef OTHER_SEG
  69. OTHER_SEG equ 0
  70. endif
  71. RENDER_OTHER_SEGMENT equ OTHER_SEG
  72. PENTIUM equ 0
  73. FIXED_POINT equ 0
  74. FLOATING_POINT equ 1
  75. Z_SHIFT equ 8h
  76. WRAPPING equ 0
  77. STRIDE_LENGTH equ 10h
  78. ;************************************************************************
  79. ifndef RENDER_GOURAUD
  80. RENDER_GOURAUD equ 0
  81. endif
  82. ifndef RENDER_TEXTURE
  83. RENDER_TEXTURE equ 0
  84. endif
  85. ifndef RENDER_TRANS
  86. RENDER_TRANS equ 0
  87. endif
  88. if RENDER_TEXTURE eq 2
  89. PERSPECTIVE equ 1
  90. else
  91. PERSPECTIVE equ 0
  92. endif
  93. if PERSPECTIVE
  94. SUBPIX_CORRECT equ 1
  95. else
  96. SUBPIX_CORRECT equ 0
  97. endif
  98. ifndef RENDER_Z
  99. RENDER_Z equ 0
  100. endif
  101. if (RENDER_TEXTURE eq 0)
  102. BIDIRECTIONAL equ 1
  103. else
  104. BIDIRECTIONAL equ 0
  105. endif
  106. ; Makes GT faster, costs RAM
  107. ;if (RENDER_TEXTURE gt 0)
  108. ;GOURAUD_TABLE equ (RENDER_GOURAUD and ((DEPTH eq 16) and (RENDER_TRANS eq 0)))
  109. ;else
  110. GOURAUD_TABLE equ 0
  111. ;endif
  112. ;************************************************************************
  113. WANT_ZBUFFER equ RENDER_Z ; Do Z-Buffering
  114. SEG_REND macro
  115. if RENDER_OTHER_SEGMENT
  116. db 26h
  117. endif
  118. endm
  119. ifdef D3D
  120. ; This section should go as soon as D3D replaces RL2.0
  121. ; For now we keep compatible.
  122. RLDDIVertex_sx equ D3DTLVERTEX_sx
  123. RLDDIVertex_sy equ D3DTLVERTEX_sy
  124. RLDDIVertex_sz equ D3DTLVERTEX_sz
  125. RLDDIVertex_rhw equ D3DTLVERTEX_rhw
  126. RLDDIVertex_tu equ D3DTLVERTEX_tu
  127. RLDDIVertex_tv equ D3DTLVERTEX_tv
  128. RLDDIVertex_color equ D3DTLVERTEX_color
  129. RLDDIVertex_specular equ D3DTLVERTEX_specular
  130. RLDDIRampDriver_fill_params equ RLDDIGenRasDriver_fill_params
  131. RLDDIRampTexture_image equ RLDDITexture_image
  132. RLDDIRampTexture_transparent equ RLDDITexture_transparent
  133. RLDDIRampTexture_tables equ RLDDITexture_tables
  134. endif
  135. WANT_DLL equ 0
  136. dseg segment para public use32 'DATA'
  137. extrn _RLDDIhdivtab:dword
  138. extrn _RLDDIFloatConstInv64K:dword
  139. extrn _RLDDIFloatConstInv256:dword
  140. extrn _RLDDIFloatConst64K:dword
  141. extrn _RLDDIFloatConst2p24:dword
  142. extrn _RLDDIFloatConst2p36:dword
  143. extrn _RLDDIFloatConst16:dword
  144. extrn _RLDDIFloatConstAffineThreshold:dword
  145. extrn _RLDDIFloatConstHalf:dword
  146. extrn _RLDDIConvertIEEE:qword
  147. if RENDER_TRANS
  148. ; extrn _RLDDIDither2:byte
  149. _RLDDIDither2 dd 0
  150. endif
  151. temp_double1 dq ?
  152. temp_double2 dq ?
  153. temp_double3 dq ?
  154. xr dd 0
  155. dd ?
  156. u0 dq 0
  157. u1 dq 0
  158. v0 dq 0
  159. v1 dq 0
  160. cull_ccw dd 0 ; needed for culling stuff
  161. cull_cw dd 0
  162. if RENDER_GOURAUD ; {
  163. sm dd 0 ; Shade of left point
  164. dd 0
  165. ms dd 0 ; Slope for top edge shade
  166. dd 0
  167. sstep dd 0 ; Shade delta per pixel
  168. dd 0
  169. endif ; }
  170. zl dd 0
  171. dd 0
  172. dz dd 0
  173. dd 0
  174. mz dd 0
  175. dd 0
  176. xm dd 0
  177. dd 0
  178. xl dd 0
  179. dd 0
  180. ml dd 0
  181. dd 0
  182. mr dd 0
  183. dd 0
  184. mr2 dd 0
  185. dd 0
  186. triptr dd 0
  187. ftemp dd 0
  188. control_save dd 0
  189. spanlength dd 0
  190. _RLDDIFloatConst2p52 dd 59800000h
  191. p1save dd 0 ; Need this for gouraud textures
  192. dwidth dd 0
  193. zwidth dd 0
  194. map dd 0
  195. pixel dd 0
  196. dzl dd 0
  197. h dd 0
  198. ;pm_lines dd 0
  199. ;zb_lines dd 0
  200. pm_pixels dd 0
  201. zb_pixels dd 0
  202. xl2 dd 0
  203. zm dd 0
  204. zr dd 0
  205. mz2 dd 0
  206. ml2 dd 0
  207. y1save dd 0
  208. save1 dd 0
  209. dx1 dd 0
  210. dx2 dd 0
  211. h1 dd 0
  212. h2 dd 0
  213. h3 dd 0
  214. h1s dd 0
  215. h3s dd 0
  216. zlzm dd 0
  217. trapezoid_vector dd 0
  218. if PERSPECTIVE
  219. pc_trapezoid_vector dd 0
  220. endif
  221. ifdef D3D ;{
  222. if RENDER_GOURAUD eq 0 ;{
  223. pp1 dd 0
  224. endif ;}
  225. endif ;}
  226. if RENDER_GOURAUD ;{
  227. sl dd 0 ; Shade of left point
  228. sr dd 0 ; Shade of right point
  229. ms2 dd 0 ; Slope for bottom edge shade
  230. endif ;}
  231. if RENDER_TEXTURE
  232. if RENDER_GOURAUD
  233. if GOURAUD_TABLE
  234. if (DEPTH eq 8)
  235. GTpixels db 32 * 256 dup (0)
  236. else
  237. GTpixels dw 32 * 256 dup (0)
  238. endif
  239. GTpixelsTexture dd 0
  240. endif
  241. else
  242. pixels dd 256 dup (0)
  243. pixels_shade dd -1
  244. endif
  245. endif
  246. ;xxxxxxxxxxxx
  247. if RENDER_TEXTURE ;{
  248. tex dd 0 ;
  249. texture dd 0 ;
  250. colors dd 0 ;
  251. wrap_u dd 0 ;
  252. wrap_v dd 0 ;
  253. u_shift dd 0 ;
  254. v_shift dd 0 ;
  255. v_mult dd 0 ;
  256. ul dd 0 ;
  257. ur dd 0 ;
  258. um dd 0 ;
  259. mu dd 0 ;
  260. mu2 dd 0 ;
  261. ustep dd 0 ;
  262. vl dd 0 ;
  263. vr dd 0 ;
  264. vm dd 0 ;
  265. mv dd 0 ;
  266. mv2 dd 0 ;
  267. vstep dd 0 ;
  268. if RENDER_TRANS
  269. transparent dd 0 ; Otherwise use this magic number
  270. trans_x dd 0
  271. trans_y dd 0
  272. TRANS_NEXT_PIXEL macro
  273. inc trans_x
  274. endm
  275. TRANS_NEXT_LINE macro
  276. inc trans_y
  277. endm
  278. endif
  279. if PERSPECTIVE
  280. ustep16 dd 0 ;
  281. vstep16 dd 0 ;
  282. wstep16 dd 0 ;
  283. if SUBPIX_CORRECT
  284. subpix dd 0
  285. recip65536 dd 0b7800000h
  286. endif
  287. endif
  288. wl dd 0 ;
  289. wr dd 0 ;
  290. wm dd 0 ;
  291. mw dd 0 ;
  292. mw2 dd 0 ;
  293. wstep dd 0 ;
  294. ; Packed uv
  295. uvl dd 0
  296. muv dd 0
  297. muv2 dd 0
  298. align 10h
  299. uvstep dd 0
  300. addrcalc_code dd 0
  301. addrentry macro u_shift, v_shift
  302. dd addrcalc_&u_shift&_&v_shift
  303. endm
  304. ; Why is there a strange "0 dup (0)" here? Because masm needs it, that's why.
  305. addrcalc_table dd 0 dup (0)
  306. i = 0
  307. rept 0ch
  308. j = 0;
  309. rept 0ch
  310. addrentry %i,%j
  311. j = j + 1
  312. endm
  313. i = i + 1
  314. endm
  315. endif ;}
  316. dseg ends
  317. cseg segment dword public use32 'CODE'
  318. assume cs:cseg,ds:dseg
  319. if (RENDER_TEXTURE eq 0) and (RENDER_GOURAUD eq 0) and (DEPTH eq 8)
  320. ;PUBLIC Haltu1
  321. ;PUBLIC Haltu2
  322. ;PUBLIC addrcalc_8_8
  323. endif
  324. if WANT_RECIPROCAL_MULTIPLY ;{
  325. HDIVTAB_POWER equ 18h
  326. DIVIDE_BY macro denom
  327. fmul [_RLDDIhdivtab + 4 * denom]
  328. endm
  329. else ;}{
  330. DIVIDE_BY macro denom
  331. mov edx, eax
  332. sar edx, 1fH
  333. idiv denom
  334. endm
  335. endif ;}
  336. SAFE_DIVIDE_BY macro denom
  337. mov edx, eax
  338. sar edx, 1fH
  339. idiv denom
  340. endm
  341. MUL16 macro multiplier
  342. imul multiplier
  343. shr eax, 10h
  344. shl edx, 10h
  345. or eax,edx
  346. endm
  347. VALTOI macro ea
  348. fild word ptr [ea + 2]
  349. endm
  350. FDUP macro
  351. fld st(0)
  352. endm
  353. FRECIPROCAL macro
  354. fld1
  355. fdivrp st(1),st
  356. endm
  357. FCOMI macro v
  358. fcom v
  359. fnstsw ax
  360. sahf
  361. endm
  362. TRICK macro prec
  363. fadd [_RLDDIConvertIEEE + (prec * 8)]
  364. endm
  365. TRICK16 macro
  366. TRICK 16
  367. endm
  368. qVALTOFX macro dst,src
  369. fld [_RLDDIConvertIEEE + (16 * 8)]
  370. fadd st,st(src + 1)
  371. fstp qword ptr dst
  372. endm
  373. VALTOFX macro dst,src
  374. fld _RLDDIFloatConst64K
  375. fmul st,st(src + 1)
  376. fistp dword ptr dst
  377. endm
  378. VALTOFX8 macro dst,src
  379. fld _RLDDIFloatConst256
  380. fmul st,st(src + 1)
  381. fistp dword ptr dst
  382. endm
  383. VALTOFX_Z macro dst,src
  384. fld _RLDDIFloatConst2p24
  385. fmul st,st(src + 1)
  386. fistp dword ptr dst
  387. endm
  388. FXTOVAL macro src
  389. if FIXED_POINT
  390. fild dword ptr src
  391. fmul _RLDDIFloatConstInv64K
  392. else
  393. fld dword ptr src
  394. endif
  395. endm
  396. FXTOVAL8 macro src
  397. if FIXED_POINT
  398. fild dword ptr src
  399. fmul _RLDDIFloatConstInv256
  400. else
  401. fld dword ptr src
  402. endif
  403. endm
  404. VALTOFXp macro dst
  405. fld _RLDDIFloatConst64K
  406. fmul
  407. fistp dword ptr dst
  408. endm
  409. if RENDER_GOURAUD ;{
  410. ;#define GTRI_GET_SHADE(p) ((signed)INCPREC(FX8TOVAL(CI_MASK_ALPHA(p->color)), 8))
  411. GTRI_GET_SHADE macro dst, p
  412. mov dst,[p + RLDDIVertex_color]
  413. shl dst,8h
  414. mov ftemp,dst
  415. fild ftemp
  416. fmul _RLDDIFloatConstInv64K
  417. endm
  418. endif ;}
  419. if RENDER_TEXTURE ;{
  420. ; #define TEXTURE_DIFF(a, b, s) ((((b) - (a)) << (s)) >> (s))
  421. TEXTURE_DIFF macro a, b, s
  422. local nowrap
  423. fld b
  424. fsub a
  425. if WRAPPING
  426. test s,-1
  427. jz nowrap
  428. shl eax,10h
  429. sar eax,10h
  430. nowrap:
  431. endif
  432. endm
  433. ; Load up ul,ur,um,vl,vr, and vm from the three points given.
  434. MVEDI macro dst, uv,lrm
  435. mov edi,[lrm + RLDDIVertex_t&uv]
  436. mov uv&dst,edi
  437. endm
  438. ; Pack up u and v into a 32-bit destination. Trashes edx.
  439. FPPACK macro udest,vdest ; v u
  440. if 1
  441. TRICK16
  442. fxch st(1)
  443. TRICK16
  444. fxch st(1)
  445. fstp vdest
  446. fstp udest
  447. else
  448. fmul _RLDDIFloatConst64K
  449. fxch st(1)
  450. fmul _RLDDIFloatConst64K
  451. fxch st(1)
  452. fistp dword ptr vdest
  453. fistp dword ptr udest
  454. endif
  455. endm
  456. ; Update the three interpolants, kick off the division
  457. STRIDE_UPDATE macro dw, du, dv
  458. fadd dw ; w u v
  459. fxch st(1) ; u w v
  460. fadd du ; u w v
  461. fxch st(2) ; v w u
  462. fadd dv ; v w u
  463. fxch st(2) ; u w v
  464. fxch st(1) ; w u v
  465. FDUP
  466. FRECIPROCAL
  467. endm
  468. STRIDE_NEXT macro reguv,regduv
  469. FDUP ; 1/w 1/w w u v
  470. fmul st,st(3) ; u/w 1/w w u v
  471. fxch st(1) ; 1/w u/w w u v
  472. push ecx
  473. mov e&reguv,dword ptr v0
  474. fmul st,st(4) ; v/w u/w w u v
  475. fxch st(1) ; u/w v/w w u v
  476. if 0
  477. fadd _RLDDIFloatConst2p36 ; U/W v/w w u v
  478. fxch st(1) ; v/w U/W w u v
  479. fadd _RLDDIFloatConst2p36 ; V/W U/W w u v
  480. fxch st(1) ; U/W V/W w u v
  481. fstp u1
  482. fstp v1
  483. endif
  484. ; Pack up into uv1
  485. FPPACK v1,u1 ; This has been expanded above...
  486. mov e&regduv,dword ptr v1
  487. sub e&regduv,e&reguv
  488. sar e&regduv,4h
  489. shl e&regduv,10h
  490. shl e&reguv,10h
  491. mov ecx,dword ptr u1
  492. mov reguv,word ptr u0
  493. sub ecx,dword ptr u0
  494. sar ecx,4h
  495. mov regduv,cx
  496. pop ecx
  497. STRIDE_UPDATE wstep16, ustep16, vstep16
  498. endm
  499. STRIDE_PRECHARGE macro
  500. if SUBPIX_CORRECT eq 0
  501. fld vl
  502. fld ul
  503. fld wl
  504. endif
  505. ; w u v
  506. FDUP
  507. FRECIPROCAL
  508. endm
  509. STRIDE_INIT macro
  510. ; 1/w w u v
  511. FDUP
  512. fmul st,st(3) ; u/w 1/w w u v
  513. fxch st(1) ; 1/w u/w w u v
  514. fmul st,st(4) ; v/w u/w w u v
  515. fxch st(1) ; u/w v/w w u v
  516. ; Pack up into u0,v0
  517. FPPACK v0,u0
  518. STRIDE_UPDATE wstep16, ustep16, vstep16
  519. endm
  520. ; If dest < src
  521. ; dest = st + 1
  522. ; else
  523. ; dest = st - 1;
  524. ORD_CHANGE macro dest, compare
  525. local under, alldone
  526. fld dest
  527. FCOMI compare
  528. fld1
  529. jae under
  530. fadd
  531. jmp alldone
  532. under:
  533. fsubp st(1),st
  534. alldone:
  535. fstp dest
  536. endm
  537. BIAS macro vv
  538. fld vv
  539. if 0
  540. fld1
  541. fadd st,st(1)
  542. fstp vv
  543. endif
  544. endm
  545. GET_ORD macro ord
  546. local small_er, small_em, alldone, never
  547. test wrap_&ord,-1
  548. je never
  549. BIAS ord&l
  550. BIAS ord&r
  551. BIAS ord&m
  552. fsub st,st(1) ; um-ur ur ul
  553. fxch st(1) ; ur um-ur ul
  554. fsubr st,st(2) ; ul-ur um-ur ul
  555. fxch st(2) ; ul um-ur ul-ur
  556. FDROP ; um-ur ul-ur
  557. FDUP ; um-ur um-ur ul-ur
  558. fsub st,st(2) ; (um-ur) - (ul-ur) = um-ul um-ur ul-ur
  559. ; ul-um um-ur ul-ur
  560. fabs ; em um-ur ul-ur
  561. fxch st(1) ; um-ur em ul-ur
  562. fabs ; er em ul-ur
  563. fxch st(2) ; ul-ur em er
  564. fabs ; el em er
  565. push edx ;[
  566. mov edx,0
  567. rept 3
  568. fcomp _RLDDIFloatConstHalf
  569. fnstsw ax
  570. sahf
  571. cmc
  572. adc edx,edx
  573. endm
  574. ; Explanation of this cunning trick:
  575. ; bit in ebx is zero if corresponding edge is greater than 0.5
  576. ; 2 1 0
  577. ; el em er
  578. ; Saves me having to write out complicated jumping code, fewer
  579. ; branches so smaller mispredict penalty.
  580. ;test edx,edx ; Fast fall-through for complex case
  581. ;jmp alldone
  582. and edx, 7
  583. cmp edx,6
  584. jne small_em
  585. ORD_CHANGE ord&l,ord&m ; el is small
  586. jmp alldone
  587. small_em:
  588. cmp edx,3
  589. jne small_er
  590. ORD_CHANGE ord&m,ord&r ; em is small
  591. jmp alldone
  592. small_er:
  593. cmp edx,5
  594. jne alldone
  595. ORD_CHANGE ord&r,ord&l ; er is small
  596. alldone:
  597. pop edx ;]
  598. never:
  599. endm
  600. TEX_PRELOAD macro l, r, m, PERSP
  601. ; Load up ul, vl, ur, vr, um, vm
  602. irp ord,<u,v>
  603. MVEDI !l, ord, l
  604. MVEDI !r, ord, r
  605. MVEDI !m, ord, m
  606. endm
  607. push eax
  608. GET_ORD u
  609. GET_ORD v
  610. pop eax
  611. if PERSP
  612. mov edi,dword ptr [l + RLDDIVertex_rhw]
  613. mov [wl],edi
  614. mov edi,dword ptr [r + RLDDIVertex_rhw]
  615. mov [wr],edi
  616. mov edi,dword ptr [m + RLDDIVertex_rhw]
  617. mov [wm],edi
  618. fld wl
  619. FDUP
  620. fmul ul
  621. fstp ul
  622. fmul vl
  623. fstp vl
  624. fld wr
  625. FDUP
  626. fmul ur
  627. fstp ur
  628. fmul vr
  629. fstp vr
  630. fld wm
  631. FDUP
  632. fmul um
  633. fstp um
  634. fmul vm
  635. fstp vm
  636. endif
  637. endm
  638. ; XXX the V-pipe thinks it's on holiday
  639. PACK macro result,u,v,delta
  640. local pos
  641. fld u
  642. fmul _RLDDIFloatConst64K ; 0-1 becomes 0-65535
  643. fistp dword ptr temp_double1
  644. fld v
  645. fmul _RLDDIFloatConst64K ; 0-1 becomes 0-65535
  646. fistp dword ptr temp_double2
  647. mov eax,dword ptr temp_double2
  648. shl eax,10h
  649. mov ax,word ptr temp_double1
  650. if delta
  651. test ah,ah
  652. jns pos
  653. sub eax,010000h
  654. pos:
  655. endif
  656. mov result,eax
  657. endm
  658. TEXPACK macro second_triangle,PERSP
  659. if PERSP eq 0
  660. PACK uvl,ul,vl,0
  661. PACK muv,mu,mv,1
  662. if second_triangle
  663. PACK muv2,mu2,mv2,1
  664. else
  665. mov muv2,eax
  666. endif
  667. PACK uvstep,ustep,vstep,1
  668. endif
  669. endm
  670. TEXFLAT macro ord,h,flatbottom,PERSP
  671. local onehigh
  672. ; mu = TEXTURE_DIFF(m->t&ord, ord&l, wrap_&ord) / h;
  673. cmp h,1
  674. je onehigh
  675. if flatbottom
  676. TEXTURE_DIFF ord&m,ord&l,wrap_&ord
  677. else
  678. TEXTURE_DIFF ord&l,ord&m,wrap_&ord
  679. endif
  680. DIVIDE_BY h
  681. fstp m&ord
  682. onehigh:
  683. ; ustep = RLDDICheckDiv16(TEXTURE_DIFF(ul, ur, wrap_u), w);
  684. TEXTURE_DIFF ord&l,ord&r,wrap_&ord
  685. fmul st,st(2)
  686. if PERSP
  687. fst ord&step
  688. fmul _RLDDIFloatConst16
  689. fstp ord&step16
  690. else
  691. fstp ord&step
  692. endif
  693. endm
  694. TEX_FLAT_BOTTOM macro h, PERSP
  695. TEXFLAT u,h,1,PERSP
  696. TEXFLAT v,h,1,PERSP
  697. if PERSP
  698. TEXFLAT w,h,1,PERSP
  699. endif
  700. ; ul = m->tu; /* start from middle */
  701. ; vl = m->tv; /* start from middle */
  702. mov eax,um
  703. mov ul,eax
  704. mov eax,vm
  705. mov vl,eax
  706. if PERSP
  707. mov eax,wm
  708. mov wl,eax
  709. endif
  710. TEXPACK 0, PERSP
  711. endm
  712. TEX_FLAT_TOP macro h, PERSP
  713. local nodiffs
  714. TEXFLAT u,h,0,PERSP
  715. TEXFLAT v,h,0,PERSP
  716. if PERSP
  717. TEXFLAT w,h,0,PERSP
  718. endif
  719. TEXPACK 0, PERSP
  720. endm
  721. TEX_RIGHT_TRI macro hls, hrs, h, PERSP
  722. irp ord,<u,v,w>
  723. ; mu = TEXTURE_DIFF(um, ul, wrap_u);
  724. TEXTURE_DIFF ord&m,ord&l,wrap_&ord
  725. fstp m&ord
  726. ; mu2 = TEXTURE_DIFF(um, ur, wrap_u);
  727. TEXTURE_DIFF ord&m,ord&r,wrap_&ord
  728. fstp m&ord&2
  729. ; ustep = RLDDIFMul16(mu2, hls) - RLDDIFMul16(mu, hrs)
  730. fld m&ord&2
  731. fmul hls
  732. fld m&ord
  733. fmul hrs ; mu*hrs mu2*hls
  734. fsubp st(1),st
  735. if PERSP
  736. fst ord&step
  737. fmul _RLDDIFloatConst16
  738. fstp ord&step16
  739. else
  740. fstp ord&step
  741. endif
  742. ; mu = mu2 = mu / h;
  743. fld m&ord
  744. mov ebp,h
  745. DIVIDE_BY ebp
  746. fst m&ord&2
  747. fstp m&ord
  748. endm
  749. mov eax,um
  750. mov ul,eax
  751. mov eax,vm
  752. mov vl,eax
  753. mov eax,wm
  754. mov wl,eax
  755. TEXPACK 0, PERSP
  756. endm
  757. TEX_LEFT_TRI macro hls, hrs, h1, h2, PERSP
  758. irp ord,<u,v,w>
  759. ; mu = TEXTURE_DIFF(um, ul, wrap_u);
  760. TEXTURE_DIFF ord&m,ord&l,wrap_&ord
  761. fstp m&ord
  762. ; mu2 = TEXTURE_DIFF(um, ur, wrap_u);
  763. TEXTURE_DIFF ord&m,ord&r,wrap_&ord
  764. fstp m&ord&2
  765. ; ustep = RLDDIFMul16(mu2, hls) - RLDDIFMul16(mu, hrs)
  766. fld m&ord&2
  767. fmul hls
  768. fld m&ord
  769. fmul hrs ; mu*hrs mu2*hls
  770. fsubp st(1),st
  771. if PERSP
  772. fst ord&step
  773. fmul _RLDDIFloatConst16
  774. fstp ord&step16
  775. else
  776. fstp ord&step
  777. endif
  778. ; mu2 = TEXTURE_DIFF(ul, ur, wrap_u);
  779. ; mu /= h1; mu2 /= h2;
  780. TEXTURE_DIFF ord&l,ord&r,wrap_&ord
  781. mov ebp,h2
  782. neg ebp
  783. DIVIDE_BY ebp
  784. fstp m&ord&2
  785. fld m&ord
  786. mov ebp,h1
  787. DIVIDE_BY ebp
  788. fstp m&ord
  789. endm
  790. mov eax,um
  791. mov ul,eax
  792. mov eax,vm
  793. mov vl,eax
  794. mov eax,wm
  795. mov wl,eax
  796. TEXPACK 1, PERSP
  797. endm
  798. endif ;}
  799. if RENDER_TEXTURE ;{
  800. ; This macro generates code to calculate the offset of a particular texcel
  801. ; from texture coordinates.
  802. ; The texture coordinates are in eax (v in hi-word, u in lo-word), and the
  803. ; result is given in eax.
  804. ; This code also adds 2 to esi, to use spare V-pipe capacity.
  805. addrcalc macro u_shift, v_shift
  806. addrcalc_&u_shift&_&v_shift:
  807. if (u_shift le 8) and (v_shift le 8)
  808. shr eax,10h + (8 - v_shift)
  809. mov al,dh ; Original u coord is in edx
  810. if (u_shift ne 8)
  811. shr eax,(8 - u_shift)
  812. endif
  813. else
  814. shr eax,10h - v_shift
  815. mov ax,dx
  816. shr eax,10h - u_shift
  817. endif
  818. ret
  819. endm
  820. i = 0
  821. rept 0ch
  822. j = 0;
  823. rept 0ch
  824. addrcalc %i,%j
  825. j = j + 1
  826. endm
  827. i = i + 1
  828. endm
  829. ; These are the register allocations for the fillspan loop for
  830. ; flat (F), gouraud (G), and perspective correct (P) textures.
  831. ; eax ebx ecx edx esi edi ebp
  832. ; FT * cnt,pix z uv zb pb texture
  833. ; GT * cnt,pix z uv zb pb shade
  834. ; FTP * u z v zb pb texture
  835. ; GTP * v z v zb pb shade
  836. ; This is the span for gouraud and flat textures (non-perspective-correct)
  837. ; Plot an affine run of ecx pixels
  838. ; eax ebx ecx edx esi edi ebp
  839. ; * * * uv * pdst duv
  840. RUNX macro a, b, counter, texture, uvstep
  841. local run0, run1, done
  842. mov e&a&x,edx
  843. xor e&b&x,e&b&x
  844. shr e&a&x,10h
  845. if (DEPTH eq 8)
  846. dec edi
  847. else
  848. sub edi,DEPTH / 8
  849. endif
  850. mov a&l,dh
  851. add edx,uvstep
  852. jmp run1
  853. if (DEPTH eq 8)
  854. run0: mov byte ptr [edi],b&l
  855. run1: mov b&l,[texture + e&a&x]
  856. mov e&a&x,edx
  857. inc edi
  858. shr e&a&x,10h
  859. mov b&l,byte ptr [pixels + 4 * e&b&x]
  860. mov a&l,dh
  861. add edx,uvstep
  862. dec counter
  863. jne run0
  864. done:
  865. mov byte ptr [edi],b&l
  866. else
  867. run0: mov word ptr [edi],b&x
  868. run1: xor e&b&x,e&b&x
  869. mov b&l,[texture + e&a&x]
  870. mov e&a&x,edx
  871. shr e&a&x,10h
  872. add edi,2
  873. mov e&b&x,dword ptr [pixels + 4 * e&b&x]
  874. mov a&l,dh
  875. add edx,uvstep
  876. dec counter
  877. jne run0
  878. done:
  879. mov word ptr [edi],b&x
  880. endif
  881. endm
  882. RUNXd macro a, b, counter, texture, uvstep, sz
  883. local run0, run1, done
  884. local shift1, shift2
  885. if (sz eq 128)
  886. dimension = 7
  887. endif
  888. if (sz eq 64)
  889. dimension = 6
  890. endif
  891. if (sz eq 32)
  892. dimension = 5
  893. endif
  894. if (sz eq 16)
  895. dimension = 4
  896. endif
  897. if (sz eq 8)
  898. dimension = 3
  899. endif
  900. shift1 = 18h - dimension
  901. shift2 = 8 - dimension
  902. mov e&a&x,edx
  903. xor e&b&x,e&b&x
  904. shr e&a&x,shift1
  905. if (DEPTH eq 8)
  906. dec edi
  907. else
  908. sub edi,DEPTH / 8
  909. endif
  910. mov a&l,dh
  911. add edx,uvstep
  912. shr eax,shift2
  913. jmp run1
  914. if (DEPTH eq 8)
  915. run0: mov byte ptr [edi],b&l
  916. run1: mov b&l,[texture + e&a&x]
  917. mov e&a&x,edx
  918. inc edi
  919. shr e&a&x,shift1
  920. mov b&l,byte ptr [pixels + 4 * e&b&x]
  921. mov a&l,dh
  922. add edx,uvstep
  923. shr e&a&x,shift2
  924. dec counter
  925. jne run0
  926. done:
  927. mov byte ptr [edi],b&l
  928. else
  929. run0: mov word ptr [edi],b&x
  930. run1: xor e&b&x,e&b&x
  931. mov b&l,[texture + e&a&x]
  932. mov e&a&x,edx
  933. shr e&a&x,shift1
  934. add edi,2
  935. mov e&b&x,dword ptr [pixels + 4 * e&b&x]
  936. mov a&l,dh
  937. shr e&a&x,shift2
  938. add edx,uvstep
  939. dec counter
  940. jne run0
  941. done:
  942. mov word ptr [edi],b&x
  943. endif
  944. endm
  945. if GOURAUD_TABLE eq 0 ;{
  946. AFILLSPAN macro size
  947. local fill_span_0, fill_span_1, fill_span_2, fill_span_3, fill_span_4
  948. local fill_span_5
  949. sar eax,10h
  950. sar ebx,10h
  951. sub ebx,eax
  952. jle fill_span_5
  953. push edi ;[
  954. push esi ;[
  955. push ecx ;[
  956. push edx ;[
  957. if RENDER_GOURAUD
  958. add ebp, 8000h ;round up
  959. endif
  960. if DEPTH eq 8
  961. add edi,eax
  962. else
  963. lea edi,[edi + 2 * eax]
  964. endif
  965. if (size ne 0) and ((RENDER_Z eq 0) and ((RENDER_GOURAUD eq 0) and (RENDER_TRANS eq 0)))
  966. ;{
  967. mov esi,[uvstep]
  968. if (size eq 256)
  969. RUNX a, c, ebx, ebp, esi
  970. else
  971. RUNXd a, c, ebx, ebp, esi, size
  972. endif
  973. else ;}{
  974. lea esi,[esi + 2 * eax]
  975. sal ebx,10h ; Make space for work in bx
  976. sub ebx,10000h
  977. ; Do the Z-test later for transparency
  978. fill_span_0:
  979. if WANT_ZBUFFER and (RENDER_TRANS eq 0)
  980. mov eax,ecx
  981. sar eax,8h
  982. fill_span_1:
  983. cmp ax,word ptr [esi]
  984. ja fill_span_2
  985. mov [esi],ax
  986. else
  987. fill_span_1:
  988. endif
  989. mov eax,edx ; eax = p(u,v)
  990. if size gt 0
  991. if size eq 256
  992. shr eax,10h
  993. add esi,2 ; V
  994. mov al,dh
  995. endif
  996. if size eq 128
  997. shr eax,11h
  998. add esi,2
  999. mov al,dh
  1000. shr eax,1
  1001. endif
  1002. if size eq 64
  1003. shr eax,12h
  1004. add esi,2
  1005. mov al,dh
  1006. shr eax,2
  1007. endif
  1008. if size eq 16
  1009. shr eax,14h
  1010. add esi,2
  1011. mov al,dh
  1012. shr eax,4
  1013. endif
  1014. if size eq 8
  1015. shr eax,15h
  1016. add esi,2
  1017. mov al,dh
  1018. shr eax,5
  1019. endif
  1020. else
  1021. call [addrcalc_code]
  1022. add esi,2
  1023. endif
  1024. if RENDER_GOURAUD
  1025. add eax,texture
  1026. if (GOURAUD_TABLE eq 0)
  1027. mov bl,[eax]
  1028. xor eax,eax
  1029. mov al,bl
  1030. endif
  1031. else
  1032. if (size gt 0) and (size le 16)
  1033. ; We know that (eax < 256), so no need to mess around
  1034. ; clearing the rest of the word
  1035. mov al,[ebp + eax]
  1036. else
  1037. mov bl,[ebp + eax]
  1038. xor eax,eax
  1039. mov al,bl
  1040. endif
  1041. endif
  1042. if (size ge 0)
  1043. if DEPTH eq 8
  1044. inc edi ; V
  1045. else
  1046. add edi,2
  1047. endif
  1048. endif
  1049. ; eax is now texture pixel
  1050. if RENDER_TRANS
  1051. if (size ge 0)
  1052. cmp eax,transparent
  1053. je fill_span_4
  1054. endif
  1055. ; Now we know we're going to plot pixel, do Z test
  1056. if RENDER_Z
  1057. push eax ;[
  1058. mov eax,ecx
  1059. sar eax,8h
  1060. cmp ax,word ptr [esi - 2]
  1061. ja fill_span_2
  1062. mov [esi - 2],ax
  1063. pop eax ;]
  1064. endif
  1065. endif
  1066. if RENDER_GOURAUD
  1067. push ebx ;[
  1068. if GOURAUD_TABLE ;{
  1069. ; eax is address of texcel
  1070. mov ebx,ebp
  1071. shr ebx,8
  1072. and ebx,01fffh
  1073. mov bl,[eax]
  1074. add ecx,dz
  1075. add edx,uvstep
  1076. add ebp,sstep
  1077. if (DEPTH eq 8)
  1078. mov bl,[GTpixels + ebx]
  1079. else
  1080. mov bx,[GTpixels + 2 * ebx]
  1081. endif
  1082. mov eax,ecx
  1083. SEG_REND
  1084. if (DEPTH eq 8)
  1085. mov [edi-1],bl
  1086. else
  1087. mov [edi-2],bx
  1088. endif
  1089. else ;}{
  1090. ; eax is texcel
  1091. ; eax = p(u,v)
  1092. mov ebx,colors
  1093. add ecx,dz
  1094. add edx,uvstep
  1095. mov eax,[ebx + 4 * eax]
  1096. ; eax = colors[p(u,v)]
  1097. mov ebx,ebp
  1098. sar ebx,10h
  1099. add ebx,eax
  1100. ; ebx = colors[p(u,v)] + (shade >> 16)
  1101. mov eax,map
  1102. add ebp,sstep
  1103. if DEPTH eq 8
  1104. mov bl,byte ptr [eax + 4 * ebx]
  1105. mov eax,ecx
  1106. SEG_REND
  1107. mov [edi-1],bl
  1108. else
  1109. mov bx,word ptr [eax + 4 * ebx]
  1110. mov eax,ecx
  1111. SEG_REND
  1112. mov [edi-2],bx
  1113. endif
  1114. endif ;}
  1115. pop ebx ;]
  1116. else
  1117. add ecx,dz
  1118. add edx,uvstep
  1119. if DEPTH eq 8
  1120. mov bl,byte ptr [pixels + 4 * eax]
  1121. mov eax,ecx
  1122. SEG_REND
  1123. mov [edi-1],bl
  1124. else
  1125. mov bx,word ptr [pixels + 4 * eax]
  1126. mov eax,ecx
  1127. SEG_REND
  1128. mov [edi-2],bx
  1129. endif
  1130. endif
  1131. shr eax,8h
  1132. sub ebx,10000h
  1133. jnc fill_span_1
  1134. jmp fill_span_3
  1135. fill_span_2:
  1136. ; Didn't plot pixel, z test failed, go to next one
  1137. if RENDER_TRANS eq 0
  1138. add esi,2
  1139. if DEPTH eq 8
  1140. inc edi
  1141. else
  1142. add edi,2
  1143. endif
  1144. else
  1145. pop eax ; trash left on stack
  1146. endif
  1147. fill_span_4: ; Failed transparency test
  1148. add ecx,dz
  1149. add edx,uvstep
  1150. mov eax,ecx
  1151. if RENDER_GOURAUD
  1152. add ebp,sstep
  1153. endif
  1154. shr eax,8h
  1155. sub ebx,10000h
  1156. jnc fill_span_1
  1157. endif ;}
  1158. fill_span_3:
  1159. pop edx ;]
  1160. pop ecx ;]
  1161. pop esi ;]
  1162. pop edi ;]
  1163. fill_span_5:
  1164. endm
  1165. else ; }{
  1166. ; We have a gouraud table (GOURAUD_TABLE is nonzero). Assume no transparency.
  1167. ; eax ebx ecx edx esi edi ebp
  1168. ; GT * * Z uv zb pb count+shade
  1169. AFILLSPAN macro size
  1170. local fill_span_0, fill_span_1, fill_span_2, fill_span_3, fill_span_4
  1171. local fill_span_5
  1172. sar eax,10h
  1173. sar ebx,10h
  1174. sub ebx,eax
  1175. jle fill_span_5
  1176. push edi ;[
  1177. push esi ;[
  1178. push ecx ;[
  1179. push edx ;[
  1180. if DEPTH eq 8
  1181. add edi,eax
  1182. else
  1183. lea edi,[edi + 2 * eax]
  1184. endif
  1185. lea esi,[esi + 2 * eax]
  1186. shr ebp,8h
  1187. add ebp,80h
  1188. and ebp,0ffffh
  1189. dec ebx
  1190. shl ebx,10h
  1191. or ebp,ebx
  1192. mov ebx,ecx
  1193. fill_span_0:
  1194. if WANT_ZBUFFER
  1195. shr ebx,8h
  1196. mov eax,edx
  1197. cmp bx,word ptr [esi]
  1198. ja fill_span_2
  1199. mov [esi],bx
  1200. endif
  1201. if size gt 0
  1202. if size eq 256
  1203. shr eax,10h
  1204. add esi,2 ; V
  1205. mov al,dh
  1206. endif
  1207. if size eq 128
  1208. shr eax,11h
  1209. add esi,2
  1210. mov al,dh
  1211. shr eax,1
  1212. endif
  1213. if size eq 64
  1214. shr eax,12h
  1215. add esi,2
  1216. mov al,dh
  1217. shr eax,2
  1218. endif
  1219. if size eq 16
  1220. shr eax,14h
  1221. add esi,2
  1222. mov al,dh
  1223. shr eax,4
  1224. endif
  1225. if size eq 8
  1226. shr eax,15h
  1227. add esi,2
  1228. mov al,dh
  1229. shr eax,5
  1230. endif
  1231. else
  1232. call [addrcalc_code]
  1233. add esi,2
  1234. endif
  1235. add eax,[texture] ; U
  1236. mov ebx,ebp
  1237. if DEPTH eq 8
  1238. inc edi ; U
  1239. else
  1240. add edi,2
  1241. endif
  1242. ; eax is address of texcel
  1243. mov bl,[eax]
  1244. and ebx,01fffh
  1245. add ecx,dz
  1246. add edx,uvstep
  1247. if (DEPTH eq 8)
  1248. mov al,[GTpixels + ebx]
  1249. else
  1250. mov ax,[GTpixels + 2 * ebx]
  1251. endif
  1252. SEG_REND
  1253. if (DEPTH eq 8)
  1254. mov [edi-1],al
  1255. else
  1256. mov [edi-2],ax
  1257. endif
  1258. mov ebx,ecx
  1259. add ebp,[sstep]
  1260. jc fill_span_0
  1261. jmp fill_span_3
  1262. fill_span_2:
  1263. ; Didn't plot pixel, z test failed, go to next one
  1264. add esi,2
  1265. if DEPTH eq 8
  1266. inc edi
  1267. else
  1268. add edi,2
  1269. endif
  1270. add ecx,dz
  1271. add edx,uvstep
  1272. add ebp,sstep
  1273. mov ebx,ecx
  1274. jc fill_span_0
  1275. fill_span_3:
  1276. pop edx ;]
  1277. pop ecx ;]
  1278. pop esi ;]
  1279. pop edi ;]
  1280. fill_span_5:
  1281. endm
  1282. endif ;}
  1283. if PERSPECTIVE eq 0 ;{
  1284. SFILLSPAN macro size
  1285. AFILLSPAN size
  1286. endm
  1287. else ; }{
  1288. ; Perspective-correct span
  1289. ; eax ebx ecx edx esi edi ebp
  1290. ; FP-no Z p0 * w uv tp dp duv
  1291. ; FP-Z p0 z w uv zp dp duv
  1292. ; GP-no Z p0 * [w] uv tp dp s
  1293. CLR8 macro r8,r32
  1294. xor r8,r8
  1295. endm
  1296. TRIPLE macro i
  1297. mov eax,edx ; u
  1298. lea ebx,[edx+ebp] ; v
  1299. shr eax,10h ; u
  1300. lea ecx,[edx+2 * ebp] ; v
  1301. shr ebx,10h ; u
  1302. mov al,dh ; v
  1303. shr ecx,10h ; u
  1304. add edx,ebp ; v
  1305. mov bl,dh ; u
  1306. add edx,ebp ; v
  1307. mov al,[esi + eax] ; u
  1308. mov bl,[esi + ebx] ; v
  1309. mov cl,dh
  1310. add edx,ebp
  1311. CLR8 ah,eax
  1312. CLR8 bh,ebx
  1313. mov cl,[esi + ecx]
  1314. mov eax,[pixels + 4 * eax]
  1315. CLR8 ch,ecx
  1316. mov ebx,[pixels + 4 * ebx]
  1317. mov ecx,[pixels + 4 * ecx]
  1318. if DEPTH eq 8
  1319. SEG_REND
  1320. mov byte ptr [edi + i],al
  1321. SEG_REND
  1322. mov byte ptr [edi + i + 1],bl
  1323. SEG_REND
  1324. mov byte ptr [edi + i + 2],cl
  1325. else
  1326. SEG_REND
  1327. mov word ptr [edi + (2 * i)],ax
  1328. SEG_REND
  1329. mov word ptr [edi + (2 * i) + 2],bx
  1330. SEG_REND
  1331. mov word ptr [edi + (2 * i) + 4],cx
  1332. endif
  1333. endm
  1334. SHUFFLE macro
  1335. mov eax,dword ptr u1
  1336. mov dword ptr u0,eax
  1337. mov eax,dword ptr v1
  1338. mov dword ptr v0,eax
  1339. endm
  1340. PCSPAN macro WANT_Z, size
  1341. local fill_span_0, fill_span_next, zerolength, a16
  1342. local fill_span_next16, here
  1343. local nextpixel, zfailed
  1344. local UNROLL
  1345. UNROLL = (((RENDER_GOURAUD eq 0) and (WANT_Z eq 0)) and (size eq 256) and (RENDER_TRANS eq 0))
  1346. if WANT_Z eq 0
  1347. mov esi,texture
  1348. endif
  1349. if RENDER_GOURAUD
  1350. if GOURAUD_TABLE
  1351. shr ebp,8h
  1352. add ebp,80h
  1353. and ebp,0ffffh
  1354. else
  1355. add ebp, 8000h ;round to nearest shade
  1356. endif
  1357. endif
  1358. STRIDE_INIT
  1359. mov eax,ecx ; Z
  1360. mov ecx,ebx ; w
  1361. mov ebx,eax ; Z
  1362. mov spanlength,ecx
  1363. cmp ecx,STRIDE_LENGTH
  1364. jb a16
  1365. mov ecx,STRIDE_LENGTH
  1366. a16:
  1367. if UNROLL
  1368. cmp ecx,STRIDE_LENGTH
  1369. je fill_span_next16
  1370. endif
  1371. fill_span_next:
  1372. if RENDER_GOURAUD eq 0
  1373. STRIDE_NEXT dx,bp
  1374. else
  1375. STRIDE_NEXT dx,ax
  1376. mov uvstep,eax
  1377. endif
  1378. if (RENDER_Z eq 0) and ((size eq 256) and (((RENDER_GOURAUD eq 0) and (RENDER_TRANS eq 0))));{
  1379. RUNX a, b, ecx, esi, ebp
  1380. else ;}{
  1381. if WANT_Z eq 0
  1382. xor ebx,ebx ; ebx is zero in this loop
  1383. endif
  1384. fill_span_0:
  1385. if WANT_Z and (RENDER_TRANS eq 0)
  1386. mov eax,ebx
  1387. shr eax,8h
  1388. cmp ax,word ptr [esi]
  1389. ja zfailed
  1390. mov word ptr [esi],ax
  1391. endif
  1392. mov eax,edx ; eax = p(u,v)
  1393. if size gt 0
  1394. if size eq 256
  1395. shr eax,10h
  1396. mov al,dh
  1397. endif
  1398. if size eq 128
  1399. shr eax,11h
  1400. mov al,dh
  1401. shr eax,1
  1402. endif
  1403. if size eq 64
  1404. shr eax,12h
  1405. mov al,dh
  1406. shr eax,2
  1407. endif
  1408. if size eq 16
  1409. shr eax,14h
  1410. mov al,dh
  1411. shr eax,4
  1412. endif
  1413. if size eq 8
  1414. shr eax,15h
  1415. mov al,dh
  1416. shr eax,5
  1417. endif
  1418. else
  1419. call [addrcalc_code]
  1420. endif
  1421. if WANT_Z eq 0
  1422. if RENDER_GOURAUD
  1423. mov al,[esi + eax]
  1424. and eax,0ffh
  1425. else
  1426. mov bl,[esi + eax]
  1427. endif
  1428. else
  1429. add eax,texture
  1430. mov al,[eax]
  1431. and eax,0ffh
  1432. endif
  1433. ; eax ( or ebx ) is now texture pixel
  1434. if RENDER_TRANS
  1435. if (RENDER_GOURAUD eq 0) and (WANT_Z eq 0)
  1436. cmp ebx,transparent
  1437. else
  1438. cmp eax,transparent
  1439. endif
  1440. je zfailed
  1441. ; Now we know we're going to plot pixel, do Z test
  1442. if RENDER_Z
  1443. push eax ;[
  1444. mov eax,ebx
  1445. sar eax,8h
  1446. cmp ax,word ptr [esi]
  1447. ja popJmp_zfailed
  1448. mov [esi],ax
  1449. pop eax ;]
  1450. jmp not_zfailed
  1451. popJmp_zfailed:
  1452. pop eax;
  1453. jmp zfailed
  1454. not_zfailed:
  1455. endif
  1456. endif
  1457. if DEPTH eq 8
  1458. inc edi ; V
  1459. else
  1460. add edi,2
  1461. endif
  1462. if WANT_Z
  1463. add esi,2
  1464. add ebx,dz
  1465. endif
  1466. if RENDER_GOURAUD
  1467. push ebx ;[
  1468. if GOURAUD_TABLE
  1469. mov ebx,ebp
  1470. and ebx,01fffh
  1471. mov bl,al
  1472. add ebp,[sstep]
  1473. add edx,[uvstep]
  1474. if (DEPTH eq 8)
  1475. mov bl,[GTpixels + ebx]
  1476. else
  1477. mov bx,[GTpixels + 2 * ebx]
  1478. endif
  1479. else
  1480. ; eax = p(u,v)
  1481. mov ebx,colors
  1482. add edx,uvstep
  1483. mov eax,[ebx + 4 * eax]
  1484. ; eax = colors[p(u,v)]
  1485. mov ebx,ebp
  1486. sar ebx,10h
  1487. add ebx,eax
  1488. ; ebx = colors[p(u,v)] + (shade >> 16)
  1489. mov eax,map
  1490. add ebp,sstep
  1491. if DEPTH eq 8
  1492. mov bl,byte ptr [eax + 4 * ebx]
  1493. else
  1494. mov bx,word ptr [eax + 4 * ebx]
  1495. endif
  1496. endif
  1497. if DEPTH eq 8
  1498. mov eax,ecx
  1499. SEG_REND
  1500. mov [edi-1],bl
  1501. else
  1502. mov eax,ecx
  1503. SEG_REND
  1504. mov [edi-2],bx
  1505. endif
  1506. pop ebx ;]
  1507. else
  1508. add edx,ebp
  1509. if WANT_Z
  1510. mov eax,dword ptr [pixels + 4 * eax]
  1511. else
  1512. mov eax,dword ptr [pixels + 4 * ebx]
  1513. endif
  1514. if DEPTH eq 8
  1515. SEG_REND
  1516. mov [edi-1],al
  1517. else
  1518. SEG_REND
  1519. mov [edi-2],ax
  1520. endif
  1521. endif
  1522. nextpixel:
  1523. dec ecx
  1524. jnz fill_span_0
  1525. endif ;}
  1526. mov ecx,spanlength
  1527. sub ecx,STRIDE_LENGTH
  1528. mov spanlength,ecx
  1529. jle zerolength
  1530. SHUFFLE ; uv0 = uv1
  1531. cmp ecx,STRIDE_LENGTH
  1532. jle fill_span_next
  1533. if UNROLL eq 0
  1534. mov ecx,STRIDE_LENGTH
  1535. jmp fill_span_next
  1536. else
  1537. fill_span_next16:
  1538. STRIDE_NEXT dx,bp
  1539. ; Ensure that we start this run in U pipe!
  1540. if 0
  1541. xor ecx,ecx
  1542. DOUBLE 0
  1543. DOUBLE 2
  1544. DOUBLE 4
  1545. DOUBLE 6
  1546. DOUBLE 8
  1547. DOUBLE 0ah
  1548. DOUBLE 0ch
  1549. DOUBLE 0eh
  1550. else
  1551. TRIPLE 0 ; 0,1,2
  1552. TRIPLE 3 ; 3,4,5
  1553. TRIPLE 6 ; 6,7,8
  1554. TRIPLE 9 ; 9,a,b
  1555. if 1
  1556. TRIPLE 0ch ; c,d,e
  1557. mov eax,edx
  1558. shr eax,10h
  1559. mov al,dh
  1560. add edx,ebp
  1561. mov al,[esi + eax]
  1562. CLR8 ah,eax
  1563. mov eax,[pixels + 4 * eax]
  1564. if DEPTH eq 8
  1565. mov byte ptr [edi + 0fh],al
  1566. else
  1567. mov word ptr [edi + 01eh],ax
  1568. endif
  1569. else
  1570. i = 0ch
  1571. rept 2
  1572. mov eax,edx
  1573. lea ebx,[edx+ebp]
  1574. shr eax,10h
  1575. shr ebx,10h
  1576. mov al,dh
  1577. add edx,ebp
  1578. mov bl,dh
  1579. add edx,ebp
  1580. mov al,[esi + eax]
  1581. mov bl,[esi + ebx]
  1582. and eax,0ffh
  1583. and ebx,0ffh
  1584. mov eax,[pixels + 4 * eax]
  1585. mov ebx,[pixels + 4 * ebx]
  1586. if DEPTH eq 8
  1587. mov byte ptr [edi + i],al
  1588. mov byte ptr [edi + i + 1],bl
  1589. else
  1590. mov byte ptr [edi + i],ax
  1591. mov byte ptr [edi + i + 2],bx
  1592. endif
  1593. i = i + 2
  1594. endm
  1595. endif
  1596. endif
  1597. lea edi,[edi + DEPTH * 2] ; 8 => 16 bytes, 16 => 32 bytes
  1598. mov ebx,spanlength
  1599. sub ebx,STRIDE_LENGTH
  1600. mov ecx,ebx
  1601. jle zerolength
  1602. mov spanlength,ebx
  1603. SHUFFLE ; uv0 = uv1
  1604. cmp ecx,STRIDE_LENGTH
  1605. jle fill_span_next
  1606. jmp fill_span_next16
  1607. endif
  1608. if (RENDER_Z or RENDER_TRANS) ;{
  1609. zfailed:
  1610. add edi,DEPTH / 8
  1611. if RENDER_Z
  1612. add esi,2
  1613. add ebx,dz
  1614. endif
  1615. ; Masm bug
  1616. if RENDER_GOURAUD
  1617. add ebp,sstep
  1618. add edx,uvstep
  1619. else
  1620. add edx,ebp
  1621. endif
  1622. jmp nextpixel
  1623. endif ;}
  1624. zerolength:
  1625. endm
  1626. SFILLSPAN macro size
  1627. local fill_span_3, fill_span_drop
  1628. local ztest0, quit, zfill, zfailed, ztest1, quit1, mixed
  1629. local evenstart, notail
  1630. sar eax,10h
  1631. sar ebx,10h
  1632. sub ebx,eax
  1633. jle fill_span_3
  1634. push edi ;[
  1635. push esi ;[
  1636. push ecx ;[
  1637. push edx ;[
  1638. STRIDE_PRECHARGE
  1639. ; eax ebx ecx edx esi edi ebp
  1640. ; * * Z * zp
  1641. lea esi,[esi + 2 * eax]
  1642. if DEPTH eq 8
  1643. add edi,eax
  1644. else
  1645. lea edi,[edi + 2 * eax]
  1646. endif
  1647. if (RENDER_Z eq 0) ; {
  1648. PCSPAN 0,size
  1649. else ; }{
  1650. if RENDER_GOURAUD or RENDER_TRANS ; {
  1651. PCSPAN 1,size
  1652. else ; }{
  1653. cmp ebx,4
  1654. jbe mixed
  1655. mov eax,ecx
  1656. shr eax,8h
  1657. cmp ax,word ptr [esi]
  1658. ja zfailed
  1659. mov word ptr [esi],ax
  1660. push ebx
  1661. push ecx
  1662. push esi
  1663. test esi,3
  1664. je evenstart
  1665. add esi,2
  1666. dec ebx
  1667. add ecx,dz
  1668. evenstart:
  1669. mov spanlength,ebx
  1670. shr ebx,1h
  1671. mov edx,dz
  1672. shl ecx,8h
  1673. shl edx,8h
  1674. add ecx,edx ; Start at hi-word
  1675. ztest0:
  1676. cmp ecx,dword ptr [esi]
  1677. ja quit
  1678. mov dword ptr [esi],ecx ; u
  1679. mov eax,ecx
  1680. add esi,4 ; u
  1681. sub eax,edx
  1682. shr eax,10h ; u
  1683. lea ecx,[ecx + 2 * edx]
  1684. mov word ptr [esi-4],ax ; u
  1685. dec ebx
  1686. jne ztest0
  1687. quit:
  1688. mov edx,esi ; Might need this in a mo...
  1689. mov eax,ecx
  1690. pop esi
  1691. pop ecx
  1692. pop ebx
  1693. ja mixed
  1694. test spanlength,1
  1695. jz notail
  1696. ; Do the final pixel
  1697. shr eax,10h
  1698. cmp ax,word ptr [edx]
  1699. ja mixed
  1700. mov word ptr [edx],ax
  1701. notail:
  1702. ; Not mixed, plot
  1703. PCSPAN 0,size
  1704. jmp fill_span_drop
  1705. zfailed:
  1706. ; If whole line fails, jump to fill_span_3. Otherwise, jump
  1707. ; to mixed.
  1708. push eax
  1709. push ebx
  1710. push ecx
  1711. push edx
  1712. push esi
  1713. ztest1:
  1714. mov eax,ecx
  1715. shr eax,8h
  1716. cmp ax,word ptr [esi]
  1717. jb quit1
  1718. add ecx,dz
  1719. add esi,2
  1720. dec ebx
  1721. jne ztest1
  1722. quit1:
  1723. pop esi
  1724. pop edx
  1725. pop ecx
  1726. pop ebx
  1727. pop eax
  1728. jae fill_span_drop
  1729. mixed:
  1730. PCSPAN 1,size
  1731. fill_span_drop:
  1732. endif ;}
  1733. endif ;}
  1734. FDROP
  1735. if SUBPIX_CORRECT eq 0
  1736. FDROP
  1737. FDROP
  1738. FDROP
  1739. endif
  1740. pop edx ;]
  1741. pop ecx ;]
  1742. pop esi ;]
  1743. pop edi ;]
  1744. fill_span_3:
  1745. if SUBPIX_CORRECT
  1746. FDROP
  1747. FDROP
  1748. FDROP
  1749. endif
  1750. endm
  1751. endif ;}
  1752. else ;}{
  1753. if ((RENDER_Z eq 0)) and (RENDER_GOURAUD eq 0) ;{
  1754. ; eax ebx ecx edx esi edi ebp
  1755. ; FLAT * counter * pixel * pb *
  1756. ; GOURAUD * counter z shade zb pb map
  1757. masks:
  1758. dd 000000000h
  1759. dd 0000000ffh
  1760. dd 00000ffffh
  1761. dd 000ffffffh
  1762. SFILLSPAN macro parm
  1763. local admit, ptail, tail, loop4, tail4, nowt, dun
  1764. shr eax,16
  1765. shr ebx,16
  1766. cmp eax,ebx
  1767. jz nowt
  1768. push edi ;[
  1769. push esi ;[
  1770. push ecx ;[
  1771. push edx ;[
  1772. jb admit
  1773. xchg eax,ebx
  1774. admit:
  1775. lea edi,[edi + (DEPTH / 8) * eax]
  1776. sub ebx,eax
  1777. ; eax is starting X, ebx is width
  1778. ; edx is pixel, repeated as necessary
  1779. cmp ebx,8 ; Must be sure that we're to do at least 8 pixels
  1780. jl tail
  1781. ; 0 4 writes PPPP 0xffffffff
  1782. ; 1 3 writes VPPP 0xffffff00
  1783. ; 2 2 writes VVPP 0xffff0000
  1784. ; 3 1 write VVVP 0xff000000
  1785. mov ecx,edi
  1786. and edi,0fffffffch
  1787. and ecx,3
  1788. if (DEPTH eq 16)
  1789. shr ecx,1
  1790. endif
  1791. mov eax,[edi] ; video = ((video ^ pix) & mask) ^ pix
  1792. if (DEPTH eq 8)
  1793. sub ebx,4 ; ebx -= (4 - ecx)
  1794. else
  1795. sub ebx,2 ; ebx -= (2 - ecx)
  1796. endif
  1797. xor eax,edx
  1798. mov ebp,[masks + (4 * (DEPTH / 8)) * ecx]
  1799. add ebx,ecx
  1800. and eax,ebp ; 1 bits stay as video, 0 bits from pixel
  1801. add edi,4
  1802. xor eax,edx
  1803. mov ecx,ebx ;[
  1804. if (DEPTH eq 8)
  1805. shr ebx,2
  1806. else
  1807. shr ebx,1
  1808. endif
  1809. mov [edi-4],eax
  1810. ; We now have a run of ebx dwords to write to edi
  1811. cmp ebx,1000
  1812. jl tail4
  1813. sub ebx,8
  1814. loop4: mov [edi],edx
  1815. mov [edi+4],edx
  1816. mov [edi+8],edx
  1817. mov [edi+12],edx
  1818. mov [edi+16],edx
  1819. mov [edi+20],edx
  1820. mov [edi+24],edx
  1821. mov [edi+28],edx
  1822. add edi,32
  1823. sub ebx,8
  1824. jnc loop4
  1825. add ebx,8
  1826. je ptail
  1827. tail4: mov [edi],edx
  1828. add edi,4
  1829. dec ebx
  1830. jnz tail4
  1831. ptail:
  1832. if (DEPTH eq 8)
  1833. and ecx,3 ;]
  1834. else
  1835. and ecx,1
  1836. endif
  1837. jz dun
  1838. mov ebx,ecx
  1839. tail:
  1840. if (DEPTH eq 8)
  1841. mov [edi],dl
  1842. inc edi
  1843. else
  1844. mov [edi],dx
  1845. add edi,2
  1846. endif
  1847. dec ebx
  1848. jnz tail
  1849. dun:
  1850. pop edx ;]
  1851. pop ecx ;]
  1852. pop esi ;]
  1853. pop edi ;]
  1854. nowt:
  1855. endm
  1856. else ;}{
  1857. ; eax ebx ecx edx esi edi ebp
  1858. ; FLAT * counter z pixel zb pb dz
  1859. ; GOURAUD * counter z shade zb pb map
  1860. SFILLSPAN macro parm
  1861. local fill_span_0, fill_span_0i, fill_span_1, fill_span_2, fill_span_3
  1862. local fill_spar_0, fill_spar_0i, fill_spar_1, fill_spar_2
  1863. local fill_span_alldone, fill_span_reverse
  1864. sar eax,10h
  1865. sar ebx,10h
  1866. sub ebx,eax
  1867. je fill_span_alldone
  1868. push edi ;[
  1869. push esi ;[
  1870. push ecx ;[
  1871. jl fill_span_reverse
  1872. push edx ;[
  1873. if RENDER_GOURAUD
  1874. add edx, 8000h ;round up
  1875. endif
  1876. if DEPTH eq 8
  1877. add edi,eax
  1878. else
  1879. lea edi,[edi + 2 * eax]
  1880. endif
  1881. lea esi,[esi + 2 * eax]
  1882. mov eax,ecx
  1883. shr eax,Z_SHIFT
  1884. jmp fill_span_1
  1885. fill_span_0:
  1886. add esi,2
  1887. if RENDER_GOURAUD
  1888. add ecx,dz
  1889. add edx,sstep
  1890. else
  1891. add ecx,ebp
  1892. endif
  1893. fill_span_0i:
  1894. if RENDER_Z
  1895. mov eax,ecx
  1896. shr eax,Z_SHIFT
  1897. endif
  1898. if DEPTH eq 8
  1899. inc edi
  1900. else
  1901. add edi,2
  1902. endif
  1903. fill_span_1:
  1904. if RENDER_Z
  1905. cmp ax,word ptr [esi]
  1906. ja fill_span_2
  1907. mov word ptr [esi],ax
  1908. endif
  1909. if RENDER_GOURAUD
  1910. mov eax,edx
  1911. sar eax,10h ; U1
  1912. ; We're going to use eax in an EA calc soon, avoid AGI by
  1913. ; doing other work.
  1914. add esi,2 ; V1
  1915. add ecx,dz ; U2
  1916. add edx,sstep ; V2
  1917. mov eax,[ebp + 4 * eax] ; U1
  1918. dec ebx ; V1
  1919. SEG_REND
  1920. if DEPTH eq 8
  1921. mov byte ptr [edi],al
  1922. else
  1923. mov word ptr [edi],ax
  1924. endif
  1925. jne fill_span_0i
  1926. jmp fill_span_3
  1927. else
  1928. SEG_REND
  1929. if DEPTH eq 8
  1930. mov byte ptr [edi],dl
  1931. else
  1932. mov word ptr [edi],dx
  1933. endif
  1934. endif
  1935. fill_span_2:
  1936. dec ebx
  1937. jne fill_span_0
  1938. jmp fill_span_3
  1939. fill_span_reverse:
  1940. ; eax is rhs, ebx is negative length
  1941. push edx ;[
  1942. if RENDER_GOURAUD
  1943. add edx, 8000h ;round up
  1944. endif
  1945. if DEPTH eq 8
  1946. lea edi,[edi + eax - 1]
  1947. else
  1948. lea edi,[edi + 2 * eax - 2]
  1949. endif
  1950. lea esi,[esi + 2 * eax - 2]
  1951. mov eax,ecx
  1952. shr eax,Z_SHIFT
  1953. jmp fill_spar_1
  1954. fill_spar_0:
  1955. sub esi,2
  1956. if RENDER_GOURAUD
  1957. add ecx,dz
  1958. add edx,sstep
  1959. else
  1960. add ecx,ebp
  1961. endif
  1962. fill_spar_0i:
  1963. if RENDER_Z
  1964. mov eax,ecx
  1965. shr eax,Z_SHIFT
  1966. endif
  1967. if DEPTH eq 8
  1968. dec edi
  1969. else
  1970. sub edi,2
  1971. endif
  1972. fill_spar_1:
  1973. if RENDER_Z
  1974. cmp ax,word ptr [esi]
  1975. ja fill_spar_2
  1976. mov word ptr [esi],ax
  1977. endif
  1978. if RENDER_GOURAUD
  1979. mov eax,edx
  1980. sar eax,10h ; U1
  1981. ; We're going to use eax in an EA calc soon, avoid AGI by
  1982. ; doing other work.
  1983. sub esi,2 ; V1
  1984. add ecx,dz ; U2
  1985. add edx,sstep ; V2
  1986. mov eax,[ebp + 4 * eax] ; U1
  1987. inc ebx ; V1
  1988. SEG_REND
  1989. if DEPTH eq 8
  1990. mov byte ptr [edi],al
  1991. else
  1992. mov word ptr [edi],ax
  1993. endif
  1994. jne fill_spar_0i
  1995. jmp fill_span_3
  1996. else
  1997. SEG_REND
  1998. if DEPTH eq 8
  1999. mov byte ptr [edi],dl
  2000. else
  2001. mov word ptr [edi],dx
  2002. endif
  2003. endif
  2004. fill_spar_2:
  2005. inc ebx
  2006. jne fill_spar_0
  2007. fill_span_3:
  2008. pop edx ;]
  2009. pop ecx ;]
  2010. pop esi ;]
  2011. pop edi ;]
  2012. fill_span_alldone:
  2013. endm
  2014. endif ;}
  2015. endif ;}
  2016. if WANT_SUB_FILLSPAN ;{
  2017. FILLSPAN macro parm
  2018. call sfillspan
  2019. endm
  2020. sfillspan:
  2021. SFILLSPAN
  2022. ret
  2023. else ;}{
  2024. FILLSPAN macro parm
  2025. if RENDER_TEXTURE
  2026. SFILLSPAN parm
  2027. else
  2028. SFILLSPAN parm
  2029. endif
  2030. endm
  2031. endif ;}
  2032. if GOURAUD_TABLE and (RENDER_TEXTURE gt 0) and RENDER_GOURAUD
  2033. GTsetup:
  2034. push eax ;[
  2035. push ebx ;[
  2036. push ecx ;[
  2037. push edx ;[
  2038. push edi ;[
  2039. push esi ;[
  2040. mov ebx,tex
  2041. ;kg this is now a straight offset from the texture
  2042. mov edx,[ebx + STEX_iPaletteSize]
  2043. ; mov ebx,[ebx + RLDDITexture_pixmaps]
  2044. ; mov edx,[ebx + RLDDIPixmap_palette_size]
  2045. mov eax,p1save
  2046. if 0
  2047. mov eax,[eax + RLDDIVertex_specular]
  2048. mov ebx,tex
  2049. mov ebx,[ebx + RLDDIRampTexture_tables]
  2050. mov eax,[ebx + 4 * eax]
  2051. mov ecx,[eax + RLDDIRampTextureTable_ramp_size]
  2052. else
  2053. mov eax,[eax + RLDDIVertex_specular]
  2054. ;kg this is now a straight offset from the texture
  2055. mov ecx,[ebx + STEX_iPaletteSize]
  2056. ; this only worked because RLDDITexture_pixmaps was 00h!
  2057. ; mov ebx,[ebx + RLDDITexture_pixmaps]
  2058. ; mov ecx,[ebx + RLDDIPixmap_palette_size]
  2059. endif
  2060. cmp ecx,32
  2061. jl enough
  2062. mov ecx,31
  2063. enough:
  2064. ; ecx is number of shades
  2065. ; edx is size of palette
  2066. mov edi,offset GTpixels
  2067. mov esi,[map]
  2068. ; Gtpixels[shade][i] = map[colors[i] + shade]
  2069. pershade:
  2070. mov ebx,0
  2071. percolor:
  2072. mov eax,[colors]
  2073. mov eax,[eax + 4 * ebx]
  2074. mov eax,[esi + 4 * eax]
  2075. if (DEPTH eq 8)
  2076. mov [edi + ebx],al
  2077. else
  2078. mov [edi + 2 * ebx],ax
  2079. endif
  2080. inc ebx
  2081. cmp ebx,edx
  2082. jne percolor
  2083. add edi,256 * (DEPTH / 8)
  2084. add esi,4
  2085. dec ecx
  2086. jne pershade
  2087. pop esi ;]
  2088. pop edi ;]
  2089. pop edx ;]
  2090. pop ecx ;]
  2091. pop ebx ;]
  2092. pop edx ;]
  2093. ret
  2094. endif
  2095. ; Sets up esi and edi for fill_span, above, takes y value.
  2096. ; Trashes eax.
  2097. ; dst = (PIXEL RLFAR*) pm->lines[y];
  2098. ; zdst = (ZPIXEL*) zb->lines[y];
  2099. SFILL_INIT macro y ;{
  2100. local pixloop, noneed
  2101. local sametex
  2102. if RENDER_TRANS
  2103. mov trans_y,y
  2104. endif
  2105. ifdef NT ;{
  2106. mov edi,y
  2107. imul edi,dwidth
  2108. add edi,pm_pixels
  2109. mov esi,y
  2110. imul esi,zwidth
  2111. add esi,zb_pixels
  2112. ;dfr: removed pm->lines
  2113. ; mov edi,pm_lines
  2114. ; mov esi,zb_lines
  2115. ; mov edi,[edi + 4 * y]
  2116. ; mov esi,[esi + 4 * y]
  2117. if RENDER_GOURAUD eq 0
  2118. ifndef D3D
  2119. mov ebx,triptr
  2120. mov ebx,[ebx + RLDDITriangle_color]
  2121. else
  2122. mov ebx,pp1
  2123. mov ebx,[ebx + D3DTLVERTEX_color]
  2124. endif
  2125. add ebx, 80h ; round up
  2126. mov eax,map
  2127. sar ebx,8
  2128. and ebx,0ffffh
  2129. endif
  2130. else ;}{
  2131. ;dfr: this section is obsolete
  2132. ; Entries are 6 bytes long
  2133. if RENDER_GOURAUD eq 0
  2134. mov ebx,triptr
  2135. endif
  2136. mov eax,y
  2137. add y,y
  2138. add y,eax
  2139. mov edi,pm_lines
  2140. mov esi,zb_lines
  2141. if RENDER_GOURAUD eq 0 ;{
  2142. mov ebx,[ebx + RLDDITriangle_color]
  2143. add ebx, 80h ; round up
  2144. mov eax,map
  2145. sar ebx,8
  2146. and ebx,0ffffh
  2147. endif ;}
  2148. if RENDER_OTHER_SEGMENT
  2149. mov es, [edi + 4]
  2150. endif
  2151. mov edi,[edi + 2 * y]
  2152. mov esi,[esi + 2 * y]
  2153. endif ;}
  2154. if RENDER_TEXTURE ;{
  2155. mov edx,ebx
  2156. ; colors = tex->tables[tri->specular]->pixels;
  2157. if RENDER_GOURAUD eq 0 ;{
  2158. ifndef D3D
  2159. mov eax,triptr
  2160. mov eax,[eax + RLDDITriangle_specular]
  2161. else
  2162. mov eax,pp1
  2163. mov eax,[eax + D3DTLVERTEX_specular]
  2164. endif
  2165. else ;}{
  2166. mov eax,p1save
  2167. mov eax,[eax + RLDDIVertex_specular]
  2168. endif ;}
  2169. if 0
  2170. mov ebx,tex
  2171. mov ebx,[ebx + RLDDIRampTexture_tables]
  2172. mov eax,[ebx + 4 * eax]
  2173. lea eax,[eax + RLDDIRampTextureTable_pixels]
  2174. endif
  2175. mov colors,eax
  2176. ; Only do the 'pixels' cache in flat texture
  2177. ; mode
  2178. if RENDER_GOURAUD eq 0 ;{
  2179. ; If same shade, don't recalc 'pixels'
  2180. cmp edx,pixels_shade
  2181. je noneed
  2182. mov pixels_shade,edx
  2183. ; pixels[i] = map[colors[i] + shade]
  2184. push ecx ;[
  2185. push ebp ;[
  2186. mov ebx,tex
  2187. ;kg this is now a straight offset from the texture
  2188. mov ebx,[ebx + STEX_iPaletteSize]
  2189. ; mov ebx,[ebx + RLDDITexture_pixmaps]
  2190. ; mov ebx,[ebx + RLDDIPixmap_palette_size]
  2191. dec ebx
  2192. mov ebp,map
  2193. lea ebp,[ebp + 4 * edx]
  2194. pixloop:
  2195. mov ecx,[eax + 4 * ebx]
  2196. mov ecx,[ebp + 4 * ecx]
  2197. mov [pixels + 4 * ebx],ecx
  2198. dec ebx
  2199. jns pixloop
  2200. pop ebp ;]
  2201. pop ecx ;]
  2202. else ;}{
  2203. if GOURAUD_TABLE ;{
  2204. mov ebx,[tex]
  2205. cmp ebx,[GTpixelsTexture]
  2206. je sametex
  2207. mov [GTpixelsTexture],ebx
  2208. call GTsetup
  2209. endif ;}
  2210. sametex:
  2211. endif ;}
  2212. noneed:
  2213. else ;}{
  2214. if RENDER_GOURAUD eq 0
  2215. mov edx,[eax + 4 * ebx]
  2216. ; And extend to fill all 32 bits
  2217. if (DEPTH eq 8)
  2218. mov dh,dl
  2219. endif
  2220. mov eax,edx
  2221. shl eax,16
  2222. or edx,eax
  2223. endif
  2224. endif ;}
  2225. endm ;}
  2226. if WANT_SUB_FILL_INIT
  2227. mfill_init:
  2228. SFILL_INIT edx
  2229. ret
  2230. FILL_INIT macro y
  2231. call mfill_init
  2232. endm
  2233. else
  2234. FILL_INIT macro y
  2235. SFILL_INIT y
  2236. endm
  2237. endif
  2238. ; TRAPEZOID
  2239. ; NAME MODE REG TRASHED DESCRIPTION
  2240. ; ---- ---- --- ------- -----------
  2241. ; pixel F edx N pixel value to write
  2242. ; sl G edx N starting shade value
  2243. ; uvl FT,GT edx N starting (u,v) value
  2244. ; xl * eax N
  2245. ; xr * ebx N
  2246. ; zl * ecx N
  2247. ; ms G - N change sl per line
  2248. ; muv FT,GT - N change uvl per line
  2249. ; dxl * - N change xl per line
  2250. ; dxr * - N change xr per line
  2251. ; dzl * - N change zl per line
  2252. ; dz F ebp N change z per pixel
  2253. ; map G ebp N ptr to color index map
  2254. ; texture FT ebp N texture, innit mate
  2255. ; sl GT ebp N starting shade value
  2256. ; h * - Y height
  2257. ; dst * edi Y destination pixel line
  2258. ; zdst * esi Y destination z-pixel line
  2259. XPREC equ 16
  2260. DO_SUBPIX_CORRECTION macro
  2261. push eax
  2262. and eax,(1 shl XPREC) - 1
  2263. mov [subpix],eax
  2264. pop eax
  2265. fild [subpix] ; sp
  2266. fmul [recip65536] ; sp'
  2267. fld [wstep] ; mw sp'
  2268. fmul st,st(1) ; mw' sp'
  2269. fld [ustep] ; mu mw' sp'
  2270. fmul st,st(2) ; mu' mw' sp'
  2271. fld [vstep] ; mv mu' mw' sp'
  2272. fmul st,st(3) ; mv' mu' mw' sp'
  2273. fxch st(2) ; mw' mu' mv' sp'
  2274. fadd [wl] ; wl' mu' mv' sp'
  2275. fxch st(1) ; mu' wl' mv' sp'
  2276. fadd [ul] ; ul' wl' mv' sp'
  2277. fxch st(2) ; mv' wl' ul' sp'
  2278. fadd [vl] ; vl' wl' ul' sp'
  2279. fxch st(3) ; sp' wl' ul' vl'
  2280. fstp st(0) ; wl' ul' vl'
  2281. endm
  2282. NEXT_LINE macro PERSP
  2283. add edi,dwidth
  2284. add esi,zwidth
  2285. add eax,ml
  2286. add ebx,mr
  2287. add ecx,dzl
  2288. if RENDER_TEXTURE
  2289. if PERSP eq 0
  2290. mov edx,uvl
  2291. add edx,muv
  2292. mov uvl,edx
  2293. else
  2294. fld ul
  2295. fadd mu
  2296. fstp ul
  2297. fld vl
  2298. fadd mv
  2299. fstp vl
  2300. fld wl
  2301. fadd mw
  2302. fstp wl
  2303. endif
  2304. if RENDER_GOURAUD
  2305. mov ebp,sm
  2306. add ebp,ms
  2307. mov sm,ebp
  2308. endif
  2309. else
  2310. if RENDER_GOURAUD
  2311. add edx,ms
  2312. endif
  2313. endif
  2314. if RENDER_TRANS
  2315. TRANS_NEXT_LINE
  2316. endif
  2317. endm
  2318. TRAPEZOID macro mlabel, fillfunc, fillparm, PERSP
  2319. local trap_0
  2320. jmp mlabel
  2321. trap_0:
  2322. NEXT_LINE PERSP
  2323. mlabel:
  2324. if PERSP and SUBPIX_CORRECT
  2325. DO_SUBPIX_CORRECTION
  2326. endif
  2327. push eax ;[
  2328. push ebx ;[
  2329. fillfunc %fillparm
  2330. pop ebx ;]
  2331. pop eax ;]
  2332. dec h
  2333. jnz trap_0
  2334. endm
  2335. DO_TRAPEZOID macro PERSP
  2336. if RENDER_TEXTURE
  2337. if PERSP
  2338. call [pc_trapezoid_vector]
  2339. else
  2340. call [trapezoid_vector]
  2341. endif
  2342. else
  2343. call dotrapezoid
  2344. endif
  2345. endm
  2346. ; NAME REG TRASHED DESCRIPTION
  2347. ; ---- --- ------- -----------
  2348. ; pixel edx NO Pixel value
  2349. ; xl eax YES start left X-coordinate
  2350. ; xr ebx YES start right X-coordinate
  2351. ; dxl change xl per line
  2352. ; dxr change xr per line
  2353. ; zl start left Z-value
  2354. ; dzl change zl per line
  2355. ; dz change zl per pixel
  2356. ; h height
  2357. ; dst edi destination pixel line
  2358. ; zdst esi destination z-pixel line
  2359. FILL1 macro xl,ml,xr,mr,zl,mz,dz ,shade, PERSP
  2360. if RENDER_GOURAUD
  2361. ; Don't know how to make masm do this.
  2362. ; ifdif shade,sl
  2363. ; mov eax,shade
  2364. ; mov sl,eax
  2365. ; endif
  2366. endif
  2367. mov eax,mz
  2368. mov dzl,eax
  2369. mov eax,xl
  2370. mov ebx,xr
  2371. mov ecx,zl
  2372. if RENDER_TEXTURE
  2373. mov edx,uvl
  2374. if RENDER_GOURAUD
  2375. mov ebp,sm
  2376. else
  2377. if PERSP eq 0
  2378. mov ebp,texture
  2379. endif
  2380. endif
  2381. else
  2382. if RENDER_GOURAUD
  2383. mov edx,sm
  2384. mov ebp,map
  2385. else
  2386. mov edx,pixel
  2387. mov ebp,dz
  2388. endif
  2389. endif
  2390. DO_TRAPEZOID PERSP
  2391. endm
  2392. ; ms2 is slope of shading for second triangle
  2393. FILL2 macro category, xl1, dxl1, xl2, dxl2, xr1, dxr1, xr2, dxr2, zl, dzl1, dzl2, dz, h1, h2, ms2, PERSP
  2394. local trash, secondhalf
  2395. ; mov eax,mr
  2396. ; mov dxr,eax
  2397. ; mov eax,ml
  2398. ; mov dxl,eax
  2399. mov eax,mz
  2400. mov dzl,eax
  2401. mov eax,h1
  2402. mov h,eax
  2403. if RENDER_TEXTURE
  2404. mov pixel,edx
  2405. mov edx,uvl
  2406. if RENDER_GOURAUD
  2407. mov ebp,sm
  2408. else
  2409. if PERSP eq 0
  2410. mov ebp,texture
  2411. endif
  2412. endif
  2413. else
  2414. if RENDER_GOURAUD
  2415. mov edx,sm
  2416. mov ebp,map
  2417. else
  2418. mov ebp,dz
  2419. endif
  2420. endif
  2421. mov eax,xm
  2422. mov ebx,eax
  2423. mov ecx,zl
  2424. NEXT_LINE PERSP ; First line is always blank
  2425. dec h
  2426. je secondhalf
  2427. DO_TRAPEZOID PERSP
  2428. NEXT_LINE PERSP
  2429. secondhalf:
  2430. ; We've got to do some setup for the second half of the triangle,
  2431. ; use whichever register we're going to reload anyway (eax or ebx)
  2432. ; as scratch. All the others are in use.
  2433. if category eq 1
  2434. trash equ ebx
  2435. else
  2436. trash equ eax
  2437. endif
  2438. if RENDER_TEXTURE
  2439. if PERSP
  2440. mov trash,mu2
  2441. mov mu,trash
  2442. mov trash,mv2
  2443. mov mv,trash
  2444. mov trash,mw2
  2445. mov mw,trash
  2446. else
  2447. mov trash,muv2
  2448. mov muv,trash
  2449. endif
  2450. endif
  2451. if category eq 0
  2452. if RENDER_GOURAUD
  2453. mov trash,ms2
  2454. mov ms,trash
  2455. endif
  2456. mov trash,ml2
  2457. mov ml,trash
  2458. mov trash,dzl2
  2459. mov dzl,trash
  2460. else
  2461. mov trash,mr2
  2462. mov mr,trash
  2463. endif
  2464. mov trash,h2
  2465. mov h,trash
  2466. ; Now we reset the appropriate vertex: we have to do this or
  2467. ; the inaccuracy causes cracking in the lower triangle.
  2468. if category eq 1
  2469. mov ebx,xr2
  2470. else
  2471. mov eax,xl2
  2472. endif
  2473. DO_TRAPEZOID PERSP
  2474. endm
  2475. if GOURAUD_TABLE
  2476. zion:
  2477. push eax ;[
  2478. push edx ;[
  2479. mov edx,[sstep]
  2480. shr edx,8
  2481. and edx,0ffffh
  2482. mov eax,edx
  2483. shl eax,1
  2484. and eax,10000h
  2485. xor eax,0ffff0000h
  2486. or edx,eax
  2487. mov [sstep],edx
  2488. pop edx ;]
  2489. pop eax ;]
  2490. ret
  2491. endif
  2492. FlatTriangle2 macro vleft, vright, vcommon, height, ystart, label, PERSP
  2493. local L307
  2494. fld1
  2495. fdivrp st(1),st
  2496. ; 1/dx xr xl
  2497. if RENDER_GOURAUD
  2498. ; sl = GTRI_GET_SHADE(p1);
  2499. ; sr = GTRI_GET_SHADE(p2);
  2500. ; sm = GTRI_GET_SHADE(p2);
  2501. GTRI_GET_SHADE edi,vleft
  2502. GTRI_GET_SHADE edi,vright
  2503. GTRI_GET_SHADE edi,vcommon
  2504. fstp sm
  2505. fstp sr
  2506. fstp sl
  2507. endif
  2508. if RENDER_TEXTURE
  2509. TEX_PRELOAD vleft,vright,vcommon,PERSP
  2510. endif
  2511. ; zl = p1->sz;
  2512. ; zr = p2->sz;
  2513. ; zstep = RLDDICheckDiv16(zr - zl, dx);
  2514. if label eq 2
  2515. if FIXED_POINT
  2516. mov edi,[vcommon + RLDDIVertex_sz]
  2517. shl edi,8h
  2518. mov zm,edi
  2519. else
  2520. FXTOVAL8 [vcommon + RLDDIVertex_sz]
  2521. VALTOFX_Z zm,0
  2522. FDROP
  2523. endif
  2524. endif
  2525. mov save1,ystart ; put y1 in save1, coz division trashes edx
  2526. FXTOVAL8 [vleft + RLDDIVertex_sz]
  2527. FDUP
  2528. TRICK 24
  2529. fstp qword ptr [zl]
  2530. FXTOVAL8 [vright + RLDDIVertex_sz]
  2531. fsubr
  2532. fmul st(0),st(1)
  2533. ; stack: zstep 1/x xr xl
  2534. if RENDER_GOURAUD
  2535. ; sstep = RLDDICheckDiv16(sr - sl, dx);
  2536. fld sr
  2537. fld sl
  2538. fsubp st(1),st
  2539. fmul st,st(2)
  2540. VALTOFXp sstep
  2541. if GOURAUD_TABLE
  2542. call zion
  2543. endif
  2544. endif
  2545. if RENDER_TEXTURE
  2546. push ecx ;[ XXX this stinks
  2547. push eax ;[
  2548. if (label eq 1)
  2549. TEX_FLAT_TOP ebp, PERSP
  2550. else
  2551. if (label eq 2)
  2552. TEX_FLAT_BOTTOM ebp, PERSP
  2553. else
  2554. TEX_FLAT_TOP ebp, PERSP
  2555. endif
  2556. endif
  2557. pop eax ;]
  2558. pop ecx ;]
  2559. endif
  2560. mov edx,save1
  2561. push eax ;[
  2562. push ebx ;[
  2563. FILL_INIT edx ; y1 (edx) => esi and edi
  2564. pop ebx ;]
  2565. pop eax ;]
  2566. ; Don't do this optimisation when rendering textures
  2567. if (RENDER_TEXTURE eq 0) and (label ne 2)
  2568. cmp ebp,1
  2569. jne L307
  2570. ; stack: zstep 1/x xr xl
  2571. TRICK 24 ; i(dz) 1/x xr xl
  2572. fxch st(2) ; xr 1/x i(dz) xl
  2573. TRICK 16 ; i(xr) 1/x i(dz) xl
  2574. fxch st(3) ; xl 1/x i(dz) i(xr)
  2575. TRICK 16 ; i(xl) 1/x i(dz) i(xr)
  2576. fstp qword ptr [xl]
  2577. FDROP
  2578. fstp qword ptr [dz]
  2579. mov eax,xl
  2580. fstp qword ptr [xr]
  2581. mov ecx,zl
  2582. mov ebp,dz
  2583. mov ebx,xr
  2584. if RENDER_TEXTURE
  2585. mov edx,uvl
  2586. if RENDER_GOURAUD
  2587. mov ebp,sl
  2588. else
  2589. mov ebp,texture
  2590. endif
  2591. else
  2592. if RENDER_GOURAUD
  2593. fld sl
  2594. TRICK16
  2595. mov ebp,map
  2596. fstp qword ptr [sm]
  2597. mov edx,sm
  2598. endif
  2599. endif
  2600. FILLSPAN 0
  2601. jmp continue4
  2602. endif
  2603. L307:
  2604. ; xm = p3->sx;
  2605. ; ml = (xm - xl) / h2;
  2606. ; mr = (xm - xr) / h2;
  2607. ; mz = (p3->sz - zl) / h2;
  2608. mov pixel,edx
  2609. mov h,ebp
  2610. ;{ This section to negate calcs on case #2
  2611. FXTOVAL [vcommon + RLDDIVertex_sx]
  2612. if label eq 2
  2613. if FIXED_POINT
  2614. mov ebx,[vcommon + RLDDIVertex_sx]
  2615. mov xm,ebx
  2616. else
  2617. qVALTOFX xm,0
  2618. endif
  2619. endif
  2620. ; stack: xm zstep x xr xl
  2621. mrsub macro p0,p1,thcond
  2622. if thcond
  2623. fsubr p0,p1
  2624. else
  2625. fsub p0,p1
  2626. endif
  2627. endm
  2628. FDUP
  2629. mrsub st,st(5),label eq 2
  2630. DIVIDE_BY ebp
  2631. VALTOFXp ml
  2632. ; stack: xm zstep x xr xl
  2633. mrsub st,st(3),label eq 2
  2634. DIVIDE_BY ebp
  2635. VALTOFXp mr
  2636. ; mrsub [ecx + RLDDIVertex_sz],zl,label eq 2
  2637. FXTOVAL8 [vcommon + RLDDIVertex_sz]
  2638. FXTOVAL8 [vleft + RLDDIVertex_sz]
  2639. ; zl zm
  2640. if label eq 2
  2641. fsubr
  2642. else
  2643. fsub
  2644. endif
  2645. DIVIDE_BY ebp
  2646. VALTOFX_Z mz,0
  2647. FDROP
  2648. VALTOFX_Z dz,0
  2649. qVALTOFX xr,2
  2650. qVALTOFX xl,3
  2651. if RENDER_GOURAUD
  2652. fld sm
  2653. if label eq 2
  2654. VALTOFX sm,0
  2655. endif
  2656. fld sl
  2657. if label ne 2
  2658. VALTOFX sm,0
  2659. endif
  2660. if label eq 2
  2661. fsubr
  2662. else
  2663. fsub
  2664. endif
  2665. DIVIDE_BY ebp
  2666. VALTOFXp ms
  2667. endif
  2668. ;}
  2669. FDROP
  2670. FDROP
  2671. FDROP
  2672. FDROP
  2673. if ((label eq 1) or (label eq 3))
  2674. FILL1 xl,ml,xr,mr,zl,mz,dz, sl, PERSP
  2675. else
  2676. if (label eq 2)
  2677. FILL1 xm,ml,xm,mr,zm,mz,dz, sm, PERSP
  2678. endif
  2679. endif
  2680. endm
  2681. FlatTriangle macro vleft, vright, vcommon, height, ystart, label
  2682. local longer, big
  2683. if (RENDER_GOURAUD ne 0) and (RENDER_TEXTURE ne 0)
  2684. mov p1save,vleft
  2685. endif
  2686. if label eq 2
  2687. cmp ebp,1
  2688. je continue
  2689. endif
  2690. ; esi,edi are now scratch
  2691. ; xl = p1->sx;
  2692. ; xr = p2->sx;
  2693. ; dx = xr - xl;
  2694. ; if (dx <= 0)
  2695. ; continue;
  2696. FXTOVAL [vleft + RLDDIVertex_sx]
  2697. FXTOVAL dword ptr [vright + RLDDIVertex_sx]
  2698. ; stack: xr xl
  2699. fcom st(1)
  2700. push eax ;[
  2701. fnstsw ax
  2702. sahf
  2703. pop eax ;]
  2704. jbe continue2
  2705. FDUP
  2706. fsub st,st(2)
  2707. if PERSPECTIVE
  2708. cmp ebp,0ch
  2709. jae big
  2710. FlatTriangle2 vleft, vright, vcommon, height, ystart, label,0
  2711. jmp continue
  2712. big: FlatTriangle2 vleft, vright, vcommon, height, ystart, label,1
  2713. else
  2714. FlatTriangle2 vleft, vright, vcommon, height, ystart, label,0
  2715. endif
  2716. endm
  2717. ; Set up interpolants for a right triangle
  2718. ;{
  2719. ; RLDDIValue __l = (l);
  2720. ; RLDDIValue __r = (r);
  2721. ; RLDDIValue __m = (m);
  2722. ; RLDDIValue __d1 = ISUB(__l, __m);
  2723. ; RLDDIValue __d2 = ISUB(__r, __m);
  2724. ;
  2725. ; (name).istep = RLDDIFMul16(__d2, hrs) - RLDDIFMul16(__d1, hls),
  2726. ; (name).mi = (name).mi2 = __d1 / h;
  2727. ; (name).il = __m;
  2728. ;}
  2729. ; This has been graph-flattened, as Intel suggests, hence the strange order
  2730. ; Stack 3 values: l m r
  2731. IP_ANY macro go,dx,dy,precision,h,hls,hrs
  2732. fld st(1) ; m l m r
  2733. TRICK precision ; i(m) l m r
  2734. fxch st(3) ; r l m i(m)
  2735. fsub st,st(2) ; r-m l m i(m)
  2736. fxch st(2) ; m l r-m i(m)
  2737. fsubp st(1),st ; l-m r-m i(m)
  2738. ; d1 d2 i(m)
  2739. fxch st(2) ; i(m) d2 d1
  2740. fstp qword ptr [go] ; d2 d1
  2741. fld st(1) ; d1 d2 d1
  2742. fmul hls ; hrs*d1 d2 d1
  2743. fxch st(1)
  2744. fmul hrs ; hls*d2 hrs*d1 d1
  2745. fxch st(2) ; d1 hrs*d1 hls*d2
  2746. DIVIDE_BY h ; d1/h hrs*d1 hls*d2
  2747. fxch st(2) ; hls*d2 hrs*d1 d1/h
  2748. ;; blocks here
  2749. fsubr ; dx d1/h
  2750. fxch st(1) ; d1/h dx
  2751. TRICK precision ; i(d1/h) dx
  2752. fxch st(1) ; dx i(d1/h)
  2753. TRICK precision ; i(dx) i(d1/h)
  2754. fxch st(1) ; i(dy) i(dx)
  2755. ;; blocks here
  2756. fstp qword ptr [dy]
  2757. fstp qword ptr [dx]
  2758. endm
  2759. AnyTriangle2 macro category, PERSP
  2760. ; h1s = RLDDIFDiv8(ITOVAL(h1), denom);
  2761. ; h3s = RLDDIFDiv8(ITOVAL(h3), denom);
  2762. fld1
  2763. fdivr
  2764. ; stack:
  2765. fild h1 ; h1 denom xl xr xm
  2766. fmul st,st(1) ; h1*denom denom xl xr xm
  2767. fxch st(1) ; denom h1*denom xl xr xm
  2768. fild h3
  2769. fmul
  2770. fxch st(1) ; h1*denom h3*denom xl xr xm
  2771. fstp h1s
  2772. fstp h3s
  2773. ; stack: xl xr xm
  2774. ; zl = p3->sz;
  2775. ; zr = p2->sz;
  2776. ; zm = p1->sz;
  2777. mov eax,save1
  2778. if BIDIRECTIONAL
  2779. fld dword ptr [ebx + RLDDIVertex_sx]
  2780. fsub dword ptr [eax + RLDDIVertex_sx] ; r-m
  2781. mov ebp,[h1]
  2782. fld dword ptr [ecx + RLDDIVertex_sx]
  2783. fsub dword ptr [eax + RLDDIVertex_sx] ; l-m r-m
  2784. fxch st(1) ; r-m l-m
  2785. mov edx,[h3]
  2786. DIVIDE_BY ebp ; (r-m)/h2 l-m
  2787. fxch st(1)
  2788. DIVIDE_BY edx ; (l-m)/h3 (r-m)/h1
  2789. fxch st(1) ; (r-m)/h1 (l-m)/h3
  2790. TRICK16
  2791. fxch st(1)
  2792. TRICK16
  2793. fxch st(1)
  2794. fstp qword ptr [mr]
  2795. cmp [mr], 0
  2796. jge mr_not_neg
  2797. inc [mr] ;correct rounding error
  2798. mr_not_neg:
  2799. fstp qword ptr [ml]
  2800. cmp [ml], 0
  2801. jge ml_not_neg
  2802. inc [ml] ;correct rounding error
  2803. ml_not_neg:
  2804. fld dword ptr [eax + RLDDIVertex_sx]
  2805. TRICK16
  2806. mov edx,[h2]
  2807. fstp qword ptr [xm]
  2808. ;; mr2 = (xl - xr) / h2
  2809. fsubr ; xl-xr xm
  2810. fxch st(1)
  2811. FDROP
  2812. DIVIDE_BY edx ; h2
  2813. TRICK16
  2814. fstp qword ptr [mr2]
  2815. cmp [mr2], 0
  2816. jge mr2_not_neg
  2817. inc [mr2] ;correct rounding error
  2818. mr2_not_neg:
  2819. endif
  2820. if BIDIRECTIONAL and RENDER_Z
  2821. mov edx,[h3]
  2822. fld dword ptr [ebx + RLDDIVertex_sz]
  2823. fld dword ptr [eax + RLDDIVertex_sz]
  2824. fld dword ptr [ecx + RLDDIVertex_sz]
  2825. ; l m r
  2826. IP_ANY zm,dz,mz,24,edx,h1s,h3s
  2827. endif
  2828. if RENDER_GOURAUD
  2829. ; sl = GTRI_GET_SHADE(p3);
  2830. ; sr = GTRI_GET_SHADE(p2);
  2831. ; sm = GTRI_GET_SHADE(p1);
  2832. GTRI_GET_SHADE edx,ebx
  2833. GTRI_GET_SHADE edx,eax
  2834. GTRI_GET_SHADE edx,ecx ; l m r
  2835. if BIDIRECTIONAL
  2836. mov edx,[h3]
  2837. IP_ANY sm,sstep,ms,16,edx,h1s,h3s
  2838. else
  2839. fstp sl
  2840. fstp sm
  2841. fstp sr
  2842. endif
  2843. endif
  2844. if RENDER_TEXTURE
  2845. TEX_PRELOAD ecx,ebx,eax,PERSP
  2846. endif
  2847. if RENDER_TEXTURE
  2848. if category
  2849. TEX_RIGHT_TRI h3s, h1s, h3, PERSP
  2850. else
  2851. TEX_LEFT_TRI h3s, h1s, h3, h2, PERSP
  2852. endif
  2853. mov eax,save1
  2854. endif
  2855. if (BIDIRECTIONAL eq 0) ;[
  2856. FXTOVAL8 [eax + RLDDIVertex_sz] ; zm
  2857. FXTOVAL8 [ecx + RLDDIVertex_sz] ; zl
  2858. FXTOVAL8 [ebx + RLDDIVertex_sz] ; zr
  2859. if FLOATING_POINT
  2860. VALTOFX_Z zl,1
  2861. VALTOFX_Z zm,2
  2862. endif
  2863. ; stack: zr zl zm xl xr xm
  2864. ; zstep = RLDDIFMul16(zr - zm, h3s) - RLDDIFMul16(zl - zm, h1s);
  2865. fsub st,st(2) ; zr-zm zl zm
  2866. fxch st(1) ; zl zr-zm zm
  2867. fsub st,st(2) ; zl-zm zr-zm zm
  2868. fst st(2) ; zl-zm zr-zm zl-zm
  2869. fmul h1s
  2870. fxch st(1)
  2871. fmul h3s ; h3s*(zr-zm) h1s*(zl-zm) zl-zm
  2872. fsubr
  2873. VALTOFX_Z dz,0
  2874. FDROP
  2875. ; stack: zl-zm xl xr xm
  2876. if RENDER_GOURAUD
  2877. ; sstep = RLDDIFMul16(sr - sm, h3s) - RLDDIFMul16(sl - sm, h1s);
  2878. fld sr
  2879. fsub sm
  2880. fld sl
  2881. fsub sm ; sl-sm sr-sm
  2882. fxch st(1) ; sr-sm sl-sm
  2883. fmul h3s ; h3*(sr-sm) sl-sm
  2884. fxch st(1) ; sl-sm h3*(sr-sm)
  2885. fmul h1s ; h1*(sl-sm) h3*(sr-sm)
  2886. fsubp st(1),st
  2887. VALTOFXp sstep
  2888. if GOURAUD_TABLE
  2889. call zion
  2890. endif
  2891. endif
  2892. ; stack: zl-zm xl xr xm
  2893. ; ml = (xl - xm) / h3;
  2894. ; mz = (zl - zm) / h3;
  2895. ; mr = (xr - xm) / h1;
  2896. mov ebp,h3
  2897. fld st(1)
  2898. fsub st,st(4)
  2899. DIVIDE_BY ebp ; h3
  2900. VALTOFXp ml
  2901. ; stack: zl-zm xl xr xm
  2902. DIVIDE_BY ebp ; h3
  2903. VALTOFX_Z mz,0
  2904. FDROP
  2905. if RENDER_GOURAUD and (BIDIRECTIONAL eq 0)
  2906. fld sl
  2907. fsub sm
  2908. DIVIDE_BY ebp ; h3
  2909. VALTOFXp ms
  2910. if (category eq 0) and (PERSP eq 0)
  2911. malaga:
  2912. endif
  2913. fld sm
  2914. TRICK16
  2915. fstp qword ptr [sm]
  2916. endif
  2917. ; stack: xl xr xm
  2918. mov ebp,h1
  2919. fld st(1)
  2920. fsub st,st(3)
  2921. DIVIDE_BY ebp ; h1
  2922. VALTOFXp mr
  2923. ; stack: xl xr xm
  2924. mov ebp,h2
  2925. if category ;[
  2926. ; mr2 = (xl - xr) / h2;
  2927. fsubr
  2928. DIVIDE_BY ebp ; h2
  2929. VALTOFXp mr2
  2930. else ;][
  2931. ; h2 = -h2;
  2932. ; ml2 = (xr - xl) / h2;
  2933. ; mz2 = (zr - zl) / h2;
  2934. xor ebp,ebp
  2935. sub ebp,h2
  2936. mov h2,ebp
  2937. fsub
  2938. DIVIDE_BY ebp ; h2
  2939. VALTOFXp ml2
  2940. FXTOVAL8 [ecx + RLDDIVertex_sz] ; zl
  2941. FXTOVAL8 [ebx + RLDDIVertex_sz] ; zr zl
  2942. fsubr ;
  2943. DIVIDE_BY ebp ; h2
  2944. VALTOFX_Z mz2,0
  2945. FDROP
  2946. if RENDER_GOURAUD
  2947. ; ms2 = RLDDIFMul16(sr - sl, inv_h2);
  2948. fld sr
  2949. fsub sl
  2950. DIVIDE_BY ebp ; h2
  2951. VALTOFXp ms2
  2952. endif
  2953. endif ;]
  2954. FDROP
  2955. endif ;]
  2956. mov edx,y1save
  2957. FILL_INIT edx
  2958. ; mov eax,0
  2959. ; mov mz,eax
  2960. ; mov mz2,eax
  2961. if category eq 1
  2962. FILL2 category, xm,ml,xl2,ml,xm,mr,xr,mr2,zm,mz,mz,dz,h1,h2,ms, PERSP
  2963. else
  2964. FILL2 category, xm,ml,xl,ml2,xm,mr,xr2,mr,zm,mz,mz2,dz,h3,h2,ms2, PERSP
  2965. endif
  2966. endm
  2967. ; l m r
  2968. ; p3 p1 p2
  2969. ;V ecx eax ebx
  2970. ;Y ebp edx edi
  2971. AnyTriangle macro category
  2972. local nocull
  2973. local big, alldone, posh2
  2974. if (RENDER_GOURAUD ne 0) and (RENDER_TEXTURE ne 0)
  2975. mov p1save,eax
  2976. endif
  2977. mov y1save,edx
  2978. ; xl = p3->sx;
  2979. ; xr = p2->sx;
  2980. ; xm = p1->sx;
  2981. FXTOVAL [eax + RLDDIVertex_sx] ; xm
  2982. FXTOVAL [ebx + RLDDIVertex_sx] ; xr xm
  2983. FXTOVAL [ecx + RLDDIVertex_sx] ; xl xr xm
  2984. ; stack: xl xr xm
  2985. ; dx2 = xl - xm;
  2986. FDUP
  2987. fsub st,st(3)
  2988. ; dx1 = xr - xm;
  2989. fld st(2)
  2990. fsub st,st(4)
  2991. ; stack: dx1 dx2 xl xr xm
  2992. ; if (dx1 < 0 && dx2 > 0) continue;
  2993. ; h1 = y2 - y1;
  2994. ; h2 = y3 - y2;
  2995. ; h3 = y3 - y1;
  2996. ; denom = RLDDIFMul24(dx1, ITOVAL(h3)) - RLDDIFMul24(dx2, ITOVAL(h1));
  2997. sub ebp,edx ; h3 = ebp - edx
  2998. sub edi,edx ; h1 = edi - edx
  2999. mov h3,ebp
  3000. mov h1,edi
  3001. fild h3
  3002. fmul
  3003. fxch st(1)
  3004. fild h1
  3005. fmul
  3006. mov save1,eax
  3007. sub ebp,edi ; h2 = ebp - edi (-edx+edx cancel!)
  3008. if BIDIRECTIONAL and (category eq 0)
  3009. fsubr ; Would have negative area otherwise
  3010. else
  3011. fsub
  3012. endif
  3013. if BIDIRECTIONAL
  3014. jge posh2
  3015. neg ebp
  3016. posh2:
  3017. endif
  3018. mov h2,ebp
  3019. ; stack: denom xl xr xm
  3020. ; if (denom <= 0)
  3021. ; continue;
  3022. ftst
  3023. fnstsw ax
  3024. test eax,0100h
  3025. jnz continue4
  3026. fld st(3) ; i(xm) denom xl xr xm
  3027. TRICK16
  3028. fld st(3) ; i(xr) i(xm) denom xl xr xm
  3029. TRICK16
  3030. fld st(3) ; i(xl) i(xr) i(xm) denom xl xr xm
  3031. TRICK16
  3032. fxch st(2) ; i(xm) i(xr) i(xl) denom xl xr xm
  3033. fstp qword ptr xm
  3034. fstp qword ptr xr
  3035. fstp qword ptr xl
  3036. if PERSPECTIVE
  3037. FCOMI _RLDDIFloatConstAffineThreshold
  3038. test eax,0100h
  3039. jz big
  3040. ;{
  3041. if (category eq 1)
  3042. mov eax,dword ptr [h3]
  3043. else
  3044. mov eax,dword ptr [h1]
  3045. endif
  3046. cmp eax,24 ; > 24 pixels high, go to PC
  3047. jg big
  3048. ;}
  3049. AnyTriangle2 category, 0
  3050. jmp alldone
  3051. big: AnyTriangle2 category, 1
  3052. alldone:
  3053. else
  3054. if BIDIRECTIONAL
  3055. if category eq 1
  3056. anytri2_1: AnyTriangle2 1, PERSPECTIVE
  3057. else
  3058. jmp anytri2_1
  3059. endif
  3060. else
  3061. AnyTriangle2 category, PERSPECTIVE
  3062. endif
  3063. endif
  3064. endm
  3065. ;void RNAME(Triangle)(RLDDIDriver* adriver,
  3066. ; RLDDIPixmap* pm,
  3067. ; RLDDIPixmap* zb,
  3068. ; size_t count,
  3069. ; size_t size,
  3070. ; RLDDITriangle* tri)
  3071. if RENDER_GOURAUD
  3072. nameFG equ G
  3073. else
  3074. nameFG equ F
  3075. endif
  3076. if RENDER_TEXTURE eq 1
  3077. nameT equ T
  3078. else
  3079. if RENDER_TEXTURE eq 2
  3080. nameT equ P
  3081. else
  3082. nameT equ <>
  3083. endif
  3084. endif
  3085. if RENDER_TRANS eq 1
  3086. nameG equ G
  3087. else
  3088. nameG equ <>
  3089. endif
  3090. if RENDER_Z eq 1
  3091. nameZ equ Z
  3092. else
  3093. nameZ equ <>
  3094. endif
  3095. ifdef MICROSOFT_NT
  3096. beginproc _RLDDIR,%nameFG,%nameZ,%nameT,%nameG,Triangle
  3097. else
  3098. beginproc RLDDIR,%nameFG,%nameZ,%nameT,%nameG,Triangle
  3099. endif
  3100. beginargs
  3101. saveregs <ebx,ebp,esi,edi,es>
  3102. ifndef D3D
  3103. regargs <adriver,pm,zb,count>
  3104. defargs <tsize,tri>
  3105. endargs
  3106. ifdef STACK_CALL
  3107. mov eax,[esp + adriver]
  3108. mov edx,[esp + pm]
  3109. mov ebx,[esp + zb]
  3110. mov ecx,[esp + count]
  3111. else
  3112. mov [esp + adriver],eax
  3113. mov [esp + pm],edx
  3114. mov [esp + zb],ebx
  3115. mov [esp + count],ecx
  3116. endif
  3117. else
  3118. defvars <count, fill_flags>
  3119. regargs <adriver,insn,vbase,tri>
  3120. endargs
  3121. ifndef STACK_CALL
  3122. mov [esp + adriver],eax
  3123. mov [esp + insn],edx
  3124. mov [esp + vbase],ebx
  3125. mov [esp + tri],ecx
  3126. endif
  3127. endif
  3128. ; For D3D we need to extract some things first
  3129. ifdef D3D
  3130. mov ecx,[esp + insn]
  3131. mov cx,[ecx + D3DINSTRUCTION_wCount]
  3132. and ecx,0ffffh
  3133. mov [esp + count],ecx
  3134. mov eax,[esp + adriver]
  3135. mov edx,[eax + RLDDIGenRasDriver_pm]
  3136. mov ebx,[eax + RLDDIGenRasDriver_zb]
  3137. endif
  3138. ; RLDDIRampDriver* driver = (RLDDIRampDriver*) adriver;
  3139. ; (Don't do anything for this, just use adriver instead)
  3140. test ecx,ecx
  3141. je triloop3
  3142. ; Set up map, pm_lines and zb_lines
  3143. mov trapezoid_vector,offset dotrapezoid
  3144. ; Set up culling flags
  3145. mov ebp,[eax + RLDDIGenRasDriver_fill_params]
  3146. mov esi,[ebp + RLDDIGenRasFillParams_culling_ccw]
  3147. mov cull_ccw, esi
  3148. mov esi,[ebp + RLDDIGenRasFillParams_culling_cw]
  3149. mov cull_cw, esi
  3150. if RENDER_TEXTURE
  3151. ; texture = driver->texture->image->buffer1;
  3152. ; wrap_u = driver->fill_params->wrap_u ? 8 : 0;
  3153. ; wrap_v = driver->fill_params->wrap_v ? 8 : 0;
  3154. ; u_shift = driver->texture->u_shift;
  3155. ; v_shift = driver->texture->v_shift;
  3156. ; v_mult = driver->texture->v_mult;
  3157. mov ebp,[eax + RLDDIGenRasDriver_texture]
  3158. mov tex,ebp
  3159. if RENDER_TRANS ;{
  3160. mov esi,[ebp + RLDDITexture_transparent]
  3161. mov transparent,esi
  3162. endif ;}
  3163. mov ebp,[ebp + STEX_pBits]
  3164. ;kg now read texture bit pointer directly
  3165. ; mov ebp,[ebp + RLDDIPixmap_pixels]
  3166. mov texture,ebp
  3167. ifndef D3D
  3168. mov ebp,[eax + RLDDIRampDriver_fill_params]
  3169. irp ord,<u,v>
  3170. mov esi,[ebp + RLDDIFillParams_wrap_&ord]
  3171. add esi,-1
  3172. sbb esi,esi
  3173. and esi,8
  3174. mov wrap_&ord,esi
  3175. endm
  3176. else
  3177. mov ebp,[eax + RLDDIGenRasDriver_fill_params]
  3178. mov esi,[ebp + RLDDIGenRasFillParams_wrap_u]
  3179. mov wrap_u,esi
  3180. mov esi,[ebp + RLDDIGenRasFillParams_wrap_v]
  3181. mov wrap_v,esi
  3182. endif
  3183. ifndef D3D
  3184. mov ebp,[eax + RLDDIGenRasDriver_texture]
  3185. mov ecx,10h
  3186. sub ecx,[ebp + RLDDIRampTexture_u_shift]
  3187. mov u_shift,ecx
  3188. mov esi,10h
  3189. sub esi,[ebp + RLDDIRampTexture_v_shift]
  3190. mov v_shift,esi
  3191. else
  3192. mov ebp,[eax + RLDDIGenRasDriver_texture]
  3193. xor ecx,ecx
  3194. ;kg this may not be the most efficent way to do
  3195. ;this
  3196. mov cx,[ebp + RLDDITexture_u_shift]
  3197. mov u_shift,ecx
  3198. xor esi,esi
  3199. mov si,[ebp + RLDDITexture_v_shift]
  3200. mov v_shift,esi
  3201. endif
  3202. ; Find address calculation function from u_shift and v_shift.
  3203. ; Entry ((u_shift * 12) + v_shift) in addrcalc_table.
  3204. lea esi,[esi + 2 * ecx]
  3205. lea ecx,[4 * ecx + ecx]
  3206. lea esi,[esi + 2 * ecx]
  3207. mov ecx,[addrcalc_table + 4 * esi]
  3208. ; Copy the 12 instruction bytes from ecx to addrcalc_code
  3209. mov [addrcalc_code],ecx
  3210. ; Transparent renderers shouldn't be too big
  3211. if (RENDER_TRANS eq 0)
  3212. cmp ecx, offset addrcalc_8_8
  3213. jne not256x256
  3214. mov trapezoid_vector,offset trapezoid_256x256
  3215. jmp any
  3216. not256x256:
  3217. cmp ecx, offset addrcalc_7_7
  3218. jne not128x128
  3219. mov trapezoid_vector,offset trapezoid_128x128
  3220. jmp any
  3221. not128x128:
  3222. cmp ecx, offset addrcalc_6_6
  3223. jne not64x64
  3224. mov trapezoid_vector,offset trapezoid_64x64
  3225. jmp any
  3226. not64x64:
  3227. cmp ecx, offset addrcalc_4_4
  3228. jne not16x16
  3229. mov trapezoid_vector,offset trapezoid_16x16
  3230. not16x16:
  3231. cmp ecx, offset addrcalc_3_3
  3232. jne any
  3233. mov trapezoid_vector,offset trapezoid_8x8
  3234. any:
  3235. endif
  3236. if PERSPECTIVE
  3237. mov ecx,trapezoid_vector
  3238. mov pc_trapezoid_vector,ecx
  3239. mov trapezoid_vector,offset trapezoid_affine
  3240. endif
  3241. if (RENDER_GOURAUD eq 0)
  3242. ; Set pixels_shade to invalid value so first triangle
  3243. ; of this texture will rebuild the 'pixels' array.
  3244. mov pixels_shade,-1
  3245. endif
  3246. endif
  3247. mov eax,[eax + RLDDIRampDriver_map]
  3248. mov map,eax
  3249. ;dfr: removed pixmap->lines
  3250. ; mov eax,[edx + RLDDIPixmap_lines]
  3251. ; mov pm_lines,eax
  3252. ; mov eax,[ebx + RLDDIPixmap_lines]
  3253. ; mov zb_lines,eax
  3254. ;kg: now read pixel pointer directly
  3255. ; mov eax,[edx + RLDDIPixmap_pixels]
  3256. mov pm_pixels,edx
  3257. if RENDER_Z
  3258. ; mov eax,[ebx + RLDDIPixmap_pixels]
  3259. mov zb_pixels,ebx
  3260. ENDIF
  3261. ; dwidth = pm->bytes_per_line / sizeof(PIXEL);
  3262. ; zwidth = zb->bytes_per_line / sizeof(ZPIXEL);
  3263. mov eax,[esp + adriver]
  3264. mov eax,[eax + RCTX_iSurfaceStride]
  3265. ; mov eax,[edx + RLDDIPixmap_bytes_per_line]
  3266. if RENDER_Z
  3267. mov ebx,[esp + adriver]
  3268. mov ebx,[ebx + RCTX_iZStride]
  3269. ; mov ebx,[ebx + RLDDIPixmap_bytes_per_line]
  3270. ENDIF
  3271. mov dwidth,eax
  3272. if RENDER_Z
  3273. mov zwidth,ebx
  3274. ENDIF
  3275. mov esi,[esp + tri]
  3276. ; Switch the NPX rounding mode to chop (round towards 0).
  3277. fstcw word ptr ftemp
  3278. mov eax,ftemp
  3279. mov control_save,eax
  3280. ; and 1111001111111111b
  3281. ; or eax,0c00h
  3282. ;kg DX5 assumes a different floating point mode
  3283. or eax,0e00h
  3284. mov ftemp,eax
  3285. fldcw word ptr ftemp
  3286. triloop1:
  3287. ; RLDDIVertex* p1 = tri->v[0];
  3288. ; RLDDIVertex* p2 = tri->v[1];
  3289. ; RLDDIVertex* p3 = tri->v[2];
  3290. ifndef D3D
  3291. mov eax,[esi + RLDDITriangle_v + 0]
  3292. mov ebx,[esi + RLDDITriangle_v + 4]
  3293. mov ecx,[esi + RLDDITriangle_v + 8]
  3294. else
  3295. mov ebx,[esp + insn]
  3296. mov eax,[esi + D3DTRIANGLE_v1] ; v2 in hi word
  3297. mov ecx,[esi + D3DTRIANGLE_v3]
  3298. mov bl,[ebx + D3DINSTRUCTION_bSize]
  3299. and ebx, 0ffh
  3300. add esi,ebx
  3301. and ecx,0ffffh
  3302. mov ebx,eax
  3303. shr ebx,11
  3304. mov edi,[esp + vbase]
  3305. shl eax,5
  3306. and ebx,0ffffh * 32
  3307. shl ecx,5
  3308. and eax,0ffffh * 32
  3309. add ebx,edi
  3310. add eax,edi
  3311. add ecx,edi
  3312. endif
  3313. p1 equ eax
  3314. p2 equ ebx
  3315. p3 equ ecx
  3316. ifdef D3D
  3317. if RENDER_GOURAUD eq 0
  3318. mov pp1,eax
  3319. endif
  3320. endif
  3321. ; Culling stuff
  3322. ; The original code implements counter clockwise culling by default.
  3323. ; Without trying to modify that code, I'm just rearranging the order
  3324. ; of the 3 vertice to implement clockwise culling and culling none.
  3325. ; So, if CONTROL_CULL_CCW is requested, nothing needs to be done;
  3326. ; if CONTROL_CULL_CW is requested, switch v2 and v3
  3327. ; if CONTROL_CULL_NONE is requested, make sure the vertices are
  3328. ; counter clockwise. The Cull test done in culling_none is the asm
  3329. ; implementaion of Cull() function in rgbgen.c
  3330. ; Here y1 y2 and y3 are computed after the culling stuff so only
  3331. ; ebx and ecx are switched if necessary.
  3332. cmp cull_ccw, 1
  3333. je culling_ccw
  3334. cmp cull_cw, 0
  3335. je culling_none
  3336. ; switch ebx and ecx
  3337. mov ebp, ebx
  3338. mov ebx, ecx
  3339. mov ecx, ebp
  3340. jmp culling_ccw
  3341. culling_none:
  3342. ; CULL_TEST
  3343. fld dword ptr [eax + D3DTLVERTEX_sx] ;x1
  3344. fld dword ptr [eax + D3DTLVERTEX_sy] ;y1 x1
  3345. fld dword ptr [ecx + D3DTLVERTEX_sy] ; y3 y1 x1
  3346. fsub st, st(1) ; y3-y1 y1 x1
  3347. fld dword ptr [ebx + D3DTLVERTEX_sx] ; x2 y3-y1 y1 x1
  3348. fsub st, st(3) ; x2-x1 y3-y1 y1 x1
  3349. fld dword ptr [ebx + D3DTLVERTEX_sy] ; y2 x2-x1 y3-y1 y1 x1
  3350. fsub st, st(3) ; y2-y1 x2-x1 y3-y1 y1 x1
  3351. fxch st(1) ; x2-x1 y2-y1 y3-y1 y1 x1
  3352. fmulp st(2), st ; y2-y1 (y3-y1)*(x2-x1) y1 x1
  3353. fld dword ptr [ecx + D3DTLVERTEX_sx] ; x3 y2-y1 (y3-y1)*(x2-x1) y1 x1
  3354. fsub st, st(4) ; x3-x1 y2-y1 (y3-y1)*(x2-x1) y1 x1
  3355. fmulp st(1), st ; (x3-x1)*(y2-y1) (y3-y1)*(x2-x1) y1 x1
  3356. mov ebp, eax
  3357. fcompp
  3358. fnstsw ax
  3359. fstp st(0)
  3360. fstp st(0)
  3361. test ah, 01
  3362. jnz done_culling_none
  3363. mov eax, ebp
  3364. ; switch ebx and ecx
  3365. mov ebp, ebx
  3366. mov ebx, ecx
  3367. mov ecx, ebp
  3368. jmp culling_ccw
  3369. done_culling_none:
  3370. mov eax, ebp
  3371. culling_ccw:
  3372. ; y1 = VALTOI(p1->sy);
  3373. ; y2 = VALTOI(p2->sy);
  3374. ; y3 = VALTOI(p3->sy);
  3375. fld dword ptr [eax + RLDDIVertex_sy]
  3376. fld dword ptr [ebx + RLDDIVertex_sy]
  3377. fld dword ptr [ecx + RLDDIVertex_sy] ; y3 y2 y1
  3378. fadd _RLDDIFloatConst2p52 ; Y3 y2 y1
  3379. fxch st(1) ; y2 Y3 y1
  3380. fadd _RLDDIFloatConst2p52 ; Y2 Y3 y1
  3381. fxch st(2) ; y1 Y3 Y2
  3382. fadd _RLDDIFloatConst2p52 ; Y1 Y3 Y2
  3383. fxch st(1) ; Y3 Y1 Y2
  3384. fstp temp_double3
  3385. fstp temp_double1
  3386. mov ebp,dword ptr temp_double3
  3387. fstp temp_double2
  3388. mov edx,dword ptr temp_double1
  3389. mov edi,dword ptr temp_double2
  3390. y1 equ edx
  3391. y2 equ edi
  3392. y3 equ ebp
  3393. ; if (y1 == y2 && y2 == y3)
  3394. ; continue;
  3395. cmp y1,y2
  3396. jne L304
  3397. cmp y2,y3
  3398. je triloop2
  3399. L304:
  3400. mov triptr,esi
  3401. ; if (y2 <= y1 && y2 <= y3)
  3402. cmp y2,y1
  3403. jg L305
  3404. cmp y2,y3
  3405. jg L305
  3406. ; y = y1;
  3407. ; y1 = y2;
  3408. ; y2 = y3;
  3409. ; y3 = y;
  3410. ; p = p1;
  3411. ; p1 = p2;
  3412. ; p2 = p3;
  3413. ; p3 = p;
  3414. rotleft macro a,b,c
  3415. mov esi,a
  3416. mov a,b
  3417. mov b,c
  3418. mov c,esi
  3419. endm
  3420. rotleft y1,y2,y3
  3421. rotleft p1,p2,p3
  3422. jmp L306
  3423. L305:
  3424. ; } else if (y3 <= y1 && y3 <= y2) {
  3425. cmp y3,y1
  3426. jg L306
  3427. cmp y3,y2
  3428. jg L306
  3429. ; y = y1;
  3430. ; y1 = y3;
  3431. ; y3 = y2;
  3432. ; y2 = y;
  3433. ; p = p1;
  3434. ; p1 = p3;
  3435. ; p3 = p2;
  3436. ; p2 = p;
  3437. rotleft y1,y3,y2
  3438. rotleft p1,p3,p2
  3439. L306:
  3440. ; h1 = y2 - y1;
  3441. ; h2 = y3 - y2;
  3442. ; h3 = y3 - y1;
  3443. ; if (h1 == 0) {
  3444. cmp y1,y2
  3445. jne L308
  3446. ; h2 = y3 - y2;
  3447. sub y3,y2 ; h2 = ebp
  3448. ; Draw flat triangle, from vertices eax,ebx shared vertex ecx.
  3449. ; ebp is height, edx is starting y.
  3450. ; This is the same as case 3 with arguments rotated
  3451. ;FlatTriangle eax, ebx, ecx, ebp, edx, 1
  3452. ;jmp continue
  3453. rotleft ecx,eax,ebx
  3454. jmp flat3
  3455. L308:
  3456. ; } else if (h2 == 0) {
  3457. ; flat bottom
  3458. cmp y3,y2
  3459. jne L310
  3460. sub y2,y1
  3461. mov ebp,y2
  3462. FlatTriangle ecx, ebx, eax, ebp, edx, 2
  3463. jmp continue
  3464. L310:
  3465. ; } else if (h3 == 0) {
  3466. cmp y3,y1
  3467. jne L312
  3468. sub y2,y1
  3469. mov ebp,y2
  3470. flat3: FlatTriangle ecx, eax, ebx, ebp, edx, 3
  3471. jmp continue
  3472. L312:
  3473. ; } else if (h1 < h3) {
  3474. cmp y2,y3
  3475. jge L314
  3476. AnyTriangle 1
  3477. jmp continue
  3478. L314:
  3479. if BIDIRECTIONAL
  3480. xchg ecx,ebx
  3481. xchg ebp,edi
  3482. endif
  3483. AnyTriangle 0
  3484. jmp continue
  3485. continue:
  3486. mov esi,triptr
  3487. triloop2:
  3488. ifndef D3D
  3489. add esi,[esp + tsize]
  3490. endif
  3491. dec dword ptr [esp + count]
  3492. jne triloop1
  3493. fldcw word ptr control_save
  3494. triloop3:
  3495. add esp, vars
  3496. pop es
  3497. pop edi
  3498. pop esi
  3499. pop ebp
  3500. pop ebx
  3501. return
  3502. continue4:
  3503. FDROP
  3504. FDROP
  3505. continue2:
  3506. FDROP
  3507. continue1:
  3508. FDROP
  3509. jmp continue
  3510. ifdef MICROSOFT_NT
  3511. endproc _RLDDIR,%nameFG,%nameZ,%nameT,%nameG,Triangle
  3512. else
  3513. endproc RLDDIR,%nameFG,%nameZ,%nameT,%nameG,Triangle
  3514. endif
  3515. TRAPEZOID dotrapezoid, FILLSPAN, 0, PERSPECTIVE
  3516. ret
  3517. if RENDER_TEXTURE
  3518. if (RENDER_TRANS eq 0)
  3519. TRAPEZOID trapezoid_256x256, FILLSPAN, 256, PERSPECTIVE
  3520. ret
  3521. TRAPEZOID trapezoid_128x128, FILLSPAN, 128, PERSPECTIVE
  3522. ret
  3523. TRAPEZOID trapezoid_64x64, FILLSPAN, 64, PERSPECTIVE
  3524. ret
  3525. TRAPEZOID trapezoid_16x16, FILLSPAN, 16, PERSPECTIVE
  3526. ret
  3527. TRAPEZOID trapezoid_8x8, FILLSPAN, 8, PERSPECTIVE
  3528. ret
  3529. endif
  3530. if PERSPECTIVE
  3531. TRAPEZOID trapezoid_affine, AFILLSPAN, 0, 0
  3532. ret
  3533. endif
  3534. endif
  3535. cseg ends
  3536. end