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