📄 mosquito.cpp
字号:
// Go through the image 2 pixels at a time and convert to YUV
for(y=0; y<dwHeight; y++)
{
for(x=0; x<dwWidth; x+=2)
{
// The equations for color conversion used here, probably aren't
// exact, but they seem to do an OK job.
color=GetPixel(hdcImage, x,y);
R=GetRValue(color);
G=GetGValue(color);
B=GetBValue(color);
Y0= (BYTE)(0.29*R + 0.59*G + 0.14*B);
U= (BYTE)(128.0 - 0.14*R - 0.29*G + 0.43*B);
color=GetPixel(hdcImage, x+1,y);
R=GetRValue(color);
G=GetGValue(color);
B=GetBValue(color);
Y1= (BYTE)(0.29*R + 0.57*G + 0.14*B);
V= (BYTE)(128.0 + 0.36*R - 0.29*G - 0.07*B);
switch (ddsd.ddpfPixelFormat.dwFourCC)
{
case MAKEFOURCC('Y','U','Y','V'):
*(pSurf++) = Y0;
*(pSurf++) = U;
*(pSurf++) = Y1;
*(pSurf++) = V;
break;
case MAKEFOURCC('U','Y','V','Y'):
*(pSurf++) = U;
*(pSurf++) = Y0;
*(pSurf++) = V;
*(pSurf++) = Y1;
break;
}
}
pSurf+=(lPitch-dwBytesInRow);
}
lpDDSurf->Unlock(NULL);
CleanUp:
if(hdcImage)
DeleteDC(hdcImage);
return TRUE;
}
//-----------------------------------------------------------------------------
// Function: LoadImageOnToSurface
// Description:
// Loads a resource based bitmap image onto a DirectDraw surface. Can
// covert the bitmap to all RGB formats, plus a couple YUV formats.
//-----------------------------------------------------------------------------
static BOOL
LoadImageOntoSurface(LPDIRECTDRAWSURFACE lpdds, LPCTSTR lpstrResID)
{
HBITMAP hbm = NULL;
HDC hdcImage = NULL;
HDC hdcSurf = NULL;
BOOL bRetVal = FALSE;
HRESULT ddrval;
DDSURFACEDESC ddsd;
if (!lpdds) return FALSE;
//
// get surface size and format.
//
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
ddrval = lpdds->GetSurfaceDesc(&ddsd);
if (FAILED(ddrval))
goto Exit;
// Load the bitmap resource. We'll use LoadImage() since it'll scale the
// image to fit our surface, and maintain the color information in the
// bitmap.
hbm = (HBITMAP)LoadImage(g_hInstance, lpstrResID, IMAGE_BITMAP, 0, 0, 0);
if (hbm == NULL)
goto Exit;
// If our surface is a FOURCC YUV format, we need to do a little work to convert
// our RGB resource bitmap into the appropriate YUV format.
if (ddsd.ddpfPixelFormat.dwFlags == DDPF_FOURCC)
{
if (!CopyBitmapToYUVSurface(lpdds, hbm))
goto Exit;
}
else //Looks like we're just using a standard RGB surface format, let GDI do the work.
{
// Create a DC and associate the bitmap with it.
hdcImage = CreateCompatibleDC(NULL);
SelectObject(hdcImage, hbm);
ddrval = lpdds->GetDC(&hdcSurf);
if (FAILED(ddrval))
goto Exit;
if (BitBlt(hdcSurf, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, 0, 0, SRCCOPY) == FALSE)
goto Exit;
}
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;
LPTSTR ResName;
// Load the Bug Image appropriate...
if (*CallCount == 0) {
ResName = szImg2;
}
else if (*CallCount == 1) {
ResName = szImg3;
}
else {
// Eh?
hr = (HRESULT)DDENUMRET_CANCEL;
goto exit;
}
if (!LoadImageOntoSurface(lpDDSurface, ResName)) {
hr = (HRESULT)DDENUMRET_CANCEL;
goto exit;
}
// Bump the count.
(*CallCount)++;
exit:
lpDDSurface->Release();
return hr;
}
//-----------------------------------------------------------------------------
// Name: LoadBugImages()
// Desc: Load the bug resource images into our various flipping surfaces.
//-----------------------------------------------------------------------------
static HRESULT
LoadBugImages()
{
HRESULT hRet;
int CallCount = 0;
// Put the first bug image onto the first buffer of our complex surface.
if (!LoadImageOntoSurface(g_pDDSOverlay, szImg1))
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_MAIN_ICON));
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, szDDrawFailedMsg);
// Get normal mode.
hRet = g_pDD->SetCooperativeLevel(hWnd, DDSCL_NORMAL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, szSetCooperativeFailMsg);
// 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, szCreateSurfaceFailMsg);
// See if we can support overlays.
memset(&ddcaps, 0, sizeof(ddcaps));
ddcaps.dwSize = sizeof(ddcaps);
hRet = g_pDD->GetCaps(&ddcaps, NULL);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, szGetCapsFailMsg);
if (ddcaps.dwOverlayCaps == 0)
return InitFail(hWnd, hRet, szNoOverlaysMsg);
// 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.
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 = 2;
int i = 0;
do {
ddsd.ddpfPixelFormat = ddpfOverlayFormats[i];
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);
} while (hRet != DD_OK && (++i < PF_TABLE_SIZE));
if (hRet != DD_OK)
return InitFail(hWnd, hRet, szCreateOverlayFailMsg);
// Load the images.
if (LoadBugImages() != DD_OK)
return InitFail(hWnd, hRet, szLoadOverlayFailMsg);
// 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;
// Set the flags we'll send to UpdateOverlay
dwUpdateFlags = DDOVER_SHOW;
// 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)
{
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;
}
// Update the overlay parameters.
hRet = g_pDDSOverlay->UpdateOverlay(&rs, g_pDDSPrimary, &rd, dwUpdateFlags, &ovfx);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, szShowOverlayFailMsg);
// 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, szSetTimerFailMsg);
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;
InitApp(hInstance, nCmdShow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if (g_szErrorMessage != NULL){
MessageBox(NULL, g_szErrorMessage, szDDrawError, MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
return msg.wParam;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -