Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,4 @@ UpgradeLog*.htm

# Microsoft Fakes
FakesAssemblies/
/scr/.vs
64 changes: 55 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,75 @@
# NoCableLauncher
Rocksmith 2014 Launcher for playing without original RealTone cable (nocable fix).
Rocksmith 2014 Remastered Launcher for playing without original RealTone cable (nocable fix).

Working principle based on [this information](http://cs.rin.ru/forum/viewtopic.php?f=10&t=63705&p=1006201#p1006201).
Created by [Maxx53](https://github.com/Maxx53)
Improved by [Mywk](https://github.com/Mywk)

Multiplayer fix based on [AutoIt script](https://dl.dropboxusercontent.com/u/1288526/rocksmith2014_nocable_pbs.au3) by [phobos2077](https://github.com/phobos2077).
### Changelog


###### Version 2.0.1

- Fixed: No need to disable all audio devices, only conflicting devices will be automatically disabled and restored

###### Version 2.0

- New logo
- Crash fixes
- Code cleanup
- Interface re-design
- Automatic enable/disable of capture devices
- Several fixes for those using the onboard soundcard
- Automatic switching to secondary input if primary isn't plugged in

This project uses [Core Audio API](https://github.com/morphx666/CoreAudio).

### Downloads

[NoCableLauncher-m-binary.rar (Lastest version with multiplayer support)](https://www.dropbox.com/s/4a7l3ggd94jjd2z/NoCableLauncher-m-binary.rar)
[NoCableLauncher Version 2.0](https://github.com/Mywk/NoCableLauncher/releases/download/2.0/NoCableLauncher.zip)

### Getting Started
1) Unpack files to any folder.

2) Configure launcher using friendly UI by running "EditSettings.bat".
1) Unpack the file "NoCableLauncher" to any folder.

2) Open the file "NoCableLauncher".

3) Run "NoCableLauncher" to play Rocksmith 2014 using your own audio interface!

Note: If you want to edit the settings again you can simply open the file "NCL_EditSettings.bat".

### Onboard soundcard

For those who, like me, don't have an extra audio capture device, there are two available options for single player mode:

3) Run "NoCableLauncher.exe" for playing Rocksmith 2014 using your own audio interface!
###### Disable devices and re-enable on game close
All audio capture devices except the one used in game will be disabled when the game opens and re-enabled when the game closes.

Note: This prevents you from using other capture devices, for example if you want to be in a call while you play.

###### Prevent game from recognizing more devices
All audio capture devices except the one used in-game will be disabled when the game opens.

After the game is opened and in the main menu, press ALT-TAB to leave the game and press 'OK' on the message prompt, this will prevent the game from recognizing any other device and re-enable the disabled ones.

This allows you to use your microphone or any other device outside the game (assuming the game is not in exclusive mode).

### Setting Tips

![Settings Window](http://images.illuzor.com/uploads/rs14ncl.png)
![Settings Window](https://techcoders.net/images/content/ncl_screenshot.png)

* If you have Steam-licensed Rocksmith 2014, check the "Steam game" box, otherwise leave this checkbox and browse game EXE-file by pressing "..." button.
* "Device" сombobox contains all **active** found input audio devices in your system. Select the device connected to your guitar. If your device is not in the list, check the "Manual" box and set VID & PID values manually (find it in "Device manager"). VID & PID sets as "0000" means default non-USB input audio device, for example integrated Realtek microphone input.
* Press "OK" to save settings and close window or "Cancel" to close window without saving.
* To play multiplayer, check "Enable Multiplayer" box in the settings window and set **different** input devices for Player1 and Player2, otherwise multiplayer will not work! To activate Player 2 in game, select "Multiplayer" from game menu and press Ctrl+M (global hotkey).


### Extra Info

Working principle based on [this information](http://cs.rin.ru/forum/viewtopic.php?f=10&t=63705&p=1006201#p1006201).

Multiplayer fix based on [AutoIt script](https://dl.dropboxusercontent.com/u/1288526/rocksmith2014_nocable_pbs.au3) by [phobos2077](https://github.com/phobos2077).

This project uses [Core Audio API](https://github.com/morphx666/CoreAudio).

### Extra Credits

phobos2077, janabimustafa, Alexx999
21 changes: 13 additions & 8 deletions scr/NoCableLauncher.sln
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29020.237
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NoCableLauncher", "NoCableLauncher\NoCableLauncher.csproj", "{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
Release|x86 = Release|x86
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Debug|x86.ActiveCfg = Debug|x86
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Debug|x86.Build.0 = Debug|x86
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Release|x86.ActiveCfg = Release|x86
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Release|x86.Build.0 = Release|x86
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C677FB12-10B8-4E81-A0C3-EF03EF980DF9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DE94F8D8-99C2-429F-98B3-CEF0B36ED02E}
EndGlobalSection
EndGlobal
115 changes: 115 additions & 0 deletions scr/NoCableLauncher/Common.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
using NoCableLauncher.CoreAudioApi;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using static NoCableLauncher.Settings;

namespace NoCableLauncher
{
public static class Common
{
internal static SettingsClass.Settings settings = SettingsClass.Settings.Default;

public static BindingList<SoundDevice> devices = new BindingList<SoundDevice>();
private static MMDeviceCollection pDevices;
private static MMDeviceEnumerator DeviceEnumerator = new MMDeviceEnumerator();
private static string defaultID = "0000";

private static PolicyConfigClient pPolicyConfig = new PolicyConfigClient();

public static string GetPDeviceId(int index)
{
return pDevices[index].ID;
}

/// <summary>
/// Gets device VID and PID from given hardware id
/// </summary>
/// <param name="hardwareId"></param>
/// <returns>VID and PID as Tuple</returns>
public static Tuple<string, string> GetDeviceVidPid(string hardwareId)
{
string vid = defaultID;
string pid = defaultID;

if (hardwareId.Contains("PID_"))
{
vid = hardwareId.Substring(hardwareId.IndexOf("VID_") + 4, 4);
pid = hardwareId.Substring(hardwareId.IndexOf("PID_") + 4, 4);
}

return new Tuple<string, string>(vid, pid);
}

public static void LoadDeviceList()
{
devices.Clear();

pDevices = DeviceEnumerator.EnumerateAudioEndPoints(EDataFlow.eCapture, EDeviceState.Active | EDeviceState.Disabled);

for (int i = 0; i < pDevices.Count; i++)
{
var deviceVidPid = GetDeviceVidPid(pDevices[i].HardwareID);
devices.Add(new SoundDevice(pDevices[i].FriendlyName, deviceVidPid.Item1, deviceVidPid.Item2));
}

}

public static bool SetDeviceState(string guid, bool enabled = false)
{
if (guid != string.Empty)
{
pPolicyConfig.SetEndpointVisibility(guid, enabled);
return true;
}

return false;
}

private static List<string> DisabledEndpoints = new List<string>();

public static void DisableAllCaptureDevicesExcept(string guid)
{
for (int i = 0; i < pDevices.Count; i++)
{
if (pDevices[i].DeviceState == EDeviceState.Active && pDevices[i].ID != guid)
{
// We do not need to disable any device that doesn't conflict with the patched vid and pid
var deviceVidPid = GetDeviceVidPid(pDevices[i].HardwareID);
if (deviceVidPid.Item1 == settings.PID && deviceVidPid.Item2 == settings.VID)
{
DisabledEndpoints.Add(pDevices[i].ID);
SetDeviceState(pDevices[i].ID);
}
}
}
}

public static void ReEnableCaptureDevices()
{
foreach (var guid in DisabledEndpoints)
{
SetDeviceState(guid, true);
}
}

public static int GetDeviceIndex(string guid)
{
if (guid != string.Empty)
{
for (int i = 0; i < pDevices.Count; i++)
{
if (pDevices[i].ID == guid)
{
return i;
}
}
}

return 0;
}

}
}
8 changes: 6 additions & 2 deletions scr/NoCableLauncher/CoreAudioApi/Interfaces/IPolicyConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,13 @@ internal interface IPolicyConfig
int SetPropertyValue(string pszDeviceName, bool bFxStore, IntPtr key, IntPtr pv);

[PreserveSig]
int SetDefaultEndpoint(string pszDeviceName, ERole role);
int SetDefaultEndpoint(
[In] [MarshalAs(UnmanagedType.LPWStr)] string pszDeviceName,
[In] [MarshalAs(UnmanagedType.U4)] ERole role);

[PreserveSig]
int SetEndpointVisibility(string pszDeviceName, bool bVisible);
int SetEndpointVisibility(
[In] [MarshalAs(UnmanagedType.LPWStr)] string pszDeviceName,
[In] [MarshalAs(UnmanagedType.Bool)] bool bVisible);
}
}
15 changes: 15 additions & 0 deletions scr/NoCableLauncher/CoreAudioApi/MMDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,24 @@ public string ID
}
}

public NoCableLauncher.CoreAudioApi.EDeviceState DeviceState
{
get
{
NoCableLauncher.CoreAudioApi.EDeviceState Result;
Marshal.ThrowExceptionForHR(_RealDevice.GetState(out Result));
return Result;
}
}

internal MMDevice(IMMDevice realDevice)
{
_RealDevice = realDevice;
}

public IMMDevice GetRealDevice()
{
return _RealDevice;
}
}
}
1 change: 0 additions & 1 deletion scr/NoCableLauncher/EditSettings.bat

This file was deleted.

30 changes: 13 additions & 17 deletions scr/NoCableLauncher/HotKeyManager.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using System.Threading;
using System.Windows.Forms;

namespace NoCableLauncher
{
Expand All @@ -12,7 +12,7 @@ public static class HotKeyManager
public static int RegisterHotKey(Keys key, KeyModifiers modifiers)
{
_windowReadyEvent.WaitOne();
int id = System.Threading.Interlocked.Increment(ref _id);
int id = Interlocked.Increment(ref _id);
_wnd.Invoke(new RegisterHotKeyDelegate(RegisterHotKeyInternal), _hwnd, id, (uint)modifiers, (uint)key);
return id;
}
Expand All @@ -37,23 +37,19 @@ private static void UnRegisterHotKeyInternal(IntPtr hwnd, int id)

private static void OnHotKeyPressed(HotKeyEventArgs e)
{
if (HotKeyManager.HotKeyPressed != null)
{
HotKeyManager.HotKeyPressed(null, e);
}
HotKeyPressed?.Invoke(null, e);
}

private static volatile MessageWindow _wnd;
private static volatile IntPtr _hwnd;
private static ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
private static readonly ManualResetEvent _windowReadyEvent = new ManualResetEvent(false);
static HotKeyManager()
{
Thread messageLoop = new Thread(delegate()
Thread messageLoop = new Thread(delegate() { Application.Run(new MessageWindow()); })
{
Application.Run(new MessageWindow());
});
messageLoop.Name = "MessageLoopThread";
messageLoop.IsBackground = true;
Name = "MessageLoopThread",
IsBackground = true
};
messageLoop.Start();
}

Expand All @@ -62,7 +58,7 @@ private class MessageWindow : Form
public MessageWindow()
{
_wnd = this;
_hwnd = this.Handle;
_hwnd = Handle;
_windowReadyEvent.Set();
}

Expand All @@ -71,7 +67,7 @@ protected override void WndProc(ref Message m)
if (m.Msg == WM_HOTKEY)
{
HotKeyEventArgs e = new HotKeyEventArgs(m.LParam);
HotKeyManager.OnHotKeyPressed(e);
OnHotKeyPressed(e);
}

base.WndProc(ref m);
Expand All @@ -92,7 +88,7 @@ protected override void SetVisibleCore(bool value)
[DllImport("user32", SetLastError = true)]
private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

private static int _id = 0;
private static int _id;
}


Expand All @@ -103,8 +99,8 @@ public class HotKeyEventArgs : EventArgs

public HotKeyEventArgs(Keys key, KeyModifiers modifiers)
{
this.Key = key;
this.Modifiers = modifiers;
Key = key;
Modifiers = modifiers;
}

public HotKeyEventArgs(IntPtr hotKeyParam)
Expand Down
Binary file added scr/NoCableLauncher/Logo.ico
Binary file not shown.
Loading