formatting, use __MSDOS__ instead of __DJGPP__
[btb/d2x.git] / 2d / 2dsline.c
1 /* $Id: 2dsline.c,v 1.6 2002-09-04 21:58:11 btb Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14
15 /*
16  *
17  * Graphical routines for drawing solid scanlines.
18  *
19  * Old Log:
20  * Revision 1.6  1995/09/14  14:24:03  allender
21  * fixed MW compile error
22  *
23  * Revision 1.5  1995/09/14  13:45:17  allender
24  * quick optimization for scanline
25  *
26  * Revision 1.4  1995/04/27  07:36:05  allender
27  * remove some memsets since all old is here now
28  *
29  * Revision 1.3  1995/04/19  14:35:33  allender
30  * *** empty log message ***
31  *
32  * Revision 1.2  1995/04/18  12:03:40  allender
33  * *** empty log message ***
34  *
35  * Revision 1.1  1995/03/09  09:24:06  allender
36  * Initial revision
37  *
38  *
39  * --- PC RCS information ---
40  * Revision 1.7  1994/11/18  22:50:48  john
41  * Changed a bunch of shorts to ints in calls.
42  *
43  * Revision 1.6  1994/09/02  11:40:32  john
44  * fixed bug with urect scanline drakening still
45  * only using 16 levels of fade.
46  *
47  * Revision 1.5  1994/04/08  16:59:12  john
48  * Add fading poly's; Made palette fade 32 instead of 16.
49  *
50  * Revision 1.4  1994/03/22  18:36:27  john
51  * Added darkening scanlines
52  *
53  * Revision 1.3  1993/10/15  16:22:52  john
54  * y
55  *
56  * Revision 1.2  1993/09/08  11:56:29  john
57  * neatened
58  *
59  * Revision 1.1  1993/09/08  11:44:27  john
60  * Initial revision
61  *
62  */
63
64 #ifdef HAVE_CONFIG_H
65 #include <conf.h>
66 #endif
67
68 #include <string.h>
69
70 #include "u_mem.h"
71
72 #include "gr.h"
73 #include "grdef.h"
74
75 #ifdef __MSDOS__
76 #include "modex.h"
77 #include "vesa.h"
78 #endif
79
80 int Gr_scanline_darkening_level = GR_FADE_LEVELS;
81
82 #if !defined(NO_ASM) && defined(__WATCOMC__)
83
84 void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table );
85 #pragma aux gr_linear_darken parm [edi] [eax] [ecx] [edx] modify exact [eax ebx ecx edx edi] = \
86 "               xor ebx, ebx                "   \
87 "               mov bh, al                  "   \
88 "gld_loop:      mov bl, [edi]               "   \
89 "               mov al, [ebx+edx]           "   \
90 "               mov [edi], al               "   \
91 "               inc edi                     "   \
92 "               dec ecx                     "   \
93 "               jnz gld_loop                "
94
95 #elif !defined(NO_ASM) && defined(__GNUC__)
96
97 static inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table ) {
98    int dummy[4];
99    __asm__ __volatile__ (
100 "               xorl %%ebx, %%ebx;"
101 "               movb %%al, %%bh;"
102 "0:             movb (%%edi), %%bl;"
103 "               movb (%%ebx, %%edx), %%al;"
104 "               movb %%al, (%%edi);"
105 "               incl %%edi;"
106 "               decl %%ecx;"
107 "               jnz 0b"
108    : "=D" (dummy[0]), "=a" (dummy[1]), "=c" (dummy[2]), "=d" (dummy[3])
109    : "0" (dest), "1" (darkening_level), "2" (count), "3" (fade_table)
110    : "%ebx");
111 }
112
113 #elif !defined(NO_ASM) && defined(_MSC_VER)
114
115 __inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table )
116 {
117         __asm {
118     mov edi,[dest]
119     mov eax,[darkening_level]
120     mov ecx,[count]
121     mov edx,[fade_table]
122     xor ebx, ebx
123     mov bh, al
124 gld_loop:
125     mov bl,[edi]
126     mov al,[ebx+edx]
127     mov [edi],al
128     inc edi
129     dec ecx
130     jnz gld_loop
131         }
132 }
133
134 #else // Unknown compiler, or no assembler. So we use C.
135
136 void gr_linear_darken(ubyte * dest, int darkening_level, int count, ubyte * fade_table) {
137         register int i;
138
139         for (i=0;i<count;i++)
140                 *dest=fade_table[(*dest++)+(darkening_level*256)];
141 }
142
143 #endif
144
145 #ifdef NO_ASM // No Assembler. So we use C.
146 #if 0
147 void gr_linear_stosd( ubyte * dest, ubyte color, unsigned short count )
148 {
149         int i, x;
150
151         if (count > 3) {
152                 while ((int)(dest) & 0x3) { *dest++ = color; count--; };
153                 if (count >= 4) {
154                         x = (color << 24) | (color << 16) | (color << 8) | color;
155                         while (count > 4) { *(int *)dest = x; dest += 4; count -= 4; };
156                 }
157                 while (count > 0) { *dest++ = color; count--; };
158         } else {
159                 for (i=0; i<count; i++ )
160                         *dest++ = color;
161         }
162 }
163 #else
164 void gr_linear_stosd( ubyte * dest, unsigned char color, unsigned int nbytes) {
165         memset(dest,color,nbytes);
166 }
167 #endif
168 #endif
169
170 void gr_uscanline( int x1, int x2, int y )
171 {
172         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) {
173 #ifdef __MSDOS__
174                 switch(TYPE)
175                 {
176                 case BM_LINEAR:
177 #endif
178                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
179 #ifdef __MSDOS__
180                         break;
181                 case BM_MODEX:
182                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
183                         break;
184                 case BM_SVGA:
185                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
186                         break;
187                 }
188 #endif
189         } else {
190 #ifdef __MSDOS__
191                 switch(TYPE)
192                 {
193                 case BM_LINEAR:
194 #endif
195                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
196 #ifdef __MSDOS__
197                         break;
198                 case BM_MODEX:
199                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
200                         break;
201                 case BM_SVGA:
202                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
203                         break;
204                 }
205 #endif
206         }
207 }
208
209 void gr_scanline( int x1, int x2, int y )
210 {
211         if ((y<0)||(y>MAXY)) return;
212
213         if (x2 < x1 ) x2 ^= x1 ^= x2;
214
215         if (x1 > MAXX) return;
216         if (x2 < MINX) return;
217
218         if (x1 < MINX) x1 = MINX;
219         if (x2 > MAXX) x2 = MAXX;
220
221         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) {
222 #ifdef __MSDOS__
223                 switch(TYPE)
224                 {
225                 case BM_LINEAR:
226 #endif
227                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
228 #ifdef __MSDOS__
229                         break;
230                 case BM_MODEX:
231                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
232                         break;
233                 case BM_SVGA:
234                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
235                         break;
236                 }
237 #endif
238         } else {
239 #ifdef __MSDOS__
240                 switch(TYPE)
241                 {
242                 case BM_LINEAR:
243 #endif
244                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
245 #ifdef __MSDOS__
246                         break;
247                 case BM_MODEX:
248                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
249                         break;
250                 case BM_SVGA:
251                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
252                         break;
253                 }
254 #endif
255         }
256 }