Fullscreen toggle added to screen res menu
[btb/d2x.git] / video / sdl_gr.c
1 /*
2  * $Source: /cvs/cvsroot/d2x/video/sdl_gr.c,v $
3  * $Revision: 1.4 $
4  * $Author: bradleyb $
5  * $Date: 2001-01-31 13:59:23 $
6  *
7  * SDL video functions.
8  *
9  * $Log: not supported by cvs2svn $
10  * Revision 1.3  2001/01/29 13:47:52  bradleyb
11  * Fixed build, some minor cleanups.
12  *
13  */
14
15 #ifdef HAVE_CONFIG_H
16 #include <conf.h>
17 #endif
18
19 #include <stdlib.h>
20 #include <string.h>
21 #include <SDL/SDL.h>
22 #include "gr.h"
23 #include "grdef.h"
24 #include "palette.h"
25 #include "u_mem.h"
26 #include "error.h"
27 //added on 9/30/98 by Matt Mueller to set the title bar.  Woohoo!
28 #include "vers_id.h"
29 //end addition -MM
30
31 #include "gamefont.h"
32
33 //added 10/05/98 by Matt Mueller - make fullscreen mode optional
34 #include "args.h"
35
36 int sdl_video_flags = SDL_SWSURFACE | SDL_HWPALETTE;
37 char checkvidmodeok=0;
38 //end addition -MM
39
40 SDL_Surface *screen;
41
42 int gr_installed = 0;
43
44 //added 05/19/99 Matt Mueller - locking stuff
45 #ifdef GR_LOCK
46 #include "checker.h"
47 #ifdef TEST_GR_LOCK
48 int gr_testlocklevel=0;
49 #endif
50 inline void gr_dolock(const char *file,int line) {
51         gr_dotestlock();
52         if ( gr_testlocklevel==1 && SDL_MUSTLOCK(screen) ) {
53 #ifdef __CHECKER__
54                 chcksetwritable(screen.pixels,screen->w*screen->h*screen->format->BytesPerPixel);
55 #endif
56                 if ( SDL_LockSurface(screen) < 0 )Error("could not lock screen (%s:%i)\n",file,line);
57         }
58 }
59 inline void gr_dounlock(void) {
60         gr_dotestunlock();
61         if (gr_testlocklevel==0 && SDL_MUSTLOCK(screen) ) {
62                 SDL_UnlockSurface(screen);
63 #ifdef __CHECKER__
64                 chcksetunwritable(screen.pixels,screen->w*screen->h*screen->format->BytesPerPixel);
65 #endif
66         }
67 }
68 #endif
69 //end addition -MM
70
71 void gr_palette_clear(); // Function prototype for gr_init;
72
73
74 void gr_update()
75 {
76         //added 05/19/99 Matt Mueller - locking stuff
77 //
78 //gr_testunlock();
79         //end addition -MM
80  SDL_UpdateRect(screen,0,0,0,0);
81 }
82
83 extern int VGA_current_mode; // DPH: kludge - remove at all costs
84
85 int gr_set_mode(u_int32_t mode)
86 {
87         int w,h;
88 #ifdef NOGRAPH
89         return 0;
90 #endif
91
92         if (mode<=0)
93                 return 0;
94
95         w=SM_W(mode);
96         h=SM_H(mode);
97         VGA_current_mode = mode;
98         
99         if (screen != NULL) gr_palette_clear();
100
101 //added on 11/06/98 by Matt Mueller to set the title bar. (moved from below)
102 //sekmu: might wanna copy this litte blurb to one of the text files or something
103 //we want to set it here so that X window manager "Style" type commands work
104 //for example, in fvwm2 or fvwm95:
105 //Style "D1X*"  NoTitle, NoHandles, BorderWidth 0
106 //if you can't use -fullscreen like me (crashes X), this is a big help in
107 //getting the window centered correctly (if you use SmartPlacement)
108         SDL_WM_SetCaption("D2x", "Descent II");
109 //end addition -MM
110
111 //edited 10/05/98 by Matt Mueller - make fullscreen mode optional
112           // changed by adb on 980913: added SDL_HWPALETTE (should be option?)
113         // changed by someone on 980923 to add SDL_FULLSCREEN
114         if(!checkvidmodeok || SDL_VideoModeOK(w,h,8,sdl_video_flags)){
115           screen = SDL_SetVideoMode(w, h, 8, sdl_video_flags);
116         } else {
117           screen=NULL;
118         }
119         // end changes by someone
120         // end changes by adb
121 //end edit -MM
122         if (screen == NULL) {
123            Error("Could not set %dx%dx8 video mode\n",w,h);
124            exit(1);
125         }
126         memset( grd_curscreen, 0, sizeof(grs_screen));
127         grd_curscreen->sc_mode = mode;
128         grd_curscreen->sc_w = w;
129         grd_curscreen->sc_h = h;
130         grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*3,grd_curscreen->sc_h*4);
131         grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0;
132         grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0;
133         grd_curscreen->sc_canvas.cv_bitmap.bm_w = w;
134         grd_curscreen->sc_canvas.cv_bitmap.bm_h = h;
135         grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = screen->pitch;
136         grd_curscreen->sc_canvas.cv_bitmap.bm_type = BM_LINEAR;
137         grd_curscreen->sc_canvas.cv_bitmap.bm_data = (unsigned char *)screen->pixels;
138         gr_set_current_canvas(NULL);
139         //gr_enable_default_palette_loading();
140
141 //added on 9/30/98 by Matt Mueller to hide the mouse if its over the game window
142         SDL_ShowCursor(0);
143 //end addition -MM
144 //--moved up--added on 9/30/98 by Matt Mueller to set the title bar.  Woohoo!
145 //--moved up--  SDL_WM_SetCaption(DESCENT_VERSION " " D1X_DATE, NULL);
146 //--moved up--end addition -MM
147
148 //      gamefont_choose_game_font(w,h);
149         return 0;
150 }
151
152 int gr_check_fullscreen(void){
153         return (sdl_video_flags & SDL_FULLSCREEN)?1:0;
154 }
155
156 int gr_toggle_fullscreen(void){
157         sdl_video_flags^=SDL_FULLSCREEN;
158 /*
159         grd_curscreen->sc_mode=0;//hack to get it to reset screen mode
160 */
161         SDL_WM_ToggleFullScreen(screen);
162         return (sdl_video_flags & SDL_FULLSCREEN)?1:0;
163 }
164
165 int gr_init(void)
166 {
167  int retcode;
168  int mode = SM(640,480);
169         // Only do this function once!
170         if (gr_installed==1)
171                 return -1;
172
173         if (SDL_Init(SDL_INIT_VIDEO) < 0)
174         {
175                 Error("SDL library video initialisation failed: %s.",SDL_GetError());
176         }
177         MALLOC( grd_curscreen,grs_screen,1 );
178         memset( grd_curscreen, 0, sizeof(grs_screen));
179
180 //added 10/05/98 by Matt Mueller - make fullscreen mode optional
181         if (FindArg("-fullscreen"))
182              sdl_video_flags|=SDL_FULLSCREEN;
183 //end addition -MM
184         //added 05/19/99 Matt Mueller - make HW surface optional
185         if (FindArg("-hwsurface"))
186              sdl_video_flags|=SDL_HWSURFACE;
187         //end addition -MM
188         if (FindArg("-nosdlvidmodecheck"))
189                 checkvidmodeok=0;
190         
191         // Set the mode.
192         if ((retcode=gr_set_mode(mode)))
193         {
194                 return retcode;
195         }
196         grd_curscreen->sc_canvas.cv_color = 0;
197         grd_curscreen->sc_canvas.cv_drawmode = 0;
198         grd_curscreen->sc_canvas.cv_font = NULL;
199         grd_curscreen->sc_canvas.cv_font_fg_color = 0;
200         grd_curscreen->sc_canvas.cv_font_bg_color = 0;
201         gr_set_current_canvas( &grd_curscreen->sc_canvas );
202
203         gr_installed = 1;
204         // added on 980913 by adb to add cleanup
205         atexit(gr_close);
206         // end changes by adb
207
208         return 0;
209 }
210
211 void gr_close()
212 {
213         if (gr_installed==1)
214         {
215                 gr_installed = 0;
216                 d_free(grd_curscreen);
217         }
218 }
219
220 // Palette functions follow.
221
222 static int last_r=0, last_g=0, last_b=0;
223
224 void gr_palette_clear()
225 {
226  SDL_Palette *palette;
227  SDL_Color colors[256];
228  int ncolors;
229
230  palette = screen->format->palette;
231
232  if (palette == NULL) {
233     return; // Display is not palettised
234  }
235
236  ncolors = palette->ncolors;
237  memset(colors, 0, ncolors * sizeof(SDL_Color));
238
239  SDL_SetColors(screen, colors, 0, 256);
240
241  gr_palette_faded_out = 1;
242 }
243
244
245 void gr_palette_step_up( int r, int g, int b )
246 {
247  int i;
248  ubyte *p = gr_palette;
249  int temp;
250
251  SDL_Palette *palette;
252  SDL_Color colors[256];
253
254  if (gr_palette_faded_out) return;
255
256  if ( (r==last_r) && (g==last_g) && (b==last_b) ) return;
257
258  last_r = r;
259  last_g = g;
260  last_b = b;
261
262  palette = screen->format->palette;
263
264  if (palette == NULL) {
265     return; // Display is not palettised
266  }
267
268  for (i=0; i<256; i++) {
269    temp = (int)(*p++) + r + gr_palette_gamma;
270    if (temp<0) temp=0;
271    else if (temp>63) temp=63;
272    colors[i].r = temp * 4;
273    temp = (int)(*p++) + g + gr_palette_gamma;
274    if (temp<0) temp=0;
275    else if (temp>63) temp=63;
276    colors[i].g = temp * 4;
277    temp = (int)(*p++) + b + gr_palette_gamma;
278    if (temp<0) temp=0;
279    else if (temp>63) temp=63;
280    colors[i].b = temp * 4;
281  }
282
283  SDL_SetColors(screen, colors, 0, 256);
284 }
285
286 //added on 980913 by adb to fix palette problems
287 // need a min without side effects...
288 #undef min
289 static inline int min(int x, int y) { return x < y ? x : y; }
290 //end changes by adb
291
292 void gr_palette_load( ubyte *pal )      
293 {
294  int i, j;
295  SDL_Palette *palette;
296  SDL_Color colors[256];
297
298  for (i=0; i<768; i++ ) {
299      gr_current_pal[i] = pal[i];
300      if (gr_current_pal[i] > 63) gr_current_pal[i] = 63;
301  }
302
303  palette = screen->format->palette;
304
305  if (palette == NULL) {
306     return; // Display is not palettised
307  }
308
309  for (i = 0, j = 0; j < 256; j++) {
310      //changed on 980913 by adb to fix palette problems
311      colors[j].r = (min(gr_current_pal[i++] + gr_palette_gamma, 63)) * 4;
312      colors[j].g = (min(gr_current_pal[i++] + gr_palette_gamma, 63)) * 4;
313      colors[j].b = (min(gr_current_pal[i++] + gr_palette_gamma, 63)) * 4;
314      //end changes by adb
315  }
316  SDL_SetColors(screen, colors, 0, 256);
317
318  gr_palette_faded_out = 0;
319  init_computed_colors();
320 }
321
322
323
324 int gr_palette_fade_out(ubyte *pal, int nsteps, int allow_keys)
325 {
326  int i, j, k;
327  ubyte c;
328  fix fade_palette[768];
329  fix fade_palette_delta[768];
330
331  SDL_Palette *palette;
332  SDL_Color fade_colors[256];
333
334  if (gr_palette_faded_out) return 0;
335
336  palette = screen->format->palette;
337  if (palette == NULL) {
338     return -1; // Display is not palettised
339  }
340
341  if (pal==NULL) pal=gr_current_pal;
342
343  for (i=0; i<768; i++ ) {
344      gr_current_pal[i] = pal[i];
345      fade_palette[i] = i2f(pal[i]);
346      fade_palette_delta[i] = fade_palette[i] / nsteps;
347  }
348  for (j=0; j<nsteps; j++ )      {
349      for (i=0, k = 0; k<256; k++ )      {
350          fade_palette[i] -= fade_palette_delta[i];
351          if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma) )
352             fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
353          c = f2i(fade_palette[i]);
354          if (c > 63) c = 63;
355          fade_colors[k].r = c * 4;
356          i++;
357
358          fade_palette[i] -= fade_palette_delta[i];
359          if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma) )
360             fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
361          c = f2i(fade_palette[i]);
362          if (c > 63) c = 63;
363          fade_colors[k].g = c * 4;
364          i++;
365
366          fade_palette[i] -= fade_palette_delta[i];
367          if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma) )
368             fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
369          c = f2i(fade_palette[i]);
370          if (c > 63) c = 63;
371          fade_colors[k].b = c * 4;
372          i++;
373      }
374
375   SDL_SetColors(screen, fade_colors, 0, 256);
376  }
377
378  gr_palette_faded_out = 1;
379  return 0;
380 }
381
382
383
384 int gr_palette_fade_in(ubyte *pal, int nsteps, int allow_keys)
385 {
386  int i, j, k, ncolors;
387  ubyte c;
388  fix fade_palette[768];
389  fix fade_palette_delta[768];
390
391  SDL_Palette *palette;
392  SDL_Color fade_colors[256];
393
394  if (!gr_palette_faded_out) return 0;
395
396  palette = screen->format->palette;
397
398  if (palette == NULL) {
399     return -1; // Display is not palettised
400  }
401
402  ncolors = palette->ncolors;
403
404  for (i=0; i<768; i++ ) {
405      gr_current_pal[i] = pal[i];
406      fade_palette[i] = 0;
407      fade_palette_delta[i] = i2f(pal[i]) / nsteps;
408  }
409
410  for (j=0; j<nsteps; j++ )      {
411      for (i=0, k = 0; k<256; k++ )      {
412          fade_palette[i] += fade_palette_delta[i];
413          if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma) )
414             fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
415          c = f2i(fade_palette[i]);
416          if (c > 63) c = 63;
417          fade_colors[k].r = c * 4;
418          i++;
419
420          fade_palette[i] += fade_palette_delta[i];
421          if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma) )
422             fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
423          c = f2i(fade_palette[i]);
424          if (c > 63) c = 63;
425          fade_colors[k].g = c * 4;
426          i++;
427
428          fade_palette[i] += fade_palette_delta[i];
429          if (fade_palette[i] > i2f(pal[i] + gr_palette_gamma) )
430             fade_palette[i] = i2f(pal[i] + gr_palette_gamma);
431          c = f2i(fade_palette[i]);
432          if (c > 63) c = 63;
433          fade_colors[k].b = c * 4;
434          i++;
435      }
436
437   SDL_SetColors(screen, fade_colors, 0, 256);
438  }
439  //added on 980913 by adb to fix palette problems
440  gr_palette_load(pal);
441  //end changes by adb
442
443  gr_palette_faded_out = 0;
444  return 0;
445 }
446
447
448
449 void gr_palette_read(ubyte * pal)
450 {
451  SDL_Palette *palette;
452  int i, j;
453
454  palette = screen->format->palette;
455
456  if (palette == NULL) {
457     return; // Display is not palettised
458  }
459
460  for (i = 0, j=0; i < 256; i++) {
461      pal[j++] = palette->colors[i].r / 4;
462      pal[j++] = palette->colors[i].g / 4;
463      pal[j++] = palette->colors[i].b / 4;
464  }
465 }