123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206 |
- #include "TouchSliderEmulator.h"
- #include "../ComponentsManager.h"
- #include "../../Constants.h"
- #include "../../framework.h"
- #include "../../Input/Mouse/Mouse.h"
- #include "../../Input/Keyboard/Keyboard.h"
- #include "../../Input/Bindings/KeyboardBinding.h"
- #include "../../Input/KeyConfig/Config.h"
- #include "../../Input/DirectInput/Ds4/DualShock4.h"
- #include "../../FileSystem/ConfigFile.h"
- #include "../../Utilities/Math.h"
- #include <algorithm>
- #include <stdio.h>
- #include "../GameState.h"
- using namespace TLAC::Input;
- using namespace TLAC::Input::KeyConfig;
- using namespace TLAC::Utilities;
- namespace TLAC::Components
- {
- const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
- TouchSliderEmulator* TouchSliderEmulator::LatestInstance;
- TouchSliderEmulator::TouchSliderEmulator()
- {
- LatestInstance = this;
- }
- TouchSliderEmulator::~TouchSliderEmulator()
- {
- delete LeftSideSlideLeft;
- delete LeftSideSlideRight;
- delete RightSideSlideLeft;
- delete RightSideSlideRight;
- }
- const char* TouchSliderEmulator::GetDisplayName()
- {
- return "touch_slider_emulator";
- }
- void TouchSliderEmulator::Initialize(ComponentsManager* manager)
- {
- componentsManager = manager;
- sliderState = (TouchSliderState*)SLIDER_CTRL_TASK_ADDRESS;
- touchSliderEmulatorIsEnabled = true;
- LeftSideSlideLeft = new Binding();
- LeftSideSlideRight = new Binding();
- RightSideSlideLeft = new Binding();
- RightSideSlideRight = new Binding();
- FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
- configFile.OpenRead();
- usePs4OfficialSlider = configFile.GetBooleanValue("ps4_official_slider");
- enableInMenus = configFile.GetBooleanValue("slider_in_menus");
- if (usePs4OfficialSlider)
- {
- DualShock4* ds4 = DualShock4::GetInstance();
- if (ds4 == nullptr)
- DualShock4::rawMode = true; // set raw mode for future instances if no current instance
- else
- ds4->SetRawMode(true); // if is a current instance, set raw mode on it (also sets for future instances)
- }
- else
- {
- DualShock4* ds4 = DualShock4::GetInstance();
- if (ds4 == nullptr)
- DualShock4::rawMode = false; // set raw mode for future instances if no current instance
- else
- ds4->SetRawMode(false); // if is a current instance, set raw mode on it (also sets for future instances)
- Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" });
- Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
- Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" });
- Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" });
- float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed");
- if (touchSliderEmulationSpeed != 0.0f)
- sliderSpeed = touchSliderEmulationSpeed;
- }
- }
- void TouchSliderEmulator::Update()
- {
- sliderState->State = SLIDER_OK;
- }
- void TouchSliderEmulator::UpdateInput()
- {
- if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || (!enableInMenus && !(*(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME && *(SubGameState*)CURRENT_GAME_SUB_STATE_ADDRESS == SUB_GAME_MAIN)))
- return;
- if (usePs4OfficialSlider)
- {
- DualShock4* ds4 = DualShock4::GetInstance();
- if (ds4 == nullptr)
- return;
- Joystick ls = ds4->GetLeftStick();
- Joystick rs = ds4->GetRightStick();
- uint32_t state = 0;
- // DualShock4 normalises sticks to floats -- this undoes that
- //printf("left stick: %9.6f, %9.6f, ", ls.XAxis, ls.YAxis);
- state |= (uint8_t)((ls.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000; // 0.001 to prevent rounding errors
- //printf("%d, ", (int)(state ^ 0b10000000));
- state |= ((uint8_t)((ls.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 8;
- //printf("%d\n", (int)((state >> 8) ^ 0b10000000));
- state |= ((uint8_t)((rs.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 16;
- state |= ((uint8_t)((rs.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 24;
- ApplyBitfieldState(state);
- }
- else
- {
- sliderIncrement = GetElapsedTime() / sliderSpeed;
- constexpr float sensorStep = (1.0f / SLIDER_SENSORS);
- EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f);
- EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep);
- sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
- for (int i = 0; i < CONTACT_POINTS; i++)
- ApplyContactPoint(ContactPoints[i], i);
- }
- }
- void TouchSliderEmulator::OnFocusLost()
- {
- if (usePs4OfficialSlider)
- sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_RAW);
- else
- sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
- }
- // EmulateSliderInput and ApplyContactPoint are used for analog stick/button slider emulation
- void TouchSliderEmulator::EmulateSliderInput(Binding *leftBinding, Binding *rightBinding, ContactPoint &contactPoint, float start, float end)
- {
- bool leftDown = leftBinding->AnyDown();
- bool rightDown = rightBinding->AnyDown();
- if (leftDown)
- contactPoint.Position -= sliderIncrement;
- else if (rightDown)
- contactPoint.Position += sliderIncrement;
- if (contactPoint.Position < start)
- contactPoint.Position = end;
- if (contactPoint.Position > end)
- contactPoint.Position = start;
- bool leftTapped = leftBinding->AnyTapped();
- bool rightTapped = rightBinding->AnyTapped();
- if (leftTapped || rightTapped)
- contactPoint.Position = (start + end) / 2.0f;
- contactPoint.InContact = leftDown || rightDown;
- }
- void TouchSliderEmulator::ApplyContactPoint(ContactPoint& contactPoint, int section)
- {
- sliderState->SectionTouched[section] = contactPoint.InContact;
- int pressure = contactPoint.InContact ? FULL_PRESSURE : NO_PRESSURE;
- float position = std::clamp(contactPoint.Position, 0.0f, 1.0f);
- if (contactPoint.InContact)
- {
- int sensor = (int)(position * (SLIDER_SENSORS - 1));
- sliderState->SetSensor(sensor, pressure, TouchSliderState::SENSOR_SET_MODE_SECTIONS);
- }
- constexpr float startRange = -1.0f;
- constexpr float endRange = +1.0f;
- sliderState->SectionPositions[section] = contactPoint.InContact ? (ConvertRange(0.0f, 1.0f, startRange, endRange, position)) : 0.0f;
- }
- // ApplyBitfieldState is used for setting raw slider data
- void TouchSliderEmulator::ApplyBitfieldState(uint32_t state)
- {
- for (int i = 0; i < 32; i++)
- {
- if (state & (1 << (31 - i)))
- sliderState->SetSensor(i, FULL_PRESSURE, TouchSliderState::SENSOR_SET_MODE_RAW);
- else
- sliderState->SetSensor(i, NO_PRESSURE, TouchSliderState::SENSOR_SET_MODE_RAW);
- }
- }
- }
|