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