/* * Copyright (C) 2009-2011 Ferreri Alessio * Copyright (C) 2009-2018 PCSX2 Dev Team * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Text; using System.Windows.Forms; using System.IO; using System.Runtime.InteropServices; using System.Threading; using System.Diagnostics; using System.Security; using TCPLibrary.MessageBased.Core; namespace GSDumpGUI { public partial class GSDumpGUI : Form { public List Processes; private Int32 _selected; public Int32 SelectedRad { get { return _selected; } set { if (value > 6) value = 0; _selected = value; switch (_selected) { case 0: rdaNone.Checked = true; break; case 1: rdaDX9HW.Checked = true; break; case 2: rdaDX1011HW.Checked = true; break; case 3: rdaOGLHW.Checked = true; break; case 4: rdaDX9SW.Checked = true; break; case 5: rdaDX1011SW.Checked = true; break; case 6: rdaOGLSW.Checked = true; break; } } } private Bitmap NoImage; public GSDumpGUI() { InitializeComponent(); Processes = new List(); NoImage = new Bitmap(320, 240, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Graphics g = Graphics.FromImage(NoImage); g.FillRectangle(new SolidBrush(Color.Black), new Rectangle(0, 0, 320, 240)); g.DrawString("No Image", new Font(FontFamily.GenericSansSerif, 48, FontStyle.Regular), new SolidBrush(Color.White), new PointF(0, 70)); g.Dispose(); } public void ReloadGSDXs() { txtIntLog.Text += "Starting GSdx Loading Procedures" + Environment.NewLine + Environment.NewLine; txtGSDXDirectory.Text = Properties.Settings.Default.GSDXDir; txtDumpsDirectory.Text = Properties.Settings.Default.DumpDir; lstGSDX.Items.Clear(); lstDumps.Items.Clear(); if (Directory.Exists(txtGSDXDirectory.Text)) { String[] File = Directory.GetFiles(txtGSDXDirectory.Text, "*.dll", SearchOption.TopDirectoryOnly); GSDXWrapper wrap = new GSDXWrapper(); foreach (var itm in File) { try { wrap.Load(itm); lstGSDX.Items.Add(Path.GetFileName(itm) + " | " + wrap.PSEGetLibName()); txtIntLog.Text += "\"" + itm + "\" correctly identified as " + wrap.PSEGetLibName() + Environment.NewLine; wrap.Unload(); } catch (InvalidGSPlugin) { txtIntLog.Text += "Failed to load \"" + itm + "\". Is it really a GSdx DLL?" + Environment.NewLine; } } } txtIntLog.Text += Environment.NewLine + "Completed GSdx Loading Procedures" + Environment.NewLine + Environment.NewLine; txtIntLog.Text += "Starting GSdx Dumps Loading Procedures : " + Environment.NewLine + Environment.NewLine; if (Directory.Exists(txtDumpsDirectory.Text)) { String[] Dumps = Directory.GetFiles(txtDumpsDirectory.Text, "*.gs", SearchOption.TopDirectoryOnly); foreach (var itm in Dumps) { BinaryReader br = new BinaryReader(System.IO.File.Open(itm, FileMode.Open)); Int32 CRC = br.ReadInt32(); br.Close(); lstDumps.Items.Add(Path.GetFileName(itm) + " | CRC : " + CRC.ToString("X")); txtIntLog.Text += "Identified Dump for game (" + CRC.ToString("X") + ") with filename \"" + itm + "\"" + Environment.NewLine; } } txtIntLog.Text += Environment.NewLine + "Completed GSdx Dumps Loading Procedures : " + Environment.NewLine + Environment.NewLine; txtIntLog.SelectionStart = txtIntLog.TextLength; txtIntLog.ScrollToCaret(); } private void GSDumpGUI_Load(object sender, EventArgs e) { ReloadGSDXs(); // Auto select GS dump lstDumps.Focus(); if (lstDumps.Items.Count > 0) lstDumps.SelectedIndex = 0; // Auto select GSdx dll if (lstGSDX.Items.Count > 0) lstGSDX.SelectedIndex = 0; } private void cmdBrowseGSDX_Click(object sender, EventArgs e) { FolderBrowserDialog fbd = new FolderBrowserDialog(); fbd.Description = "Select the GSdx DLL Directory"; fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory; if (fbd.ShowDialog() == DialogResult.OK) txtGSDXDirectory.Text = fbd.SelectedPath; SaveConfig(); ReloadGSDXs(); } private void cmdBrowseDumps_Click(object sender, EventArgs e) { FolderBrowserDialog fbd = new FolderBrowserDialog(); fbd.Description = "Select the GSdx Dumps Directory"; fbd.SelectedPath = AppDomain.CurrentDomain.BaseDirectory; if (fbd.ShowDialog() == DialogResult.OK) txtDumpsDirectory.Text = fbd.SelectedPath; SaveConfig(); ReloadGSDXs(); } private void cmdRun_Click(object sender, EventArgs e) { // Execute the GSReplay function if (lstDumps.SelectedIndex != -1) { if (lstGSDX.SelectedIndex != -1) ExecuteFunction("GSReplay"); else MessageBox.Show("Select your GSdx first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } else MessageBox.Show("Select your Dump first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void ExecuteFunction(String Function) { txtLog.Text = ""; String GSDXName = lstGSDX.SelectedItem.ToString().Split(new char[] { '|' })[0].TrimEnd(); CreateDirs(); // Set the Arguments to pass to the child String DLLPath = Properties.Settings.Default.GSDXDir + "\\" + GSDXName; String DumpPath = ""; String SelectedRenderer = ""; switch (SelectedRad) { case 0: SelectedRenderer = "-1"; break; case 1: SelectedRenderer = "0"; break; case 2: SelectedRenderer = "3"; break; case 3: SelectedRenderer = "12"; break; case 4: SelectedRenderer = "1"; break; case 5: SelectedRenderer = "4"; break; case 6: SelectedRenderer = "13"; break; } if (SelectedRenderer != "-1") { String GSdxIniPath = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\inis\\gsdx.ini"; NativeMethods.WritePrivateProfileString("Settings", "Renderer", SelectedRenderer, GSdxIniPath); } if (lstDumps.SelectedItem != null) DumpPath = Properties.Settings.Default.DumpDir + "\\" + lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0]; // Start the child and link the events. ProcessStartInfo psi = new ProcessStartInfo(); psi.UseShellExecute = false; psi.RedirectStandardOutput = true; psi.RedirectStandardError = false; psi.CreateNoWindow = true; psi.FileName = Process.GetCurrentProcess().ProcessName; psi.Arguments = "\"" + DLLPath + "\"" + " \"" + DumpPath + "\"" + " \"" + Function + "\"" + " " + SelectedRenderer; Process p = Process.Start(psi); p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived); p.BeginOutputReadLine(); p.Exited += new EventHandler(p_Exited); Processes.Add(p); } private static void CreateDirs() { // Create and set the config directory. String Dir = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\"; if (!Directory.Exists(Dir)) { Directory.CreateDirectory(Dir); } Dir += "\\Inis\\"; if (!Directory.Exists(Dir)) { Directory.CreateDirectory(Dir); File.Create(Dir + "\\gsdx.ini").Close(); } Dir = AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs"; Directory.SetCurrentDirectory(Dir); } void p_Exited(object sender, EventArgs e) { // Remove the child if is closed Processes.Remove((Process)sender); } void p_OutputDataReceived(object sender, DataReceivedEventArgs e) { // Write the log. txtLog.Invoke(new Action(delegate(object o) { txtLog.Text += e.Data + Environment.NewLine; txtLog.SelectionStart = txtLog.Text.Length - 1; txtLog.ScrollToCaret(); }), new object[] { null }); } private void cmdConfigGSDX_Click(object sender, EventArgs e) { // Execute the GSconfigure function if (lstGSDX.SelectedIndex != -1) ExecuteFunction("GSconfigure"); else MessageBox.Show("Select your GSdx first", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } private void cmdOpenIni_Click(object sender, EventArgs e) { // Execute the GSconfigure function CreateDirs(); Process.Start(AppDomain.CurrentDomain.BaseDirectory + "GSDumpGSDXConfigs\\inis\\gsdx.ini"); } private void lstDumps_SelectedIndexChanged(object sender, EventArgs e) { if (lstDumps.SelectedIndex != -1) { String [] Extensions = new String[] { ".png", ".bmp" }; String DumpFileName = lstDumps.SelectedItem.ToString().Split(new char[] { '|' })[0]; String Filename = Path.GetDirectoryName(Properties.Settings.Default.DumpDir + "\\") + "\\" + Path.GetFileNameWithoutExtension(DumpFileName); foreach (String Extension in Extensions) { if (File.Exists(Filename + Extension)) { pctBox.Load(Filename + Extension); pctBox.Cursor = Cursors.Hand; return; } } pctBox.Image = NoImage; pctBox.Cursor = Cursors.Default; } } private void pctBox_Click(object sender, EventArgs e) { if (pctBox.Cursor == Cursors.Hand) { Process.Start(pctBox.ImageLocation); } } private void GSDumpGUI_KeyDown(object sender, KeyEventArgs e) { if (e.KeyCode == Keys.Return) cmdRun_Click(sender, e); if (e.KeyCode == Keys.F1) cmdConfigGSDX_Click(sender, e); if ((e.KeyCode == Keys.F2)) SelectedRad++; } private void rda_CheckedChanged(object sender, EventArgs e) { RadioButton itm = ((RadioButton)(sender)); if (itm.Checked == true) SelectedRad = Convert.ToInt32(itm.Tag); } private void txtGSDXDirectory_Leave(object sender, EventArgs e) { SaveConfig(); ReloadGSDXs(); } private void txtDumpsDirectory_Leave(object sender, EventArgs e) { SaveConfig(); ReloadGSDXs(); } private void SaveConfig() { Properties.Settings.Default.GSDXDir = txtGSDXDirectory.Text; Properties.Settings.Default.DumpDir = txtDumpsDirectory.Text; Properties.Settings.Default.Save(); } private void lstProcesses_SelectedIndexChanged(object sender, EventArgs e) { if (lstProcesses.SelectedIndex != -1) { chkDebugMode.Enabled = true; TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.GetDebugMode; msg.Parameters.Add(chkDebugMode.Checked); Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); msg = new TCPMessage(); msg.MessageType = MessageType.SizeDump; Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); msg = new TCPMessage(); msg.MessageType = MessageType.Statistics; Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } else { chkDebugMode.Enabled = false; } } private void chkDebugMode_CheckedChanged(object sender, EventArgs e) { if (lstProcesses.SelectedIndex != -1) { TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.SetDebugMode; msg.Parameters.Add(chkDebugMode.Checked); Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } } private void btnStep_Click(object sender, EventArgs e) { TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.Step; Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } private void btnRunToSelection_Click(object sender, EventArgs e) { if (treTreeView.SelectedNode != null) { TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.RunToCursor; msg.Parameters.Add(Convert.ToInt32(treTreeView.SelectedNode.Text.Split(new string[]{" - "}, StringSplitOptions.None)[0])); Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } else MessageBox.Show("You have not selected a node to jump to"); } private void cmdGoToStart_Click(object sender, EventArgs e) { TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.RunToCursor; msg.Parameters.Add(0); Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } private void cmdGoToNextVSync_Click(object sender, EventArgs e) { TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.RunToNextVSync; Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } private void treTreeView_AfterSelect(object sender, TreeViewEventArgs e) { if (treTreeView.SelectedNode != null) { TCPMessage msg = new TCPMessage(); msg.MessageType = MessageType.PacketInfo; msg.Parameters.Add(Convert.ToInt32(treTreeView.SelectedNode.Text.Split(new string[] { " - " }, StringSplitOptions.None)[0])); Program.Clients.Find(a => a.IPAddress == lstProcesses.SelectedItem.ToString()).Send(msg); } treTreeView.SelectedNode = e.Node; } private void GSDumpGUI_FormClosing(object sender, FormClosingEventArgs e) { // Make sure all child processes are closed upon closing the main form Processes.ForEach(p => { try { p.Kill(); } catch { } p.Dispose(); }); } } }