]> icculus.org git repositories - btb/d2x.git/blob - 2d/2dsline.c
actually use PHYSFSX_openRead/WriteBuffered
[btb/d2x.git] / 2d / 2dsline.c
1 /* $Id: 2dsline.c,v 1.11 2004-08-28 23:17:45 schaffner 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  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <conf.h>
23 #endif
24
25 #include <string.h>
26
27 #include "u_mem.h"
28
29 #include "gr.h"
30 #include "grdef.h"
31 #include "error.h"
32
33 #ifdef __MSDOS__
34 #include "modex.h"
35 #include "vesa.h"
36 #endif
37
38 #if defined(POLY_ACC)
39 #include "poly_acc.h"
40 #endif
41
42 int Gr_scanline_darkening_level = GR_FADE_LEVELS;
43
44 #if !defined(NO_ASM) && defined(__WATCOMC__)
45
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(NO_ASM) && defined(__GNUC__)
58
59 static inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table ) {
60    int dummy[4];
61    __asm__ __volatile__ (
62 "               xorl %%ebx, %%ebx;"
63 "               movb %%al, %%bh;"
64 "0:             movb (%%edi), %%bl;"
65 "               movb (%%ebx, %%edx), %%al;"
66 "               movb %%al, (%%edi);"
67 "               incl %%edi;"
68 "               decl %%ecx;"
69 "               jnz 0b"
70    : "=D" (dummy[0]), "=a" (dummy[1]), "=c" (dummy[2]), "=d" (dummy[3])
71    : "0" (dest), "1" (darkening_level), "2" (count), "3" (fade_table)
72    : "%ebx");
73 }
74
75 #elif !defined(NO_ASM) && defined(_MSC_VER)
76
77 __inline void gr_linear_darken( ubyte * dest, int darkening_level, int count, ubyte * fade_table )
78 {
79         __asm {
80     mov edi,[dest]
81     mov eax,[darkening_level]
82     mov ecx,[count]
83     mov edx,[fade_table]
84     xor ebx, ebx
85     mov bh, al
86 gld_loop:
87     mov bl,[edi]
88     mov al,[ebx+edx]
89     mov [edi],al
90     inc edi
91     dec ecx
92     jnz gld_loop
93         }
94 }
95
96 #else // Unknown compiler, or no assembler. So we use C.
97
98 void gr_linear_darken(ubyte * dest, int darkening_level, int count, ubyte * fade_table) {
99         register int i;
100
101         for (i=0;i<count;i++)
102         {
103                 *dest = fade_table[(*dest)+(darkening_level*256)];
104                 dest++;
105         }
106 }
107
108 #endif
109
110 #ifdef NO_ASM // No Assembler. So we use C.
111 #if 0
112 void gr_linear_stosd( ubyte * dest, ubyte color, unsigned short count )
113 {
114         int i, x;
115
116         if (count > 3) {
117                 while ((int)(dest) & 0x3) { *dest++ = color; count--; };
118                 if (count >= 4) {
119                         x = (color << 24) | (color << 16) | (color << 8) | color;
120                         while (count > 4) { *(int *)dest = x; dest += 4; count -= 4; };
121                 }
122                 while (count > 0) { *dest++ = color; count--; };
123         } else {
124                 for (i=0; i<count; i++ )
125                         *dest++ = color;
126         }
127 }
128 #else
129 void gr_linear_stosd( ubyte * dest, unsigned char color, unsigned int nbytes) {
130         memset(dest,color,nbytes);
131 }
132 #endif
133 #endif
134
135 #if defined(POLY_ACC)
136 //$$ Note that this code WAS a virtual clone of the mac code and any changes to mac should be reflected here.
137 void gr_linear15_darken( short * dest, int darkening_level, int count, ubyte * fade_table )
138 {
139     //$$ this routine is a prime candidate for using the alpha blender.
140     int i;
141     unsigned short rt[32], gt[32], bt[32];
142     unsigned long level, int_level, dlevel;
143
144     dlevel = (darkening_level << 16) / GR_FADE_LEVELS;
145     level = int_level = 0;
146     for(i = 0; i != 32; ++i)
147     {
148         rt[i] = int_level << 10;
149         gt[i] = int_level << 5;
150         bt[i] = int_level;
151
152         level += dlevel;
153         int_level = level >> 16;
154     }
155
156     pa_flush();
157     for (i=0; i<count; i++ )    {
158         if(*dest & 0x8000)
159                 *dest =
160                  rt[((*dest >> 10) & 0x1f)] |
161               gt[((*dest >> 5) & 0x1f)] |
162                    bt[((*dest >> 0) & 0x1f)] |
163                 0x8000;
164                 dest++;
165         }
166 }
167
168 void gr_linear15_stosd( short * dest, ubyte color, unsigned short count )
169 {
170     //$$ this routine is a prime candidate for using the alpha blender.
171     short c = pa_clut[color];
172     pa_flush();
173     while(count--)
174         *dest++ = c;
175 }
176 #endif
177
178 void gr_uscanline( int x1, int x2, int y )
179 {
180         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) {
181                 switch(TYPE)
182                 {
183                 case BM_LINEAR:
184 #ifdef OGL
185                 case BM_OGL:
186 #endif
187                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
188                         break;
189 #ifdef __MSDOS__
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 #endif
197 #if defined(POLY_ACC)
198                 case BM_LINEAR15:
199                         gr_linear15_stosd( (short *)(DATA + ROWSIZE*y + x1 * PA_BPP), COLOR, x2-x1+1);
200                         break;
201 #endif
202                 }
203         } else {
204                 switch(TYPE)
205                 {
206                 case BM_LINEAR:
207 #ifdef OGL
208                 case BM_OGL:
209 #endif
210                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
211                         break;
212 #ifdef __MSDOS__
213                 case BM_MODEX:
214                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
215                         break;
216                 case BM_SVGA:
217 #if 1
218                         {
219                                 ubyte * vram = (ubyte *)0xA0000;
220                                 int VideoLocation,page,offset1, offset2;
221
222                                 VideoLocation = (ROWSIZE * y) + x1;
223                                 page    = VideoLocation >> 16;
224                                 offset1  = VideoLocation & 0xFFFF;
225                                 offset2   = offset1 + (x2-x1+1);
226
227                                 gr_vesa_setpage( page );
228                                 if ( offset2 <= 0xFFFF ) {
229                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
230                                 } else {
231                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, 0xFFFF-offset1+1, gr_fade_table);
232                                         page++;
233                                         gr_vesa_setpage(page);
234                                         gr_linear_darken( vram, Gr_scanline_darkening_level, offset2 - 0xFFFF, gr_fade_table);
235                                 }
236                         }
237 #else
238                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
239 #endif
240                         break;
241 #endif
242 #if defined(POLY_ACC)
243                 case BM_LINEAR15:
244                         gr_linear15_darken( (short *)(DATA + ROWSIZE*y + x1 * PA_BPP), Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
245                         break;
246 #endif
247                 }
248         }
249 }
250
251 void gr_scanline( int x1, int x2, int y )
252 {
253         if ((y<0)||(y>MAXY)) return;
254
255         if (x2 < x1 ) x2 ^= x1 ^= x2;
256
257         if (x1 > MAXX) return;
258         if (x2 < MINX) return;
259
260         if (x1 < MINX) x1 = MINX;
261         if (x2 > MAXX) x2 = MAXX;
262
263         if (Gr_scanline_darkening_level >= GR_FADE_LEVELS ) {
264                 switch(TYPE)
265                 {
266                 case BM_LINEAR:
267 #ifdef OGL
268                 case BM_OGL:
269 #endif
270                         gr_linear_stosd( DATA + ROWSIZE*y + x1, (unsigned char)COLOR, x2-x1+1);
271                         break;
272 #ifdef __MSDOS__
273                 case BM_MODEX:
274                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
275                         break;
276                 case BM_SVGA:
277                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
278                         break;
279 #endif
280 #if defined(POLY_ACC)
281                 case BM_LINEAR15:
282                         gr_linear15_stosd( (short *)(DATA + ROWSIZE*y + x1 * PA_BPP), COLOR, x2-x1+1);
283                         break;
284 #endif
285                 }
286         } else {
287                 switch(TYPE)
288                 {
289                 case BM_LINEAR:
290 #ifdef OGL
291                 case BM_OGL:
292 #endif
293                         gr_linear_darken( DATA + ROWSIZE*y + x1, Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
294                         break;
295 #ifdef __MSDOS__
296                 case BM_MODEX:
297                         gr_modex_uscanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
298                         break;
299                 case BM_SVGA:
300 #if 1
301                         {
302                                 ubyte * vram = (ubyte *)0xA0000;
303                                 int VideoLocation,page,offset1, offset2;
304
305                                 VideoLocation = (ROWSIZE * y) + x1;
306                                 page    = VideoLocation >> 16;
307                                 offset1  = VideoLocation & 0xFFFF;
308                                 offset2   = offset1 + (x2-x1+1);
309
310                                 gr_vesa_setpage( page );
311                                 if ( offset2 <= 0xFFFF )        {
312                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
313                                 } else {
314                                         gr_linear_darken( &vram[offset1], Gr_scanline_darkening_level, 0xFFFF-offset1+1, gr_fade_table);
315                                         page++;
316                                         gr_vesa_setpage(page);
317                                         gr_linear_darken( vram, Gr_scanline_darkening_level, offset2 - 0xFFFF, gr_fade_table);
318                                 }
319                         }
320 #else
321                         gr_vesa_scanline( x1+XOFFSET, x2+XOFFSET, y+YOFFSET, COLOR );
322 #endif
323                         break;
324 #endif
325 #if defined(POLY_ACC)
326                 case BM_LINEAR15:
327                         gr_linear15_darken( (short *)(DATA + ROWSIZE*y + x1 * PA_BPP), Gr_scanline_darkening_level, x2-x1+1, gr_fade_table);
328                         break;
329 #endif
330                 }
331         }
332 }