├── FodyWeavers.xml ├── file-drop.gif ├── host-flow.gif ├── setup_demo.gif ├── guest-flow-pop-out.gif ├── nullDCNetplayLauncher ├── naomi.ico ├── Resources │ ├── 1.png │ ├── 2.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── coin.png │ ├── down.png │ ├── left.png │ ├── test.png │ ├── up.png │ ├── naomi.ico │ ├── right.png │ ├── start.png │ ├── base_full.png │ ├── settings.ico │ ├── naomi_nvmem.bin │ ├── nulldc-1-0-4-en-win.zip │ ├── round_publish_black_18dp.ico │ ├── round_publish_black_18dp.png │ ├── icons8-game-controller-26.ico │ ├── icons8-game-controller-26.png │ ├── round_multiple_stop_black_24dp.ico │ ├── round_multiple_stop_black_24dp.png │ ├── outline_highlight_alt_black_48dp.png │ ├── round_not_listed_location_black_18dp.ico │ ├── round_not_listed_location_black_18dp.png │ ├── launcher.cfg │ ├── Keyboard.qkc │ ├── GamePadMappingList.xml │ └── nullDC.cfg ├── Costura32 │ ├── XInputDotNetPure.dll │ └── XInputInterface.dll ├── Properties │ ├── Settings.settings │ ├── Settings.Designer.cs │ ├── AssemblyInfo.cs │ └── Resources.resx ├── FodyWeavers.xml ├── packages.config ├── app.config ├── ConnectionPreset.cs ├── DragLoadControl.Designer.cs ├── ControllerEngine.cs ├── DragLoadControl.resx ├── ControllerControl.resx ├── GamePadMapping.cs ├── SettingsControl.resx ├── FodyWeavers.xsd ├── DragLoadControl.cs ├── NetworkQuery.cs ├── JoinControl.resx ├── HostControl.resx ├── ControllerControl.Designer.cs ├── NetplayLaunchForm.Designer.cs ├── JoinControl.cs ├── Program.cs ├── HostControl.cs └── SettingsControl.cs ├── nullDCNetplayLauncher.sln ├── .gitignore ├── README.es.md └── README.md /FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /file-drop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/file-drop.gif -------------------------------------------------------------------------------- /host-flow.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/host-flow.gif -------------------------------------------------------------------------------- /setup_demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/setup_demo.gif -------------------------------------------------------------------------------- /guest-flow-pop-out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/guest-flow-pop-out.gif -------------------------------------------------------------------------------- /nullDCNetplayLauncher/naomi.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/naomi.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/1.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/2.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/3.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/4.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/5.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/6.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/coin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/coin.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/down.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/left.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/test.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/test.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/up.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/naomi.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/naomi.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/right.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/start.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/base_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/base_full.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/settings.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/settings.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/naomi_nvmem.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/naomi_nvmem.bin -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Costura32/XInputDotNetPure.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Costura32/XInputDotNetPure.dll -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Costura32/XInputInterface.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Costura32/XInputInterface.dll -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/nulldc-1-0-4-en-win.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/nulldc-1-0-4-en-win.zip -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/round_publish_black_18dp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/round_publish_black_18dp.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/round_publish_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/round_publish_black_18dp.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/icons8-game-controller-26.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/icons8-game-controller-26.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/icons8-game-controller-26.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/icons8-game-controller-26.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/round_multiple_stop_black_24dp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/round_multiple_stop_black_24dp.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/round_multiple_stop_black_24dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/round_multiple_stop_black_24dp.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/outline_highlight_alt_black_48dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/outline_highlight_alt_black_48dp.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/round_not_listed_location_black_18dp.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/round_not_listed_location_black_18dp.ico -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/round_not_listed_location_black_18dp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blueminder/nullDCNetplayLauncher/HEAD/nullDCNetplayLauncher/Resources/round_not_listed_location_black_18dp.png -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/launcher.cfg: -------------------------------------------------------------------------------- 1 | enable_mapper=0 2 | host_fps=63 3 | guest_fps=90 4 | custom_size=0 5 | width=640 6 | height=480 7 | maximized=0 8 | player1=joy1 9 | region=japan 10 | custom_cfg=0 11 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/Keyboard.qkc: -------------------------------------------------------------------------------- 1 | 5=Start 2 | 3=Test 3 | w=Up 4 | s=Down 5 | a=Left 6 | d=Right 7 | 8=Button_1 8 | 9=Button_2 9 | 0=Button_3 10 | u=Button_4 11 | i=Button_5 12 | o=Button_6 13 | 1=Coin 14 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/FodyWeavers.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | XInputDotNetPure 5 | 6 | 7 | XInputInterface 8 | 9 | 10 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace nullDCNetplayLauncher.Properties { 12 | 13 | 14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.5.0.0")] 16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { 17 | 18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 19 | 20 | public static Settings Default { 21 | get { 22 | return defaultInstance; 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // General Information about an assembly is controlled through the following 5 | // set of attributes. Change these attribute values to modify the information 6 | // associated with an assembly. 7 | [assembly: AssemblyTitle("nullDCNetplayLauncher")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("nullDCNetplayLauncher")] 12 | [assembly: AssemblyCopyright("")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Setting ComVisible to false makes the types in this assembly not visible 17 | // to COM components. If you need to access a type in this assembly from 18 | // COM, set the ComVisible attribute to true on that type. 19 | [assembly: ComVisible(false)] 20 | 21 | // The following GUID is for the ID of the typelib if this project is exposed to COM 22 | [assembly: Guid("5e28a32b-1d97-4647-b9ca-6fae8a5a94c8")] 23 | 24 | // Version information for an assembly consists of the following four values: 25 | // 26 | // Major Version 27 | // Minor Version 28 | // Build Number 29 | // Revision 30 | // 31 | // You can specify all the values or you can default the Build and Revision Numbers 32 | // by using the '*' as shown below: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("0.6.5.11")] 35 | [assembly: AssemblyFileVersion("0.6.5.11")] 36 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30011.22 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "nullDCNetplayLauncher", "nullDCNetplayLauncher\nullDCNetplayLauncher.csproj", "{5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Debug|x86 = Debug|x86 12 | Release|Any CPU = Release|Any CPU 13 | Release|x86 = Release|x86 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Debug|x86.ActiveCfg = Debug|x86 19 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Debug|x86.Build.0 = Debug|x86 20 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Release|Any CPU.ActiveCfg = Release|Any CPU 21 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Release|Any CPU.Build.0 = Release|Any CPU 22 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Release|x86.ActiveCfg = Debug|x86 23 | {5E28A32B-1D97-4647-B9CA-6FAE8A5A94C8}.Release|x86.Build.0 = Debug|x86 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {5089B39F-1C9D-486B-99C6-38069DEA924E} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/ConnectionPreset.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Xml.Serialization; 5 | 6 | namespace nullDCNetplayLauncher 7 | { 8 | public class ConnectionPresetList 9 | { 10 | public List ConnectionPresets = new List(); 11 | } 12 | public class ConnectionPreset 13 | { 14 | public string Name; 15 | public string IP; 16 | public string Port; 17 | public decimal Delay; 18 | public int Method; 19 | public string Region { get; set; } = "japan"; 20 | 21 | public override string ToString() 22 | { 23 | return Name; 24 | } 25 | 26 | public static ConnectionPresetList ReadPresetsFile() 27 | { 28 | string path = Launcher.GetDistributionRootDirectoryName() + "//ConnectionPresetList.xml"; 29 | ConnectionPresetList readPresetList; 30 | try 31 | { 32 | XmlSerializer serializer = 33 | new XmlSerializer(typeof(ConnectionPresetList)); 34 | FileStream fs = new FileStream(path, FileMode.Open); 35 | 36 | readPresetList = (ConnectionPresetList)serializer.Deserialize(fs); 37 | fs.Close(); 38 | } 39 | catch (Exception) 40 | { 41 | ConnectionPreset defaultPreset = new ConnectionPreset 42 | { 43 | Name = "Default", 44 | IP = "127.0.0.1", 45 | Port = "27886", 46 | Delay = 1, 47 | Method = 0, 48 | Region = "japan" 49 | }; 50 | readPresetList = new ConnectionPresetList(); 51 | readPresetList.ConnectionPresets.Add(defaultPreset); 52 | 53 | // generates a new file if it does not exist 54 | System.Xml.Serialization.XmlSerializer serializer = 55 | new System.Xml.Serialization.XmlSerializer(typeof(ConnectionPresetList)); 56 | StreamWriter writer = new StreamWriter(path); 57 | serializer.Serialize(writer.BaseStream, readPresetList); 58 | writer.Close(); 59 | } 60 | return readPresetList; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/DragLoadControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace nullDCNetplayLauncher 2 | { 3 | partial class DragLoadControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.picDragLoad = new System.Windows.Forms.PictureBox(); 32 | this.lblDragInfo = new System.Windows.Forms.Label(); 33 | ((System.ComponentModel.ISupportInitialize)(this.picDragLoad)).BeginInit(); 34 | this.SuspendLayout(); 35 | // 36 | // picDragLoad 37 | // 38 | this.picDragLoad.Image = global::nullDCNetplayLauncher.Properties.Resources.outline_highlight_alt_black_48dp; 39 | this.picDragLoad.InitialImage = global::nullDCNetplayLauncher.Properties.Resources.outline_highlight_alt_black_48dp; 40 | this.picDragLoad.Location = new System.Drawing.Point(36, 18); 41 | this.picDragLoad.Name = "picDragLoad"; 42 | this.picDragLoad.Size = new System.Drawing.Size(126, 120); 43 | this.picDragLoad.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 44 | this.picDragLoad.TabIndex = 0; 45 | this.picDragLoad.TabStop = false; 46 | // 47 | // lblDragInfo 48 | // 49 | this.lblDragInfo.Anchor = System.Windows.Forms.AnchorStyles.Top; 50 | this.lblDragInfo.Location = new System.Drawing.Point(19, 150); 51 | this.lblDragInfo.Name = "lblDragInfo"; 52 | this.lblDragInfo.Size = new System.Drawing.Size(161, 71); 53 | this.lblDragInfo.TabIndex = 1; 54 | this.lblDragInfo.Text = "Drag NAOMI ROMs && BIN Files Here"; 55 | this.lblDragInfo.TextAlign = System.Drawing.ContentAlignment.TopCenter; 56 | // 57 | // DragLoadControl 58 | // 59 | this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); 60 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 61 | this.Controls.Add(this.lblDragInfo); 62 | this.Controls.Add(this.picDragLoad); 63 | this.Name = "DragLoadControl"; 64 | this.Size = new System.Drawing.Size(199, 221); 65 | ((System.ComponentModel.ISupportInitialize)(this.picDragLoad)).EndInit(); 66 | this.ResumeLayout(false); 67 | 68 | } 69 | 70 | #endregion 71 | 72 | private System.Windows.Forms.PictureBox picDragLoad; 73 | private System.Windows.Forms.Label lblDragInfo; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/GamePadMappingList.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Default 6 | 2 7 | 1 8 | 3 9 | 5 10 | 4 11 | 6 12 | Coin 13 | Start 14 | 15 | 16 | 17 | 18 | Up 19 | Down 20 | Left 21 | Right 22 | 23 | true 24 | 25 | 26 | 6 axis 15 button gamepad with hat switch 27 | 2 28 | 1 29 | 30 | 5 31 | 4 32 | 6 33 | Coin 34 | Start 35 | Test 36 | 3 37 | 38 | 39 | Up 40 | Down 41 | Left 42 | Right 43 | 44 | false 45 | 46 | 47 | Controller (Xbox One For Windows) 48 | 2 49 | 4 50 | Coin 51 | 1 52 | 5 53 | Start 54 | 55 | 56 | 57 | 3 58 | 59 | 6 60 | Up 61 | Down 62 | Left 63 | Right 64 | 65 | false 66 | 67 | 68 | P4 Wired Gamepad V1.6 69 | 2 70 | 1 71 | 72 | 5 73 | 4 74 | 6 75 | Coin 76 | Start 77 | 78 | 3 79 | 80 | 6 81 | Up 82 | Down 83 | Left 84 | Right 85 | 86 | false 87 | 88 | 89 | Controller (XBOX 360 For Windows) 90 | 2 91 | 4 92 | Coin 93 | 1 94 | 5 95 | Start 96 | 97 | 98 | 99 | 3 100 | 101 | 6 102 | Up 103 | Down 104 | Left 105 | Right 106 | 107 | false 108 | 109 | 110 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/ControllerEngine.cs: -------------------------------------------------------------------------------- 1 | using OpenTK.Input; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Diagnostics; 5 | using System.IO; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Runtime.InteropServices; 9 | using System.Windows; 10 | using System.Windows.Threading; 11 | 12 | namespace nullDCNetplayLauncher 13 | { 14 | public class ControllerEngine : IDisposable 15 | { 16 | bool disposed; 17 | 18 | protected virtual void Dispose(bool disposing) 19 | { 20 | if (!disposed) 21 | { 22 | if (disposing) 23 | { 24 | //dispose managed resources 25 | } 26 | } 27 | //dispose unmanaged resources 28 | disposed = true; 29 | } 30 | 31 | public void Dispose() 32 | { 33 | clock.Stop(); 34 | Dispose(true); 35 | GC.SuppressFinalize(this); 36 | } 37 | 38 | public DispatcherTimer clock; 39 | private GamePadState oldgstate; 40 | 41 | // Event Declaration 42 | // GamePadAction: Triggered when the oldgstate is different from the current GamePadState 43 | public event EventHandler GamePadAction; 44 | 45 | private int clockspeed = 16; 46 | 47 | public ControllerEngine() 48 | { 49 | this.ActiveDevice = 0; 50 | oldgstate = GamePad.GetState(this.ActiveDevice); 51 | createNewTimer(); 52 | } 53 | private void createNewTimer() 54 | { 55 | clock = new DispatcherTimer(); 56 | clock.Tick += new EventHandler(checkGamePads); 57 | clock.Interval = new TimeSpan(0, 0, 0, 0, this.clockspeed); 58 | clock.Start(); 59 | } 60 | public int ActiveDevice { get; set; } 61 | 62 | public GamePadCapabilities CapabilitiesGamePad { get { return GamePad.GetCapabilities(this.ActiveDevice); } } 63 | 64 | public JoystickCapabilities CapabilitiesJoystick { get { return Joystick.GetCapabilities(this.ActiveDevice); } } 65 | 66 | protected virtual void OnGamePadAction(ActionEventArgs e) 67 | { 68 | EventHandler handler = GamePadAction; 69 | if (handler != null) 70 | { 71 | handler(this, e); 72 | } 73 | } 74 | 75 | private void checkGamePads(Object sender, EventArgs e) 76 | { 77 | ActionEventArgs args = new ActionEventArgs(this.ActiveDevice); 78 | if (!args.GamePadState.Equals(oldgstate)) 79 | { 80 | //call event 81 | OnGamePadAction(args); 82 | oldgstate = args.GamePadState; 83 | } 84 | if (!args.GamePadState.Triggers.Equals(oldgstate.Triggers)) 85 | { 86 | //call event 87 | OnGamePadAction(args); 88 | oldgstate = args.GamePadState; 89 | } 90 | 91 | } 92 | 93 | } 94 | 95 | public class ActionEventArgs : EventArgs 96 | { 97 | public ActionEventArgs() 98 | { 99 | this.Instance = 0; 100 | } 101 | 102 | public ActionEventArgs(int ControllerInstance) 103 | { 104 | this.Instance = ControllerInstance; 105 | } 106 | 107 | public int Instance { get; set; } 108 | 109 | public GamePadState GamePadState { get { return GamePad.GetState(this.Instance); } } 110 | 111 | public JoystickState JoystickState { get { return Joystick.GetState(this.Instance); } } 112 | 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | ################### 5 | # compiled source # 6 | ################### 7 | *.com 8 | *.class 9 | *.dll 10 | *.exe 11 | *.pdb 12 | *.dll.config 13 | *.cache 14 | *.suo 15 | # Include dlls if they’re in the NuGet packages directory 16 | !/packages/*/lib/*.dll 17 | # Include dlls if they're in the CommonReferences directory 18 | !*CommonReferences/*.dll 19 | #################### 20 | # VS Upgrade stuff # 21 | #################### 22 | _UpgradeReport_Files/ 23 | ############### 24 | # Directories # 25 | ############### 26 | bin/ 27 | obj/ 28 | TestResults/ 29 | ################### 30 | # Web publish log # 31 | ################### 32 | *.Publish.xml 33 | ############# 34 | # Resharper # 35 | ############# 36 | /_ReSharper.* 37 | *.ReSharper.* 38 | ############ 39 | # Packages # 40 | ############ 41 | # it’s better to unpack these files and commit the raw source 42 | # git has its own built in compression methods 43 | *.7z 44 | *.dmg 45 | *.gz 46 | *.iso 47 | *.jar 48 | *.rar 49 | *.tar 50 | *.zip 51 | ###################### 52 | # Logs and databases # 53 | ###################### 54 | *.log 55 | *.sqlite 56 | # OS generated files # 57 | ###################### 58 | .DS_Store? 59 | ehthumbs.db 60 | Icon? 61 | Thumbs.db 62 | 63 | 64 | # User-specific files 65 | *.user 66 | *.userosscache 67 | *.sln.docstates 68 | 69 | # User-specific files (MonoDevelop/Xamarin Studio) 70 | *.userprefs 71 | 72 | # Build results 73 | [Dd]ebug/ 74 | [Dd]ebugPublic/ 75 | [Rr]elease/ 76 | [Rr]eleases/ 77 | x64/ 78 | x86/ 79 | build/ 80 | bld/ 81 | [Bb]in/ 82 | [Oo]bj/ 83 | 84 | # Visual Studio 2015 cache/options directory 85 | .vs/ 86 | 87 | # MSTest test Results 88 | [Tt]est[Rr]esult*/ 89 | [Bb]uild[Ll]og.* 90 | 91 | # NUNIT 92 | *.VisualState.xml 93 | TestResult.xml 94 | 95 | # Build Results of an ATL Project 96 | [Dd]ebugPS/ 97 | [Rr]eleasePS/ 98 | dlldata.c 99 | 100 | # DNX 101 | project.lock.json 102 | artifacts/ 103 | 104 | *_i.c 105 | *_p.c 106 | *_i.h 107 | *.ilk 108 | *.meta 109 | *.obj 110 | *.pch 111 | *.pgc 112 | *.pgd 113 | *.rsp 114 | *.sbr 115 | *.tlb 116 | *.tli 117 | *.tlh 118 | *.tmp 119 | *.tmp_proj 120 | *.vspscc 121 | *.vssscc 122 | .builds 123 | *.pidb 124 | *.svclog 125 | *.scc 126 | 127 | # Chutzpah Test files 128 | _Chutzpah* 129 | 130 | # Visual C++ cache files 131 | ipch/ 132 | *.aps 133 | *.ncb 134 | *.opensdf 135 | *.sdf 136 | *.cachefile 137 | 138 | # Visual Studio profiler 139 | *.psess 140 | *.vsp 141 | *.vspx 142 | 143 | # TFS 2012 Local Workspace 144 | $tf/ 145 | 146 | # Guidance Automation Toolkit 147 | *.gpState 148 | 149 | # ReSharper is a .NET coding add-in 150 | _ReSharper*/ 151 | *.[Rr]e[Ss]harper 152 | *.DotSettings.user 153 | 154 | # JustCode is a .NET coding add-in 155 | .JustCode 156 | 157 | # TeamCity is a build add-in 158 | _TeamCity* 159 | 160 | # DotCover is a Code Coverage Tool 161 | *.dotCover 162 | 163 | # NCrunch 164 | _NCrunch_* 165 | .*crunch*.local.xml 166 | 167 | # MightyMoose 168 | *.mm.* 169 | AutoTest.Net/ 170 | 171 | # Web workbench (sass) 172 | .sass-cache/ 173 | 174 | # Installshield output folder 175 | [Ee]xpress/ 176 | 177 | # DocProject is a documentation generator add-in 178 | DocProject/buildhelp/ 179 | DocProject/Help/*.HxT 180 | DocProject/Help/*.HxC 181 | DocProject/Help/*.hhc 182 | DocProject/Help/*.hhk 183 | DocProject/Help/*.hhp 184 | DocProject/Help/Html2 185 | DocProject/Help/html 186 | 187 | # Click-Once directory 188 | publish/ 189 | 190 | # Publish Web Output 191 | *.[Pp]ublish.xml 192 | *.azurePubxml 193 | # TODO: Comment the next line if you want to checkin your web deploy settings 194 | # but database connection strings (with potential passwords) will be unencrypted 195 | *.pubxml 196 | *.publishproj 197 | 198 | # NuGet Packages 199 | *.nupkg 200 | # The packages folder can be ignored because of Package Restore 201 | **/packages/* 202 | # except build/, which is used as an MSBuild target. 203 | !**/packages/build/ 204 | # Uncomment if necessary however generally it will be regenerated when needed 205 | #!**/packages/repositories.config 206 | 207 | # Windows Azure Build Output 208 | csx/ 209 | *.build.csdef 210 | 211 | # Windows Store app package directory 212 | AppPackages/ 213 | 214 | # Visual Studio cache files 215 | # files ending in .cache can be ignored 216 | *.[Cc]ache 217 | # but keep track of directories ending in .cache 218 | !*.[Cc]ache/ 219 | 220 | # Others 221 | ClientBin/ 222 | [Ss]tyle[Cc]op.* 223 | ~$* 224 | *~ 225 | *.dbmdl 226 | *.dbproj.schemaview 227 | *.pfx 228 | *.publishsettings 229 | node_modules/ 230 | bower_components/ 231 | orleans.codegen.cs 232 | 233 | # RIA/Silverlight projects 234 | Generated_Code/ 235 | 236 | # Backup & report files from converting an old project file 237 | # to a newer Visual Studio version. Backup files are not needed, 238 | # because we have git ;-) 239 | _UpgradeReport_Files/ 240 | Backup*/ 241 | UpgradeLog*.XML 242 | UpgradeLog*.htm 243 | 244 | # SQL Server files 245 | *.mdf 246 | *.ldf 247 | 248 | # Business Intelligence projects 249 | *.rdl.data 250 | *.bim.layout 251 | *.bim_*.settings 252 | 253 | # Microsoft Fakes 254 | FakesAssemblies/ 255 | 256 | # Node.js Tools for Visual Studio 257 | .ntvs_analysis.dat 258 | 259 | # Visual Studio 6 build log 260 | *.plg 261 | 262 | # Visual Studio 6 workspace options file 263 | *.opt -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Resources/nullDC.cfg: -------------------------------------------------------------------------------- 1 | ;; nullDC config file;; 2 | [nullDC] 3 | Dynarec.Enabled=1 4 | Dynarec.DoConstantPropagation=1 5 | Dynarec.UnderclockFpu=0 6 | Dreamcast.Cable=1 7 | Dreamcast.RTC=1917526710 8 | Dreamcast.Region=0 9 | Dreamcast.Broadcast=0 10 | Emulator.AutoStart=0 11 | Emulator.NoConsole=0 12 | Dynarec.SafeMode=1 13 | 14 | [nullDC_plugins] 15 | GUI=nullDC_GUI_Win32.dll 16 | Current_PVR=drkPvr_Win32.dll 17 | Current_GDR=ImgReader_Win32.dll 18 | Current_AICA=nullAICA_Win32.dll 19 | Current_ARM=vbaARM_Win32.dll 20 | Current_ExtDevice=nullExtDev_Win32.dll 21 | Current_maple0_5=qkoJAMMAMaple_Win32.dll:0 22 | Current_maple1_5=NULL 23 | Current_maple2_5=NULL 24 | Current_maple3_5=NULL 25 | Current_maple0_0=NULL 26 | Current_maple0_1=NULL 27 | Current_maple0_2=NULL 28 | Current_maple0_3=NULL 29 | Current_maple0_4=NULL 30 | Current_maple1_0=NULL 31 | Current_maple1_1=NULL 32 | Current_maple1_2=NULL 33 | Current_maple1_3=NULL 34 | Current_maple1_4=NULL 35 | Current_maple2_0=NULL 36 | Current_maple2_1=NULL 37 | Current_maple2_2=NULL 38 | Current_maple2_3=NULL 39 | Current_maple2_4=NULL 40 | Current_maple3_0=NULL 41 | Current_maple3_1=NULL 42 | Current_maple3_2=NULL 43 | Current_maple3_3=NULL 44 | Current_maple3_4=NULL 45 | 46 | [nullDC_GUI] 47 | AutoHideMenu=0 48 | Fullscreen=0 49 | AlwaysOnTop=0 50 | 51 | [drkpvr] 52 | Emulation.AlphaSortMode=1 53 | Emulation.PaletteMode=1 54 | Emulation.ModVolMode=1 55 | Emulation.ZBufferMode=0 56 | Emulation.TexCacheMode=0 57 | OSD.ShowFPS=1 58 | OSD.ShowStats=0 59 | Video.ResolutionMode=2 60 | Video.VSync=0 61 | Enhancements.MultiSampleCount=0 62 | Enhancements.MultiSampleQuality=0 63 | Enhancements.AspectRatioMode=1 64 | 65 | [ImageReader] 66 | PatchRegion=0 67 | LoadDefaultImage=0 68 | DefaultImage=default.gdi 69 | LastImage=c:\game.gdi 70 | 71 | [nullAica] 72 | BufferSize=2048 73 | LimitFPS=0 74 | HW_mixing=0 75 | SoundRenderer=1 76 | GlobalFocus=1 77 | BufferCount=1 78 | CDDAMute=0 79 | GlobalMute=0 80 | DSPEnabled=0 81 | Volume=90 82 | 83 | [nullExtDev] 84 | mode=0 85 | adapter=0 86 | 87 | [ndc_hookjoy] 88 | PortA_I_SERVICE_KEY_1=50 89 | PortA_I_TEST_KEY_1=88 90 | PortA_I_SERVICE_KEY_2=117 91 | PortA_I_TEST_KEY_2=67 92 | PortA_I_START_KEY=49 93 | PortA_I_COIN_KEY=13 94 | PortA_I_UP_KEY=1 95 | PortA_I_DOWN_KEY=83 96 | PortA_I_LEFT_KEY=65 97 | PortA_I_RIGHT_KEY=68 98 | PortA_I_BTN0_KEY=56 99 | PortA_I_BTN1_KEY=57 100 | PortA_I_BTN2_KEY=48 101 | PortA_I_BTN3_KEY=85 102 | PortA_I_BTN4_KEY=73 103 | PortA_I_BTN5_KEY=79 104 | local_port=0 105 | server_addr=192.168.1.33 106 | server_port=11122 107 | PortB_I_SERVICE_KEY_1=109 108 | PortB_I_TEST_KEY_1=107 109 | PortB_I_SERVICE_KEY_2=117 110 | PortB_I_TEST_KEY_2=118 111 | PortB_I_START_KEY=88 112 | PortB_I_COIN_KEY=53 113 | PortB_I_UP_KEY=38 114 | PortB_I_DOWN_KEY=40 115 | PortB_I_LEFT_KEY=37 116 | PortB_I_RIGHT_KEY=39 117 | PortB_I_BTN0_KEY=74 118 | PortB_I_BTN1_KEY=75 119 | PortB_I_BTN2_KEY=76 120 | PortB_I_BTN3_KEY=78 121 | PortB_I_BTN4_KEY=77 122 | PortB_I_BTN5_KEY=188 123 | PortC_I_SERVICE_KEY_1=115 124 | PortC_I_TEST_KEY_1=116 125 | PortC_I_SERVICE_KEY_2=117 126 | PortC_I_TEST_KEY_2=118 127 | PortC_I_START_KEY=49 128 | PortC_I_COIN_KEY=53 129 | PortC_I_UP_KEY=38 130 | PortC_I_DOWN_KEY=40 131 | PortC_I_LEFT_KEY=37 132 | PortC_I_RIGHT_KEY=39 133 | PortC_I_BTN0_KEY=90 134 | PortC_I_BTN1_KEY=88 135 | PortC_I_BTN2_KEY=67 136 | PortC_I_BTN3_KEY=65 137 | PortC_I_BTN4_KEY=83 138 | PortC_I_BTN5_KEY=68 139 | PortD_I_SERVICE_KEY_1=115 140 | PortD_I_TEST_KEY_1=116 141 | PortD_I_SERVICE_KEY_2=117 142 | PortD_I_TEST_KEY_2=118 143 | PortD_I_START_KEY=49 144 | PortD_I_COIN_KEY=53 145 | PortD_I_UP_KEY=38 146 | PortD_I_DOWN_KEY=40 147 | PortD_I_LEFT_KEY=37 148 | PortD_I_RIGHT_KEY=39 149 | PortD_I_BTN0_KEY=90 150 | PortD_I_BTN1_KEY=88 151 | PortD_I_BTN2_KEY=67 152 | PortD_I_BTN3_KEY=65 153 | PortD_I_BTN4_KEY=83 154 | PortD_I_BTN5_KEY=68 155 | 156 | [drkMaple] 157 | VMU.Show=1 158 | Mouse.Sensitivity=100 159 | ShowVMU=1 160 | 161 | [Xmaple] 162 | Controller.DeadZone=25 163 | PuruPuru.UseRealFrequency=1 164 | PuruPuru.Length=175 165 | PuruPuru.Intensity=100 166 | 167 | [PuruPuru_Pad_1] 168 | l_shoulder=B4 169 | r_shoulder=B5 170 | a_button=B0 171 | b_button=B2 172 | x_button=B1 173 | y_button=B3 174 | start_button=-1 175 | dpad_up=H1 176 | dpad_down=H4 177 | dpad_left=H8 178 | dpad_right=H2 179 | main_x_left=H8 180 | main_x_right=H2 181 | main_y_up=H1 182 | main_y_down=H4 183 | halfpress=-1 184 | deadzone=24 185 | keyboard=0 186 | joy_id=0 187 | controllertype=0 188 | eventnum=0 189 | 190 | [PuruPuru_Pad_2] 191 | l_shoulder=-1 192 | r_shoulder=-1 193 | a_button=-1 194 | b_button=-1 195 | x_button=-1 196 | y_button=-1 197 | start_button=-1 198 | dpad_up=-1 199 | dpad_down=-1 200 | dpad_left=-1 201 | dpad_right=-1 202 | main_x_left=-1 203 | main_x_right=-1 204 | main_y_up=-1 205 | main_y_down=-1 206 | halfpress=-1 207 | deadzone=24 208 | keyboard=0 209 | joy_id=0 210 | controllertype=0 211 | eventnum=0 212 | 213 | [PuruPuru_Pad_3] 214 | l_shoulder=-1 215 | r_shoulder=-1 216 | a_button=-1 217 | b_button=-1 218 | x_button=-1 219 | y_button=-1 220 | start_button=-1 221 | dpad_up=-1 222 | dpad_down=-1 223 | dpad_left=-1 224 | dpad_right=-1 225 | main_x_left=-1 226 | main_x_right=-1 227 | main_y_up=-1 228 | main_y_down=-1 229 | halfpress=-1 230 | deadzone=24 231 | keyboard=0 232 | joy_id=0 233 | controllertype=0 234 | eventnum=0 235 | 236 | [PuruPuru_Pad_4] 237 | l_shoulder=-1 238 | r_shoulder=-1 239 | a_button=-1 240 | b_button=-1 241 | x_button=-1 242 | y_button=-1 243 | start_button=-1 244 | dpad_up=-1 245 | dpad_down=-1 246 | dpad_left=-1 247 | dpad_right=-1 248 | main_x_left=-1 249 | main_x_right=-1 250 | main_y_up=-1 251 | main_y_down=-1 252 | halfpress=-1 253 | deadzone=24 254 | keyboard=0 255 | joy_id=0 256 | controllertype=0 257 | eventnum=0 258 | 259 | [Netplay] 260 | Enabled=0 261 | Hosting=0 262 | Host=0.0.0.0 263 | Port=27886 264 | Delay=1 265 | 266 | [qkoJAMMA] 267 | player1=joy1 268 | backup=NULL 269 | player2=NULL 270 | 271 | [Replay] 272 | Enabled=0 273 | Playback=0 274 | File= 275 | 276 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/DragLoadControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/ControllerControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/GamePadMapping.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Reflection; 5 | using System.Xml.Serialization; 6 | 7 | namespace nullDCNetplayLauncher 8 | { 9 | public class GamePadMappingList 10 | { 11 | public List GamePadMappings = new List(); 12 | } 13 | public class GamePadMapping 14 | { 15 | public string Name; 16 | public string Y { get; set; } = ""; 17 | public string A { get; set; } = ""; 18 | public string Back { get; set; } = ""; 19 | public string X { get; set; } = ""; 20 | public string B { get; set; } = ""; 21 | public string Start { get; set; } = ""; 22 | public string LeftStick { get; set; } = ""; 23 | public string RightStick { get; set; } = ""; 24 | public string LeftShoulder { get; set; } = ""; 25 | public string RightShoulder { get; set; } = ""; 26 | public string LeftTrigger { get; set; } = ""; 27 | public string RightTrigger { get; set; } = ""; 28 | public string IsUp { get; set; } = ""; 29 | public string IsDown { get; set; } = ""; 30 | public string IsLeft { get; set; } = ""; 31 | public string IsRight { get; set; } = ""; 32 | public string BigButton { get; set; } = ""; 33 | 34 | public string Button11 { get; set; } = ""; 35 | public string Button12 { get; set; } = ""; 36 | public string Button13 { get; set; } = ""; 37 | public string Button14 { get; set; } = ""; 38 | public string Button15 { get; set; } = ""; 39 | 40 | 41 | public Boolean Default { get; set; } = false; 42 | 43 | public Dictionary ToDictionary() 44 | { 45 | Dictionary rDict = new Dictionary(); 46 | rDict.Add("Y", Y); 47 | rDict.Add("A", A); 48 | rDict.Add("Back", Back); 49 | rDict.Add("X", X); 50 | rDict.Add("B", B); 51 | rDict.Add("Start", Start); 52 | rDict.Add("LeftStick", LeftStick); 53 | rDict.Add("RightStick", RightStick); 54 | rDict.Add("LeftShoulder", LeftShoulder); 55 | rDict.Add("RightShoulder", RightShoulder); 56 | rDict.Add("LeftTrigger", LeftTrigger); 57 | rDict.Add("RightTrigger", RightTrigger); 58 | rDict.Add("BigButton", BigButton); 59 | rDict.Add("Up", IsUp); 60 | rDict.Add("Down", IsDown); 61 | rDict.Add("Left", IsLeft); 62 | rDict.Add("Right", IsRight); 63 | rDict.Add("Button11", Button11); 64 | rDict.Add("Button12", Button12); 65 | rDict.Add("Button13", Button13); 66 | rDict.Add("Button14", Button14); 67 | rDict.Add("Button15", Button15); 68 | 69 | return rDict; 70 | } 71 | 72 | public object this[string propertyName] 73 | { 74 | get 75 | { 76 | if (propertyName.Equals("Left")) 77 | propertyName = "LeftTrigger"; 78 | else if(propertyName.Equals("Right")) 79 | propertyName = "RightTrigger"; 80 | System.Diagnostics.Debug.WriteLine(propertyName); 81 | PropertyInfo property = GetType().GetProperty(propertyName); 82 | return property.GetValue(this, null); 83 | } 84 | set 85 | { 86 | if (propertyName.Equals("Left")) 87 | propertyName = "LeftTrigger"; 88 | else if (propertyName.Equals("Right")) 89 | propertyName = "RightTrigger"; 90 | System.Diagnostics.Debug.WriteLine(propertyName); 91 | PropertyInfo property = GetType().GetProperty(propertyName); 92 | property.SetValue(this, value, null); 93 | } 94 | } 95 | 96 | public override string ToString() 97 | { 98 | return Name; 99 | } 100 | 101 | public static GamePadMappingList ReadMappingsFile() 102 | { 103 | string path = Launcher.rootDir + "GamePadMappingList.xml"; 104 | GamePadMappingList readMappingList; 105 | 106 | Launcher.RestoreGamePadMappings(); 107 | 108 | try 109 | { 110 | XmlSerializer serializer = 111 | new XmlSerializer(typeof(GamePadMappingList)); 112 | FileStream fs = new FileStream(path, FileMode.Open); 113 | 114 | readMappingList = (GamePadMappingList)serializer.Deserialize(fs); 115 | fs.Close(); 116 | } 117 | catch (Exception) 118 | { 119 | GamePadMapping defaultMapping = new GamePadMapping 120 | { 121 | Name = "Default", 122 | IsUp = "Up", 123 | IsDown = "Down", 124 | IsLeft = "Left", 125 | IsRight = "Right", 126 | A = "1", 127 | Y = "2", 128 | Back = "3", 129 | B = "4", 130 | X = "5", 131 | Start = "6", 132 | LeftStick = "Coin", 133 | RightStick = "Start", 134 | LeftShoulder = "", 135 | RightShoulder = "", 136 | LeftTrigger = "", 137 | RightTrigger = "", 138 | BigButton = "", 139 | Button11 = "Coin", 140 | }; 141 | readMappingList = new GamePadMappingList(); 142 | readMappingList.GamePadMappings.Add(defaultMapping); 143 | 144 | // generates a new file if it does not exist 145 | System.Xml.Serialization.XmlSerializer serializer = 146 | new System.Xml.Serialization.XmlSerializer(typeof(GamePadMappingList)); 147 | StreamWriter writer = new StreamWriter(path); 148 | serializer.Serialize(writer.BaseStream, readMappingList); 149 | writer.Close(); 150 | } 151 | return readMappingList; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/SettingsControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 124 | xAAADsQBlSsOGwAAALFJREFUOE+tkDESwiAQRbmA17C2tKb2EBbeICfKEeQGXkZNFWho1/wdlsEMgXVM 125 | 8cJC9r9ZMET0F/yJMZ6AHK73LaTZJzhY7muhEgj8Y7gRQO3fz3C/nPO+JzFhehEC4/HAIamxqgRLw7WU 126 | SBiT9MKA30DGFoF2fGDKMFap1W8gAoBarpMEXfIVAOoFfhPnHFlrm7AAY6RgHhU/0ODnsMmXYM1ugh5N 127 | gZaq4Beqh3rIfADNkAPZUpn57QAAAABJRU5ErkJggg== 128 | 129 | 130 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/FodyWeavers.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks 13 | 14 | 15 | 16 | 17 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. 18 | 19 | 20 | 21 | 22 | A list of unmanaged 32 bit assembly names to include, delimited with line breaks. 23 | 24 | 25 | 26 | 27 | A list of unmanaged 64 bit assembly names to include, delimited with line breaks. 28 | 29 | 30 | 31 | 32 | The order of preloaded assemblies, delimited with line breaks. 33 | 34 | 35 | 36 | 37 | 38 | This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. 39 | 40 | 41 | 42 | 43 | Controls if .pdbs for reference assemblies are also embedded. 44 | 45 | 46 | 47 | 48 | Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. 49 | 50 | 51 | 52 | 53 | As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. 54 | 55 | 56 | 57 | 58 | Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. 59 | 60 | 61 | 62 | 63 | Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. 64 | 65 | 66 | 67 | 68 | A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | 69 | 70 | 71 | 72 | 73 | A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. 74 | 75 | 76 | 77 | 78 | A list of unmanaged 32 bit assembly names to include, delimited with |. 79 | 80 | 81 | 82 | 83 | A list of unmanaged 64 bit assembly names to include, delimited with |. 84 | 85 | 86 | 87 | 88 | The order of preloaded assemblies, delimited with |. 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. 97 | 98 | 99 | 100 | 101 | A comma-separated list of error codes that can be safely ignored in assembly verification. 102 | 103 | 104 | 105 | 106 | 'false' to turn off automatic generation of the XML Schema file. 107 | 108 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/DragLoadControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.IO; 11 | using System.IO.Compression; 12 | using System.Linq.Expressions; 13 | 14 | namespace nullDCNetplayLauncher 15 | { 16 | public partial class DragLoadControl : UserControl 17 | { 18 | public DragLoadControl() 19 | { 20 | InitializeComponent(); 21 | this.AllowDrop = true; 22 | this.DragEnter += new System.Windows.Forms.DragEventHandler(DragLoadControl_DragEnter); 23 | this.DragDrop += new System.Windows.Forms.DragEventHandler(DragLoadControl_DragDrop); 24 | } 25 | 26 | private void DragLoadControl_DragEnter(object sender, DragEventArgs e) 27 | { 28 | if (e.Data.GetDataPresent(DataFormats.FileDrop)) 29 | e.Effect = DragDropEffects.Copy; 30 | else 31 | e.Effect = DragDropEffects.None; 32 | } 33 | 34 | private void DragLoadControl_DragDrop(object sender, DragEventArgs e) 35 | { 36 | string[] files = (string[])e.Data.GetData(DataFormats.FileDrop); 37 | foreach (string file in files) 38 | { 39 | string path = files[0]; 40 | string destpath = Launcher.rootDir + "nulldc-1-0-4-en-win\\"; 41 | 42 | if (Path.GetExtension(path).Equals(".bin")) 43 | { 44 | destpath += "data\\" + Path.GetFileName(files[0]); 45 | if (File.Exists(destpath)) 46 | { 47 | File.SetAttributes(destpath, FileAttributes.Normal); 48 | } 49 | if (path == destpath) 50 | { 51 | MessageBox.Show("Your file is already in the correct place, you silly billy."); 52 | return; 53 | } 54 | else 55 | { 56 | lblDragInfo.Text = "Copying BIN..."; 57 | File.Copy(path, destpath, true); 58 | File.SetAttributes(destpath, FileAttributes.ReadOnly); 59 | lblDragInfo.Text = $"BIN copied to {Launcher.ExtractRelativePath(destpath)}"; 60 | } 61 | } 62 | else if (Path.GetExtension(path).Equals(".qjc")) 63 | { 64 | lblDragInfo.Text = "Copying QJC..."; 65 | destpath += "qkoJAMMA\\" + Path.GetFileName(files[0]); 66 | if (File.Exists(destpath)) 67 | { 68 | File.SetAttributes(destpath, FileAttributes.Normal); 69 | } 70 | File.Copy(path, destpath, true); 71 | lblDragInfo.Text = $"QJC copied to {Launcher.ExtractRelativePath(destpath)}"; 72 | } 73 | else if (Path.GetExtension(path).Equals(".qkc")) 74 | { 75 | lblDragInfo.Text = "Copying QKC..."; 76 | destpath += "qkoJAMMA\\" + Path.GetFileName(files[0]); 77 | if (File.Exists(destpath)) 78 | { 79 | File.SetAttributes(destpath, FileAttributes.Normal); 80 | } 81 | File.Copy(path, destpath, true); 82 | lblDragInfo.Text = $"QKC copied to {Launcher.ExtractRelativePath(destpath)}"; 83 | } 84 | else if (Path.GetFileName(path) == "nullDC.cfg") 85 | { 86 | lblDragInfo.Text = "Copying CFG..."; 87 | destpath += Path.GetFileName(files[0]); 88 | if (File.Exists(destpath)) 89 | { 90 | File.SetAttributes(destpath, FileAttributes.Normal); 91 | } 92 | File.Copy(path, destpath, true); 93 | lblDragInfo.Text = $"nullDC.cfg copied to {Launcher.ExtractRelativePath(destpath)}. Restart to restore defaults."; 94 | } 95 | else if (Path.GetExtension(path).Equals(".zip")) 96 | { 97 | bool zipHasEntry = false; 98 | var folderName = Path.GetFileNameWithoutExtension(files[0]); 99 | Launcher.Game GamesJsonEntry = null; 100 | if (Launcher.GamesJson != null) 101 | { 102 | try 103 | { 104 | GamesJsonEntry = Launcher.GamesJson.Where(g => g.Name == folderName).First(); 105 | if (GamesJsonEntry != null && GamesJsonEntry.Assets.Count() > 0) 106 | { 107 | zipHasEntry = true; 108 | } 109 | } 110 | catch (Exception) { }; 111 | } 112 | 113 | destpath += "roms\\" + folderName; 114 | Directory.CreateDirectory(destpath); 115 | lblDragInfo.Text = "Extracting ROM..."; 116 | if (File.Exists(path)) 117 | { 118 | ZipArchive archive = ZipFile.OpenRead(path); 119 | if (zipHasEntry) 120 | { 121 | Program.ShowConsoleWindow(); 122 | Console.Clear(); 123 | } 124 | foreach (ZipArchiveEntry entry in archive.Entries) 125 | { 126 | Launcher.Asset asset = null; 127 | 128 | if (GamesJsonEntry != null) 129 | asset = GamesJsonEntry.Assets.Where(a => a.Name == entry.Name).First(); 130 | 131 | if (zipHasEntry) 132 | { 133 | entry.ExtractToFile(Path.Combine(destpath, asset.LocalName()), true); 134 | var verifiedString = asset.VerifyFile(Path.Combine(destpath, asset.LocalName())); 135 | Console.WriteLine(verifiedString); 136 | } 137 | else 138 | { 139 | entry.ExtractToFile(Path.Combine(destpath, entry.FullName), true); 140 | } 141 | } 142 | if (zipHasEntry) 143 | { 144 | Console.WriteLine("\nPress any key to continue."); 145 | Console.ReadKey(); 146 | Program.HideConsoleWindow(); 147 | } 148 | 149 | } 150 | lblDragInfo.Text = $"Rom Extracted to {Launcher.ExtractRelativePath(destpath)}"; 151 | } 152 | } 153 | 154 | 155 | } 156 | 157 | } 158 | } 159 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/NetworkQuery.cs: -------------------------------------------------------------------------------- 1 | using CG.Web.MegaApiClient; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.IO.Compression; 6 | using System.Linq; 7 | using System.Net; 8 | using System.Net.NetworkInformation; 9 | using System.Net.Sockets; 10 | using System.Text; 11 | using System.Text.RegularExpressions; 12 | using System.Threading.Tasks; 13 | using System.Web.UI.WebControls; 14 | using WebClient = System.Net.WebClient; 15 | 16 | namespace nullDCNetplayLauncher 17 | { 18 | public class NetworkQuery 19 | { 20 | public Dictionary LocalIPsByNetwork { get; set; } 21 | 22 | public NetworkQuery() 23 | { 24 | LocalIPsByNetwork = GetIPsByNetwork(); 25 | } 26 | 27 | // https://stackoverflow.com/questions/11412956/what-is-the-best-way-of-validating-an-ip-address 28 | public static bool ValidateIPv4(string ipString) 29 | { 30 | if (String.IsNullOrWhiteSpace(ipString)) 31 | { 32 | return false; 33 | } 34 | 35 | string[] splitValues = ipString.Split('.'); 36 | if (splitValues.Length != 4) 37 | { 38 | return false; 39 | } 40 | 41 | byte tempForParsing; 42 | 43 | return splitValues.All(r => byte.TryParse(r, out tempForParsing)); 44 | } 45 | 46 | /// 47 | /// This utility function displays all the IPv4 addresses of the local computer. 48 | /// 49 | /// https://blog.stephencleary.com/2009/05/getting-local-ip-addresses.html 50 | public static Dictionary GetIPsByNetwork() 51 | { 52 | var IPsByNetwork = new Dictionary(); 53 | 54 | var externalIP = GetExternalIP(); 55 | if (externalIP != null) 56 | IPsByNetwork.Add("External", externalIP); 57 | 58 | NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); 59 | 60 | foreach (NetworkInterface network in networkInterfaces) 61 | { 62 | IPInterfaceProperties properties = network.GetIPProperties(); 63 | foreach (IPAddressInformation address in properties.UnicastAddresses) 64 | { 65 | if (address.Address.AddressFamily != AddressFamily.InterNetwork) 66 | continue; 67 | 68 | if (IPAddress.IsLoopback(address.Address)) 69 | continue; 70 | 71 | IPsByNetwork[network.Name] = address.Address.ToString(); 72 | } 73 | } 74 | 75 | return IPsByNetwork; 76 | } 77 | 78 | public static string GetExternalIP() 79 | { 80 | try 81 | { 82 | string externalIP; 83 | externalIP = (new WebClient()).DownloadString("http://checkip.dyndns.org/"); 84 | externalIP = (new Regex(@"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}")) 85 | .Matches(externalIP)[0].ToString(); 86 | return externalIP; 87 | } 88 | catch { return null; } 89 | } 90 | 91 | public static String GetRadminHostIP() 92 | { 93 | String radminHostIP; 94 | try 95 | { 96 | radminHostIP = GetIPsByNetwork()["Radmin VPN"]; 97 | } 98 | catch 99 | { 100 | radminHostIP = null; 101 | } 102 | return radminHostIP; 103 | } 104 | 105 | public static void DownloadReferenceUrl(Launcher.Game game, bool clearCache = true) 106 | { 107 | string displayName; 108 | if (game.Name.Length > 0) 109 | displayName = game.Name; 110 | else 111 | displayName = game.ID; 112 | 113 | string workingDir = ""; 114 | if (game.Root == "roms" || game.Root == "data") 115 | { 116 | workingDir = Path.Combine(Launcher.rootDir, "nulldc-1-0-4-en-win", game.Root); 117 | } 118 | else 119 | { 120 | Console.WriteLine("no valid root found in reference entry"); 121 | return; 122 | } 123 | var di = new DirectoryInfo(workingDir); 124 | di.Attributes |= FileAttributes.Normal; 125 | var zipPath = Path.Combine(workingDir, $"{Path.GetFileNameWithoutExtension(game.ReferenceUrl)}.zip"); 126 | 127 | if (!File.Exists(zipPath)) 128 | { 129 | Console.WriteLine($"Downloading {displayName}..."); 130 | var referenceUri = new Uri(game.ReferenceUrl); 131 | if (referenceUri.Host == "mega.nz") 132 | { 133 | MegaApiClient client = new MegaApiClient(); 134 | client.LoginAnonymous(); 135 | 136 | INodeInfo node = client.GetNodeFromLink(referenceUri); 137 | 138 | Console.WriteLine($"Downloading {node.Name}"); 139 | client.DownloadFile(referenceUri, zipPath); 140 | 141 | client.Logout(); 142 | } 143 | else 144 | { 145 | using (WebClient client = new WebClient()) 146 | { 147 | Console.WriteLine($"Downloading {Path.GetFileName(referenceUri.LocalPath)}"); 148 | client.DownloadFile(referenceUri, 149 | zipPath); 150 | } 151 | } 152 | Console.WriteLine($"Download Complete"); 153 | } 154 | 155 | Console.WriteLine($"Extracting...\n"); 156 | 157 | string extractPath; 158 | if (game.Root == "roms") 159 | { 160 | extractPath = Path.Combine(workingDir, displayName); 161 | Directory.CreateDirectory(extractPath); 162 | } 163 | else 164 | { 165 | extractPath = workingDir; 166 | } 167 | 168 | using (ZipArchive archive = ZipFile.OpenRead(zipPath)) 169 | { 170 | List files = game.Assets; 171 | foreach (ZipArchiveEntry entry in archive.Entries) 172 | { 173 | try 174 | { 175 | var fileEntry = files.Where(f => f.Name == entry.Name).First(); 176 | if (fileEntry != null) 177 | { 178 | var destinationFile = Path.Combine(extractPath, fileEntry.LocalName()); 179 | entry.ExtractToFile(destinationFile, true); 180 | Console.WriteLine(fileEntry.VerifyFile(destinationFile)); 181 | } 182 | 183 | } 184 | catch (Exception) { } 185 | } 186 | } 187 | 188 | if(clearCache) 189 | File.Delete(zipPath); 190 | 191 | Console.WriteLine($"\nPress any key to continue."); 192 | Console.ReadKey(); 193 | } 194 | 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/JoinControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 124 | xAAADsQBlSsOGwAAAKdJREFUOE/tkjEOwyAMRZlzLJgRbByuvQgnara2UmF1+RYgIDTkAEV6wcH+TwwI 125 | IhLtijFuiXvik0G95Xa3ODsR3Lz3ZIxhUOMMPcwWyj9/0gCGKgjuj52x1lIIoetPBVLKilKKXs83o7Xu 126 | elkyF5RACbeSsl8SjJQboV4KzmgEzFLgnDvcBHPgkgCh8Qz8BScCBFraF7kUzMDgL9CvgiwZOQhHiEh8 127 | AZUG69nGtx0DAAAAAElFTkSuQmCC 128 | 129 | 130 | 131 | 132 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 133 | xAAADsQBlSsOGwAAAHhJREFUOE9j+PbtWzgQvwHi/yRikJ5wkAFvtAvW/GcInkMSBukB6QUZgFUBMRis 134 | F9mAD+8/EoWHswGk4kFqADY/I2NktbQ1AJ2PLg7CMAPuFM8/hqEBnY8uDsIwA2SQDUFXiKwZWRyEwQaA 135 | AMwQkABIEYgmDn/7DwBpTOrUXkrGYgAAAABJRU5ErkJggg== 136 | 137 | 138 | 139 | 140 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 141 | xAAADsQBlSsOGwAAALFJREFUOE+tkDESwiAQRbmA17C2tKb2EBbeICfKEeQGXkZNFWho1/wdlsEMgXVM 142 | 8cJC9r9ZMET0F/yJMZ6AHK73LaTZJzhY7muhEgj8Y7gRQO3fz3C/nPO+JzFhehEC4/HAIamxqgRLw7WU 143 | SBiT9MKA30DGFoF2fGDKMFap1W8gAoBarpMEXfIVAOoFfhPnHFlrm7AAY6RgHhU/0ODnsMmXYM1ugh5N 144 | gZaq4Beqh3rIfADNkAPZUpn57QAAAABJRU5ErkJggg== 145 | 146 | 147 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/HostControl.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | 123 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 124 | xAAADsQBlSsOGwAAAKdJREFUOE/tkjEOwyAMRZlzLJgRbByuvQgnara2UmF1+RYgIDTkAEV6wcH+TwwI 125 | IhLtijFuiXvik0G95Xa3ODsR3Lz3ZIxhUOMMPcwWyj9/0gCGKgjuj52x1lIIoetPBVLKilKKXs83o7Xu 126 | elkyF5RACbeSsl8SjJQboV4KzmgEzFLgnDvcBHPgkgCh8Qz8BScCBFraF7kUzMDgL9CvgiwZOQhHiEh8 127 | AZUG69nGtx0DAAAAAElFTkSuQmCC 128 | 129 | 130 | 131 | True 132 | 133 | 134 | 135 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 136 | xAAADsQBlSsOGwAAAHhJREFUOE9j+PbtWzgQvwHi/yRikJ5wkAFvtAvW/GcInkMSBukB6QUZgFUBMRis 137 | F9mAD+8/EoWHswGk4kFqADY/I2NktbQ1AJ2PLg7CMAPuFM8/hqEBnY8uDsIwA2SQDUFXiKwZWRyEwQaA 138 | AMwQkABIEYgmDn/7DwBpTOrUXkrGYgAAAABJRU5ErkJggg== 139 | 140 | 141 | 142 | 143 | iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO 144 | xAAADsQBlSsOGwAAALFJREFUOE+tkDESwiAQRbmA17C2tKb2EBbeICfKEeQGXkZNFWho1/wdlsEMgXVM 145 | 8cJC9r9ZMET0F/yJMZ6AHK73LaTZJzhY7muhEgj8Y7gRQO3fz3C/nPO+JzFhehEC4/HAIamxqgRLw7WU 146 | SBiT9MKA30DGFoF2fGDKMFap1W8gAoBarpMEXfIVAOoFfhPnHFlrm7AAY6RgHhU/0ODnsMmXYM1ugh5N 147 | gZaq4Beqh3rIfADNkAPZUpn57QAAAABJRU5ErkJggg== 148 | 149 | 150 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/ControllerControl.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace nullDCNetplayLauncher 2 | { 3 | partial class ControllerControl 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | this.lblController = new System.Windows.Forms.Label(); 32 | this.picArcadeStick = new System.Windows.Forms.PictureBox(); 33 | this.btnSetup = new System.Windows.Forms.Button(); 34 | this.btnCancel = new System.Windows.Forms.Button(); 35 | this.btnDPad = new System.Windows.Forms.Button(); 36 | this.btnAnalog = new System.Windows.Forms.Button(); 37 | this.chkForceMapper = new System.Windows.Forms.CheckBox(); 38 | this.btnSkip = new System.Windows.Forms.Button(); 39 | this.btnTestKB = new System.Windows.Forms.Button(); 40 | this.btnTestController = new System.Windows.Forms.Button(); 41 | ((System.ComponentModel.ISupportInitialize)(this.picArcadeStick)).BeginInit(); 42 | this.SuspendLayout(); 43 | // 44 | // lblController 45 | // 46 | this.lblController.Location = new System.Drawing.Point(22, 188); 47 | this.lblController.Margin = new System.Windows.Forms.Padding(2, 0, 2, 0); 48 | this.lblController.Name = "lblController"; 49 | this.lblController.Size = new System.Drawing.Size(286, 75); 50 | this.lblController.TabIndex = 0; 51 | this.lblController.Text = "Plug in your controller to continue."; 52 | this.lblController.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; 53 | // 54 | // picArcadeStick 55 | // 56 | this.picArcadeStick.Image = global::nullDCNetplayLauncher.Properties.Resources.base_full; 57 | this.picArcadeStick.Location = new System.Drawing.Point(22, 10); 58 | this.picArcadeStick.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); 59 | this.picArcadeStick.Name = "picArcadeStick"; 60 | this.picArcadeStick.Size = new System.Drawing.Size(286, 176); 61 | this.picArcadeStick.SizeMode = System.Windows.Forms.PictureBoxSizeMode.Zoom; 62 | this.picArcadeStick.TabIndex = 1; 63 | this.picArcadeStick.TabStop = false; 64 | this.picArcadeStick.Paint += new System.Windows.Forms.PaintEventHandler(this.picArcadeStick_Paint); 65 | // 66 | // btnSetup 67 | // 68 | this.btnSetup.AutoSize = true; 69 | this.btnSetup.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 70 | this.btnSetup.Location = new System.Drawing.Point(86, 251); 71 | this.btnSetup.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); 72 | this.btnSetup.Name = "btnSetup"; 73 | this.btnSetup.Size = new System.Drawing.Size(45, 23); 74 | this.btnSetup.TabIndex = 2; 75 | this.btnSetup.Text = "Setup"; 76 | this.btnSetup.UseVisualStyleBackColor = true; 77 | this.btnSetup.Click += new System.EventHandler(this.btnSetup_Click); 78 | // 79 | // btnCancel 80 | // 81 | this.btnCancel.AutoSize = true; 82 | this.btnCancel.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 83 | this.btnCancel.Location = new System.Drawing.Point(200, 251); 84 | this.btnCancel.Margin = new System.Windows.Forms.Padding(2); 85 | this.btnCancel.Name = "btnCancel"; 86 | this.btnCancel.Size = new System.Drawing.Size(50, 23); 87 | this.btnCancel.TabIndex = 3; 88 | this.btnCancel.Text = "Cancel"; 89 | this.btnCancel.UseVisualStyleBackColor = true; 90 | this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click); 91 | // 92 | // btnDPad 93 | // 94 | this.btnDPad.AutoSize = true; 95 | this.btnDPad.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 96 | this.btnDPad.Location = new System.Drawing.Point(80, 251); 97 | this.btnDPad.Margin = new System.Windows.Forms.Padding(2); 98 | this.btnDPad.Name = "btnDPad"; 99 | this.btnDPad.Size = new System.Drawing.Size(106, 23); 100 | this.btnDPad.TabIndex = 8; 101 | this.btnDPad.Text = "Digital or Keyboard"; 102 | this.btnDPad.UseVisualStyleBackColor = true; 103 | this.btnDPad.Visible = false; 104 | this.btnDPad.Click += new System.EventHandler(this.btnDPad_Click); 105 | // 106 | // btnAnalog 107 | // 108 | this.btnAnalog.AutoSize = true; 109 | this.btnAnalog.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 110 | this.btnAnalog.Cursor = System.Windows.Forms.Cursors.Arrow; 111 | this.btnAnalog.Location = new System.Drawing.Point(200, 251); 112 | this.btnAnalog.Margin = new System.Windows.Forms.Padding(2); 113 | this.btnAnalog.Name = "btnAnalog"; 114 | this.btnAnalog.Size = new System.Drawing.Size(50, 23); 115 | this.btnAnalog.TabIndex = 9; 116 | this.btnAnalog.Text = "Analog"; 117 | this.btnAnalog.UseVisualStyleBackColor = true; 118 | this.btnAnalog.Visible = false; 119 | this.btnAnalog.Click += new System.EventHandler(this.btnAnalog_Click); 120 | // 121 | // chkForceMapper 122 | // 123 | this.chkForceMapper.AutoSize = true; 124 | this.chkForceMapper.Location = new System.Drawing.Point(97, 288); 125 | this.chkForceMapper.Margin = new System.Windows.Forms.Padding(2); 126 | this.chkForceMapper.Name = "chkForceMapper"; 127 | this.chkForceMapper.Size = new System.Drawing.Size(140, 17); 128 | this.chkForceMapper.TabIndex = 11; 129 | this.chkForceMapper.Text = "Force Keyboard Mapper"; 130 | this.chkForceMapper.UseVisualStyleBackColor = true; 131 | this.chkForceMapper.CheckedChanged += new System.EventHandler(this.chkForceMapper_CheckedChanged); 132 | // 133 | // btnSkip 134 | // 135 | this.btnSkip.AutoSize = true; 136 | this.btnSkip.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 137 | this.btnSkip.Enabled = false; 138 | this.btnSkip.Location = new System.Drawing.Point(145, 251); 139 | this.btnSkip.Name = "btnSkip"; 140 | this.btnSkip.Size = new System.Drawing.Size(38, 23); 141 | this.btnSkip.TabIndex = 12; 142 | this.btnSkip.Text = "Skip"; 143 | this.btnSkip.UseVisualStyleBackColor = true; 144 | this.btnSkip.Visible = false; 145 | this.btnSkip.Click += new System.EventHandler(this.btnSkip_Click); 146 | // 147 | // btnTestKB 148 | // 149 | this.btnTestKB.AutoSize = true; 150 | this.btnTestKB.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 151 | this.btnTestKB.Location = new System.Drawing.Point(159, 251); 152 | this.btnTestKB.Name = "btnTestKB"; 153 | this.btnTestKB.Size = new System.Drawing.Size(86, 23); 154 | this.btnTestKB.TabIndex = 13; 155 | this.btnTestKB.Text = "Test Keyboard"; 156 | this.btnTestKB.UseVisualStyleBackColor = true; 157 | this.btnTestKB.Click += new System.EventHandler(this.btnTestKB_Click); 158 | // 159 | // btnTestController 160 | // 161 | this.btnTestController.AutoSize = true; 162 | this.btnTestController.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 163 | this.btnTestController.Location = new System.Drawing.Point(159, 251); 164 | this.btnTestController.Name = "btnTestController"; 165 | this.btnTestController.Size = new System.Drawing.Size(85, 23); 166 | this.btnTestController.TabIndex = 14; 167 | this.btnTestController.Text = "Test Controller"; 168 | this.btnTestController.UseVisualStyleBackColor = true; 169 | this.btnTestController.Click += new System.EventHandler(this.btnTestController_Click); 170 | // 171 | // ControllerControl 172 | // 173 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 174 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 175 | this.Controls.Add(this.btnTestController); 176 | this.Controls.Add(this.btnSkip); 177 | this.Controls.Add(this.chkForceMapper); 178 | this.Controls.Add(this.picArcadeStick); 179 | this.Controls.Add(this.btnSetup); 180 | this.Controls.Add(this.btnCancel); 181 | this.Controls.Add(this.btnDPad); 182 | this.Controls.Add(this.btnAnalog); 183 | this.Controls.Add(this.btnTestKB); 184 | this.Controls.Add(this.lblController); 185 | this.Margin = new System.Windows.Forms.Padding(2, 3, 2, 3); 186 | this.Name = "ControllerControl"; 187 | this.Size = new System.Drawing.Size(331, 318); 188 | this.Load += new System.EventHandler(this.ControllerControl_Load); 189 | this.HandleDestroyed += new System.EventHandler(this.ControllerControl_Close); 190 | ((System.ComponentModel.ISupportInitialize)(this.picArcadeStick)).EndInit(); 191 | this.ResumeLayout(false); 192 | this.PerformLayout(); 193 | 194 | } 195 | 196 | #endregion 197 | 198 | private System.Windows.Forms.Label lblController; 199 | private System.Windows.Forms.PictureBox picArcadeStick; 200 | private System.Windows.Forms.Button btnSetup; 201 | private System.Windows.Forms.Button btnCancel; 202 | private System.Windows.Forms.Button btnDPad; 203 | private System.Windows.Forms.Button btnAnalog; 204 | private System.Windows.Forms.CheckBox chkForceMapper; 205 | private System.Windows.Forms.Button btnSkip; 206 | private System.Windows.Forms.Button btnTestKB; 207 | private System.Windows.Forms.Button btnTestController; 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/NetplayLaunchForm.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace nullDCNetplayLauncher 2 | { 3 | partial class NetplayLaunchForm 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Windows Form Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | //private void InitializeComponent() 30 | private void InitializeComponent(bool StartTray) 31 | { 32 | this.components = new System.ComponentModel.Container(); 33 | System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(NetplayLaunchForm)); 34 | this.cboGameSelect = new System.Windows.Forms.ComboBox(); 35 | this.btnHost = new System.Windows.Forms.Button(); 36 | this.btnOffline = new System.Windows.Forms.Button(); 37 | this.btnJoin = new System.Windows.Forms.Button(); 38 | this.panel1 = new System.Windows.Forms.Panel(); 39 | this.btnSettings = new System.Windows.Forms.Button(); 40 | this.btnController = new System.Windows.Forms.Button(); 41 | this.btnDragLoad = new System.Windows.Forms.Button(); 42 | this.notifyIcon = new System.Windows.Forms.NotifyIcon(this.components); 43 | this.btnHelp = new System.Windows.Forms.Button(); 44 | this.tipSettings = new System.Windows.Forms.ToolTip(this.components); 45 | this.tipController = new System.Windows.Forms.ToolTip(this.components); 46 | this.tipFileDrop = new System.Windows.Forms.ToolTip(this.components); 47 | this.tipHelp = new System.Windows.Forms.ToolTip(this.components); 48 | this.panel1.SuspendLayout(); 49 | this.SuspendLayout(); 50 | // 51 | // cboGameSelect 52 | // 53 | this.cboGameSelect.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed; 54 | this.cboGameSelect.FormattingEnabled = true; 55 | this.cboGameSelect.Location = new System.Drawing.Point(4, 97); 56 | this.cboGameSelect.Margin = new System.Windows.Forms.Padding(2); 57 | this.cboGameSelect.Name = "cboGameSelect"; 58 | this.cboGameSelect.Size = new System.Drawing.Size(255, 21); 59 | this.cboGameSelect.TabIndex = 38; 60 | this.cboGameSelect.DrawItem += new System.Windows.Forms.DrawItemEventHandler(this.cboGameSelect_DrawItem); 61 | this.cboGameSelect.SelectedIndexChanged += new System.EventHandler(this.cboGameSelect_SelectedIndexChanged); 62 | // 63 | // btnHost 64 | // 65 | this.btnHost.Location = new System.Drawing.Point(3, 38); 66 | this.btnHost.Margin = new System.Windows.Forms.Padding(2); 67 | this.btnHost.Name = "btnHost"; 68 | this.btnHost.Size = new System.Drawing.Size(255, 26); 69 | this.btnHost.TabIndex = 36; 70 | this.btnHost.Text = "Host Game"; 71 | this.btnHost.UseVisualStyleBackColor = true; 72 | this.btnHost.Click += new System.EventHandler(this.btnHost_Click); 73 | // 74 | // btnOffline 75 | // 76 | this.btnOffline.Location = new System.Drawing.Point(3, 9); 77 | this.btnOffline.Margin = new System.Windows.Forms.Padding(2); 78 | this.btnOffline.Name = "btnOffline"; 79 | this.btnOffline.Size = new System.Drawing.Size(255, 26); 80 | this.btnOffline.TabIndex = 35; 81 | this.btnOffline.Text = "Play Offline"; 82 | this.btnOffline.UseVisualStyleBackColor = true; 83 | this.btnOffline.Click += new System.EventHandler(this.btnOffline_Click); 84 | // 85 | // btnJoin 86 | // 87 | this.btnJoin.Location = new System.Drawing.Point(3, 67); 88 | this.btnJoin.Margin = new System.Windows.Forms.Padding(2); 89 | this.btnJoin.Name = "btnJoin"; 90 | this.btnJoin.Size = new System.Drawing.Size(255, 26); 91 | this.btnJoin.TabIndex = 37; 92 | this.btnJoin.Text = "Join Game"; 93 | this.btnJoin.UseVisualStyleBackColor = true; 94 | this.btnJoin.Click += new System.EventHandler(this.btnJoin_Click); 95 | // 96 | // panel1 97 | // 98 | this.panel1.Controls.Add(this.btnOffline); 99 | this.panel1.Controls.Add(this.cboGameSelect); 100 | this.panel1.Controls.Add(this.btnJoin); 101 | this.panel1.Controls.Add(this.btnHost); 102 | this.panel1.Location = new System.Drawing.Point(0, 0); 103 | this.panel1.Name = "panel1"; 104 | this.panel1.Size = new System.Drawing.Size(262, 124); 105 | this.panel1.TabIndex = 39; 106 | // 107 | // btnSettings 108 | // 109 | this.btnSettings.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("btnSettings.BackgroundImage"))); 110 | this.btnSettings.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 111 | this.btnSettings.Location = new System.Drawing.Point(3, 124); 112 | this.btnSettings.Margin = new System.Windows.Forms.Padding(2); 113 | this.btnSettings.Name = "btnSettings"; 114 | this.btnSettings.Size = new System.Drawing.Size(25, 25); 115 | this.btnSettings.TabIndex = 42; 116 | this.tipSettings.SetToolTip(this.btnSettings, "Settings"); 117 | this.btnSettings.UseVisualStyleBackColor = true; 118 | this.btnSettings.Click += new System.EventHandler(this.btnSettings_Click); 119 | // 120 | // btnController 121 | // 122 | this.btnController.BackgroundImage = global::nullDCNetplayLauncher.Properties.Resources.icons8_game_controller_26; 123 | this.btnController.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 124 | this.btnController.Location = new System.Drawing.Point(32, 124); 125 | this.btnController.Margin = new System.Windows.Forms.Padding(2); 126 | this.btnController.Name = "btnController"; 127 | this.btnController.Size = new System.Drawing.Size(25, 25); 128 | this.btnController.TabIndex = 43; 129 | this.tipController.SetToolTip(this.btnController, "Controller Setup"); 130 | this.btnController.UseVisualStyleBackColor = true; 131 | this.btnController.Click += new System.EventHandler(this.btnController_Click); 132 | // 133 | // btnDragLoad 134 | // 135 | this.btnDragLoad.BackgroundImage = global::nullDCNetplayLauncher.Properties.Resources.round_publish_black_18dp; 136 | this.btnDragLoad.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 137 | this.btnDragLoad.Location = new System.Drawing.Point(62, 124); 138 | this.btnDragLoad.Margin = new System.Windows.Forms.Padding(2); 139 | this.btnDragLoad.Name = "btnDragLoad"; 140 | this.btnDragLoad.Size = new System.Drawing.Size(25, 25); 141 | this.btnDragLoad.TabIndex = 44; 142 | this.tipFileDrop.SetToolTip(this.btnDragLoad, "File Drop"); 143 | this.btnDragLoad.UseVisualStyleBackColor = true; 144 | this.btnDragLoad.Click += new System.EventHandler(this.btnDragLoad_Click); 145 | // 146 | // notifyIcon 147 | // 148 | this.notifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon.Icon"))); 149 | this.notifyIcon.Text = "NullDC Netplay"; 150 | this.notifyIcon.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon_MouseDoubleClick); 151 | // 152 | // btnHelp 153 | // 154 | this.btnHelp.BackgroundImage = global::nullDCNetplayLauncher.Properties.Resources.round_not_listed_location_black_18dp; 155 | this.btnHelp.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch; 156 | this.btnHelp.Location = new System.Drawing.Point(233, 124); 157 | this.btnHelp.Margin = new System.Windows.Forms.Padding(2); 158 | this.btnHelp.Name = "btnHelp"; 159 | this.btnHelp.Size = new System.Drawing.Size(25, 25); 160 | this.btnHelp.TabIndex = 45; 161 | this.tipHelp.SetToolTip(this.btnHelp, "Help"); 162 | this.btnHelp.UseVisualStyleBackColor = true; 163 | this.btnHelp.Click += new System.EventHandler(this.btnHelp_Click); 164 | // 165 | // NetplayLaunchForm 166 | // 167 | this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); 168 | this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 169 | this.AutoSize = true; 170 | this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink; 171 | this.ClientSize = new System.Drawing.Size(261, 150); 172 | this.Controls.Add(this.btnHelp); 173 | this.Controls.Add(this.btnDragLoad); 174 | this.Controls.Add(this.btnController); 175 | this.Controls.Add(this.btnSettings); 176 | this.Controls.Add(this.panel1); 177 | this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); 178 | this.Name = "NetplayLaunchForm"; 179 | if (StartTray) 180 | this.ShowInTaskbar = false; 181 | this.Text = "NullDC Netplay"; 182 | this.Resize += new System.EventHandler(this.NetplayLaunchForm_Resize); 183 | this.panel1.ResumeLayout(false); 184 | this.ResumeLayout(false); 185 | 186 | } 187 | 188 | #endregion 189 | private System.Windows.Forms.ComboBox cboGameSelect; 190 | private System.Windows.Forms.Button btnHost; 191 | private System.Windows.Forms.Button btnOffline; 192 | private System.Windows.Forms.Button btnJoin; 193 | private System.Windows.Forms.Panel panel1; 194 | private System.Windows.Forms.Button btnSettings; 195 | private System.Windows.Forms.Button btnController; 196 | private System.Windows.Forms.Button btnDragLoad; 197 | private System.Windows.Forms.NotifyIcon notifyIcon; 198 | private System.Windows.Forms.Button btnHelp; 199 | private System.Windows.Forms.ToolTip tipSettings; 200 | private System.Windows.Forms.ToolTip tipController; 201 | private System.Windows.Forms.ToolTip tipFileDrop; 202 | private System.Windows.Forms.ToolTip tipHelp; 203 | } 204 | } -------------------------------------------------------------------------------- /README.es.md: -------------------------------------------------------------------------------- 1 | # NullDC-NAOMI Netplay Launcher Distribution 0.6.3.1 2 | Configuracion optimizada por blueminder *(Junio 21, 2020)* 3 | 4 | Documentación traducida por BRBS 5 | 6 | 7 | 8 | **Muchas Gracias** 9 | 10 | - supersonicstep del Discord de FGC Arcadia 11 | - MarioBrotha del Discord de FGC Arcadia(nullDCMultiLauncher, nullDCControlSetup) 12 | - RossenX del Discord de FGC Arcadia por las optimizaciones al juego en linea 13 | - pof & shine de [Fightcade](https://web.fightcade.com/) por la integracion y pruebas en general 14 | - BRBS del Discord de FGC Arcadia Discord por ayudar en las preubas de cada beta y ayuda en general 15 | - DQRF del Discord de GGXXACR(guilty gear) 16 | - RaptorIIRC 17 | - Teyah 18 | - Jakstation 19 | - reaVer 20 | 21 | ## Requisitos previos a la instalacion 22 | 23 | Asegurate de tener instalado lo sgiguiene: 24 | 25 | 1. [DirectX](https://www.microsoft.com/en-us/download/details.aspx?id=35) 26 | 2. [Microsoft Visual C++ 2010 Redistributable Package (x86)](https://www.microsoft.com/en-us/download/details.aspx?id=5555) 27 | 3. [.NET Framework 4.8 Runtime](https://dotnet.microsoft.com/download/dotnet-framework/net48) 28 | 29 | Asegurate de tener los siguientes archivos antes de empezar 30 | 31 | 1. La BIOS de NAOMI (`naomi_bios.bin`) 32 | 2.Los ROMs de los juegos NAOMI en formato `.zip` y que estos contengan los archivos `.lst` & `.bin` 33 | 34 | ## Instalando los ROMs 35 | 36 | NullDC Netplay Launcher no provee ningun tipo de ROMs. Tu deberas encontrar y descargar la NAOMI BIOS, y cualquiera de los ROMs NAOMI que desees jugar por tu cuenta. Cualquier evento o comunidad en la que participes debera tener una lista de los ROMs aprobados para asegurar la compartibilidad entre oponentes, asi que puedes preguntar. 37 | 38 | Una vez que tengas los archivos necesarios: 39 | 40 | 1. Abre `nullDCNetplayLauncher.exe` 41 | 2. Abre el menu *File Drop* presionando el boton que esta a la derecha del icono con forma de control(tiene forma de una flechita hacia arriba). 42 | 3. Localiza el `naomi_bios.bin` y los ROMs(en formato.zip) y arrastralos sobre el cuadro. Cada ROM en formato .zip contener dentro el archivo `.bin`/`.dat` asi como el correspondiente archivo`.lst`. 43 | 44 | ![Demostración de File Drop](file_drop_demo.gif) 45 | 46 | Si lo prefieres puedes hacerlo manualmente, solo coloca el archivo (`naomi_bios.bin`) en `nulldc-1-0-4-en-win\data` y coloca tus ROMs descomprimidos en `nulldc-1-0-4-en-win\roms` cada juego en su folder por separado(ejemplo: `nulldc-1-0-4-en-win\roms\mvc2`, el nombre del folder en el que esten los archivos del ROM sera usado para dicho juego en el launcher. 47 | 48 | Archivos CDI y GDI ROMs (Dreamcast) no son soportados por el momento. 49 | 50 | ## Offline Setup (Juego Local) 51 | 52 | 1. Abre `nullDCNetplayLauncher.exe` 53 | 54 | 2. Presiona el icono del control en la esquina izquierda. Asegurate de que solo un control este conectado(fightstick, gamepad o el mando que vayas a utilizar) y sigue las instrucciones. 55 | 56 | 3. Selecciona cualkier ROM (juego) del menu y presiona el boton *Play Offline* 57 | 58 | Esto ejecutara el ROM que seleccionaste en el emulador NullDC, dandote la oportunidad de probar tus controles. Si el juego te asigna el jugador 1 y tus controles funcionan bien ya estas listo para el juego en linea! 59 | 60 | # Netplay Setup (Juego Online) 61 | 62 | **(OPCIONAL, PERO RECOMENDADO)** [Radmin VPN](https://www.radmin-vpn.com/) 63 | 64 | El metodo de juego en linea funciona para cualquier tipo de LAN local o virtual como Radmin VPN, ZeroTier o Hamachi. Radmin VPN es la VLAN usada por FGC Arcadia. Asegurate de tenerla instalada y activa antes de buscar partidas en el canal de Discord, pues tendras que crear o unisrte a una red con las personas con las que desees jugar. 65 | 66 | Las sugientes instrucciones son asumiendo que ya tienes Radmin instalado, pero deberian funcionar igual para cualquier otro tipo de VLAN o LAN mientras tengas la IP de host correcta, puertos y tu firewallo no este bloqueando las conecciones o puertos relevantes. 67 | 68 | 1. Abre `nullDCNetplayLauncher.exe` 69 | 70 | 71 | 2. Elige el ROM que deseas jugar online 72 | 73 | 74 | 3. Inicia sesion presionando el boton *Host Game* o el boton *Join Game* 75 | 76 | - **Hosting a Game** (tu oponente se conecta a tu pc) 77 | 78 | 1. Si tu eres el HOST asegurate de copiar tu IP de Radmin a la columna del launcher en donde dice *Host IP*. Puedes salvar este cambio para que el launcher ya tenga tu ip de Radmin por defecto cada vez que seas host. 79 | 80 | 2. Copia la IP de tu contrincantede Radmin y pegala en la columna *Guest IP*. ahora, presiona el boton *Guess* para determinar el Delay apropiado basado en la distancia entre tu y tu oponente. Si la coneccion no fuera posible entre los 2 el cuadro de delay se pondra en color rojo. 81 | 82 | 3. Presiona *Generate Host Code* y presiona el icono (Clipboard) a la derecha para copiar el enlace generado. 83 | 84 | 4. Proporcionale ese codigo a tu openente(por discord o algun otro metodo de chat online), el pegara ese codigo en su respectivo emulador y todos los detalles de coneccion se generan automaticamente para el. Otro metodo que podrias usar seria proporcionarle tu ip, puerto y delay, cualquiera de los 2 metodos funciona. 85 | 86 | 5. Verifica que los 2 tengan el mismo Delay. 87 | 88 | 6. Presiona el boton *Launch Game*. 89 | 90 | Espera un momento a que todo cargue y una vez que entres al juego si eres 'host' tu seras player 1 y tu oponente bplayer 2. Si es asi quiere decir que todo salio bien ahora a disfrutar tu partida. 91 | 92 | ![Demostración de Host Game](host_demo.gif) 93 | 94 | - **Joining a Game** (tu te conectas a la pc de tu oponente) 95 | 96 | 1. Selecciona el ROM 97 | 98 | 2. Presiona el boton *join Game* 99 | 100 | 3. Pega el codigo de host que tu oponente te envio y todos los detalles se llenaran automaticamente. Tambien puedes ingresar manualmente los datos de tu oponente(HOST IP, PORT, DELAY) caulquiera de los 2 metodos funciona. 101 | 102 | 103 | Asegurate de que la IP de Radmin de tu oponente es la misma que la de la columna in the *Host IP* en el launcher. Asegurate que tu y tu oponente tengan seleccionado el mismo delay. 104 | 105 | ![Demostración de Join Game](join_demo.gif) 106 | 107 | 4. Presiona el boton *Launch Game*. 108 | 109 | 5. Juega! 110 | 111 | Si experimentan algun tipo de alentamiento o cualquier tipo de desincronizacion, asegurense de experimentar con diferentes delays dentro del rango establecido. Toma algo de prueba y error, pero una vez que encuentras un valor correcto, es realmente genial y la jugabilidad es excelente. Solo asegurense de que los dos usen el mismo delay. 112 | 113 | Una vez que encuentren los settings para una coneccion buena, puedes salvar esos parametros y asi tenerlos disponibles para la proxima vez que tengan una partida. 114 | 115 | Solo en casa de que el boton *Guess* no sea confiable para ti, aqui estan unos parametros recomendados para el Delay basados en el ping promedio en milisegundos: 116 | 117 | > < 25ms = 1 Delay Frame recomendado 118 | > < 60ms = 2 Delay Frame recomendado 119 | > < 100ms = 3 Delay Frame recomendado 120 | > < 130ms = 4 Delay Frame recomendado 121 | > < 155ms = 5 Delay Frame recomendado 122 | > < 180ms = 6 Delay Frame recomendado 123 | > mas de 180ms = no pierdas tu tiempo, es mejor buscar otro contrincante :( 124 | 125 | ## Command Line (lineas de comando) 126 | 127 | El launcher ahora tiene opciones de lineas de comando, para que si asi lo deseas puedas integrarlo al emulador o sistema de lobby que gustes. Para ver todas las opciones, puedes ejecutar: 128 | 129 | `nullDCNetplayLauncher.exe --help` 130 | 131 | Los juegos deberan ser especificados en el archivo `games.json`, mostrandolos detalles del ROM como la descripcion y hubicacion. Loa juegos enlistados en este archivo puedes ser llamados usando `--gameid` : 132 | 133 | `nullDCNetplayLauncher.exe --gameid cvs2 --offline 1` 134 | 135 | De otra forma,puedes ejecutar los juegos usando la hubicacion: 136 | 137 | `nullDCNetplayLauncher.exe --lst-path --offline 1` 138 | 139 | Para hostear un juego: 140 | 141 | `nullDCNetplayLauncher.exe --gameid cvs2 --hosting 1 --ip --port --delay ` 142 | 143 | para unirse a un juego: 144 | 145 | `nullDCNetplayLauncher.exe --gameid cvs2 --hosting 0 --ip --port --delay ` 146 | 147 | Si quieres que el launcher adivine el dalay automaticamente puedes usar `--guess-ip`: 148 | 149 | `nullDCNetplayLauncher.exe --gameid cvs2 --hosting 0 --ip --port --guess-ip ` 150 | 151 | 152 | 153 | ## Solución de Problemas 154 | 155 | > Mi control no es detectado por completo / tengo problemas con algunos inputs en la configuracion del control 156 | > 157 | 158 | Si tienes problemas para configurar tu control, intenta marcando la casilla *Force Keyboard Mapper* en el menu del configuracion del control. Esto activara el mapeador de teclado interno del launcher que provee soporte extendido para controles no soportados en el plugin qkoJAMMA que se usa como default. 159 | 160 | Si usas un stick/pad que cuente con la opcion *modo PS3* intenta usar este modo y no el *Keyboard Mapper*. Los controles de PS3 han desmostrado tener la mejor compatibilidad con el plug in qkoJAMMA. 161 | 162 | ------ 163 | 164 | 165 | 166 | > Cuando trato de unirme a un juego o hostear un juego, ninguno de los 2 logra conectarse al otro. Que debo hacer? 167 | 168 | El primer paso para solucionar problemas de coneccion seria deshabilitar tu firewall para ver si de esa forma la coneccion funciona. Puedes hacer esto en el Panel de Control de "Windows Defender Firewall". Si pueden conectarse cuando el firewall esta deshabilitado, verifica en las opciones que `nullDC_Win32_Release-NoTrace.exe` tiene permisos para acceder a redes privadas. Si eso no funciona habilita redes publicas desde ahi. 169 | 170 | A la hora de intentar solucionar algun problema de coneccion, puedes pasar por el Discor de FGC Arcadia y preguntar en la seccion de ayuda, pon atencion a la ventana de comandos para cualquier detalle. Esto le sera de ayuda a cualquier persona que te ayude . 171 | 172 | ------ 173 | 174 | 175 | 176 | > Accidentalmente active el Keyboard Mapper para mi control en el menu de configuracion. como lo desactivo? 177 | > 178 | 179 | Para deshabilitar el Keyboard Mapper ve a opciones y desmarca la casilla *Enable Keyboard Mapper*. Esto revertira NulDC a los driver de control por defecto. 180 | 181 | ------ 182 | 183 | 184 | 185 | > Cuando juego ROMs Atomiswave , todos los botones actuan como el boton de creditos(coin) o start 186 | > 187 | 188 | Verifica si el boton *test* presenta algun conflicto con el boton *start*. Es recomendable evitar(skip) el boton *test* a la hora de configurar el control, ya que no es necesario para jugar. Es recomendable asegurarse de que ninguno de los botones se repitan en la configuracion de tu control. Puedes verificar esto hechando un vistazo al archivo `.qjc` que correesponde a tu control en el directorio `nulldc-1-0-4-en-win\qkoJAMMA`. Puedes acceder a este directorio atravez de la pestaña de opciones avanzadas. 189 | 190 | Si no encuentras la manera de solucionar el problema con el control considera usar el Keyboard Mapper. Esto a sido la solucion major solucion para muchas personas con este problema en los juegos Atomiswave. 191 | 192 | Si tienes mas preguntas tomate la libertad de pasar por el canal de discord oficial [FGC Arcadia](https://discord.com/invite/KczAkRr). -------------------------------------------------------------------------------- /nullDCNetplayLauncher/JoinControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.Text.RegularExpressions; 11 | using System.IO; 12 | 13 | namespace nullDCNetplayLauncher 14 | { 15 | public partial class JoinControl : UserControl 16 | { 17 | ConnectionPresetList presets; 18 | 19 | public JoinControl() 20 | { 21 | presets = ConnectionPreset.ReadPresetsFile(); 22 | InitializeComponent(); 23 | 24 | cboPresetName.DataSource = presets.ConnectionPresets; 25 | 26 | btnDeletePreset.Enabled = presets.ConnectionPresets.Count > 1; 27 | 28 | Dictionary RegionOptions = new Dictionary(); 29 | RegionOptions["Japan"] = "japan"; 30 | RegionOptions["USA"] = "usa"; 31 | 32 | cboRegion.DataSource = new BindingSource(RegionOptions, null); 33 | cboRegion.DisplayMember = "Key"; 34 | cboRegion.ValueMember = "Value"; 35 | 36 | var us_bios_path = Path.Combine(Launcher.rootDir, "nulldc-1-0-4-en-win", "data", "naomi_boot.bin"); 37 | if (!File.Exists(us_bios_path) && !File.Exists($"{us_bios_path}.inactive")) 38 | cboRegion.Enabled = false; 39 | } 40 | 41 | private void JoinControl_Load(object sender, EventArgs e) 42 | { 43 | cboMethod.DataSource = new BindingSource(Launcher.MethodOptions, null); 44 | cboMethod.DisplayMember = "Key"; 45 | cboMethod.ValueMember = "Value"; 46 | 47 | txtOpponentIP.Text = ""; 48 | } 49 | 50 | private void GuessDelay(string ip) 51 | { 52 | long guessedDelay = Launcher.GuessDelay(ip); 53 | if (guessedDelay >= 0) 54 | { 55 | numDelay.Value = guessedDelay; 56 | txtOpponentIP.BackColor = Color.Honeydew; 57 | numDelay.BackColor = Color.Honeydew; 58 | } 59 | else 60 | { 61 | numDelay.Text = ""; 62 | txtOpponentIP.BackColor = Color.LightCoral; 63 | numDelay.BackColor = Color.LightCoral; 64 | } 65 | } 66 | 67 | private void btnGuess_Click(object sender, EventArgs e) 68 | { 69 | GuessDelay(txtOpponentIP.Text); 70 | } 71 | 72 | private void btnLaunchGame_Click(object sender, EventArgs e) 73 | { 74 | Launcher.SwitchRegion(cboRegion.SelectedValue.ToString()); 75 | Launcher.CleanMalformedQjcFiles(); 76 | Launcher.UpdateCFGFile( 77 | netplayEnabled: true, 78 | isHost: false, 79 | hostAddress: txtOpponentIP.Text, 80 | hostPort: txtHostPort.Text, 81 | frameDelay: Convert.ToInt32(numDelay.Value) 82 | .ToString()); 83 | Launcher.LaunchNullDC(Launcher.SelectedGame, isHost: false); 84 | } 85 | 86 | private void btnPaste_Click(object sender, EventArgs e) 87 | { 88 | txtHostCode.BackColor = Color.LemonChiffon; 89 | txtHostCode.Text = Clipboard.GetText(); 90 | } 91 | 92 | private void txtHostCode_GotFocus(object sender, EventArgs e) 93 | { 94 | txtHostCode.BackColor = Color.White; 95 | } 96 | 97 | private void txtGuestPort_GotFocus(object sender, EventArgs e) 98 | { 99 | txtHostPort.BackColor = Color.White; 100 | } 101 | 102 | private void numDelay_GotFocus(object sender, EventArgs e) 103 | { 104 | txtHostCode.BackColor = Color.White; 105 | } 106 | 107 | private void cboPresetName_GotFocus(object sender, EventArgs e) 108 | { 109 | cboPresetName.BackColor = Color.White; 110 | } 111 | 112 | private void txtHostCode_TextChanged(object sender, EventArgs e) 113 | { 114 | txtHostCode.BackColor = Color.White; 115 | string base64Pattern = @"^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9 +/]{3}=)?$"; 116 | bool isBase64 = Regex.IsMatch(txtHostCode.Text, base64Pattern); 117 | if (isBase64 || txtHostCode.Text == "") 118 | { 119 | var hostInfo = Launcher.DecodeHostCode(txtHostCode.Text); 120 | 121 | if (!String.IsNullOrEmpty(hostInfo.Port)) 122 | { 123 | cboPresetName.Text = ""; 124 | 125 | txtHostCode.BackColor = Color.LemonChiffon; 126 | 127 | txtOpponentIP.BackColor = Color.Honeydew; 128 | numDelay.BackColor = Color.Honeydew; 129 | 130 | txtHostIP.BackColor = Color.LemonChiffon; 131 | txtHostPort.BackColor = Color.LemonChiffon; 132 | cboMethod.BackColor = Color.LemonChiffon; 133 | cboRegion.BackColor = Color.LemonChiffon; 134 | 135 | txtOpponentIP.Text = hostInfo.IP; 136 | txtHostIP.Text = hostInfo.IP; 137 | txtHostPort.Text = hostInfo.Port; 138 | numDelay.Value = Convert.ToInt32(hostInfo.Delay); 139 | 140 | var oldRegion = cboRegion.SelectedValue.ToString(); 141 | var newRegion = hostInfo.Region; 142 | 143 | var us_bios_path = Path.Combine(Launcher.rootDir, "nulldc-1-0-4-en-win", "data", "naomi_boot.bin"); 144 | if (hostInfo.Region != "japan" 145 | && !File.Exists(us_bios_path) 146 | && !File.Exists($"{us_bios_path}.inactive")) 147 | { 148 | MessageBox.Show($"Your opponent has chosen the unsupported region \"{hostInfo.Region}\".\nPlease install the appropriate BIOS or ask your opponent to change their region."); 149 | } 150 | 151 | cboRegion.SelectedValue = hostInfo.Region; 152 | 153 | var oldMethod = Convert.ToInt32(cboMethod.SelectedValue); 154 | var newMethod = Convert.ToInt32(hostInfo.Method); 155 | cboMethod.SelectedValue = newMethod; 156 | 157 | if (oldMethod != newMethod || oldRegion != newRegion) 158 | { 159 | splitGuest.Panel2Collapsed = false; 160 | 161 | btnExpandCollapse.Text = "↓ Advanced Options ↓"; 162 | var win = this.Parent; 163 | win.Size = win.MaximumSize; 164 | } 165 | } 166 | } 167 | } 168 | 169 | public void SavePreset(string presetName) 170 | { 171 | var toEdit = presets.ConnectionPresets.FirstOrDefault(p => p.Name == presetName); 172 | if (toEdit != null) 173 | { 174 | toEdit.IP = txtOpponentIP.Text; 175 | toEdit.Port = txtHostPort.Text; 176 | toEdit.Delay = numDelay.Value; 177 | toEdit.Method = Convert.ToInt32(cboMethod.SelectedValue); 178 | toEdit.Region = cboRegion.SelectedValue.ToString(); 179 | } 180 | else 181 | { 182 | var toAdd = new ConnectionPreset(); 183 | toAdd.Name = cboPresetName.Text; 184 | toAdd.IP = txtOpponentIP.Text; 185 | toAdd.Port = txtHostPort.Text; 186 | toAdd.Delay = numDelay.Value; 187 | toAdd.Method = Convert.ToInt32(cboMethod.SelectedValue); 188 | toAdd.Region = cboRegion.SelectedValue.ToString(); 189 | presets.ConnectionPresets.Add(toAdd); 190 | } 191 | 192 | var path = Launcher.GetApplicationConfigurationDirectoryName() + "//ConnectionPresetList.xml"; 193 | System.Xml.Serialization.XmlSerializer serializer = 194 | new System.Xml.Serialization.XmlSerializer(typeof(ConnectionPresetList)); 195 | StreamWriter writer = new StreamWriter(path); 196 | serializer.Serialize(writer.BaseStream, presets); 197 | writer.Close(); 198 | presets = ConnectionPreset.ReadPresetsFile(); 199 | cboPresetName.DataSource = presets.ConnectionPresets; 200 | cboPresetName.SelectedIndex = cboPresetName.FindStringExact(presetName); 201 | if (presets.ConnectionPresets.Count > 1) 202 | { 203 | btnDeletePreset.Enabled = true; 204 | } 205 | cboPresetName.BackColor = Color.LemonChiffon; 206 | } 207 | 208 | public void DeletePreset(string presetName) 209 | { 210 | if (presets.ConnectionPresets.Count > 1) 211 | { 212 | var toDelete = presets.ConnectionPresets.FirstOrDefault(p => p.Name == presetName); 213 | presets.ConnectionPresets.Remove(toDelete); 214 | 215 | var path = Launcher.rootDir + "\\ConnectionPresetList.xml"; 216 | System.Xml.Serialization.XmlSerializer serializer = 217 | new System.Xml.Serialization.XmlSerializer(typeof(ConnectionPresetList)); 218 | StreamWriter writer = new StreamWriter(path); 219 | serializer.Serialize(writer.BaseStream, presets); 220 | writer.Close(); 221 | presets = ConnectionPreset.ReadPresetsFile(); 222 | cboPresetName.DataSource = presets.ConnectionPresets; 223 | cboPresetName.SelectedIndex = 0; 224 | if (presets.ConnectionPresets.Count == 1) 225 | { 226 | btnDeletePreset.Enabled = false; 227 | } 228 | } 229 | } 230 | 231 | private void LoadPreset(string presetName) 232 | { 233 | ConnectionPreset toLoad = presets.ConnectionPresets.FirstOrDefault(p => p.Name == presetName); 234 | if (toLoad != null) 235 | { 236 | txtHostCode.Text = ""; 237 | txtOpponentIP.Text = toLoad.IP; 238 | txtHostIP.Text = toLoad.IP; 239 | txtHostPort.Text = toLoad.Port; 240 | numDelay.Value = toLoad.Delay; 241 | cboMethod.SelectedValue = toLoad.Method; 242 | cboRegion.SelectedValue = toLoad.Region; 243 | } 244 | } 245 | 246 | private void btnSavePreset_Click(object sender, EventArgs e) 247 | { 248 | SavePreset(cboPresetName.Text); 249 | } 250 | 251 | private void btnDeletePreset_Click(object sender, EventArgs e) 252 | { 253 | DeletePreset(cboPresetName.Text); 254 | } 255 | 256 | private void cboPresetName_TextChanged(object sender, EventArgs e) 257 | { 258 | LoadPreset(cboPresetName.Text); 259 | } 260 | 261 | private void cboPresetName_SelectedIndexChanged(object sender, EventArgs e) 262 | { 263 | txtHostCode.Text = ""; 264 | cboPresetName.BackColor = Color.White; 265 | txtHostCode.BackColor = Color.White; 266 | txtOpponentIP.BackColor = Color.White; 267 | txtHostIP.BackColor = Color.White; 268 | txtHostPort.BackColor = Color.White; 269 | numDelay.BackColor = Color.White; 270 | cboMethod.BackColor = Color.White; 271 | LoadPreset(cboPresetName.Text); 272 | } 273 | 274 | private void btnExpandCollapse_Click(object sender, EventArgs e) 275 | { 276 | var win = this.Parent; 277 | if (splitGuest.Panel2Collapsed) 278 | { 279 | btnExpandCollapse.Text = "↓ Advanced Options ↓"; 280 | win.Size = win.MaximumSize; 281 | splitGuest.Panel2Collapsed = false; 282 | } 283 | else 284 | { 285 | btnExpandCollapse.Text = "↑ Advanced Options ↑"; 286 | win.Size = win.MinimumSize; 287 | splitGuest.Panel2Collapsed = true; 288 | } 289 | } 290 | } 291 | } 292 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Program.cs: -------------------------------------------------------------------------------- 1 | using SharpDX.DirectInput; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Runtime.InteropServices; 7 | using System.Text.RegularExpressions; 8 | using System.Windows.Forms; 9 | 10 | namespace nullDCNetplayLauncher 11 | { 12 | static class Program 13 | { 14 | /// 15 | /// The main entry point for the application. 16 | /// 17 | [STAThread] 18 | 19 | [DllImport("kernel32.dll", SetLastError = true)] 20 | static extern bool AllocConsole(); 21 | 22 | [DllImport("kernel32.dll")] 23 | static extern IntPtr GetConsoleWindow(); 24 | 25 | [DllImport("user32.dll")] 26 | static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 27 | 28 | const int SW_HIDE = 0; 29 | const int SW_SHOW = 5; 30 | 31 | public static void ShowConsoleWindow() 32 | { 33 | var handle = GetConsoleWindow(); 34 | 35 | if (handle == IntPtr.Zero) 36 | { 37 | AllocConsole(); 38 | } 39 | else 40 | { 41 | ShowWindow(handle, SW_SHOW); 42 | } 43 | } 44 | 45 | public static void HideConsoleWindow() 46 | { 47 | var handle = GetConsoleWindow(); 48 | ShowWindow(handle, SW_HIDE); 49 | } 50 | 51 | public static void LoadInteractive(bool tray = false) 52 | { 53 | HideConsoleWindow(); 54 | Application.EnableVisualStyles(); 55 | Application.SetCompatibleTextRenderingDefault(false); 56 | Application.Run(new NetplayLaunchForm(tray: tray)); 57 | } 58 | 59 | public static void LoadController(bool controllerSetup = true) 60 | { 61 | HideConsoleWindow(); 62 | Application.EnableVisualStyles(); 63 | Application.SetCompatibleTextRenderingDefault(false); 64 | Application.Run(new NetplayLaunchForm(controllerSetup: true)); 65 | } 66 | 67 | [STAThread] 68 | static void Main(string[] args) 69 | { 70 | Launcher.RestoreLauncherCfg(); 71 | 72 | if (args.Length > 0 && args[0].StartsWith("--")) 73 | { 74 | ShowConsoleWindow(); 75 | Dictionary arguments = new Dictionary(); 76 | bool hosting = false; 77 | bool offline = false; 78 | string hostCode; 79 | Launcher.HostInfo hostInfo = new Launcher.HostInfo(); 80 | hostInfo.Method = "0"; 81 | string romPath = ""; 82 | 83 | if (args.Length == 1 && args[0] == "--help") 84 | { 85 | Array.Resize(ref args, args.Length + 1); 86 | args[1] = "1"; 87 | } 88 | 89 | for (int index = 0; index < args.Length - 1; index += 2) 90 | { 91 | string arg = args[index].Replace("--", ""); 92 | if (arg == "help") 93 | { 94 | arguments[arg] = "1"; 95 | } 96 | else 97 | { 98 | arguments[arg] = args[index + 1]; 99 | } 100 | 101 | } 102 | 103 | if (arguments.ContainsKey("help")) 104 | { 105 | Console.WriteLine("--root-dir "); 106 | Console.WriteLine("--lst-path "); 107 | Console.WriteLine("--gameid "); 108 | Console.WriteLine(""); 109 | Console.WriteLine("--host-fps "); 110 | Console.WriteLine("--guest-fps "); 111 | Console.WriteLine(""); 112 | Console.WriteLine("--offline <0/1>"); 113 | Console.WriteLine("--delay "); 114 | Console.WriteLine("--host-code "); 115 | Console.WriteLine("--hosting <0/1>"); 116 | Console.WriteLine("--ip "); 117 | Console.WriteLine("--port "); 118 | Console.WriteLine(""); 119 | Console.WriteLine("--audio-sync (only for host)"); 120 | Console.WriteLine("--frame-limit (only for host)"); 121 | Console.WriteLine(""); 122 | Console.WriteLine("--controller-setup 1"); 123 | return; 124 | } 125 | 126 | if (arguments.ContainsKey("root-dir")) 127 | { 128 | Launcher.rootDir = Regex.Replace(arguments["root-dir"], @"\s+", string.Empty) + "\\"; 129 | } 130 | 131 | if (arguments.ContainsKey("controller-setup")) 132 | { 133 | LoadController(); 134 | return; 135 | } 136 | 137 | Launcher.RestoreFiles(); 138 | 139 | if (!arguments.ContainsKey("offline") 140 | && !arguments.ContainsKey("ip") 141 | && !arguments.ContainsKey("host-code")) 142 | { 143 | LoadInteractive(); 144 | return; 145 | } 146 | 147 | if (arguments.ContainsKey("lst-path")) 148 | { 149 | romPath = arguments["lst-path"]; 150 | } 151 | else if (arguments.ContainsKey("gameid")) 152 | { 153 | if (File.Exists(Launcher.rootDir + "games.json")) 154 | { 155 | // disables usa bios for fightcade launching to ensure same region on both sides 156 | // will add region command line option soon 157 | var us_bios_path = Path.Combine(Launcher.rootDir, "nulldc-1-0-4-en-win", "data", "naomi_boot.bin"); 158 | if (File.Exists(us_bios_path)) 159 | { 160 | if (File.Exists($"{us_bios_path}.inactive")) 161 | { 162 | File.Delete($"{us_bios_path}.inactive"); 163 | } 164 | File.Move(us_bios_path, $"{us_bios_path}.inactive"); 165 | } 166 | 167 | romPath = Launcher.GetRomPathFromGameId(arguments["gameid"]); 168 | if (string.IsNullOrEmpty(romPath)) 169 | { 170 | MessageBox.Show($"Game ID '{arguments["gameid"]}' not found.\n\nPlease check your ROM directory and make sure your files match the provided games.json file."); 171 | return; 172 | } 173 | } 174 | else 175 | { 176 | MessageBox.Show("Please provide a valid games.json file to use the launcher from command line."); 177 | return; 178 | } 179 | } 180 | else 181 | { 182 | MessageBox.Show("Please enter a valid LST path (--lst-path) or Game ID (--gameid) to continue."); 183 | return; 184 | } 185 | 186 | if (arguments.ContainsKey("host-fps") || arguments.ContainsKey("guest-fps")) 187 | { 188 | string launcherCfgPath = Launcher.rootDir + "launcher.cfg"; 189 | var launcherCfgLines = File.ReadAllLines(launcherCfgPath); 190 | 191 | var host_fps_old = launcherCfgLines.Where(s => s.Contains("host_fps=")).ToList().First(); 192 | var guest_fps_old = launcherCfgLines.Where(s => s.Contains("guest_fps=")).ToList().First(); 193 | 194 | var hostFpsEntry = host_fps_old.Split('=')[1]; 195 | var guestFpsEntry = guest_fps_old.Split('=')[1]; 196 | 197 | int host_fps = Convert.ToInt32(hostFpsEntry); 198 | int guest_fps = Convert.ToInt32(guestFpsEntry); 199 | if (arguments.ContainsKey("host-fps")) 200 | { 201 | host_fps = Convert.ToInt32(arguments["host-fps"]); 202 | } 203 | 204 | if (arguments.ContainsKey("guest-fps")) 205 | { 206 | guest_fps = Convert.ToInt32(arguments["guest-fps"]); 207 | } 208 | Launcher.SaveFpsSettings(host_fps, guest_fps); 209 | } 210 | 211 | if (arguments.ContainsKey("offline")) 212 | { 213 | offline = arguments["offline"] == "1"; 214 | hosting = false; 215 | 216 | Launcher.CleanMalformedQjcFiles(); 217 | 218 | Launcher.UpdateCFGFile( 219 | netplayEnabled: !offline, 220 | isHost: hosting); 221 | 222 | Launcher.LaunchNullDC( 223 | RomPath: romPath, 224 | isHost: hosting); 225 | } 226 | else 227 | { 228 | if (arguments.ContainsKey("hosting")) 229 | { 230 | hosting = arguments["hosting"] == "1"; 231 | } 232 | 233 | if (arguments.ContainsKey("audio-sync")) 234 | { 235 | hostInfo.Method = "1"; 236 | Console.WriteLine("audio sync"); 237 | } 238 | 239 | if (arguments.ContainsKey("guess-ip")) 240 | { 241 | hostInfo.Delay = Launcher.GuessDelay(arguments["guess-ip"]).ToString(); 242 | Console.WriteLine($"Delay is set to {hostInfo.Delay}"); 243 | } 244 | else if (arguments.ContainsKey("delay")) 245 | { 246 | hostInfo.Delay = arguments["delay"]; 247 | } 248 | else if (arguments.ContainsKey("host-code")) 249 | { 250 | hostCode = arguments["host-code"]; 251 | hostInfo = Launcher.DecodeHostCode(hostCode); 252 | Console.WriteLine($"Delay is set to {hostInfo.Delay}"); 253 | } 254 | else 255 | { 256 | MessageBox.Show("No delay entered."); 257 | return; 258 | } 259 | 260 | if (arguments.ContainsKey("ip")) 261 | hostInfo.IP = arguments["ip"]; 262 | if (arguments.ContainsKey("port")) 263 | hostInfo.Port = arguments["port"]; 264 | 265 | if (hosting) 266 | { 267 | var genHost = Launcher.GenerateHostCode(hostInfo.IP, hostInfo.Port, hostInfo.Delay, hostInfo.Method); 268 | Console.WriteLine($"Generated Host Code: {genHost}"); 269 | } 270 | 271 | Launcher.CleanMalformedQjcFiles(); 272 | 273 | Launcher.UpdateCFGFile( 274 | netplayEnabled: !offline, 275 | isHost: hosting, 276 | hostAddress: hostInfo.IP, 277 | hostPort: hostInfo.Port, 278 | frameDelay: hostInfo.Delay, 279 | frameMethod: hostInfo.Method); 280 | 281 | Launcher.LaunchNullDC( 282 | RomPath: romPath, 283 | isHost: hosting); 284 | } 285 | 286 | LoadInteractive(tray: true); 287 | } 288 | else 289 | { 290 | LoadInteractive(); 291 | } 292 | } 293 | } 294 | } 295 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NullDC-NAOMI Netplay Launcher Distribution 0.6.5.10 2 | Configuration optimized by blueminder *(July 7, 2020)* 3 | 4 | **Special Thanks** 5 | 6 | - supersonicstep of [FGC Arcadia Discord](https://discord.com/invite/KczAkRr) 7 | - [MarioBrotha](https://github.com/MarioBrotha) of FGC Arcadia Discord (nullDCMultiLauncher, nullDCControlSetup) 8 | - [RossenX](https://github.com/RossenX) of FGC Arcadia Discord for Netplay optimizations 9 | - [poliva](https://github.com/poliva) & [JordiRos](https://github.com/JordiRos) of [Fightcade](https://web.fightcade.com/) for integration & testing 10 | - Labreezy for window handling code & Netplay protocol research 11 | - BRBS of FGC Arcadia Discord for jumping on every beta as it comes out and providing feedback. 12 | - DQRF of GGXXACR Discord 13 | - RaptorIIRC 14 | - Teyah 15 | - Jakstation 16 | - reaVer 17 | - [skmp](https://github.com/skmp) for writing [nullDC](https://github.com/skmp/nulldc) 18 | - [Kegetys](http://www.kegetys.fi/) for [D3D antilag](http://www.kegetys.fi/d3d-antilag-v1-01/) 19 | 20 | ## Prerequisites 21 | 22 | Be sure the following is installed: 23 | 24 | 1. [DirectX](https://www.microsoft.com/en-us/download/details.aspx?id=35) 25 | 2. [Microsoft Visual C++ 2010 Redistributable Package (x86)](https://www.microsoft.com/en-us/download/details.aspx?id=5555) 26 | 3. [.NET Framework 4.8 Runtime](https://dotnet.microsoft.com/download/dotnet-framework/net48) 27 | 28 | Be sure to have the following files gathered prior to testing: 29 | 30 | 1. NAOMI BIOS Files 31 | - Japanese BIOS: `naomi_bios.bin` (EPR-21576D) 32 | - USA BIOS: `naomi_boot.bin` (EPR-21577D) 33 | 2. NAOMI ROMs in the format of a ZIP file containing `.lst` & `.bin` files. 34 | 35 | ## Installing ROMs 36 | 37 | No ROMs are provided with any NullDC Netplay Launcher release. You will have to find the NAOMI BIOS, and any NAOMI ROMs you wish to play on your own. Any community or event you participate in should have a list of approved ROMs to ensure compatibility between opponents, so feel free to ask there. 38 | 39 | Once you have gathered the necessary files: 40 | 41 | 1. Open `nullDCNetplayLauncher.exe` 42 | 2. Open the *File Drop* menu by pressing the up button next to the controller icon on the right. 43 | 3. Locate your `naomi_bios.bin` & ROM `.zip` files in the appropriate format and drag the file into the square. Each ROM `.zip` file must be a collection of `.bin`/`.dat` files along with a corresponding `.lst` file. 44 | 45 | 46 | ![File Drop Demo](file-drop.gif) 47 | 48 | 49 | Alternatively, you can manually place the NAOMI BIOS (`naomi_bios.bin`) in `nulldc-1-0-4-en-win\data` and place your unzipped ROMs in `nulldc-1-0-4-en-win\roms` in their own corresponding directories. 50 | 51 | Dreamcast CDI and GDI ROMs are unsupported at this time. The directory names they reside in will be used at the ROM's display name in the launcher. 52 | 53 | ## Offline Setup 54 | 55 | 1. Open `nullDCNetplayLauncher.exe` 56 | 57 | 2. Press the Controller Icon in the bottom left corner to set your controller or keyboard. 58 | 59 | If you have a keyboard, keep in that numpad buttons, and arrow keys are unsupported at this time. These will be available in an update very soon. Just click the "Setup" button and follow the prompts. 60 | 61 | If you have a controller, be sure that only one game controller is plugged in to your computer and follow the prompts. 62 | 63 | **If the option is available on your arcade stick or controller, switch to PS3 mode.** This has been shown to have the best native compatibility with the qkoJAMMA netplay plugin. If you are using a Brook Universal Fighting Board, you can hold down the *Light Punch* button as you plug it into your PC to activate PS3 mode. 64 | 65 | Once you are done with setup, you may test your button mapping before you exit the dialog. If you ever need to test your current keyboard or controller mapping at any time, the Controller Setup & Testing menu will default to the launcher's current input settings. 66 | 67 | ![setup_demo](setup_demo.gif) 68 | 69 | 3. Select any ROM from the drop-down menu, and press the *Play Offline* button 70 | 71 | This will launch your ROM of choice in NullDC, giving you an opportunity to test your inputs. If this works and you are assigned to Player 1, then you're all set for netplay! 72 | 73 | ## Netplay Setup 74 | 75 | **(OPTIONAL, BUT RECOMMENDED)** [Radmin VPN](https://www.radmin-vpn.com/) 76 | 77 | This netplay method works for any local LAN or virtual LAN setup like Radmin VPN, ZeroTier, or Hamachi. Radmin VPN is the de facto service used on FGC Arcadia. Be sure to have this installed and running before asking for matches on the Discord. You will either need to create or join a network with others also using NullDC prior to playing. 78 | 79 | The rest of the instructions assume that Radmin is installed, but this should work the same way with any network configuration so long as you have the right host IP, ports, and your firewall isn't blocking the relevant ports. 80 | 81 | 1. Open `nullDCNetplayLauncher.exe` 82 | 83 | 2. Select any ROM from the drop-down menu 84 | 85 | 3. Start Session by pressing *Host Game* or *Join Game* 86 | 87 | - **Hosting a Game** 88 | 89 | Copy your target's IP from Radmin and paste it in the *Opponent IP* column. From there, the Launcher will automatically guess the Delay setting for your match based on your distance and ping times. If you are unable to connect, the Delay field will clear and turn red. If applicable, press the *Guess* button to try again. 90 | 91 | Press *Generate Host Code* and press the Clipboard icon to copy the generated code. 92 | 93 | Paste it to your opponent, and they should be able to generate the server details from there. Alternatively, you may expand the window and give them your Host IP, Port, and Delay. Either method works. 94 | 95 | Verify that you and your opponent have the same Delay set. 96 | 97 | Press the *Launch Game* button. 98 | 99 | ![Host Game Demo](host-flow.gif) 100 | 101 | - **Joining a Game** 102 | 103 | Paste the generated Host Code and server details should automatically be filled in. If any advanced options have been set by your host, your window will expand to reveal these options. 104 | 105 | Alternatively, you may expand your window to manually enter your opponent's Host IP, Port, and Delay to continue. Either method works. 106 | 107 | Make sure you have your opponent's Radmin IP in the launcher's *Opponent IP* column. Verify that you and your opponent have the same Delay. 108 | 109 | ![Join Game Demo](guest-flow-pop-out.gif) 110 | 111 | 4. Press the *Launch Game* button. 112 | 113 | 5. Play! 114 | 115 | If you experience any significant slowdown or strange performance, be sure to change the Delay around the determined value. It takes some trial and error, but once you have it, it's smooth sailing from there. Just be sure that you and your opponent have a matching Delay. 116 | 117 | After you found the sweet spot, you can change the name of the preset where you would typically find "Default", and save your settings for the next time you want to play against your new Internet fight buddies. 118 | 119 | Just in case the *Guess* button isn't reliable, these are the recommended Delay parameters based on average ping in milliseconds according to the archived [GuiltyGear XX AC Online](https://web.archive.org/web/20111028233111/https://sites.google.com/site/ggxxaconline/) site: 120 | ``` 121 | < 25ms = 1 Delay Frame needed 122 | < 60ms = 2 Delay Frame needed 123 | < 100ms = 3 Delay Frame needed 124 | < 130ms = 4 Delay Frame needed 125 | < 155ms = 5 Delay Frame needed 126 | < 180ms = 6 Delay Frame needed 127 | > 180ms = Don't even bother :( 128 | ``` 129 | 130 | ## Command Line 131 | 132 | The launcher now has command line options, so that you may integrate NullDC Netplay into any emulator launcher or lobby software of your choice. To see all options, you can run: 133 | 134 | `nullDCNetplayLauncher.exe --help` 135 | 136 | Games may be specified in a provided `games.json` file, showing ROM details like description and file location. Games listed in this file may be called by using the `--gameid` flag: 137 | 138 | `nullDCNetplayLauncher.exe --gameid cvs2 --offline 1` 139 | 140 | Otherwise, you may launch any path by running: 141 | 142 | `nullDCNetplayLauncher.exe --lst-path --offline 1` 143 | 144 | To host a game: 145 | 146 | `nullDCNetplayLauncher.exe --gameid cvs2 --hosting 1 --ip --port --delay ` 147 | 148 | To join a game: 149 | 150 | `nullDCNetplayLauncher.exe --gameid cvs2 --hosting 0 --ip --port --delay ` 151 | 152 | If you want the launcher to automatically guess the delay, you may use the `--guess-ip` flag: 153 | 154 | `nullDCNetplayLauncher.exe --gameid cvs2 --hosting 0 --ip --port --guess-ip ` 155 | 156 | When the Launcher is invoked for game sessions via command line, the launcher menu is kept available through an icon on the system tray. You may adjust your Keyboard Mapper options in here while your game is in session. 157 | 158 | To access the Controller Setup & Testing by itself via the command line: 159 | 160 | `nullDCNetplayLauncher.exe --controller-setup 1 ` 161 | 162 | ## Troubleshooting 163 | 164 | > My controller is only half-detected / I am encountering input issues when I use the controller setup. 165 | 166 | If you are having trouble with mapping your controls, try pressing the *Force Keyboard Mapper* checkbox on the controller setup menu. This will activate the launcher's internal keyboard mapper which provides expanded controller support from the default qkoJAMMA controller drivers. 167 | 168 | If the option is available on your arcade stick, you can also try to select the "PS3" option on your controller and try again without the Keyboard Mapper enabled. PS3 controllers have been found to have the best compatibility with qkoJAMMA. If you have a Brook Universal Fighting Board, you can activate the PS3 mode by holding down Light Punch as you plug it in your computer. 169 | 170 | ------ 171 | 172 | 173 | 174 | > Is there any way to change my Keyboard controls, or joystick controls manually without the aid of the launcher? 175 | 176 | You may edit your keyboard and joystick definitions by editing the'`.qkc` and `.qjc`files respectively, found in the `nulldc-1-0-4-en-win\qkoJAMMA` directory. You may be able to access this folder directly by going to *Settings* > *Advanced* > *Open qkoJAMMA Folder*. You may edit these files with any text editor of your choice. 177 | 178 | If you are setting Keyboard keys, note that numpad and arrow keys are not supported at this time. A known workaround people have used is AutoHotkey. That said, expanding keyboard controls is anticipated in a future release, since arcade cabinets popularly use IPAC and similar devices that simulate keyboard inputs. 179 | 180 | If you are setting your joystick, be sure that the button numbers set in your corresponding `.qjc` file match your controller's definition in the *Windows Game Controllers*. You may also be able to find a shortcut to this in the *Settings* > *Advanced* menu. 181 | 182 | ------ 183 | 184 | 185 | 186 | > When I try to join or host a game, neither of us are able to connect. What should I do? 187 | 188 | The very first step to troubleshooting network connectivity issues is to temporarily disable your firewalls to see if everything works in those conditions. You can do this in the "Windows Defender Firewall" Control Panel. If you are able to connect to each other when the firewall is off, verify your settings and make sure that you give `nullDC_Win32_Release-NoTrace.exe` permission to access private networks. If that doesn't work, enable public networks from there. 189 | 190 | When troubleshooting network issues, keep an eye on the Command Window for any details. This will be useful information for anyone who helps you in the [FGC Arcadia Discord](https://discord.com/invite/KczAkRr). 191 | 192 | 193 | 194 | ------ 195 | 196 | 197 | 198 | > When I play Atomiswave games, every button I press just adds coins or is stuck on start. 199 | 200 | Check to see if the Test button assignment conflicts with the Start button. It's best to make sure that none of your buttons overlap when doing the controller mapping. You can verify this by looking up the `.qjc` file that corresponds with your joystick in the `nulldc-1-0-4-en-win\qkoJAMMA` directory. This directory is accessible via the Advanced tab of the Settings. 201 | 202 | If you are unable to fix the controls manually for a regular joystick, consider using the Keyboard Mapper. This alone has cleared up the problem for many people. 203 | 204 | If you have any additional questions, feel free to ask in the [FGC Arcadia Discord](https://discord.com/invite/KczAkRr). 205 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/HostControl.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Drawing; 5 | using System.Data; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | using System.Windows.Forms; 10 | using System.IO; 11 | using System.Xml; 12 | using System.Net; 13 | using System.Net.NetworkInformation; 14 | using System.Net.Sockets; 15 | using System.DirectoryServices; 16 | using System.Text.RegularExpressions; 17 | 18 | namespace nullDCNetplayLauncher 19 | { 20 | public partial class HostControl : UserControl 21 | { 22 | ConnectionPresetList presets; 23 | 24 | public HostControl() 25 | { 26 | presets = ConnectionPreset.ReadPresetsFile(); 27 | InitializeComponent(); 28 | 29 | cboPresetName.DataSource = presets.ConnectionPresets; 30 | 31 | btnDeletePreset.Enabled = presets.ConnectionPresets.Count > 1; 32 | 33 | Dictionary RegionOptions = new Dictionary(); 34 | RegionOptions["Japan"] = "japan"; 35 | RegionOptions["USA"] = "usa"; 36 | 37 | cboRegion.DataSource = new BindingSource(RegionOptions, null); 38 | cboRegion.DisplayMember = "Key"; 39 | cboRegion.ValueMember = "Value"; 40 | 41 | var us_bios_path = Path.Combine(Launcher.rootDir, "nulldc-1-0-4-en-win", "data", "naomi_boot.bin"); 42 | if (!File.Exists(us_bios_path) && !File.Exists($"{us_bios_path}.inactive")) 43 | cboRegion.Enabled = false; 44 | } 45 | 46 | private void HostControl_Load(object sender, EventArgs e) 47 | { 48 | cboMethod.DataSource = new BindingSource(Launcher.MethodOptions, null); 49 | cboMethod.DisplayMember = "Key"; 50 | cboMethod.ValueMember = "Value"; 51 | 52 | 53 | cboHostIP.DataSource = new BindingSource(Launcher.NetQuery.LocalIPsByNetwork, null); 54 | cboHostIP.DisplayMember = "Value"; 55 | cboHostIP.ValueMember = "Value"; 56 | 57 | String hostIP; 58 | if (NetworkQuery.GetRadminHostIP() != null) 59 | hostIP = NetworkQuery.GetRadminHostIP(); 60 | else if (NetworkQuery.GetExternalIP() != null) 61 | hostIP = NetworkQuery.GetExternalIP(); 62 | else 63 | hostIP = (string)Launcher.NetQuery.LocalIPsByNetwork.First().Value; 64 | cboHostIP.SelectedValue = hostIP; 65 | 66 | } 67 | 68 | public void SavePreset(string presetName) 69 | { 70 | var toEdit = presets.ConnectionPresets.FirstOrDefault(p => p.Name == presetName); 71 | if (toEdit != null) 72 | { 73 | toEdit.IP = cboHostIP.Text; 74 | toEdit.Port = txtHostPort.Text; 75 | toEdit.Delay = numDelay.Value; 76 | toEdit.Method = Convert.ToInt32(cboMethod.SelectedValue); 77 | toEdit.Region = cboRegion.SelectedValue.ToString(); 78 | } 79 | else 80 | { 81 | var toAdd = new ConnectionPreset(); 82 | toAdd.Name = cboPresetName.Text; 83 | toAdd.IP = cboHostIP.Text; 84 | toAdd.Port = txtHostPort.Text; 85 | toAdd.Delay = numDelay.Value; 86 | toAdd.Method = Convert.ToInt32(cboMethod.SelectedValue); 87 | toAdd.Region = cboRegion.SelectedValue.ToString(); 88 | presets.ConnectionPresets.Add(toAdd); 89 | } 90 | 91 | var path = Launcher.GetApplicationConfigurationDirectoryName() + "//ConnectionPresetList.xml"; 92 | System.Xml.Serialization.XmlSerializer serializer = 93 | new System.Xml.Serialization.XmlSerializer(typeof(ConnectionPresetList)); 94 | StreamWriter writer = new StreamWriter(path); 95 | serializer.Serialize(writer.BaseStream, presets); 96 | writer.Close(); 97 | presets = ConnectionPreset.ReadPresetsFile(); 98 | cboPresetName.DataSource = presets.ConnectionPresets; 99 | cboPresetName.SelectedIndex = cboPresetName.FindStringExact(presetName); 100 | if (presets.ConnectionPresets.Count > 1) 101 | { 102 | btnDeletePreset.Enabled = true; 103 | } 104 | cboPresetName.BackColor = Color.LemonChiffon; 105 | } 106 | 107 | public void DeletePreset(string presetName) 108 | { 109 | if (presets.ConnectionPresets.Count > 1) 110 | { 111 | var toDelete = presets.ConnectionPresets.FirstOrDefault(p => p.Name == presetName); 112 | presets.ConnectionPresets.Remove(toDelete); 113 | 114 | var path = Launcher.GetApplicationConfigurationDirectoryName() + "//ConnectionPresetList.xml"; 115 | System.Xml.Serialization.XmlSerializer serializer = 116 | new System.Xml.Serialization.XmlSerializer(typeof(ConnectionPresetList)); 117 | StreamWriter writer = new StreamWriter(path); 118 | serializer.Serialize(writer.BaseStream, presets); 119 | writer.Close(); 120 | presets = ConnectionPreset.ReadPresetsFile(); 121 | cboPresetName.DataSource = presets.ConnectionPresets; 122 | cboPresetName.SelectedIndex = 0; 123 | if (presets.ConnectionPresets.Count == 1) 124 | { 125 | btnDeletePreset.Enabled = false; 126 | } 127 | } 128 | } 129 | 130 | private void LoadPreset(string presetName) 131 | { 132 | ConnectionPreset toLoad = presets.ConnectionPresets.FirstOrDefault(p => p.Name == presetName); 133 | if (toLoad != null) 134 | { 135 | cboHostIP.Text = toLoad.IP; 136 | txtHostPort.Text = toLoad.Port; 137 | numDelay.Value = toLoad.Delay; 138 | cboMethod.SelectedValue = toLoad.Method; 139 | cboRegion.SelectedValue = toLoad.Region; 140 | } 141 | } 142 | 143 | private void GuessDelay(string ip) 144 | { 145 | long guessedDelay = Launcher.GuessDelay(ip); 146 | if (guessedDelay >= 0) 147 | { 148 | numDelay.Value = guessedDelay; 149 | txtOpponentIP.BackColor = Color.Honeydew; 150 | numDelay.BackColor = Color.Honeydew; 151 | } 152 | else 153 | { 154 | numDelay.Text = ""; 155 | txtOpponentIP.BackColor = Color.LightCoral; 156 | numDelay.BackColor = Color.LightCoral; 157 | } 158 | } 159 | 160 | private void btnGuess_Click(object sender, EventArgs e) 161 | { 162 | GuessDelay(txtOpponentIP.Text); 163 | } 164 | 165 | private void btnGenHostCode_Click(object sender, EventArgs e) 166 | { 167 | if (cboRegion.SelectedValue.ToString() != "japan") 168 | cboRegion.BackColor = Color.Honeydew; 169 | 170 | var hostCode = Launcher.GenerateHostCode(cboHostIP.Text, 171 | txtHostPort.Text, 172 | Convert.ToInt32(numDelay.Value).ToString(), 173 | Convert.ToInt32(cboMethod.SelectedValue).ToString(), 174 | cboRegion.SelectedValue.ToString()); 175 | txtHostCode.Text = hostCode; 176 | txtHostCode.BackColor = Color.Honeydew; 177 | } 178 | 179 | private void btnLaunchGame_Click(object sender, EventArgs e) 180 | { 181 | Launcher.SwitchRegion(cboRegion.SelectedValue.ToString()); 182 | Launcher.CleanMalformedQjcFiles(); 183 | Launcher.UpdateCFGFile( 184 | netplayEnabled: true, 185 | isHost: true, 186 | hostAddress: cboHostIP.Text, 187 | hostPort: txtHostPort.Text, 188 | frameDelay: Convert.ToInt32(numDelay.Value) 189 | .ToString(), 190 | frameMethod: cboMethod.SelectedValue.ToString()); 191 | Launcher.LaunchNullDC(Launcher.SelectedGame, isHost: true); 192 | } 193 | 194 | private void btnCopy_Click(object sender, EventArgs e) 195 | { 196 | if (txtHostCode.Text == "") 197 | { 198 | txtHostCode.BackColor = Color.Tomato; 199 | } 200 | else 201 | { 202 | txtHostCode.BackColor = Color.LemonChiffon; 203 | Clipboard.SetText(txtHostCode.Text); 204 | } 205 | } 206 | 207 | private void txtHostCode_GotFocus(object sender, EventArgs e) 208 | { 209 | txtHostCode.BackColor = Color.White; 210 | } 211 | 212 | private void txtHostPort_GotFocus(object sender, EventArgs e) 213 | { 214 | txtHostPort.BackColor = Color.White; 215 | } 216 | 217 | private void numDelay_GotFocus(object sender, EventArgs e) 218 | { 219 | numDelay.BackColor = Color.White; 220 | } 221 | 222 | private void cboPresetName_GotFocus(object sender, EventArgs e) 223 | { 224 | cboPresetName.BackColor = Color.White; 225 | } 226 | 227 | private void btnSavePreset_Click(object sender, EventArgs e) 228 | { 229 | SavePreset(cboPresetName.Text); 230 | } 231 | 232 | private void btnDeletePreset_Click(object sender, EventArgs e) 233 | { 234 | DeletePreset(cboPresetName.Text); 235 | } 236 | 237 | private void cboPresetName_TextChanged(object sender, EventArgs e) 238 | { 239 | LoadPreset(cboPresetName.Text); 240 | } 241 | 242 | private void cboPresetName_SelectedIndexChanged(object sender, EventArgs e) 243 | { 244 | txtHostCode.BackColor = Color.White; 245 | cboHostIP.BackColor = Color.White; 246 | txtHostPort.BackColor = Color.White; 247 | numDelay.BackColor = Color.White; 248 | cboMethod.BackColor = Color.White; 249 | LoadPreset(cboPresetName.Text); 250 | } 251 | 252 | private void btnExpandCollapse_Click(object sender, EventArgs e) 253 | { 254 | var win = this.Parent; 255 | if (splitHost.Panel2Collapsed) 256 | { 257 | btnExpandCollapse.Text = "↓ Advanced Options ↓"; 258 | win.Size = win.MaximumSize; 259 | splitHost.Panel2Collapsed = false; 260 | } 261 | else 262 | { 263 | btnExpandCollapse.Text = "↑ Advanced Options ↑"; 264 | win.Size = win.MinimumSize; 265 | splitHost.Panel2Collapsed = true; 266 | } 267 | } 268 | 269 | private void txtOpponentIP_TextChanged(object sender, EventArgs e) 270 | { 271 | if (NetworkQuery.ValidateIPv4(txtOpponentIP.Text)) 272 | { 273 | string hostIP; 274 | // if radmin ip not detected, changes host to external 275 | // falls back to local if external connection can not be made 276 | if (txtOpponentIP.Text.StartsWith("26")) 277 | { 278 | hostIP = NetworkQuery.GetRadminHostIP(); 279 | } 280 | else 281 | { 282 | hostIP = NetworkQuery.GetExternalIP(); 283 | if (hostIP == null) 284 | hostIP = (string)Launcher.NetQuery.LocalIPsByNetwork.First().Value; 285 | } 286 | cboHostIP.SelectedValue = hostIP; 287 | GuessDelay(txtOpponentIP.Text); 288 | } 289 | else 290 | txtOpponentIP.BackColor = Color.White; 291 | } 292 | 293 | private void numDelay_ValueChanged(object sender, EventArgs e) 294 | { 295 | numDelay.BackColor = Color.White; 296 | } 297 | 298 | private void txtHostCode_TextChanged(object sender, EventArgs e) 299 | { 300 | txtHostCode.BackColor = Color.White; 301 | } 302 | 303 | private void cboHostIP_SelectedIndexChanged(object sender, EventArgs e) 304 | { 305 | txtHostCode.Text = ""; 306 | } 307 | 308 | private void cboRegion_SelectedIndexChanged(object sender, EventArgs e) 309 | { 310 | cboRegion.BackColor = Color.White; 311 | } 312 | } 313 | } 314 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/Properties/Resources.resx: -------------------------------------------------------------------------------- 1 | 2 | 3 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | text/microsoft-resx 110 | 111 | 112 | 2.0 113 | 114 | 115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 116 | 117 | 118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 119 | 120 | 121 | 122 | ..\Resources\left.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 123 | 124 | 125 | ..\Resources\5.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 126 | 127 | 128 | ..\Resources\round_publish_black_18dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 129 | 130 | 131 | ..\Resources\icons8-game-controller-26.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 132 | 133 | 134 | ..\Resources\coin.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 135 | 136 | 137 | ..\Resources\2.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 138 | 139 | 140 | ..\Resources\base_full.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 141 | 142 | 143 | ..\Resources\down.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 144 | 145 | 146 | ..\Resources\start.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 147 | 148 | 149 | ..\Resources\1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 150 | 151 | 152 | ..\Resources\round_multiple_stop_black_24dp.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 153 | 154 | 155 | ..\Resources\6.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 156 | 157 | 158 | ..\Resources\right.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 159 | 160 | 161 | ..\Resources\up.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 162 | 163 | 164 | ..\Resources\4.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 165 | 166 | 167 | ..\Resources\naomi.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 168 | 169 | 170 | ..\Resources\3.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 171 | 172 | 173 | ..\Resources\test.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 174 | 175 | 176 | ..\Resources\settings.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 177 | 178 | 179 | ..\Resources\icons8-game-controller-26.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 180 | 181 | 182 | ..\Resources\outline_highlight_alt_black_48dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 183 | 184 | 185 | ..\resources\round_publish_black_18dp.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 186 | 187 | 188 | ..\Resources\GamePadMappingList.xml;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 189 | 190 | 191 | ..\resources\launcher.cfg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 192 | 193 | 194 | ..\Resources\naomi_nvmem.bin;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 195 | 196 | 197 | ..\Resources\nulldc-1-0-4-en-win.zip;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 198 | 199 | 200 | ..\resources\round_publish_black_18dp.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 201 | 202 | 203 | ..\Resources\nullDC.cfg;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 204 | 205 | 206 | ..\Resources\round_not_listed_location_black_18dp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 207 | 208 | 209 | ..\Resources\round_not_listed_location_black_18dp.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a 210 | 211 | 212 | ..\Resources\README.html;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;Windows-1252 213 | 214 | 215 | ..\resources\keyboard.qkc;System.Byte[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 216 | 217 | -------------------------------------------------------------------------------- /nullDCNetplayLauncher/SettingsControl.cs: -------------------------------------------------------------------------------- 1 | using Onova; 2 | using Onova.Services; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel; 6 | using System.Data; 7 | using System.Diagnostics; 8 | using System.Drawing; 9 | using System.IO; 10 | using System.Linq; 11 | using System.Net; 12 | using System.Runtime.InteropServices; 13 | using System.Text; 14 | using System.Text.RegularExpressions; 15 | using System.Threading.Tasks; 16 | using System.Windows.Forms; 17 | 18 | namespace nullDCNetplayLauncher 19 | { 20 | public partial class SettingsControl : UserControl 21 | { 22 | private readonly IUpdateManager _updateManager = new UpdateManager( 23 | new GithubPackageResolver("blueminder", "nullDCNetplayLauncher", "*Distribution*"), 24 | new ZipPackageExtractor()); 25 | 26 | public SettingsControl() 27 | { 28 | InitializeComponent(); 29 | } 30 | 31 | string[] cfgLines; 32 | 33 | string player1_old; 34 | string backup_old; 35 | string player2_old; 36 | 37 | string p1Entry; 38 | string backupEntry; 39 | string p2Entry; 40 | 41 | private void SettingsForm_Load(object sender, EventArgs e) 42 | { 43 | cfgLines = File.ReadAllLines(Launcher.rootDir + "nulldc-1-0-4-en-win\\nullDC.cfg"); 44 | player1_old = cfgLines.Where(s => s.Contains("player1=")).ToList().First(); 45 | backup_old = cfgLines.Where(s => s.Contains("backup=")).ToList().First(); 46 | player2_old = cfgLines.Where(s => s.Contains("player2=")).ToList().First(); 47 | 48 | Dictionary InputOptions = new Dictionary(); 49 | InputOptions[""] = ""; 50 | InputOptions["Keyboard"] = "keyboard"; 51 | InputOptions["Joystick 1"] = "joy1"; 52 | 53 | cboPlayer1.DataSource = new BindingSource(InputOptions, null); 54 | cboPlayer1.DisplayMember = "Key"; 55 | cboPlayer1.ValueMember = "Value"; 56 | 57 | p1Entry = player1_old.Split('=')[1]; 58 | backupEntry = backup_old.Split('=')[1]; 59 | p2Entry = player2_old.Split('=')[1]; 60 | 61 | cboPlayer1.SelectedValue = p1Entry; 62 | 63 | var windowSettings = Launcher.LoadWindowSettings(); 64 | if (windowSettings[3] == 1) 65 | { 66 | rdoStartMax.Checked = true; 67 | } 68 | else if(windowSettings[0] == 1) 69 | { 70 | rdoCustomSize.Checked = true; 71 | } 72 | else 73 | { 74 | rdoDefault.Checked = true; 75 | } 76 | 77 | txtWindowX.Text = windowSettings[1].ToString(); 78 | txtWindowY.Text = windowSettings[2].ToString(); 79 | 80 | string launcherCfgPath = Launcher.rootDir + "launcher.cfg"; 81 | string launcherText = File.ReadAllText(launcherCfgPath); 82 | if (launcherText.Contains("enable_mapper=1") || NetplayLaunchForm.EnableMapper == true) 83 | { 84 | chkEnableMapper.Checked = true; 85 | } 86 | else 87 | { 88 | chkEnableMapper.Checked = false; 89 | } 90 | 91 | if (launcherText.Contains("custom_cfg=1")) 92 | chkCustomCFG.Checked = true; 93 | 94 | Dictionary RegionOptions = new Dictionary(); 95 | RegionOptions["Japan"] = "japan"; 96 | RegionOptions["USA"] = "usa"; 97 | 98 | cboRegion.DataSource = new BindingSource(RegionOptions, null); 99 | cboRegion.DisplayMember = "Key"; 100 | cboRegion.ValueMember = "Value"; 101 | 102 | var launcherCfgLines = File.ReadAllLines(launcherCfgPath); 103 | var host_fps_old = launcherCfgLines.Where(s => s.Contains("host_fps=")).ToList().First(); 104 | var guest_fps_old = launcherCfgLines.Where(s => s.Contains("guest_fps=")).ToList().First(); 105 | var region_old = launcherCfgLines.Where(s => s.Contains("region=")).ToList().First(); 106 | 107 | var hostFpsEntry = host_fps_old.Split('=')[1]; 108 | var guestFpsEntry = guest_fps_old.Split('=')[1]; 109 | var regionEntry = region_old.Split('=')[1]; 110 | 111 | numHostFPS.Value = Convert.ToInt32(hostFpsEntry); 112 | 113 | try 114 | { 115 | Launcher.mappings = GamePadMapping.ReadMappingsFile(); 116 | Launcher.ActiveGamePadMapping = Launcher.mappings.GamePadMappings.Where(g => g.Default == true).ToList().First(); 117 | } 118 | catch 119 | { 120 | Launcher.ActiveGamePadMapping = Launcher.mappings.GamePadMappings.First(); 121 | } 122 | 123 | cboGamePadMappings.DataSource = Launcher.mappings.GamePadMappings; 124 | cboGamePadMappings.DisplayMember = Name; 125 | 126 | cboGamePadMappings.SelectedItem = Launcher.ActiveGamePadMapping; 127 | 128 | cboRegion.SelectedValue = regionEntry; 129 | 130 | var us_bios_path = Path.Combine(Launcher.rootDir, "nulldc-1-0-4-en-win", "data", "naomi_boot.bin"); 131 | if (!File.Exists(us_bios_path) && !File.Exists($"{us_bios_path}.inactive")) 132 | cboRegion.Enabled = false; 133 | 134 | lblVersion.Text = Application.ProductVersion; 135 | } 136 | 137 | private void btnEditCFG_Click(object sender, EventArgs e) 138 | { 139 | Process.Start("notepad.exe", Launcher.rootDir + "nulldc-1-0-4-en-win\\nullDC.cfg"); 140 | } 141 | 142 | private void btnOpenQKO_Click(object sender, EventArgs e) 143 | { 144 | Process.Start("explorer.exe", Launcher.rootDir + "nulldc-1-0-4-en-win\\qkoJAMMA"); 145 | } 146 | 147 | private void btnSaveInput_Click(object sender, EventArgs e) 148 | { 149 | string launcherText = File.ReadAllText(Launcher.rootDir + "launcher.cfg"); 150 | string[] launcherCfgLines = File.ReadAllLines(Launcher.rootDir + "launcher.cfg"); 151 | string cfgText = File.ReadAllText(Launcher.rootDir + "nulldc-1-0-4-en-win\\nullDC.cfg"); 152 | string[] cfgLines = File.ReadAllLines(Launcher.rootDir + "nulldc-1-0-4-en-win\\nullDC.cfg"); 153 | 154 | if(chkCustomCFG.Checked) 155 | { 156 | if (!launcherText.Contains("custom_cfg")) 157 | { 158 | launcherText += "custom_cfg=1" + Environment.NewLine; 159 | } 160 | else 161 | { 162 | launcherText = launcherText.Replace("custom_cfg=0", "custom_cfg=1"); 163 | } 164 | } 165 | else 166 | { 167 | if (!launcherText.Contains("custom_cfg")) 168 | { 169 | launcherText += "custom_cfg=0" + Environment.NewLine; 170 | } 171 | else 172 | { 173 | launcherText = launcherText.Replace("custom_cfg=1", "custom_cfg=0"); 174 | } 175 | } 176 | 177 | 178 | if (chkEnableMapper.Checked) 179 | { 180 | launcherText = launcherText.Replace("enable_mapper=0", "enable_mapper=1"); 181 | launcherText = launcherText.Replace("player1=joy1", "player1=keyboard"); 182 | 183 | var player1_old = cfgLines.Where(s => s.Contains("player1=")).ToList().First(); 184 | cfgText = cfgText.Replace(player1_old, "player1=keyboard"); 185 | 186 | foreach (GamePadMapping mapping in Launcher.mappings.GamePadMappings) 187 | { 188 | mapping.Default = false; 189 | } 190 | 191 | ((GamePadMapping)cboGamePadMappings.SelectedValue).Default = true; 192 | 193 | Launcher.ActiveGamePadMapping = (GamePadMapping)cboGamePadMappings.SelectedValue; 194 | 195 | var path = Launcher.rootDir + "//GamePadMappingList.xml"; 196 | System.Xml.Serialization.XmlSerializer serializer = 197 | new System.Xml.Serialization.XmlSerializer(typeof(GamePadMappingList)); 198 | StreamWriter writer = new StreamWriter(path); 199 | serializer.Serialize(writer.BaseStream, Launcher.mappings); 200 | writer.Close(); 201 | 202 | NetplayLaunchForm.StopMapper(true); 203 | NetplayLaunchForm.StartMapper(); 204 | } 205 | else 206 | { 207 | launcherText = launcherText.Replace("enable_mapper=1", "enable_mapper=0"); 208 | if (cboPlayer1.SelectedValue.ToString() == "joy1") 209 | launcherText = launcherText.Replace("player1=keyboard", "player1=joy1"); 210 | var player1_old = cfgLines.Where(s => s.Contains("player1=")).ToList().First(); 211 | cfgText = cfgText.Replace(player1_old, "player1=joy1"); 212 | 213 | NetplayLaunchForm.StopMapper(); 214 | } 215 | 216 | String p1_val = $"{cboPlayer1.SelectedValue}"; 217 | 218 | if (p1_val.Length == 0) 219 | p1_val = "NULL"; 220 | 221 | var region_old = launcherCfgLines.Where(s => s.Contains("region=")).ToList().First(); 222 | String region_val = $"{cboRegion.SelectedValue}"; 223 | 224 | cfgText = cfgText.Replace(player1_old, "player1=" + p1_val); 225 | launcherText = launcherText.Replace(player1_old, "player1=" + p1_val); 226 | launcherText = launcherText.Replace(region_old, "region=" + region_val); 227 | File.WriteAllText(Launcher.rootDir + "nulldc-1-0-4-en-win\\nullDC.cfg", cfgText); 228 | File.WriteAllText(Launcher.rootDir + "launcher.cfg", launcherText); 229 | 230 | // reload from file 231 | cfgLines = File.ReadAllLines(Launcher.rootDir + "nulldc-1-0-4-en-win\\nullDC.cfg"); 232 | player1_old = cfgLines.Where(s => s.Contains("player1=")).ToList().First(); 233 | backup_old = cfgLines.Where(s => s.Contains("backup=")).ToList().First(); 234 | player2_old = cfgLines.Where(s => s.Contains("player2=")).ToList().First(); 235 | 236 | Launcher.LoadRegionSettings(); 237 | Launcher.RestoreFiles(); 238 | 239 | MessageBox.Show("Main Settings Successfully Saved"); 240 | } 241 | 242 | private void chkEnableMapper_CheckedChanged(object sender, EventArgs e) 243 | { 244 | if (chkEnableMapper.Checked) 245 | { 246 | cboPlayer1.Text = "Keyboard"; 247 | cboPlayer1.Enabled = false; 248 | cboGamePadMappings.Enabled = true; 249 | if (Launcher.mappings.GamePadMappings.Count > 1) 250 | btnDeleteMapping.Enabled = true; 251 | NetplayLaunchForm.EnableMapper = true; 252 | } 253 | else 254 | { 255 | cboPlayer1.Enabled = true; 256 | cboGamePadMappings.Enabled = false; 257 | btnDeleteMapping.Enabled = false; 258 | NetplayLaunchForm.EnableMapper = false; 259 | } 260 | } 261 | 262 | private void btnJoyCpl_Click(object sender, EventArgs e) 263 | { 264 | Process.Start("joy.cpl"); 265 | } 266 | 267 | private void btnSaveWindow_Click(object sender, EventArgs e) 268 | { 269 | var width = Convert.ToInt32(txtWindowX.Text); 270 | var height = Convert.ToInt32(txtWindowY.Text); 271 | 272 | if (rdoStartMax.Checked) 273 | Launcher.SaveWindowSettings(0, width, height, 1); 274 | else if (rdoCustomSize.Checked) 275 | Launcher.SaveWindowSettings(1, width, height); 276 | else 277 | Launcher.SaveWindowSettings(0, width, height); 278 | MessageBox.Show("Window Settings Successfully Saved"); 279 | } 280 | 281 | private void btnGrabWindowSize_Click(object sender, EventArgs e) 282 | { 283 | rdoCustomSize.Checked = true; 284 | Point ndcWin = Launcher.NullDCWindowDimensions(); 285 | txtWindowX.Text = ndcWin.X.ToString(); 286 | txtWindowY.Text = ndcWin.Y.ToString(); 287 | } 288 | 289 | private void btnSaveFPS_Click(object sender, EventArgs e) 290 | { 291 | Launcher.SaveFpsSettings(Convert.ToInt32(numHostFPS.Value), 90); 292 | MessageBox.Show("FPS Limits Successfully Saved"); 293 | } 294 | 295 | private void txtWindowX_GotFocus(object sender, EventArgs e) 296 | { 297 | rdoCustomSize.Checked = true; 298 | } 299 | 300 | private void txtWindowY_GotFocus(object sender, EventArgs e) 301 | { 302 | rdoCustomSize.Checked = true; 303 | } 304 | 305 | private void btnDeleteMapping_Click(object sender, EventArgs e) 306 | { 307 | DeleteMapping(cboGamePadMappings.Text); 308 | } 309 | 310 | public void DeleteMapping(string mappingName) 311 | { 312 | if (Launcher.mappings.GamePadMappings.Count > 1) 313 | { 314 | var toDelete = Launcher.mappings.GamePadMappings.FirstOrDefault(p => p.Name == mappingName); 315 | Launcher.mappings.GamePadMappings.Remove(toDelete); 316 | 317 | var path = Launcher.rootDir + "GamePadMappingList.xml"; 318 | System.Xml.Serialization.XmlSerializer serializer = 319 | new System.Xml.Serialization.XmlSerializer(typeof(GamePadMappingList)); 320 | StreamWriter writer = new StreamWriter(path); 321 | serializer.Serialize(writer.BaseStream, Launcher.mappings); 322 | writer.Close(); 323 | Launcher.mappings = GamePadMapping.ReadMappingsFile(); 324 | cboGamePadMappings.DataSource = Launcher.mappings.GamePadMappings; 325 | cboGamePadMappings.SelectedIndex = 0; 326 | if (Launcher.mappings.GamePadMappings.Count == 1) 327 | { 328 | btnDeleteMapping.Enabled = false; 329 | } 330 | } 331 | } 332 | 333 | private void cboGamePadMappings_SelectedIndexChanged(object sender, EventArgs e) 334 | { 335 | System.Diagnostics.Debug.WriteLine(cboGamePadMappings.SelectedValue); 336 | } 337 | 338 | private void btnUpdate_Click(object sender, EventArgs e) 339 | { 340 | NetplayLaunchForm.launcher.UpdateLauncher(false); 341 | } 342 | 343 | } 344 | } 345 | --------------------------------------------------------------------------------