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()); } } } }
/// <exception cref="Exception"><paramref name="file"/> does not exist</exception> public RomGame(HawkFile file, string patch) { if (!file.Exists) { throw new Exception("The file needs to exist, yo."); } Extension = file.Extension.ToUpperInvariant(); 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 that's 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, 128, 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.Position = 0; 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 (file.Extension == ".dsk" || file.Extension == ".tap" || file.Extension == ".tzx" || file.Extension == ".pzx" || file.Extension == ".csw" || file.Extension == ".wav" || file.Extension == ".cdt") { // these are not roms. unfortunately if treated as such there are certain edge-cases // where a header offset is detected. This should mitigate this issue until a cleaner solution is found // (-Asnivor) 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 isn't 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); if (GameInfo.NotInDatabase && headerOffset == 128 && file.Extension == ".a78") { // if the game is not in the DB, add the header back in so the core can use it // for now only .A78 games, but probably should be for other systems as well RomData = FileData; } CheckForPatchOptions(); if (patch != null) { using var patchFile = new HawkFile(patch); patchFile.BindFirstOf(".ips"); if (patchFile.IsBound) { RomData = IPS.Patch(RomData, patchFile.GetStream()); } } }
private void Download() { //the temp file is owned by this thread var fn = TempFileManager.GetTempFilename("ffmpeg_download", ".7z", false); try { using (var evt = new ManualResetEvent(false)) { using (var client = new System.Net.WebClient()) { System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; client.DownloadFileAsync(new Uri(FFmpegService.Url), fn); client.DownloadProgressChanged += (object sender, System.Net.DownloadProgressChangedEventArgs e) => { pct = e.ProgressPercentage; }; client.DownloadFileCompleted += (object sender, System.ComponentModel.AsyncCompletedEventArgs e) => { //we don't really need a status. we'll just try to unzip it when it's done evt.Set(); }; for (; ;) { if (evt.WaitOne(10)) { break; } //if the gui thread ordered an exit, cancel the download and wait for it to acknowledge if (exiting) { client.CancelAsync(); evt.WaitOne(); break; } } } } //throw new Exception("test of download failure"); //if we were ordered to exit, bail without wasting any more time if (exiting) { return; } //try acquiring file using (var hf = new HawkFile(fn)) { using (var exe = hf.BindFirstOf(".exe")) { var data = exe.ReadAllBytes(); //last chance. exiting, don't dump the new ffmpeg file if (exiting) { return; } File.WriteAllBytes(FFmpegService.FFmpegPath, data); } } //make sure it worked if (!new FFmpegService().QueryServiceAvailable()) { throw new Exception("download failed"); } succeeded = true; } catch { failed = true; } finally { try { File.Delete(fn); } catch { } } }
private void Download() { //the temp file is owned by this thread var fn = TempFileManager.GetTempFilename("ffmpeg_download", ".7z", false); try { using (var evt = new ManualResetEvent(false)) { using (var client = new System.Net.WebClient()) { System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls12; client.DownloadFileAsync(new Uri(FFmpegService.Url), fn); client.DownloadProgressChanged += (object sender, System.Net.DownloadProgressChangedEventArgs e) => { pct = e.ProgressPercentage; }; client.DownloadFileCompleted += (object sender, System.ComponentModel.AsyncCompletedEventArgs e) => { //we don't really need a status. we'll just try to unzip it when it's done evt.Set(); }; for (; ;) { if (evt.WaitOne(10)) { break; } //if the gui thread ordered an exit, cancel the download and wait for it to acknowledge if (exiting) { client.CancelAsync(); evt.WaitOne(); break; } } } } //throw new Exception("test of download failure"); //if we were ordered to exit, bail without wasting any more time if (exiting) { return; } //try acquiring file using (var hf = new HawkFile(fn)) { using (var exe = OSTailoredCode.IsUnixHost ? hf.BindArchiveMember("ffmpeg") : hf.BindFirstOf(".exe")) { var data = exe !.ReadAllBytes(); //last chance. exiting, don't dump the new ffmpeg file if (exiting) { return; } DirectoryInfo parentDir = new(Path.GetDirectoryName(FFmpegService.FFmpegPath) !); if (!parentDir.Exists) { parentDir.Create(); } File.WriteAllBytes(FFmpegService.FFmpegPath, data); if (OSTailoredCode.IsUnixHost) { OSTailoredCode.ConstructSubshell("chmod", $"+x {FFmpegService.FFmpegPath}", checkStdout: false).Start(); Thread.Sleep(50); // Linux I/O flush idk } } } //make sure it worked if (!FFmpegService.QueryServiceAvailable()) { throw new Exception("download failed"); } succeeded = true; } catch { failed = true; } finally { try { File.Delete(fn); } catch { } } }