This commit is contained in:
nastys
2019-07-30 13:48:28 +02:00
parent 17b6c02aee
commit d1349cfebe
157 changed files with 0 additions and 0 deletions
@@ -0,0 +1,14 @@
#pragma once
namespace TLAC::Components
{
enum InputBufferType
{
InputBufferType_Tapped,
InputBufferType_Released,
InputBufferType_Down,
InputBufferType_DoubleTapped,
InputBufferType_IntervalTapped,
InputBufferType_Max,
};
}
@@ -0,0 +1,308 @@
#include <iostream>
#include "windows.h"
#include "InputEmulator.h"
#include "../ComponentsManager.h"
#include "../../Constants.h"
#include "../../framework.h"
#include "../../Input/Bindings/KeyboardBinding.h"
#include "../../Input/Bindings/XinputBinding.h"
#include "../../Input/Bindings/MouseBinding.h"
#include "../../Input/Bindings/Ds4Binding.h"
#include "../../Input/KeyConfig/Config.h"
#include "../../Utilities/Operations.h"
#include "../../Utilities/EnumBitwiseOperations.h"
#include "../../FileSystem/ConfigFile.h"
const std::string KEY_CONFIG_FILE_NAME = "keyconfig.ini";
using namespace TLAC::Input;
using namespace TLAC::Input::KeyConfig;
using namespace TLAC::Utilities;
namespace TLAC::Components
{
InputEmulator::InputEmulator()
{
}
InputEmulator::~InputEmulator()
{
delete TestBinding;
delete ServiceBinding;
delete StartBinding;
delete SankakuBinding;
delete ShikakuBinding;
delete BatsuBinding;
delete MaruBinding;
delete LeftBinding;
delete RightBinding;
}
const char* InputEmulator::GetDisplayName()
{
return "input_emulator";
}
void InputEmulator::Initialize(ComponentsManager* manager)
{
componentsManager = manager;
componentsManager->SetIsInputEmulatorUsed(true);
inputState = GetInputStatePtr((void*)INPUT_STATE_PTR_ADDRESS);
inputState->HideCursor();
TestBinding = new Binding();
ServiceBinding = new Binding();
StartBinding = new Binding();
SankakuBinding = new Binding();
ShikakuBinding = new Binding();
BatsuBinding = new Binding();
MaruBinding = new Binding();
LeftBinding = new Binding();
RightBinding = new Binding();
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
configFile.OpenRead();
Config::BindConfigKeys(configFile.ConfigMap, "JVS_TEST", *TestBinding, { "F1" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_SERVICE", *ServiceBinding, { "F2" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_START", *StartBinding, { "Enter" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_TRIANGLE", *SankakuBinding, { "W", "I" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_SQUARE", *ShikakuBinding, { "A", "J" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_CROSS", *BatsuBinding, { "S", "K" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_CIRCLE", *MaruBinding, { "D", "L" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_LEFT", *LeftBinding, { "Q", "U" });
Config::BindConfigKeys(configFile.ConfigMap, "JVS_RIGHT", *RightBinding, { "E", "O" });
mouseScrollPvSelection = configFile.GetBooleanValue("mouse_scroll_pv_selection");
}
void InputEmulator::Update()
{
return;
}
void InputEmulator::OnFocusLost()
{
// to prevent buttons from being "stuck"
inputState->ClearState();
inputState->HideCursor();
}
void InputEmulator::UpdateInput()
{
if (!componentsManager->GetUpdateGameInput())
return;
if (!componentsManager->IsDwGuiActive())
{
UpdateJvsInput();
if (mouseScrollPvSelection && !componentsManager->IsDwGuiHovered())
UpdateMousePvScroll();
}
UpdateDwGuiInput();
}
void InputEmulator::UpdateJvsInput()
{
auto tappedFunc = [](void* binding) { return ((Binding*)binding)->AnyTapped(); };
auto releasedFunc = [](void* binding) { return ((Binding*)binding)->AnyReleased(); };
auto downFunc = [](void* binding) { return ((Binding*)binding)->AnyDown(); };
lastDownState = inputState->Down.Buttons;
inputState->Tapped.Buttons = GetJvsButtonsState(tappedFunc);
inputState->Released.Buttons = GetJvsButtonsState(releasedFunc);
inputState->Down.Buttons = GetJvsButtonsState(downFunc);
inputState->DoubleTapped.Buttons = GetJvsButtonsState(tappedFunc);
inputState->IntervalTapped.Buttons = GetJvsButtonsState(tappedFunc);
UpdateHoldState();
heldButtons = GetButtonFromHold();
if ((lastDownState &= inputState->Tapped.Buttons) != 0)
{
inputState->Down.Buttons ^= inputState->Tapped.Buttons;
if (IsHold() && !TargetInspector::IsAnyRepress())
inputState->Down.Buttons |= heldButtons;
}
// repress held down buttons to not block input
//inputState->Down.Buttons ^= inputState->Tapped.Buttons;
}
HoldState InputEmulator::GetHoldState()
{
return (HoldState) * ((int*)HOLD_STATE_ADDRESS);
}
int InputEmulator::GetMaxHoldState()
{
return *(int*)MAX_HOLD_STATE_ADDRESS;
}
bool InputEmulator::IsHold()
{
return ((holdState != HOLD_NONE) && (GetMaxHoldState() != 1));
}
void InputEmulator::UpdateHoldState()
{
holdState = GetHoldState();
for (int i = 0; i < 4; ++i)
{
int holdId = 1 << (i + 6);
if ((holdId & holdState) != 0)
holdTbl[i] = 1;
else
holdTbl[i] = 0;
}
}
void InputEmulator::UpdateDwGuiInput()
{
auto keyboard = Keyboard::GetInstance();
auto mouse = Mouse::GetInstance();
auto pos = mouse->GetRelativePosition();
inputState->MouseX = (int)pos.x;
inputState->MouseY = (int)pos.y;
auto deltaPos = mouse->GetDeltaPosition();
inputState->MouseDeltaX = (int)deltaPos.x;
inputState->MouseDeltaY = (int)deltaPos.y;
inputState->Key = GetKeyState();
for (int i = 0; i < sizeof(keyBits) / sizeof(KeyBit); i++)
UpdateInputBit(keyBits[i].Bit, keyBits[i].KeyCode);
for (int i = InputBufferType_Tapped; i < InputBufferType_Max; i++)
{
inputState->SetBit(scrollUpBit, mouse->GetIsScrolledUp(), (InputBufferType)i);
inputState->SetBit(scrollDownBit, mouse->GetIsScrolledDown(), (InputBufferType)i);
}
}
void InputEmulator::UpdateMousePvScroll()
{
// I originally wanted to use a MouseBinding set to JVS_LEFT / JVS_RIGHT
// but that ended up being too slow because a PV slot can only be scrolled to once the scroll animation has finished playing
int* slotsToScroll = (int*)PV_SEL_SLOTS_TO_SCROLL;
int* modulesToScroll = (int*)MODULE_SEL_SLOTS_TO_SCROLL;
auto mouse = Mouse::GetInstance();
if (mouse->GetIsScrolledUp())
{
if (*(int*)PV_SEL_SLOTS_CONST < 26) *slotsToScroll -= 1;
if (*(int*)MODULE_IS_RECOMMENDED == 0) *modulesToScroll -= 1;
}
if (mouse->GetIsScrolledDown())
{
if (*(int*)PV_SEL_SLOTS_CONST < 26) *slotsToScroll += 1;
if (*(int*)MODULE_IS_RECOMMENDED == 0) *modulesToScroll += 1;
}
}
InputState* InputEmulator::GetInputStatePtr(void* address)
{
return (InputState*)(*(uint64_t*)address);
}
JvsButtons InputEmulator::GetJvsButtonsState(bool(*buttonTestFunc)(void*))
{
JvsButtons buttons = JVS_NONE;
if (buttonTestFunc(TestBinding))
buttons |= JVS_TEST;
if (buttonTestFunc(ServiceBinding))
buttons |= JVS_SERVICE;
if (buttonTestFunc(StartBinding))
buttons |= JVS_START;
if (buttonTestFunc(SankakuBinding))
buttons |= JVS_TRIANGLE;
if (buttonTestFunc(ShikakuBinding))
buttons |= JVS_SQUARE;
if (buttonTestFunc(BatsuBinding))
buttons |= JVS_CROSS;
if (buttonTestFunc(MaruBinding))
buttons |= JVS_CIRCLE;
if (buttonTestFunc(LeftBinding))
buttons |= JVS_L;
if (buttonTestFunc(RightBinding))
buttons |= JVS_R;
return buttons;
}
JvsButtons InputEmulator::GetButtonFromHold()
{
JvsButtons buttons = JVS_NONE;
if (holdTbl[0])
buttons |= JVS_TRIANGLE;
if (holdTbl[1])
buttons |= JVS_CIRCLE;
if (holdTbl[2])
buttons |= JVS_CROSS;
if (holdTbl[3])
buttons |= JVS_SQUARE;
return buttons;
}
char InputEmulator::GetKeyState()
{
auto keyboard = Keyboard::GetInstance();
bool upper = keyboard->IsDown(VK_SHIFT);
constexpr char caseDifference = 'A' - 'a';
char inputKey = 0x00;
for (char key = '0'; key < 'Z'; key++)
{
if (keyboard->IsIntervalTapped(key))
inputKey = (upper || key < 'A') ? key : (key - caseDifference);
}
if (keyboard->IsIntervalTapped(VK_BACK))
inputKey = 0x08;
if (keyboard->IsIntervalTapped(VK_TAB))
inputKey = 0x09;
if (keyboard->IsIntervalTapped(VK_SPACE))
inputKey = 0x20;
if (keyboard->IsIntervalTapped(VK_ESCAPE))
exit(0);
return inputKey;
}
void InputEmulator::UpdateInputBit(uint32_t bit, uint8_t keycode)
{
auto keyboard = Keyboard::GetInstance();
inputState->SetBit(bit, keyboard->IsTapped(keycode), InputBufferType_Tapped);
inputState->SetBit(bit, keyboard->IsReleased(keycode), InputBufferType_Released);
inputState->SetBit(bit, keyboard->IsDown(keycode), InputBufferType_Down);
inputState->SetBit(bit, keyboard->IsDoubleTapped(keycode), InputBufferType_DoubleTapped);
inputState->SetBit(bit, keyboard->IsIntervalTapped(keycode), InputBufferType_IntervalTapped);
}
}
@@ -0,0 +1,102 @@
#pragma once
#include <functional>
#include <Windows.h>
#include "InputState.h"
#include "../EmulatorComponent.h"
#include "../../Input/Bindings/Binding.h"
#include "../GameTargets/TargetTypes.h"
#include "../GameTargets/TargetHitStates.h"
#include "../GameTargets/HoldState.h"
#include "../GameTargets/TargetInspector.h"
namespace TLAC::Components
{
struct KeyBit
{
uint32_t Bit;
uint8_t KeyCode;
};
class InputEmulator : public EmulatorComponent
{
public:
Input::Binding* TestBinding;
Input::Binding* ServiceBinding;
Input::Binding* StartBinding;
Input::Binding* SankakuBinding;
Input::Binding* ShikakuBinding;
Input::Binding* BatsuBinding;
Input::Binding* MaruBinding;
Input::Binding* LeftBinding;
Input::Binding* RightBinding;
InputEmulator();
~InputEmulator();
virtual const char* GetDisplayName() override;
virtual void Initialize(ComponentsManager*) override;
virtual void Update() override;
virtual void UpdateInput() override;
virtual void OnFocusLost() override;
private:
ComponentsManager* componentsManager;
bool mouseScrollPvSelection = false;
const uint32_t scrollUpBit = 99;
const uint32_t scrollDownBit = 100;
KeyBit keyBits[20] =
{
{ 5, VK_LEFT },
{ 6, VK_RIGHT },
{ 29, VK_SPACE },
{ 39, 'A' },
{ 43, 'E' },
{ 42, 'D' },
{ 55, 'Q' },
{ 57, 'S' }, // unsure
{ 61, 'W' },
{ 63, 'Y' },
{ 84, 'L' }, // unsure
{ 80, VK_RETURN },
{ 81, VK_SHIFT },
{ 82, VK_CONTROL },
{ 83, VK_MENU },
{ 91, VK_UP },
{ 93, VK_DOWN },
{ 96, MK_LBUTTON },
{ 97, VK_MBUTTON },
{ 98, MK_RBUTTON },
};
InputState* inputState;
JvsButtons lastDownState;
JvsButtons heldButtons;
int holdTbl[4];
HoldState holdState;
void UpdateJvsInput();
void UpdateDwGuiInput();
void UpdateMousePvScroll();
void UpdateHoldState();
InputState* GetInputStatePtr(void* address);
JvsButtons GetJvsButtonsState(bool(*buttonTestFunc)(void*));
JvsButtons GetButtonFromHold();
char GetKeyState();
HoldState GetHoldState();
int GetMaxHoldState();
bool IsHold();
void UpdateInputBit(uint32_t bit, uint8_t keycode);
};
}
@@ -0,0 +1,58 @@
#include "InputState.h"
#include <windows.h>
#include <stdio.h>
namespace TLAC::Components
{
void InputState::ClearState()
{
memset(this, 0, sizeof(InputState));
}
void InputState::HideCursor()
{
MouseX = INT32_MIN;
MouseY = INT32_MIN;
MouseDeltaX = 0;
MouseDeltaY = 0;
}
void InputState::SetBit(uint32_t bit, bool value, InputBufferType inputType)
{
uint8_t* data = GetInputBuffer(inputType);
if (data == nullptr || bit < 0 || bit >= MAX_BUTTON_BIT)
return;
int byteIndex = (bit / 8);
int bitIndex = (bit % 8);
BYTE mask = (1 << bitIndex);
data[byteIndex] = value ? (data[byteIndex] | mask) : (data[byteIndex] & ~mask);
}
uint8_t* InputState::GetInputBuffer(InputBufferType inputType)
{
switch (inputType)
{
case InputBufferType_Tapped:
return (uint8_t*)&Tapped;
case InputBufferType_Released:
return (uint8_t*)&Released;
case InputBufferType_Down:
return (uint8_t*)&Down;
case InputBufferType_DoubleTapped:
return (uint8_t*)&DoubleTapped;
case InputBufferType_IntervalTapped:
return (uint8_t*)&IntervalTapped;
default:
return nullptr;
}
}
}
@@ -0,0 +1,47 @@
#pragma once
#include "JvsButtons.h"
#include "InputBufferType.h"
namespace TLAC::Components
{
const int MAX_BUTTON_BIT = 0x6F;
// The button state is larger than the size of a register
// but only the first 32 bits are used during normal gameplay
// so this will provide the convenience of still being able to access them through a bit field
union ButtonState
{
JvsButtons Buttons;
uint32_t State[4];
};
// total sizeof() == 0x20E0
struct InputState
{
ButtonState Tapped;
ButtonState Released;
ButtonState Down;
uint32_t Padding_20[4];
ButtonState DoubleTapped;
uint32_t Padding_30[4];
ButtonState IntervalTapped;
uint32_t Padding_38[12];
int32_t MouseX;
int32_t MouseY;
int32_t MouseDeltaX;
int32_t MouseDeltaY;
uint32_t Padding_AC[8];
uint8_t Padding_D0[3];
char Key;
void ClearState();
void HideCursor();
void SetBit(uint32_t bit, bool value, InputBufferType inputType);
uint8_t* GetInputBuffer(InputBufferType inputType);
};
}
@@ -0,0 +1,24 @@
#pragma once
#include <stdint.h>
namespace TLAC::Components
{
enum JvsButtons : uint32_t
{
JVS_NONE = 0 << 0x00, // 0x0
JVS_TEST = 1 << 0x00, // 0x1
JVS_SERVICE = 1 << 0x01, // 0x2
JVS_START = 1 << 0x02, // 0x4
JVS_TRIANGLE = 1 << 0x07, // 0x80
JVS_SQUARE = 1 << 0x08, // 0x100
JVS_CROSS = 1 << 0x09, // 0x200
JVS_CIRCLE = 1 << 0x0A, // 0x400
JVS_L = 1 << 0x0B, // 0x800
JVS_R = 1 << 0x0C, // 0x1000
JVS_SW1 = 1 << 0x12, // 0x40000
JVS_SW2 = 1 << 0x13, // 0x80000
};
}
@@ -0,0 +1,59 @@
#include "TouchPanelEmulator.h"
#include <iostream>
#include "../ComponentsManager.h"
#include "../../Constants.h"
#include "../../Input/Mouse/Mouse.h"
#include "../../Input/Keyboard/Keyboard.h"
using namespace TLAC::Input;
namespace TLAC::Components
{
TouchPanelEmulator::TouchPanelEmulator()
{
}
TouchPanelEmulator::~TouchPanelEmulator()
{
}
const char* TouchPanelEmulator::GetDisplayName()
{
return "touch_panel_emulator";
}
void TouchPanelEmulator::Initialize(ComponentsManager* manager)
{
componentsManager = manager;
state = GetTouchStatePtr((void*)TASK_TOUCH_ADDRESS);
}
void TouchPanelEmulator::Update()
{
state->ConnectionState = 1;
}
void TouchPanelEmulator::UpdateInput()
{
if (!componentsManager->GetUpdateGameInput() || componentsManager->IsDwGuiActive() || componentsManager->IsDwGuiHovered())
return;
// TODO: rescale TouchReaction aet position
auto keyboard = Keyboard::GetInstance();
auto pos = Mouse::GetInstance()->GetRelativePosition();
state->XPosition = (float)pos.x;
state->YPosition = (float)pos.y;
bool down = keyboard->IsDown(VK_LBUTTON);
bool released = keyboard->IsReleased(VK_LBUTTON);
state->ContactType = (down ? 0x2 : released ? 0x1 : 0x0);
state->Pressure = (float)(state->ContactType != 0);
}
TouchPanelState* TouchPanelEmulator::GetTouchStatePtr(void *address)
{
return (TouchPanelState*)address;
}
}
@@ -0,0 +1,26 @@
#pragma once
#include "../EmulatorComponent.h"
#include "TouchPanelState.h"
namespace TLAC::Components
{
class TouchPanelEmulator : public EmulatorComponent
{
public:
TouchPanelEmulator();
~TouchPanelEmulator();
virtual const char* GetDisplayName() override;
virtual void Initialize(ComponentsManager*) override;
virtual void Update() override;
virtual void UpdateInput() override;
private:
ComponentsManager* componentsManager;
TouchPanelState* state;
TouchPanelState* GetTouchStatePtr(void *address);
};
}
@@ -0,0 +1,15 @@
#pragma once
namespace TLAC::Components
{
struct TouchPanelState
{
int Padding00[0x1E];
int ConnectionState;
int Padding01[0x06];
float XPosition;
float YPosition;
float Pressure;
int ContactType;
};
}
@@ -0,0 +1,138 @@
#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 "../../FileSystem/ConfigFile.h"
#include "../../Utilities/Math.h"
#include <algorithm>
#include <stdio.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()
{
}
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;
LeftSideSlideLeft = new Binding();
LeftSideSlideRight = new Binding();
RightSideSlideLeft = new Binding();
RightSideSlideRight = new Binding();
FileSystem::ConfigFile configFile(framework::GetModuleDirectory(), KEY_CONFIG_FILE_NAME);
configFile.OpenRead();
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())
return;
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();
for (int i = 0; i < CONTACT_POINTS; i++)
ApplyContactPoint(ContactPoints[i], i);
}
void TouchSliderEmulator::OnFocusLost()
{
sliderState->ResetSensors();
}
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);
}
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;
}
}
@@ -0,0 +1,49 @@
#pragma once
#include "../EmulatorComponent.h"
#include "TouchSliderState.h"
#include "../../Input/Bindings/Binding.h"
namespace TLAC::Components
{
constexpr int SLIDER_INPUTS = 4;
constexpr int CONTACT_POINTS = 2;
struct ContactPoint
{
float Position;
bool InContact;
};
class TouchSliderEmulator : public EmulatorComponent
{
public:
Input::Binding* LeftSideSlideLeft;
Input::Binding* LeftSideSlideRight;
Input::Binding* RightSideSlideLeft;
Input::Binding* RightSideSlideRight;
TouchSliderEmulator();
~TouchSliderEmulator();
virtual const char* GetDisplayName() override;
virtual void Initialize(ComponentsManager*) override;
virtual void Update() override;
virtual void UpdateInput() override;
virtual void OnFocusLost() override;
private:
ComponentsManager* componentsManager;
float sliderSpeed = 750.0f;
float sliderIncrement;
TouchSliderState *sliderState;
ContactPoint ContactPoints[CONTACT_POINTS];
void EmulateSliderInput(Input::Binding *leftBinding, Input::Binding *rightBinding, ContactPoint &contactPoint, float start, float end);
void ApplyContactPoint(ContactPoint &contactPoint, int section);
};
}
@@ -0,0 +1,19 @@
#include "TouchSliderState.h"
namespace TLAC::Components
{
void TouchSliderState::SetSensor(int index, int value)
{
if (index < 0 || index >= SLIDER_SENSORS)
return;
SensorPressureLevels[index] = value;
SensorTouched[index].IsTouched = value > 0;
}
void TouchSliderState::ResetSensors()
{
for (int i = 0; i < SLIDER_SENSORS; i++)
SetSensor(i, NO_PRESSURE);
}
}
@@ -0,0 +1,43 @@
#pragma once
#include <stdint.h>
#define SLIDER_OK 3
#define SLIDER_SECTIONS 4
#define SLIDER_SENSORS 32
#define NO_PRESSURE 0
#define FULL_PRESSURE 180
namespace TLAC::Components
{
struct TouchSliderState
{
uint8_t Padding0000[112];
int32_t State;
uint8_t Padding0074[20 + 12];
int32_t SensorPressureLevels[SLIDER_SENSORS];
uint8_t Padding0108[52 - 12];
float SectionPositions[SLIDER_SECTIONS];
int SectionConnections[SLIDER_SECTIONS];
uint8_t Padding015C[4];
bool SectionTouched[SLIDER_SECTIONS];
uint8_t Padding013C[3128 - 52 - 40];
struct
{
uint8_t Padding00[2];
bool IsTouched;
uint8_t Padding[45];
} SensorTouched[SLIDER_SENSORS];
void SetSensor(int index, int value);
void ResetSensors();
};
}