/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : Command & Conquer * * * * $Archive:: /Commando/Code/Library/wwmouse.cpp $* * * * $Author:: Byon_g $* * * * $Modtime:: 8/11/97 10:14a $* * * * $Revision:: 2 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * Callback_Process_Mouse -- Mouse O/S callback function. * * WWMouseClass::WWMouseClass -- Constructor for mouse handler object. * * WWMouseClass::~WWMouseClass -- Destructor for mouse handler object. * * WWMouseClass::Get_Mouse_State -- Fetch the current mouse visibility state. * * WWMouseClass::Set_Cursor -- Set the mouse cursor shape. * * WWMouseClass::Is_Data_Valid -- Determines if there is valid shape image data. * * WWMouseClass::Validate_Copy_Buffer -- Checks for and validates the background copy buffer.* * WWMouseClass::Matching_Rect -- Finds rectangle of current cursor position & size. * * WWMouseClass::Save_Background -- Saves the background to a copy buffer. * * WWMouseClass::Restore_Background -- Restores the image back where it came from. * * WWMouseClass::Draw_Mouse -- Manually draw the mouse to the surface specified. * * WWMouseClass::Erase_Mouse -- Restores the surface after a Draw_Mouse call. * * WWMouseClass::Raw_Draw_Mouse -- Draws the mouse to the surface specified. * * WWMouseClass::Low_Show_Mouse -- Shows the mouse and saves the background. * * WWMouseClass::Low_Hide_Mouse -- Restores the surface image in order to hide the mouse. * * WWMouseClass::Show_Mouse -- Shows the mouse on the visible surface. * * WWMouseClass::Hide_Mouse -- Hides the mouse from the visible surface. * * WWMouseClass::Capture_Mouse -- Capture the mouse into the mouse handler region. * * WWMouseClass::Release_Mouse -- Release the mouse back to the O/S. * * WWMouseClass::Conditional_Hide_Mouse -- Hides the mouse if it would overlap the region spe* * WWMouseClass::Conditional_Show_Mouse -- Releases the mouse hiding region tracking. * * WWMouseClass::Convert_Coordinate -- Convert an O/S coordinate into a logical coordinate. * * WWMouseClass::Get_Bounded_Position -- Fetches the mouse position from the O/S. * * WWMouseClass::Update_Mouse_Position -- Updates the mouse position to match that specified.* * WWMouseClass::Process_Mouse -- Mouse processing callback routine. * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #include "always.h" #include "_convert.h" #include "_mono.h" #include "blit.h" #include "bsurface.h" #include "draw.h" #include "shapeset.h" #include "surface.h" #include "win.h" #include "wwmouse.h" #include /* ** Persistant mouse object pointer that is used to facilitate access to the mouse ** handler object outside of the context of a member function. This will be set to the ** mouse object most recently created. */ static WWMouseClass * _MousePtr = NULL; /*********************************************************************************************** * Callback_Process_Mouse -- Mouse O/S callback function. * * * * This routine is called periodically by the operating system. It handles updating the * * mouse cursor position to match the mouse movement. * * * * INPUT: n/a * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void CALLBACK Callback_Process_Mouse( UINT, UINT, DWORD, DWORD, DWORD ) { if (_MousePtr != NULL) { _MousePtr->Process_Mouse(); } } /*********************************************************************************************** * WWMouseClass::WWMouseClass -- Constructor for mouse handler object. * * * * This is the constructor for the mouse handler object. It is assigned to a surface and * * given a confining rectangle. The mouse begins in a non-captured state. * * * * INPUT: surfaceptr -- Pointer to the visible display surface that will show the mouse. * * * * confine -- The confining rectangle within the visible surface. The mouse * * coordinates are bound to this rectangle. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ WWMouseClass::WWMouseClass(Surface * surfaceptr, HWND window) : Blocked(false), MouseState(-1), IsCaptured(false), MouseX(0), MouseY(0), SurfacePtr(surfaceptr), Window(window), MouseShape(NULL), ShapeNumber(0), MouseXHot(0), MouseYHot(0), Background(NULL), Alternate(NULL), SidebarAlternate(NULL), ConditionalRect(0,0,0,0), ConditionalState(-1), TimerHandle(0) { _MousePtr = this; TimerHandle = timeSetEvent(1000/60, 1, Callback_Process_Mouse, 0, TIME_PERIODIC); Calc_Confining_Rect(); MouseXHot = ConfiningRect.X + (ConfiningRect.Width/2); MouseYHot = ConfiningRect.Y + (ConfiningRect.Height/2); } /*********************************************************************************************** * WWMouseClass::~WWMouseClass -- Destructor for mouse handler object. * * * * This will remove the mouse handler object from being processed. It returns the mouse * * back to O/S control. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ WWMouseClass::~WWMouseClass(void) { if (TimerHandle != 0) { timeKillEvent(TimerHandle); _MousePtr = NULL; } delete Background; Background = NULL; delete Alternate; Alternate = NULL; delete SidebarAlternate; SidebarAlternate = NULL; } void WWMouseClass::Calc_Confining_Rect(void) { RECT rect; GetClientRect(Window, &rect); POINT point; point.x = rect.left; point.y = rect.top; ClientToScreen(Window, &point); POINT lr; lr.x = rect.right; lr.y = rect.bottom; ClientToScreen(Window, &lr); ConfiningRect = Rect(point.x, point.y, lr.x-point.x, lr.y-point.y); // ConfiningRect = Rect(point.x, point.y, lr.x-point.x+1, lr.y-point.y+1); } /*********************************************************************************************** * WWMouseClass::Get_Mouse_State -- Fetch the current mouse visibility state. * * * * This routine is used to retrieve the current mouse state as it relates to visiblity. * * By using this routine it is possible to determine if the mouse is visible. * * * * INPUT: none * * * * OUTPUT: Returns with the current mouse visibility state. If the return value is less than * * 0 (i.e., negative), then the mouse is hidden. * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ int WWMouseClass::Get_Mouse_State(void) const { if (!Is_Captured()) { ShowCursor(FALSE); int state = ShowCursor(TRUE); return(state); } return(MouseState); } /*********************************************************************************************** * WWMouseClass::Set_Cursor -- Set the mouse cursor shape. * * * * This routine sets the mouse cursor image and hot-spot. The shape only applies to the * * mouse when it is captured (the normal case). Repeated calls to this routine is used * * to give the mouse animation. * * * * INPUT: xhotspot, yhotspot -- The X,Y offset from the upper left corner of the shape * * that specifies the hot-spot of the image. Positive values * * are right and down from the upper left corner. * * * * cursor -- Pointer to the shape data. * * * * shape -- The shape number to use within the shape data set specified. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, ShapeSet const * cursor, int shape) { if (cursor != NULL) { if (Is_Captured()) { Block_Mouse(); if (!Is_Hidden()) Low_Hide_Mouse(); MouseShape = cursor; ShapeNumber = shape; MouseXHot = xhotspot; MouseYHot = yhotspot; if (!Is_Hidden()) Low_Show_Mouse(); Unblock_Mouse(); } else { MouseShape = cursor; ShapeNumber = shape; MouseXHot = xhotspot; MouseYHot = yhotspot; } } } /*********************************************************************************************** * WWMouseClass::Is_Data_Valid -- Determines if there is valid shape image data. * * * * This routine does a simple check to determine if the shape handler has been supplied * * a pointer to shape imagery. Any internal routine that requires the data to be present * * should call this routine to be sure it actually is. * * * * INPUT: none * * * * OUTPUT: bool; Has a shape image data pointer been supplied to this mouse handler? * * * * WARNINGS: When the mouse object is first created, no image data has been assigned. The * * Set_Cursor must be called before this routine will return TRUE. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ bool WWMouseClass::Is_Data_Valid(void) const { if (MouseShape != NULL) { return(true); } return(false); } /*********************************************************************************************** * WWMouseClass::Validate_Copy_Buffer -- Checks for and validates the background copy buffer. * * * * This routine checks and allocates if necessary a buffer that is big enough to hold the * * background image under the mouse. Whenever the background buffer is needed, this routine * * should be called to ensure that it is valid. * * * * INPUT: none * * * * OUTPUT: bool; Is the buffer valid? * * * * WARNINGS: This routine might fail if there was insufficient memory. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ bool WWMouseClass::Validate_Copy_Buffer(void) { if (Is_Data_Valid()) { /* ** If there is a background buffer already allocated, then verify that ** it is large enough for the current shape data. If not, then free the ** buffer and reallocate it at the larger size. */ if (Background != NULL) { if (MouseShape->Get_Width() > Background->Get_Width() || MouseShape->Get_Height() > Background->Get_Height()) { delete Background; Background = NULL; } } if (Alternate != NULL) { if (MouseShape->Get_Width() > Alternate->Get_Width() || MouseShape->Get_Height() > Alternate->Get_Height()) { delete Alternate; Alternate = NULL; } } if (SidebarAlternate != NULL) { if (MouseShape->Get_Width() > SidebarAlternate->Get_Width() || MouseShape->Get_Height() > SidebarAlternate->Get_Height()) { delete SidebarAlternate; SidebarAlternate = NULL; } } /* ** Allocate a new background buffer if necessary. This must be big enough to ** hold the largest sized shape from the currently assigned shape set data. */ if (Background == NULL) { Background = new BSurface(MouseShape->Get_Width(), MouseShape->Get_Height(), SurfacePtr->Bytes_Per_Pixel()); } if (Alternate == NULL) { Alternate = new BSurface(MouseShape->Get_Width(), MouseShape->Get_Height(), SurfacePtr->Bytes_Per_Pixel()); } if (SidebarAlternate == NULL) { SidebarAlternate = new BSurface(MouseShape->Get_Width(), MouseShape->Get_Height(), SurfacePtr->Bytes_Per_Pixel()); } return(Background != NULL && Alternate != NULL && SidebarAlternate != NULL); } return(false); } /*********************************************************************************************** * WWMouseClass::Matching_Rect -- Finds rectangle of current cursor position & size. * * * * This routine will return the logical rectangle that exactly encloses the cursor. This * * routine is typically used when drawing the cursor and manipulating the background buffer * * under it. * * * * INPUT: none * * * * OUTPUT: Returns with the rectangle that surrounds the cursor. * * * * WARNINGS: The rectangle is in logical coordinates. It may have to be biased to O/S * * coordinates if necessary. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ Rect WWMouseClass::Matching_Rect(void) const { Rect rect; if (Is_Data_Valid()) { ((WWMouseClass *)this)->Block_Mouse(); /* ** Build the rectangle that the mouse shape will consume. */ rect = MouseShape->Get_Rect(ShapeNumber); rect.X += MouseX - MouseXHot; rect.Y += MouseY - MouseYHot; ((WWMouseClass *)this)->Unblock_Mouse(); } return(rect); } /*********************************************************************************************** * WWMouseClass::Save_Background -- Saves the background to a copy buffer. * * * * This routine will save the region under the mouse (or where the mouse would appear at) * * to a copy buffer. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: The previous contents of the copy buffer will be overwritten by this routine. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Save_Background(void) { if (Validate_Copy_Buffer()) { /* ** Build the rectangle that the mouse shape will consume. */ SavedRegion = Matching_Rect(); Rect rect = SavedRegion; rect.X += ConfiningRect.X; rect.Y += ConfiningRect.Y; /* ** Blit the background from the surface to the holding buffer. */ // Rect old = SurfacePtr->Get_Rect(); // SurfacePtr->Window.Reset(); Background->Blit_From(Rect(0, 0, rect.Width, rect.Height), *SurfacePtr, rect); // SurfacePtr->Window.Set(old); } } /*********************************************************************************************** * WWMouseClass::Restore_Background -- Restores the image back where it came from. * * * * This is the counterpart routine to the Save_Background function. It will restore the * * image from the copy buffer back to the screen where it came from. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Restore_Background(void) { if (SavedRegion.Is_Valid()) { Rect rect = SavedRegion; rect.X += ConfiningRect.X; rect.Y += ConfiningRect.Y; /* ** Blit the background from the holding buffer to the surface. */ // Rect old = SurfacePtr->Get_Rect(); // SurfacePtr->Window.Reset(); SurfacePtr->Blit_From(rect, *Background, Rect(0, 0, rect.Width, rect.Height)); // SurfacePtr->Window.Set(old); } } /*********************************************************************************************** * WWMouseClass::Draw_Mouse -- Manually draw the mouse to the surface specified. * * * * This is a kludge function that can be used to reduce mouse flicker. Normally the mouse * * must be hidden before an image is copied to the visible surface. By drawing the mouse * * in the correct position on the source image prior to the copy, the mouse doesn't need * * to be hidden and no mouse flicker occurs. This routine handles this manual draw process. * * * * INPUT: surface -- Pointer to the surface that the mouse will be drawn to. * * * * OUTPUT: none * * * * WARNINGS: The destination surface is presumed to be the exact dimensions of the bouding * * rectangle specified in the mouse constructor. The call to Erase_Mouse must * * occur as soon as possible since the mouse is frozen until it is called. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Draw_Mouse(Surface * surface, bool issidebarsurface) { BSurface *savesurface; Rect *savedregion; int xoffset; int yoffset; if (issidebarsurface){ xoffset = -480; yoffset = 0; savesurface = SidebarAlternate; savedregion = &SidebarAltRegion; }else{ xoffset = 0; yoffset = 0; savesurface = Alternate; savedregion = &AltRegion; } if (!Is_Hidden() && surface != NULL && surface != SurfacePtr && savesurface != NULL) { Block_Mouse(); /* ** Blit the background from the surface to the holding buffer. */ //Rect old = surface->Window.Get_Rect(); //surface->Window.Reset(); *savedregion = SavedRegion; savedregion->X += xoffset; savedregion->Y += yoffset; savesurface->Blit_From(Rect(0, 0, savedregion->Width, savedregion->Height), *surface, *savedregion); if (issidebarsurface){ if (savedregion->X < 0 && -savedregion->X < Background->Get_Width()){ Background->Blit_From(Rect(-savedregion->X, 0, savedregion->Width, savedregion->Height), *surface, Rect(0,savedregion->Y, savedregion->Width, savedregion->Height)); } }else{ Background->Blit_From(Rect(0, 0, savedregion->Width, savedregion->Height), *surface, *savedregion); } //surface->Window.Set(old); Raw_Draw_Mouse(surface, xoffset, yoffset); Unblock_Mouse(); } else { savedregion->Width = 0; } } /*********************************************************************************************** * WWMouseClass::Erase_Mouse -- Restores the surface after a Draw_Mouse call. * * * * This is the counterpart routine to Draw_Mouse. It will restore the specified surface * * back to its original state. The mouse is frozen between the calls to Draw_Mouse and * * Erase_Mouse, so it is imperative to call this routine at the first legal opportunity. * * * * INPUT: surface -- Pointer to the surface that the mouse was previously drawn to. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Erase_Mouse(Surface * surface, bool issidebarsurface) { if (!Is_Hidden() && surface != NULL && surface != SurfacePtr && Alternate != NULL && SidebarAlternate != NULL) { BSurface *savesurface; Rect savedregion; if (issidebarsurface){ savesurface = SidebarAlternate; savedregion = SidebarAltRegion; }else{ savesurface = Alternate; savedregion = AltRegion; } /* ** Blit the background from the holding buffer to the surface. */ Block_Mouse(); //Rect old = surface->Window.Get_Rect(); //surface->Window.Reset(); surface->Blit_From(savedregion, *savesurface, Rect(0, 0, savedregion.Width, savedregion.Height)); //surface->Window.Set(old); Unblock_Mouse(); } } /*********************************************************************************************** * WWMouseClass::Raw_Draw_Mouse -- Draws the mouse to the surface specified. * * * * This will draw the mouse image to the surface specified. It does not do any checking * * except to make sure that the mouse image data is nominally valid. * * * * INPUT: surface -- The surface to draw the mouse upon. * * * * OUTPUT: none * * * * WARNINGS: The background is not preserved by this routine. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Raw_Draw_Mouse(Surface * surface, int xoffset, int yoffset) { if (Is_Data_Valid() && surface != NULL) { /* ** Determine the rectangle that the mouse will be drawn ** to. */ Rect rect = SavedRegion; rect.X += xoffset; rect.Y += yoffset; // if (surface == SurfacePtr) { // rect.X += ConfiningRect.X; // rect.Y += ConfiningRect.Y; // } // Rect old = surface->Get_Rect(); // surface->Window.Reset(); BSurface mdata(rect.Width, rect.Height, 1, MouseShape->Get_Data(ShapeNumber)); if (surface == SurfacePtr) { Blit_Block(*surface, *NormalDrawer, mdata, Rect(0, 0, rect.Width, rect.Height), Point2D(rect.X, rect.Y), ConfiningRect); } else { Blit_Block(*surface, *NormalDrawer, mdata, Rect(0, 0, rect.Width, rect.Height), Point2D(rect.X, rect.Y), surface->Get_Rect()); } //surface->Window.Set(old); } } /*********************************************************************************************** * WWMouseClass::Low_Show_Mouse -- Shows the mouse and saves the background. * * * * This routine will save the background and then draw the mouse to the visible surface. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Low_Show_Mouse(void) { Block_Mouse(); Save_Background(); Raw_Draw_Mouse(SurfacePtr, 0, 0); Unblock_Mouse(); } /*********************************************************************************************** * WWMouseClass::Low_Hide_Mouse -- Restores the surface image in order to hide the mouse. * * * * This routine will hide the mouse on the visible surface. It does this by restoring the * * pixels under where the mouse was previously drawn. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Low_Hide_Mouse(void) { Block_Mouse(); Restore_Background(); Unblock_Mouse(); } /*********************************************************************************************** * WWMouseClass::Show_Mouse -- Shows the mouse on the visible surface. * * * * This routine is called when the mouse can be shown on the visible surface. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Show_Mouse(void) { if (!Is_Captured()) { ShowCursor(TRUE); } else { Block_Mouse(); InterlockedIncrement(&MouseState); if (MouseState == 0) { Low_Show_Mouse(); } assert(MouseState != 1); if (MouseState > 0) MouseState = 0; Unblock_Mouse(); } } /*********************************************************************************************** * WWMouseClass::Hide_Mouse -- Hides the mouse from the visible surface. * * * * This routine is called when the mouse is desired to be hidden from the visible surface. * * Typically, this must occur if the pixels where the mouse is located will be accessed. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Hide_Mouse(void) { if (!Is_Captured()) { ShowCursor(FALSE); } else { Block_Mouse(); InterlockedDecrement(&MouseState); if (MouseState == -1) { Low_Hide_Mouse(); } Unblock_Mouse(); } } /*********************************************************************************************** * WWMouseClass::Capture_Mouse -- Capture the mouse into the mouse handler region. * * * * This routine will confine the mouse to the confining rectangle and take over drawing * * of the mouse image from the operating system. The typical state is to keep the mouse * * captured throughout the lifetime of the owning program. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Capture_Mouse(void) { if (this != NULL && !Is_Captured()) { Block_Mouse(); while (ShowCursor(FALSE) > -1) {} while (ShowCursor(TRUE) < -1) {} Hide_Mouse(); IsCaptured = true; Show_Mouse(); Unblock_Mouse(); } } /*********************************************************************************************** * WWMouseClass::Release_Mouse -- Release the mouse back to the O/S. * * * * This is the counterpart routine to Capture_Mouse. This routine will return the drawing * * and movement controls back to the operating system. Although the mouse will probably * * be able to roam outside the confining rectangle, the coordinates returned by this class * * are clipped to the confining rectangle anyway. This gives the impression that the mouse * * is still at a legal position. The presumption is that the mouse needs to be released to * * the O/S for reasons outside of the game itself. As such, the shouldn't detect any * * illegal mouse position. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: All mouse shape changes won't be relected while the mouse is released. The O/S * * handles drawing the mouse in that case. * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Release_Mouse(void) { if (this != NULL && Is_Captured()) { Block_Mouse(); Hide_Mouse(); IsCaptured = false; while (ShowCursor(FALSE) > -1) {} while (ShowCursor(TRUE) < -1) {} Show_Mouse(); Unblock_Mouse(); } } /*********************************************************************************************** * WWMouseClass::Conditional_Hide_Mouse -- Hides the mouse if it would overlap the region spec * * * * This routine will hide the mouse if it lies within the region specified or if it moves * * within the region. * * * * INPUT: rect -- The rectangle that the mouse should not be drawn within. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Conditional_Hide_Mouse(Rect ) { Hide_Mouse(); } /*********************************************************************************************** * WWMouseClass::Conditional_Show_Mouse -- Releases the mouse hiding region tracking. * * * * This routine will release the region hiding tracking that was set up with a previous * * call to Conditional_Hide_Mouse(). * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Conditional_Show_Mouse(void) { Show_Mouse(); } /*********************************************************************************************** * WWMouseClass::Convert_Coordinate -- Convert an O/S coordinate into a logical coordinate. * * * * Sometimes you come across system mouse coordinates and they need to be converted into * * game logical coordinates. This routine will perform this function. * * * * INPUT: x,y -- Reference to the coordinates that will be converted into game logical * * coordinates. * * * * OUTPUT: none * * * * WARNINGS: The coordinates will be bound as well as transformed by the confining rectangle.* * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Convert_Coordinate(int & x, int & y) const { /* ** Convert the mouse position to legal bounds. */ x -= ConfiningRect.X; y -= ConfiningRect.Y; if (x < 0) x = 0; if (y < 0) y = 0; if (x >= ConfiningRect.Width) x = ConfiningRect.Width-1; if (y >= ConfiningRect.Height) y = ConfiningRect.Height-1; } /*********************************************************************************************** * WWMouseClass::Get_Bounded_Position -- Fetches the mouse position from the O/S. * * * * Fetches the mouse coordinates from the O/S and converts them into logical coordinates. * * * * INPUT: x,y -- Reference to the coordinates that will be set by this routine. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Get_Bounded_Position(int & x, int & y) const { /* ** Get the mouse's current real cursor position */ POINT pt; GetCursorPos(&pt); // get the current cursor position x = pt.x; y = pt.y; Convert_Coordinate(x, y); } /*********************************************************************************************** * WWMouseClass::Update_Mouse_Position -- Updates the mouse position to match that specified. * * * * This routine will update the mouse to match the position speicifed. * * * * INPUT: x,y -- The coordinates to position the mouse (hot spot). The coordinates are * * specified as logical not O/S relative. * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Update_Mouse_Position(int x, int y) { /* ** If the desired position is not the same as the current ** position, then hide the mouse, reposition it, then show ** the mouse. */ Block_Mouse(); if (x != MouseX || y != MouseY) { if (Is_Captured() && !Is_Hidden()) Low_Hide_Mouse(); MouseX = x; MouseY = y; if (Is_Captured() && !Is_Hidden()) Low_Show_Mouse(); } Unblock_Mouse(); } /*********************************************************************************************** * WWMouseClass::Process_Mouse -- Mouse processing callback routine. * * * * This routine should be called periodically (recommended 15 times per second). It will * * examine the operating system mouse position and then update the visible mouse to match. * * * * INPUT: none * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 03/10/1997 JLB : Created. * *=============================================================================================*/ void WWMouseClass::Process_Mouse(void) { if (!Is_Blocked()) { Block_Mouse(); /* ** Fetch and update the mouse position. */ int x; int y; Get_Bounded_Position(x, y); Update_Mouse_Position(x, y); Unblock_Mouse(); } } /*********************************************************************************************** * WWMouseClass::Set_Mouse_XY -- Sets the cursor position * * * * This routine will convert the position passed into screen coordinates and tell Windows * * to position the mouse cursor there * * * * INPUT: x and y in game coordinates * * * * OUTPUT: none * * * * WARNINGS: none * * * * HISTORY: * * 08/11/1997 BG : Created. * *=============================================================================================*/ void WWMouseClass::Set_Mouse_XY( int x, int y ) { if (x < 0) x = 0; // clamp to game coordinates if (y < 0) y = 0; if (x >= ConfiningRect.Width) x = ConfiningRect.Width-1; if (y >= ConfiningRect.Height) y = ConfiningRect.Height-1; x += ConfiningRect.X; // convert to screen coordinates y += ConfiningRect.Y; SetCursorPos( x, y ); // set the current cursor position }