HRESULT BltFastDDSurfaceUsingSoftware( LPDIRECTDRAWSURFACE2 pDestSurface, INT32 uiX, INT32 uiY, LPDIRECTDRAWSURFACE2 pSrcSurface, LPRECT pSrcRect, UINT32 uiTrans ) { DDSURFACEDESC SurfaceDescription; UINT32 uiDestPitchBYTES, uiSrcPitchBYTES; UINT8 *pDestBuf, *pSrcBuf; HRESULT ReturnCode; DDCOLORKEY ColorKey; UINT16 us16BPPColorKey; // Lock surfaces DDLockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL, &SurfaceDescription, 0, NULL); uiDestPitchBYTES = SurfaceDescription.lPitch; pDestBuf = SurfaceDescription.lpSurface; // Lock surfaces DDLockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL, &SurfaceDescription, 0, NULL); uiSrcPitchBYTES = SurfaceDescription.lPitch; pSrcBuf = SurfaceDescription.lpSurface; if ( uiTrans == DDBLTFAST_NOCOLORKEY ) { Blt16BPPTo16BPP( (UINT16 *)pDestBuf, uiDestPitchBYTES, (UINT16 *)pSrcBuf, uiSrcPitchBYTES, uiX , uiY, pSrcRect->left , pSrcRect->top, ( pSrcRect->right - pSrcRect->left ), ( pSrcRect->bottom - pSrcRect->top ) ); } else if ( uiTrans == DDBLTFAST_SRCCOLORKEY ) { // Get 16 bpp color key..... ReturnCode = IDirectDrawSurface2_GetColorKey( pSrcSurface, DDCKEY_SRCBLT, &ColorKey); if (ReturnCode == DD_OK) { us16BPPColorKey = (UINT16)ColorKey.dwColorSpaceLowValue; Blt16BPPTo16BPPTrans( (UINT16 *)pDestBuf, uiDestPitchBYTES, (UINT16 *)pSrcBuf, uiSrcPitchBYTES, uiX , uiY, pSrcRect->left , pSrcRect->top, ( pSrcRect->right - pSrcRect->left ), ( pSrcRect->bottom - pSrcRect->top ), us16BPPColorKey ); } } else { // Not supported..... } DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL ); DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL ); return( DD_OK ); }
BOOLEAN BinkPollFlics(void) { UINT32 uiCount; BOOLEAN fFlicStatus=FALSE; DDSURFACEDESC SurfaceDescription; BINKFLIC *pBink=NULL; UINT32 uiCopyToBufferFlags = guiBinkPixelFormat; //loop through all the open flics for(uiCount=0; uiCount < BINK_NUM_FLICS; uiCount++) { pBink = &BinkList[uiCount]; if( pBink->uiFlags & BINK_FLIC_PLAYING ) { fFlicStatus = TRUE; //do we still have to wait for the frame to be finished being displayed if( !( BinkWait( pBink->BinkHandle ) ) ) { DDLockSurface( pBink->lpDDS, NULL, &SurfaceDescription, 0, NULL); BinkDoFrame( pBink->BinkHandle ); BinkCopyToBuffer( pBink->BinkHandle, SurfaceDescription.lpSurface, SurfaceDescription.lPitch, pBink->BinkHandle->Height, pBink->uiLeft, pBink->uiTop, uiCopyToBufferFlags ); DDUnlockSurface( pBink->lpDDS, SurfaceDescription.lpSurface); // Check to see if the flic is done the last frame if( pBink->BinkHandle->FrameNum == ( pBink->BinkHandle->Frames-1 ) ) { // If flic is looping, reset frame to 0 if( pBink->uiFlags & BINK_FLIC_LOOP) { BinkGoto( pBink->BinkHandle, 0, 0 ); } else if( pBink->uiFlags & BINK_FLIC_AUTOCLOSE) { BinkCloseFlic( pBink ); } } else { BinkNextFrame( BinkList[uiCount].BinkHandle ); } } } } return( fFlicStatus ); }
HRESULT BltDDSurfaceUsingSoftware( LPDIRECTDRAWSURFACE2 pDestSurface, LPRECT pDestRect, LPDIRECTDRAWSURFACE2 pSrcSurface, LPRECT pSrcRect, UINT32 uiFlags, LPDDBLTFX pDDBltFx ) { DDSURFACEDESC SurfaceDescription; UINT32 uiDestPitchBYTES, uiSrcPitchBYTES; UINT8 *pDestBuf, *pSrcBuf; HRESULT ReturnCode; DDCOLORKEY ColorKey; UINT16 us16BPPColorKey; // Lock surfaces DDLockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL, &SurfaceDescription, 0, NULL); uiDestPitchBYTES = SurfaceDescription.lPitch; pDestBuf = SurfaceDescription.lpSurface; if ( pSrcSurface != NULL ) { // Lock surfaces DDLockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL, &SurfaceDescription, 0, NULL); uiSrcPitchBYTES = SurfaceDescription.lPitch; pSrcBuf = SurfaceDescription.lpSurface; } if ( pSrcRect != NULL && ( ( pSrcRect->right - pSrcRect->left ) != ( pDestRect->right - pDestRect->left ) || ( pSrcRect->bottom - pSrcRect->top ) != ( pDestRect->bottom - pDestRect->top ) ) ) { DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL ); if ( pSrcSurface != NULL ) { DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL ); } // Fall back to DD IDirectDrawSurface2_Blt( pDestSurface, pDestRect, pSrcSurface, pSrcRect, uiFlags, pDDBltFx ); return( DD_OK ); } else if ( uiFlags == DDBLT_WAIT ) { // Lock surfaces DDLockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL, &SurfaceDescription, 0, NULL); uiSrcPitchBYTES = SurfaceDescription.lPitch; pSrcBuf = SurfaceDescription.lpSurface; Blt16BPPTo16BPP( (UINT16 *)pDestBuf, uiDestPitchBYTES, (UINT16 *)pSrcBuf, uiSrcPitchBYTES, pDestRect->left , pDestRect->top, pSrcRect->left , pSrcRect->top, ( pSrcRect->right - pSrcRect->left ), ( pSrcRect->bottom - pSrcRect->top ) ); } else if ( uiFlags & DDBLT_KEYSRC ) { // Get 16 bpp color key..... ReturnCode = IDirectDrawSurface2_GetColorKey( pSrcSurface, DDCKEY_SRCBLT, &ColorKey); if (ReturnCode == DD_OK) { us16BPPColorKey = (UINT16)ColorKey.dwColorSpaceLowValue; Blt16BPPTo16BPPTrans( (UINT16 *)pDestBuf, uiDestPitchBYTES, (UINT16 *)pSrcBuf, uiSrcPitchBYTES, pDestRect->left , pDestRect->top, pSrcRect->left , pSrcRect->top, ( pSrcRect->right - pSrcRect->left ), ( pSrcRect->bottom - pSrcRect->top ), us16BPPColorKey ); } } else if ( uiFlags & DDBLT_COLORFILL ) { // do color fill here... FillRect16BPP( (UINT16 *)pDestBuf, uiDestPitchBYTES, pDestRect->left, pDestRect->top, pDestRect->right, pDestRect->bottom, (UINT16)pDDBltFx->dwFillColor ); } else { // Not supported..... } DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pDestSurface, NULL ); if ( pSrcSurface != NULL ) { DDUnlockSurface( (LPDIRECTDRAWSURFACE2)pSrcSurface, NULL ); } return( DD_OK ); }
/* * 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; }
/* * 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; }
/* * 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; }