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

📄 ddutil.cpp

📁 vc ad
💻 CPP
字号:
#include "stdafx.h"
#include "ddraw.h"
#include "card.h"

LPDIRECTDRAW			g_pDD;
LPDIRECTDRAWSURFACE		g_pDDSPrimary;
LPDIRECTDRAWSURFACE		g_pDDSOverlay;
DDOVERLAYFX				g_OverlayFX;         // DirectDraw overlay effects struct
int						g_PrimeMode;
DDCOLORKEY				g_ColorKey;
int						g_InitScaleX=1000;
int						g_InitScaleY=1000;
int						g_ScaleX=1000;
int						g_ScaleY=1000;

AVE2KLIB_DISPLAY_PARAMETER g_ParaPrimary, g_ParaOverlay;
enum {DD_RGB565=1, DD_RGB1555, DD_RGB24, DD_RGB32, DD_RGB8};
RECT						g_rcSrc, g_rcDest;
int						m_DDRAWValid=0;
BOOL					bYUV=FALSE;

///////////DDRAW functions
void PrintDDrawError(HRESULT hResult)
{
	if(hResult==DD_OK)
		return;
	char szBuffer[100];
	switch(hResult)	
	{
    case	DDERR_NODIRECTDRAWHW:
			sprintf(szBuffer, "DDERR_INCOMPATIBLEPRIMARY\n");
			break ;

	case	DDERR_INVALIDPARAMS:
			sprintf(szBuffer, "DDERR_INVALIDOBJECT\n");
			break ;

	case	DDERR_INVALIDPIXELFORMAT:
			sprintf(szBuffer, "DDERR_INVALIDPIXELFORMAT\n");
			break;

	case	DDERR_NOALPHAHW :
			sprintf(szBuffer, "DDERR_NOCOOPERATIVELEVELSET\n");
			break;


	case	DDERR_INVALIDCAPS:
			sprintf(szBuffer, "DDERR_INVALIDPARAMS\n");
			break;

	case	DDERR_PRIMARYSURFACEALREADYEXISTS:
			sprintf(szBuffer, "DDERR_INVALIDCAPS\n");
			break;		

	case	DDERR_NOOVERLAYHW:
			sprintf(szBuffer, "DDERR_NOOVERLAYHW\n");
			break;	

    case	DDERR_OUTOFVIDEOMEMORY:
			sprintf(szBuffer, "DDERR_OUTOFVIDEOMEMORY\n");
			break;		

    case	DDERR_TOOBIGWIDTH:
			sprintf(szBuffer, "DDERR_TOOBIGWIDTH\n");
			break;		

    case	DDERR_TOOBIGSIZE:
			sprintf(szBuffer, "DDERR_TOOBIGSIZE\n");
			break;		
	case	DDERR_NOCOLORKEYHW:
			sprintf(szBuffer, "DDERR_NOCOLORKEYHW\n");
			break;		
    default:
            sprintf(szBuffer, "DDERR_UNKNOWN\n");
	}
	AfxMessageBox( szBuffer, MB_OK);
}
DWORD DDColorMatch(IDirectDrawSurface * pdds, COLORREF rgb)
{
    COLORREF                rgbT;
    HDC                     hdc;
    DWORD                   dw = CLR_INVALID;
    DDSURFACEDESC          ddsd;
    HRESULT                 hres;

    //
    //  Use GDI SetPixel to color match for us
    //
    if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
    {
        rgbT = GetPixel(hdc, 0, 0);     // Save current pixel value
        SetPixel(hdc, 0, 0, rgb);       // Set our value
        pdds->ReleaseDC(hdc);
    }
    //
    // Now lock the surface so we can read back the converted color
    //
    ddsd.dwSize = sizeof(ddsd);
    while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
        ;
    if (hres == DD_OK)
    {
        dw = *(DWORD *) ddsd.lpSurface;                 // Get DWORD
        if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
            dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1;  // Mask it to bpp
		//memset(ddsd.lpSurface, dw, 3200);
        pdds->Unlock(NULL);
    }
    //
    //  Now put the color that was there back.
    //
    if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
    {
        SetPixel(hdc, 0, 0, rgbT);
        pdds->ReleaseDC(hdc);
    }
    return dw;
}

//-----------------------------------------------------------------------------
// Name: DestroyOverlay()
// Desc: Releases the overlay surface
//-----------------------------------------------------------------------------
void
DestroyOverlay()
{
    if (g_pDDSOverlay)
    {
        g_pDDSOverlay->Release();
        g_pDDSOverlay = NULL;
    }
}




//-----------------------------------------------------------------------------
// Name: DestroyPrimary()
// Desc: Releases the primary surface
//-----------------------------------------------------------------------------
void
DestroyPrimary()
{
    if (g_pDDSPrimary)
    {
        g_pDDSPrimary->Release();
        g_pDDSPrimary = NULL;
    }
}
//-----------------------------------------------------------------------------
// Name: DestroyDDraw()
// Desc: Releases core DirectDraw objects
//-----------------------------------------------------------------------------
void
DestroyDDraw()
{
    DestroyPrimary();
    // Release the DDraw object
    if (g_pDD)
    {
        g_pDD->Release();
        g_pDD = NULL;
    }
}
//-----------------------------------------------------------------------------
// Name: DDPrimaryInit()
// Desc: Init the primary surface
//-----------------------------------------------------------------------------
int
DDPrimaryInit()
{
    HRESULT                     hRet;
    DDSURFACEDESC              ddsd;  // A surface description structure

	if(g_pDD==NULL)
		return FALSE;
    // Create the primary surface.  The primary surface is the full screen -
    // since we're a windowed app - we'll just write to the portion of the
    // screen within our window.
    memset(&ddsd, 0, sizeof(ddsd)); // Set all fields of struct to 0 and set .dwSize to
    ddsd.dwSize = sizeof(ddsd);     // Sizeof the variable - these two steps required for most DDraw structs
    ddsd.dwFlags = DDSD_CAPS;       // Set flags for variables we're using...
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;  // Set the variables we said we would in dwFlags
    hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
    if (hRet != DD_OK)
        return FALSE;

	//detect g_PrimeMode
	hRet = g_pDDSPrimary->GetSurfaceDesc(&ddsd);
	if ( hRet != DD_OK )
	{
	    g_pDD->Release();
		MessageBox(0, "Failed to get surface desciption!", "Error", MB_OK);
	    return FALSE;
	}

	// check if it is RGB Format
	// delete format check because I'm sure primary surface is RGB only
	//if ( ddsd.ddpfPixelFormat.dwFlags & DDPF_RGB )
	//{
	DWORD m_dwVGAPitch			= (DWORD)ddsd.lPitch;
	DWORD m_dwVGABitCount		= ddsd.ddpfPixelFormat.dwRGBBitCount;
	DWORD m_dwVGAPixelDepth		= (ddsd.ddpfPixelFormat.dwRGBBitCount + 7) / 8;
    g_ParaPrimary.Pitch = m_dwVGAPitch;
	g_ParaPrimary.Depth = m_dwVGAPixelDepth;
	g_ParaPrimary.Height = ddsd.dwHeight;
	g_ParaPrimary.Width = ddsd.dwWidth;

	if (ddsd.ddpfPixelFormat.dwRGBBitCount == 16)
	{
		if ((ddsd.ddpfPixelFormat.dwRBitMask == 0x7C00) &&
			(ddsd.ddpfPixelFormat.dwGBitMask == 0x03E0) &&
			(ddsd.ddpfPixelFormat.dwBBitMask == 0x001F))
        {
		    m_dwVGABitCount = 15;
			g_PrimeMode=DD_RGB1555;
        }
		else
			g_PrimeMode=DD_RGB565;
	}
	else
		if(ddsd.ddpfPixelFormat.dwRGBBitCount == 24)
			g_PrimeMode=DD_RGB24;
		else
			if(ddsd.ddpfPixelFormat.dwRGBBitCount == 8)
				g_PrimeMode=DD_RGB8;
			else
				g_PrimeMode=DD_RGB32;
	g_ParaPrimary.BitCount=m_dwVGABitCount;

	g_pDDSPrimary->Lock( NULL , &ddsd , 0 , NULL );
    g_ParaPrimary.VirtualAddress = (DWORD)ddsd.lpSurface; 
	g_pDDSPrimary->Unlock( NULL );
    return TRUE;
}
//-----------------------------------------------------------------------------
// Name: DDOverlayInit()
// Desc: Setup the overlay object
//-----------------------------------------------------------------------------
int
DDOverlayInit()
{
    DDSURFACEDESC              ddsd;  // DirectDraw surface descriptor
    HRESULT                     hRet;  // I'm not even going to try...
	int nTestPass=0;
    DDPIXELFORMAT               ddpfOverlayFormat =
    // The pixel format that we want the surface to be in
                                {
                                    sizeof(DDPIXELFORMAT),
                                    DDPF_RGB,
                                    0, 16,
                                    0xf800, 0x07e0, 0x001F,   // 16 bit RGB 5:6:5
                                    //0x7c00, 0x03e0, 0x001F,   // 16 bit RGB 1:5:5:5
                                    0
                                };
	//return FALSE;
    // Setup the overlay surface's attributes in the surface descriptor
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_VIDEOMEMORY;
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;
    ddsd.dwBackBufferCount = 0;
    ddsd.dwWidth = (g_ParaPrimary.Width*1000)/g_InitScaleX;
    ddsd.dwHeight = (g_ParaPrimary.Height*1000)/g_InitScaleY;
    //ddsd.ddpfPixelFormat = ddpfOverlayFormat;  // Use 16 bit RGB 5:6:5 pixel format
	ddsd.ddpfPixelFormat.dwSize = sizeof( DDPIXELFORMAT );
	ddsd.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
	ddsd.ddpfPixelFormat.dwFourCC = 0x32595559L; // YUY2
RECREATE:
    // Attempt to create the surface with theses settings
    hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
	//PrintDDrawError(hRet);
    if (hRet != DD_OK){
		switch(nTestPass){
		case 0:
			ddsd.ddpfPixelFormat.dwFourCC = 0x59565955L; // YUYV
			nTestPass++;
			goto RECREATE;
		case 1:
			ddsd.ddpfPixelFormat = ddpfOverlayFormat;
			nTestPass++;
			goto RECREATE;
		case 2:
			ddpfOverlayFormat.dwRBitMask=0x7c00;
			ddpfOverlayFormat.dwGBitMask=0x3e0;
			ddpfOverlayFormat.dwBBitMask=0x001f;
			ddsd.ddpfPixelFormat = ddpfOverlayFormat;
			nTestPass++;
			goto RECREATE;
		case 3:
			return FALSE;
		}
	}
	switch(nTestPass){
	case 0:
		g_ParaOverlay.BitCount=0x80000000|15;
		break;
	case 1:
		g_ParaOverlay.BitCount=0x80000000|16;
		break;
	case 2:
		g_ParaOverlay.BitCount=16;
		break;
	case 3:
		g_ParaOverlay.BitCount=15;
		break;
	}
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwFlags=DDSD_ALL;
	ddsd.dwSize=sizeof(ddsd);
	hRet = g_pDDSOverlay->GetSurfaceDesc(&ddsd);
	DWORD m_dwVGAPitch			= (DWORD)ddsd.lPitch;
	DWORD m_dwVGABitCount		= ddsd.ddpfPixelFormat.dwYUVBitCount;
	DWORD m_dwVGAPixelDepth		= (ddsd.ddpfPixelFormat.dwYUVBitCount + 7) / 8;
    g_ParaOverlay.Pitch = m_dwVGAPitch;
	g_ParaOverlay.Depth = m_dwVGAPixelDepth;
	if(g_ParaOverlay.Depth==0)
		g_ParaOverlay.Depth=((g_ParaOverlay.BitCount&0xff)+7)/8;
	g_ParaOverlay.Height = ddsd.dwHeight;
	g_ParaOverlay.Width = ddsd.dwWidth;
	
	g_pDDSOverlay->Lock( NULL , &ddsd , 0 , NULL );
    g_ParaOverlay.VirtualAddress = (DWORD)ddsd.lpSurface; 
	PULONG pDest=(PULONG)ddsd.lpSurface;
	memset(pDest, 0, ddsd.dwHeight*ddsd.dwWidth*m_dwVGAPixelDepth);
	g_pDDSOverlay->Unlock( NULL );
	g_ColorKey.dwColorSpaceHighValue=DDColorMatch(g_pDDSPrimary, RGB(255,0,255));
	g_ColorKey.dwColorSpaceLowValue = g_ColorKey.dwColorSpaceHighValue;
	g_pDDSOverlay->SetColorKey(DDCKEY_DESTOVERLAY, &g_ColorKey);
    return TRUE;
}
//-----------------------------------------------------------------------------
// Name: DDInit()
// Desc: Init DirectDraw Stuff
//-----------------------------------------------------------------------------
int
DDInit()
{
    HRESULT                     hRet;

    //hRet = DirectDrawCreateEx(NULL, (VOID**)&g_pDD, IID_IDirectDraw7, NULL);
	hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
    if (hRet != DD_OK)
        return FALSE;

    // Set cooperation level with other windows to be normal (ie. not full screen)
    // You MUST set the cooperation level to be SOMETHING, for windowed apps use
    // DDSCL_NORMAL, for full screen use: DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN.
    hRet = g_pDD->SetCooperativeLevel(0/*g_hAppWnd*/, DDSCL_NORMAL);
    if (hRet != DD_OK)
        return FALSE;

    if (!DDPrimaryInit())
        return FALSE;
    return TRUE;
}
int 
DDUpdate()
{
	HRESULT hRet;
    // Check the primary surface to see if it's lost - if so you can
    // pretty much bet that the other surfaces are also lost - thus
    // restore EVERYTHING!  If we got our surfaces stolen by a full
    // screen app - then we'll destroy our primary - and won't be able
    // to initialize it again. When we get our next paint message (the
    // full screen app closed for example) we'll want to try to reinit
    // the surfaces again - that's why there is a check for
    // g_pDDSPrimary == NULL.  The other option, is that our program
    // went through this process, could init the primary again, but it
    // couldn't init the overlay, that's why there's a third check for
    // g_pDDSOverlay == NULL.  Make sure that the check for
    // !g_pDDSPrimary is BEFORE the IsLost call - that way if the
    // pointer is NULL (ie. !g_pDDSPrimary is TRUE) - the compiler
    // won't try to evaluate the IsLost function (which, since the
    // g_pDDSPrimary surface is NULL, would be bad...).
    if (!g_pDDSPrimary || (g_pDDSPrimary->IsLost() != DD_OK) ||
        (g_pDDSOverlay == NULL))
    {
        DestroyOverlay();
        DestroyPrimary();
        if (DDPrimaryInit())
            if (!DDOverlayInit())
				return FALSE;
                //if (!DrawOverlay())
                //    DestroyOverlay();
    }
	//PrintDDrawError(hRet);
    if (g_pDDSOverlay && g_pDDSPrimary)
        hRet = g_pDDSOverlay->UpdateOverlay(NULL, g_pDDSPrimary,
                                            NULL, DDOVER_SHOW,
                                            NULL);
    memset(&g_OverlayFX, 0, sizeof(g_OverlayFX));
	g_OverlayFX.dwSize = sizeof(g_OverlayFX);
	g_OverlayFX.dckDestColorkey = g_ColorKey;
    // UpdateOverlay is how we put the overlay on the screen.
    if (g_pDDSOverlay && g_pDDSPrimary)
        hRet = g_pDDSOverlay->UpdateOverlay(&g_rcSrc, g_pDDSPrimary,
                                            &g_rcDest, DDOVER_SHOW|DDOVER_DDFX|DDOVER_KEYDESTOVERRIDE,
                                            &g_OverlayFX);
	return TRUE;
}

int UpdateScreen()
{
	if(!g_pDDSOverlay)
		return FALSE;
	//if(!bFullScreen){
		g_rcDest.left=0;
		g_rcDest.right=g_ParaPrimary.Width;
		g_rcDest.top=0;
		g_rcDest.bottom=g_ParaPrimary.Height;
		//if(bFullScreen)
		g_rcSrc.left=0;
		g_rcSrc.right=(g_ParaOverlay.Width*g_InitScaleX)/g_ScaleX;
		g_rcSrc.top=0;
		g_rcSrc.bottom=(g_ParaOverlay.Height*g_InitScaleY)/g_ScaleY;
	//}
	return DDUpdate();
}

BOOL PrepareScreen(
	int *pMode
	)
{
	if(g_pDDSPrimary)
		//forbid to call this function more than once
		return FALSE;
	g_pDDSPrimary=NULL;
    if (DDInit() == FALSE)
    {
        DestroyDDraw();
        //DisplayError("Unable to initialize the DirectDraw object");
		*pMode=AVE2KLIB_SCREEN_NONE;
        return FALSE;
    }
	g_pDDSOverlay=NULL;
	//if(*pMode!=AVE2KLIB_SCREEN_PRIMARY)
		if (DDOverlayInit() == FALSE)
		{
			DestroyOverlay();
			//DestroyDDraw();
			//DisplayError("Could not create the overlay surface.  The display card may not support the requested format, or may not have enough memory available.");
		}
	if(g_pDDSOverlay){
		*pMode=AVE2KLIB_SCREEN_OVERLAY;
		UpdateScreen();
	}
	else{
		*pMode=AVE2KLIB_SCREEN_PRIMARY;
	}
	return 1;
}
int ReleaseScreen(
	)
{
    DestroyOverlay();
    DestroyDDraw();
	return 1;
}

⌨️ 快捷键说明

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