r_edgea.asm 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. .386P
  2. .model FLAT
  3. ;
  4. ; r_edgea.s
  5. ; x86 assembly-language edge-processing code.
  6. ;
  7. include qasm.inc
  8. if id386
  9. _DATA SEGMENT
  10. Ltemp dd 0
  11. float_1_div_0100000h dd 035800000h ; 1.0/(float)0x100000
  12. float_point_999 dd 0.999
  13. float_1_point_001 dd 1.001
  14. _DATA ENDS
  15. _TEXT SEGMENT
  16. ;--------------------------------------------------------------------
  17. edgestoadd equ 4+8 ; note odd stack offsets because of interleaving
  18. edgelist equ 8+12 ; with pushes
  19. public _R_EdgeCodeStart
  20. _R_EdgeCodeStart:
  21. public _R_InsertNewEdges
  22. _R_InsertNewEdges:
  23. push edi
  24. push esi ; preserve register variables
  25. mov edx,ds:dword ptr[edgestoadd+esp]
  26. push ebx
  27. mov ecx,ds:dword ptr[edgelist+esp]
  28. LDoNextEdge:
  29. mov eax,ds:dword ptr[et_u+edx]
  30. mov edi,edx
  31. LContinueSearch:
  32. mov ebx,ds:dword ptr[et_u+ecx]
  33. mov esi,ds:dword ptr[et_next+ecx]
  34. cmp eax,ebx
  35. jle LAddedge
  36. mov ebx,ds:dword ptr[et_u+esi]
  37. mov ecx,ds:dword ptr[et_next+esi]
  38. cmp eax,ebx
  39. jle LAddedge2
  40. mov ebx,ds:dword ptr[et_u+ecx]
  41. mov esi,ds:dword ptr[et_next+ecx]
  42. cmp eax,ebx
  43. jle LAddedge
  44. mov ebx,ds:dword ptr[et_u+esi]
  45. mov ecx,ds:dword ptr[et_next+esi]
  46. cmp eax,ebx
  47. jg LContinueSearch
  48. LAddedge2:
  49. mov edx,ds:dword ptr[et_next+edx]
  50. mov ebx,ds:dword ptr[et_prev+esi]
  51. mov ds:dword ptr[et_next+edi],esi
  52. mov ds:dword ptr[et_prev+edi],ebx
  53. mov ds:dword ptr[et_next+ebx],edi
  54. mov ds:dword ptr[et_prev+esi],edi
  55. mov ecx,esi
  56. cmp edx,0
  57. jnz LDoNextEdge
  58. jmp LDone
  59. align 4
  60. LAddedge:
  61. mov edx,ds:dword ptr[et_next+edx]
  62. mov ebx,ds:dword ptr[et_prev+ecx]
  63. mov ds:dword ptr[et_next+edi],ecx
  64. mov ds:dword ptr[et_prev+edi],ebx
  65. mov ds:dword ptr[et_next+ebx],edi
  66. mov ds:dword ptr[et_prev+ecx],edi
  67. cmp edx,0
  68. jnz LDoNextEdge
  69. LDone:
  70. pop ebx ; restore register variables
  71. pop esi
  72. pop edi
  73. ret
  74. ;--------------------------------------------------------------------
  75. predge equ 4+4
  76. public _R_RemoveEdges
  77. _R_RemoveEdges:
  78. push ebx
  79. mov eax,ds:dword ptr[predge+esp]
  80. Lre_loop:
  81. mov ecx,ds:dword ptr[et_next+eax]
  82. mov ebx,ds:dword ptr[et_nextremove+eax]
  83. mov edx,ds:dword ptr[et_prev+eax]
  84. test ebx,ebx
  85. mov ds:dword ptr[et_prev+ecx],edx
  86. jz Lre_done
  87. mov ds:dword ptr[et_next+edx],ecx
  88. mov ecx,ds:dword ptr[et_next+ebx]
  89. mov edx,ds:dword ptr[et_prev+ebx]
  90. mov eax,ds:dword ptr[et_nextremove+ebx]
  91. mov ds:dword ptr[et_prev+ecx],edx
  92. test eax,eax
  93. mov ds:dword ptr[et_next+edx],ecx
  94. jnz Lre_loop
  95. pop ebx
  96. ret
  97. Lre_done:
  98. mov ds:dword ptr[et_next+edx],ecx
  99. pop ebx
  100. ret
  101. ;--------------------------------------------------------------------
  102. pedgelist equ 4+4 ; note odd stack offset because of interleaving
  103. ; with pushes
  104. public _R_StepActiveU
  105. _R_StepActiveU:
  106. push edi
  107. mov edx,ds:dword ptr[pedgelist+esp]
  108. push esi ; preserve register variables
  109. push ebx
  110. mov esi,ds:dword ptr[et_prev+edx]
  111. LNewEdge:
  112. mov edi,ds:dword ptr[et_u+esi]
  113. LNextEdge:
  114. mov eax,ds:dword ptr[et_u+edx]
  115. mov ebx,ds:dword ptr[et_u_step+edx]
  116. add eax,ebx
  117. mov esi,ds:dword ptr[et_next+edx]
  118. mov ds:dword ptr[et_u+edx],eax
  119. cmp eax,edi
  120. jl LPushBack
  121. mov edi,ds:dword ptr[et_u+esi]
  122. mov ebx,ds:dword ptr[et_u_step+esi]
  123. add edi,ebx
  124. mov edx,ds:dword ptr[et_next+esi]
  125. mov ds:dword ptr[et_u+esi],edi
  126. cmp edi,eax
  127. jl LPushBack2
  128. mov eax,ds:dword ptr[et_u+edx]
  129. mov ebx,ds:dword ptr[et_u_step+edx]
  130. add eax,ebx
  131. mov esi,ds:dword ptr[et_next+edx]
  132. mov ds:dword ptr[et_u+edx],eax
  133. cmp eax,edi
  134. jl LPushBack
  135. mov edi,ds:dword ptr[et_u+esi]
  136. mov ebx,ds:dword ptr[et_u_step+esi]
  137. add edi,ebx
  138. mov edx,ds:dword ptr[et_next+esi]
  139. mov ds:dword ptr[et_u+esi],edi
  140. cmp edi,eax
  141. jnl LNextEdge
  142. LPushBack2:
  143. mov ebx,edx
  144. mov eax,edi
  145. mov edx,esi
  146. mov esi,ebx
  147. LPushBack:
  148. ; push it back to keep it sorted
  149. mov ecx,ds:dword ptr[et_prev+edx]
  150. mov ebx,ds:dword ptr[et_next+edx]
  151. ; done if the -1 in edge_aftertail triggered this
  152. cmp edx,offset _edge_aftertail
  153. jz LUDone
  154. ; pull the edge out of the edge list
  155. mov edi,ds:dword ptr[et_prev+ecx]
  156. mov ds:dword ptr[et_prev+esi],ecx
  157. mov ds:dword ptr[et_next+ecx],ebx
  158. ; find out where the edge goes in the edge list
  159. LPushBackLoop:
  160. mov ecx,ds:dword ptr[et_prev+edi]
  161. mov ebx,ds:dword ptr[et_u+edi]
  162. cmp eax,ebx
  163. jnl LPushBackFound
  164. mov edi,ds:dword ptr[et_prev+ecx]
  165. mov ebx,ds:dword ptr[et_u+ecx]
  166. cmp eax,ebx
  167. jl LPushBackLoop
  168. mov edi,ecx
  169. ; put the edge back into the edge list
  170. LPushBackFound:
  171. mov ebx,ds:dword ptr[et_next+edi]
  172. mov ds:dword ptr[et_prev+edx],edi
  173. mov ds:dword ptr[et_next+edx],ebx
  174. mov ds:dword ptr[et_next+edi],edx
  175. mov ds:dword ptr[et_prev+ebx],edx
  176. mov edx,esi
  177. mov esi,ds:dword ptr[et_prev+esi]
  178. cmp edx,offset _edge_tail
  179. jnz LNewEdge
  180. LUDone:
  181. pop ebx ; restore register variables
  182. pop esi
  183. pop edi
  184. ret
  185. ;--------------------------------------------------------------------
  186. surf equ 4 ; note this is loaded before any pushes
  187. align 4
  188. TrailingEdge:
  189. mov eax,ds:dword ptr[st_spanstate+esi] ; check for edge inversion
  190. dec eax
  191. jnz LInverted
  192. mov ds:dword ptr[st_spanstate+esi],eax
  193. mov ecx,ds:dword ptr[st_insubmodel+esi]
  194. mov edx,ds:dword ptr[12345678h] ; surfaces[1].st_next
  195. LPatch0:
  196. mov eax,ds:dword ptr[_r_bmodelactive]
  197. sub eax,ecx
  198. cmp edx,esi
  199. mov ds:dword ptr[_r_bmodelactive],eax
  200. jnz LNoEmit ; surface isn't on top, just remove
  201. ; emit a span (current top going away)
  202. mov eax,ds:dword ptr[et_u+ebx]
  203. shr eax,20 ; iu = integral pixel u
  204. mov edx,ds:dword ptr[st_last_u+esi]
  205. mov ecx,ds:dword ptr[st_next+esi]
  206. cmp eax,edx
  207. jle LNoEmit2 ; iu <= surf->last_u, so nothing to emit
  208. mov ds:dword ptr[st_last_u+ecx],eax ; surf->next->last_u = iu;
  209. sub eax,edx
  210. mov ds:dword ptr[espan_t_u+ebp],edx ; span->u = surf->last_u;
  211. mov ds:dword ptr[espan_t_count+ebp],eax ; span->count = iu - span->u;
  212. mov eax,ds:dword ptr[_current_iv]
  213. mov ds:dword ptr[espan_t_v+ebp],eax ; span->v = current_iv;
  214. mov eax,ds:dword ptr[st_spans+esi]
  215. mov ds:dword ptr[espan_t_pnext+ebp],eax ; span->pnext = surf->spans;
  216. mov ds:dword ptr[st_spans+esi],ebp ; surf->spans = span;
  217. add ebp,offset espan_t_size
  218. mov edx,ds:dword ptr[st_next+esi] ; remove the surface from the surface
  219. mov esi,ds:dword ptr[st_prev+esi] ; stack
  220. mov ds:dword ptr[st_next+esi],edx
  221. mov ds:dword ptr[st_prev+edx],esi
  222. ret
  223. LNoEmit2:
  224. mov ds:dword ptr[st_last_u+ecx],eax ; surf->next->last_u = iu;
  225. mov edx,ds:dword ptr[st_next+esi] ; remove the surface from the surface
  226. mov esi,ds:dword ptr[st_prev+esi] ; stack
  227. mov ds:dword ptr[st_next+esi],edx
  228. mov ds:dword ptr[st_prev+edx],esi
  229. ret
  230. LNoEmit:
  231. mov edx,ds:dword ptr[st_next+esi] ; remove the surface from the surface
  232. mov esi,ds:dword ptr[st_prev+esi] ; stack
  233. mov ds:dword ptr[st_next+esi],edx
  234. mov ds:dword ptr[st_prev+edx],esi
  235. ret
  236. LInverted:
  237. mov ds:dword ptr[st_spanstate+esi],eax
  238. ret
  239. ;--------------------------------------------------------------------
  240. ; trailing edge only
  241. Lgs_trailing:
  242. push offset Lgs_nextedge
  243. jmp TrailingEdge
  244. public _R_GenerateSpans
  245. _R_GenerateSpans:
  246. push ebp ; preserve caller's stack frame
  247. push edi
  248. push esi ; preserve register variables
  249. push ebx
  250. ; clear active surfaces to just the background surface
  251. mov eax,ds:dword ptr[_surfaces]
  252. mov edx,ds:dword ptr[_edge_head_u_shift20]
  253. add eax,offset st_size
  254. ; %ebp = span_p throughout
  255. mov ebp,ds:dword ptr[_span_p]
  256. mov ds:dword ptr[_r_bmodelactive],0
  257. mov ds:dword ptr[st_next+eax],eax
  258. mov ds:dword ptr[st_prev+eax],eax
  259. mov ds:dword ptr[st_last_u+eax],edx
  260. mov ebx,ds:dword ptr[_edge_head+et_next] ; edge=edge_head.next
  261. ; generate spans
  262. cmp ebx,offset _edge_tail ; done if empty list
  263. jz Lgs_lastspan
  264. Lgs_edgeloop:
  265. mov edi,ds:dword ptr[et_surfs+ebx]
  266. mov eax,ds:dword ptr[_surfaces]
  267. mov esi,edi
  268. and edi,0FFFF0000h
  269. and esi,0FFFFh
  270. jz Lgs_leading ; not a trailing edge
  271. ; it has a left surface, so a surface is going away for this span
  272. shl esi,offset SURF_T_SHIFT
  273. add esi,eax
  274. test edi,edi
  275. jz Lgs_trailing
  276. ; both leading and trailing
  277. call near ptr TrailingEdge
  278. mov eax,ds:dword ptr[_surfaces]
  279. ; ---------------------------------------------------------------
  280. ; handle a leading edge
  281. ; ---------------------------------------------------------------
  282. Lgs_leading:
  283. shr edi,16-SURF_T_SHIFT
  284. mov eax,ds:dword ptr[_surfaces]
  285. add edi,eax
  286. mov esi,ds:dword ptr[12345678h] ; surf2 = surfaces[1].next;
  287. LPatch2:
  288. mov edx,ds:dword ptr[st_spanstate+edi]
  289. mov eax,ds:dword ptr[st_insubmodel+edi]
  290. test eax,eax
  291. jnz Lbmodel_leading
  292. ; handle a leading non-bmodel edge
  293. ; don't start a span if this is an inverted span, with the end edge preceding
  294. ; the start edge (that is, we've already seen the end edge)
  295. test edx,edx
  296. jnz Lxl_done
  297. ; if (surf->key < surf2->key)
  298. ; goto newtop;
  299. inc edx
  300. mov eax,ds:dword ptr[st_key+edi]
  301. mov ds:dword ptr[st_spanstate+edi],edx
  302. mov ecx,ds:dword ptr[st_key+esi]
  303. cmp eax,ecx
  304. jl Lnewtop
  305. ; main sorting loop to search through surface stack until insertion point
  306. ; found. Always terminates because background surface is sentinel
  307. ; do
  308. ; {
  309. ; surf2 = surf2->next;
  310. ; } while (surf->key >= surf2->key);
  311. Lsortloopnb:
  312. mov esi,ds:dword ptr[st_next+esi]
  313. mov ecx,ds:dword ptr[st_key+esi]
  314. cmp eax,ecx
  315. jge Lsortloopnb
  316. jmp LInsertAndExit
  317. ; handle a leading bmodel edge
  318. align 4
  319. Lbmodel_leading:
  320. ; don't start a span if this is an inverted span, with the end edge preceding
  321. ; the start edge (that is, we've already seen the end edge)
  322. test edx,edx
  323. jnz Lxl_done
  324. mov ecx,ds:dword ptr[_r_bmodelactive]
  325. inc edx
  326. inc ecx
  327. mov ds:dword ptr[st_spanstate+edi],edx
  328. mov ds:dword ptr[_r_bmodelactive],ecx
  329. ; if (surf->key < surf2->key)
  330. ; goto newtop;
  331. mov eax,ds:dword ptr[st_key+edi]
  332. mov ecx,ds:dword ptr[st_key+esi]
  333. cmp eax,ecx
  334. jl Lnewtop
  335. ; if ((surf->key == surf2->key) && surf->insubmodel)
  336. ; {
  337. jz Lzcheck_for_newtop
  338. ; main sorting loop to search through surface stack until insertion point
  339. ; found. Always terminates because background surface is sentinel
  340. ; do
  341. ; {
  342. ; surf2 = surf2->next;
  343. ; } while (surf->key > surf2->key);
  344. Lsortloop:
  345. mov esi,ds:dword ptr[st_next+esi]
  346. mov ecx,ds:dword ptr[st_key+esi]
  347. cmp eax,ecx
  348. jg Lsortloop
  349. jne LInsertAndExit
  350. ; Do 1/z sorting to see if we've arrived in the right position
  351. mov eax,ds:dword ptr[et_u+ebx]
  352. sub eax,0FFFFFh
  353. mov ds:dword ptr[Ltemp],eax
  354. fild ds:dword ptr[Ltemp]
  355. fmul ds:dword ptr[float_1_div_0100000h] ; fu = (float)(edge->u - 0xFFFFF) *
  356. ; (1.0 / 0x100000);
  357. fld st(0) ; fu | fu
  358. fmul ds:dword ptr[st_d_zistepu+edi] ; fu*surf->d_zistepu | fu
  359. fld ds:dword ptr[_fv] ; fv | fu*surf->d_zistepu | fu
  360. fmul ds:dword ptr[st_d_zistepv+edi] ; fv*surf->d_zistepv | fu*surf->d_zistepu | fu
  361. fxch st(1) ; fu*surf->d_zistepu | fv*surf->d_zistepv | fu
  362. fadd ds:dword ptr[st_d_ziorigin+edi] ; fu*surf->d_zistepu + surf->d_ziorigin |
  363. ; fv*surf->d_zistepv | fu
  364. fld ds:dword ptr[st_d_zistepu+esi] ; surf2->d_zistepu |
  365. ; fu*surf->d_zistepu + surf->d_ziorigin |
  366. ; fv*surf->d_zistepv | fu
  367. fmul st(0),st(3) ; fu*surf2->d_zistepu |
  368. ; fu*surf->d_zistepu + surf->d_ziorigin |
  369. ; fv*surf->d_zistepv | fu
  370. fxch st(1) ; fu*surf->d_zistepu + surf->d_ziorigin |
  371. ; fu*surf2->d_zistepu |
  372. ; fv*surf->d_zistepv | fu
  373. faddp st(2),st(0) ; fu*surf2->d_zistepu | newzi | fu
  374. fld ds:dword ptr[_fv] ; fv | fu*surf2->d_zistepu | newzi | fu
  375. fmul ds:dword ptr[st_d_zistepv+esi] ; fv*surf2->d_zistepv |
  376. ; fu*surf2->d_zistepu | newzi | fu
  377. fld st(2) ; newzi | fv*surf2->d_zistepv |
  378. ; fu*surf2->d_zistepu | newzi | fu
  379. fmul ds:dword ptr[float_point_999] ; newzibottom | fv*surf2->d_zistepv |
  380. ; fu*surf2->d_zistepu | newzi | fu
  381. fxch st(2) ; fu*surf2->d_zistepu | fv*surf2->d_zistepv |
  382. ; newzibottom | newzi | fu
  383. fadd ds:dword ptr[st_d_ziorigin+esi] ; fu*surf2->d_zistepu + surf2->d_ziorigin |
  384. ; fv*surf2->d_zistepv | newzibottom | newzi |
  385. ; fu
  386. faddp st(1),st(0) ; testzi | newzibottom | newzi | fu
  387. fxch st(1) ; newzibottom | testzi | newzi | fu
  388. ; if (newzibottom >= testzi)
  389. ; goto Lgotposition;
  390. fcomp st(1) ; testzi | newzi | fu
  391. fxch st(1) ; newzi | testzi | fu
  392. fmul ds:dword ptr[float_1_point_001] ; newzitop | testzi | fu
  393. fxch st(1) ; testzi | newzitop | fu
  394. fnstsw ax
  395. test ah,001h
  396. jz Lgotposition_fpop3
  397. ; if (newzitop >= testzi)
  398. ; {
  399. fcomp st(1) ; newzitop | fu
  400. fnstsw ax
  401. test ah,045h
  402. jz Lsortloop_fpop2
  403. ; if (surf->d_zistepu >= surf2->d_zistepu)
  404. ; goto newtop;
  405. fld ds:dword ptr[st_d_zistepu+edi] ; surf->d_zistepu | newzitop| fu
  406. fcomp ds:dword ptr[st_d_zistepu+esi] ; newzitop | fu
  407. fnstsw ax
  408. test ah,001h
  409. jz Lgotposition_fpop2
  410. fstp st(0) ; clear the FPstack
  411. fstp st(0)
  412. mov eax,ds:dword ptr[st_key+edi]
  413. jmp Lsortloop
  414. Lgotposition_fpop3:
  415. fstp st(0)
  416. Lgotposition_fpop2:
  417. fstp st(0)
  418. fstp st(0)
  419. jmp LInsertAndExit
  420. ; emit a span (obscures current top)
  421. Lnewtop_fpop3:
  422. fstp st(0)
  423. Lnewtop_fpop2:
  424. fstp st(0)
  425. fstp st(0)
  426. mov eax,ds:dword ptr[st_key+edi] ; reload the sorting key
  427. Lnewtop:
  428. mov eax,ds:dword ptr[et_u+ebx]
  429. mov edx,ds:dword ptr[st_last_u+esi]
  430. shr eax,20 ; iu = integral pixel u
  431. mov ds:dword ptr[st_last_u+edi],eax ; surf->last_u = iu;
  432. cmp eax,edx
  433. jle LInsertAndExit ; iu <= surf->last_u, so nothing to emit
  434. sub eax,edx
  435. mov ds:dword ptr[espan_t_u+ebp],edx ; span->u = surf->last_u;
  436. mov ds:dword ptr[espan_t_count+ebp],eax ; span->count = iu - span->u;
  437. mov eax,ds:dword ptr[_current_iv]
  438. mov ds:dword ptr[espan_t_v+ebp],eax ; span->v = current_iv;
  439. mov eax,ds:dword ptr[st_spans+esi]
  440. mov ds:dword ptr[espan_t_pnext+ebp],eax ; span->pnext = surf->spans;
  441. mov ds:dword ptr[st_spans+esi],ebp ; surf->spans = span;
  442. add ebp,offset espan_t_size
  443. LInsertAndExit:
  444. ; insert before surf2
  445. mov ds:dword ptr[st_next+edi],esi ; surf->next = surf2;
  446. mov eax,ds:dword ptr[st_prev+esi]
  447. mov ds:dword ptr[st_prev+edi],eax ; surf->prev = surf2->prev;
  448. mov ds:dword ptr[st_prev+esi],edi ; surf2->prev = surf;
  449. mov ds:dword ptr[st_next+eax],edi ; surf2->prev->next = surf;
  450. ; ---------------------------------------------------------------
  451. ; leading edge done
  452. ; ---------------------------------------------------------------
  453. ; ---------------------------------------------------------------
  454. ; see if there are any more edges
  455. ; ---------------------------------------------------------------
  456. Lgs_nextedge:
  457. mov ebx,ds:dword ptr[et_next+ebx]
  458. cmp ebx,offset _edge_tail
  459. jnz Lgs_edgeloop
  460. ; clean up at the right edge
  461. Lgs_lastspan:
  462. ; now that we've reached the right edge of the screen, we're done with any
  463. ; unfinished surfaces, so emit a span for whatever's on top
  464. mov esi,ds:dword ptr[12345678h] ; surfaces[1].st_next
  465. LPatch3:
  466. mov eax,ds:dword ptr[_edge_tail_u_shift20]
  467. xor ecx,ecx
  468. mov edx,ds:dword ptr[st_last_u+esi]
  469. sub eax,edx
  470. jle Lgs_resetspanstate
  471. mov ds:dword ptr[espan_t_u+ebp],edx
  472. mov ds:dword ptr[espan_t_count+ebp],eax
  473. mov eax,ds:dword ptr[_current_iv]
  474. mov ds:dword ptr[espan_t_v+ebp],eax
  475. mov eax,ds:dword ptr[st_spans+esi]
  476. mov ds:dword ptr[espan_t_pnext+ebp],eax
  477. mov ds:dword ptr[st_spans+esi],ebp
  478. add ebp,offset espan_t_size
  479. ; reset spanstate for all surfaces in the surface stack
  480. Lgs_resetspanstate:
  481. mov ds:dword ptr[st_spanstate+esi],ecx
  482. mov esi,ds:dword ptr[st_next+esi]
  483. cmp esi,012345678h ; &surfaces[1]
  484. LPatch4:
  485. jnz Lgs_resetspanstate
  486. ; store the final span_p
  487. mov ds:dword ptr[_span_p],ebp
  488. pop ebx ; restore register variables
  489. pop esi
  490. pop edi
  491. pop ebp ; restore the caller's stack frame
  492. ret
  493. ; ---------------------------------------------------------------
  494. ; 1/z sorting for bmodels in the same leaf
  495. ; ---------------------------------------------------------------
  496. align 4
  497. Lxl_done:
  498. inc edx
  499. mov ds:dword ptr[st_spanstate+edi],edx
  500. jmp Lgs_nextedge
  501. align 4
  502. Lzcheck_for_newtop:
  503. mov eax,ds:dword ptr[et_u+ebx]
  504. sub eax,0FFFFFh
  505. mov ds:dword ptr[Ltemp],eax
  506. fild ds:dword ptr[Ltemp]
  507. fmul ds:dword ptr[float_1_div_0100000h] ; fu = (float)(edge->u - 0xFFFFF) *
  508. ; (1.0 / 0x100000);
  509. fld st(0) ; fu | fu
  510. fmul ds:dword ptr[st_d_zistepu+edi] ; fu*surf->d_zistepu | fu
  511. fld ds:dword ptr[_fv] ; fv | fu*surf->d_zistepu | fu
  512. fmul ds:dword ptr[st_d_zistepv+edi] ; fv*surf->d_zistepv | fu*surf->d_zistepu | fu
  513. fxch st(1) ; fu*surf->d_zistepu | fv*surf->d_zistepv | fu
  514. fadd ds:dword ptr[st_d_ziorigin+edi] ; fu*surf->d_zistepu + surf->d_ziorigin |
  515. ; fv*surf->d_zistepv | fu
  516. fld ds:dword ptr[st_d_zistepu+esi] ; surf2->d_zistepu |
  517. ; fu*surf->d_zistepu + surf->d_ziorigin |
  518. ; fv*surf->d_zistepv | fu
  519. fmul st(0),st(3) ; fu*surf2->d_zistepu |
  520. ; fu*surf->d_zistepu + surf->d_ziorigin |
  521. ; fv*surf->d_zistepv | fu
  522. fxch st(1) ; fu*surf->d_zistepu + surf->d_ziorigin |
  523. ; fu*surf2->d_zistepu |
  524. ; fv*surf->d_zistepv | fu
  525. faddp st(2),st(0) ; fu*surf2->d_zistepu | newzi | fu
  526. fld ds:dword ptr[_fv] ; fv | fu*surf2->d_zistepu | newzi | fu
  527. fmul ds:dword ptr[st_d_zistepv+esi] ; fv*surf2->d_zistepv |
  528. ; fu*surf2->d_zistepu | newzi | fu
  529. fld st(2) ; newzi | fv*surf2->d_zistepv |
  530. ; fu*surf2->d_zistepu | newzi | fu
  531. fmul ds:dword ptr[float_point_999] ; newzibottom | fv*surf2->d_zistepv |
  532. ; fu*surf2->d_zistepu | newzi | fu
  533. fxch st(2) ; fu*surf2->d_zistepu | fv*surf2->d_zistepv |
  534. ; newzibottom | newzi | fu
  535. fadd ds:dword ptr[st_d_ziorigin+esi] ; fu*surf2->d_zistepu + surf2->d_ziorigin |
  536. ; fv*surf2->d_zistepv | newzibottom | newzi |
  537. ; fu
  538. faddp st(1),st(0) ; testzi | newzibottom | newzi | fu
  539. fxch st(1) ; newzibottom | testzi | newzi | fu
  540. ; if (newzibottom >= testzi)
  541. ; goto newtop;
  542. fcomp st(1) ; testzi | newzi | fu
  543. fxch st(1) ; newzi | testzi | fu
  544. fmul ds:dword ptr[float_1_point_001] ; newzitop | testzi | fu
  545. fxch st(1) ; testzi | newzitop | fu
  546. fnstsw ax
  547. test ah,001h
  548. jz Lnewtop_fpop3
  549. ; if (newzitop >= testzi)
  550. ; {
  551. fcomp st(1) ; newzitop | fu
  552. fnstsw ax
  553. test ah,045h
  554. jz Lsortloop_fpop2
  555. ; if (surf->d_zistepu >= surf2->d_zistepu)
  556. ; goto newtop;
  557. fld ds:dword ptr[st_d_zistepu+edi] ; surf->d_zistepu | newzitop | fu
  558. fcomp ds:dword ptr[st_d_zistepu+esi] ; newzitop | fu
  559. fnstsw ax
  560. test ah,001h
  561. jz Lnewtop_fpop2
  562. Lsortloop_fpop2:
  563. fstp st(0) ; clear the FP stack
  564. fstp st(0)
  565. mov eax,ds:dword ptr[st_key+edi]
  566. jmp Lsortloop
  567. public _R_EdgeCodeEnd
  568. _R_EdgeCodeEnd:
  569. ;----------------------------------------------------------------------
  570. ; Surface array address code patching routine
  571. ;----------------------------------------------------------------------
  572. align 4
  573. public _R_SurfacePatch
  574. _R_SurfacePatch:
  575. mov eax,ds:dword ptr[_surfaces]
  576. add eax,offset st_size
  577. mov ds:dword ptr[LPatch4-4],eax
  578. add eax,offset st_next
  579. mov ds:dword ptr[LPatch0-4],eax
  580. mov ds:dword ptr[LPatch2-4],eax
  581. mov ds:dword ptr[LPatch3-4],eax
  582. ret
  583. _TEXT ENDS
  584. endif ;id386
  585. END