⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ddvideo.cpp

📁 英特尔&#174 线程构建模块(英特尔&#174 TBB)是一个屡获殊荣的 C++ 运行时库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    // Set cooperation level with other windows to be normal (ie. not full screen)    // You MUST set the cooperation level to be SOMETHING, for windowed apps use    // DDSCL_NORMAL, for full screen use: DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN.    hRet = g_pDD->SetCooperativeLevel(g_hAppWnd, DDSCL_NORMAL);    if (hRet != DD_OK)        return DisplayError("Can't set cooperative level", hRet);    return DDPrimaryInit();}//! Setup the overlay objectbool DDOverlayInit(){    // Get hardware's CAPabilitieS    memset(&g_DDCaps, 0, sizeof(g_DDCaps));    g_DDCaps.dwSize = sizeof(g_DDCaps);    if (g_pDD->GetCaps(&g_DDCaps, 0))        return DisplayError("Can't get capabilities");    // Make sure it supports overlays    if (!(g_DDCaps.dwCaps & DDCAPS_OVERLAY))        return DisplayError("Hardware doesn't support overlays");    //DO NOT Make sure it supports stretching (scaling)    //if (!(g_DDCaps.dwCaps & DDCAPS_OVERLAYSTRETCH)) return false;    DDSURFACEDESC2              ddsd;  // DirectDraw surface descriptor    HRESULT                     hRet;  // I'm not even going to try...    // The pixel formats that we want the surface to be in    DDPIXELFORMAT               ddpfOverlayFormats[] = {        {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 32, 0xFF0000, 0x0FF00, 0x0000FF, 0}, // 32-bit RGB        {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x007C00, 0x003e0, 0x00001F, 0}, // 16-bit RGB 5:5:5        {sizeof(DDPIXELFORMAT), DDPF_RGB, 0, 16, 0x00F800, 0x007e0, 0x00001F, 0}, // 16-bit RGB 5:6:5        {sizeof(DDPIXELFORMAT), DDPF_FOURCC, mmioFOURCC('U','Y','V','Y'), 16, 0, 0, 0, 0}, // UYVY        {sizeof(DDPIXELFORMAT), DDPF_FOURCC, mmioFOURCC('Y','4','2','2'), 16, 0, 0, 0, 0}, // the same as UYVY        {sizeof(DDPIXELFORMAT), DDPF_FOURCC, mmioFOURCC('Y','U','Y','2'), 16, 0, 0, 0, 0}, // YUY2 is unsupported color-space here        {0}};    // Setup the overlay surface's attributes in the surface descriptor    memset(&ddsd, 0, sizeof(ddsd));    ddsd.dwSize = sizeof(ddsd);    ddsd.ddsCaps.dwCaps = DDSCAPS_OVERLAY | g_DDCaps.ddsCaps.dwCaps&DDSCAPS_VIDEOMEMORY;    ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT;    ddsd.dwBackBufferCount = 0;    ddsd.dwWidth = g_sizex;    ddsd.dwHeight = g_sizey;    for(int format = 0; ddpfOverlayFormats[format].dwSize; format++) {        ddsd.ddpfPixelFormat = ddpfOverlayFormats[format];        // Attempt to create the surface with theses settings        hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSOverlay, NULL);        if(hRet == DD_OK) break;    }    if (hRet != DD_OK)        return DisplayError("Can't create appropriate overlay surface", hRet);    return true;}inline void mouse(int k, LPARAM lParam){    int x = (int)LOWORD(lParam), y = (int)HIWORD(lParam);    g_video->on_mouse( x*g_sizex/(g_rcDst.right - g_rcDst.left),        y*g_sizey/(g_rcDst.bottom - g_rcDst.top), k);}LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam){    PAINTSTRUCT                 ps;         // Structure for the paint message    POINT                       p = {0, 0}; // Translation point for the window's client region    HRESULT                     hRet;    switch (iMsg)    {        case WM_MOVE:            // Make sure we're not moving to be minimized - because otherwise            // our ratio varialbes (g_dwXRatio and g_dwYRatio) will end up            // being 0, and once we hit CheckBoundries it divides by 0.            if (!IsIconic(hwnd))            {                g_rcSrc.left = 0;                g_rcSrc.right = g_sizex;                g_rcSrc.top = 0;                g_rcSrc.bottom = g_sizey;                GetClientRect(hwnd, &g_rcDst);                g_dwXRatio = (g_rcDst.right - g_rcDst.left) * 1000 /                             (g_rcSrc.right - g_rcSrc.left);                g_dwYRatio = (g_rcDst.bottom - g_rcDst.top) * 1000 /                             (g_rcSrc.bottom - g_rcSrc.top);                ClientToScreen(hwnd, &p);                g_rcDst.left = p.x;                g_rcDst.top = p.y;                g_rcDst.bottom += p.y;                g_rcDst.right += p.x;                CheckBoundries();            }            else                // Else, hide the overlay... just in case we can't do                // destination color keying, this will pull the overlay                // off of the screen for the user.                if (g_pDDSOverlay && g_pDDSPrimary)                    g_pDDSOverlay->UpdateOverlay(NULL, g_pDDSPrimary, NULL, DDOVER_HIDE, NULL);            // Check to make sure our window exists before we tell it to            // repaint. This will fail the first time (while the window is being created).            if (hwnd)            {                InvalidateRect(hwnd, NULL, FALSE);                UpdateWindow(hwnd);            }            return 0L;        case WM_SIZE:            // Another check for the minimization action.  This check is            // quicker though...            if (wParam != SIZE_MINIMIZED)            {                GetClientRect(hwnd, &g_rcDst);                ClientToScreen(hwnd, &p);                g_rcDst.left = p.x;                g_rcDst.top = p.y;                g_rcDst.bottom += p.y;                g_rcDst.right += p.x;                g_rcSrc.left = 0;                g_rcSrc.right = g_sizex;                g_rcSrc.top = 0;                g_rcSrc.bottom = g_sizey;                // Here we multiply by 1000 to preserve 3 decimal places in the                // division opperation (we picked 1000 to be on the same order                // of magnitude as the stretch factor for easier comparisons)                g_dwXRatio = (g_rcDst.right - g_rcDst.left) * 1000 /                             (g_rcSrc.right - g_rcSrc.left);                g_dwYRatio = (g_rcDst.bottom - g_rcDst.top) * 1000 /                             (g_rcSrc.bottom - g_rcSrc.top);                CheckBoundries();            }            return 0L;        case WM_PAINT:            BeginPaint(hwnd, &ps);            // Check the primary surface to see if it's lost - if so you can            // pretty much bet that the other surfaces are also lost - thus            // restore EVERYTHING!  If we got our surfaces stolen by a full            // screen app - then we'll destroy our primary - and won't be able            // to initialize it again. When we get our next paint message (the            // full screen app closed for example) we'll want to try to reinit            // the surfaces again - that's why there is a check for            // g_pDDSPrimary == NULL.  The other option, is that our program            // went through this process, could init the primary again, but it            // couldn't init the overlay, that's why there's a third check for            // g_pDDSOverlay == NULL.  Make sure that the check for            // !g_pDDSPrimary is BEFORE the IsLost call - that way if the            // pointer is NULL (ie. !g_pDDSPrimary is TRUE) - the compiler            // won't try to evaluate the IsLost function (which, since the            // g_pDDSPrimary surface is NULL, would be bad...).            if (!g_pDDSPrimary || (g_pDDSPrimary->IsLost() != DD_OK) ||                (g_pDDSOverlay == NULL))            {                DestroyOverlay();                DestroyPrimary();                if (DDPrimaryInit())                    if (DDOverlayInit())                        if (!DrawOverlay())                            DestroyOverlay();            }            // UpdateOverlay is how we put the overlay on the screen.            if (g_pDDSOverlay && g_pDDSPrimary && g_video->updating)            {                hRet = g_pDDSOverlay->UpdateOverlay(&g_rcSrc, g_pDDSPrimary,                                                    &g_rcDst, g_OverlayFlags,                                                    &g_OverlayFX);#ifdef _DEBUG                if(hRet != DD_OK) DisplayError("Can't update overlay", hRet);#endif            }            EndPaint(hwnd, &ps);            return 0L;        // process mouse and keyboard events        case WM_LBUTTONDOWN:    mouse(1, lParam); break;        case WM_LBUTTONUP:      mouse(-1, lParam); break;        case WM_RBUTTONDOWN:    mouse(2, lParam); break;        case WM_RBUTTONUP:      mouse(-2, lParam); break;        case WM_MBUTTONDOWN:    mouse(3, lParam); break;        case WM_MBUTTONUP:      mouse(-3, lParam); break;        case WM_CHAR:           g_video->on_key(wParam); break;        case WM_DISPLAYCHANGE:  return 0L;        case WM_DESTROY:            // Now, shut down the window...            PostQuitMessage(0);            return 0L;    }    return g_pUserProc? g_pUserProc(hwnd, iMsg, wParam, lParam) : DefWindowProc(hwnd, iMsg, wParam, lParam);}DWORD WINAPI thread_vsync(LPVOID lpParameter){    BOOL vblank = false;    while(g_video && g_video->running) {        while(!vblank && g_video && g_video->running) {            Sleep(0); LPDIRECTDRAW7 pDD(g_pDD); if(pDD) pDD->GetVerticalBlankStatus(&vblank);        }        LPDIRECTDRAWSURFACE7 pDDSOverlay(g_pDDSOverlay);        if(pDDSOverlay) pDDSOverlay->UpdateOverlay(&g_rcSrc, g_pDDSPrimary, &g_rcDst, g_OverlayFlags | DDOVER_REFRESHALL, &g_OverlayFX);        do {            Sleep(1); LPDIRECTDRAW7 pDD(g_pDD); if(pDD) pDD->GetVerticalBlankStatus(&vblank);        } while(vblank && g_video && g_video->running);        while(g_video && !g_video->updating && g_video->running) Sleep(10);    }    return 0;}///////////////////////////////////////////// public methods of video class ///////////////////////inline void mask2bits(unsigned int mask, color_t &save, char &shift){    save  = mask; if(!mask) { shift = 8; return; }    shift = 0; while(!(mask&1)) ++shift, mask >>= 1;    int bits = 0; while(mask&1) ++bits,  mask >>= 1;    shift += bits - 8;}bool video::init_window(int sizex, int sizey){    assert(win_hInstance != 0);    g_sizex = sizex; g_sizey = sizey;    if( !WinInit(win_hInstance, win_iCmdShow, gWndClass, title, false) )        return DisplayError("Unable to initialize the program's window.");    running = true;    if( !DDInit() ) {        DestroyDDraw();        goto fail;    }    if( !DDOverlayInit() || !DrawOverlay() ) {        DestroyOverlay();        DestroyDDraw();        goto fail;    }    DDPIXELFORMAT PixelFormat; memset(&PixelFormat, 0, sizeof(PixelFormat)); PixelFormat.dwSize = sizeof(PixelFormat);    g_pDDSOverlay->GetPixelFormat(&PixelFormat);    mask2bits(PixelFormat.dwRBitMask, red_mask, red_shift);    mask2bits(PixelFormat.dwGBitMask, green_mask, green_shift);    mask2bits(PixelFormat.dwBBitMask, blue_mask, blue_shift);    if(PixelFormat.dwFlags == DDPF_RGB)         depth = char(PixelFormat.dwRGBBitCount);    else depth = -char(PixelFormat.dwFourCC);    for(int i = 0, e = sizex * sizey * PixelFormat.dwRGBBitCount / 32, c = get_color(0, 0, 0); i < e; i++)        g_pImg[i] = c; // clear surface    ShowWindow(g_hAppWnd, SW_SHOW);    g_hVSync = CreateThread (	    NULL,				// LPSECURITY_ATTRIBUTES security_attrs	    0,					// SIZE_T stacksize	    (LPTHREAD_START_ROUTINE) thread_vsync,	    this,               // argument	    0, 0);    SetPriorityClass(g_hVSync, IDLE_PRIORITY_CLASS); // questionable    return true;fail:    g_pImg = new unsigned int[g_sizex * g_sizey];    return false;}void video::terminate(){    running = false;    DestroyOverlay();    if(WaitForSingleObject(g_hVSync, 100) == WAIT_TIMEOUT) TerminateThread(g_hVSync, 0);    CloseHandle(g_hVSync);    DestroyDDraw();    if(g_pImg) delete[] g_pImg;    g_pImg = 0; g_video = 0;}//////////// drawing area constructor & destructor /////////////drawing_area::drawing_area(int x, int y, int sizex, int sizey): start_x(x), start_y(y), size_x(sizex), size_y(sizey), pixel_depth(g_video->depth),    base_index(y*g_sizex + x), max_index(g_sizex*g_sizey), index_stride(g_sizex), ptr32(g_pImg){    assert(ptr32); assert(x < g_sizex); assert(y < g_sizey);    assert(x+sizex <= g_sizex); assert(y+sizey <= g_sizey);    index = base_index; // current index}drawing_area::~drawing_area(){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -