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