TMAP_MUL.ASM 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935
  1. ;THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
  2. ;SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
  3. ;END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
  4. ;ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
  5. ;IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
  6. ;SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
  7. ;FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
  8. ;CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
  9. ;AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
  10. ;COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
  11. ;
  12. ; $Source: f:/miner/source/texmap/rcs/tmap_mul.asm $
  13. ; $Revision: 1.4 $
  14. ; $Author: mike $
  15. ; $Date: 1994/11/30 00:56:56 $
  16. ;
  17. ; Inner loop of 2 multiplies per 8 pixels texture mapper.
  18. ;
  19. ; $Log: tmap_mul.asm $
  20. ; Revision 1.4 1994/11/30 00:56:56 mike
  21. ; optimization.
  22. ;
  23. ; Revision 1.3 1994/11/12 16:41:00 mike
  24. ; jae -> ja.
  25. ;
  26. ; Revision 1.2 1994/11/02 21:33:33 john
  27. ; Added Burger Bill's optimization, ie.. 2 muls per 8 pixels.
  28. ;
  29. ; Revision 1.1 1994/11/02 20:57:36 john
  30. ; Initial revision
  31. ;
  32. ;
  33. .386
  34. public asm_tmap_scanline_mul_
  35. extrn _divide_table:dword
  36. include tmap_inc.asm
  37. extrn _fx_u:dword
  38. extrn _fx_v:dword
  39. extrn _fx_z:dword
  40. extrn _fx_du_dx:dword
  41. extrn _fx_dv_dx:dword
  42. extrn _fx_dz_dx:dword
  43. extrn _fx_y:dword
  44. extrn _fx_xleft:dword
  45. extrn _fx_xright:dword
  46. extrn _pixptr:dword
  47. extrn _x:dword
  48. extrn _loop_count:dword
  49. extern _pixel_data_selector:word, _gr_fade_table_selector:word
  50. extern _transparency_on:dword
  51. extern _fx_l:dword
  52. extern _fx_dl_dx:dword
  53. extern _dither_intensity_lighting:dword
  54. extern _Lighting_on:dword
  55. _DATA SEGMENT DWORD PUBLIC USE32 'DATA'
  56. ;---------- local variables
  57. align 4
  58. req_base dd ?
  59. req_size dd ?
  60. U0 dd ?
  61. U1 dd ?
  62. V0 dd ?
  63. V1 dd ?
  64. num_left_over dd ?
  65. DU1 dd ?
  66. DV1 dd ?
  67. DZ1 dd ?
  68. _DATA ENDS
  69. DGROUP GROUP _DATA
  70. _TEXT SEGMENT PARA PUBLIC USE32 'CODE'
  71. ASSUME DS:_DATA
  72. ASSUME CS:_TEXT
  73. ; --------------------------------------------------------------------------------------------------
  74. ; Enter:
  75. ; _xleft fixed point left x coordinate
  76. ; _xright fixed point right x coordinate
  77. ; _y fixed point y coordinate
  78. ; _pixptr address of source pixel map
  79. ; _u fixed point initial u coordinate
  80. ; _v fixed point initial v coordinate
  81. ; _z fixed point initial z coordinate
  82. ; _du_dx fixed point du/dx
  83. ; _dv_dx fixed point dv/dx
  84. ; _dz_dx fixed point dz/dx
  85. ; for (x = (int) xleft; x <= (int) xright; x++) {
  86. ; _setcolor(read_pixel_from_tmap(srcb,((int) (u/z)) & 63,((int) (v/z)) & 63));
  87. ; _setpixel(x,y);
  88. ;
  89. ; u += du_dx;
  90. ; v += dv_dx;
  91. ; z += dz_dx;
  92. ; }
  93. asm_tmap_scanline_mul_:
  94. push es
  95. pusha
  96. ;---------------------------- setup for loop ---------------------------------
  97. ; Setup for loop: _loop_count iterations = (int) xright - (int) xleft
  98. ; esi source pixel pointer = pixptr
  99. ; edi initial row pointer = y*320+x
  100. ; set esi = pointer to start of texture map data
  101. mov es,_pixel_data_selector ; selector[0*2]
  102. ; set edi = address of first pixel to modify
  103. mov edi,_fx_y
  104. cmp edi,_window_bottom
  105. ja _none_to_do
  106. imul edi,_bytes_per_row
  107. mov eax,_fx_xleft
  108. sar eax,16
  109. jns eax_ok
  110. sub eax,eax
  111. eax_ok:
  112. add edi,eax
  113. add edi,write_buffer
  114. ; set _loop_count = # of iterations
  115. mov eax,_fx_xright
  116. sar eax,16
  117. cmp eax,_window_right
  118. jb eax_ok1
  119. mov eax,_window_right
  120. eax_ok1: cmp eax,_window_left
  121. ja eax_ok2
  122. mov eax,_window_left
  123. eax_ok2:
  124. mov ebx,_fx_xleft
  125. sar ebx,16
  126. sub eax,ebx
  127. js _none_to_do
  128. cmp eax,_window_width
  129. jbe _ok_to_do
  130. mov eax,_window_width
  131. _ok_to_do:
  132. mov _loop_count,eax
  133. ;-------------------------- setup for dithering -----------------------------
  134. ; lighting values are passed in fixed point, but need to be in 8 bit integer, 8 bit fraction so we can easily
  135. ; get the integer by reading %bh
  136. sar _fx_l, 8
  137. sar _fx_dl_dx,8
  138. jns dl_dx_ok
  139. inc _fx_dl_dx ; round towards 0 for negative deltas
  140. dl_dx_ok:
  141. ; set initial values
  142. mov ebx,_fx_u
  143. mov ebp,_fx_v
  144. mov ecx,_fx_z
  145. ; test _per2_flag,-1
  146. ; je tmap_loop
  147. ;cmp _Lighting_on, 0
  148. ;je tmap_loop_mul_nolight
  149. jmp tmap_loop_mul
  150. ;================ PERSPECTIVE TEXTURE MAP INNER LOOPS ========================
  151. ;
  152. ; Usage in loop: eax division, pixel value
  153. ; ebx u
  154. ; ecx z
  155. ; edx division
  156. ; ebp v
  157. ; esi source pixel pointer
  158. ; edi destination pixel pointer
  159. ;-------------------- NORMAL PERSPECTIVE TEXTURE MAP LOOP -----------------
  160. align 4
  161. tmap_loop:
  162. xchg ebx, esi
  163. ; compute v coordinate
  164. mov eax,ebp ; get v
  165. cdq
  166. idiv ecx ; eax = (v/z)
  167. and eax,3fh ; mask with height-1
  168. mov ebx,eax
  169. ; compute u coordinate
  170. mov eax,esi ; get u
  171. cdq
  172. idiv ecx ; eax = (u/z)
  173. shl eax,26
  174. shld ebx,eax,6 ; esi = v*64+u
  175. ; read 1 pixel
  176. movzx eax,byte ptr es:[ebx] ; get pixel from source bitmap
  177. cmp _Lighting_on, 0
  178. je NoLight1
  179. ; LIGHTING CODE
  180. mov ebx, _fx_l ; get temp copy of lighting value
  181. mov ah, bh ; get lighting level
  182. add ebx, _fx_dl_dx ; update lighting value
  183. mov al, _gr_fade_table[eax] ; xlat pixel thru lighting tables
  184. mov _fx_l, ebx ; save temp copy of lighting value
  185. ; transparency check
  186. NoLight1: cmp al,255
  187. je skip1
  188. mov [edi],al
  189. skip1: inc edi
  190. ; update deltas
  191. add ebp,_fx_dv_dx
  192. add esi,_fx_du_dx
  193. add ecx,_fx_dz_dx
  194. je _div_0_abort ; would be dividing by 0, so abort
  195. xchg esi, ebx
  196. dec _loop_count
  197. jns tmap_loop
  198. _none_to_do:
  199. popa
  200. pop es
  201. ret
  202. ; We detected a z=0 condition, which seems pretty bogus, don't you think?
  203. ; So, we abort, but maybe we want to know about it.
  204. _div_0_abort:
  205. ;** int 3
  206. jmp _none_to_do
  207. ;-------------------------- PER/4 TMAPPER ----------------
  208. ;
  209. ; x = x1
  210. ; U0 = u/w; V0 = v/w;
  211. ; while ( 1 )
  212. ; u += du_dx*4; v+= dv_dx*4
  213. ; U1 = u/w; V1 = v/w;
  214. ; DUDX = (U1-U0)/4; DVDX = (V1-V0)/4;
  215. ;
  216. ; ; Pixel 0
  217. ; pixels = texmap[V0*64+U0];
  218. ; U0 += DUDX; V0 += DVDX
  219. ; ; Pixel 1
  220. ; pixels = (pixels<<8)+texmap[V0*64+U0];
  221. ; U0 += DUDX; V0 += DVDX
  222. ; ; Pixel 2
  223. ; pixels = (pixels<<8)+texmap[V0*64+U0];
  224. ; U0 += DUDX; V0 += DVDX
  225. ; ; Pixel 3
  226. ; pixels = (pixels<<8)+texmap[V0*64+U0];
  227. ;
  228. ; screen[x] = pixel
  229. ; x += 4;
  230. ; U0 = U1; V0 = V1
  231. NBITS = 3
  232. ZSHIFT = 3
  233. DIVIDE_SIG_BITS = 12
  234. DIVIDE_SHIFT_BITS = (20-DIVIDE_SIG_BITS)
  235. DIVIDE_TABLE_SIZE = (1 SHL DIVIDE_SIG_BITS)
  236. PDIV_START MACRO
  237. push ecx
  238. shr ecx, DIVIDE_SHIFT_BITS
  239. and ecx, DIVIDE_TABLE_SIZE-1
  240. mov cx, word ptr _divide_table[ecx*2];
  241. ENDM
  242. PDIV_END MACRO
  243. pop ecx
  244. ENDM
  245. PDIV MACRO
  246. ; Returns EAX/ECX in 16.16 format in EAX. Trashes EDX
  247. ; sig bits 6.3
  248. ;--old-- cdq
  249. ;--old-- shld edx,eax, ZSHIFT
  250. ;--old-- lea eax, [eax*8]
  251. ;--old-- idiv ecx ; eax = (v/z)
  252. ;--old-- shl eax, 16-ZSHIFT
  253. ; mov edx,eax
  254. ; shl eax,ZSHIFT
  255. ; sar edx,32-ZSHIFT
  256. ; idiv ecx ; eax = (v/z)
  257. ; shl eax, 16-ZSHIFT
  258. mov edx,eax
  259. shl eax,ZSHIFT
  260. sar edx,32-ZSHIFT
  261. imul ecx ; eax = (v*z)
  262. shl edx, 16-ZSHIFT
  263. mov eax, edx
  264. ENDM
  265. wr_onepix macro num
  266. local skip
  267. cmp cl,255
  268. je skip
  269. mov num[edi],cl
  270. ror ecx,8
  271. skip:
  272. endm
  273. public tmap_loop_mul
  274. ; -------------------------------------- Start of Getting Dword Aligned ----------------------------------------------
  275. ; ebx fx_u
  276. tmap_loop_mul:
  277. mov esi,ebx
  278. align 4
  279. NotDwordAligned1:
  280. test edi, 11b
  281. jz DwordAligned1
  282. ; compute v coordinate
  283. mov eax,ebp ; get v
  284. cdq
  285. ; idiv ecx ; eax = (v/z)
  286. push ecx
  287. shr ecx, DIVIDE_SHIFT_BITS
  288. and ecx, DIVIDE_TABLE_SIZE-1
  289. mov cx, word ptr _divide_table[ecx*2];
  290. imul ecx
  291. mov eax, edx
  292. and eax,3fh ; mask with height-1
  293. mov ebx,eax
  294. ; compute u coordinate
  295. mov eax,esi ; get u
  296. cdq
  297. ; idiv ecx ; eax = (u/z)
  298. imul ecx
  299. mov eax, edx
  300. pop ecx
  301. shl eax,26
  302. shld ebx,eax,6 ; esi = v*64+u
  303. ; read 1 pixel
  304. movzx eax,byte ptr es:[ebx] ; get pixel from source bitmap
  305. ; lighting code
  306. mov ebx, _fx_l ; get temp copy of lighting value
  307. mov ah, bh ; get lighting level
  308. add ebx, _fx_dl_dx ; update lighting value
  309. mov _fx_l, ebx ; save temp copy of lighting value
  310. ; transparency check
  311. cmp al,255
  312. je skip2 ; this pixel is transparent, so don't write it (or light it)
  313. mov al, _gr_fade_table[eax] ; xlat pixel thru lighting tables
  314. ; write 1 pixel
  315. mov [edi],al
  316. skip2: inc edi
  317. ; update deltas
  318. add ebp,_fx_dv_dx
  319. add esi,_fx_du_dx
  320. add ecx,_fx_dz_dx
  321. je _div_0_abort ; would be dividing by 0, so abort
  322. dec _loop_count
  323. jns NotDwordAligned1
  324. jmp _none_to_do
  325. ; -------------------------------------- End of Getting Dword Aligned ----------------------------------------------
  326. DwordAligned1:
  327. mov ebx,esi ; get fx_u
  328. mov eax, _loop_count
  329. inc eax
  330. mov num_left_over, eax
  331. shr eax, NBITS
  332. cmp eax, 0
  333. je tmap_loop
  334. mov _loop_count, eax ; _loop_count = pixels / NPIXS
  335. shl eax, 3
  336. sub num_left_over, eax ; num_left_over = obvious
  337. ; compute initial v coordinate
  338. mov eax,ebp ; get v
  339. ; mov edx,ebp
  340. ; shl eax,ZSHIFT
  341. ; sar edx,32-ZSHIFT
  342. ; idiv ecx ; eax = (v/z)
  343. ; shl eax, 16-ZSHIFT
  344. PDIV_START
  345. PDIV
  346. mov V0, eax
  347. ; compute initial u coordinate
  348. mov eax,ebx ; get u
  349. ; mov edx,ebx
  350. ; shl eax,ZSHIFT
  351. ; sar edx,32-ZSHIFT
  352. ; idiv ecx ; eax = (v/z)
  353. ; shl eax, 16-ZSHIFT
  354. PDIV
  355. PDIV_END
  356. mov U0, eax
  357. ; Set deltas to NPIXS pixel increments
  358. mov eax, _fx_du_dx
  359. shl eax, 3
  360. mov DU1, eax
  361. mov eax, _fx_dv_dx
  362. shl eax, 3
  363. mov DV1, eax
  364. mov eax, _fx_dz_dx
  365. shl eax, 3
  366. mov DZ1, eax
  367. align 4
  368. TopOfLoop4:
  369. add ebx, DU1
  370. add ebp, DV1
  371. add ecx, DZ1
  372. je _div_0_abort ; would be dividing by 0, so abort
  373. ; Done with ebx, ebp, ecx until next iteration
  374. push ebx
  375. push ecx
  376. push ebp
  377. push edi
  378. ; Find fixed U1
  379. mov eax, ebx
  380. ; mov edx,ebx
  381. ; shl eax,ZSHIFT
  382. ; sar edx,32-ZSHIFT
  383. ; idiv ecx ; eax = (v/z)
  384. ; shl eax, 16-ZSHIFT
  385. PDIV_START
  386. PDIV
  387. mov ebx, eax ; ebx = U1 until pop's
  388. ; Find fixed V1
  389. mov eax, ebp
  390. ; mov edx, ebp
  391. ; shl eax,ZSHIFT
  392. ; sar edx,32-ZSHIFT
  393. ; idiv ecx ; eax = (v/z)
  394. ; shl eax, 16-ZSHIFT
  395. PDIV
  396. PDIV_END
  397. mov ecx, U0 ; ecx = U0 until pop's
  398. mov edi, V0 ; edi = V0 until pop's
  399. mov ebp, eax ; ebp = V1 until pop's
  400. ; Make ESI = V0:U0 in 6:10,6:10 format
  401. mov eax, ecx
  402. shr eax, 6
  403. mov esi, edi
  404. shl esi, 10
  405. mov si, ax
  406. ; Make EDX = DV:DU in 6:10,6:10 format
  407. mov eax, ebx
  408. sub eax, ecx
  409. sar eax, NBITS+6
  410. mov edx, ebp
  411. sub edx, edi
  412. shl edx, 10-NBITS ; EDX = V1-V0/ 4 in 6:10 int:frac
  413. mov dx, ax ; put delta u in low word
  414. ; Save the U1 and V1 so we don't have to divide on the next iteration
  415. mov U0, ebx
  416. mov V0, ebp
  417. pop edi ; Restore EDI before using it
  418. ; LIGHTING CODE
  419. mov ebx, _fx_l
  420. mov ebp, _fx_dl_dx
  421. test _transparency_on,-1
  422. je no_trans1
  423. REPT (1 SHL (NBITS-2))
  424. local skip3,no_trans1
  425. REPT 2
  426. local skipa1,skipa2
  427. mov eax, esi ; get u,v
  428. shr eax, 26 ; shift out all but int(v)
  429. shld ax,si,6 ; shift in u, shifting up v
  430. add esi, edx ; inc u,v
  431. mov al, es:[eax] ; get pixel from source bitmap
  432. cmp al,255
  433. je skipa1
  434. mov ah, bh ; form lighting table lookup value
  435. add ebx, ebp ; update lighting value
  436. mov al, _gr_fade_table[eax] ; xlat thru lighting table into dest buffer
  437. mov [edi],al
  438. skipa1:
  439. inc edi
  440. ; Do odd pixel
  441. mov eax, esi ; get u,v
  442. shr eax, 26 ; shift out all but int(v)
  443. shld ax,si,6 ; shift in u, shifting up v
  444. add esi, edx ; inc u,v
  445. mov al, es:[eax] ; get pixel from source bitmap
  446. cmp al,255
  447. je skipa2
  448. mov ah, bh ; form lighting table lookup value
  449. add ebx, ebp ; update lighting value
  450. mov al, _gr_fade_table[eax] ; xlat thru lighting table into dest buffer
  451. mov [edi],al
  452. skipa2:
  453. inc edi
  454. ENDM
  455. ENDM
  456. jmp cont1
  457. ; -------------------------------------------------------
  458. no_trans1:
  459. REPT (1 SHL (NBITS-2))
  460. local skip3
  461. REPT 2
  462. mov eax, esi ; get u,v
  463. shr eax, 26 ; shift out all but int(v)
  464. shld ax,si,6 ; shift in u, shifting up v
  465. add esi, edx ; inc u,v
  466. mov al, es:[eax] ; get pixel from source bitmap
  467. mov ah, bh ; form lighting table lookup value
  468. add ebx, ebp ; update lighting value
  469. mov cl, _gr_fade_table[eax] ; xlat thru lighting table into dest buffer
  470. ; Do odd pixel
  471. mov eax, esi ; get u,v
  472. shr eax, 26 ; shift out all but int(v)
  473. shld ax,si,6 ; shift in u, shifting up v
  474. add esi, edx ; inc u,v
  475. mov al, es:[eax] ; get pixel from source bitmap
  476. mov ah, bh ; form lighting table lookup value
  477. add ebx, ebp ; update lighting value
  478. mov ch, _gr_fade_table[eax] ; xlat thru lighting table into dest buffer
  479. ror ecx, 16 ; move to next double dest pixel position
  480. ENDM
  481. mov [edi],ecx ; Draw 4 pixels to display
  482. skip3: add edi,4
  483. ENDM
  484. cont1:
  485. ; -------------------------------------------------------
  486. ; LIGHTING CODE
  487. mov _fx_l, ebx
  488. pop ebp
  489. pop ecx
  490. pop ebx
  491. dec _loop_count
  492. jnz TopOfLoop4
  493. EndOfLoop4:
  494. cmp num_left_over, 0
  495. je _none_to_do
  496. ; ----------------------------------------- Start of LeftOver Pixels ------------------------------------------
  497. DoEndPixels:
  498. add ebx, DU1
  499. add ebp, DV1
  500. add ecx, DZ1
  501. je _div_0_abort
  502. push edi ; use edi as a temporary variable
  503. cmp ecx,10
  504. jg ecx_ok
  505. mov ecx,10
  506. ecx_ok:
  507. ; Find fixed U1
  508. mov eax, ebx
  509. PDIV_START
  510. PDIV
  511. mov ebx, eax ; ebx = U1 until pop's
  512. ; Find fixed V1
  513. mov eax, ebp
  514. PDIV
  515. PDIV_END
  516. mov ebp, eax ; ebp = V1 until pop's
  517. mov ecx, U0 ; ecx = U0 until pop's
  518. mov edi, V0 ; edi = V0 until pop's
  519. ; Make ESI = V0:U0 in 6:10,6:10 format
  520. mov eax, ecx
  521. shr eax, 6
  522. mov esi, edi
  523. shl esi, 10
  524. mov si, ax
  525. ; Make EDX = DV:DU in 6:10,6:10 format
  526. mov eax, ebx
  527. sub eax, ecx
  528. sar eax, NBITS+6
  529. mov edx, ebp
  530. sub edx, edi
  531. shl edx, 10-NBITS ; EDX = V1-V0/ 4 in 6:10 int:frac
  532. mov dx, ax ; put delta u in low word
  533. pop edi ; Restore EDI before using it
  534. mov ecx, num_left_over
  535. ; LIGHTING CODE
  536. mov ebx, _fx_l
  537. mov ebp, _fx_dl_dx
  538. ITERATION = 0
  539. REPT (1 SHL (NBITS-1))
  540. local skip4, skip5
  541. ; Do even pixel
  542. mov eax, esi ; get u,v
  543. shr eax, 26 ; shift out all but int(v)
  544. shld ax,si,6 ; shift in u, shifting up v
  545. mov al, es:[eax] ; get pixel from source bitmap
  546. add esi, edx ; inc u,v
  547. mov ah, bh ; form lighting table lookup value
  548. ;SAFETYand ah,0fh
  549. add ebx, ebp ; update lighting value
  550. cmp al,255
  551. je skip4
  552. mov al, _gr_fade_table[eax] ; xlat thru lighting table into dest buffer
  553. mov [edi+ITERATION], al ; write pixel
  554. skip4: dec ecx
  555. jz _none_to_do
  556. ITERATION = ITERATION + 1
  557. ; Do odd pixel
  558. mov eax, esi ; get u,v
  559. shr eax, 26 ; shift out all but int(v)
  560. shld ax,si,6 ; shift in u, shifting up v
  561. mov al, es:[eax] ; get pixel from source bitmap
  562. add esi, edx ; inc u,v
  563. mov ah, bh ; form lighting table lookup value
  564. add ebx, _fx_dl_dx ; update lighting value
  565. cmp al,255
  566. je skip5
  567. ;SAFETYand ah,0fh
  568. mov al, _gr_fade_table[eax] ; xlat thru lighting table into dest buffer
  569. mov [edi+ITERATION], al ; write pixel
  570. skip5: dec ecx
  571. jz _none_to_do
  572. ITERATION = ITERATION + 1
  573. ENDM
  574. ; ----------------------------------------- End of LeftOver Pixels ------------------------------------------
  575. ; Should never get here!!!!
  576. int 3
  577. jmp _none_to_do
  578. ; ==================================================== No Lighting Code ======================================================
  579. public tmap_loop_mul_nolight
  580. tmap_loop_mul_nolight:
  581. mov esi,ebx
  582. align 4
  583. NotDwordAligned1_nolight:
  584. test edi, 11b
  585. jz DwordAligned1_nolight
  586. ; compute v coordinate
  587. mov eax,ebp ; get v
  588. cdq
  589. idiv ecx ; eax = (v/z)
  590. and eax,3fh ; mask with height-1
  591. mov ebx,eax
  592. ; compute u coordinate
  593. mov eax,esi ; get u
  594. cdq
  595. idiv ecx ; eax = (u/z)
  596. shl eax,26
  597. shld ebx,eax,6 ; esi = v*64+u
  598. ; read 1 pixel
  599. mov al,es:[ebx] ; get pixel from source bitmap
  600. ; write 1 pixel
  601. cmp al,255
  602. je skip6
  603. mov [edi],al
  604. skip6: inc edi
  605. ; update deltas
  606. add ebp,_fx_dv_dx
  607. add esi,_fx_du_dx
  608. add ecx,_fx_dz_dx
  609. je _div_0_abort ; would be dividing by 0, so abort
  610. dec _loop_count
  611. jns NotDwordAligned1_nolight
  612. jmp _none_to_do
  613. DwordAligned1_nolight:
  614. mov ebx,esi
  615. mov eax, _loop_count
  616. inc eax
  617. mov num_left_over, eax
  618. shr eax, NBITS
  619. cmp eax, 0
  620. je tmap_loop
  621. mov _loop_count, eax ; _loop_count = pixels / NPIXS
  622. shl eax, NBITS
  623. sub num_left_over, eax ; num_left_over = obvious
  624. ; compute initial v coordinate
  625. mov eax,ebp ; get v
  626. PDIV_START
  627. PDIV
  628. mov V0, eax
  629. ; compute initial u coordinate
  630. mov eax,ebx ; get u
  631. PDIV
  632. PDIV_END
  633. mov U0, eax
  634. ; Set deltas to NPIXS pixel increments
  635. mov eax, _fx_du_dx
  636. shl eax, NBITS
  637. mov DU1, eax
  638. mov eax, _fx_dv_dx
  639. shl eax, NBITS
  640. mov DV1, eax
  641. mov eax, _fx_dz_dx
  642. shl eax, NBITS
  643. mov DZ1, eax
  644. align 4
  645. TopOfLoop4_nolight:
  646. add ebx, DU1
  647. add ebp, DV1
  648. add ecx, DZ1
  649. je _div_0_abort
  650. ; Done with ebx, ebp, ecx until next iteration
  651. push ebx
  652. push ecx
  653. push ebp
  654. push edi
  655. ; Find fixed U1
  656. mov eax, ebx
  657. PDIV_START
  658. PDIV
  659. mov ebx, eax ; ebx = U1 until pop's
  660. ; Find fixed V1
  661. mov eax, ebp
  662. PDIV
  663. PDIV_END
  664. mov ebp, eax ; ebp = V1 until pop's
  665. mov ecx, U0 ; ecx = U0 until pop's
  666. mov edi, V0 ; edi = V0 until pop's
  667. ; Make ESI = V0:U0 in 6:10,6:10 format
  668. mov eax, ecx
  669. shr eax, 6
  670. mov esi, edi
  671. shl esi, 10
  672. mov si, ax
  673. ; Make EDX = DV:DU in 6:10,6:10 format
  674. mov eax, ebx
  675. sub eax, ecx
  676. sar eax, NBITS+6
  677. mov edx, ebp
  678. sub edx, edi
  679. shl edx, 10-NBITS ; EDX = V1-V0/ 4 in 6:10 int:frac
  680. mov dx, ax ; put delta u in low word
  681. ; Save the U1 and V1 so we don't have to divide on the next iteration
  682. mov U0, ebx
  683. mov V0, ebp
  684. pop edi ; Restore EDI before using it
  685. REPT (1 SHL (NBITS-2))
  686. local skip7, no_trans2
  687. REPT 4
  688. ; Do 1 pixel
  689. mov eax, esi ; get u,v
  690. shr eax, 26 ; shift out all but int(v)
  691. shld ax,si,6 ; shift in u, shifting up v
  692. mov cl, es:[eax] ; load into buffer register
  693. add esi, edx ; inc u,v
  694. ror ecx, 8 ; move to next dest pixel
  695. ENDM
  696. test _transparency_on,-1
  697. je no_trans2
  698. cmp ecx,-1
  699. je skip7
  700. wr_onepix 0
  701. wr_onepix 1
  702. wr_onepix 2
  703. wr_onepix 3
  704. jmp skip7
  705. no_trans2:
  706. mov [edi],ecx ; Draw 4 pixels to display
  707. skip7: add edi,4
  708. ENDM
  709. pop ebp
  710. pop ecx
  711. pop ebx
  712. dec _loop_count
  713. jnz TopOfLoop4_nolight
  714. EndOfLoop4_nolight:
  715. cmp num_left_over, 0
  716. je _none_to_do
  717. DoEndPixels_nolight:
  718. add ebx, DU1
  719. add ebp, DV1
  720. add ecx, DZ1
  721. je _div_0_abort
  722. push edi ; use edi as a temporary variable
  723. ; Find fixed U1
  724. mov eax, ebx
  725. PDIV_START
  726. PDIV
  727. mov ebx, eax ; ebx = U1 until pop's
  728. ; Find fixed V1
  729. mov eax, ebp
  730. PDIV
  731. PDIV_END
  732. mov ebp, eax ; ebp = V1 until pop's
  733. mov ecx, U0 ; ecx = U0 until pop's
  734. mov edi, V0 ; edi = V0 until pop's
  735. ; Make ESI = V0:U0 in 6:10,6:10 format
  736. mov eax, ecx
  737. shr eax, 6
  738. mov esi, edi
  739. shl esi, 10
  740. mov si, ax
  741. ; Make EDX = DV:DU in 6:10,6:10 format
  742. mov eax, ebx
  743. sub eax, ecx
  744. sar eax, NBITS+6
  745. mov edx, ebp
  746. sub edx, edi
  747. shl edx, 10-NBITS ; EDX = V1-V0/ 4 in 6:10 int:frac
  748. mov dx, ax ; put delta u in low word
  749. pop edi ; Restore EDI before using it
  750. mov ecx, num_left_over
  751. ITERATION = 0
  752. REPT (1 SHL NBITS)
  753. local skip8
  754. ; Do 1 pixel
  755. mov eax, esi ; get u,v
  756. shr eax, 26 ; shift out all but int(v)
  757. shld ax,si,6 ; shift in u, shifting up v
  758. mov al, es:[eax] ; load into buffer register
  759. add esi, edx ; inc u,v
  760. cmp al,255
  761. je skip8
  762. mov [edi+ITERATION], al ; write pixel
  763. skip8: dec ecx
  764. jz _none_to_do
  765. ITERATION = ITERATION + 1
  766. ENDM
  767. ; Should never get here!!!!!
  768. int 3
  769. jmp _none_to_do
  770. _TEXT ends
  771. end