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