It builds
This commit is contained in:
@ -358,18 +358,18 @@ int main(int argc, char** argv) {
|
|||||||
// Register frontend applets
|
// Register frontend applets
|
||||||
Frontend::RegisterDefaultApplets();
|
Frontend::RegisterDefaultApplets();
|
||||||
|
|
||||||
EmuWindow_SDL2::InitializeSDL2();
|
InputCommon::InputSubsystem input_subsystem{};
|
||||||
|
|
||||||
const auto create_emu_window = [](bool fullscreen,
|
const auto create_emu_window = [&](bool fullscreen,
|
||||||
bool is_secondary) -> std::unique_ptr<EmuWindow_SDL2> {
|
bool is_secondary) -> std::unique_ptr<EmuWindow_SDL2> {
|
||||||
switch (Settings::values.graphics_api.GetValue()) {
|
switch (Settings::values.graphics_api.GetValue()) {
|
||||||
case Settings::GraphicsAPI::OpenGL:
|
case Settings::GraphicsAPI::OpenGL:
|
||||||
return std::make_unique<EmuWindow_SDL2_GL>(fullscreen, is_secondary);
|
return std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, fullscreen, is_secondary);
|
||||||
case Settings::GraphicsAPI::Software:
|
case Settings::GraphicsAPI::Software:
|
||||||
return std::make_unique<EmuWindow_SDL2_SW>(fullscreen, is_secondary);
|
return std::make_unique<EmuWindow_SDL2_SW>(&input_subsystem, fullscreen, is_secondary);
|
||||||
}
|
}
|
||||||
LOG_ERROR(Frontend, "Invalid Graphics API, using OpenGL");
|
LOG_ERROR(Frontend, "Invalid Graphics API, using OpenGL");
|
||||||
return std::make_unique<EmuWindow_SDL2_GL>(fullscreen, is_secondary);
|
return std::make_unique<EmuWindow_SDL2_GL>(&input_subsystem, fullscreen, is_secondary);
|
||||||
};
|
};
|
||||||
|
|
||||||
const auto emu_window{create_emu_window(fullscreen, false)};
|
const auto emu_window{create_emu_window(fullscreen, false)};
|
||||||
@ -496,7 +496,6 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Network::Shutdown();
|
Network::Shutdown();
|
||||||
InputCommon::Shutdown();
|
|
||||||
|
|
||||||
system.Shutdown();
|
system.Shutdown();
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ void Config::ReadSetting(const std::string& group, Settings::Setting<Type, range
|
|||||||
|
|
||||||
void Config::ReadValues() {
|
void Config::ReadValues() {
|
||||||
// Controls
|
// Controls
|
||||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
/*for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||||
Settings::values.current_input_profile.buttons[i] =
|
Settings::values.current_input_profile.buttons[i] =
|
||||||
sdl2_config->GetString("Controls", Settings::NativeButton::mapping[i], default_param);
|
sdl2_config->GetString("Controls", Settings::NativeButton::mapping[i], default_param);
|
||||||
@ -124,7 +124,7 @@ void Config::ReadValues() {
|
|||||||
"Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_ADDR);
|
"Controls", "udp_input_address", InputCommon::CemuhookUDP::DEFAULT_ADDR);
|
||||||
Settings::values.current_input_profile.udp_input_port =
|
Settings::values.current_input_profile.udp_input_port =
|
||||||
static_cast<u16>(sdl2_config->GetInteger("Controls", "udp_input_port",
|
static_cast<u16>(sdl2_config->GetInteger("Controls", "udp_input_port",
|
||||||
InputCommon::CemuhookUDP::DEFAULT_PORT));
|
InputCommon::CemuhookUDP::DEFAULT_PORT));*/
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
ReadSetting("Core", Settings::values.use_cpu_jit);
|
ReadSetting("Core", Settings::values.use_cpu_jit);
|
||||||
|
@ -2,131 +2,38 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <string>
|
#include <string>
|
||||||
#define SDL_MAIN_HANDLED
|
|
||||||
#include <SDL.h>
|
|
||||||
#include "citra/emu_window/emu_window_sdl2.h"
|
#include "citra/emu_window/emu_window_sdl2.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/scm_rev.h"
|
#include "common/scm_rev.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "input_common/keyboard.h"
|
#include "input_common/drivers/keyboard.h"
|
||||||
|
#include "input_common/drivers/mouse.h"
|
||||||
|
#include "input_common/drivers/touch_screen.h"
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "input_common/motion_emu.h"
|
|
||||||
#include "network/network.h"
|
#include "network/network.h"
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
|
EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, bool is_secondary)
|
||||||
TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
|
: EmuWindow(is_secondary), input_subsystem{input_subsystem_} {
|
||||||
InputCommon::GetMotionEmu()->Tilt(x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
|
||||||
if (button == SDL_BUTTON_LEFT) {
|
|
||||||
if (state == SDL_PRESSED) {
|
|
||||||
TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0));
|
|
||||||
} else {
|
|
||||||
TouchReleased();
|
|
||||||
}
|
|
||||||
} else if (button == SDL_BUTTON_RIGHT) {
|
|
||||||
if (state == SDL_PRESSED) {
|
|
||||||
InputCommon::GetMotionEmu()->BeginTilt(x, y);
|
|
||||||
} else {
|
|
||||||
InputCommon::GetMotionEmu()->EndTilt();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<unsigned, unsigned> EmuWindow_SDL2::TouchToPixelPos(float touch_x, float touch_y) const {
|
|
||||||
int w, h;
|
|
||||||
SDL_GetWindowSize(render_window, &w, &h);
|
|
||||||
|
|
||||||
touch_x *= w;
|
|
||||||
touch_y *= h;
|
|
||||||
|
|
||||||
return {static_cast<unsigned>(std::max(std::round(touch_x), 0.0f)),
|
|
||||||
static_cast<unsigned>(std::max(std::round(touch_y), 0.0f))};
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnFingerDown(float x, float y) {
|
|
||||||
// TODO(NeatNit): keep track of multitouch using the fingerID and a dictionary of some kind
|
|
||||||
// This isn't critical because the best we can do when we have that is to average them, like the
|
|
||||||
// 3DS does
|
|
||||||
|
|
||||||
const auto [px, py] = TouchToPixelPos(x, y);
|
|
||||||
TouchPressed(px, py);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnFingerMotion(float x, float y) {
|
|
||||||
const auto [px, py] = TouchToPixelPos(x, y);
|
|
||||||
TouchMoved(px, py);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnFingerUp() {
|
|
||||||
TouchReleased();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
|
||||||
if (state == SDL_PRESSED) {
|
|
||||||
InputCommon::GetKeyboard()->PressKey(key);
|
|
||||||
} else if (state == SDL_RELEASED) {
|
|
||||||
InputCommon::GetKeyboard()->ReleaseKey(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmuWindow_SDL2::IsOpen() const {
|
|
||||||
return is_open;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::RequestClose() {
|
|
||||||
is_open = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnResize() {
|
|
||||||
int width, height;
|
|
||||||
SDL_GL_GetDrawableSize(render_window, &width, &height);
|
|
||||||
UpdateCurrentFramebufferLayout(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::Fullscreen() {
|
|
||||||
if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError());
|
|
||||||
|
|
||||||
// Try a different fullscreening method
|
|
||||||
LOG_INFO(Frontend, "Attempting to use borderless fullscreen...");
|
|
||||||
if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError());
|
|
||||||
|
|
||||||
// Fallback algorithm: Maximise window.
|
|
||||||
// Works on all systems (unless something is seriously wrong), so no fallback for this one.
|
|
||||||
LOG_INFO(Frontend, "Falling back on a maximised window...");
|
|
||||||
SDL_MaximizeWindow(render_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
EmuWindow_SDL2::EmuWindow_SDL2(bool is_secondary) : EmuWindow(is_secondary) {}
|
|
||||||
|
|
||||||
EmuWindow_SDL2::~EmuWindow_SDL2() {
|
|
||||||
SDL_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuWindow_SDL2::InitializeSDL2() {
|
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) {
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0) {
|
||||||
LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}! Exiting...", SDL_GetError());
|
LOG_CRITICAL(Frontend, "Failed to initialize SDL2: {}! Exiting...", SDL_GetError());
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
InputCommon::Init();
|
input_subsystem->Initialize();
|
||||||
Network::Init();
|
Network::Init();
|
||||||
|
|
||||||
SDL_SetMainReady();
|
SDL_SetMainReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmuWindow_SDL2::~EmuWindow_SDL2() {
|
||||||
|
SDL_Quit();
|
||||||
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::PollEvents() {
|
void EmuWindow_SDL2::PollEvents() {
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
std::vector<SDL_Event> other_window_events;
|
std::vector<SDL_Event> other_window_events;
|
||||||
@ -170,10 +77,12 @@ void EmuWindow_SDL2::PollEvents() {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SDL_FINGERDOWN:
|
case SDL_FINGERDOWN:
|
||||||
OnFingerDown(event.tfinger.x, event.tfinger.y);
|
OnFingerDown(event.tfinger.x, event.tfinger.y,
|
||||||
|
static_cast<std::size_t>(event.tfinger.touchId));
|
||||||
break;
|
break;
|
||||||
case SDL_FINGERMOTION:
|
case SDL_FINGERMOTION:
|
||||||
OnFingerMotion(event.tfinger.x, event.tfinger.y);
|
OnFingerMotion(event.tfinger.x, event.tfinger.y,
|
||||||
|
static_cast<std::size_t>(event.tfinger.touchId));
|
||||||
break;
|
break;
|
||||||
case SDL_FINGERUP:
|
case SDL_FINGERUP:
|
||||||
OnFingerUp();
|
OnFingerUp();
|
||||||
@ -195,6 +104,106 @@ void EmuWindow_SDL2::PollEvents() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) {
|
||||||
|
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
||||||
|
input_subsystem->GetMouse()->Move(x, y, 0, 0);
|
||||||
|
input_subsystem->GetMouse()->MouseMove(touch_x, touch_y);
|
||||||
|
input_subsystem->GetMouse()->TouchMove(touch_x, touch_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
InputCommon::MouseButton EmuWindow_SDL2::SDLButtonToMouseButton(u32 button) const {
|
||||||
|
switch (button) {
|
||||||
|
case SDL_BUTTON_LEFT:
|
||||||
|
return InputCommon::MouseButton::Left;
|
||||||
|
case SDL_BUTTON_RIGHT:
|
||||||
|
return InputCommon::MouseButton::Right;
|
||||||
|
case SDL_BUTTON_MIDDLE:
|
||||||
|
return InputCommon::MouseButton::Wheel;
|
||||||
|
case SDL_BUTTON_X1:
|
||||||
|
return InputCommon::MouseButton::Backward;
|
||||||
|
case SDL_BUTTON_X2:
|
||||||
|
return InputCommon::MouseButton::Forward;
|
||||||
|
default:
|
||||||
|
return InputCommon::MouseButton::Undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<float, float> EmuWindow_SDL2::MouseToTouchPos(s32 touch_x, s32 touch_y) const {
|
||||||
|
int w, h;
|
||||||
|
SDL_GetWindowSize(render_window, &w, &h);
|
||||||
|
const float fx = static_cast<float>(touch_x) / w;
|
||||||
|
const float fy = static_cast<float>(touch_y) / h;
|
||||||
|
|
||||||
|
return {std::clamp<float>(fx, 0.0f, 1.0f), std::clamp<float>(fy, 0.0f, 1.0f)};
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) {
|
||||||
|
const auto mouse_button = SDLButtonToMouseButton(button);
|
||||||
|
if (state == SDL_PRESSED) {
|
||||||
|
const auto [touch_x, touch_y] = MouseToTouchPos(x, y);
|
||||||
|
input_subsystem->GetMouse()->PressButton(x, y, mouse_button);
|
||||||
|
input_subsystem->GetMouse()->PressMouseButton(mouse_button);
|
||||||
|
input_subsystem->GetMouse()->PressTouchButton(touch_x, touch_y, mouse_button);
|
||||||
|
} else {
|
||||||
|
input_subsystem->GetMouse()->ReleaseButton(mouse_button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnFingerDown(float x, float y, std::size_t id) {
|
||||||
|
input_subsystem->GetTouchScreen()->TouchPressed(x, y, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnFingerMotion(float x, float y, std::size_t id) {
|
||||||
|
input_subsystem->GetTouchScreen()->TouchMoved(x, y, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnFingerUp() {
|
||||||
|
input_subsystem->GetTouchScreen()->ReleaseAllTouch();
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) {
|
||||||
|
if (state == SDL_PRESSED) {
|
||||||
|
input_subsystem->GetKeyboard()->PressKey(static_cast<std::size_t>(key));
|
||||||
|
} else if (state == SDL_RELEASED) {
|
||||||
|
input_subsystem->GetKeyboard()->ReleaseKey(static_cast<std::size_t>(key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EmuWindow_SDL2::IsOpen() const {
|
||||||
|
return is_open;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::RequestClose() {
|
||||||
|
is_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::OnResize() {
|
||||||
|
int width, height;
|
||||||
|
SDL_GL_GetDrawableSize(render_window, &width, &height);
|
||||||
|
UpdateCurrentFramebufferLayout(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EmuWindow_SDL2::Fullscreen() {
|
||||||
|
if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERROR(Frontend, "Fullscreening failed: {}", SDL_GetError());
|
||||||
|
|
||||||
|
// Try a different fullscreening method
|
||||||
|
LOG_INFO(Frontend, "Attempting to use borderless fullscreen...");
|
||||||
|
if (SDL_SetWindowFullscreen(render_window, SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_ERROR(Frontend, "Borderless fullscreening failed: {}", SDL_GetError());
|
||||||
|
|
||||||
|
// Fallback algorithm: Maximise window.
|
||||||
|
// Works on all systems (unless something is seriously wrong), so no fallback for this one.
|
||||||
|
LOG_INFO(Frontend, "Falling back on a maximised window...");
|
||||||
|
SDL_MaximizeWindow(render_window);
|
||||||
|
}
|
||||||
|
|
||||||
void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
|
void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) {
|
||||||
SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
|
SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second);
|
||||||
}
|
}
|
||||||
|
@ -10,14 +10,16 @@
|
|||||||
|
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
|
|
||||||
|
namespace InputCommon {
|
||||||
|
class InputSubsystem;
|
||||||
|
enum class MouseButton;
|
||||||
|
} // namespace InputCommon
|
||||||
|
|
||||||
class EmuWindow_SDL2 : public Frontend::EmuWindow {
|
class EmuWindow_SDL2 : public Frontend::EmuWindow {
|
||||||
public:
|
public:
|
||||||
explicit EmuWindow_SDL2(bool is_secondary);
|
explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem, bool is_secondary);
|
||||||
~EmuWindow_SDL2();
|
~EmuWindow_SDL2();
|
||||||
|
|
||||||
/// Initializes SDL2
|
|
||||||
static void InitializeSDL2();
|
|
||||||
|
|
||||||
/// Presents the most recent frame from the video backend
|
/// Presents the most recent frame from the video backend
|
||||||
virtual void Present() {}
|
virtual void Present() {}
|
||||||
|
|
||||||
@ -37,17 +39,20 @@ protected:
|
|||||||
/// Called by PollEvents when the mouse moves.
|
/// Called by PollEvents when the mouse moves.
|
||||||
void OnMouseMotion(s32 x, s32 y);
|
void OnMouseMotion(s32 x, s32 y);
|
||||||
|
|
||||||
|
/// Converts a SDL mouse button into MouseInput mouse button
|
||||||
|
InputCommon::MouseButton SDLButtonToMouseButton(u32 button) const;
|
||||||
|
|
||||||
|
/// Translates pixel position to float position
|
||||||
|
std::pair<float, float> MouseToTouchPos(s32 touch_x, s32 touch_y) const;
|
||||||
|
|
||||||
/// Called by PollEvents when a mouse button is pressed or released
|
/// Called by PollEvents when a mouse button is pressed or released
|
||||||
void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
|
void OnMouseButton(u32 button, u8 state, s32 x, s32 y);
|
||||||
|
|
||||||
/// Translates pixel position (0..1) to pixel positions
|
|
||||||
std::pair<unsigned, unsigned> TouchToPixelPos(float touch_x, float touch_y) const;
|
|
||||||
|
|
||||||
/// Called by PollEvents when a finger starts touching the touchscreen
|
/// Called by PollEvents when a finger starts touching the touchscreen
|
||||||
void OnFingerDown(float x, float y);
|
void OnFingerDown(float x, float y, std::size_t id);
|
||||||
|
|
||||||
/// Called by PollEvents when a finger moves while touching the touchscreen
|
/// Called by PollEvents when a finger moves while touching the touchscreen
|
||||||
void OnFingerMotion(float x, float y);
|
void OnFingerMotion(float x, float y, std::size_t id);
|
||||||
|
|
||||||
/// Called by PollEvents when a finger stops touching the touchscreen
|
/// Called by PollEvents when a finger stops touching the touchscreen
|
||||||
void OnFingerUp();
|
void OnFingerUp();
|
||||||
@ -78,4 +83,7 @@ protected:
|
|||||||
|
|
||||||
/// Keeps track of how often to update the title bar during gameplay
|
/// Keeps track of how often to update the title bar during gameplay
|
||||||
u32 last_time = 0;
|
u32 last_time = 0;
|
||||||
|
|
||||||
|
/// Input subsystem to use with this window.
|
||||||
|
InputCommon::InputSubsystem* input_subsystem;
|
||||||
};
|
};
|
||||||
|
@ -42,8 +42,8 @@ private:
|
|||||||
SDL_GLContext context;
|
SDL_GLContext context;
|
||||||
};
|
};
|
||||||
|
|
||||||
EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(bool fullscreen, bool is_secondary)
|
EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen, bool is_secondary)
|
||||||
: EmuWindow_SDL2{is_secondary} {
|
: EmuWindow_SDL2{input_subsystem, is_secondary} {
|
||||||
// Initialize the window
|
// Initialize the window
|
||||||
if (Settings::values.use_gles) {
|
if (Settings::values.use_gles) {
|
||||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||||
|
@ -11,7 +11,7 @@ struct SDL_Window;
|
|||||||
|
|
||||||
class EmuWindow_SDL2_GL : public EmuWindow_SDL2 {
|
class EmuWindow_SDL2_GL : public EmuWindow_SDL2 {
|
||||||
public:
|
public:
|
||||||
explicit EmuWindow_SDL2_GL(bool fullscreen, bool is_secondary);
|
explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, bool fullscreen, bool is_secondary);
|
||||||
~EmuWindow_SDL2_GL();
|
~EmuWindow_SDL2_GL();
|
||||||
|
|
||||||
void Present() override;
|
void Present() override;
|
||||||
|
@ -19,8 +19,8 @@
|
|||||||
|
|
||||||
class DummyContext : public Frontend::GraphicsContext {};
|
class DummyContext : public Frontend::GraphicsContext {};
|
||||||
|
|
||||||
EmuWindow_SDL2_SW::EmuWindow_SDL2_SW(bool fullscreen, bool is_secondary)
|
EmuWindow_SDL2_SW::EmuWindow_SDL2_SW(InputCommon::InputSubsystem* input_subsystem, bool fullscreen, bool is_secondary)
|
||||||
: EmuWindow_SDL2{is_secondary} {
|
: EmuWindow_SDL2{input_subsystem, is_secondary} {
|
||||||
std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_fullname,
|
std::string window_title = fmt::format("Citra {} | {}-{}", Common::g_build_fullname,
|
||||||
Common::g_scm_branch, Common::g_scm_desc);
|
Common::g_scm_branch, Common::g_scm_desc);
|
||||||
render_window =
|
render_window =
|
||||||
|
@ -12,7 +12,7 @@ struct SDL_Surface;
|
|||||||
|
|
||||||
class EmuWindow_SDL2_SW : public EmuWindow_SDL2 {
|
class EmuWindow_SDL2_SW : public EmuWindow_SDL2 {
|
||||||
public:
|
public:
|
||||||
explicit EmuWindow_SDL2_SW(bool fullscreen, bool is_secondary);
|
explicit EmuWindow_SDL2_SW(InputCommon::InputSubsystem* input_subsystem, bool fullscreen, bool is_secondary);
|
||||||
~EmuWindow_SDL2_SW();
|
~EmuWindow_SDL2_SW();
|
||||||
|
|
||||||
void Present() override;
|
void Present() override;
|
||||||
|
@ -37,7 +37,7 @@ CalibrationConfigurationDialog::CalibrationConfigurationDialog(QWidget* parent,
|
|||||||
|
|
||||||
using namespace InputCommon::CemuhookUDP;
|
using namespace InputCommon::CemuhookUDP;
|
||||||
job = std::make_unique<CalibrationConfigurationJob>(
|
job = std::make_unique<CalibrationConfigurationJob>(
|
||||||
host, port,
|
host, port, pad_index,
|
||||||
[this](CalibrationConfigurationJob::Status status) {
|
[this](CalibrationConfigurationJob::Status status) {
|
||||||
QMetaObject::invokeMethod(this, [status, this] {
|
QMetaObject::invokeMethod(this, [status, this] {
|
||||||
QString text;
|
QString text;
|
||||||
@ -203,6 +203,7 @@ void ConfigureMotionTouch::OnCemuhookUDPTest() {
|
|||||||
udp_test_in_progress = true;
|
udp_test_in_progress = true;
|
||||||
InputCommon::CemuhookUDP::TestCommunication(
|
InputCommon::CemuhookUDP::TestCommunication(
|
||||||
ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()),
|
ui->udp_server->text().toStdString(), static_cast<u16>(ui->udp_port->text().toInt()),
|
||||||
|
static_cast<u8>(ui->udp_pad_index->currentIndex()),
|
||||||
[this] {
|
[this] {
|
||||||
LOG_INFO(Frontend, "UDP input test success");
|
LOG_INFO(Frontend, "UDP input test success");
|
||||||
QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
|
QMetaObject::invokeMethod(this, "ShowUDPTestResult", Q_ARG(bool, true));
|
||||||
|
@ -101,6 +101,7 @@ add_library(citra_common STATIC
|
|||||||
scope_exit.h
|
scope_exit.h
|
||||||
settings.cpp
|
settings.cpp
|
||||||
settings.h
|
settings.h
|
||||||
|
settings_input.h
|
||||||
slot_vector.h
|
slot_vector.h
|
||||||
serialization/atomic.h
|
serialization/atomic.h
|
||||||
serialization/boost_discrete_interval.hpp
|
serialization/boost_discrete_interval.hpp
|
||||||
|
@ -39,6 +39,28 @@ enum class PollingError {
|
|||||||
Unknown,
|
Unknown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Different results that can happen from a device request
|
||||||
|
enum class DriverResult {
|
||||||
|
Success,
|
||||||
|
WrongReply,
|
||||||
|
Timeout,
|
||||||
|
UnsupportedControllerType,
|
||||||
|
HandleInUse,
|
||||||
|
ErrorReadingData,
|
||||||
|
ErrorWritingData,
|
||||||
|
NoDeviceDetected,
|
||||||
|
InvalidHandle,
|
||||||
|
NotSupported,
|
||||||
|
Disabled,
|
||||||
|
Unknown,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hint for amplification curve to be used
|
||||||
|
enum class VibrationAmplificationType {
|
||||||
|
Linear,
|
||||||
|
Exponential,
|
||||||
|
};
|
||||||
|
|
||||||
// Analog properties for calibration
|
// Analog properties for calibration
|
||||||
struct AnalogProperties {
|
struct AnalogProperties {
|
||||||
// Anything below this value will be detected as zero
|
// Anything below this value will be detected as zero
|
||||||
@ -119,6 +141,15 @@ struct TouchStatus {
|
|||||||
int id{};
|
int id{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// HD rumble data
|
||||||
|
struct VibrationStatus {
|
||||||
|
f32 low_amplitude{};
|
||||||
|
f32 low_frequency{};
|
||||||
|
f32 high_amplitude{};
|
||||||
|
f32 high_frequency{};
|
||||||
|
VibrationAmplificationType type;
|
||||||
|
};
|
||||||
|
|
||||||
// List of buttons to be passed to Qt that can be translated
|
// List of buttons to be passed to Qt that can be translated
|
||||||
enum class ButtonNames {
|
enum class ButtonNames {
|
||||||
Undefined,
|
Undefined,
|
||||||
|
@ -101,24 +101,6 @@ void Apply() {
|
|||||||
Core::DSP().SetSink(values.output_type.GetValue(), values.output_device.GetValue());
|
Core::DSP().SetSink(values.output_type.GetValue(), values.output_device.GetValue());
|
||||||
Core::DSP().EnableStretching(values.enable_audio_stretching.GetValue());
|
Core::DSP().EnableStretching(values.enable_audio_stretching.GetValue());
|
||||||
|
|
||||||
auto hid = Service::HID::GetModule(system);
|
|
||||||
if (hid) {
|
|
||||||
hid->ReloadInputDevices();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto apt = Service::APT::GetModule(system);
|
|
||||||
if (apt) {
|
|
||||||
apt->GetAppletManager()->ReloadInputDevices();
|
|
||||||
}
|
|
||||||
|
|
||||||
auto sm = system.ServiceManager();
|
|
||||||
auto ir_user = sm.GetService<Service::IR::IR_USER>("ir:USER");
|
|
||||||
if (ir_user)
|
|
||||||
ir_user->ReloadInputDevices();
|
|
||||||
auto ir_rst = sm.GetService<Service::IR::IR_RST>("ir:rst");
|
|
||||||
if (ir_rst)
|
|
||||||
ir_rst->ReloadInputDevices();
|
|
||||||
|
|
||||||
auto cam = Service::CAM::GetModule(system);
|
auto cam = Service::CAM::GetModule(system);
|
||||||
if (cam) {
|
if (cam) {
|
||||||
cam->ReloadCameraDevices();
|
cam->ReloadCameraDevices();
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "audio_core/input_details.h"
|
#include "audio_core/input_details.h"
|
||||||
#include "audio_core/sink_details.h"
|
#include "audio_core/sink_details.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
#include "common/settings_input.h"
|
||||||
#include "core/hle/service/cam/cam_params.h"
|
#include "core/hle/service/cam/cam_params.h"
|
||||||
|
|
||||||
namespace Settings {
|
namespace Settings {
|
||||||
@ -53,8 +54,8 @@ enum class StereoRenderOption : u32 {
|
|||||||
CardboardVR = 5
|
CardboardVR = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
// Which eye to render when 3d is off. 800px wide mode could be added here in the future, when
|
// Which eye to render when 3d is off. 800px wide mode
|
||||||
// implemented
|
// could be added here in the future, when implemented.
|
||||||
enum class MonoRenderOption : u32 {
|
enum class MonoRenderOption : u32 {
|
||||||
LeftEye = 0,
|
LeftEye = 0,
|
||||||
RightEye = 1,
|
RightEye = 1,
|
||||||
@ -75,109 +76,6 @@ enum class TextureFilter : u32 {
|
|||||||
xBRZ = 5,
|
xBRZ = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace NativeButton {
|
|
||||||
|
|
||||||
enum Values {
|
|
||||||
A,
|
|
||||||
B,
|
|
||||||
X,
|
|
||||||
Y,
|
|
||||||
DUp,
|
|
||||||
DDown,
|
|
||||||
DLeft,
|
|
||||||
DRight,
|
|
||||||
L,
|
|
||||||
R,
|
|
||||||
Start,
|
|
||||||
Select,
|
|
||||||
Debug,
|
|
||||||
Gpio14,
|
|
||||||
|
|
||||||
ZL,
|
|
||||||
ZR,
|
|
||||||
|
|
||||||
Home,
|
|
||||||
|
|
||||||
NumButtons,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr int BUTTON_HID_BEGIN = A;
|
|
||||||
constexpr int BUTTON_IR_BEGIN = ZL;
|
|
||||||
constexpr int BUTTON_NS_BEGIN = Home;
|
|
||||||
|
|
||||||
constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN;
|
|
||||||
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
|
|
||||||
constexpr int BUTTON_NS_END = NumButtons;
|
|
||||||
|
|
||||||
constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
|
||||||
constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
|
|
||||||
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
|
||||||
|
|
||||||
constexpr std::array<const char*, NumButtons> mapping = {{
|
|
||||||
"button_a",
|
|
||||||
"button_b",
|
|
||||||
"button_x",
|
|
||||||
"button_y",
|
|
||||||
"button_up",
|
|
||||||
"button_down",
|
|
||||||
"button_left",
|
|
||||||
"button_right",
|
|
||||||
"button_l",
|
|
||||||
"button_r",
|
|
||||||
"button_start",
|
|
||||||
"button_select",
|
|
||||||
"button_debug",
|
|
||||||
"button_gpio14",
|
|
||||||
"button_zl",
|
|
||||||
"button_zr",
|
|
||||||
"button_home",
|
|
||||||
}};
|
|
||||||
} // namespace NativeButton
|
|
||||||
|
|
||||||
namespace NativeAnalog {
|
|
||||||
enum Values {
|
|
||||||
CirclePad,
|
|
||||||
CStick,
|
|
||||||
|
|
||||||
NumAnalogs,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr std::array<const char*, NumAnalogs> mapping = {{
|
|
||||||
"circle_pad",
|
|
||||||
"c_stick",
|
|
||||||
}};
|
|
||||||
} // namespace NativeAnalog
|
|
||||||
|
|
||||||
namespace NativeMotion {
|
|
||||||
enum Values : int {
|
|
||||||
MotionLeft,
|
|
||||||
MotionRight,
|
|
||||||
|
|
||||||
NumMotions,
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr int MOTION_HID_BEGIN = MotionLeft;
|
|
||||||
constexpr int MOTION_HID_END = NumMotions;
|
|
||||||
constexpr int NUM_MOTIONS_HID = NumMotions;
|
|
||||||
|
|
||||||
constexpr std::array<const char*, NumMotions> mapping = {{
|
|
||||||
"motionleft",
|
|
||||||
"motionright",
|
|
||||||
}};
|
|
||||||
} // namespace NativeMotion
|
|
||||||
|
|
||||||
using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
|
|
||||||
using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
|
|
||||||
using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
|
|
||||||
|
|
||||||
struct PlayerInput {
|
|
||||||
ButtonsRaw buttons;
|
|
||||||
AnalogsRaw analogs;
|
|
||||||
MotionsRaw motions;
|
|
||||||
|
|
||||||
std::string profile_name;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** The Setting class is a simple resource manager. It defines a label and default value alongside
|
/** The Setting class is a simple resource manager. It defines a label and default value alongside
|
||||||
* the actual value of the setting for simpler and less-error prone use with frontend
|
* the actual value of the setting for simpler and less-error prone use with frontend
|
||||||
* configurations. Specifying a default value and label is required. A minimum and maximum range can
|
* configurations. Specifying a default value and label is required. A minimum and maximum range can
|
||||||
@ -440,11 +338,6 @@ private:
|
|||||||
Type custom{}; ///< The custom setting value
|
Type custom{}; ///< The custom setting value
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TouchFromButtonMap {
|
|
||||||
std::string name;
|
|
||||||
std::vector<std::string> buttons;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A special region value indicating that citra will automatically select a region
|
/// A special region value indicating that citra will automatically select a region
|
||||||
/// value to fit the region lockout info of the game
|
/// value to fit the region lockout info of the game
|
||||||
static constexpr s32 REGION_VALUE_AUTO_SELECT = -1;
|
static constexpr s32 REGION_VALUE_AUTO_SELECT = -1;
|
||||||
@ -461,6 +354,9 @@ struct Values {
|
|||||||
Setting<u16> udp_input_port{26760, "udp_input_port"};
|
Setting<u16> udp_input_port{26760, "udp_input_port"};
|
||||||
Setting<u8> udp_pad_index{0, "udp_pad_index"};
|
Setting<u8> udp_pad_index{0, "udp_pad_index"};
|
||||||
|
|
||||||
|
Setting<bool> emulate_analog_keyboard{false, "emulate_analog_keyboard"};
|
||||||
|
Setting<bool> keyboard_enabled{false, "keyboard_enabled"};
|
||||||
|
|
||||||
// Core
|
// Core
|
||||||
Setting<bool> use_cpu_jit{true, "use_cpu_jit"};
|
Setting<bool> use_cpu_jit{true, "use_cpu_jit"};
|
||||||
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, "cpu_clock_percentage"};
|
SwitchableSetting<s32, true> cpu_clock_percentage{100, 5, 400, "cpu_clock_percentage"};
|
||||||
|
119
src/common/settings_input.h
Normal file
119
src/common/settings_input.h
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
namespace NativeButton {
|
||||||
|
enum Values : int {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
DUp,
|
||||||
|
DDown,
|
||||||
|
DLeft,
|
||||||
|
DRight,
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
Start,
|
||||||
|
Select,
|
||||||
|
Debug,
|
||||||
|
Gpio14,
|
||||||
|
|
||||||
|
ZL,
|
||||||
|
ZR,
|
||||||
|
|
||||||
|
Home,
|
||||||
|
|
||||||
|
NumButtons,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int BUTTON_HID_BEGIN = A;
|
||||||
|
constexpr int BUTTON_IR_BEGIN = ZL;
|
||||||
|
constexpr int BUTTON_NS_BEGIN = Home;
|
||||||
|
|
||||||
|
constexpr int BUTTON_HID_END = BUTTON_IR_BEGIN;
|
||||||
|
constexpr int BUTTON_IR_END = BUTTON_NS_BEGIN;
|
||||||
|
constexpr int BUTTON_NS_END = NumButtons;
|
||||||
|
|
||||||
|
constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
||||||
|
constexpr int NUM_BUTTONS_IR = BUTTON_IR_END - BUTTON_IR_BEGIN;
|
||||||
|
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
||||||
|
|
||||||
|
constexpr std::array<const char*, NumButtons> mapping = {{
|
||||||
|
"button_a",
|
||||||
|
"button_b",
|
||||||
|
"button_x",
|
||||||
|
"button_y",
|
||||||
|
"button_up",
|
||||||
|
"button_down",
|
||||||
|
"button_left",
|
||||||
|
"button_right",
|
||||||
|
"button_l",
|
||||||
|
"button_r",
|
||||||
|
"button_start",
|
||||||
|
"button_select",
|
||||||
|
"button_debug",
|
||||||
|
"button_gpio14",
|
||||||
|
"button_zl",
|
||||||
|
"button_zr",
|
||||||
|
"button_home",
|
||||||
|
}};
|
||||||
|
} // namespace NativeButton
|
||||||
|
|
||||||
|
namespace NativeAnalog {
|
||||||
|
enum Values : int {
|
||||||
|
CirclePad,
|
||||||
|
CStick,
|
||||||
|
|
||||||
|
NumAnalogs,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr std::array<const char*, NumAnalogs> mapping = {{
|
||||||
|
"circle_pad",
|
||||||
|
"c_stick",
|
||||||
|
}};
|
||||||
|
} // namespace NativeAnalog
|
||||||
|
|
||||||
|
namespace NativeMotion {
|
||||||
|
enum Values : int {
|
||||||
|
MotionLeft,
|
||||||
|
MotionRight,
|
||||||
|
|
||||||
|
NumMotions,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int MOTION_HID_BEGIN = MotionLeft;
|
||||||
|
constexpr int MOTION_HID_END = NumMotions;
|
||||||
|
constexpr int NUM_MOTIONS_HID = NumMotions;
|
||||||
|
|
||||||
|
constexpr std::array<const char*, NumMotions> mapping = {{
|
||||||
|
"motionleft",
|
||||||
|
"motionright",
|
||||||
|
}};
|
||||||
|
} // namespace NativeMotion
|
||||||
|
|
||||||
|
using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
|
||||||
|
using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
|
||||||
|
using MotionsRaw = std::array<std::string, NativeMotion::NumMotions>;
|
||||||
|
|
||||||
|
struct PlayerInput {
|
||||||
|
ButtonsRaw buttons;
|
||||||
|
AnalogsRaw analogs;
|
||||||
|
MotionsRaw motions;
|
||||||
|
|
||||||
|
std::string profile_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TouchFromButtonMap {
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> buttons;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Settings
|
@ -113,10 +113,6 @@ add_library(citra_core STATIC
|
|||||||
gdbstub/gdbstub.h
|
gdbstub/gdbstub.h
|
||||||
gdbstub/hio.cpp
|
gdbstub/hio.cpp
|
||||||
gdbstub/hio.h
|
gdbstub/hio.h
|
||||||
frontend/mic.cpp
|
|
||||||
frontend/mic.h
|
|
||||||
frontend/scope_acquire_context.cpp
|
|
||||||
frontend/scope_acquire_context.h
|
|
||||||
gdbstub/gdbstub.cpp
|
gdbstub/gdbstub.cpp
|
||||||
gdbstub/gdbstub.h
|
gdbstub/gdbstub.h
|
||||||
hid/emulated_console.cpp
|
hid/emulated_console.cpp
|
||||||
|
@ -19,38 +19,6 @@ EmuWindow::EmuWindow(bool is_secondary_) : is_secondary{is_secondary_} {}
|
|||||||
|
|
||||||
EmuWindow::~EmuWindow() = default;
|
EmuWindow::~EmuWindow() = default;
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the given x/y coordinates are within the touchpad specified by the framebuffer layout
|
|
||||||
* @param layout FramebufferLayout object describing the framebuffer size and screen positions
|
|
||||||
* @param framebuffer_x Framebuffer x-coordinate to check
|
|
||||||
* @param framebuffer_y Framebuffer y-coordinate to check
|
|
||||||
* @return True if the coordinates are within the touchpad, otherwise false
|
|
||||||
*/
|
|
||||||
static bool IsWithinTouchscreen(const Layout::FramebufferLayout& layout, unsigned framebuffer_x,
|
|
||||||
unsigned framebuffer_y) {
|
|
||||||
if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::SideBySide) {
|
|
||||||
return (framebuffer_y >= layout.bottom_screen.top &&
|
|
||||||
framebuffer_y < layout.bottom_screen.bottom &&
|
|
||||||
((framebuffer_x >= layout.bottom_screen.left / 2 &&
|
|
||||||
framebuffer_x < layout.bottom_screen.right / 2) ||
|
|
||||||
(framebuffer_x >= (layout.bottom_screen.left / 2) + (layout.width / 2) &&
|
|
||||||
framebuffer_x < (layout.bottom_screen.right / 2) + (layout.width / 2))));
|
|
||||||
} else if (Settings::values.render_3d.GetValue() == Settings::StereoRenderOption::CardboardVR) {
|
|
||||||
return (framebuffer_y >= layout.bottom_screen.top &&
|
|
||||||
framebuffer_y < layout.bottom_screen.bottom &&
|
|
||||||
((framebuffer_x >= layout.bottom_screen.left &&
|
|
||||||
framebuffer_x < layout.bottom_screen.right) ||
|
|
||||||
(framebuffer_x >= layout.cardboard.bottom_screen_right_eye + (layout.width / 2) &&
|
|
||||||
framebuffer_x < layout.cardboard.bottom_screen_right_eye +
|
|
||||||
layout.bottom_screen.GetWidth() + (layout.width / 2))));
|
|
||||||
} else {
|
|
||||||
return (framebuffer_y >= layout.bottom_screen.top &&
|
|
||||||
framebuffer_y < layout.bottom_screen.bottom &&
|
|
||||||
framebuffer_x >= layout.bottom_screen.left &&
|
|
||||||
framebuffer_x < layout.bottom_screen.right);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<f32, f32> EmuWindow::MapToTouchScreen(u32 framebuffer_x, u32 framebuffer_y) const {
|
std::pair<f32, f32> EmuWindow::MapToTouchScreen(u32 framebuffer_x, u32 framebuffer_y) const {
|
||||||
std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y);
|
std::tie(framebuffer_x, framebuffer_y) = ClipToTouchScreen(framebuffer_x, framebuffer_y);
|
||||||
const float x = static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) /
|
const float x = static_cast<float>(framebuffer_x - framebuffer_layout.bottom_screen.left) /
|
||||||
|
@ -134,7 +134,7 @@ void EmulatedController::ReloadInput() {
|
|||||||
}
|
}
|
||||||
motion_devices[index]->SetCallback({
|
motion_devices[index]->SetCallback({
|
||||||
.on_change =
|
.on_change =
|
||||||
[this, index](const Common::Input::CallbackStatus& callback) {
|
[/*this, index*/](const Common::Input::CallbackStatus& callback) {
|
||||||
// SetMotion(callback, index);
|
// SetMotion(callback, index);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/frontend/input.h"
|
#include "core/hid/emulated_controller.h"
|
||||||
|
#include "core/hid/hid_core.h"
|
||||||
#include "core/hle/applets/applet.h"
|
#include "core/hle/applets/applet.h"
|
||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/apt/applet_manager.h"
|
#include "core/hle/service/apt/applet_manager.h"
|
||||||
@ -1230,33 +1231,25 @@ void AppletManager::CaptureFrameBuffers() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletManager::LoadInputDevices() {
|
|
||||||
home_button = Input::CreateDevice<Input::ButtonDevice>(
|
|
||||||
Settings::values.current_input_profile.buttons[Settings::NativeButton::Home]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppletManager::HomeButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late) {
|
void AppletManager::HomeButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late) {
|
||||||
if (is_device_reload_pending.exchange(false)) {
|
//const auto& controller = hid_core.GetEmulatedController();
|
||||||
LoadInputDevices();
|
//const bool state = home_button->GetStatus();
|
||||||
}
|
|
||||||
|
|
||||||
const bool state = home_button->GetStatus();
|
|
||||||
// NOTE: We technically do support loading and jumping to home menu even if it isn't
|
// NOTE: We technically do support loading and jumping to home menu even if it isn't
|
||||||
// initially registered. However since the home menu suspend is not bug-free, we don't
|
// initially registered. However since the home menu suspend is not bug-free, we don't
|
||||||
// want normal users who didn't launch the home menu accidentally pressing the home
|
// want normal users who didn't launch the home menu accidentally pressing the home
|
||||||
// button binding and freezing their game, so for now, gate it to only environments
|
// button binding and freezing their game, so for now, gate it to only environments
|
||||||
// where the home menu was already loaded by the user (last condition).
|
// where the home menu was already loaded by the user (last condition).
|
||||||
if (state && !last_home_button_state && GetAppletSlot(AppletSlot::HomeMenu)->registered) {
|
if (/*state &&*/ !last_home_button_state && GetAppletSlot(AppletSlot::HomeMenu)->registered) {
|
||||||
SendNotification(Notification::HomeButtonSingle);
|
SendNotification(Notification::HomeButtonSingle);
|
||||||
}
|
}
|
||||||
last_home_button_state = state;
|
//last_home_button_state = state;
|
||||||
|
|
||||||
// Reschedule recurrent event
|
// Reschedule recurrent event
|
||||||
Core::System::GetInstance().CoreTiming().ScheduleEvent(
|
system.CoreTiming().ScheduleEvent(
|
||||||
usToCycles(home_button_update_interval_us) - cycles_late, home_button_update_event);
|
usToCycles(home_button_update_interval_us) - cycles_late, home_button_update_event);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppletManager::AppletManager(Core::System& system) : system(system) {
|
AppletManager::AppletManager(Core::System& system) : system(system), hid_core(system.HIDCore()) {
|
||||||
lock = system.Kernel().CreateMutex(false, "APT_U:Lock");
|
lock = system.Kernel().CreateMutex(false, "APT_U:Lock");
|
||||||
for (std::size_t slot = 0; slot < applet_slots.size(); ++slot) {
|
for (std::size_t slot = 0; slot < applet_slots.size(); ++slot) {
|
||||||
auto& slot_data = applet_slots[slot];
|
auto& slot_data = applet_slots[slot];
|
||||||
@ -1283,8 +1276,4 @@ AppletManager::~AppletManager() {
|
|||||||
HLE::Applets::Shutdown();
|
HLE::Applets::Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletManager::ReloadInputDevices() {
|
|
||||||
is_device_reload_pending.store(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Service::APT
|
} // namespace Service::APT
|
||||||
|
@ -23,6 +23,10 @@ namespace Core {
|
|||||||
class System;
|
class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace Core::HID {
|
||||||
|
class HIDCore;
|
||||||
|
};
|
||||||
|
|
||||||
namespace Service::APT {
|
namespace Service::APT {
|
||||||
|
|
||||||
/// Signals used by APT functions
|
/// Signals used by APT functions
|
||||||
@ -228,8 +232,6 @@ public:
|
|||||||
explicit AppletManager(Core::System& system);
|
explicit AppletManager(Core::System& system);
|
||||||
~AppletManager();
|
~AppletManager();
|
||||||
|
|
||||||
void ReloadInputDevices();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears any existing parameter and places a new one. This function is currently only used by
|
* Clears any existing parameter and places a new one. This function is currently only used by
|
||||||
* HLE Applets and should be likely removed in the future
|
* HLE Applets and should be likely removed in the future
|
||||||
@ -428,11 +430,10 @@ private:
|
|||||||
AppletSlot application_close_target = AppletSlot::Error;
|
AppletSlot application_close_target = AppletSlot::Error;
|
||||||
|
|
||||||
Core::TimingEventType* home_button_update_event;
|
Core::TimingEventType* home_button_update_event;
|
||||||
std::atomic<bool> is_device_reload_pending{true};
|
|
||||||
std::unique_ptr<Input::ButtonDevice> home_button;
|
|
||||||
bool last_home_button_state = false;
|
bool last_home_button_state = false;
|
||||||
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
|
Core::HID::HIDCore& hid_core;
|
||||||
|
|
||||||
AppletSlotData* GetAppletSlot(AppletSlot slot) {
|
AppletSlotData* GetAppletSlot(AppletSlot slot) {
|
||||||
return &applet_slots[static_cast<std::size_t>(slot)];
|
return &applet_slots[static_cast<std::size_t>(slot)];
|
||||||
@ -454,7 +455,6 @@ private:
|
|||||||
|
|
||||||
void CaptureFrameBuffers();
|
void CaptureFrameBuffers();
|
||||||
|
|
||||||
void LoadInputDevices();
|
|
||||||
void HomeButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late);
|
void HomeButtonUpdateEvent(std::uintptr_t user_data, s64 cycles_late);
|
||||||
|
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
@ -479,10 +479,6 @@ private:
|
|||||||
}
|
}
|
||||||
ar& applet_slots;
|
ar& applet_slots;
|
||||||
ar& library_applet_closing_command;
|
ar& library_applet_closing_command;
|
||||||
|
|
||||||
if (Archive::is_loading::value) {
|
|
||||||
LoadInputDevices();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
friend class boost::serialization::access;
|
friend class boost::serialization::access;
|
||||||
};
|
};
|
||||||
|
@ -54,7 +54,8 @@ if (ENABLE_LIBUSB)
|
|||||||
drivers/gc_adapter.cpp
|
drivers/gc_adapter.cpp
|
||||||
drivers/gc_adapter.h
|
drivers/gc_adapter.h
|
||||||
)
|
)
|
||||||
target_link_libraries(input_common PRIVATE libusb::usb)
|
target_include_directories(input_common PRIVATE ${LIBUSB_INCLUDE_DIR})
|
||||||
|
target_link_libraries(input_common PRIVATE ${LIBUSB_LIBRARIES})
|
||||||
target_compile_definitions(input_common PRIVATE HAVE_LIBUSB)
|
target_compile_definitions(input_common PRIVATE HAVE_LIBUSB)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ namespace InputCommon {
|
|||||||
class LibUSBContext {
|
class LibUSBContext {
|
||||||
public:
|
public:
|
||||||
explicit LibUSBContext() {
|
explicit LibUSBContext() {
|
||||||
init_result = libusb_init(&ctx);
|
init_result = libusb_init_context(&ctx, nullptr, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
~LibUSBContext() {
|
~LibUSBContext() {
|
||||||
@ -324,7 +324,7 @@ bool GCAdapter::GetGCEndpoint(libusb_device* device) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Input::VibrationError GCAdapter::SetVibration(
|
Common::Input::DriverResult GCAdapter::SetVibration(
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) {
|
||||||
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
|
const auto mean_amplitude = (vibration.low_amplitude + vibration.high_amplitude) * 0.5f;
|
||||||
const auto processed_amplitude =
|
const auto processed_amplitude =
|
||||||
@ -333,9 +333,9 @@ Common::Input::VibrationError GCAdapter::SetVibration(
|
|||||||
pads[identifier.port].rumble_amplitude = processed_amplitude;
|
pads[identifier.port].rumble_amplitude = processed_amplitude;
|
||||||
|
|
||||||
if (!rumble_enabled) {
|
if (!rumble_enabled) {
|
||||||
return Common::Input::VibrationError::Disabled;
|
return Common::Input::DriverResult::Disabled;
|
||||||
}
|
}
|
||||||
return Common::Input::VibrationError::None;
|
return Common::Input::DriverResult::Success;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
|
bool GCAdapter::IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
|
||||||
@ -421,14 +421,14 @@ ButtonMapping GCAdapter::GetButtonMappingForDevice(const Common::ParamPackage& p
|
|||||||
{Settings::NativeButton::B, PadButton::ButtonB},
|
{Settings::NativeButton::B, PadButton::ButtonB},
|
||||||
{Settings::NativeButton::X, PadButton::ButtonX},
|
{Settings::NativeButton::X, PadButton::ButtonX},
|
||||||
{Settings::NativeButton::Y, PadButton::ButtonY},
|
{Settings::NativeButton::Y, PadButton::ButtonY},
|
||||||
{Settings::NativeButton::Plus, PadButton::ButtonStart},
|
{Settings::NativeButton::Start, PadButton::ButtonStart},
|
||||||
|
{Settings::NativeButton::Select, PadButton::ButtonSelect},
|
||||||
{Settings::NativeButton::DLeft, PadButton::ButtonLeft},
|
{Settings::NativeButton::DLeft, PadButton::ButtonLeft},
|
||||||
{Settings::NativeButton::DUp, PadButton::ButtonUp},
|
{Settings::NativeButton::DUp, PadButton::ButtonUp},
|
||||||
{Settings::NativeButton::DRight, PadButton::ButtonRight},
|
{Settings::NativeButton::DRight, PadButton::ButtonRight},
|
||||||
{Settings::NativeButton::DDown, PadButton::ButtonDown},
|
{Settings::NativeButton::DDown, PadButton::ButtonDown},
|
||||||
{Settings::NativeButton::SL, PadButton::TriggerL},
|
{Settings::NativeButton::L, PadButton::TriggerL},
|
||||||
{Settings::NativeButton::SR, PadButton::TriggerR},
|
{Settings::NativeButton::R, PadButton::TriggerR},
|
||||||
{Settings::NativeButton::R, PadButton::TriggerZ},
|
|
||||||
};
|
};
|
||||||
if (!params.Has("port")) {
|
if (!params.Has("port")) {
|
||||||
return {};
|
return {};
|
||||||
@ -474,13 +474,13 @@ AnalogMapping GCAdapter::GetAnalogMappingForDevice(const Common::ParamPackage& p
|
|||||||
left_analog_params.Set("port", params.Get("port", 0));
|
left_analog_params.Set("port", params.Get("port", 0));
|
||||||
left_analog_params.Set("axis_x", static_cast<int>(PadAxes::StickX));
|
left_analog_params.Set("axis_x", static_cast<int>(PadAxes::StickX));
|
||||||
left_analog_params.Set("axis_y", static_cast<int>(PadAxes::StickY));
|
left_analog_params.Set("axis_y", static_cast<int>(PadAxes::StickY));
|
||||||
mapping.insert_or_assign(Settings::NativeAnalog::LStick, std::move(left_analog_params));
|
mapping.insert_or_assign(Settings::NativeAnalog::CirclePad, std::move(left_analog_params));
|
||||||
Common::ParamPackage right_analog_params;
|
Common::ParamPackage right_analog_params;
|
||||||
right_analog_params.Set("engine", GetEngineName());
|
right_analog_params.Set("engine", GetEngineName());
|
||||||
right_analog_params.Set("port", params.Get("port", 0));
|
right_analog_params.Set("port", params.Get("port", 0));
|
||||||
right_analog_params.Set("axis_x", static_cast<int>(PadAxes::SubstickX));
|
right_analog_params.Set("axis_x", static_cast<int>(PadAxes::SubstickX));
|
||||||
right_analog_params.Set("axis_y", static_cast<int>(PadAxes::SubstickY));
|
right_analog_params.Set("axis_y", static_cast<int>(PadAxes::SubstickY));
|
||||||
mapping.insert_or_assign(Settings::NativeAnalog::RStick, std::move(right_analog_params));
|
mapping.insert_or_assign(Settings::NativeAnalog::CStick, std::move(right_analog_params));
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
explicit GCAdapter(std::string input_engine_);
|
explicit GCAdapter(std::string input_engine_);
|
||||||
~GCAdapter() override;
|
~GCAdapter() override;
|
||||||
|
|
||||||
Common::Input::VibrationError SetVibration(
|
Common::Input::DriverResult SetVibration(
|
||||||
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
const PadIdentifier& identifier, const Common::Input::VibrationStatus& vibration) override;
|
||||||
|
|
||||||
bool IsVibrationEnabled(const PadIdentifier& identifier) override;
|
bool IsVibrationEnabled(const PadIdentifier& identifier) override;
|
||||||
@ -53,6 +53,7 @@ private:
|
|||||||
ButtonX = 0x0400,
|
ButtonX = 0x0400,
|
||||||
ButtonY = 0x0800,
|
ButtonY = 0x0800,
|
||||||
ButtonStart = 0x1000,
|
ButtonStart = 0x1000,
|
||||||
|
ButtonSelect = 0x2000,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class PadAxes : u8 {
|
enum class PadAxes : u8 {
|
||||||
|
@ -54,6 +54,21 @@ void Mouse::UpdateThread(std::stop_token stop_token) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Mouse::Move(int x, int y, int, int) {
|
||||||
|
if (button_pressed) {
|
||||||
|
const auto mouse_move = Common::MakeVec<int>(x, y) - mouse_origin;
|
||||||
|
const float sensitivity = /*Settings::values.mouse_panning_sensitivity.GetValue()*/50 * 0.0012f;
|
||||||
|
SetAxis(identifier, mouse_axis_x, static_cast<float>(mouse_move.x) * sensitivity);
|
||||||
|
SetAxis(identifier, mouse_axis_y, static_cast<float>(-mouse_move.y) * sensitivity);
|
||||||
|
|
||||||
|
last_motion_change = {
|
||||||
|
static_cast<float>(-mouse_move.y) / 50.0f,
|
||||||
|
static_cast<float>(-mouse_move.x) / 50.0f,
|
||||||
|
last_motion_change.z,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
|
void Mouse::MouseMove(f32 touch_x, f32 touch_y) {
|
||||||
SetAxis(real_mouse_identifier, mouse_axis_x, touch_x);
|
SetAxis(real_mouse_identifier, mouse_axis_x, touch_x);
|
||||||
SetAxis(real_mouse_identifier, mouse_axis_y, touch_y);
|
SetAxis(real_mouse_identifier, mouse_axis_y, touch_y);
|
||||||
|
@ -101,6 +101,7 @@ private:
|
|||||||
Common::Vec2<int> mouse_origin;
|
Common::Vec2<int> mouse_origin;
|
||||||
Common::Vec2<int> last_mouse_position;
|
Common::Vec2<int> last_mouse_position;
|
||||||
Common::Vec2<float> last_mouse_change;
|
Common::Vec2<float> last_mouse_change;
|
||||||
|
Common::Vec3<float> last_motion_change;
|
||||||
Common::Vec2<int> wheel_position;
|
Common::Vec2<int> wheel_position;
|
||||||
bool button_pressed;
|
bool button_pressed;
|
||||||
std::jthread update_thread;
|
std::jthread update_thread;
|
||||||
|
@ -25,9 +25,10 @@ class Socket {
|
|||||||
public:
|
public:
|
||||||
using clock = std::chrono::system_clock;
|
using clock = std::chrono::system_clock;
|
||||||
|
|
||||||
explicit Socket(const std::string& host, u16 port, SocketCallback callback_)
|
explicit Socket(const std::string& host, u16 port, u8 pad_index, SocketCallback callback_)
|
||||||
: callback(std::move(callback_)), timer(io_service),
|
: callback(std::move(callback_)), timer(io_service),
|
||||||
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()) {
|
socket(io_service, udp::endpoint(udp::v4(), 0)), client_id(GenerateRandomClientId()),
|
||||||
|
pad_index(pad_index) {
|
||||||
boost::system::error_code ec{};
|
boost::system::error_code ec{};
|
||||||
auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
|
auto ipv4 = boost::asio::ip::make_address_v4(host, ec);
|
||||||
if (ec.value() != boost::system::errc::success) {
|
if (ec.value() != boost::system::errc::success) {
|
||||||
@ -95,17 +96,13 @@ private:
|
|||||||
void HandleSend(const boost::system::error_code&) {
|
void HandleSend(const boost::system::error_code&) {
|
||||||
boost::system::error_code _ignored{};
|
boost::system::error_code _ignored{};
|
||||||
// Send a request for getting port info for the pad
|
// Send a request for getting port info for the pad
|
||||||
const Request::PortInfo port_info{4, {0, 1, 2, 3}};
|
const Request::PortInfo port_info{1, {pad_index, 0, 0, 0}};
|
||||||
const auto port_message = Request::Create(port_info, client_id);
|
const auto port_message = Request::Create(port_info, client_id);
|
||||||
std::memcpy(&send_buffer1, &port_message, PORT_INFO_SIZE);
|
std::memcpy(&send_buffer1, &port_message, PORT_INFO_SIZE);
|
||||||
socket.send_to(boost::asio::buffer(send_buffer1), send_endpoint, {}, _ignored);
|
socket.send_to(boost::asio::buffer(send_buffer1), send_endpoint, {}, _ignored);
|
||||||
|
|
||||||
// Send a request for getting pad data for the pad
|
// Send a request for getting pad data for the pad
|
||||||
const Request::PadData pad_data{
|
const Request::PadData pad_data{Request::RegisterFlags::PadID, pad_index, EMPTY_MAC_ADDRESS};
|
||||||
Request::RegisterFlags::AllPads,
|
|
||||||
0,
|
|
||||||
EMPTY_MAC_ADDRESS,
|
|
||||||
};
|
|
||||||
const auto pad_message = Request::Create(pad_data, client_id);
|
const auto pad_message = Request::Create(pad_data, client_id);
|
||||||
std::memcpy(send_buffer2.data(), &pad_message, PAD_DATA_SIZE);
|
std::memcpy(send_buffer2.data(), &pad_message, PAD_DATA_SIZE);
|
||||||
socket.send_to(boost::asio::buffer(send_buffer2), send_endpoint, {}, _ignored);
|
socket.send_to(boost::asio::buffer(send_buffer2), send_endpoint, {}, _ignored);
|
||||||
@ -118,6 +115,7 @@ private:
|
|||||||
udp::socket socket;
|
udp::socket socket;
|
||||||
|
|
||||||
const u32 client_id;
|
const u32 client_id;
|
||||||
|
const u8 pad_index;
|
||||||
|
|
||||||
static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
|
static constexpr std::size_t PORT_INFO_SIZE = sizeof(Message<Request::PortInfo>);
|
||||||
static constexpr std::size_t PAD_DATA_SIZE = sizeof(Message<Request::PadData>);
|
static constexpr std::size_t PAD_DATA_SIZE = sizeof(Message<Request::PadData>);
|
||||||
@ -161,7 +159,7 @@ void UDPClient::ReloadSockets() {
|
|||||||
LOG_ERROR(Input, "Duplicated UDP servers found");
|
LOG_ERROR(Input, "Duplicated UDP servers found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StartCommunication(0, host, udp_input_port);
|
StartCommunication(0, host, udp_input_port, pad_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t UDPClient::GetClientNumber(std::string_view host, u16 port) const {
|
std::size_t UDPClient::GetClientNumber(std::string_view host, u16 port) const {
|
||||||
@ -239,7 +237,7 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
|||||||
static_cast<int>(id == 0 ? PadButton::Touch1 : PadButton::Touch2);
|
static_cast<int>(id == 0 ? PadButton::Touch1 : PadButton::Touch2);
|
||||||
|
|
||||||
// TODO: Use custom calibration per device
|
// TODO: Use custom calibration per device
|
||||||
/* const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
|
const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
|
||||||
const u16 min_x = static_cast<u16>(touch_param.Get("min_x", 100));
|
const u16 min_x = static_cast<u16>(touch_param.Get("min_x", 100));
|
||||||
const u16 min_y = static_cast<u16>(touch_param.Get("min_y", 50));
|
const u16 min_y = static_cast<u16>(touch_param.Get("min_y", 50));
|
||||||
const u16 max_x = static_cast<u16>(touch_param.Get("max_x", 1800));
|
const u16 max_x = static_cast<u16>(touch_param.Get("max_x", 1800));
|
||||||
@ -260,7 +258,7 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
|||||||
}
|
}
|
||||||
SetAxis(identifier, touch_axis_x_id, 0);
|
SetAxis(identifier, touch_axis_x_id, 0);
|
||||||
SetAxis(identifier, touch_axis_y_id, 0);
|
SetAxis(identifier, touch_axis_y_id, 0);
|
||||||
SetButton(identifier, touch_button_id, false);*/
|
SetButton(identifier, touch_button_id, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAxis(identifier, static_cast<int>(PadAxes::LeftStickX),
|
SetAxis(identifier, static_cast<int>(PadAxes::LeftStickX),
|
||||||
@ -288,7 +286,7 @@ void UDPClient::OnPadData(Response::PadData data, std::size_t client) {
|
|||||||
SetButton(identifier, static_cast<int>(PadButton::TouchHardPress), data.touch_hard_press != 0);
|
SetButton(identifier, static_cast<int>(PadButton::TouchHardPress), data.touch_hard_press != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UDPClient::StartCommunication(std::size_t client, const std::string& host, u16 port) {
|
void UDPClient::StartCommunication(std::size_t client, const std::string& host, u16 port, u8 pad_index) {
|
||||||
SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
|
SocketCallback callback{[this](Response::Version version) { OnVersion(version); },
|
||||||
[this](Response::PortInfo info) { OnPortInfo(info); },
|
[this](Response::PortInfo info) { OnPortInfo(info); },
|
||||||
[this, client](Response::PadData data) { OnPadData(data, client); }};
|
[this, client](Response::PadData data) { OnPadData(data, client); }};
|
||||||
@ -297,7 +295,7 @@ void UDPClient::StartCommunication(std::size_t client, const std::string& host,
|
|||||||
clients[client].host = host;
|
clients[client].host = host;
|
||||||
clients[client].port = port;
|
clients[client].port = port;
|
||||||
clients[client].active = 0;
|
clients[client].active = 0;
|
||||||
clients[client].socket = std::make_unique<Socket>(host, port, callback);
|
clients[client].socket = std::make_unique<Socket>(host, port, pad_index, callback);
|
||||||
clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
|
clients[client].thread = std::thread{SocketLoop, clients[client].socket.get()};
|
||||||
for (std::size_t index = 0; index < PADS_PER_CLIENT; ++index) {
|
for (std::size_t index = 0; index < PADS_PER_CLIENT; ++index) {
|
||||||
const PadIdentifier identifier = GetPadIdentifier(client * PADS_PER_CLIENT + index);
|
const PadIdentifier identifier = GetPadIdentifier(client * PADS_PER_CLIENT + index);
|
||||||
@ -502,7 +500,7 @@ bool UDPClient::IsStickInverted(const Common::ParamPackage& params) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestCommunication(const std::string& host, u16 port,
|
void TestCommunication(const std::string& host, u16 port, u8 pad_index,
|
||||||
const std::function<void()>& success_callback,
|
const std::function<void()>& success_callback,
|
||||||
const std::function<void()>& failure_callback) {
|
const std::function<void()>& failure_callback) {
|
||||||
std::thread([=] {
|
std::thread([=] {
|
||||||
@ -512,7 +510,7 @@ void TestCommunication(const std::string& host, u16 port,
|
|||||||
.port_info = [](Response::PortInfo) {},
|
.port_info = [](Response::PortInfo) {},
|
||||||
.pad_data = [&](Response::PadData) { success_event.Set(); },
|
.pad_data = [&](Response::PadData) { success_event.Set(); },
|
||||||
};
|
};
|
||||||
Socket socket{host, port, std::move(callback)};
|
Socket socket{host, port, pad_index, std::move(callback)};
|
||||||
std::thread worker_thread{SocketLoop, &socket};
|
std::thread worker_thread{SocketLoop, &socket};
|
||||||
const bool result =
|
const bool result =
|
||||||
success_event.WaitUntil(std::chrono::steady_clock::now() + std::chrono::seconds(10));
|
success_event.WaitUntil(std::chrono::steady_clock::now() + std::chrono::seconds(10));
|
||||||
@ -527,7 +525,7 @@ void TestCommunication(const std::string& host, u16 port,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CalibrationConfigurationJob::CalibrationConfigurationJob(
|
CalibrationConfigurationJob::CalibrationConfigurationJob(
|
||||||
const std::string& host, u16 port, std::function<void(Status)> status_callback,
|
const std::string& host, u16 port, u8 pad_index, std::function<void(Status)> status_callback,
|
||||||
std::function<void(u16, u16, u16, u16)> data_callback) {
|
std::function<void(u16, u16, u16, u16)> data_callback) {
|
||||||
|
|
||||||
std::thread([=, this] {
|
std::thread([=, this] {
|
||||||
@ -571,7 +569,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
|
|||||||
complete_event.Set();
|
complete_event.Set();
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
Socket socket{host, port, std::move(callback)};
|
Socket socket{host, port, pad_index, std::move(callback)};
|
||||||
std::thread worker_thread{SocketLoop, &socket};
|
std::thread worker_thread{SocketLoop, &socket};
|
||||||
complete_event.Wait();
|
complete_event.Wait();
|
||||||
socket.Stop();
|
socket.Stop();
|
||||||
|
@ -144,7 +144,7 @@ private:
|
|||||||
void OnVersion(Response::Version);
|
void OnVersion(Response::Version);
|
||||||
void OnPortInfo(Response::PortInfo);
|
void OnPortInfo(Response::PortInfo);
|
||||||
void OnPadData(Response::PadData, std::size_t client);
|
void OnPadData(Response::PadData, std::size_t client);
|
||||||
void StartCommunication(std::size_t client, const std::string& host, u16 port);
|
void StartCommunication(std::size_t client, const std::string& host, u16 port, u8 pad_index);
|
||||||
PadIdentifier GetPadIdentifier(std::size_t pad_index) const;
|
PadIdentifier GetPadIdentifier(std::size_t pad_index) const;
|
||||||
Common::UUID GetHostUUID(const std::string& host) const;
|
Common::UUID GetHostUUID(const std::string& host) const;
|
||||||
|
|
||||||
@ -172,7 +172,7 @@ public:
|
|||||||
* @param status_callback Callback for job status updates
|
* @param status_callback Callback for job status updates
|
||||||
* @param data_callback Called when calibration data is ready
|
* @param data_callback Called when calibration data is ready
|
||||||
*/
|
*/
|
||||||
explicit CalibrationConfigurationJob(const std::string& host, u16 port,
|
explicit CalibrationConfigurationJob(const std::string& host, u16 port, u8 pad_index,
|
||||||
std::function<void(Status)> status_callback,
|
std::function<void(Status)> status_callback,
|
||||||
std::function<void(u16, u16, u16, u16)> data_callback);
|
std::function<void(u16, u16, u16, u16)> data_callback);
|
||||||
~CalibrationConfigurationJob();
|
~CalibrationConfigurationJob();
|
||||||
@ -182,7 +182,7 @@ private:
|
|||||||
Common::Event complete_event;
|
Common::Event complete_event;
|
||||||
};
|
};
|
||||||
|
|
||||||
void TestCommunication(const std::string& host, u16 port,
|
void TestCommunication(const std::string& host, u16 port, u8 pad_index,
|
||||||
const std::function<void()>& success_callback,
|
const std::function<void()>& success_callback,
|
||||||
const std::function<void()>& failure_callback);
|
const std::function<void()>& failure_callback);
|
||||||
|
|
||||||
|
@ -11,6 +11,14 @@ namespace InputCommon {
|
|||||||
|
|
||||||
class Stick final : public Common::Input::InputDevice {
|
class Stick final : public Common::Input::InputDevice {
|
||||||
public:
|
public:
|
||||||
|
// Some games such as EARTH DEFENSE FORCE: WORLD BROTHERS
|
||||||
|
// do not play nicely with the theoretical maximum range.
|
||||||
|
// Using a value one lower from the maximum emulates real stick behavior.
|
||||||
|
static constexpr float MAX_RANGE = 32766.0f / 32767.0f;
|
||||||
|
static constexpr float TAU = Common::PI * 2.0f;
|
||||||
|
// Use wider angle to ease the transition.
|
||||||
|
static constexpr float APERTURE = TAU * 0.15f;
|
||||||
|
|
||||||
using Button = std::unique_ptr<Common::Input::InputDevice>;
|
using Button = std::unique_ptr<Common::Input::InputDevice>;
|
||||||
|
|
||||||
Stick(Button up_, Button down_, Button left_, Button right_, Button modifier_,
|
Stick(Button up_, Button down_, Button left_, Button right_, Button modifier_,
|
||||||
|
@ -84,7 +84,7 @@ enum RegisterFlags : u8 {
|
|||||||
struct Version {};
|
struct Version {};
|
||||||
/**
|
/**
|
||||||
* Requests the server to send information about what controllers are plugged into the ports
|
* Requests the server to send information about what controllers are plugged into the ports
|
||||||
* In yuzu's case, we only have one controller, so for simplicity's sake, we can just send a
|
* In citra's case, we only have one controller, so for simplicity's sake, we can just send a
|
||||||
* request explicitly for the first controller port and leave it at that. In the future it would be
|
* request explicitly for the first controller port and leave it at that. In the future it would be
|
||||||
* nice to make this configurable
|
* nice to make this configurable
|
||||||
*/
|
*/
|
||||||
|
@ -100,6 +100,18 @@ public:
|
|||||||
// Disable configuring mode for mapping
|
// Disable configuring mode for mapping
|
||||||
void EndConfiguration();
|
void EndConfiguration();
|
||||||
|
|
||||||
|
// Sets rumble to a controller
|
||||||
|
virtual Common::Input::DriverResult SetVibration(
|
||||||
|
[[maybe_unused]] const PadIdentifier& identifier,
|
||||||
|
[[maybe_unused]] const Common::Input::VibrationStatus& vibration) {
|
||||||
|
return Common::Input::DriverResult::NotSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns true if device supports vibrations
|
||||||
|
virtual bool IsVibrationEnabled([[maybe_unused]] const PadIdentifier& identifier) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Sets polling mode to a controller
|
// Sets polling mode to a controller
|
||||||
virtual Common::Input::PollingError SetPollingMode(
|
virtual Common::Input::PollingError SetPollingMode(
|
||||||
[[maybe_unused]] const PadIdentifier& identifier,
|
[[maybe_unused]] const PadIdentifier& identifier,
|
||||||
|
@ -4,14 +4,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include "common/input.h"
|
#include "common/input.h"
|
||||||
#include "common/param_package.h"
|
#include "common/param_package.h"
|
||||||
<<<<<<< HEAD
|
|
||||||
#include "input_common/analog_from_button.h"
|
|
||||||
#ifdef ENABLE_GCADAPTER
|
|
||||||
#include "input_common/gcadapter/gc_adapter.h"
|
|
||||||
#include "input_common/gcadapter/gc_poller.h"
|
|
||||||
#endif
|
|
||||||
#include "input_common/keyboard.h"
|
|
||||||
== == == =
|
|
||||||
#include "input_common/drivers/keyboard.h"
|
#include "input_common/drivers/keyboard.h"
|
||||||
#include "input_common/drivers/mouse.h"
|
#include "input_common/drivers/mouse.h"
|
||||||
#include "input_common/drivers/touch_screen.h"
|
#include "input_common/drivers/touch_screen.h"
|
||||||
@ -22,8 +14,7 @@
|
|||||||
#include "input_common/input_engine.h"
|
#include "input_common/input_engine.h"
|
||||||
#include "input_common/input_mapping.h"
|
#include "input_common/input_mapping.h"
|
||||||
#include "input_common/input_poller.h"
|
#include "input_common/input_poller.h"
|
||||||
>>>>>>> 6e5fec9fe (add input common changes)
|
#include "input_common/main.h"
|
||||||
#include "input_common/main.h"
|
|
||||||
|
|
||||||
#ifdef HAVE_LIBUSB
|
#ifdef HAVE_LIBUSB
|
||||||
#include "input_common/drivers/gc_adapter.h"
|
#include "input_common/drivers/gc_adapter.h"
|
||||||
@ -32,52 +23,20 @@
|
|||||||
#include "input_common/drivers/sdl_driver.h"
|
#include "input_common/drivers/sdl_driver.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace InputCommon {
|
namespace InputCommon {
|
||||||
|
|
||||||
<<<<<<< HEAD
|
struct InputSubsystem::Impl {
|
||||||
#ifdef ENABLE_GCADAPTER std::shared_ptr < GCButtonFactory> gcbuttons;
|
|
||||||
std::shared_ptr<GCAnalogFactory> gcanalog;
|
|
||||||
std::shared_ptr<GCAdapter::Adapter> gcadapter;
|
|
||||||
#endif
|
|
||||||
static std::shared_ptr<Keyboard> keyboard;
|
|
||||||
static std::shared_ptr<MotionEmu> motion_emu;
|
|
||||||
static std::unique_ptr<CemuhookUDP::State> udp;
|
|
||||||
static std::unique_ptr<SDL::State> sdl;
|
|
||||||
|
|
||||||
void Init() {
|
|
||||||
#ifdef ENABLE_GCADAPTER
|
|
||||||
gcadapter = std::make_shared<GCAdapter::Adapter>();
|
|
||||||
gcbuttons = std::make_shared<GCButtonFactory>(gcadapter);
|
|
||||||
Input::RegisterFactory<Input::ButtonDevice>("gcpad", gcbuttons);
|
|
||||||
gcanalog = std::make_shared<GCAnalogFactory>(gcadapter);
|
|
||||||
Input::RegisterFactory<Input::AnalogDevice>("gcpad", gcanalog);
|
|
||||||
#endif
|
|
||||||
keyboard = std::make_shared<Keyboard>();
|
|
||||||
Input::RegisterFactory<Input::ButtonDevice>("keyboard", keyboard);
|
|
||||||
Input::RegisterFactory<Input::AnalogDevice>("analog_from_button",
|
|
||||||
std::make_shared<AnalogFromButton>());
|
|
||||||
motion_emu = std::make_shared<MotionEmu>();
|
|
||||||
Input::RegisterFactory<Input::MotionDevice>("motion_emu", motion_emu);
|
|
||||||
Input::RegisterFactory<Input::TouchDevice>("touch_from_button",
|
|
||||||
std::make_shared<TouchFromButtonFactory>());
|
|
||||||
== == == = struct InputSubsystem::Impl {
|
|
||||||
template <typename Engine>
|
template <typename Engine>
|
||||||
void RegisterEngine(std::string name, std::shared_ptr<Engine>& engine) {
|
void RegisterEngine(std::string name, std::shared_ptr<Engine>& engine) {
|
||||||
MappingCallback mapping_callback{
|
MappingCallback mapping_callback{[this](const MappingData& data) { RegisterInput(data); }};
|
||||||
[this](const MappingData& data) { RegisterInput(data); }};
|
|
||||||
|
|
||||||
engine = std::make_shared<Engine>(name);
|
engine = std::make_shared<Engine>(name);
|
||||||
engine->SetMappingCallback(mapping_callback);
|
engine->SetMappingCallback(mapping_callback);
|
||||||
>>>>>>> 6e5fec9fe (add input common changes)
|
|
||||||
|
|
||||||
std::shared_ptr<InputFactory> input_factory =
|
std::shared_ptr<InputFactory> input_factory = std::make_shared<InputFactory>(engine);
|
||||||
std::make_shared<InputFactory>(engine);
|
std::shared_ptr<OutputFactory> output_factory = std::make_shared<OutputFactory>(engine);
|
||||||
std::shared_ptr<OutputFactory> output_factory =
|
Common::Input::RegisterInputFactory(engine->GetEngineName(), std::move(input_factory));
|
||||||
std::make_shared<OutputFactory>(engine);
|
Common::Input::RegisterOutputFactory(engine->GetEngineName(), std::move(output_factory));
|
||||||
Common::Input::RegisterInputFactory(engine->GetEngineName(),
|
|
||||||
std::move(input_factory));
|
|
||||||
Common::Input::RegisterOutputFactory(engine->GetEngineName(),
|
|
||||||
std::move(output_factory));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() {
|
void Initialize() {
|
||||||
@ -305,138 +264,115 @@
|
|||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
std::shared_ptr<SDLDriver> sdl;
|
std::shared_ptr<SDLDriver> sdl;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
|
InputSubsystem::InputSubsystem() : impl{std::make_unique<Impl>()} {}
|
||||||
|
|
||||||
InputSubsystem::~InputSubsystem() = default;
|
InputSubsystem::~InputSubsystem() = default;
|
||||||
|
|
||||||
void InputSubsystem::Initialize() {
|
void InputSubsystem::Initialize() {
|
||||||
impl->Initialize();
|
impl->Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
<<<<<<< HEAD
|
void InputSubsystem::Shutdown() {
|
||||||
void Shutdown() {
|
|
||||||
#ifdef ENABLE_GCADAPTER
|
|
||||||
Input::UnregisterFactory<Input::ButtonDevice>("gcpad");
|
|
||||||
Input::UnregisterFactory<Input::AnalogDevice>("gcpad");
|
|
||||||
gcbuttons.reset();
|
|
||||||
gcanalog.reset();
|
|
||||||
#endif
|
|
||||||
Input::UnregisterFactory<Input::ButtonDevice>("keyboard");
|
|
||||||
keyboard.reset();
|
|
||||||
Input::UnregisterFactory<Input::AnalogDevice>("analog_from_button");
|
|
||||||
Input::UnregisterFactory<Input::MotionDevice>("motion_emu");
|
|
||||||
motion_emu.reset();
|
|
||||||
Input::UnregisterFactory<Input::TouchDevice>("emu_window");
|
|
||||||
Input::UnregisterFactory<Input::TouchDevice>("touch_from_button");
|
|
||||||
sdl.reset();
|
|
||||||
udp.reset();
|
|
||||||
== == == = void InputSubsystem::Shutdown() {
|
|
||||||
impl->Shutdown();
|
impl->Shutdown();
|
||||||
>>>>>>> 6e5fec9fe (add input common changes)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Keyboard* InputSubsystem::GetKeyboard() {
|
Keyboard* InputSubsystem::GetKeyboard() {
|
||||||
return impl->keyboard.get();
|
return impl->keyboard.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Keyboard* InputSubsystem::GetKeyboard() const {
|
const Keyboard* InputSubsystem::GetKeyboard() const {
|
||||||
return impl->keyboard.get();
|
return impl->keyboard.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Mouse* InputSubsystem::GetMouse() {
|
Mouse* InputSubsystem::GetMouse() {
|
||||||
return impl->mouse.get();
|
return impl->mouse.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Mouse* InputSubsystem::GetMouse() const {
|
const Mouse* InputSubsystem::GetMouse() const {
|
||||||
return impl->mouse.get();
|
return impl->mouse.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchScreen* InputSubsystem::GetTouchScreen() {
|
TouchScreen* InputSubsystem::GetTouchScreen() {
|
||||||
return impl->touch_screen.get();
|
return impl->touch_screen.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const TouchScreen* InputSubsystem::GetTouchScreen() const {
|
const TouchScreen* InputSubsystem::GetTouchScreen() const {
|
||||||
return impl->touch_screen.get();
|
return impl->touch_screen.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualGamepad* InputSubsystem::GetVirtualGamepad() {
|
VirtualGamepad* InputSubsystem::GetVirtualGamepad() {
|
||||||
return impl->virtual_gamepad.get();
|
return impl->virtual_gamepad.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
const VirtualGamepad* InputSubsystem::GetVirtualGamepad() const {
|
const VirtualGamepad* InputSubsystem::GetVirtualGamepad() const {
|
||||||
return impl->virtual_gamepad.get();
|
return impl->virtual_gamepad.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
|
std::vector<Common::ParamPackage> InputSubsystem::GetInputDevices() const {
|
||||||
return impl->GetInputDevices();
|
return impl->GetInputDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalogMapping InputSubsystem::GetAnalogMappingForDevice(
|
AnalogMapping InputSubsystem::GetAnalogMappingForDevice(const Common::ParamPackage& device) const {
|
||||||
const Common::ParamPackage& device) const {
|
|
||||||
return impl->GetAnalogMappingForDevice(device);
|
return impl->GetAnalogMappingForDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonMapping InputSubsystem::GetButtonMappingForDevice(
|
ButtonMapping InputSubsystem::GetButtonMappingForDevice(const Common::ParamPackage& device) const {
|
||||||
const Common::ParamPackage& device) const {
|
|
||||||
return impl->GetButtonMappingForDevice(device);
|
return impl->GetButtonMappingForDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
MotionMapping InputSubsystem::GetMotionMappingForDevice(
|
MotionMapping InputSubsystem::GetMotionMappingForDevice(const Common::ParamPackage& device) const {
|
||||||
const Common::ParamPackage& device) const {
|
|
||||||
return impl->GetMotionMappingForDevice(device);
|
return impl->GetMotionMappingForDevice(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::Input::ButtonNames InputSubsystem::GetButtonName(
|
Common::Input::ButtonNames InputSubsystem::GetButtonName(const Common::ParamPackage& params) const {
|
||||||
const Common::ParamPackage& params) const {
|
|
||||||
return impl->GetButtonName(params);
|
return impl->GetButtonName(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputSubsystem::IsController(const Common::ParamPackage& params) const {
|
bool InputSubsystem::IsController(const Common::ParamPackage& params) const {
|
||||||
return impl->IsController(params);
|
return impl->IsController(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputSubsystem::IsStickInverted(const Common::ParamPackage& params) const {
|
bool InputSubsystem::IsStickInverted(const Common::ParamPackage& params) const {
|
||||||
if (params.Has("axis_x") && params.Has("axis_y")) {
|
if (params.Has("axis_x") && params.Has("axis_y")) {
|
||||||
return impl->IsStickInverted(params);
|
return impl->IsStickInverted(params);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputSubsystem::ReloadInputDevices() {
|
void InputSubsystem::ReloadInputDevices() {
|
||||||
impl->udp_client.get()->ReloadSockets();
|
impl->udp_client.get()->ReloadSockets();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputSubsystem::BeginMapping(Polling::InputType type) {
|
void InputSubsystem::BeginMapping(Polling::InputType type) {
|
||||||
impl->BeginConfiguration();
|
impl->BeginConfiguration();
|
||||||
impl->mapping_factory->BeginMapping(type);
|
impl->mapping_factory->BeginMapping(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::ParamPackage InputSubsystem::GetNextInput() const {
|
Common::ParamPackage InputSubsystem::GetNextInput() const {
|
||||||
return impl->mapping_factory->GetNextInput();
|
return impl->mapping_factory->GetNextInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputSubsystem::StopMapping() const {
|
void InputSubsystem::StopMapping() const {
|
||||||
impl->EndConfiguration();
|
impl->EndConfiguration();
|
||||||
impl->mapping_factory->StopMapping();
|
impl->mapping_factory->StopMapping();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputSubsystem::PumpEvents() const {
|
void InputSubsystem::PumpEvents() const {
|
||||||
impl->PumpEvents();
|
impl->PumpEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateKeyboardParam(int key_code) {
|
std::string GenerateKeyboardParam(int key_code) {
|
||||||
Common::ParamPackage param;
|
Common::ParamPackage param;
|
||||||
param.Set("engine", "keyboard");
|
param.Set("engine", "keyboard");
|
||||||
param.Set("code", key_code);
|
param.Set("code", key_code);
|
||||||
param.Set("toggle", false);
|
param.Set("toggle", false);
|
||||||
return param.Serialize();
|
return param.Serialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left,
|
std::string GenerateAnalogParamFromKeys(int key_up, int key_down, int key_left, int key_right,
|
||||||
int key_right, int key_modifier,
|
int key_modifier, float modifier_scale) {
|
||||||
float modifier_scale) {
|
|
||||||
Common::ParamPackage circle_pad_param{
|
Common::ParamPackage circle_pad_param{
|
||||||
{"engine", "analog_from_button"},
|
{"engine", "analog_from_button"},
|
||||||
{"up", GenerateKeyboardParam(key_up)},
|
{"up", GenerateKeyboardParam(key_up)},
|
||||||
@ -447,75 +383,5 @@
|
|||||||
{"modifier_scale", std::to_string(modifier_scale)},
|
{"modifier_scale", std::to_string(modifier_scale)},
|
||||||
};
|
};
|
||||||
return circle_pad_param.Serialize();
|
return circle_pad_param.Serialize();
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
} // namespace InputCommon
|
||||||
|
|
||||||
Common::ParamPackage GetControllerButtonBinds(const Common::ParamPackage& params,
|
|
||||||
int button) {
|
|
||||||
const auto native_button{static_cast<Settings::NativeButton::Values>(button)};
|
|
||||||
const auto engine{params.Get("engine", "")};
|
|
||||||
if (engine == "sdl") {
|
|
||||||
return dynamic_cast<SDL::SDLState*>(sdl.get())
|
|
||||||
->GetSDLControllerButtonBindByGUID(params.Get("guid", "0"),
|
|
||||||
params.Get("port", 0), native_button);
|
|
||||||
}
|
|
||||||
#ifdef ENABLE_GCADAPTER
|
|
||||||
if (engine == "gcpad") {
|
|
||||||
return gcbuttons->GetGcTo3DSMappedButton(params.Get("port", 0), native_button);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::ParamPackage GetControllerAnalogBinds(const Common::ParamPackage& params,
|
|
||||||
int analog) {
|
|
||||||
const auto native_analog{static_cast<Settings::NativeAnalog::Values>(analog)};
|
|
||||||
const auto engine{params.Get("engine", "")};
|
|
||||||
if (engine == "sdl") {
|
|
||||||
return dynamic_cast<SDL::SDLState*>(sdl.get())
|
|
||||||
->GetSDLControllerAnalogBindByGUID(params.Get("guid", "0"),
|
|
||||||
params.Get("port", 0), native_analog);
|
|
||||||
}
|
|
||||||
#ifdef ENABLE_GCADAPTER
|
|
||||||
if (engine == "gcpad") {
|
|
||||||
return gcanalog->GetGcTo3DSMappedAnalog(params.Get("port", 0), native_analog);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReloadInputDevices() {
|
|
||||||
if (!udp) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
udp->ReloadUDPClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Polling {
|
|
||||||
|
|
||||||
std::vector<std::unique_ptr<DevicePoller>> GetPollers(DeviceType type) {
|
|
||||||
std::vector<std::unique_ptr<DevicePoller>> pollers;
|
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
pollers = sdl->GetPollers(type);
|
|
||||||
#endif
|
|
||||||
#ifdef ENABLE_GCADAPTER
|
|
||||||
switch (type) {
|
|
||||||
case DeviceType::Analog:
|
|
||||||
pollers.push_back(std::make_unique<GCAnalogFactory>(*gcanalog));
|
|
||||||
break;
|
|
||||||
case DeviceType::Button:
|
|
||||||
pollers.push_back(std::make_unique<GCButtonFactory>(*gcbuttons));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return pollers;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Polling
|
|
||||||
== == == =
|
|
||||||
>>>>>>> 6e5fec9fe (add input common changes)
|
|
||||||
} // namespace InputCommon
|
|
||||||
|
Reference in New Issue
Block a user