2019-08-30 22:49:55 +00:00
|
|
|
#include <windows.h>
|
|
|
|
#include <xinput.h>
|
|
|
|
|
|
|
|
#include <limits.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
|
|
|
|
#include "mu3io/mu3io.h"
|
2023-07-13 22:54:30 +00:00
|
|
|
#include "mu3io/config.h"
|
2023-08-15 15:40:32 +00:00
|
|
|
#include "util/dprintf.h"
|
2019-08-30 22:49:55 +00:00
|
|
|
|
|
|
|
static uint8_t mu3_opbtn;
|
|
|
|
static uint8_t mu3_left_btn;
|
|
|
|
static uint8_t mu3_right_btn;
|
|
|
|
static int16_t mu3_lever_pos;
|
|
|
|
static int16_t mu3_lever_xpos;
|
2023-07-13 22:54:30 +00:00
|
|
|
static struct mu3_io_config mu3_io_cfg;
|
|
|
|
static bool mu3_io_coin;
|
2019-08-30 22:49:55 +00:00
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
// Mouse control factor to adjust the speed of mouse movement
|
|
|
|
const double MOUSE_SENSITIVITY = 0.5;
|
|
|
|
|
2021-06-06 18:25:32 +00:00
|
|
|
uint16_t mu3_io_get_api_version(void)
|
|
|
|
{
|
2024-05-12 17:36:08 +00:00
|
|
|
return 0x0101;
|
2021-06-06 18:25:32 +00:00
|
|
|
}
|
|
|
|
|
2019-08-30 22:49:55 +00:00
|
|
|
HRESULT mu3_io_init(void)
|
|
|
|
{
|
2023-07-13 22:54:30 +00:00
|
|
|
mu3_io_config_load(&mu3_io_cfg, L".\\segatools.ini");
|
2023-08-15 15:40:32 +00:00
|
|
|
|
|
|
|
dprintf("XInput: --- Begin configuration ---\n");
|
|
|
|
dprintf("XInput: Mouse lever emulation : %i\n", mu3_io_cfg.use_mouse);
|
|
|
|
dprintf("XInput: --- End configuration ---\n");
|
|
|
|
|
2019-08-30 22:49:55 +00:00
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT mu3_io_poll(void)
|
|
|
|
{
|
|
|
|
int lever;
|
|
|
|
int xlever;
|
|
|
|
XINPUT_STATE xi;
|
|
|
|
WORD xb;
|
|
|
|
|
|
|
|
mu3_opbtn = 0;
|
|
|
|
mu3_left_btn = 0;
|
|
|
|
mu3_right_btn = 0;
|
|
|
|
|
2023-07-13 22:54:30 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_test) & 0x8000) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_opbtn |= MU3_IO_OPBTN_TEST;
|
|
|
|
}
|
|
|
|
|
2023-07-13 22:54:30 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_service) & 0x8000) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_opbtn |= MU3_IO_OPBTN_SERVICE;
|
|
|
|
}
|
|
|
|
|
2023-07-13 22:54:30 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_coin) & 0x8000) {
|
|
|
|
if (!mu3_io_coin) {
|
|
|
|
mu3_io_coin = true;
|
|
|
|
mu3_opbtn |= MU3_IO_OPBTN_COIN;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
mu3_io_coin = false;
|
|
|
|
}
|
|
|
|
|
2019-08-30 22:49:55 +00:00
|
|
|
memset(&xi, 0, sizeof(xi));
|
|
|
|
XInputGetState(0, &xi);
|
|
|
|
xb = xi.Gamepad.wButtons;
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_left_1) || (xb & XINPUT_GAMEPAD_DPAD_LEFT)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_left_btn |= MU3_IO_GAMEBTN_1;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_left_2) || (xb & XINPUT_GAMEPAD_DPAD_UP)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_left_btn |= MU3_IO_GAMEBTN_2;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_left_3) || (xb & XINPUT_GAMEPAD_DPAD_RIGHT)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_left_btn |= MU3_IO_GAMEBTN_3;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_right_1) || (xb & XINPUT_GAMEPAD_X)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_right_btn |= MU3_IO_GAMEBTN_1;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_right_2) || (xb & XINPUT_GAMEPAD_Y)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_right_btn |= MU3_IO_GAMEBTN_2;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_right_3) || (xb & XINPUT_GAMEPAD_B)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_right_btn |= MU3_IO_GAMEBTN_3;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_left_menu) || (xb & XINPUT_GAMEPAD_BACK)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_left_btn |= MU3_IO_GAMEBTN_MENU;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_right_menu) || (xb & XINPUT_GAMEPAD_START)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_right_btn |= MU3_IO_GAMEBTN_MENU;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_left_side) || (xb & XINPUT_GAMEPAD_LEFT_SHOULDER)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_left_btn |= MU3_IO_GAMEBTN_SIDE;
|
|
|
|
}
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (GetAsyncKeyState(mu3_io_cfg.vk_right_side) || (xb & XINPUT_GAMEPAD_RIGHT_SHOULDER)) {
|
2019-08-30 22:49:55 +00:00
|
|
|
mu3_right_btn |= MU3_IO_GAMEBTN_SIDE;
|
|
|
|
}
|
|
|
|
|
|
|
|
lever = mu3_lever_pos;
|
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
if (mu3_io_cfg.use_mouse) {
|
|
|
|
// mouse movement
|
|
|
|
POINT mousePos;
|
|
|
|
GetCursorPos(&mousePos);
|
|
|
|
|
|
|
|
// int mouseMovement = (int)(xi.Gamepad.sThumbLX * MOUSE_SENSITIVITY);
|
|
|
|
// int newXPos = mousePos.x + mouseMovement;
|
|
|
|
int mouse_x = mousePos.x;
|
|
|
|
|
|
|
|
// clamp the mouse_x position to the screen width
|
|
|
|
int screenWidth = GetSystemMetrics(SM_CXSCREEN);
|
|
|
|
if (mouse_x < 0) {
|
|
|
|
mouse_x = 0;
|
|
|
|
}
|
|
|
|
else if (mouse_x > screenWidth) {
|
|
|
|
mouse_x = screenWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
// normalize the mouse_x position from 0 to 1
|
|
|
|
double mouse_x_norm = (double)mouse_x / screenWidth;
|
2019-08-30 22:49:55 +00:00
|
|
|
|
2023-08-15 15:40:32 +00:00
|
|
|
// scale the mouse_x_norm to the range of INT16_MIN to INT16_MAX
|
|
|
|
mouse_x = (int)((mouse_x_norm * (INT16_MAX - INT16_MIN)) + INT16_MIN);
|
|
|
|
|
|
|
|
lever = mouse_x;
|
|
|
|
} else {
|
|
|
|
if (abs(xi.Gamepad.sThumbLX) > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
|
|
|
|
lever += xi.Gamepad.sThumbLX / 24;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (abs(xi.Gamepad.sThumbRX) > XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
|
|
|
|
lever += xi.Gamepad.sThumbRX / 24;
|
|
|
|
}
|
2019-08-30 22:49:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (lever < INT16_MIN) {
|
|
|
|
lever = INT16_MIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lever > INT16_MAX) {
|
|
|
|
lever = INT16_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
mu3_lever_pos = lever;
|
|
|
|
|
|
|
|
xlever = mu3_lever_pos
|
2019-11-04 00:55:02 +00:00
|
|
|
- xi.Gamepad.bLeftTrigger * 64
|
|
|
|
+ xi.Gamepad.bRightTrigger * 64;
|
2019-08-30 22:49:55 +00:00
|
|
|
|
|
|
|
if (xlever < INT16_MIN) {
|
|
|
|
xlever = INT16_MIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (xlever > INT16_MAX) {
|
|
|
|
xlever = INT16_MAX;
|
|
|
|
}
|
|
|
|
|
|
|
|
mu3_lever_xpos = xlever;
|
|
|
|
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mu3_io_get_opbtns(uint8_t *opbtn)
|
|
|
|
{
|
|
|
|
if (opbtn != NULL) {
|
|
|
|
*opbtn = mu3_opbtn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void mu3_io_get_gamebtns(uint8_t *left, uint8_t *right)
|
|
|
|
{
|
|
|
|
if (left != NULL) {
|
|
|
|
*left = mu3_left_btn;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (right != NULL ){
|
|
|
|
*right = mu3_right_btn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void mu3_io_get_lever(int16_t *pos)
|
|
|
|
{
|
|
|
|
if (pos != NULL) {
|
|
|
|
*pos = mu3_lever_xpos;
|
|
|
|
}
|
|
|
|
}
|
2024-05-12 17:36:08 +00:00
|
|
|
|
|
|
|
HRESULT mu3_io_led_init(void)
|
|
|
|
{
|
|
|
|
return S_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void mu3_io_led_set_colors(uint8_t board, uint8_t *rgb)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|