This commit was manufactured by cvs2svn to create tag 'd2x-0_1_2'.
[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  * $Source: /cvs/cvsroot/d2x/2d/2dsline.c,v $
16  * $Revision: 1.3 $
17  * $Author: bradleyb $
18  * $Date: 2001-10-18 22:45:58 $
19  *
20  * FIXME: add description
21  *
22  * $Log: not supported by cvs2svn $
23  *
24  */
25
26 #ifdef HAVE_CONFIG_H
27 #include <conf.h>
28 #endif
29
30 #include <string.h>
31
32 #include "u_mem.h"
33
34 #include "gr.h"
35 #include "grdef.h"
36
37 #ifdef __DJGPP__
38 #include "modex.h"
39 #include "vesa.h"
40 #endif
41
42 int Gr_scanline_darkening_level = GR_FADE_LEVELS;
43
44 #ifndef NO_ASM
45 # ifdef __WATCOMC__
46 void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table );
47 #  pragma aux gr_linear_darken parm [edi] [eax] [ecx] [edx] modify exact [eax ebx ecx edx edi] = \
48 "                                       xor     ebx, ebx                                        "       \
49 "                                       mov     bh, al                                  "  \
50 "gld_loop:              mov     bl, [edi]                               "       \
51 "                                       mov     al, [ebx+edx]                   "       \
52 "                                       mov     [edi], al                               "       \
53 "                                       inc     edi                                             "       \
54 "                                       dec     ecx                                             "       \
55 "                   jnz gld_loop                    "
56
57 # elif defined __GNUC__
58 static inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table ) {
59    int dummy[4];
60    __asm__ __volatile__ (
61 "               xorl %%ebx, %%ebx;"
62 "               movb %%al, %%bh;"
63 "0:             movb (%%edi), %%bl;"
64 "               movb (%%ebx, %%edx), %%al;"
65 "               movb %%al, (%%edi);"
66 "               incl %%edi;"
67 "               decl %%ecx;"
68 "               jnz 0b"
69    : "=D" (dummy[0]), "=a" (dummy[1]), "=c" (dummy[2]), "=d" (dummy[3])
70    : "0" (dest), "1" (darkening_level), "2" (count), "3" (fade_table)
71    : "%ebx");
72 }
73 # elif defined _MSC_VER
74 __inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table )
75 {
76   __asm {
77     mov edi,[dest]
78         mov eax,[darkening_level]
79         mov ecx,[count]
80         mov edx,[fade_table]
81         xor ebx, ebx
82         mov bh, al
83 gld_loop:
84         mov bl,[edi]
85         mov al,[ebx+edx]
86         mov [edi],al
87         inc edi
88         dec ecx
89         jnz gld_loop
90   }
91 }
92 # else
93 // Unknown compiler. So we use C rather than inline assembler.
94 #  define USE_C_GR_LINEAR_DARKEN 1
95 # endif
96
97 #else // No Assembler. So we use C.
98 # define USE_C_GR_LINEAR_DARKEN 1
99 void gr_linear_stosd( ubyte * dest, unsigned char color, unsigned int nbytes) {
100         memset(dest,color,nbytes);
101 }
102 #endif
103
104 #ifdef USE_C_GR_LINEAR_DARKEN
105 void gr_linear_darken(ubyte * dest, int darkening_level, int count, ubyte * fade_table) {
106         register int i;
107
108         for (i=0;i<count;i++)
109                 *dest=fade_table[(*dest++)+(darkening_level*256)];
110 }
111 #endif
112
113 void gr_uscanline( int x1, int x2, int y )
114 {
115         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS )     {
116 #ifdef __DJGPP__
117                 switch(TYPE)
118                 {
119                 case BM_LINEAR:
120 #endif
121                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
122 #ifdef __DJGPP__
123                         break;
124                 case BM_MODEX:
125                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
126                         break;
127                 case BM_SVGA:
128                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
129                         break;
130                 }
131 #endif
132         } else {
133 #ifdef __DJGPP__
134                 switch(TYPE)
135                 {
136                 case BM_LINEAR:
137 #endif
138                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
139 #ifdef __DJGPP__
140                         break;
141                 case BM_MODEX:
142                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
143                         break;
144                 case BM_SVGA:
145                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
146                         break;
147                 }
148 #endif
149         }
150 }
151
152 void gr_scanline( int x1, int x2, int y )
153 {
154         if ((y<0)||(y>MAXY)) return;
155
156         if (x2 < x1 ) x2 ^= x1 ^= x2;
157
158         if (x1 > MAXX) return;
159         if (x2 < MINX) return;
160
161         if (x1 < MINX) x1 = MINX;
162         if (x2 > MAXX) x2 = MAXX;
163
164         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS )     {
165 #ifdef __DJGPP__
166                 switch(TYPE)
167                 {
168                 case BM_LINEAR:
169 #endif
170                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
171 #ifdef __DJGPP__
172                         break;
173                 case BM_MODEX:
174                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
175                         break;
176                 case BM_SVGA:
177                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
178                         break;
179                 }
180 #endif
181         } else {
182 #ifdef __DJGPP__
183                 switch(TYPE)
184                 {
185                 case BM_LINEAR:
186 #endif
187                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
188 #ifdef __DJGPP__
189                         break;
190                 case BM_MODEX:
191                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
192                         break;
193                 case BM_SVGA:
194                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
195                         break;
196                 }
197 #endif
198         }
199 }