]> icculus.org git repositories - btb/d2x.git/blob - 2d/2dsline.c
remove rcs tags
[btb/d2x.git] / 2d / 2dsline.c
1 /*
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
14 /*
15  *
16  * Graphical routines for drawing solid scanlines.
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <conf.h>
22 #endif
23
24 #include <string.h>
25
26 #include "u_mem.h"
27
28 #include "gr.h"
29 #include "grdef.h"
30 #include "error.h"
31
32 #ifdef __MSDOS__
33 #include "modex.h"
34 #include "vesa.h"
35 #endif
36
37 int Gr_scanline_darkening_level = GR_FADE_LEVELS;
38
39 #if !defined(NO_ASM) && defined(__WATCOMC__)
40
41 void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table );
42 #pragma aux gr_linear_darken parm [edi] [eax] [ecx] [edx] modify exact [eax ebx ecx edx edi] = \
43 "               xor ebx, ebx                "   \
44 "               mov bh, al                  "   \
45 "gld_loop:      mov bl, [edi]               "   \
46 "               mov al, [ebx+edx]           "   \
47 "               mov [edi], al               "   \
48 "               inc edi                     "   \
49 "               dec ecx                     "   \
50 "               jnz gld_loop                "
51
52 #elif !defined(NO_ASM) && defined(__GNUC__)
53
54 static inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table ) {
55    int dummy[4];
56    __asm__ __volatile__ (
57 "               xorl %%ebx, %%ebx;"
58 "               movb %%al, %%bh;"
59 "0:             movb (%%edi), %%bl;"
60 "               movb (%%ebx, %%edx), %%al;"
61 "               movb %%al, (%%edi);"
62 "               incl %%edi;"
63 "               decl %%ecx;"
64 "               jnz 0b"
65    : "=D" (dummy[0]), "=a" (dummy[1]), "=c" (dummy[2]), "=d" (dummy[3])
66    : "0" (dest), "1" (darkening_level), "2" (count), "3" (fade_table)
67    : "%ebx");
68 }
69
70 #elif !defined(NO_ASM) && defined(_MSC_VER)
71
72 __inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table )
73 {
74         __asm {
75     mov edi,[dest]
76     mov eax,[darkening_level]
77     mov ecx,[count]
78     mov edx,[fade_table]
79     xor ebx, ebx
80     mov bh, al
81 gld_loop:
82     mov bl,[edi]
83     mov al,[ebx+edx]
84     mov [edi],al
85     inc edi
86     dec ecx
87     jnz gld_loop
88         }
89 }
90
91 #else // Unknown compiler, or no assembler. So we use C.
92
93 void gr_linear_darken(ubyte * dest, int darkening_level, int count, ubyte * fade_table) {
94         register int i;
95
96         for (i=0;i<count;i++)
97         {
98                 *dest = fade_table[(*dest)+(darkening_level*256)];
99                 dest++;
100         }
101 }
102
103 #endif
104
105 #ifdef NO_ASM // No Assembler. So we use C.
106 #if 0
107 void gr_linear_stosd( ubyte * dest, ubyte color, unsigned short count )
108 {
109         int i, x;
110
111         if (count > 3) {
112                 while ((int)(dest) & 0x3) { *dest++ = color; count--; };
113                 if (count >= 4) {
114                         x = (color << 24) | (color << 16) | (color << 8) | color;
115                         while (count > 4) { *(int *)dest = x; dest += 4; count -= 4; };
116                 }
117                 while (count > 0) { *dest++ = color; count--; };
118         } else {
119                 for (i=0; i<count; i++ )
120                         *dest++ = color;
121         }
122 }
123 #else
124 void gr_linear_stosd( ubyte * dest, unsigned char color, unsigned int nbytes) {
125         memset(dest,color,nbytes);
126 }
127 #endif
128 #endif
129
130 void gr_uscanline( int x1, int x2, int y )
131 {
132         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) {
133                 switch(TYPE)
134                 {
135                 case BM_LINEAR:
136 #ifdef OGL
137                 case BM_OGL:
138 #endif
139                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
140                         break;
141 #ifdef __MSDOS__
142                 case BM_MODEX:
143                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
144                         break;
145                 case BM_SVGA:
146                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
147                         break;
148 #endif
149                 }
150         } else {
151                 switch(TYPE)
152                 {
153                 case BM_LINEAR:
154 #ifdef OGL
155                 case BM_OGL:
156 #endif
157                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
158                         break;
159 #ifdef __MSDOS__
160                 case BM_MODEX:
161                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
162                         break;
163                 case BM_SVGA:
164 #if 1
165                         {
166                                 ubyte * vram = (ubyte *)0xA0000;
167                                 int VideoLocation,page,offset1, offset2;
168
169                                 VideoLocation = (ROWSIZE * y) + x1;
170                                 page    = VideoLocation >> 16;
171                                 offset1  = VideoLocation & 0xFFFF;
172                                 offset2   = offset1 + (x2-x1+1);
173
174                                 gr_vesa_setpage( page );
175                                 if ( offset2 <= 0xFFFF ) {
176                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
177                                 } else {
178                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, 0xFFFF-offset1+1, gr_fade_table);
179                                         page++;
180                                         gr_vesa_setpage(page);
181                                         gr_linear_darken( vram, Gr_scanline_darkening_level, offset2 - 0xFFFF, gr_fade_table);
182                                 }
183                         }
184 #else
185                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
186 #endif
187                         break;
188 #endif
189                 }
190         }
191 }
192
193 void gr_scanline( int x1, int x2, int y )
194 {
195         if ((y<0)||(y>MAXY)) return;
196
197         if (x2 < x1 ) x2 ^= x1 ^= x2;
198
199         if (x1 > MAXX) return;
200         if (x2 < MINX) return;
201
202         if (x1 < MINX) x1 = MINX;
203         if (x2 > MAXX) x2 = MAXX;
204
205         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) {
206                 switch(TYPE)
207                 {
208                 case BM_LINEAR:
209 #ifdef OGL
210                 case BM_OGL:
211 #endif
212                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
213                         break;
214 #ifdef __MSDOS__
215                 case BM_MODEX:
216                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
217                         break;
218                 case BM_SVGA:
219                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
220                         break;
221 #endif
222                 }
223         } else {
224                 switch(TYPE)
225                 {
226                 case BM_LINEAR:
227 #ifdef OGL
228                 case BM_OGL:
229 #endif
230                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
231                         break;
232 #ifdef __MSDOS__
233                 case BM_MODEX:
234                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
235                         break;
236                 case BM_SVGA:
237 #if 1
238                         {
239                                 ubyte * vram = (ubyte *)0xA0000;
240                                 int VideoLocation,page,offset1, offset2;
241
242                                 VideoLocation = (ROWSIZE * y) + x1;
243                                 page    = VideoLocation >> 16;
244                                 offset1  = VideoLocation & 0xFFFF;
245                                 offset2   = offset1 + (x2-x1+1);
246
247                                 gr_vesa_setpage( page );
248                                 if ( offset2 <= 0xFFFF )        {
249                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
250                                 } else {
251                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, 0xFFFF-offset1+1, gr_fade_table);
252                                         page++;
253                                         gr_vesa_setpage(page);
254                                         gr_linear_darken( vram, Gr_scanline_darkening_level, offset2 - 0xFFFF, gr_fade_table);
255                                 }
256                         }
257 #else
258                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
259 #endif
260                         break;
261 #endif
262                 }
263         }
264 }