当前位置:首页 > 芯闻号 > 充电吧
[导读]在代码中增加了很多对代码的注释。同时,对在不同平台(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;
}



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

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭