private void StartPlaytest(WMap map, MapLayer active_layer) { string dolphinPath = Path.Combine(WSettingsManager.GetSettings().DolphinDirectory.FilePath, "Dolphin.exe"); if (!File.Exists(dolphinPath)) { MessageBox.Show("You must specify the path to Dolphin in the options menu before you can playtest.", "Dolphin not found", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } if (map.MapName.Length > 7) { string error = ""; error += "The name of the stage you are trying to playtest is too long.\n"; error += "Stage names must be 7 characters or shorter.\n"; error += "The game would crash if you loaded this map without shortening its name.\n"; error += "Aborting playtest."; MessageBox.Show(error, "Warning"); return; } Console.WriteLine($"Stage name: { map.MapName }, Room Name: { map.FocusedSceneLabel }"); string map_path = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "files", "res", "stage", map.MapName); map.ExportToDirectory(map_path); BackupSystemFiles(); string dolPath = Path.Combine(WSettingsManager.GetSettings().RootDirectoryPath, "sys", "main.dol"); m_DolphinStartInfo = new ProcessStartInfo(dolphinPath); m_DolphinStartInfo.Arguments = $"-b -e \"{ dolPath }\""; int room_no = 0; int spawn_id = 0; GetRoomAndSpawnID(map.FocusedScene, out room_no, out spawn_id); int numMatchingSpawns = 0; foreach (var scn in map.SceneList) { numMatchingSpawns += scn.GetChildrenOfType <SpawnPoint>().Where(x => x.Room == room_no && x.SpawnID == spawn_id).Count(); } if (numMatchingSpawns == 0) { MessageBox.Show($"No spawns found with room number {room_no} and spawn ID {spawn_id}.", "Warning"); return; } if (numMatchingSpawns > 1) { MessageBox.Show($"There are {numMatchingSpawns} duplicate spawns with room number {room_no} and spawn ID {spawn_id}.", "Warning"); return; } if (!File.Exists(dolPath)) { Console.WriteLine("ISO root has no executable!"); return; } Patch testRoomPatch = JsonConvert.DeserializeObject <Patch>(File.ReadAllText(@"resources\patches\test_room_diff.json")); testRoomPatch.Files[0].Patchlets.Add(new Patchlet(0x8022D034, new List <byte>(Encoding.ASCII.GetBytes(map.MapName)))); testRoomPatch.Files[0].Patchlets.Add(new Patchlet(0x800531E3, new List <byte>(new byte[] { (byte)spawn_id }))); testRoomPatch.Files[0].Patchlets.Add(new Patchlet(0x800531E7, new List <byte>(new byte[] { (byte)room_no }))); testRoomPatch.Files[0].Patchlets.Add(new Patchlet(0x800531EB, new List <byte>(new byte[] { (byte)(active_layer - 1) }))); // Starting items list is at 0x8022D03C and can contain a maximum of 256 item IDs List <byte> ItemIDs = m_InventorySettings.ViewModel.ItemIDs; for (int i = 0; i < ItemIDs.Count; i++) { testRoomPatch.Files[0].Patchlets.Add(new Patchlet(0x8022D03C + i, new List <byte>(new byte[] { ItemIDs[i] }))); } // Save slot testRoomPatch.Files[0].Patchlets.Add(new Patchlet(0x8022CFDF, new List <byte>(new byte[] { m_InventorySettings.ViewModel.SaveFileIndex }))); testRoomPatch.Apply(WSettingsManager.GetSettings().RootDirectoryPath); Patch devModePatch = JsonConvert.DeserializeObject <Patch>(File.ReadAllText(@"resources\patches\developer_mode_diff.json")); devModePatch.Apply(WSettingsManager.GetSettings().RootDirectoryPath); Patch particleIdsPatch = JsonConvert.DeserializeObject <Patch>(File.ReadAllText(@"resources\patches\missing_particle_ids_diff.json")); particleIdsPatch.Apply(WSettingsManager.GetSettings().RootDirectoryPath); if (WSettingsManager.GetSettings().HeapDisplay) { Patch heapDisplayPatch = JsonConvert.DeserializeObject <Patch>(File.ReadAllText(@"resources\patches\heap_display_diff.json")); heapDisplayPatch.Apply(WSettingsManager.GetSettings().RootDirectoryPath); } m_DolphinInstance = Process.Start(m_DolphinStartInfo); m_DolphinInstance.EnableRaisingEvents = true; m_DolphinInstance.Exited += OnDolphinExited; }