Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
wwmouse.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** 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 ***
21 ***********************************************************************************************
22 * *
23 * Project Name : Command & Conquer *
24 * *
25 * $Archive:: /Commando/Code/Library/wwmouse.cpp $*
26 * *
27 * $Author:: Byon_g $*
28 * *
29 * $Modtime:: 8/11/97 10:14a $*
30 * *
31 * $Revision:: 2 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * Callback_Process_Mouse -- Mouse O/S callback function. *
36 * WWMouseClass::WWMouseClass -- Constructor for mouse handler object. *
37 * WWMouseClass::~WWMouseClass -- Destructor for mouse handler object. *
38 * WWMouseClass::Get_Mouse_State -- Fetch the current mouse visibility state. *
39 * WWMouseClass::Set_Cursor -- Set the mouse cursor shape. *
40 * WWMouseClass::Is_Data_Valid -- Determines if there is valid shape image data. *
41 * WWMouseClass::Validate_Copy_Buffer -- Checks for and validates the background copy buffer.*
42 * WWMouseClass::Matching_Rect -- Finds rectangle of current cursor position & size. *
43 * WWMouseClass::Save_Background -- Saves the background to a copy buffer. *
44 * WWMouseClass::Restore_Background -- Restores the image back where it came from. *
45 * WWMouseClass::Draw_Mouse -- Manually draw the mouse to the surface specified. *
46 * WWMouseClass::Erase_Mouse -- Restores the surface after a Draw_Mouse call. *
47 * WWMouseClass::Raw_Draw_Mouse -- Draws the mouse to the surface specified. *
48 * WWMouseClass::Low_Show_Mouse -- Shows the mouse and saves the background. *
49 * WWMouseClass::Low_Hide_Mouse -- Restores the surface image in order to hide the mouse. *
50 * WWMouseClass::Show_Mouse -- Shows the mouse on the visible surface. *
51 * WWMouseClass::Hide_Mouse -- Hides the mouse from the visible surface. *
52 * WWMouseClass::Capture_Mouse -- Capture the mouse into the mouse handler region. *
53 * WWMouseClass::Release_Mouse -- Release the mouse back to the O/S. *
54 * WWMouseClass::Conditional_Hide_Mouse -- Hides the mouse if it would overlap the region spe*
55 * WWMouseClass::Conditional_Show_Mouse -- Releases the mouse hiding region tracking. *
56 * WWMouseClass::Convert_Coordinate -- Convert an O/S coordinate into a logical coordinate. *
57 * WWMouseClass::Get_Bounded_Position -- Fetches the mouse position from the O/S. *
58 * WWMouseClass::Update_Mouse_Position -- Updates the mouse position to match that specified.*
59 * WWMouseClass::Process_Mouse -- Mouse processing callback routine. *
60 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
61
62#include "always.h"
63#include "_convert.h"
64#include "_mono.h"
65#include "blit.h"
66#include "bsurface.h"
67#include "draw.h"
68#include "shapeset.h"
69#include "surface.h"
70#include "win.h"
71#include "wwmouse.h"
72#include <assert.h>
73
74
75/*
76** Persistant mouse object pointer that is used to facilitate access to the mouse
77** handler object outside of the context of a member function. This will be set to the
78** mouse object most recently created.
79*/
80static WWMouseClass * _MousePtr = NULL;
81
82
83/***********************************************************************************************
84 * Callback_Process_Mouse -- Mouse O/S callback function. *
85 * *
86 * This routine is called periodically by the operating system. It handles updating the *
87 * mouse cursor position to match the mouse movement. *
88 * *
89 * INPUT: n/a *
90 * *
91 * OUTPUT: none *
92 * *
93 * WARNINGS: none *
94 * *
95 * HISTORY: *
96 * 03/10/1997 JLB : Created. *
97 *=============================================================================================*/
99{
100 if (_MousePtr != NULL) {
101 _MousePtr->Process_Mouse();
102 }
103}
104
105
106/***********************************************************************************************
107 * WWMouseClass::WWMouseClass -- Constructor for mouse handler object. *
108 * *
109 * This is the constructor for the mouse handler object. It is assigned to a surface and *
110 * given a confining rectangle. The mouse begins in a non-captured state. *
111 * *
112 * INPUT: surfaceptr -- Pointer to the visible display surface that will show the mouse. *
113 * *
114 * confine -- The confining rectangle within the visible surface. The mouse *
115 * coordinates are bound to this rectangle. *
116 * *
117 * OUTPUT: none *
118 * *
119 * WARNINGS: none *
120 * *
121 * HISTORY: *
122 * 03/10/1997 JLB : Created. *
123 *=============================================================================================*/
124WWMouseClass::WWMouseClass(Surface * surfaceptr, HWND window) :
125 Blocked(false),
126 MouseState(-1),
127 IsCaptured(false),
128 MouseX(0),
129 MouseY(0),
130 SurfacePtr(surfaceptr),
131 Window(window),
132 MouseShape(NULL),
133 ShapeNumber(0),
134 MouseXHot(0),
135 MouseYHot(0),
136 Background(NULL),
137 Alternate(NULL),
138 SidebarAlternate(NULL),
139 ConditionalRect(0,0,0,0),
140 ConditionalState(-1),
141 TimerHandle(0)
142{
143 _MousePtr = this;
144 TimerHandle = timeSetEvent(1000/60, 1, Callback_Process_Mouse, 0, TIME_PERIODIC);
146 MouseXHot = ConfiningRect.X + (ConfiningRect.Width/2);
147 MouseYHot = ConfiningRect.Y + (ConfiningRect.Height/2);
148}
149
150
151/***********************************************************************************************
152 * WWMouseClass::~WWMouseClass -- Destructor for mouse handler object. *
153 * *
154 * This will remove the mouse handler object from being processed. It returns the mouse *
155 * back to O/S control. *
156 * *
157 * INPUT: none *
158 * *
159 * OUTPUT: none *
160 * *
161 * WARNINGS: none *
162 * *
163 * HISTORY: *
164 * 03/10/1997 JLB : Created. *
165 *=============================================================================================*/
167{
168 if (TimerHandle != 0) {
169 timeKillEvent(TimerHandle);
170 _MousePtr = NULL;
171 }
172
173 delete Background;
174 Background = NULL;
175
176 delete Alternate;
177 Alternate = NULL;
178 delete SidebarAlternate;
179 SidebarAlternate = NULL;
180}
181
182
184{
185 RECT rect;
186 GetClientRect(Window, &rect);
187
188 POINT point;
189 point.x = rect.left;
190 point.y = rect.top;
191 ClientToScreen(Window, &point);
192
193 POINT lr;
194 lr.x = rect.right;
195 lr.y = rect.bottom;
196 ClientToScreen(Window, &lr);
197
198 ConfiningRect = Rect(point.x, point.y, lr.x-point.x, lr.y-point.y);
199// ConfiningRect = Rect(point.x, point.y, lr.x-point.x+1, lr.y-point.y+1);
200}
201
202
203/***********************************************************************************************
204 * WWMouseClass::Get_Mouse_State -- Fetch the current mouse visibility state. *
205 * *
206 * This routine is used to retrieve the current mouse state as it relates to visiblity. *
207 * By using this routine it is possible to determine if the mouse is visible. *
208 * *
209 * INPUT: none *
210 * *
211 * OUTPUT: Returns with the current mouse visibility state. If the return value is less than *
212 * 0 (i.e., negative), then the mouse is hidden. *
213 * *
214 * WARNINGS: none *
215 * *
216 * HISTORY: *
217 * 03/10/1997 JLB : Created. *
218 *=============================================================================================*/
220{
221 if (!Is_Captured()) {
222 ShowCursor(FALSE);
223 int state = ShowCursor(TRUE);
224 return(state);
225 }
226 return(MouseState);
227}
228
229
230/***********************************************************************************************
231 * WWMouseClass::Set_Cursor -- Set the mouse cursor shape. *
232 * *
233 * This routine sets the mouse cursor image and hot-spot. The shape only applies to the *
234 * mouse when it is captured (the normal case). Repeated calls to this routine is used *
235 * to give the mouse animation. *
236 * *
237 * INPUT: xhotspot, yhotspot -- The X,Y offset from the upper left corner of the shape *
238 * that specifies the hot-spot of the image. Positive values *
239 * are right and down from the upper left corner. *
240 * *
241 * cursor -- Pointer to the shape data. *
242 * *
243 * shape -- The shape number to use within the shape data set specified. *
244 * *
245 * OUTPUT: none *
246 * *
247 * WARNINGS: none *
248 * *
249 * HISTORY: *
250 * 03/10/1997 JLB : Created. *
251 *=============================================================================================*/
252void WWMouseClass::Set_Cursor(int xhotspot, int yhotspot, ShapeSet const * cursor, int shape)
253{
254 if (cursor != NULL) {
255 if (Is_Captured()) {
256 Block_Mouse();
257 if (!Is_Hidden()) Low_Hide_Mouse();
258 MouseShape = cursor;
259 ShapeNumber = shape;
260 MouseXHot = xhotspot;
261 MouseYHot = yhotspot;
262 if (!Is_Hidden()) Low_Show_Mouse();
263 Unblock_Mouse();
264 } else {
265 MouseShape = cursor;
266 ShapeNumber = shape;
267 MouseXHot = xhotspot;
268 MouseYHot = yhotspot;
269 }
270 }
271}
272
273
274/***********************************************************************************************
275 * WWMouseClass::Is_Data_Valid -- Determines if there is valid shape image data. *
276 * *
277 * This routine does a simple check to determine if the shape handler has been supplied *
278 * a pointer to shape imagery. Any internal routine that requires the data to be present *
279 * should call this routine to be sure it actually is. *
280 * *
281 * INPUT: none *
282 * *
283 * OUTPUT: bool; Has a shape image data pointer been supplied to this mouse handler? *
284 * *
285 * WARNINGS: When the mouse object is first created, no image data has been assigned. The *
286 * Set_Cursor must be called before this routine will return TRUE. *
287 * *
288 * HISTORY: *
289 * 03/10/1997 JLB : Created. *
290 *=============================================================================================*/
291bool WWMouseClass::Is_Data_Valid(void) const
292{
293 if (MouseShape != NULL) {
294 return(true);
295 }
296 return(false);
297}
298
299
300/***********************************************************************************************
301 * WWMouseClass::Validate_Copy_Buffer -- Checks for and validates the background copy buffer. *
302 * *
303 * This routine checks and allocates if necessary a buffer that is big enough to hold the *
304 * background image under the mouse. Whenever the background buffer is needed, this routine *
305 * should be called to ensure that it is valid. *
306 * *
307 * INPUT: none *
308 * *
309 * OUTPUT: bool; Is the buffer valid? *
310 * *
311 * WARNINGS: This routine might fail if there was insufficient memory. *
312 * *
313 * HISTORY: *
314 * 03/10/1997 JLB : Created. *
315 *=============================================================================================*/
316bool WWMouseClass::Validate_Copy_Buffer(void)
317{
318 if (Is_Data_Valid()) {
319
320 /*
321 ** If there is a background buffer already allocated, then verify that
322 ** it is large enough for the current shape data. If not, then free the
323 ** buffer and reallocate it at the larger size.
324 */
325 if (Background != NULL) {
326 if (MouseShape->Get_Width() > Background->Get_Width() ||
327 MouseShape->Get_Height() > Background->Get_Height()) {
328
329 delete Background;
330 Background = NULL;
331 }
332 }
333 if (Alternate != NULL) {
334 if (MouseShape->Get_Width() > Alternate->Get_Width() ||
335 MouseShape->Get_Height() > Alternate->Get_Height()) {
336
337 delete Alternate;
338 Alternate = NULL;
339 }
340 }
341 if (SidebarAlternate != NULL) {
342 if (MouseShape->Get_Width() > SidebarAlternate->Get_Width() ||
343 MouseShape->Get_Height() > SidebarAlternate->Get_Height()) {
344
345 delete SidebarAlternate;
346 SidebarAlternate = NULL;
347 }
348 }
349
350 /*
351 ** Allocate a new background buffer if necessary. This must be big enough to
352 ** hold the largest sized shape from the currently assigned shape set data.
353 */
354 if (Background == NULL) {
355 Background = new BSurface(MouseShape->Get_Width(), MouseShape->Get_Height(), SurfacePtr->Bytes_Per_Pixel());
356 }
357 if (Alternate == NULL) {
358 Alternate = new BSurface(MouseShape->Get_Width(), MouseShape->Get_Height(), SurfacePtr->Bytes_Per_Pixel());
359 }
360 if (SidebarAlternate == NULL) {
361 SidebarAlternate = new BSurface(MouseShape->Get_Width(), MouseShape->Get_Height(), SurfacePtr->Bytes_Per_Pixel());
362 }
363
364 return(Background != NULL && Alternate != NULL && SidebarAlternate != NULL);
365 }
366 return(false);
367}
368
369
370/***********************************************************************************************
371 * WWMouseClass::Matching_Rect -- Finds rectangle of current cursor position & size. *
372 * *
373 * This routine will return the logical rectangle that exactly encloses the cursor. This *
374 * routine is typically used when drawing the cursor and manipulating the background buffer *
375 * under it. *
376 * *
377 * INPUT: none *
378 * *
379 * OUTPUT: Returns with the rectangle that surrounds the cursor. *
380 * *
381 * WARNINGS: The rectangle is in logical coordinates. It may have to be biased to O/S *
382 * coordinates if necessary. *
383 * *
384 * HISTORY: *
385 * 03/10/1997 JLB : Created. *
386 *=============================================================================================*/
387Rect WWMouseClass::Matching_Rect(void) const
388{
389 Rect rect;
390 if (Is_Data_Valid()) {
391 ((WWMouseClass *)this)->Block_Mouse();
392
393 /*
394 ** Build the rectangle that the mouse shape will consume.
395 */
396 rect = MouseShape->Get_Rect(ShapeNumber);
397 rect.X += MouseX - MouseXHot;
398 rect.Y += MouseY - MouseYHot;
399
400 ((WWMouseClass *)this)->Unblock_Mouse();
401 }
402 return(rect);
403}
404
405
406/***********************************************************************************************
407 * WWMouseClass::Save_Background -- Saves the background to a copy buffer. *
408 * *
409 * This routine will save the region under the mouse (or where the mouse would appear at) *
410 * to a copy buffer. *
411 * *
412 * INPUT: none *
413 * *
414 * OUTPUT: none *
415 * *
416 * WARNINGS: The previous contents of the copy buffer will be overwritten by this routine. *
417 * *
418 * HISTORY: *
419 * 03/10/1997 JLB : Created. *
420 *=============================================================================================*/
421void WWMouseClass::Save_Background(void)
422{
423 if (Validate_Copy_Buffer()) {
424
425 /*
426 ** Build the rectangle that the mouse shape will consume.
427 */
428 SavedRegion = Matching_Rect();
429
430 Rect rect = SavedRegion;
431 rect.X += ConfiningRect.X;
432 rect.Y += ConfiningRect.Y;
433
434 /*
435 ** Blit the background from the surface to the holding buffer.
436 */
437// Rect old = SurfacePtr->Get_Rect();
438// SurfacePtr->Window.Reset();
439 Background->Blit_From(Rect(0, 0, rect.Width, rect.Height), *SurfacePtr, rect);
440// SurfacePtr->Window.Set(old);
441 }
442}
443
444
445/***********************************************************************************************
446 * WWMouseClass::Restore_Background -- Restores the image back where it came from. *
447 * *
448 * This is the counterpart routine to the Save_Background function. It will restore the *
449 * image from the copy buffer back to the screen where it came from. *
450 * *
451 * INPUT: none *
452 * *
453 * OUTPUT: none *
454 * *
455 * WARNINGS: none *
456 * *
457 * HISTORY: *
458 * 03/10/1997 JLB : Created. *
459 *=============================================================================================*/
460void WWMouseClass::Restore_Background(void)
461{
462 if (SavedRegion.Is_Valid()) {
463
464 Rect rect = SavedRegion;
465 rect.X += ConfiningRect.X;
466 rect.Y += ConfiningRect.Y;
467
468 /*
469 ** Blit the background from the holding buffer to the surface.
470 */
471// Rect old = SurfacePtr->Get_Rect();
472// SurfacePtr->Window.Reset();
473 SurfacePtr->Blit_From(rect, *Background, Rect(0, 0, rect.Width, rect.Height));
474// SurfacePtr->Window.Set(old);
475 }
476}
477
478
479/***********************************************************************************************
480 * WWMouseClass::Draw_Mouse -- Manually draw the mouse to the surface specified. *
481 * *
482 * This is a kludge function that can be used to reduce mouse flicker. Normally the mouse *
483 * must be hidden before an image is copied to the visible surface. By drawing the mouse *
484 * in the correct position on the source image prior to the copy, the mouse doesn't need *
485 * to be hidden and no mouse flicker occurs. This routine handles this manual draw process. *
486 * *
487 * INPUT: surface -- Pointer to the surface that the mouse will be drawn to. *
488 * *
489 * OUTPUT: none *
490 * *
491 * WARNINGS: The destination surface is presumed to be the exact dimensions of the bouding *
492 * rectangle specified in the mouse constructor. The call to Erase_Mouse must *
493 * occur as soon as possible since the mouse is frozen until it is called. *
494 * *
495 * HISTORY: *
496 * 03/10/1997 JLB : Created. *
497 *=============================================================================================*/
498void WWMouseClass::Draw_Mouse(Surface * surface, bool issidebarsurface)
499{
500
501 BSurface *savesurface;
502 Rect *savedregion;
503 int xoffset;
504 int yoffset;
505
506 if (issidebarsurface){
507 xoffset = -480;
508 yoffset = 0;
509 savesurface = SidebarAlternate;
510 savedregion = &SidebarAltRegion;
511 }else{
512 xoffset = 0;
513 yoffset = 0;
514 savesurface = Alternate;
515 savedregion = &AltRegion;
516 }
517
518 if (!Is_Hidden() && surface != NULL && surface != SurfacePtr && savesurface != NULL) {
519 Block_Mouse();
520
521 /*
522 ** Blit the background from the surface to the holding buffer.
523 */
524 //Rect old = surface->Window.Get_Rect();
525 //surface->Window.Reset();
526 *savedregion = SavedRegion;
527 savedregion->X += xoffset;
528 savedregion->Y += yoffset;
529 savesurface->Blit_From(Rect(0, 0, savedregion->Width, savedregion->Height), *surface, *savedregion);
530 if (issidebarsurface){
531 if (savedregion->X < 0 && -savedregion->X < Background->Get_Width()){
532 Background->Blit_From(Rect(-savedregion->X, 0, savedregion->Width, savedregion->Height),
533 *surface, Rect(0,savedregion->Y, savedregion->Width, savedregion->Height));
534 }
535 }else{
536 Background->Blit_From(Rect(0, 0, savedregion->Width, savedregion->Height), *surface, *savedregion);
537 }
538 //surface->Window.Set(old);
539 Raw_Draw_Mouse(surface, xoffset, yoffset);
540 Unblock_Mouse();
541 } else {
542 savedregion->Width = 0;
543 }
544}
545
546
547/***********************************************************************************************
548 * WWMouseClass::Erase_Mouse -- Restores the surface after a Draw_Mouse call. *
549 * *
550 * This is the counterpart routine to Draw_Mouse. It will restore the specified surface *
551 * back to its original state. The mouse is frozen between the calls to Draw_Mouse and *
552 * Erase_Mouse, so it is imperative to call this routine at the first legal opportunity. *
553 * *
554 * INPUT: surface -- Pointer to the surface that the mouse was previously drawn to. *
555 * *
556 * OUTPUT: none *
557 * *
558 * WARNINGS: none *
559 * *
560 * HISTORY: *
561 * 03/10/1997 JLB : Created. *
562 *=============================================================================================*/
563void WWMouseClass::Erase_Mouse(Surface * surface, bool issidebarsurface)
564{
565 if (!Is_Hidden() && surface != NULL && surface != SurfacePtr && Alternate != NULL && SidebarAlternate != NULL) {
566
567 BSurface *savesurface;
568 Rect savedregion;
569
570 if (issidebarsurface){
571 savesurface = SidebarAlternate;
572 savedregion = SidebarAltRegion;
573 }else{
574 savesurface = Alternate;
575 savedregion = AltRegion;
576 }
577
578 /*
579 ** Blit the background from the holding buffer to the surface.
580 */
581 Block_Mouse();
582 //Rect old = surface->Window.Get_Rect();
583 //surface->Window.Reset();
584 surface->Blit_From(savedregion, *savesurface, Rect(0, 0, savedregion.Width, savedregion.Height));
585 //surface->Window.Set(old);
586 Unblock_Mouse();
587 }
588}
589
590
591/***********************************************************************************************
592 * WWMouseClass::Raw_Draw_Mouse -- Draws the mouse to the surface specified. *
593 * *
594 * This will draw the mouse image to the surface specified. It does not do any checking *
595 * except to make sure that the mouse image data is nominally valid. *
596 * *
597 * INPUT: surface -- The surface to draw the mouse upon. *
598 * *
599 * OUTPUT: none *
600 * *
601 * WARNINGS: The background is not preserved by this routine. *
602 * *
603 * HISTORY: *
604 * 03/10/1997 JLB : Created. *
605 *=============================================================================================*/
606void WWMouseClass::Raw_Draw_Mouse(Surface * surface, int xoffset, int yoffset)
607{
608 if (Is_Data_Valid() && surface != NULL) {
609
610 /*
611 ** Determine the rectangle that the mouse will be drawn
612 ** to.
613 */
614
615 Rect rect = SavedRegion;
616 rect.X += xoffset;
617 rect.Y += yoffset;
618// if (surface == SurfacePtr) {
619// rect.X += ConfiningRect.X;
620// rect.Y += ConfiningRect.Y;
621// }
622
623// Rect old = surface->Get_Rect();
624// surface->Window.Reset();
625 BSurface mdata(rect.Width, rect.Height, 1, MouseShape->Get_Data(ShapeNumber));
626
627 if (surface == SurfacePtr) {
628 Blit_Block(*surface, *NormalDrawer, mdata, Rect(0, 0, rect.Width, rect.Height), Point2D(rect.X, rect.Y), ConfiningRect);
629 } else {
630 Blit_Block(*surface, *NormalDrawer, mdata, Rect(0, 0, rect.Width, rect.Height), Point2D(rect.X, rect.Y), surface->Get_Rect());
631 }
632
633 //surface->Window.Set(old);
634 }
635}
636
637
638/***********************************************************************************************
639 * WWMouseClass::Low_Show_Mouse -- Shows the mouse and saves the background. *
640 * *
641 * This routine will save the background and then draw the mouse to the visible surface. *
642 * *
643 * INPUT: none *
644 * *
645 * OUTPUT: none *
646 * *
647 * WARNINGS: none *
648 * *
649 * HISTORY: *
650 * 03/10/1997 JLB : Created. *
651 *=============================================================================================*/
652void WWMouseClass::Low_Show_Mouse(void)
653{
654 Block_Mouse();
655 Save_Background();
656 Raw_Draw_Mouse(SurfacePtr, 0, 0);
657 Unblock_Mouse();
658}
659
660
661/***********************************************************************************************
662 * WWMouseClass::Low_Hide_Mouse -- Restores the surface image in order to hide the mouse. *
663 * *
664 * This routine will hide the mouse on the visible surface. It does this by restoring the *
665 * pixels under where the mouse was previously drawn. *
666 * *
667 * INPUT: none *
668 * *
669 * OUTPUT: none *
670 * *
671 * WARNINGS: none *
672 * *
673 * HISTORY: *
674 * 03/10/1997 JLB : Created. *
675 *=============================================================================================*/
676void WWMouseClass::Low_Hide_Mouse(void)
677{
678 Block_Mouse();
679 Restore_Background();
680 Unblock_Mouse();
681}
682
683
684/***********************************************************************************************
685 * WWMouseClass::Show_Mouse -- Shows the mouse on the visible surface. *
686 * *
687 * This routine is called when the mouse can be shown on the visible surface. *
688 * *
689 * INPUT: none *
690 * *
691 * OUTPUT: none *
692 * *
693 * WARNINGS: none *
694 * *
695 * HISTORY: *
696 * 03/10/1997 JLB : Created. *
697 *=============================================================================================*/
699{
700 if (!Is_Captured()) {
701 ShowCursor(TRUE);
702 } else {
703 Block_Mouse();
704 InterlockedIncrement(&MouseState);
705 if (MouseState == 0) {
706 Low_Show_Mouse();
707 }
708 assert(MouseState != 1);
709 if (MouseState > 0) MouseState = 0;
710 Unblock_Mouse();
711 }
712}
713
714
715/***********************************************************************************************
716 * WWMouseClass::Hide_Mouse -- Hides the mouse from the visible surface. *
717 * *
718 * This routine is called when the mouse is desired to be hidden from the visible surface. *
719 * Typically, this must occur if the pixels where the mouse is located will be accessed. *
720 * *
721 * INPUT: none *
722 * *
723 * OUTPUT: none *
724 * *
725 * WARNINGS: none *
726 * *
727 * HISTORY: *
728 * 03/10/1997 JLB : Created. *
729 *=============================================================================================*/
731{
732 if (!Is_Captured()) {
733 ShowCursor(FALSE);
734 } else {
735 Block_Mouse();
736 InterlockedDecrement(&MouseState);
737 if (MouseState == -1) {
738 Low_Hide_Mouse();
739 }
740 Unblock_Mouse();
741 }
742}
743
744
745/***********************************************************************************************
746 * WWMouseClass::Capture_Mouse -- Capture the mouse into the mouse handler region. *
747 * *
748 * This routine will confine the mouse to the confining rectangle and take over drawing *
749 * of the mouse image from the operating system. The typical state is to keep the mouse *
750 * captured throughout the lifetime of the owning program. *
751 * *
752 * INPUT: none *
753 * *
754 * OUTPUT: none *
755 * *
756 * WARNINGS: none *
757 * *
758 * HISTORY: *
759 * 03/10/1997 JLB : Created. *
760 *=============================================================================================*/
762{
763 if (this != NULL && !Is_Captured()) {
764 Block_Mouse();
765 while (ShowCursor(FALSE) > -1) {}
766 while (ShowCursor(TRUE) < -1) {}
767 Hide_Mouse();
768 IsCaptured = true;
769
770 Show_Mouse();
771 Unblock_Mouse();
772 }
773}
774
775
776/***********************************************************************************************
777 * WWMouseClass::Release_Mouse -- Release the mouse back to the O/S. *
778 * *
779 * This is the counterpart routine to Capture_Mouse. This routine will return the drawing *
780 * and movement controls back to the operating system. Although the mouse will probably *
781 * be able to roam outside the confining rectangle, the coordinates returned by this class *
782 * are clipped to the confining rectangle anyway. This gives the impression that the mouse *
783 * is still at a legal position. The presumption is that the mouse needs to be released to *
784 * the O/S for reasons outside of the game itself. As such, the shouldn't detect any *
785 * illegal mouse position. *
786 * *
787 * INPUT: none *
788 * *
789 * OUTPUT: none *
790 * *
791 * WARNINGS: All mouse shape changes won't be relected while the mouse is released. The O/S *
792 * handles drawing the mouse in that case. *
793 * *
794 * HISTORY: *
795 * 03/10/1997 JLB : Created. *
796 *=============================================================================================*/
798{
799 if (this != NULL && Is_Captured()) {
800 Block_Mouse();
801 Hide_Mouse();
802 IsCaptured = false;
803 while (ShowCursor(FALSE) > -1) {}
804 while (ShowCursor(TRUE) < -1) {}
805 Show_Mouse();
806
807 Unblock_Mouse();
808 }
809}
810
811
812/***********************************************************************************************
813 * WWMouseClass::Conditional_Hide_Mouse -- Hides the mouse if it would overlap the region spec *
814 * *
815 * This routine will hide the mouse if it lies within the region specified or if it moves *
816 * within the region. *
817 * *
818 * INPUT: rect -- The rectangle that the mouse should not be drawn within. *
819 * *
820 * OUTPUT: none *
821 * *
822 * WARNINGS: none *
823 * *
824 * HISTORY: *
825 * 03/10/1997 JLB : Created. *
826 *=============================================================================================*/
831
832
833/***********************************************************************************************
834 * WWMouseClass::Conditional_Show_Mouse -- Releases the mouse hiding region tracking. *
835 * *
836 * This routine will release the region hiding tracking that was set up with a previous *
837 * call to Conditional_Hide_Mouse(). *
838 * *
839 * INPUT: none *
840 * *
841 * OUTPUT: none *
842 * *
843 * WARNINGS: none *
844 * *
845 * HISTORY: *
846 * 03/10/1997 JLB : Created. *
847 *=============================================================================================*/
852
853
854/***********************************************************************************************
855 * WWMouseClass::Convert_Coordinate -- Convert an O/S coordinate into a logical coordinate. *
856 * *
857 * Sometimes you come across system mouse coordinates and they need to be converted into *
858 * game logical coordinates. This routine will perform this function. *
859 * *
860 * INPUT: x,y -- Reference to the coordinates that will be converted into game logical *
861 * coordinates. *
862 * *
863 * OUTPUT: none *
864 * *
865 * WARNINGS: The coordinates will be bound as well as transformed by the confining rectangle.*
866 * *
867 * HISTORY: *
868 * 03/10/1997 JLB : Created. *
869 *=============================================================================================*/
870void WWMouseClass::Convert_Coordinate(int & x, int & y) const
871{
872 /*
873 ** Convert the mouse position to legal bounds.
874 */
875 x -= ConfiningRect.X;
876 y -= ConfiningRect.Y;
877 if (x < 0) x = 0;
878 if (y < 0) y = 0;
879 if (x >= ConfiningRect.Width) x = ConfiningRect.Width-1;
880 if (y >= ConfiningRect.Height) y = ConfiningRect.Height-1;
881}
882
883
884/***********************************************************************************************
885 * WWMouseClass::Get_Bounded_Position -- Fetches the mouse position from the O/S. *
886 * *
887 * Fetches the mouse coordinates from the O/S and converts them into logical coordinates. *
888 * *
889 * INPUT: x,y -- Reference to the coordinates that will be set by this routine. *
890 * *
891 * OUTPUT: none *
892 * *
893 * WARNINGS: none *
894 * *
895 * HISTORY: *
896 * 03/10/1997 JLB : Created. *
897 *=============================================================================================*/
898void WWMouseClass::Get_Bounded_Position(int & x, int & y) const
899{
900 /*
901 ** Get the mouse's current real cursor position
902 */
903 POINT pt;
904 GetCursorPos(&pt); // get the current cursor position
905 x = pt.x;
906 y = pt.y;
907 Convert_Coordinate(x, y);
908}
909
910
911/***********************************************************************************************
912 * WWMouseClass::Update_Mouse_Position -- Updates the mouse position to match that specified. *
913 * *
914 * This routine will update the mouse to match the position speicifed. *
915 * *
916 * INPUT: x,y -- The coordinates to position the mouse (hot spot). The coordinates are *
917 * specified as logical not O/S relative. *
918 * *
919 * OUTPUT: none *
920 * *
921 * WARNINGS: none *
922 * *
923 * HISTORY: *
924 * 03/10/1997 JLB : Created. *
925 *=============================================================================================*/
926void WWMouseClass::Update_Mouse_Position(int x, int y)
927{
928 /*
929 ** If the desired position is not the same as the current
930 ** position, then hide the mouse, reposition it, then show
931 ** the mouse.
932 */
933 Block_Mouse();
934 if (x != MouseX || y != MouseY) {
935 if (Is_Captured() && !Is_Hidden()) Low_Hide_Mouse();
936 MouseX = x;
937 MouseY = y;
938 if (Is_Captured() && !Is_Hidden()) Low_Show_Mouse();
939 }
940 Unblock_Mouse();
941}
942
943
944/***********************************************************************************************
945 * WWMouseClass::Process_Mouse -- Mouse processing callback routine. *
946 * *
947 * This routine should be called periodically (recommended 15 times per second). It will *
948 * examine the operating system mouse position and then update the visible mouse to match. *
949 * *
950 * INPUT: none *
951 * *
952 * OUTPUT: none *
953 * *
954 * WARNINGS: none *
955 * *
956 * HISTORY: *
957 * 03/10/1997 JLB : Created. *
958 *=============================================================================================*/
960{
961 if (!Is_Blocked()) {
962 Block_Mouse();
963
964 /*
965 ** Fetch and update the mouse position.
966 */
967 int x;
968 int y;
969 Get_Bounded_Position(x, y);
970 Update_Mouse_Position(x, y);
971 Unblock_Mouse();
972 }
973}
974
975
976/***********************************************************************************************
977 * WWMouseClass::Set_Mouse_XY -- Sets the cursor position *
978 * *
979 * This routine will convert the position passed into screen coordinates and tell Windows *
980 * to position the mouse cursor there *
981 * *
982 * INPUT: x and y in game coordinates *
983 * *
984 * OUTPUT: none *
985 * *
986 * WARNINGS: none *
987 * *
988 * HISTORY: *
989 * 08/11/1997 BG : Created. *
990 *=============================================================================================*/
991void WWMouseClass::Set_Mouse_XY( int x, int y )
992{
993 if (x < 0) x = 0; // clamp to game coordinates
994 if (y < 0) y = 0;
995 if (x >= ConfiningRect.Width) x = ConfiningRect.Width-1;
996 if (y >= ConfiningRect.Height) y = ConfiningRect.Height-1;
997
998 x += ConfiningRect.X; // convert to screen coordinates
999 y += ConfiningRect.Y;
1000
1001 SetCursorPos( x, y ); // set the current cursor position
1002}
1003
1004
1005
ConvertClass * NormalDrawer
Definition _convert.cpp:44
#define NULL
Definition BaseType.h:92
#define TRUE
Definition BaseType.h:109
#define FALSE
Definition BaseType.h:113
TPoint2D< int > Point2D
Definition Point.h:114
unsigned int UINT
Definition bittype.h:63
unsigned long DWORD
Definition bittype.h:57
@ false
Definition bool.h:59
void * Get_Data(int shape) const
Definition shapeset.h:200
virtual Rect Get_Rect(void) const
Definition Surface.h:102
virtual bool Blit_From(Rect const &dcliprect, Rect const &destrect, Surface const &source, Rect const &scliprect, Rect const &sourcerect, bool trans=false)=0
T Width
Definition trect.h:115
T Y
Definition trect.h:109
T Height
Definition trect.h:116
T X
Definition trect.h:108
virtual void Set_Cursor(int xhotspot, int yhotspot, ShapeSet const *cursor, int shape)
Definition wwmouse.cpp:252
virtual void Set_Mouse_XY(int xpos, int ypos)
Definition wwmouse.cpp:991
virtual void Erase_Mouse(Surface *scr, bool issidebarsurface=false)
Definition wwmouse.cpp:563
virtual void Convert_Coordinate(int &x, int &y) const
Definition wwmouse.cpp:870
virtual void Release_Mouse(void)
Definition wwmouse.cpp:797
virtual void Hide_Mouse(void)
Definition wwmouse.cpp:730
virtual ~WWMouseClass(void)
Definition wwmouse.cpp:166
virtual void Conditional_Hide_Mouse(Rect region)
Definition wwmouse.cpp:827
virtual void Capture_Mouse(void)
Definition wwmouse.cpp:761
virtual int Get_Mouse_State(void) const
Definition wwmouse.cpp:219
virtual bool Is_Captured(void) const
Definition wwmouse.h:82
virtual void Show_Mouse(void)
Definition wwmouse.cpp:698
virtual void Conditional_Show_Mouse(void)
Definition wwmouse.cpp:848
WWMouseClass(Surface *surfaceptr, HWND window)
Definition wwmouse.cpp:124
void Calc_Confining_Rect(void)
Definition wwmouse.cpp:183
virtual void Draw_Mouse(Surface *scr, bool issidebarsurface=false)
Definition wwmouse.cpp:498
void Process_Mouse(void)
Definition wwmouse.cpp:959
virtual bool Blit_From(Rect const &dcliprect, Rect const &destrect, Surface const &source, Rect const &scliprect, Rect const &sourcerect, bool trans=false)
Definition xsurface.cpp:525
void Blit_Block(Surface &surface, ConvertClass &convert, Surface const &source, Rect const &sourcerect, Point2D const &point, Rect const &window, unsigned char const *remap, Blitter const *blitter)
Definition draw.cpp:177
TRect< int > Rect
Definition trect.h:221
void CALLBACK Callback_Process_Mouse(UINT, UINT, DWORD, DWORD, DWORD)
Definition wwmouse.cpp:98