/* $Id: video.cpp,v 1.36.2.3 2006/02/08 19:28:33 chfreund Exp $ */ #include #include "constants.hpp" #include "global.hpp" #include "wopsettings.hpp" #include "video.hpp" #include "loader.hpp" #include "spritesequence.cpp" #include "spriteset.cpp" #include "wopsprites.cpp" /***********************************************************/ int Video::m_BPP; /***********************************************************/ SDL_Surface* Video::getScreen() { return m_screen; } /***********************************************************/ Video::Video() : m_cursor( NULL ) { WopSettings* settings = WopSettings::getInstance(); LOG( 1 ) INFO( "Video::Video: Initializing video\n" ); ASSERT( !SDL_InitSubSystem( SDL_INIT_VIDEO ), "Video::Video: Couldn't initialize video\n" ); LOG( 2 ) INFO( "Video::Video: Setting video mode\n" ); int viewMode = settings->getView(); m_flags = SDL_HWSURFACE | SDL_DOUBLEBUF; if ( viewMode == FULLSCREEN ) { m_flags |= SDL_FULLSCREEN; } else { // C3B6 is Unicode for "o ;-) SDL_WM_SetCaption( "W\xC3\xB6rms of Prey", 0 ); } // detailed SDL information DBG( 2 ) { // Name of video driver char driverName[256]; if ( SDL_VideoDriverName( driverName, 256 ) ) { INFO( "Video::Video: Name of video driver: %s\n", driverName ); } else { INFO( "Video::Video: Could not determine name of video driver\n" ); } // Available video modes SDL_Rect** modes; // Get available fullscreen/hardware modes modes = SDL_ListModes( NULL, m_flags ); // Check is there are any modes available ASSERT( modes, "Video::Video: No modes available!\n" ); // Check if our resolution is restricted if ( modes == reinterpret_cast( -1 ) ) { INFO( "Video::Video: All resolutions available.\n" ); } else { // Print valid modes INFO( "Video::Video: Available Modes\n" ) ; for ( int i = 0; modes[i]; ++i ) INFO( "Video::Video: %d x %d\n", modes[i]->w, modes[i]->h ); } } // check availabily of video mode m_BPP = SDL_VideoModeOK( m_SIZE_X, m_SIZE_Y, 32, m_flags ); ASSERT( m_BPP, "Video::Video: Video mode %d x %d (flags %x) is not available\n", m_SIZE_X, m_SIZE_Y, m_flags ); m_screen = SDL_SetVideoMode( m_SIZE_X, m_SIZE_Y, m_BPP, m_flags ); ASSERT( m_screen, "Video::Video: Couldn't set video mode\n" ); DBG( 2 ) { // Get information about the video format const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo(); INFO( "Video::Video: Information about video mode:\n" ); INFO( "Video::Video: create hardware surfaces: %s\n", videoInfo->hw_available ? "yes" : "no" ); INFO( "Video::Video: window manager available: %s\n", videoInfo->wm_available ? "yes" : "no" ); INFO( "Video::Video: hardware blits accelerated: %s\n", videoInfo->blit_hw ? "yes" : "no" ); INFO( "Video::Video: hardware colorkey blits accelerated: %s\n", videoInfo->blit_hw_CC ? "yes" : "no" ); INFO( "Video::Video: hardware alpha blits accelerated: %s\n", videoInfo->blit_hw_A ? "yes" : "no" ); INFO( "Video::Video: software blits accelerated: %s\n", videoInfo->blit_sw ? "yes" : "no" ); INFO( "Video::Video: software colorkey blits accelerated: %s\n", videoInfo->blit_sw_CC ? "yes" : "no" ); INFO( "Video::Video: software alpha blits accelerated: %s\n", videoInfo->blit_sw_A ? "yes" : "no" ); INFO( "Video::Video: color fills accelerated: %s\n", videoInfo->blit_fill ? "yes" : "no" ); INFO( "Video::Video: total amount of video memory: %d KBytes\n", videoInfo->video_mem ); INFO( "Video::Video: bits per pixel: %d\n", videoInfo->vfmt->BitsPerPixel ); } m_BPP = m_screen->format->BitsPerPixel; SDL_ShowCursor( SDL_DISABLE ); } /***********************************************************/ Video::~Video() { LOG( 1 ) INFO( "Video::~Video: shutting down video\n" ); if( m_cursor != NULL ) SDL_FreeCursor( m_cursor ); SDL_QuitSubSystem( SDL_INIT_VIDEO ); LOG( 1 ) INFO( "Video::~Video: done\n" ); } /***********************************************************/ void Video::setMouseCursor( const char* shape, const int width, const int height, const int hotX, const int hotY ) { const int width8 = (width % 8 == 0) ? width : (width & ~7) + 8; Uint8 image[width8 * height / 8], mask [width8 * height / 8]; int x, y; for( x = 0; x < width8 * height / 8; x++ ) { image[x] = 0; mask[x] = 0; } Uint8 point = 128; int shapePos = 0, dataPos = 0; for( y = 0; y < height; y++ ) { for( x = 0; x < width8; x++ ) { if( x < width ) { switch( shape[shapePos] ) { case '#': image[dataPos] |= point; case '+': mask[dataPos] |= point; break; case '\0': ASSERT( false, "Video::setMouseCursor: shape array too small\n" ); break; default: ; } shapePos++; } if( point == 1 ) { point = 128; dataPos++; } else point >>= 1; } } DBG( 2 ) CHECK( shape[shapePos] == '\0', "Video::setMouseCursor: shape array too large\n" ); m_cursor = SDL_CreateCursor( image, mask, width8, height, hotX, hotY ); SDL_SetCursor( m_cursor ); } /***********************************************************/ void Video::showMouseCursor( const bool show ) { if( show ) SDL_ShowCursor( SDL_ENABLE ); else SDL_ShowCursor( SDL_DISABLE ); } /***********************************************************/ SDL_Surface* Video::loadImage( const char* filename, const bool alpha ) { SDL_Surface *loadedSurf, *optimizedSurf; ASSERT( (loadedSurf = IMG_Load( filename )) != NULL, "Video::loadImage: Couldn't load image '%s'\n", filename ); optimizedSurf = convertSurface(loadedSurf, alpha); SDL_FreeSurface( loadedSurf ); return optimizedSurf; } /***********************************************************/ // convert the given surface to screen pixel format (used by loader) SDL_Surface* Video::convertSurface( SDL_Surface *src, const bool alpha ) { SDL_Surface *optimizedSurf = NULL; if( alpha ) { SDL_SetColorKey( src, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB( src->format, 0, 0, 0 ) ); SDL_SetAlpha( src, SDL_SRCALPHA | SDL_RLEACCEL, 255 ); ASSERT( (optimizedSurf = SDL_DisplayFormatAlpha( src ) ) != NULL, "Video::convertSurface: Couldn't convert alpha image to display format\n"); } else { ASSERT( (optimizedSurf = SDL_DisplayFormat( src ) ) != NULL, "Video::convertSurface: Couldn't convert image to display format\n"); } return optimizedSurf; } /***********************************************************/ void Video::loadSprites( ProgressLog *const progresslog ) { ASSERT( m_sprites.load(progresslog), "Video::loadSprites: no sprites, no game\n" ); } /***********************************************************/ void Video::saveScreenshot( const char* filename ) { INFO( "Video::saveScreenshot: storing schreenshot to '%s'\n", filename ); SDL_SaveBMP( m_screen, filename ); INFO( "Video::saveScreenshot: done\n" ); } void Video::toggleFullscreen() { // check if toggled mode is available at all m_flags ^= SDL_FULLSCREEN; m_BPP = SDL_VideoModeOK( m_SIZE_X, m_SIZE_Y, 32, m_flags ); if ( !m_BPP ) { LOG( 1 ) INFO( "Video::toggleFullscreen: Video mode %d x %d (flags %x) " "is not available\n", m_SIZE_X, m_SIZE_Y, m_flags ); LOG( 1 ) INFO( "Video::toggleFullscreen: preserving current video mode\n" ); return; } // set new mode m_screen = SDL_SetVideoMode( m_SIZE_X, m_SIZE_Y, m_BPP, m_flags ); // if setting new mode fails, try to recover the old mode if ( !m_screen ) { LOG( 1 ) INFO( "Video::toggleFullscreen: toggle failed (%s)\n", SDL_GetError() ); LOG( 1 ) INFO( "Video::toggleFullscreen: switching back to old mode\n" ); m_flags ^= SDL_FULLSCREEN; m_BPP = SDL_VideoModeOK( m_SIZE_X, m_SIZE_Y, 32, m_flags ); ASSERT( m_BPP, "Video::toggleFullscreen: Video mode %d x %d (flags %x) " "is not available, bailing out\n", m_SIZE_X, m_SIZE_Y, m_flags ); m_screen = SDL_SetVideoMode( m_SIZE_X, m_SIZE_Y, m_BPP, m_flags ); ASSERT( m_screen, "Video::toggleFullscreen: could not restore old " "video mode (%s)\n", SDL_GetError() ); } }