Esempio n. 1
0
bool allegro_init() {
	cpu_capabilities = 0;
	notes << "Allegro: ";
	
	if(cfgUseSSE && SDL_HasSSE()) cpu_capabilities |= CPU_SSE;
	if(cfgUseMMX && SDL_HasMMX()) cpu_capabilities |= CPU_MMX;
	if(cfgUseMMXExt && SDL_HasMMXExt()) cpu_capabilities |= CPU_MMXPLUS;
	
	if(cpu_capabilities & CPU_SSE) notes << "SSE, "; else notes << "no SSE, ";
	if(cpu_capabilities & CPU_MMX) notes << "MMX, "; else notes << "no MMX, ";
	if(cpu_capabilities & CPU_MMXPLUS) notes << "MMXExt"; else notes << "no MMXExt";
	notes << endl;
	
	screen = create_bitmap_ex(32, SCREEN_W, SCREEN_H);
	notes << "Allegro screen format:" << endl;
	DumpPixelFormat(screen->surf->format);
	
	return true;
}
Esempio n. 2
0
/* This function does not reset the video mode if it fails, because we might be trying
 * yet another video mode, so we'd just thrash the display.  On fatal error,
 * LowLevelWindow_Win32::~LowLevelWindow_Win32 will call Shutdown(). */
CString LowLevelWindow_Win32::TryVideoMode( RageDisplay::VideoModeParams p, bool &bNewDeviceOut )
{
    ASSERT_M( p.bpp == 16 || p.bpp == 32, ssprintf("%i", p.bpp) );

    bNewDeviceOut = false;

    /* We're only allowed to change the pixel format of a window exactly once. */
    bool bCanSetPixelFormat = true;

    /* Do we have an old window? */
    if( GraphicsWindow::GetHwnd() == NULL )
    {
        /* No.  Always create and show the window before changing the video mode.
         * Otherwise, some other window may have focus, and changing the video mode will
         * cause that window to be resized. */
        GraphicsWindow::CreateGraphicsWindow( p );
        GraphicsWindow::ConfigureGraphicsWindow( p );
    } else {
        /* We already have a window.  Assume that it's pixel format has already been
         * set. */
        LOG->Trace("Setting new window, can't reuse old");
        bCanSetPixelFormat = false;
    }

    ASSERT( GraphicsWindow::GetHwnd() );

    /* Set the display mode: switch to a fullscreen mode or revert to windowed mode. */
    LOG->Trace("SetScreenMode ...");
    CString sErr = GraphicsWindow::SetScreenMode( p );
    if( !sErr.empty() )
        return sErr;

    PIXELFORMATDESCRIPTOR PixelFormat;
    int iPixelFormat = ChooseWindowPixelFormat( p, &PixelFormat );
    if( iPixelFormat == 0 )
    {
        /* Destroy the window. */
        DestroyGraphicsWindowAndOpenGLContext();
        return "Pixel format not found";
    }

    bool bNeedToSetPixelFormat = false;
    {
        /* We'll need to recreate it if the pixel format is going to change.  We
         * aren't allowed to change the pixel format twice. */
        PIXELFORMATDESCRIPTOR DestPixelFormat;
        ZERO( DestPixelFormat );
        DescribePixelFormat( GraphicsWindow::GetHDC(), iPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &DestPixelFormat );
        if( memcmp( &DestPixelFormat, &g_CurrentPixelFormat, sizeof(PIXELFORMATDESCRIPTOR) ) )
        {
            LOG->Trace("Reset: pixel format changing" );
            bNeedToSetPixelFormat = true;
        }
    }

    if( bNeedToSetPixelFormat && !bCanSetPixelFormat )
    {
        /*
         * The screen mode has changed, so we need to set the pixel format.  If we're
         * not allowed to do so, destroy the window and make a new one.
         *
         * For some reason, if we destroy the old window before creating the new one,
         * the "fullscreen apps go under the taskbar" glitch will happen when we quit.
         * We have to create the new window first.
         */
        LOG->Trace( "Mode requires new pixel format, and we've already set one; resetting OpenGL context" );
        if( g_HGLRC != NULL )
        {
            wglMakeCurrent( NULL, NULL );
            wglDeleteContext( g_HGLRC );
            g_HGLRC = NULL;
        }

        GraphicsWindow::RecreateGraphicsWindow(p);
//		DestroyGraphicsWindowAndOpenGLContext();
//		GraphicsWindow::CreateGraphicsWindow( p );
        bNewDeviceOut = true;
    }

    GraphicsWindow::ConfigureGraphicsWindow( p );

    GraphicsWindow::SetVideoModeParams( p );

    if( bNeedToSetPixelFormat )
    {
        /* Set the pixel format. */
        if( !SetPixelFormat(GraphicsWindow::GetHDC(), iPixelFormat, &PixelFormat) )
        {
            /* Destroy the window. */
            DestroyGraphicsWindowAndOpenGLContext();

            return werr_ssprintf( GetLastError(), "Pixel format failed" );
        }

        DescribePixelFormat( GraphicsWindow::GetHDC(), iPixelFormat, sizeof(g_CurrentPixelFormat), &g_CurrentPixelFormat );

        DumpPixelFormat( g_CurrentPixelFormat );
    }

    if( g_HGLRC == NULL )
    {
        g_HGLRC = wglCreateContext( GraphicsWindow::GetHDC() );
        if ( g_HGLRC == NULL )
        {
            DestroyGraphicsWindowAndOpenGLContext();
            return hr_ssprintf( GetLastError(), "wglCreateContext" );
        }

        if( !wglMakeCurrent( GraphicsWindow::GetHDC(), g_HGLRC ) )
        {
            DestroyGraphicsWindowAndOpenGLContext();
            return hr_ssprintf( GetLastError(), "wglCreateContext" );
        }
    }
    return "";	// we set the video mode successfully
}
Esempio n. 3
0
///////////////////
// Set the video mode
bool SetVideoMode()
{
	if(bDedicated) {
		notes << "SetVideoMode: dedicated mode, ignoring" << endl;
		return true; // ignore this case
	}

	if (!tLXOptions)  {
		warnings << "SetVideoMode: Don't know what video mode to set, ignoring" << endl;
		return false;
	}

	bool resetting = false;

	// Check if already running
	if (VideoPostProcessor::videoSurface())  {
		resetting = true;
		notes << "resetting video mode" << endl;

		// seems to be a win-only problem, it works without problems here under MacOSX
#ifdef WIN32
		// using hw surfaces?
		if ((VideoPostProcessor::videoSurface()->flags & SDL_HWSURFACE) != 0) {
			warnings << "cannot change video mode because current mode uses hardware surfaces" << endl;
			// TODO: you would have to reset whole game, this is not enough!
			// The problem is in all allocated surfaces - they are hardware and when you switch
			// to window, you will most probably get software rendering
			// Also, hardware surfaces are freed from the video memory when reseting video mode
			// so you would first have to convert all surfaces to software and then perform this
			// TODO: in menu_options, restart the game also for fullscreen-change if hw surfaces are currently used
			return false;
		}
#endif
	} else {
		notes << "setting video mode" << endl;
	}

	// uninit first to ensure that the video thread is not running
	VideoPostProcessor::uninit();

	bool HardwareAcceleration = false;
	int DoubleBuf = false;
	int vidflags = 0;

	// it is faster with doublebuffering in hardware accelerated mode
	// also, it seems that it's possible that there are effects in hardware mode with double buf disabled
	// Use doublebuf when hardware accelerated
	if (HardwareAcceleration)
		DoubleBuf = true;

	// Check that the bpp is valid
	switch (tLXOptions->iColourDepth) {
	case 0:
	case 16:
	case 24:
	case 32:
		break;
	default: tLXOptions->iColourDepth = 16;
	}
	notes << "ColorDepth: " << tLXOptions->iColourDepth << endl;

	// BlueBeret's addition (2007): OpenGL support
	bool opengl = tLXOptions->bOpenGL;

	// Initialize the video
	if(tLXOptions->bFullscreen)  {
		vidflags |= SDL_FULLSCREEN;
	}

	if (opengl) {
		vidflags |= SDL_OPENGL;
#ifndef REAL_OPENGL
		vidflags |= SDL_OPENGLBLIT; // SDL will behave like normally
#endif
		// HINT: it seems that with OGL activated, SDL_SetVideoMode will already set the OGL depth size
		// though this main pixel format of the screen surface was always 32 bit for me in OGL under MacOSX
		//#ifndef MACOSX
		/*
		 short colorbitsize = (tLXOptions->iColourDepth==16) ? 5 : 8;
		 SDL_GL_SetAttribute (SDL_GL_RED_SIZE,   colorbitsize);
		 SDL_GL_SetAttribute (SDL_GL_GREEN_SIZE, colorbitsize);
		 SDL_GL_SetAttribute (SDL_GL_BLUE_SIZE,  colorbitsize);
		 SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE, colorbitsize);
		 //SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, tLXOptions->iColourDepth);
		 */
		//#endif
		//SDL_GL_SetAttribute (SDL_GL_ALPHA_SIZE,  8);
		//SDL_GL_SetAttribute (SDL_GL_DEPTH_SIZE, 24);
		//SDL_GL_SetAttribute (SDL_GL_BUFFER_SIZE, 32);
		SDL_GL_SetAttribute (SDL_GL_DOUBLEBUFFER, 1); // always use double buffering in OGL mode
	}	

	if(HardwareAcceleration)  {
		vidflags |= SDL_HWSURFACE | SDL_HWPALETTE | SDL_HWACCEL;
		// Most (perhaps all) systems use software drawing for their stuff (windows etc.)
		// Because of that we cannot have hardware accelerated support in window - OS screen
		// is software surface. How would you make the window hardware, if it's on the screen?
		// Anyway, SDL takes care of this by istelf and disables the flag when needed
		iSurfaceFormat = SDL_HWSURFACE;
	}
	else  {
		vidflags |= SDL_SWSURFACE;
		iSurfaceFormat = SDL_SWSURFACE;
	}

	if(DoubleBuf && !opengl)
		vidflags |= SDL_DOUBLEBUF;

#ifdef WIN32
	UnSubclassWindow();  // Unsubclass before doing anything with the window
#endif


#ifdef WIN32
	// Reset the video subsystem under WIN32, else we get a "Could not reset OpenGL context" error when switching mode
	if (opengl && tLX)  {  // Don't reset when we're setting up the mode for first time (OpenLieroX not yet initialized)
		SDL_QuitSubSystem(SDL_INIT_VIDEO);
		SDL_InitSubSystem(SDL_INIT_VIDEO);
	}
#endif

	VideoPostProcessor::init();
	int scrW = VideoPostProcessor::get()->screenWidth();
	int scrH = VideoPostProcessor::get()->screenHeight();
setvideomode:
	if( SDL_SetVideoMode(scrW, scrH, tLXOptions->iColourDepth, vidflags) == NULL) {
		if (resetting)  {
			errors << "Failed to reset video mode"
					<< " (ErrorMsg: " << SDL_GetError() << "),"
					<< " let's wait a bit and retry" << endl;
			SDL_Delay(500);
			resetting = false;
			goto setvideomode;
		}

		if(tLXOptions->iColourDepth != 0) {
			errors << "Failed to use " << tLXOptions->iColourDepth << " bpp"
					<< " (ErrorMsg: " << SDL_GetError() << "),"
					<< " trying automatic bpp detection ..." << endl;
			tLXOptions->iColourDepth = 0;
			goto setvideomode;
		}

		if(vidflags & SDL_OPENGL) {
			errors << "Failed to use OpenGL"
					<< " (ErrorMsg: " << SDL_GetError() << "),"
					<< " trying without ..." << endl;
			vidflags &= ~(SDL_OPENGL | SDL_OPENGLBLIT | SDL_HWSURFACE | SDL_HWPALETTE | SDL_HWACCEL);
			goto setvideomode;
		}
		
		if(vidflags & SDL_FULLSCREEN) {
			errors << "Failed to set full screen video mode "
					<< scrW << "x" << scrH << "x" << tLXOptions->iColourDepth
					<< " (ErrorMsg: " << SDL_GetError() << "),"
					<< " trying window mode ..." << endl;
			vidflags &= ~SDL_FULLSCREEN;
			goto setvideomode;
		}

		SystemError("Failed to set the video mode " + itoa(scrW) + "x" + itoa(scrH) + "x" + itoa(tLXOptions->iColourDepth) + "\nErrorMsg: " + std::string(SDL_GetError()));
		return false;
	}

	SDL_WM_SetCaption(GetGameVersion().asHumanString().c_str(),NULL);
	SDL_ShowCursor(SDL_DISABLE);

#ifdef WIN32
	// Hint: Reset the mouse state - this should avoid the mouse staying pressed
	GetMouse()->Button = 0;
	GetMouse()->Down = 0;
	GetMouse()->FirstDown = 0;
	GetMouse()->Up = 0;

	if (!tLXOptions->bFullscreen)  {
		SubclassWindow();
	}
#endif

	// Set the change mode flag
	if (tLX)
		tLX->bVideoModeChanged = true;
	
#ifdef REAL_OPENGL	
	if((SDL_GetVideoSurface()->flags & SDL_OPENGL)) {
		static SDL_PixelFormat OGL_format32 =
		{
			NULL, //SDL_Palette *palette;
			32, //Uint8  BitsPerPixel;
			4, //Uint8  BytesPerPixel;
			0, 0, 0, 0, //Uint8  Rloss, Gloss, Bloss, Aloss;
#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
			0, 8, 16, 24, //Uint8  Rshift, Gshift, Bshift, Ashift;
			0x000000FF,
			0x0000FF00,
			0x00FF0000,
			0xFF000000,
#else
			24, 16, 8, 0, //Uint8  Rshift, Gshift, Bshift, Ashift;
			0xFF000000,
			0x00FF0000,
			0x0000FF00,
			0x000000FF,
#endif
			0, //Uint32 colorkey;
			255 //Uint8  alpha;
		};
		// some GFX stuff in OLX seems very slow when this is used
		// (probably the blit from alpha surf to this format is slow)
	/*	static SDL_PixelFormat OGL_format24 =
		{
			NULL, //SDL_Palette *palette;
			24, //Uint8  BitsPerPixel;
			3, //Uint8  BytesPerPixel;
			0, 0, 0, 0, //Uint8  Rloss, Gloss, Bloss, Aloss;
			#if SDL_BYTEORDER == SDL_LIL_ENDIAN // OpenGL RGBA masks
			0, 8, 16, 0, //Uint8  Rshift, Gshift, Bshift, Ashift;
			0x000000FF,
			0x0000FF00,
			0x00FF0000,
			0x00000000,
			#else
			16, 8, 0, 0, //Uint8  Rshift, Gshift, Bshift, Ashift;
			0x00FF0000,
			0x0000FF00,
			0x000000FF,
			0x00000000,
			#endif
			0, //Uint32 colorkey;
			255 //Uint8  alpha;
		}; */
		//if(tLXOptions->iColourDepth == 32)
			mainPixelFormat = &OGL_format32;
		//else
		//	mainPixelFormat = &OGL_format24;
	} else
#endif		
		mainPixelFormat = SDL_GetVideoSurface()->format;
	DumpPixelFormat(mainPixelFormat);
	if(SDL_GetVideoSurface()->flags & SDL_DOUBLEBUF)
		notes << "using doublebuffering" << endl;

	// Correct the surface format according to SDL
#ifdef REAL_OPENGL
	if(((SDL_GetVideoSurface()->flags & SDL_OPENGL) != 0)) {
		iSurfaceFormat = SDL_SWSURFACE;
	} else
#endif	
	if((SDL_GetVideoSurface()->flags & SDL_HWSURFACE) != 0)  {
		iSurfaceFormat = SDL_HWSURFACE;
		notes << "using hardware surfaces" << endl;
	}
	else {
		iSurfaceFormat = SDL_SWSURFACE; // HINT: under MacOSX, it doesn't seem to make any difference in performance
		if (HardwareAcceleration)
			hints << "Unable to use hardware surfaces, falling back to software." << endl;
		notes << "using software surfaces" << endl;
	}

	if(SDL_GetVideoSurface()->flags & SDL_OPENGL) {
		hints << "using OpenGL" << endl;
		
#ifdef REAL_OPENGL
		OGL_init();
#else
		FillSurface(SDL_GetVideoSurface(), Color(0, 0, 0));		
#endif
	}
	else
		FillSurface(SDL_GetVideoSurface(), Color(0, 0, 0));
	
	VideoPostProcessor::get()->resetVideo();

	notes << "video mode was set successfully" << endl;
	return true;
}