Untitled
unknown
c_cpp
9 months ago
6.0 kB
6
Indexable
#pragma once
#include <Windows.h>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstdint>
#include <thread>
#include <chrono>
#include <Xinput.h>
#include <ViGEm/Client.h>
namespace ControllerAim {
inline PVIGEM_CLIENT vigemClient = nullptr;
inline PVIGEM_TARGET vigemTarget = nullptr;
inline XUSB_REPORT controllerReport = { 0 };
inline bool running = false;
inline bool Initialize()
{
if (vigemClient != nullptr && vigemTarget != nullptr)
return true;
vigemClient = vigem_alloc();
if (vigemClient == nullptr)
{
std::cerr << "Failed to allocate ViGEm client." << std::endl;
return false;
}
VIGEM_ERROR ret = vigem_connect(vigemClient);
if (!VIGEM_SUCCESS(ret))
{
std::cerr << "Failed to connect ViGEm client." << std::endl;
vigem_free(vigemClient);
vigemClient = nullptr;
return false;
}
vigemTarget = vigem_target_x360_alloc();
if (vigemTarget == nullptr)
{
std::cerr << "Failed to allocate virtual controller." << std::endl;
vigem_disconnect(vigemClient);
vigem_free(vigemClient);
vigemClient = nullptr;
return false;
}
ret = vigem_target_add(vigemClient, vigemTarget);
if (!VIGEM_SUCCESS(ret))
{
std::cerr << "Failed to add virtual controller." << std::endl;
vigem_target_free(vigemTarget);
vigem_disconnect(vigemClient);
vigem_free(vigemClient);
vigemTarget = nullptr;
vigemClient = nullptr;
return false;
}
ZeroMemory(&controllerReport, sizeof(XUSB_REPORT));
running = true;
return true;
}
inline void Cleanup()
{
running = false;
if (vigemClient && vigemTarget)
{
vigem_target_remove(vigemClient, vigemTarget);
vigem_target_free(vigemTarget);
vigemTarget = nullptr;
vigem_disconnect(vigemClient);
vigem_free(vigemClient);
vigemClient = nullptr;
}
}
inline void RunVirtualController()
{
if (!Initialize())
{
std::cerr << "Virtual controller initialization failed." << std::endl;
return;
}
std::cout << "Virtual controller is running. Press CTRL+C to exit." << std::endl;
XINPUT_STATE state;
while (running)
{
ZeroMemory(&state, sizeof(XINPUT_STATE));
DWORD dwResult = XInputGetState(0, &state);
if (dwResult == ERROR_SUCCESS)
{
const XINPUT_GAMEPAD& gamepad = state.Gamepad;
controllerReport.wButtons = gamepad.wButtons;
controllerReport.bLeftTrigger = gamepad.bLeftTrigger;
controllerReport.bRightTrigger = gamepad.bRightTrigger;
controllerReport.sThumbLX = gamepad.sThumbLX;
controllerReport.sThumbLY = gamepad.sThumbLY;
}
else
{
controllerReport.wButtons = 0;
controllerReport.bLeftTrigger = 0;
controllerReport.bRightTrigger = 0;
controllerReport.sThumbLX = 0;
controllerReport.sThumbLY = 0;
}
VIGEM_ERROR ret = vigem_target_x360_update(vigemClient, vigemTarget, controllerReport);
if (!VIGEM_SUCCESS(ret))
std::cerr << "Failed to update virtual controller." << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
Cleanup();
}
/*inline void ControllerMoveRightStick(float tarx, float tary, float screenX, float screenY, int smooth)
{
if (!running)
{
if (!Initialize())
{
std::cerr << "Virtual controller initialization failed in ControllerMoveRightStick." << std::endl;
return;
}
}
float ScreenCenterX = screenX / 2.0f;
float ScreenCenterY = screenY / 2.0f;
float offsetX = 0.0f;
float offsetY = 0.0f;
if (tarx != 0.0f)
{
offsetX = (tarx > ScreenCenterX) ? -(ScreenCenterX - tarx) : tarx - ScreenCenterX;
offsetX /= smooth;
}
if (tary != 0.0f)
{
offsetY = (tary > ScreenCenterY) ? -(ScreenCenterY - tary) : tary - ScreenCenterY;
offsetY /= smooth;
}
short newRX = static_cast<short>(std::clamp(offsetX, -32768.0f, 32767.0f));
short newRY = static_cast<short>(std::clamp(offsetY, -32768.0f, 32767.0f));
controllerReport.sThumbRX = newRX;
controllerReport.sThumbRY = newRY;
VIGEM_ERROR ret = vigem_target_x360_update(vigemClient, vigemTarget, controllerReport);
if (!VIGEM_SUCCESS(ret))
std::cerr << "Failed to update virtual controller right stick." << std::endl;
}*/
inline void ControllerMoveRightStick(float tarx, float tary, float /*screenX*/, float /*screenY*/, int /*smooth*/)
{
const float conversionFactor = 32767.0f / 127.0f;
short newRX = static_cast<short>(tarx * conversionFactor);
short newRY = static_cast<short>(tary * conversionFactor);
controllerReport.sThumbRX = newRX;
controllerReport.sThumbRY = newRY;
VIGEM_ERROR ret = vigem_target_x360_update(vigemClient, vigemTarget, controllerReport);
if (!VIGEM_SUCCESS(ret))
std::cerr << "Failed to update virtual controller right stick." << std::endl;
}
inline std::thread LaunchVirtualController()
{
return std::thread(RunVirtualController);
}
}
Editor is loading...
Leave a Comment