This commit was generated by cvs2svn to compensate for changes in r2,
[btb/d2x.git] / video / ggi_gr.c
1 #include <ggi/ggi.h>
2 #include <stdlib.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include "gr.h"
6 #include "grdef.h"
7 #include "palette.h"
8 #include "u_mem.h"
9 #include "error.h"
10
11 #include "gamefont.h"
12
13 int gr_installed = 0;
14 void *screenbuffer;
15
16 ggi_visual_t *screenvis;
17 const ggi_directbuffer *dbuffer;
18
19 ubyte use_directbuffer;
20
21 void gr_update()
22 {
23         ggiFlush(screenvis);
24         if (!use_directbuffer)
25                 ggiPutBox(screenvis, 0, 0, grd_curscreen->sc_w, grd_curscreen->sc_h, screenbuffer);
26 }
27
28 int gr_set_mode(u_int32_t mode)
29 {
30         unsigned int w, h;
31         ggi_mode other_mode;    
32
33 #ifdef NOGRAPH
34         return 0;
35 #endif
36         if (mode<=0)
37                 return 0;
38
39         w=SM_W(mode);
40         h=SM_H(mode);
41         
42         
43         gr_palette_clear();
44
45         if(ggiCheckGraphMode(screenvis, w, h, GGI_AUTO, GGI_AUTO, GT_8BIT, &other_mode))
46                 ggiSetMode(screenvis, &other_mode);
47         else
48                 ggiSetGraphMode(screenvis, w, h, GGI_AUTO, GGI_AUTO, GT_8BIT);
49
50         ggiSetFlags(screenvis, GGIFLAG_ASYNC);
51                 
52         if (!ggiDBGetNumBuffers(screenvis))
53                 use_directbuffer = 0;
54         else
55         {       
56                 dbuffer = ggiDBGetBuffer(screenvis, 0);
57                 if (!(dbuffer->type & GGI_DB_SIMPLE_PLB))
58                         use_directbuffer = 0;
59                 else
60                         use_directbuffer = 1;
61         }
62
63         memset(grd_curscreen, 0, sizeof(grs_screen));
64
65         grd_curscreen->sc_mode = mode;
66         grd_curscreen->sc_w = w;
67         grd_curscreen->sc_h = h;
68         grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4);
69         grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0;
70         grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0;
71         grd_curscreen->sc_canvas.cv_bitmap.bm_w = w;
72         grd_curscreen->sc_canvas.cv_bitmap.bm_h = h;
73         grd_curscreen->sc_canvas.cv_bitmap.bm_type = BM_LINEAR;
74
75         if (use_directbuffer)
76         {
77                 grd_curscreen->sc_canvas.cv_bitmap.bm_data = dbuffer->write;
78                 grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = dbuffer->buffer.plb.stride;
79         }
80         else
81         {
82                 d_free(screenbuffer);
83                 screenbuffer = d_malloc (w * h);
84                 grd_curscreen->sc_canvas.cv_bitmap.bm_data = screenbuffer;
85                 grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = w;
86         }
87
88         gr_set_current_canvas(NULL);
89         
90         gamefont_choose_game_font(w,h);
91         
92         return 0;
93 }
94
95 int gr_init(int mode)
96 {
97         int retcode;
98         // Only do this function once!
99         if (gr_installed==1)
100                 return -1;
101         MALLOC(grd_curscreen,grs_screen, 1);
102         memset(grd_curscreen, 0, sizeof(grs_screen));
103         
104         ggiInit();
105         screenvis = ggiOpen(NULL);
106
107         if ((retcode=gr_set_mode(mode)))
108                 return retcode;
109         
110         grd_curscreen->sc_canvas.cv_color = 0;
111         grd_curscreen->sc_canvas.cv_drawmode = 0;
112         grd_curscreen->sc_canvas.cv_font = NULL;
113         grd_curscreen->sc_canvas.cv_font_fg_color = 0;
114         grd_curscreen->sc_canvas.cv_font_bg_color = 0;
115         gr_set_current_canvas( &grd_curscreen->sc_canvas );
116
117         gr_installed = 1;
118         atexit(gr_close);
119         return 0;
120 }
121
122 void gr_close ()
123 {
124         if (gr_installed==1)
125         {
126                 ggiClose(screenvis);
127                 ggiExit();
128                 gr_installed = 0;
129                 d_free(grd_curscreen);
130         }
131 }
132
133 // Palette functions follow.
134
135 static int last_r=0, last_g=0, last_b=0;
136
137 void gr_palette_clear()
138 {
139         ggi_color *colors = calloc (256, sizeof(ggi_color));
140
141         ggiSetPalette (screenvis, 0, 256, colors);
142
143         gr_palette_faded_out = 1;
144 }
145
146
147 void gr_palette_step_up (int r, int g, int b)
148 {
149         int i;
150         ubyte *p = gr_palette;
151         int temp;
152
153         ggi_color colors[256];
154
155         if (gr_palette_faded_out) return;
156
157         if ((r==last_r) && (g==last_g) && (b==last_b)) return;
158
159         last_r = r;
160         last_g = g;
161         last_b = b;
162
163         for (i = 0; i < 256; i++)
164         {
165                 temp = (int)(*p++) + r + gr_palette_gamma;
166                 if (temp<0) temp=0;
167                 else if (temp>63) temp=63;
168                 colors[i].r = temp * 0x3ff;
169                 temp = (int)(*p++) + g + gr_palette_gamma;
170                 if (temp<0) temp=0;
171                 else if (temp>63) temp=63;
172                 colors[i].g = temp * 0x3ff;
173                 temp = (int)(*p++) + b + gr_palette_gamma;
174                 if (temp<0) temp=0;
175                 else if (temp>63) temp=63;
176                 colors[i].b = temp * 0x3ff;
177         }
178         ggiSetPalette (screenvis, 0, 256, colors);
179 }
180
181 //added on 980913 by adb to fix palette problems
182 // need a min without side effects...
183 #undef min
184 static inline int min(int x, int y) { return x < y ? x : y; }
185 //end changes by adb
186
187 void gr_palette_load (ubyte *pal)       
188 {
189         int i, j;
190         ggi_color colors[256];
191
192         for (i = 0, j = 0; j < 256; j++)
193         {
194                 gr_current_pal[i] = pal[i];
195                 if (gr_current_pal[i] > 63) gr_current_pal[i] = 63;
196                 colors[j].r = (min(gr_current_pal[i] + gr_palette_gamma, 63)) * 0x3ff;
197                 i++;
198                 gr_current_pal[i] = pal[i];
199                 if (gr_current_pal[i] > 63) gr_current_pal[i] = 63;
200                 colors[j].g = (min(gr_current_pal[i] + gr_palette_gamma, 63)) * 0x3ff;
201                 i++;
202                 gr_current_pal[i] = pal[i];
203                 if (gr_current_pal[i] > 63) gr_current_pal[i] = 63;
204                 colors[j].b = (min(gr_current_pal[i] + gr_palette_gamma, 63)) * 0x3ff;
205                 i++;
206         }
207
208         ggiSetPalette(screenvis, 0, 256, colors);
209
210         gr_palette_faded_out = 0;
211         init_computed_colors();
212 }
213
214
215
216 int gr_palette_fade_out (ubyte *pal, int nsteps, int allow_keys)
217 {
218         int i, j, k;
219         ubyte c;
220         fix fade_palette[768];
221         fix fade_palette_delta[768];
222
223         ggi_color fade_colors[256];
224
225         if (gr_palette_faded_out) return 0;
226
227         if (pal==NULL) pal=gr_current_pal;
228
229         for (i=0; i<768; i++)
230         {
231                 gr_current_pal[i] = pal[i];
232                 fade_palette[i] = i2f(pal[i]);
233                 fade_palette_delta[i] = fade_palette[i] / nsteps;
234         }
235
236         for (j=0; j<nsteps; j++)
237         {
238                 for (i = 0; i < 768; i++)
239                 {
240                         fade_palette[i] -= fade_palette_delta[i];
241                         if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma))
242                                 fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
243                 }
244                 for (i = 0, k = 0; k < 256; k++)
245                 {
246                         c = f2i(fade_palette[i++]);
247                         if (c > 63) c = 63;
248                         fade_colors[k].r = c * 0x3ff;
249                         c = f2i(fade_palette[i++]);
250                         if (c > 63) c = 63;
251                         fade_colors[k].g = c * 0x3ff;
252                         c = f2i(fade_palette[i++]);
253                         if (c > 63) c = 63;
254                         fade_colors[k].b = c * 0x3ff;
255                 }
256                 ggiSetPalette (screenvis, 0, 256, fade_colors);
257                 gr_update();
258         }
259
260         gr_palette_faded_out = 1;
261         return 0;
262 }
263
264
265
266 int gr_palette_fade_in (ubyte *pal, int nsteps, int allow_keys)
267 {
268         int i, j, k;
269         ubyte c;
270         fix fade_palette[768];
271         fix fade_palette_delta[768];
272
273         ggi_color fade_colors[256];
274
275         if (!gr_palette_faded_out) return 0;
276
277         for (i=0; i<768; i++)
278         {
279                 gr_current_pal[i] = pal[i];
280                 fade_palette[i] = 0;
281                 fade_palette_delta[i] = i2f(pal[i] + gr_palette_gamma) / nsteps;
282         }
283
284         for (j=0; j<nsteps; j++ )
285         {
286                 for (i = 0; i < 768; i++ )
287                 {
288                         fade_palette[i] += fade_palette_delta[i];
289                         if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma))
290                                 fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
291                 }
292                 for (i = 0, k = 0; k < 256; k++)
293                 {
294                         c = f2i(fade_palette[i++]);
295                         if (c > 63) c = 63;
296                         fade_colors[k].r = c * 0x3ff;
297                         c = f2i(fade_palette[i++]);
298                         if (c > 63) c = 63;
299                         fade_colors[k].g = c * 0x3ff;
300                         c = f2i(fade_palette[i++]);
301                         if (c > 63) c = 63;
302                         fade_colors[k].b = c * 0x3ff;
303                 }
304                 ggiSetPalette (screenvis, 0, 256, fade_colors);
305                 gr_update();
306         }
307
308         gr_palette_faded_out = 0;
309         return 0;
310 }
311
312
313
314 void gr_palette_read (ubyte *pal)
315 {
316         ggi_color colors[256];
317         int i, j;
318
319         ggiGetPalette (screenvis, 0, 256, colors);
320
321         for (i = 0, j = 0; i < 256; i++)
322         {
323                 pal[j++] = colors[i].r / 0x3ff;
324                 pal[j++] = colors[i].g / 0x3ff;
325                 pal[j++] = colors[i].b / 0x3ff;
326         }
327 }
328