您的位置:首页 > 其它

【转】WM(WinCE)模拟器如何调试ddraw程序?

2010-07-13 14:39 267 查看
上次在参考研究mobile sdk 6.0中自带的DDraw例子时发现在模拟器上跑到创建后备缓冲时由于不支持DDSCAPS_BACKBUFFER而导致程序不能运行,google了一通发现m$网站和其他一些论坛上也有人问过类似问题,得到的答案貌似是说emlator上不能跑DDraw和D3D的程序,要测只能用device,其实只要自己实现一个创建后备缓冲以及用blit模拟flip的方式就可以在模拟器上跑了,并不是模拟器根本就没有实现DDraw,只是没有实现硬件后备缓冲、翻转等操作(其实在现在的PC模拟器上的这2种方式应该也没有什么效率上的差异吧)。
具体代码:

//************************************
// Method:    InitDDraw 初始化DDraw
// FullName:  InitDDraw
// Access:    public
// Returns:   BOOL
// Qualifier:
// Parameter: void
//************************************
BOOL InitDDraw( void )
{
DDSURFACEDESC ddsd;
HRESULT hRet;
DDCAPS ddCaps;
DDCAPS ddHelCaps;
// DDraw对象
hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
if (hRet != DD_OK)
{
InitFail(g_hGameWnd,hRet,_T("DDraw failed to create!"));
return FALSE;
}
// 全屏排他模式
hRet = g_pDD->SetCooperativeLevel(g_hGameWnd, DDSCL_FULLSCREEN);
if (hRet != DD_OK)
{
InitFail(g_hGameWnd,hRet,_T("Failed to set cooperative level!"));
return FALSE;
}
// 取DDraw可用能力
g_pDD->GetCaps(&ddCaps, &ddHelCaps);
// flip和backbuffer有1个不支持就启用单缓冲模式
if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) || !(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP))
{
// 单缓冲模式
g_bSingleBuffer = TRUE;
}
// 显示模式设置
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);

hRet = g_pDD->GetDisplayMode(&ddsd);

if(hRet != DD_OK)
{
InitFail(g_hGameWnd,hRet,_T("GetDisplayMode Failed!"));
return FALSE;
}

g_dwScreenX = ddsd.dwWidth;
g_dwScreenY = ddsd.dwHeight;
g_dwScreenBpp = ddsd.ddpfPixelFormat.dwRGBBitCount;

// color key 硬件能力
g_dwTransType = DDBLT_KEYSRC;
ddCaps.dwSize = sizeof(ddCaps);
if(g_bSingleBuffer)
{
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
}
else
{
ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
ddsd.dwBackBufferCount = 1;
}
// 主缓冲创建
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);

if (hRet != DD_OK)
{
if (hRet = DDERR_NOFLIPHW)
{
InitFail(g_hGameWnd,hRet,_T("******** Display driver doesn't support flipping surfaces. ********"));
return FALSE;
}
InitFail(g_hGameWnd,hRet,_T("CreateSurface FrontBuffer Failed!"));
return FALSE;
}

if (g_bSingleBuffer)
{
ddsd.dwFlags = DDSD_WIDTH|DDSD_HEIGHT;
ddsd.dwWidth = g_dwScreenX;
ddsd.dwHeight = g_dwScreenY;
hRet = g_pDD->CreateSurface(&ddsd,&g_pDDSBack,NULL);
if(hRet != DD_OK)
{
InitFail(g_hGameWnd,hRet,_T("BackBuffer failed to create!"));
return FALSE;
}
}
else
{
// Get a pointer to the back buffer
hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction);
if (hRet != DD_OK)
{
InitFail(g_hGameWnd,hRet,_T("EnumAttachedSurfaces Failed!"));
return FALSE;
}
}
return TRUE;
}


在绘图循环的时候这样处理flip:

HRESULT ddrval;
RECT src, dest;

src.left = 0;
src.top = 0;
src.right = g_dwScreenX;
src.bottom = g_dwScreenY;

dest.left = 0;
dest.top  = 0;
dest.right = g_dwScreenX;
dest.bottom = g_dwScreenY;

// Flip the surfaces
while( 1 )
{
if (g_bSingleBuffer)
{
//copy back buffer to front.
ddrval = g_pDDSPrimary->Blt(&dest, g_pDDSBack, &src, DDBLT_WAITNOTBUSY, NULL );
}
else
{
ddrval = g_pDDSPrimary->Flip(NULL, 0);
}

if( ddrval == DD_OK )
{
break;
}
if( ddrval == DDERR_SURFACELOST )
{
if( !RestoreSurfaces() )
{
return 0;
}
}
if( ddrval != DDERR_WASSTILLDRAWING )
{
break;
}
}


from:http://blog.k-res.net/?p=472
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: