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

📄 ddhsurf.cpp

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 CPP
📖 第 1 页 / 共 4 页
字号:
			pd->ddRVal = DD_OK;
			return DDHAL_DRIVER_HANDLED;
		}
		else if (! ((pd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) == DDSD_PIXELFORMAT) )
		{
			// can create surfaces of same type as current primary surface
			pd->ddRVal = DD_OK;
			return DDHAL_DRIVER_HANDLED;
		}
		else // trying to create a different surface type
		{
			// DDGPEGetPixelFormatFromSurfaceDesc calls DDGPE::DetectPixelFormat
			// for now, we will assume that if the surface type can be detected, it can
			// be created

			// BUGBUG
			// no checking for:
			//  overlays
			//  video/system memory
			//  memory availability
			// is this necessary based on the spec?

			pd->ddRVal = DD_OK;
			return DDHAL_DRIVER_HANDLED;
		}
	}

	pd->ddRVal = DD_OK;
	DEBUGLEAVE( HalCanCreateSurface );
	return DDHAL_DRIVER_HANDLED;
}



EXTERN_C DWORD WINAPI DDGPECreateSurface( LPDDHAL_CREATESURFACEDATA pd )
{
	SCODE				sc = S_OK;
	unsigned int		iSurf;		// Surface index
	//unsigned int		nBPP;		// Bits-per-pixel on surface
	unsigned int		nWidth;		// Width of surface in pixels
	//unsigned int		nPitch;		// Width of surface in bytes
	unsigned int		nHeight;	// Height of surface in pixels
	LPDDRAWI_DDRAWSURFACE_LCL
						pSurf;		// Pointer to surface data
	EDDGPEPixelFormat	pixelFormat;
	EGPEFormat			format;		// Pixel format of surface(s) being created
	DWORD 				dwFlags = pd->lpDDSurfaceDesc->dwFlags;
	DWORD 				dwCaps = pd->lpDDSurfaceDesc->ddsCaps.dwCaps;

	DEBUGENTER( DDGPECreateSurface );

	//DebugBreak();

	/*
	typedef struct _DDHAL_CREATESURFACEDATA
	{
	    LPDDRAWI_DIRECTDRAW_GBL     lpDD;           // driver struct
	    LPDDSURFACEDESC             lpDDSurfaceDesc;// description of surface being created
	    LPDDRAWI_DDRAWSURFACE_LCL   FAR *lplpSList; // list of created surface objects
	    DWORD                       dwSCnt;         // number of surfaces in SList
	    HRESULT                     ddRVal;         // return value
	    LPDDHAL_CREATESURFACE       CreateSurface;  // PRIVATE: ptr to callback
	} DDHAL_CREATESURFACEDATA;
	*/


	sc = DDGPEGetPixelFormatFromSurfaceDesc(
				pd->lpDDSurfaceDesc,
				&pixelFormat,
				&format
				);

	if (FAILED(sc))
	{
		DEBUGMSG(HAL_ZONE_WARNING,(TEXT("DDGPECreateSurface ERROR - DDERR_UNSUPPORTEDFORMAT (0x%08x)\r\n"),
											sc ));
		pd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
		DEBUGLEAVE(HalCreateSurface);
		return DDHAL_DRIVER_HANDLED;
	}

	// Use pd->lpDDSurfaceDesc->dwFlags to determine which fields are valid and use them
/*	nBPP = (pd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) ?
		((USHORT)(pd->lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount)) :
		g_pDDrawPrimarySurface->Bpp();*/
/*#ifdef FB16BPP
		16;		// REVIEW!
#else
		8;	// REVIEW!
#endif*/


	nWidth = (pd->lpDDSurfaceDesc->dwFlags & DDSD_WIDTH) ?
		( pd->lpDDSurfaceDesc->dwWidth ) : DDRAW_SCREEN_WIDTH;		// resolves to a call to
																	//  g_pDDrawPrimarySurface or a GPE query

	nHeight = (pd->lpDDSurfaceDesc->dwFlags & DDSD_HEIGHT) ?
		( pd->lpDDSurfaceDesc->dwHeight ) : DDRAW_SCREEN_HEIGHT;	// resolves to a call to
																	//  g_pDDrawPrimarySurface or a GPE query

	//DEBUGMSG(GPE_ZONE_CREATE,(TEXT("nBPP: %d\r\n"), nBPP ));

	/*switch(nBPP)
	{
	case 8:
		format = gpe8Bpp;
		break;
	case 16:
		format = gpe16Bpp;
		break;
	case 24:
//		if( pd->lpDDSurfaceDesc->ddpfPixelFormat.dwFlags & DDPF_ALPHAPIXELS )
//			format = pfmt_24a;
//		else
//			format = pfmt_24;
//		nBPP = 32;
//		break;
		DEBUGMSG(GPE_ZONE_WARNING,(TEXT("HalCreateSurface rejecting %d BPP surface\r\n"), nBPP));
		pd->ddRVal = DDERR_UNSUPPORTEDFORMAT;
		return DDHAL_DRIVER_HANDLED;
	case 32:
		format = gpe32Bpp;
		break;
	}*/

	//nPitch = ( nWidth * nBPP ) >>3;
	//nPitch = ( nPitch + 3 ) & ~3;


#if DEBUG
	DEBUGMSG(HAL_ZONE_CREATE,(TEXT("Number of surfaces to create: %d\r\n"), pd->dwSCnt ));
	DEBUGMSG(HAL_ZONE_CREATE,(TEXT("Create Surface flags: ")));
//	DumpDDSCAPS(pd->lpDDSurfaceDesc->ddsCaps);
#endif

	for( iSurf=0; iSurf<pd->dwSCnt; iSurf++ )
	{
		pSurf = pd->lplpSList[iSurf];

//#if DEBUG
#if 0
		DEBUGMSG(HAL_ZONE_CREATE,(TEXT("Surface #%d: LCL:%08x FLAGS:"), iSurf, pSurf ));
		DumpDDSCAPS( pSurf->ddsCaps );
		if( dwCaps & DDSCAPS_MIPMAP )
		{
			DEBUGMSG(HAL_ZONE_CREATE,(TEXT("MipMap count: %d\r\n"), pSurf->lpSurfMore->dwMipMapCount ));
		}
		DEBUGMSG(HAL_ZONE_CREATE,(TEXT("\r\nAddr of GBL: 0x%08x, Addr of LCL: 0x%08x\r\n"),
			pSurf->lpGbl, pSurf ));
#endif

        if ( pSurf->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE )
        {
			DEBUGMSG(HAL_ZONE_INFO, (TEXT("dwCaps4 = 0x%x\r\n"), pSurf->lpSurfMore->ddsCapsEx.dwCaps4));
			if ( (pSurf->lpSurfMore->ddsCapsEx.dwCaps4 & DDSCAPS4_NONGDIPRIMARY) )
			{
				DWORD	dwModeID = -1L;

				DEBUGMSG(HAL_ZONE_INFO, (TEXT("SPLITTING THE DDRAW SURFACE\r\n") ));

				// g_pDrawPrimarySurface is originally set to the GDI primary surface, but this isn't what we want
				// for our model. We want a ddraw primary surface that is separate from the GDI primary surface.
				// (and that could have a different pixel depth, stride, format, etc.)

				DEBUGMSG(HAL_ZONE_INFO, (TEXT("still have pixelFormat %d\r\n"), pixelFormat));

				if ( (pd->lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) )
				{
					DEBUGMSG(HAL_ZONE_INFO, (TEXT("Using pixel format to find split mode\r\n") ));
					sc = g_pGPE->DetectMode(&dwModeID, nWidth, nHeight, format, pixelFormat, &pd->lpDDSurfaceDesc->ddpfPixelFormat);
				}
				else
				{
					DEBUGMSG(HAL_ZONE_INFO, (TEXT("NOT using pixel format to find split mode\r\n") ));
					sc = g_pGPE->DetectMode(&dwModeID, nWidth, nHeight, format, pixelFormat);
				}

				GPEMode		modeInfo;
				DDGPESurf*	pDDGPESurf = NULL;

				if (FAILED(sc))
				{

					DEBUGMSG(HAL_ZONE_WARNING, (TEXT("Could not find requested primary surface mode 0x%08x\r\n"), sc));

					// try to just split off a surface of the same type as the current primary surface (GDI surface)
					sc = S_OK;
					dwModeID = g_pGPE->GetModeId(); // can only split off GDI surface
				}
				else
				{
					DEBUGMSG(HAL_ZONE_INFO, (TEXT("Found requested primary surface mode: ID = %d\r\n"), dwModeID));
				}

				if (SUCCEEDED(sc))
				{
					sc = g_pGPE->GetModeInfo(&modeInfo, dwModeID);
					if (SUCCEEDED(sc))
					{
						GPEModeEx	modeInfoEx; // restrict the scope of this, since we can't rely on it being valid for all drivers
						sc = g_pGPE->GetModeInfoEx(&modeInfoEx, dwModeID);
						if (FAILED(sc))
						{
							// function probably wasn't supported by the driver
							pixelFormat = EGPEFormatToEDDGPEPixelFormat[modeInfo.format];
							sc = S_OK;
						}
						else
						{
							pixelFormat = modeInfoEx.ePixelFormat;
						}
					}
				}
				
				if (FAILED(sc))
				{
					DEBUGMSG(HAL_ZONE_ERROR, (TEXT("DDGPECreateSurface- Could not find a good mode: DetectMode and GetModeInfo failed. 0x%x\r\n"), sc ));
				}
				else
				{
					BOOL	bSplitToSame = FALSE;

					if (DDGPEGDIHasSplitFromDDraw())
					{
						// for now, don't worry about the case where the rect is invalid.
						// let it just fall through.

						if (	(g_pDDrawPrimarySurface->PixelFormat()	== pixelFormat)		&&
								(g_pDDrawPrimarySurface->Format()		== modeInfo.format)	&&
								(g_pDDrawPrimarySurface->Width()		== modeInfo.width)	&&
								(g_pDDrawPrimarySurface->Height()		== modeInfo.height) &&
								(1) )
						{
							bSplitToSame = TRUE;
						}

					}

					// don't need to split if the ddraw surface is already split, and
					// the mode requested is the same as the current ddraw primary surface's mode
					if (bSplitToSame)
					{
						pDDGPESurf = g_pDDrawPrimarySurface;

						DEBUGMSG(HAL_ZONE_WARNING, (TEXT("Surface is already split in requested mode!\r\n") ));
					}
					else
					{
						unsigned long	dwOffsetInVideoMemory = 0L;

						// don't deallocate our existing surface yet, because the allocate
						// might fail

						sc = g_pGPE->AllocVideoSurface(
								&pDDGPESurf,
								modeInfo.width,
								modeInfo.height,
								modeInfo.format,
								pixelFormat,
								&dwOffsetInVideoMemory );
					
						DEBUGMSG(
							HAL_ZONE_INFO,
							(TEXT("Created primary surface at: 0x%x (%d)\r\n"), 
							dwOffsetInVideoMemory, 
							dwOffsetInVideoMemory
							));
					}

				}
				if (FAILED(sc))
				{
					DEBUGMSG(HAL_ZONE_ERROR, (TEXT("DDGPECreateSurface-AllocSurface failed 0x%x\r\n"), sc ));
				}
				else
				{
					if (pDDGPESurf != NULL)
					{
						g_pDDrawPrimarySurface = pDDGPESurf; //(DDGPESurf*)g_pGPE->PrimarySurface();
						DEBUGMSG(HAL_ZONE_SUCCESS, (TEXT("DDGPECreateSurface-AllocSurface successful 0x%x\r\n"), g_pDDrawPrimarySurface->OffsetInVideoMemory() ));
					}
					else
					{
						DEBUGMSG(HAL_ZONE_ERROR, (TEXT("DDGPECreateSurface-AllocSurface returned NULL 0x%x\r\n"), sc ));
					}
				}

				if (dwModeID != (DWORD)-1L)
				{
					if (dwModeID != (DWORD)g_pGPE->GetPhysicalModeId())
					{
						DEBUGMSG(HAL_ZONE_INFO, (TEXT("Setting DDraw Primary mode to id %d\r\n"), dwModeID));

						sc = g_pGPE->SetMode(dwModeID, NULL, FALSE); // don't change GDI mode (just HW)
						if (FAILED(sc))
						{
							DEBUGMSG(HAL_ZONE_ERROR, (TEXT("Failed to set the physical mode 0x%08x\r\n"), sc));
						}

						DEBUGMSG(HAL_ZONE_INFO, (TEXT("Calling UpdateHALInit\r\n") ));
						UpdateHALInit(pd->lpDD, dwModeID);
						DEBUGMSG(HAL_ZONE_INFO, (TEXT("Done calling UpdateHALInit\r\n") ));

						/*
						// This is handled by UpdateHALInit, so we shouldn't have to call this any more
						pd->lpDD->vmiData.ddpfDisplay.dwFlags = DDPF_RGB; // NOTENOTE this must be updated when splitting or changing display mode
						pd->lpDD->vmiData.ddpfDisplay.dwFlags |= (pDDGPESurf->HasAlpha()) ? DDPF_ALPHAPIXELS : 0;

						pd->lpDD->vmiData.ddpfDisplay.dwRBitMask = pd->lpDD->lpModeInfo[dwModeID].dwRBitMask;
 						pd->lpDD->vmiData.ddpfDisplay.dwGBitMask = pd->lpDD->lpModeInfo[dwModeID].dwGBitMask;
 						pd->lpDD->vmiData.ddpfDisplay.dwBBitMask = pd->lpDD->lpModeInfo[dwModeID].dwBBitMask;
 						pd->lpDD->vmiData.ddpfDisplay.dwRGBAlphaBitMask = pd->lpDD->lpModeInfo[dwModeID].dwAlphaBitMask;
						pd->lpDD->vmiData.ddpfDisplay.dwRGBBitCount = pd->lpDD->lpModeInfo[dwModeID].dwBPP;
						*/
					}
					else
					{
						DEBUGMSG(HAL_ZONE_WARNING, (TEXT("Current mode is same as requested split mode (%d)\r\n"), dwModeID));
					}
				}

				//DEBUGMSG(HAL_ZONE_INFO, (TEXT("Setting up lpGbl\r\n") ));
				pSurf->lpGbl->fpVidMem = (unsigned long)(g_pVideoMemory) + g_pDDrawPrimarySurface->OffsetInVideoMemory();
				pSurf->lpGbl->lPitch = g_pDDrawPrimarySurface->Stride();

				// BUGBUG
				// This will cause a problem if more than one process creates a primary surface
				// but I don't think ddraw lets that happen.
				//DEBUGMSG(HAL_ZONE_INFO, (TEXT("Setting DDGPESurf for new ddraw primary surface\r\n") ));
				g_pDDrawPrimarySurface->SetDDGPESurf(pSurf->lpGbl);

				// show the new primary surface						// don't wait for vblank
				//DEBUGMSG(HAL_ZONE_INFO, (TEXT("Flipping to the new primary surface\r\n") ));
				g_pGPE->SetVisibleSurface(g_pDDrawPrimarySurface, NULL, FALSE);
				//DEBUGMSG(HAL_ZONE_INFO, (TEXT("Done flipping to the new primary surface\r\n") ));

				// OLDOLD
				// last but not least, change the video mode
				// GPE should NOT know about this change
				// DDGPE must keep track of the OLD mode so it knows what to restore it as when
				// FlipToGDISurface is called.
				// TODO: Will there be a case where the caller wants to flip the GDI to front, then flip the
				// ddraw primary to front? Mode switching will need to be done there.
				// NOTE: This is done above, now.
			}
			else // not split primary
			{
				// We could get here in one of two cases:
				// 1. The program is creating ddraw and just wants to create a primary surface
				// 2. The ddraw primary is split and the user is getting the GDI ddraw surface

				// The GDI primary surface should already exist, so we don't need to
				// do any allocation for it

				DDGPESurf* pPrimary = (DDGPESurf*)g_pGPE->PrimarySurface();

				//PrimarySurface() should always return a valid surface

⌨️ 快捷键说明

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