]> icculus.org git repositories - btb/d2x.git/blob - texmap/tmap_ll.asm
remove rcs tags
[btb/d2x.git] / texmap / tmap_ll.asm
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 ;
13 ; Linear, lighted texture mapper inner loop.
14 ;
15 ;
16
17 [BITS 32]
18
19 global  _asm_tmap_scanline_lin_lighted
20 global  asm_tmap_scanline_lin_lighted
21
22 [SECTION .data]
23
24 %include        "tmap_inc.asm"
25
26 ALLOW_DITHERING equ     1
27
28 _fx_dl_dx1      dd 0
29 _fx_dl_dx2      dd 0
30
31 _loop_count     dd 0
32
33
34 [SECTION .text]
35
36 ; --------------------------------------------------------------------------------------------------
37 ; Enter:
38 ;       _xleft  fixed point left x coordinate
39 ;       _xright fixed point right x coordinate
40 ;       _y      fixed point y coordinate
41 ;       _pixptr address of source pixel map
42 ;       _u      fixed point initial u coordinate
43 ;       _v      fixed point initial v coordinate
44 ;       _du_dx  fixed point du/dx
45 ;       _dv_dx  fixed point dv/dx
46
47 ;   for (x = (int) xleft; x <= (int) xright; x++) {
48 ;      _setcolor(read_pixel_from_tmap(srcb,((int) (u/z)) & 63,((int) (v/z)) & 63));
49 ;      _setpixel(x,y);
50 ;
51 ;      u += du_dx;
52 ;      v += dv_dx;
53 ;      z += dz_dx;
54 ;   }
55
56         align   4
57 _asm_tmap_scanline_lin_lighted:
58 asm_tmap_scanline_lin_lighted:
59 ;        push    es  ; DPH: No selectors in windows :-(
60 ;        push    fs
61         pusha
62
63 ;        mov     es,[_pixel_data_selector]       ; selector[0*2] ; DPH: No... :-)
64 ;        mov     fs,[_gr_fade_table_selector]    ; selector[1*2] ; fs = bmd_fade_table
65
66 ; Setup for loop:       _loop_count  iterations = (int) xright - (int) xleft
67 ;   esi source pixel pointer = pixptr
68 ;   edi initial row pointer = y*320+x
69
70 ; set esi = pointer to start of texture map data
71         mov     esi,[_pixptr]
72
73 ; set edi = address of first pixel to modify
74         mov     edi,[_fx_y]     ; this is actually an int
75         cmp     edi,[_window_bottom]
76         ja      near all_done
77
78         imul    edi,[_bytes_per_row]
79         mov     ebx,[_fx_xleft]
80         test    ebx,ebx
81         jns     ebx_ok
82         sub     ebx,ebx
83 ebx_ok:
84         add     edi,ebx
85         add     edi,[_write_buffer]
86
87 ; set _loop_count = # of iterations
88         mov     eax,[_fx_xright]
89         cmp     eax,[_window_right]
90         jl      eax_ok1
91         mov     eax,[_window_right]
92 eax_ok1:        cmp     eax,[_window_left]
93         jg      eax_ok2
94         mov     eax,[_window_left]
95 eax_ok2:
96
97         sub     eax,ebx
98         js      near all_done
99         cmp     eax,[_window_width]
100         jbe     _ok_to_do
101         mov     eax,[_window_width]
102 _ok_to_do:
103         mov     [_loop_count],eax
104
105 ;       edi     destination pixel pointer
106
107
108         mov     ecx,_gr_fade_table  ;originally offset _lighting_tables
109         mov     eax,[_fx_u]     ; get 32 bit u coordinate
110         shr     eax,6   ; get 6:10 int:frac u coordinate into low word
111         mov     ebp,[_fx_v]     ; get 32 bit v coordinate
112         shl     ebp,10  ; put 6:10 int:frac into high word
113         mov     bp,ax   ; put u coordinate in low word
114
115         mov     eax,[_fx_du_dx] ; get 32 bit delta u
116         shr     eax,6   ; get 6:10 int:frac delta u into low word
117         mov     edx,[_fx_dv_dx] ; get 32 bit delta v
118         shl     edx,10  ; put 6:10 int:frac into high word
119         mov     dx,ax   ; put delta u in low word
120
121         sar     dword [_fx_dl_dx],8
122         jns     dl_dx_ok
123         inc     dword [_fx_dl_dx]       ; round towards 0 for negative deltas
124 dl_dx_ok:
125
126 %if ALLOW_DITHERING
127 ; do dithering, use lighting values which are .5 less than and .5 more than actual value
128         mov     ebx,80h ; assume dithering on
129         test    dword [_dither_intensity_lighting],-1
130         jne     do_dither
131         sub     ebx,ebx ; no dithering
132 do_dither:
133         mov     eax,[_fx_dl_dx]
134         add     eax,ebx ; add 1/2
135         mov     [_fx_dl_dx1],eax
136         sub     eax,ebx
137         sub     eax,ebx
138         mov     [_fx_dl_dx2],eax
139         mov     ebx,[_fx_xleft]
140         xor     ebx,[_fx_y]
141         and     ebx,1
142         jne     dith_1
143         xchg    eax,[_fx_dl_dx1]
144 dith_1: mov     [_fx_dl_dx2],eax
145 %endif
146
147         mov     ebx,[_fx_l]
148
149 ; lighting values are passed in fixed point, but need to be in 8 bit integer, 8 bit fraction so we can easily
150 ; get the integer by reading %bh
151         sar     ebx,8
152
153         test    dword [_Transparency_on],-1
154         jne     do_transparency_ll
155
156 ;; esi, ecx should be free
157 loop_test equ 1 ; set to 1 to run as loop for better profiling
158 %if loop_test
159         mov     esi,[_fx_dl_dx]
160
161         mov     ecx,[_loop_count]
162         inc     ecx
163         shr     ecx,1
164         je      one_more_pix
165         pushf
166
167         align   4
168
169 loop1:
170         mov     eax,ebp ; get u, v
171         shr     eax,26  ; shift out all but int(v)
172         shld    ax,bp,6 ; shift in u, shifting up v
173
174         add     ebp,edx ; u += du, v += dv
175
176         add eax,[_pixptr] ; DPH: No selectors in windows
177         movzx   eax,byte [eax]     ; get pixel from source bitmap
178         mov     ah,bh   ; get lighting table
179         add     ebx,esi ; _fx_dl_dx     ; update lighting value
180         mov     al,[_gr_fade_table + eax]     ; xlat pixel through lighting tables
181         mov     [edi],al        ; write pixel...
182         inc     edi     ; ...and advance
183
184 ; --- ---
185
186         mov     eax,ebp ; get u, v
187         shr     eax,26  ; shift out all but int(v)
188         shld    ax,bp,6 ; shift in u, shifting up v
189
190         add     ebp,edx ; u += du, v += dv
191
192         add eax,[_pixptr] ; DPH:
193         movzx   eax,byte [eax]     ; get pixel from source bitmap
194         mov     ah,bh   ; get lighting table
195         add     ebx,esi ; _fx_dl_dx     ; update lighting value
196         mov     al,[_gr_fade_table + eax]     ; xlat pixel through lighting tables
197         mov     [edi],al        ; write pixel...
198         inc     edi     ; ...and advance
199
200         dec     ecx     ; _loop_count
201         jne     loop1
202
203         popf
204         jnc     all_done
205
206 one_more_pix:   mov     eax,ebp ; get u, v
207         shr     eax,26  ; shift out all but int(v)
208         shld    ax,bp,6 ; shift in u, shifting up v
209
210         add eax,[_pixptr] ; DPH:
211         movzx   eax,byte [eax]     ; get pixel from source bitmap
212         mov     ah,bh   ; get lighting table
213         mov     al,[_gr_fade_table + eax]     ; xlat pixel through lighting tables
214         mov     [edi],al        ; write pixel...
215
216 all_done:       popa
217 ;        pop     fs
218 ;        pop     es
219         ret
220
221
222 %else
223
224 ; usage:
225 ;       eax     work
226 ;       ebx     lighting value
227 ;       ecx     _lighting_tables
228 ;       edx     du, dv 6:10:6:10
229 ;       ebp     u, v coordinates 6:10:6:10
230 ;       esi     pointer to source bitmap
231 ;       edi     write address
232
233 ;_size = (_end1 - _start1)/num_iters
234 ;  note: if eax is odd, you will not be writing the last pixel, you must clean up at the end
235 %if ALLOW_DITHERING
236     mov eax,[_loop_count]
237     shr eax,1
238     neg eax
239     add eax,num_iters
240 %else
241         mov     eax,num_iters
242         sub     eax,[_loop_count]
243
244 %endif
245         imul    eax,eax,(_end1 - _start1)/num_iters
246         add     eax,_start1     ;originally offset _start1
247         jmp     eax
248
249         align   4
250 _start1:
251
252 ; usage:
253 ;       eax     work
254 ;       ebx     lighting value
255 ;       ecx     _lighting_tables
256 ;       edx     du, dv 6:10:6:10
257 ;       ebp     u, v coordinates 6:10:6:10
258 ;       esi     pointer to source bitmap
259 ;       edi     write address
260
261 ; do all but the last pixel in the unwound loop, last pixel done separately because less work is needed
262 %rep num_iters
263 %if 1
264
265 ;**; inner loop if lighting value is constant
266 ;**; can be optimized if source bitmap pixels are stored as words, then the mov ah,bh is not necessary
267 ;**     mov     eax,ebp ; get u, v
268 ;**     shr     eax,26  ; shift out all but int(v)
269 ;**     shld    ax,bp,6 ; shift in u, shifting up v
270 ;**
271 ;**     add     ebp,edx ; u += du, v += dv
272 ;**
273 ;**     mov     al,[esi+eax]    ; get pixel from source bitmap
274 ;**     mov     ah,bh   ; get lighting table
275 ;**     mov     al,[ecx+eax]    ; xlat pixel through lighting tables
276 ;**     mov     [edi],al        ; write pixel...
277 ;**     inc     edi     ; ...and advance
278
279
280 %if ALLOW_DITHERING
281
282 ; dithering
283 ; loop contains two iterations which must be the same length
284         mov     eax,ebp ; get u, v
285         shr     eax,26  ; shift out all but int(v)
286         shld    ax,bp,6 ; shift in u, shifting up v
287
288         add     ebp,edx ; u += du, v += dv
289
290         mov     al,[esi+eax]    ; get pixel from source bitmap
291         mov     ah,bh   ; get lighting table
292         add     ebx,[_fx_dl_dx1]        ; update lighting value
293         mov     al,[ecx+eax]    ; xlat pixel through lighting tables
294         mov     [edi],al        ; write pixel...
295         inc     edi     ; ...and advance
296
297 ; second iteration
298         mov     eax,ebp ; get u, v
299         shr     eax,26  ; shift out all but int(v)
300         shld    ax,bp,6 ; shift in u, shifting up v
301
302         add     ebp,edx ; u += du, v += dv
303
304         mov     al,[esi+eax]    ; get pixel from source bitmap
305         mov     ah,bh   ; get lighting table
306         add     ebx,[_fx_dl_dx2]        ; update lighting value
307         mov     al,[ecx+eax]    ; xlat pixel through lighting tables
308         mov     [edi],al        ; write pixel...
309         inc     edi     ; ...and advance
310 %else
311         mov     eax,ebp ; get u, v
312         shr     eax,26  ; shift out all but int(v)
313         shld    ax,bp,6 ; shift in u, shifting up v
314
315         add     ebp,edx ; u += du, v += dv
316
317         mov     al,[esi+eax]    ; get pixel from source bitmap
318         mov     ah,bh   ; get lighting table
319         add     ebx,[_fx_dl_dx] ; update lighting value
320         mov     al,[ecx+eax]    ; xlat pixel through lighting tables
321         mov     [edi],al        ; write pixel...
322         inc     edi     ; ...and advance
323 %endif
324
325
326 %else
327
328 ;obsolete: ; version which assumes segment overrides are in place (which they are obviously not)
329 ;obsolete:      mov     eax,ebp ; get u, v
330 ;obsolete:      shr     eax,26  ; shift out all but int(v)
331 ;obsolete:      shld    ax,bp,6 ; shift in u, shifting up v
332 ;obsolete:
333 ;obsolete:      add     ebp,edx ; u += du, v += dv
334 ;obsolete:
335 ;obsolete:      mov     al,[eax]        ; get pixel from source bitmap
336 ;obsolete:      mov     ah,bh   ; get lighting table
337 ;obsolete:      add     ebx,esi ; update lighting value
338 ;obsolete:      mov     al,[eax]        ; xlat pixel through lighting tables
339 ;obsolete:      mov     [edi],al        ; write pixel...
340 ;obsolete:      inc     edi     ; ...and advance
341 %endif
342 %endrep
343
344 _end1:
345
346 ; now do the leftover pixel
347         mov     eax,ebp
348         shr     eax,26  ; shift in v coordinate
349         shld    ax,bp,6 ; shift in u coordinate while shifting up v coordinate
350         mov     al,[esi+eax]    ; get pixel from source bitmap
351         mov     ah,bh   ; get lighting table
352  or ah,ah
353  jns ok1
354  sub ah,ah
355 ok1:
356         mov     al,[_gr_fade_table+eax] ; xlat pixel through lighting tables
357         mov     [edi],al        ; write pixel...
358
359 _none_to_do:    popa
360 ;        pop     fs
361 ;        pop     es
362         ret
363
364 %endif
365 ; -- Code to get rgb 5 bits integer, 5 bits fraction value into 5 bits integer (for each gun)
366 ; suitable for inverse color lookup
367 ;**__test:
368 ;** int 3
369 ;**;                  rrrrrfffffrrrrrfffffxxbbbbbfffff
370 ;**     mov     eax,11111001001010101110101101110111b
371 ;**     and     eax,11111000001111100000001111100000b
372 ;**     shld    ebx,eax,15
373 ;**     or      bx,ax
374
375
376 ;; esi, ecx should be free
377 do_transparency_ll:
378         mov     esi,[_fx_dl_dx]
379
380         mov     ecx,[_loop_count]
381         inc     ecx
382         shr     ecx,1
383         je      one_more_pix2
384         pushf
385
386         align   4
387
388 loop1a:
389         mov     eax,ebp ; get u, v
390         shr     eax,26  ; shift out all but int(v)
391         shld    ax,bp,6 ; shift in u, shifting up v
392
393         add     ebp,edx ; u += du, v += dv
394
395         add eax,[_pixptr] ; DPH:
396         movzx   eax,byte [eax]     ; get pixel from source bitmap
397         cmp     al,255
398         je      skip1a
399         mov     ah,bh   ; get lighting table
400         add     ebx,esi ; _fx_dl_dx     ; update lighting value
401         mov     al,[_gr_fade_table + eax]     ; xlat pixel through lighting tables
402         mov     [edi],al        ; write pixel...
403 skip1a: inc     edi     ; ...and advance
404
405 ; --- ---
406
407         mov     eax,ebp ; get u, v
408         shr     eax,26  ; shift out all but int(v)
409         shld    ax,bp,6 ; shift in u, shifting up v
410
411         add     ebp,edx ; u += du, v += dv
412
413         add eax,[_pixptr] ; DPH:
414         movzx   eax,byte [eax]     ; get pixel from source bitmap
415         cmp     al,255
416         je      skip2a
417         mov     ah,bh   ; get lighting table
418         add     ebx,esi ; _fx_dl_dx     ; update lighting value
419         mov     al,[_gr_fade_table + eax]     ; xlat pixel through lighting tables
420         mov     [edi],al        ; write pixel...
421 skip2a: inc     edi     ; ...and advance
422
423         dec     ecx     ; _loop_count
424         jne     loop1a
425
426         popf
427         jnc     all_done_1
428
429 one_more_pix2:  mov     eax,ebp ; get u, v
430         shr     eax,26  ; shift out all but int(v)
431         shld    ax,bp,6 ; shift in u, shifting up v
432
433         add eax,[_pixptr] ; DPH:
434         movzx   eax,byte [eax]     ; get pixel from source bitmap
435         cmp     al,255
436         je      skip3a
437         mov     ah,bh   ; get lighting table
438         mov     al,[_gr_fade_table + eax]     ; xlat pixel through lighting tables
439         mov     [edi],al        ; write pixel...
440
441 skip3a:
442 all_done_1:     popa
443 ;        pop     fs ; DPH:
444 ;        pop     es
445         ret
446