CnC_Remastered_Collection

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

MOUSEWW.CPP (20098B)


      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  *                                                                                             *
     18  *                 Project Name : Westwood 32 bit Library                                      *
     19  *                                                                                             *
     20  *                    File Name : MOUSE.CPP                                                    *
     21  *                                                                                             *
     22  *                   Programmer : Philip W. Gorrow                                             *
     23  *                                                                                             *
     24  *                   Start Date : 12/12/95                                                     *
     25  *                                                                                             *
     26  *                  Last Update : December 12, 1995 [PWG]                                      *
     27  *                                                                                             *
     28  *---------------------------------------------------------------------------------------------*
     29  * Functions:                                                                                  *
     30  *   WWMouseClass::WWMouseClass -- Constructor for the Mouse Class                                 *
     31  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     32 
     33 #include "mouse.h"
     34 #include <mmsystem.h>
     35 
     36 static WWMouseClass *_Mouse=NULL;
     37 void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD  res2, DWORD  res3 );
     38 extern bool GameInFocus;
     39 
     40 
     41 /***********************************************************************************************
     42  * MOUSECLASS::MOUSECLASS -- Constructor for the Mouse Class                                   *
     43  *                                                                                             *
     44  * INPUT:		GraphicViewPortClass * screen - pointer to screen mouse is created for				 *
     45  *                                                                                             *
     46  * OUTPUT:     none                                                                            *
     47  *                                                                                             *
     48  * HISTORY:                                                                                    *
     49  *   12/12/1995 PWG : Created.                                                                 *
     50  *=============================================================================================*/
     51 WWMouseClass::WWMouseClass(GraphicViewPortClass *scr, int mouse_max_width, int mouse_max_height)
     52 {
     53 	MouseCursor 	= new char[mouse_max_width * mouse_max_height];
     54 	MouseXHot		= 0;
     55 	MouseYHot		= 0;
     56 	CursorWidth		= 0;
     57 	CursorHeight	= 0;
     58 
     59 	MouseBuffer		= new char[mouse_max_width * mouse_max_height];
     60 	MouseBuffX		= -1;
     61 	MouseBuffY  	= -1;
     62 	MaxWidth			= mouse_max_width;
     63 	MaxHeight		= mouse_max_height;
     64 
     65 	MouseCXLeft		= 0;
     66 	MouseCYUpper	= 0;
     67 	MouseCXRight	= 0;
     68 	MouseCYLower	= 0;
     69 	MCFlags			= 0;
     70 	MCCount			= 0;
     71 
     72 	Screen			= scr;
     73 	PrevCursor		= NULL;
     74 	MouseUpdate		= 0;
     75 	State				= 1;
     76 	timeBeginPeriod ( 1000/ 60);
     77 
     78 	InitializeCriticalSection (&MouseCriticalSection);
     79 	//
     80 	// Install the timer callback event handler
     81 	//
     82 
     83 	EraseBuffer		= new char[mouse_max_width * mouse_max_height];
     84 	EraseBuffX		= -1;
     85 	EraseBuffY  	= -1;
     86 	EraseBuffHotX	= -1;
     87 	EraseBuffHotY	= -1;
     88 	EraseFlags		= FALSE;
     89 
     90 	_Mouse			= this;
     91 	
     92 	// Add TIME_KILL_SYNCHRONOUS flag. ST - 2/13/2019 5:07PM
     93 	//TimerHandle = timeSetEvent( 1000/60 , 1 , ::Process_Mouse, 0 , TIME_PERIODIC);
     94 	//TimerHandle = timeSetEvent( 1000/60 , 1 , ::Process_Mouse, 0 , TIME_PERIODIC | TIME_KILL_SYNCHRONOUS);		// Removed. ST - 2/13/2019 5:12PM
     95 
     96 	/*
     97 	** Force the windows mouse pointer to stay withing the graphic view port region
     98 	*/
     99 	Set_Cursor_Clip();
    100 }
    101 
    102 WWMouseClass::~WWMouseClass()
    103 {
    104 	MouseUpdate++;
    105 
    106 	if (MouseCursor) delete[] MouseCursor;
    107 	if (MouseBuffer) delete[] MouseBuffer;
    108 	if (TimerHandle) {
    109 		timeKillEvent(TimerHandle);
    110 		TimerHandle = 0;		//ST - 2/13/2019 5:12PM
    111 	}
    112 	timeEndPeriod (1000/60);
    113 	DeleteCriticalSection(&MouseCriticalSection);
    114 
    115 	/*
    116 	** Free up the windows mouse pointer movement
    117 	*/
    118 	Clear_Cursor_Clip();
    119 }
    120 
    121 
    122 void Block_Mouse(GraphicBufferClass *buffer)
    123 {
    124 	if (_Mouse){
    125 		_Mouse->Block_Mouse(buffer);
    126 	}
    127 }
    128 
    129 
    130 void Unblock_Mouse(GraphicBufferClass *buffer)
    131 {
    132 	if (_Mouse){
    133 		_Mouse->Unblock_Mouse(buffer);
    134 	}
    135 }
    136 
    137 
    138 
    139 void WWMouseClass::Block_Mouse(GraphicBufferClass *buffer)
    140 {
    141 	if (buffer == Screen->Get_Graphic_Buffer()){
    142 		EnterCriticalSection(&MouseCriticalSection);
    143 	}
    144 }
    145 
    146 
    147 void WWMouseClass::Unblock_Mouse(GraphicBufferClass *buffer)
    148 {
    149 	if (buffer == Screen->Get_Graphic_Buffer()){
    150 		LeaveCriticalSection(&MouseCriticalSection);
    151 	}
    152 }
    153 
    154 
    155 
    156 
    157 
    158 void WWMouseClass::Set_Cursor_Clip(void)
    159 {
    160 #if (0)		// Not needed. ST - 1/3/2019 2:18PM
    161 	if (Screen){
    162 		RECT	region;
    163 
    164 		region.left		= 0;
    165 		region.top 		= 0;
    166 		region.right	= Screen->Get_Width();
    167 		region.bottom	= Screen->Get_Height();
    168 
    169 		ClipCursor(&region);
    170 	}
    171 #endif
    172 }
    173 
    174 
    175 
    176 void WWMouseClass::Clear_Cursor_Clip(void)
    177 {
    178 #if (0)
    179 	ClipCursor(NULL);
    180 #endif
    181 }
    182 
    183 
    184 
    185 void WWMouseClass::Process_Mouse(void)
    186 {
    187 //ST - 1/3/2019 10:50AM	
    188 	return;
    189 #if (0)
    190 	POINT 	pt;					// define a structure to hold current cursor pos
    191 
    192 	//
    193 	// If the mouse is currently hidden or it has not been installed, then we
    194 	// have no need to redraw the mouse.
    195 	//
    196 	if (!Screen || !_Mouse || State > 0 || MouseUpdate || EraseFlags || !GameInFocus)
    197 		return;
    198 
    199 	//
    200 	// Make sure there are no conflicts with other
    201 	// threads that may try and lock the screen buffer
    202 	//
    203 	//Block_Mouse(Screen->Get_Graphic_Buffer());
    204 
    205 	//
    206 	// If the screen is already locked by another thread then just exit
    207 	//
    208 	if (Screen->Get_LockCount()!=0){
    209 		//Unblock_Mouse(Screen->Get_Graphic_Buffer());
    210 		return;
    211 	}
    212 
    213 	//
    214 	// Get the mouse's current real cursor position
    215 	//
    216 	GetCursorPos(&pt);			// get the current cursor position
    217 	//
    218 	// If the mouse has moved then we are responsible to redraw the mouse
    219 	//
    220 	if (pt.x != MouseBuffX || pt.y != MouseBuffY) {
    221 		//
    222 		// If we can't lock the surface we need to draw to, we cannot update
    223 		// the mouse.
    224 		//
    225 		if (Screen->Lock()) 	{
    226 			//
    227 			// Erase the old mouse by dumping the mouses shadow buff
    228 			//   to the screen (if its position had ever been recorded).
    229 			//
    230 			Low_Hide_Mouse();
    231 
    232 			//
    233 			// Verify that the mouse has not gone into a conditional hiden area
    234 			// If it has, mark it as being in one.
    235 			//
    236 			if (MCFlags & CONDHIDE && pt.x >= MouseCXLeft && pt.x <= MouseCXRight && pt.y >= MouseCYUpper && pt.y <= MouseCYLower) {
    237 				MCFlags |= CONDHIDDEN;
    238 			}
    239 
    240 			//
    241 			// Show the mouse if we are allowed to.
    242 			//
    243 			if (!(MCFlags & CONDHIDDEN)) 	{
    244 				Low_Show_Mouse(pt.x, pt.y);
    245 			}
    246 			//
    247 			// Finally unlock the destination surface as we have sucessfully
    248 			// updated the mouse.
    249 			//
    250 			Screen->Unlock();
    251 		}
    252 	}
    253 
    254 	//
    255 	// Allow other threads to lock the screen again
    256 	//
    257 	//Unblock_Mouse(Screen->Get_Graphic_Buffer());
    258 #endif
    259 }
    260 
    261 void *WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, void *cursor)
    262 {
    263 //ST - 1/3/2019 10:50AM	
    264 	xhotspot;
    265 	yhotspot;
    266 	cursor;
    267 	return cursor;
    268 
    269 #if (0)
    270 	
    271 	//
    272 	// If the pointer to the cursor we got is invalid, or its the same as the
    273 	// currently set cursor then just return.
    274 	if (!cursor || cursor == PrevCursor)
    275 		return(cursor);
    276 
    277 	//
    278 	// Wait until we have exclusive access to our data
    279 	//
    280 	MouseUpdate++;
    281 	//
    282 	// Since we are updating the mouse we need to hide the cursor so we
    283 	// do not get some sort of weird transformation.
    284 	//
    285 	Hide_Mouse();
    286 	//
    287 	// Now convert the shape to a mouse cursor with the given hotspots and
    288 	// set it as our current mouse.
    289 	//
    290 	void *retval = ASM_Set_Mouse_Cursor(this, xhotspot, yhotspot, cursor);
    291 	//
    292 	// Show the mouse which will force it to appear with the new shape we
    293 	// have assigned.
    294 	//
    295 	Show_Mouse();
    296 	//
    297 	// We are done updating the mouse cursor so on to bigger and better things.
    298 	//
    299 	MouseUpdate--;
    300 	//
    301 	// Return the previous mouse cursor which as conveniantly passed back by
    302 	// Asm_Set_Mouse_Cursor.
    303 	//
    304 	return(retval);
    305 #endif
    306 }
    307 
    308 void WWMouseClass::Low_Hide_Mouse()
    309 {
    310 //ST - 1/3/2019 10:50AM	
    311 #if (0)
    312 	if (!State) {
    313 		if (MouseBuffX != -1 || MouseBuffY != -1) {
    314 			if (Screen->Lock()){
    315 				Mouse_Shadow_Buffer(this, Screen, MouseBuffer, MouseBuffX, MouseBuffY, MouseXHot, MouseYHot, 0);
    316 				Screen->Unlock();
    317 			}
    318 		}
    319 		MouseBuffX = -1;
    320 		MouseBuffY = -1;
    321 	}
    322 #endif
    323 	State++;
    324 }
    325 void WWMouseClass::Hide_Mouse()
    326 {
    327 	MouseUpdate++;
    328 	Low_Hide_Mouse();
    329 	MouseUpdate--;
    330 }
    331 
    332 
    333 void WWMouseClass::Low_Show_Mouse(int x, int y)
    334 {
    335 	//
    336 	// If the mouse is already visible then just ignore the problem.
    337 	//
    338 	if (State == 0) return;
    339 	//
    340 	// Make the mouse a little bit more visible
    341 	//
    342 	State--;
    343 
    344 //ST - 1/3/2019 10:50AM	
    345 #if (0)
    346 
    347 	//
    348 	//	If the mouse is completely visible then draw it at its current
    349 	// position.
    350 	//
    351 	if (!State)	{
    352 		//
    353 		// Try to lock the screen til we sucessfully get a lock.
    354 		//
    355 		if (Screen->Lock()){
    356 			//
    357 			// Save off the area behind the mouse.
    358 			//
    359 			Mouse_Shadow_Buffer(this, Screen, MouseBuffer, x, y, MouseXHot, MouseYHot, 1);
    360 			//
    361 			// Draw the mouse in its new location
    362 			//
    363 			::Draw_Mouse(this, Screen, x, y);
    364 			//
    365 			// Save off the positions that we saved the buffer from
    366 			//
    367 			MouseBuffX = x;
    368 			MouseBuffY = y;
    369 			//
    370 			// Unlock the screen and lets get moving.
    371 			//
    372 			Screen->Unlock();
    373 		}
    374 	}
    375 #endif
    376 }
    377 
    378 void WWMouseClass::Show_Mouse()
    379 {
    380 	POINT	pt;
    381 	GetCursorPos(&pt);
    382 
    383 	MouseUpdate++;
    384 	Low_Show_Mouse(pt.x, pt.y);
    385 	MouseUpdate--;
    386 }
    387 
    388 void WWMouseClass::Conditional_Hide_Mouse(int x1, int y1, int x2, int y2)
    389 {
    390 	POINT	pt;
    391 
    392 	MouseUpdate++;
    393 
    394 	//
    395 	// First of all, adjust all the coordinates so that they handle
    396 	// the fact that the hotspot is not necessarily the upper left
    397 	// corner of the mouse.
    398 	//
    399 	x1 -= (CursorWidth - MouseXHot);
    400 	x1  = MAX(0, x1);
    401 	y1 -= (CursorHeight - MouseYHot);
    402 	y1  = MAX(0, y1);
    403 	x2  += MouseXHot;
    404 	x2  = MIN(x2, Screen->Get_Width());
    405 	y2  += MouseYHot;
    406 	y2  = MIN(y2, Screen->Get_Height());
    407 
    408 	// The mouse could be in one of four conditions.
    409 	// 1) The mouse is visible and no conditional hide has been specified.
    410 	// 	(perform normal region checking with possible hide)
    411 	// 2) The mouse is hidden and no conditional hide as been specified.
    412 	// 	(record region and do nothing)
    413 	// 3) The mouse is visible and a conditional region has been specified
    414 	// 	(expand region and perform check with possible hide).
    415 	// 4) The mouse is already hidden by a previous conditional.
    416 	// 	(expand region and do nothing)
    417 	//
    418 	// First: Set or expand the region according to the specified parameters
    419 	if (!MCCount) {
    420 		MouseCXLeft		= x1;
    421 		MouseCYUpper	= y1;
    422 		MouseCXRight	= x2;
    423 		MouseCYLower	= y2;
    424 	} else {
    425 		MouseCXLeft		= MIN(x1, MouseCXLeft);
    426 		MouseCYUpper	= MIN(y1, MouseCYUpper);
    427 		MouseCXRight	= MAX(x2, MouseCXRight);
    428 		MouseCYLower	= MAX(y2, MouseCYLower);
    429 	}
    430 	//
    431 	// If the mouse isn't already hidden, then check its location against
    432 	// the hiding region and hide if necessary.
    433 	//
    434 	if (!(MCFlags & CONDHIDDEN)) {
    435 		GetCursorPos(&pt);
    436 		if (MouseBuffX >= MouseCXLeft && MouseBuffX <= MouseCXRight && MouseBuffY >= MouseCYUpper && MouseBuffY <= MouseCYLower) {
    437 			Low_Hide_Mouse();
    438 			MCFlags |= CONDHIDDEN;
    439 		}
    440 	}
    441 	//
    442 	// Record the fact that a conditional hide was called and then exit
    443 	//
    444 	//
    445 	MCFlags |= CONDHIDE;
    446 	MCCount++;
    447 	MouseUpdate--;
    448 
    449 }
    450 void WWMouseClass::Conditional_Show_Mouse(void)
    451 {
    452 	MouseUpdate++;
    453 
    454 	//
    455 	// if there are any nested hides then dec the count
    456 	//
    457 	if (MCCount) {
    458 		MCCount--;
    459 		//
    460 		// If the mouse is now not hidden and it had actually been
    461 		// hidden before then display it.
    462 		//
    463 		if (!MCCount) {
    464 			if (MCFlags & CONDHIDDEN) {
    465 				Show_Mouse();
    466 			}
    467 			MCFlags = 0;
    468 		}
    469 	}
    470 
    471 	MouseUpdate--;
    472 }
    473 
    474 
    475 void WWMouseClass::Draw_Mouse(GraphicViewPortClass *scr)
    476 {
    477 	scr;
    478 	return;
    479 //ST - 1/3/2019 10:50AM	
    480 #if (0)
    481 	
    482 	POINT pt;
    483 
    484 	if (State != 0) return;
    485 	MouseUpdate++;
    486 	//
    487 	//	Get the position that the mouse is currently located at
    488 	//
    489 	GetCursorPos(&pt);
    490 	if (MCFlags & CONDHIDE && pt.x >= MouseCXLeft && pt.x <= MouseCXRight && pt.y >= MouseCYUpper && pt.y <= MouseCYLower) {
    491 		Hide_Mouse();
    492 		MCFlags |= CONDHIDDEN;
    493 	} else {
    494 		//
    495 		// If the mouse is already visible then just ignore the problem.
    496 		//
    497 		EraseFlags = TRUE;
    498 
    499 		//
    500 		// Try to lock the screen  - dont do video stuff if we cant.
    501 		//
    502 		if (scr->Lock()){
    503 			//
    504 			// Save off the area behind the mouse into two different buffers, one
    505 			// which will be used to restore the mouse and the other which will
    506 			// be used to restore the hidden surface when we get a chance.
    507 			//
    508 			Mouse_Shadow_Buffer(this, scr, EraseBuffer, pt.x, pt.y, MouseXHot, MouseYHot, 1);
    509 			memcpy(MouseBuffer, EraseBuffer, MaxWidth * MaxHeight);
    510 			//
    511 			// Draw the mouse in its new location
    512 			//
    513 			::Draw_Mouse(this, scr, pt.x, pt.y);
    514 			//
    515 			// Save off the positions that we saved the buffer from
    516 			//
    517 			EraseBuffX 		= pt.x;
    518 			MouseBuffX 		= pt.x;
    519 			EraseBuffY 		= pt.y;
    520 			MouseBuffY 		= pt.y;
    521 			EraseBuffHotX	= MouseXHot;
    522 			EraseBuffHotY	= MouseYHot;
    523 			//
    524 			// Unlock the screen and lets get moving.
    525 			//
    526 			scr->Unlock();
    527 		}
    528 	}
    529 
    530 	MouseUpdate--;
    531 #endif
    532 }
    533 
    534 void WWMouseClass::Erase_Mouse(GraphicViewPortClass *scr, int forced)
    535 {
    536 //ST - 1/3/2019 10:50AM	
    537 	scr;
    538 	forced;
    539 	return;
    540 #if (0)
    541 	//
    542 	// If we are forcing the redraw of a mouse we already managed to
    543 	// restore then just get outta here.
    544 	//
    545 	if (forced && EraseBuffX == -1 && EraseBuffY == -1) return;
    546 
    547 	MouseUpdate++;
    548 
    549 	//
    550 	// If this is not a forced call, only update the mouse is we can legally
    551 	//	lock the buffer.
    552 	//
    553 	if (!forced) {
    554 #if(0)
    555 		if (scr->Lock()) {
    556 			//
    557 			// If the surface has not already been restore then restore it and erase the
    558 			// restoration coordinates so we don't accidentally do it twice.
    559 			//
    560 			if (EraseBuffX != -1 || EraseBuffY != -1) {
    561 				Mouse_Shadow_Buffer(this, scr, EraseBuffer, EraseBuffX, EraseBuffY, 0);
    562 				EraseBuffX = -1;
    563 				EraseBuffY = -1;
    564 			}
    565 			//
    566 			// We are done writing to the buffer so unlock it.
    567 			//
    568 			scr->Unlock();
    569 		}
    570 #endif
    571 	} else	{
    572 			//
    573 			// If the surface has not already been restore then restore it and erase the
    574 			// restoration coordinates so we don't accidentally do it twice.
    575 			//
    576 			if (EraseBuffX != -1 || EraseBuffY != -1) {
    577 				if (scr->Lock()){
    578 					Mouse_Shadow_Buffer(this, scr, EraseBuffer, EraseBuffX, EraseBuffY, EraseBuffHotX, EraseBuffHotY, 0);
    579 					scr->Unlock();
    580 				}
    581 				EraseBuffX = -1;
    582 				EraseBuffY = -1;
    583 			}
    584 	}
    585 	MouseUpdate--;
    586   	EraseFlags = FALSE;
    587 #endif
    588 }
    589 
    590 int WWMouseClass::Get_Mouse_State(void)
    591 {
    592 	return(State);
    593 }
    594 /***********************************************************************************************
    595  * WWKeyboardClass::Get_Mouse_X -- Returns the mouses current x position in pixels             *
    596  *                                                                                             *
    597  * INPUT:		none                                                                            *
    598  *                                                                                             *
    599  * OUTPUT:     int		- returns the mouses current x position in pixels                      *
    600  *                                                                                             *
    601  * HISTORY:                                                                                    *
    602  *   10/17/1995 PWG : Created.                                                                 *
    603  *=============================================================================================*/
    604 int WWMouseClass::Get_Mouse_X(void)
    605 {
    606 	POINT 	pt;
    607 	GetCursorPos(&pt);
    608 	return(pt.x);
    609 }
    610 
    611 
    612 /***********************************************************************************************
    613  * WWKeyboardClass::Get_Mouse_Y -- returns the mouses current y position in pixels             *
    614  *                                                                                             *
    615  * INPUT:		none                                                                            *
    616  *                                                                                             *
    617  * OUTPUT:     int		- returns the mouses current y position in pixels                      *
    618  *                                                                                             *
    619  * HISTORY:                                                                                    *
    620  *   10/17/1995 PWG : Created.                                                                 *
    621  *=============================================================================================*/
    622 int WWMouseClass::Get_Mouse_Y(void)
    623 {
    624 	POINT 	pt;
    625 	GetCursorPos(&pt);
    626 	return(pt.y);
    627 }
    628 
    629 /***********************************************************************************************
    630  * WWKeyboardClass::Get_Mouse_XY -- Returns the mouses x,y position via reference vars         *
    631  *                                                                                             *
    632  * INPUT:		int &x		- variable to return the mouses x position in pixels                *
    633  *					int &y		- variable to return the mouses y position in pixels					  *
    634  *                                                                                             *
    635  * OUTPUT:     none - output is via reference variables                                        *
    636  *                                                                                             *
    637  * HISTORY:                                                                                    *
    638  *   10/17/1995 PWG : Created.                                                                 *
    639  *=============================================================================================*/
    640 void WWMouseClass::Get_Mouse_XY(int &x, int &y)
    641 {
    642 	POINT 	pt;
    643 
    644 	GetCursorPos(&pt);
    645 	x = pt.x;
    646 	y = pt.y;
    647 }
    648 
    649 //#pragma off(unreferenced)
    650 
    651 void CALLBACK Process_Mouse( UINT event_id, UINT res1 , DWORD user, DWORD  res2, DWORD  res3 )
    652 {
    653 	static	BOOL	in_mouse_callback = false;
    654 
    655 	if (_Mouse && !in_mouse_callback) {
    656 		in_mouse_callback = TRUE;
    657 		_Mouse->Process_Mouse();
    658 		in_mouse_callback = FALSE;
    659 	}
    660 }
    661 //#pragma on(unreferenced)
    662 
    663 void Hide_Mouse(void)
    664 {
    665 	if (!_Mouse) return;
    666 	_Mouse->Hide_Mouse();
    667 }
    668 
    669 void Show_Mouse(void)
    670 {
    671 	if (!_Mouse) return;
    672 	_Mouse->Show_Mouse();
    673 }
    674 
    675 void Conditional_Hide_Mouse(int x1, int y1, int x2, int y2)
    676 {
    677 	if (!_Mouse) return;
    678 	_Mouse->Conditional_Hide_Mouse(x1, y1, x2, y2);
    679 }
    680 
    681 void Conditional_Show_Mouse(void)
    682 {
    683 	if (!_Mouse) return;
    684 	_Mouse->Conditional_Show_Mouse();
    685 }
    686 
    687 int Get_Mouse_State(void)
    688 {
    689 	if (!_Mouse) return(0);
    690 	return(_Mouse->Get_Mouse_State());
    691 }
    692 
    693 void *Set_Mouse_Cursor(int hotx, int hoty, void *cursor)
    694 {
    695 	if (!_Mouse) return(0);
    696 	return(_Mouse->Set_Cursor(hotx,hoty,cursor));
    697 }
    698 
    699 extern int DLLForceMouseX;
    700 extern int DLLForceMouseY;
    701 
    702 
    703 int Get_Mouse_X(void)
    704 {
    705 	if (DLLForceMouseX >= 0) {
    706 		return DLLForceMouseX;
    707 	}
    708 	if (!_Mouse) return(0);
    709 	return(_Mouse->Get_Mouse_X());
    710 }
    711 
    712 int Get_Mouse_Y(void)
    713 {
    714 	if (DLLForceMouseY >= 0) {
    715 		return DLLForceMouseY;
    716 	}
    717 	
    718 	if (!_Mouse) return(0);
    719 	return(_Mouse->Get_Mouse_Y());
    720 }