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