]> icculus.org git repositories - taylor/freespace2.git/blob - src/graphics/shade.cpp
Initial revision
[taylor/freespace2.git] / src / graphics / shade.cpp
1 /*
2  * $Logfile: /Freespace2/code/Graphics/Shade.cpp $
3  * $Revision$
4  * $Date$
5  * $Author$
6  *
7  * Routines to shade an area.
8  *
9  * $Log$
10  * Revision 1.1  2002/05/03 03:28:09  root
11  * Initial revision
12  *
13  * 
14  * 2     10/07/98 10:53a Dave
15  * Initial checkin.
16  * 
17  * 1     10/07/98 10:49a Dave
18  * 
19  * 19    3/12/98 5:36p John
20  * Took out any unused shaders.  Made shader code take rgbc instead of
21  * matrix and vector since noone used it like a matrix and it would have
22  * been impossible to do in hardware.   Made Glide implement a basic
23  * shader for online help.  
24  * 
25  * 18    3/10/98 4:19p John
26  * Cleaned up graphics lib.  Took out most unused gr functions.   Made D3D
27  * & Glide have popups and print screen.  Took out all >8bpp software
28  * support.  Made Fred zbuffer.  Made zbuffer allocate dynamically to
29  * support Fred.  Made zbuffering key off of functions rather than one
30  * global variable.
31  * 
32  * 17    11/30/97 12:18p John
33  * added more 24 & 32-bpp primitives
34  * 
35  * 16    10/19/97 12:55p John
36  * new code to lock / unlock surfaces for smooth directx integration.
37  * 
38  * 15    10/09/97 5:23p John
39  * Added support for more 16-bpp functions
40  * 
41  * 14    10/03/97 12:16p John
42  * optimized the shader.  About 50% faster.
43  * 
44  * 13    10/03/97 9:10a John
45  * added better antialiased line drawer
46  * 
47  * 12    9/09/97 10:41a Sandeep
48  * fixed warning level 4
49  * 
50  * 11    6/18/97 12:07p John
51  * fixed some color bugs
52  * 
53  * 10    6/17/97 7:04p John
54  * added d3d support for gradients.
55  * fixed some color bugs by adding screen signatures instead of watching
56  * flags and palette changes.
57  * 
58  * 9     5/28/97 8:59a John
59  * Fixed bug with shader not working when switching to fullscreen.
60  * 
61  * 8     5/12/97 12:27p John
62  * Restructured Graphics Library to add support for multiple renderers.
63  * 
64  * 7     11/19/96 2:44p Allender
65  * fix up shader for 15 bpp
66  * 
67  * 6     11/18/96 2:27p Allender
68  * made faster hacked version of shader for 16 bits
69  * 
70  * 5     11/18/96 1:48p Allender
71  * added 16 bit version of (very slow) shader
72  * 
73  * 4     11/15/96 3:34p Allender
74  * started on 16 bit support for the shader
75  * 
76  * 3     10/26/96 1:40p John
77  * Added some now primitives to the 2d library and
78  * cleaned up some old ones.
79  *
80  * $NoKeywords: $
81  */
82
83 #include "2d.h"
84 #include "grinternal.h"
85 #include "floating.h"
86 #include "line.h"
87 #include "palman.h"
88
89 void grx_create_shader(shader * shade, float r, float g, float b, float c )
90 {
91         int i;
92         float Sr, Sg, Sb;
93         float Dr, Dg, Db;
94         int ri, gi, bi;
95
96         shade->screen_sig = gr_screen.signature;
97         shade->r = r;
98         shade->g = g;
99         shade->b = b;
100         shade->c = c;
101
102         for (i=0; i<256; i++ )  {
103                 Sr = i2fl( gr_palette[i*3+0] );
104                 Sg = i2fl( gr_palette[i*3+1] );
105                 Sb = i2fl( gr_palette[i*3+2] );
106                 Dr = Sr*r + Sg*r + Sb*r + c*256.0f;
107                 Dg = Sr*g + Sg*g + Sb*g + c*256.0f;
108                 Db = Sr*b + Sg*b + Sb*b + c*256.0f;
109                 ri = fl2i(Dr); if ( ri < 0 ) ri = 0; else if (ri>255) ri = 255;
110                 gi = fl2i(Dg); if ( gi < 0 ) gi = 0; else if (gi>255) gi = 255;
111                 bi = fl2i(Db); if ( bi < 0 ) bi = 0; else if (bi>255) bi = 255;
112                 shade->lookup[i] = (unsigned char)(palette_find(ri,gi,bi));
113         }
114
115 }
116
117 void grx_set_shader( shader * shade )
118 {
119         if ( shade ) {
120                 if (shade->screen_sig != gr_screen.signature)   {
121                         gr_create_shader( shade, shade->r, shade->g, shade->b, shade->c );
122                 }
123                 gr_screen.current_shader = *shade;
124         } else {
125                 gr_create_shader( &gr_screen.current_shader, 0.0f, 0.0f, 0.0f, 0.0f );
126         }
127 }
128
129
130 void gr8_shade(int x,int y,int w,int h)
131 {
132         int x1, y1, x2, y2;
133         ubyte *xlat_table;
134
135         x1 = x; 
136         if (x1 < gr_screen.clip_left) x1 = gr_screen.clip_left;
137         if (x1 > gr_screen.clip_right) x1 = gr_screen.clip_right;
138
139         x2 = x+w-1; 
140         if (x2 < gr_screen.clip_left) x2 = gr_screen.clip_left;
141         if (x2 > gr_screen.clip_right) x2 = gr_screen.clip_right;
142
143         y1 = y; 
144         if (y1 < gr_screen.clip_top) y1 = gr_screen.clip_top;
145         if (y1 > gr_screen.clip_bottom) y1 = gr_screen.clip_bottom;
146
147         y2 = y+h-1; 
148         if (y2 < gr_screen.clip_top) y2 = gr_screen.clip_top;
149         if (y2 > gr_screen.clip_bottom) y2 = gr_screen.clip_bottom;
150
151         w = x2 - x1 + 1;
152         if ( w < 1 ) return;
153
154         h = y2 - y1 + 1;
155         if ( h < 1 ) return;
156
157         int i;
158         xlat_table = gr_screen.current_shader.lookup;
159
160         gr_lock();
161
162         for (i=0; i<h; i++ )    {
163                 ubyte * dp = GR_SCREEN_PTR(ubyte,x1,y1+i);
164                                 #ifdef USE_INLINE_ASM
165
166                                         int w1=w;
167
168                                         // 4 byte align
169                                         while ( (uint)dp & 3 )  {
170                                                 *dp = xlat_table[*dp];
171                                                 dp++;
172                                                 w1--;
173                                                 if ( w1 < 1 ) break;
174                                         }
175
176                                         if ( w1 < 1 ) continue;
177                                 
178                                         int wd4 = w1 / 4;
179                                         int left_over = w1 % 4;
180                         
181                                         if ( wd4 > 0 )  {
182 #ifdef PLAT_UNIX
183                                                 STUB_FUNCTION;
184 #else
185                                                 _asm push eax
186                                                 _asm push ebx
187                                                 _asm push ecx
188                                                 _asm push edx
189                                                 _asm push edi           
190                                                 _asm push esi
191                                                 _asm mov esi, xlat_table
192                                                 _asm mov edi, dp
193                                                 _asm mov edi, dp
194                                                 _asm mov ecx, wd4
195                                                 _asm mov eax, 0
196                                                 _asm mov ebx, 0
197                                                 _asm mov edx, 0
198
199         NextPixel:
200                                                 _asm mov eax, [edi]
201
202                                                 _asm mov dl, al
203                                                 _asm mov bl, ah
204
205                                                 _asm add edi, 4
206
207                                                 _asm mov al, [edx+esi]
208                                                 _asm mov ah, [ebx+esi]
209
210                                                 _asm ror eax, 16
211                                                 
212                                                 _asm mov dl, al
213                                                 _asm mov bl, ah
214
215                                                 _asm mov al, [edx+esi]
216                                                 _asm mov ah, [ebx+esi]
217
218                                                 _asm ror eax, 16
219
220                                                 _asm mov [edi-4], eax
221
222                                                 _asm dec ecx
223                                                 _asm jnz NextPixel
224
225
226                                                 _asm mov dp, edi
227
228                                                 _asm pop esi
229                                                 _asm pop edi
230                                                 _asm pop edx
231                                                 _asm pop ecx
232                                                 _asm pop ebx
233                                                 _asm pop eax
234 #endif
235                                         }
236
237                                         for (int j=0; j<left_over; j++ )        {
238                                                 *dp = xlat_table[*dp];
239                                                 dp++;
240                                         }
241
242                         
243                                 #else
244                                         for (int j=0; j<w; j++ )        {
245                                                 *dp = xlat_table[*dp];
246                                                 dp++;
247                                         }
248                                 #endif
249         }
250
251         gr_unlock();
252         
253 }
254