Archived

This topic is now archived and is closed to further replies.

zephon

Problem when locking a surface (DDERR_SURFACELOST)

Recommended Posts

Hi Everyone, I have looked at the other posts on this error but none of the solutions seem to apply to me. I am currently teaching myself direct draw and am trying to convert a basic 32 bit pixel plotting program to use double buffering. No matter what I do when I attempt to lock my secondary surface I get a DDERR_SURFACELOST returned, I attempt to Restore the surfaces using RestoreAllSurfaces() but this makes no difference. I am a little lost as I'm still coming to grips with directx and I'm sure it's something simple I'm missing. Here's the culprit code, the initialisation code is taken straight from Lamothe minus the palette stuff. I know it is extremely messy.. that's from many many different attempts at it!
  
//********************************************************
// Function: GameInit()
//
// Game Initialisation
//********************************************************

int GameInit()
{
		
	//Create IDirectDraw7 Interface
	if(FAILED(DirectDrawCreateEx(NULL, (VOID**)&lpDirectDraw, IID_IDirectDraw7, NULL)))
	{
		MessageBox(hMainWindow, "Error Creating Interface", "Error", MB_OK);
		return(0);
	} //end if

	//Set cooperation to full screen
	if(FAILED(lpDirectDraw->SetCooperativeLevel(hMainWindow, DDSCL_FULLSCREEN | DDSCL_EXCLUSIVE | DDSCL_ALLOWREBOOT)))
	{
		MessageBox(hMainWindow, "Error Setting Cooperation", "Error", MB_OK);
		return(0);
	} //end if

	//Set display mode to 640x480x32
	if(FAILED(lpDirectDraw->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,32,0,0)))
	{
		MessageBox(hMainWindow, "Error Setting Display Mode", "Error", MB_OK);
		//error
		return(0);
	} //end if

	//Setup the primary surface with back buffer

	DDRAW_INIT_STRUCT(directDrawSurfaceDesc);

	//enable valid fields
	directDrawSurfaceDesc.dwFlags			= DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
	
	//set the backbuffer count to 1
	directDrawSurfaceDesc.dwBackBufferCount	= 1;

	//request a complex, flippable surface
	directDrawSurfaceDesc.ddsCaps.dwCaps	= DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;

	//Create the primary surface
	if(FAILED(lpDirectDraw->CreateSurface(&directDrawSurfaceDesc, &lpPrimaryDirectDrawSurface, NULL)))
	{
		MessageBox(hMainWindow, "Error Creating Primary Surface", "Error", MB_OK);
		//error
		return(0);
	} //end if

	//Now query for attached surface from the primary surface

	//this line is needed by the call... ?
	directDrawSurfaceDesc.ddsCaps.dwCaps = DDSCAPS_BACKBUFFER;

	if(FAILED(lpPrimaryDirectDrawSurface->GetAttachedSurface(&directDrawSurfaceDesc.ddsCaps, &lpSecondaryDirectDrawSurface)))
	{
		MessageBox(hMainWindow, "Error Creating Secondary Surface", "Error", MB_OK);
		return(0);
	}

	return(1); //return success

} //end GameInit()

//********************************************************
// Function: GameMain()
//
// Main Game Processing
//********************************************************

int GameMain()
{
	// this is the main loop of the game, do all your processing
	// here

	// for now test if user is hitting ESC and send WM_CLOSE
	if (KEYDOWN(VK_ESCAPE))
		SendMessage(hMainWindow,WM_CLOSE,0,0);

	//clear out surface description and set the size
	DDRAW_INIT_STRUCT(directDrawSurfaceDesc);
	//lock the surface
/*	if(FAILED(lpSecondaryDirectDrawSurface->Lock(NULL, &directDrawSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL)))
	{
		MessageBox(hMainWindow, "Lock Failed", "Error", MB_OK);
		return(0);
	}*/

	int testInt;


	
	testInt = lpSecondaryDirectDrawSurface->Lock(NULL, &directDrawSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);

	while(testInt != DD_OK)
	{
		if(testInt == DDERR_INVALIDOBJECT)
		{
			MessageBox(hMainWindow, "DDERR_INVALIDOBJECT", "Error", MB_OK);
			return(0);
		}
		else if(testInt == DDERR_INVALIDPARAMS)
		{
			MessageBox(hMainWindow, "DDERR_INVALIDPARAMS", "Error", MB_OK);
			return(0);
		}
		else if(testInt == DDERR_OUTOFMEMORY)
		{
			MessageBox(hMainWindow, "DDERR_OUTOFMEMORY", "Error", MB_OK);
			return(0);
		}
		else if(testInt == DDERR_SURFACEBUSY)
		{
			MessageBox(hMainWindow, "DDERR_SURFACEBUSY", "Error", MB_OK);
			return(0);
		}
		else if(testInt == DDERR_SURFACELOST)
		{
			//MessageBox(hMainWindow, "DDERR_SURFACELOST", "Error", MB_OK);
			
			if(FAILED(lpPrimaryDirectDrawSurface->Restore()))
			{
				MessageBox(hMainWindow, "Primary Surface Restore Failed", "Error", MB_OK);
				return(0);
			}
			
			if(FAILED(lpSecondaryDirectDrawSurface->Restore()))
			{
				MessageBox(hMainWindow, "Secondary Surface Restore Failed", "Error", MB_OK);
				return(0);
			}


			//return(0);
		}
		else if(testInt == DDERR_WASSTILLDRAWING)
		{
			MessageBox(hMainWindow, "DDERR_WASSTILLDRAWING", "Error", MB_OK);
			return(0);
		}
	testInt = lpSecondaryDirectDrawSurface->Lock(NULL, &directDrawSurfaceDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL);
	
	}
	
	// alias pointer to back buffer surface
//UCHAR *back_buffer = (UCHAR *)directDrawSurfaceDesc.lpSurface;
	UINT *video_buffer		= (UINT *)directDrawSurfaceDesc.lpSurface;
// now clear the back buffer out

// linear memory?
if (directDrawSurfaceDesc.lPitch == SCREEN_WIDTH)
    memset(video_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);
else
   {
   // non-linear memory
   
   // make copy of video pointer
   UINT *dest_ptr = video_buffer;

   // clear out memory one line at a time
   for (int y=0; y<SCREEN_HEIGHT; y++)
       {
       // clear next line
       memset(dest_ptr,0,SCREEN_WIDTH);
       
       // advance pointer to next line
       dest_ptr+=directDrawSurfaceDesc.lPitch;

       } // end for y

   } // end else

	

	// now ddsd.lPitch is valid and so is ddsd.lpSurface

	// make a couple aliases to make code cleaner, so we don't
	// have to cast
	UINT mempitch			= directDrawSurfaceDesc.lPitch >> 2;


	// plot 1000 random pixels with random colors on the
	// primary surface, they will be instantly visible
	for (int index=0; index < 1000; index++)
    {
		// select random position and color for 640x480x32
		UINT colour = RGB_32BIT(rand()%255,rand()%255,rand()%255);
		int x = rand()%640;
		int y = rand()%480;

		plotPixel32(x,y,colour,mempitch,video_buffer);
    } // end for index

/*	for(int i=0; i<1000; i++)
	{
		Plot16(rand()%640,rand()%480,rand()%30,rand()%30,rand()%30,(USHORT *) directDrawSurfaceDesc.lpSurface,(int) directDrawSurfaceDesc.lPitch);
	}*/
	//unlock the surface

	if(FAILED(lpSecondaryDirectDrawSurface->Unlock(NULL)))
	{
		return(0);
	}

	//perform the flip

	lpPrimaryDirectDrawSurface->Flip(NULL, DDFLIP_WAIT);
	// return success or failure or your own return code here

	return(1);
}
  
[edited by - zephon on July 15, 2002 11:30:35 AM]

Share this post


Link to post
Share on other sites
Thanks for your reply, I did what you said and when the secondary surface is lost I restore it, however now the restore fails with the error DDERR_IMPLICITLYCREATED, being a "newbie" Direct X programmer I am not sure what the description for this error actually means "The surface cannot be restored because it is an implicitly created surface."

I can''t help but think that maybe there is something wrong with my initialisation function or something but I can''t see it.

Share this post


Link to post
Share on other sites