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


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

    1 //************************************
    2  // Method: InitDDraw 初始化DDraw
    3  // FullName: InitDDraw
    4  // Access: public
    5  // Returns: BOOL
    6  // Qualifier:
    7  // Parameter: void
    8  //************************************
    9  BOOL InitDDraw( void )
    10 {
    11 DDSURFACEDESC ddsd;
    12 HRESULT hRet;
    13 DDCAPS ddCaps;
    14 DDCAPS ddHelCaps;
    15 // DDraw对象
    16   hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
    17 if (hRet != DD_OK)
    18 {
    19 InitFail(g_hGameWnd,hRet,_T("DDraw failed to create!"));
    20 return FALSE;
    21 }
    22 // 全屏排他模式
    23   hRet = g_pDD->SetCooperativeLevel(g_hGameWnd, DDSCL_FULLSCREEN);
    24 if (hRet != DD_OK)
    25 {
    26 InitFail(g_hGameWnd,hRet,_T("Failed to set cooperative level!"));
    27 return FALSE;
    28 }
    29 // 取DDraw可用能力
    30   g_pDD->GetCaps(&ddCaps, &ddHelCaps);
    31 // flip和backbuffer有1个不支持就启用单缓冲模式
    32   if (!(ddCaps.ddsCaps.dwCaps & DDSCAPS_BACKBUFFER) || !(ddCaps.ddsCaps.dwCaps & DDSCAPS_FLIP))
    33 {
    34 // 单缓冲模式
    35   g_bSingleBuffer = TRUE;
    36 }
    37 // 显示模式设置
    38   memset(&ddsd, 0, sizeof(ddsd));
    39 ddsd.dwSize = sizeof(ddsd);
    40
    41 hRet = g_pDD->GetDisplayMode(&ddsd);
    42
    43 if(hRet != DD_OK)
    44 {
    45 InitFail(g_hGameWnd,hRet,_T("GetDisplayMode Failed!"));
    46 return FALSE;
    47 }
    48
    49 g_dwScreenX = ddsd.dwWidth;
    50 g_dwScreenY = ddsd.dwHeight;
    51 g_dwScreenBpp = ddsd.ddpfPixelFormat.dwRGBBitCount;
    52
    53 // color key 硬件能力
    54 g_dwTransType = DDBLT_KEYSRC;
    55 ddCaps.dwSize = sizeof(ddCaps);
    56 if(g_bSingleBuffer)
    57 {
    58 ddsd.dwFlags = DDSD_CAPS;
    59 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    60 }
    61 else
    62 {
    63 ddsd.dwFlags = DDSD_CAPS|DDSD_BACKBUFFERCOUNT;
    64 ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE|DDSCAPS_FLIP;
    65 ddsd.dwBackBufferCount = 1;
    66 }
    67 // 主缓冲创建
    68 hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
    69
    70 if (hRet != DD_OK)
    71 {
    72 if (hRet = DDERR_NOFLIPHW)
    73 {
    74 InitFail(g_hGameWnd,hRet,_T("******** Display driver doesn't support flipping surfaces. ********"));
    75 return FALSE;
    76 }
    77 InitFail(g_hGameWnd,hRet,_T("CreateSurface FrontBuffer Failed!"));
    78 return FALSE;
    79 }
    80
    81 if (g_bSingleBuffer)
    82 {
    83 ddsd.dwFlags = DDSD_WIDTH|DDSD_HEIGHT;
    84 ddsd.dwWidth = g_dwScreenX;
    85 ddsd.dwHeight = g_dwScreenY;
    86 hRet = g_pDD->CreateSurface(&ddsd,&g_pDDSBack,NULL);
    87 if(hRet != DD_OK)
    88 {
    89 InitFail(g_hGameWnd,hRet,_T("BackBuffer failed to create!"));
    90 return FALSE;
    91 }
    92 }
    93 else
    94 {
    95 // Get a pointer to the back buffer
    96 hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction);
    97 if (hRet != DD_OK)
    98 {
    99 InitFail(g_hGameWnd,hRet,_T("EnumAttachedSurfaces Failed!"));
    100 return FALSE;
    101 }
    102 }
    103 return TRUE;
    104 }

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

    1 HRESULT ddrval;
    2 RECT src, dest;
    3
    4 src.left = 0;
    5 src.top = 0;
    6 src.right = g_dwScreenX;
    7 src.bottom = g_dwScreenY;
    8
    9 dest.left = 0;
    10 dest.top = 0;
    11 dest.right = g_dwScreenX;
    12 dest.bottom = g_dwScreenY;
    13
    14 // Flip the surfaces
    15 while( 1 )
    16 {
    17 if (g_bSingleBuffer)
    18 {
    19 //copy back buffer to front.
    20 ddrval = g_pDDSPrimary->Blt(&dest, g_pDDSBack, &src, DDBLT_WAITNOTBUSY, NULL );
    21 }
    22 else
    23 {
    24 ddrval = g_pDDSPrimary->Flip(NULL, 0);
    25 }
    26
    27 if( ddrval == DD_OK )
    28 {
    29 break;
    30 }
    31 if( ddrval == DDERR_SURFACELOST )
    32 {
    33 if( !RestoreSurfaces() )
    34 {
    35 return 0;
    36 }
    37 }
    38 if( ddrval != DDERR_WASSTILLDRAWING )
    39 {
    40 break;
    41 }
    42 }

    from:http://blog.k-res.net/?p=472

  • 相关阅读:
    ScrollView 字典
    centos 6.x 安装redis
    Linux 添加epel源
    Linux 关于解压
    Linux 删除文件夹
    Linux sz rz
    让div 实现 input效果
    解决js浮点数计算bug
    键盘绑定事件和焦点处理
    npm的镜像替换成淘宝
  • 原文地址:https://www.cnblogs.com/dahai/p/1776459.html
Copyright © 2020-2023  润新知