2014-03-28 02:50:40 +01:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
2014-09-02 01:23:02 +02:00
|
|
|
|
using System.Drawing;
|
2015-02-08 22:51:52 +01:00
|
|
|
|
|
|
|
|
|
namespace DS4Windows
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{
|
2014-06-02 05:19:04 +02:00
|
|
|
|
public class DS4LightBar
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{
|
|
|
|
|
private readonly static byte[/* Light On duration */, /* Light Off duration */] BatteryIndicatorDurations =
|
|
|
|
|
{
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{ 0, 0 }, // 0 is for "charging" OR anything sufficiently-"charged"
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{ 28, 252 },
|
|
|
|
|
{ 56, 224 },
|
|
|
|
|
{ 84, 196 },
|
|
|
|
|
{ 112, 168 },
|
|
|
|
|
{ 140, 140 },
|
|
|
|
|
{ 168, 112 },
|
|
|
|
|
{ 196, 84 },
|
|
|
|
|
{ 224, 56}, // on 80% of the time at 80, etc.
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{ 252, 28 } // on 90% of the time at 90
|
2014-03-28 02:50:40 +01:00
|
|
|
|
};
|
2014-06-02 19:29:38 +02:00
|
|
|
|
static double[] counters = new double[4] { 0, 0, 0, 0 };
|
|
|
|
|
public static double[] fadetimer = new double[4] { 0, 0, 0, 0 };
|
|
|
|
|
static bool[] fadedirection = new bool[4] { false, false, false, false };
|
2014-05-23 04:42:07 +02:00
|
|
|
|
static DateTime oldnow = DateTime.UtcNow;
|
2014-12-02 01:07:29 +01:00
|
|
|
|
public static bool[] forcelight = new bool[4] { false, false, false, false };
|
|
|
|
|
public static DS4Color[] forcedColor = new DS4Color[4];
|
|
|
|
|
public static byte[] forcedFlash = new byte[4];
|
2014-10-31 00:56:51 +01:00
|
|
|
|
public static void updateLightBar(DS4Device device, int deviceNum, DS4State cState, DS4StateExposed eState, Mouse tp)
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{
|
2014-06-02 05:19:04 +02:00
|
|
|
|
DS4Color color;
|
2014-12-02 01:07:29 +01:00
|
|
|
|
if (!defualtLight && !forcelight[deviceNum])
|
2014-06-02 05:19:04 +02:00
|
|
|
|
{
|
2015-02-08 22:51:52 +01:00
|
|
|
|
if (Global.ShiftColorOn[deviceNum] && Global.ShiftModifier[deviceNum] > 0 && shiftMod(device, deviceNum, cState, eState, tp))
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.ShiftColor[deviceNum];
|
2014-04-30 21:32:44 +02:00
|
|
|
|
}
|
2014-07-26 01:17:45 +02:00
|
|
|
|
else
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{
|
2015-02-08 22:51:52 +01:00
|
|
|
|
if (Global.Rainbow[deviceNum] > 0)
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{// Display rainbow
|
|
|
|
|
DateTime now = DateTime.UtcNow;
|
|
|
|
|
if (now >= oldnow + TimeSpan.FromMilliseconds(10)) //update by the millisecond that way it's a smooth transtion
|
2014-06-02 05:19:04 +02:00
|
|
|
|
{
|
2014-07-26 01:17:45 +02:00
|
|
|
|
oldnow = now;
|
|
|
|
|
if (device.Charging)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
counters[deviceNum] -= 1.5 * 3 / Global.Rainbow[deviceNum];
|
2014-07-26 01:17:45 +02:00
|
|
|
|
else
|
2015-02-08 22:51:52 +01:00
|
|
|
|
counters[deviceNum] += 1.5 * 3 / Global.Rainbow[deviceNum];
|
2014-07-26 01:17:45 +02:00
|
|
|
|
}
|
|
|
|
|
if (counters[deviceNum] < 0)
|
|
|
|
|
counters[deviceNum] = 180000;
|
2015-02-08 22:51:52 +01:00
|
|
|
|
if (counters[deviceNum] > 180000)
|
|
|
|
|
counters[deviceNum] = 0;
|
|
|
|
|
if (Global.LedAsBatteryIndicator[deviceNum])
|
2014-07-26 01:17:45 +02:00
|
|
|
|
color = HuetoRGB((float)counters[deviceNum] % 360, (byte)(2.55 * device.Battery));
|
|
|
|
|
else
|
|
|
|
|
color = HuetoRGB((float)counters[deviceNum] % 360, 255);
|
2014-03-28 02:50:40 +01:00
|
|
|
|
|
2014-07-26 01:17:45 +02:00
|
|
|
|
}
|
2015-02-08 22:51:52 +01:00
|
|
|
|
else if (Global.LedAsBatteryIndicator[deviceNum])
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{
|
|
|
|
|
//if (device.Charging == false || device.Battery >= 100) // when charged, don't show the charging animation
|
2014-06-02 05:19:04 +02:00
|
|
|
|
{
|
2015-02-08 22:51:52 +01:00
|
|
|
|
DS4Color fullColor = Global.MainColor[deviceNum];
|
|
|
|
|
DS4Color lowColor = Global.LowColor[deviceNum];
|
2014-03-28 02:50:40 +01:00
|
|
|
|
|
2014-07-26 01:17:45 +02:00
|
|
|
|
color = Global.getTransitionedColor(lowColor, fullColor, (uint)device.Battery);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
2014-06-02 19:29:38 +02:00
|
|
|
|
{
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.MainColor[deviceNum];
|
2014-06-02 19:29:38 +02:00
|
|
|
|
}
|
2014-07-26 01:17:45 +02:00
|
|
|
|
|
2014-08-23 22:52:20 +02:00
|
|
|
|
|
2015-02-08 22:51:52 +01:00
|
|
|
|
if (device.Battery <= Global.FlashAt[deviceNum] && !defualtLight && !device.Charging)
|
2014-08-23 22:52:20 +02:00
|
|
|
|
{
|
2015-02-08 22:51:52 +01:00
|
|
|
|
if (!(Global.FlashColor[deviceNum].red == 0 &&
|
|
|
|
|
Global.FlashColor[deviceNum].green == 0 &&
|
|
|
|
|
Global.FlashColor[deviceNum].blue == 0))
|
|
|
|
|
color = Global.FlashColor[deviceNum];
|
|
|
|
|
if (Global.FlashType[deviceNum] == 1)
|
|
|
|
|
{
|
|
|
|
|
if (fadetimer[deviceNum] <= 0)
|
|
|
|
|
fadedirection[deviceNum] = true;
|
|
|
|
|
else if (fadetimer[deviceNum] >= 100)
|
|
|
|
|
fadedirection[deviceNum] = false;
|
|
|
|
|
if (fadedirection[deviceNum])
|
|
|
|
|
fadetimer[deviceNum] += 1;
|
|
|
|
|
else
|
|
|
|
|
fadetimer[deviceNum] -= 1;
|
|
|
|
|
color = Global.getTransitionedColor(color, new DS4Color(0,0,0), fadetimer[deviceNum]);
|
|
|
|
|
}
|
2014-08-23 22:52:20 +02:00
|
|
|
|
}
|
|
|
|
|
|
2015-02-08 22:51:52 +01:00
|
|
|
|
if (Global.IdleDisconnectTimeout[deviceNum] > 0 && Global.LedAsBatteryIndicator[deviceNum] && (!device.Charging || device.Battery >= 100))
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{//Fade lightbar by idle time
|
|
|
|
|
TimeSpan timeratio = new TimeSpan(DateTime.UtcNow.Ticks - device.lastActive.Ticks);
|
|
|
|
|
double botratio = timeratio.TotalMilliseconds;
|
2015-02-08 22:51:52 +01:00
|
|
|
|
double topratio = TimeSpan.FromSeconds(Global.IdleDisconnectTimeout[deviceNum]).TotalMilliseconds;
|
2014-07-26 01:17:45 +02:00
|
|
|
|
double ratio = ((botratio / topratio) * 100);
|
|
|
|
|
if (ratio >= 50 && ratio <= 100)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.getTransitionedColor(color, new DS4Color(0, 0, 0), (uint)((ratio - 50) * 2));
|
2014-07-26 01:17:45 +02:00
|
|
|
|
else if (ratio >= 100)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.getTransitionedColor(color, new DS4Color(0, 0, 0), 100);
|
2014-07-26 01:17:45 +02:00
|
|
|
|
}
|
|
|
|
|
if (device.Charging && device.Battery < 100)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
switch (Global.ChargingType[deviceNum])
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{
|
|
|
|
|
case 1:
|
|
|
|
|
if (fadetimer[deviceNum] <= 0)
|
|
|
|
|
fadedirection[deviceNum] = true;
|
|
|
|
|
else if (fadetimer[deviceNum] >= 105)
|
|
|
|
|
fadedirection[deviceNum] = false;
|
|
|
|
|
if (fadedirection[deviceNum])
|
|
|
|
|
fadetimer[deviceNum] += .1;
|
|
|
|
|
else
|
|
|
|
|
fadetimer[deviceNum] -= .1;
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.getTransitionedColor(color, new DS4Color(0, 0, 0), fadetimer[deviceNum]);
|
2014-07-26 01:17:45 +02:00
|
|
|
|
break;
|
|
|
|
|
case 2:
|
|
|
|
|
counters[deviceNum] += .167;
|
|
|
|
|
color = HuetoRGB((float)counters[deviceNum] % 360, 255);
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.ChargingColor[deviceNum];
|
2014-07-26 01:17:45 +02:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-05-22 21:13:38 +02:00
|
|
|
|
}
|
2014-12-02 01:07:29 +01:00
|
|
|
|
else if (forcelight[deviceNum])
|
|
|
|
|
{
|
|
|
|
|
color = forcedColor[deviceNum];
|
|
|
|
|
}
|
2014-06-02 19:29:38 +02:00
|
|
|
|
else if (shuttingdown)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = new DS4Color(0, 0, 0);
|
2014-06-02 05:19:04 +02:00
|
|
|
|
else
|
2014-09-02 20:41:32 +02:00
|
|
|
|
{
|
|
|
|
|
if (device.ConnectionType == ConnectionType.BT)
|
2015-02-12 20:36:40 +01:00
|
|
|
|
color = new DS4Color(32, 64, 64);
|
2014-09-02 20:41:32 +02:00
|
|
|
|
else
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = new DS4Color(0, 0, 0);
|
2014-09-02 20:41:32 +02:00
|
|
|
|
}
|
2015-02-08 22:51:52 +01:00
|
|
|
|
bool distanceprofile = (Global.ProfilePath[deviceNum].ToLower().Contains("distance") || Global.tempprofilename[deviceNum].ToLower().Contains("distance"));
|
2014-09-15 04:37:14 +02:00
|
|
|
|
if (distanceprofile && !defualtLight)
|
2014-09-02 01:23:02 +02:00
|
|
|
|
{ //Thing I did for Distance
|
|
|
|
|
float rumble = device.LeftHeavySlowRumble / 2.55f;
|
2015-02-08 22:51:52 +01:00
|
|
|
|
byte max = Math.Max(color.red, Math.Max(color.green, color.blue));
|
2014-09-15 04:37:14 +02:00
|
|
|
|
if (device.LeftHeavySlowRumble > 100)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.getTransitionedColor(new DS4Color(max, max, 0), new DS4Color(255, 0, 0), rumble);
|
2014-09-15 04:37:14 +02:00
|
|
|
|
else
|
2015-02-08 22:51:52 +01:00
|
|
|
|
color = Global.getTransitionedColor(color, Global.getTransitionedColor(new DS4Color(max, max, 0), new DS4Color(255, 0, 0), 39.6078f), device.LeftHeavySlowRumble);
|
2014-09-02 01:23:02 +02:00
|
|
|
|
}
|
2014-03-29 06:29:08 +01:00
|
|
|
|
DS4HapticState haptics = new DS4HapticState
|
|
|
|
|
{
|
|
|
|
|
LightBarColor = color
|
|
|
|
|
};
|
|
|
|
|
if (haptics.IsLightBarSet())
|
2014-03-28 02:50:40 +01:00
|
|
|
|
{
|
2014-12-02 01:07:29 +01:00
|
|
|
|
if (forcelight[deviceNum] && forcedFlash[deviceNum] > 0)
|
|
|
|
|
{
|
|
|
|
|
haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = (byte)(25 - forcedFlash[deviceNum]);
|
|
|
|
|
haptics.LightBarExplicitlyOff = true;
|
|
|
|
|
}
|
2015-02-08 22:51:52 +01:00
|
|
|
|
else if (device.Battery <= Global.FlashAt[deviceNum] && Global.FlashType[deviceNum] == 0 && !defualtLight && !device.Charging)
|
2014-03-29 06:29:08 +01:00
|
|
|
|
{
|
|
|
|
|
int level = device.Battery / 10;
|
2014-08-23 22:52:20 +02:00
|
|
|
|
//if (level >= 10)
|
2014-09-02 01:23:02 +02:00
|
|
|
|
//level = 0; // all values of ~0% or >~100% are rendered the same
|
2014-03-29 06:29:08 +01:00
|
|
|
|
haptics.LightBarFlashDurationOn = BatteryIndicatorDurations[level, 0];
|
|
|
|
|
haptics.LightBarFlashDurationOff = BatteryIndicatorDurations[level, 1];
|
|
|
|
|
}
|
2014-09-15 04:37:14 +02:00
|
|
|
|
else if (distanceprofile && device.LeftHeavySlowRumble > 155) //also part of Distance
|
2014-09-02 01:23:02 +02:00
|
|
|
|
{
|
|
|
|
|
haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = (byte)((-device.LeftHeavySlowRumble + 265));
|
|
|
|
|
haptics.LightBarExplicitlyOff = true;
|
|
|
|
|
}
|
2014-03-29 06:29:08 +01:00
|
|
|
|
else
|
|
|
|
|
{
|
2014-08-23 22:52:20 +02:00
|
|
|
|
//haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1;
|
2014-03-29 06:29:08 +01:00
|
|
|
|
haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 0;
|
2014-06-02 05:19:04 +02:00
|
|
|
|
haptics.LightBarExplicitlyOff = true;
|
2014-03-29 06:29:08 +01:00
|
|
|
|
}
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2014-03-29 06:29:08 +01:00
|
|
|
|
haptics.LightBarExplicitlyOff = true;
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
2014-09-02 01:23:02 +02:00
|
|
|
|
if (device.LightBarOnDuration != haptics.LightBarFlashDurationOn && device.LightBarOnDuration != 1 && haptics.LightBarFlashDurationOn == 0)
|
|
|
|
|
haptics.LightBarFlashDurationOff = haptics.LightBarFlashDurationOn = 1;
|
2014-09-02 20:41:32 +02:00
|
|
|
|
if (device.LightBarOnDuration == 1) //helps better reset the color
|
2014-09-02 01:23:02 +02:00
|
|
|
|
System.Threading.Thread.Sleep(5);
|
2014-03-29 06:29:08 +01:00
|
|
|
|
device.pushHapticState(haptics);
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
2014-12-02 01:07:29 +01:00
|
|
|
|
|
2014-06-02 19:29:38 +02:00
|
|
|
|
public static bool defualtLight = false, shuttingdown = false;
|
2014-03-28 02:50:40 +01:00
|
|
|
|
|
2014-10-31 00:56:51 +01:00
|
|
|
|
public static bool shiftMod(DS4Device device, int deviceNum, DS4State cState, DS4StateExposed eState, Mouse tp)
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{
|
2014-08-23 22:52:20 +02:00
|
|
|
|
bool shift;
|
2015-02-08 22:51:52 +01:00
|
|
|
|
switch (Global.ShiftModifier[deviceNum])
|
2014-07-26 01:17:45 +02:00
|
|
|
|
{
|
2014-10-31 00:56:51 +01:00
|
|
|
|
case 1: shift = Mapping.getBoolMapping(DS4Controls.Cross, cState, eState, tp); break;
|
|
|
|
|
case 2: shift = Mapping.getBoolMapping(DS4Controls.Circle, cState, eState, tp); break;
|
|
|
|
|
case 3: shift = Mapping.getBoolMapping(DS4Controls.Square, cState, eState, tp); break;
|
|
|
|
|
case 4: shift = Mapping.getBoolMapping(DS4Controls.Triangle, cState, eState, tp); break;
|
|
|
|
|
case 5: shift = Mapping.getBoolMapping(DS4Controls.Options, cState, eState, tp); break;
|
|
|
|
|
case 6: shift = Mapping.getBoolMapping(DS4Controls.Share, cState, eState, tp); break;
|
|
|
|
|
case 7: shift = Mapping.getBoolMapping(DS4Controls.DpadUp, cState, eState, tp); break;
|
|
|
|
|
case 8: shift = Mapping.getBoolMapping(DS4Controls.DpadDown, cState, eState, tp); break;
|
|
|
|
|
case 9: shift = Mapping.getBoolMapping(DS4Controls.DpadLeft, cState, eState, tp); break;
|
|
|
|
|
case 10: shift = Mapping.getBoolMapping(DS4Controls.DpadRight, cState, eState, tp); break;
|
|
|
|
|
case 11: shift = Mapping.getBoolMapping(DS4Controls.PS, cState, eState, tp); break;
|
|
|
|
|
case 12: shift = Mapping.getBoolMapping(DS4Controls.L1, cState, eState, tp); break;
|
|
|
|
|
case 13: shift = Mapping.getBoolMapping(DS4Controls.R1, cState, eState, tp); break;
|
|
|
|
|
case 14: shift = Mapping.getBoolMapping(DS4Controls.L2, cState, eState, tp); break;
|
|
|
|
|
case 15: shift = Mapping.getBoolMapping(DS4Controls.R2, cState, eState, tp); break;
|
|
|
|
|
case 16: shift = Mapping.getBoolMapping(DS4Controls.L3, cState, eState, tp); break;
|
|
|
|
|
case 17: shift = Mapping.getBoolMapping(DS4Controls.R3, cState, eState, tp); break;
|
|
|
|
|
case 18: shift = Mapping.getBoolMapping(DS4Controls.TouchLeft, cState, eState, tp); break;
|
|
|
|
|
case 19: shift = Mapping.getBoolMapping(DS4Controls.TouchUpper, cState, eState, tp); break;
|
|
|
|
|
case 20: shift = Mapping.getBoolMapping(DS4Controls.TouchMulti, cState, eState, tp); break;
|
|
|
|
|
case 21: shift = Mapping.getBoolMapping(DS4Controls.TouchRight, cState, eState, tp); break;
|
|
|
|
|
case 22: shift = Mapping.getBoolMapping(DS4Controls.GyroZNeg, cState, eState, tp); break;
|
|
|
|
|
case 23: shift = Mapping.getBoolMapping(DS4Controls.GyroZPos, cState, eState, tp); break;
|
|
|
|
|
case 24: shift = Mapping.getBoolMapping(DS4Controls.GyroXPos, cState, eState, tp); break;
|
|
|
|
|
case 25: shift = Mapping.getBoolMapping(DS4Controls.GyroXNeg, cState, eState, tp); break;
|
2014-07-26 01:17:45 +02:00
|
|
|
|
case 26: shift = device.getCurrentState().Touch1; break;
|
|
|
|
|
default: shift = false; break;
|
|
|
|
|
}
|
|
|
|
|
return shift;
|
|
|
|
|
}
|
2014-04-30 21:32:44 +02:00
|
|
|
|
public static DS4Color HuetoRGB(float hue, byte sat)
|
|
|
|
|
{
|
|
|
|
|
byte C = sat;
|
|
|
|
|
int X = (int)((C * (float)(1 - Math.Abs((hue / 60) % 2 - 1))));
|
|
|
|
|
if (0 <= hue && hue < 60)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color(C, (byte)X, 0);
|
2014-04-30 21:32:44 +02:00
|
|
|
|
else if (60 <= hue && hue < 120)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color((byte)X, C, 0);
|
2014-04-30 21:32:44 +02:00
|
|
|
|
else if (120 <= hue && hue < 180)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color(0, C, (byte)X);
|
2014-04-30 21:32:44 +02:00
|
|
|
|
else if (180 <= hue && hue < 240)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color(0, (byte)X, C);
|
2014-04-30 21:32:44 +02:00
|
|
|
|
else if (240 <= hue && hue < 300)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color((byte)X, 0, C);
|
2014-04-30 21:32:44 +02:00
|
|
|
|
else if (300 <= hue && hue < 360)
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color(C, 0, (byte)X);
|
2014-04-30 21:32:44 +02:00
|
|
|
|
else
|
2015-02-08 22:51:52 +01:00
|
|
|
|
return new DS4Color(Color.Red);
|
2014-09-02 01:23:02 +02:00
|
|
|
|
}
|
2014-03-28 02:50:40 +01:00
|
|
|
|
}
|
|
|
|
|
}
|