TouchSliderEmulator.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. #include "TouchSliderEmulator.h"
  2. #include "../ComponentsManager.h"
  3. #include "../../Constants.h"
  4. #include "../../framework.h"
  5. #include "../../Input/Mouse/Mouse.h"
  6. #include "../../Input/Keyboard/Keyboard.h"
  7. #include "../../Input/Bindings/KeyboardBinding.h"
  8. #include "../../Input/KeyConfig/Config.h"
  9. #include "../../Input/DirectInput/Ds4/DualShock4.h"
  10. #include "../../FileSystem/ConfigFile.h"
  11. #include "../../Utilities/Math.h"
  12. #include <algorithm>
  13. #include <stdio.h>
  14. #include "../GameState.h"
  15. using namespace TLAC::Input;
  16. using namespace TLAC::Input::KeyConfig;
  17. using namespace TLAC::Utilities;
  18. namespace TLAC::Components
  19. {
  20. const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
  21. TouchSliderEmulator* TouchSliderEmulator::LatestInstance;
  22. TouchSliderEmulator::TouchSliderEmulator()
  23. {
  24. LatestInstance = this;
  25. }
  26. TouchSliderEmulator::~TouchSliderEmulator()
  27. {
  28. delete LeftSideSlideLeft;
  29. delete LeftSideSlideRight;
  30. delete RightSideSlideLeft;
  31. delete RightSideSlideRight;
  32. }
  33. const char* TouchSliderEmulator::GetDisplayName()
  34. {
  35. return "touch_slider_emulator";
  36. }
  37. void TouchSliderEmulator::Initialize(ComponentsManager* manager)
  38. {
  39. componentsManager = manager;
  40. sliderState = (TouchSliderState*)SLIDER_CTRL_TASK_ADDRESS;
  41. touchSliderEmulatorIsEnabled = true;
  42. LeftSideSlideLeft = new Binding();
  43. LeftSideSlideRight = new Binding();
  44. RightSideSlideLeft = new Binding();
  45. RightSideSlideRight = new Binding();
  46. FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
  47. configFile.OpenRead();
  48. usePs4OfficialSlider = configFile.GetBooleanValue("ps4_official_slider");
  49. enableInMenus = configFile.GetBooleanValue("slider_in_menus");
  50. if (usePs4OfficialSlider)
  51. {
  52. DualShock4* ds4 = DualShock4::GetInstance();
  53. if (ds4 == nullptr)
  54. DualShock4::rawMode = true; // set raw mode for future instances if no current instance
  55. else
  56. ds4->SetRawMode(true); // if is a current instance, set raw mode on it (also sets for future instances)
  57. }
  58. else
  59. {
  60. DualShock4* ds4 = DualShock4::GetInstance();
  61. if (ds4 == nullptr)
  62. DualShock4::rawMode = false; // set raw mode for future instances if no current instance
  63. else
  64. ds4->SetRawMode(false); // if is a current instance, set raw mode on it (also sets for future instances)
  65. Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_LEFT", *LeftSideSlideLeft, { "Q" });
  66. Config::BindConfigKeys(configFile.ConfigMap, "LEFT_SIDE_SLIDE_RIGHT", *LeftSideSlideRight, { "E" });
  67. Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_LEFT", *RightSideSlideLeft, { "U" });
  68. Config::BindConfigKeys(configFile.ConfigMap, "RIGHT_SIDE_SLIDE_RIGHT", *RightSideSlideRight, { "O" });
  69. float touchSliderEmulationSpeed = configFile.GetFloatValue("touch_slider_emulation_speed");
  70. if (touchSliderEmulationSpeed != 0.0f)
  71. sliderSpeed = touchSliderEmulationSpeed;
  72. }
  73. }
  74. void TouchSliderEmulator::Update()
  75. {
  76. sliderState->State = SLIDER_OK;
  77. }
  78. void TouchSliderEmulator::UpdateInput()
  79. {
  80. if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || (!enableInMenus && !(*(GameState*)CURRENT_GAME_STATE_ADDRESS == GS_GAME && *(SubGameState*)CURRENT_GAME_SUB_STATE_ADDRESS == SUB_GAME_MAIN)))
  81. return;
  82. if (usePs4OfficialSlider)
  83. {
  84. DualShock4* ds4 = DualShock4::GetInstance();
  85. if (ds4 == nullptr)
  86. return;
  87. Joystick ls = ds4->GetLeftStick();
  88. Joystick rs = ds4->GetRightStick();
  89. uint32_t state = 0;
  90. // DualShock4 normalises sticks to floats -- this undoes that
  91. //printf("left stick: %9.6f, %9.6f, ", ls.XAxis, ls.YAxis);
  92. state |= (uint8_t)((ls.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000; // 0.001 to prevent rounding errors
  93. //printf("%d, ", (int)(state ^ 0b10000000));
  94. state |= ((uint8_t)((ls.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 8;
  95. //printf("%d\n", (int)((state >> 8) ^ 0b10000000));
  96. state |= ((uint8_t)((rs.XAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 16;
  97. state |= ((uint8_t)((rs.YAxis + 1.0 + 0.001) * 127.5) ^ 0b10000000) << 24;
  98. ApplyBitfieldState(state);
  99. }
  100. else
  101. {
  102. sliderIncrement = GetElapsedTime() / sliderSpeed;
  103. constexpr float sensorStep = (1.0f / SLIDER_SENSORS);
  104. EmulateSliderInput(LeftSideSlideLeft, LeftSideSlideRight, ContactPoints[0], 0.0f, 0.5f);
  105. EmulateSliderInput(RightSideSlideLeft, RightSideSlideRight, ContactPoints[1], 0.5f + sensorStep, 1.0f + sensorStep);
  106. sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
  107. for (int i = 0; i < CONTACT_POINTS; i++)
  108. ApplyContactPoint(ContactPoints[i], i);
  109. }
  110. }
  111. void TouchSliderEmulator::OnFocusLost()
  112. {
  113. if (usePs4OfficialSlider)
  114. sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_RAW);
  115. else
  116. sliderState->ResetSensors(TouchSliderState::SENSOR_SET_MODE_SECTIONS);
  117. }
  118. // EmulateSliderInput and ApplyContactPoint are used for analog stick/button slider emulation
  119. void TouchSliderEmulator::EmulateSliderInput(Binding *leftBinding, Binding *rightBinding, ContactPoint &contactPoint, float start, float end)
  120. {
  121. bool leftDown = leftBinding->AnyDown();
  122. bool rightDown = rightBinding->AnyDown();
  123. if (leftDown)
  124. contactPoint.Position -= sliderIncrement;
  125. else if (rightDown)
  126. contactPoint.Position += sliderIncrement;
  127. if (contactPoint.Position < start)
  128. contactPoint.Position = end;
  129. if (contactPoint.Position > end)
  130. contactPoint.Position = start;
  131. bool leftTapped = leftBinding->AnyTapped();
  132. bool rightTapped = rightBinding->AnyTapped();
  133. if (leftTapped || rightTapped)
  134. contactPoint.Position = (start + end) / 2.0f;
  135. contactPoint.InContact = leftDown || rightDown;
  136. }
  137. void TouchSliderEmulator::ApplyContactPoint(ContactPoint& contactPoint, int section)
  138. {
  139. sliderState->SectionTouched[section] = contactPoint.InContact;
  140. int pressure = contactPoint.InContact ? FULL_PRESSURE : NO_PRESSURE;
  141. float position = std::clamp(contactPoint.Position, 0.0f, 1.0f);
  142. if (contactPoint.InContact)
  143. {
  144. int sensor = (int)(position * (SLIDER_SENSORS - 1));
  145. sliderState->SetSensor(sensor, pressure, TouchSliderState::SENSOR_SET_MODE_SECTIONS);
  146. }
  147. constexpr float startRange = -1.0f;
  148. constexpr float endRange = +1.0f;
  149. sliderState->SectionPositions[section] = contactPoint.InContact ? (ConvertRange(0.0f, 1.0f, startRange, endRange, position)) : 0.0f;
  150. }
  151. // ApplyBitfieldState is used for setting raw slider data
  152. void TouchSliderEmulator::ApplyBitfieldState(uint32_t state)
  153. {
  154. for (int i = 0; i < 32; i++)
  155. {
  156. if (state & (1 << (31 - i)))
  157. sliderState->SetSensor(i, FULL_PRESSURE, TouchSliderState::SENSOR_SET_MODE_RAW);
  158. else
  159. sliderState->SetSensor(i, NO_PRESSURE, TouchSliderState::SENSOR_SET_MODE_RAW);
  160. }
  161. }
  162. }