Added n64 support (#1138)

* Added n64 support

* Updated icon n64

* fixed Y axis in C buttons

* Added dynamic calibration for n64 joy

* Added option real 64 range

* corrected the stick minimum value for both axis
This commit is contained in:
Gino Moena 2024-07-19 10:44:25 -04:00 committed by GitHub
parent 461f5f8f5c
commit 8890b053c7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 225 additions and 29 deletions

View file

@ -46,6 +46,8 @@
<!-- When enabled, can only calibrate one controller at a time.--> <!-- When enabled, can only calibrate one controller at a time.-->
<!-- Default: false --> <!-- Default: false -->
<add key="AllowCalibration" value="false" /> <add key="AllowCalibration" value="false" />
<!-- Allows to emulate the n64 range of joystick (.8, .8) instead of real xbox360 (1, 1). -->
<add key="N64Range" value="true" />
<!-- Default calibration; used for third party controller --> <!-- Default calibration; used for third party controller -->
<add key="acc_sensiti" value="16384,16384,16384"/> <add key="acc_sensiti" value="16384,16384,16384"/>
<add key="gyr_sensiti" value="18642,18642,18642"/> <add key="gyr_sensiti" value="18642,18642,18642"/>

View file

@ -239,6 +239,7 @@
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content> </Content>
<Content Include="Icons\snes.png" /> <Content Include="Icons\snes.png" />
<Content Include="Icons\ultra.png" />
<None Include="Properties\app.manifest" /> <None Include="Properties\app.manifest" />
<Content Include="Icons\betterjoyforcemu_icon.ico" /> <Content Include="Icons\betterjoyforcemu_icon.ico" />
<Content Include="x86\hidapi.dll"> <Content Include="x86\hidapi.dll">

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View file

@ -16,8 +16,16 @@ namespace BetterJoyForCemu {
public string path = String.Empty; public string path = String.Empty;
public bool isPro = false; public bool isPro = false;
public bool isSnes = false; public bool isSnes = false;
public bool is64 = false;
bool isUSB = false; bool isUSB = false;
private Joycon _other = null; private Joycon _other = null;
// 64 vars
float maxX = 0.5f;
float minX = -0.5f;
float maxY = 0.5f;
float minY = -0.5f;
public Joycon other { public Joycon other {
get { get {
return _other; return _other;
@ -282,7 +290,7 @@ namespace BetterJoyForCemu {
static float AHRS_beta = float.Parse(ConfigurationManager.AppSettings["AHRS_beta"]); static float AHRS_beta = float.Parse(ConfigurationManager.AppSettings["AHRS_beta"]);
private MadgwickAHRS AHRS = new MadgwickAHRS(0.005f, AHRS_beta); // for getting filtered Euler angles of rotation; 5ms sampling rate private MadgwickAHRS AHRS = new MadgwickAHRS(0.005f, AHRS_beta); // for getting filtered Euler angles of rotation; 5ms sampling rate
public Joycon(IntPtr handle_, bool imu, bool localize, float alpha, bool left, string path, string serialNum, int id = 0, bool isPro = false, bool isSnes = false, bool thirdParty = false) { public Joycon(IntPtr handle_, bool imu, bool localize, float alpha, bool left, string path, string serialNum, int id = 0, bool isPro = false, bool isSnes = false, bool is64 = false, bool thirdParty = false) {
serial_number = serialNum; serial_number = serialNum;
activeData = new float[6]; activeData = new float[6];
handle = handle_; handle = handle_;
@ -296,8 +304,9 @@ namespace BetterJoyForCemu {
PadId = id; PadId = id;
LED = (byte)(0x1 << PadId); LED = (byte)(0x1 << PadId);
this.isPro = isPro || isSnes; this.isPro = isPro || isSnes || is64;
this.isSnes = isSnes; this.isSnes = isSnes;
this.is64 = is64;
isUSB = serialNum == "000000000001"; isUSB = serialNum == "000000000001";
this.thirdParty = thirdParty; this.thirdParty = thirdParty;
@ -501,7 +510,7 @@ namespace BetterJoyForCemu {
if (battery <= 1) { if (battery <= 1) {
form.notifyIcon.Visible = true; form.notifyIcon.Visible = true;
form.notifyIcon.BalloonTipText = String.Format("Controller {0} ({1}) - low battery notification!", PadId, isPro ? "Pro Controller" : (isSnes ? "SNES Controller" : (isLeft ? "Joycon Left" : "Joycon Right"))); form.notifyIcon.BalloonTipText = String.Format("Controller {0} ({1}) - low battery notification!", PadId, isPro ? "Pro Controller" : (isSnes ? "SNES Controller" : (is64? "N64 Controller" : (isLeft ? "Joycon Left" : "Joycon Right"))));
form.notifyIcon.ShowBalloonTip(0); form.notifyIcon.ShowBalloonTip(0);
} }
} }
@ -590,7 +599,7 @@ namespace BetterJoyForCemu {
} }
if (ts_en == raw_buf[1] && !isSnes) { if (ts_en == raw_buf[1] && !(isSnes || is64)) {
form.AppendTextBox("Duplicate timestamp enqueued.\r\n"); form.AppendTextBox("Duplicate timestamp enqueued.\r\n");
DebugPrint(string.Format("Duplicate timestamp enqueued. TS: {0:X2}", ts_en), DebugType.THREADING); DebugPrint(string.Format("Duplicate timestamp enqueued. TS: {0:X2}", ts_en), DebugType.THREADING);
} }
@ -891,6 +900,7 @@ namespace BetterJoyForCemu {
bool swapAB = Boolean.Parse(ConfigurationManager.AppSettings["SwapAB"]); bool swapAB = Boolean.Parse(ConfigurationManager.AppSettings["SwapAB"]);
bool swapXY = Boolean.Parse(ConfigurationManager.AppSettings["SwapXY"]); bool swapXY = Boolean.Parse(ConfigurationManager.AppSettings["SwapXY"]);
bool realn64Range = Boolean.Parse(ConfigurationManager.AppSettings["N64Range"]);
float stickScalingFactor = float.Parse(ConfigurationManager.AppSettings["StickScalingFactor"]); float stickScalingFactor = float.Parse(ConfigurationManager.AppSettings["StickScalingFactor"]);
float stickScalingFactor2 = float.Parse(ConfigurationManager.AppSettings["StickScalingFactor2"]); float stickScalingFactor2 = float.Parse(ConfigurationManager.AppSettings["StickScalingFactor2"]);
@ -1009,7 +1019,7 @@ namespace BetterJoyForCemu {
// Get Gyro/Accel data // Get Gyro/Accel data
private void ExtractIMUValues(byte[] report_buf, int n = 0) { private void ExtractIMUValues(byte[] report_buf, int n = 0) {
if (!isSnes) { if (!(isSnes || is64)) {
gyr_r[0] = (Int16)(report_buf[19 + n * 12] | ((report_buf[20 + n * 12] << 8) & 0xff00)); gyr_r[0] = (Int16)(report_buf[19 + n * 12] | ((report_buf[20 + n * 12] << 8) & 0xff00));
gyr_r[1] = (Int16)(report_buf[21 + n * 12] | ((report_buf[22 + n * 12] << 8) & 0xff00)); gyr_r[1] = (Int16)(report_buf[21 + n * 12] | ((report_buf[22 + n * 12] << 8) & 0xff00));
gyr_r[2] = (Int16)(report_buf[23 + n * 12] | ((report_buf[24 + n * 12] << 8) & 0xff00)); gyr_r[2] = (Int16)(report_buf[23 + n * 12] | ((report_buf[24 + n * 12] << 8) & 0xff00));
@ -1181,7 +1191,7 @@ namespace BetterJoyForCemu {
} }
private void dump_calibration_data() { private void dump_calibration_data() {
if (isSnes || thirdParty) { if (isSnes || is64 || thirdParty) {
short[] temp = (short[])ConfigurationManager.AppSettings["acc_sensiti"].Split(',').Select(s => short.Parse(s)).ToArray(); short[] temp = (short[])ConfigurationManager.AppSettings["acc_sensiti"].Split(',').Select(s => short.Parse(s)).ToArray();
acc_sensiti[0] = temp[0]; acc_sensiti[1] = temp[1]; acc_sensiti[2] = temp[2]; acc_sensiti[0] = temp[0]; acc_sensiti[1] = temp[1]; acc_sensiti[2] = temp[2];
temp = (short[])ConfigurationManager.AppSettings["gyr_sensiti"].Split(',').Select(s => short.Parse(s)).ToArray(); temp = (short[])ConfigurationManager.AppSettings["gyr_sensiti"].Split(',').Select(s => short.Parse(s)).ToArray();
@ -1325,15 +1335,103 @@ namespace BetterJoyForCemu {
DebugPrint(string.Format(format, tostr), d); DebugPrint(string.Format(format, tostr), d);
} }
private static float GetNormalizedValue(float value, float rawMin, float rawMax, float normalizedMin, float normalizedMax)
{
return (value - rawMin) / (rawMax - rawMin) * (normalizedMax - normalizedMin) + normalizedMin;
}
private static float[] Getn64StickValues(Joycon input)
{
var isLeft = input.isLeft;
var other = input.other;
var stick = input.stick;
var stick2 = input.stick2;
var stick_correction = new float[] { 0f, 0f};
var xAxis = (other == input && !isLeft) ? stick2[0] : stick[0];
var yAxis = (other == input && !isLeft) ? stick2[1] : stick[1];
if (xAxis < input.minX)
{
input.minX = xAxis;
}
if (xAxis > input.maxX)
{
input.maxX = xAxis;
}
if (yAxis < input.minY)
{
input.minY = yAxis;
}
if (yAxis > input.maxY)
{
input.maxY = yAxis;
}
var middleX = (input.minX + (input.maxX - input.minX)/2);
var middleY = (input.minY + (input.maxY - input.minY)/2);
#if DEBUG
var desc = "";
desc += "x: "+xAxis+"; y: "+yAxis;
desc += "\n X: ["+input.minX+", "+input.maxX+"]; Y: ["+input.minY+", "+input.maxY+"] ";
desc += "; middle ["+middleX+", "+middleY+"]";
Debug.WriteLine(desc);
#endif
var negative_normalized = new float[] {-1, 0};
var positive_normalized = new float[] {0, 1};
var xRange = new float[] {-1f, 1f};
var yRange = new float[] {-1f, 1f};
if (input.realn64Range)
{
xRange = new float[] {-0.79f, 0.79f};
yRange = new float[] {-0.79f, 0.79f};
}
if (xAxis < (middleX - middleX))
{
stick_correction[0] = GetNormalizedValue(xAxis, input.minX, (middleX - middleX), xRange[0], 0f);
}
if (xAxis > (middleX+middleX))
{
stick_correction[0] = GetNormalizedValue(xAxis, (middleX+middleX), input.maxX, 0f, xRange[1]);
}
if (yAxis < (middleY-middleY))
{
stick_correction[1] = GetNormalizedValue(yAxis, input.minY, (middleY-middleY), yRange[0], 0f);
}
if (yAxis > (middleY+middleY))
{
stick_correction[1] = GetNormalizedValue(yAxis, (middleY+middleY), input.maxY, 0f, yRange[1]);
}
return stick_correction;
}
private static OutputControllerXbox360InputState MapToXbox360Input(Joycon input) { private static OutputControllerXbox360InputState MapToXbox360Input(Joycon input) {
var output = new OutputControllerXbox360InputState(); var output = new OutputControllerXbox360InputState();
var swapAB = input.swapAB; var swapAB = input.swapAB;
var swapXY = input.swapXY; var swapXY = input.swapXY;
var isPro = input.isPro; var isPro = input.isPro;
var isLeft = input.isLeft; var isLeft = input.isLeft;
var isSnes = input.isSnes; var isSnes = input.isSnes;
var is64 = input.is64;
var other = input.other; var other = input.other;
var GyroAnalogSliders = input.GyroAnalogSliders; var GyroAnalogSliders = input.GyroAnalogSliders;
@ -1342,7 +1440,34 @@ namespace BetterJoyForCemu {
var stick2 = input.stick2; var stick2 = input.stick2;
var sliderVal = input.sliderVal; var sliderVal = input.sliderVal;
if (isPro) { if (is64)
{
output.axis_right_x = (short) ((buttons[(int)Button.X] ? Int16.MinValue : 0) + (buttons[(int)Button.MINUS] ? Int16.MaxValue : 0));
output.axis_right_y = (short) ((buttons[(int)Button.SHOULDER2_2] ? Int16.MinValue: 0) + (buttons[(int)Button.Y] ? Int16.MaxValue: 0));
var n64Stick = Getn64StickValues(input);
output.axis_left_x = CastStickValue(n64Stick[0]);
output.axis_left_y = CastStickValue(n64Stick[1]);
output.start = buttons[(int)Button.PLUS];
output.a = buttons[(int)(!swapAB ? Button.B : Button.A)];
output.b = buttons[(int)(!swapAB ? Button.A : Button.B)];
output.shoulder_left = buttons[(int)Button.SHOULDER_1];
output.shoulder_right = buttons[(int)Button.SHOULDER2_1];
output.trigger_left = (byte)(buttons[(int)Button.SHOULDER_2] ? Byte.MaxValue : 0);
output.trigger_right = (byte)(buttons[(int)Button.STICK] ? Byte.MaxValue : 0);
output.dpad_down = buttons[(int)Button.DPAD_DOWN];
output.dpad_left = buttons[(int)Button.DPAD_LEFT];
output.dpad_right = buttons[(int)Button.DPAD_RIGHT];
output.dpad_up = buttons[(int)Button.DPAD_UP];
output.guide = buttons[(int)Button.HOME];
}
else if (isPro) {
output.a = buttons[(int)(!swapAB ? Button.B : Button.A)]; output.a = buttons[(int)(!swapAB ? Button.B : Button.A)];
output.b = buttons[(int)(!swapAB ? Button.A : Button.B)]; output.b = buttons[(int)(!swapAB ? Button.A : Button.B)];
output.y = buttons[(int)(!swapXY ? Button.X : Button.Y)]; output.y = buttons[(int)(!swapXY ? Button.X : Button.Y)];
@ -1403,7 +1528,7 @@ namespace BetterJoyForCemu {
if (Config.Value("home") != "0") if (Config.Value("home") != "0")
output.guide = false; output.guide = false;
if (!isSnes) { if (!(isSnes || is64)) {
if (other != null || isPro) { // no need for && other != this if (other != null || isPro) { // no need for && other != this
output.axis_left_x = CastStickValue((other == input && !isLeft) ? stick2[0] : stick[0]); output.axis_left_x = CastStickValue((other == input && !isLeft) ? stick2[0] : stick[0]);
output.axis_left_y = CastStickValue((other == input && !isLeft) ? stick2[1] : stick[1]); output.axis_left_y = CastStickValue((other == input && !isLeft) ? stick2[1] : stick[1]);
@ -1416,14 +1541,17 @@ namespace BetterJoyForCemu {
} }
} }
if (other != null || isPro) { if (!is64)
byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue; {
byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue; if (other != null || isPro) {
output.trigger_left = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0); byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue;
output.trigger_right = (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0); byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue;
} else { output.trigger_left = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0);
output.trigger_left = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0); output.trigger_right = (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0);
output.trigger_right = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0); } else {
output.trigger_left = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0);
output.trigger_right = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0);
}
} }
return output; return output;
@ -1438,6 +1566,7 @@ namespace BetterJoyForCemu {
var isPro = input.isPro; var isPro = input.isPro;
var isLeft = input.isLeft; var isLeft = input.isLeft;
var isSnes = input.isSnes; var isSnes = input.isSnes;
var is64 = input.is64;
var other = input.other; var other = input.other;
var GyroAnalogSliders = input.GyroAnalogSliders; var GyroAnalogSliders = input.GyroAnalogSliders;
@ -1446,6 +1575,47 @@ namespace BetterJoyForCemu {
var stick2 = input.stick2; var stick2 = input.stick2;
var sliderVal = input.sliderVal; var sliderVal = input.sliderVal;
if (is64)
{
output.thumb_right_x = (byte) ((buttons[(int)Button.X] ? Byte.MinValue : 0) + (buttons[(int)Button.MINUS] ? Byte.MaxValue : 0));
output.thumb_right_y = (byte) ((buttons[(int)Button.SHOULDER2_2] ? Byte.MinValue: 0) + (buttons[(int)Button.Y] ? Byte.MaxValue: 0));
output.thumb_left_x = CastStickValueByte((other == input && !isLeft) ? -stick2[0] : -stick[0]);
output.thumb_left_y = CastStickValueByte((other == input && !isLeft) ? stick2[1] : stick[1]);
output.options = buttons[(int)Button.PLUS];
output.cross = buttons[(int)(!swapAB ? Button.B : Button.A)];
output.circle = buttons[(int)(!swapAB ? Button.A : Button.B)];
output.shoulder_left = buttons[(int)Button.SHOULDER_1];
output.shoulder_right = buttons[(int)Button.SHOULDER2_1];
output.trigger_left = buttons[(int)Button.SHOULDER_2];
output.trigger_right = buttons[(int)Button.STICK];
output.trigger_left_value = (byte)(buttons[(int)Button.SHOULDER_2] ? Byte.MaxValue : 0);
output.trigger_right_value = (byte)(buttons[(int)Button.STICK] ? Byte.MaxValue : 0);
if (buttons[(int)Button.DPAD_UP]) {
if (buttons[(int)Button.DPAD_LEFT])
output.dPad = DpadDirection.Northwest;
else if (buttons[(int)Button.DPAD_RIGHT])
output.dPad = DpadDirection.Northeast;
else
output.dPad = DpadDirection.North;
} else if (buttons[(int)Button.DPAD_DOWN]) {
if (buttons[(int)Button.DPAD_LEFT])
output.dPad = DpadDirection.Southwest;
else if (buttons[(int)Button.DPAD_RIGHT])
output.dPad = DpadDirection.Southeast;
else
output.dPad = DpadDirection.South;
} else if (buttons[(int)Button.DPAD_LEFT])
output.dPad = DpadDirection.West;
else if (buttons[(int)Button.DPAD_RIGHT])
output.dPad = DpadDirection.East;
}
if (isPro) { if (isPro) {
output.cross = buttons[(int)(!swapAB ? Button.B : Button.A)]; output.cross = buttons[(int)(!swapAB ? Button.B : Button.A)];
output.circle = buttons[(int)(!swapAB ? Button.A : Button.B)]; output.circle = buttons[(int)(!swapAB ? Button.A : Button.B)];
@ -1534,7 +1704,7 @@ namespace BetterJoyForCemu {
if (Config.Value("home") != "0") if (Config.Value("home") != "0")
output.ps = false; output.ps = false;
if (!isSnes) { if (!(isSnes || is64)) {
if (other != null || isPro) { // no need for && other != this if (other != null || isPro) { // no need for && other != this
output.thumb_left_x = CastStickValueByte((other == input && !isLeft) ? -stick2[0] : -stick[0]); output.thumb_left_x = CastStickValueByte((other == input && !isLeft) ? -stick2[0] : -stick[0]);
output.thumb_left_y = CastStickValueByte((other == input && !isLeft) ? stick2[1] : stick[1]); output.thumb_left_y = CastStickValueByte((other == input && !isLeft) ? stick2[1] : stick[1]);
@ -1546,18 +1716,21 @@ namespace BetterJoyForCemu {
} }
} }
if (other != null || isPro) { if (!is64)
byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue; {
byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue; if (other != null || isPro) {
output.trigger_left_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0); byte lval = GyroAnalogSliders ? sliderVal[0] : Byte.MaxValue;
output.trigger_right_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0); byte rval = GyroAnalogSliders ? sliderVal[1] : Byte.MaxValue;
} else { output.trigger_left_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER2_2)] ? lval : 0);
output.trigger_left_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0); output.trigger_right_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER2_2 : Button.SHOULDER_2)] ? rval : 0);
output.trigger_right_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0); } else {
} output.trigger_left_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_2 : Button.SHOULDER_1)] ? Byte.MaxValue : 0);
output.trigger_right_value = (byte)(buttons[(int)(isLeft ? Button.SHOULDER_1 : Button.SHOULDER_2)] ? Byte.MaxValue : 0);
}
// Output digital L2 / R2 in addition to analog L2 / R2 // Output digital L2 / R2 in addition to analog L2 / R2
output.trigger_left = output.trigger_left_value > 0 ? output.trigger_left = true : output.trigger_left = false; output.trigger_left = output.trigger_left_value > 0 ? output.trigger_left = true : output.trigger_left = false;
output.trigger_right = output.trigger_right_value > 0 ? output.trigger_right = true : output.trigger_right = false; output.trigger_right = output.trigger_right_value > 0 ? output.trigger_right = true : output.trigger_right = false;
}
return output; return output;
} }

View file

@ -30,6 +30,7 @@ namespace BetterJoyForCemu {
private const ushort product_r = 0x2007; private const ushort product_r = 0x2007;
private const ushort product_pro = 0x2009; private const ushort product_pro = 0x2009;
private const ushort product_snes = 0x2017; private const ushort product_snes = 0x2017;
private const ushort product_n64 = 0x2019;
public ConcurrentList<Joycon> j { get; private set; } // Array of all connected Joy-Cons public ConcurrentList<Joycon> j { get; private set; } // Array of all connected Joy-Cons
static JoyconManager instance; static JoyconManager instance;
@ -128,7 +129,7 @@ namespace BetterJoyForCemu {
} }
bool validController = (enumerate.product_id == product_l || enumerate.product_id == product_r || bool validController = (enumerate.product_id == product_l || enumerate.product_id == product_r ||
enumerate.product_id == product_pro || enumerate.product_id == product_snes) && enumerate.vendor_id == vendor_id; enumerate.product_id == product_pro || enumerate.product_id == product_snes || enumerate.product_id == product_n64) && enumerate.vendor_id == vendor_id;
// check list of custom controllers specified // check list of custom controllers specified
foreach (SController v in Program.thirdPartyCons) { foreach (SController v in Program.thirdPartyCons) {
if (enumerate.vendor_id == v.vendor_id && enumerate.product_id == v.product_id && enumerate.serial_number == v.serial_number) { if (enumerate.vendor_id == v.vendor_id && enumerate.product_id == v.product_id && enumerate.serial_number == v.serial_number) {
@ -158,6 +159,9 @@ namespace BetterJoyForCemu {
case product_snes: case product_snes:
isLeft = true; isLeft = true;
form.AppendTextBox("SNES controller connected.\r\n"); break; form.AppendTextBox("SNES controller connected.\r\n"); break;
case product_n64:
isLeft = true;
form.AppendTextBox("N64 controller connected.\r\n"); break;
default: default:
form.AppendTextBox("Non Joy-Con Nintendo input device skipped.\r\n"); break; form.AppendTextBox("Non Joy-Con Nintendo input device skipped.\r\n"); break;
} }
@ -194,7 +198,8 @@ namespace BetterJoyForCemu {
bool isPro = prod_id == product_pro; bool isPro = prod_id == product_pro;
bool isSnes = prod_id == product_snes; bool isSnes = prod_id == product_snes;
j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, enumerate.path, enumerate.serial_number, j.Count, isPro, isSnes, thirdParty != null)); bool is64 = prod_id == product_n64;
j.Add(new Joycon(handle, EnableIMU, EnableLocalize & EnableIMU, 0.05f, isLeft, enumerate.path, enumerate.serial_number, j.Count, isPro, isSnes, is64,thirdParty != null));
foundNew = true; foundNew = true;
j.Last().form = form; j.Last().form = form;
@ -214,6 +219,8 @@ namespace BetterJoyForCemu {
temp = Properties.Resources.pro; break; temp = Properties.Resources.pro; break;
case (product_snes): case (product_snes):
temp = Properties.Resources.snes; break; temp = Properties.Resources.snes; break;
case (product_n64):
temp = Properties.Resources.ultra; break;
default: default:
temp = Properties.Resources.cross; break; temp = Properties.Resources.cross; break;
} }

View file

@ -139,5 +139,15 @@ namespace BetterJoyForCemu.Properties {
return ((System.Drawing.Bitmap)(obj)); return ((System.Drawing.Bitmap)(obj));
} }
} }
/// <summary>
/// Looks up a localized resource of type System.Drawing.Bitmap.
/// </summary>
internal static System.Drawing.Bitmap ultra {
get {
object obj = ResourceManager.GetObject("ultra", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
} }
} }

View file

@ -121,6 +121,9 @@
<data name="snes" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="snes" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icons\snes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Icons\snes.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>
<data name="ultra" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icons\ultra.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="pro" type="System.Resources.ResXFileRef, System.Windows.Forms"> <data name="pro" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>..\Icons\pro.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value> <value>..\Icons\pro.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data> </data>

View file

@ -104,4 +104,4 @@ A last thanks goes out to [dekuNukem](https://github.com/dekuNukem/Nintendo_Swit
Massive *thank you* to **all** code contributors! Massive *thank you* to **all** code contributors!
Icons (modified): "[Switch Pro Controller](https://thenounproject.com/term/nintendo-switch/930119/)", "[ Icons (modified): "[Switch Pro Controller](https://thenounproject.com/term/nintendo-switch/930119/)", "[
Switch Detachable Controller Left](https://thenounproject.com/remsing/uploads/?i=930115)", "[Switch Detachable Controller Right](https://thenounproject.com/remsing/uploads/?i=930121)" icons by Chad Remsing from [the Noun Project](http://thenounproject.com/). [Super Nintendo Controller](https://thenounproject.com/themizarkshow/collection/vectogram/?i=193592) icon by Mark Davis from the [the Noun Project](http://thenounproject.com/); icon modified by [Amy Alexander](https://www.linkedin.com/in/-amy-alexander/). Switch Detachable Controller Left](https://thenounproject.com/remsing/uploads/?i=930115)", "[Switch Detachable Controller Right](https://thenounproject.com/remsing/uploads/?i=930121)" icons by Chad Remsing from [the Noun Project](http://thenounproject.com/). [Super Nintendo Controller](https://thenounproject.com/themizarkshow/collection/vectogram/?i=193592) icon by Mark Davis from the [the Noun Project](http://thenounproject.com/); icon modified by [Amy Alexander](https://www.linkedin.com/in/-amy-alexander/). [Nintendo 64 Controller](https://thenounproject.com/icon/game-controller-193588/) icon by Mark Davis from the [the Noun Project](http://thenounproject.com/); icon modified by [Gino Moena](https://www.github.com/GinoMoena).