⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sdl_video.c

📁 Simple DirectMedia Layer - Simple DirectMedia Layer 是一个跨平台的多媒体库设计用来提供快速图形framebuffer和音频驱动。应用MPEG为软件
💻 C
📖 第 1 页 / 共 4 页
字号:
			--i;			*w = sizes[i]->w;			*h = sizes[i]->h;			*BitsPerPixel = SDL_closest_depths[table][b];			supported = 1;		}	}	if ( ! supported ) {		SDL_SetError("No video mode large enough for %dx%d", *w, *h);	}	return(supported);}/* This should probably go somewhere else -- like SDL_surface.c */static void SDL_ClearSurface(SDL_Surface *surface){	Uint32 black;	black = SDL_MapRGB(surface->format, 0, 0, 0);	SDL_FillRect(surface, NULL, black);	if ((surface->flags&SDL_HWSURFACE) && (surface->flags&SDL_DOUBLEBUF)) {		SDL_Flip(surface);		SDL_FillRect(surface, NULL, black);	}	SDL_Flip(surface);}/* * Create a shadow surface suitable for fooling the app. :-) */static void SDL_CreateShadowSurface(int depth){	Uint32 Rmask, Gmask, Bmask;	/* Allocate the shadow surface */	if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {		Rmask = (SDL_VideoSurface->format)->Rmask;		Gmask = (SDL_VideoSurface->format)->Gmask;		Bmask = (SDL_VideoSurface->format)->Bmask;	} else {		Rmask = Gmask = Bmask = 0;	}	SDL_ShadowSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,				SDL_VideoSurface->w, SDL_VideoSurface->h,						depth, Rmask, Gmask, Bmask, 0);	if ( SDL_ShadowSurface == NULL ) {		return;	}	/* 8-bit shadow surfaces report that they have exclusive palette */	if ( SDL_ShadowSurface->format->palette ) {		SDL_ShadowSurface->flags |= SDL_HWPALETTE;		if ( depth == (SDL_VideoSurface->format)->BitsPerPixel ) {			memcpy(SDL_ShadowSurface->format->palette->colors,				SDL_VideoSurface->format->palette->colors,				SDL_VideoSurface->format->palette->ncolors*							sizeof(SDL_Color));		} else {			SDL_DitherColors(			SDL_ShadowSurface->format->palette->colors, depth);		}	}	/* If the video surface is resizable, the shadow should say so */	if ( (SDL_VideoSurface->flags & SDL_RESIZABLE) == SDL_RESIZABLE ) {		SDL_ShadowSurface->flags |= SDL_RESIZABLE;	}	/* If the video surface has no frame, the shadow should say so */	if ( (SDL_VideoSurface->flags & SDL_NOFRAME) == SDL_NOFRAME ) {		SDL_ShadowSurface->flags |= SDL_NOFRAME;	}	/* If the video surface is fullscreen, the shadow should say so */	if ( (SDL_VideoSurface->flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {		SDL_ShadowSurface->flags |= SDL_FULLSCREEN;	}	/* If the video surface is flippable, the shadow should say so */	if ( (SDL_VideoSurface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {		SDL_ShadowSurface->flags |= SDL_DOUBLEBUF;	}	return;}/* * Set the requested video mode, allocating a shadow buffer if necessary. */SDL_Surface * SDL_SetVideoMode (int width, int height, int bpp, Uint32 flags){	SDL_VideoDevice *video, *this;	SDL_Surface *prev_mode, *mode;	int video_w;	int video_h;	int video_bpp;	int is_opengl;	SDL_GrabMode saved_grab;	/* Start up the video driver, if necessary..	   WARNING: This is the only function protected this way!	 */	if ( ! current_video ) {		if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_NOPARACHUTE) < 0 ) {			return(NULL);		}	}	this = video = current_video;	/* Default to the current video bpp */	if ( bpp == 0 ) {		flags |= SDL_ANYFORMAT;		bpp = SDL_VideoSurface->format->BitsPerPixel;	}	/* Get a good video mode, the closest one possible */	video_w = width;	video_h = height;	video_bpp = bpp;	if ( ! SDL_GetVideoMode(&video_w, &video_h, &video_bpp, flags) ) {		return(NULL);	}	/* Check the requested flags */	/* There's no palette in > 8 bits-per-pixel mode */	if ( video_bpp > 8 ) {		flags &= ~SDL_HWPALETTE;	}#if 0	if ( (flags&SDL_FULLSCREEN) != SDL_FULLSCREEN ) {		/* There's no windowed double-buffering */		flags &= ~SDL_DOUBLEBUF;	}#endif	if ( (flags&SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {		/* Use hardware surfaces when double-buffering */		flags |= SDL_HWSURFACE;	}	is_opengl = ( ( flags & SDL_OPENGL ) == SDL_OPENGL );	if ( is_opengl ) {		/* These flags are for 2D video modes only */		flags &= ~(SDL_HWSURFACE|SDL_DOUBLEBUF);	}	/* Reset the keyboard here so event callbacks can run */	SDL_ResetKeyboard();	SDL_ResetMouse();	/* Clean up any previous video mode */	if ( SDL_PublicSurface != NULL ) {		SDL_PublicSurface = NULL;	}	if ( SDL_ShadowSurface != NULL ) {		SDL_Surface *ready_to_go;		ready_to_go = SDL_ShadowSurface;		SDL_ShadowSurface = NULL;		SDL_FreeSurface(ready_to_go);	}	if ( video->physpal ) {		free(video->physpal->colors);		free(video->physpal);		video->physpal = NULL;	}	if( video->gammacols) {	        free(video->gammacols);		video->gammacols = NULL;	}	/* Save the previous grab state and turn off grab for mode switch */	saved_grab = SDL_WM_GrabInputOff();	/* Try to set the video mode, along with offset and clipping */	prev_mode = SDL_VideoSurface;	SDL_LockCursor();	SDL_VideoSurface = NULL;	/* In case it's freed by driver */	mode = video->SetVideoMode(this, prev_mode,video_w,video_h,video_bpp,flags);	if ( mode ) { /* Prevent resize events from mode change */	    SDL_PrivateResize(mode->w, mode->h);	    /* Sam - If we asked for OpenGL mode, and didn't get it, fail */	    if ( is_opengl && !(mode->flags & SDL_OPENGL) ) {		mode = NULL;	    }        }	/*	 * rcg11292000	 * If you try to set an SDL_OPENGL surface, and fail to find a	 * matching  visual, then the next call to SDL_SetVideoMode()	 * will segfault, since  we no longer point to a dummy surface,	 * but rather NULL.	 * Sam 11/29/00	 * WARNING, we need to make sure that the previous mode hasn't	 * already been freed by the video driver.  What do we do in	 * that case?  Should we call SDL_VideoInit() again?	 */	SDL_VideoSurface = (mode != NULL) ? mode : prev_mode;	if ( (mode != NULL) && (!is_opengl) ) {		/* Sanity check */		if ( (mode->w < width) || (mode->h < height) ) {			SDL_SetError("Video mode smaller than requested");			return(NULL);		}		/* If we have a palettized surface, create a default palette */		if ( mode->format->palette ) {	        	SDL_PixelFormat *vf = mode->format;			SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);			video->SetColors(this, 0, vf->palette->ncolors,			                           vf->palette->colors);		}		/* Clear the surface to black */		video->offset_x = 0;		video->offset_y = 0;		mode->offset = 0;		SDL_SetClipRect(mode, NULL);		SDL_ClearSurface(mode);		/* Now adjust the offsets to match the desired mode */		video->offset_x = (mode->w-width)/2;		video->offset_y = (mode->h-height)/2;		mode->offset = video->offset_y*mode->pitch +				video->offset_x*mode->format->BytesPerPixel;#ifdef DEBUG_VIDEO  fprintf(stderr,	"Requested mode: %dx%dx%d, obtained mode %dx%dx%d (offset %d)\n",		width, height, bpp,		mode->w, mode->h, mode->format->BitsPerPixel, mode->offset);#endif		mode->w = width;		mode->h = height;		SDL_SetClipRect(mode, NULL);	}	SDL_ResetCursor();	SDL_UnlockCursor();	/* If we failed setting a video mode, return NULL... (Uh Oh!) */	if ( mode == NULL ) {		return(NULL);	}	/* If there is no window manager, set the SDL_NOFRAME flag */	if ( ! video->info.wm_available ) {		mode->flags |= SDL_NOFRAME;	}	/* Reset the mouse cursor and grab for new video mode */	SDL_SetCursor(NULL);	if ( video->UpdateMouse ) {		video->UpdateMouse(this);	}	SDL_WM_GrabInput(saved_grab);	SDL_GetRelativeMouseState(NULL, NULL); /* Clear first large delta */	/* If we're running OpenGL, make the context current */	if ( (video->screen->flags & SDL_OPENGL) &&	      video->GL_MakeCurrent ) {		if ( video->GL_MakeCurrent(this) < 0 ) {			return(NULL);		}	}	/* Set up a fake SDL surface for OpenGL "blitting" */	if ( (flags & SDL_OPENGLBLIT) == SDL_OPENGLBLIT ) {		/* Load GL functions for performing the texture updates */#ifdef HAVE_OPENGL#define SDL_PROC(ret,func,params) \do { \	video->func = SDL_GL_GetProcAddress(#func); \	if ( ! video->func ) { \		SDL_SetError("Couldn't load GL function: %s\n", #func); \		return(NULL); \	} \} while ( 0 );#include "SDL_glfuncs.h"#undef SDL_PROC			/* Create a software surface for blitting */#ifdef GL_VERSION_1_2		/* If the implementation either supports the packed pixels		   extension, or implements the core OpenGL 1.2 API, it will		   support the GL_UNSIGNED_SHORT_5_6_5 texture format.		 */		if ( (bpp == 16) &&		     (strstr((const char *)video->glGetString(GL_EXTENSIONS), "GL_EXT_packed_pixels") ||		     (atof((const char *)video->glGetString(GL_VERSION)) >= 1.2f))		   ) {			video->is_32bit = 0;			SDL_VideoSurface = SDL_CreateRGBSurface(				flags, 				width, 				height,  				16,				31 << 11,				63 << 5,				31,				0				);		}		else#endif /* OpenGL 1.2 */		{			video->is_32bit = 1;			SDL_VideoSurface = SDL_CreateRGBSurface(				flags, 				width, 				height, 				32, #if SDL_BYTEORDER == SDL_LIL_ENDIAN				0x000000FF,				0x0000FF00,				0x00FF0000,				0xFF000000#else				0xFF000000,				0x00FF0000,				0x0000FF00,				0x000000FF#endif				);		}		if ( ! SDL_VideoSurface ) {			return(NULL);		}		SDL_VideoSurface->flags = mode->flags | SDL_OPENGLBLIT;		/* Free the original video mode surface (is this safe?) */		SDL_FreeSurface(mode);                /* Set the surface completely opaque & white by default */		memset( SDL_VideoSurface->pixels, 255, SDL_VideoSurface->h * SDL_VideoSurface->pitch );		video->glGenTextures( 1, &video->texture );		video->glBindTexture( GL_TEXTURE_2D, video->texture );		video->glTexImage2D(			GL_TEXTURE_2D,			0,			video->is_32bit ? GL_RGBA : GL_RGB,			256,			256,			0,			video->is_32bit ? GL_RGBA : GL_RGB,#ifdef GL_VERSION_1_2			video->is_32bit ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT_5_6_5,#else			GL_UNSIGNED_BYTE,#endif			NULL);		video->UpdateRects = SDL_GL_UpdateRectsLock;#else		SDL_SetError("Somebody forgot to #define HAVE_OPENGL");		return(NULL);#endif	}	/* Create a shadow surface if necessary */	/* There are three conditions under which we create a shadow surface:		1.  We need a particular bits-per-pixel that we didn't get.		2.  We need a hardware palette and didn't get one.		3.  We need a software surface and got a hardware surface.	*/	if ( !(SDL_VideoSurface->flags & SDL_OPENGL) &&	     (	     (  !(flags&SDL_ANYFORMAT) &&			(SDL_VideoSurface->format->BitsPerPixel != bpp)) ||	     (   (flags&SDL_HWPALETTE) && 				!(SDL_VideoSurface->flags&SDL_HWPALETTE)) ||		/* If the surface is in hardware, video writes are visible		   as soon as they are performed, so we need to buffer them		 */	     (   ((flags&SDL_HWSURFACE) == SDL_SWSURFACE) &&				(SDL_VideoSurface->flags&SDL_HWSURFACE))	     ) ) {		SDL_CreateShadowSurface(bpp);		if ( SDL_ShadowSurface == NULL ) {			SDL_SetError("Couldn't create shadow surface");			return(NULL);		}		SDL_PublicSurface = SDL_ShadowSurface;	} else {		SDL_PublicSurface = SDL_VideoSurface;	}	video->info.vfmt = SDL_VideoSurface->format;	/* We're done! */	return(SDL_PublicSurface);}/*  * Convert a surface into the video pixel format. */SDL_Surface * SDL_DisplayFormat (SDL_Surface *surface){	Uint32 flags;	if ( ! SDL_PublicSurface ) {		SDL_SetError("No video mode has been set");		return(NULL);	}	/* Set the flags appropriate for copying to display surface */	if (((SDL_PublicSurface->flags&SDL_HWSURFACE) == SDL_HWSURFACE) && current_video->info.blit_hw)		flags = SDL_HWSURFACE;	else 		flags = SDL_SWSURFACE;#ifdef AUTORLE_DISPLAYFORMAT	flags |= (surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA));	flags |= SDL_RLEACCELOK;#else	flags |= surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA|SDL_RLEACCELOK);#endif	return(SDL_ConvertSurface(surface, SDL_PublicSurface->format, flags));}/* * Convert a surface into a format that's suitable for blitting to * the screen, but including an alpha channel. */SDL_Surface *SDL_DisplayFormatAlpha(SDL_Surface *surface){	SDL_PixelFormat *vf;	SDL_PixelFormat *format;	SDL_Surface *converted;	Uint32 flags;	/* default to ARGB8888 */	Uint32 amask = 0xff000000;	Uint32 rmask = 0x00ff0000;	Uint32 gmask = 0x0000ff00;	Uint32 bmask = 0x000000ff;	if ( ! SDL_PublicSurface ) {		SDL_SetError("No video mode has been set");		return(NULL);	}	vf = SDL_PublicSurface->format;	switch(vf->BytesPerPixel) {	    case 2:		/* For XGY5[56]5, use, AXGY8888, where {X, Y} = {R, B}.		   For anything else (like ARGB4444) it doesn't matter		   since we have no special code for it anyway */		if ( (vf->Rmask == 0x1f) &&		     (vf->Bmask == 0xf800 || vf->Bmask == 0x7c00)) {			rmask = 0xff;			bmask = 0xff0000;		}		break;	    case 3:	    case 4:		/* Keep the video format, as long as the high 8 bits are		   unused or alpha */		if ( (vf->Rmask == 0xff) && (vf->Bmask == 0xff0000) ) {			rmask = 0xff;			bmask = 0xff0000;		}		break;	    default:		/* We have no other optimised formats right now. When/if a new		   optimised alpha format is written, add the converter here */		break;	}	format = SDL_AllocFormat(32, rmask, gmask, bmask, amask);	flags = SDL_PublicSurface->flags & SDL_HWSURFACE;	flags |= surface->flags & (SDL_SRCALPHA | SDL_RLEACCELOK);	converted = SDL_ConvertSurface(surface, format, flags);	SDL_FreeFormat(format);	return(converted);}/*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -