private int? AddMovieToList(string filename, bool force) { using (var file = new HawkFile(filename)) { if (!file.Exists) { return null; } var index = IsDuplicateOf(filename); if (!index.HasValue) { //System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); var movie = PreLoadMovieFile(file, force); if (movie == null) { return null; } //watch.Stop(); Console.WriteLine("[{0}] {1}",watch.ElapsedMilliseconds,Path.GetFileName(filename)); lock (_movieList) { _movieList.Add(movie); index = _movieList.Count - 1; } _sortReverse = false; _sortedCol = string.Empty; } return index; } }
public ArchiveChooser(HawkFile hawkfile) { InitializeComponent(); errorBalloon.IsBalloon = true; errorBalloon.InitialDelay = 0; if (useRegEx) radRegEx.Checked = true; else radSimple.Checked = true; cbInstantFilter.Checked = matchWhileTyping; var items = hawkfile.ArchiveItems; for (int i = 0; i < items.Count; i++) { var item = items[i]; var lvi = new ListViewItem { Tag = i }; lvi.SubItems.Add(new ListViewItem.ListViewSubItem()); lvi.Text = item.Name; long size = item.Size; var extension = Path.GetExtension(item.Name); if (extension != null && (size % 1024 == 16 && extension.ToUpper() == ".NES")) size -= 16; lvi.SubItems[1].Text = Util.FormatFileSize(size); archiveItems.Add(lvi); } InitializeFileView(); }
private void buttonPal_Click(object sender, EventArgs e) { OpenFileDialog ofd = new OpenFileDialog { InitialDirectory = PathManager.MakeAbsolutePath(Global.Config.PathEntries["NES", "Palettes"].Path, "NES"), Filter = "Palette Files (.pal)|*.PAL|All Files (*.*)|*.*", RestoreDirectory = true }; var result = ofd.ShowDialog(); if (result != DialogResult.OK) { return; } HawkFile palette = new HawkFile(ofd.FileName); if (palette != null && palette.Exists) { var data = Emulation.Cores.Nintendo.NES.NES.Palettes.Load_FCEUX_Palette(HawkFile.ReadAllBytes(palette.Name)); Settings.SetNesHawkPalette(data); SetPaletteImage(); } }
public MainForm(string[] args) { GlobalWin.MainForm = this; Global.Rewinder = new Rewinder { MessageCallback = GlobalWin.OSD.AddMessage }; Global.ControllerInputCoalescer = new ControllerInputCoalescer(); Global.FirmwareManager = new FirmwareManager(); Global.MovieSession = new MovieSession { Movie = MovieService.DefaultInstance, MovieControllerAdapter = MovieService.DefaultInstance.LogGeneratorInstance().MovieControllerAdapter, MessageCallback = GlobalWin.OSD.AddMessage, AskYesNoCallback = StateErrorAskUser, PauseCallback = PauseEmulator, ModeChangedCallback = SetMainformMovieInfo }; new AutoResetEvent(false); Icon = Properties.Resources.logo; InitializeComponent(); Global.Game = GameInfo.NullInstance; if (Global.Config.ShowLogWindow) { LogConsole.ShowConsole(); DisplayLogWindowMenuItem.Checked = true; } _throttle = new Throttle(); Global.CheatList = new CheatCollection(); Global.CheatList.Changed += ToolHelpers.UpdateCheatRelatedTools; UpdateStatusSlots(); UpdateKeyPriorityIcon(); // In order to allow late construction of this database, we hook up a delegate here to dearchive the data and provide it on demand // we could background thread this later instead if we wanted to be real clever NES.BootGodDB.GetDatabaseBytes = () => { using (var NesCartFile = new HawkFile(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "NesCarts.7z")).BindFirst()) { return NesCartFile .GetStream() .ReadAllBytes(); } }; // TODO - replace this with some kind of standard dictionary-yielding parser in a separate component string cmdRom = null; string cmdLoadState = null; string cmdMovie = null; string cmdDumpType = null; string cmdDumpName = null; bool startFullscreen = false; for (int i = 0; i < args.Length; i++) { // For some reason sometimes visual studio will pass this to us on the commandline. it makes no sense. if (args[i] == ">") { i++; var stdout = args[i]; Console.SetOut(new StreamWriter(stdout)); continue; } var arg = args[i].ToLower(); if (arg.StartsWith("--load-slot=")) { cmdLoadState = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--movie=")) { cmdMovie = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--dump-type=")) { cmdDumpType = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--dump-frames=")) { var list = arg.Substring(arg.IndexOf('=') + 1); var items = list.Split(','); _currAviWriterFrameList = new HashSet<int>(); for (int j = 0; j < items.Length; j++) _currAviWriterFrameList.Add(int.Parse(items[j])); //automatically set dump length to maximum frame _autoDumpLength = _currAviWriterFrameList.OrderBy(x => x).Last(); } else if (arg.StartsWith("--dump-name=")) { cmdDumpName = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--dump-length=")) { int.TryParse(arg.Substring(arg.IndexOf('=') + 1), out _autoDumpLength); } else if (arg.StartsWith("--dump-close")) { _autoCloseOnDump = true; } else if (arg.StartsWith("--chromeless")) { _chromeless = true; } else if (arg.StartsWith("--fullscreen")) { startFullscreen = true; } else { cmdRom = arg; } } Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt")); //TODO GL - a lot of disorganized wiring-up here PresentationPanel = new PresentationPanel(); GlobalWin.DisplayManager = new DisplayManager(PresentationPanel); Controls.Add(PresentationPanel); Controls.SetChildIndex(PresentationPanel, 0); //TODO GL - move these event handlers somewhere less obnoxious line in the On* overrides Load += (o, e) => { AllowDrop = true; DragEnter += FormDragEnter; DragDrop += FormDragDrop; }; Closing += (o, e) => { if (GlobalWin.Tools.AskSave()) { CloseGame(); Global.MovieSession.Movie.Stop(); GlobalWin.Tools.Close(); SaveConfig(); } else { e.Cancel = true; } }; ResizeBegin += (o, e) => { _inResizeLoop = true; if (GlobalWin.Sound != null) { GlobalWin.Sound.StopSound(); } }; Resize += (o, e) => { SetWindowText(); }; ResizeEnd += (o, e) => { _inResizeLoop = false; SetWindowText(); if (PresentationPanel != null) { PresentationPanel.Resized = true; } if (GlobalWin.Sound != null) { GlobalWin.Sound.StartSound(); } }; Input.Initialize(); InitControls(); var comm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(comm); Global.Emulator = new NullEmulator(comm, Global.Config.GetCoreSettings<NullEmulator>()); Global.ActiveController = new Controller(NullEmulator.NullController); Global.AutoFireController = Global.AutofireNullControls; Global.AutofireStickyXORAdapter.SetOnOffPatternFromConfig(); try { GlobalWin.Sound = new Sound(Handle); } catch { string message = "Couldn't initialize sound device! Try changing the output method in Sound config."; if (Global.Config.SoundOutputMethod == Config.ESoundOutputMethod.DirectSound) message = "Couldn't initialize DirectSound! Things may go poorly for you. Try changing your sound driver to 44.1khz instead of 48khz in mmsys.cpl."; MessageBox.Show(message, "Initialization Error", MessageBoxButtons.OK, MessageBoxIcon.Error); Global.Config.SoundOutputMethod = Config.ESoundOutputMethod.Dummy; GlobalWin.Sound = new Sound(Handle); } GlobalWin.Sound.StartSound(); InputManager.RewireInputChain(); GlobalWin.Tools = new ToolManager(this); RewireSound(); // Workaround for windows, location is -32000 when minimized, if they close it during this time, that's what gets saved if (Global.Config.MainWndx == -32000) { Global.Config.MainWndx = 0; } if (Global.Config.MainWndy == -32000) { Global.Config.MainWndy = 0; } if (Global.Config.MainWndx != -1 && Global.Config.MainWndy != -1 && Global.Config.SaveWindowPosition) { Location = new Point(Global.Config.MainWndx, Global.Config.MainWndy); } if (cmdRom != null) { // Commandline should always override auto-load LoadRom(cmdRom); if (Global.Game == null) { MessageBox.Show("Failed to load " + cmdRom + " specified on commandline"); } } else if (Global.Config.RecentRoms.AutoLoad && !Global.Config.RecentRoms.Empty) { LoadRomFromRecent(Global.Config.RecentRoms.MostRecent); } if (cmdMovie != null) { if (Global.Game == null) { OpenRom(); } else { var movie = MovieService.Get(cmdMovie); Global.MovieSession.ReadOnly = true; // if user is dumping and didnt supply dump length, make it as long as the loaded movie if (_autoDumpLength == 0) { _autoDumpLength = movie.InputLogLength; } StartNewMovie(movie, false); Global.Config.RecentMovies.Add(cmdMovie); } } else if (Global.Config.RecentMovies.AutoLoad && !Global.Config.RecentMovies.Empty) { if (Global.Game.IsNullInstance) { OpenRom(); } // If user picked a game, then do the autoload logic if (!Global.Game.IsNullInstance) { if (File.Exists(Global.Config.RecentMovies.MostRecent)) { StartNewMovie(MovieService.Get(Global.Config.RecentMovies.MostRecent), false); } else { Global.Config.RecentMovies.HandleLoadError(Global.Config.RecentMovies.MostRecent); } } } if (startFullscreen || Global.Config.StartFullscreen) { ToggleFullscreen(); } if (cmdLoadState != null && !Global.Game.IsNullInstance) { LoadQuickSave("QuickSave" + cmdLoadState); } else if (Global.Config.AutoLoadLastSaveSlot && !Global.Game.IsNullInstance) { LoadQuickSave("QuickSave" + Global.Config.SaveSlot); } GlobalWin.Tools.AutoLoad(); if (Global.Config.RecentWatches.AutoLoad) { GlobalWin.Tools.LoadRamWatch(!Global.Config.DisplayRamWatch); } if (Global.Config.RecentCheats.AutoLoad) { GlobalWin.Tools.Load<Cheats>(); } if (Global.Config.DisplayStatusBar == false) { MainStatusBar.Visible = false; } else { DisplayStatusBarMenuItem.Checked = true; } if (Global.Config.StartPaused) { PauseEmulator(); } // start dumping, if appropriate if (cmdDumpType != null && cmdDumpName != null) { RecordAv(cmdDumpType, cmdDumpName); } SetMainformMovieInfo(); SynchChrome(); //TODO POOP PresentationPanel.Control.Paint += (o, e) => { GlobalWin.DisplayManager.NeedsToPaint = true; }; }
private static byte[] GetRomBytes() { var path = GlobalWin.MainForm.CurrentlyOpenRomArgs.OpenAdvanced.SimplePath; if (string.IsNullOrEmpty(path)) { return new byte[] { 0xFF }; } using (var file = new HawkFile()) { file.Open(path); if (!file.Exists) { return null; } if (file.IsArchive) { var stream = file.GetStream(); return stream.ReadAllBytes(); } return File.ReadAllBytes(path); } }
/// <summary> /// Utility: attempts to read all the content from the provided path. /// </summary> public static byte[] ReadAllBytes(string path) { using (var file = new HawkFile(path)) { if (!file.Exists) { throw new FileNotFoundException(path); } using (Stream stream = file.GetStream()) { var ms = new MemoryStream((int)stream.Length); stream.CopyTo(ms); return ms.GetBuffer(); } } }
/// <summary> /// Utility: Uses full HawkFile processing to determine whether a file exists at the provided path /// </summary> public static bool ExistsAt(string path) { using (var file = new HawkFile(path)) { return file.Exists; } }
public Mainform(string[] args) { GLManager.CreateInstance(); InitializeComponent(); _throttle = new BizHawk.Client.EmuHawk.Throttle(); _inputManager = new InputManager(this); Global.Config = ConfigService.Load<Config>(PathManager.DefaultIniPath); Global.Config.DispFixAspectRatio = false; // TODO: don't hardcode this Global.Config.ResolveDefaults(); GlobalWin.MainForm = this; Global.ControllerInputCoalescer = new ControllerInputCoalescer(); Global.FirmwareManager = new FirmwareManager(); Global.MovieSession = new MovieSession { Movie = MovieService.DefaultInstance, MovieControllerAdapter = MovieService.DefaultInstance.LogGeneratorInstance().MovieControllerAdapter, MessageCallback = AddMessage, AskYesNoCallback = StateErrorAskUser, PauseCallback = PauseEmulator, ModeChangedCallback = SetMainformMovieInfo }; new AutoResetEvent(false); // TODO //Icon = Properties.Resources.logo; Global.Game = GameInfo.NullInstance; // In order to allow late construction of this database, we hook up a delegate here to dearchive the data and provide it on demand // we could background thread this later instead if we wanted to be real clever NES.BootGodDB.GetDatabaseBytes = () => { using (var NesCartFile = new HawkFile(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "NesCarts.7z")).BindFirst()) { return NesCartFile .GetStream() .ReadAllBytes(); } }; Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt")); Input.Initialize(this.Handle); InitControls(); // TODO //CoreFileProvider.SyncCoreCommInputSignals(); Global.ActiveController = new Controller(NullEmulator.NullController); Global.AutoFireController = Global.AutofireNullControls; Global.AutofireStickyXORAdapter.SetOnOffPatternFromConfig(); Closing += (o, e) => { Global.MovieSession.Movie.Stop(); foreach (var ew in EmulatorWindows.ToList()) { ew.ShutDown(); } SaveConfig(); }; if (Global.Config.MainWndx != -1 && Global.Config.MainWndy != -1 && Global.Config.SaveWindowPosition) { Location = new Point(Global.Config.MainWndx, Global.Config.MainWndy); } }
private int[,] ResolvePalette(bool showmsg = false) { if (AutoLoadPalette.Checked) // checkbox checked: try to load palette from file { if (PalettePath.Text.Length > 0) { HawkFile palette = new HawkFile(PalettePath.Text); if (palette != null && palette.Exists) { var data = Palettes.Load_FCEUX_Palette(HawkFile.ReadAllBytes(palette.Name)); if (showmsg) GlobalWin.OSD.AddMessage("Palette file loaded: " + palette.Name); return data; } else { return settings.Palette; } } else // no filename: interpret this as "reset to default" { if (showmsg) GlobalWin.OSD.AddMessage("Standard Palette set"); return (int[,])Palettes.QuickNESPalette.Clone(); } } else // checkbox unchecked: we're reusing whatever palette was set { return settings.Palette; } }
public bool PreLoadHeaderAndLength(HawkFile hawkFile) { var file = new FileInfo(Filename); if (!file.Exists) { return false; } Filename = file.FullName; return Load(true); }
private static byte[] GetRomBytes() { var path = GlobalWin.MainForm.CurrentlyOpenRom; if (path == null) { return new byte[] { 0xFF }; } using (var file = new HawkFile()) { file.Open(path); if (!file.Exists) { return null; } if (file.IsArchive) { var stream = file.GetStream(); return stream.ReadAllBytes(); } return File.ReadAllBytes(path); } }
/// <summary> /// Load Header information only for displaying file information in dialogs such as play movie /// TODO - consider not loading the SavestateBinaryBase64Blob key? /// </summary> public bool PreLoadHeaderAndLength(HawkFile hawkFile) { Loaded = false; var file = new FileInfo(hawkFile.CanonicalFullPath); if (file.Exists == false) { return false; } Header.Clear(); _log.Clear(); var origStreamPosn = hawkFile.GetStream().Position; hawkFile.GetStream().Position = 0; // Reset to start // No using block because we're sharing the stream and need to give it back undisposed. var sr = new StreamReader(hawkFile.GetStream()); for (; ; ) { //read to first space (key/value delimeter), or pipe, or EOF int first = sr.Read(); if (first == -1) { break; } // EOF if (first == '|') //pipe: begin input log { //NOTE - this code is a bit convoluted due to its predating the basic outline of the parser which was upgraded in may 2014 var line = '|' + sr.ReadLine(); //how many bytes are left, total? long remain = sr.BaseStream.Length - sr.BaseStream.Position; //try to find out whether we use \r\n or \n //but only look for 1K characters. bool usesR = false; for (int i = 0; i < 1024; i++) { int c = sr.Read(); if (c == -1) break; if (c == '\r') { usesR = true; break; } if (c == '\n') break; } int lineLen = line.Length + 1; //account for \n if (usesR) lineLen++; //account for \r _preloadFramecount = (int)(remain / lineLen); //length is remaining bytes / length per line _preloadFramecount++; //account for the current line break; } else { //a header line. finish reading key token, to make sure it isn't one of the FORBIDDEN keys var sbLine = new StringBuilder(); sbLine.Append((char)first); for (; ; ) { int c = sr.Read(); if (c == -1) break; if (c == '\n') break; if (c == ' ') break; sbLine.Append((char)c); } var line = sbLine.ToString(); //ignore these suckers, theyre way too big for preloading. seriously, we will get out of memory errors. var skip = line == HeaderKeys.SAVESTATEBINARYBASE64BLOB; if (skip) { //skip remainder of the line sr.DiscardBufferedData(); var stream = sr.BaseStream; for (; ; ) { int c = stream.ReadByte(); if (c == -1) break; if (c == '\n') break; } //proceed to next line continue; } var remainder = sr.ReadLine(); sbLine.Append(' '); sbLine.Append(remainder); line = sbLine.ToString(); if (string.IsNullOrWhiteSpace(line) || Header.ParseLineFromFile(line)) { continue; } Header.Comments.Add(line); } } hawkFile.GetStream().Position = origStreamPosn; return true; }
private IMovie PreLoadMovieFile(HawkFile hf, bool force) { var movie = MovieService.Get(hf.CanonicalFullPath); try { movie.PreLoadHeaderAndLength(hf); // Don't do this from browse if (movie.Hash == Global.Game.Hash || Global.Config.PlayMovie_MatchHash == false || force) { return movie; } } catch (Exception ex) { // TODO: inform the user that a movie failed to parse in some way Console.WriteLine(ex.Message); } return null; }
public bool PreLoadHeaderAndLength(HawkFile hawkFile) { // For now, preload simply loads everything var file = new FileInfo(Filename); if (!file.Exists) { return false; } Filename = file.FullName; return Load(); }
public RomGame(HawkFile file, string patch) { if (!file.Exists) { throw new Exception("The file needs to exist, yo."); } Extension = file.Extension; var stream = file.GetStream(); int fileLength = (int)stream.Length; // read the entire contents of the file into memory. // unfortunate in the case of large files, but thats what we've got to work with for now. // if we're offset exactly 512 bytes from a 1024-byte boundary, // assume we have a header of that size. Otherwise, assume it's just all rom. // Other 'recognized' header sizes may need to be added. int headerOffset = fileLength % BankSize; if (headerOffset.In(0, 512) == false) { Console.WriteLine("ROM was not a multiple of 1024 bytes, and not a recognized header size: {0}. Assume it's purely ROM data.", headerOffset); headerOffset = 0; } else if (headerOffset > 0) { Console.WriteLine("Assuming header of {0} bytes.", headerOffset); } // read the entire file into FileData. FileData = new byte[fileLength]; stream.Read(FileData, 0, fileLength); // if there was no header offset, RomData is equivalent to FileData // (except in cases where the original interleaved file data is necessary.. in that case we'll have problems.. // but this whole architecture is not going to withstand every peculiarity and be fast as well. if (headerOffset == 0) { RomData = FileData; } else { // if there was a header offset, read the whole file into FileData and then copy it into RomData (this is unfortunate, in case RomData isnt needed) int romLength = fileLength - headerOffset; RomData = new byte[romLength]; Buffer.BlockCopy(FileData, headerOffset, RomData, 0, romLength); } if (file.Extension == ".SMD") { RomData = DeInterleaveSMD(RomData); } if (file.Extension == ".Z64" || file.Extension == ".N64" || file.Extension == ".V64") { RomData = MutateSwapN64(RomData); } // note: this will be taking several hashes, of a potentially large amount of data.. yikes! GameInfo = Database.GetGameInfo(RomData, file.Name); CheckForPatchOptions(); if (patch != null) { using (var patchFile = new HawkFile(patch)) { patchFile.BindFirstOf("IPS"); if (patchFile.IsBound) { IPS.Patch(RomData, patchFile.GetStream()); } } } }
public RomGame(HawkFile file) : this(file, null) { }
public static ToolStripItem[] RecentMenu(this RecentFiles recent, Action<string> loadFileCallback, bool autoload = false) { var items = new List<ToolStripItem>(); if (recent.Empty) { var none = new ToolStripMenuItem { Enabled = false, Text = "None" }; items.Add(none); } else { foreach (var filename in recent) { //TODO - do TSMI and TSDD need disposing? yuck var temp = filename; var item = new ToolStripMenuItem { Text = temp }; items.Add(item); item.Click += (o, ev) => { loadFileCallback(temp); }; //TODO - use standard methods to split filename (hawkfile acquire?) var hf = new HawkFile(); hf.Parse(temp); bool canExplore = true; if (!File.Exists(hf.FullPathWithoutMember)) canExplore = false; var tsdd = new ToolStripDropDownMenu(); if (canExplore) { //make a menuitem to show the last modified timestamp var timestamp = File.GetLastWriteTime(hf.FullPathWithoutMember); var tsmiTimestamp = new ToolStripLabel { Text = timestamp.ToString() }; tsdd.Items.Add(tsmiTimestamp); tsdd.Items.Add(new ToolStripSeparator()); if (hf.IsArchive) { //make a menuitem to let you copy the path var tsmiCopyCanonicalPath = new ToolStripMenuItem { Text = "&Copy Canonical Path" }; tsmiCopyCanonicalPath.Click += (o, ev) => { System.Windows.Forms.Clipboard.SetText(temp); }; tsdd.Items.Add(tsmiCopyCanonicalPath); var tsmiCopyArchivePath = new ToolStripMenuItem { Text = "Copy Archive Path" }; tsmiCopyArchivePath.Click += (o, ev) => { System.Windows.Forms.Clipboard.SetText(hf.FullPathWithoutMember); }; tsdd.Items.Add(tsmiCopyArchivePath); var tsmiOpenArchive = new ToolStripMenuItem { Text = "Open &Archive" }; tsmiOpenArchive.Click += (o, ev) => { System.Diagnostics.Process.Start(hf.FullPathWithoutMember); }; tsdd.Items.Add(tsmiOpenArchive); } else { //make a menuitem to let you copy the path var tsmiCopyPath = new ToolStripMenuItem { Text = "&Copy Path" }; tsmiCopyPath.Click += (o, ev) => { System.Windows.Forms.Clipboard.SetText(temp); }; tsdd.Items.Add(tsmiCopyPath); } tsdd.Items.Add(new ToolStripSeparator()); //make a menuitem to let you explore to it var tsmiExplore = new ToolStripMenuItem { Text = "&Explore" }; string explorePath = "\"" + hf.FullPathWithoutMember + "\""; tsmiExplore.Click += (o, ev) => { System.Diagnostics.Process.Start("explorer.exe", "/select, " + explorePath); }; tsdd.Items.Add(tsmiExplore); var tsmiCopyFile = new ToolStripMenuItem { Text = "Copy &File" }; var lame = new System.Collections.Specialized.StringCollection(); lame.Add(hf.FullPathWithoutMember); tsmiCopyFile.Click += (o, ev) => { System.Windows.Forms.Clipboard.SetFileDropList(lame); }; tsdd.Items.Add(tsmiCopyFile); var tsmiTest = new ToolStripMenuItem { Text = "&Shell Context Menu" }; tsmiTest.Click += (o, ev) => { var si = new GongSolutions.Shell.ShellItem(hf.FullPathWithoutMember); var scm = new GongSolutions.Shell.ShellContextMenu(si); var tsddi = o as ToolStripDropDownItem; tsddi.Owner.Update(); scm.ShowContextMenu(tsddi.Owner, new System.Drawing.Point(0, 0)); }; tsdd.Items.Add(tsmiTest); tsdd.Items.Add(new ToolStripSeparator()); } else { //make a menuitem to show the last modified timestamp var tsmiMissingFile = new ToolStripLabel { Text = "-Missing-" }; tsdd.Items.Add(tsmiMissingFile); tsdd.Items.Add(new ToolStripSeparator()); } //in either case, make a menuitem to let you remove the path var tsmiRemovePath = new ToolStripMenuItem { Text = "&Remove" }; tsmiRemovePath.Click += (o, ev) => { recent.Remove(temp); }; tsdd.Items.Add(tsmiRemovePath); ////experiment of popping open a submenu. doesnt work well. //item.MouseDown += (o, mev) => //{ // if (mev.Button != MouseButtons.Right) return; // //location of the menu containing this item that was just rightclicked // var pos = item.Owner.Bounds.Location; // //the offset within that menu of this item // var tsddi = item as ToolStripDropDownItem; // pos.Offset(tsddi.Bounds.Location); // //the offset of the click // pos.Offset(mev.Location); // //tsdd.OwnerItem = item; //has interesting promise, but breaks things otherwise // tsdd.Show(pos); //}; //just add it to the submenu for now item.MouseDown += (o, mev) => { if (mev.Button != MouseButtons.Right) return; if (item.DropDown != null) item.DropDown = tsdd; item.ShowDropDown(); }; } } items.Add(new ToolStripSeparator()); var clearitem = new ToolStripMenuItem { Text = "&Clear", Enabled = !recent.Frozen }; clearitem.Click += (o, ev) => recent.Clear(); items.Add(clearitem); var freezeitem = new ToolStripMenuItem { Text = recent.Frozen ? "&Unfreeze" : "&Freeze" }; freezeitem.Click += (o, ev) => recent.Frozen ^= true; items.Add(freezeitem); if (autoload) { var auto = new ToolStripMenuItem { Text = "&Autoload", Checked = recent.AutoLoad }; auto.Click += (o, ev) => recent.ToggleAutoLoad(); items.Add(auto); } var settingsitem = new ToolStripMenuItem { Text = "&Recent Settings..." }; settingsitem.Click += (o, ev) => { using (var prompt = new InputPrompt { TextInputType = InputPrompt.InputType.Unsigned, Message = "Number of recent files to track", InitialValue = recent.MAX_RECENT_FILES.ToString() }) { var result = prompt.ShowDialog(); if (result == DialogResult.OK) { int val = int.Parse(prompt.PromptText); if (val > 0) recent.MAX_RECENT_FILES = val; } } }; items.Add(settingsitem); return items.ToArray(); }
void RunImportJob(IEnumerable<string> files) { bool didSomething = false; var basepath = PathManager.MakeAbsolutePath(Global.Config.PathEntries.FirmwaresPathFragment, null); string errors = ""; foreach(var f in files) { using (var hf = new HawkFile(f)) { if (hf.IsArchive) { //blech. the worst extraction code in the universe. string extractpath = System.IO.Path.GetTempFileName() + ".dir"; DirectoryInfo di = null; di = System.IO.Directory.CreateDirectory(extractpath); try { foreach (var ai in hf.ArchiveItems) { hf.BindArchiveMember(ai); var stream = hf.GetStream(); var ms = new MemoryStream(); Util.CopyStream(hf.GetStream(), ms, stream.Length); string outfile = ai.Name; string myname = Path.GetFileName(outfile); outfile = Path.Combine(extractpath, myname); File.WriteAllBytes(outfile, ms.ToArray()); hf.Unbind(); didSomething |= RunImportJobSingle(basepath, outfile, ref errors); } } finally { di.Delete(true); } } else didSomething |= RunImportJobSingle(basepath, f, ref errors); } } if (errors != "") System.Windows.Forms.MessageBox.Show(errors, "Error importing these files"); if (didSomething) DoScan(); }
private static bool CurrentRomIsArchive() { var path = GlobalWin.MainForm.CurrentlyOpenRom; if (path == null) { return false; } using (var file = new HawkFile()) { file.Open(path); if (!file.Exists) { return false; } return file.IsArchive; } }
public IList<string> AssetFullPaths { get; set; } // TODO: Hack work around, to avoid having to refactor Assets into a object array, should be refactored! public static XmlGame Create(HawkFile f) { try { var x = new XmlDocument(); x.Load(f.GetStream()); var y = x.SelectSingleNode("./BizHawk-XMLGame"); if (y == null) { return null; } var ret = new XmlGame { GI = { System = y.Attributes["System"].Value, Name = y.Attributes["Name"].Value, Status = RomStatus.Unknown }, Xml = x }; string fullpath = string.Empty; var n = y.SelectSingleNode("./LoadAssets"); if (n != null) { var HashStream = new MemoryStream(); int? OriginalIndex = null; foreach (XmlNode a in n.ChildNodes) { string filename = a.Attributes["FileName"].Value; byte[] data = new byte[0]; if (filename[0] == '|') { // in same archive var ai = f.FindArchiveMember(filename.Substring(1)); if (ai != null) { if (OriginalIndex == null) { OriginalIndex = f.GetBoundIndex(); } f.Unbind(); f.BindArchiveMember(ai); data = f.GetStream().ReadAllBytes(); } else { throw new Exception("Couldn't load XMLGame Asset \"" + filename + "\""); } } else { // relative path fullpath = Path.GetDirectoryName(f.CanonicalFullPath.Split('|').First()) ?? string.Empty; fullpath = Path.Combine(fullpath, filename.Split('|').First()); try { using (var hf = new HawkFile(fullpath)) { if (hf.IsArchive) { var archiveItem = hf.ArchiveItems.First(ai => ai.Name == filename.Split('|').Skip(1).First()); hf.Unbind(); hf.BindArchiveMember(archiveItem); data = hf.GetStream().ReadAllBytes(); } else { data = File.ReadAllBytes(fullpath.Split('|').First()); } } } catch { throw new Exception("Couldn't load XMLGame LoadAsset \"" + filename + "\""); } } ret.Assets.Add(new KeyValuePair<string, byte[]>(filename, data)); ret.AssetFullPaths.Add(fullpath); using (var sha1 = System.Security.Cryptography.SHA1.Create()) { sha1.TransformFinalBlock(data, 0, data.Length); HashStream.Write(sha1.Hash, 0, sha1.Hash.Length); } } ret.GI.Hash = HashStream.GetBuffer().HashSHA1(0, (int)HashStream.Length); HashStream.Close(); if (OriginalIndex != null) { f.Unbind(); f.BindArchiveMember((int)OriginalIndex); } } else { ret.GI.Hash = "0000000000000000000000000000000000000000"; } return ret; } catch (Exception ex) { throw new InvalidOperationException(ex.ToString()); } }
int? ChooseArchive(HawkFile hf) { int ret = multiindex; multiindex++; multihasnext = multiindex < hf.ArchiveItems.Count; return ret; }
/// <summary>Utility: Uses full HawkFile processing to determine whether a file exists at the provided path</summary> public static bool ExistsAt(string path) { using var file = new HawkFile(path); return(file.Exists); }
private int? LoadArhiveChooser(HawkFile file) { var ac = new BizHawk.Client.EmuHawk.ArchiveChooser(file); if (ac.ShowDialog(this) == DialogResult.OK) { return ac.SelectedMemberIndex; } else { return null; } }
/// <summary>reads all the contents of the file at <paramref name="path"/></summary> /// <exception cref="FileNotFoundException">could not find <paramref name="path"/></exception> public static byte[] ReadAllBytes(string path) { using var file = new HawkFile(path); return(file.Exists ? file.ReadAllBytes() : throw new FileNotFoundException(path)); }
// LSMV file format: http://tasvideos.org/Lsnes/Movieformat.html private static BkmMovie ImportLSMV(string path, out string errorMsg, out string warningMsg) { errorMsg = warningMsg = string.Empty; var m = new BkmMovie(path); var hf = new HawkFile(path); // .LSMV movies are .zip files containing data files. if (!hf.IsArchive) { errorMsg = "This is not an archive."; return null; } string platform = "SNES"; foreach (var item in hf.ArchiveItems) { if (item.Name == "authors") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string authors = Encoding.UTF8.GetString(stream.ReadAllBytes()); string author_list = ""; string author_last = ""; using (StringReader reader = new StringReader(authors)) { string line; // Each author is on a different line. while ((line = reader.ReadLine()) != null) { string author = line.Trim(); if (author != "") { if (author_last != "") { author_list += author_last + ", "; } author_last = author; } } } if (author_list != "") { author_list += "and "; } if (author_last != "") { author_list += author_last; } m.Header[HeaderKeys.AUTHOR] = author_list; hf.Unbind(); } else if (item.Name == "coreversion") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string coreversion = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Comments.Add(COREORIGIN + " " + coreversion); hf.Unbind(); } else if (item.Name == "gamename") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string gamename = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[HeaderKeys.GAMENAME] = gamename; hf.Unbind(); } else if (item.Name == "gametype") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string gametype = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); // TODO: Handle the other types. switch (gametype) { case "gdmg": platform = "GB"; break; case "ggbc": case "ggbca": platform = "GBC"; break; case "sgb_ntsc": case "sgb_pal": platform = "SNES"; Global.Config.GB_AsSGB = true; break; } bool pal = (gametype == "snes_pal" || gametype == "sgb_pal"); m.Header[HeaderKeys.PAL] = pal.ToString(); hf.Unbind(); } else if (item.Name == "input") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string input = Encoding.UTF8.GetString(stream.ReadAllBytes()); int lineNum = 0; using (StringReader reader = new StringReader(input)) { lineNum++; string line; while ((line = reader.ReadLine()) != null) { if (line == "") { continue; } m = ImportTextFrame(line, lineNum, m, path, platform, ref warningMsg); if (errorMsg != "") { hf.Unbind(); return null; } } } hf.Unbind(); } else if (item.Name.StartsWith("moviesram.")) { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); byte[] moviesram = stream.ReadAllBytes(); if (moviesram.Length != 0) { errorMsg = "Movies that begin with SRAM are not supported."; hf.Unbind(); return null; } hf.Unbind(); } else if (item.Name == "port1") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string port1 = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[PORT1] = port1; hf.Unbind(); } else if (item.Name == "port2") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string port2 = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[PORT2] = port2; hf.Unbind(); } else if (item.Name == "projectid") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string projectid = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[PROJECTID] = projectid; hf.Unbind(); } else if (item.Name == "rerecords") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string rerecords = Encoding.UTF8.GetString(stream.ReadAllBytes()); int rerecordCount; // Try to parse the re-record count as an integer, defaulting to 0 if it fails. try { rerecordCount = int.Parse(rerecords); } catch { rerecordCount = 0; } m.Rerecords = (ulong)rerecordCount; hf.Unbind(); } else if (item.Name.EndsWith(".sha256")) { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string rom = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); int pos = item.Name.LastIndexOf(".sha256"); string name = item.Name.Substring(0, pos); m.Header[SHA256 + "_" + name] = rom; hf.Unbind(); } else if (item.Name == "savestate") { errorMsg = "Movies that begin with a savestate are not supported."; return null; } else if (item.Name == "subtitles") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string subtitles = Encoding.UTF8.GetString(stream.ReadAllBytes()); using (StringReader reader = new StringReader(subtitles)) { string line; while ((line = reader.ReadLine()) != null) m = ImportTextSubtitle(line, m, path); } hf.Unbind(); } else if (item.Name == "starttime.second") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string startSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[STARTSECOND] = startSecond; hf.Unbind(); } else if (item.Name == "starttime.subsecond") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string startSubSecond = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Header[STARTSUBSECOND] = startSubSecond; hf.Unbind(); } else if (item.Name == "systemid") { hf.BindArchiveMember(item.Index); var stream = hf.GetStream(); string systemid = Encoding.UTF8.GetString(stream.ReadAllBytes()).Trim(); m.Comments.Add(EMULATIONORIGIN + " " + systemid); hf.Unbind(); } } m.Header[HeaderKeys.PLATFORM] = platform; LibsnesCore.SnesSyncSettings ss = new LibsnesCore.SnesSyncSettings(); ss.Profile = "Compatibility"; m.SyncSettingsJson = ConfigService.SaveWithType(ss); return m; }
public MainForm(string[] args) { GlobalWin.MainForm = this; Global.Rewinder = new Rewinder { MessageCallback = GlobalWin.OSD.AddMessage }; Global.ControllerInputCoalescer = new ControllerInputCoalescer(); Global.RAInterface = new RetroAchievementsInterface(); Global.FirmwareManager = new FirmwareManager(); Global.MovieSession = new MovieSession { Movie = MovieService.DefaultInstance, MovieControllerAdapter = MovieService.DefaultInstance.LogGeneratorInstance().MovieControllerAdapter, MessageCallback = GlobalWin.OSD.AddMessage, AskYesNoCallback = StateErrorAskUser, PauseCallback = PauseEmulator, ModeChangedCallback = SetMainformMovieInfo }; new AutoResetEvent(false); Icon = Properties.Resources.logo; InitializeComponent(); Global.Game = GameInfo.NullInstance; if (Global.Config.ShowLogWindow) { LogConsole.ShowConsole(); DisplayLogWindowMenuItem.Checked = true; } _throttle = new Throttle(); Global.CheatList = new CheatCollection(); Global.CheatList.Changed += ToolHelpers.UpdateCheatRelatedTools; UpdateStatusSlots(); UpdateKeyPriorityIcon(); // In order to allow late construction of this database, we hook up a delegate here to dearchive the data and provide it on demand // we could background thread this later instead if we wanted to be real clever NES.BootGodDB.GetDatabaseBytes = () => { using (var NesCartFile = new HawkFile(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "NesCarts.7z")).BindFirst()) { return NesCartFile .GetStream() .ReadAllBytes(); } }; Database.LoadDatabase(Path.Combine(PathManager.GetExeDirectoryAbsolute(), "gamedb", "gamedb.txt")); //TODO GL - a lot of disorganized wiring-up here GlobalWin.PresentationPanel = new PresentationPanel(); GlobalWin.DisplayManager = new DisplayManager(GlobalWin.PresentationPanel); Controls.Add(GlobalWin.PresentationPanel); Controls.SetChildIndex(GlobalWin.PresentationPanel, 0); //TODO GL - move these event handlers somewhere less obnoxious line in the On* overrides Load += (o, e) => { AllowDrop = true; DragEnter += FormDragEnter; DragDrop += FormDragDrop; }; Closing += (o, e) => { if (GlobalWin.Tools.AskSave()) { Global.CheatList.SaveOnClose(); CloseGame(); Global.MovieSession.Movie.Stop(); GlobalWin.Tools.Close(); SaveConfig(); } else { e.Cancel = true; } }; ResizeBegin += (o, e) => { if (GlobalWin.Sound != null) { GlobalWin.Sound.StopSound(); } }; ResizeEnd += (o, e) => { if (GlobalWin.PresentationPanel != null) { GlobalWin.PresentationPanel.Resized = true; } if (GlobalWin.Sound != null) { GlobalWin.Sound.StartSound(); } }; Input.Initialize(); InitControls(); Global.CoreComm = CreateCoreComm(); CoreFileProvider.SyncCoreCommInputSignals(); Global.Emulator = new NullEmulator(Global.CoreComm); Global.ActiveController = Global.NullControls; Global.AutoFireController = Global.AutofireNullControls; Global.AutofireStickyXORAdapter.SetOnOffPatternFromConfig(); #if WINDOWS GlobalWin.Sound = new Sound(Handle, GlobalWin.DSound); #else Global.Sound = new Sound(); #endif GlobalWin.Sound.StartSound(); InputManager.RewireInputChain(); GlobalWin.Tools = new ToolManager(); RewireSound(); // TODO - replace this with some kind of standard dictionary-yielding parser in a separate component string cmdRom = null; string cmdLoadState = null; string cmdMovie = null; string cmdDumpType = null; string cmdDumpName = null; if (Global.Config.MainWndx >= 0 && Global.Config.MainWndy >= 0 && Global.Config.SaveWindowPosition) { Location = new Point(Global.Config.MainWndx, Global.Config.MainWndy); } bool startFullscreen = false; for (int i = 0; i < args.Length; i++) { // For some reason sometimes visual studio will pass this to us on the commandline. it makes no sense. if (args[i] == ">") { i++; var stdout = args[i]; Console.SetOut(new StreamWriter(stdout)); continue; } var arg = args[i].ToLower(); if (arg.StartsWith("--load-slot=")) { cmdLoadState = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--movie=")) { cmdMovie = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--dump-type=")) { cmdDumpType = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--dump-name=")) { cmdDumpName = arg.Substring(arg.IndexOf('=') + 1); } else if (arg.StartsWith("--dump-length=")) { int.TryParse(arg.Substring(arg.IndexOf('=') + 1), out _autoDumpLength); } else if (arg.StartsWith("--dump-close")) { _autoCloseOnDump = true; } else if (arg.StartsWith("--fullscreen")) { startFullscreen = true; } else { cmdRom = arg; } } if (cmdRom != null) { // Commandline should always override auto-load LoadRom(cmdRom); if (Global.Game == null) { MessageBox.Show("Failed to load " + cmdRom + " specified on commandline"); } } else if (Global.Config.RecentRoms.AutoLoad && !Global.Config.RecentRoms.Empty) { LoadRomFromRecent(Global.Config.RecentRoms.MostRecent); } if (cmdMovie != null) { if (Global.Game == null) { OpenRom(); } else { var movie = MovieService.Get(cmdMovie); Global.MovieSession.ReadOnly = true; // if user is dumping and didnt supply dump length, make it as long as the loaded movie if (_autoDumpLength == 0) { _autoDumpLength = movie.InputLogLength; } StartNewMovie(movie, false); Global.Config.RecentMovies.Add(cmdMovie); } } else if (Global.Config.RecentMovies.AutoLoad && !Global.Config.RecentMovies.Empty) { if (Global.Game == null) { OpenRom(); } else { StartNewMovie(MovieService.Get(Global.Config.RecentMovies.MostRecent), false); } } if (startFullscreen || Global.Config.StartFullscreen) { ToggleFullscreen(); } if (cmdLoadState != null && !Global.Game.IsNullInstance) { LoadQuickSave("QuickSave" + cmdLoadState); } else if (Global.Config.AutoLoadLastSaveSlot && !Global.Game.IsNullInstance) { LoadQuickSave("QuickSave" + Global.Config.SaveSlot); } if (Global.Config.RecentWatches.AutoLoad) { GlobalWin.Tools.LoadRamWatch(!Global.Config.DisplayRamWatch); } if (Global.Config.RecentSearches.AutoLoad) { GlobalWin.Tools.Load<RamSearch>(); } if (Global.Config.AutoLoadHexEditor) { GlobalWin.Tools.Load<HexEditor>(); } if (Global.Config.RecentCheats.AutoLoad) { GlobalWin.Tools.Load<Cheats>(); } if (Global.Config.AutoLoadNESPPU && Global.Emulator is NES) { GlobalWin.Tools.Load<NesPPU>(); } if (Global.Config.AutoLoadNESNameTable && Global.Emulator is NES) { GlobalWin.Tools.Load<NESNameTableViewer>(); } if (Global.Config.AutoLoadNESDebugger && Global.Emulator is NES) { GlobalWin.Tools.Load<NESDebugger>(); } if (Global.Config.NESGGAutoload && Global.Emulator.SystemId == "NES") { GlobalWin.Tools.LoadGameGenieEc(); } if (Global.Config.AutoLoadGBGPUView && Global.Emulator is Gameboy) { GlobalWin.Tools.Load<GBGPUView>(); } if (Global.Config.AutoloadTAStudio) { GlobalWin.Tools.Load<TAStudio>(); } if (Global.Config.AutoloadExperimentalTAStudio) { GlobalWin.Tools.Load<TasStudioExperiment>(); } if (Global.Config.AutoloadVirtualPad) { GlobalWin.Tools.Load<VirtualpadTool>(); } if (Global.Config.AutoLoadLuaConsole) { OpenLuaConsole(); } if (Global.Config.SmsVdpAutoLoad && Global.Emulator is SMS) { GlobalWin.Tools.Load<SmsVDPViewer>(); } if (Global.Config.PCEBGViewerAutoload && Global.Emulator is PCEngine) { GlobalWin.Tools.Load<PceBgViewer>(); } if (Global.Config.PceVdpAutoLoad && Global.Emulator is PCEngine) { GlobalWin.Tools.Load<PCETileViewer>(); } if (Global.Config.RecentPceCdlFiles.AutoLoad && Global.Emulator is PCEngine) { GlobalWin.Tools.Load<PCECDL>(); } if (Global.Config.PceSoundDebuggerAutoload && Global.Emulator is PCEngine) { GlobalWin.Tools.Load<PCESoundDebugger>(); } if (Global.Config.GenVdpAutoLoad && Global.Emulator is GPGX) { GlobalWin.Tools.Load<GenVDPViewer>(); } if (Global.Config.AutoLoadSNESGraphicsDebugger && Global.Emulator is LibsnesCore) { GlobalWin.Tools.Load<SNESGraphicsDebugger>(); } if (Global.Config.TraceLoggerAutoLoad) { GlobalWin.Tools.LoadTraceLogger(); } if (Global.Config.Atari2600DebuggerAutoload && Global.Emulator is Atari2600) { GlobalWin.Tools.Load<Atari2600Debugger>(); } if (Global.Config.DisplayStatusBar == false) { MainStatusBar.Visible = false; } else { DisplayStatusBarMenuItem.Checked = true; } if (Global.Config.StartPaused) { PauseEmulator(); } // start dumping, if appropriate if (cmdDumpType != null && cmdDumpName != null) { RecordAv(cmdDumpType, cmdDumpName); } UpdateStatusSlots(); SetMainformMovieInfo(); //TODO POOP GlobalWin.PresentationPanel.Control.Paint += (o, e) => { GlobalWin.DisplayManager.NeedsToPaint = true; }; // RA: // Test: RACore.Init(); RAWebInterface.PerformBackgroundLogin("qwe", "qwe"); RACore.EventService.RegisterHandler(RAEventType.Login, RAOnLogin); }