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

📄 sdl_video.c

📁 MPEG-4编解码的实现(包括MPEG4视音频编解码)
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
    SDL - Simple DirectMedia Layer
    Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

    Sam Lantinga
    slouken@libsdl.org
*/

#ifdef SAVE_RCSID
static char rcsid =
 "@(#) $Id: SDL_video.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
#endif

/* The high-level video driver subsystem */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "SDL.h"
#include "SDL_error.h"
#include "SDL_video.h"
#include "SDL_events.h"
#include "SDL_mutex.h"
#include "SDL_sysvideo.h"
#include "SDL_sysevents.h"
#include "SDL_blit.h"
#include "SDL_pixels_c.h"
#include "SDL_events_c.h"
#include "SDL_cursor_c.h"

/* Available video drivers */
static VideoBootStrap *bootstrap[] = {
#ifdef ENABLE_X11
	&X11_bootstrap,
#endif
#ifdef ENABLE_DGA
	&DGA_bootstrap,
#endif
#ifdef ENABLE_NANOX
	&NX_bootstrap,
#endif
#ifdef ENABLE_FBCON
	&FBCON_bootstrap,
#endif
#ifdef ENABLE_DIRECTFB
	&DirectFB_bootstrap,
#endif
#ifdef ENABLE_PS2GS
	&PS2GS_bootstrap,
#endif
#ifdef ENABLE_GGI
	&GGI_bootstrap,
#endif
#ifdef ENABLE_VGL
	&VGL_bootstrap,
#endif
#ifdef ENABLE_SVGALIB
	&SVGALIB_bootstrap,
#endif
#ifdef ENABLE_AALIB
    &AALIB_bootstrap,
#endif
#ifdef ENABLE_DIRECTX
	&DIRECTX_bootstrap,
#endif
#ifdef ENABLE_WINDIB
	&WINDIB_bootstrap,
#endif
#ifdef ENABLE_BWINDOW
	&BWINDOW_bootstrap,
#endif
#ifdef ENABLE_TOOLBOX
	&TOOLBOX_bootstrap,
#endif
#ifdef ENABLE_DRAWSPROCKET
	&DSp_bootstrap,
#endif
#ifdef ENABLE_QUARTZ
	&QZ_bootstrap,
#endif
#ifdef ENABLE_CYBERGRAPHICS
	&CGX_bootstrap,
#endif
#ifdef ENABLE_PHOTON
	&ph_bootstrap,
#endif
#ifdef ENABLE_EPOC
	&EPOC_bootstrap,
#endif
#ifdef ENABLE_DUMMYVIDEO
	&DUMMY_bootstrap,
#endif
#ifdef ENABLE_XBIOS
	&XBIOS_bootstrap,
#endif
#ifdef ENABLE_GEM
	&GEM_bootstrap,
#endif
	NULL
};

SDL_VideoDevice *current_video = NULL;

/* Various local functions */
int SDL_VideoInit(const char *driver_name, Uint32 flags);
void SDL_VideoQuit(void);
void SDL_GL_UpdateRectsLock(SDL_VideoDevice* this, int numrects, SDL_Rect* rects);

static SDL_GrabMode SDL_WM_GrabInputOff(void);
#ifdef HAVE_OPENGL
static int lock_count = 0;
#endif


/*
 * Initialize the video and event subsystems -- determine native pixel format
 */
int SDL_VideoInit (const char *driver_name, Uint32 flags)
{
	SDL_VideoDevice *video;
	int index;
	int i;
	SDL_PixelFormat vformat;
	Uint32 video_flags;

	/* Toggle the event thread flags, based on OS requirements */
#if defined(MUST_THREAD_EVENTS)
	flags |= SDL_INIT_EVENTTHREAD;
#elif defined(CANT_THREAD_EVENTS)
	if ( (flags & SDL_INIT_EVENTTHREAD) == SDL_INIT_EVENTTHREAD ) {
		SDL_SetError("OS doesn't support threaded events");
		return(-1);
	}
#endif

	/* Check to make sure we don't overwrite 'current_video' */
	if ( current_video != NULL ) {
		SDL_VideoQuit();
	}

	/* Select the proper video driver */
	index = 0;
	video = NULL;
	if ( driver_name != NULL ) {
#if 0	/* This will be replaced with a better driver selection API */
		if ( strrchr(driver_name, ':') != NULL ) {
			index = atoi(strrchr(driver_name, ':')+1);
		}
#endif
		for ( i=0; bootstrap[i]; ++i ) {
			if ( strncmp(bootstrap[i]->name, driver_name,
			             strlen(bootstrap[i]->name)) == 0 ) {
				if ( bootstrap[i]->available() ) {
					video = bootstrap[i]->create(index);
					break;
				}
			}
		}
	} else {
		for ( i=0; bootstrap[i]; ++i ) {
			if ( bootstrap[i]->available() ) {
				video = bootstrap[i]->create(index);
				if ( video != NULL ) {
					break;
				}
			}
		}
	}
	if ( video == NULL ) {
		SDL_SetError("No available video device");
		return(-1);
	}
	current_video = video;
	current_video->name = bootstrap[i]->name;

	/* Do some basic variable initialization */
	video->screen = NULL;
	video->shadow = NULL;
	video->visible = NULL;
	video->physpal = NULL;
	video->gammacols = NULL;
	video->gamma = NULL;
	video->wm_title = NULL;
	video->wm_icon  = NULL;
	video->offset_x = 0;
	video->offset_y = 0;
	memset(&video->info, 0, (sizeof video->info));

	/* Set some very sane GL defaults */
	video->gl_config.driver_loaded = 0;
	video->gl_config.dll_handle = NULL;
	video->gl_config.red_size = 5;
#if 1 /* This seems to work on more video cards, as a default */
	video->gl_config.green_size = 5;
#else
	video->gl_config.green_size = 6;
#endif
	video->gl_config.blue_size = 5;
	video->gl_config.alpha_size = 0;
	video->gl_config.buffer_size = 0;
	video->gl_config.depth_size = 16;
	video->gl_config.stencil_size = 0;
	video->gl_config.double_buffer = 1;
	video->gl_config.accum_red_size = 0;
	video->gl_config.accum_green_size = 0;
	video->gl_config.accum_blue_size = 0;
	video->gl_config.accum_alpha_size = 0;
	
	/* Initialize the video subsystem */
	memset(&vformat, 0, sizeof(vformat));
	if ( video->VideoInit(video, &vformat) < 0 ) {
		SDL_VideoQuit();
		return(-1);
	}

	/* Create a zero sized video surface of the appropriate format */
	video_flags = SDL_SWSURFACE;
	SDL_VideoSurface = SDL_CreateRGBSurface(video_flags, 0, 0,
				vformat.BitsPerPixel,
				vformat.Rmask, vformat.Gmask, vformat.Bmask, 0);
	if ( SDL_VideoSurface == NULL ) {
		SDL_VideoQuit();
		return(-1);
	}
	SDL_PublicSurface = NULL;	/* Until SDL_SetVideoMode() */

#if 0 /* Don't change the current palette - may be used by other programs.
       * The application can't do anything with the display surface until
       * a video mode has been set anyway. :)
       */
	/* If we have a palettized surface, create a default palette */
	if ( SDL_VideoSurface->format->palette ) {
	        SDL_PixelFormat *vf = SDL_VideoSurface->format;
		SDL_DitherColors(vf->palette->colors, vf->BitsPerPixel);
		video->SetColors(video,
				 0, vf->palette->ncolors, vf->palette->colors);
	}
#endif
	video->info.vfmt = SDL_VideoSurface->format;

	/* Start the event loop */
	if ( SDL_StartEventLoop(flags) < 0 ) {
		SDL_VideoQuit();
		return(-1);
	}
	SDL_CursorInit(flags & SDL_INIT_EVENTTHREAD);

	/* We're ready to go! */
	return(0);
}

char *SDL_VideoDriverName(char *namebuf, int maxlen)
{
	if ( current_video != NULL ) {
		strncpy(namebuf, current_video->name, maxlen-1);
		namebuf[maxlen-1] = '\0';
		return(namebuf);
	}
	return(NULL);
}

/*
 * Get the current display surface
 */
SDL_Surface *SDL_GetVideoSurface(void)
{
	SDL_Surface *visible;

	visible = NULL;
	if ( current_video ) {
		visible = current_video->visible;
	}
	return(visible);
}

/*
 * Get the current information about the video hardware
 */
const SDL_VideoInfo *SDL_GetVideoInfo(void)
{
	const SDL_VideoInfo *info;

	info = NULL;
	if ( current_video ) {
		info = &current_video->info;
	}
	return(info);
}

/*
 * Return a pointer to an array of available screen dimensions for the
 * given format, sorted largest to smallest.  Returns NULL if there are
 * no dimensions available for a particular format, or (SDL_Rect **)-1
 * if any dimension is okay for the given format.  If 'format' is NULL,
 * the mode list will be for the format given by SDL_GetVideoInfo()->vfmt
 */
SDL_Rect ** SDL_ListModes (SDL_PixelFormat *format, Uint32 flags)
{
	SDL_VideoDevice *video = current_video;
	SDL_VideoDevice *this  = current_video;
	SDL_Rect **modes;

	modes = NULL;
	if ( SDL_VideoSurface ) {
		if ( format == NULL ) {
			format = SDL_VideoSurface->format;
		}
		modes = video->ListModes(this, format, flags);
	}
	return(modes);
}

/*
 * Check to see if a particular video mode is supported.
 * It returns 0 if the requested mode is not supported under any bit depth,
 * or returns the bits-per-pixel of the closest available mode with the
 * given width and height.  If this bits-per-pixel is different from the
 * one used when setting the video mode, SDL_SetVideoMode() will succeed,
 * but will emulate the requested bits-per-pixel with a shadow surface.
 */
static Uint8 SDL_closest_depths[4][8] = {
	/* 8 bit closest depth ordering */
	{ 0, 8, 16, 15, 32, 24, 0, 0 },
	/* 15,16 bit closest depth ordering */
	{ 0, 16, 15, 32, 24, 8, 0, 0 },
	/* 24 bit closest depth ordering */
	{ 0, 24, 32, 16, 15, 8, 0, 0 },
	/* 32 bit closest depth ordering */
	{ 0, 32, 16, 15, 24, 8, 0, 0 }
};

int SDL_VideoModeOK (int width, int height, int bpp, Uint32 flags) 
{
	int table, b, i;
	int supported;
	SDL_PixelFormat format;
	SDL_Rect **sizes;

	/* Currently 1 and 4 bpp are not supported */
	if ( bpp < 8 || bpp > 32 ) {
		return(0);
	}
	if ( (width == 0) || (height == 0) ) {
		return(0);
	}

	/* Search through the list valid of modes */
	memset(&format, 0, sizeof(format));
	supported = 0;
	table = ((bpp+7)/8)-1;
	SDL_closest_depths[table][0] = bpp;
	SDL_closest_depths[table][7] = 0;
	for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
		format.BitsPerPixel = SDL_closest_depths[table][b];
		sizes = SDL_ListModes(&format, flags);
		if ( sizes == (SDL_Rect **)0 ) {
			/* No sizes supported at this bit-depth */
			continue;
		} else 
#ifdef macintosh /* MPW optimization bug? */
		if ( (sizes == (SDL_Rect **)0xFFFFFFFF) ||
#else
		if ( (sizes == (SDL_Rect **)-1) ||
#endif
		     current_video->handles_any_size ) {
			/* Any size supported at this bit-depth */
			supported = 1;
			continue;
		} else
		for ( i=0; sizes[i]; ++i ) {
			if ((sizes[i]->w == width) && (sizes[i]->h == height)) {
				supported = 1;
				break;
			}
		}
	}
	if ( supported ) {
		--b;
		return(SDL_closest_depths[table][b]);
	} else {
		return(0);
	}
}

/*
 * Get the closest non-emulated video mode to the one requested
 */
static int SDL_GetVideoMode (int *w, int *h, int *BitsPerPixel, Uint32 flags)
{
	int table, b, i;
	int supported;
	int native_bpp;
	SDL_PixelFormat format;
	SDL_Rect **sizes;

	/* Try the original video mode, get the closest depth */
	native_bpp = SDL_VideoModeOK(*w, *h, *BitsPerPixel, flags);
	if ( native_bpp == *BitsPerPixel ) {
		return(1);
	}
	if ( native_bpp > 0 ) {
		*BitsPerPixel = native_bpp;
		return(1);
	}

	/* No exact size match at any depth, look for closest match */
	memset(&format, 0, sizeof(format));
	supported = 0;
	table = ((*BitsPerPixel+7)/8)-1;
	SDL_closest_depths[table][0] = *BitsPerPixel;
	SDL_closest_depths[table][7] = SDL_VideoSurface->format->BitsPerPixel;
	for ( b = 0; !supported && SDL_closest_depths[table][b]; ++b ) {
		format.BitsPerPixel = SDL_closest_depths[table][b];
		sizes = SDL_ListModes(&format, flags);
		if ( sizes == (SDL_Rect **)0 ) {
			/* No sizes supported at this bit-depth */
			continue;
		}
		for ( i=0; sizes[i]; ++i ) {
			if ((sizes[i]->w < *w) || (sizes[i]->h < *h)) {
				if ( i > 0 ) {
					--i;
					*w = sizes[i]->w;
					*h = sizes[i]->h;
					*BitsPerPixel = SDL_closest_depths[table][b];
					supported = 1;
				} else {
					/* Largest mode too small... */;
				}
				break;
			}
		}
		if ( (i > 0) && ! sizes[i] ) {
			/* The smallest mode was larger than requested, OK */
			--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);

⌨️ 快捷键说明

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