示例#1
0
//-----------------------------------------------------------------------------
// Name: dx_Affiche()
// Desc: Affiche le contenu du buffer à l'écran
//-----------------------------------------------------------------------------
bool dx_Affiche ()
{
    if (PleinEcran)
    {
        ErrDd = SurfacePrimaire->Flip (0, DDFLIP_WAIT);
    }
    else
    {
        RECT tRectSrc;
        RECT tRectDest;
        POINT tPosition = {0,0};

        // Copie de Surface suivant la position de la fenêtre
        ClientToScreen (Fenetre, &tPosition);
        GetClientRect  (Fenetre, &tRectDest);

        if (TailleFenetre)
            SetRect (&tRectSrc, 0, 0, tRectDest.right-tRectDest.left,
                     tRectDest.bottom-tRectDest.top);
        else SetRect (&tRectSrc, 0, 0, ResolutionX, ResolutionY);

        OffsetRect (&tRectDest, tPosition.x, tPosition.y);

        ErrDd = SurfacePrimaire->Blt
                (&tRectDest,SurfaceBack,&tRectSrc,DDBLT_WAIT,NULL);
    }

    return dx_Test ();
};
示例#2
0
文件: demo8_5.cpp 项目: 7er/T3DCHAP08
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

// make sure this isn't executed again
if (window_closed)
   return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
   {
   PostMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed = 1;
   } // end if

// clear out the back buffer
DDraw_Fill_Surface(lpddsback, 0);

// lock primary buffer
DDRAW_INIT_STRUCT(ddsd);

if (FAILED(lpddsback->Lock(NULL,&ddsd,
                           DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
                           NULL)))
return(0);

// do the graphics
Draw_Polygon2D(&asteroid, (UCHAR *)ddsd.lpSurface, ddsd.lPitch);

// test for scale
if (KEYDOWN('A')) // scale up
   Scale_Polygon2D(&asteroid, 1.1, 1.1);
else
if (KEYDOWN('S')) // scale down
   Scale_Polygon2D(&asteroid, 0.9, 0.9);

// rotate the polygon by 5 degrees
Rotate_Polygon2D(&asteroid, 5);

// unlock primary buffer
if (FAILED(lpddsback->Unlock(NULL)))
   return(0);

// perform the flip
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

// wait a sec
Sleep(33);

// return success or failure or your own return code here
return(1);

} // end Game_Main
int DD_Flip(void)
{
// this function flip the primary surface with the secondary surface

// flip pages
while(lpddsprimary->Flip(NULL, DDFLIP_WAIT)!=DD_OK);

// flip the surface

// return success
return(1);

} // end DD_Flip
示例#4
0
//-----------------------------------------------------------------------------
// Name: Flip()
// Desc: this function flip the primary surface with the secondary surface
//-----------------------------------------------------------------------------   
int Flip()
{// this function flip the primary surface with the secondary surface

	// flip pages
	while( (ddReturnVal=lpddsPrimary->Flip(NULL, DDFLIP_WAIT) )!= DD_OK)
	{
		if(ddReturnVal!=DD_OK)
			if(ddReturnVal==DDERR_SURFACELOST)
			{	OutputDebugString("Surfacelost Flip()\n"); lpddsPrimary->Restore(); return(1);	}
			else
				if (DDFailedCheck(ddReturnVal, "Flip()", cpErrorBuf ))
				{	MessageBox(NULL, cpErrorBuf, "SurfaceFuncs", MB_ICONEXCLAMATION);   return(0); }
	}

	// return success
	return(1);

} // end DD_Flip
示例#5
0
void ProcessIdle()
{
	HRESULT hRet;
	static int iX = 0, iY = 0;
	static iLastBlit;

	if(GetTickCount() - iLastBlit < 50)
	{
		return;
	}

	g_surfCar.Draw(g_pDDSBack, 245, 170, iX, iY, 150, 140);

	while( 1 )
	{
		hRet = g_pDDSFront->Flip(NULL, 0 );
		if( hRet == DD_OK )
		{
			break;
		}
		if( hRet == DDERR_SURFACELOST )
		{
			g_pDDSFront->Restore();
		}
		if( hRet != DDERR_WASSTILLDRAWING )
		{
			break;
		}
	}

	iX += 150;
	if(iX >= 1500)
	{
		iX = 0;
		iY += 140;
		if(iY >= 280)
		{
			iY = 0;
		}
	}

	iLastBlit = GetTickCount();
}
示例#6
0
HRESULT STDMETHODCALLTYPE Flip(LPDIRECTDRAWSURFACE7 surface, LPDIRECTDRAWSURFACE7 lpDDSurface, DWORD flags)
{
    //logOutput << CurrentTimeString() << "Hooked Flip()" << endl;

    HRESULT hr;

    EnterCriticalSection(&ddrawMutex);

    ddrawSurfaceFlip.Unhook();
    hr = surface->Flip(lpDDSurface, flags);
    ddrawSurfaceFlip.Rehook();

    g_bUseFlipMethod = true;

    if (getFrontSurface(surface))
    {
        CaptureDDraw();
    }

    LeaveCriticalSection(&ddrawMutex);

    return hr;
}
示例#7
0
//////////////////////////////////////////////////////////////////////////////
//MAIN GAME LOOP
//////////////////////////////////////////////////////////////////////////////
void Prog_Loop()
{
	//set up the vertex positions
	vert[0].sx=(float) (cos(angle)*240.0+320.0);
	vert[0].sy=(float) (sin(angle)*240.0+240.0);
	vert[0].sz=(float) (sin(angle)*240.0+240.0);

	vert[1].sx=(float) (cos(angle+PI/2)*240.0+320.0);
	vert[1].sy=(float) (sin(angle+PI/2)*240.0+240.0);
	vert[1].sz=(float) (sin(angle+PI/2)*240.0+240.0);

	vert[2].sx=(float) (cos(angle-PI/2)*240.0+320.0);
	vert[2].sy=(float) (sin(angle-PI/2)*240.0+240.0);
	vert[2].sz=(float) (sin(angle-PI/2)*240.0+240.0);

	vert[3].sx=(float) (cos(angle-PI)*240.0+320.0);
	vert[3].sy=(float) (sin(angle-PI)*240.0+240.0);
	vert[3].sz=(float) (sin(angle-PI)*240.0+240.0);

	//add to the angle for next time
	angle+=PI/90;

	//clear the viewport to black
	lpd3ddev->Clear(0,NULL,D3DCLEAR_TARGET,0,0,0);

	//start the scene
	lpd3ddev->BeginScene();

	//draw the triangle
	lpd3ddev->DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_TLVERTEX,vert,4,0);

	//end the scene
	lpd3ddev->EndScene();

	//flip 
	lpddsPrime->Flip(NULL,DDFLIP_WAIT);
}
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

// make sure this isn't executed again
if (window_closed)
   return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
   {
   PostMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed = 1;
   } // end if

// clear out the back buffer
DDraw_Fill_Surface(lpddsback, 0);

// lock primary buffer
DDRAW_INIT_STRUCT(ddsd);

if (FAILED(lpddsback->Lock(NULL,&ddsd,
                           DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
                           NULL)))
return(0);

// draw all the asteroids
for (int curr_index = 0; curr_index < NUM_ASTEROIDS; curr_index++)
    {
    // do the graphics
    Draw_Polygon2D(&asteroids[curr_index], (UCHAR *)ddsd.lpSurface, ddsd.lPitch);

    // move the asteroid
    Translate_Polygon2D(&asteroids[curr_index],
                        asteroids[curr_index].xv,
                        asteroids[curr_index].yv);


    // rotate the polygon by 5 degrees
    Rotate_Polygon2D(&asteroids[curr_index], 5);

    // test for out of bounds
    if (asteroids[curr_index].x0 > SCREEN_WIDTH+100)
        asteroids[curr_index].x0 = - 100;

    if (asteroids[curr_index].y0 > SCREEN_HEIGHT+100)
        asteroids[curr_index].y0 = - 100;

    if (asteroids[curr_index].x0 < -100)
        asteroids[curr_index].x0 = SCREEN_WIDTH+100;

    if (asteroids[curr_index].y0 < -100)
        asteroids[curr_index].y0 = SCREEN_HEIGHT+100;

    } // end for curr_asteroid


// unlock primary buffer
if (FAILED(lpddsback->Unlock(NULL)))
   return(0);

// perform the flip
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

// wait a sec
Sleep(33);

// return success or failure or your own return code here
return(1);

} // end Game_Main
int Game_Main(void *parms = NULL, int num_parms = 0)
{
   // this is the main loop of the game, do all your processing
   // here
   
   // not doing this will cause occasional errors 
   // make sure this isn't executed again
   if (window_closed)
      return(0);

   // for now test if user is hitting ESC and send WM_CLOSE
   if (KEYDOWN(VK_ESCAPE))
   {
      PostMessage(main_window_handle,WM_CLOSE,0,0);
      window_closed = 1;
   } // end if

   // lock the back buffer
   DDRAW_INIT_STRUCT(ddsd);
   lpddsback->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL);

   // alias pointer to back buffer surface
   UCHAR *back_buffer = (UCHAR *)ddsd.lpSurface;

   // now clear the back buffer out

   // linear memory?
   if (ddsd.lPitch == SCREEN_WIDTH)
   {
      memset(back_buffer,0,SCREEN_WIDTH*SCREEN_HEIGHT);
   }
   else
   {
      // non-linear memory
      
      // make copy of video pointer
      UCHAR *dest_ptr = back_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+=ddsd.lPitch;

      } // end for y

   } // end else


   // you would perform game logic...
       
   // draw the next frame into the back buffer, notice that we
   // must use the lpitch since it's a surface and may not be linear

   // plot 5000 random pixels
   for (int index=0; index < 5000; index++)
   {
      int   x   = rand()%SCREEN_WIDTH;
      int   y   = rand()%SCREEN_HEIGHT;
      UCHAR col = rand()%256;
      back_buffer[x+y*ddsd.lPitch] = col;
   } // end for index

   // unlock the back buffer
   if (FAILED(lpddsback->Unlock(NULL)))
      return(0);

   // perform the flip
   while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));


   // return success or failure or your own return code here
   return(1);

} // end Game_Main
示例#10
0
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

// lookup for proper walking sequence
static int animation_seq[4] = {0,1,0,2};

int index; // general looping variable

// make sure this isn't executed again
if (window_closed)
   return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
   {
   PostMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed = 1;
   } // end if

// copy background to back buffer
DDraw_Draw_Surface(lpddsbackground,0,0, SCREEN_WIDTH,SCREEN_HEIGHT, lpddsback,0);    

// move objects around

for (index=0; index < 3; index++)
    {
    // move each object to the right at its given velocity
    aliens[index].x++; // =aliens[index].velocity;

    // test if off screen edge, and wrap around
    if (aliens[index].x > SCREEN_WIDTH)
       aliens[index].x = - 80;

    // animate bot
    if (++aliens[index].counter >= (8 - aliens[index].velocity))
        {
        // reset counter
        aliens[index].counter = 0;

        // advance to next frame
        if (++aliens[index].current_frame > 3)
           aliens[index].current_frame = 0;
  
        } // end if

    } // end for index


// draw all the bots
for (index=0; index < 3; index++)
    {
    // draw objects but with scaled destination size
    DDraw_Draw_Surface_Scaled(aliens[index].frames[animation_seq[aliens[index].current_frame]], 
                       aliens[index].x, aliens[index].y,
                       aliens[index].width,aliens[index].height,
                       (float)aliens[index].width*aliens[index].scale,
                       (float)aliens[index].height*aliens[index].scale,
                       lpddsback);

    } // end for index


// flip pages
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

// wait a sec
Sleep(30);

// return success or failure or your own return code here
return(1);

} // end Game_Main
示例#11
0
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

DDBLTFX ddbltfx; // the blitter fx structure
static int feeling_counter = 0;   // tracks how we feel :)
static int happy = 1;             // let's start off being happy

// make sure this isn't executed again
if (window_closed)
   return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
   {
   PostMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed = 1;
   } // end if

// use the blitter to erase the back buffer
// first initialize the DDBLTFX structure
DDRAW_INIT_STRUCT(ddbltfx);

// now set the color word info to the color we desire
ddbltfx.dwFillColor = 0;

// make the blitter call
if (FAILED(lpddsback->Blt(NULL, // pointer to dest RECT, NULL for whole thing
                          NULL, // pointer to source surface
                          NULL, // pointer to source RECT
                          DDBLT_COLORFILL | DDBLT_WAIT, 
                          // do a color fill and wait if you have to
                          &ddbltfx))) // pointer to DDBLTFX holding info
return(0);

// initialize ddsd
DDRAW_INIT_STRUCT(ddsd);

// lock the back buffer surface
if (FAILED(lpddsback->Lock(NULL,&ddsd,
                              DDLOCK_WAIT | DDLOCK_SURFACEMEMORYPTR,
                              NULL)))
    return(0);


// increment how we feel
if (++feeling_counter > 200)
   {
   feeling_counter = 0; 
   happy = -happy;
   } // end if

// draw all the happy faces
for (int face=0; face < 100; face++)
    {
    // are we happy or sad?
    if (happy==1) // we are happy :)
       Blit_Clipped(happy_faces[face].x, 
                    happy_faces[face].y,
                    8,8,    
                    happy_bitmap, 
                    (UCHAR *)ddsd.lpSurface,
                    ddsd.lPitch);         
     else // we must be sad :(
     Blit_Clipped(happy_faces[face].x, 
                  happy_faces[face].y,
                  8,8,    
                  sad_bitmap, 
                  (UCHAR *)ddsd.lpSurface,
                  ddsd.lPitch);     

    } // end face

// move all happy faces
for (face=0; face < 100; face++)
    {
    // move
    happy_faces[face].x+=happy_faces[face].xv;
    happy_faces[face].y+=happy_faces[face].yv;

    // check for off screen, if so wrap
    if (happy_faces[face].x > SCREEN_WIDTH)
         happy_faces[face].x = -8;
    else
    if (happy_faces[face].x < -8)
        happy_faces[face].x = SCREEN_WIDTH;

    if (happy_faces[face].y > SCREEN_HEIGHT)
         happy_faces[face].y = -8;
    else
    if (happy_faces[face].y < -8)
        happy_faces[face].y = SCREEN_HEIGHT;

    } // end face

// unlock surface
if (FAILED(lpddsback->Unlock(NULL)))
   return(0);

// flip the pages
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

// wait a sec
Sleep(30);

// return success or failure or your own return code here
return(1);

} // end Game_Main
示例#12
0
int Game_Main(void *parms = NULL, int num_parms = 0)
{
// this is the main loop of the game, do all your processing
// here

// lookup for proper walking sequence
// 动画帧、先播放站立动作、然后是摆左手、然后再恢复站立动作、然后是摆右手
// 如此重复播放
// 声明为静态、所以不会随着Game_Main的调用而重复初始化
static int animation_seq[4] = {0,1,0,2};

int index; // general looping variable


// make sure this isn't executed again
if (window_closed)
   return(0);

// for now test if user is hitting ESC and send WM_CLOSE
if (KEYDOWN(VK_ESCAPE))
   {
   PostMessage(main_window_handle,WM_CLOSE,0,0);
   window_closed = 1;
   } // end if


DDRAW_INIT_STRUCT(ddbltfx);

if(lpddsback->Blt(NULL, lpddsbackground, NULL, DDBLT_WAIT, &ddbltfx)) return 0;


// move objects around
// 这里是移动异形
for (index=0; index < 3; index++)
{
// move each object to the right at its given velocity
// 移动异形向右走
aliens[index].x++; // =aliens[index].velocity;

// 测试异形的位置是否已经到达了右边界已经完全看不着了
// 就把它又扔会左边从头走过来
// 因为x是左上角的坐标、所以x超过了屏幕宽度刚好完全看不见
// 而因为异形图片的人物宽度刚好为80、所以重置到左边时设置为-80
// test if off screen edge, and wrap around
if (aliens[index].x > SCREEN_WIDTH)
   aliens[index].x = - 80;

// animate bot
if (++aliens[index].counter >= (8 - aliens[index].velocity))
    {
    // reset counter
    aliens[index].counter = 0;

    // advance to next frame
	// 如果超过第三帧、则重置为第0帧、这里是由前面的结构所决定的、只有三个动作
	// 由于采用了先自增再比较的办法、所以条件这里current_frame的范围恒为1~4
	// 所谓的第零帧、也就是标准的站立动作、可以从位图图片得知、
    if (++aliens[index].current_frame > 3)
       aliens[index].current_frame = 0;

    } // end if

} // end for index


// draw all the bots
for (index=0; index < 3; index++)
{
/*
原型
int DDraw_Draw_Surface(LPDIRECTDRAWSURFACE7 source, // source surface to draw
					  int x, int y,                 // position to draw at
					  int width, int height,        // size of source surface
					  LPDIRECTDRAWSURFACE7 dest,    // surface to draw the surface on
					  int transparent = 1)          // transparency flag
*/
// draw objects
// 把相应的三个异形的每帧动作拷贝进缓冲表面中
// 其中animation_seq[aliens[index].current_frame]决定了产生哪些动作帧
// 在Game_Main函数就已经有定义了static int animation_seq[4] = {0,1,0,2};
// 这里current_frame的范围就是0~3
DDraw_Draw_Surface(aliens[index].frames[animation_seq[aliens[index].current_frame]], 
                   aliens[index].x, aliens[index].y,
                   72,80,
                   lpddsback);

} // end for index


while(FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));

// 每秒30帧
Sleep(33);


// do nothing -- look at pretty picture

// return success or failure or your own return code here
return(1);

} // end Game_Main
示例#13
0
/**
 * vdraw_ddraw_flip(): Flip the screen buffer. [Called by vdraw_flip().]
 * @return 0 on success; non-zero on error.
 */
int vdraw_ddraw_flip(void)
{
	if (!lpDD)
		return -1;
	
	HRESULT rval = DD_OK;
	DDSURFACEDESC2 ddsd;
	ddsd.dwSize = sizeof(ddsd);
	RECT RectSrc;
	
	// Calculate the source rectangle.
	vdraw_ddraw_calc_RectSrc(RectSrc);
	
	if (vdraw_get_fullscreen())
	{
		// Fullscreen.
		if (vdraw_ddraw_is_hw_render())
		{
			// Hardware rendering.
			
			// 1x rendering.
			// TODO: Test this with border color stuff.
			// Wine doesn't seem to have a 320x240 fullscreen mode available...
			// TODO: Test this on a system that supports 1x in fullscreen on DirectDraw.
			
			vdraw_ddraw_draw_text(&ddsd, lpDDS_Back, true);
			if (Video.VSync_FS)
			{
				lpDDS_Flip->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL);
				lpDDS_Primary->Flip(NULL, DDFLIP_WAIT);
			}
			else
			{
				lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL);
				//lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, NULL, NULL);
			}
		}
		else
		{
			// Software rendering.
			LPDIRECTDRAWSURFACE7 curBlit = lpDDS_Blit;
			rval = curBlit->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
			
			if (FAILED(rval))
				goto cleanup_flip;
			
			vdraw_rInfo.destScreen = (void*)ddsd.lpSurface;
			vdraw_rInfo.width = 320;
			vdraw_rInfo.height = 240;
			vdraw_rInfo.destPitch = ddsd.lPitch;
			
			if (vdraw_needs_conversion)
			{
				// Color depth conversion is required.
				vdraw_rgb_convert(&vdraw_rInfo);
			}
			else
			{
				// Color conversion is not required.
				vdraw_blitFS(&vdraw_rInfo);
			}
			
			// Draw the text.
			vdraw_ddraw_draw_text(&ddsd, curBlit, false);
			
			curBlit->Unlock(NULL);
			
			if (curBlit == lpDDS_Back) // note: this can happen in windowed fullscreen, or if CORRECT_256_ASPECT_RATIO is defined and the current display mode is 256 pixels across
			{
				if (Video.VSync_FS)
				{
					int vb;
					lpDD->GetVerticalBlankStatus(&vb);
					if (!vb)
						lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
				}
				
				lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL);
			}
			else
			{
				if (Video.VSync_FS)
				{
					lpDDS_Primary->Flip(NULL, DDFLIP_WAIT);
				}
			}
		}
	}
	else
	{
		// Windowed mode.
		if (!vdraw_ddraw_is_hw_render())
		{
			rval = lpDDS_Blit->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL);
			
			if (FAILED(rval))
				goto cleanup_flip;
			
			vdraw_rInfo.destScreen = (void*)ddsd.lpSurface;
			vdraw_rInfo.width = 320;
			vdraw_rInfo.height = 240;
			vdraw_rInfo.destPitch = ddsd.lPitch;
			
			if (vdraw_needs_conversion)
			{
				// Color depth conversion is required.
				vdraw_rgb_convert(&vdraw_rInfo);
			}
			else
			{
				// Color conversion is not required.
				vdraw_blitW(&vdraw_rInfo);
			}
			
			// Draw the text.
			vdraw_ddraw_draw_text(&ddsd, lpDDS_Blit, false);
			
			lpDDS_Blit->Unlock(NULL);
		}
		else
		{
			// Draw the text.
			vdraw_ddraw_draw_text(&ddsd, lpDDS_Blit, true);
		}
		
		if (RectDest.top < RectDest.bottom)
		{
			if (Video.VSync_W)
			{
				int vb;
				lpDD->GetVerticalBlankStatus(&vb);
				if (!vb)
					lpDD->WaitForVerticalBlank(DDWAITVB_BLOCKBEGIN, 0);
			}
			
			// Blit the image.
			rval = lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, DDBLT_WAIT | DDBLT_ASYNC, NULL);
			//rval = lpDDS_Primary->Blt(&RectDest, lpDDS_Back, &RectSrc, NULL, NULL);
		}
	}

cleanup_flip:
	if (rval == DDERR_SURFACELOST)
		rval = vdraw_ddraw_restore_graphics();
	
	return 1;
}
示例#14
0
/**
 * vdraw_ddraw_clear_primary_screen(): Clear the primary screen.
 * @return 0 on success; non-zero on error.
 */
int WINAPI vdraw_ddraw_clear_primary_screen(void)
{
	if (!lpDD || !lpDDS_Primary)
		return -1;
	
	DDSURFACEDESC2 ddsd;
	DDBLTFX ddbltfx;
	RECT rd;
	POINT p;
	
	memset(&ddsd, 0, sizeof(ddsd));
	ddsd.dwSize = sizeof(ddsd);
	
	memset(&ddbltfx, 0, sizeof(ddbltfx));
	ddbltfx.dwSize = sizeof(ddbltfx);
	ddbltfx.dwFillColor = 0; // Black
	
	if (vdraw_get_fullscreen())
	{
		if (Video.VSync_FS)
		{
			lpDDS_Flip->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
			lpDDS_Primary->Flip(NULL, DDFLIP_WAIT);
			
			lpDDS_Flip->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
			lpDDS_Primary->Flip(NULL, DDFLIP_WAIT);
			
			lpDDS_Flip->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
			lpDDS_Primary->Flip(NULL, DDFLIP_WAIT);
		}
		else
		{
			lpDDS_Primary->Blt(NULL, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
		}
	}
	else
	{
		p.x = p.y = 0;
		GetClientRect(gens_window, &rd);
		ClientToScreen(gens_window, &p);
		
		rd.left = p.x;
		rd.top = p.y;
		rd.right += p.x;
		rd.bottom += p.y;
		
		// Clip the destination rectangle to the screen.
		if (rd.bottom > vdraw_rectDisplay.bottom)
			rd.bottom += (vdraw_rectDisplay.bottom - rd.bottom);
		if (rd.top < vdraw_rectDisplay.top)
			rd.top += (vdraw_rectDisplay.top - rd.top);
		if (rd.left < vdraw_rectDisplay.left)
			rd.left += (vdraw_rectDisplay.left - rd.left);
		if (rd.right > vdraw_rectDisplay.right)
			rd.right += (vdraw_rectDisplay.right - rd.right);
		
		if (rd.top < rd.bottom)
			lpDDS_Primary->Blt(&rd, NULL, NULL, DDBLT_WAIT | DDBLT_COLORFILL, &ddbltfx);
	}
	
	return 0;
}