Browse Source

change hardware cursor to software cursor when joystick available

kdmcser 1 year ago
parent
commit
60c4ddb515

+ 8 - 2
client/eventsSDL/InputSourceGameController.cpp

@@ -200,13 +200,19 @@ void InputSourceGameController::doCursorMove(int deltaX, int deltaY)
     if(deltaX == 0 && deltaY == 0)
         return;
     const Point & screenSize = GH.screenDimensions();
-    const Point &cursorPosition = GH.getCursorPosition();
+
+    // if joystick is connected when intro video plays, using hardware position will move cursor to the right position.
+    bool isHardwareCursor = CCS && CCS->curh && CCS->curh->getShowType() == Cursor::ShowType::HARDWARE;
+    const Point & cursorPosition = isHardwareCursor ? CCS->curh->getCursorPosition() : GH.getCursorPosition();
     int newX = std::min(std::max(cursorPosition.x + deltaX, 0), screenSize.x);
     int newY = std::min(std::max(cursorPosition.y + deltaY, 0), screenSize.y);
     Point targetPosition{newX, newY};
     GH.input().setCursorPosition(targetPosition);
-    if(CCS && CCS->curh)
+    if(CCS && CCS->curh) {
+        if(CCS->curh->getShowType() == Cursor::ShowType::HARDWARE)
+            CCS->curh->ChangeCursor(Cursor::ShowType::SOFTWARE);
         CCS->curh->cursorMove(GH.getCursorPosition().x, GH.getCursorPosition().y);
+    }
 }
 
 int InputSourceGameController::getMoveDis(float planDis)

+ 30 - 0
client/gui/CursorHandler.cpp

@@ -57,6 +57,7 @@ CursorHandler::CursorHandler()
 		cursor->preload();
 
 	set(Cursor::Map::POINTER);
+    showType = dynamic_cast<CursorSoftware *>(cursor.get()) ? Cursor::ShowType::SOFTWARE : Cursor::ShowType::HARDWARE;
 }
 
 CursorHandler::~CursorHandler() = default;
@@ -290,3 +291,32 @@ void CursorHandler::show()
 	cursor->setVisible(true);
 }
 
+Cursor::ShowType CursorHandler::getShowType()
+{
+    return showType;
+}
+
+void CursorHandler::ChangeCursor(Cursor::ShowType showType)
+{
+    if(this->showType == showType)
+        return;
+
+    switch(showType)
+    {
+        case Cursor::ShowType::SOFTWARE:
+            cursor.reset(new CursorSoftware());
+            showType = Cursor::ShowType::SOFTWARE;
+            cursor->setImage(getCurrentImage(), getPivotOffset());
+            break;
+        case Cursor::ShowType::HARDWARE:
+            cursor.reset(new CursorHardware());
+            showType = Cursor::ShowType::HARDWARE;
+            cursor->setImage(getCurrentImage(), getPivotOffset());
+            break;
+    }
+}
+
+const Point & CursorHandler::getCursorPosition()
+{
+    return cursor->getCursorPosition();
+}

+ 10 - 0
client/gui/CursorHandler.h

@@ -25,6 +25,11 @@ namespace Cursor
 		SPELLBOOK  // animated cursor for spellcasting
 	};
 
+    enum class ShowType {
+        SOFTWARE,
+        HARDWARE
+    };
+
 	enum class Default {
 		POINTER      = 0,
 		//ARROW_COPY = 1, // probably unused
@@ -120,6 +125,7 @@ class CursorHandler final
 
 	/// Current cursor
 	Cursor::Type type;
+    Cursor::ShowType showType;
 	size_t frame;
 	float frameTime;
 	Point pos;
@@ -179,4 +185,8 @@ public:
 
 	/// change cursor's positions to (x, y)
 	void cursorMove(const int & x, const int & y);
+
+    Cursor::ShowType getShowType();
+    void ChangeCursor(Cursor::ShowType showType);
+    const Point & getCursorPosition();
 };

+ 1 - 0
client/render/ICursor.h

@@ -24,5 +24,6 @@ public:
 	virtual void setCursorPosition( const Point & newPos ) = 0;
 	virtual void render() = 0;
 	virtual void setVisible( bool on) = 0;
+    virtual const Point & getCursorPosition() = 0;
 };
 

+ 3 - 0
client/render/IScreenHandler.h

@@ -43,4 +43,7 @@ public:
 
 	/// Window has focus
 	virtual bool hasFocus() = 0;
+
+    /// Get the scale value of screen
+    virtual void getRenderScale(float & scaleX, float & scaleY) = 0;
 };

+ 12 - 0
client/renderSDL/CursorHardware.cpp

@@ -12,6 +12,7 @@
 #include "CursorHardware.h"
 
 #include "../gui/CGuiHandler.h"
+#include "../renderSDL/ScreenHandler.h"
 #include "../render/Colors.h"
 #include "../render/IImage.h"
 #include "SDL_Extensions.h"
@@ -66,6 +67,17 @@ void CursorHardware::setImage(std::shared_ptr<IImage> image, const Point & pivot
 	});
 }
 
+const Point & CursorHardware::getCursorPosition()
+{
+    int mouseX, mouseY;
+    SDL_GetMouseState(&mouseX, &mouseY);
+    float scaleX, scaleY;
+    GH.screenHandler().getRenderScale(scaleX, scaleY);
+    pos.x = int(mouseX / scaleX);
+    pos.y = int(mouseY / scaleY);
+    return pos;
+}
+
 void CursorHardware::setCursorPosition( const Point & newPos )
 {
 	//no-op

+ 2 - 0
client/renderSDL/CursorHardware.h

@@ -23,6 +23,7 @@ class CursorHardware : public ICursor
 	std::shared_ptr<IImage> cursorImage;
 
 	SDL_Cursor * cursor;
+    Point pos;
 
 public:
 	CursorHardware();
@@ -32,5 +33,6 @@ public:
 	void setCursorPosition( const Point & newPos ) override;
 	void render() override;
 	void setVisible( bool on) override;
+    const Point & getCursorPosition() override;
 };
 

+ 5 - 0
client/renderSDL/CursorSoftware.cpp

@@ -81,6 +81,11 @@ void CursorSoftware::setVisible(bool on)
 	visible = on;
 }
 
+const Point & CursorSoftware::getCursorPosition()
+{
+    return pos;
+}
+
 CursorSoftware::CursorSoftware():
 	cursorTexture(nullptr),
 	cursorSurface(nullptr),

+ 1 - 0
client/renderSDL/CursorSoftware.h

@@ -40,5 +40,6 @@ public:
 	void setCursorPosition( const Point & newPos ) override;
 	void render() override;
 	void setVisible( bool on) override;
+    const Point & getCursorPosition() override;
 };
 

+ 5 - 0
client/renderSDL/ScreenHandler.cpp

@@ -583,3 +583,8 @@ bool ScreenHandler::hasFocus()
 	ui32 flags = SDL_GetWindowFlags(mainWindow);
 	return flags & SDL_WINDOW_INPUT_FOCUS;
 }
+
+void ScreenHandler::getRenderScale(float & scaleX, float & scaleY)
+{
+    SDL_RenderGetScale(mainRenderer, &scaleX, &scaleY);
+}

+ 3 - 0
client/renderSDL/ScreenHandler.h

@@ -89,6 +89,9 @@ public:
 	/// Window has focus
 	bool hasFocus() final;
 
+    /// Get the scale value of screen
+    void getRenderScale(float & scaleX, float & scaleY);
+
 	std::vector<Point> getSupportedResolutions() const final;
 	std::vector<Point> getSupportedResolutions(int displayIndex) const;
 	std::tuple<int, int> getSupportedScalingRange() const final;