/* ------------------------------------------------------------------ */ // DirectDraw Surface Stack implementation /* ------------------------------------------------------------------ */ #define _CRT_SECURE_NO_WARNINGS #include #include "dxwnd.h" #include "dxwcore.hpp" // uncomment line below to activate surface stack tracing //#define DXW_SURFACE_STACK_TRACING #define OutTraceSDB OutTrace dxwSStack::dxwSStack() { // three variables used as cache ... lpDDSPrimary = NULL; lpDDSBackBuffer = NULL; lpDDSZBuffer = NULL; lpDDS3DRef = NULL; memset(SurfaceDB, 0, sizeof(SurfaceDB)); } dxwSStack::~dxwSStack() { } static char *sRole(USHORT role) { char *s; switch (role){ case SURFACE_ROLE_PRIMARY: s="(PRIM)"; break; case SURFACE_ROLE_BACKBUFFER: s="(BACK)"; break; case SURFACE_ROLE_ZBUFFER: s="(ZBUF)"; break; case SURFACE_ROLE_3DREF: s="(3DREF)"; break; default: s="??"; break; // should never happen ... } return s; } #ifdef DXW_SURFACE_STACK_TRACING extern char*ExplainDDSCaps(DWORD); static void CheckSurfaceList(SurfaceDB_Type *SurfaceDB) { char sMsg[81]; int iPCount = 0; int iBCount = 0; int iZCount = 0; for (int i=0;i 1) { sprintf(sMsg, "Primary count = %d", iPCount); MessageBox(0, sMsg, "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); } if(iBCount > 1) { sprintf(sMsg, "Backbuffer count = %d", iPCount); MessageBox(0, sMsg, "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); } if(iZCount > 1) { sprintf(sMsg, "Zbuffer count = %d", iZCount); MessageBox(0, sMsg, "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); } } static void DumpSurfaceList(SurfaceDB_Type *SurfaceDB) { for (int i=0;i>> SURFACELIST CLEAR UNREF\n"); #endif // v2.03.91.fx5: emptying the list entirely is no good for "Warhammer 40K Rites of War" // better leave the last used primary and backbuffer surfaces. int i, j; SurfaceDB_Type NewEntries[DDSQLEN]; lpDDSPrimary = NULL; lpDDSBackBuffer = NULL; lpDDSZBuffer = NULL; lpDDS3DRef = NULL; // search for valid entries and copy to safe place for (i=0, j=0; i>> SURFACELIST UNREF: lpdds=%x%s ref=%x vers=%d\n", ps, sRole(SurfaceDB[i].uRole), SurfaceDB[i].uRef, SurfaceDB[i].uVersion); #endif } #ifdef DXW_SURFACE_STACK_TRACING DumpSurfaceList(SurfaceDB); #endif } void dxwSStack::PushSurface(LPDIRECTDRAWSURFACE ps, USHORT role, USHORT version, DWORD dwCaps) { int i; SurfaceDB_Type *e; #ifdef DXW_SURFACE_STACK_TRACING OutTraceSDB(">>> SURFACELIST MARK: lpdds=%x%s vers=%d\n", ps, sRole(role), version); #endif for (i=0;ilpdds==ps) || (e->lpdds==(DWORD)0)) break; // got matching entry or end of the list } if(i == DDSQLEN) { //MessageBox(0, "Surface stack is full", "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); //return; for(int j=0;jlpdds=ps; e->uRole = role; e->uRef = TRUE; e->uVersion = version; e->dwCaps = dwCaps; switch(e->uRole){ case SURFACE_ROLE_PRIMARY: lpDDSPrimary = e->lpdds; break; case SURFACE_ROLE_BACKBUFFER: lpDDSBackBuffer = e->lpdds; break; case SURFACE_ROLE_ZBUFFER: lpDDSZBuffer = e->lpdds; break; } #ifdef DXW_SURFACE_STACK_TRACING DumpSurfaceList(SurfaceDB); #endif } void dxwSStack::PushPrimarySurface(LPDIRECTDRAWSURFACE ps, int version, DWORD dwCaps) { PushSurface(ps, SURFACE_ROLE_PRIMARY, (USHORT)version, dwCaps); } void dxwSStack::PushBackBufferSurface(LPDIRECTDRAWSURFACE ps, int version, DWORD dwCaps) { PushSurface(ps, SURFACE_ROLE_BACKBUFFER, (USHORT)version, dwCaps); } void dxwSStack::PushZBufferSurface(LPDIRECTDRAWSURFACE ps, int version, DWORD dwCaps) { PushSurface(ps, SURFACE_ROLE_ZBUFFER, (USHORT)version, dwCaps); } void dxwSStack::Push3DRefSurface(LPDIRECTDRAWSURFACE ps, int version, DWORD dwCaps) { PushSurface(ps, SURFACE_ROLE_3DREF, (USHORT)version, dwCaps); } DWORD dxwSStack::DuplicateSurface(LPDIRECTDRAWSURFACE psfrom, LPDIRECTDRAWSURFACE psto, int version) { int i; SurfaceDB_Type *e; SurfaceDB_Type sentry; #ifdef DXW_SURFACE_STACK_TRACING OutTraceSDB(">>> SURFACELIST DUPL: from=%x to=%x vers=%d\n", psfrom, psto, version); #endif // search for source or empty slot for (i=0;ilpdds==psfrom) || (e->lpdds==(DWORD)0)) break; // got matching entry or end of the list } // if not found, return if (!e->lpdds) { #ifdef DXW_SURFACE_STACK_TRACING OutTraceSDB("--- NO ENTRY: from=%x\n", psfrom); #endif return 0; } // save surface entry sentry = *e; // search for destination or empty slot for (i=0;ilpdds==psto) || (e->lpdds==(DWORD)0)) break; // got matching entry or end of the list } if(i == DDSQLEN) { //MessageBox(0, "Surface stack is full", "DxWnd SurfaceList", MB_OK | MB_ICONEXCLAMATION); //return; for(int j=0;jlpdds = psto; e->uVersion = version; e->uRef = TRUE; #ifdef DXW_SURFACE_STACK_TRACING DumpSurfaceList(SurfaceDB); #endif return e->dwCaps; } void dxwSStack::PopSurface(LPDIRECTDRAWSURFACE ps) { int i; // look for entry for (i=0;i>> SURFACELIST CLEAR: i=%d lpdds=%x%s ref=%x vers=%d\n", i, ps, sRole(SurfaceDB[i].uRole), SurfaceDB[i].uRef, SurfaceDB[i].uVersion); #endif for (; i>> GETCAPS: lpdds=%x caps=%x(%s)\n", ps, SurfaceDB[i].dwCaps, ExplainDDSCaps(SurfaceDB[i].dwCaps)); #endif return SurfaceDB[i].dwCaps; } } return 0; } SurfaceDB_Type *dxwSStack::GetSurface(LPDIRECTDRAWSURFACE ps) { for (int i=0;i>> GETCAPS: lpdds=%x caps=%x(%s)\n", ps, SurfaceDB[i].dwCaps, ExplainDDSCaps(SurfaceDB[i].dwCaps)); #endif return &SurfaceDB[i]; } } return NULL; }