public string Play() { if (!SteamUtil.IsSteamRunning()) { MessageBox.Show("If you own the Steam Version, please open Steam, then click OK"); } var options = profile.Options; bool playerKeyboard = (bool)profile.Options["keyboardPlayer"]; IniFile file = new IniFile(saveFile); file.IniWriteValue("SystemSettings", "WindowedFullscreen", "False"); file.IniWriteValue("SystemSettings", "Fullscreen", "False"); file.IniWriteValue("Engine.Engine", "bMuteAudioWhenNotInFocus", "False"); file.IniWriteValue("Engine.Engine", "bPauseOnLossOfFocus", "False"); file.IniWriteValue("WillowGame.WillowGameEngine", "bPauseLostFocusWindowed", "False"); file.IniWriteValue("WillowGame.WillowGameEngine", "bMuteAudioWhenNotInFocus", "False"); Screen[] all = Screen.AllScreens; // minimize everything //User32.MinimizeEverything(); List<PlayerInfo> players = profile.PlayerData; for (int i = 0; i < players.Count; i++) { PlayerInfo player = players[i]; // Set Borderlands 2 Resolution and stuff to run Rectangle playerBounds = player.monitorBounds; // find the monitor that has this screen Screen owner = null; for (int j = 0; j < all.Length; j++) { Screen s = all[j]; if (s.Bounds.Contains(playerBounds)) { owner = s; break; } } int width = playerBounds.Width; int height = playerBounds.Height; if (owner == null) { // log // screen doesn't exist //continue; } else { Rectangle ob = owner.Bounds; if (playerBounds.X == ob.X && playerBounds.Y == ob.Y && playerBounds.Width == ob.Width && playerBounds.Height == ob.Height) { // borderlands 2 has a limitation for max-screen size, we can't go up to the monitor's bounds // in windowed mode file.IniWriteValue("SystemSettings", "WindowedFullscreen", "True"); } else { file.IniWriteValue("SystemSettings", "WindowedFullscreen", "False"); } } file.IniWriteValue("SystemSettings", "ResX", width.ToString(CultureInfo.InvariantCulture)); file.IniWriteValue("SystemSettings", "ResY", height.ToString(CultureInfo.InvariantCulture)); ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = executablePlace; startInfo.WindowStyle = ProcessWindowStyle.Hidden; // NEW object option = options["saveid" + i]; //object option = 11; int id = (int)option; if (playerKeyboard) { startInfo.Arguments = "-AlwaysFocus -NoController -ControllerOffset=" + (i - 1).ToString(CultureInfo.InvariantCulture) + " -SaveDataId=" + id.ToString(CultureInfo.InvariantCulture); } else { startInfo.Arguments = "-AlwaysFocus -ControllerOffset=" + i.ToString(CultureInfo.InvariantCulture) + " -SaveDataId=" + id.ToString(CultureInfo.InvariantCulture); } startInfo.UseShellExecute = true; startInfo.WorkingDirectory = Path.GetDirectoryName(executablePlace); Process proc = Process.Start(startInfo); ScreenData data = new ScreenData(); data.Position = new Point(playerBounds.X, playerBounds.Y); data.Size = new Size(playerBounds.Width, playerBounds.Height); player.Process = proc; player.Tag = data; } return string.Empty; }
public string Play() { List<PlayerInfo> players = profile.PlayerData; Screen[] all = Screen.AllScreens; string backupDir = GameManager.Instance.GetBackupFolder(this.userGame.Game); string binFolder = Path.GetDirectoryName(userGame.ExePath); string rootFolder = ReplaceCaseInsensitive(binFolder, gen.BinariesFolder, ""); int gamePadId = 0; for (int i = 0; i < players.Count; i++) { PlayerInfo player = players[i]; if (i > 0 && gen.KillMutex.Length > 0) { PlayerInfo before = players[i - 1]; for (;;) { if (exited > 0) { return ""; } Thread.Sleep(100); if (before.screenData.KilledMutexes) { break; } } } Rectangle playerBounds = player.monitorBounds; // find the monitor that has this screen Screen owner = null; for (int j = 0; j < all.Length; j++) { Screen s = all[j]; if (s.Bounds.Contains(playerBounds)) { owner = s; break; } } int width = playerBounds.Width; int height = playerBounds.Height; bool isFullscreen = false; if (owner != null) { Rectangle ob = owner.Bounds; if (playerBounds.X == ob.X && playerBounds.Y == ob.Y && playerBounds.Width == ob.Width && playerBounds.Height == ob.Height) { isFullscreen = true; } } engine.SetValue("Id", i.ToString(CultureInfo.InvariantCulture)); engine.SetValue("Width", width.ToString(CultureInfo.InvariantCulture)); engine.SetValue("Height", height.ToString(CultureInfo.InvariantCulture)); engine.SetValue("IsFullscreen", isFullscreen); // symlink the game folder // find out the folder that contains the game executable string root = GetRootFolder(gen.BinariesFolder); string linkFolder = Path.Combine(backupDir, "Instance" + i); Directory.CreateDirectory(linkFolder); int exitCode; CmdUtil.LinkDirectories(rootFolder, linkFolder, out exitCode, root.ToLower()); string linkBin = Path.Combine(linkFolder, gen.BinariesFolder); if (!string.IsNullOrEmpty(gen.BinariesFolder)) { // this needs fixing, if there are several folder to the exe and they have important files inside, this won't work! TODO Directory.CreateDirectory(linkBin); CmdUtil.LinkDirectories(binFolder, linkBin, out exitCode); } string exePath = Path.Combine(linkBin, this.userGame.Game.ExecutableName); if (gen.SymlinkExe) { CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput"); } else { CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput", Path.GetFileNameWithoutExtension(gen.ExecutableName.ToLower())); File.Copy(userGame.ExePath, exePath, true); } // some games have save files inside their game folder, so we need to access them inside the loop this.data[NucleusFolderEnum.GameFolder.ToString()] = linkFolder; string saveFile = ProcessPath(gen.SavePath); IniFile file = new IniFile(saveFile); switch (gen.SaveType) { case GenericGameSaveType.INI: foreach (var modPair in gen.ModifySave) { string key = modPair.Key; string[] keys = key.Split('/'); engine.Execute(modPair.Value); string val = engine.GetCompletionValue().ToString(); file.IniWriteValue(keys[0], keys[1], val); } break; } string startArgs = gen.StartArguments; byte[] xdata = null; if (gen.SupportsKeyboard && i == (int)profile.Options["KeyboardPlayer"]) { engine.SetValue("Keyboard", true); // need to make an xinput that answers to no gamepad? xdata = Properties.Resources.xinput4; } else { engine.SetValue("Keyboard", false); switch (gamePadId) { case 0: xdata = Properties.Resources.xinput1; break; case 1: xdata = Properties.Resources.xinput2; break; case 2: xdata = Properties.Resources.xinput3; break; case 3: xdata = Properties.Resources.xinput4; break; default: xdata = Properties.Resources.xinput4; break; } gamePadId++; } using (Stream str = File.OpenWrite(Path.Combine(linkBin, "xinput1_3.dll"))) { str.Write(xdata, 0, xdata.Length); } if (!string.IsNullOrEmpty(startArgs)) { startArgs = engine.Execute(startArgs).GetCompletionValue().AsString(); } if (gen.NeedsSteamEmulation) { string steamEmu = GameManager.Instance.ExtractSteamEmu(); string emuExe = Path.Combine(steamEmu, "SmartSteamLoader.exe"); string emuIni = Path.Combine(steamEmu, "SmartSteamEmu.ini"); IniFile emu = new IniFile(emuIni); emu.IniWriteValue("Launcher", "Target", exePath); emu.IniWriteValue("Launcher", "StartIn", Path.GetDirectoryName(exePath)); emu.IniWriteValue("Launcher", "CommandLine", startArgs); emu.IniWriteValue("Launcher", "SteamClientPath", Path.Combine(steamEmu, "SmartSteamEmu.dll")); emu.IniWriteValue("Launcher", "SteamClientPath64", Path.Combine(steamEmu, "SmartSteamEmu64.dll")); emu.IniWriteValue("Launcher", "InjectDll", "0"); emu.IniWriteValue("SmartSteamEmu", "AppId", gen.SteamID); Process proc; if (gen.KillMutex.Length > 0) { // to kill the mutexes we need to orphanize the process proc = ProcessUtil.RunOrphanProcess(emuExe); } else { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = emuExe; proc = Process.Start(startInfo); } player.Process = proc; player.SteamEmu = true; } else { Process proc; if (gen.KillMutex.Length > 0) { proc = Process.GetProcessById(StartGameUtil.StartGame(exePath, startArgs)); } else { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = exePath; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.Arguments = startArgs; startInfo.UseShellExecute = true; startInfo.WorkingDirectory = Path.GetDirectoryName(exePath); proc = Process.Start(startInfo); } if (proc == null) { for (int times = 0; times < 200; times++) { Thread.Sleep(50); Process[] procs = Process.GetProcesses(); string proceName = Path.GetFileNameWithoutExtension(gen.ExecutableName).ToLower(); string launcherName = Path.GetFileNameWithoutExtension(gen.LauncherExe).ToLower(); for (int j = 0; j < procs.Length; j++) { Process p = procs[j]; string lowerP = p.ProcessName.ToLower(); if (((lowerP == proceName) || lowerP ==launcherName) && !attached.Contains(p)) { attached.Add(p); proc = p; break; } } if (proc != null) { break; } } } else { attached.Add(proc); } player.Process = proc; } ScreenData data = new ScreenData(); data.Position = new Point(playerBounds.X, playerBounds.Y); data.Size = new Size(playerBounds.Width, playerBounds.Height); data.KilledMutexes = gen.KillMutex.Length == 0; player.screenData = data; } return string.Empty; }
public void Update(int delayMS) { if (profile == null) { return; } exited = 0; List <PlayerInfo> players = profile.PlayerData; timer += delayMS; for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; if (p.screenData == null || p.Process == null) { continue; } if (p.SteamEmu) { List <int> children = ProcessUtil.GetChildrenProcesses(p.Process); if (children.Count > 0) { for (int j = 0; j < children.Count; j++) { int id = children[j]; Process child = Process.GetProcessById(id); try { if (child.ProcessName.Contains("conhost")) { continue; } } catch { continue; } p.Process = child; p.SteamEmu = child.ProcessName.Contains("SmartSteamLoader") || child.ProcessName.Contains("cmd"); } } } else { ScreenData data = p.screenData; if (data.Set) { if (p.Process.HasExited) { exited++; continue; } if (!p.screenData.KilledMutexes && gen.KillMutex.Length > 0) { StartGameUtil.KillMutex(p.Process, gen.KillMutex); p.screenData.KilledMutexes = true; } uint lStyle = User32Interop.GetWindowLong(data.HWND.Hwnd, User32_WS.GWL_STYLE); if (lStyle != data.RegLong) { uint toRemove = User32_WS.WS_CAPTION; lStyle = lStyle & (~toRemove); User32Interop.SetWindowLong(data.HWND.Hwnd, User32_WS.GWL_STYLE, lStyle); data.RegLong = lStyle; data.HWND.Location = data.Position; } } else { p.Process.Refresh(); if (p.Process.HasExited) { if (p.GotLauncher) { if (p.GotGame) { exited++; } else { List <int> children = ProcessUtil.GetChildrenProcesses(p.Process); if (children.Count > 0) { for (int j = 0; j < children.Count; j++) { int id = children[j]; Process pro = Process.GetProcessById(id); if (!attached.Contains(pro)) { attached.Add(pro); data.HWND = null; p.GotGame = true; p.Process = pro; } } } } } else { // Steam showing a launcher, need to find our game process string launcher = gen.LauncherExe; if (launcher.ToLower().EndsWith(".exe")) { launcher = launcher.Remove(launcher.Length - 4, 4); } Process[] procs = Process.GetProcessesByName(launcher); for (int j = 0; j < procs.Length; j++) { Process pro = procs[j]; if (!attached.Contains(pro)) { attached.Add(pro); p.Process = pro; p.GotLauncher = true; } } } } else { if (data.HWNDRetry || data.HWND == null || data.HWND.Hwnd != p.Process.MainWindowHandle) { data.HWND = new HwndObject(p.Process.MainWindowHandle); Point pos = data.HWND.Location; if (String.IsNullOrEmpty(data.HWND.Title) || pos.X == -32000 || data.HWND.Title.ToLower() == gen.LauncherTitle.ToLower()) { data.HWNDRetry = true; } else { Size s = data.Size; data.Set = true; data.HWND.TopMost = true; data.HWND.Size = data.Size; data.HWND.Location = data.Position; } } } } } if (exited == players.Count) { if (!hasEnded) { hasEnded = true; GameManager.Instance.ExecuteBackup(this.userGame.Game); if (Ended != null) { Ended(); } } } } }
public string Play() { List <PlayerInfo> players = profile.PlayerData; Screen[] all = Screen.AllScreens; string backupDir = GameManager.Instance.GetBackupFolder(this.userGame.Game); string binFolder = Path.GetDirectoryName(userGame.ExePath); string rootFolder = ReplaceCaseInsensitive(binFolder, gen.BinariesFolder, ""); int gamePadId = 0; for (int i = 0; i < players.Count; i++) { PlayerInfo player = players[i]; if (i > 0 && gen.KillMutex.Length > 0) { PlayerInfo before = players[i - 1]; for (;;) { if (exited > 0) { return(""); } Thread.Sleep(100); if (before.screenData.KilledMutexes) { break; } } } Rectangle playerBounds = player.monitorBounds; // find the monitor that has this screen Screen owner = null; for (int j = 0; j < all.Length; j++) { Screen s = all[j]; if (s.Bounds.Contains(playerBounds)) { owner = s; break; } } int width = playerBounds.Width; int height = playerBounds.Height; bool isFullscreen = false; if (owner != null) { Rectangle ob = owner.Bounds; if (playerBounds.X == ob.X && playerBounds.Y == ob.Y && playerBounds.Width == ob.Width && playerBounds.Height == ob.Height) { isFullscreen = true; } } engine.SetValue("Id", i.ToString(CultureInfo.InvariantCulture)); engine.SetValue("Width", width.ToString(CultureInfo.InvariantCulture)); engine.SetValue("Height", height.ToString(CultureInfo.InvariantCulture)); engine.SetValue("IsFullscreen", isFullscreen); // symlink the game folder // find out the folder that contains the game executable string root = GetRootFolder(gen.BinariesFolder); string linkFolder = Path.Combine(backupDir, "Instance" + i); Directory.CreateDirectory(linkFolder); int exitCode; CmdUtil.LinkDirectories(rootFolder, linkFolder, out exitCode, root.ToLower()); string linkBin = Path.Combine(linkFolder, gen.BinariesFolder); if (!string.IsNullOrEmpty(gen.BinariesFolder)) { // this needs fixing, if there are several folder to the exe and they have important files inside, this won't work! TODO Directory.CreateDirectory(linkBin); CmdUtil.LinkDirectories(binFolder, linkBin, out exitCode); } string exePath = Path.Combine(linkBin, this.userGame.Game.ExecutableName); if (gen.SymlinkExe) { CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput"); } else { CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput", Path.GetFileNameWithoutExtension(gen.ExecutableName.ToLower())); File.Copy(userGame.ExePath, exePath, true); } // some games have save files inside their game folder, so we need to access them inside the loop this.data[NucleusFolderEnum.GameFolder.ToString()] = linkFolder; string saveFile = ProcessPath(gen.SavePath); IniFile file = new IniFile(saveFile); switch (gen.SaveType) { case GenericGameSaveType.INI: foreach (var modPair in gen.ModifySave) { string key = modPair.Key; string[] keys = key.Split('/'); engine.Execute(modPair.Value); string val = engine.GetCompletionValue().ToString(); file.IniWriteValue(keys[0], keys[1], val); } break; } string startArgs = gen.StartArguments; byte[] xdata = null; if (gen.SupportsKeyboard && i == (int)profile.Options["KeyboardPlayer"]) { engine.SetValue("Keyboard", true); // need to make an xinput that answers to no gamepad? xdata = Properties.Resources.xinput4; } else { engine.SetValue("Keyboard", false); switch (gamePadId) { case 0: xdata = Properties.Resources.xinput1; break; case 1: xdata = Properties.Resources.xinput2; break; case 2: xdata = Properties.Resources.xinput3; break; case 3: xdata = Properties.Resources.xinput4; break; default: xdata = Properties.Resources.xinput4; break; } gamePadId++; } using (Stream str = File.OpenWrite(Path.Combine(linkBin, "xinput1_3.dll"))) { str.Write(xdata, 0, xdata.Length); } if (!string.IsNullOrEmpty(startArgs)) { startArgs = engine.Execute(startArgs).GetCompletionValue().AsString(); } if (gen.NeedsSteamEmulation) { string steamEmu = GameManager.Instance.ExtractSteamEmu(); string emuExe = Path.Combine(steamEmu, "SmartSteamLoader.exe"); string emuIni = Path.Combine(steamEmu, "SmartSteamEmu.ini"); IniFile emu = new IniFile(emuIni); emu.IniWriteValue("Launcher", "Target", exePath); emu.IniWriteValue("Launcher", "StartIn", Path.GetDirectoryName(exePath)); emu.IniWriteValue("Launcher", "CommandLine", startArgs); emu.IniWriteValue("Launcher", "SteamClientPath", Path.Combine(steamEmu, "SmartSteamEmu.dll")); emu.IniWriteValue("Launcher", "SteamClientPath64", Path.Combine(steamEmu, "SmartSteamEmu64.dll")); emu.IniWriteValue("Launcher", "InjectDll", "0"); emu.IniWriteValue("SmartSteamEmu", "AppId", gen.SteamID); Process proc; if (gen.KillMutex.Length > 0) { // to kill the mutexes we need to orphanize the process proc = ProcessUtil.RunOrphanProcess(emuExe); } else { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = emuExe; proc = Process.Start(startInfo); } player.Process = proc; player.SteamEmu = true; } else { Process proc; if (gen.KillMutex.Length > 0) { proc = Process.GetProcessById(StartGameUtil.StartGame(exePath, startArgs)); } else { ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = exePath; startInfo.WindowStyle = ProcessWindowStyle.Hidden; startInfo.Arguments = startArgs; startInfo.UseShellExecute = true; startInfo.WorkingDirectory = Path.GetDirectoryName(exePath); proc = Process.Start(startInfo); } if (proc == null) { for (int times = 0; times < 200; times++) { Thread.Sleep(50); Process[] procs = Process.GetProcesses(); string proceName = Path.GetFileNameWithoutExtension(gen.ExecutableName).ToLower(); string launcherName = Path.GetFileNameWithoutExtension(gen.LauncherExe).ToLower(); for (int j = 0; j < procs.Length; j++) { Process p = procs[j]; string lowerP = p.ProcessName.ToLower(); if (((lowerP == proceName) || lowerP == launcherName) && !attached.Contains(p)) { attached.Add(p); proc = p; break; } } if (proc != null) { break; } } } else { attached.Add(proc); } player.Process = proc; } ScreenData data = new ScreenData(); data.Position = new Point(playerBounds.X, playerBounds.Y); data.Size = new Size(playerBounds.Width, playerBounds.Height); data.KilledMutexes = gen.KillMutex.Length == 0; player.screenData = data; } return(string.Empty); }
public string Play() { if (!SteamUtil.IsSteamRunning()) { MessageBox.Show("If you own the Steam Version, please open Steam, then click OK"); } var options = profile.Options; KeyboardPlayer playerKeyboard = (KeyboardPlayer)profile.Options["keyboardPlayer"]; int pKeyboard = (int)playerKeyboard; IniFile file = new IniFile(saveFile); file.IniWriteValue("SystemSettings", "WindowedFullscreen", "False"); file.IniWriteValue("SystemSettings", "Fullscreen", "False"); file.IniWriteValue("Engine.Engine", "bMuteAudioWhenNotInFocus", "False"); file.IniWriteValue("Engine.Engine", "bPauseOnLossOfFocus", "False"); file.IniWriteValue("WillowGame.WillowGameEngine", "bPauseLostFocusWindowed", "False"); file.IniWriteValue("WillowGame.WillowGameEngine", "bMuteAudioWhenNotInFocus", "False"); Screen[] all = Screen.AllScreens; // minimize everything //User32.MinimizeEverything(); List<PlayerInfo> players = profile.PlayerData; string backupDir = GameManager.Instance.GetBackupFolder(this.userGame.Game); string binFolder = Path.GetDirectoryName(executablePlace); string rootFolder = Path.GetDirectoryName( Path.GetDirectoryName(binFolder)); int gamePadId = 0; for (int i = 0; i < players.Count; i++) { string linkFolder = Path.Combine(backupDir, "Instance" + i); PlayerInfo player = players[i]; // Set Borderlands 2 Resolution and stuff to run Rectangle playerBounds = player.monitorBounds; // find the monitor that has this screen Screen owner = null; for (int j = 0; j < all.Length; j++) { Screen s = all[j]; if (s.Bounds.Contains(playerBounds)) { owner = s; break; } } int width = playerBounds.Width; int height = playerBounds.Height; if (owner == null) { // log // screen doesn't exist //continue; } else { Rectangle ob = owner.Bounds; if (playerBounds.X == ob.X && playerBounds.Y == ob.Y && playerBounds.Width == ob.Width && playerBounds.Height == ob.Height) { // borderlands 2 has a limitation for max-screen size, we can't go up to the monitor's bounds // in windowed mode file.IniWriteValue("SystemSettings", "WindowedFullscreen", "True"); } else { file.IniWriteValue("SystemSettings", "WindowedFullscreen", "False"); } } file.IniWriteValue("SystemSettings", "ResX", width.ToString(CultureInfo.InvariantCulture)); file.IniWriteValue("SystemSettings", "ResY", height.ToString(CultureInfo.InvariantCulture)); // Link-making Directory.CreateDirectory(linkFolder); int exitCode; CmdUtil.LinkDirectories(rootFolder, linkFolder, out exitCode, "binaries"); string linkBin = Path.Combine(linkFolder, @"Binaries\Win32"); Directory.CreateDirectory(linkBin); CmdUtil.LinkDirectories(binFolder, linkBin, out exitCode); CmdUtil.LinkFiles(binFolder, linkBin, out exitCode, "xinput", "borderlands"); string exePath = Path.Combine(linkBin, this.userGame.Game.ExecutableName); File.Copy(this.executablePlace, exePath, true); // Link-end ProcessStartInfo startInfo = new ProcessStartInfo(); startInfo.FileName = exePath; startInfo.WindowStyle = ProcessWindowStyle.Hidden; // NEW object option = options["saveid" + i]; //object option = 11; int id = (int)option; if (i == pKeyboard) { startInfo.Arguments = "-AlwaysFocus -NoController -SaveDataId=" + id.ToString(CultureInfo.InvariantCulture); } else { byte[] xdata = null; switch (gamePadId) { case 0: xdata = Nucleus.Coop.Games.GamesResources.xinput1; break; case 1: xdata = Nucleus.Coop.Games.GamesResources.xinput2; break; case 2: xdata = Nucleus.Coop.Games.GamesResources.xinput3; break; case 3: xdata = Nucleus.Coop.Games.GamesResources.xinput4; break; default: xdata = Nucleus.Coop.Games.GamesResources.xinput4; break; } using (Stream str = File.OpenWrite(Path.Combine(linkBin, "xinput1_3.dll"))) { str.Write(xdata, 0, xdata.Length); } startInfo.Arguments = "-AlwaysFocus -nostartupmovies -SaveDataId=" + id.ToString(CultureInfo.InvariantCulture); gamePadId++; } startInfo.UseShellExecute = true; startInfo.WorkingDirectory = Path.GetDirectoryName(exePath); Process proc = Process.Start(startInfo); ScreenData data = new ScreenData(); data.Position = new Point(playerBounds.X, playerBounds.Y); data.Size = new Size(playerBounds.Width, playerBounds.Height); player.Process = proc; player.Tag = data; } return string.Empty; }
public string Play() { if (!SteamUtil.IsSteamRunning()) { return "Steam must be opened to play Left 4 Dead splitscreen"; } using (Stream videoStream = new FileStream(videoFile, FileMode.Open)) { videoCfg = new SourceCfgFile(videoStream); } string originalCFG = String.Copy(videoCfg.RawData); // minimize everything User32.MinimizeEverything(); Screen[] allScreens = Screen.AllScreens; string folder = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location); string l4dFolder = Path.GetDirectoryName(executablePlace); int gamePadId = 0; if (instances) { for (int i = 0; i < players.Count; i++) { PlayerInfo p = players[i]; Screen screen = allScreens[p.ScreenIndex]; int width = 0; int height = 0; Rectangle bounds = screen.Bounds; Point location = new Point(); ViewportUtil.GetPlayerViewport(p, 0, out width, out height, out location); CultureInfo c = CultureInfo.InvariantCulture; UpdateVideoCfg(width.ToString(c), height.ToString(c), "0", "1"); if (i == 0) { MakeAutoExecServer(); } else { MakeAutoExecClient(); } MakeMakeSplit(); string execPlace = executablePlace; string l4dBinFolder = Path.Combine(l4dFolder, "bin"); if (i != 0) { string l4d = Path.Combine(folder, "L4D_" + (i + 1)); Directory.CreateDirectory(l4d); FolderUtil.MkLink(l4dFolder, l4d, "bin", "left4dead.exe"); // copy executable execPlace = Path.Combine(l4d, "left4dead.exe"); File.Copy(Path.Combine(l4dFolder, "left4dead.exe"), execPlace, true); // make bin folder now l4dBinFolder = Path.Combine(l4d, "bin"); string originalBinFolder = Path.Combine(l4dFolder, "bin"); Directory.CreateDirectory(l4dBinFolder); FolderUtil.MkLink(originalBinFolder, l4dBinFolder, "xinput1_3.dll"); // add exec to firewall FirewallUtil.AuthorizeProgram("Left 4 Dead", execPlace); } // copy the correct xinput to the bin folder byte[] xdata = null; if (firstKeyboard) { switch (gamePadId) { case 0: xdata = GamesResources._4_xinput1_3; break; case 1: xdata = GamesResources._1_xinput1_3; break; case 2: xdata = GamesResources._2_xinput1_3; break; case 3: xdata = GamesResources._3_xinput1_3; break; } } else { switch (gamePadId) { case 0: xdata = GamesResources._1_xinput1_3; break; case 1: xdata = GamesResources._2_xinput1_3; break; case 2: xdata = GamesResources._3_xinput1_3; break; case 3: xdata = GamesResources._4_xinput1_3; break; } } string xinputPath = Path.Combine(l4dBinFolder, "xinput1_3.dll"); using (MemoryStream stream = new MemoryStream(xdata)) { // write to bin folder using (FileStream file = new FileStream(xinputPath, FileMode.Create)) { stream.WriteTo(file); } } gamePadId++; int pid = StartGameUtil.StartGame(execPlace, "-novid -insecure", delayTime, "hl2_singleton_mutex", "steam_singleton_mutext"); Process proc = Process.GetProcessById(pid); HwndObject hwnd = new HwndObject(proc.Handle); ScreenData data = new ScreenData(); data.Position = location; data.HWND = hwnd; data.Size = new Size(width, height); p.Process = proc; p.Tag = data; Thread.Sleep(delayTime); } loaded = true; } else { int screenIndex = -1; int fullWidth = 0; int fullHeight = 0; for (int i = 0; i < players.Count; i++) { PlayerInfo player = players[i]; Screen scr = allScreens[player.ScreenIndex]; if (screenIndex == -1) { screenIndex = player.ScreenIndex; fullWidth = scr.Bounds.Width; fullHeight = scr.Bounds.Height; } else { if (screenIndex != player.ScreenIndex) { //twoScreens = true; // Add 2nd monitor fullWidth += scr.Bounds.Width; } } } loaded = true; string fWidth = fullWidth.ToString(); string fHeight = fullHeight.ToString(); string fullScr = (0).ToString(); string noWindowBorderStr = (1).ToString(); int splitMode = 1; for (int i = 0; i < players.Count; i++) { PlayerInfo player = players[i]; if (player.ScreenType == ScreenType.HorizontalBottom || player.ScreenType == ScreenType.HorizontalTop) { splitMode = 1; } else { splitMode = 2; } } MakeAutoExecSplitscreen(splitMode.ToString(CultureInfo.InvariantCulture)); MakeMakeSplit(); StartGameUtil.StartGame(executablePlace, "-novid -insecure", delayTime, "hl2_singleton_mutex", "steam_singleton_mutext"); } return string.Empty; }