Skip to content

Commit

Permalink
- Fix rumble (also change default freq values)
Browse files Browse the repository at this point in the history
 - Fix bug on seeing whether a controller is 3rd party
  • Loading branch information
Davidobot committed Sep 6, 2020
1 parent debace5 commit a68a2ee
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 25 deletions.
7 changes: 4 additions & 3 deletions BetterJoyForCemu/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@
<!--The response of rumble does not only depend on this setting and it's always high. Default: 300 -->
<add key="RumblePeriod" value="300" />
<!--The controller's HD rumble settings for the low/high frequency rumble. Change to change the pitch of the rumble.-->
<!--Don't set above ~1200. Default: 20 and 400 -->
<add key="LowFreqRumble" value="20" />
<add key="HighFreqRumble" value="400" />
<!--Don't set above ~1200. Default: 40 and 120 -->
<!--To have "stronger" rumble, try setting the low/high to 160/320-->
<add key="LowFreqRumble" value="40" />
<add key="HighFreqRumble" value="120" />
<!--Rumble Setting. Turns rumble on or off.-->
<!--On is "true"; off is "false". Default: true -->
<add key="EnableRumble" value="true" />
Expand Down
54 changes: 33 additions & 21 deletions BetterJoyForCemu/Joycon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,14 +123,13 @@ public enum Button : int {

private struct Rumble {
private float h_f, l_f;
public float amp, fullamp;
public float amp;
public bool controller_informed;
public long end_rumble_time_milliseconds;

public void set_vals(float low_freq, float high_freq, float amplitude, int rumble_duration_ms = 0) {
h_f = high_freq;
amp = amplitude;
fullamp = amplitude;
l_f = low_freq;
if (rumble_duration_ms != 0) {
end_rumble_time_milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds() + rumble_duration_ms;
Expand All @@ -143,7 +142,6 @@ private struct Rumble {
public Rumble(float low_freq, float high_freq, float amplitude, int rumble_duration_ms = 0) {
h_f = high_freq;
amp = amplitude;
fullamp = amplitude;
l_f = low_freq;
if (rumble_duration_ms != 0) {
end_rumble_time_milliseconds = DateTimeOffset.Now.ToUnixTimeMilliseconds() + rumble_duration_ms;
Expand All @@ -164,6 +162,22 @@ private struct Rumble {
amp = 0;
}
}

private byte EncodeAmp(float amp) {
byte en_amp;

if (amp == 0)
en_amp = 0;
else if (amp < 0.117)
en_amp = (byte)(((Math.Log(amp * 1000, 2) * 32) - 0x60) / (5 - Math.Pow(amp, 2)) - 1);
else if (amp < 0.23)
en_amp = (byte)(((Math.Log(amp * 1000, 2) * 32) - 0x60) - 0x5c);
else
en_amp = (byte)((((Math.Log(amp * 1000, 2) * 32) - 0x60) * 2) - 0xf6);

return en_amp;
}

public byte[] GetData() {
byte[] rumble_data = new byte[8];

Expand All @@ -174,15 +188,13 @@ private struct Rumble {
rumble_data[3] = 0x40;
} else {
l_f = clamp(l_f, 40.875885f, 626.286133f);
amp = clamp(amp, 0.0f, 1.0f);
h_f = clamp(h_f, 81.75177f, 1252.572266f);

amp = clamp(amp, 0.0f, 1.0f);

UInt16 hf = (UInt16)((Math.Round(32f * Math.Log(h_f * 0.1f, 2)) - 0x60) * 4);
byte lf = (byte)(Math.Round(32f * Math.Log(l_f * 0.1f, 2)) - 0x40);
byte hf_amp;
if (amp == 0) hf_amp = 0;
else if (amp < 0.117) hf_amp = (byte)(((Math.Log(amp * 1000, 2) * 32) - 0x60) / (5 - Math.Pow(amp, 2)) - 1);
else if (amp < 0.23) hf_amp = (byte)(((Math.Log(amp * 1000, 2) * 32) - 0x60) - 0x5c);
else hf_amp = (byte)((((Math.Log(amp * 1000, 2) * 32) - 0x60) * 2) - 0xf6);
byte hf_amp = EncodeAmp(amp);

UInt16 lf_amp = (UInt16)(Math.Round((double)hf_amp) * .5);
byte parity = (byte)(lf_amp % 2);
Expand All @@ -193,14 +205,14 @@ private struct Rumble {
lf_amp = (UInt16)(lf_amp >> 1);
lf_amp += 0x40;
if (parity > 0) lf_amp |= 0x8000;
rumble_data = new byte[8];

hf_amp = (byte)(hf_amp - (hf_amp % 2)); // make even at all times to prevent weird hum
rumble_data[0] = (byte)(hf & 0xff);
rumble_data[1] = (byte)((hf >> 8) & 0xff);
rumble_data[2] = lf;
rumble_data[1] += hf_amp;
rumble_data[2] += (byte)((lf_amp >> 8) & 0xff);
rumble_data[3] += (byte)(lf_amp & 0xff);
rumble_data[1] = (byte)(((hf >> 8) & 0xff) + hf_amp);
rumble_data[2] = (byte)(((lf_amp >> 8) & 0xff) + lf);
rumble_data[3] = (byte)(lf_amp & 0xff);
}

for (int i = 0; i < 4; ++i) {
rumble_data[4 + i] = rumble_data[i];
}
Expand Down Expand Up @@ -254,7 +266,7 @@ private struct Rumble {
handle = handle_;
imu_enabled = imu;
do_localize = localize;
rumble_obj = new Rumble(160, 320, 0);
rumble_obj = new Rumble(lowFreq, highFreq, 0, 0);
for (int i = 0; i < buttons_down_timestamp.Length; i++)
buttons_down_timestamp[i] = -1;
filterweight = alpha;
Expand All @@ -265,7 +277,7 @@ private struct Rumble {
this.isPro = isPro || isSnes;
this.isSnes = isSnes;
isUSB = serialNum == "000000000001";
thirdParty = thirdParty;
this.thirdParty = thirdParty;

this.path = path;

Expand All @@ -289,17 +301,17 @@ private struct Rumble {
}

public void ReceiveRumble(Xbox360FeedbackReceivedEventArgs e) {
SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);

if (other != null && other != this)
other.SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
other.SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);
}

public void Ds4_FeedbackReceived(DualShock4FeedbackReceivedEventArgs e) {
SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);

if (other != null && other != this)
other.SetRumble(lowFreq, highFreq, (float)(e.LargeMotor + e.SmallMotor) / (float)255, rumblePeriod);
other.SetRumble(lowFreq, highFreq, (float)Math.Max(e.LargeMotor, e.SmallMotor) / (float)255, rumblePeriod);
}

public void DebugPrint(String s, DebugType d) {
Expand Down
2 changes: 1 addition & 1 deletion BetterJoyForCemu/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public partial class MainForm : Form {

if (button.Tag.GetType() == typeof(Joycon)) {
Joycon v = (Joycon)button.Tag;
v.SetRumble(20.0f, 400.0f, 1.0f, 300);
v.SetRumble(160.0f, 320.0f, 1.0f, 300);
}
}
}
Expand Down

0 comments on commit a68a2ee

Please sign in to comment.