diff --git a/CheckUpdates.cs b/CheckUpdates.cs index d607b54..e17b112 100644 --- a/CheckUpdates.cs +++ b/CheckUpdates.cs @@ -31,7 +31,7 @@ private async void CheckUpdates_Load(object sender, EventArgs e) { await CheckGitHubNewerVersion(); } - catch (Exception err) + catch { label1.Text = "Could not check for updates"; } diff --git a/Config/config.default.json b/Config/config.default.json index eeb7a60..4b51590 100644 --- a/Config/config.default.json +++ b/Config/config.default.json @@ -258,6 +258,7 @@ }, "TrackRemapping": {}, "Shuffle": false, + "CutsceneMovement": false, "ShuffleRotation": [ "Battle_00", "Battle_0a", diff --git a/Config/config.json b/Config/config.json index 3c9d1fc..877044d 100644 --- a/Config/config.json +++ b/Config/config.json @@ -258,6 +258,7 @@ }, "TrackRemapping": {}, "Shuffle": false, + "CutsceneMovement": false, "ShuffleRotation": [ "Battle_00", "Battle_0a", diff --git a/DMC3MusicConfig.cs b/DMC3MusicConfig.cs index 5a39341..f64bbfc 100644 --- a/DMC3MusicConfig.cs +++ b/DMC3MusicConfig.cs @@ -12,6 +12,7 @@ public class DMC3MusicConfig public Dictionary> RoomTracks { get; set; } public Dictionary> AmbientTracks { get; set; } public bool Shuffle { get; set; } + public bool CutsceneMovement { get; set; } public List ShuffleRotation { get; set; } public int BattleTimer { get; set; } public int AmbientTimer { get; set; } diff --git a/DMC3Process.cs b/DMC3Process.cs new file mode 100644 index 0000000..ba4e403 --- /dev/null +++ b/DMC3Process.cs @@ -0,0 +1,180 @@ +using Microsoft.Win32.SafeHandles; +using System; +using System.Diagnostics; +using System.Runtime.InteropServices; + +namespace dmc3music +{ + class DMC3Process : IDisposable + { + [DllImport("kernel32.dll")] + private static extern UIntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId); + + [DllImport("kernel32", SetLastError = true)] + private static extern int ReadProcessMemory(UIntPtr hProcess, IntPtr lpBase, ref int lpBuffer, int nSize, int lpNumberOfBytesRead); + + [DllImport("kernel32.dll", SetLastError = true)] + private static extern bool WriteProcessMemory(UIntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten); + + [DllImport("kernel32.dll")] + private static extern int CloseHandle(UIntPtr hProcess); + + [Flags] + public enum ProcessAccessFlags : uint + { + All = 0x001F0FFF, + Terminate = 0x00000001, + CreateThread = 0x00000002, + VMOperation = 0x00000008, + VMRead = 0x00000010, + VMWrite = 0x00000020, + DupHandle = 0x00000040, + SetInformation = 0x00000200, + QueryInformation = 0x00000400, + Synchronize = 0x00100000 + } + + public Process Process { get; set; } + public UIntPtr Handle { get; set; } + public IntPtr BaseAddress { get; set; } + public Version VersionInfo { get; set; } + public bool ProcHasExited { get; set; } = false; + + private void HasExited(object sender, EventArgs e) + { + ProcHasExited = true; + } + + public bool OpenReadOnly() + { + Process[] localProcess = Process.GetProcessesByName("dmc3se"); + + if (localProcess.Length == 0) + { + return false; + } + + Process = localProcess[0]; + Handle = OpenProcess(ProcessAccessFlags.VMRead, false, Process.Id); + + if (Handle == UIntPtr.Zero) + { + return false; + } + + BaseAddress = Process.MainModule.BaseAddress; + try + { + VersionInfo = new Version(Process.MainModule.FileVersionInfo.ProductVersion.Replace(",", ".")); + } + catch + { + return false; + } + + Process.EnableRaisingEvents = true; + Process.Exited += new EventHandler(HasExited); + + return true; + } + + public bool OpenReadWrite() + { + Process[] localProcess = Process.GetProcessesByName("dmc3se"); + + if (localProcess.Length == 0) + { + return false; + } + + Process = localProcess[0]; + Handle = OpenProcess(ProcessAccessFlags.All, false, Process.Id); + + if (Handle == UIntPtr.Zero) + { + return false; + } + + BaseAddress = Process.MainModule.BaseAddress; + try + { + VersionInfo = new Version(Process.MainModule.FileVersionInfo.ProductVersion.Replace(",", ".")); + } + catch + { + return false; + } + + Process.EnableRaisingEvents = true; + Process.Exited += new EventHandler(HasExited); + + return true; + } + + public void WriteMem(byte[] bytes, int address) + { + IntPtr offset = IntPtr.Add(BaseAddress, address); + WriteProcessMemory(Handle, offset, bytes, (uint)bytes.LongLength, out _); + } + + public void WriteInt(int intVal, int address) + { + byte[] bytes = new byte[4]; + + bytes[3] = (byte)(intVal >> 24); + bytes[2] = (byte)(intVal >> 16); + bytes[1] = (byte)(intVal >> 8); + bytes[0] = (byte)intVal; + + WriteProcessMemory(Handle, new IntPtr(address), bytes, (uint)bytes.LongLength, out _); + } + + public void WriteExactMem(byte[] bytes, int address) + { + WriteProcessMemory(Handle, new IntPtr(address), bytes, (uint)bytes.LongLength, out int bytesWritten); + Console.WriteLine(bytesWritten); + } + + public int ReadExactMem(int address) + { + int res = -1; + ReadProcessMemory(Handle, new IntPtr(address), ref res, sizeof(int), 0); + return res; + } + + public int ReadMem(int address) + { + IntPtr offset = IntPtr.Add(BaseAddress, address); + int res = -1; + ReadProcessMemory(Handle, offset, ref res, sizeof(int), 0); + return res; + } + + public int GetIntPtr(IntPtr address) + { + int res = 0; + ReadProcessMemory(Handle, address, ref res, sizeof(int), 0); + return res; + } + + private bool _disposedValue; + + private readonly SafeHandle _safeHandle = new SafeFileHandle(IntPtr.Zero, true); + + public void Dispose() => Dispose(true); + + protected virtual void Dispose(bool disposing) + { + if (!_disposedValue) + { + if (disposing) + { + CloseHandle(Handle); + _safeHandle.Dispose(); + } + + _disposedValue = true; + } + } + } +} diff --git a/Form1.Designer.cs b/Form1.Designer.cs index c79f26a..d3fcad8 100644 --- a/Form1.Designer.cs +++ b/Form1.Designer.cs @@ -53,14 +53,13 @@ private void InitializeComponent() this.button2 = new System.Windows.Forms.Button(); this.listBox1 = new System.Windows.Forms.ListBox(); this.tabPage2 = new System.Windows.Forms.TabPage(); + this.button7 = new System.Windows.Forms.Button(); this.button6 = new System.Windows.Forms.Button(); this.button5 = new System.Windows.Forms.Button(); - this.label9 = new System.Windows.Forms.Label(); this.checkBox2 = new System.Windows.Forms.CheckBox(); this.button4 = new System.Windows.Forms.Button(); this.button9 = new System.Windows.Forms.Button(); this.label8 = new System.Windows.Forms.Label(); - this.label7 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); this.comboBox1 = new System.Windows.Forms.ComboBox(); this.button1 = new System.Windows.Forms.Button(); @@ -271,14 +270,13 @@ private void InitializeComponent() // // tabPage2 // + this.tabPage2.Controls.Add(this.button7); this.tabPage2.Controls.Add(this.button6); this.tabPage2.Controls.Add(this.button5); - this.tabPage2.Controls.Add(this.label9); this.tabPage2.Controls.Add(this.checkBox2); this.tabPage2.Controls.Add(this.button4); this.tabPage2.Controls.Add(this.button9); this.tabPage2.Controls.Add(this.label8); - this.tabPage2.Controls.Add(this.label7); this.tabPage2.Controls.Add(this.label6); this.tabPage2.Controls.Add(this.comboBox1); this.tabPage2.Controls.Add(this.button1); @@ -291,6 +289,16 @@ private void InitializeComponent() this.tabPage2.Text = "Options"; this.tabPage2.UseVisualStyleBackColor = true; // + // button7 + // + this.button7.Location = new System.Drawing.Point(6, 215); + this.button7.Name = "button7"; + this.button7.Size = new System.Drawing.Size(93, 23); + this.button7.TabIndex = 29; + this.button7.Text = "Open Folder"; + this.button7.UseVisualStyleBackColor = true; + this.button7.Click += new System.EventHandler(this.button7_Click); + // // button6 // this.button6.Location = new System.Drawing.Point(129, 185); @@ -311,14 +319,6 @@ private void InitializeComponent() this.button5.UseVisualStyleBackColor = true; this.button5.Click += new System.EventHandler(this.button5_Click); // - // label9 - // - this.label9.AutoSize = true; - this.label9.Location = new System.Drawing.Point(3, 151); - this.label9.Name = "label9"; - this.label9.Size = new System.Drawing.Size(0, 13); - this.label9.TabIndex = 26; - // // checkBox2 // this.checkBox2.AutoSize = true; @@ -359,14 +359,6 @@ private void InitializeComponent() this.label8.TabIndex = 5; this.label8.Text = "DMC3 Path"; // - // label7 - // - this.label7.AutoSize = true; - this.label7.Location = new System.Drawing.Point(8, 84); - this.label7.Name = "label7"; - this.label7.Size = new System.Drawing.Size(0, 13); - this.label7.TabIndex = 4; - // // label6 // this.label6.AutoSize = true; @@ -523,7 +515,6 @@ private void InitializeComponent() private System.Windows.Forms.TabPage tabPage2; private System.Windows.Forms.Button button9; private System.Windows.Forms.Label label8; - private System.Windows.Forms.Label label7; private System.Windows.Forms.Label label6; private System.Windows.Forms.ComboBox comboBox1; private System.Windows.Forms.Button button1; @@ -544,9 +535,9 @@ private void InitializeComponent() private System.Windows.Forms.TabControl tabControl1; private System.Windows.Forms.CheckBox checkBox2; private System.Windows.Forms.Button button4; - private System.Windows.Forms.Label label9; private System.Windows.Forms.Button button6; private System.Windows.Forms.Button button5; + private System.Windows.Forms.Button button7; } } diff --git a/Form1.cs b/Form1.cs index 20d4787..1735694 100644 --- a/Form1.cs +++ b/Form1.cs @@ -4,7 +4,6 @@ using System.Drawing; using System.IO; using System.Linq; -using System.Runtime.InteropServices; using System.Text.RegularExpressions; using System.Windows.Forms; using System.Xml; @@ -13,16 +12,10 @@ namespace dmc3music { public partial class Form1 : Form { - private const int PROCESS_WM_READ = 0x0010; - - [DllImport("kernel32.dll")] - public static extern IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); - - [DllImport("kernel32", SetLastError = true)] - public static extern int ReadProcessMemory(IntPtr hProcess, int lpBase, ref int lpBuffer, int nSize, int lpNumberOfBytesRead); - private DMC3MusicConfig Config { get; set; } + private DMC3Process DMC3 { get; set; } + private Timer SongChangeTimer { get; set; } private Timer SongProgressTimer { get; set; } @@ -31,55 +24,16 @@ public partial class Form1 : Form private SongPlayer Player { get; set; } - private Process DMC3Process { get; set; } - private IntPtr ProcessHandle { get; set; } - private int BaseAddress { get; set; } - private bool ConfigChanged { get; set; } private bool newTrack { get; set; } = true; private string outMaxPos { get; set; } - private void getGamePath() - { - string steamPath = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", null); - string libraryPath = Path.Combine(steamPath, "steamapps/libraryfolders.vdf"); - string[] steamLibraries = File.ReadAllLines(libraryPath); - string gamePath = ""; - string tmpGamePath = ""; - - foreach (string line in steamLibraries) - { - Match matchPath = Regex.Match(line, @"""(?\w:\\\\.*)"""); - if (matchPath.Success) - { - tmpGamePath = matchPath.Groups["path"].Value.Replace(@"\\", @"\"); - } - Match matchGame = Regex.Match(line, @"""(?<6550>\w:\\\\.*)"""); - if (matchGame.Success) - { - gamePath = tmpGamePath; - } - } - - - gamePath = Path.GetFullPath(Path.Combine(gamePath, "steamapps/common/Devil May Cry 3")); - if (Directory.Exists(gamePath)) - { - Config.DMC3Path = gamePath; - DMC3MusicConfigWriter.WriteConfig(Config); - MessageBox.Show($"Automatically set the game path to '{gamePath}'. To change this, set the path in the options tab.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - } - public Form1() { - try - { - InitializeComponent(); - } - catch { } + + InitializeComponent(); try { Config = DMC3MusicConfigWriter.ReadConfig(); @@ -87,6 +41,7 @@ public Form1() catch { MessageBox.Show("Error", "There was a problem opening the config", MessageBoxButtons.OK, MessageBoxIcon.Error); + Application.Exit(); } try @@ -105,7 +60,10 @@ public Form1() SongChangeTimer = new Timer(); SongProgressTimer = new Timer(); } - catch { } + catch + { + Application.Exit(); + } try { @@ -120,43 +78,17 @@ public Form1() } catch { - System.Windows.Forms.Application.Exit(); + Application.Exit(); } try { if (!Directory.Exists("tracks")) { - MessageBox.Show("You will need to download the tracks from the Options tab", "Information", MessageBoxButtons.OK, MessageBoxIcon.None); + NotifyUser(5000, "Missing Tracks", "You will need to download the tracks from the otions tab to play music"); } } catch { } - - /* try - { - var MusicPath1 = Path.Combine(Config.DMC3Path, "native/sound"); - var MusicPath2 = Path.Combine(Config.DMC3Path, "sound"); - if (((string)Config.DMC3Path == string.Empty || Config.DMC3Path == null || !Directory.Exists(Config.DMC3Path)) && !Directory.Exists("tracks/")) - { - MessageBox.Show("You will need to set the DMC3 Path in the Options tab, or download the tracks folder from the github and add it to the root directory of this tool in order to play music", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); - } - else if (Directory.Exists(MusicPath1)) - { - Config.MusicPath = MusicPath1; - Config.ExtensionType = ".ogg"; - } - else if (Directory.Exists(MusicPath2)) - { - Config.MusicPath = MusicPath2; - Config.ExtensionType = ".bin"; - } - else - { - Config.MusicPath = "tracks"; - Config.ExtensionType = ".ogg"; - } - } - catch { }*/ } #region Form Control Methods @@ -173,7 +105,7 @@ private void Form1_Load(object sender, EventArgs e) } catch { - MessageBox.Show("Error", "There was a problem opening the config", MessageBoxButtons.OK, MessageBoxIcon.Error); + NotifyUser(5000, "Error", "There was a problem opening the config"); } try @@ -250,21 +182,19 @@ private void pictureBox2_Click(object sender, EventArgs e) } catch { - MessageBox.Show("Error", "There was a problem loading the Song Player", MessageBoxButtons.OK, MessageBoxIcon.Error); - } - try - { - DMC3Process = Process.GetProcessesByName("dmc3se")[0]; + NotifyUser(5000, "Error", "There was a problem loading the Song Player"); } - catch + + DMC3 = new DMC3Process(); + if (!DMC3.OpenReadOnly()) { - MessageBox.Show("pls start game first", "dmc3se.exe not found", MessageBoxButtons.OK, MessageBoxIcon.Error); + DMC3.Dispose(); + NotifyUser(5000, "pls start game first", "dmc3se.exe not found"); return; } + try { - ProcessHandle = OpenProcess(PROCESS_WM_READ, false, DMC3Process.Id); - BaseAddress = DMC3Process.MainModule.BaseAddress.ToInt32(); SongChangeTimer = new Timer { Interval = 50 @@ -289,11 +219,12 @@ private void pictureBox1_Click(object sender, EventArgs e) SongChangeTimer.Stop(); SongProgressTimer.Stop(); Player.Stop(); + DMC3.Dispose(); EnableConfigControls(); } catch { - MessageBox.Show("Error", "There was a problem stopping the Song Player", MessageBoxButtons.OK, MessageBoxIcon.Error); + NotifyUser(5000, "Error", "There was a problem stopping the Song Player"); } } @@ -308,181 +239,83 @@ private void button9_Click(object sender, EventArgs e) catch { } } - #endregion - - #region Functionality Methods - - private void GameStart(object sender, EventArgs e) + private void button4_Click(object sender, EventArgs e) { try { - DMC3Process = Process.GetProcessesByName("dmc3se")[0]; - } - catch - { - return; - } - Player = new SongPlayer(Config); - try - { - GameStartTimer.Stop(); - DisableConfigControls(); - ProcessHandle = OpenProcess(PROCESS_WM_READ, false, DMC3Process.Id); - BaseAddress = DMC3Process.MainModule.BaseAddress.ToInt32(); - SongChangeTimer = new Timer - { - Interval = 50 - }; - SongChangeTimer.Tick += new EventHandler(CheckSong); - SongChangeTimer.Start(); - - SongProgressTimer = new Timer - { - Interval = 100 - }; - SongProgressTimer.Tick += new EventHandler(GetSongProgress); - SongProgressTimer.Start(); - } - catch - { - MessageBox.Show("Error", "There was a problem opening the DMC3 Process", MessageBoxButtons.OK, MessageBoxIcon.Error); + StyleSwitcher StyleForm = new StyleSwitcher(); + DialogResult result = StyleForm.ShowDialog(); + ConfigChanged = StyleForm.ConfigChanged; + StyleForm.Dispose(); } + catch { } } - private void GetSongProgress(object sender, EventArgs e) + private void checkBox2_CheckedChanged(object sender, EventArgs e) { - if (Player.isPlaying) + try { - label2.Text = $"Playing: {Player.OldTrack}"; - TimeSpan currentPos = TimeSpan.FromMilliseconds(Player.TrackPos); - - if (newTrack) + if (Config.DMC3Path == string.Empty || Config.DMC3Path == null || !Directory.Exists(Config.DMC3Path)) { - newTrack = false; - TimeSpan maxPos = TimeSpan.FromSeconds(Player.TrackLength); - outMaxPos = maxPos.ToString(@"m\:ss\.ff"); + NotifyUser(5000, "Error", "Please make sure the path to DMC3 is correct in the Options tab"); + return; } - - string outCurrentPos; - - if (currentPos.Minutes > 0) + if (checkBox2.Checked) { - outCurrentPos = currentPos.ToString(@"m\:ss\.ff"); + foreach (string filename in Directory.EnumerateFiles("./inputsthing")) + { + string modName = filename.Split('\\').Last(); + string dest = Path.Combine(Config.DMC3Path, modName); + File.Copy(filename, dest, true); + NotifyUser(5000, "DMC3 Inputs Thing", "Successfully Installed!"); + } } else { - outCurrentPos = currentPos.ToString(@"ss\.ff"); + string dinputSrc = "./styleswitcher/dinput8.dll"; + string dest = Path.Combine(Config.DMC3Path, "dinput8.dll"); + File.Copy(dinputSrc, dest, true); + NotifyUser(5000, "DMC3 Inputs Thing", "Successfully Uninstalled!"); } - - label2.Text = $"Playing : {Player.OldTrack} ({outCurrentPos}/{outMaxPos})"; } - else + catch { - label2.Text = "Not Playing"; + NotifyUser(5000, "DMC3 Inputs Thing", "Failed To Install!"); } } - private void CheckSong(object sender, EventArgs e) + private void button5_Click(object sender, EventArgs e) { try { - if (Process.GetProcessesByName("dmc3se").Length == 0) - { - Player.Stop(); - SongChangeTimer.Stop(); - SongProgressTimer.Stop(); - GameStartTimer.Start(); - return; - } - } - catch { } - - try - { - int checkRoom = 0; - ReadProcessMemory(ProcessHandle, BaseAddress + 0x20C39EC, ref checkRoom, sizeof(int), 0); - - if (checkRoom == 0) - { - if (Player.isPlaying) - { - Player.FadeOut(); - } - return; - } - - int roomId = -1; - int enemyCount = -1; - int enemyCountPtr1 = -1; - int enemyCountPtr2 = -1; - int missionNumber = -1; - int isLoading = -1; - int vanguardSpawned = -1; - - ReadProcessMemory(ProcessHandle, BaseAddress + 0x76B150, ref roomId, sizeof(int), 0); - ReadProcessMemory(ProcessHandle, BaseAddress + 0x76B860 + 0xC40 + 0x8, ref enemyCountPtr1, sizeof(int), 0); - ReadProcessMemory(ProcessHandle, enemyCountPtr1 + 0x18, ref enemyCountPtr2, sizeof(int), 0); - ReadProcessMemory(ProcessHandle, enemyCountPtr2 + 0xA78, ref enemyCount, sizeof(int), 0); - ReadProcessMemory(ProcessHandle, BaseAddress + 0x76B148, ref missionNumber, sizeof(int), 0); - ReadProcessMemory(ProcessHandle, BaseAddress + 0x205BCB8, ref isLoading, sizeof(int), 0); - - if (missionNumber == 2) - { - ReadProcessMemory(ProcessHandle, BaseAddress + 0x5585AC, ref vanguardSpawned, sizeof(int), 0); - if (vanguardSpawned == 770) - { - roomId = 66; - } - } - - Player.PlayRoomSong(roomId, enemyCount, missionNumber); - newTrack = true; + CheckUpdates UpdateForm = new CheckUpdates(); + DialogResult result = UpdateForm.ShowDialog(); + UpdateForm.Dispose(); } catch { } } - private bool SaveConfigPrompt() + private void button6_Click(object sender, EventArgs e) { try { - DialogResult result = MessageBox.Show("Would you like to save your current configuration settings?", - "Save Configuration", - MessageBoxButtons.YesNoCancel, - MessageBoxIcon.Exclamation); - - if (result == DialogResult.Yes) - { - DMC3MusicConfigWriter.WriteConfig(Config); - ConfigChanged = false; - } - return result != DialogResult.Cancel; - } - catch - { - return false; + GetMusic MusicForm = new GetMusic(); + DialogResult result = MusicForm.ShowDialog(); + MusicForm.Dispose(); } + catch { } } - private void DisableConfigControls() + private void button7_Click(object sender, EventArgs e) { - try + if (Directory.Exists(Config.DMC3Path)) { - shuffleCheckBox.Enabled = false; - changeShuffle.Enabled = false; - pictureBox2.Enabled = false; + Process.Start("explorer.exe", Config.DMC3Path); } - catch { } - } - - private void EnableConfigControls() - { - try + else { - shuffleCheckBox.Enabled = true; - changeShuffle.Enabled = true; - pictureBox2.Enabled = true; + NotifyUser(5000, "Error", "Couldn't find the path to DMC3. Make sure it's set above."); } - catch { } } private void numericUpDown1_ValueChanged(object sender, EventArgs e) @@ -536,12 +369,11 @@ private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) string destination = Path.Combine(Config.DMC3Path, "save0.sav"); File.Copy(source, destination, true); - label7.Text = $"Copied '{fileName}' Successfully!"; - label7.MaximumSize = new Size((sender as Control).ClientSize.Width - label7.Left, 10000); + NotifyUser(5000, "Save Loader", $"Copied '{fileName}' Successfully!"); } catch { - label7.Text = "Failed To Copy!"; + NotifyUser(5000, "Save Loader", "Failed To Copy!"); } } @@ -728,70 +560,264 @@ private void button3_Click(object sender, EventArgs e) #endregion - private void button4_Click(object sender, EventArgs e) + #region Functionality Methods + + private void getGamePath() { + string steamPath = (string)Registry.GetValue(@"HKEY_LOCAL_MACHINE\SOFTWARE\Valve\Steam", "InstallPath", null); + string libraryPath = Path.Combine(steamPath, "steamapps/libraryfolders.vdf"); + string[] steamLibraries = File.ReadAllLines(libraryPath); + string gamePath = ""; + string tmpGamePath = ""; + + foreach (string line in steamLibraries) + { + Match matchPath = Regex.Match(line, @"""(?\w:\\\\.*)"""); + if (matchPath.Success) + { + tmpGamePath = matchPath.Groups["path"].Value.Replace(@"\\", @"\"); + } + Match matchGame = Regex.Match(line, @"""(?<6550>\w:\\\\.*)"""); + if (matchGame.Success) + { + gamePath = tmpGamePath; + } + } + + + gamePath = Path.GetFullPath(Path.Combine(gamePath, "steamapps/common/Devil May Cry 3")); + if (Directory.Exists(gamePath)) + { + Config.DMC3Path = gamePath; + DMC3MusicConfigWriter.WriteConfig(Config); + MessageBox.Show($"Automatically set the game path to '{gamePath}'. To change this, set the path in the options tab.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); + } + } + + private void GameStart(object sender, EventArgs e) + { + using (DMC3Process DMC3RW = new DMC3Process()) + { + if (ConfigChanged) + { + ConfigChanged = false; + Config = DMC3MusicConfigWriter.ReadConfig(); + } + + if (!DMC3RW.OpenReadWrite()) + { + return; + } + + if (Config.CutsceneMovement) + { + IntPtr cutsceneMovementPtrSS = IntPtr.Add(DMC3RW.BaseAddress, 0x1DFF20); + int cutsceneMovementPtrSS2 = DMC3RW.GetIntPtr(cutsceneMovementPtrSS); + + if (DMC3RW.ReadExactMem(cutsceneMovementPtrSS2 + 0x26) != 2) + { + return; + } + + DMC3RW.WriteExactMem(new byte[] { 0x00 }, cutsceneMovementPtrSS2 + 0x26); + DMC3RW.WriteMem(new byte[] { 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00 }, 0x2C1A6F); + } + } + + DMC3 = new DMC3Process(); + + if (!DMC3.OpenReadOnly()) + { + DMC3.Dispose(); + return; + } + + Player = new SongPlayer(Config); + try { - StyleSwitcher StyleForm = new StyleSwitcher(); - DialogResult result = StyleForm.ShowDialog(); - StyleForm.Dispose(); + GameStartTimer.Stop(); + DisableConfigControls(); + + SongChangeTimer = new Timer + { + Interval = 50 + }; + SongChangeTimer.Tick += new EventHandler(CheckSong); + SongChangeTimer.Start(); + + SongProgressTimer = new Timer + { + Interval = 100 + }; + SongProgressTimer.Tick += new EventHandler(GetSongProgress); + SongProgressTimer.Start(); + } + catch + { + DMC3.Dispose(); + NotifyUser(5000, "Error", "There was a problem opening the DMC3 Process"); } - catch { } } - private void checkBox2_CheckedChanged(object sender, EventArgs e) + private void GetSongProgress(object sender, EventArgs e) + { + if (Player.isPlaying) + { + label2.Text = $"Playing: {Player.OldTrack}"; + TimeSpan currentPos = TimeSpan.FromMilliseconds(Player.TrackPos); + + if (newTrack) + { + newTrack = false; + TimeSpan maxPos = TimeSpan.FromSeconds(Player.TrackLength); + outMaxPos = maxPos.ToString(@"m\:ss\.ff"); + } + + string outCurrentPos; + + if (currentPos.Minutes > 0) + { + outCurrentPos = currentPos.ToString(@"m\:ss\.ff"); + } + else + { + outCurrentPos = currentPos.ToString(@"ss\.ff"); + } + + label2.Text = $"Playing : {Player.OldTrack} ({outCurrentPos}/{outMaxPos})"; + } + else + { + label2.Text = "Not Playing"; + } + } + + private void CheckSong(object sender, EventArgs e) { + if (DMC3.ProcHasExited) + { + DMC3.Dispose(); + Player.Stop(); + SongChangeTimer.Stop(); + SongProgressTimer.Stop(); + GameStartTimer.Start(); + return; + } + try { - if (Config.DMC3Path == string.Empty || Config.DMC3Path == null || !Directory.Exists(Config.DMC3Path)) + int checkRoom = 0; + checkRoom = DMC3.ReadMem(0x20C39EC); + + if (checkRoom <= 0) { - MessageBox.Show("Please make sure the path to DMC3 is correct in the Options tab", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); + if (Player.isPlaying) + { + Player.FadeOut(); + } return; } - if (checkBox2.Checked) + + int roomId = -1; + int enemyCount = -1; + int missionNumber = -1; + int isLoading = -1; + int vanguardSpawned = -1; + + roomId = DMC3.ReadMem(0x76B150); + + IntPtr tmpPtr = IntPtr.Add(DMC3.BaseAddress, 0x76B860 + 0xC40 + 0x8); + int enemyCountPtr1 = DMC3.GetIntPtr(tmpPtr); + tmpPtr = IntPtr.Add(new IntPtr(enemyCountPtr1), 0x18); + int enemyCountPtr2 = DMC3.GetIntPtr(tmpPtr); + tmpPtr = IntPtr.Add(new IntPtr(enemyCountPtr2), 0xA78); + enemyCount = DMC3.GetIntPtr(tmpPtr); + + missionNumber = DMC3.ReadMem(0x76B148); + isLoading = DMC3.ReadMem(0x205BCB8); + + if (missionNumber == 2) { - foreach (string filename in Directory.EnumerateFiles("./inputsthing")) + vanguardSpawned = DMC3.ReadMem(0x5585AC); + if (vanguardSpawned == 770) { - string modName = filename.Split('\\').Last(); - string dest = Path.Combine(Config.DMC3Path, modName); - File.Copy(filename, dest, true); - label9.Text = "Successfully Installed!"; + roomId = 66; } } - else + + if (roomId != -1) { - string dinputSrc = "./styleswitcher/dinput8.dll"; - string dest = Path.Combine(Config.DMC3Path, "dinput8.dll"); - File.Copy(dinputSrc, dest, true); - label9.Text = "Successfully Uninstalled!"; + Player.PlayRoomSong(roomId, enemyCount, missionNumber); + newTrack = true; } } catch { - label9.Text = "Failed To Install!"; + DMC3.Dispose(); + Player.Stop(); + SongChangeTimer.Stop(); + SongProgressTimer.Stop(); + GameStartTimer.Start(); + return; } } - private void button5_Click(object sender, EventArgs e) + private bool SaveConfigPrompt() { try { - CheckUpdates UpdateForm = new CheckUpdates(); - DialogResult result = UpdateForm.ShowDialog(); - UpdateForm.Dispose(); + DialogResult result = MessageBox.Show("Would you like to save your current configuration settings?", "Save Configuration", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Exclamation); + + if (result == DialogResult.Yes) + { + DMC3MusicConfigWriter.WriteConfig(Config); + ConfigChanged = false; + } + + return result != DialogResult.Cancel; + } + catch + { + return false; + } + } + + private void DisableConfigControls() + { + try + { + shuffleCheckBox.Enabled = false; + changeShuffle.Enabled = false; + pictureBox2.Enabled = false; } catch { } } - private void button6_Click(object sender, EventArgs e) + private void EnableConfigControls() { try { - GetMusic MusicForm = new GetMusic(); - DialogResult result = MusicForm.ShowDialog(); - MusicForm.Dispose(); + shuffleCheckBox.Enabled = true; + changeShuffle.Enabled = true; + pictureBox2.Enabled = true; } catch { } } + + private void NotifyUser(int timeout, string tipTitle, string tipText) + { + NotifyIcon notifyIcon1 = new NotifyIcon(this.components); + notifyIcon1.Icon = this.Icon; + notifyIcon1.Visible = true; + notifyIcon1.ShowBalloonTip(timeout, tipTitle, tipText, ToolTipIcon.None); + notifyIcon1.BalloonTipClosed += (sender, e) => { + var thisIcon = (NotifyIcon)sender; + thisIcon.Visible = false; + thisIcon.Dispose(); + }; + } + + #endregion } } diff --git a/GetMusic.cs b/GetMusic.cs index e1e414c..6fd95f5 100644 --- a/GetMusic.cs +++ b/GetMusic.cs @@ -76,7 +76,7 @@ private void WcOnDownloadProgressChanged(object sender, DownloadProgressChangedE string readRecv = ReadableSize(e.BytesReceived); string maxRecv = ReadableSize(e.TotalBytesToReceive); - label1.Text = $"Downloaded {readRecv} of {maxRecv} ({e.ProgressPercentage}%)"; + label1.Text = $"Downloading {readRecv} of {maxRecv} ({e.ProgressPercentage}%)"; RecenterLabel1(); progressBar1.Value = e.ProgressPercentage; } diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index 3397e81..666b863 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -32,6 +32,6 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("2.2.0.0")] -[assembly: AssemblyFileVersion("2.2.0.0")] +[assembly: AssemblyVersion("2.3.0.0")] +[assembly: AssemblyFileVersion("2.3.0.0")] [assembly: NeutralResourcesLanguage("en")] diff --git a/StyleSwitcher.Designer.cs b/StyleSwitcher.Designer.cs index 8bd7897..b4b952d 100644 --- a/StyleSwitcher.Designer.cs +++ b/StyleSwitcher.Designer.cs @@ -47,6 +47,9 @@ private void InitializeComponent() this.comboBox4 = new System.Windows.Forms.ComboBox(); this.label5 = new System.Windows.Forms.Label(); this.label6 = new System.Windows.Forms.Label(); + this.volumeSlider1 = new NAudio.Gui.VolumeSlider(); + this.label2 = new System.Windows.Forms.Label(); + this.checkBox9 = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // // checkBox1 @@ -115,7 +118,7 @@ private void InitializeComponent() // checkBox4 // this.checkBox4.AutoSize = true; - this.checkBox4.Location = new System.Drawing.Point(12, 302); + this.checkBox4.Location = new System.Drawing.Point(15, 331); this.checkBox4.Name = "checkBox4"; this.checkBox4.Size = new System.Drawing.Size(60, 17); this.checkBox4.TabIndex = 5; @@ -199,7 +202,7 @@ private void InitializeComponent() // // textBox1 // - this.textBox1.Location = new System.Drawing.Point(12, 348); + this.textBox1.Location = new System.Drawing.Point(15, 378); this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(92, 20); this.textBox1.TabIndex = 16; @@ -208,7 +211,7 @@ private void InitializeComponent() // label3 // this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(12, 332); + this.label3.Location = new System.Drawing.Point(15, 362); this.label3.Name = "label3"; this.label3.Size = new System.Drawing.Size(72, 13); this.label3.TabIndex = 17; @@ -239,7 +242,7 @@ private void InitializeComponent() "18", "19", "20"}); - this.comboBox3.Location = new System.Drawing.Point(136, 347); + this.comboBox3.Location = new System.Drawing.Point(136, 377); this.comboBox3.Name = "comboBox3"; this.comboBox3.Size = new System.Drawing.Size(92, 21); this.comboBox3.TabIndex = 18; @@ -248,7 +251,7 @@ private void InitializeComponent() // label4 // this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(133, 331); + this.label4.Location = new System.Drawing.Point(133, 361); this.label4.Name = "label4"; this.label4.Size = new System.Drawing.Size(79, 13); this.label4.TabIndex = 19; @@ -289,11 +292,41 @@ private void InitializeComponent() this.label6.TabIndex = 24; this.label6.Visible = false; // + // volumeSlider1 + // + this.volumeSlider1.Location = new System.Drawing.Point(11, 287); + this.volumeSlider1.Name = "volumeSlider1"; + this.volumeSlider1.Size = new System.Drawing.Size(96, 16); + this.volumeSlider1.TabIndex = 25; + // + // label2 + // + this.label2.AutoSize = true; + this.label2.Location = new System.Drawing.Point(11, 271); + this.label2.Name = "label2"; + this.label2.Size = new System.Drawing.Size(73, 13); + this.label2.TabIndex = 26; + this.label2.Text = "Game Volume"; + // + // checkBox9 + // + this.checkBox9.AutoSize = true; + this.checkBox9.Location = new System.Drawing.Point(136, 67); + this.checkBox9.Name = "checkBox9"; + this.checkBox9.Size = new System.Drawing.Size(160, 17); + this.checkBox9.TabIndex = 27; + this.checkBox9.Text = "Enable Cutscene Movement"; + this.checkBox9.UseVisualStyleBackColor = true; + this.checkBox9.CheckedChanged += new System.EventHandler(this.checkBox9_CheckedChanged); + // // StyleSwitcher // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size(398, 450); + this.Controls.Add(this.checkBox9); + this.Controls.Add(this.label2); + this.Controls.Add(this.volumeSlider1); this.Controls.Add(this.label6); this.Controls.Add(this.label5); this.Controls.Add(this.comboBox4); @@ -340,5 +373,8 @@ private void InitializeComponent() private System.Windows.Forms.ComboBox comboBox4; private System.Windows.Forms.Label label5; private System.Windows.Forms.Label label6; + private NAudio.Gui.VolumeSlider volumeSlider1; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.CheckBox checkBox9; } } \ No newline at end of file diff --git a/StyleSwitcher.cs b/StyleSwitcher.cs index 20209f3..1ce6c25 100644 --- a/StyleSwitcher.cs +++ b/StyleSwitcher.cs @@ -10,6 +10,7 @@ namespace dmc3music public partial class StyleSwitcher : Form { private DMC3MusicConfig Config { get; set; } + public bool ConfigChanged { get; set; } = false; public string styleWindowed { get; set; } = "0"; public INIFile styleIni { get; set; } public Dictionary stylesDict { get; set; } = new Dictionary() @@ -22,7 +23,7 @@ public partial class StyleSwitcher : Form { "Doppelganger", "5" } }; - public string styleLoc, styleBGM, bossRush, hotKeys, blurShader, + public string styleLoc, styleBGM, styleSEVol, bossRush, hotKeys, blurShader, fogShader, shadowEngine, gammaCorrection, arcadeMode, arcadeRoom, arcadeMission, arcadeStyle, arcadeWeapons, styleResolution; @@ -56,12 +57,30 @@ public StyleSwitcher() private void getIniConfig() { + checkBox9.Checked = Config.CutsceneMovement; + styleWindowed = styleIni.GetValue("DISPLAY", "Mode"); checkBox1.Checked = (styleWindowed == "0") ? true : false; styleBGM = styleIni.GetValue("SOUND", "DisableSoundDriver"); checkBox2.Checked = (styleBGM == "1") ? true : false; + styleSEVol = styleIni.GetValue("SOUND", "Volume.SE"); + + float x = Convert.ToSingle(styleSEVol) / 100f; + float y; + if (x <= 0) + { + y = 0; + } + else + { + float dbVolume = (1 - x) * -48f; + y = (float)Math.Pow(10, dbVolume / 20); + } + + volumeSlider1.Volume = y; + bossRush = styleIni.GetValue("GAME", "BossRush"); checkBox3.Checked = (bossRush == "1") ? true : false; @@ -102,6 +121,8 @@ private void button2_Click(object sender, EventArgs e) { try { + DMC3MusicConfigWriter.WriteConfig(Config); + string styleDll = Path.Combine(Config.DMC3Path, "StyleSwitcher.dll"); if (!File.Exists(styleDll)) { @@ -119,6 +140,25 @@ private void button2_Click(object sender, EventArgs e) styleIni["DISPLAY"]["Mode"] = styleWindowed; styleIni["SOUND"]["DisableSoundDriver"] = styleBGM; + + float db = 20 * (float)Math.Log10(volumeSlider1.Volume); + int percent = (int)Math.Round((1 - (db / -48f)) * 100f); + + if (percent <= 0) + { + styleSEVol = "0"; + } + else if (percent >= 100) + { + styleSEVol = "100"; + } + else + { + styleSEVol = percent.ToString(); + } + + styleIni["SOUND"]["Volume.SE"] = styleSEVol; + styleIni["GAME"]["BossRush"] = bossRush; styleIni["GAME"]["Arcade"] = arcadeMode; styleIni["INPUT"]["Hotkeys"] = hotKeys; @@ -134,6 +174,7 @@ private void button2_Click(object sender, EventArgs e) File.WriteAllText(styleLoc, styleIni.ToString().Replace("BGM[]={", "BGM[] = {")); label6.Text = "Installed Successfully!"; label6.Visible = true; + ConfigChanged = true; } catch { @@ -142,6 +183,11 @@ private void button2_Click(object sender, EventArgs e) } } + private void checkBox9_CheckedChanged(object sender, EventArgs e) + { + Config.CutsceneMovement = checkBox9.Checked; + } + private void checkBox1_CheckedChanged(object sender, EventArgs e) { styleWindowed = (checkBox1.Checked) ? "0" : "1"; diff --git a/dmc3music.csproj b/dmc3music.csproj index 566dbd4..1be3a4d 100644 --- a/dmc3music.csproj +++ b/dmc3music.csproj @@ -37,6 +37,7 @@ DEBUG;TRACE prompt 4 + true AnyCPU @@ -46,16 +47,19 @@ TRACE prompt 4 + true x86 bin\x86\Debug\ TRACE;DEBUG + true x86 bin\x86\Release\ true + true dante.ico @@ -202,6 +206,7 @@ ControllerConfig.cs + Form @@ -339,6 +344,17 @@ - + + + False + Microsoft .NET Framework 4.7.2 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 + false + + \ No newline at end of file