/* * * SDL video functions. * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include #include #include #include "gr.h" #include "grdef.h" #include "palette.h" #include "u_mem.h" #include "error.h" #include "vers_id.h" #include "gamefont.h" #include "args.h" #include "config.h" int sdl_video_flags = SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF; SDL_Surface *screen; int gr_installed = 0; void gr_flip() { SDL_Flip(screen); } // Set the buffer to draw to. 0 is front, 1 is back // With SDL, can't use it without resetting the video mode void gr_set_draw_buffer(int buf) { buf = buf; } int gr_set_mode(u_int32_t mode) { unsigned int w, h; if (mode<=0) return 0; w=SM_W(mode); h=SM_H(mode); screen=NULL; SDL_WM_SetCaption(DESCENT_VERSION, "Descent II"); if(SDL_VideoModeOK(w,h,8,sdl_video_flags)) { screen=SDL_SetVideoMode(w, h, 8, sdl_video_flags); } else { con_printf(CON_URGENT,"Cannot set %ix%i. Fallback to 640x480\n",w,h); w=640; h=480; Game_screen_mode=mode=SM(w,h); screen=SDL_SetVideoMode(w, h, 8, sdl_video_flags); } if (screen == NULL) { Error("Could not set %dx%dx8 video mode\n",w,h); exit(1); } memset( grd_curscreen, 0, sizeof(grs_screen)); grd_curscreen->sc_mode = mode; grd_curscreen->sc_w = w; grd_curscreen->sc_h = h; grd_curscreen->sc_aspect = fixdiv(grd_curscreen->sc_w*GameCfg.AspectX,grd_curscreen->sc_h*GameCfg.AspectY); grd_curscreen->sc_canvas.cv_bitmap.bm_x = 0; grd_curscreen->sc_canvas.cv_bitmap.bm_y = 0; grd_curscreen->sc_canvas.cv_bitmap.bm_w = w; grd_curscreen->sc_canvas.cv_bitmap.bm_h = h; grd_curscreen->sc_canvas.cv_bitmap.bm_rowsize = screen->pitch; grd_curscreen->sc_canvas.cv_bitmap.bm_type = BM_LINEAR; grd_curscreen->sc_canvas.cv_bitmap.bm_data = (unsigned char *)screen->pixels; gr_set_current_canvas(NULL); SDL_ShowCursor(0); gamefont_choose_game_font(w,h); gr_palette_load(gr_palette); gr_remap_color_fonts(); gr_remap_mono_fonts(); return 0; } int gr_check_fullscreen(void) { return (sdl_video_flags & SDL_FULLSCREEN)?1:0; } int gr_toggle_fullscreen(void) { gr_remap_color_fonts(); gr_remap_mono_fonts(); sdl_video_flags^=SDL_FULLSCREEN; SDL_WM_ToggleFullScreen(screen); GameCfg.WindowMode = (sdl_video_flags & SDL_FULLSCREEN)?0:1; return (sdl_video_flags & SDL_FULLSCREEN)?1:0; } void gr_set_attributes(void) { } int gr_init(int mode) { int retcode; // Only do this function once! if (gr_installed==1) return -1; if (SDL_Init(SDL_INIT_VIDEO) < 0) { Error("SDL library video initialisation failed: %s.",SDL_GetError()); } MALLOC( grd_curscreen,grs_screen,1 ); memset( grd_curscreen, 0, sizeof(grs_screen)); if (!GameCfg.WindowMode && !GameArg.SysWindow) sdl_video_flags|=SDL_FULLSCREEN; if (GameArg.DbgSdlHWSurface) sdl_video_flags|=SDL_HWSURFACE; if (GameArg.DbgSdlASyncBlit) sdl_video_flags|=SDL_ASYNCBLIT; // Set the mode. if ((retcode=gr_set_mode(mode))) return retcode; grd_curscreen->sc_canvas.cv_color = 0; grd_curscreen->sc_canvas.cv_drawmode = 0; grd_curscreen->sc_canvas.cv_font = NULL; grd_curscreen->sc_canvas.cv_font_fg_color = 0; grd_curscreen->sc_canvas.cv_font_bg_color = 0; gr_set_current_canvas( &grd_curscreen->sc_canvas ); gr_installed = 1; return 0; } void gr_close() { if (gr_installed==1) { gr_installed = 0; d_free(grd_curscreen); SDL_ShowCursor(1); } } // Palette functions follow. static int last_r=0, last_g=0, last_b=0; void gr_palette_step_up( int r, int g, int b ) { int i; ubyte *p = gr_palette; int temp; SDL_Palette *palette; SDL_Color colors[256]; if ( (r==last_r) && (g==last_g) && (b==last_b) ) return; last_r = r; last_g = g; last_b = b; palette = screen->format->palette; if (palette == NULL) return; // Display is not palettised for (i=0; i<256; i++) { temp = (int)(*p++) + r + gr_palette_gamma; if (temp<0) temp=0; else if (temp>63) temp=63; colors[i].r = temp * 4; temp = (int)(*p++) + g + gr_palette_gamma; if (temp<0) temp=0; else if (temp>63) temp=63; colors[i].g = temp * 4; temp = (int)(*p++) + b + gr_palette_gamma; if (temp<0) temp=0; else if (temp>63) temp=63; colors[i].b = temp * 4; } SDL_SetColors(screen, colors, 0, 256); } #undef min static inline int min(int x, int y) { return x < y ? x : y; } void gr_palette_load( ubyte *pal ) { int i, j; SDL_Palette *palette; SDL_Color colors[256]; ubyte gamma[64]; if (memcmp(pal,gr_current_pal,768)) SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 0, 0, 0)); for (i=0; i<768; i++ ) { gr_current_pal[i] = pal[i]; if (gr_current_pal[i] > 63) gr_current_pal[i] = 63; } if (screen == NULL) return; palette = screen->format->palette; if (palette == NULL) return; // Display is not palettised for (i=0;i<64;i++) gamma[i] = (int)((pow(((double)(14)/(double)(32)), 1.0)*i) + 0.5); for (i = 0, j = 0; j < 256; j++) { int c; c = gr_find_closest_color(gamma[gr_palette[j*3]],gamma[gr_palette[j*3+1]],gamma[gr_palette[j*3+2]]); gr_fade_table[14*256+j] = c; colors[j].r = (min(gr_current_pal[i++] + gr_palette_gamma, 63)) * 4; colors[j].g = (min(gr_current_pal[i++] + gr_palette_gamma, 63)) * 4; colors[j].b = (min(gr_current_pal[i++] + gr_palette_gamma, 63)) * 4; } SDL_SetColors(screen, colors, 0, 256); init_computed_colors(); gr_remap_color_fonts(); gr_remap_mono_fonts(); } void gr_palette_read(ubyte * pal) { SDL_Palette *palette; int i, j; palette = screen->format->palette; if (palette == NULL) return; // Display is not palettised for (i = 0, j=0; i < 256; i++) { pal[j++] = palette->colors[i].r / 4; pal[j++] = palette->colors[i].g / 4; pal[j++] = palette->colors[i].b / 4; } }