First create a global BOOL variable bSingleBuffer and initialize it to FALSE. As before, comment out the part in InitApp() function where after doing GetCaps() it fails with an error message saying that the device does not support back buffers. So with that code out of the way, add the following piece of code:
}
memset(&ddsd, 0, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
if(bSingleBuffer)
{
ddsd.dwFlags = DDSD_CAPS;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
}
else
{
ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE |
DDSCAPS_FLIP;
ddsd.dwBackBufferCount = 1;
}
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSPrimary, NULL);
If the device does not support back buffer or flip then we set the bSingleBuffer variable to TRUE. Then create our primary surface and store the pointer to the surface in g_pDDSPrimary variable. The next part of code gets the back buffer from the primary surface using EnumAttachedSurfaces() function, that part has to be modified as below:
if(bSingleBuffer)
{
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT;
ddsd.dwWidth = 240;
ddsd.dwHeight = 320;
hRet = g_pDD->CreateSurface(&ddsd, &g_pDDSBack, NULL);
if(hRet != DD_OK)
{
return InitFail(hWnd, hRet, TEXT(“Failed to create normal surface”));
}
}
else
{
// Get a pointer to the back buffer
hRet = g_pDDSPrimary->EnumAttachedSurfaces(&g_pDDSBack, EnumFunction);
if (hRet != DD_OK)
return InitFail(hWnd, hRet, szEnumAttachedSurfacesFailMsg);
}
Here, if bSingleBuffer is set, we create a normal surface, 240 pixels wide and 320 pixels high. The resolution of the emulator. Otherwise we get the back buffer from the primary surface.
Then the two off-screen surfaces are created. This part of code remains the same, the only change is,
// Create a offscreen bitmap.
ddsd.dwFlags = DDSD_HEIGHT | DDSD_WIDTH;
ddsd.dwHeight = 320;
ddsd.dwWidth = 240;
This is same as the original code, only thing I changed here are the height and width.
Next change would be in the InitSurfaces() function,
DDCopyBitmap(g_pDDSOne, hbm, 0, 0, 240, 320);
DDCopyBitmap(g_pDDSTwo, hbm, 0, 320, 240, 320);
Originally, the bitmap was getting copied from 0, 0, 640, 480 and 0, 480, 640, 480. I think the original program was intended for a VGA resolution device but since the emulator runs Quarter VGA, I modified the dimensions.
The final change is in the WindowProc() function under the WM_TIMER message inside the while loop. The original code simply called Flip() on the primary surface to display the image in the back buffer, and as I have been repeating like a million times, the emulator does not support flipping (: So the original code,
hRet = g_pDDSPrimary->Flip(NULL, 0);
becomes,
if(bSingleBuffer)
{
//RECT src, dest;
hRet = g_pDDSPrimary->Blt(NULL, g_pDDSBack, NULL, 0, NULL);
if(hRet != DD_OK)
{
printf(“DDEX3: Blt on primary surface failed, errcode:0x%x\n”, GetLastError());
}
}
else
{
hRet = g_pDDSPrimary->Flip(NULL, 0);
}
And that is all! DDEX3 is now ready to be run on the emulator (: Notice that last time I had used the src and dest RECT’s to specify the size and location of the source and destination rectangles on the source and destination surfaces respectively. Specifying NULL for both src and dest would make use of the entire source and destination surfaces, which is exactly what we want. The remaning part of the while loop remains same.
The emulator screen now flips between the following two screens every half-second.
and
As you can see, I replaced the stale red and blue screens with something a bit more nice (: Well, obviously you know how to do that. Don’t you? (:
Hi,
I tried this but am getting szEnumAttachedSurfacesFailMsg and EnumAttachedSurfaces FAILED errors in teraterm
Regards
Syed