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

📄 sdl_surface.c

📁 Simple DirectMedia Layer - Simple DirectMedia Layer 是一个跨平台的多媒体库设计用来提供快速图形framebuffer和音频驱动。应用MPEG为软件
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/* clip the source rectangle to the source surface */	if(srcrect) {	        int maxw, maxh;			srcx = srcrect->x;		w = srcrect->w;		if(srcx < 0) {		        w += srcx;			dstrect->x -= srcx;			srcx = 0;		}		maxw = src->w - srcx;		if(maxw < w)			w = maxw;		srcy = srcrect->y;		h = srcrect->h;		if(srcy < 0) {		        h += srcy;			dstrect->y -= srcy;			srcy = 0;		}		maxh = src->h - srcy;		if(maxh < h)			h = maxh;	    	} else {	        srcx = srcy = 0;		w = src->w;		h = src->h;	}	/* clip the destination rectangle against the clip rectangle */	{	        SDL_Rect *clip = &dst->clip_rect;		int dx, dy;		dx = clip->x - dstrect->x;		if(dx > 0) {			w -= dx;			dstrect->x += dx;			srcx += dx;		}		dx = dstrect->x + w - clip->x - clip->w;		if(dx > 0)			w -= dx;		dy = clip->y - dstrect->y;		if(dy > 0) {			h -= dy;			dstrect->y += dy;			srcy += dy;		}		dy = dstrect->y + h - clip->y - clip->h;		if(dy > 0)			h -= dy;	}	if(w > 0 && h > 0) {	        SDL_Rect sr;	        sr.x = srcx;		sr.y = srcy;		sr.w = dstrect->w = w;		sr.h = dstrect->h = h;		return SDL_LowerBlit(src, &sr, dst, dstrect);	}	dstrect->w = dstrect->h = 0;	return 0;}/*  * This function performs a fast fill of the given rectangle with 'color' */int SDL_FillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color){	SDL_VideoDevice *video = current_video;	SDL_VideoDevice *this  = current_video;	int x, y;	Uint8 *row;	/* If 'dstrect' == NULL, then fill the whole surface */	if ( dstrect ) {		/* Perform clipping */		if ( !SDL_IntersectRect(dstrect, &dst->clip_rect, dstrect) ) {			return(0);		}	} else {		dstrect = &dst->clip_rect;	}	/* Check for hardware acceleration */	if ( ((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) &&					video->info.blit_fill ) {		SDL_Rect hw_rect;		if ( dst == SDL_VideoSurface ) {			hw_rect = *dstrect;			hw_rect.x += current_video->offset_x;			hw_rect.y += current_video->offset_y;			dstrect = &hw_rect;		}		return(video->FillHWRect(this, dst, dstrect, color));	}	/* Perform software fill */	if ( SDL_LockSurface(dst) != 0 ) {		return(-1);	}	row = (Uint8 *)dst->pixels+dstrect->y*dst->pitch+			dstrect->x*dst->format->BytesPerPixel;	if ( dst->format->palette || (color == 0) ) {		x = dstrect->w*dst->format->BytesPerPixel;		if ( !color && !((long)row&3) && !(x&3) && !(dst->pitch&3) ) {			int n = x >> 2;			for ( y=dstrect->h; y; --y ) {				SDL_memset4(row, 0, n);				row += dst->pitch;			}		} else {#ifdef __powerpc__			/*			 * memset() on PPC (both glibc and codewarrior) uses			 * the dcbz (Data Cache Block Zero) instruction, which			 * causes an alignment exception if the destination is			 * uncachable, so only use it on software surfaces			 */			if((dst->flags & SDL_HWSURFACE) == SDL_HWSURFACE) {				if(dstrect->w >= 8) {					/*					 * 64-bit stores are probably most					 * efficient to uncached video memory					 */					double fill;					memset(&fill, color, (sizeof fill));					for(y = dstrect->h; y; y--) {						Uint8 *d = row;						unsigned n = x;						unsigned nn;						Uint8 c = color;						double f = fill;						while((unsigned long)d						      & (sizeof(double) - 1)) {							*d++ = c;							n--;						}						nn = n / (sizeof(double) * 4);						while(nn) {							((double *)d)[0] = f;							((double *)d)[1] = f;							((double *)d)[2] = f;							((double *)d)[3] = f;							d += 4*sizeof(double);							nn--;						}						n &= ~(sizeof(double) * 4 - 1);						nn = n / sizeof(double);						while(nn) {							*(double *)d = f;							d += sizeof(double);							nn--;						}						n &= ~(sizeof(double) - 1);						while(n) {							*d++ = c;							n--;						}						row += dst->pitch;					}				} else {					/* narrow boxes */					for(y = dstrect->h; y; y--) {						Uint8 *d = row;						Uint8 c = color;						int n = x;						while(n) {							*d++ = c;							n--;						}						row += dst->pitch;					}				}			} else#endif /* __powerpc__ */			{				for(y = dstrect->h; y; y--) {					memset(row, color, x);					row += dst->pitch;				}			}		}	} else {		switch (dst->format->BytesPerPixel) {		    case 2:			for ( y=dstrect->h; y; --y ) {				Uint16 *pixels = (Uint16 *)row;				Uint16 c = color;				Uint32 cc = (Uint32)c << 16 | c;				int n = dstrect->w;				if((unsigned long)pixels & 3) {					*pixels++ = c;					n--;				}				if(n >> 1)					SDL_memset4(pixels, cc, n >> 1);				if(n & 1)					pixels[n - 1] = c;				row += dst->pitch;			}			break;		    case 3:			if(SDL_BYTEORDER == SDL_BIG_ENDIAN)				color <<= 8;			for ( y=dstrect->h; y; --y ) {				Uint8 *pixels = row;				for ( x=dstrect->w; x; --x ) {					memcpy(pixels, &color, 3);					pixels += 3;				}				row += dst->pitch;			}			break;		    case 4:			for(y = dstrect->h; y; --y) {				SDL_memset4(row, color, dstrect->w);				row += dst->pitch;			}			break;		}	}	SDL_UnlockSurface(dst);	/* We're done! */	return(0);}/* * Lock a surface to directly access the pixels * -- Do not call this from any blit function, as SDL_DrawCursor() may recurse *    Instead, use: *    if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) *               video->LockHWSurface(video, surface); */int SDL_LockSurface (SDL_Surface *surface){	if ( ! surface->locked ) {		/* Perform the lock */		if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) {			SDL_VideoDevice *video = current_video;			SDL_VideoDevice *this  = current_video;			if ( video->LockHWSurface(this, surface) < 0 ) {				return(-1);			}		}		if ( surface->flags & SDL_RLEACCEL ) {			SDL_UnRLESurface(surface, 1);			surface->flags |= SDL_RLEACCEL;	/* save accel'd state */		}		/* This needs to be done here in case pixels changes value */		surface->pixels = (Uint8 *)surface->pixels + surface->offset;	}	/* Increment the surface lock count, for recursive locks */	++surface->locked;	/* Ready to go.. */	return(0);}/* * Unlock a previously locked surface * -- Do not call this from any blit function, as SDL_DrawCursor() may recurse *    Instead, use: *    if ( (surface->flags & SDL_HWSURFACE) == SDL_HWSURFACE ) *               video->UnlockHWSurface(video, surface); */void SDL_UnlockSurface (SDL_Surface *surface){	/* Only perform an unlock if we are locked */	if ( ! surface->locked || (--surface->locked > 0) ) {		return;	}	/* Perform the unlock */	surface->pixels = (Uint8 *)surface->pixels - surface->offset;	/* Unlock hardware or accelerated surfaces */	if ( surface->flags & (SDL_HWSURFACE|SDL_ASYNCBLIT) ) {		SDL_VideoDevice *video = current_video;		SDL_VideoDevice *this  = current_video;		video->UnlockHWSurface(this, surface);	} else {		/* Update RLE encoded surface with new data */		if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {		        surface->flags &= ~SDL_RLEACCEL; /* stop lying */			SDL_RLESurface(surface);		}	}}/*  * Convert a surface into the specified pixel format. */SDL_Surface * SDL_ConvertSurface (SDL_Surface *surface,					SDL_PixelFormat *format, Uint32 flags){	SDL_Surface *convert;	Uint32 colorkey = 0;	Uint8 alpha = 0;	Uint32 surface_flags;	SDL_Rect bounds;	/* Check for empty destination palette! (results in empty image) */	if ( format->palette != NULL ) {		int i;		for ( i=0; i<format->palette->ncolors; ++i ) {			if ( (format->palette->colors[i].r != 0) ||			     (format->palette->colors[i].g != 0) ||			     (format->palette->colors[i].b != 0) )				break;		}		if ( i == format->palette->ncolors ) {			SDL_SetError("Empty destination palette");			return(NULL);		}	}	/* Only create hw surfaces with alpha channel if hw alpha blits	   are supported */	if(format->Amask != 0 && (flags & SDL_HWSURFACE)) {		const SDL_VideoInfo *vi = SDL_GetVideoInfo();		if(!vi || !vi->blit_hw_A)			flags &= ~SDL_HWSURFACE;	}	/* Create a new surface with the desired format */	convert = SDL_CreateRGBSurface(flags,				surface->w, surface->h, format->BitsPerPixel,		format->Rmask, format->Gmask, format->Bmask, format->Amask);	if ( convert == NULL ) {		return(NULL);	}	/* Copy the palette if any */	if ( format->palette && convert->format->palette ) {		memcpy(convert->format->palette->colors,				format->palette->colors,				format->palette->ncolors*sizeof(SDL_Color));		convert->format->palette->ncolors = format->palette->ncolors;	}	/* Save the original surface color key and alpha */	surface_flags = surface->flags;	if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {		/* Convert colourkeyed surfaces to RGBA if requested */		if((flags & SDL_SRCCOLORKEY) != SDL_SRCCOLORKEY		   && format->Amask) {			surface_flags &= ~SDL_SRCCOLORKEY;		} else {			colorkey = surface->format->colorkey;			SDL_SetColorKey(surface, 0, 0);		}	}	if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {		/* Copy over the alpha channel to RGBA if requested */		if ( format->Amask ) {			surface->flags &= ~SDL_SRCALPHA;		} else {			alpha = surface->format->alpha;			SDL_SetAlpha(surface, 0, 0);		}	}	/* Copy over the image data */	bounds.x = 0;	bounds.y = 0;	bounds.w = surface->w;	bounds.h = surface->h;	SDL_LowerBlit(surface, &bounds, convert, &bounds);	/* Clean up the original surface, and update converted surface */	if ( convert != NULL ) {		SDL_SetClipRect(convert, &surface->clip_rect);	}	if ( (surface_flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {		Uint32 cflags = surface_flags&(SDL_SRCCOLORKEY|SDL_RLEACCELOK);		if ( convert != NULL ) {			Uint8 keyR, keyG, keyB;			SDL_GetRGB(colorkey,surface->format,&keyR,&keyG,&keyB);			SDL_SetColorKey(convert, cflags|(flags&SDL_RLEACCELOK),				SDL_MapRGB(convert->format, keyR, keyG, keyB));		}		SDL_SetColorKey(surface, cflags, colorkey);	}	if ( (surface_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {		Uint32 aflags = surface_flags&(SDL_SRCALPHA|SDL_RLEACCELOK);		if ( convert != NULL ) {		        SDL_SetAlpha(convert, aflags|(flags&SDL_RLEACCELOK),				alpha);		}		if ( format->Amask ) {			surface->flags |= SDL_SRCALPHA;		} else {			SDL_SetAlpha(surface, aflags, alpha);		}	}	/* We're ready to go! */	return(convert);}/* * Free a surface created by the above function. */void SDL_FreeSurface (SDL_Surface *surface){	/* Free anything that's not NULL, and not the screen surface */	if ((surface == NULL) ||	    (current_video &&	    ((surface == SDL_ShadowSurface)||(surface == SDL_VideoSurface)))) {		return;	}	if ( --surface->refcount > 0 ) {		return;	}	if ( (surface->flags & SDL_RLEACCEL) == SDL_RLEACCEL ) {	        SDL_UnRLESurface(surface, 0);	}	if ( surface->format ) {		SDL_FreeFormat(surface->format);		surface->format = NULL;	}	if ( surface->map != NULL ) {		SDL_FreeBlitMap(surface->map);		surface->map = NULL;	}	if ( surface->hwdata ) {		SDL_VideoDevice *video = current_video;		SDL_VideoDevice *this  = current_video;		video->FreeHWSurface(this, surface);	}	if ( surface->pixels &&	     ((surface->flags & SDL_PREALLOC) != SDL_PREALLOC) ) {		free(surface->pixels);	}	free(surface);#ifdef CHECK_LEAKS	--surfaces_allocated;#endif}

⌨️ 快捷键说明

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