Got rid of all compiler warnings, for non-OpenGL on linux, anyway...
[btb/d2x.git] / 2d / linear.h
1 #ifndef _LINEAR_H
2 #define _LINEAR_H
3
4 #ifndef NO_ASM
5 #ifdef __WATCOMC__
6 extern unsigned int gr_var_color;
7 extern unsigned int gr_var_bwidth;
8 extern unsigned char * gr_var_bitmap;
9
10 void gr_linear_stosd( void * source, unsigned char color, unsigned int nbytes);
11 void gr_linear_line( int x0, int y0, int x1, int y1);
12 void gr_update_buffer( void * sbuf1, void * sbuf2, void * dbuf, int size );
13
14 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
15 void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels );
16 #pragma aux gr_linear_movsd parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
17 " cld "                 \
18 " mov       ebx, ecx    "   \
19 " mov       eax, edi"   \
20 " and       eax, 011b"  \
21 " jz        d_aligned"  \
22 " mov       ecx, 4"     \
23 " sub       ecx, eax"   \
24 " sub       ebx, ecx"   \
25 " rep       movsb"      \
26 " d_aligned: "          \
27 " mov       ecx, ebx"   \
28 " shr       ecx, 2"     \
29 " rep   movsd"      \
30 " mov       ecx, ebx"   \
31 " and   ecx, 11b"   \
32 " rep   movsb";
33
34 void gr_linear_rep_movsdm(void * src, void * dest, unsigned int num_pixels );
35 #pragma aux gr_linear_rep_movsdm parm [esi] [edi] [ecx] modify exact [ecx esi edi eax] = \
36 "nextpixel:"                    \
37     "mov    al,[esi]"           \
38     "inc    esi"                    \
39     "cmp    al, 255"                \
40     "je skip_it"                \
41     "mov    [edi], al"          \
42 "skip_it:"                      \
43     "inc    edi"                    \
44     "dec    ecx"                    \
45     "jne    nextpixel";
46
47 void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value );
48 #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] = \
49 "  xor eax, eax"    \
50 "  mov ah, bl"  \
51 "nextpixel:"                    \
52     "mov    al,[esi]"           \
53     "inc    esi"                    \
54     "cmp    al, 255"                \
55     "je skip_it"                \
56     "movb  al, gr_fade_table[eax]"   \
57     "movb  [edi], al"          \
58 "skip_it:"                      \
59     "inc    edi"                    \
60     "dec    ecx"                    \
61     "jne    nextpixel";
62
63
64 void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, int num_dest_pixels );
65 #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] = \
66     "shr    ecx, 1"             \
67     "jnc    nextpixel"          \
68     "mov    al, [esi]"          \
69     "mov    [edi], al"          \
70     "inc    esi"                    \
71     "inc    edi"                    \
72     "cmp    ecx, 0"             \
73     "je done"                   \
74 "nextpixel:"                    \
75     "mov    al,[esi]"           \
76     "mov    ah, al"             \
77     "mov    [edi], ax"          \
78     "inc    esi"                    \
79     "inc    edi"                    \
80     "inc    edi"                    \
81     "dec    ecx"                    \
82     "jne    nextpixel"          \
83 "done:"
84
85
86
87 void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
88 #pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
89 "nextpixel:"                            \
90     "mov    al,[esi]"           \
91     "add    esi, ebx"   \
92     "mov    [edi], al"  \
93     "add    edi, edx"   \
94     "dec    ecx"            \
95     "jne    nextpixel"  
96
97 void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize );
98 #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = \
99 "nextpixel:"                            \
100     "mov    al,[esi]"           \
101     "add    esi, ebx"   \
102     "cmp    al, 255"        \
103     "je skip_itx"       \
104     "mov    [edi], al"  \
105 "skip_itx:"             \
106     "add    edi, edx"   \
107     "dec    ecx"            \
108     "jne    nextpixel"  
109
110 void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels );
111 #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
112 "       mov ebx, ecx                "   \
113 "       and ebx, 11b                "   \
114 "       shr ecx, 2              "   \
115 "       cmp ecx, 0              "   \
116 "       je      no2group                "   \
117 "next4pixels:                       "   \
118 "       mov al, [esi+8]         "   \
119 "       mov ah, [esi+12]        "   \
120 "       shl eax, 16             "   \
121 "       mov al, [esi]           "   \
122 "       mov ah, [esi+4]         "   \
123 "       mov [edi], eax          "   \
124 "       add esi, 16             "   \
125 "       add edi, 4              "   \
126 "       dec ecx                 "   \
127 "       jne next4pixels         "   \
128 "no2group:                          "   \
129 "       cmp ebx, 0              "   \
130 "       je      done2                   "   \
131 "finishend:                         "   \
132 "       mov al, [esi]           "   \
133 "       add esi, 4              "   \
134 "       mov [edi], al           "   \
135 "       inc edi                 "   \
136 "       dec ebx                 "   \
137 "       jne finishend           "   \
138 "done2:                             ";
139
140 void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels );
141 #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = \
142 "       mov ebx, ecx                "   \
143 "       and ebx, 11b                "   \
144 "       shr ecx, 2              "   \
145 "       cmp ecx, 0              "   \
146 "       je      no2group                "   \
147 "next4pixels:                       "   \
148 "       mov al, [esi+4]         "   \
149 "       mov ah, [esi+6]         "   \
150 "       shl eax, 16             "   \
151 "       mov al, [esi]           "   \
152 "       mov ah, [esi+2]         "   \
153 "       mov [edi], eax          "   \
154 "       add esi, 8              "   \
155 "       add edi, 4              "   \
156 "       dec ecx                 "   \
157 "       jne next4pixels         "   \
158 "no2group:                          "   \
159 "       cmp ebx, 0              "   \
160 "       je      done2                   "   \
161 "finishend:                         "   \
162 "       mov al, [esi]           "   \
163 "       add esi, 2              "   \
164 "       mov [edi], al           "   \
165 "       inc edi                 "   \
166 "       dec ebx                 "   \
167 "       jne finishend           "   \
168 "done2:                             ";
169
170 #elif defined __GNUC__
171 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
172 inline void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels ) {
173         int dummy[3];
174  __asm__ __volatile__ (
175 " cld;"
176 " movl      %%ecx, %%ebx;"
177 " movl      %%edi, %%eax;"
178 " andl      $3, %%eax;"
179 " jz        0f;"
180 " movl      $4, %%ecx;"
181 " subl      %%eax,%%ecx;"
182 " subl      %%ecx,%%ebx;"
183 " rep;      movsb;"
184 "0: ;"
185 " movl      %%ebx, %%ecx;"
186 " shrl      $2, %%ecx;"
187 " rep;      movsl;"
188 " movl      %%ebx, %%ecx;"
189 " andl      $3, %%ecx;"
190 " rep;      movsb"
191  : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
192  : "0" (src), "1" (dest), "2" (num_pixels)
193  :      "%eax", "%ebx");
194 }
195
196 static inline void gr_linear_rep_movsdm(void * src, void * dest, unsigned int num_pixels ) {
197         int dummy[3];
198  __asm__ __volatile__ (
199 "0: ;"
200 " movb  (%%esi), %%al;"
201 " incl  %%esi;"
202 " cmpb  $255, %%al;"
203 " je    1f;"
204 " movb  %%al,(%%edi);"
205 "1: ;"
206 " incl  %%edi;"
207 " decl  %%ecx;"
208 " jne   0b"
209  : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
210  : "0" (src), "1" (dest), "2" (num_pixels)
211  :      "%eax");
212 }
213
214 /* #pragma aux gr_linear_rep_movsdm_faded parm [esi] [edi] [ecx] [ebx] modify exact [ecx esi edi eax ebx] */
215 static inline void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value ) {
216         int dummy[4];
217  __asm__ __volatile__ (
218 "  xorl   %%eax, %%eax;"
219 "  movb   %%bl, %%ah;"
220 "0:;"
221 "  movb   (%%esi), %%al;"
222 "  incl   %%esi;"
223 "  cmpb   $255, %%al;"
224 "  je 1f;"
225 #ifdef __ENV_LINUX__
226 "  movb   gr_fade_table(%%eax), %%al;"
227 #else
228 "  movb   _gr_fade_table(%%eax), %%al;"
229 #endif
230 "  movb   %%al, (%%edi);"
231 "1:"
232 "  incl   %%edi;"
233 "  decl   %%ecx;"
234 "  jne    0b"
235  : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2]), "=b" (dummy[3])
236  : "0" (src), "1" (dest), "2" (num_pixels), "3" (fade_value)
237  :      "%eax");
238 }
239
240 inline void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, unsigned int num_dest_pixels ) {
241 /* #pragma aux gr_linear_rep_movsd_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx] */
242         int dummy[3];
243  __asm__ __volatile__ (
244     "shrl   $1, %%ecx;"
245     "jnc    0f;"
246     "movb   (%%esi), %%al;"
247     "movb   %%al, (%%edi);"
248     "incl   %%esi;"
249     "incl   %%edi;"
250     "cmpl   $0, %%ecx;"
251     "je 1f;"
252 "0: ;"
253     "movb   (%%esi), %%al;"
254     "movb   %%al, %%ah;"
255     "movw   %%ax, (%%edi);"
256     "incl   %%esi;"
257     "incl   %%edi;"
258     "incl   %%edi;"
259     "decl   %%ecx;"
260     "jne    0b;"
261 "1:"
262  : "=S" (dummy[0]), "=D" (dummy[1]), "=c" (dummy[2])
263  : "0" (src), "1" (dest), "2" (num_dest_pixels)
264  :      "%eax");
265 }
266
267 static inline void modex_copy_column(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
268 /*#pragma aux modex_copy_column parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
269  __asm__ __volatile__ (
270 "0: ;"
271     "movb   (%%esi), %%al;"
272     "addl   %%ebx, %%esi;"
273     "movb   %%al, (%%edi);"
274     "addl   %%edx, %%edi;"
275     "decl   %%ecx;"
276     "jne    0b"
277  : : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
278  :      "%eax", "%ecx", "%esi", "%edi");
279 }
280
281 static inline void modex_copy_column_m(ubyte * src, ubyte * dest, int num_pixels, int src_rowsize, int dest_rowsize ) {
282 /* #pragma aux modex_copy_column_m parm [esi] [edi] [ecx] [ebx] [edx] modify exact [ecx esi edi] = */
283  __asm__ __volatile__ (
284 "0: ;"
285     "movb    (%%esi), %%al;"
286     "addl    %%ebx, %%esi;"
287     "cmpb    $255, %%al;"
288     "je 1f;"
289     "movb   %%al, (%%edi);"
290 "1: ;"
291     "addl   %%edx, %%edi;"
292     "decl   %%ecx;"
293     "jne    0b"
294  : "=c" (num_pixels), "=S" (src), "=D" (dest) : "S" (src), "D" (dest), "c" (num_pixels), "b" (src_rowsize), "d" (dest_rowsize)
295  :      "%eax");
296 }
297
298 static inline void modex_copy_scanline( ubyte * src, ubyte * dest, int npixels ) {
299 /* #pragma aux modex_copy_scanline parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] */
300  __asm__ __volatile__ (
301 "       movl %%ecx, %%ebx;"
302 "       andl $3, %%ebx;"
303 "       shrl $2, %%ecx;"
304 "       cmpl $0, %%ecx;"
305 "       je   1f;"
306 "0: ;"
307 "       movb 8(%%esi), %%al;"
308 "       movb 12(%%esi), %%ah;"
309 "       shll $16, %%eax;"
310 "       movb (%%esi), %%al;"
311 "       movb 4(%%esi), %%ah;"
312 "       movl %%eax, (%%edi);"
313 "       addl $16, %%esi;"
314 "       addl $4, %%edi;"
315 "       decl %%ecx;"
316 "       jne 0b;"
317 "1: ;"
318 "       cmpl $0, %%ebx;"
319 "       je      3f;"
320 "2: ;"
321 "       movb (%%esi), %%al;"
322 "       addl $4, %%esi;"
323 "       movb %%al, (%%edi);"
324 "       incl %%edi;"
325 "       decl %%ebx;"
326 "       jne 2b;"
327 "3:"
328  : "=c" (npixels), "=S" (src), "=D" (dest): "S" (src), "D" (dest), "c" (npixels)
329  :      "%eax", "%ebx", "%edx");
330 }
331
332 static inline void modex_copy_scanline_2x( ubyte * src, ubyte * dest, int npixels ) {
333 /* #pragma aux modex_copy_scanline_2x parm [esi] [edi] [ecx] modify exact [ecx esi edi eax ebx edx] = */
334  __asm__ __volatile__ (
335 "       movl %%ecx, %%ebx;"
336 "       andl $3, %%ebx;"
337 "       shrl $2, %%ecx;"
338 "       cmpl $0, %%ecx;"
339 "       je 1f;"
340 "0: ;"
341 "       movb 4(%%esi), %%al;"
342 "       movb 6(%%esi), %%ah;"
343 "       shll $16, %%eax;"
344 "       movb (%%esi), %%al;"
345 "       movb 2(%%esi), %%ah;"
346 "       movl %%eax, (%%edi);"
347 "       addl $8, %%esi;"
348 "       addl $4, %%edi;"
349 "       decl %%ecx;"
350 "       jne 0b;"
351 "1: ;"
352 "       cmp $0, %%ebx;"
353 "       je  3f;"
354 "2:"
355 "       movb (%%esi),%%al;"
356 "       addl $2, %%esi;"
357 "       movb %%al, (%%edi);"
358 "       incl %%edi;"
359 "       decl %%ebx;"
360 "       jne 2b;"
361 "3:"
362  : "=c" (npixels), "=S" (src), "=D" (dest): "S" (src), "D" (dest), "c" (npixels)
363  :      "%eax", "%ebx", "%edx");
364 }
365 #elif defined _MSC_VER
366
367 extern unsigned int gr_var_color;
368 extern unsigned int gr_var_bwidth;
369 extern unsigned char * gr_var_bitmap;
370
371 void gr_linear_stosd( ubyte * source, unsigned char color, unsigned int nbytes);
372 void gr_linear_line( int x0, int y0, int x1, int y1);
373 void gr_update_buffer( void * sbuf1, void * sbuf2, void * dbuf, int size );
374
375 // This code aligns edi so that the destination is aligned to a dword boundry before rep movsd
376 __inline void gr_linear_movsd(ubyte * src, ubyte * dest, unsigned int num_pixels )
377 {
378  __asm {
379    mov esi, [src]
380    mov edi, [dest]
381    mov ecx, [num_pixels]
382    cld
383    mov ebx, ecx
384    mov eax, edi
385    and eax, 011b
386    jz d_aligned
387    mov ecx, 4
388    sub ecx, eax
389    sub ebx, ecx
390    rep movsb
391 d_aligned:
392    mov ecx, ebx
393    shr ecx, 2
394    rep movsd
395    mov ecx, ebx
396    and ecx, 11b
397    rep movsb
398  }
399 }
400
401 __inline void gr_linear_rep_movsdm(void * src, void * dest, unsigned int num_pixels )
402 {
403  __asm {
404   nextpixel:
405   mov esi, [src]
406   mov edi, [dest]
407   mov ecx, [num_pixels]
408   mov al,  [esi]
409   inc esi
410   cmp al,  255
411   je skip_it
412   mov [edi], al
413   skip_it:
414   inc edi
415   dec ecx
416   jne nextpixel
417  }
418 }
419
420 __inline void gr_linear_rep_movsdm_faded(void * src, void * dest, unsigned int num_pixels, ubyte fade_value )
421 {
422  __asm {
423   mov esi, [src]
424   mov edi, [dest]
425   mov ecx, [num_pixels]
426   movzx ebx, byte ptr [fade_value]
427   xor eax, eax
428   mov ah, bl
429   nextpixel:
430   mov al, [esi]
431   inc esi
432   cmp al, 255
433   je skip_it
434   mov al, gr_fade_table[eax]
435   mov [edi], al
436   skip_it:
437   inc edi
438   dec ecx
439   jne nextpixel
440  }
441 }
442
443 __inline void gr_linear_rep_movsd_2x(ubyte * src, ubyte * dest, uint num_dest_pixels )
444 {
445  __asm {
446   mov esi, [src]
447   mov edi, [dest]
448   mov ecx, [num_dest_pixels]
449   shr ecx, 1
450   jnc nextpixel
451   mov al, [esi]
452   mov [edi], al
453   inc esi
454   inc edi
455   cmp ecx, 0
456   je done
457 nextpixel:
458   mov al, [esi]
459   mov ah, al
460   mov [edi], ax
461   inc esi
462   inc edi
463   inc edi
464   dec ecx
465   jne nextpixel
466 done:
467  }
468 }
469
470 #else
471 #define NO_ASM 1 // We really do want no assembler...
472
473 #endif
474 #endif // NO_ASM
475
476 #endif