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

📄 sdl_gsvideo.c

📁 Simple DirectMedia Layer - Simple DirectMedia Layer 是一个跨平台的多媒体库设计用来提供快速图形framebuffer和音频驱动。应用MPEG为软件
💻 C
📖 第 1 页 / 共 2 页
字号:
		}	}	/* We're done! */	return(0);}static SDL_Rect **GS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags){	static SDL_Rect GS_vesa_mode_list[] = {		{ 0, 0, 1280, 1024 },		{ 0, 0, 1024, 768 },		{ 0, 0, 800, 600 },		{ 0, 0, 640, 480 }	};	static SDL_Rect *GS_vesa_modes[] = {		&GS_vesa_mode_list[0],		&GS_vesa_mode_list[1],		&GS_vesa_mode_list[2],		&GS_vesa_mode_list[3],		NULL	};	static SDL_Rect GS_tvout_stretch;	static SDL_Rect GS_tvout_mode;	static SDL_Rect *GS_tvout_modes[3];	SDL_Rect **modes = NULL;	switch (format->BitsPerPixel) {	    case 16:	    case 24:	    case 32:		if ( saved_vinfo.mode == PS2_GS_VESA ) {			modes = GS_vesa_modes;		} else {			int i, j = 0;// FIXME - what's wrong with the stretch code at 16 bpp?if ( format->BitsPerPixel != 32 ) break;			/* Add a mode that we could possibly stretch to */			for ( i=0; GS_vesa_modes[i]; ++i ) {				if ( (GS_vesa_modes[i]->w == saved_vinfo.w) &&				     (GS_vesa_modes[i]->h != saved_vinfo.h) ) {					GS_tvout_stretch.w=GS_vesa_modes[i]->w;					GS_tvout_stretch.h=GS_vesa_modes[i]->h;					GS_tvout_modes[j++] = &GS_tvout_stretch;					break;				}			}			/* Add the current TV video mode */			GS_tvout_mode.w = saved_vinfo.w;			GS_tvout_mode.h = saved_vinfo.h;			GS_tvout_modes[j++] = &GS_tvout_mode;			GS_tvout_modes[j++] = NULL;			/* Return the created list of modes */			modes = GS_tvout_modes;		}		break;	    default:		break;	}	return(modes);}/* Various screen update functions available */static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect *rects);static SDL_Surface *GS_SetVideoMode(_THIS, SDL_Surface *current,				int width, int height, int bpp, Uint32 flags){	struct ps2_screeninfo vinfo;	/* Set the terminal into graphics mode */	if ( GS_EnterGraphicsMode(this) < 0 ) {		return(NULL);	}	/* Set the video mode and get the final screen format */	if ( ioctl(console_fd, PS2IOC_GSCREENINFO, &vinfo) < 0 ) {		SDL_SetError("Couldn't get console screen info");		return(NULL);	}	if ( (vinfo.w != width) || (vinfo.h != height) ||	     (GS_pixelmasks[vinfo.psm].bpp != bpp) ) {		/* If we're not in VESA mode, we have to scale resolution */		if ( saved_vinfo.mode == PS2_GS_VESA ) {			switch (width) {			    case 640:				vinfo.res = PS2_GS_640x480;				break;			    case 800:				vinfo.res = PS2_GS_800x600;				break;			    case 1024:				vinfo.res = PS2_GS_1024x768;				break;			    case 1280:				vinfo.res = PS2_GS_1280x1024;				break;			    default:				SDL_SetError("Unsupported resolution: %dx%d\n",					     width, height);				return(NULL);			}			vinfo.res |= (PS2_GS_75Hz << 8);			vinfo.w = width;			vinfo.h = height;		}		vinfo.fbp = 0;		vinfo.psm = GS_formatmap[bpp/8];		if ( vinfo.psm < 0 ) {			SDL_SetError("Unsupported depth: %d bpp\n", bpp);			return(NULL);		}		if ( ioctl(console_fd, PS2IOC_SSCREENINFO, &vinfo) < 0 ) {			SDL_SetError("Couldn't set console screen info");			return(NULL);		}		/* Unmap the previous DMA buffer */		if ( mapped_mem ) {			munmap(mapped_mem, mapped_len);			mapped_mem = NULL;		}	}	if ( ! SDL_ReallocFormat(current, GS_pixelmasks[vinfo.psm].bpp,	                                  GS_pixelmasks[vinfo.psm].r,	                                  GS_pixelmasks[vinfo.psm].g,	                                  GS_pixelmasks[vinfo.psm].b, 0) ) {		return(NULL);	}	/* Set up the new mode framebuffer */	current->flags = SDL_FULLSCREEN;	current->w = width;	current->h = height;	current->pitch = SDL_CalculatePitch(current);	/* Memory map the DMA area for block memory transfer */	if ( ! mapped_mem ) {		pixels_len = height * current->pitch;		mapped_len = pixels_len +		             /* Screen update DMA command area */		             sizeof(head_tags) + ((2 * MAXTAGS) * 16);		if ( saved_vinfo.mode != PS2_GS_VESA ) {			mapped_len += sizeof(tex_tags) + sizeof(scale_tags);		}		mapped_mem = mmap(0, mapped_len, PROT_READ|PROT_WRITE,		                  MAP_SHARED, memory_fd, 0);		if ( mapped_mem == MAP_FAILED ) {			SDL_SetError("Unable to map %d bytes for DMA",			             mapped_len);			mapped_mem = NULL;			return(NULL);		}		/* Set up the entire screen for DMA transfer */		screen_image.ptr = mapped_mem;		screen_image.fbp = 0;		screen_image.fbw = (vinfo.w + 63) / 64;		screen_image.psm = vinfo.psm;		screen_image.x = 0;		if ( vinfo.h == height ) {			screen_image.y = 0;		} else {			/* Put image offscreen and scale to screen height */			screen_image.y = vinfo.h;		}		screen_image.w = current->w;		screen_image.h = current->h;		/* get screen image data size (qword aligned) */		screen_image_size = (screen_image.w * screen_image.h);		switch (screen_image.psm) {		    case PS2_GS_PSMCT32:			screen_image_size *= 4;			break;		    case PS2_GS_PSMCT24:			screen_image_size *= 3;			break;		    case PS2_GS_PSMCT16:			screen_image_size *= 2;			break;		}		screen_image_size = (screen_image_size + 15) & ~15;		/* Set up the memory for screen update DMA commands */		head_tags_mem = (unsigned long long *)		                (mapped_mem + pixels_len);		image_tags_mem = (unsigned long long *)		                 ((caddr_t)head_tags_mem + sizeof(head_tags));		memcpy(head_tags_mem, head_tags, sizeof(head_tags));		if ( saved_vinfo.mode != PS2_GS_VESA ) {			tex_tags_mem = (unsigned long long *)		                 ((caddr_t)image_tags_mem + ((2*MAXTAGS)*16));			scale_tags_mem = (unsigned long long *)		                 ((caddr_t)tex_tags_mem + sizeof(tex_tags));			memcpy(tex_tags_mem, tex_tags, sizeof(tex_tags));			tex_tags_mem[2] = 				(vinfo.h * vinfo.w) / 64 +	          		((unsigned long long)screen_image.fbw << 14) +	          		((unsigned long long)screen_image.psm << 20) +	          		((unsigned long long)power_of_2(screen_image.w) << 26) +	          		((unsigned long long)power_of_2(screen_image.h) << 30) +	          		((unsigned long long)1 << 34) +	          		((unsigned long long)1 << 35);			memcpy(scale_tags_mem, scale_tags, sizeof(scale_tags));			scale_tags_mem[8] =				((unsigned long long)screen_image.w * 16) +			         (((unsigned long long)screen_image.h * 16) << 16);			scale_tags_mem[10] =				((unsigned long long)vinfo.w * 16) +			         (((unsigned long long)vinfo.h * 16) << 16);		}	}	current->pixels = NULL;	if ( getenv("SDL_FULLSCREEN_UPDATE") ) {		/* Correct semantics */		current->flags |= SDL_ASYNCBLIT;	} else {		/* We lie here - the screen memory isn't really the visible		   display memory and still requires an update, but this		   has the desired effect for most applications.		 */		current->flags |= SDL_HWSURFACE;	}	/* Set the update rectangle function */	this->UpdateRects = GS_DMAFullUpdate;	/* We're done */	return(current);}/* We don't support hardware surfaces yet */static int GS_AllocHWSurface(_THIS, SDL_Surface *surface){	return(-1);}static void GS_FreeHWSurface(_THIS, SDL_Surface *surface){	return;}static int GS_LockHWSurface(_THIS, SDL_Surface *surface){	if ( surface == this->screen ) {		/* Since mouse motion affects 'pixels', lock it */		SDL_LockCursor();		/* Make sure any pending DMA has completed */		if ( dma_pending ) {			ioctl(console_fd, PS2IOC_SENDQCT, 1);			dma_pending = 0;		}		/* If the cursor is drawn on the DMA area, remove it */		if ( cursor_drawn ) {			surface->pixels = mapped_mem + surface->offset;			SDL_EraseCursorNoLock(this->screen);			cursor_drawn = 0;		}		/* Set the surface pixels to the base of the DMA area */		surface->pixels = mapped_mem;		/* We're finished! */		SDL_UnlockCursor();	}	return(0);}static void GS_UnlockHWSurface(_THIS, SDL_Surface *surface){	if ( surface == this->screen ) {		/* Since mouse motion affects 'pixels', lock it */		SDL_LockCursor();		surface->pixels = NULL;		SDL_UnlockCursor();	}}static void GS_DMAFullUpdate(_THIS, int numrects, SDL_Rect *rects){	/* Lock so we aren't interrupted by a mouse update */	SDL_LockCursor();	/* Make sure any pending DMA has completed */	if ( dma_pending ) {		ioctl(console_fd, PS2IOC_SENDQCT, 1);		dma_pending = 0;	}	/* If the mouse is visible, draw it on the DMA area */	if ( (SDL_cursorstate & CURSOR_VISIBLE) && !cursor_drawn ) {		this->screen->pixels = mapped_mem + this->screen->offset;		SDL_DrawCursorNoLock(this->screen);		this->screen->pixels = NULL;		cursor_drawn = 1;	}	/* Put the image onto the screen */	loadimage_nonblock(console_fd,	                   &screen_image, screen_image_size,	                   head_tags_mem, image_tags_mem);	if ( screen_image.y > 0 ) {		/* Need to scale offscreen image to TV output */		ioctl(console_fd, PS2IOC_SENDQCT, 1);		dma_pending = 0;		scaleimage_nonblock(console_fd, tex_tags_mem, scale_tags_mem);	} else {		dma_pending = 1;	}	/* We're finished! */	SDL_UnlockCursor();}static int GS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors){	return(0);}static void GS_VideoQuit(_THIS){	/* Close console and input file descriptors */	if ( console_fd > 0 ) {		/* Unmap the video framebuffer */		if ( mapped_mem ) {			/* Unmap the video framebuffer */			munmap(mapped_mem, mapped_len);			mapped_mem = NULL;		}		close(memory_fd);		/* Restore the original video mode */		if ( GS_InGraphicsMode(this) ) {			ioctl(console_fd, PS2IOC_SSCREENINFO, &saved_vinfo);		}		/* We're all done with the graphics device */		close(console_fd);		console_fd = -1;	}	GS_CloseMouse(this);	GS_CloseKeyboard(this);}

⌨️ 快捷键说明

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