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

📄 sdl_dx5video.c

📁 linux下面的一个开源的多媒体中间件
💻 C
📖 第 1 页 / 共 5 页
字号:
				(DDSCAPS_OFFSCREENPLAIN|DDSCAPS_VIDEOMEMORY);	} else {		ddsd.ddsCaps.dwCaps =				(DDSCAPS_OFFSCREENPLAIN|DDSCAPS_SYSTEMMEMORY);	}	ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);	ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;	if ( surface->format->palette ) {		ddsd.ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;	}#if defined(NONAMELESSUNION)	ddsd.ddpfPixelFormat.u1.dwRGBBitCount = surface->format->BitsPerPixel;	ddsd.ddpfPixelFormat.u2.dwRBitMask = surface->format->Rmask;	ddsd.ddpfPixelFormat.u3.dwGBitMask = surface->format->Gmask;	ddsd.ddpfPixelFormat.u4.dwBBitMask = surface->format->Bmask;#else	ddsd.ddpfPixelFormat.dwRGBBitCount = surface->format->BitsPerPixel;	ddsd.ddpfPixelFormat.dwRBitMask = surface->format->Rmask;	ddsd.ddpfPixelFormat.dwGBitMask = surface->format->Gmask;	ddsd.ddpfPixelFormat.dwBBitMask = surface->format->Bmask;#endif	/* Create the DirectDraw video surface */	if ( requested != NULL ) {		dd_surface3 = requested;	} else {		result = IDirectDraw2_CreateSurface(ddraw2,						&ddsd, &dd_surface1, NULL); 		if ( result != DD_OK ) {			SetDDerror("DirectDraw2::CreateSurface", result);			goto error_end;		}		result = IDirectDrawSurface_QueryInterface(dd_surface1,			&IID_IDirectDrawSurface3, (LPVOID *)&dd_surface3);		IDirectDrawSurface_Release(dd_surface1);		if ( result != DD_OK ) {			SetDDerror("DirectDrawSurface::QueryInterface", result);			goto error_end;		}	}	if ( (flag & SDL_HWSURFACE) == SDL_HWSURFACE ) {		/* Check to see whether the surface actually ended up		   in video memory, and fail if not.  We expect the		   surfaces we create here to actually be in hardware!		*/		result = IDirectDrawSurface3_GetCaps(dd_surface3,&ddsd.ddsCaps);		if ( result != DD_OK ) {			SetDDerror("DirectDrawSurface3::GetCaps", result);			goto error_end;		}		if ( (ddsd.ddsCaps.dwCaps&DDSCAPS_VIDEOMEMORY) !=							DDSCAPS_VIDEOMEMORY ) {			SDL_SetError("No room in video memory");			goto error_end;		}	} else {		/* Try to hook our surface memory */		ddsd.dwFlags = DDSD_LPSURFACE;		ddsd.lpSurface = surface->pixels;		result = IDirectDrawSurface3_SetSurfaceDesc(dd_surface3,								&ddsd, 0);		if ( result != DD_OK ) {			SetDDerror("DirectDraw2::SetSurfaceDesc", result);			goto error_end;		}		}	/* Make sure the surface format was set properly */	SDL_memset(&ddsd, 0, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	result = IDirectDrawSurface3_Lock(dd_surface3, NULL,		&ddsd, (DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface3::Lock", result);		goto error_end;	}	IDirectDrawSurface3_Unlock(dd_surface3, NULL);	if ( (flag & SDL_HWSURFACE) == SDL_SWSURFACE ) {		if ( ddsd.lpSurface != surface->pixels ) {			SDL_SetError("DDraw didn't use SDL surface memory");			goto error_end;		}		if (#if defined(NONAMELESSUNION)			ddsd.u1.lPitch#else			ddsd.lPitch#endif				 != (LONG)surface->pitch ) {			SDL_SetError("DDraw created surface with wrong pitch");			goto error_end;		}	} else {#if defined(NONAMELESSUNION)		surface->pitch = (Uint16)ddsd.u1.lPitch;#else		surface->pitch = (Uint16)ddsd.lPitch;#endif	}#if defined(NONAMELESSUNION)	if ( (ddsd.ddpfPixelFormat.u1.dwRGBBitCount != 					surface->format->BitsPerPixel) ||	     (ddsd.ddpfPixelFormat.u2.dwRBitMask != surface->format->Rmask) ||	     (ddsd.ddpfPixelFormat.u3.dwGBitMask != surface->format->Gmask) ||	     (ddsd.ddpfPixelFormat.u4.dwBBitMask != surface->format->Bmask) ){#else	if ( (ddsd.ddpfPixelFormat.dwRGBBitCount != 					surface->format->BitsPerPixel) ||	     (ddsd.ddpfPixelFormat.dwRBitMask != surface->format->Rmask) ||	     (ddsd.ddpfPixelFormat.dwGBitMask != surface->format->Gmask) ||	     (ddsd.ddpfPixelFormat.dwBBitMask != surface->format->Bmask) ){#endif		SDL_SetError("DDraw didn't use SDL surface description");		goto error_end;	}	if ( (ddsd.dwWidth != (DWORD)surface->w) ||		(ddsd.dwHeight != (DWORD)surface->h) ) {		SDL_SetError("DDraw created surface with wrong size");		goto error_end;	}	/* Set the surface private data */	surface->flags |= flag;	surface->hwdata->dd_surface = dd_surface3;	if ( (surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF ) {		LPDIRECTDRAWSURFACE3 dd_writebuf;		ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;		result = IDirectDrawSurface3_GetAttachedSurface(dd_surface3,						&ddsd.ddsCaps, &dd_writebuf);		if ( result != DD_OK ) {			SetDDerror("DirectDrawSurface3::GetAttachedSurface",								result);		} else {			dd_surface3 = dd_writebuf;		}	}	surface->hwdata->dd_writebuf = dd_surface3;	/* We're ready to go! */	return(0);	/* Okay, so goto's are cheesy, but there are so many possible	   errors in this function, and the cleanup is the same in 	   every single case.  Is there a better way, other than deeply	   nesting the code?	*/error_end:	if ( (dd_surface3 != NULL) && (dd_surface3 != requested) ) {		IDirectDrawSurface_Release(dd_surface3);	}	SDL_free(surface->hwdata);	surface->hwdata = NULL;	return(-1);}static int DX5_AllocHWSurface(_THIS, SDL_Surface *surface){	/* DDraw limitation -- you need to set cooperative level first */	if ( SDL_primary == NULL ) {		SDL_SetError("You must set a non-GL video mode first");		return(-1);	}	return(DX5_AllocDDSurface(this, surface, NULL, SDL_HWSURFACE));}#ifdef DDRAW_DEBUGvoid PrintSurface(char *title, LPDIRECTDRAWSURFACE3 surface, Uint32 flags){	DDSURFACEDESC ddsd;	/* Lock and load! */	SDL_memset(&ddsd, 0, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	if ( IDirectDrawSurface3_Lock(surface, NULL, &ddsd,			(DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL) != DD_OK ) {		return;	}	IDirectDrawSurface3_Unlock(surface, NULL);		fprintf(stderr, "%s:\n", title);	fprintf(stderr, "\tSize: %dx%d in %s at %ld bpp (pitch = %ld)\n",		ddsd.dwWidth, ddsd.dwHeight,		(flags & SDL_HWSURFACE) ? "hardware" : "software",#if defined(NONAMELESSUNION)		ddsd.ddpfPixelFormat.u1.dwRGBBitCount, ddsd.u1.lPitch);#else		ddsd.ddpfPixelFormat.dwRGBBitCount, ddsd.lPitch);#endif	fprintf(stderr, "\tR = 0x%X, G = 0x%X, B = 0x%X\n", #if defined(NONAMELESSUNION)	     		ddsd.ddpfPixelFormat.u2.dwRBitMask,	     		ddsd.ddpfPixelFormat.u3.dwGBitMask,	     		ddsd.ddpfPixelFormat.u4.dwBBitMask);#else	     		ddsd.ddpfPixelFormat.dwRBitMask,	     		ddsd.ddpfPixelFormat.dwGBitMask,	     		ddsd.ddpfPixelFormat.dwBBitMask);#endif}#endif /* DDRAW_DEBUG */static int DX5_HWAccelBlit(SDL_Surface *src, SDL_Rect *srcrect,					SDL_Surface *dst, SDL_Rect *dstrect){	LPDIRECTDRAWSURFACE3 src_surface;	LPDIRECTDRAWSURFACE3 dst_surface;	DWORD flags;	RECT rect;	HRESULT result;	/* Set it up.. the desination must have a DDRAW surface */	src_surface = src->hwdata->dd_writebuf;	dst_surface = dst->hwdata->dd_writebuf;	rect.top    = (LONG)srcrect->y;	rect.bottom = (LONG)srcrect->y+srcrect->h;	rect.left   = (LONG)srcrect->x;	rect.right  = (LONG)srcrect->x+srcrect->w;	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY )		flags = DDBLTFAST_SRCCOLORKEY;	else		flags = DDBLTFAST_NOCOLORKEY;	/* FIXME:  We can remove this flag for _really_ fast blit queuing,	           but it will affect the return values of locks and flips.	 */	flags |= DDBLTFAST_WAIT;	/* Do the blit! */	result = IDirectDrawSurface3_BltFast(dst_surface,			dstrect->x, dstrect->y, src_surface, &rect, flags);	if ( result != DD_OK ) {		if ( result == DDERR_SURFACELOST ) {			result = IDirectDrawSurface3_Restore(src_surface);			result = IDirectDrawSurface3_Restore(dst_surface);			/* The surfaces need to be reloaded with artwork */			SDL_SetError("Blit surfaces were lost, reload them");			return(-2);		}		SetDDerror("IDirectDrawSurface3::BltFast", result);#ifdef DDRAW_DEBUG fprintf(stderr, "Original dest rect: %dx%d at %d,%d\n", dstrect->w, dstrect->h, dstrect->x, dstrect->y); fprintf(stderr, "HW accelerated %sblit to from 0x%p to 0x%p at (%d,%d)\n",		(src->flags & SDL_SRCCOLORKEY) ? "colorkey " : "", src, dst,					dstrect->x, dstrect->y);  PrintSurface("SRC", src_surface, src->flags);  PrintSurface("DST", dst_surface, dst->flags); fprintf(stderr, "Source rectangle: (%d,%d) - (%d,%d)\n",		rect.left, rect.top, rect.right, rect.bottom);#endif		/* Unexpected error, fall back to software blit */		return(src->map->sw_blit(src, srcrect, dst, dstrect));	}	return(0);}static int DX5_CheckHWBlit(_THIS, SDL_Surface *src, SDL_Surface *dst){	int accelerated;	/* We need to have a DDraw surface for HW blits */	if ( (src->flags & SDL_HWSURFACE) == SDL_SWSURFACE ) {		/* Allocate a DDraw surface for the blit */		if ( src->hwdata == NULL ) {			DX5_AllocDDSurface(this, src, NULL, SDL_SWSURFACE);		}	}	if ( src->hwdata == NULL ) {		return(0);	}	/* Set initial acceleration on */	src->flags |= SDL_HWACCEL;	/* Set the surface attributes */	if ( (src->flags & SDL_SRCCOLORKEY) == SDL_SRCCOLORKEY ) {		if ( DX5_SetHWColorKey(this, src, src->format->colorkey) < 0 ) {			src->flags &= ~SDL_HWACCEL;		}	}	if ( (src->flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {		if ( DX5_SetHWAlpha(this, src, src->format->alpha) < 0 ) {			src->flags &= ~SDL_HWACCEL;		}	}	/* Check to see if final surface blit is accelerated */	accelerated = !!(src->flags & SDL_HWACCEL);	if ( accelerated ) {#ifdef DDRAW_DEBUG  fprintf(stderr, "Setting accelerated blit on 0x%p\n", src);#endif		src->map->hw_blit = DX5_HWAccelBlit;	}	return(accelerated);}static int DX5_FillHWRect(_THIS, SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color){	LPDIRECTDRAWSURFACE3 dst_surface;	RECT area;	DDBLTFX bltfx;	HRESULT result;#ifdef DDRAW_DEBUG fprintf(stderr, "HW accelerated fill at (%d,%d)\n", dstrect->x, dstrect->y);#endif	dst_surface = dst->hwdata->dd_writebuf;	area.top    = (LONG)dstrect->y;	area.bottom = (LONG)dstrect->y+dstrect->h;	area.left   = (LONG)dstrect->x;	area.right  = (LONG)dstrect->x+dstrect->w;	bltfx.dwSize = sizeof(bltfx);#if defined(NONAMELESSUNION)	bltfx.u5.dwFillColor = color;#else	bltfx.dwFillColor = color;#endif	result = IDirectDrawSurface3_Blt(dst_surface,			&area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &bltfx);	if ( result == DDERR_SURFACELOST ) {		IDirectDrawSurface3_Restore(dst_surface);		result = IDirectDrawSurface3_Blt(dst_surface,			&area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &bltfx);	}	if ( result != DD_OK ) {		SetDDerror("IDirectDrawSurface3::Blt", result);		return(-1);	}	return(0);}static int DX5_SetHWColorKey(_THIS, SDL_Surface *surface, Uint32 key){	DDCOLORKEY colorkey;	HRESULT result;	/* Set the surface colorkey */	colorkey.dwColorSpaceLowValue = key;	colorkey.dwColorSpaceHighValue = key;	result = IDirectDrawSurface3_SetColorKey(			surface->hwdata->dd_surface, DDCKEY_SRCBLT, &colorkey);	if ( result != DD_OK ) {		SetDDerror("IDirectDrawSurface3::SetColorKey", result);		return(-1);	}	return(0);}static int DX5_SetHWAlpha(_THIS, SDL_Surface *surface, Uint8 alpha){	return(-1);}static int DX5_LockHWSurface(_THIS, SDL_Surface *surface){	HRESULT result;	LPDIRECTDRAWSURFACE3 dd_surface;	DDSURFACEDESC ddsd;	/* Lock and load! */	dd_surface = surface->hwdata->dd_writebuf;	SDL_memset(&ddsd, 0, sizeof(ddsd));	ddsd.dwSize = sizeof(ddsd);	result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd,					(DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);	if ( result == DDERR_SURFACELOST ) {		result = IDirectDrawSurface3_Restore(						surface->hwdata->dd_surface);		result = IDirectDrawSurface3_Lock(dd_surface, NULL, &ddsd, 					(DDLOCK_NOSYSLOCK|DDLOCK_WAIT), NULL);	}	if ( result != DD_OK ) {		SetDDerror("DirectDrawSurface3::Lock", result);		return(-1);	}	/* Pitch might have changed -- recalculate pitch and offset */#if defined(NONAMELESSUNION)	if ( surface->pitch != ddsd.u1.lPitch ) {		surface->pitch = ddsd.u1.lPitch;#else	if ( surface->pitch != ddsd.lPitch ) {		surface->pitch = (Uint16)ddsd.lPitch;#endif		surface->offset =			((ddsd.dwHeight-surface->h)/2)*surface->pitch +			((ddsd.dwWidth-surface->w)/2)*					surface->format->BytesPerPixel;	}	surface->pixels = ddsd.lpSurface;	return(0);}static void DX5_UnlockHWSurface(_THIS, SDL_Surface *surface){	IDirectDrawSurface3_Unlock(surface->hwdata->dd_writebuf, NULL);	surface->pixels = NULL;}static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface){	HRESULT result;	LPDIRECTDRAWSURFACE3 dd_surface;	dd_surface = surface->hwdata->dd_surface;	/* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */	/* Dmitry Yakimov (ftech@tula.net) */	while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);	result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);	if ( result == DDERR_SURFACELOST ) {		result = IDirectDrawSurface3_Restore(						surface->hwdata->dd_surface);		while(ID

⌨️ 快捷键说明

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