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

📄 sdl_fbvideo.c

📁 linux下面的一个开源的多媒体中间件
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef VGA16_FBCON_SUPPORTstatic SDL_Surface *FB_SetVGA16Mode(_THIS, SDL_Surface *current,				int width, int height, int bpp, Uint32 flags){	struct fb_fix_screeninfo finfo;	struct fb_var_screeninfo vinfo;	/* Set the terminal into graphics mode */	if ( FB_EnterGraphicsMode(this) < 0 ) {		return(NULL);	}	/* Restore the original palette */	FB_RestorePalette(this);	/* Set the video mode and get the final screen format */	if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {		SDL_SetError("Couldn't get console screen info");		return(NULL);	}	cache_vinfo = vinfo;#ifdef FBCON_DEBUG	fprintf(stderr, "Printing actual vinfo:\n");	print_vinfo(&vinfo);#endif	if ( ! SDL_ReallocFormat(current, bpp, 0, 0, 0, 0) ) {		return(NULL);	}	current->format->palette->ncolors = 16;	/* Get the fixed information about the console hardware.	   This is necessary since finfo.line_length changes.	 */	if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {		SDL_SetError("Couldn't get console hardware info");		return(NULL);	}#ifdef FBCON_DEBUG	fprintf(stderr, "Printing actual finfo:\n");	print_finfo(&finfo);#endif	/* Save hardware palette, if needed */	FB_SavePalette(this, &finfo, &vinfo);	/* Set up the new mode framebuffer */	current->flags = SDL_FULLSCREEN;	current->w = vinfo.xres;	current->h = vinfo.yres;	current->pitch = current->w;	current->pixels = SDL_malloc(current->h*current->pitch);	/* Set the update rectangle function */	this->UpdateRects = FB_VGA16Update;	/* We're done */	return(current);}#endif /* VGA16_FBCON_SUPPORT */static SDL_Surface *FB_SetVideoMode(_THIS, SDL_Surface *current,				int width, int height, int bpp, Uint32 flags){	struct fb_fix_screeninfo finfo;	struct fb_var_screeninfo vinfo;	int i;	Uint32 Rmask;	Uint32 Gmask;	Uint32 Bmask;	char *surfaces_mem;	int surfaces_len;	/* Set the terminal into graphics mode */	if ( FB_EnterGraphicsMode(this) < 0 ) {		return(NULL);	}	/* Restore the original palette */	FB_RestorePalette(this);	/* Set the video mode and get the final screen format */	if ( ioctl(console_fd, FBIOGET_VSCREENINFO, &vinfo) < 0 ) {		SDL_SetError("Couldn't get console screen info");		return(NULL);	}#ifdef FBCON_DEBUG	fprintf(stderr, "Printing original vinfo:\n");	print_vinfo(&vinfo);#endif	if ( (vinfo.xres != width) || (vinfo.yres != height) ||	     (vinfo.bits_per_pixel != bpp) || (flags & SDL_DOUBLEBUF) ) {		vinfo.activate = FB_ACTIVATE_NOW;		vinfo.accel_flags = 0;		vinfo.bits_per_pixel = bpp;		vinfo.xres = width;		vinfo.xres_virtual = width;		vinfo.yres = height;		if ( flags & SDL_DOUBLEBUF ) {			vinfo.yres_virtual = height*2;		} else {			vinfo.yres_virtual = height;		}		vinfo.xoffset = 0;		vinfo.yoffset = 0;		vinfo.red.length = vinfo.red.offset = 0;		vinfo.green.length = vinfo.green.offset = 0;		vinfo.blue.length = vinfo.blue.offset = 0;		vinfo.transp.length = vinfo.transp.offset = 0;		if ( ! choose_fbmodes_mode(&vinfo) ) {			choose_vesa_mode(&vinfo);		}#ifdef FBCON_DEBUG		fprintf(stderr, "Printing wanted vinfo:\n");		print_vinfo(&vinfo);#endif		if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {			vinfo.yres_virtual = height;			if ( ioctl(console_fd, FBIOPUT_VSCREENINFO, &vinfo) < 0 ) {				SDL_SetError("Couldn't set console screen info");				return(NULL);			}		}	} else {		int maxheight;		/* Figure out how much video memory is available */		if ( flags & SDL_DOUBLEBUF ) {			maxheight = height*2;		} else {			maxheight = height;		}		if ( vinfo.yres_virtual > maxheight ) {			vinfo.yres_virtual = maxheight;		}	}	cache_vinfo = vinfo;#ifdef FBCON_DEBUG	fprintf(stderr, "Printing actual vinfo:\n");	print_vinfo(&vinfo);#endif	Rmask = 0;	for ( i=0; i<vinfo.red.length; ++i ) {		Rmask <<= 1;		Rmask |= (0x00000001<<vinfo.red.offset);	}	Gmask = 0;	for ( i=0; i<vinfo.green.length; ++i ) {		Gmask <<= 1;		Gmask |= (0x00000001<<vinfo.green.offset);	}	Bmask = 0;	for ( i=0; i<vinfo.blue.length; ++i ) {		Bmask <<= 1;		Bmask |= (0x00000001<<vinfo.blue.offset);	}	if ( ! SDL_ReallocFormat(current, vinfo.bits_per_pixel,	                                  Rmask, Gmask, Bmask, 0) ) {		return(NULL);	}	/* Get the fixed information about the console hardware.	   This is necessary since finfo.line_length changes.	 */	if ( ioctl(console_fd, FBIOGET_FSCREENINFO, &finfo) < 0 ) {		SDL_SetError("Couldn't get console hardware info");		return(NULL);	}	/* Save hardware palette, if needed */	FB_SavePalette(this, &finfo, &vinfo);	/* Set up the new mode framebuffer */	current->flags = (SDL_FULLSCREEN|SDL_HWSURFACE);	current->w = vinfo.xres;	current->h = vinfo.yres;	current->pitch = finfo.line_length;	current->pixels = mapped_mem+mapped_offset;	/* Set up the information for hardware surfaces */	surfaces_mem = (char *)current->pixels +	                        vinfo.yres_virtual*current->pitch;	surfaces_len = (mapped_memlen-(surfaces_mem-mapped_mem));	FB_FreeHWSurfaces(this);	FB_InitHWSurfaces(this, current, surfaces_mem, surfaces_len);	/* Let the application know we have a hardware palette */	switch (finfo.visual) {	    case FB_VISUAL_PSEUDOCOLOR:		current->flags |= SDL_HWPALETTE;		break;	    default:		break;	}	/* Update for double-buffering, if we can */	if ( flags & SDL_DOUBLEBUF ) {		if ( vinfo.yres_virtual == (height*2) ) {			current->flags |= SDL_DOUBLEBUF;			flip_page = 0;			flip_address[0] = (char *)current->pixels;			flip_address[1] = (char *)current->pixels+			                          current->h*current->pitch;			this->screen = current;			FB_FlipHWSurface(this, current);			this->screen = NULL;		}	}	/* Set the update rectangle function */	this->UpdateRects = FB_DirectUpdate;	/* We're done */	return(current);}#ifdef FBCON_DEBUGvoid FB_DumpHWSurfaces(_THIS){	vidmem_bucket *bucket;	printf("Memory left: %d (%d total)\n", surfaces_memleft, surfaces_memtotal);	printf("\n");	printf("         Base  Size\n");	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {		printf("Bucket:  %p, %d (%s)\n", bucket->base, bucket->size, bucket->used ? "used" : "free");		if ( bucket->prev ) {			if ( bucket->base != bucket->prev->base+bucket->prev->size ) {				printf("Warning, corrupt bucket list! (prev)\n");			}		} else {			if ( bucket != &surfaces ) {				printf("Warning, corrupt bucket list! (!prev)\n");			}		}		if ( bucket->next ) {			if ( bucket->next->base != bucket->base+bucket->size ) {				printf("Warning, corrupt bucket list! (next)\n");			}		}	}	printf("\n");}#endifstatic int FB_InitHWSurfaces(_THIS, SDL_Surface *screen, char *base, int size){	vidmem_bucket *bucket;	surfaces_memtotal = size;	surfaces_memleft = size;	if ( surfaces_memleft > 0 ) {		bucket = (vidmem_bucket *)SDL_malloc(sizeof(*bucket));		if ( bucket == NULL ) {			SDL_OutOfMemory();			return(-1);		}		bucket->prev = &surfaces;		bucket->used = 0;		bucket->dirty = 0;		bucket->base = base;		bucket->size = size;		bucket->next = NULL;	} else {		bucket = NULL;	}	surfaces.prev = NULL;	surfaces.used = 1;	surfaces.dirty = 0;	surfaces.base = screen->pixels;	surfaces.size = (unsigned int)((long)base - (long)surfaces.base);	surfaces.next = bucket;	screen->hwdata = (struct private_hwdata *)&surfaces;	return(0);}static void FB_FreeHWSurfaces(_THIS){	vidmem_bucket *bucket, *freeable;	bucket = surfaces.next;	while ( bucket ) {		freeable = bucket;		bucket = bucket->next;		SDL_free(freeable);	}	surfaces.next = NULL;}static int FB_AllocHWSurface(_THIS, SDL_Surface *surface){	vidmem_bucket *bucket;	int size;	int extra;/* Temporarily, we only allow surfaces the same width as display.   Some blitters require the pitch between two hardware surfaces   to be the same.  Others have interesting alignment restrictions.   Until someone who knows these details looks at the code...*/if ( surface->pitch > SDL_VideoSurface->pitch ) {	SDL_SetError("Surface requested wider than screen");	return(-1);}surface->pitch = SDL_VideoSurface->pitch;	size = surface->h * surface->pitch;#ifdef FBCON_DEBUG	fprintf(stderr, "Allocating bucket of %d bytes\n", size);#endif	/* Quick check for available mem */	if ( size > surfaces_memleft ) {		SDL_SetError("Not enough video memory");		return(-1);	}	/* Search for an empty bucket big enough */	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {		if ( ! bucket->used && (size <= bucket->size) ) {			break;		}	}	if ( bucket == NULL ) {		SDL_SetError("Video memory too fragmented");		return(-1);	}	/* Create a new bucket for left-over memory */	extra = (bucket->size - size);	if ( extra ) {		vidmem_bucket *newbucket;#ifdef FBCON_DEBUG	fprintf(stderr, "Adding new free bucket of %d bytes\n", extra);#endif		newbucket = (vidmem_bucket *)SDL_malloc(sizeof(*newbucket));		if ( newbucket == NULL ) {			SDL_OutOfMemory();			return(-1);		}		newbucket->prev = bucket;		newbucket->used = 0;		newbucket->base = bucket->base+size;		newbucket->size = extra;		newbucket->next = bucket->next;		if ( bucket->next ) {			bucket->next->prev = newbucket;		}		bucket->next = newbucket;	}	/* Set the current bucket values and return it! */	bucket->used = 1;	bucket->size = size;	bucket->dirty = 0;#ifdef FBCON_DEBUG	fprintf(stderr, "Allocated %d bytes at %p\n", bucket->size, bucket->base);#endif	surfaces_memleft -= size;	surface->flags |= SDL_HWSURFACE;	surface->pixels = bucket->base;	surface->hwdata = (struct private_hwdata *)bucket;	return(0);}static void FB_FreeHWSurface(_THIS, SDL_Surface *surface){	vidmem_bucket *bucket, *freeable;	/* Look for the bucket in the current list */	for ( bucket=&surfaces; bucket; bucket=bucket->next ) {		if ( bucket == (vidmem_bucket *)surface->hwdata ) {			break;		}	}	if ( bucket && bucket->used ) {		/* Add the memory back to the total */#ifdef DGA_DEBUG	printf("Freeing bucket of %d bytes\n", bucket->size);#endif		surfaces_memleft += bucket->size;		/* Can we merge the space with surrounding buckets? */		bucket->used = 0;		if ( bucket->next && ! bucket->next->used ) {#ifdef DGA_DEBUG	printf("Merging with next bucket, for %d total bytes\n", bucket->size+bucket->next->size);#endif			freeable = bucket->next;			bucket->size += bucket->next->size;			bucket->next = bucket->next->next;			if ( bucket->next ) {				bucket->next->prev = bucket;			}			SDL_free(freeable);		}		if ( bucket->prev && ! bucket->prev->used ) {#ifdef DGA_DEBUG	printf("Merging with previous bucket, for %d total bytes\n", bucket->prev->size+bucket->size);#endif			freeable = bucket;			bucket->prev->size += bucket->size;			bucket->prev->next = bucket->next;			if ( bucket->next ) {				bucket->next->prev = bucket->prev;			}			SDL_free(freeable);		}	}	surface->pixels = NULL;	surface->hwdata = NULL;}static int FB_LockHWSurface(_THIS, SDL_Surface *surface){	if ( switched_away ) {		return -2; /* no hardware access */	}	if ( surface == this->screen ) {		SDL_mutexP(hw_lock);		if ( FB_IsSurfaceBusy(surface) ) {			FB_WaitBusySurfaces(this);

⌨️ 快捷键说明

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