//Generates or applies a blast layer using one of the multiple BlastRadius algorithms public static BlastLayer Blast(BlastLayer _layer, string[] _selectedDomains) { string Domain = null; long MaxAddress = -1; long RandomAddress = -1; BlastUnit bu; BlastLayer bl; try { if (_layer != null) { _layer.Apply(); //If the BlastLayer was provided, there's no need to generate a new one. return(_layer); } else if (RTC_Core.SelectedEngine == CorruptionEngine.EXTERNALROM) { //External ROM Plugin: Bypasses domains and uses an alternative algorithm to fetch corruption. //It will query a BlastLayer generated from a differential between an original and corrupted rom. bl = RTC_ExternalRomPlugin.GetBlastLayer(); if (bl == null) { return(null); } else { return(bl); } } else { bl = new BlastLayer(); if (_selectedDomains == null || _selectedDomains.Count() == 0) { return(null); } // Age distortion BlastBytes if (RTC_Core.SelectedEngine == CorruptionEngine.DISTORTION && RTC_DistortionEngine.CurrentAge < RTC_DistortionEngine.MaxAge) { RTC_DistortionEngine.CurrentAge++; } //Run Pipes on Corrupt Step if required if (RTC_Core.SelectedEngine == CorruptionEngine.PIPE && !RTC_PipeEngine.ProcessOnStep) { RTC_PipeEngine.ExecutePipes(); } // Capping intensity at engine-specific maximums int _Intensity = Intensity; //general RTC intensity if ((RTC_Core.SelectedEngine == CorruptionEngine.HELLGENIE || RTC_Core.SelectedEngine == CorruptionEngine.FREEZE) && _Intensity > RTC_HellgenieEngine.MaxCheats) { _Intensity = RTC_HellgenieEngine.MaxCheats; //Capping for cheat max } if (RTC_Core.SelectedEngine == CorruptionEngine.PIPE && _Intensity > RTC_PipeEngine.MaxPipes) { _Intensity = RTC_PipeEngine.MaxPipes; //Capping for pipe max } switch (Radius) //Algorithm branching { case BlastRadius.SPREAD: //Randomly spreads all corruption bytes to all selected domains for (int i = 0; i < _Intensity; i++) { Domain = _selectedDomains[RND.Next(_selectedDomains.Length)]; MaxAddress = RTC_MemoryDomains.getInterface(Domain).Size; RandomAddress = RTC_Core.RND.RandomLong(MaxAddress - 1); bu = getBlastUnit(Domain, RandomAddress); if (bu != null) { bl.Layer.Add(bu); } } break; case BlastRadius.CHUNK: //Randomly spreads the corruption bytes in one randomly selected domain Domain = _selectedDomains[RND.Next(_selectedDomains.Length)]; MaxAddress = RTC_MemoryDomains.getInterface(Domain).Size; for (int i = 0; i < _Intensity; i++) { RandomAddress = RTC_Core.RND.RandomLong(MaxAddress - 1); bu = getBlastUnit(Domain, RandomAddress); if (bu != null) { bl.Layer.Add(bu); } } break; case BlastRadius.BURST: // 10 shots of 10% chunk for (int j = 0; j < 10; j++) { Domain = _selectedDomains[RND.Next(_selectedDomains.Length)]; MaxAddress = RTC_MemoryDomains.getInterface(Domain).Size; for (int i = 0; i < (int)((double)_Intensity / 10); i++) { RandomAddress = RTC_Core.RND.RandomLong(MaxAddress - 1); bu = getBlastUnit(Domain, RandomAddress); if (bu != null) { bl.Layer.Add(bu); } } } break; case BlastRadius.NORMALIZED: // Blasts based on the size of the largest selected domain. Intensity = Intensity / (domainSize[largestdomain]/domainSize[currentdomain]) //Find the smallest domain and base our normalization around it //Domains aren't IComparable so I used keys long[] domainSize = new long [_selectedDomains.Length]; for (int i = 0; i < _selectedDomains.Length; i++) { Domain = _selectedDomains[i]; domainSize[i] = RTC_MemoryDomains.getInterface(Domain).Size; } //Sort the arrays Array.Sort(domainSize, _selectedDomains); for (int i = 0; i < _selectedDomains.Length; i++) { Domain = _selectedDomains[i]; //Get the intensity divider. The size of the largest domain divided by the size of the current domain long normalized = ((domainSize[_selectedDomains.Length - 1] / (domainSize[i]))); for (int j = 0; j < (_Intensity / normalized); j++) { MaxAddress = RTC_MemoryDomains.getInterface(Domain).Size; RandomAddress = RTC_Core.RND.RandomLong(MaxAddress - 1); bu = getBlastUnit(Domain, RandomAddress); if (bu != null) { bl.Layer.Add(bu); } } } break; case BlastRadius.PROPORTIONAL: //Blasts proportionally based on the total size of all selected domains long totalSize = _selectedDomains.Select(it => RTC_MemoryDomains.getInterface(it).Size).Sum(); //Gets the total size of all selected domains long[] normalizedIntensity = new long[_selectedDomains.Length]; //matches the index of selectedDomains for (int i = 0; i < _selectedDomains.Length; i++) { //calculates the proportionnal normalized Intensity based on total selected domains size double proportion = (double)RTC_MemoryDomains.getInterface(_selectedDomains[i]).Size / (double)totalSize; normalizedIntensity[i] = Convert.ToInt64((double)_Intensity * proportion); } for (int i = 0; i < _selectedDomains.Length; i++) { Domain = _selectedDomains[i]; for (int j = 0; j < normalizedIntensity[i]; j++) { MaxAddress = RTC_MemoryDomains.getInterface(Domain).Size; RandomAddress = RTC_Core.RND.RandomLong(MaxAddress - 1); bu = getBlastUnit(Domain, RandomAddress); if (bu != null) { bl.Layer.Add(bu); } } } break; case BlastRadius.EVEN: //Evenly distributes the blasts through all selected domains for (int i = 0; i < _selectedDomains.Length; i++) { Domain = _selectedDomains[i]; for (int j = 0; j < (_Intensity / _selectedDomains.Length); j++) { MaxAddress = RTC_MemoryDomains.getInterface(Domain).Size; RandomAddress = RTC_Core.RND.RandomLong(MaxAddress - 1); bu = getBlastUnit(Domain, RandomAddress); if (bu != null) { bl.Layer.Add(bu); } } } break; case BlastRadius.NONE: //Shouldn't ever happen but handled anyway return(null); } if (bl.Layer.Count == 0) { return(null); } else { return(bl); } } } catch (Exception ex) { DialogResult dr = MessageBox.Show("Something went wrong in the RTC Core. \n" + "This is not a BizHawk error so you should probably send a screenshot of this to the devs\n\n" + "If you know the steps to reproduce this error it would be greatly appreaciated.\n\n" + (RTC_Core.coreForm.AutoCorrupt ? ">> STOP AUTOCORRUPT ?.\n\n" : "") + $"domain:{Domain.ToString()} maxaddress:{MaxAddress.ToString()} randomaddress:{RandomAddress.ToString()} \n\n" + ex.ToString(), "Error", (RTC_Core.coreForm.AutoCorrupt ? MessageBoxButtons.YesNo : MessageBoxButtons.OK)); if (dr == DialogResult.Yes || dr == DialogResult.OK) { RTC_Core.coreForm.AutoCorrupt = false; } return(null); } }
private void btnExternalOpenWindow_Click(object sender, EventArgs e) { RTC_ExternalRomPlugin.OpenWindow(); }
//Generates or queries a blast layer then applies it. public static BlastLayer Blast(BlastLayer _layer) { try { if (_layer != null) { _layer.Apply(); //If the BlastLayer was provided, there's no need to generate a new one. return(_layer); } else if (RTC_Core.SelectedEngine == CorruptionEngine.EXTERNALROM) { BlastLayer romLayer = RTC_ExternalRomPlugin.GetLayer(); if (romLayer == null) { return(null); } else { romLayer.Apply(); return(romLayer); } } else { BlastLayer bl = new BlastLayer(); if (RTC_Core.SelectedEngine != CorruptionEngine.FREEZE && RTC_MemoryZones.SelectedDomains.Count == 0) { return(null); } string Domain; long MaxAdress; long RandomAdress = 0; BlastUnit bu; if (RTC_Core.SelectedEngine == CorruptionEngine.DISTORTION && RTC_DistortionEngine.CurrentAge < RTC_DistortionEngine.MaxAge) { RTC_DistortionEngine.CurrentAge++; } switch (Radius) { case BlastRadius.SPREAD: for (int i = 0; i < Intensity; i++) //Randomly spreads all corruption bytes to all selected zones { if (RTC_Core.SelectedEngine != CorruptionEngine.FREEZE) { Domain = RTC_MemoryZones.SelectedDomains[RND.Next(RTC_MemoryZones.SelectedDomains.Count)]; } else { Domain = RTC_Core.hexeditor._domain.ToString(); } MaxAdress = RTC_MemoryZones.getDomain(Domain).Size; RandomAdress = LongRandom(MaxAdress); bu = getBlastUnit(Domain, RandomAdress); if (bu != null) { bl.Layer.Add(bu); } } break; case BlastRadius.CHUNK: //Randomly spreads the corruption bytes in one randomly selected zone if (RTC_Core.SelectedEngine != CorruptionEngine.FREEZE) { Domain = RTC_MemoryZones.SelectedDomains[RND.Next(RTC_MemoryZones.SelectedDomains.Count)]; } else { Domain = RTC_Core.hexeditor._domain.ToString(); } MaxAdress = RTC_MemoryZones.getDomain(Domain).Size; for (int i = 0; i < Intensity; i++) { RandomAdress = LongRandom(MaxAdress); bu = getBlastUnit(Domain, RandomAdress); if (bu != null) { bl.Layer.Add(bu); } } break; case BlastRadius.BURST: for (int j = 0; j < 10; j++) // 10 shots of 10% chunk { if (RTC_Core.SelectedEngine != CorruptionEngine.FREEZE) { Domain = RTC_MemoryZones.SelectedDomains[RND.Next(RTC_MemoryZones.SelectedDomains.Count)]; } else { Domain = RTC_Core.hexeditor._domain.ToString(); } MaxAdress = RTC_MemoryZones.getDomain(Domain).Size; for (int i = 0; i < (int)((double)Intensity / 10); i++) { RandomAdress = LongRandom(MaxAdress); bu = getBlastUnit(Domain, RandomAdress); if (bu != null) { bl.Layer.Add(bu); } } } break; case BlastRadius.NONE: return(null); } bl.Apply(); RTC_HellgenieEngine.RemoveExcessCheats(); if (bl.Layer.Count == 0) { return(null); } else { return(bl); } } } catch (Exception ex) { MessageBox.Show("Something went wrong in the RTC Core. \n" + "This is not a BizHawk error so you should probably send a screenshot of this to the devs\n\n" + ex.ToString()); return(null); } }
private void cbExternalSelectedPlugin_SelectedIndexChanged(object sender, EventArgs e) { RTC_ExternalRomPlugin.SelectedPlugin = (sender as ComboBox).SelectedItem.ToString(); RTC_ExternalRomPlugin.KillLastPlugin(); }
public static StashKey getRawBlastlayer() { RTC_Core.StopSound(); StashKey sk = RTC_StockpileManager.SaveState_NET(false); BlastLayer bl = new BlastLayer(); foreach (var item in Global.CheatList) { string[] disassembleCheat = item.Name.Split('|'); if (disassembleCheat[0] == "RTC Cheat") { string _domain = disassembleCheat[1]; long _address = Convert.ToInt64(disassembleCheat[2]); BizHawk.Client.Common.DisplayType _displayType = BizHawk.Client.Common.DisplayType.Unsigned; bool _bigEndian = Convert.ToBoolean(disassembleCheat[4]); byte[] _value = disassembleCheat[5].Split(',').Select(it => Convert.ToByte(it)).ToArray(); bool _isEnabled = Convert.ToBoolean(disassembleCheat[6]); bool _isFreeze = Convert.ToBoolean(disassembleCheat[7]); bl.Layer.Add(new BlastCheat(_domain, _address, _displayType, _bigEndian, _value, _isEnabled, _isFreeze)); } } bl.Layer.AddRange(RTC_PipeEngine.AllBlastPipes); string thisSystem = Global.Game.System; string romFilename = GlobalWin.MainForm.CurrentlyOpenRom; var rp = RTC_MemoryDomains.GetRomParts(thisSystem, romFilename); if (rp.error == null) { if (rp.primarydomain != null) { List <byte> addData = new List <byte>(); if (rp.skipbytes != 0) { byte[] padding = new byte[rp.skipbytes]; for (int i = 0; i < rp.skipbytes; i++) { padding[i] = 0; } addData.AddRange(padding); } addData.AddRange(RTC_MemoryDomains.getDomainData(rp.primarydomain)); if (rp.seconddomain != null) { addData.AddRange(RTC_MemoryDomains.getDomainData(rp.seconddomain)); } byte[] corrupted = addData.ToArray(); byte[] original = File.ReadAllBytes(GlobalWin.MainForm.CurrentlyOpenRom); if (RTC_MemoryDomains.MemoryInterfaces.ContainsKey("32X FB")) //Flip 16-bit words on 32X rom { original = original.FlipWords(2); } else if (thisSystem.ToUpper() == "N64") { original = BizHawk.Client.Common.RomGame.MutateSwapN64(original); } else if (GlobalWin.MainForm.CurrentlyOpenRom.ToUpper().Contains(".SMD")) { original = BizHawk.Client.Common.RomGame.DeInterleaveSMD(original); } for (int i = 0; i < rp.skipbytes; i++) { original[i] = 0; } BlastLayer romBlast = RTC_ExternalRomPlugin.GetBlastLayer(original, corrupted); if (romBlast != null && romBlast.Layer.Count > 0) { bl.Layer.AddRange(romBlast.Layer); } } } sk.BlastLayer = bl; RTC_Core.StartSound(); return(sk); }