/* ------------------------------------------------------------------ */ // DirectDraw Surface Stack implementation /* ------------------------------------------------------------------ */ #define _CRT_SECURE_NO_WARNINGS #include #include "dxwnd.h" #include "dxwcore.hpp" //#define DXW_SURFACE_STACK_TRACING //#define OutTraceSDB OutTrace dxwSStack::dxwSStack() { // three variables used as cache ... lpDDSPrimary = NULL; lpDDSBackBuffer = NULL; lpDDSZBuffer = 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; 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; 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); } } static void DumpSurfaceList(SurfaceDB_Type *SurfaceDB) { for (int i=0;i>> SURFACELIST CLEAR ALL\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; SurfaceDB_Type LastEntries[3]; LastEntries[0].lpdds = 0; LastEntries[1].lpdds = 0; LastEntries[2].lpdds = 0; lpDDSPrimary = NULL; lpDDSBackBuffer = NULL; lpDDSZBuffer = NULL; // search for last (more recent) entries and copy to safe place for (i=0;i>> SAVED lpDDSPrimary=%x\n", lpDDSPrimary); #endif } if(LastEntries[1].lpdds) { SurfaceDB[i++]=LastEntries[1]; lpDDSBackBuffer = LastEntries[1].lpdds; #ifdef DXW_SURFACE_STACK_TRACING OutTrace(">>> SAVED lpDDSBackBuffer=%x\n", lpDDSBackBuffer); #endif } if(LastEntries[2].lpdds) { SurfaceDB[i++]=LastEntries[2]; lpDDSZBuffer = LastEntries[2].lpdds; #ifdef DXW_SURFACE_STACK_TRACING OutTrace(">>> SAVED lpDDSZBuffer=%x\n", lpDDSZBuffer); #endif } #ifdef DXW_SURFACE_STACK_TRACING DumpSurfaceList(SurfaceDB); #endif } void dxwSStack::UnrefSurface(LPDIRECTDRAWSURFACE ps) { int i; // look for entry for (i=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::DuplicateSurface(LPDIRECTDRAWSURFACE psfrom, LPDIRECTDRAWSURFACE psto, int version) { int i, j; SurfaceDB_Type *e; #ifdef DXW_SURFACE_STACK_TRACING OutTraceSDB(">>> SURFACELIST DUPL: from=%x to=%x vers=%d\n", psfrom, psto, version); #endif 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) return; // search for an empty slot j = i; for (j=0;j>> 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; }