using System; using System.Diagnostics; using System.Drawing; using System.IO; using System.IO.Compression; using System.Runtime.InteropServices; using System.Threading; using System.Windows.Forms; using System.Xml; namespace PSMUI { public partial class PSMUI : Form { int NumberOfGames = 0; Label noGamesMessage = new Label(); [DllImport("user32.dll", SetLastError = true)] internal static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint); [DllImport("user32.dll")] static extern int SetWindowText(IntPtr hWnd, string text); public struct Rect { public int Left { get; set; } public int Top { get; set; } public int Right { get; set; } public int Bottom { get; set; } } [DllImport("user32.dll")] public static extern bool GetWindowRect(IntPtr hwnd, ref Rect rectangle); [DllImport("user32.dll")] internal extern static int SetWindowLong(IntPtr hwnd, int index, int value); [DllImport("user32.dll")] internal extern static int GetWindowLong(IntPtr hwnd, int index); public PSMUI() { InitializeComponent(); screenResolution.SelectedIndex = 0; } private string GetPSMName(string id) { XmlDocument Docu = new XmlDocument(); Docu.Load(Path.Combine("APPMETA", id , id + ".xml")); XmlNode node = Docu.DocumentElement.SelectSingleNode("/application/name/localized_item[1]"); return node.Attributes["value"].InnerText; } private Point GetImagePosition() { Point location = new Point(160, 45); for (int i = 0; i < NumberOfGames; i++) { location.X += 128 + 35; if (location.X + 128 + 35 >= 1280) { location.Y += 128 + 45; location.X = 160; } } return location; } private Point GetTextPosition() { Point location = new Point(160, 170); for (int i = 0; i < NumberOfGames; i++) { location.X += 128 + 35; if (location.X + 128 + 35 >= 1280) { location.Y += 128 + 45; location.X = 160; } } return location; } private void AddPsmGame(string id) { noGamesMessage.Visible = false; PictureBox PSMGameHighlight = new PictureBox(); PictureBox PSMGameIcon = new PictureBox(); Label PSMGameName = new Label(); Point ImgPos = GetImagePosition(); PSMGameHighlight.Visible = true; PSMGameHighlight.Width = 160; PSMGameHighlight.Height = 180; PSMGameHighlight.BackColor = Color.Transparent; PSMGameHighlight.Location = new Point(ImgPos.X - 16, ImgPos.Y - 16); PSMGameHighlight.MouseEnter += PSMGameHighlight_MouseEnter; PSMGameHighlight.MouseLeave += PSMGameHighlight_MouseLeave; PSMGameHighlight.MouseClick += PSMGameHighlight_MouseClick; PSMGameHighlight.Tag = PSMGameName; PSMGameHighlight.Name = id; GameList.Controls.Add(PSMGameHighlight); PSMGameIcon.Visible = true; PSMGameIcon.Width = 128; PSMGameIcon.Height = 128; PSMGameIcon.BackgroundImage = Image.FromFile(Path.Combine("APPMETA", id, "files", "images", "icon_128x128.png")); PSMGameIcon.Location = ImgPos; PSMGameIcon.MouseEnter += PSMGameHighlight_MouseEnter; PSMGameIcon.MouseLeave += PSMGameHighlight_MouseLeave; PSMGameIcon.MouseClick += PSMGameHighlight_MouseClick; PSMGameIcon.Tag = PSMGameHighlight; PSMGameIcon.Name = id; GameList.Controls.Add(PSMGameIcon); PSMGameName.Visible = true; PSMGameName.Width = 128; PSMGameName.Height = 35; PSMGameName.TextAlign = ContentAlignment.MiddleCenter; PSMGameName.BackColor = Color.Transparent; PSMGameName.ForeColor = Color.White; PSMGameName.Text = GetPSMName(id); PSMGameName.Location = GetTextPosition(); PSMGameName.Tag = PSMGameHighlight; PSMGameName.MouseEnter += PSMGameHighlight_MouseEnter; PSMGameName.MouseLeave += PSMGameHighlight_MouseLeave; PSMGameName.MouseClick += PSMGameHighlight_MouseClick; PSMGameName.Name = id; GameList.Controls.Add(PSMGameName); NumberOfGames += 1; PSMGameHighlight.SendToBack(); Application.DoEvents(); } private void PSMGameHighlight_MouseClick(object PSMGameBackground, MouseEventArgs e) { String id = PSMGameBackground.GetType().GetProperty("Name").GetValue(PSMGameBackground, null).ToString(); Console.WriteLine("Starting: "+id); Process proc = new Process(); string PSM_SDK = Path.Combine(Directory.GetCurrentDirectory(), "SDK"); if (proc.StartInfo.EnvironmentVariables.ContainsKey("SCE_PSM_SDK")) proc.StartInfo.EnvironmentVariables.Remove("SCE_PSM_SDK"); string[] DIMENSIONS = screenResolution.Text.Split('x'); string SIM_PATH = Path.Combine("SDK", "target","win32","psm.exe"); proc.StartInfo.FileName = SIM_PATH; proc.StartInfo.Arguments = "\""+Path.Combine(Directory.GetCurrentDirectory(),"PSM",id,"Application","app.exe")+ "\" --window-width " + DIMENSIONS[0] + " --window-height " + DIMENSIONS[1]; proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardError = true; proc.StartInfo.RedirectStandardOutput = true; proc.StartInfo.CreateNoWindow = true; proc.StartInfo.EnvironmentVariables.Add("SCE_PSM_SDK", PSM_SDK); proc.OutputDataReceived += Proc_OutputDataReceived; proc.ErrorDataReceived += Proc_ErrorDataReceived; Console.WriteLine(proc.StartInfo.FileName + " " + proc.StartInfo.Arguments); proc.Start(); this.Hide(); IntPtr myhnd = Process.GetCurrentProcess().MainWindowHandle; Rect MySize = new Rect(); GetWindowRect(myhnd, ref MySize); Thread.Sleep(1100); IntPtr hnd = proc.MainWindowHandle; Console.WriteLine("Window Handle: "+hnd); Rect CurSize = new Rect(); GetWindowRect(hnd, ref CurSize); int width = CurSize.Right - CurSize.Left; int height = CurSize.Bottom - CurSize.Top; Console.WriteLine("Window Info: t "+CurSize.Top+" l "+CurSize.Left+" r "+CurSize.Right+" b "+CurSize.Bottom); MoveWindow(hnd, (Screen.PrimaryScreen.Bounds.Width / 2) - width / 2, (Screen.PrimaryScreen.Bounds.Height / 2) - height / 2, width, height, false); SetWindowText(hnd, GetPSMName(id)); const int GWL_STYLE = -16; long value = GetWindowLong(hnd, GWL_STYLE); SetWindowLong(hnd, GWL_STYLE, (int)(value & -131073 & -65537)); proc.WaitForExit(); this.Show(); } private void Proc_ErrorDataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine(e.Data); MessageBox.Show(e.Data, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error); } private void Proc_OutputDataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine(e.Data); } private void PSMGameHighlight_MouseLeave(object PSMGameBackground, EventArgs e) { object TaggedObject = PSMGameBackground.GetType().GetProperty("Tag").GetValue(PSMGameBackground, null); object TaggedTaggedObject = TaggedObject.GetType().GetProperty("Tag").GetValue(TaggedObject, null); PSMGameBackground.GetType().GetProperty("BackColor").SetValue(PSMGameBackground, Color.Transparent); if (TaggedObject != null) TaggedObject.GetType().GetProperty("BackColor").SetValue(TaggedObject, Color.Transparent); if (TaggedTaggedObject != null) TaggedTaggedObject.GetType().GetProperty("BackColor").SetValue(TaggedTaggedObject, Color.Transparent); } private void PSMGameHighlight_MouseEnter(object PSMGameBackground, EventArgs e) { object TaggedObject = PSMGameBackground.GetType().GetProperty("Tag").GetValue(PSMGameBackground, null); object TaggedTaggedObject = TaggedObject.GetType().GetProperty("Tag").GetValue(TaggedObject, null); PSMGameBackground.GetType().GetProperty("BackColor").SetValue(PSMGameBackground, Color.BlueViolet); if (TaggedObject != null) TaggedObject.GetType().GetProperty("BackColor").SetValue(TaggedObject, Color.BlueViolet); if (TaggedTaggedObject != null) TaggedTaggedObject.GetType().GetProperty("BackColor").SetValue(TaggedTaggedObject, Color.BlueViolet); } private void ReloadGameList() { NumberOfGames = 0; GameList.Controls.Clear(); if (Directory.Exists("PSM")) { noGamesMessage.Visible = false; foreach (string dir in Directory.GetDirectories("APPMETA")) { AddPsmGame(Path.GetFileNameWithoutExtension(dir)); } } else { noGamesMessage.Visible = true; noGamesMessage.BackColor = Color.Transparent; noGamesMessage.ForeColor =Color.White; noGamesMessage.Location = new Point(GameList.Width / 2 - 60, GameList.Height / 2); noGamesMessage.Name = "noGamesMessage"; noGamesMessage.Size = new Size(127, 26); noGamesMessage.TabIndex = 2; noGamesMessage.Text = "No games are installed...\r\nDrag n drop .zip files here"; GameList.Controls.Add(noGamesMessage); } } private void PSMUI_Load(object sender, EventArgs e) { ReloadGameList(); } private void PSMUI_DragDrop(object sender, DragEventArgs e) { var files = (string[])e.Data.GetData(DataFormats.FileDrop); foreach(string file in files) { Console.WriteLine("Processing: " + file); if (Path.GetExtension(file) != ".zip") { Console.WriteLine("ERROR: " + file + " Is not .zip!"); MessageBox.Show(file+" is not a ZIP file.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } Console.WriteLine("Extracting app.info" + file); ZipArchive zf = ZipFile.OpenRead(file); ZipArchiveEntry entry = zf.GetEntry("Application/app.info"); if(entry == null) { Console.WriteLine("ERROR: " + file + " Missing app.info!"); MessageBox.Show(file + " is not a PSM Game (missing Application/app.info)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } Directory.CreateDirectory("APPMETA"); Directory.CreateDirectory("PSM"); string InfoFile = Path.Combine("APPMETA/", Path.GetFileNameWithoutExtension(file)+".info"); entry.ExtractToFile(InfoFile, true); Console.WriteLine("Decompiling "+ InfoFile); CXML.CXMLParser.DecompileCXML(InfoFile,false,"APPMETA/"); Console.WriteLine("Done!"); Console.WriteLine("Extracting game..."); foreach(ZipArchiveEntry ze in zf.Entries) { string name = Path.Combine("PSM", Path.GetFileNameWithoutExtension(file)) + "/"+ ze.FullName; if(ze.FullName.EndsWith("\\") || ze.FullName.EndsWith("/")) { Directory.CreateDirectory(name); } else { ze.ExtractToFile(name, true); } Console.WriteLine("Writing: " + name); Application.DoEvents(); } Console.WriteLine("Done!"); ReloadGameList(); } } private void PSMUI_DragEnter(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy; } } }