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