1 using System; 2 using System.Collections.Generic; 3 using System.IO; 4 using System.IO.Compression; 5 using System.Linq; 6 using System.Text; 7 using System.Text.RegularExpressions; 8 using System.Threading.Tasks; 9 using System.Windows.Forms; 10 using Mesen.GUI.Config; 11 using Mesen.GUI.Debugger; 12 using Mesen.GUI.Forms.Cheats; 13 using Mesen.GUI.Forms.HdPackEditor; 14 using Mesen.GUI.Forms.NetPlay; 15 16 namespace Mesen.GUI.Forms 17 { 18 public partial class frmMain 19 { mnuDebug_DropDownOpening(object sender, EventArgs e)20 private void mnuDebug_DropDownOpening(object sender, EventArgs e) 21 { 22 mnuEditHeader.Enabled = _emuThread != null && InteropEmu.GetRomInfo().Format == RomFormat.iNes; 23 } 24 mnuEditHeader_Click(object sender, EventArgs e)25 private void mnuEditHeader_Click(object sender, EventArgs e) 26 { 27 using(frmEditHeader frm = new frmEditHeader()) { 28 frm.ShowDialog(sender, this); 29 } 30 } 31 mnuPlayMovie_Click(object sender, EventArgs e)32 private void mnuPlayMovie_Click(object sender, EventArgs e) 33 { 34 using(OpenFileDialog ofd = new OpenFileDialog()) { 35 ofd.SetFilter(ResourceHelper.GetMessage("FilterMovie")); 36 ofd.InitialDirectory = ConfigManager.MovieFolder; 37 if(ofd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { 38 InteropEmu.MoviePlay(ofd.FileName); 39 } 40 } 41 } 42 mnuStopMovie_Click(object sender, EventArgs e)43 private void mnuStopMovie_Click(object sender, EventArgs e) 44 { 45 InteropEmu.MovieStop(); 46 } 47 mnuRecordMovie_Click(object sender, EventArgs e)48 private void mnuRecordMovie_Click(object sender, EventArgs e) 49 { 50 using(frmRecordMovie frm = new frmRecordMovie()) { 51 frm.ShowDialog(mnuMovies, this); 52 } 53 } 54 mnuWaveRecord_Click(object sender, EventArgs e)55 private void mnuWaveRecord_Click(object sender, EventArgs e) 56 { 57 using(SaveFileDialog sfd = new SaveFileDialog()) { 58 sfd.SetFilter(ResourceHelper.GetMessage("FilterWave")); 59 sfd.InitialDirectory = ConfigManager.WaveFolder; 60 sfd.FileName = InteropEmu.GetRomInfo().GetRomName() + ".wav"; 61 if(sfd.ShowDialog(this) == System.Windows.Forms.DialogResult.OK) { 62 InteropEmu.WaveRecord(sfd.FileName); 63 } 64 } 65 } 66 mnuWaveStop_Click(object sender, EventArgs e)67 private void mnuWaveStop_Click(object sender, EventArgs e) 68 { 69 InteropEmu.WaveStop(); 70 } 71 mnuAviRecord_Click(object sender, EventArgs e)72 private void mnuAviRecord_Click(object sender, EventArgs e) 73 { 74 using(frmRecordAvi frm = new frmRecordAvi()) { 75 if(frm.ShowDialog(mnuVideoRecorder, this) == DialogResult.OK) { 76 InteropEmu.AviRecord(frm.Filename, ConfigManager.Config.AviRecordInfo.Codec, ConfigManager.Config.AviRecordInfo.CompressionLevel); 77 } 78 } 79 } 80 mnuAviStop_Click(object sender, EventArgs e)81 private void mnuAviStop_Click(object sender, EventArgs e) 82 { 83 InteropEmu.AviStop(); 84 } 85 mnuCheats_Click(object sender, EventArgs e)86 private void mnuCheats_Click(object sender, EventArgs e) 87 { 88 if(_cheatListWindow == null) { 89 _cheatListWindow = new frmCheatList(); 90 _cheatListWindow.Show(sender, this); 91 _cheatListWindow.FormClosed += (s, evt) => { 92 CheatInfo.ApplyCheats(); 93 _cheatListWindow = null; 94 }; 95 } else { 96 _cheatListWindow.WindowState = FormWindowState.Normal; 97 _cheatListWindow.BringToFront(); 98 _cheatListWindow.Focus(); 99 } 100 } 101 mnuHistoryViewer_Click(object sender, EventArgs e)102 private void mnuHistoryViewer_Click(object sender, EventArgs e) 103 { 104 if(_historyViewerWindow == null) { 105 _historyViewerWindow = new frmHistoryViewer(); 106 _historyViewerWindow.Show(sender, this); 107 _historyViewerWindow.FormClosed += (s, evt) => { 108 _historyViewerWindow = null; 109 }; 110 } else { 111 _historyViewerWindow.WindowState = FormWindowState.Normal; 112 _historyViewerWindow.BringToFront(); 113 _historyViewerWindow.Focus(); 114 } 115 } 116 LoadRandomGame()117 private void LoadRandomGame() 118 { 119 IEnumerable<string> gameFolders; 120 SearchOption searchOptions = SearchOption.TopDirectoryOnly; 121 if(ConfigManager.Config.PreferenceInfo.OverrideGameFolder && Directory.Exists(ConfigManager.Config.PreferenceInfo.GameFolder)) { 122 gameFolders = new List<string>() { ConfigManager.Config.PreferenceInfo.GameFolder }; 123 searchOptions = SearchOption.AllDirectories; 124 } else { 125 gameFolders = ConfigManager.Config.RecentFiles.Select(recentFile => recentFile.RomFile.Folder.ToLowerInvariant()).Distinct(); 126 } 127 List<string> gameRoms = new List<string>(); 128 129 foreach(string folder in gameFolders) { 130 if(Directory.Exists(folder)) { 131 gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.nes", searchOptions)); 132 gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.unf", searchOptions)); 133 gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.unif", searchOptions)); 134 gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.fds", searchOptions)); 135 136 if(searchOptions == SearchOption.AllDirectories) { 137 //When loading from a user-specified folder, assume zip/7z files will likely contain a ROM 138 gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.zip", searchOptions)); 139 gameRoms.AddRange(Directory.EnumerateFiles(folder, "*.7z", searchOptions)); 140 } 141 } 142 } 143 144 if(gameRoms.Count == 0) { 145 MesenMsgBox.Show("RandomGameNoGameFound", MessageBoxButtons.OK, MessageBoxIcon.Information); 146 } else { 147 int retryCount = 0; 148 Random random = new Random(); 149 do { 150 string randomGame = gameRoms[random.Next(gameRoms.Count)]; 151 152 if(randomGame.EndsWith(".7z", StringComparison.InvariantCultureIgnoreCase) || randomGame.EndsWith(".zip", StringComparison.InvariantCultureIgnoreCase)) { 153 List<InteropEmu.ArchiveRomEntry> archiveRomList = InteropEmu.GetArchiveRomList(randomGame); 154 if(archiveRomList.Count > 0) { 155 ResourcePath res = new ResourcePath() { 156 InnerFile = archiveRomList[0].Filename, 157 Path = randomGame 158 }; 159 if(!archiveRomList[0].IsUtf8) { 160 res.InnerFileIndex = 1; 161 } 162 LoadROM(res); 163 break; 164 } else { 165 retryCount++; 166 } 167 } else { 168 LoadFile(randomGame); 169 break; 170 } 171 } while(retryCount < 5); 172 } 173 } 174 mnuLogWindow_Click(object sender, EventArgs e)175 private void mnuLogWindow_Click(object sender, EventArgs e) 176 { 177 if(_logWindow == null) { 178 _logWindow = new frmLogWindow(); 179 _logWindow.Show(sender, this); 180 _logWindow.FormClosed += (object a, FormClosedEventArgs b) => { 181 _logWindow = null; 182 }; 183 } else { 184 _logWindow.WindowState = FormWindowState.Normal; 185 _logWindow.BringToFront(); 186 _logWindow.Focus(); 187 } 188 } 189 mnuInstallHdPack_Click(object sender, EventArgs e)190 private void mnuInstallHdPack_Click(object sender, EventArgs e) 191 { 192 using(OpenFileDialog ofd = new OpenFileDialog()) { 193 ofd.SetFilter(ResourceHelper.GetMessage("FilterZipFiles")); 194 if(ofd.ShowDialog(this) == DialogResult.OK) { 195 try { 196 using(FileStream stream = File.Open(ofd.FileName, FileMode.Open)) { 197 ZipArchive zip = new ZipArchive(stream); 198 199 //Find the hires.txt file 200 ZipArchiveEntry hiresEntry = null; 201 foreach(ZipArchiveEntry entry in zip.Entries) { 202 if(entry.Name == "hires.txt") { 203 hiresEntry = entry; 204 break; 205 } 206 } 207 208 if(hiresEntry != null) { 209 using(Stream entryStream = hiresEntry.Open()) { 210 using(StreamReader reader = new StreamReader(entryStream)) { 211 string hiresData = reader.ReadToEnd(); 212 RomInfo romInfo = InteropEmu.GetRomInfo(); 213 214 //If there's a "supportedRom" tag, check if it matches the current ROM 215 Regex supportedRomRegex = new Regex("<supportedRom>([^\\n]*)"); 216 Match match = supportedRomRegex.Match(hiresData); 217 if(match.Success) { 218 if(!match.Groups[1].Value.ToUpper().Contains(InteropEmu.GetRomInfo().Sha1.ToUpper())) { 219 MesenMsgBox.Show("InstallHdPackWrongRom", MessageBoxButtons.OK, MessageBoxIcon.Error); 220 return; 221 } 222 } 223 224 //Extract HD pack 225 try { 226 string targetFolder = Path.Combine(ConfigManager.HdPackFolder, romInfo.GetRomName()); 227 if(Directory.Exists(targetFolder)) { 228 //Warn if the folder already exists 229 if(MesenMsgBox.Show("InstallHdPackConfirmOverwrite", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, targetFolder) != DialogResult.OK) { 230 return; 231 } 232 } else { 233 Directory.CreateDirectory(targetFolder); 234 } 235 236 string hiresFileFolder = hiresEntry.FullName.Substring(0, hiresEntry.FullName.Length - "hires.txt".Length); 237 foreach(ZipArchiveEntry entry in zip.Entries) { 238 //Extract only the files in the same subfolder as the hires.txt file (and only if they have a name & size > 0) 239 if(!string.IsNullOrWhiteSpace(entry.Name) && entry.Length > 0 && entry.FullName.StartsWith(hiresFileFolder)) { 240 entry.ExtractToFile(Path.Combine(targetFolder, entry.Name), true); 241 } 242 } 243 } catch(Exception ex) { 244 MesenMsgBox.Show("InstallHdPackError", MessageBoxButtons.OK, MessageBoxIcon.Error, ex.ToString()); 245 return; 246 } 247 } 248 249 //Turn on HD Pack support automatically after installation succeeds 250 ConfigManager.Config.VideoInfo.UseHdPacks = true; 251 ConfigManager.ApplyChanges(); 252 ConfigManager.Config.ApplyConfig(); 253 254 if(MesenMsgBox.Show("InstallHdPackConfirmReset", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK) { 255 //Power cycle game if the user agrees 256 InteropEmu.PowerCycle(); 257 } 258 } 259 } else { 260 MesenMsgBox.Show("InstallHdPackInvalidPack", MessageBoxButtons.OK, MessageBoxIcon.Error); 261 } 262 } 263 } catch { 264 //Invalid file (file missing, not a zip file, etc.) 265 MesenMsgBox.Show("InstallHdPackInvalidZipFile", MessageBoxButtons.OK, MessageBoxIcon.Error); 266 } 267 } 268 } 269 } 270 mnuHdPackEditor_Click(object sender, EventArgs e)271 private void mnuHdPackEditor_Click(object sender, EventArgs e) 272 { 273 if(_hdPackEditorWindow == null) { 274 _hdPackEditorWindow = new frmHdPackEditor(); 275 _hdPackEditorWindow.Show(sender, this); 276 _hdPackEditorWindow.FormClosed += (object a, FormClosedEventArgs b) => { 277 _hdPackEditorWindow = null; 278 }; 279 } else { 280 _hdPackEditorWindow.WindowState = FormWindowState.Normal; 281 _hdPackEditorWindow.BringToFront(); 282 _hdPackEditorWindow.Focus(); 283 } 284 } 285 mnuStartServer_Click(object sender, EventArgs e)286 private void mnuStartServer_Click(object sender, EventArgs e) 287 { 288 if(InteropEmu.IsServerRunning()) { 289 Task.Run(() => InteropEmu.StopServer()); 290 } else { 291 using(frmServerConfig frm = new frmServerConfig()) { 292 if(frm.ShowDialog(sender, this) == System.Windows.Forms.DialogResult.OK) { 293 InteropEmu.StartServer(ConfigManager.Config.ServerInfo.Port, ConfigManager.Config.ServerInfo.Password, ConfigManager.Config.Profile.PlayerName); 294 } 295 } 296 } 297 } 298 mnuConnect_Click(object sender, EventArgs e)299 private void mnuConnect_Click(object sender, EventArgs e) 300 { 301 if(InteropEmu.IsConnected()) { 302 Task.Run(() => InteropEmu.Disconnect()); 303 } else { 304 using(frmClientConfig frm = new frmClientConfig()) { 305 if(frm.ShowDialog(sender, this) == System.Windows.Forms.DialogResult.OK) { 306 Task.Run(() => { 307 InteropEmu.Connect( 308 ConfigManager.Config.ClientConnectionInfo.Host, 309 ConfigManager.Config.ClientConnectionInfo.Port, 310 ConfigManager.Config.ClientConnectionInfo.Password, 311 ConfigManager.Config.Profile.PlayerName, 312 ConfigManager.Config.ClientConnectionInfo.Spectator 313 ); 314 }); 315 } 316 } 317 } 318 } 319 mnuProfile_Click(object sender, EventArgs e)320 private void mnuProfile_Click(object sender, EventArgs e) 321 { 322 using(frmPlayerProfile frm = new frmPlayerProfile()) { 323 frm.ShowDialog(sender, this); 324 } 325 } 326 mnuNetPlayPlayer1_Click(object sender, EventArgs e)327 private void mnuNetPlayPlayer1_Click(object sender, EventArgs e) 328 { 329 InteropEmu.NetPlaySelectController(0); 330 } 331 mnuNetPlayPlayer2_Click(object sender, EventArgs e)332 private void mnuNetPlayPlayer2_Click(object sender, EventArgs e) 333 { 334 InteropEmu.NetPlaySelectController(1); 335 } 336 mnuNetPlayPlayer3_Click(object sender, EventArgs e)337 private void mnuNetPlayPlayer3_Click(object sender, EventArgs e) 338 { 339 InteropEmu.NetPlaySelectController(2); 340 } 341 mnuNetPlayPlayer4_Click(object sender, EventArgs e)342 private void mnuNetPlayPlayer4_Click(object sender, EventArgs e) 343 { 344 InteropEmu.NetPlaySelectController(3); 345 } 346 mnuNetPlayPlayer5_Click(object sender, EventArgs e)347 private void mnuNetPlayPlayer5_Click(object sender, EventArgs e) 348 { 349 InteropEmu.NetPlaySelectController(4); 350 } 351 mnuNetPlaySpectator_Click(object sender, EventArgs e)352 private void mnuNetPlaySpectator_Click(object sender, EventArgs e) 353 { 354 InteropEmu.NetPlaySelectController(0xFF); 355 } 356 mnuApuViewer_Click(object sender, EventArgs e)357 private void mnuApuViewer_Click(object sender, EventArgs e) 358 { 359 DebugWindowManager.OpenDebugWindow(DebugWindow.ApuViewer); 360 } 361 mnuAssembler_Click(object sender, EventArgs e)362 private void mnuAssembler_Click(object sender, EventArgs e) 363 { 364 DebugWindowManager.OpenDebugWindow(DebugWindow.Assembler); 365 } 366 mnuDebugger_Click(object sender, EventArgs e)367 private void mnuDebugger_Click(object sender, EventArgs e) 368 { 369 DebugWindowManager.OpenDebugWindow(DebugWindow.Debugger); 370 } 371 mnuDebugDebugger_Click(object sender, EventArgs e)372 private void mnuDebugDebugger_Click(object sender, EventArgs e) 373 { 374 DebugWindowManager.OpenDebugWindow(DebugWindow.Debugger); 375 } 376 mnuMemoryViewer_Click(object sender, EventArgs e)377 private void mnuMemoryViewer_Click(object sender, EventArgs e) 378 { 379 DebugWindowManager.OpenDebugWindow(DebugWindow.MemoryViewer); 380 } 381 mnuEventViewer_Click(object sender, EventArgs e)382 private void mnuEventViewer_Click(object sender, EventArgs e) 383 { 384 DebugWindowManager.OpenDebugWindow(DebugWindow.EventViewer); 385 } 386 mnuPpuViewer_Click(object sender, EventArgs e)387 private void mnuPpuViewer_Click(object sender, EventArgs e) 388 { 389 DebugWindowManager.OpenDebugWindow(DebugWindow.PpuViewer); 390 } 391 mnuScriptWindow_Click(object sender, EventArgs e)392 private void mnuScriptWindow_Click(object sender, EventArgs e) 393 { 394 DebugWindowManager.OpenDebugWindow(DebugWindow.ScriptWindow); 395 } 396 mnuTraceLogger_Click(object sender, EventArgs e)397 private void mnuTraceLogger_Click(object sender, EventArgs e) 398 { 399 DebugWindowManager.OpenDebugWindow(DebugWindow.TraceLogger); 400 } 401 mnuWatchWindow_Click(object sender, EventArgs e)402 private void mnuWatchWindow_Click(object sender, EventArgs e) 403 { 404 DebugWindowManager.OpenDebugWindow(DebugWindow.WatchWindow); 405 } 406 mnuTextHooker_Click(object sender, EventArgs e)407 private void mnuTextHooker_Click(object sender, EventArgs e) 408 { 409 DebugWindowManager.OpenDebugWindow(DebugWindow.TextHooker); 410 } 411 mnuProfiler_Click(object sender, EventArgs e)412 private void mnuProfiler_Click(object sender, EventArgs e) 413 { 414 DebugWindowManager.OpenDebugWindow(DebugWindow.Profiler); 415 } 416 mnuOpenNametableViewer_Click(object sender, EventArgs e)417 private void mnuOpenNametableViewer_Click(object sender, EventArgs e) 418 { 419 DebugWindowManager.OpenPpuViewer(PpuViewerMode.NametableViewer); 420 } 421 mnuOpenChrViewer_Click(object sender, EventArgs e)422 private void mnuOpenChrViewer_Click(object sender, EventArgs e) 423 { 424 DebugWindowManager.OpenPpuViewer(PpuViewerMode.ChrViewer); 425 } 426 mnuOpenSpriteViewer_Click(object sender, EventArgs e)427 private void mnuOpenSpriteViewer_Click(object sender, EventArgs e) 428 { 429 DebugWindowManager.OpenPpuViewer(PpuViewerMode.SpriteViewer); 430 } 431 mnuOpenPaletteViewer_Click(object sender, EventArgs e)432 private void mnuOpenPaletteViewer_Click(object sender, EventArgs e) 433 { 434 DebugWindowManager.OpenPpuViewer(PpuViewerMode.PaletteViewer); 435 } 436 mnuDebugDualSystemSecondaryCpu_Click(object sender, EventArgs e)437 private void mnuDebugDualSystemSecondaryCpu_Click(object sender, EventArgs e) 438 { 439 bool switchCpu = false; 440 441 if(!DebugWindowManager.HasOpenedWindow) { 442 switchCpu = true; 443 } else { 444 if(MessageBox.Show("Warning: Changing this setting will close all currently opened debug tools!", "Warning", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.OK) { 445 DebugWindowManager.CloseAll(); 446 if(!DebugWindowManager.HasOpenedWindow) { 447 switchCpu = true; 448 } 449 } 450 } 451 452 if(switchCpu) { 453 mnuDebugDualSystemSecondaryCpu.Checked = !mnuDebugDualSystemSecondaryCpu.Checked; 454 ConfigManager.Config.DebugInfo.DebugConsoleId = mnuDebugDualSystemSecondaryCpu.Checked ? InteropEmu.ConsoleId.Slave : InteropEmu.ConsoleId.Master; 455 ConfigManager.ApplyChanges(); 456 InteropEmu.DebugSetDebuggerConsole(ConfigManager.Config.DebugInfo.DebugConsoleId); 457 } 458 } 459 } 460 461 } 462