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); }