Skip to content

Commit

Permalink
[Agents] Add keyboard and mouse input
Browse files Browse the repository at this point in the history
  • Loading branch information
garbear committed Jan 17, 2024
1 parent e68a3b9 commit 6bf1626
Show file tree
Hide file tree
Showing 22 changed files with 573 additions and 18 deletions.
5 changes: 5 additions & 0 deletions xbmc/games/addons/input/GameClientInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,11 @@ float CGameClientInput::GetPortActivation(const std::string& portAddress)
auto it = m_joysticks.find(portAddress);
if (it != m_joysticks.end())
activation = it->second->GetActivation();

if (portAddress == KEYBOARD_PORT_ADDRESS && m_keyboard)
activation = std::max(m_keyboard->GetActivation(), activation);
else if (portAddress == MOUSE_PORT_ADDRESS && m_mouse)
activation = std::max(m_mouse->GetActivation(), activation);
}

return activation;
Expand Down
15 changes: 14 additions & 1 deletion xbmc/games/addons/input/GameClientKeyboard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "addons/kodi-dev-kit/include/kodi/addon-instance/Game.h"
#include "games/addons/GameClient.h"
#include "games/addons/GameClientTranslator.h"
#include "games/controllers/input/ControllerActivity.h"
#include "input/keyboard/interfaces/IKeyboardInputProvider.h"
#include "utils/log.h"

Expand All @@ -27,7 +28,8 @@ CGameClientKeyboard::CGameClientKeyboard(CGameClient& gameClient,
KEYBOARD::IKeyboardInputProvider* inputProvider)
: m_gameClient(gameClient),
m_controllerId(std::move(controllerId)),
m_inputProvider(inputProvider)
m_inputProvider(inputProvider),
m_keyboardActivity(std::make_unique<CControllerActivity>())
{
m_inputProvider->RegisterKeyboardHandler(this, false);
}
Expand All @@ -51,6 +53,9 @@ bool CGameClientKeyboard::OnKeyPress(const KEYBOARD::KeyName& key,
KEYBOARD::Modifier mod,
uint32_t unicode)
{
m_keyboardActivity->OnKeyPress(key);
m_keyboardActivity->OnInputFrame();

// Only allow activated input in fullscreen game
if (!m_gameClient.Input().AcceptsInput())
{
Expand All @@ -76,6 +81,9 @@ void CGameClientKeyboard::OnKeyRelease(const KEYBOARD::KeyName& key,
KEYBOARD::Modifier mod,
uint32_t unicode)
{
m_keyboardActivity->OnKeyRelease(key);
m_keyboardActivity->OnInputFrame();

game_input_event event;

event.type = GAME_INPUT_EVENT_KEY;
Expand All @@ -90,6 +98,11 @@ void CGameClientKeyboard::OnKeyRelease(const KEYBOARD::KeyName& key,
m_gameClient.Input().InputEvent(event);
}

float CGameClientKeyboard::GetActivation() const
{
return m_keyboardActivity->GetActivation();
}

void CGameClientKeyboard::SetSource(PERIPHERALS::PeripheralPtr sourcePeripheral)
{
m_sourcePeripheral = std::move(sourcePeripheral);
Expand Down
3 changes: 3 additions & 0 deletions xbmc/games/addons/input/GameClientKeyboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class IKeyboardInputProvider;

namespace GAME
{
class CControllerActivity;
class CGameClient;

/*!
Expand Down Expand Up @@ -59,6 +60,7 @@ class CGameClientKeyboard : public KEYBOARD::IKeyboardInputHandler
// Input accessors
const std::string& GetControllerID() const { return m_controllerId; }
const PERIPHERALS::PeripheralPtr& GetSource() const { return m_sourcePeripheral; }
float GetActivation() const;

// Input mutators
void SetSource(PERIPHERALS::PeripheralPtr sourcePeripheral);
Expand All @@ -72,6 +74,7 @@ class CGameClientKeyboard : public KEYBOARD::IKeyboardInputHandler

// Input parameters
PERIPHERALS::PeripheralPtr m_sourcePeripheral;
std::unique_ptr<CControllerActivity> m_keyboardActivity;
};
} // namespace GAME
} // namespace KODI
23 changes: 22 additions & 1 deletion xbmc/games/addons/input/GameClientMouse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "GameClientInput.h"
#include "addons/kodi-dev-kit/include/kodi/addon-instance/Game.h"
#include "games/addons/GameClient.h"
#include "games/controllers/input/ControllerActivity.h"
#include "input/mouse/interfaces/IMouseInputProvider.h"

#include <utility>
Expand All @@ -23,7 +24,8 @@ CGameClientMouse::CGameClientMouse(CGameClient& gameClient,
MOUSE::IMouseInputProvider* inputProvider)
: m_gameClient(gameClient),
m_controllerId(std::move(controllerId)),
m_inputProvider(inputProvider)
m_inputProvider(inputProvider),
m_mouseActivity(std::make_unique<CControllerActivity>())
{
inputProvider->RegisterMouseHandler(this, false);
}
Expand All @@ -40,6 +42,9 @@ std::string CGameClientMouse::ControllerID(void) const

bool CGameClientMouse::OnMotion(const std::string& relpointer, int dx, int dy)
{
//! @todo Fix this
//m_mouseActivity->OnMouseMotion(relpointer, differenceX, differenceY);

// Only allow activated input in fullscreen game
if (!m_gameClient.Input().AcceptsInput())
{
Expand All @@ -63,6 +68,9 @@ bool CGameClientMouse::OnMotion(const std::string& relpointer, int dx, int dy)

bool CGameClientMouse::OnButtonPress(const std::string& button)
{
m_mouseActivity->OnMouseButtonPress(button);
m_mouseActivity->OnInputFrame();

// Only allow activated input in fullscreen game
if (!m_gameClient.Input().AcceptsInput())
{
Expand All @@ -83,6 +91,9 @@ bool CGameClientMouse::OnButtonPress(const std::string& button)

void CGameClientMouse::OnButtonRelease(const std::string& button)
{
m_mouseActivity->OnMouseButtonRelease(button);
m_mouseActivity->OnInputFrame();

game_input_event event;

event.type = GAME_INPUT_EVENT_DIGITAL_BUTTON;
Expand All @@ -95,6 +106,16 @@ void CGameClientMouse::OnButtonRelease(const std::string& button)
m_gameClient.Input().InputEvent(event);
}

void CGameClientMouse::OnInputFrame()
{
m_mouseActivity->OnInputFrame();
}

float CGameClientMouse::GetActivation() const
{
return m_mouseActivity->GetActivation();
}

void CGameClientMouse::SetSource(PERIPHERALS::PeripheralPtr sourcePeripheral)
{
m_sourcePeripheral = std::move(sourcePeripheral);
Expand Down
4 changes: 4 additions & 0 deletions xbmc/games/addons/input/GameClientMouse.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class IMouseInputProvider;

namespace GAME
{
class CControllerActivity;
class CGameClient;

/*!
Expand Down Expand Up @@ -53,10 +54,12 @@ class CGameClientMouse : public MOUSE::IMouseInputHandler
bool OnMotion(const std::string& relpointer, int dx, int dy) override;
bool OnButtonPress(const std::string& button) override;
void OnButtonRelease(const std::string& button) override;
void OnInputFrame() override;

// Input accessors
const std::string& GetControllerID() const { return m_controllerId; }
const PERIPHERALS::PeripheralPtr& GetSource() const { return m_sourcePeripheral; }
float GetActivation() const;

// Input mutators
void SetSource(PERIPHERALS::PeripheralPtr sourcePeripheral);
Expand All @@ -70,6 +73,7 @@ class CGameClientMouse : public MOUSE::IMouseInputHandler

// Input parameters
PERIPHERALS::PeripheralPtr m_sourcePeripheral;
std::unique_ptr<CControllerActivity> m_mouseActivity;
};
} // namespace GAME
} // namespace KODI
72 changes: 65 additions & 7 deletions xbmc/games/agents/input/AgentController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,41 @@
#include "AgentController.h"

#include "AgentJoystick.h"
#include "AgentKeyboard.h"
#include "AgentMouse.h"
#include "games/controllers/Controller.h"
#include "games/controllers/ControllerLayout.h"
#include "peripherals/devices/Peripheral.h"

#include <algorithm>

using namespace KODI;
using namespace GAME;

CAgentController::CAgentController(PERIPHERALS::PeripheralPtr peripheral)
: m_peripheral(std::move(peripheral)), m_joystick(std::make_unique<CAgentJoystick>(m_peripheral))
: m_peripheral(std::move(peripheral))
{
switch (m_peripheral->Type())
{
case PERIPHERALS::PERIPHERAL_JOYSTICK:
{
m_joystick = std::make_unique<CAgentJoystick>(m_peripheral);
break;
}
case PERIPHERALS::PERIPHERAL_KEYBOARD:
{
m_keyboard = std::make_unique<CAgentKeyboard>(m_peripheral);
break;
}
case PERIPHERALS::PERIPHERAL_MOUSE:
{
m_mouse = std::make_unique<CAgentMouse>(m_peripheral);
break;
}
default:
break;
}

Initialize();
}

Expand All @@ -29,12 +54,22 @@ CAgentController::~CAgentController()

void CAgentController::Initialize()
{
m_joystick->Initialize();
if (m_joystick)
m_joystick->Initialize();
if (m_keyboard)
m_keyboard->Initialize();
if (m_mouse)
m_mouse->Initialize();
}

void CAgentController::Deinitialize()
{
m_joystick->Deinitialize();
if (m_mouse)
m_mouse->Deinitialize();
if (m_keyboard)
m_keyboard->Deinitialize();
if (m_joystick)
m_joystick->Deinitialize();
}

std::string CAgentController::GetPeripheralName() const
Expand All @@ -60,9 +95,12 @@ const std::string& CAgentController::GetPeripheralLocation() const
ControllerPtr CAgentController::GetController() const
{
// Use joystick controller if joystick is initialized
ControllerPtr controller = m_joystick->Appearance();
if (controller)
return controller;
if (m_joystick)
{
ControllerPtr controller = m_joystick->Appearance();
if (controller)
return controller;
}

// Use peripheral controller if joystick is deinitialized
return m_peripheral->ControllerProfile();
Expand All @@ -75,5 +113,25 @@ CDateTime CAgentController::LastActive() const

float CAgentController::GetActivation() const
{
return m_joystick->GetActivation();
// Return the maximum activation of all joystick, keyboard and mice input providers
float activation = 0.0f;

if (m_joystick)
activation = std::max(activation, m_joystick->GetActivation());
if (m_keyboard)
activation = std::max(activation, m_keyboard->GetActivation());
if (m_mouse)
activation = std::max(activation, m_mouse->GetActivation());

return activation;
}

void CAgentController::ClearButtonState()
{
if (m_joystick)
m_joystick->ClearButtonState();
if (m_keyboard)
m_keyboard->ClearButtonState();
if (m_mouse)
m_mouse->ClearButtonState();
}
5 changes: 5 additions & 0 deletions xbmc/games/agents/input/AgentController.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ namespace KODI
namespace GAME
{
class CAgentJoystick;
class CAgentKeyboard;
class CAgentMouse;

/*!
* \ingroup games
Expand All @@ -45,13 +47,16 @@ class CAgentController
ControllerPtr GetController() const;
CDateTime LastActive() const;
float GetActivation() const;
void ClearButtonState();

private:
// Construction parameters
const PERIPHERALS::PeripheralPtr m_peripheral;

// Input parameters
std::unique_ptr<CAgentJoystick> m_joystick;
std::unique_ptr<CAgentKeyboard> m_keyboard;
std::unique_ptr<CAgentMouse> m_mouse;
};

} // namespace GAME
Expand Down
20 changes: 18 additions & 2 deletions xbmc/games/agents/input/AgentInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ void CAgentInput::Start(GameClientPtr gameClient)
// Register callbacks
if (m_gameClient)
m_gameClient->Input().RegisterObserver(this);

// Perform initial refresh
Refresh();
}

void CAgentInput::Stop()
Expand Down Expand Up @@ -214,7 +217,7 @@ std::string CAgentInput::GetMouseAddress(MOUSE::IMouseInputProvider* inputProvid
return "";
}

std::vector<std::string> CAgentInput::GetInputPorts() const
std::vector<std::string> CAgentInput::GetGameInputPorts() const
{
std::vector<std::string> inputPorts;

Expand All @@ -227,7 +230,7 @@ std::vector<std::string> CAgentInput::GetInputPorts() const
return inputPorts;
}

float CAgentInput::GetPortActivation(const std::string& portAddress) const
float CAgentInput::GetGamePortActivation(const std::string& portAddress) const
{
float activation = 0.0f;

Expand All @@ -250,6 +253,19 @@ float CAgentInput::GetPeripheralActivation(const std::string& peripheralLocation
return 0.0f;
}

void CAgentInput::SetAppFocusState(bool isAppFocused)
{
if (m_appFocused && !isAppFocused)
{
// Clear button state
for (const std::shared_ptr<CAgentController>& controller : m_controllers)
controller->ClearButtonState();
}

// Update state
m_appFocused = isAppFocused;
}

void CAgentInput::ProcessJoysticks(PERIPHERALS::EventLockHandlePtr& inputHandlingLock)
{
// Get system joysticks.
Expand Down
6 changes: 4 additions & 2 deletions xbmc/games/agents/input/AgentInput.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ class CAgentInput : public Observable,
std::string GetPortAddress(JOYSTICK::IInputProvider* inputProvider) const;
std::string GetKeyboardAddress(KEYBOARD::IKeyboardInputProvider* inputProvider) const;
std::string GetMouseAddress(MOUSE::IMouseInputProvider* inputProvider) const;
std::vector<std::string> GetInputPorts() const;
float GetPortActivation(const std::string& address) const;
std::vector<std::string> GetGameInputPorts() const;
float GetGamePortActivation(const std::string& address) const;
float GetPeripheralActivation(const std::string& peripheralLocation) const;
void SetAppFocusState(bool isAppFocused);

private:
//! @todo De-duplicate these types
Expand Down Expand Up @@ -149,6 +150,7 @@ class CAgentInput : public Observable,
int m_initialMouseX{-1};
int m_initialMouseY{-1};
std::vector<std::shared_ptr<CAgentController>> m_controllers;
bool m_appFocused{true};

// Synchronization parameters
mutable std::mutex m_controllerMutex;
Expand Down
5 changes: 5 additions & 0 deletions xbmc/games/agents/input/AgentJoystick.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ void CAgentJoystick::Deinitialize()
m_controllerAppearance.reset();
}

void CAgentJoystick::ClearButtonState()
{
return m_controllerActivity->ClearButtonState();
}

float CAgentJoystick::GetActivation() const
{
return m_controllerActivity->GetActivation();
Expand Down
Loading

0 comments on commit 6bf1626

Please sign in to comment.