This commit was manufactured by cvs2svn to create tag 'd2x-0_1_2'.
[btb/d2x.git] / 2d / tmerge_a.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 [BITS 32]
13
14 section .data
15
16 row_count dd     0
17
18 section .text
19
20 ; C-calling:
21 ; void gr_merge_textures( ubyte * lower, ubyte * upper, ubyte * dest )
22
23 global  _gr_merge_textures, _gr_merge_textures_1, _gr_merge_textures_2, _gr_merge_textures_3
24 global gr_merge_textures, gr_merge_textures_1, gr_merge_textures_2, gr_merge_textures_3
25
26 ; case 1:
27 ;    // 
28 ;    for (y=0; y<64; y++ )
29 ;       for (x=0; x<64; x++ )   {
30 ;          c = top_data[ 64*x+(63-y) ];      
31 ;          if (c==255)
32 ;             c = bottom_data[ 64*y+x ];
33 ;          *dest_data++ = c;
34 ;       }
35 ;    break;
36 ; case 2:
37 ;    // Normal
38 ;    for (y=0; y<64; y++ )
39 ;       for (x=0; x<64; x++ )   {
40 ;          c = top_data[ 64*(63-y)+(63-x) ];
41 ;          if (c==255)
42 ;             c = bottom_data[ 64*y+x ];
43 ;          *dest_data++ = c;
44 ;       }
45 ;    break;
46 ; case 3:
47 ;    // Normal
48 ;    for (y=0; y<64; y++ )
49 ;       for (x=0; x<64; x++ )   {
50 ;          c = top_data[ 64*(63-x)+y  ];
51 ;          if (c==255)
52 ;             c = bottom_data[ 64*y+x ];
53 ;          *dest_data++ = c;
54 ;       }
55 ;    break;
56 _gr_merge_textures:
57 gr_merge_textures:
58
59         ; EAX = lower data
60         ; EDX = upper data
61         ; EBX = dest data
62
63         push    ebx
64         push    esi
65         push    edi
66         push    ebp
67
68         mov     eax, [esp+20]
69         mov     edx, [esp+24]
70         mov     ebx, [esp+28]
71
72         mov     ebp, edx
73         mov     edi, ebx
74         mov     bl, 255
75         mov     bh, bl
76         and     ebx, 0ffffh
77         and     edx, 0ffffh
78         mov     esi, eax
79         mov     ecx, (64*64)/2
80
81         jmp     gmt1
82
83 second_must_be_not_trans:
84         mov     ah, dh
85         mov     [edi],ax
86         add     edi,2
87         dec     ecx
88         je      donegmt
89
90 gmt1:   mov     dx, [ebp]
91         add     ebp, 2
92         cmp     edx, ebx
93         jne     not_transparent
94
95 ; both transparent
96         movsw
97         dec     ecx
98         jne     gmt1
99         jmp     donegmt
100
101 ; DH OR DL ARE INVISIBLE
102 not_transparent:
103         mov     ax,[esi]
104         add     esi,2
105                 
106         cmp     dl, bl
107         je      second_must_be_not_trans
108         mov     al, dl
109         cmp     dh, bh
110         je      @@1
111         mov     ah, dh
112 @@1:    mov     [edi],ax
113         add     edi,2
114         dec     ecx
115         jne     gmt1
116
117 donegmt:
118
119         pop     ebp
120         pop     edi
121         pop     esi
122         pop     ebx
123         ret
124
125 ; -----------------------------------------------------------------------------------------
126 ; case 1, normal in x, flip in y
127 _gr_merge_textures_1:
128 gr_merge_textures_1:
129
130 ; eax = background data
131 ; edx = foreground data
132 ; ebx = destination address
133
134         push    ebp
135         push    edi
136         push    esi
137         push    ebx
138
139         mov     eax, [esp+20]
140         mov     edx, [esp+24]
141         mov     ebx, [esp+28]
142
143         mov     ch, 255 ; transparent color, stick in a register, is this faster?
144
145         mov     esi, 63 ; esi will be the offset to the current pixel
146         mov     [row_count], esi
147
148         mov     ebp, 64 ; do for 64 pixels
149
150         align   4
151 gmt1_1: mov     cl, [edx + esi] ; get foreground pixel
152         add     esi, 64 ; point at next row
153         cmp     cl, ch  ; see if transparent
154         jne     not_transparent_1       ; dl contains a solid color, just write it
155
156         mov     cl,[eax]        ; get background pixel
157
158 not_transparent_1:      mov     [ebx], cl       ; write pixel
159         inc     ebx     ; point at next destination address
160         inc     eax
161
162         dec     ebp     ; see if done a whole row
163         jne     gmt1_1  ; no, so do next pixel
164
165         mov     ebp, 64 ; do for 64 pixels
166
167         dec     dword [row_count] ; advance to next row
168         mov     esi, [row_count]  ; doing next row, get offset, DANGER: DOESN'T SET FLAGS, BEWARE ON 68000, POWERPC!!
169         jns     gmt1_1  ; no (going down to 0)
170
171         pop     ebx
172         pop     esi
173         pop     edi
174         pop     ebp
175         ret
176
177 ; -----------------------------------------------------------------------------------------
178 ; case 1, normal in x, flip in y
179 _gr_merge_textures_2:
180 gr_merge_textures_2:
181
182 ; eax = background data
183 ; edx = foreground data
184 ; ebx = destination address
185
186         push    ebp
187         push    edi
188         push    esi
189         push    ebx
190
191         mov     eax, [esp+20]
192         mov     edx, [esp+24]
193         mov     ebx, [esp+28]
194
195         mov     ch, 255 ; transparent color, stick in a register, is this faster?
196
197         mov     esi, 63 + 64*63 ; esi will be the offset to the current pixel
198
199         align   4
200 gmt1_2: mov     cl, [edx + esi] ; get foreground pixel
201         cmp     cl, ch  ; see if transparent
202         jne     not_transparent_2       ; dl contains a solid color, just write it
203
204         mov     cl,[eax]        ; get background pixel
205
206 not_transparent_2:      mov     [ebx], cl       ; write pixel
207         inc     ebx     ; point at next destination address
208         inc     eax
209
210         dec     esi     ; advance to next row
211         jns     gmt1_2  ; no (going down to 0)
212
213         pop     ebx
214         pop     esi
215         pop     edi
216         pop     ebp
217         ret
218
219 ; -----------------------------------------------------------------------------------------
220 ; case 1, normal in x, flip in y
221 _gr_merge_textures_3:
222 gr_merge_textures_3:
223
224 ; eax = background data
225 ; edx = foreground data
226 ; ebx = destination address
227
228         push    ebp
229         push    edi
230         push    esi
231         push    ebx
232
233         mov     eax, [esp+20]
234         mov     edx, [esp+24]
235         mov     ebx, [esp+28]
236
237         mov     ch, 255 ; transparent color, stick in a register, is this faster?
238
239         mov     esi, 64*63      ; esi will be the offset to the current pixel
240         mov     dword [row_count], 64
241
242         mov     ebp, 32 ; do for 64 pixels (2x loop)
243
244 ; first copy of loop
245         align   4
246 gmt1_3: mov     cl, [edx + esi] ; get foreground pixel
247         sub     esi, 64 ; point at next row
248         cmp     cl, ch  ; see if transparent
249         jne     not_transparent_3       ; dl contains a solid color, just write it
250
251         mov     cl,[eax]        ; get background pixel
252
253 not_transparent_3:      inc     eax
254         mov     [ebx], cl       ; write pixel
255         inc     ebx     ; point at next destination address
256
257 ; second copy of loop
258         mov     cl, [edx + esi] ; get foreground pixel
259         sub     esi, 64 ; point at next row
260         cmp     cl, ch  ; see if transparent
261         jne     nt_3a   ; dl contains a solid color, just write it
262
263         mov     cl,[eax]        ; get background pixel
264
265 nt_3a:  inc     eax
266         mov     [ebx], cl       ; write pixel
267         inc     ebx     ; point at next destination address
268
269         dec     ebp     ; see if done a whole row
270         jne     gmt1_3  ; no, so do next pixel
271
272         mov     ebp, 32 ; do for 64 pixels
273
274         add     esi, 64*64+1    ; doing next row, get offset, DANGER: DOESN'T SET FLAGS, BEWARE ON 68000, POWERPC!!
275
276         dec     dword [row_count] ; advance to next row
277         jne     gmt1_3  ; no (going down to 0)
278
279         pop     ebx
280         pop     esi
281         pop     edi
282         pop     ebp
283         ret