//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void DrawAllOverlays(void) { OverlayBase_t* pCurrOverlay = s_pOverlays; OverlayBase_t* pPrevOverlay = NULL; OverlayBase_t* pNextOverlay; while (pCurrOverlay) { // Is it time to kill this overlay? if ( pCurrOverlay->IsDead() ) { if (pPrevOverlay) { // If I had a last overlay reset it's next pointer pPrevOverlay->m_pNextOverlay = pCurrOverlay->m_pNextOverlay; } else { // If the first line, reset the s_pOverlays pointer s_pOverlays = pCurrOverlay->m_pNextOverlay; } pNextOverlay = pCurrOverlay->m_pNextOverlay; DestroyOverlay( pCurrOverlay ); pCurrOverlay = pNextOverlay; } else { DrawOverlay( pCurrOverlay ); pPrevOverlay = pCurrOverlay; pCurrOverlay = pCurrOverlay->m_pNextOverlay; } } }
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; }
//------------------------------------------------------------------------------ // Purpose : Deletes all overlays // Input : // Output : //------------------------------------------------------------------------------ void ClearAllOverlays(void) { while (s_pOverlays) { OverlayBase_t *pOldOverlay = s_pOverlays; s_pOverlays = s_pOverlays->m_pNextOverlay; DestroyOverlay( pOldOverlay ); } while (s_pOverlayText) { OverlayText_t *cur_ol = s_pOverlayText; s_pOverlayText = s_pOverlayText->nextOverlayText; delete cur_ol; } s_bDrawGrid = false; }
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; }
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); }