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