void AlliesWhiteboard::DrawTextMarker(LPDIRECTDRAWSURFACE DestSurf, int X, int Y, char *cText, char C) { int x = X - *MapX + 128; int y = Y - *MapY + 32; DDBLTFX ddbltfx; DDRAW_INIT_STRUCT(ddbltfx); ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = 102; ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 102; RECT Dest; Dest.left = x-TextMarkerWidth/2; Dest.top = y-TextMarkerHeight/2; Dest.right = Dest.left+TextMarkerWidth; Dest.bottom = Dest.top+TextMarkerHeight; RECT Source; Source.left = C*TextMarkerWidth; Source.top = 0; Source.right = Source.left+TextMarkerWidth; Source.bottom = TextMarkerHeight; if(DestSurf->Blt(&Dest, lpSmallCircle, &Source, DDBLT_ASYNC | DDBLT_KEYSRCOVERRIDE, &ddbltfx)!=DD_OK) { DestSurf->Blt(&Dest, lpSmallCircle, &Source, DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx); } Dialog *pDialog = (Dialog*)LocalShare->Dialog; pDialog->DrawText(DestSurf, x+TextMarkerWidth , y-5, cText); }
void AlliesWhiteboard::DrawTextInput(LPDIRECTDRAWSURFACE DestSurf) { Dialog *DialogPTR = (Dialog*)LocalShare->Dialog; int BFHalfX = (LocalShare->ScreenWidth-128)/2 + 128; int BFHalfY = (LocalShare->ScreenHeight-64)/2 + 32; if(CurrentElement) DialogPTR->DrawText(DestSurf, BFHalfX-InputBoxWidth/2+5, BFHalfY-InputBoxHeight/2-13, "Edit Textmarker"); else DialogPTR->DrawText(DestSurf, BFHalfX-InputBoxWidth/2+5, BFHalfY-InputBoxHeight/2-13, "Add Textmarker"); DDBLTFX ddbltfx; DDRAW_INIT_STRUCT(ddbltfx); ddbltfx.ddckSrcColorkey.dwColorSpaceLowValue = 102; ddbltfx.ddckSrcColorkey.dwColorSpaceHighValue = 102; RECT Dest; Dest.left = BFHalfX-InputBoxWidth/2; Dest.top = BFHalfY-InputBoxHeight/2; Dest.right = Dest.left+InputBoxWidth; Dest.bottom = Dest.top+InputBoxHeight; if(DestSurf->Blt(&Dest, lpInputBox, NULL, DDBLT_ASYNC | DDBLT_KEYSRCOVERRIDE, &ddbltfx)!=DD_OK) { DestSurf->Blt(&Dest, lpInputBox, NULL, DDBLT_WAIT | DDBLT_KEYSRCOVERRIDE, &ddbltfx); } DialogPTR->DrawSmallText(DestSurf, BFHalfX-(InputBoxWidth/2)+14, BFHalfY-5, Text); //draw cursor if textbox overlap if((MouseX-128)>Dest.left-10 && (MouseX-128)<Dest.right && (MouseY-32)>Dest.top-34 && (MouseY-32)<Dest.bottom) DialogPTR->BlitCursor(DestSurf, MouseX-128, MouseY-32); }
void dd_Window::flip_fullscreen() { int i=0; HRESULT hr; //hack for 320x200 letterboxing if(xres == 320 && yres == 200) { hr = dx_bs->BltFast(0,20,dx_os,NULL,DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY); DDBLTFX ddbltfx; memset(&ddbltfx, 0, sizeof(DDBLTFX)); ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwFillColor = 0; RECT rBlit; rBlit.left = 0; rBlit.top = 0; rBlit.right = 320; rBlit.bottom = 20; dx_bs->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); rBlit.left = 0; rBlit.top = 220; rBlit.right = 320; rBlit.bottom = 240; dx_bs->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } //regular case else hr = dx_bs->BltFast(0,0,dx_os,NULL,DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY); if(hr==DDERR_SURFACELOST) { dx_bs->Restore(); dx_os->Restore(); dx_bs->BltFast(0,0,dx_os,NULL,DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY); } hr=dx_ps->Flip(0,DDFLIP_WAIT | DDFLIP_NOVSYNC); //dx_ps->Flip(0,0); if(hr==DDERR_SURFACELOST) { dx_ps->Restore(); hr=dx_ps->Flip(0,DDFLIP_WAIT | DDFLIP_NOVSYNC); } hr=dx_os->Lock(0,&dx_osd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT,0); if(hr==DDERR_SURFACELOST) { dx_os->Restore(); hr=dx_os->Lock(0,&dx_osd,DDLOCK_SURFACEMEMORYPTR | DDLOCK_WRITEONLY | DDLOCK_WAIT,0); } dx_os->Unlock(0); img->data=(quad*)dx_osd.lpSurface; img->pitch=dx_osd.lPitch/vid_bytesperpixel; }
bool flip(long bltWidth,long bltHeight){ if (m_ddsback==0) return true; if (m_IS_USER_BACK_BUFFER){ if ((bltWidth>0)&&(bltHeight>0)){ RECT rt; rt.left=0; rt.top=0; rt.right=bltWidth; rt.bottom=bltHeight; #ifdef WINCE HRESULT ddrval=m_ddsprimary->Blt(&rt,m_ddsback, &rt,DDBLT_WAITNOTBUSY, NULL); #else HRESULT ddrval=m_ddsprimary->BltFast(0,0, m_ddsback, &rt, NULL); #endif return (ddrval == DD_OK); }else return true; }else{ //flip while( true ) { HRESULT ddrval= m_ddsprimary->Flip( NULL, DDFLIP_WAIT );// 交换表面 if( ddrval == DD_OK ) return true; if( ddrval == DDERR_SURFACELOST ) { ddrval = m_ddsprimary->Restore(); if( ddrval!= DD_OK ) return false; } if( ddrval != DDERR_WASSTILLDRAWING ){ return false; } ::Sleep(0); } } }
//----------------------------------------------------------------------------- // Name: EraseScreen() // Desc: //----------------------------------------------------------------------------- VOID EraseScreen() { // Erase the background DDBLTFX ddbltfx; ZeroMemory( &ddbltfx, sizeof(ddbltfx) ); ddbltfx.dwSize = sizeof(ddbltfx); #ifdef NONAMELESSUNION ddbltfx.u5.dwFillColor = g_dwFillColor; #else ddbltfx.dwFillColor = g_dwFillColor; #endif while( 1 ) { HRESULT hr = g_pddsBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx ); if( SUCCEEDED(hr) ) return; if( hr == DDERR_SURFACELOST ) { if( FAILED( RestoreSurfaces() ) ) return; } if( hr != DDERR_WASSTILLDRAWING ) return; } }
void CALLBACK _GameProc(HWND hWnd, UINT message, UINT wParam, DWORD lParam) { static int Frame = 0, Count = 0; RECT BackRect = { 0, 0, 640, 480 }, SpriteRect; BackScreen -> BltFast( 0, 0, BackGround, &BackRect, DDBLTFAST_WAIT | DDBLTFAST_NOCOLORKEY ); SpriteRect.left = Frame * 100; SpriteRect.top = 0; SpriteRect.right = SpriteRect.left + 100; SpriteRect.bottom = 70; BackScreen -> BltFast( MouseX - 50, MouseY - 35, SpriteImage, &SpriteRect, DDBLTFAST_WAIT | DDBLTFAST_SRCCOLORKEY ); // enter animation code here! if(gFullScreen) RealScreen->Flip(NULL, DDFLIP_WAIT); else{ RECT WinRect, SrcRect={0, 0, gWidth, gHeight}; GetWindowRect(MainHwnd, &WinRect); RealScreen->Blt(&WinRect, BackScreen, &SrcRect, DDBLT_WAIT, NULL ); } }
STDMETHODIMP CeE2DPage::BitBlt(ICeE2DPage *pdest, LONG destx, LONG desty, LONG width, LONG height, LONG srcx, LONG srcy, LONG rop) { HRESULT hr; LPDIRECTDRAWSURFACE lpddsDest = NULL; DWORD bltFlags = 0; DDBLTFX ddbltfx; RECT rectdest; RECT rectsrc; if (pdest == NULL) return E_FAIL; hr = ((CeE2DPage *)pdest)->get_lpdds(&lpddsDest); if (FAILED(hr)) return hr; bltFlags = DDBLT_ROP; ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwROP = rop; rectdest.left = destx; rectdest.top = desty; rectdest.right = destx + width - 1; rectdest.bottom = desty + height - 1; rectsrc.left = srcx; rectsrc.top = srcy; rectsrc.right = rectdest.right; rectsrc.bottom = rectdest.bottom; hr = lpddsDest->Blt(&rectdest, this->m_lpDDS, &rectsrc, bltFlags, &ddbltfx); if (FAILED(hr)) { return hr; } return NOERROR; }
HRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_PAINT: if(flag) { RectClient = GetClientRect(hWnd, diff_x, diff_y); HRESULT ddrval = lpDDSPrimary->Blt (&RectClient, lpDDSTemp, &RectTemp, DDBLT_WAIT, NULL); if(ddrval == DDERR_SURFACELOST) { ddrval = lpDDSPrimary->Restore(); if (ddrval != DD_OK) break; } } return 0; //这里一定要是return,而不是break,否则不显示画面 case WM_DESTROY: FreeDDraw(); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); }
void DXGame::fillSurface(LPDIRECTDRAWSURFACE lpdds,COLORREF color) { DDBLTFX fx; ZeroMemory(&fx, sizeof(fx)); fx.dwSize = sizeof(fx); fx.dwFillColor = color; lpdds->Blt(NULL,NULL,NULL,DDBLT_COLORFILL | DDBLT_WAIT,&fx); }
extern "C" void updateFrame(void) { HRESULT ddrval; RECT destRect, rcRect; POINT pt; if (!useDirectDraw) { noddrawUpdateFrame(); return; } if (WINDOWED) { GetClientRect(hwnd, &destRect); pt.x = pt.y = 0; ClientToScreen(hwnd, &pt); OffsetRect(&destRect, pt.x, pt.y); rcRect.left = 0; rcRect.top = 0; rcRect.right = SCRWIDTH; rcRect.bottom = SCRHEIGHT; } else { rcRect.left = rcRect.top = 0; rcRect.right = SCRWIDTH; rcRect.bottom = SCRHEIGHT; destRect = rcRect; } if (bSaveFramebuffer) { rglCopyScratchBuffer(); } for (;;) { ddrval = PrimarySurface->Blt(&destRect, BackSurface, &rcRect, 0, NULL); // ddrval = PrimarySurface->BltFast(0, 0, BackSurface, &rcRect, 0); if (ddrval == DD_OK) { break; } if (ddrval == DDERR_SURFACELOST) { if (!restoreAll()) { return; } } if (ddrval != DDERR_WASSTILLDRAWING) { return; } } }
HRESULT DDFlip(void) { #ifndef DOD_WINDOWED HRESULT ddrval; ddrval = lpDDSPrimary->Flip(NULL, DDFLIP_WAIT); // flip the surfaces return ddrval; #else RECT rect = { 0, 0, 640, 480 }; lpDDSPrimary->Blt(&rcWindow, lpDDSBack, &rect, DDBLT_WAIT, NULL); return 1; #endif }
void TAGameAreaReDrawer::BlitTAGameArea(LPDIRECTDRAWSURFACE DestSurf) { if (NULL!=GameAreaSurfaceFront_ptr) { if ( DD_OK!=GameAreaSurfaceFront_ptr->IsLost ( )) { GameAreaSurfaceFront_ptr->Restore ( ); } // DDBLTFX ddbltfx; // DDRAW_INIT_STRUCT(ddbltfx); RECT GameScreen; TAWGameAreaRect ( &GameScreen); if(DestSurf->Blt ( &GameScreen, GameAreaSurfaceFront_ptr, NULL, DDBLT_ASYNC , NULL)!=DD_OK) { DestSurf->Blt ( &GameScreen, GameAreaSurfaceFront_ptr, NULL, DDBLT_WAIT , NULL); } } }
void __fillRect(DWORD dwFillColor) { DDBLTFX ddbltfx; HRESULT ddrval; memset (&ddbltfx, 0, sizeof (ddbltfx)); ddbltfx.dwSize = sizeof( ddbltfx ); #ifdef NONAMELESSUNION ddbltfx.u5.dwFillColor = dwFillColor; #else ddbltfx.dwFillColor = dwFillColor; #endif ddrval = g_pDDSBack->Blt(NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx ); }
int Draw_BOB(BITMAP_OBJ_PTR bob, LPDIRECTDRAWSURFACE dest) { RECT dest_rect, source_rect; dest_rect.left = bob->x; dest_rect.top = bob->y; dest_rect.right = bob->x + bob->width; dest_rect.bottom = bob->y + bob->height; source_rect.left = 0; source_rect.top = 0; source_rect.right = bob->width ; source_rect.bottom = bob->height; dest->Blt(&dest_rect, bob->image, &source_rect, (DDBLT_WAIT | DDBLT_KEYSRC), NULL); return 1; }
void DDFillSurface(LPDIRECTDRAWSURFACE lpdds, WORD color) { DDBLTFX ddbltfx; // this contains the DDBLTFX structure // clear out the structure and set the size field DD_INIT_STRUCT(ddbltfx); // set the dwfillcolor field to the desired color ddbltfx.dwFillColor = color; // ready to blt to surface lpdds->Blt(NULL, // ptr to dest rectangle NULL, // ptr to source surface, NA NULL, // ptr to source rectangle, NA DDBLT_COLORFILL | DDBLT_WAIT, // fill and wait &ddbltfx); // ptr to DDBLTFX structure }
BOOL ComposeFrame(){ //compose a frame of animation //draw background static int next_powerup = Timer.time()+Random.number(3000,12000); static int frame = 1; RECT rect; //drawing rectangle rect.left=0; rect.right=g_nScreenWidth; rect.top=0; rect.bottom=g_nScreenHeight; lpSecondary->Blt(&rect,lpBackground,&rect,DDBLT_WAIT,NULL); //move objects Viewpoint.draw_background(lpBackground,lpSecondary,8); int collision = theObjects.collisiondetection(); theObjects.animate(lpSecondary); //animate the current frame theObjects.refresh(collision); //refresh the objects if(Timer.time()>=next_powerup){ theObjects.powerup(); next_powerup += Random.number(10000,30000); //next power up in 10 - 30 sec } //frame rate framecount++; //count frame if(Timer.elapsed(framerate_timer,500)){ theObjects.set_current(STARFIRE_INDEX); theObjects.changedirection(0,0); last_framecount=framecount; framecount=0; } return PageFlip(); //flip video memory surfaces // return TRUE; } //ComposeFrame
//----------------------------------------------------------------------------- // Name: FlipScreen() // Desc: //----------------------------------------------------------------------------- VOID FlipScreen() { // Flip the surfaces if( g_bFullscreen ) { while( 1 ) { HRESULT hr = g_pddsFrontBuffer->Flip( NULL, 0 ); if( hr == DDERR_SURFACELOST ) { if( FAILED( RestoreSurfaces() ) ) return; } if( hr != DDERR_WASSTILLDRAWING ) return; } } else { g_pddsFrontBuffer->Blt( &g_rcWindow, g_pddsBackBuffer, NULL, DDBLT_WAIT, NULL ); } }
//----------------------------------------------------------------------------- // Name: BltSplashScreen() // Desc: //----------------------------------------------------------------------------- HRESULT BltSplashScreen( RECT* prc ) { HRESULT hr; HBITMAP hbm; if( ( g_pddsFrontBuffer == NULL ) || ( g_pSplashPalette == NULL ) || ( g_pddsBackBuffer == NULL ) ) return E_FAIL; // Set the palette before loading the splash screen g_pddsFrontBuffer->SetPalette( g_pSplashPalette ); hbm = (HBITMAP)LoadImage( GetModuleHandle( NULL ), TEXT("SPLASH"), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION ); if( NULL == hbm ) return E_FAIL; // If the surface is lost, DDUtil_CopyBitmap will fail and the surface will // be restored below. hr = DDUtil_CopyBitmap( g_pddsBackBuffer, hbm, 0, 0, 0, 0 ); DeleteObject( hbm ); while( 1 ) { hr = g_pddsFrontBuffer->Blt( &g_rcWindow, g_pddsBackBuffer, prc, DDBLT_WAIT, NULL); if( SUCCEEDED(hr) ) return S_OK; if( hr == DDERR_SURFACELOST ) if( FAILED( RestoreSurfaces() ) ) return E_FAIL; if( hr != DDERR_WASSTILLDRAWING ) return E_FAIL; } }
/* * FadeToSurface: * Fades into a surface from black */ void FadeToSurface(LPDIRECTDRAWSURFACE lpDDS) { int c; // counter variable long i; // incrementing variable WORD *tmp, *ref, *prm; WORD *fasttmp, *fastref; // temporary and destination surface mem pointers RECT SrcRect, DesRect; // Source and destination rectangles int tpitch, rpitch, ppitch; // temporary and destination surface pitch WORD *shade; // Set the source and destination rectangles to the size of the screen SetRect(&SrcRect, 0, 0, 640, 480); SetRect(&DesRect, 0, 0, 640, 480); // Create the surfaces lpDDSTmp = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // the temporary surface lpDDSRef = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // the temporary surface lpDDSRef->Blt(&DesRect, lpDDS, &SrcRect, DDBLT_WAIT, NULL); // blit the desired surface into our destination surface // Lock our surfaces temporary, and destination tmp = DDLockSurface(lpDDSTmp, &tpitch); prm = DDLockSurface(lpDDSPrimary, &ppitch); ref = DDLockSurface(lpDDSRef, &rpitch); // This can be changed, but it worx out nice to do 10 iterations for (c = 1; c <= 30; c++) { // get pointer indexed to the start of the current shade level shade = PixelShade[c]; // "reset" our *fast* surface pointers fasttmp = tmp; fastref = ref; // for every pixel on the screen (640*480=307200) for (i = 0; i < 307200; i++, fasttmp++, fastref++) { // new pixel please..... *fasttmp = shade[*fastref]; } // copy the temp surface to the primary surface // method depends on windowed/full screen #ifdef WINDOWED WORD *fastprm = prm + (g_rcWindow.top * ppitch) + g_rcWindow.left; fasttmp = tmp; for (i = 0; i < 480; i++, fastprm += ppitch, fasttmp += 640) { g_MemCpySys2Vid(fastprm, fasttmp, 1280); // 1280 = 614400 (see below) / 480 } #else // (640*480) = 307200 (words) * 2 = 614400 (bytes) g_MemCpySys2Vid(prm, tmp, 614400); #endif } // unlock the temporary surface and destination surface DDUnlockSurface(lpDDSTmp); DDUnlockSurface(lpDDSPrimary); DDUnlockSurface(lpDDSRef); // blit the actual destination surface to the primary surface so we're sure // the screen is where it should be #ifdef WINDOWED lpDDSPrimary->Blt(&g_rcWindow, lpDDS, &SrcRect, DDBLT_WAIT, NULL); #else lpDDSPrimary->Blt(&DesRect, lpDDS, &SrcRect, DDBLT_WAIT, NULL); #endif // release the temporary and destination surfaces lpDDSTmp->Release(); lpDDSTmp = NULL; lpDDSRef->Release(); lpDDSRef = NULL; }
/******************************************************************** * Function : SimLoop() * Purpose : Performs a single Simulation Loop iteration. Includes * drawing. ********************************************************************/ int SimLoop(void) { static int nFramesPerSecond = 0; static int nFramesSinceLastTick; static DWORD LastTicks = 0; DWORD Ticks; HDC hDC; HFONT hOldFont; char s[80]; int slen; DDSURFACEDESC ddsd; DDBLTFX BltFx; HRESULT ddreturn; /* Perform a single step in our world. */ if (StepWorld(bForwardKey, bBackKey, bLeftKey, bRightKey, nState, nGauge)) { if (lpPrimary->IsLost() == DDERR_SURFACELOST) lpPrimary->Restore(); /* Clear the backbuffer. */ #if CLEARBCKGRND BltFx.dwSize = sizeof(BltFx); BltFx.dwFillColor = 255; ddreturn = lpBackbuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &BltFx); #else ddreturn = DD_OK; #endif if (ddreturn == DD_OK) { /* While this is running, prepare * the drawing. */ if (PrepDrawWorld()) { /* Lock the surface. */ memset(&ddsd, 0, sizeof(DDSURFACEDESC)); ddsd.dwSize = sizeof(ddsd); ddreturn = lpBackbuffer->Lock(NULL, &ddsd, DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR, NULL); if (ddreturn == DD_OK) { DrawWorld((unsigned char *)ddsd.lpSurface, (int)ddsd.lPitch); int nX, nY; static unsigned char dummy; unsigned char ni; ni = 0; for (nY = 0; nY < 16; nY++) for (nX = 0; nX < 16; nX++) { /* Draw a small block at (nX * 3, nY * 3) */ ((unsigned char *)ddsd.lpSurface)[(nY * 3 * ddsd.lPitch) + (nX * 3)] = ni; ((unsigned char *)ddsd.lpSurface)[(nY * 3 * ddsd.lPitch) + (nX * 3 + 1)] = ni; ((unsigned char *)ddsd.lpSurface)[((nY * 3 + 1) * ddsd.lPitch) + (nX * 3)] = ni; ((unsigned char *)ddsd.lpSurface)[((nY * 3 + 1) * ddsd.lPitch) + (nX * 3 + 1)] = ni; ni++; } lpBackbuffer->Unlock(NULL); /* And now write Frames per second. */ /* Increment Frame counter. */ nFramesSinceLastTick++; /* Get system tick count. */ Ticks = GetTickCount(); /* Update fps value every second. */ if (Ticks > (LastTicks + 1000)) { nFramesPerSecond = nFramesSinceLastTick; nFramesSinceLastTick = 0; LastTicks = Ticks; } /* Get a DC to the buffer & write count. */ if (DD_OK == lpBackbuffer->GetDC(&hDC)) { SetBkMode(hDC, TRANSPARENT); hOldFont = SelectObject(hDC, AppFont); /* Build a string for display. */ slen = wsprintf(s, "FPS : %d", nFramesPerSecond); /* And draw the text. */ SetTextColor(hDC, RGB(0,0,0)); SIZE sz; GetTextExtentPoint32(hDC, s, slen, &sz); RECT rc; rc.top = 0; rc.left = 16 * 3; rc.right = 16 * 3 + sz.cx + 10; rc.bottom = sz.cy + 10; DrawFrameControl(hDC, &rc, DFC_BUTTON, DFCS_BUTTONPUSH); TextOut(hDC, 16*3 + 5, 5, s, slen); SelectObject(hDC, hOldFont); lpBackbuffer->ReleaseDC(hDC); } /* Perform required pageflipping to make the surface * we drawed visible. */ ddreturn = lpPrimary->Flip(NULL, DDFLIP_WAIT); if (ddreturn == DD_OK) { return 1; } } } } } return 0; }
/******************************************************************** * Function : WinMain() * Purpose : Mandatory Windows Init function. ********************************************************************/ int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; HWND hwnd; WNDCLASS wc; static char ClassName[] = "ChromeTestingFacility"; DDSURFACEDESC ddsd; DDSCAPS ddscaps; HRESULT ddreturn; int n; // Set all key booleans to FALSE, assume no key is pressed. bForwardKey = FALSE; bBackKey = FALSE; bLeftKey = FALSE; bRightKey = FALSE; nState = 0; nGauge = 0; lpCmdLine = lpCmdLine; hPrevInstance = hPrevInstance; RealTime = 0; /* Start of using spacebar for frameflipping. */ /* Register and realize our display window */ wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = WindowProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, IDI_APPLICATION); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = ClassName; wc.lpszClassName = ClassName; RegisterClass(&wc); /* Initialize our test world. */ if (!InitWorld(XRES, YRES, Colormap)) { return FALSE; } /* Convert the Chrome colormap to a windows colormap. */ for (n = 0; n < 256; n++) { WinColormap[n].peRed = (unsigned char)((Colormap[n] & 0xFF0000) >> 16); WinColormap[n].peGreen = (unsigned char)((Colormap[n] & 0xFF00) >> 8); WinColormap[n].peBlue = (unsigned char)((Colormap[n] & 0xFF)); WinColormap[n].peFlags = 0; } /* Create a full screen window so that GDI won't ever be * called. */ hwnd = CreateWindowEx(WS_EX_TOPMOST, ClassName, ClassName, WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL); if (hwnd == NULL) return FALSE; ShowWindow(hwnd, nCmdShow); UpdateWindow(hwnd); SetFocus(hwnd); ShowCursor(FALSE); /* Remove cursor to prevent GDI from writing. */ /* Instanciate our DirectDraw object */ ddreturn = DirectDrawCreate(NULL, &lpDirectDrawObject, NULL); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } ddreturn = lpDirectDrawObject->SetCooperativeLevel(hwnd, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN| DDSCL_ALLOWMODEX); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } /* Create a palette for the surfaces. */ ddreturn = lpDirectDrawObject->CreatePalette(DDPCAPS_8BIT | DDPCAPS_ALLOW256 | DDPCAPS_INITIALIZE, (LPPALETTEENTRY)WinColormap, &lpPalette, NULL); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } /* Set the video mode to XRESxYRESx8. */ ddreturn = lpDirectDrawObject->SetDisplayMode(XRES, YRES, 8); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } /* Create a default font for the application. */ AppFont = CreateFont(11, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, NONANTIALIASED_QUALITY, VARIABLE_PITCH, "Comic Sans MS"); /* Create the primary surface and one back buffer surface */ ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; ddreturn = lpDirectDrawObject->CreateSurface(&ddsd, &lpPrimary, NULL); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } ddreturn = lpPrimary->SetPalette(lpPalette); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } /* Get a surface pointer to our back buffer. */ ddscaps.dwCaps = DDSCAPS_BACKBUFFER; ddreturn = lpPrimary->GetAttachedSurface(&ddscaps, &lpBackbuffer); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } /* ddreturn = lpBackbuffer->SetPalette(lpPalette); if (ddreturn != DD_OK) { DestroyWindow(hwnd); return FALSE; } */ { /* Clear the background once for both buffers so we don't get anoying flicker effect. */ DDBLTFX BltFx; BltFx.dwSize = sizeof(BltFx); BltFx.dwFillColor = 255; ddreturn = lpBackbuffer->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &BltFx); BltFx.dwSize = sizeof(BltFx); BltFx.dwFillColor = 255; ddreturn = lpPrimary->Blt(NULL, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &BltFx); } while (1) { if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (!GetMessage(&msg, NULL, 0, 0)) return msg.wParam; TranslateMessage(&msg); DispatchMessage(&msg); } else { if (ActiveApp && RealTime) { // Simulation Iteration should go here. // Only do this when running Realtime. SimLoop(); } else { WaitMessage(); } } } }
void UpdateFrame2(HWND hWnd, void* videoMem) { static BYTE phase = 0; HRESULT hRet; LPDIRECTDRAWSURFACE pdds; DDBLTFX ddbltfx; static int cnt = 0; memset(&ddbltfx, 0, sizeof(ddbltfx)); ddbltfx.dwSize = sizeof(ddbltfx); ddbltfx.dwROP = SRCCOPY; if (phase) { pdds = g_pDDSTwo; phase = 0; } else { pdds = g_pDDSOne; phase = 1; } #if 1 DDSURFACEDESC ddsd; ddsd.dwSize = sizeof(ddsd); while (true) { WaitForSingleObject(g_hRefreshScreen, INFINITE); hRet = g_pDDSPrimary->Lock(NULL, &ddsd, DDLOCK_WAITNOTBUSY | DDLOCK_DISCARD | DDLOCK_WRITEONLY, NULL); if (hRet == DD_OK) { //memcpy((char*)ddsd.lpSurface, g_videoMem, (ddsd.dwHeight - 26) * ddsd.lPitch); memcpy((char*)ddsd.lpSurface + ddsd.lPitch * 26, g_videoMem, (ddsd.dwHeight - 26) * ddsd.lPitch); //memcpy((char*)ddsd.lpSurface, videoMem, ddsd.dwHeight * ddsd.lPitch); hRet = g_pDDSPrimary->Unlock(NULL); } } //hRet = g_pDDSPrimary->Blt(NULL, g_pDDSBack, NULL, DDBLT_ROP, &ddbltfx);//dwTransType, NULL); #else while (TRUE) { hRet = g_pDDSBack->Blt(NULL, pdds, NULL, DDBLT_ROP, &ddbltfx); if (hRet == DD_OK) break; if (hRet == DDERR_SURFACELOST) { hRet = RestoreAll(); if (hRet != DD_OK) break; } if (hRet != DDERR_WASSTILLDRAWING) break; Sleep(10); } while (TRUE) { hRet = g_pDDSPrimary->Flip(NULL, 0); if (hRet == DD_OK) break; if (hRet == DDERR_SURFACELOST) { hRet = RestoreAll(); if (hRet != DD_OK) break; } if (hRet != DDERR_WASSTILLDRAWING) break; Sleep(10); } #endif }
PRBool nsWindow::OnPaint(HDC aDC) { #ifdef MOZ_IPC if (mWindowType == eWindowType_plugin) { /** * After we CallUpdateWindow to the child, occasionally a WM_PAINT message * is posted to the parent event loop with an empty update rect. Do a * dummy paint so that Windows stops dispatching WM_PAINT in an inifinite * loop. See bug 543788. */ RECT updateRect; if (!GetUpdateRect(mWnd, &updateRect, FALSE) || (updateRect.left == updateRect.right && updateRect.top == updateRect.bottom)) { PAINTSTRUCT ps; BeginPaint(mWnd, &ps); EndPaint(mWnd, &ps); return PR_TRUE; } PluginInstanceParent* instance = reinterpret_cast<PluginInstanceParent*>( ::GetPropW(mWnd, L"PluginInstanceParentProperty")); if (instance) { instance->CallUpdateWindow(); ValidateRect(mWnd, NULL); return PR_TRUE; } } #endif #ifdef MOZ_IPC // We never have reentrant paint events, except when we're running our RPC // windows event spin loop. If we don't trap for this, we'll try to paint, // but view manager will refuse to paint the surface, resulting is black // flashes on the plugin rendering surface. if (mozilla::ipc::RPCChannel::IsSpinLoopActive() && mPainting) return PR_FALSE; #endif nsPaintEvent willPaintEvent(PR_TRUE, NS_WILL_PAINT, this); DispatchWindowEvent(&willPaintEvent); #ifdef CAIRO_HAS_DDRAW_SURFACE if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_DDRAW16)) { return OnPaintImageDDraw16(); } #endif PRBool result = PR_TRUE; PAINTSTRUCT ps; nsEventStatus eventStatus = nsEventStatus_eIgnore; #ifdef MOZ_XUL if (!aDC && (eTransparencyTransparent == mTransparencyMode)) { // For layered translucent windows all drawing should go to memory DC and no // WM_PAINT messages are normally generated. To support asynchronous painting // we force generation of WM_PAINT messages by invalidating window areas with // RedrawWindow, InvalidateRect or InvalidateRgn function calls. // BeginPaint/EndPaint must be called to make Windows think that invalid area // is painted. Otherwise it will continue sending the same message endlessly. ::BeginPaint(mWnd, &ps); ::EndPaint(mWnd, &ps); aDC = mMemoryDC; } #endif mPainting = PR_TRUE; #ifdef WIDGET_DEBUG_OUTPUT HRGN debugPaintFlashRegion = NULL; HDC debugPaintFlashDC = NULL; if (debug_WantPaintFlashing()) { debugPaintFlashRegion = ::CreateRectRgn(0, 0, 0, 0); ::GetUpdateRgn(mWnd, debugPaintFlashRegion, TRUE); debugPaintFlashDC = ::GetDC(mWnd); } #endif // WIDGET_DEBUG_OUTPUT HDC hDC = aDC ? aDC : (::BeginPaint(mWnd, &ps)); if (!IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) { mPaintDC = hDC; } #ifdef MOZ_XUL PRBool forceRepaint = aDC || (eTransparencyTransparent == mTransparencyMode); #else PRBool forceRepaint = NULL != aDC; #endif nsCOMPtr<nsIRegion> paintRgnWin = GetRegionToPaint(forceRepaint, ps, hDC); if (paintRgnWin && !paintRgnWin->IsEmpty() && mEventCallback) { // generate the event and call the event callback nsPaintEvent event(PR_TRUE, NS_PAINT, this); InitEvent(event); event.region = paintRgnWin; event.rect = nsnull; // Should probably pass in a real region here, using GetRandomRgn // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/clipping_4q0e.asp #ifdef WIDGET_DEBUG_OUTPUT debug_DumpPaintEvent(stdout, this, &event, nsCAutoString("noname"), (PRInt32) mWnd); #endif // WIDGET_DEBUG_OUTPUT nsRefPtr<gfxASurface> targetSurface; #if defined(MOZ_XUL) // don't support transparency for non-GDI rendering, for now if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) && eTransparencyTransparent == mTransparencyMode) { if (mTransparentSurface == nsnull) SetupTranslucentWindowMemoryBitmap(mTransparencyMode); targetSurface = mTransparentSurface; } #endif nsRefPtr<gfxWindowsSurface> targetSurfaceWin; if (!targetSurface && IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) { targetSurfaceWin = new gfxWindowsSurface(hDC); targetSurface = targetSurfaceWin; } #ifdef CAIRO_HAS_D2D_SURFACE if (!targetSurface && IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D)) { if (!mD2DWindowSurface) { mD2DWindowSurface = new gfxD2DSurface(mWnd); } targetSurface = mD2DWindowSurface; } #endif #ifdef CAIRO_HAS_DDRAW_SURFACE nsRefPtr<gfxDDrawSurface> targetSurfaceDDraw; if (!targetSurface && (IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW) || IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW_GL))) { if (!glpDD) { if (!nsWindowGfx::InitDDraw()) { NS_WARNING("DirectDraw init failed; falling back to RENDER_IMAGE_STRETCH24"); gfxWindowsPlatform::GetPlatform()->SetRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24); goto DDRAW_FAILED; } } // create a rect that maps the window in screen space // create a new sub-surface that aliases this one RECT winrect; GetClientRect(mWnd, &winrect); MapWindowPoints(mWnd, NULL, (LPPOINT)&winrect, 2); targetSurfaceDDraw = new gfxDDrawSurface(gpDDSurf.get(), winrect); targetSurface = targetSurfaceDDraw; } #endif DDRAW_FAILED: nsRefPtr<gfxImageSurface> targetSurfaceImage; if (!targetSurface && (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32) || IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24))) { gfxIntSize surfaceSize(ps.rcPaint.right - ps.rcPaint.left, ps.rcPaint.bottom - ps.rcPaint.top); if (!EnsureSharedSurfaceSize(surfaceSize)) { NS_ERROR("Couldn't allocate a shared image surface!"); return NS_ERROR_FAILURE; } // don't use the shared surface directly; instead, create a new one // that just reuses its buffer. targetSurfaceImage = new gfxImageSurface(sSharedSurfaceData.get(), surfaceSize, surfaceSize.width * 4, gfxASurface::ImageFormatRGB24); if (targetSurfaceImage && !targetSurfaceImage->CairoStatus()) { targetSurfaceImage->SetDeviceOffset(gfxPoint(-ps.rcPaint.left, -ps.rcPaint.top)); targetSurface = targetSurfaceImage; } } if (!targetSurface) { NS_ERROR("Invalid RenderMode!"); return NS_ERROR_FAILURE; } nsRefPtr<gfxContext> thebesContext = new gfxContext(targetSurface); thebesContext->SetFlag(gfxContext::FLAG_DESTINED_FOR_SCREEN); if (IsRenderMode(gfxWindowsPlatform::RENDER_DIRECT2D) && paintRgnWin) { PRUint32 rects; paintRgnWin->GetNumRects(&rects); nsRegionRectSet *rectSet = NULL; paintRgnWin->GetRects(&rectSet); for (int i = 0; i < rectSet->mNumRects; i++) { thebesContext->Rectangle( gfxRect( rectSet->mRects[i].x, rectSet->mRects[i].y, rectSet->mRects[i].width, rectSet->mRects[i].height), PR_TRUE); } thebesContext->Clip(); paintRgnWin->FreeRects(rectSet); } #ifdef WINCE thebesContext->SetFlag(gfxContext::FLAG_SIMPLIFY_OPERATORS); #endif // don't need to double buffer with anything but GDI if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) { # if defined(MOZ_XUL) && !defined(WINCE) if (eTransparencyGlass == mTransparencyMode && nsUXThemeData::sHaveCompositor) { thebesContext->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA); } else if (eTransparencyTransparent == mTransparencyMode) { // If we're rendering with translucency, we're going to be // rendering the whole window; make sure we clear it first thebesContext->SetOperator(gfxContext::OPERATOR_CLEAR); thebesContext->Paint(); thebesContext->SetOperator(gfxContext::OPERATOR_OVER); } else #endif { // If we're not doing translucency, then double buffer thebesContext->PushGroup(gfxASurface::CONTENT_COLOR); } } nsCOMPtr<nsIRenderingContext> rc; nsresult rv = mContext->CreateRenderingContextInstance (*getter_AddRefs(rc)); if (NS_FAILED(rv)) { NS_WARNING("CreateRenderingContextInstance failed"); return PR_FALSE; } rv = rc->Init(mContext, thebesContext); if (NS_FAILED(rv)) { NS_WARNING("RC::Init failed"); return PR_FALSE; } event.renderingContext = rc; result = DispatchWindowEvent(&event, eventStatus); event.renderingContext = nsnull; #ifdef MOZ_XUL if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI) && eTransparencyTransparent == mTransparencyMode) { // Data from offscreen drawing surface was copied to memory bitmap of transparent // bitmap. Now it can be read from memory bitmap to apply alpha channel and after // that displayed on the screen. UpdateTranslucentWindow(); } else #endif #ifdef CAIRO_HAS_D2D_SURFACE if (result) { if (mD2DWindowSurface) { mD2DWindowSurface->Present(); } } #endif if (result) { if (IsRenderMode(gfxWindowsPlatform::RENDER_GDI)) { // Only update if DispatchWindowEvent returned TRUE; otherwise, nothing handled // this, and we'll just end up painting with black. thebesContext->PopGroupToSource(); thebesContext->SetOperator(gfxContext::OPERATOR_SOURCE); thebesContext->Paint(); } else if (IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW) || IsRenderMode(gfxWindowsPlatform::RENDER_DDRAW_GL)) { #ifdef CAIRO_HAS_DDRAW_SURFACE // blit with direct draw HRESULT hr = glpDDClipper->SetHWnd(0, mWnd); #ifdef DEBUG if (FAILED(hr)) DDError("SetHWnd", hr); #endif // blt from the affected area from the window back-buffer to the // screen-relative coordinates of the window paint area RECT dst_rect = ps.rcPaint; MapWindowPoints(mWnd, NULL, (LPPOINT)&dst_rect, 2); hr = glpDDPrimary->Blt(&dst_rect, gpDDSurf->GetDDSurface(), &dst_rect, DDBLT_WAITNOTBUSY, NULL); #ifdef DEBUG if (FAILED(hr)) DDError("SetHWnd", hr); #endif #endif } else if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24) || IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH32)) { gfxIntSize surfaceSize = targetSurfaceImage->GetSize(); // Just blit this directly BITMAPINFOHEADER bi; memset(&bi, 0, sizeof(BITMAPINFOHEADER)); bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = surfaceSize.width; bi.biHeight = - surfaceSize.height; bi.biPlanes = 1; bi.biBitCount = 32; bi.biCompression = BI_RGB; if (IsRenderMode(gfxWindowsPlatform::RENDER_IMAGE_STRETCH24)) { // On Windows CE/Windows Mobile, 24bpp packed-pixel sources // seem to be far faster to blit than 32bpp (see bug 484864). // So, convert the bits to 24bpp by stripping out the unused // alpha byte. 24bpp DIBs also have scanlines that are 4-byte // aligned though, so that must be taken into account. int srcstride = surfaceSize.width*4; int dststride = surfaceSize.width*3; dststride = (dststride + 3) & ~3; // Convert in place for (int j = 0; j < surfaceSize.height; ++j) { unsigned int *src = (unsigned int*) (targetSurfaceImage->Data() + j*srcstride); unsigned int *dst = (unsigned int*) (targetSurfaceImage->Data() + j*dststride); // go 4 pixels at a time, since each 4 pixels // turns into 3 DWORDs when converted into BGR: // BGRx BGRx BGRx BGRx -> BGRB GRBG RBGR // // However, since we're dealing with little-endian ints, this is actually: // xRGB xrgb xRGB xrgb -> bRGB GBrg rgbR int width_left = surfaceSize.width; while (width_left >= 4) { unsigned int a = *src++; unsigned int b = *src++; unsigned int c = *src++; unsigned int d = *src++; *dst++ = (a & 0x00ffffff) | (b << 24); *dst++ = ((b & 0x00ffff00) >> 8) | (c << 16); *dst++ = ((c & 0x00ff0000) >> 16) | (d << 8); width_left -= 4; } // then finish up whatever number of pixels are left, // using bytes. unsigned char *bsrc = (unsigned char*) src; unsigned char *bdst = (unsigned char*) dst; switch (width_left) { case 3: *bdst++ = *bsrc++; *bdst++ = *bsrc++; *bdst++ = *bsrc++; bsrc++; case 2: *bdst++ = *bsrc++; *bdst++ = *bsrc++; *bdst++ = *bsrc++; bsrc++; case 1: *bdst++ = *bsrc++; *bdst++ = *bsrc++; *bdst++ = *bsrc++; bsrc++; case 0: break; } } bi.biBitCount = 24; } StretchDIBits(hDC, ps.rcPaint.left, ps.rcPaint.top, surfaceSize.width, surfaceSize.height, 0, 0, surfaceSize.width, surfaceSize.height, targetSurfaceImage->Data(), (BITMAPINFO*) &bi, DIB_RGB_COLORS, SRCCOPY); } }
void dd_Window::flip_win() { RECT r; if(!bVisible) return; if(!img) return; //convert the image format if necessary if(DesktopBPP != vid_bpp) { image* temp = ImageAdapt(img, vid_bpp, DesktopBPP); memcpy((quad*)dx_win_bsd.lpSurface,temp->data,img->width*img->height*DesktopBPP/8); delete temp; } GetClientRect(hwnd, &r); int xres = img->width; int yres = img->height; //disable letterboxing if(0) { ClientToScreen(hwnd, (POINT *)&r); ClientToScreen(hwnd, (POINT *)&r + 1); dx_win_ps->Blt(&r, dx_win_bs, 0, 0, 0); return; } //----- //grump calculations int w = r.right - r.left; int h = r.bottom - r.top; //will contain w/h to render at int iw,ih; float ratio = (float)w / xres; float ph = ratio * (float)yres; if((int)ph>h) { ratio = (float)h / (float)yres; ih = h; iw = (int)(ratio * (float)xres); } else { ih = (int)ph; iw = w; } //create a client rectangle with the render destination properly set, possibly in the middle of the client area r.left += (w-iw)/2; r.top += (h-ih)/2; r.right = r.left + iw; r.bottom = r.top + ih; ClientToScreen(hwnd, (POINT *)&r); ClientToScreen(hwnd, (POINT *)&r + 1); //render the screen dx_win_ps->SetClipper(clipper); dx_win_ps->Blt(&r, dx_win_bs, 0, DDBLT_WAIT, 0); //draw black letterbox bars if(iw != w || ih != h) { RECT rClient; GetClientRect(hwnd, &rClient); ClientToScreen(hwnd, (POINT *)&rClient); ClientToScreen(hwnd, (POINT *)&rClient + 1); DDBLTFX ddbltfx; memset(&ddbltfx, 0, sizeof(DDBLTFX)); ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwFillColor = 0; if(iw < w) { RECT rBlit; rBlit.left = rClient.left; rBlit.right = r.left; rBlit.top = r.top; rBlit.bottom = r.bottom; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); rBlit.left = r.right; rBlit.right = rClient.right; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } else { RECT rBlit; rBlit.left = r.left; rBlit.right = r.right; rBlit.top = rClient.top; rBlit.bottom = r.top; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); rBlit.top = r.bottom; rBlit.bottom = rClient.bottom; dx_win_ps->Blt(&rBlit, 0, 0, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx); } } }
/* * AlphaTransition: * Does an alpha transition from Src -> Des */ void AlphaTransition(LPDIRECTDRAWSURFACE Src, LPDIRECTDRAWSURFACE Des) { long i; // index into surfaces int alpha; // Holds current alpha value int dpitch, spitch, tpitch, ppitch; // surface pitch for destination, source, temp surfaces WORD *AlphaPTR; // pointer to the current AlphaMap level (Source) WORD *InvAlphaPTR; // the inverted pointer to the current AlphaMap level (Destination) WORD *src, *des, *tmp, *prm; WORD *fastsrc, *fastdes, *fasttmp; // Surface memory pointer for source, destination, and temporary surfaces RECT SrcRect, DesRect; // Source and destination rectangles // Set source and destination rectangles to the screen size SetRect(&SrcRect, 0, 0, 640, 480); SetRect(&DesRect, 0, 0, 640, 480); // Create the three surface we are going to use lpDDSTmp = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // The temporary surface lpDDSSrc = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // The source surface lpDDSDes = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // The destination surface // Blit the transition surfaces into out newly created source/destination surfaces lpDDSSrc->Blt(&DesRect, Src, &SrcRect, DDBLT_WAIT, NULL); // Blit Src->lpDDSSrc lpDDSDes->Blt(&DesRect, Des, &SrcRect, DDBLT_WAIT, NULL); // Blit Des->lpDDSDes // lock all three surfaces temporary, source, and destination des = DDLockSurface(lpDDSDes, &dpitch); src = DDLockSurface(lpDDSSrc, &spitch); tmp = DDLockSurface(lpDDSTmp, &tpitch); prm = DDLockSurface(lpDDSPrimary, &ppitch); // for each alpha level for (alpha = 31; alpha >= 0; alpha--) { // set AlphaMap pointers to appropriate levels AlphaPTR = PixelShade[alpha]; InvAlphaPTR = PixelShade[31 - alpha]; // "reset" the *fast* pointers to the locked surfaces fastsrc = src; fastdes = des; fasttmp = tmp; // loop through every pixel for (i = 0; i < 307200; i++, fasttmp++, fastsrc++, fastdes++) { // Set the new pixel value in temporary surface *fasttmp = AlphaPTR[*fastsrc] + InvAlphaPTR[*fastdes]; } // copy the temp surface to the primary surface // method depends on windowed/full screen #ifdef WINDOWED WORD *fastprm = prm + (g_rcWindow.top * ppitch) + g_rcWindow.left; fasttmp = tmp; for (i = 0; i < 480; i++, fastprm += ppitch, fasttmp += 640) { g_MemCpySys2Vid(fastprm, fasttmp, 1280); // 1280 = 614400 (see below) / 480 } #else // (640*480) = 307200 (words) * 2 = 614400 (bytes) g_MemCpySys2Vid(prm, tmp, 614400); #endif } // Unlock our temporary, source, and destination surfaces DDUnlockSurface(lpDDSPrimary); DDUnlockSurface(lpDDSTmp); DDUnlockSurface(lpDDSDes); DDUnlockSurface(lpDDSSrc); // Release or temporary, source, and destination surfaces lpDDSTmp->Release(); lpDDSTmp = NULL; lpDDSSrc->Release(); lpDDSSrc = NULL; lpDDSDes->Release(); lpDDSDes = NULL; }
/* * FadeToBlack: * Fades a screen to black */ void FadeToBlack(void) { RECT SrcRect, DesRect; // Source and Destination Rectangles WORD *tmp; // temporary surface memory pointer WORD *ref; WORD *prm; WORD *fastref, *fasttmp; int c, tpitch, rpitch, ppitch; // incrementing variable, temporary surface pitch long i; // another incrementing variable WORD *shade; // Set source and destination rectangles to size of screen SetRect(&SrcRect, 0, 0, 640, 480); SetRect(&DesRect, 0, 0, 640, 480); // Create our temporary surface lpDDSTmp = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); lpDDSRef = DDCreateSurface(640, 480, DDSCAPS_SYSTEMMEMORY); // Blit our primary surface into our temporary SYSTEM MEMORY surface #ifdef WINDOWED lpDDSRef->Blt(&DesRect, lpDDSPrimary, &g_rcWindow, DDBLT_WAIT, NULL); #else lpDDSRef->Blt(&DesRect, lpDDSPrimary, &SrcRect, DDBLT_WAIT, NULL); #endif // Lock our temporary surface tmp = DDLockSurface(lpDDSTmp, &tpitch); ref = DDLockSurface(lpDDSRef, &rpitch); prm = DDLockSurface(lpDDSPrimary, &ppitch); for (c = 30; c >= 1; c--) { // get a pointer indexed to the start of the current shade level shade = PixelShade[c]; // "reset" our *fast* surface pointers fastref = ref; fasttmp = tmp; // for every pixel on the screen (640*480=307200) for (i = 0; i < 307200; i++, fasttmp++, fastref++) { // new pixel please.... *fasttmp = shade[*fastref]; } // copy the temp surface to the primary surface // method depends on windowed/full screen #ifdef WINDOWED WORD *fastprm = prm + (g_rcWindow.top * ppitch) + g_rcWindow.left; fasttmp = tmp; for (i = 0; i < 480; i++, fastprm += ppitch, fasttmp += 640) { g_MemCpySys2Vid(fastprm, fasttmp, 1280); // 1280 = 614400 (see below) / 480 } #else // (640*480) = 307200 (words) * 2 = 614400 (bytes) g_MemCpySys2Vid(prm, tmp, 614400); #endif } // unlock our temporary surface DDUnlockSurface(lpDDSTmp); DDUnlockSurface(lpDDSRef); DDUnlockSurface(lpDDSPrimary); // just to make sure the screen is black when this routine is over, fill it with 0 DDFillSurface(lpDDSPrimary, 0); // release our temporary surface lpDDSTmp->Release(); lpDDSTmp = NULL; lpDDSRef->Release(); lpDDSRef = NULL; }