Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Generals/Code/GameEngine/Include/Common/UserPreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
//-----------------------------------------------------------------------------
#include "Common/STLTypedefs.h"

enum CursorCaptureMode CPP_11(: Int);

//-----------------------------------------------------------------------------
// PUBLIC TYPES ///////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -90,6 +92,7 @@ class OptionPreferences : public UserPreferences
void setOnlineIPAddress(UnsignedInt IP); // convenience function
Bool getAlternateMouseModeEnabled(void); // convenience function
Real getScrollFactor(void); // convenience function
CursorCaptureMode getCursorCaptureMode() const;
Bool getSendDelay(void); // convenience function
Int getFirewallBehavior(void); // convenience function
Short getFirewallPortAllocationDelta(void); // convenience function
Expand Down
62 changes: 56 additions & 6 deletions Generals/Code/GameEngine/Include/GameClient/Mouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@

// FORWARD REFERENCES /////////////////////////////////////////////////////////

enum GameMode CPP_11(: Int);

// TYPE DEFINES ///////////////////////////////////////////////////////////////

enum MouseButtonState CPP_11(: Int)
Expand Down Expand Up @@ -139,13 +141,43 @@ class CursorInfo
Int numDirections; //number of directions for cursors like scrolling/panning.
};

enum CursorCaptureMode CPP_11(: Int)
{
CursorCaptureMode_None, // Does not capture the cursor
CursorCaptureMode_InGame, // Captures the cursor when playing and observing
CursorCaptureMode_Always, // Captures the cursor always in menus and game
CursorCaptureMode_Auto, // Applies mode "InGame" when Windowed, "Always" when Fullscreen

CursorCaptureMode_Count,
CursorCaptureMode_Default = CursorCaptureMode_Auto,
};

extern const char* const TheCursorCaptureModeNames[];

// Mouse ----------------------------------------------------------------------
/** Class interface for working with a mouse pointing device */
// Class interface for working with a mouse pointing device
//
// TheSuperHackers @feature xezon 26/07/2025 Implements mouse cursor capture
// functionality. The Mouse class handles most of the logic for it internally.
//-----------------------------------------------------------------------------
class Mouse : public SubsystemInterface
{

public: // enumerations and types
// enumerations and types

typedef UnsignedInt CursorCaptureBlockReasonInt;

enum CursorCaptureBlockReason
{
CursorCaptureBlockReason_NoInit,
CursorCaptureBlockReason_NoGame,
CursorCaptureBlockReason_Paused,
CursorCaptureBlockReason_Unfocused,

CursorCaptureBlockReason_Count
};

public:

// ----------------------------------------------------------------------------------------------
/** If you update this enum make sure you update CursorININames[] */
Expand Down Expand Up @@ -228,10 +260,12 @@ class Mouse : public SubsystemInterface
RM_W3D, //W3D model tied to frame rate.
RM_POLYGON, //alpha blended polygon tied to frame rate.
RM_DX8, //hardware cursor independent of frame rate.

RM_MAX // keep this last.
};

static const char *RedrawModeName[RM_MAX];
static const char *const CursorCaptureBlockReasonNames[];
static const char *const RedrawModeName[];

CursorInfo m_cursorInfo[NUM_MOUSE_CURSORS];

Expand All @@ -255,8 +289,8 @@ class Mouse : public SubsystemInterface
virtual void setPosition( Int x, Int y ); ///< set the mouse position
virtual void setCursor( MouseCursor cursor ) = 0; ///< set mouse cursor

virtual void capture( void ) = 0; ///< capture the mouse
virtual void releaseCapture( void ) = 0; ///< release mouse capture
void setCursorCaptureMode(CursorCaptureMode mode); ///< set the rules for the mouse capture
void refreshCursorCapture(); ///< refresh the mouse capture

// access methods for the mouse data
const MouseIO *getMouseStatus( void ) { return &m_currMouse; } ///< get current mouse status
Expand All @@ -278,7 +312,12 @@ class Mouse : public SubsystemInterface
Int getCursorIndex( const AsciiString& name );
void resetTooltipDelay( void );

virtual void loseFocus();
virtual void regainFocus();

void mouseNotifyResolutionChange(void);
void onGameModeChanged(GameMode prev, GameMode next);
void onGamePaused(Bool paused);

Bool isClick(const ICoord2D *anchor, const ICoord2D *dest, UnsignedInt previousMouseClick, UnsignedInt currentMouseClick);

Expand Down Expand Up @@ -308,6 +347,14 @@ class Mouse : public SubsystemInterface

protected:

void initCapture();
Bool canCapture() const;
void unblockCapture(CursorCaptureBlockReason reason);
void blockCapture(CursorCaptureBlockReason reason);

virtual void capture( void ) = 0; ///< capture the mouse
virtual void releaseCapture( void ) = 0; ///< release mouse capture

/// you must implement getting a buffered mouse event from you device here
virtual UnsignedByte getMouseEvent( MouseIO *result, Bool flush ) = 0;

Expand All @@ -324,7 +371,7 @@ class Mouse : public SubsystemInterface

UnsignedByte m_numButtons; ///< number of buttons on this mouse
UnsignedByte m_numAxes; ///< number of axes this mouse has
Bool m_forceFeedback; ///< set to TRUE if mouse supprots force feedback
Bool m_forceFeedback; ///< set to TRUE if mouse supports force feedback

UnicodeString m_tooltipString; ///< tooltip text
DisplayString *m_tooltipDisplayString; ///< tooltipDisplayString
Expand Down Expand Up @@ -368,6 +415,9 @@ class Mouse : public SubsystemInterface

Int m_eventsThisFrame;

CursorCaptureMode m_cursorCaptureMode;
CursorCaptureBlockReasonInt m_captureBlockReasonBits;

}; // end class Mouse

// TheSuperHackers @feature helmutbuhler 17/05/2025
Expand Down
23 changes: 13 additions & 10 deletions Generals/Code/GameEngine/Include/GameLogic/GameLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ enum BuildableStatus CPP_11(: Int);
typedef const CommandButton* ConstCommandButtonPtr;

// What kind of game we're in.
enum
enum GameMode CPP_11(: Int)
{
GAME_SINGLE_PLAYER,
GAME_LAN,
Expand Down Expand Up @@ -116,7 +116,7 @@ class GameLogic : public SubsystemInterface, public Snapshot

void processCommandList( CommandList *list ); ///< process the command list

void prepareNewGame( Int gameMode, GameDifficulty diff, Int rankPoints ); ///< prepare for new game
void prepareNewGame( GameMode gameMode, GameDifficulty diff, Int rankPoints ); ///< prepare for new game

void logicMessageDispatcher( GameMessage *msg,
void *userData ); ///< Logic command list processing
Expand Down Expand Up @@ -162,16 +162,20 @@ class GameLogic : public SubsystemInterface, public Snapshot
void deleteLoadScreen( void );

void setGameLoading( Bool loading );
void setGameMode( Int mode );
Int getGameMode( void );
Bool isInGame( void );
void setGameMode( GameMode mode );
GameMode getGameMode( void );

Bool isInGame( void ); // Includes Shell Game
Bool isInLanGame( void );
Bool isInSinglePlayerGame( void );
Bool isInSkirmishGame( void );
Bool isInReplayGame( void );
Bool isInInternetGame( void );
Bool isInShellGame( void );
Bool isInMultiplayerGame( void );

static Bool isInInteractiveGame(GameMode mode) { return mode != GAME_NONE && mode != GAME_SHELL; }

Bool isLoadingGame();
void enableScoring(Bool score) { m_isScoringEnabled = score; }
Bool isScoringEnabled() const { return m_isScoringEnabled; }
Expand Down Expand Up @@ -335,7 +339,7 @@ class GameLogic : public SubsystemInterface, public Snapshot
virtual TerrainLogic *createTerrainLogic( void );
virtual GhostObjectManager *createGhostObjectManager(void);

Int m_gameMode;
GameMode m_gameMode;
Int m_rankLevelLimit;

LoadScreen *getLoadScreen( Bool saveGame );
Expand Down Expand Up @@ -386,12 +390,11 @@ inline void GameLogic::setHeight( Real height ) { m_height = height; }
inline Real GameLogic::getHeight( void ) { return m_height; }
inline UnsignedInt GameLogic::getFrame( void ) { return m_frame; }

inline Bool GameLogic::isInGame( void ) { return !(m_gameMode == GAME_NONE); }
inline void GameLogic::setGameMode( Int mode ) { m_gameMode = mode; }
inline Int GameLogic::getGameMode( void ) { return m_gameMode; }
inline Bool GameLogic::isInGame( void ) { return m_gameMode != GAME_NONE; }
inline GameMode GameLogic::getGameMode( void ) { return m_gameMode; }
inline Bool GameLogic::isInLanGame( void ) { return (m_gameMode == GAME_LAN); }
inline Bool GameLogic::isInSkirmishGame( void ) { return (m_gameMode == GAME_SKIRMISH); }
inline Bool GameLogic::isInMultiplayerGame( void ) { return ((m_gameMode == GAME_LAN) || (m_gameMode == GAME_INTERNET)) ; }
inline Bool GameLogic::isInMultiplayerGame( void ) { return (m_gameMode == GAME_LAN) || (m_gameMode == GAME_INTERNET) ; }
inline Bool GameLogic::isInReplayGame( void ) { return (m_gameMode == GAME_REPLAY); }
inline Bool GameLogic::isInInternetGame( void ) { return (m_gameMode == GAME_INTERNET); }
inline Bool GameLogic::isInShellGame( void ) { return (m_gameMode == GAME_SHELL); }
Expand Down
5 changes: 0 additions & 5 deletions Generals/Code/GameEngine/Source/Common/GameEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,6 @@ void GameEngine::init()
initSubsystem(TheWritableGlobalData, "TheWritableGlobalData", TheWritableGlobalData, &xferCRC, "Data\\INI\\Default\\GameData.ini", "Data\\INI\\GameData.ini");
TheWritableGlobalData->parseCustomDefinition();

// TheSuperHackers @bugfix helmutbuhler 14/04/2025
// Pump messages during startup to ensure that the application window is correctly
// positioned on slower computers and in debug builds by a later call to SetWindowPos.
// It is unclear what the issue with SetWindowPos is when it fails to reposition the window.
serviceWindowsOS();


#if defined(RTS_DEBUG)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ void GameStateMap::xfer( Xfer *xfer )
if (currentVersion >= 2)
{
// save the game mode.
Int gameMode = TheGameLogic->getGameMode();
Int gameMode = (Int)TheGameLogic->getGameMode();
xfer->xferInt( &gameMode);
}

Expand Down Expand Up @@ -338,7 +338,7 @@ void GameStateMap::xfer( Xfer *xfer )
// get the game mode.
Int gameMode;
xfer->xferInt(&gameMode);
TheGameLogic->setGameMode(gameMode);
TheGameLogic->setGameMode((GameMode)gameMode);
}

} // end else, load
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,24 @@ Real OptionPreferences::getScrollFactor(void)
return factor/100.0f;
}

CursorCaptureMode OptionPreferences::getCursorCaptureMode() const
{
CursorCaptureMode mode = CursorCaptureMode_Default;
OptionPreferences::const_iterator it = find("CursorCaptureMode");
if (it != end())
{
for (Int i = 0; i < CursorCaptureMode_Count; ++i)
{
if (stricmp(it->second.str(), TheCursorCaptureModeNames[i]) == 0)
{
mode = static_cast<CursorCaptureMode>(i);
break;
}
}
}
return mode;
}

Bool OptionPreferences::usesSystemMapDir(void)
{
OptionPreferences::const_iterator it = find("UseSystemMapDir");
Expand Down Expand Up @@ -1140,6 +1158,13 @@ static void saveOptions( void )
TheWritableGlobalData->m_useAlternateMouse = GadgetCheckBoxIsChecked(checkAlternateMouse);
(*pref)["UseAlternateMouse"] = TheWritableGlobalData->m_useAlternateMouse ? AsciiString("yes") : AsciiString("no");

// TheSuperHackers @todo Add combo box ?
{
CursorCaptureMode mode = pref->getCursorCaptureMode();
(*pref)["CursorCaptureMode"] = TheCursorCaptureModeNames[mode];
TheMouse->setCursorCaptureMode(mode);
}

//-------------------------------------------------------------------------------------------------
// scroll speed val
val = GadgetSliderGetPosition(sliderScrollSpeed);
Expand Down
1 change: 1 addition & 0 deletions Generals/Code/GameEngine/Source/GameClient/GameClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ GameClient::~GameClient()
delete TheFontLibrary;
TheFontLibrary = NULL;

TheMouse->reset();
delete TheMouse;
TheMouse = NULL;

Expand Down
6 changes: 0 additions & 6 deletions Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2810,7 +2810,6 @@ void InGameUI::setScrolling( Bool isScrolling )

if (isScrolling)
{
TheMouse->capture();
setMouseCursor( Mouse::SCROLL );

// break any camera locks
Expand All @@ -2820,7 +2819,6 @@ void InGameUI::setScrolling( Bool isScrolling )
else
{
setMouseCursor( Mouse::ARROW );
TheMouse->releaseCapture();
}

m_isScrolling = isScrolling;
Expand Down Expand Up @@ -3019,9 +3017,6 @@ void InGameUI::placeBuildAvailable( const ThingTemplate *build, Drawable *buildD

Drawable *draw;

// capture the mouse for our window, windows is lame and changes it if we don't
TheMouse->capture();

// hack for changing cursor
setMouseCursor( Mouse::CROSS );

Expand Down Expand Up @@ -3070,7 +3065,6 @@ void InGameUI::placeBuildAvailable( const ThingTemplate *build, Drawable *buildD
m_mouseModeCursor = Mouse::ARROW;
}

TheMouse->releaseCapture();
setMouseCursor( Mouse::ARROW );
setPlacementStart( NULL );

Expand Down
Loading
Loading