CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

GBUFFER.CPP (32817B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /***************************************************************************
     17  **   C O N F I D E N T I A L --- W E S T W O O D   A S S O C I A T E S   **
     18  ***************************************************************************
     19  *                                                                         *
     20  *                 Project Name : Westwood 32 bit Library                  *
     21  *                                                                         *
     22  *                    File Name : GBUFFER.CPP                              *
     23  *                                                                         *
     24  *                   Programmer : Phil W. Gorrow                           *
     25  *                                                                         *
     26  *                   Start Date : May 3, 1994                              *
     27  *                                                                         *
     28  *                  Last Update : October 9, 1995   []                     *
     29  *                                                                         *
     30  *-------------------------------------------------------------------------*
     31  * Functions:                                                              *
     32  *   VVPC::VirtualViewPort -- Default constructor for a virtual viewport   *
     33  *   VVPC:~VirtualViewPortClass -- Destructor for a virtual viewport       *
     34  *   VVPC::Clear -- Clears a graphic page to correct color                 *
     35  *   VBC::VideoBufferClass -- Lowlevel constructor for video buffer class  *
     36  *   GVPC::Change -- Changes position and size of a Graphic View Port      *
     37  *   VVPC::Change -- Changes position and size of a Video View Port      	*
     38  *   Set_Logic_Page -- Sets LogicPage to new buffer                        *
     39  *   GBC::DD_Init -- Inits a direct draw surface for a GBC                 *
     40  *   GBC::Init -- Core function responsible for initing a GBC              *
     41  *   GBC::Lock -- Locks a Direct Draw Surface                              *
     42  *   GBC::Unlock -- Unlocks a direct draw surface                          *
     43  *   GBC::GraphicBufferClass -- Default constructor (requires explicit init)*
     44  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     45 
     46 #ifndef GBUFFER_H
     47 #include "gbuffer.h"
     48 #include "misc.h"
     49 #endif
     50 //#pragma inline
     51 
     52 int		TotalLocks;
     53 BOOL 	AllowHardwareBlitFills = TRUE;
     54 
     55 
     56 //int	CacheAllowed;
     57 
     58 /*=========================================================================*/
     59 /* The following PRIVATE functions are in this file:                       */
     60 /*=========================================================================*/
     61 
     62 
     63 /*= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*/
     64 
     65 
     66 
     67 /***************************************************************************
     68  * GVPC::GRAPHICVIEWPORTCLASS -- Constructor for basic view port class     *
     69  *                                                   m                      *
     70  * INPUT:		GraphicBufferClass * gbuffer	- buffer to attach to			*
     71  *					int x								- x offset into buffer			*
     72  *					int y								- y offset into buffer			*
     73  *					int w								- view port width in pixels   *
     74  *					int h   							- view port height in pixels	*
     75  *                                                                         *
     76  * OUTPUT:     Constructors may not have a return value							*
     77  *                                                                         *
     78  * HISTORY:                                                                *
     79  *   05/09/1994 PWG : Created.                                             *
     80  *=========================================================================*/
     81 GraphicViewPortClass::GraphicViewPortClass(GraphicBufferClass *gbuffer, int x, int y, int w, int h) :
     82 	LockCount(0),
     83 	GraphicBuff(NULL)
     84 {
     85 	Attach(gbuffer, x, y, w, h);
     86 }
     87 
     88 /***************************************************************************
     89  * GVPC::GRAPHICVIEWPORTCLASS -- Default constructor for view port class   *
     90  *                                                                         *
     91  * INPUT:		none                                                        *
     92  *                                                                         *
     93  * OUTPUT:     none                                                        *
     94  *                                                                         *
     95  * HISTORY:                                                                *
     96  *   05/09/1994 PWG : Created.                                             *
     97  *=========================================================================*/
     98 GraphicViewPortClass::GraphicViewPortClass(void)
     99 {
    100 }
    101 
    102 /***************************************************************************
    103  * GVPC::~GRAPHICVIEWPORTCLASS -- Destructor for GraphicViewPortClass		*
    104  *                                                                         *
    105  * INPUT:		none                                                        *
    106  *                                                                         *
    107  * OUTPUT:     A destructor may not return a value.                        *
    108  *                                                                         *
    109  * HISTORY:                                                                *
    110  *   05/10/1994 PWG : Created.                                             *
    111  *=========================================================================*/
    112 GraphicViewPortClass::~GraphicViewPortClass(void)
    113 {
    114  	Offset			= 0;
    115 	Width				= 0;										// Record width of Buffer
    116 	Height			= 0;										// Record height of Buffer
    117 	XAdd				= 0;										// Record XAdd of Buffer
    118 	XPos				= 0;										// Record XPos of Buffer
    119 	YPos				= 0;										// Record YPos of Buffer
    120 	Pitch				= 0;										// Record width of Buffer
    121 	IsDirectDraw	= FALSE;
    122 	LockCount		= 0;
    123 	GraphicBuff		= NULL;
    124 }
    125 
    126 /***************************************************************************
    127  * GVPC::ATTACH -- Attaches a viewport to a buffer class                   *
    128  *                                                                         *
    129  * INPUT:		GraphicBufferClass *g_buff	- pointer to gbuff to attach to  *
    130  *					int x                     - x position to attach to			*
    131  *					int y 							- y position to attach to			*
    132  *					int w							- width of the view port			*
    133  *					int h							- height of the view port			*
    134  *                                                                         *
    135  * OUTPUT:     none                                                        *
    136  *                                                                         *
    137  * HISTORY:                                                                *
    138  *   05/10/1994 PWG : Created.                                             *
    139  *=========================================================================*/
    140 void GraphicViewPortClass::Attach(GraphicBufferClass *gbuffer, int x, int y, int w, int h)
    141 {
    142 	/*======================================================================*/
    143 	/* Can not attach a Graphic View Port if it is actually the physical		*/
    144 	/*	   representation of a Graphic Buffer.											*/
    145 	/*======================================================================*/
    146 	if (this == Get_Graphic_Buffer())  {
    147 		return;
    148 	}
    149 
    150 	/*======================================================================*/
    151 	/* Verify that the x and y coordinates are valid and placed within the	*/
    152 	/*		physical buffer.																	*/
    153 	/*======================================================================*/
    154 	if (x < 0) 										// you cannot place view port off
    155 		x = 0;										//		the left edge of physical buf
    156 	if (x >= gbuffer->Get_Width())			// you cannot place left edge off
    157 		x = gbuffer->Get_Width() - 1;			//		the right edge of physical buf
    158 	if (y < 0) 										// you cannot place view port off
    159 		y = 0;										//		the top edge of physical buf
    160 	if (y >= gbuffer->Get_Height()) 			// you cannot place view port off
    161 		y = gbuffer->Get_Height() - 1;		//		bottom edge of physical buf
    162 
    163 	/*======================================================================*/
    164 	/* Adjust the width and height of necessary										*/
    165 	/*======================================================================*/
    166 	if (x + w > gbuffer->Get_Width()) 		// if the x plus width is larger
    167 		w = gbuffer->Get_Width() - x;			//		than physical, fix width
    168 
    169 	if (y + h > gbuffer->Get_Height()) 		// if the y plus height is larger
    170 		h = gbuffer->Get_Height() - y;		//		than physical, fix height
    171 
    172 	/*======================================================================*/
    173 	/* Get a pointer to the top left edge of the buffer.							*/
    174 	/*======================================================================*/
    175  	Offset 		= gbuffer->Get_Offset() + ((gbuffer->Get_Width()+gbuffer->Get_Pitch()) * y) + x;
    176 
    177 	/*======================================================================*/
    178 	/* Copy over all of the variables that we need to store.						*/
    179 	/*======================================================================*/
    180  	XPos			= x;
    181  	YPos			= y;
    182  	XAdd			= gbuffer->Get_Width() - w;
    183  	Width			= w;
    184  	Height		= h;
    185 	Pitch			= gbuffer->Get_Pitch();
    186  	GraphicBuff = gbuffer;
    187 	IsDirectDraw= gbuffer->IsDirectDraw;
    188 }
    189 
    190 
    191 /***************************************************************************
    192  * GVPC::CHANGE -- Changes position and size of a Graphic View Port        *
    193  *                                                                         *
    194  * INPUT:   	int the new x pixel position of the graphic view port      *
    195  *					int the new y pixel position of the graphic view port		*
    196  *					int the new width of the viewport in pixels						*
    197  *					int the new height of the viewport in pixels					*
    198  *                                                                         *
    199  * OUTPUT:  	BOOL whether the Graphic View Port could be sucessfully     *
    200  *				      resized.																	*
    201  *                                                                         *
    202  * WARNINGS:   You may not resize a Graphic View Port which is derived 		*
    203  *						from a Graphic View Port Buffer, 								*
    204  *                                                                         *
    205  * HISTORY:                                                                *
    206  *   09/14/1994 SKB : Created.                                             *
    207  *=========================================================================*/
    208 BOOL GraphicViewPortClass::Change(int x, int y, int w, int h)
    209 {
    210 	/*======================================================================*/
    211 	/* Can not change a Graphic View Port if it is actually the physical		*/
    212 	/*	   representation of a Graphic Buffer.											*/
    213 	/*======================================================================*/
    214 	if (this == Get_Graphic_Buffer())  {
    215 		return(FALSE);
    216 	}
    217 
    218 	/*======================================================================*/
    219 	/* Since there is no allocated information, just re-attach it to the		*/
    220 	/*		existing graphic buffer as if we were creating the						*/
    221 	/*		GraphicViewPort.																	*/
    222 	/*======================================================================*/
    223 	Attach(Get_Graphic_Buffer(), x, y, w, h);
    224 	return(TRUE);
    225 }
    226 
    227 
    228 /***************************************************************************
    229  * GBC::DD_INIT -- Inits a direct draw surface for a GBC                   *
    230  *                                                                         *
    231  * INPUT:		none                                                        *
    232  *                                                                         *
    233  * OUTPUT:     none                                                        *
    234  *                                                                         *
    235  * HISTORY:                                                                *
    236  *   10/09/1995     : Created.                                             *
    237  *=========================================================================*/
    238 void GraphicBufferClass::DD_Init(GBC_Enum flags)
    239 {
    240 	//
    241 	// Create the direct draw surface description
    242 	//
    243 	memset (&VideoSurfaceDescription , 0 , sizeof ( VideoSurfaceDescription ));
    244 
    245 	VideoSurfaceDescription.dwSize			= sizeof( VideoSurfaceDescription );
    246 	VideoSurfaceDescription.dwFlags 			= DDSD_CAPS;
    247 	VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    248 
    249 
    250 	if (!(flags & GBC_VISIBLE)) {
    251 		VideoSurfaceDescription.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
    252 		VideoSurfaceDescription.dwFlags 		  |=	DDSD_HEIGHT | DDSD_WIDTH;
    253 		VideoSurfaceDescription.dwHeight			= Height;
    254 		VideoSurfaceDescription.dwWidth			= Width;
    255 	}
    256 
    257 	//
    258 	// Need to set the DDSCAPS_MODEX  flag if we want a 320 wide mode
    259 	//
    260 	if ( Width == 320 ) {
    261 		VideoSurfaceDescription.ddsCaps.dwCaps |= DDSCAPS_MODEX;
    262 	}
    263 
    264 	//
    265 	// Call CreateSurface
    266 	//
    267 	DirectDrawObject->CreateSurface( &VideoSurfaceDescription , &VideoSurfacePtr , NULL);
    268 	AllSurfaces.Add_DD_Surface (VideoSurfacePtr);
    269 
    270 	if ( GBC_VISIBLE & flags ){
    271 		PaletteSurface=VideoSurfacePtr;
    272 	}
    273 
    274 	Allocated		= FALSE;			//	even if system alloced, dont flag it cuz
    275 											//   we dont want it freed.
    276 	IsDirectDraw	= TRUE;			//	flag it as a video surface
    277 	Offset			= NOT_LOCKED;	//	flag it as unavailable for reading or writing
    278 	LockCount		= 0;				//  surface is not locked
    279 }
    280 
    281 
    282 void GraphicBufferClass::Attach_DD_Surface (GraphicBufferClass * attach_buffer)
    283 {
    284 	VideoSurfacePtr->AddAttachedSurface (attach_buffer->Get_DD_Surface());
    285 }
    286 
    287 
    288 /***************************************************************************
    289  * GBC::INIT -- Core function responsible for initing a GBC                *
    290  *                                                                         *
    291  * INPUT:		int 		- the width in pixels of the GraphicBufferClass    *
    292  *					int		- the heigh in pixels of the GraphicBufferClass		*
    293  *					void *	- pointer to user supplied buffer (system will		*
    294  *								  allocate space if buffer is NULL)						*
    295  *					long		- size of the user provided buffer						*
    296  *					GBC_Enum	- flags if this is defined as a direct draw			*
    297  *	                       surface														*
    298  *                                                                         *
    299  * OUTPUT:		none                                                        *
    300  *                                                                         *
    301  * HISTORY:                                                                *
    302  *   10/09/1995     : Created.                                             *
    303  *=========================================================================*/
    304 void GraphicBufferClass::Init(int w, int h, void *buffer, long size, GBC_Enum flags)
    305 {
    306 	Size			= size;									// find size of physical buffer
    307 	Width			= w;										// Record width of Buffer
    308 	Height		= h;										// Record height of Buffer
    309 
    310 	//
    311 	// If the surface we are creating is a direct draw object then
    312 	//   we need to do a direct draw init.  Otherwise we will do
    313 	//   a normal alloc.
    314 	//
    315 	if (flags & (GBC_VIDEOMEM | GBC_VISIBLE)) {
    316 		DD_Init(flags);
    317 	} else {
    318 		if (buffer) {										// if buffer is specified
    319 			Buffer		= (BYTE *)buffer;				//		point to it and mark
    320 			Allocated	= FALSE;							//		it as user allocated
    321 		} else {
    322 			if (!Size) Size = w*h;
    323 			Buffer		= new BYTE[Size];				// otherwise allocate it and
    324 			Allocated	= TRUE;							//		mark it system alloced
    325 		}
    326 		Offset			= (long)Buffer;				// Get offset to the buffer
    327 		IsDirectDraw	= FALSE;
    328 	}
    329 
    330 	Pitch			= 0;										// Record width of Buffer
    331 	XAdd			= 0;										// Record XAdd of Buffer
    332 	XPos			= 0;										// Record XPos of Buffer
    333 	YPos			= 0;										// Record YPos of Buffer
    334 	GraphicBuff	= this;									// Get a pointer to our self
    335 }
    336 
    337 
    338 /***********************************************************************************************
    339  * GBC::Un_Init -- releases the video surface belonging to this gbuffer                        *
    340  *                                                                                             *
    341  *                                                                                             *
    342  *                                                                                             *
    343  * INPUT:    Nothing                                                                           *
    344  *                                                                                             *
    345  * OUTPUT:   Nothing                                                                           *
    346  *                                                                                             *
    347  * WARNINGS: None                                                                              *
    348  *                                                                                             *
    349  * HISTORY:                                                                                    *
    350  *    6/6/96 12:44PM ST : Created                                                              *
    351  *=============================================================================================*/
    352 
    353 void GraphicBufferClass::Un_Init (void)
    354 {
    355 	if ( IsDirectDraw ){
    356 
    357 		if ( VideoSurfacePtr ){
    358 
    359 			while ( LockCount ){
    360 
    361 				if (VideoSurfacePtr->Unlock ( NULL ) == DDERR_SURFACELOST){
    362 					if (Gbuffer_Focus_Loss_Function){
    363 						Gbuffer_Focus_Loss_Function();
    364 					}
    365 					AllSurfaces.Restore_Surfaces();
    366 				}
    367 			}
    368 
    369 			AllSurfaces.Remove_DD_Surface (VideoSurfacePtr);
    370 			VideoSurfacePtr->Release();
    371 			VideoSurfacePtr = NULL;
    372 		}
    373 	}
    374 }
    375 
    376 
    377 /***************************************************************************
    378  * GBC::GRAPHICBUFFERCLASS -- Default constructor (requires explicit init) *
    379  *                                                                         *
    380  * INPUT:		none                                                        *
    381  *                                                                         *
    382  * OUTPUT:     none                                                        *
    383  *                                                                         *
    384  * HISTORY:                                                                *
    385  *   10/09/1995     : Created.                                             *
    386  *=========================================================================*/
    387 GraphicBufferClass::GraphicBufferClass(void)
    388 {
    389 	GraphicBuff			= this; 							// Get a pointer to our self
    390 	VideoSurfacePtr	= NULL;
    391 	memset(&VideoSurfaceDescription, 0, sizeof(DDSURFACEDESC));
    392 }
    393 
    394 
    395 /***************************************************************************
    396  * GBC::GRAPHICBUFFERCLASS -- Constructor for fixed size buffers           *
    397  *                                                                         *
    398  * INPUT:		long size		- size of the buffer to create					*
    399  *					int w			- width of buffer in pixels (default = 320)  *
    400  *					int h			- height of buffer in pixels (default = 200) *
    401  *					void *buffer	- a pointer to the buffer if any (optional)	*
    402  *                                                                         *
    403  * OUTPUT:                                                                 *
    404  *                                                                         *
    405  * WARNINGS:                                                               *
    406  *                                                                         *
    407  * HISTORY:                                                                *
    408  *   05/13/1994 PWG : Created.                                             *
    409  *=========================================================================*/
    410 GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer, long size)
    411 {
    412 	Init(w, h, buffer, size, GBC_NONE);
    413 }
    414 /*=========================================================================*
    415  * GBC::GRAPHICBUFFERCLASS -- inline constructor for GraphicBufferClass		*
    416  *                                                                         *
    417  * INPUT:		int w			- width of buffer in pixels (default = 320)  *
    418  *					int h			- height of buffer in pixels (default = 200) *
    419  *					void *buffer	- a pointer to the buffer if any (optional)	*
    420  *                                                                         *
    421  * OUTPUT:     none                                                        *
    422  *                                                                         *
    423  * HISTORY:                                                                *
    424  *   05/03/1994 PWG : Created.                                             *
    425  *=========================================================================*/
    426 GraphicBufferClass::GraphicBufferClass(int w, int h, void *buffer)
    427 {
    428 	Init(w, h, buffer, w * h, GBC_NONE);
    429 }
    430 
    431 /*====================================================================================*
    432  * GBC::GRAPHICBUFFERCLASS -- contructor for GraphicsBufferClass with special flags   *
    433  *                                                                                    *
    434  * INPUT:		int w			- width of buffer in pixels (default = 320)           *
    435  *					int h			- height of buffer in pixels (default = 200)      *
    436  *					void *buffer	- unused                                	      *
    437  *               unsigned flags - flags for creation of special buffer types          *
    438  *                                GBC_VISIBLE - buffer is a visible screen surface    *
    439  *                                GBC_VIDEOMEM - buffer resides in video memory       *
    440  *                                                                                    *
    441  * OUTPUT:     none                                                                   *
    442  *                                                                                    *
    443  * HISTORY:                                                                           *
    444  *   09-21-95 04:19pm ST : Created                                                    *
    445  *====================================================================================*/
    446 GraphicBufferClass::GraphicBufferClass(int w, int h, GBC_Enum flags)
    447 {
    448 	Init(w, h, NULL, w * h, flags);
    449 }
    450 
    451 /*=========================================================================*
    452  * GBC::~GRAPHICBUFFERCLASS -- Destructor for the graphic buffer class     *
    453  *                                                                         *
    454  *	INPUT:		none																			*
    455  *                                                                         *
    456  * OUTPUT:     none                                                        *
    457  *                                                                         *
    458  * HISTORY:                                                                *
    459  *   05/03/1994 PWG : Created.                                             *
    460  *=========================================================================*/
    461 GraphicBufferClass::~GraphicBufferClass()
    462 {
    463 
    464 //
    465 // Release the direct draw surface if it exists
    466 //
    467 	Un_Init();
    468 }
    469 
    470 
    471 
    472 /***************************************************************************
    473  * SET_LOGIC_PAGE -- Sets LogicPage to new buffer                          *
    474  *                                                                         *
    475  * INPUT:		GraphicBufferClass * the buffer we are going to set         *
    476  *                                                                         *
    477  * OUTPUT:     GraphicBufferClass * the previous buffer type					*
    478  *                                                                         *
    479  * WARNINGS:                                                               *
    480  *                                                                         *
    481  * HISTORY:                                                                *
    482  *   02/23/1995 PWG : Created.                                             *
    483  *=========================================================================*/
    484 GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass *ptr)
    485 {
    486 	GraphicViewPortClass *old = LogicPage;
    487 	LogicPage					= ptr;
    488 	return(old);
    489 }
    490 
    491 /***************************************************************************
    492  * SET_LOGIC_PAGE -- Sets LogicPage to new buffer                          *
    493  *                                                                         *
    494  * INPUT:		GraphicBufferClass & the buffer we are going to set         *
    495  *                                                                         *
    496  * OUTPUT:     GraphicBufferClass * the previous buffer type					*
    497  *                                                                         *
    498  * WARNINGS:                                                               *
    499  *                                                                         *
    500  * HISTORY:                                                                *
    501  *   02/23/1995 PWG : Created.                                             *
    502  *=========================================================================*/
    503 GraphicViewPortClass *Set_Logic_Page(GraphicViewPortClass &ptr)
    504 {
    505 	GraphicViewPortClass *old = LogicPage;
    506 	LogicPage					= &ptr;
    507 	return(old);
    508 }
    509 
    510 
    511 /***************************************************************************
    512  * GBC::LOCK -- Locks a Direct Draw Surface                                *
    513  *                                                                         *
    514  * INPUT:		none                                                        *
    515  *                                                                         *
    516  * OUTPUT:     none                                                        *
    517  *                                                                         *
    518  * HISTORY:                                                                *
    519  *   10/09/1995     : Created.                                             *
    520  *   10/09/1995     : Code stolen from Steve Tall                          *
    521  *=========================================================================*/
    522 extern	void Colour_Debug (int call_number);
    523 extern bool GameInFocus;
    524 
    525 extern void Block_Mouse(GraphicBufferClass *buffer);
    526 extern void Unblock_Mouse(GraphicBufferClass *buffer);
    527 
    528 BOOL GraphicBufferClass::Lock(void)
    529 {
    530 	HRESULT	result;
    531 	int		restore_attempts=0;
    532 
    533 	//
    534 	// If its not a direct draw surface then the lock is always sucessful.
    535 	//
    536 	if (!IsDirectDraw) return(TRUE);
    537 
    538 	/*
    539 	** If the video surface pointer is null then return
    540 	*/
    541 	if (!VideoSurfacePtr) return (FALSE);
    542 
    543 	/*
    544 	** If we dont have focus then return failure
    545 	*/
    546 	if (!GameInFocus) return (FALSE);
    547 
    548 
    549 	Block_Mouse(this);
    550 
    551 
    552 	//
    553 	// If surface is already locked then inc the lock count and return true
    554 	//
    555 	if (LockCount){
    556 		LockCount++;
    557 		Unblock_Mouse(this);
    558 		return(TRUE);
    559 	}
    560 
    561 	//
    562 	// If it isn't locked at all then we will have to request that Direct
    563 	// Draw actually lock the surface.
    564 	//
    565 
    566 	if (VideoSurfacePtr){
    567 		while (!LockCount && restore_attempts<2) {
    568 			result = VideoSurfacePtr->Lock ( NULL
    569 										, &(VideoSurfaceDescription)
    570 										, DDLOCK_WAIT
    571 										, NULL);
    572 
    573 			switch (result){
    574 				case DD_OK :
    575 					Offset	= (unsigned long)VideoSurfaceDescription.lpSurface;
    576 					Pitch		= VideoSurfaceDescription.lPitch;
    577 					Pitch	  -= Width;
    578 					LockCount++;		// increment count so we can track if
    579 					TotalLocks++;		// Total number of times we have locked (for debugging)
    580 					//Colour_Debug (1);
    581 					Unblock_Mouse(this);
    582 					return (TRUE);		// we locked it multiple times.
    583 
    584 				case DDERR_SURFACELOST :
    585 					if (Gbuffer_Focus_Loss_Function){
    586 						Gbuffer_Focus_Loss_Function();
    587 					}
    588 					AllSurfaces.Restore_Surfaces();
    589 					restore_attempts++;
    590 					break;
    591 
    592 				default :
    593 					Unblock_Mouse(this);
    594 					return (FALSE);
    595 			}
    596 		}
    597 	}
    598 	//Colour_Debug(1);
    599 	Unblock_Mouse(this);
    600 	return (FALSE);		//Return false because we couldnt lock or restore the surface
    601 }
    602 
    603 /***************************************************************************
    604  * GBC::UNLOCK -- Unlocks a direct draw surface                            *
    605  *                                                                         *
    606  * INPUT:		none                                                        *
    607  *                                                                         *
    608  * OUTPUT:     none                                                        *
    609  *                                                                         *
    610  * HISTORY:                                                                *
    611  *   10/09/1995     : Created.                                             *
    612  *   10/09/1995     : Code stolen from Steve Tall                          *
    613  *=========================================================================*/
    614 
    615 
    616 BOOL GraphicBufferClass::Unlock(void)
    617 {
    618 	//
    619 	// If there is no lock count or this is not a direct draw surface
    620 	// then just return true as there is no harm done.
    621 	//
    622 	if (!(LockCount && IsDirectDraw)) {
    623 		return(TRUE);
    624 	}
    625 
    626 	//
    627 	// If lock count is directly equal to one then we actually need to
    628 	// unlock so just give it a shot.
    629 	//
    630 	if (LockCount == 1 && VideoSurfacePtr) {
    631 		Block_Mouse(this);
    632 		if ( VideoSurfacePtr->Unlock ( NULL ) != DD_OK ){
    633 			Unblock_Mouse(this);
    634 			return(FALSE);
    635 		} else {
    636 			Offset=NOT_LOCKED;
    637 			LockCount--;
    638 			Unblock_Mouse(this);
    639 			return(TRUE);
    640 		}
    641 	}
    642 	//Colour_Debug (0);
    643 	LockCount--;
    644 	return(TRUE);
    645 }
    646 
    647 
    648 /***********************************************************************************************
    649  * GVPC::DD_Linear_Blit_To_Linear -- blit using the hardware blitter                           *
    650  *                                                                                             *
    651  *                                                                                             *
    652  *                                                                                             *
    653  * INPUT:    destination vvpc                                                                  *
    654  *           x coord to blit from                                                              *
    655  *           y coord to blit from                                                              *
    656  *           x coord to blit to                                                                *
    657  *           y coord to blit to                                                                *
    658  *           width to blit                                                                     *
    659  *           height to blit                                                                    *
    660  *                                                                                             *
    661  * OUTPUT:   DD_OK if successful                                                               *
    662  *                                                                                             *
    663  * WARNINGS: None                                                                              *
    664  *                                                                                             *
    665  * HISTORY:                                                                                    *
    666  *   09-22-95 11:05am ST : Created                                                             *
    667  *=============================================================================================*/
    668 
    669 HRESULT GraphicViewPortClass::DD_Linear_Blit_To_Linear (
    670 								  GraphicViewPortClass &dest
    671 								, int source_x
    672 								, int source_y
    673 								, int dest_x
    674 								, int dest_y
    675 								, int width
    676 								, int height
    677 								, BOOL mask )
    678 
    679 {
    680 	RECT	source_rectangle;
    681 	RECT	dest_rectangle;
    682 	int		key_source=0;
    683 
    684 	if ( mask ){
    685 		key_source=DDBLT_KEYSRC;
    686 	}
    687 
    688 
    689 	source_rectangle.left 	= source_x;
    690 	source_rectangle.top  	= source_y;
    691 	source_rectangle.right	= source_x+width;
    692 	source_rectangle.bottom	= source_y+height;
    693 
    694 	dest_rectangle.left 	= dest_x;
    695 	dest_rectangle.top  	= dest_y;
    696 	dest_rectangle.right	= dest_x+width;
    697 	dest_rectangle.bottom	= dest_y+height;
    698 
    699    return (	dest.GraphicBuff->Get_DD_Surface()->Blt ( &dest_rectangle,
    700 												GraphicBuff->Get_DD_Surface(),
    701 												&source_rectangle,
    702 												key_source | DDBLT_WAIT | DDBLT_ASYNC,
    703 												NULL ) );
    704 }
    705 
    706 
    707