1
0
mirror of https://github.com/DxWnd/DxWnd.reloaded synced 2024-12-30 09:25:35 +01:00
DxWnd.reloaded/dll/ddblit.cpp
gho tik 0e42098a3d v2_04_14_src
Former-commit-id: 7fc0c92fb4c1f9dc744aefc42d4acaf08de38d85
2017-03-06 11:50:18 -05:00

483 lines
19 KiB
C++

#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <ddraw.h>
#include "dxwnd.h"
#include "dxwcore.hpp"
#include "stdio.h"
#include "hddraw.h"
#include "dxhelper.h"
extern LPDIRECTDRAWSURFACE lpDDSEmu_Prim;
extern BOOL bVSyncDone;
extern LPDIRECTDRAW lpPrimaryDD;
extern Blt_Type pBlt;
extern ReleaseS_Type pReleaseSMethod(int);
extern CreateSurface1_Type pCreateSurface1;
extern CreateSurface1_Type pCreateSurface2;
extern CreateSurface1_Type pCreateSurface3;
extern CreateSurface2_Type pCreateSurface4;
extern CreateSurface2_Type pCreateSurface7;
extern Unlock4_Type pUnlockMethod(int);
extern HDC hFlippedDC;
extern BOOL bFlippedDC;
extern ReleaseDC_Type pReleaseDC1;
extern ReleaseDC_Type pReleaseDC2;
extern ReleaseDC_Type pReleaseDC3;
extern ReleaseDC_Type pReleaseDC4;
extern ReleaseDC_Type pReleaseDC7;
extern void BlitError(HRESULT, LPRECT, LPRECT, int);
extern void BlitTrace(char *, LPRECT, LPRECT, int);
extern void DescribeSurface(LPDIRECTDRAWSURFACE, int, char *, int);
extern void TextureHandling(LPDIRECTDRAWSURFACE, int);
extern GetSurfaceDesc2_Type pGetSurfaceDescMethod();
extern GetSurfaceDesc2_Type GetSurfaceDescMethod();
extern Blt_Type pBltMethod();
static HRESULT sBltNoPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx)
{
RECT srcrect;
HRESULT res;
BOOL FromScreen;
FromScreen=dxwss.IsAPrimarySurface(lpddssrc);
// make a working copy of srcrect if not NULL
if (lpsrcrect) srcrect=*lpsrcrect;
// when blitting from a primary surface on screen (that is in non emulated mode), correct offsets
// You should take account also for scaled primary surfaces, but that would be a hard task:
// a reduced primary surface (in not-emulated mode) would bring quality loss!!!
// v2.1.83: BLITFROMBACKBUFFER mode, let you chose to blit from backbuffer, where the surface size
// is fixed no matter how the window/primary surface is scaled.
// In "The Sims" there is no quality loss, but some scrolling artifact.
//if(lpsrcrect && FromScreen){
if(FromScreen){
if ((dxw.dwFlags1 & EMULATESURFACE) || (dxw.dwFlags1 & EMULATEBUFFER)){
if(dxw.dwFlags1 & BLITFROMBACKBUFFER){
LPDIRECTDRAWSURFACE lpDDSBack;
lpDDSBack = dxwss.GetBackBufferSurface();
if(lpDDSBack) lpddssrc=lpDDSBack;
}
}
else {
if(dxw.dwFlags1 & BLITFROMBACKBUFFER){
LPDIRECTDRAWSURFACE lpDDSBack;
lpDDSBack = dxwss.GetBackBufferSurface();
if(lpDDSBack) lpddssrc=lpDDSBack;
}
else{
srcrect=dxw.MapWindowRect(lpsrcrect);
}
}
}
if (IsDebug) BlitTrace("NOPRIM", lpsrcrect, lpdestrect, __LINE__);
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
// Blitting compressed data may work to screen surfaces only. In this case, it may be worth
// trying blitting directly to lpDDSEmu_Prim: it makes DK2 intro movies working.
// Wrong guess!!! The cause was not compression, but simply a pixelformat mismatch. Better
// configure things properly and avoid this branch.
switch(res){
// commented out: it was the cause of the "Divine Divinity" flickering.
// commented in?: it seems useful in "Axis and Allies"....
//case DDERR_UNSUPPORTED:
// if (dxw.dwFlags1 & EMULATESURFACE){
// RECT targetrect;
// if (IsDebug) BlitTrace("UNSUPP", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__);
// targetrect = dxw.MapWindowRect(lpdestrect);
// res=(*pBlt)(lpDDSEmu_Prim, &targetrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
// }
// break;
case DDERR_SURFACEBUSY:
if (lpsrcrect) srcrect=*lpsrcrect;
(*pUnlockMethod(dxversion))(lpdds, NULL);
if (lpddssrc) (*pUnlockMethod(dxversion))(lpddssrc, NULL);
if (IsDebug) BlitTrace("BUSY", lpsrcrect ? &srcrect : NULL, lpdestrect, __LINE__);
res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_WAIT, lpddbltfx);
break;
case DDERR_UNSUPPORTED:
// to be fixed: parameters coming from BltFast in Star Defender 1 are not compatible with Blt transformation, so clear all....
if(dwflags & (DDBLT_KEYDEST|DDBLT_KEYSRC)){
#if 1
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, 0, 0);
#else
DDBLTFX ddbltfx;
memset(&ddbltfx, 0, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
if(dwflags & DDBLT_KEYDEST) ddbltfx.dwROP |= DDCKEYCAPS_DESTBLT;
if(dwflags & DDBLT_KEYSRC ) ddbltfx.dwROP |= DDCKEYCAPS_SRCBLT;
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags|DDBLT_ROP, &ddbltfx);
#endif
}
break;
case DDERR_SURFACELOST:
lpdds->Restore();
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect ? &srcrect : NULL, dwflags, lpddbltfx);
OutTraceDW("Blt SURFACELOST RETRY: ret=%x(%s)\n", res, ExplainDDError(res));
break;
default:
break;
}
if (res) BlitError(res, &srcrect, lpdestrect, __LINE__);
if(IsDebug) {
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
}
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=0;
if(dxw.dwFlags5 & TEXTUREMASK) {
// Texture Handling on Blt
TextureHandling(lpdds, dxversion);
}
return res;
}
static HRESULT sBltToPrimary(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping)
{
HRESULT res;
RECT destrect, emurect;
extern PrimaryBlt_Type pPrimaryBlt;
// handle minimized states
if(!dxw.IsVisible) return DD_OK;
// check coordinates
dxw.UpdateDesktopCoordinates();
// debug suppressions
if(isFlipping){
if(dxw.dwFlags3 & NODDRAWFLIP) return DD_OK;
}
else {
if(dxw.dwFlags3 & NODDRAWBLT) return DD_OK;
}
// v2.03.48: on WinXP it may happen (reported by Cloudstr) that alt tabbing produces
// bad blit attempts where the client coordinates get the (-32000,-32000) - (-32000,-32000)
// value. In such cases, it's adviseable to simulate an OK return code without attempting
// any blit operation!
if(lpdestrect && (lpdestrect->left == -32000)) return DD_OK; // no blit on invisible window
#ifdef ONEPIXELFIX
if (lpdestrect){
if ((lpdestrect->top == 0) && (lpdestrect->bottom == dxw.GetScreenHeight() -1)) lpdestrect->bottom = dxw.GetScreenHeight();
if ((lpdestrect->left == 0) && (lpdestrect->right == dxw.GetScreenWidth() -1)) lpdestrect->right = dxw.GetScreenWidth();
}
if (lpsrcrect){
if ((lpsrcrect->top == 0) && (lpsrcrect->bottom == dxw.GetScreenHeight() -1)) lpsrcrect->bottom = dxw.GetScreenHeight();
if ((lpsrcrect->left == 0) && (lpsrcrect->right == dxw.GetScreenWidth() -1)) lpsrcrect->right = dxw.GetScreenWidth();
}
#endif
// seems necessary to "cure" the "FIFA 2000" soccer game in hw accelerated graphics, when the Unlock() method
// receives RECT coordinates with big positive or negative numbers!
// v2.03.94fx1: "FIFA2002" is ok with Unlock rect set to Lock previous value, but other games ("Aztec Wars", ...)
// require some software clipping when moving the cursor outside the window or similar cases
if(lpdestrect){
if(lpdestrect->top < 0) lpdestrect->top = 0;
if(lpdestrect->top > (LONG)dxw.GetScreenHeight()) lpdestrect->top = dxw.GetScreenHeight();
if(lpdestrect->left < 0) lpdestrect->left = 0;
if(lpdestrect->left > (LONG)dxw.GetScreenWidth()) lpdestrect->left = (LONG)dxw.GetScreenWidth();
if(lpdestrect->bottom > (LONG)dxw.GetScreenHeight()) lpdestrect->bottom = dxw.GetScreenHeight();
if(lpdestrect->right > (LONG)dxw.GetScreenWidth()) lpdestrect->right = dxw.GetScreenWidth();
if(lpdestrect->bottom < lpdestrect->top) lpdestrect->bottom = lpdestrect->top;
if(lpdestrect->right < lpdestrect->left) lpdestrect->right = lpdestrect->left;
}
if(dxw.dwFlags5 & QUARTERBLT){
BOOL QuarterUpdate;
QuarterUpdate = lpdestrect ?
(((lpdestrect->bottom - lpdestrect->top) * (lpdestrect->right - lpdestrect->left)) > ((LONG)(dxw.GetScreenHeight() * dxw.GetScreenWidth()) >> 2))
:
TRUE;
if(QuarterUpdate) if(dxw.HandleFPS()) return DD_OK;
}
else
if(dxw.HandleFPS()) return DD_OK;
if(dxw.dwFlags5 & NOBLT) return DD_OK;
destrect=dxw.MapWindowRect(lpdestrect);
OutTraceB("DESTRECT=(%d,%d)-(%d,%d) Screen=(%dx%d)\n",
destrect.left, destrect.top, destrect.right, destrect.bottom,
dxw.GetScreenWidth(), dxw.GetScreenHeight());
//if(!(lpddssrc || (dwflags & DDBLT_COLORFILL))) {
if((lpddssrc==0) && !(dwflags & DDBLT_COLORFILL)){
lpddssrc = dxwss.GetBackBufferSurface();
OutTraceDW("Flip: setting flip chain to lpdds=%x\n", lpddssrc);
}
// =========================
// Blit to primary direct or fullscreen surface
// =========================
if(!dxw.IsEmulated){
res=DD_OK;
if((dxw.dwFlags1 & SAVELOAD) || (dxw.dwFlags8 & FORCEVSYNC)) {
HRESULT res2;
if(!bVSyncDone){
if(res2=lpPrimaryDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN , 0))
OutTraceE("WaitForVerticalBlank ERROR: res=%x\n", res2);
}
bVSyncDone = FALSE;
}
if(dxw.Windowize) lpdestrect = &destrect;
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
if (lpdds != lpddssrc) {
dxw.ShowOverlay(lpddssrc);
if (IsDebug) BlitTrace("PRIM-NOEMU", lpsrcrect, lpdestrect, __LINE__);
res=(*pPrimaryBlt)(dxversion, pBlt, lpdds, lpdestrect, lpddssrc, lpsrcrect, lpddbltfx);
//res=(*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
}
if(res){
BlitError(res, lpsrcrect, lpdestrect, __LINE__);
if(IsDebug) {
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
}
// Try to handle HDC lock concurrency....
if(res==DDERR_SURFACEBUSY){
(*pUnlockMethod(dxversion))(lpdds, NULL);
if(lpddssrc) (*pUnlockMethod(dxversion))(lpdds, NULL);
if (IsDebug) BlitTrace("BUSY", lpsrcrect, lpdestrect, __LINE__);
res= (*pBlt)(lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
if (res) BlitError(res, lpsrcrect, lpdestrect, __LINE__);
}
// Try to handle DDBLT_KEYSRC on primary surface
if((res==DDERR_INVALIDPARAMS) && (dwflags & DDBLT_KEYSRC)){
// to do: handle possible situations with surface 2 / 4 / 7 types
DDSURFACEDESC2 ddsd;
LPDIRECTDRAWSURFACE2 lpddsTmp;
extern CreateSurface2_Type pCreateSurfaceMethod(int);
if (IsDebug) BlitTrace("KEYSRC", lpsrcrect, lpdestrect, __LINE__);
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = (dxversion < 4) ? sizeof(DDSURFACEDESC) : sizeof(DDSURFACEDESC2);
(*pGetSurfaceDescMethod())((LPDIRECTDRAWSURFACE2)lpddssrc, &ddsd);
res=(*pCreateSurfaceMethod(dxversion))(lpPrimaryDD, &ddsd, (LPDIRECTDRAWSURFACE *)&lpddsTmp, NULL);
if(res) OutTraceE("CreateSurface: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
// copy background
res= (*pBlt)((LPDIRECTDRAWSURFACE)lpddsTmp, lpsrcrect, lpdds, lpdestrect, DDBLT_WAIT, NULL);
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
// overlay texture
res= (*pBlt)((LPDIRECTDRAWSURFACE)lpddsTmp, lpsrcrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
// copy back to destination
res= (*pBlt)(lpdds, lpdestrect, (LPDIRECTDRAWSURFACE)lpddsTmp, lpsrcrect, DDBLT_WAIT, lpddbltfx);
if(res) OutTraceE("Blt: ERROR %x(%s) at %d", res, ExplainDDError(res), __LINE__);
if (res) BlitError(res, lpsrcrect, lpdestrect, __LINE__);
(*pReleaseSMethod(dxversion))((LPDIRECTDRAWSURFACE)lpddsTmp);
}
if(res==DDERR_SURFACELOST){
lpdds->Restore();
res=(*pPrimaryBlt)(dxversion, pBlt, lpdds, lpdestrect, lpddssrc, lpsrcrect, lpddbltfx);
OutTraceDW("Blt SURFACELOST RETRY: ret=%x(%s) at %d\n", res, ExplainDDError(res), __LINE__);
}
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
}
return res;
}
// ... else blitting on emulated surface
// =========================
// Blit/Flip to emulated primary surface
// =========================
if(dxw.dwFlags5 & GDIMODE){
extern void BlitToWindow(HWND, LPDIRECTDRAWSURFACE);
if((dxw.dwFlags1 & SAVELOAD) || (dxw.dwFlags8 & FORCEVSYNC)){
HRESULT res2;
if(!bVSyncDone){
if(res2=lpPrimaryDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN , 0))
OutTraceE("WaitForVerticalBlank ERROR: res=%x\n", res2);
}
bVSyncDone = FALSE;
}
BlitToWindow(dxw.GethWnd(), lpddssrc);
return DD_OK;
}
if (lpdestrect){
emurect=*lpdestrect;
}
else{
// emurect: emulated rect is full surface (dwWidth x dwHeight)
emurect.left = 0;
emurect.top = 0;
emurect.right = dxw.GetScreenWidth();
emurect.bottom = dxw.GetScreenHeight();
}
res=DD_OK;
// blit only when source and dest surface are different. Should make ScreenRefresh faster.
if (lpdds != lpddssrc){
if (IsDebug) BlitTrace("SRC2EMU", &emurect, &destrect, __LINE__);
if(destrect.top == -32000) return DD_OK; // happens when window is minimized & do not notify on task switch ...
if(lpdds->IsLost()) lpdds->Restore(); // lpDDSEmu_Back could get lost .....
res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
}
if (res) {
BlitError(res, lpsrcrect, &emurect, __LINE__);
DescribeSurface(lpdds, 0, "[DST]" , __LINE__);
if (lpddssrc) DescribeSurface(lpddssrc, 0, "[SRC]" , __LINE__); // lpddssrc could be NULL!!!
/*
Dungeon Keeper II intro movies bug ....
it seems that you can't blit from compressed or different surfaces in memory,
while the operation COULD be supported to video. As a mater of fact, it DOES
work on my PC. The error code is DDERR_UNSUPPORTED.
v2.02.98: The same thing happens with "New York Racer", but with DDERR_EXCEPTION error code.
V2.03.15: The same thing happens with "Silent Hunter III", but with DDERR_INVALIDRECT error code.
*/
if((res==DDERR_UNSUPPORTED) || (res==DDERR_EXCEPTION) || (res==DDERR_INVALIDRECT)){
//RECT targetrect;
dxw.ShowOverlay(lpddssrc);
if (IsDebug) BlitTrace("UNSUPP", &emurect, &destrect, __LINE__);
//targetrect=dxw.MapWindowRect(&destrect); // v2.03.18
//res=(*pBlt)(lpDDSEmu_Prim, &targetrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
res=(*pBlt)(lpDDSEmu_Prim, &destrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
}
// Try to handle HDC lock concurrency....
if(res==DDERR_SURFACEBUSY){
if (bFlippedDC) {
ReleaseDC_Type pReleaseDC;
switch(dxversion){
case 1: pReleaseDC=pReleaseDC1; break;
case 2: pReleaseDC=pReleaseDC2; break;
case 3: pReleaseDC=pReleaseDC3; break;
case 4: pReleaseDC=pReleaseDC4; break;
case 7: pReleaseDC=pReleaseDC7; break;
}
(*pReleaseDC)(lpdds, hFlippedDC);
}
// v2.03.49: resumed because if fixes locked surfaces on "Red Alert 1" on WinXP as reported by cloudstr
if(lpddssrc) { // lpddssrc could be NULL!!!
res=(*pUnlockMethod(dxversion))(lpddssrc, NULL);
if(res && (res!=DDERR_NOTLOCKED)) OutTraceE("Unlock ERROR: lpdds=%x err=%x(%s)\n", lpddssrc, res, ExplainDDError(res));
}
res=(*pUnlockMethod(dxversion))(lpdds, NULL); // v2.03.24 reintroduced because of "Virtua Cop"
if(res && (res!=DDERR_NOTLOCKED)) OutTraceE("Unlock ERROR: lpdds=%x err=%x(%s)\n", lpdds, res, ExplainDDError(res));
if (IsDebug) BlitTrace("BUSY", &emurect, &destrect, __LINE__);
res=(*pBlt)(lpdds, &emurect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
if (res) BlitError(res, lpsrcrect, &destrect, __LINE__);
}
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
return res;
}
LPDIRECTDRAWSURFACE lpDDSSource;
if (res=(*pColorConversion)(dxversion, lpdds, emurect, &lpDDSSource)) {
OutTraceE("sBlt ERROR: Color conversion failed res=%x(%s)\n", res, ExplainDDError(res));
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
return res;
}
if(lpDDSEmu_Prim->IsLost()) lpDDSEmu_Prim->Restore();
dxw.ShowOverlay(lpDDSSource);
if(dxw.dwFlags4 & BILINEAR2XFILTER){
emurect.right <<= 1;
emurect.bottom <<= 1;
}
if((dxw.dwFlags1 & SAVELOAD) || (dxw.dwFlags8 & FORCEVSYNC)) {
HRESULT res2;
if(!bVSyncDone){
if(res2=lpPrimaryDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN , 0))
OutTraceE("WaitForVerticalBlank ERROR: res=%x\n", res2);
}
bVSyncDone = FALSE;
}
if (IsDebug) BlitTrace("BACK2PRIM", &emurect, &destrect, __LINE__);
res=(*pPrimaryBlt)(dxversion, pBlt, lpDDSEmu_Prim, &destrect, lpDDSSource, &emurect, NULL);
if (res) BlitError(res, &emurect, &destrect, __LINE__);
if(dxw.dwFlags1 & SUPPRESSDXERRORS) res=DD_OK;
if (IsDebug) OutTrace("%s: done ret=%x at %d\n", api, res, __LINE__);
return res;
}
HRESULT WINAPI sBlt(int dxversion, Blt_Type pBlt, char *api, LPDIRECTDRAWSURFACE lpdds, LPRECT lpdestrect,
LPDIRECTDRAWSURFACE lpddssrc, LPRECT lpsrcrect, DWORD dwflags, LPDDBLTFX lpddbltfx, BOOL isFlipping)
{
POINT p = {0, 0};
HRESULT res;
BOOL ToPrim, FromPrim, ToScreen, FromScreen;
if(dxw.dwFlags5 & MESSAGEPUMP) dxw.MessagePump();
ToPrim=dxwss.IsAPrimarySurface(lpdds);
FromPrim=dxwss.IsAPrimarySurface(lpddssrc);
ToScreen=ToPrim && !(dxw.dwFlags1 & EMULATESURFACE);
FromScreen=FromPrim && !(dxw.dwFlags1 & EMULATESURFACE) && !(dxw.dwFlags1 & EMULATEBUFFER); // v2.02.77
// log
if(IsTraceDW){
char sLog[256];
char sInfo[128];
sprintf(sLog, "%s: dest=%x%s src=%x%s dwFlags=%x(%s)",
api, lpdds, (ToPrim ? "(PRIM)":""), lpddssrc, (FromPrim ? "(PRIM)":""), dwflags, ExplainBltFlags(dwflags));
if (lpdestrect)
sprintf(sInfo, " destrect=(%d,%d)-(%d,%d)", lpdestrect->left, lpdestrect->top, lpdestrect->right, lpdestrect->bottom);
else
sprintf(sInfo, " destrect=(NULL)");
strcat(sLog, sInfo);
if (lpsrcrect)
sprintf(sInfo, " srcrect=(%d,%d)-(%d,%d)", lpsrcrect->left, lpsrcrect->top, lpsrcrect->right, lpsrcrect->bottom);
else
sprintf(sInfo, " srcrect=(NULL)");
strcat(sLog, sInfo);
if(lpddbltfx){
if (dwflags & DDBLT_COLORFILL){
sprintf(sInfo, " ddbltfx.FillColor=%x", lpddbltfx->dwFillColor);
strcat(sLog, sInfo);
}
if (dwflags & DDBLT_KEYDESTOVERRIDE){
sprintf(sInfo, " ddbltfx.DestColorkey=%x", lpddbltfx->ddckDestColorkey);
strcat(sLog, sInfo);
}
if (dwflags & DDBLT_KEYSRCOVERRIDE){
sprintf(sInfo, " ddbltfx.SrcColorkey=%x", lpddbltfx->ddckSrcColorkey);
strcat(sLog, sInfo);
}
if (dwflags & DDBLT_ROP){
sprintf(sInfo, " ddbltfx.ROP=%x", lpddbltfx->dwROP);
strcat(sLog, sInfo);
}
if (dwflags & DDBLT_DEPTHFILL){
sprintf(sInfo, " ddbltfx.FillDepth=%x", lpddbltfx->dwFillDepth);
strcat(sLog, sInfo);
}
}
strcat(sLog,"\n");
OutTrace(sLog);
}
if(dxw.dwFlags8 & FORCEWAIT){
dwflags |= DDBLT_WAIT;
dwflags &= ~(DDBLT_ASYNC|DDBLT_DONOTWAIT);
}
if(dxw.dwFlags8 & FORCENOWAIT){
dwflags &= ~DDBLT_WAIT;
dwflags |= (DDBLT_ASYNC|DDBLT_DONOTWAIT);
}
if(ToPrim)
res = sBltToPrimary(dxversion, pBlt, api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx, isFlipping);
else
res = sBltNoPrimary(dxversion, pBlt, api, lpdds, lpdestrect, lpddssrc, lpsrcrect, dwflags, lpddbltfx);
return res;
}