Skip to content
Open
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
2 changes: 2 additions & 0 deletions src/gui/wxgui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ add_library(CemuWxGui STATIC
input/settings/DefaultControllerSettings.h
input/settings/WiimoteControllerSettings.cpp
input/settings/WiimoteControllerSettings.h
input/settings/MouseControllerSettings.cpp
input/settings/MouseControllerSettings.h
LoggingWindow.cpp
LoggingWindow.h
MainWindow.cpp
Expand Down
6 changes: 6 additions & 0 deletions src/gui/wxgui/MainWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1383,6 +1383,12 @@ void MainWindow::OnMouseMove(wxMouseEvent& event)
std::unique_lock lock(instance.m_main_mouse.m_mutex);
auto physPos = ToPhys(event.GetPosition());
instance.m_main_mouse.position = { physPos.x, physPos.y };
auto renderCanvasMouse = m_render_canvas->ScreenToClient(m_mouse_position);
instance.SetMousePositionInRenderBox
({
static_cast<float>(renderCanvasMouse.x) / m_render_canvas->GetClientSize().GetWidth(),
static_cast<float>(renderCanvasMouse.y) / m_render_canvas->GetClientSize().GetHeight(),
});
lock.unlock();

if (!IsFullScreen())
Expand Down
17 changes: 15 additions & 2 deletions src/gui/wxgui/input/InputAPIAddWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,23 @@ void InputAPIAddWindow::on_api_selected(wxCommandEvent& event)
m_controller_list->SetSelection(wxNOT_FOUND);

const auto selection = m_input_api->GetStringSelection();
// keyboard is a special case, as theres only one device supported atm
// keyboard and mouse are special cases, as theres only one device supported atm
bool isSingleDeviceOnly{false};
InputAPI::Type singleDeviceAPI;
if (selection == wxString::FromUTF8(to_string(InputAPI::Keyboard)))
{
const auto controllers = InputManager::instance().get_api_provider(InputAPI::Keyboard)->get_controllers();
isSingleDeviceOnly = true;
singleDeviceAPI = InputAPI::Keyboard;
}
else if (selection == wxString::FromUTF8(to_string(InputAPI::Mouse)))
{
isSingleDeviceOnly = true;
singleDeviceAPI = InputAPI::Mouse;
}

if (isSingleDeviceOnly)
{
const auto controllers = InputManager::instance().get_api_provider(singleDeviceAPI)->get_controllers();
if (!controllers.empty())
{
m_controller = controllers[0];
Expand Down
11 changes: 10 additions & 1 deletion src/gui/wxgui/input/InputSettings2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "wxgui/input/PairingDialog.h"
#endif

#include "input/api/Mouse/MouseController.h"
#include "wxgui/input/panels/VPADInputPanel.h"
#include "wxgui/input/panels/ProControllerInputPanel.h"

Expand All @@ -35,6 +36,7 @@
#include "util/EventService.h"

#include "resource/embedded/resources.h"
#include "settings/MouseControllerSettings.h"

bool g_inputConfigWindowHasFocus = false;

Expand Down Expand Up @@ -960,7 +962,14 @@ void InputSettings2::on_controller_settings(wxCommandEvent& event)
wnd.ShowModal();
break;
}

case InputAPI::Mouse:
{
const auto mouse_controller = std::dynamic_pointer_cast<MouseController>(controller);
wxASSERT(mouse_controller);
MouseControllerSettings wnd(this, wxGetMousePosition() + wxSize(5, 5), mouse_controller);
wnd.ShowModal();
break;
}
case InputAPI::Keyboard: break;

#ifdef SUPPORTS_WIIMOTE
Expand Down
72 changes: 72 additions & 0 deletions src/gui/wxgui/input/settings/MouseControllerSettings.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#include "MouseControllerSettings.h"

#include "input/api/Mouse/MouseController.h"

#include <wx/sizer.h>
#include <wx/button.h>
#include <wx/checkbox.h>
#include <wx/statbox.h>

#include "wxgui/helpers/wxHelpers.h"
#include "wxgui/input/InputAPIAddWindow.h"


MouseControllerSettings::MouseControllerSettings(wxWindow* parent, const wxPoint& position, std::shared_ptr<MouseController> controller)
: wxDialog(parent, wxID_ANY, _("Controller settings"), position, wxDefaultSize,
wxDEFAULT_DIALOG_STYLE), m_controller(std::move(controller))
{
this->SetSizeHints(wxDefaultSize, wxDefaultSize);

auto* sizer = new wxBoxSizer(wxVERTICAL);

// options
{
auto* box = new wxStaticBox(this, wxID_ANY, _("Options"));
auto* box_sizer = new wxStaticBoxSizer(box, wxVERTICAL);

// Position (wiimote pointer)
m_usePosition = new wxCheckBox(box, wxID_ANY, _("Use position"));
m_usePosition->SetValue(m_controller->IsPositionEnabled());
m_usePosition->Enable(m_controller->has_position());
box_sizer->Add(m_usePosition, 0, wxEXPAND | wxALL, 5);

sizer->Add(box_sizer, 1, wxALL|wxEXPAND, 5);
}

{
auto* control_sizer = new wxFlexGridSizer(0, 3, 0, 0);
control_sizer->AddGrowableCol(2);

auto* ok_button = new wxButton(this, wxID_ANY, _("OK"));
ok_button->Bind(wxEVT_BUTTON, [this](auto&) { UpdateSettings(); EndModal(wxID_OK); });
control_sizer->Add(ok_button, 0, wxALL, 5);

control_sizer->Add(0, 0, 0, wxEXPAND, 5);

auto* cancel_button = new wxButton(this, wxID_ANY, _("Cancel"));
cancel_button->Bind(wxEVT_BUTTON, [this](auto&) { EndModal(wxID_CANCEL); });
control_sizer->Add(cancel_button, 0, wxALL, 5);

sizer->Add(control_sizer, 0, wxEXPAND, 5);
}

this->SetSizer(sizer);
this->Layout();
this->Fit();

this->Bind(wxEVT_CLOSE_WINDOW, &MouseControllerSettings::OnClose, this);
}

void MouseControllerSettings::UpdateSettings()
{
if (m_usePosition)
m_controller->SetPositionEnabled(m_usePosition->GetValue());
}

void MouseControllerSettings::OnClose(wxCloseEvent& event)
{
if (this->GetReturnCode() == 0 || this->GetReturnCode() == wxID_OK)
UpdateSettings();

event.Skip();
}
25 changes: 25 additions & 0 deletions src/gui/wxgui/input/settings/MouseControllerSettings.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include "input/api/Controller.h"
#include "wx/dialog.h"

#include <memory>

class wxCheckBox;
class wxPoint;
class wxWindow;
class MouseController;

class MouseControllerSettings : public wxDialog
{
public:
MouseControllerSettings(wxWindow* parent, const wxPoint& position, std::shared_ptr<MouseController> controller);

private:
std::shared_ptr<MouseController> m_controller;

wxCheckBox* m_usePosition = nullptr;

void UpdateSettings();
void OnClose(wxCloseEvent& event);
};
4 changes: 4 additions & 0 deletions src/input/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ add_library(CemuInput
api/Keyboard/KeyboardControllerProvider.cpp
api/Keyboard/KeyboardController.cpp
api/Keyboard/KeyboardController.h
api/Mouse/MouseControllerProvider.h
api/Mouse/MouseControllerProvider.cpp
api/Mouse/MouseController.cpp
api/Mouse/MouseController.h
emulated/ProController.cpp
emulated/EmulatedController.h
emulated/EmulatedController.cpp
Expand Down
5 changes: 5 additions & 0 deletions src/input/ControllerFactory.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "input/ControllerFactory.h"

#include "api/Mouse/MouseController.h"
#include "input/emulated/VPADController.h"
#include "input/emulated/ProController.h"
#include "input/emulated/ClassicController.h"
Expand Down Expand Up @@ -31,6 +32,10 @@ ControllerPtr ControllerFactory::CreateController(InputAPI::Type api, std::strin
case InputAPI::Keyboard:
return std::make_shared<KeyboardController>();
#endif
#if HAS_MOUSE
case InputAPI::Mouse:
return std::make_shared<MouseController>();
#endif
#if HAS_DIRECTINPUT
case InputAPI::DirectInput:
{
Expand Down
16 changes: 16 additions & 0 deletions src/input/InputManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <pugixml.hpp>
#include "Cafe/GameProfile/GameProfile.h"
#include "util/EventService.h"
#include "input/api/Mouse/MouseControllerProvider.h"

InputManager::InputManager()
{
Expand All @@ -28,6 +29,9 @@ InputManager::InputManager()
#if HAS_KEYBOARD
create_provider<KeyboardControllerProvider>();
#endif
#if HAS_MOUSE
create_provider<MouseControllerProvider>();
#endif
#ifdef HAS_SDL
create_provider<SDLControllerProvider>();
#endif
Expand Down Expand Up @@ -233,6 +237,8 @@ bool InputManager::migrate_config(const fs::path& file_path)
std::string uuid;
if (api_string == to_string(InputAPI::Keyboard))
uuid = to_string(InputAPI::Keyboard);
else if (api_string == to_string(InputAPI::Mouse))
uuid = to_string(InputAPI::Mouse);
else
{
if (!uuid_opt)
Expand Down Expand Up @@ -928,6 +934,16 @@ std::optional<glm::ivec2> InputManager::get_right_down_mouse_info(bool* is_pad)
return {};
}

glm::vec2 InputManager::GetMousePositionInRenderBox() const
{
return m_mouseInRenderCanvas;
}

void InputManager::SetMousePositionInRenderBox(glm::vec2 newMousePosition)
{
m_mouseInRenderCanvas = newMousePosition;
}

void InputManager::update_thread()
{
SetThreadName("Input_update");
Expand Down
7 changes: 7 additions & 0 deletions src/input/InputManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,17 @@ class InputManager : public Singleton<InputManager>
glm::ivec2 get_mouse_position(bool pad_window) const;
std::optional<glm::ivec2> get_left_down_mouse_info(bool* is_pad);
std::optional<glm::ivec2> get_right_down_mouse_info(bool* is_pad);
// Returns the mouse position relative to the render canvas (see MainWindow::m_render_canvas).
// (0, 0) is up left; (1, 1) is down right. The values may be negative or above 1 if the mouse cursor
// is outside the render canvas. At the time of writing this, it is used only for mouse-to-wiimote pointer feature.
glm::vec2 GetMousePositionInRenderBox() const;
void SetMousePositionInRenderBox(glm::vec2 newMousePosition);

std::atomic<float> m_mouse_wheel;

private:
glm::vec2 m_mouseInRenderCanvas{};

void update_thread();

std::thread m_update_thread;
Expand Down
5 changes: 5 additions & 0 deletions src/input/api/InputAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace InputAPI
enum Type
{
Keyboard,
Mouse,
SDLController,
XInput,
DirectInput,
Expand All @@ -26,6 +27,8 @@ namespace InputAPI
{
case Keyboard:
return "Keyboard";
case Mouse:
return "Mouse";
case DirectInput:
return "DirectInput";
case XInput:
Expand Down Expand Up @@ -53,6 +56,8 @@ namespace InputAPI
{
if (str == to_string(Keyboard))
return Keyboard;
else if (str == to_string(Mouse))
return Mouse;
else if (str == to_string(DirectInput))
return DirectInput;
else if (str == to_string(XInput))
Expand Down
26 changes: 26 additions & 0 deletions src/input/api/Mouse/MouseController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#include "MouseController.h"
#include "input/api/Controller.h"

std::string_view MouseController::api_name() const
{
static_assert(to_string(InputAPI::Mouse) == "Mouse");
return to_string(InputAPI::Mouse);
}

MouseController& MouseController::SetPositionEnabled(bool value)
{
m_isPositionEnabled = value;
return *this;
}

glm::vec2 MouseController::get_position()
{
return InputManager::instance().GetMousePositionInRenderBox();
}

PositionVisibility MouseController::GetPositionVisibility()
{
return IsPositionEnabled()
? PositionVisibility::FULL
: PositionVisibility::NONE;
}
26 changes: 26 additions & 0 deletions src/input/api/Mouse/MouseController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "MouseControllerProvider.h"
#include "input/api/Controller.h"


class MouseController : public Controller<MouseControllerProvider>
{
public:
MouseController() : base_type("mouse", "Mouse") {}

std::string_view api_name() const override;
InputAPI::Type api() const override { return InputAPI::Mouse; }
bool is_connected() override { return true; }
ControllerState raw_state() override { return {}; }

bool has_position() override { return true; }
bool IsPositionEnabled() const { return m_isPositionEnabled; }
MouseController& SetPositionEnabled(bool value);
glm::vec2 get_position() override;
PositionVisibility GetPositionVisibility() override;

private:
bool m_isPositionEnabled = false;
};

10 changes: 10 additions & 0 deletions src/input/api/Mouse/MouseControllerProvider.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "MouseControllerProvider.h"

#include "MouseController.h"

std::vector<std::shared_ptr<ControllerBase>> MouseControllerProvider::get_controllers()
{
std::vector<std::shared_ptr<ControllerBase>> result;
result.emplace_back(std::make_shared<MouseController>());
return result;
}
17 changes: 17 additions & 0 deletions src/input/api/Mouse/MouseControllerProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#pragma once

#include "input/api/ControllerProvider.h"

#ifndef HAS_MOUSE
#define HAS_MOUSE 1
#endif

class MouseControllerProvider : public ControllerProviderBase
{
public:
inline static InputAPI::Type kAPIType = InputAPI::Mouse;
InputAPI::Type api() const override { return kAPIType; }

std::vector<std::shared_ptr<ControllerBase>> get_controllers() override;
};