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

📄 ddrawdisplay.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
📖 第 1 页 / 共 2 页
字号:
				return	false;
			}
		}
	}
	return true;
}

//my best guess for best performance is fast, blt, flip
//dma is off for now because it ran horribly on the machine
//I tested it on.  If people get 500mhz agp bus action in a few
//years it might be useful perhaps
static bool DDRAWDisplay_SetMode(DDRAWDisplay *D, int width, int height, int bpp, uint flags)
{
	HRESULT			dDriveral;
	DDSURFACEDESC2	ddsd;
	DDSCAPS2		ddscaps;

	assert( DDRAWDisplay_IsValid(D)!=false );


	D->ModeFlags = 0;

	dDriveral	=D->DLL.lpDD4->lpVtbl->SetDisplayMode(D->DLL.lpDD4, width, height, bpp, 0, 0);
	
	D->Height	=height;
	D->Width	=width;
	D->BitsPerPixel	=bpp;

	if(!(flags & MODEXMODE))
	{

		memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
		ddsd.dwSize			=sizeof(ddsd);
		ddsd.dwFlags		=DDSD_CAPS;
		ddsd.ddsCaps.dwCaps	=DDSCAPS_PRIMARYSURFACE | DDSCAPS_VIDEOMEMORY;

		dDriveral	=D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
		if(dDriveral==DD_OK)
		{

			memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
			ddsd.dwSize		=sizeof(ddsd);
			ddsd.dwFlags	=DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
			ddsd.ddsCaps.dwCaps	=DDSCAPS_SYSTEMMEMORY;
			//ddsd.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
			ddsd.dwHeight	=height;
			ddsd.dwWidth	=width;

			dDriveral	=D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSBack, NULL);
			if(dDriveral==DD_OK)
			{
				
				//both were created, make sure they are in vidram
				memset(&ddscaps, 0, sizeof(DDSCAPS2));
				D->lpDDSPrimary->lpVtbl->GetCaps(D->lpDDSPrimary, &ddscaps);
				if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
				{
					memset(&ddscaps, 0, sizeof(DDSCAPS2));
					D->lpDDSBack->lpVtbl->GetCaps(D->lpDDSBack, &ddscaps);
					if(ddscaps.dwCaps & DDSCAPS_VIDEOMEMORY)
					{

						//both are good to go
						D->ModeFlags   |=VIDEO;

						//mark fastblt unless it's stretching
						if(!(flags & STRETCHMODE))
						{
							D->ModeFlags	|=FASTBLT;
						}
					}
				}
			}
		}
			#pragma message ("this cant be set can it?")
		else if(!(D->ModeFlags & VIDEO)	&& !(D->ModeFlags & STRETCHMODE))
		{
			if(D->lpDDSBack)		D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
			if(D->lpDDSPrimary)	D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);

			memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
			ddsd.dwSize			=sizeof(ddsd);
			ddsd.dwFlags		=DDSD_CAPS;
			ddsd.ddsCaps.dwCaps	=DDSCAPS_PRIMARYSURFACE;

			dDriveral	=D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
			if(dDriveral==DD_OK)
			{
				memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
				ddsd.dwSize		=sizeof(ddsd);
				ddsd.dwFlags	=DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
				ddsd.dwHeight	=height;
				ddsd.dwWidth	=width;

				dDriveral	=D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSBack, NULL);
				if(dDriveral==DD_OK)
				{
					//both were created good enough
					D->ModeFlags	|=SYSTEM|SAFEBLT;
				}
			}
		}
	}	//flip 

	if((flags & MODEXMODE)	|| D->lpDDSBack==NULL)
	{
		if(D->lpDDSBack)		D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
		if(D->lpDDSPrimary)	D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);

		//try flip
		memset(&ddsd, 0, sizeof(DDSURFACEDESC2));
		ddsd.dwSize				=sizeof(ddsd);
		ddsd.dwFlags			=DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
		ddsd.ddsCaps.dwCaps		=DDSCAPS_PRIMARYSURFACE |
									DDSCAPS_COMPLEX | DDSCAPS_FLIP;
		ddsd.dwBackBufferCount	=1;

		dDriveral	=D->DLL.lpDD4->lpVtbl->CreateSurface(D->DLL.lpDD4, &ddsd, &D->lpDDSPrimary, NULL);
		if(dDriveral==DD_OK)
		{
			memset(&ddscaps, 0, sizeof(DDSCAPS2));
			ddscaps.dwCaps	=DDSCAPS_BACKBUFFER;
			dDriveral	=D->lpDDSPrimary->lpVtbl->GetAttachedSurface(D->lpDDSPrimary, &ddscaps, &D->lpDDSBack);
			if(dDriveral==DD_OK)
			{
				D->ModeFlags	|=SYSTEM|FLIP;
			}
			else
			{
				geErrorLog_AddString(-1,"Unable to create primary buffer",NULL);
				return false;
			}
		}		
	}
	return true;
}


	 

DDRAWDisplay *DDRAWDisplay_Create(HWND hwnd, int Width, int Height, int BPP, uint Flags)
{
	DDRAWDisplay *D = NULL;
	
	HRESULT				dDriveral     = 0;

	D = malloc(sizeof(DDRAWDisplay));
	if (D == NULL)
		{
			geErrorLog_AddString(-1,"Failed to create DDRAWDisplay object",NULL);
			return NULL;
		}

	memset(D,0,sizeof(DDRAWDisplay));


	if (DDRAWDisplay_LoadDLL(&(D->DLL))==false)
		{
			geErrorLog_AddString(-1,"failed to load ddraw dll",NULL);
			goto Create_ERROR;
		}
	D->hWnd = hwnd;
	D->bActive = false;
		
	dDriveral	=D->DLL.lpDD4->lpVtbl->SetCooperativeLevel(D->DLL.lpDD4, hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
	if(dDriveral!=DD_OK)
	{
		geErrorLog_AddString(-1,"DDRAWDisplay_Create: failed to set cooperative level. ", D3DErrorToString(dDriveral));
		goto Create_ERROR;
	}
	
	if (DDRAWDisplay_SetMode(D, Width, Height, BPP, Flags)==false)
	{
		geErrorLog_AddString(-1,"Failed to create buffers",NULL);
		goto Create_ERROR;
	}
	
	assert( DDRAWDisplay_IsValid(D)!=false );
	return D;	

	Create_ERROR:
	if (D)
		{
			DDRAWDisplay_UnloadDLL(&(D->DLL));
			free(D);
		}
	return NULL;
}




bool	DDRAWDisplay_GetPixelFormat(	DDRAWDisplay *D,
											//int *pixel_pitch, 
											int *bytes_per_pixel,
											int *R_shift,
											uint *R_mask,
											int *R_width,
											int *G_shift,
											uint *G_mask,
											int *G_width,
											int *B_shift,
											uint *B_mask,
											int *B_width)
{
	DDPIXELFORMAT	ddpf;
	uint			i, j;

	assert( DDRAWDisplay_IsValid(D)!=false );
	//assert( pixel_pitch     != NULL );
	assert( bytes_per_pixel != NULL );
	assert( R_shift         != NULL );
	assert( R_mask          != NULL );
	assert( R_width         != NULL );
	assert( G_shift         != NULL );
	assert( G_mask          != NULL );
	assert( G_width         != NULL );
	assert( B_shift         != NULL );
	assert( B_mask          != NULL );
	assert( B_width         != NULL );

	ddpf.dwSize	=sizeof(ddpf);
	D->lpDDSPrimary->lpVtbl->GetPixelFormat(D->lpDDSPrimary, &ddpf);

	if(!(ddpf.dwFlags & DDPF_RGB))
	{
		return false;
	}
	*bytes_per_pixel	=ddpf.dwRGBBitCount / 8;
	*R_mask		=ddpf.dwRBitMask;
	*G_mask		=ddpf.dwGBitMask;
	*B_mask		=ddpf.dwBBitMask;

	for(j=0,i=ddpf.dwRBitMask;!(i & 1);i>>=1,j++);
	*R_shift	=j;

	for(j=0,i=ddpf.dwGBitMask;!(i & 1);i>>=1,j++);
	*G_shift	=j;

	for(j=0,i=ddpf.dwBBitMask;!(i & 1);i>>=1,j++);
	*B_shift	=j;

	for(i=(ddpf.dwRBitMask>>*R_shift),*R_width=0;i;i >>= 1, (*R_width)++);
	for(i=(ddpf.dwGBitMask>>*G_shift),*G_width=0;i;i >>= 1, (*G_width)++);
	for(i=(ddpf.dwBBitMask>>*B_shift),*B_width=0;i;i >>= 1, (*B_width)++);
	return true;
}


bool	DDRAWDisplay_Wipe(DDRAWDisplay *D,uint color)
{
	DDSURFACEDESC2	ddsd;
	int				Width, Height;

	assert( DDRAWDisplay_IsValid(D)!=false );

	if(!D->bActive)
	{
		return false;
	}

	if (!D->Locked)
	{
		geErrorLog_AddString(-1,"DDRAWDisplay_Wipe: surface not locked",NULL );
		return false;
	}

	memset(&ddsd, 0, sizeof(DDSCAPS2));
	ddsd.dwSize	=sizeof(ddsd);
	ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;
	#pragma message ("this may not be necessary")
	D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);

	Width	=ddsd.dwWidth;
	Height	=ddsd.dwHeight;

	memset(D->Buffer, color, (Height*D->Pitch));
	return true;
}

bool DDRAWDisplay_SetActive(DDRAWDisplay *D, bool wParam)
{
	assert( D != NULL );

	D->bActive	=wParam;

	if(D->bActive)
	{	
		if(D->lpDDSPrimary->lpVtbl->IsLost(D->lpDDSPrimary)==DDERR_SURFACELOST)
		{
			if(DDRAWDisplay_RestoreAll(D)!=false)
			{
				ShowWindow(D->hWnd, SW_SHOWNORMAL);	//dx doesn't restore it
			}
			else
			{
				geErrorLog_AddString(-1,"DDRAWDisplay_SetActive: Couldn't restore surfaces",NULL);
				return false;
			}
		}
	}
	return	true;
}

// -----------------------------------------------------------


static HRESULT WINAPI DDRAWDisplay_ModeCallback(LPDDSURFACEDESC2 pdds, LPVOID lParam)
{
	DisplayModeInfo *Info =(DisplayModeInfo *)lParam;

	#pragma message ("only 16 bit display is supported")
	if(pdds->ddpfPixelFormat.dwRGBBitCount==16)		
	{
		DisplayModeInfo_AddEntry(Info,
				pdds->dwWidth,
				pdds->dwHeight,
				pdds->ddpfPixelFormat.dwRGBBitCount,
				pdds->ddpfPixelFormat.dwRGBBitCount);
	}
	return	S_FALSE;
}

bool DDRAWDisplay_GetDescriptionString(char *DescriptionString, unsigned int DescriptionStringMaxLength)
{
	DDRAWDisplay_DLLHooks DLL={NULL,0};

	DDDEVICEIDENTIFIER	DDDeviceIdentifier;
	HRESULT				hRet;

	assert( DescriptionString != NULL );
	
	if (DDRAWDisplay_LoadDLL(&DLL)==false)
		{	
			geErrorLog_AddString(-1,"unable to load ddraw dll",NULL);
			goto GetDescriptionString_ERROR;
		}
	
	memset(&DDDeviceIdentifier, 0, sizeof(DDDeviceIdentifier));

	hRet	=DLL.lpDD4->lpVtbl->GetDeviceIdentifier(DLL.lpDD4, &DDDeviceIdentifier,0);
	
	if(hRet != DD_OK)
	{
		geErrorLog_AddString(-1,"DDRAWDisplay_GetDescriptionString: ddraw GetDeviceIdentifier() failed", NULL);
		goto GetDescriptionString_ERROR;
	}

	DDRAWDisplay_UnloadDLL(&DLL);		
	if (strlen(DDDeviceIdentifier.szDescription) + strlen(DDRAWDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
		{
			geErrorLog_AddString(-1,"DDRAWDisplay_GetDescriptionString: description string too short",NULL);
			goto GetDescriptionString_ERROR;
		}

	strcpy(DescriptionString,DDRAWDISPLAY_DESCRIPTION_STRING);
	//strcat(DescriptionString,DDDeviceIdentifier.szDescription);

	return	true;

	//------
	GetDescriptionString_ERROR:
		DDRAWDisplay_UnloadDLL(&DLL);
		return false;
}


bool DDRAWDisplay_GetDisplayInfo(	char			*DescriptionString, 
										unsigned int	 DescriptionStringMaxLength,
										DisplayModeInfo *Info)
{
	DDDEVICEIDENTIFIER	DDDeviceIdentifier;
	DDRAWDisplay_DLLHooks DLL={NULL,0};
	HRESULT				dDriveral = 0;
	
	assert( Info != NULL );

	if (DDRAWDisplay_LoadDLL( &DLL )==false)
		{
			geErrorLog_AddString(-1,"failed to load DDRAW dll",NULL);
			return false;
		}
	
	#if 0
		{
			//test for general dma support
			DDCAPS				ddcaps;
			memset(&ddcaps, 0, sizeof(DDCAPS));
			ddcaps.dwSize	=sizeof(ddcaps);
			DLL.lpDD4->lpVtbl->GetCaps(DLL.lpDD4, &ddcaps, NULL);

			if(ddcaps.dwCaps & DDCAPS_CANBLTSYSMEM)
			{
				//System to video blits supported
				if(ddcaps.dwSVBCaps & DDCAPS_BLTQUEUE)
				{
					D->bDMA	=TRUE;	//	DMA Asynch System to Video blits supported
				}
			}
		}
	#endif


	#if 0		// need this?
		dDriveral	=DLL.lpDD4->lpVtbl->SetCooperativeLevel(DLL.lpDD4, ActiveWnd,
			DDSCL_ALLOWMODEX | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
		if(dDriveral != DD_OK)
			{
				geErrorLog_Add(-1,"Failed to set Cooperative Level",NULL);
				goto GetDisplayInfo_ERROR;
			}
	#endif
	
	memset(&DDDeviceIdentifier, 0, sizeof(DDDeviceIdentifier));

	dDriveral	=DLL.lpDD4->lpVtbl->GetDeviceIdentifier(DLL.lpDD4, &DDDeviceIdentifier,0);
	
	if(dDriveral != DD_OK)
	{
		geErrorLog_AddString(-1,"ddraw GetDeviceIdentifier() failed", NULL);
		goto GetDisplayInfo_ERROR;
	}

	if (strlen(DDDeviceIdentifier.szDescription) + strlen(DDRAWDISPLAY_DESCRIPTION_STRING) >= DescriptionStringMaxLength)
		{
			geErrorLog_AddString(-1,"description string too short",NULL);
			goto GetDisplayInfo_ERROR;
		}

	strcpy(DescriptionString,DDRAWDISPLAY_DESCRIPTION_STRING);
//	strcat(DescriptionString,DDDeviceIdentifier.szDescription);


	DLL.lpDD4->lpVtbl->EnumDisplayModes(DLL.lpDD4, 0, NULL, (LPVOID)Info, DDRAWDisplay_ModeCallback);

	DDRAWDisplay_UnloadDLL(&DLL);
	return		true;	

	GetDisplayInfo_ERROR:
		DDRAWDisplay_UnloadDLL(&DLL);
		return false;

}


bool DDRAWDisplay_UpdateWindow( DDRAWDisplay *D )
{
	// can't do this with full screen modes.
	return false;
}

⌨️ 快捷键说明

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