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