当前位置:首页 > 芯闻号 > 充电吧
[导读]在代码中增加了很多对代码的注释。同时,对在不同平台(Telechips,MStar)的测试效果也做了说明。虽然代码是 Overlay 示例,但还是增加了一些东东,对 Overlay 有兴趣的童鞋可以看

在代码中增加了很多对代码的注释。

同时,对在不同平台(Telechips,MStar)的测试效果也做了说明。

虽然代码是 Overlay 示例,但还是增加了一些东东,对 Overlay 有兴趣的童鞋可以看看。  



// mosquito.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include#include#include "Resource.h"
//-----------------------------------------------------------------------------
// Include files
//-----------------------------------------------------------------------------
#include//-----------------------------------------------------------------------------
// Local definitions
//-----------------------------------------------------------------------------
#define NAME                TEXT("MosquitoWndClass")
#define TITLE               TEXT("Mosquito")

#define BUG_WIDTH           320
#define BUG_HEIGHT          200

#ifdef UNDER_CE
#define RAND_INT(x) (Random() % x)
#else
#define RAND_INT(x) (rand()*x/RAND_MAX)
#endif
#define RANDOM_VELOCITY() (int)(((RAND_INT(5)+3)*2))

//-----------------------------------------------------------------------------
// Default settings
//-----------------------------------------------------------------------------
#define TIMER_ID            1
#define TIMER_RATE          200

//-----------------------------------------------------------------------------
// Global data
//-----------------------------------------------------------------------------
LPDIRECTDRAW                g_pDD = NULL;        // DirectDraw object
LPDIRECTDRAWSURFACE         g_pDDSPrimary = NULL; // Primary Surface.
LPDIRECTDRAWSURFACE         g_pDDSOverlay = NULL; // The overlay primary.
BOOL                        g_bActive = FALSE;   // Is application active?
int                         g_RotationAngles = 0; // Supported rotation angles.
int                         g_CurrentAngle = 0;   // Current rotation angle.

// Overlay position and velocity data.

int g_nOverlayXPos, g_nOverlayYPos;
int g_nOverlayXVel, g_nOverlayYVel;
int g_nOverlayWidth, g_nOverlayHeight;
DWORD g_dwOverlayXPositionAlignment;

// Our instance handle.

HINSTANCE g_hInstance;

//-----------------------------------------------------------------------------
// Local data
//-----------------------------------------------------------------------------
static TCHAR                szImg1[] = TEXT("IDB_BUGIMAGE1");//TEXT("IDB_BUGIMAGE1");
static TCHAR                szImg2[] = TEXT("IDB_BUGIMAGE2");
static TCHAR                szImg3[] = TEXT("IDB_BUGIMAGE3");

// These are the pixel formats this app supports.  Most display adapters
// with overlay support will recognize one or more of these formats.
// We start with YUV format, then work down to RGB. (All 16 bpp.)

/*
 * Telechips 8902 支持 2 层 overlay
 * 只能创建一层 YUV 的 overlay (可以再创建一层 RGB overlay)
 * RGB 模式可以创建多个,模式与顺序没有不影响创建
*/
static DDPIXELFORMAT ddpfOverlayFormats[] = {
    //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('Y','U','Y','V'),0,0,0,0,0},  // YUYV - Leo.Zheng Telechips 8902 可以支持
    //{sizeof(DDPIXELFORMAT), DDPF_FOURCC, MAKEFOURCC('U','Y','V','Y'),0,0,0,0,0},  // UYVY - Leo.Zheng Telechips 8902:Create No.1 surface return: 0x88760218
    // {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0x7C00, 0x03e0, 0x001F, 0},        // 16-bit RGB 5:5:5
    {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16,  0xF800, 0x07e0, 0x001F, 0},        // 16-bit RGB 5:6:5
};

#define PF_TABLE_SIZE (sizeof(ddpfOverlayFormats) / sizeof(ddpfOverlayFormats[0]))

static RECT rs;
static RECT rd;

//-----------------------------------------------------------------------------
// Prototypes
//-----------------------------------------------------------------------------
void ReleaseAllObjects(void);
HRESULT InitFail(HWND, HRESULT, LPCTSTR, ...);
HRESULT RestoreAllSurfaces();
void MoveOverlay();
long FAR PASCAL WindowProc(HWND, UINT, WPARAM, LPARAM);
BOOL CopyBitmapToYUVSurface(LPDIRECTDRAWSURFACE, HBITMAP);
BOOL LoadImageOntoSurface(LPDIRECTDRAWSURFACE, UINT);
HRESULT WINAPI EnumSurfacesCallback(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID);
HRESULT LoadBugImages();
HRESULT InitApp(HINSTANCE hInstance, int nCmdShow);

//-----------------------------------------------------------------------------
// Name: ReleaseAllObjects()
// Desc: Finished with all objects we use; release them
//-----------------------------------------------------------------------------
static void ReleaseAllObjects(void)
{
    if(g_pDDSOverlay != NULL)
    {
                // 如果不再需要一个覆盖表面或只想不让覆盖可见, 就可以设定适当的标志调用 UpdateOverlay 方法来隐藏该覆盖表面
        // Use UpdateOverlay() with the DDOVER_HIDE flag to remove an overlay from the display.
            // g_pDDSOverlay->UpdateOverlay(NULL, g_pDDSPrimary, NULL, DDOVER_HIDE, NULL);
        g_pDDSOverlay->Release();
        g_pDDSOverlay = NULL;
    }

    if(g_pDDSPrimary != NULL)
    {
        g_pDDSPrimary->Release();
        g_pDDSPrimary = NULL;
    }

    if(g_pDD != NULL)
    {
        g_pDD->Release();
        g_pDD = NULL;
    }
}

//-----------------------------------------------------------------------------
// Name: InitFail()
// Desc: This function is called if an initialization function fails
//-----------------------------------------------------------------------------
#define PREFIX      TEXT("MOSQUITO: ")
#define PREFIX_LEN  10

static HRESULT InitFail(HWND hWnd, HRESULT hRet, LPCTSTR szError,...)
{
    TCHAR szBuff[128] = PREFIX;
    va_list vl;

    va_start(vl, szError);
    StringCchVPrintf(szBuff + PREFIX_LEN, (128-PREFIX_LEN), szError, vl);    
    size_t len = wcslen(szBuff);
    StringCchPrintf(szBuff + len, 128 - len, TEXT("rn"));
    ReleaseAllObjects();
    OutputDebugString(szBuff);
    DestroyWindow(hWnd);
    va_end(vl);
    return hRet;
}

#undef PREFIX_LEN
#undef PREFIX

//-----------------------------------------------------------------------------
// Name: RestoreAllSurfaces
// Desc: Called in case we lose our surface's vram.
//-----------------------------------------------------------------------------
static HRESULT RestoreAllSurfaces()
{
    HRESULT hRet = 0;

    // Try Restoring the primary surface.
    hRet = g_pDDSPrimary->Restore();
    if(hRet != DD_OK)
            return hRet;

    // Try Restoring the overlay surface.
    hRet = g_pDDSOverlay->Restore();
    if(hRet != DD_OK)
            return hRet;

    // Reload the images.
    hRet = LoadBugImages();
    if(hRet != DD_OK)
        return hRet;

    // Show the overlay.
    hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, DDOVER_SHOW, NULL);

    return hRet;
}

//-----------------------------------------------------------------------------
// Name: MoveOverlay()
// Desc: Called on the timer, this function moves the overlay around the
//       screen, periodically calling flip to animate the mosquito.
//-----------------------------------------------------------------------------
static void MoveOverlay()
{
    HRESULT hRet = 0;
    DWORD dwXAligned = 0;

    // Add the current velocity vectors to the position.
    g_nOverlayXPos += g_nOverlayXVel;
    g_nOverlayYPos += g_nOverlayYVel;

    // Check to see if this new position puts the overlay off the edge of the screen.
    // SetOverlayPosition() won't like that.
    // Have we gone off the left edge?
    if(g_nOverlayXPos < 0)
        {
           g_nOverlayXPos = 0;
           g_nOverlayXVel = RANDOM_VELOCITY();
    }

    // Have we gone off the right edge?

    if((g_nOverlayXPos + g_nOverlayWidth) > GetSystemMetrics(SM_CXSCREEN))
        {
           g_nOverlayXPos = GetSystemMetrics(SM_CXSCREEN) - g_nOverlayWidth;
           g_nOverlayXVel = -RANDOM_VELOCITY();
    }

    // Have we gone off the top edge?
    if(g_nOverlayYPos < 0)
        {
           g_nOverlayYPos = 0;
           g_nOverlayYVel = RANDOM_VELOCITY();
    }

    // Have we gone off the bottom edge?
    if((g_nOverlayYPos + g_nOverlayHeight) > GetSystemMetrics(SM_CYSCREEN))
        {
           g_nOverlayYPos = GetSystemMetrics(SM_CYSCREEN) - g_nOverlayHeight;
           g_nOverlayYVel = -RANDOM_VELOCITY();
    }

    // We need to check for any alignment restrictions on the X position.
    if(g_dwOverlayXPositionAlignment)
           dwXAligned = g_nOverlayXPos - g_nOverlayXPos % g_dwOverlayXPositionAlignment;
    else
           dwXAligned = g_nOverlayXPos;

    // Set the overlay to it's new position. 重新放置覆盖
    hRet = g_pDDSOverlay->SetOverlayPosition(dwXAligned, g_nOverlayYPos);
    if(hRet == DDERR_SURFACELOST)
    {
            if(FAILED(RestoreAllSurfaces())) 
                return;
    }

        // 注意, 不要使用太靠近目标表面的右/下边界的坐标. 因为 SetOverlayPosition 方法并不执行剪切功能,
        // 所以使用那些可能导致覆盖超出目标表面边界的坐标会引起调用的失败, 并返回 DDERR_INVALIDPOSITION.

    // Flip.
    while(TRUE)
    {
        hRet = g_pDDSOverlay->Flip(NULL, 0);
        if(hRet == DD_OK)
            break;
        if(hRet == DDERR_SURFACELOST)           // 正常情况下,不执行此 if 语句
        {
            hRet = RestoreAllSurfaces();
            if(hRet != DD_OK)
                break;
        }
        if(hRet != DDERR_WASSTILLDRAWING)
            break;
    }
}


//-----------------------------------------------------------------------------
// Name: WindowProc()
// Desc: The Main Window Procedure
//-----------------------------------------------------------------------------
long FAR PASCAL WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int                         NewAngle;
    DEVMODE                     DevMode;

    switch (message)
    {
#ifdef UNDER_CE
        case WM_ACTIVATE:
#else
        case WM_ACTIVATEAPP:
#endif
            // Pause if minimized or not the top window
            g_bActive = (wParam == WA_ACTIVE) || (wParam == WA_CLICKACTIVE);
            return 0L;

        case WM_KILLFOCUS:
            // We do not allow anyone else to have the keyboard focus until
            // we are done.
            SetFocus(hWnd);
            return 0L;

        case WM_DESTROY:
            // Clean up and close the app
                        RETAILMSG(1,(L"[mosquito]overlay test - release overlay objects.rn"));
            ReleaseAllObjects();
            PostQuitMessage(0);
                        return 0L;

                case WM_LBUTTONDOWN:            // Leo.Zheng 没有窗体,无法响应 MOUSE 消息
                        PostMessage(hWnd, WM_CLOSE, 0, 0);
                        break;

        case WM_KEYDOWN:
            // Handle any non-accelerated key commands
            switch (wParam)
            {
                case VK_ESCAPE:
                case VK_F12:
                    PostMessage(hWnd, WM_CLOSE, 0, 0);
                    return 0L;

                case VK_SPACE:
                    // Rotate to the "next" angle.
                    if (g_CurrentAngle >= 0 && g_RotationAngles >= 0)
                                        {
                        NewAngle = g_CurrentAngle;
                        do
                        {
                            NewAngle < DMDO_270)
                            {
                                NewAngle = DMDO_0;
                            }
                        }while (!(NewAngle & g_RotationAngles) && (NewAngle != DMDO_0));

                        memset(&DevMode, 0, sizeof (DevMode));
                        DevMode.dmSize = sizeof (DevMode);
                        DevMode.dmFields = DM_DISPLAYORIENTATION;
                        DevMode.dmDisplayOrientation = NewAngle;

                        if (DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_RESET, NULL))
                                                {
                            g_CurrentAngle = NewAngle;
                                                        RestoreAllSurfaces();
                        }
                    }
                    return 0L;
            }
            break;

        case WM_TIMER:
            // Update and flip surfaces
            if (g_bActive && TIMER_ID == wParam)
            {
                MoveOverlay();
                                Sleep(100);
                                LoadBugImages();
            }
            break;
    }
    return DefWindowProc(hWnd, message, wParam, lParam);
}

//-----------------------------------------------------------------------------
//  Function: CopyBitmapToYUVSurface
//  Description: 
//      Copies an RGB GDI bitmap to a YUV surface. Both bitmap and surface
//      must be a multiple of 2 pixels in width for the supported YUV formats.  
//      The following formats are supported:
//              YUYV
//              UYVY
//      
//      The "YUYV" YUV pixel format looks like this:
//          As a series of BYTES:    [Y0][U][Y1][V] (reverse it for a DWORD)
// 
//      The "UYVY" YUV pixel format looks like this:
//          As a series of BYTES:    [U][Y0][V][Y1] (reverse it for a DWORD)
// 
//      As you can see, both formats pack two pixels into a single DWORD. The 
//      pixels share U and V components and have separate Y components.
//      
//  Returns: TRUE if successful, otherwise FALSE.
//-----------------------------------------------------------------------------
static BOOL CopyBitmapToYUVSurface(LPDIRECTDRAWSURFACE lpDDSurf, HBITMAP hbm)
{
    HDC                 hdcImage;
    HRESULT             ddrval;
    DDSURFACEDESC       ddsd;
    DWORD               x, y, dwWidth, dwHeight;
    DWORD               dwPitch;
    LPBYTE              pSurf;
    DWORD               dwBytesInRow;
    COLORREF            color;
    BYTE                R,G,B, Y0,Y1,U,V;
    BOOL                bRet = FALSE;

    if (hbm == NULL || lpDDSurf == NULL)
        return FALSE;

    //
    //  select bitmap into a memoryDC so we can use it.
    //
    hdcImage = CreateCompatibleDC(NULL);
    SelectObject(hdcImage, hbm);

    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    // Lock down the surface so we can modify it's contents.
    ddrval=lpDDSurf->Lock( NULL, &ddsd, DDLOCK_WAITNOTBUSY, NULL);
    if (FAILED(ddrval))
            goto CleanUp;

    dwWidth=ddsd.dwWidth;
    dwHeight=ddsd.dwHeight;
    dwPitch=ddsd.lPitch;
    pSurf=(LPBYTE)ddsd.lpSurface;
        dwBytesInRow=ddsd.dwWidth*2;

    // Go through the image 2 pixels at a time and convert to YUV
    for(y=0; y<dwHeight; y++)
    {
                for(x=0; xGetDC(&hdcSurf);
            if(FAILED(ddrval))
                goto Exit;
    
            if(BitBlt(hdcSurf, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0, SRCCOPY) == FALSE)
                goto Exit;

                ::SetBkMode(hdcSurf,TRANSPARENT);
                ::SetTextColor(hdcSurf,RGB(255,0,0));
                RECT Rect={0,0,100,50};
                ::DrawText(hdcSurf,_T("ABCD"),4,&Rect,DT_SINGLELINE|DT_LEFT);
    }

    bRetVal = TRUE;
    
Exit:
    if(hdcSurf)
            lpdds->ReleaseDC(hdcSurf);
    if(hdcImage)
            DeleteDC(hdcImage);
    if(hbm)
            DeleteObject(hbm);

    return bRetVal;
}

//-----------------------------------------------------------------------------
// Name: EnumSurfacesCallback()
// Desc: Used by LoadBugImages to aid it loading all three bug images.
//-----------------------------------------------------------------------------
static HRESULT WINAPI EnumSurfacesCallback(LPDIRECTDRAWSURFACE lpDDSurface,  
                     LPDDSURFACEDESC lpDDSurfaceDesc,  
                     LPVOID lpContext)
{
    int *CallCount = (int *)lpContext;
    HRESULT hr = (HRESULT)DDENUMRET_OK;
    UINT ResName;

    // Load the Bug Image appropriate...
    if(*CallCount == 0)
        {
        ResName = IDB_BUGIMAGE2;
    }
    else if(*CallCount == 1)
        {
        ResName = IDB_BUGIMAGE3;
    }
    else
        {
        hr = (HRESULT)DDENUMRET_CANCEL;
        goto exit;
    }

    if(!LoadImageOntoSurface(lpDDSurface, ResName))
        {
        hr = (HRESULT)DDENUMRET_CANCEL;
        goto exit;
    }

    // Bump the count.
    (*CallCount)++;
        if(*CallCount >= 2)
        {
                *CallCount = 0;
        }

exit:
    lpDDSurface->Release();
    return hr;
}

//-----------------------------------------------------------------------------
// Name: LoadBugImages()
// Desc: Load the bug resource images into our various flipping surfaces.
//-----------------------------------------------------------------------------
static HRESULT LoadBugImages()
{
    HRESULT hRet;
    static int CallCount = 0;

    // Put the first bug image onto the first buffer of our complex surface.
        if(0 == CallCount)
        {
                if(!LoadImageOntoSurface(g_pDDSOverlay, IDB_BUGIMAGE1))
                        return (E_FAIL);
        }

    // Use the enumeration attachment function to load the other images.
    hRet = g_pDDSOverlay->EnumAttachedSurfaces((LPVOID)&CallCount,EnumSurfacesCallback);

    return (hRet);
}

//-----------------------------------------------------------------------------
// Name: InitApp()
// Desc: Do work required for every instance of the application:
//          Create the window, initialize data
//-----------------------------------------------------------------------------
static HRESULT InitApp(HINSTANCE hInstance, int nCmdShow)
{
    HWND          hWnd;
    WNDCLASS      wc;
    DDSURFACEDESC ddsd;
    DDCAPS        ddcaps;
    HRESULT       hRet;
    DWORD         dwUpdateFlags = 0;
    DDOVERLAYFX   ovfx;
    DEVMODE       DevMode;

    // Check for rotation support by getting the rotation angles supported.
    memset(&DevMode, 0, sizeof(DevMode));
    DevMode.dmSize = sizeof(DevMode);
    DevMode.dmFields = DM_DISPLAYQUERYORIENTATION;
    if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))
        {
        g_RotationAngles = DevMode.dmDisplayOrientation;
    }
    else
        {
        OutputDebugString(L"MOSQUITO: Device does not support any rotation modes. Rotation disabled.");
        g_RotationAngles = -1;
    }

    // Get the current rotation angle.
    memset(&DevMode, 0, sizeof (DevMode));
    DevMode.dmSize = sizeof (DevMode);
    DevMode.dmFields = DM_DISPLAYORIENTATION;
    if(DISP_CHANGE_SUCCESSFUL == ChangeDisplaySettingsEx(NULL, &DevMode, NULL, CDS_TEST, NULL))
        {
        g_CurrentAngle = DevMode.dmDisplayOrientation;
    }
    else
        {
        OutputDebugString(L"MOSQUITO: Unable to read current rotation. Rotation disabled.");
        g_CurrentAngle = -1;
    }

    // Set up and register window class.
    wc.style = CS_HREDRAW | CS_VREDRAW;
    wc.lpfnWndProc = WindowProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MOSQUITO));
    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH )GetStockObject(BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = NAME;
    RegisterClass(&wc);

    // Create a window.
    hWnd = CreateWindowEx(WS_EX_TOPMOST,
      NAME,
      TITLE,
      WS_POPUP,
      0,
      0,
      GetSystemMetrics(SM_CXSCREEN),
      GetSystemMetrics(SM_CYSCREEN),
      NULL,
      NULL,
      hInstance,
      NULL);
    if(!hWnd)
        return FALSE;
    // We never show the window, only set focus to it.
    SetFocus(hWnd);

    // Create the main DirectDraw object
    hRet = DirectDrawCreate(NULL, &g_pDD, NULL);
    if(hRet != DD_OK)
        return InitFail(hWnd, hRet, TEXT("DirectDrawCreate FAILED"));

    // Get normal mode.
    hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
    if(hRet != DD_OK)
        return InitFail(hWnd, hRet, TEXT("SetCooperativeLevel FAILED"));

    // Get a primary surface interface pointer (only needed for init.)
        // 要使用覆盖表面, 必须先要初始化一个主表面, 覆盖表面将显示在该主表面上
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
    if(hRet != DD_OK)
        return InitFail(hWnd, hRet, TEXT("CreateSurface FAILED"));

    // See if we can support overlays.
        // 初始化 DirectDraw 后, 需要检测设备是否支持覆盖表面
        // 因为 DirectDraw 不能仿真覆盖, 所以如果硬件不支持覆盖, 就不能继续下面的工作
    memset(&ddcaps, 0, sizeof(ddcaps));
    ddcaps.dwSize = sizeof(ddcaps);
    hRet = g_pDD->GetCaps(&ddcaps, NULL);
    if(hRet != DD_OK)
        return InitFail(hWnd, hRet, TEXT("GetCaps FAILED"));

    if(ddcaps.dwOverlayCaps == 0)
        return InitFail(hWnd, hRet, TEXT("Overlays are not supported in hardware!"));
        /* // Leo.Zheng Add
        if(!(capsDrv.dwCaps & DDCAPS_OVERLAY))
                return FALSE;
        */

    // Get alignment info to compute our overlay surface size.
    rs.left = 0;
    rs.top = 0;
    rs.right = BUG_WIDTH;
    rs.bottom = BUG_HEIGHT;
    if(ddcaps.dwAlignSizeSrc != 0)
            rs.right += rs.right % ddcaps.dwAlignSizeSrc;
    
    // Create the overlay flipping surface. We will attempt the pixel formats
        // in our table one at a time until we find one that jives.
        // 如果知道显示设备支持覆盖表面, 就可以创建一个. 因为没有指明设备怎样支持覆盖表面的标准, 所以不能够期望创建任意大小的像素格式的表面.
        // 另外, 也不要期望第一次创建覆盖表面就会成功. 因此, 必须作好准备进行多次创建的尝试, 直到有一个能够工作为止.
        int i = 0;
    memset(&ddsd, 0, sizeof(ddsd));
    ddsd.dwSize = sizeof(ddsd);
    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | DDSCAPS_FLIP;
    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_BACKBUFFERCOUNT | DDSD_PIXELFORMAT;
        ddsd.dwWidth = rs.right;
        ddsd.dwHeight = rs.bottom;
    ddsd.dwBackBufferCount = 1;
    do
        {       // Leo.Zheng MStar 2521 只创建 16-bit RGB 5:6:5 成功; 创建 16-bit RGB 5:5:5 失败.
            ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];
            hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);                   // Leo.Zheng 此处调用后引起使用 IOCtrl 显示在 LCD 上的消失
                RETAILMSG(1,(L"[mosquito]Create No.%d surface return: 0x%Xrn",i + 1,hRet));
    }while(hRet != DD_OK && (++i < PF_TABLE_SIZE));
    if(hRet != DD_OK)
        return InitFail(hWnd, hRet, TEXT("Unable to create overlay surface!"));

    // Load the images.
    if(LoadBugImages() != DD_OK)
        return InitFail(hWnd, hRet, TEXT("Unable to load images to overlay surface!"));

    // Finish setting up the overlay.
    int StretchFactor1000 = ddcaps.dwMinOverlayStretch > 1000 ? ddcaps.dwMinOverlayStretch : 1000;

    rd.left=0; 
    rd.top=0;
    // Adding 999 takes care of integer truncation problems.
    rd.right  = (rs.right * StretchFactor1000 + 999) / 1000;
    rd.bottom = rs.bottom * StretchFactor1000 / 1000;
    if (ddcaps.dwAlignSizeDest != 0)
            rd.right = (int)((rd.right + ddcaps.dwAlignSizeDest - 1)/ ddcaps.dwAlignSizeDest) * ddcaps.dwAlignSizeDest;

        // 显示覆盖表面: 在设置了源矩形和目的矩形后, 就可以显示覆盖了.
        // 程序开始在临时变量 dwUpdateFlags 中设定了 DDOVER_SHOW 和 DDOVER_DDFX 标志, 指明该覆盖是第一次显示, 
        // 硬件应该使用包含在 DDOVERLAYFX 结构中的效果信息完成这一工作.
        // UpdateOverlay 用于重新定位一个覆盖页面, 或修改其视觉属性.
    // Set the flags we'll send to UpdateOverlay
    dwUpdateFlags = DDOVER_SHOW;
        // dwUpdateFlags = DDOVER_SHOW | DDOVER_DDFX;                   // Leo.Zheng DDOVER_DDFX WinCE 不支持

        // 检查 DDCAPS 结构确定覆盖是否支持源 Color Key
    // Does the overlay hardware support source color keying?
    // If so, we can hide the black background around the image.
    // This probably won't work with YUV formats
    memset(&ovfx, 0, sizeof(ovfx));
    ovfx.dwSize = sizeof(ovfx);
    if(ddcaps.dwOverlayCaps & DDOVERLAYCAPS_CKEYSRC)                    // MStar2521 不支持 color key
    {
        dwUpdateFlags |= DDOVER_KEYSRCOVERRIDE;

        // Create an overlay FX structure so we can specify a source color key.
        // This information is ignored if the DDOVER_SRCKEYOVERRIDE flag 
        // isn't set.
        ovfx.dckSrcColorkey.dwColorSpaceLowValue=0; // black as the color key
        ovfx.dckSrcColorkey.dwColorSpaceHighValue=0;
    }
        else
        {
                RETAILMSG(1,(L"[mosquito]cannot support color key: 0x%X(0x%x)rn",ddcaps.dwOverlayCaps,DDOVERLAYCAPS_CKEYSRC));
        }

    // Update the overlay parameters.
        // 调用 IDirectDrawSurface::UpdateOverlay 方法来显示覆盖
    hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx);
    if(hRet != DD_OK)
        {
                // 在 MStar 2521 设备上运行第二个此程序实例时出错。
                // 在 TeleChips 8902 设备上运行第三个此程序实例时出错。
                return InitFail(hWnd, hRet, TEXT("Unable to show overlay surface: 0x%x!"),hRet);
        }

    // Set a bunch of position and velocity module vars.
    g_nOverlayXPos = 0;
    g_nOverlayYPos = 0;
    g_nOverlayXVel = RANDOM_VELOCITY();
    g_nOverlayYVel = RANDOM_VELOCITY();
    g_nOverlayWidth = rd.right - rd.left;
    g_nOverlayHeight = rd.bottom - rd.top;
    
    // Set the "destination position alignment" global so we won't have to
    // keep calling GetCaps() everytime we move the overlay surface.
    g_dwOverlayXPositionAlignment = ddcaps.dwAlignBoundaryDest;

    // Create a timer to flip the pages.
    if(TIMER_ID != SetTimer(hWnd, TIMER_ID, TIMER_RATE, NULL))
        return InitFail(hWnd, hRet, TEXT("SetTimer FAILED"));

    return DD_OK;
}

//-----------------------------------------------------------------------------
// Name: WinMain()
// Desc: Initialization, message loop
//-----------------------------------------------------------------------------
int PASCAL WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
#ifdef UNDER_CE
        LPWSTR lpCmdLine,
#else
        LPSTR lpCmdLine,
#endif
        int nCmdShow)
{
    MSG msg;

    g_hInstance = hInstance;
    if(InitApp(hInstance, nCmdShow) != DD_OK)
        return FALSE;

    while(GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}



本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

OverlayFS,顾名思义是一种堆叠文件系统,可以将多个目录的内容叠加到另一个目录上。OverlayFS并不直接涉及磁盘空间结构,看起来像是将多个目录的文件按照规则合并到同一个目录。且对多个源目录具体使用文件系统类型没...

关键字: overlay

摘 要:启动装载程序是嵌入式系统的重要组成部分。文章结合在ARM平台上广泛使用的U-Boot,详细讨论了Boot Loader开发中用到的主要技术,分析引导程序的执行流程,提出了WinCE和Linux在ARM平台下...

关键字: 启动装载程序 U-Boot 嵌入式系统 WinCE Linux

摘 要:火车货运在高速发展的同时,也带来了越来越多的不安全因素,货运物资被盗是铁路货运事故的主要原因之一。 基于此,设计和实现了基于ZigBee和WinCE技术的火车货运防盗预警系统,用于解决站停、待编、待卸和运行途中...

关键字: 火车货运 智能防盗 Zigbee WinCE PDA软件

OverlayFS,顾名思义是一种堆叠文件系统,可以将多个目录的内容叠加到另一个目录上。OverlayFS并不直接涉及磁盘空间结构,看起来像是将多个目录的文件按照规则合并到同一个目录。且对多个源目录具体使用文件系统类型没...

关键字: overlay

电源大家都知道,为我们的社会的发展,贡献了很大的能量,现有的所有的电子产品都离不开电源,那么你知道电源管理吗?伴随着移动嵌入式产品的普及,电源管理已经成为重要技术指标和产品的有机组成。典型移动嵌入式设备对能耗越来越敏感,...

关键字: 电源管理 WinCE 有机组成

  车载操作系统(AutomoTIve OperaTIng System,简称AOS)是管理和控制车载硬件与车载软件资源的程序系统,是直接运行在AB上的最基本的系统软件,任何上层软件,HMI,数

关键字: iOS Linux WinCE
关闭
关闭