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

📄 ddrawdisplay.c

📁 傅立叶变换和小波变换是图像压缩的重要工具。该代大戏是利用小波变换进行图像压缩。
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************************/
/*  DDRAWDisplay.C                                                                      */
/*                                                                                      */
/*  Author:  Mike Sandige                                                               */
/*  Description:  display surface manager for full screen Direct Draw using a direct    */
/*                draw surface for the the frame buffer                                 */
/*                                                                                      */
/*  The contents of this file are subject to the Genesis3D Public License               */
/*  Version 1.0 (the "License"); you may not use this file except in                    */
/*  compliance with the License. You may obtain a copy of the License at                */
/*  http://www.genesis3d.com                                                            */
/*                                                                                      */
/*  Software distributed under the License is distributed on an "AS IS"                 */
/*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
/*  the License for the specific language governing rights and limitations              */
/*  under the License.                                                                  */
/*                                                                                      */
/*  The Original Code is Genesis3D, released March 25, 1999.                            */
/*  Copyright (C) 1996-1999 Eclipse Entertainment, L.L.C. All Rights Reserved           */
/*                                                                                      */
/****************************************************************************************/

#define DIRECTDRAW_VERSION	0x0400

#pragma warning(disable : 4201 4214 4115)
#include <windows.h>
#include <assert.h>
#include "ddraw.h"
#include <stdio.h>
#pragma warning(default : 4201 4214 4115; disable : 4514)

#include "driver.h"
#include "DDRAWDisplay.h" 
#include "errorlog.h"
#include "d3d_err.h"

#undef DEFINE_GUID
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
    EXTERN_C const GUID name \
                    = { l, w1, w2, { b1, b2,  b3,  b4,  b5,  b6,  b7,  b8 } }

DEFINE_GUID( IID_IDirectDraw4,                  0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 );

static const char * DDRAWDISPLAY_DESCRIPTION_STRING = "Full Screen ";

typedef struct 
{
	LPDIRECTDRAW4			lpDD4;
	HANDLE					ddrawinst;
} DDRAWDisplay_DLLHooks;

typedef struct DDRAWDisplay 
{
	DDRAWDisplay_DLLHooks  DLL;

	LPDIRECTDRAWSURFACE4	lpDDSPrimary;	// DirectDraw primary surface
	LPDIRECTDRAWSURFACE4	lpDDSBack;		// DirectDraw back surface
	BOOL					bActive;

	int				Width;
	int				Height;
	int				BitsPerPixel;
	int				ModeFlags;

	HWND			hWnd;
	bool		Locked;
	ubyte			*Buffer;
	int			Pitch;
} DDRAWDisplay;

typedef HRESULT (WINAPI *LPDIRECTDRAWCREATE)( GUID FAR *lpGUID, LPDIRECTDRAW FAR *lplpDD, IUnknown FAR *pUnkOuter );


static bool DDRAWDisplay_IsValid(DDRAWDisplay *D)
{
	if ( D == NULL )
		return false;

	if (D->DLL.ddrawinst == NULL )
		return false;

	if (D->DLL.lpDD4 == NULL)
		return false;

	if (D->hWnd == NULL )
		return false;

	return true;
}

static void DDRAWDisplay_UnloadDLL( DDRAWDisplay_DLLHooks *H )
{
	assert( H != NULL );
	if (H->lpDD4)
		{
			H->lpDD4->lpVtbl->Release(H->lpDD4);
			H->lpDD4 = NULL;
		}
	if (H->ddrawinst)
		{
			FreeLibrary(H->ddrawinst);
			H->ddrawinst = NULL;
		}
}

static bool DDRAWDisplay_LoadDLL( DDRAWDisplay_DLLHooks *H )
{
	LPDIRECTDRAW			lpDD       = NULL;			// DirectDraw object
	LPDIRECTDRAWCREATE		lpDDCreate = NULL;
	HRESULT	dDriveral;
	assert( H != NULL );
	
	H->ddrawinst = NULL;
	H->lpDD4	 = NULL;


	H->ddrawinst	=LoadLibrary("ddraw.dll");

	if(!H->ddrawinst)
	{
		geErrorLog_AddString(-1,"failed to load","ddraw.dll");
		goto LoadDLL_ERROR;
	}
	
	lpDDCreate	=(LPDIRECTDRAWCREATE)GetProcAddress(H->ddrawinst, "DirectDrawCreate");
	if(lpDDCreate)
		{
			dDriveral	=lpDDCreate(NULL, &(lpDD), NULL);
			if((dDriveral != DD_OK) || ((lpDD)==NULL))
				{
					geErrorLog_AddString(-1,"ddraw lpDDCreate failed. ",  D3DErrorToString(dDriveral));
					goto LoadDLL_ERROR;
				}
		}
	else
		{
			geErrorLog_AddString(-1 ,"Unable to find DirectDrawCreate entry into ddraw.dll",NULL);
			goto LoadDLL_ERROR;
		}
	
	dDriveral = lpDD->lpVtbl->QueryInterface(lpDD, &IID_IDirectDraw4, (LPVOID *)&(H->lpDD4));
	if(dDriveral!=DD_OK)
	{
		geErrorLog_AddString(-1,"QueryInterface failed. ", D3DErrorToString(dDriveral));
		goto LoadDLL_ERROR;
	}
	
	lpDD->lpVtbl->Release(lpDD);
	lpDD	=NULL;


	return true;


	LoadDLL_ERROR:
		if (lpDD != NULL )
			{
				lpDD->lpVtbl->Release(lpDD);
				lpDD	=NULL;
			}
		DDRAWDisplay_UnloadDLL(H);
	return false;
}
	
void DDRAWDisplay_GetDisplayFormat(	const DDRAWDisplay *D,
									int   *Width, 
									int   *Height,
									int   *BitsPerPixel,
									uint  *Flags)
{
	assert( D            != NULL );
	assert( Width        != NULL );
	assert( Height       != NULL );
	assert( BitsPerPixel != NULL );
	assert( Flags        != NULL );

	*Width        = D->Width;
	*Height       = D->Height;
	*BitsPerPixel = D->BitsPerPixel;
	*Flags        = D->ModeFlags;
}	

void	DDRAWDisplay_Destroy(DDRAWDisplay **pD)
{
	DDRAWDisplay *D;

	assert( pD );
	assert( DDRAWDisplay_IsValid(*pD)!=false );
	D = *pD;

	if (D->Locked == true)
		DDRAWDisplay_Unlock(D);

	if (D->ModeFlags & FLIP)
	{
		D->lpDDSBack	=NULL;
	}
	else
	{
		if(D->lpDDSBack)
		{
			D->lpDDSBack->lpVtbl->Release(D->lpDDSBack);
			D->lpDDSBack	=NULL;
		}
	}
	if(D->lpDDSPrimary)
	{
		D->lpDDSPrimary->lpVtbl->Release(D->lpDDSPrimary);
		D->lpDDSPrimary	=NULL;
	}

	DDRAWDisplay_UnloadDLL(&(D->DLL));
	
	free(D);
	*pD = NULL;
}

static bool DDRAWDisplay_RestoreAll(DDRAWDisplay *D)
{
	HRESULT	dDriveral;
	assert( DDRAWDisplay_IsValid(D)!=false );

	dDriveral	=D->DLL.lpDD4->lpVtbl->SetCooperativeLevel(D->DLL.lpDD4, D->hWnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN);
	if(dDriveral!=DD_OK)
	{
		geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll(): ddraw SetCooperativeLevel. ", D3DErrorToString(dDriveral));
		return	false;
	}

	dDriveral	=D->DLL.lpDD4->lpVtbl->SetDisplayMode(D->DLL.lpDD4, D->Width, D->Height, D->BitsPerPixel, 0, 0);
	if(dDriveral!=DD_OK)
	{
		geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll: ddraw SetDisplayMode. ", D3DErrorToString(dDriveral));
		return	false;
	}
	dDriveral	=D->DLL.lpDD4->lpVtbl->RestoreAllSurfaces(D->DLL.lpDD4);
	if(dDriveral!=DD_OK)
	{
		geErrorLog_AddString(-1,"DDRAWDisplay_RestoreAll: ddraw RestoreAllSurfaces. ", D3DErrorToString(dDriveral));
		return	false;
	}
	return	true;
}


bool	DDRAWDisplay_Lock(DDRAWDisplay *D, ubyte **Buffer, int *Pitch)
{
	HRESULT			dDriveral;
	DDSURFACEDESC2	ddsd;
	RECT			wrect;
	int Forever = 1;
	assert( DDRAWDisplay_IsValid(D)!=false );

	if(!D->bActive)
		return true;
		// <> should probably be false, but this stays compatible with the existing convention

	assert( Buffer != NULL );
	assert( Pitch  != NULL );

	if (D->Locked != false)
		{
			geErrorLog_AddString(-1,"DDRAWDisplay_Lock: already locked",NULL );
			return false;
		}
	
	memset(&ddsd, 0, sizeof(DDSCAPS2));
	ddsd.dwSize	=sizeof(ddsd);
	ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;

	D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
	wrect.left   = 0;
	wrect.top    = 0;
	wrect.right  = ddsd.dwWidth-1;
	wrect.bottom = ddsd.dwHeight-1;

	while(Forever)
	{
		dDriveral	=D->lpDDSBack->lpVtbl->Lock(D->lpDDSBack, &wrect, &ddsd, DDLOCK_SURFACEMEMORYPTR, NULL);
		if(dDriveral==DD_OK)
		{
			break;
		}

		if(dDriveral==DDERR_SURFACELOST)
		{
			if (DDRAWDisplay_RestoreAll(D) == false) 
			{
				geErrorLog_AddString(-1,"DDRAWDisplay_Lock: lost ddraw surface", NULL);
				return	false;
			}
		}
		else if(dDriveral!=DDERR_WASSTILLDRAWING)
		{
			geErrorLog_AddString(-1,"DDRAWDisplay_Lock: was still drawing. ",D3DErrorToString(dDriveral));
			return	false;
		}
	}
	*Buffer	= (ubyte *)ddsd.lpSurface;
	*Pitch  = ddsd.lPitch;
	D->Locked = true;
	D->Buffer = *Buffer;
	D->Pitch  = *Pitch;
	return true;
}

bool	DDRAWDisplay_Unlock(DDRAWDisplay *D)
{
	int Forever=1;
	HRESULT			dDriveral	=DD_OK;
	assert( DDRAWDisplay_IsValid(D)!=false );

	if(!D->bActive)
		return true;
		// <> should probably be false, but this stays compatible with the existing convention

	if (D->Locked != true)
		{
			geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: surface not locked",NULL);
			return false;
		}
	
	D->Locked = false;
	
	while(Forever)
	{
		dDriveral	=D->lpDDSBack->lpVtbl->Unlock(D->lpDDSBack, NULL);
		if(dDriveral==DD_OK)
			break;

		#pragma message (" can you loose a locked surface?")
		if(dDriveral==DDERR_SURFACELOST)		
		{
			if (DDRAWDisplay_RestoreAll(D) == false)
			{
				geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: surface lost\n",NULL);
				return	false;
			}
		}
		else if(dDriveral!=DDERR_WASSTILLDRAWING)
		{
			geErrorLog_AddString(-1,"DDRAWDisplay_Unlock: was still drawing. ",D3DErrorToString(dDriveral));
			return	false;
		}
	}

	D->Locked = false;
	return true;
}

bool	DDRAWDisplay_Blit(DDRAWDisplay *D)
{
	HRESULT			dDriveral;
	DDSURFACEDESC2	ddsd;
	RECT			rDest, rSrc;
	int				Forever=1;
	assert( DDRAWDisplay_IsValid(D)!=false );

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

	memset(&ddsd, 0, sizeof(DDSCAPS2));
	ddsd.dwSize	=sizeof(ddsd);
	ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH; 

	D->lpDDSBack->lpVtbl->GetSurfaceDesc(D->lpDDSBack, &ddsd);
	rDest.left	=rDest.top	=0;
	rDest.right	=ddsd.dwWidth-1;
	rDest.bottom=ddsd.dwHeight-1;

	memset(&ddsd, 0, sizeof(DDSCAPS2));
	ddsd.dwSize	=sizeof(ddsd);
	ddsd.dwFlags=DDSD_HEIGHT | DDSD_WIDTH;

	D->lpDDSPrimary->lpVtbl->GetSurfaceDesc(D->lpDDSPrimary, &ddsd);
	rSrc.left	=rSrc.top	=0;
	rSrc.right	=ddsd.dwWidth-1;
	rSrc.bottom	=ddsd.dwHeight-1;

	dDriveral	=DD_OK;
	if((D->ModeFlags & VIDEO) && (D->ModeFlags & FASTBLT))
	{
		while(Forever)
		{
			dDriveral	=D->lpDDSPrimary->lpVtbl->BltFast(D->lpDDSPrimary, 0, 0, D->lpDDSBack, NULL, 0);
			if(dDriveral==DD_OK)
			{
				break;
			}

			if(dDriveral==DDERR_SURFACELOST)
			{
				if (DDRAWDisplay_RestoreAll(D) == false)
				{
					geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
					return	false;
				}
			}
			else if(dDriveral!=DDERR_WASSTILLDRAWING)
			{
				geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
				return	false;
			}
		}
	}
	else if(D->ModeFlags & FLIP)
	{
		while(Forever)
		{
			dDriveral	=D->lpDDSPrimary->lpVtbl->Flip(D->lpDDSPrimary, D->lpDDSBack, DDFLIP_NOVSYNC);
			if(dDriveral==DD_OK)
			{
				break;
			}

			if(dDriveral==DDERR_SURFACELOST)
			{
				if (DDRAWDisplay_RestoreAll(D)==false)
				{
					geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
					return	false;
				}
			}
			else if(dDriveral!=DDERR_WASSTILLDRAWING)
			{
				geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);
				return	false;
			}
		}
	}
	else	//safe blt
	{
		while(Forever)
		{
			dDriveral	=D->lpDDSPrimary->lpVtbl->Blt(D->lpDDSPrimary, NULL, D->lpDDSBack, NULL, DDBLT_WAIT, NULL);
			if(dDriveral==DD_OK)
				break;

			if(dDriveral==DDERR_SURFACELOST)
			{
				if (DDRAWDisplay_RestoreAll(D)==false)
				{
					geErrorLog_AddString(-1,"DDRAWDisplay_Blit: lost surface",NULL);
					return	false;
				}
			}
			else if(dDriveral!=DDERR_WASSTILLDRAWING)
			{
				geErrorLog_AddString(-1,"DDRAWDisplay_Blit: was still drawing",NULL);

⌨️ 快捷键说明

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