implementation of joycon pair

This commit is contained in:
minenice55 2024-02-02 23:55:54 -05:00
parent acc33e5a90
commit d5d6d73eca
4 changed files with 301 additions and 49 deletions

View file

@ -56,199 +56,369 @@ namespace HeavenStudio.InputSystem
{ {
public class InputJoyconPair : InputController public class InputJoyconPair : InputController
{ {
static readonly string[] nsConButtonNames = new[]
{
"Up",
"Down",
"Left",
"Right",
"Plus",
"Minus",
"Left Stick Click",
"Right Stick Click",
"L",
"R",
"ZL",
"ZR",
"B",
"A",
"Y",
"X",
"Home",
"Capture",
"", // mic on playstation, unused here
"SL",
"SR",
"Stick Up",
"Stick Down",
"Stick Left",
"Stick Right",
};
static int[] defaultMappings
{
get
{
return new[]
{
ButtonMaskUp,
ButtonMaskDown,
ButtonMaskLeft,
ButtonMaskRight,
ButtonMaskS,
ButtonMaskE,
ButtonMaskW,
ButtonMaskN,
ButtonMaskL,
ButtonMaskR,
ButtonMaskPlus,
-1
};
}
}
InputJoyshock leftController, rightController;
bool pairIsPossible = false;
public void SetLeftController(InputJoyshock leftController)
{
this.leftController = leftController;
}
public void SetRightController(InputJoyshock rightController)
{
this.rightController = rightController;
}
public bool HasControllers()
{
return leftController != null && rightController != null;
}
public override bool GetAction(ControlStyles style, int action) public override bool GetAction(ControlStyles style, int action)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return false;
}
return leftController.GetAction(style, action) || rightController.GetAction(style, action);
} }
public override bool GetActionDown(ControlStyles style, int action, out double dt) public override bool GetActionDown(ControlStyles style, int action, out double dt)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
dt = 0;
return false;
}
return leftController.GetActionDown(style, action, out dt) || rightController.GetActionDown(style, action, out dt);
} }
public override bool GetActionUp(ControlStyles style, int action, out double dt) public override bool GetActionUp(ControlStyles style, int action, out double dt)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
dt = 0;
return false;
}
return leftController.GetActionUp(style, action, out dt) || rightController.GetActionUp(style, action, out dt);
} }
public override float GetAxis(InputAxis axis) public override float GetAxis(InputAxis axis)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return 0;
}
return leftController.GetAxis(axis) + rightController.GetAxis(axis);
} }
public override int GetBindingsVersion() public override int GetBindingsVersion()
{ {
throw new NotImplementedException(); return 0;
} }
public override string[] GetButtonNames() public override string[] GetButtonNames()
{ {
throw new NotImplementedException(); return nsConButtonNames;
} }
public override ControlBindings GetCurrentBindings() public override ControlBindings GetCurrentBindings()
{ {
throw new NotImplementedException(); return currentBindings;
} }
public override bool GetCurrentStyleSupported() public override bool GetCurrentStyleSupported()
{ {
throw new NotImplementedException(); return PlayerInput.CurrentControlStyle is ControlStyles.Pad; // or ControlStyles.Baton
} }
public override ControlBindings GetDefaultBindings() public override ControlBindings GetDefaultBindings()
{ {
throw new NotImplementedException(); ControlBindings binds = new ControlBindings
{
Pad = defaultMappings,
version = GetBindingsVersion(),
PointerSensitivity = 3
};
return binds;
} }
public override ControlStyles GetDefaultStyle() public override ControlStyles GetDefaultStyle()
{ {
throw new NotImplementedException(); return ControlStyles.Pad;
} }
public override string GetDeviceName() public override string GetDeviceName()
{ {
throw new NotImplementedException(); return "Joy-Con Pair";
} }
public override InputFeatures GetFeatures() public override InputFeatures GetFeatures()
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return 0;
}
InputFeatures features = leftController.GetFeatures() | rightController.GetFeatures();
return features;
} }
public override bool GetFlick(out double dt) public override bool GetFlick(out double dt)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
dt = 0;
return false;
}
return leftController.GetFlick(out dt) || rightController.GetFlick(out dt);
} }
public override bool GetHatDirection(InputDirection direction) public override bool GetHatDirection(InputDirection direction)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return false;
}
return leftController.GetHatDirection(direction) || rightController.GetHatDirection(direction);
} }
public override bool GetHatDirectionDown(InputDirection direction, out double dt) public override bool GetHatDirectionDown(InputDirection direction, out double dt)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
dt = 0;
return false;
}
return leftController.GetHatDirectionDown(direction, out dt) || rightController.GetHatDirectionDown(direction, out dt);
} }
public override bool GetHatDirectionUp(InputDirection direction, out double dt) public override bool GetHatDirectionUp(InputDirection direction, out double dt)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
dt = 0;
return false;
}
return leftController.GetHatDirectionUp(direction, out dt) || rightController.GetHatDirectionUp(direction, out dt);
} }
public override bool GetIsActionUnbindable(int action, ControlStyles style) public override bool GetIsActionUnbindable(int action, ControlStyles style)
{ {
throw new NotImplementedException(); return false;
} }
public override bool GetIsConnected() public override bool GetIsConnected()
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return false;
}
return leftController.GetIsConnected() && rightController.GetIsConnected();
} }
public override bool GetIsPoorConnection() public override bool GetIsPoorConnection()
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return false;
}
return leftController.GetIsPoorConnection() || rightController.GetIsPoorConnection();
} }
public override int GetLastActionDown() public override int GetLastActionDown()
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return -1;
}
return Math.Max(leftController.GetLastActionDown(), rightController.GetLastActionDown());
} }
public override int GetLastButtonDown(bool strict = false) public override int GetLastButtonDown(bool strict = false)
{ {
throw new NotImplementedException(); if (strict || leftController == null || rightController == null)
{
return -1;
}
return Math.Max(leftController.GetLastButtonDown(strict), rightController.GetLastButtonDown(strict));
} }
public override int? GetPlayer() public override int? GetPlayer()
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return null;
}
return playerNum;
} }
public override Vector2 GetPointer() public override Vector2 GetPointer()
{ {
throw new NotImplementedException(); Camera cam = GameManager.instance.CursorCam;
Vector3 rawPointerPos = Input.mousePosition;
rawPointerPos.z = Mathf.Abs(cam.gameObject.transform.position.z);
return cam.ScreenToWorldPoint(rawPointerPos);
} }
public override bool GetPointerLeftRight() public override bool GetPointerLeftRight()
{ {
throw new NotImplementedException(); return false;
} }
public override bool GetSlide(out double dt) public override bool GetSlide(out double dt)
{ {
throw new NotImplementedException(); dt = 0;
return false;
} }
public override bool GetSqueeze() public override bool GetSqueeze()
{ {
throw new NotImplementedException(); return false;
} }
public override bool GetSqueezeDown(out double dt) public override bool GetSqueezeDown(out double dt)
{ {
throw new NotImplementedException(); dt = 0;
return false;
} }
public override bool GetSqueezeUp(out double dt) public override bool GetSqueezeUp(out double dt)
{ {
throw new NotImplementedException(); dt = 0;
return false;
} }
public override Vector3 GetVector(InputVector vector) public override Vector3 GetVector(InputVector vector)
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return Vector3.zero;
}
return leftController.GetVector(vector) + rightController.GetVector(vector);
} }
public override void InitializeController() public override void InitializeController()
{ {
throw new NotImplementedException(); leftController = null;
rightController = null;
} }
public override void OnSelected() public override void OnSelected()
{ {
throw new NotImplementedException(); if (leftController == null || rightController == null)
{
return;
}
leftController.OnSelected();
leftController.SetRotatedStickMode(false);
rightController.OnSelected();
rightController.SetRotatedStickMode(false);
}
async void SelectionVibrate(int handle)
{
JslSetRumbleFrequency(handle, 0.5f, 0.5f, 80f, 160f);
await Task.Delay(100);
JslSetRumbleFrequency(handle, 0f, 0f, 160f, 320f);
} }
public override void RecentrePointer() public override void RecentrePointer()
{ {
throw new NotImplementedException();
} }
public override void ResetBindings() public override void ResetBindings()
{ {
throw new NotImplementedException(); currentBindings = GetDefaultBindings();
} }
public override void SetCurrentBindings(ControlBindings newBinds) public override void SetCurrentBindings(ControlBindings newBinds)
{ {
throw new NotImplementedException(); currentBindings = newBinds;
} }
public override void SetMaterialProperties(Material m) public override void SetMaterialProperties(Material m)
{ {
throw new NotImplementedException(); Color colour;
m.SetColor("_BodyColor", ColorUtility.TryParseHtmlString("#2F353A", out colour) ? colour : Color.white);
m.SetColor("_BtnColor", ColorUtility.TryParseHtmlString("#2F353A", out colour) ? colour : Color.white);
m.SetColor("_LGripColor", leftController.GetBodyColor());
m.SetColor("_RGripColor", rightController.GetBodyColor());
} }
public override void SetPlayer(int? playerNum) public override void SetPlayer(int? playerNum)
{ {
throw new NotImplementedException(); if (leftController != null)
{
leftController.SetPlayer(playerNum);
}
if (rightController != null)
{
rightController.SetPlayer(playerNum);
}
} }
public override void TogglePointerLock(bool locked) public override void TogglePointerLock(bool locked)
{ {
throw new NotImplementedException();
} }
public override ControlBindings UpdateBindings(ControlBindings lastBinds) public override ControlBindings UpdateBindings(ControlBindings lastBinds)
{ {
throw new NotImplementedException(); return lastBinds;
} }
public override void UpdateState() public override void UpdateState()
{ {
throw new NotImplementedException();
} }
} }
} }

View file

@ -11,14 +11,25 @@ namespace HeavenStudio.InputSystem.Loaders
{ {
public static class InputJoyshockInitializer public static class InputJoyshockInitializer
{ {
static bool failedJsl = false;
[LoadOrder(2)] [LoadOrder(2)]
public static InputController[] Initialize() public static InputController[] Initialize()
{ {
failedJsl = false;
InputJoyshock.joyshocks = new(); InputJoyshock.joyshocks = new();
PlayerInput.PlayerInputCleanUp += DisposeJoyshocks; PlayerInput.PlayerInputCleanUp += DisposeJoyshocks;
PlayerInput.PlayerInputRefresh.Add(Refresh); PlayerInput.PlayerInputRefresh.Add(Refresh);
try
{
InputJoyshock.JslEventInit(); InputJoyshock.JslEventInit();
}
catch (Exception e)
{
Debug.LogError("Failed to initialize JoyShockLibrary: " + e.Message);
failedJsl = true;
return null;
}
InputController[] controllers; InputController[] controllers;
int jslDevicesFound = 0; int jslDevicesFound = 0;
@ -57,16 +68,18 @@ namespace HeavenStudio.InputSystem.Loaders
public static void DisposeJoyshocks() public static void DisposeJoyshocks()
{ {
if (failedJsl) return;
foreach (InputJoyshock joyshock in InputJoyshock.joyshocks.Values) foreach (InputJoyshock joyshock in InputJoyshock.joyshocks.Values)
{ {
joyshock.CleanUp(); joyshock.CleanUp();
} }
JslSetCallback(null);
JslDisconnectAndDisposeAll(); JslDisconnectAndDisposeAll();
JslSetCallback(null);
} }
public static InputController[] Refresh() public static InputController[] Refresh()
{ {
if (failedJsl) return null;
InputJoyshock.joyshocks.Clear(); InputJoyshock.joyshocks.Clear();
InputController[] controllers; InputController[] controllers;
int jslDevicesFound = 0; int jslDevicesFound = 0;
@ -299,6 +312,7 @@ namespace HeavenStudio.InputSystem
int lightbarColour; int lightbarColour;
string joyshockName; string joyshockName;
DateTime startTime; DateTime startTime;
bool joyConWantRotatedStick;
//buttons, sticks, triggers //buttons, sticks, triggers
JoyshockButtonState[] actionStates = new JoyshockButtonState[BINDS_MAX]; JoyshockButtonState[] actionStates = new JoyshockButtonState[BINDS_MAX];
@ -471,6 +485,25 @@ namespace HeavenStudio.InputSystem
xAxis = joyBtStateCurrent.stickLX; xAxis = joyBtStateCurrent.stickLX;
yAxis = joyBtStateCurrent.stickLY; yAxis = joyBtStateCurrent.stickLY;
if (joyConWantRotatedStick && splitType != SplitFull)
{
float tempX = xAxis;
float tempY = yAxis;
switch (splitType)
{
case SplitLeft:
xAxis = -tempY;
yAxis = tempX;
break;
case SplitRight:
xAxis = joyBtStateCurrent.stickRX;
yAxis = joyBtStateCurrent.stickRY;
xAxis = tempY;
yAxis = -tempX;
break;
}
}
directionStateLast = directionStateCurrent; directionStateLast = directionStateCurrent;
directionStateCurrent = 0; directionStateCurrent = 0;
directionStateCurrent |= ((yAxis >= stickDeadzone) ? (1 << ((int)InputDirection.Up)) : 0); directionStateCurrent |= ((yAxis >= stickDeadzone) ? (1 << ((int)InputDirection.Up)) : 0);
@ -484,6 +517,7 @@ namespace HeavenStudio.InputSystem
public override void OnSelected() public override void OnSelected()
{ {
SetRotatedStickMode(true);
Task.Run(() => SelectionVibrate()); Task.Run(() => SelectionVibrate());
} }
@ -570,7 +604,7 @@ namespace HeavenStudio.InputSystem
break; break;
} }
binds.PointerSensitivity = 3; binds.PointerSensitivity = 3;
binds.version = 1; binds.version = GetBindingsVersion();
return binds; return binds;
} }
@ -864,6 +898,11 @@ namespace HeavenStudio.InputSystem
return type; return type;
} }
public void SetRotatedStickMode(bool rotated)
{
joyConWantRotatedStick = rotated;
}
public void SetLightbarColour(Color color) public void SetLightbarColour(Color color)
{ {
lightbarColour = BitwiseUtils.RgbToInt(color); lightbarColour = BitwiseUtils.RgbToInt(color);

View file

@ -83,7 +83,6 @@ namespace {context.TargetClass.Namespace}
string fullMethodLabel = $"{callingClass}.{method}"; string fullMethodLabel = $"{callingClass}.{method}";
sb.Append($@" sb.Append($@"
Debug.Log(""Running game loader {callingClass}"");
game = {fullMethodLabel}(eventCaller); game = {fullMethodLabel}(eventCaller);
if (game != null) if (game != null)
{{ {{

View file

@ -113,9 +113,32 @@ namespace HeavenStudio.Editor
} }
} }
} }
// else if (isPairSearching) else if (currentController is InputJoyconPair)
// { {
// } InputJoyconPair pair = (InputJoyconPair)currentController;
if (!pair.HasControllers())
{
List<InputJoyshock> controllers = PlayerInput.GetInputControllers()
.Select(x => x as InputJoyshock)
.Where(x => x != null && x.GetJoyshockType() is TypeJoyConLeft or TypeJoyConRight)
.ToList();
foreach (var possibleController in controllers)
{
if (possibleController.GetLastButtonDown(true) == ButtonMaskZL && possibleController.GetJoyshockType() is TypeJoyConLeft)
{
pair.SetLeftController(possibleController);
}
else if (possibleController.GetLastButtonDown(true) == ButtonMaskZR && possibleController.GetJoyshockType() is TypeJoyConRight)
{
pair.SetRightController(possibleController);
}
}
if (pair.HasControllers())
{
pairSearchItem.SetActive(false);
}
}
}
} }
} }
@ -179,6 +202,17 @@ namespace HeavenStudio.Editor
stylesDropdown.SetValueWithoutNotify((int)PlayerInput.CurrentControlStyle); stylesDropdown.SetValueWithoutNotify((int)PlayerInput.CurrentControlStyle);
} }
newController.OnSelected();
if (newController is InputJoyconPair)
{
pairSearchItem.SetActive(true);
}
else
{
pairSearchItem.SetActive(false);
}
UpdateControlStyleMapping(); UpdateControlStyleMapping();
ShowControllerBinds(newController); ShowControllerBinds(newController);
ShowControllerIcon(newController); ShowControllerIcon(newController);
@ -197,7 +231,12 @@ namespace HeavenStudio.Editor
public void StartBindSingle(int bt) public void StartBindSingle(int bt)
{ {
CancelBind(); CancelBind();
if (PlayerInput.GetInputController(1).GetIsActionUnbindable(bt, PlayerInput.CurrentControlStyle)) InputController currentController = PlayerInput.GetInputController(1);
if (currentController.GetIsActionUnbindable(bt, PlayerInput.CurrentControlStyle))
{
return;
}
if (currentController is InputJoyconPair && !(currentController as InputJoyconPair).HasControllers())
{ {
return; return;
} }
@ -220,9 +259,14 @@ namespace HeavenStudio.Editor
public void StartBindAll() public void StartBindAll()
{ {
CancelBind(); CancelBind();
InputController currentController = PlayerInput.GetInputController(1);
if (currentController is InputJoyconPair && !(currentController as InputJoyconPair).HasControllers())
{
return;
}
bindAllMode = true; bindAllMode = true;
currentBindingBt = -1; currentBindingBt = -1;
AdvanceAutoBind(PlayerInput.GetInputController(1)); AdvanceAutoBind(currentController);
} }
public void CancelBind() public void CancelBind()