Cannot Bltfast

Started by
4 comments, last by Ladhra 18 years, 8 months ago
Hi all. I've just started game programming. So everything is quite confusing for me; and actually that was just what I expected it to be. :) Here's my problem. I created 4 surfaces: primary surface, backbuffer, 2 off-screen surfaces(one for the background, and one for the sprites). The program loads one bitmap for each of the ofscreen surfaces. Then blits them to the backbuffer so I can use page flipping. Everything seems to be OK (IMHO), but all I see is a blank screen. :( Below code snippet is supposed to load the bitmap to the off-screen surface, then blit it to the back-buffer. //This fn creates the off-screen surfaces int Create_Offscreen(LPDIRECTDRAWSURFACE7 lpsurface, int ix = SCREEN_WIDTH, int iy = SCREEN_HEIGHT, int memflag = DDSCAPS_VIDEOMEMORY) { ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_WIDTH | DDSD_CKSRCBLT; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | memflag; ddsd.dwWidth = ix; ddsd.dwHeight = iy; ddsd.ddckCKSrcBlt.dwColorSpaceHighValue = RGB(0,0,0); ddsd.ddckCKSrcBlt.dwColorSpaceLowValue = RGB(0,0,0); if(FAILED(lpdd->CreateSurface(&ddsd, &lpsurface, NULL))) return(0); return(1); } //Start-up functions int Game_Init(void *parms = NULL, int num_parms = 0) { if(FAILED(DirectDrawCreateEx(NULL, (void **)&lpdd, IID_IDirectDraw7, NULL))) return(0); if(FAILED(lpdd->SetCooperativeLevel(main_window_handle, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT|DDSCL_ALLOWMODEX))) return(0); if(FAILED(lpdd->SetDisplayMode(SCREEN_WIDTH, SCREEN_HEIGHT, BPP, 0, 0))) return(0); ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.dwBackBufferCount = 1; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP; if(FAILED(lpdd->CreateSurface(&ddsd, &lpddsprimary, NULL))) return(0); ddsd.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER; if(FAILED(lpddsprimary->GetAttachedSurface(&ddsd.ddsCaps, &lpddsback))) return(0); //Create the off-screen surface if(!Create_Offscreen(lpddsoffscr, 640, 480)) return(0); //Load the bitmap(uses functions from ddutil.cpp/h) DDReLoadBitmap(lpddsoffscr, "some_bitmap.bmp"); RECT source = {0, 0, 640, 480}; lpddsback->BltFast(0, 0, lpddsoffscr, &source, DDBLTFAST_NOCOLORKEY | DDBLTFAST_WAIT); return(1); } //Show the bitmap int Game_Main(void *parms = NULL, int num_parms = 0) { if(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT))) return(0); return(1); } I've tested the program several times(well actually several hundred times). There seems to be no problem with bitmap loading; but can't get the BltFast fn working. Thanks in advance.
Advertisement
The only obvious thing I see is that the BltFast call should be in Game_Main, just before the Flip call. When you flip, the front becomes the back and the back becomes the front. By only blitting the one time (to the back buffer), you will get a (possibly invisble) flash of the image before the next flip. The next flip swaps the buffers again, leaving you with whatever was put into the backbuffer on that frame (which is nothing).

I know that was a bit confusing, but basically the drawing should be done in Game_Main before the Flip.

It that doesn't help, then try checking the return code from the BltFast and see if it is failing. If so, look up the error code and that should tell you why it failed.
Try using this code to check the return value:
void ShowError(int result, int x, int y, LPDIRECTDRAWSURFACE7 lpdds) {	switch (result) {		case DDERR_GENERIC:			DrawString("DDERR_GENERIC", x, y, lpdds);			break;		case DDERR_INVALIDCLIPLIST:			DrawString("DDERR_INVALIDCLIPLIST", x, y, lpdds);			break;		case DDERR_INVALIDOBJECT:			DrawString("DDERR_INVALIDOBJECT", x, y, lpdds);			break;		case DDERR_INVALIDPARAMS:			DrawString("DDERR_INVALIDPARAMS", x, y, lpdds);			break;		case DDERR_INVALIDRECT:			DrawString("DDERR_INVALIDRECT", x, y, lpdds);			break;		case DDERR_NOALPHAHW:			DrawString("DDERR_NOALPHAHW", x, y, lpdds);			break;		case DDERR_NOBLTHW:			DrawString("DDERR_NOBLTHW", x, y, lpdds);			break;		case DDERR_NOCLIPLIST:			DrawString("DDERR_NOCLIPLIST", x, y, lpdds);			break;		case DDERR_NODDROPSHW:			DrawString("DDERR_NODDROPSHW", x, y, lpdds);			break;		case DDERR_NOMIRRORHW:			DrawString("DDERR_NOMIRRORHW", x, y, lpdds);			break;		case DDERR_NORASTEROPHW:			DrawString("DDERR_NORASTEROPHW", x, y, lpdds);			break;		case DDERR_NOSTRETCHHW:			DrawString("DDERR_NOSTRETCHHW", x, y, lpdds);			break;		case DDERR_NOZBUFFERHW:			DrawString("DDERR_NOZBUFFERHW", x, y, lpdds);			break;		case DDERR_SURFACEBUSY:			DrawString("DDERR_SURFACEBUSY", x, y, lpdds);			break;		case DDERR_SURFACELOST:			DrawString("DDERR_SURFACELOST", x, y, lpdds);			break;		case DDERR_UNSUPPORTED:			DrawString("DDERR_UNSUPPORTED", x, y, lpdds);			break;		case DDERR_WASSTILLDRAWING:			DrawString("DDERR_WASSTILLDRAWING", x, y, lpdds);			break;		default:			DrawString("no error detected", x, y, lpdds);			break;	}}void DrawString(char *text, int x, int y, LPDIRECTDRAWSURFACE7 lpdds) {	HDC xdc;	lpdds->GetDC(&xdc);	SetTextColor(xdc, RGB(50, 50, 50));	SetBkMode(xdc, TRANSPARENT);	TextOut(xdc, x, y, text, strlen(text));	lpdds->ReleaseDC(xdc);}

If you don't get an error, then you probably just need to Blt() from Game_Main() right before the call to Flip();
(by the way, are you learning from Tricks of the Windows Game Programming Gurus? I noticed that your function naming convention is the same as Andre Lamothe's. Its a good book [smile].)
Still 2^10 :P
Blittin in the Game_Main locked the application. I'll be on a night shift today. Tomorrow I'll check what error code BltFast returns.

And yes! I found Andre to be easy to read and easy to understand (well, most of the time:)) The book is a good start point for rookies like me.

Thanks guys. I'll write ASAP.
The BltFast fn return an "S_OK". After hours of frustration and lock-ups, I found out that DDCopyBitmap fn (ddutil.cpp/h) fails when copying bitmaps to the offscreen surface. It has no problem working on the backbuffer or the primary surface, though.

I'm stuck in the same place for almost a week. :,( Any ideas how to work that out?
The problem's been solved. I was making a call to the wrong function. :)

Thanks again if you're still out there.

This topic is closed to new replies.

Advertisement