private void variableSpinner_ValueChanged(object sender, EventArgs e) { AsmPatch patch = (clb_Patches.SelectedItem as AsmPatch); if (!ignoreChanges) { UInt32 newValue = (UInt32)variableSpinner.Value; VariableType variable = patch.VariableMap[(string)variableComboBox.SelectedItem]; UpdateVariable(variable, newValue); /* * if (variable.PresetValues.Count > 0) * { * VariableType.VariablePreset preset = FindSelectedPreset(variable); * if (preset == null) * { * cmb_Variable_Preset.SelectedIndex = -1; * } * else * { * cmb_Variable_Preset.SelectedIndex = variablePresetIndexMap[preset]; * } * } */ } }
private void clb_Patches_ItemCheck(object sender, ItemCheckEventArgs e) { if ((skipCheckEventHandler) || (lsb_FilesList.SelectedItem == null)) { return; } int selectedIndex = lsb_FilesList.SelectedIndex; AsmPatch asmPatch = clb_Patches.Items[e.Index] as AsmPatch; if ((e.CurrentValue == CheckState.Unchecked) && (e.NewValue == CheckState.Checked) && (!asmPatch.ValidatePatch())) { e.NewValue = CheckState.Unchecked; } if (e.NewValue == CheckState.Checked) { patchData.SelectedPatches.Add(asmPatch); } else if (e.NewValue == CheckState.Unchecked) { if (patchData.SelectedPatches.Contains(asmPatch)) { patchData.SelectedPatches.Remove(asmPatch); } } patchData.CurrentSelectedPatches = GetCurrentFileSelectedPatches(); bool enablePatchButtons = (patchData.CurrentSelectedPatches.Count > 0); btnPatch.Enabled = enablePatchButtons; btnPatchSaveState.Enabled = enablePatchButtons; }
private void UpdateReferenceVariableValue(VariableType variable) { if (variable.isReference) { byte[] referenceBytes = VariableMap[variable.reference.name].byteArray; uint value = AsmPatch.GetUnsignedByteArrayValue_LittleEndian(referenceBytes); switch (variable.reference.operatorSymbol) { case "+": value += variable.reference.operand; break; case "-": value -= variable.reference.operand; break; case "*": value *= variable.reference.operand; break; case "/": value /= variable.reference.operand; break; } UpdateVariable(variable, value); } }
private void btnMove_Click(object sender, EventArgs e) { long newOffset = 0U; if (long.TryParse(txtAddress.Text, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.InvariantCulture, out newOffset)) { DataGridViewSelectedRowCollection selectedRows = dgv_FreeSpace.SelectedRows; if (selectedRows.Count > 0) { DataGridViewRow row = selectedRows[0]; long offset = (long)(row.Cells[1].Value); if (offset != newOffset) { PatchedByteArray patchedByteArray = rowPatchMap[row]; AsmPatch asmPatch = freeSpaceMaps.InnerPatchMap[patchedByteArray]; long moveOffset = newOffset - offset; MovePatchRange movePatchRange = new MovePatchRange(new PatchRange(patchedByteArray), moveOffset); asmPatch.MoveBlock(asmUtility, movePatchRange); asmPatch.Update(asmUtility); txtAddress.BackColor = Color.White; Reload(); } } } else { txtAddress.BackColor = Color.FromArgb(225, 125, 125); } }
public AsmPatch Copy() { AsmPatch result = new AsmPatch(Name, Filename, Description, CopyableEntry.CopyList <PatchedByteArray>(innerList), HideInDefault, IsHidden, CopyableEntry.CopyArray <VariableType>(Variables)); result.ErrorText = ErrorText; return(result); }
void clb_Patches_SelectedIndexChanged(object sender, EventArgs e) { AsmPatch p = clb_Patches.SelectedItem as AsmPatch; if (p != null) { textBox1.Text = p.Description; int index = clb_Patches.SelectedIndex; txt_Messages.Text = (index >= 0) ? patchMessages[index] : ""; if (p.Variables.Count > 0) { ignoreChanges = true; variableComboBox.Items.Clear(); p.Variables.ForEach(varType => variableComboBox.Items.Add(varType.content.Key)); variableComboBox.SelectedIndex = 0; //variableSpinner.Value = p.Variables[0].content.Value.GetBytes()[0]; Byte[] byteArray = p.Variables[0].content.Value.GetBytes(); variableSpinner.Maximum = (decimal)Math.Pow(256, p.Variables[0].bytes) - 1; variableSpinner.Value = p.GetUnsignedByteArrayValue_LittleEndian(byteArray); variableSpinner.Visible = true; ignoreChanges = false; variableComboBox.Visible = true; } else { variableSpinner.Visible = false; ignoreChanges = true; variableComboBox.Visible = false; } } }
public PatchRangeConflict(PatchRange range, AsmPatch conflictPatch, PatchRange conflictRange, bool isInFreeSpace) { this.Range = range; this.ConflictPatch = conflictPatch; this.ConflictRange = conflictRange; this.IsInFreeSpace = isInFreeSpace; }
private void ShowConflicts(AsmPatch patch) { List <PatchRangeConflict> conflictList = conflictPatchData.ConflictMap[patch]; foreach (PatchRangeConflict conflict in conflictList) { //PsxIso.Sectors sector = (PsxIso.Sectors)(conflict.ConflictRange.Sector); //string strSector = Enum.GetName(typeof(PsxIso.Sectors), sector); //string strSector = PatcherLib.Iso.PsxIso.GetSectorName(sector); /* * Type sectorType = (mode == FreeSpaceMode.PSP) ? typeof(PspIso.Sectors) : typeof(PsxIso.Sectors); * Enum sector = (Enum)Enum.ToObject(sectorType, conflict.ConflictRange.Sector); * string strSector = (mode == FreeSpaceMode.PSP) ? PspIso.GetSectorName((PspIso.Sectors)sector) : PsxIso.GetSectorName((PsxIso.Sectors)sector); */ string strSector = ISOHelper.GetSectorName(conflict.ConflictRange.Sector, FreeSpace.GetContext(mode)); // Patch #, Sector, Location, Conflict Location ListViewItem item = new ListViewItem(); item.Text = conflict.ConflictPatchNumber.ToString(); item.SubItems.Add(strSector); item.SubItems.Add(conflict.Range.StartOffset.ToString("X")); item.SubItems.Add(conflict.ConflictRange.StartOffset.ToString("X")); item.BackColor = conflict.IsInFreeSpace ? backColor_Conflict_FreeSpace : backColor_Conflict_NonFreeSpace; lv_Conflicts.Items.Add(item); } }
private void variableSpinner_ValueChanged(object sender, EventArgs e) { AsmPatch patch = (clb_Patches.SelectedItem as AsmPatch); if (!ignoreChanges) { UInt32 newValue = (UInt32)variableSpinner.Value; VariableType variable = patch.VariableMap[(string)variableComboBox.SelectedItem]; UpdateVariable(variable, newValue); } }
private void LoadItems(int freeSpacePositionIndex) { lbl_NumberOfPatches.Text = "0"; lbl_NumberOfWrites.Text = "0"; if (freeSpacePositionIndex < 0) { return; } dgv_FreeSpace.Rows.Clear(); txtAddress.Clear(); rowPatchMap = new Dictionary <DataGridViewRow, PatchedByteArray>(); PatchRange range = FreeSpace.GetRanges(mode)[freeSpacePositionIndex]; if (!freeSpaceMaps.PatchRangeMap.ContainsKey(range)) { return; } //long positionEndOffset = position.StartLocation + position.Length - 1; List <PatchedByteArray> patchedByteArrayList = freeSpaceMaps.PatchRangeMap[range]; HashSet <AsmPatch> asmPatchSet = freeSpaceMaps.OuterPatchRangeMap[range]; for (int index = 0; index < patchedByteArrayList.Count; index++) { PatchedByteArray patchedByteArray = patchedByteArrayList[index]; AsmPatch asmPatch = freeSpaceMaps.InnerPatchMap[patchedByteArray]; // Column order: Number, Address, Length, Next Address, Space to Next Patch, File, Name int length = patchedByteArray.GetBytes().Length; long nextAddress = patchedByteArray.Offset + length; long nextPatchLocation = (index < (patchedByteArrayList.Count - 1)) ? patchedByteArrayList[index + 1].Offset : range.EndOffset; long spaceToNextPatch = nextPatchLocation - nextAddress; bool isSpaceToNextPatchNegative = (spaceToNextPatch < 0); //string strSpaceToNextPatch = isSpaceToNextPatchNegative ? ("-" + (-spaceToNextPatch).ToString("X")) : spaceToNextPatch.ToString("X"); //dgv_FreeSpace.Rows.Add(index, patchedByteArray.Offset.ToString("X"), length.ToString("X"), nextAddress.ToString("X"), strSpaceToNextPatch, asmPatch.Filename, asmPatch.Name); dgv_FreeSpace.Rows.Add(index, patchedByteArray.Offset, length, nextAddress, spaceToNextPatch, asmPatch.Filename, asmPatch.Name); if (isSpaceToNextPatchNegative) { dgv_FreeSpace.Rows[index].Cells[4].Style.BackColor = Color.FromArgb(225, 125, 125); } rowPatchMap.Add(dgv_FreeSpace.Rows[index], patchedByteArray); } lbl_NumberOfPatches.Text = asmPatchSet.Count.ToString(); lbl_NumberOfWrites.Text = patchedByteArrayList.Count.ToString(); }
void variableSpinner_ValueChanged(object sender, EventArgs e) { AsmPatch patch = (clb_Patches.SelectedItem as AsmPatch); if (!ignoreChanges) { UInt32 def = (UInt32)variableSpinner.Value; for (int i = 0; i < patch.Variables[variableComboBox.SelectedIndex].bytes; i++) { patch.Variables[variableComboBox.SelectedIndex].content.Value.GetBytes()[i] = (Byte)((def >> (i * 8)) & 0xff); } } }
private void clb_Patches_SelectedIndexChanged(object sender, EventArgs e) { AsmPatch p = clb_Patches.SelectedItem as AsmPatch; if (p != null) { textBox1.Text = p.Description; int index = clb_Patches.SelectedIndex; txt_Messages.Text = p.ErrorText; //if (p.Variables.Count > 0) if (p.CountNonReferenceVariables() > 0) { ignoreChanges = true; variableComboBox.Items.Clear(); bool foundFirst = false; VariableType firstNonReferenceVariable = p.Variables[0]; foreach (VariableType variable in p.Variables) { if (!variable.isReference) { variableComboBox.Items.Add(variable.name); if (!foundFirst) { firstNonReferenceVariable = variable; foundFirst = true; } } } variableComboBox.SelectedIndex = 0; byte[] byteArray = firstNonReferenceVariable.byteArray; variableSpinner.Maximum = (decimal)Math.Pow(256, firstNonReferenceVariable.numBytes) - 1; variableSpinner.Value = AsmPatch.GetUnsignedByteArrayValue_LittleEndian(byteArray); variableSpinner.Visible = true; ignoreChanges = false; variableComboBox.Visible = true; } else { variableSpinner.Visible = false; ignoreChanges = true; variableComboBox.Visible = false; } } }
private void cmb_Variable_Preset_SelectedIndexChanged(object sender, EventArgs e) { if (!ignoreChanges) { AsmPatch patch = (clb_Patches.SelectedItem as AsmPatch); VariableType selectedVariable = patch.VariableMap[(string)variableComboBox.SelectedItem]; VariableType.VariablePreset preset = (VariableType.VariablePreset)cmb_Variable_Preset.SelectedItem; variableSpinner.Visible = preset.IsModifiable; if (!preset.IsModifiable) { variableSpinner.Value = preset.Value; } } }
void variableComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (!ignoreChanges) { AsmPatch patch = (clb_Patches.SelectedItem as AsmPatch); Byte[] byteArray = patch.Variables[variableComboBox.SelectedIndex].content.Value.GetBytes(); // Setting Maximum can trigger the variableSpinner_ValueChanged event, but we don't want to change the variable value here, so set ignoreChanges = true before setting Maximum. ignoreChanges = true; variableSpinner.Maximum = (decimal)Math.Pow(256, patch.Variables[variableComboBox.SelectedIndex].bytes) - 1; ignoreChanges = false; variableSpinner.Value = patch.GetUnsignedByteArrayValue_LittleEndian(byteArray); } }
private void variableComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (!ignoreChanges) { AsmPatch patch = (clb_Patches.SelectedItem as AsmPatch); VariableType selectedVariable = patch.VariableMap[(string)variableComboBox.SelectedItem]; byte[] byteArray = selectedVariable.byteArray; // Setting Maximum can trigger the variableSpinner_ValueChanged event, but we don't want to change the variable value here, so set ignoreChanges = true before setting Maximum. ignoreChanges = true; variableSpinner.Maximum = (decimal)Math.Pow(256, selectedVariable.numBytes) - 1; ignoreChanges = false; variableSpinner.Value = AsmPatch.GetUnsignedByteArrayValue_LittleEndian(byteArray); } }
private void ShowPatches(ConflictCheckResult conflictPatchData) { lv_Patches.Items.Clear(); for (int patchIndex = 0; patchIndex < conflictPatchData.PatchList.Count; patchIndex++) { AsmPatch patch = conflictPatchData.PatchList[patchIndex]; int leastConflictPatchIndex = GetLeastConflictPatchIndex(patchIndex, conflictPatchData.ConflictMap[patch]); // Patch #, File, Name ListViewItem listViewItem = new ListViewItem(); listViewItem.Text = patchIndex.ToString(); listViewItem.SubItems.Add(patch.Filename); listViewItem.SubItems.Add(patch.Name); listViewItem.BackColor = patchColors[leastConflictPatchIndex]; lv_Patches.Items.Add(listViewItem); } lv_Patches_columnHeader_Name.AutoResize(System.Windows.Forms.ColumnHeaderAutoResizeStyle.ColumnContent); }
public void Update(ASMEncoding.ASMEncodingUtility asmUtility) { UpdateReferenceVariableValues(); List <PatchedByteArray> allPatches = GetAllPatches(); foreach (PatchedByteArray patchedByteArray in allPatches) { if (patchedByteArray.IsAsm) { string encodeContent = patchedByteArray.AsmText; //string strPrefix = ""; //IList<VariableType> variables = Variables; System.Text.StringBuilder sbPrefix = new System.Text.StringBuilder(); foreach (PatchedByteArray currentPatchedByteArray in allPatches) { if (!string.IsNullOrEmpty(currentPatchedByteArray.Label)) { sbPrefix.AppendFormat(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine); } } foreach (VariableType variable in Variables) { sbPrefix.AppendFormat(".eqv %{0}, {1}{2}", ASMEncoding.Helpers.ASMStringHelper.RemoveSpaces(variable.name).Replace(",", ""), AsmPatch.GetUnsignedByteArrayValue_LittleEndian(variable.byteArray), Environment.NewLine); } encodeContent = sbPrefix.ToString() + patchedByteArray.AsmText; //patchedByteArray.SetBytes(asmUtility.EncodeASM(encodeContent, (uint)patchedByteArray.RamOffset).EncodedBytes); byte[] bytes = asmUtility.EncodeASM(encodeContent, (uint)patchedByteArray.RamOffset).EncodedBytes; if ((!patchedByteArray.IsMoveSimple) && (blockMoveList.Count > 0)) { bytes = asmUtility.UpdateBlockReferences(bytes, (uint)patchedByteArray.RamOffset, true, blockMoveList); } patchedByteArray.SetBytes(bytes); } } }
private void ShowConflicts(AsmPatch patch) { List <PatchRangeConflict> conflictList = conflictPatchData.ConflictMap[patch]; foreach (PatchRangeConflict conflict in conflictList) { PsxIso.Sectors sector = (PsxIso.Sectors)(conflict.ConflictRange.Sector); //string strSector = Enum.GetName(typeof(PsxIso.Sectors), sector); string strSector = PatcherLib.Iso.PsxIso.GetSectorName(sector); // Patch #, Sector, Location, Conflict Location ListViewItem item = new ListViewItem(); item.Text = conflict.ConflictPatchNumber.ToString(); item.SubItems.Add(strSector); item.SubItems.Add(conflict.Range.StartOffset.ToString("X")); item.SubItems.Add(conflict.ConflictRange.StartOffset.ToString("X")); item.BackColor = conflict.IsInFreeSpace ? backColor_Conflict_FreeSpace : backColor_Conflict_NonFreeSpace; lv_Conflicts.Items.Add(item); } }
void checkedListBox1_SelectedIndexChanged(object sender, EventArgs e) { AsmPatch p = checkedListBox1.SelectedItem as AsmPatch; textBox1.Text = p.Description; if (p.Variables.Count > 0) { ignoreChanges = true; variableComboBox.Items.Clear(); p.Variables.ForEach(kvp => variableComboBox.Items.Add(kvp.Key)); variableComboBox.SelectedIndex = 0; variableSpinner.Value = p.Variables[0].Value.Bytes[0]; ignoreChanges = false; variableSpinner.Visible = true; variableComboBox.Visible = true; } else { ignoreChanges = true; variableComboBox.Visible = false; variableSpinner.Visible = false; } }
private void LoadFilePatches(int selectedIndex) { ClearCurrentPatch(); if (selectedIndex == 0) { LoadPatches(patchData.AllShownPatches); clb_Patches.BackColors = patchData.BackgroundColors[selectedIndex]; } else if (!patchData.LoadedCorrectly[selectedIndex - 1]) { clb_Patches.Items.Clear(); PatcherLib.MyMessageBox.Show(this, lsb_FilesList.SelectedItem + " did not load correctly!", "Error", MessageBoxButtons.OK); } else { LoadPatches(patchData.FilePatches[selectedIndex - 1].Patches); clb_Patches.BackColors = patchData.BackgroundColors[selectedIndex]; } //patchData.CurrentSelectedPatches = GetCurrentFileSelectedPatches(); skipCheckEventHandler = true; for (int index = 0; index < clb_Patches.Items.Count; index++) { AsmPatch asmPatch = (AsmPatch)(clb_Patches.Items[index]); clb_Patches.ForceSetItemChecked(index, patchData.SelectedPatches.Contains(asmPatch)); } skipCheckEventHandler = false; //bool enablePatchButtons = (patchData.CurrentSelectedPatches.Count > 0); bool enablePatchButtons = (patchData.SelectedPatches.Count > 0); btnPatch.Enabled = enablePatchButtons; //btnPatchSaveState.Enabled = enablePatchButtons; }
public AsmPatchEnumerator(AsmPatch owner) { this.owner = owner; }
public static ConflictResolveResult ResolveConflicts(IList <AsmPatch> patchList, ASMEncoding.ASMEncodingUtility asmUtility, int maxConflictResolveAttempts = MaxConflictResolveAttempts) { List <AsmPatch> resultPatchList = new List <AsmPatch>(); Dictionary <AsmPatch, int> patchIndexMap = new Dictionary <AsmPatch, int>(); StringBuilder sbMessage = new StringBuilder(); bool hasConflicts = false; for (int index = 0; index < patchList.Count; index++) { resultPatchList.Add(patchList[index]); patchIndexMap.Add(patchList[index], index); } Context context = (asmUtility.EncodingMode == ASMEncoding.ASMEncodingMode.PSP) ? Context.US_PSP : Context.US_PSX; FreeSpaceMode mode = FreeSpace.GetMode(context); FreeSpaceMaps freeSpaceMaps = FreeSpace.GetFreeSpaceMaps(resultPatchList, mode); foreach (PatchRange freeSpaceRange in freeSpaceMaps.PatchRangeMap.Keys) { List <PatchedByteArray> innerPatches = freeSpaceMaps.PatchRangeMap[freeSpaceRange]; FreeSpaceAnalyzeResult analyzeResult = FreeSpace.Analyze(innerPatches, freeSpaceRange, true); int conflictResolveAttempts = 0; /* * Type sectorType = ISOHelper.GetSectorType(context); * Enum sector = (Enum)Enum.ToObject(sectorType, freeSpaceRange.Sector); * string strSector = (mode == FreeSpaceMode.PSP) ? PspIso.GetSectorName((PspIso.Sectors)sector) : PsxIso.GetSectorName((PsxIso.Sectors)sector); */ string strSector = ISOHelper.GetSectorName(freeSpaceRange.Sector, context); while ((analyzeResult.HasConflicts) && (conflictResolveAttempts < maxConflictResolveAttempts)) { bool isStatic = false; bool stayStatic = false; int endIndex = innerPatches.Count - 1; for (int index = 0; index < endIndex; index++) { PatchedByteArray innerPatch = innerPatches[index]; isStatic = innerPatch.IsStatic || stayStatic; stayStatic = (innerPatch.IsStatic) && (innerPatch.IsPatchEqual(innerPatches[index + 1])); if ((analyzeResult.ConflictIndexes.Contains(index)) && (!isStatic)) { long moveOffset = analyzeResult.LargestGapOffset - innerPatch.Offset; MovePatchRange movePatchRange = new MovePatchRange(new PatchRange(innerPatch), moveOffset); AsmPatch asmPatch = freeSpaceMaps.InnerPatchMap[innerPatch]; int resultPatchIndex = patchIndexMap[asmPatch]; patchIndexMap.Remove(asmPatch); asmPatch = asmPatch.Copy(); resultPatchList[resultPatchIndex] = asmPatch; patchIndexMap.Add(asmPatch, resultPatchIndex); asmPatch.MoveBlock(asmUtility, movePatchRange); asmPatch.Update(asmUtility); sbMessage.AppendLine("Conflict resolved by moving segment of patch \"" + asmPatch.Name + "\" in sector " + strSector + " from offset " + innerPatch.Offset.ToString("X") + " to " + analyzeResult.LargestGapOffset.ToString("X") + "."); freeSpaceMaps = FreeSpace.GetFreeSpaceMaps(resultPatchList, mode); innerPatches = freeSpaceMaps.PatchRangeMap[freeSpaceRange]; analyzeResult = FreeSpace.Analyze(innerPatches, freeSpaceRange, false); conflictResolveAttempts++; break; } } } if (analyzeResult.HasConflicts) { hasConflicts = true; int endIndex = innerPatches.Count - 1; for (int index = 0; index < endIndex; index++) { if (analyzeResult.ConflictIndexes.Contains(index)) { sbMessage.Length = 0; sbMessage.AppendLine("Conflict in sector " + strSector + " at offset " + innerPatches[index].Offset.ToString("X") + "!"); break; } } } } return(new ConflictResolveResult(resultPatchList, hasConflicts, sbMessage.ToString())); }
private void clb_Patches_SelectedIndexChanged(object sender, EventArgs e) { AsmPatch p = clb_Patches.SelectedItem as AsmPatch; if (p != null) { string description = ""; if (!string.IsNullOrEmpty(p.Description)) { StringBuilder sb = new StringBuilder(); string[] lines = p.Description.Split('\n'); for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++) { string line = lines[lineIndex]; string newLine = line.Trim().Replace("\r", ""); if (((lineIndex != 0) && (lineIndex < (lines.Length - 1))) || (!string.IsNullOrEmpty(newLine))) { sb.AppendLine(newLine); } } description = sb.ToString(); description = description.Substring(0, description.LastIndexOf(Environment.NewLine)); } textBox1.Text = description; int index = clb_Patches.SelectedIndex; txt_Messages.Text = p.ErrorText; //if (p.Variables.Count > 0) if (p.CountNonReferenceVariables() > 0) { ignoreChanges = true; variableComboBox.Items.Clear(); bool foundFirst = false; VariableType firstNonReferenceVariable = p.Variables[0]; foreach (VariableType variable in p.Variables) { if (!variable.IsReference) { variableComboBox.Items.Add(variable.Name); if (!foundFirst) { firstNonReferenceVariable = variable; foundFirst = true; } } } variableComboBox.SelectedIndex = 0; byte[] byteArray = firstNonReferenceVariable.ByteArray; variableSpinner.Maximum = (decimal)Math.Pow(256, firstNonReferenceVariable.NumBytes) - 1; variableSpinner.Value = Utilities.GetUnsignedByteArrayValue_LittleEndian(byteArray); variableSpinner.Visible = true; ignoreChanges = false; variableComboBox.Visible = true; HandleVariablePresets(firstNonReferenceVariable); } else { variableSpinner.Visible = false; ignoreChanges = true; variableComboBox.Visible = false; cmb_Variable_Preset.Visible = false; } } }
private void UpdateVariable(VariableType variable, UInt32 newValue) { AsmPatch.UpdateVariable(variable, newValue); }
private ConflictCheckResult CheckConflicts(List <AsmPatch> patchList) { List <AsmPatch> resultPatchList = new List <AsmPatch>(); Dictionary <AsmPatch, List <PatchRangeConflict> > conflictMap = new Dictionary <AsmPatch, List <PatchRangeConflict> >(); Dictionary <AsmPatch, List <PatchedByteArray> > combinedPatchListMap = new Dictionary <AsmPatch, List <PatchedByteArray> >(); foreach (AsmPatch patch in patchList) { combinedPatchListMap[patch] = patch.GetCombinedPatchList(); } for (int patchIndex = 0; patchIndex < patchList.Count; patchIndex++) { AsmPatch patch = patchList[patchIndex]; List <PatchedByteArray> combinedPatchList = combinedPatchListMap[patch]; foreach (PatchedByteArray patchedByteArray in combinedPatchList) { if (patchedByteArray is InputFilePatch) { continue; } PatchRange range = new PatchRange(patchedByteArray); for (int conflictPatchIndex = patchIndex + 1; conflictPatchIndex < patchList.Count; conflictPatchIndex++) { AsmPatch conflictPatch = patchList[conflictPatchIndex]; List <PatchedByteArray> conflictCombinedPatchList = combinedPatchListMap[conflictPatch]; foreach (PatchedByteArray conflictPatchedByteArray in conflictCombinedPatchList) { if (conflictPatchedByteArray is InputFilePatch) { continue; } //if (patchedByteArray.IsPatchEqual(conflictPatchedByteArray)) if (!patchedByteArray.HasConflict(conflictPatchedByteArray)) { continue; } PatchRange conflictRange = new PatchRange(conflictPatchedByteArray); if (range.HasOverlap(conflictRange)) { bool isInFreeSpace = FreeSpace.IsContainedWithinPsxFreeSpace(range); PatchRangeConflict patchConflict = new PatchRangeConflict(range, conflictPatch, conflictRange, isInFreeSpace); PatchRangeConflict reversePatchConflict = new PatchRangeConflict(conflictRange, patch, range, isInFreeSpace); if (conflictMap.ContainsKey(patch)) { conflictMap[patch].Add(patchConflict); } else { conflictMap.Add(patch, new List <PatchRangeConflict> { patchConflict }); } if (conflictMap.ContainsKey(conflictPatch)) { conflictMap[conflictPatch].Add(reversePatchConflict); } else { conflictMap.Add(conflictPatch, new List <PatchRangeConflict> { reversePatchConflict }); } } } } } if (conflictMap.ContainsKey(patch)) { resultPatchList.Add(patch); } } return(new ConflictCheckResult(resultPatchList, conflictMap)); }
private void CheckPatches() { List <Color> bgColors = new List <Color>(); List <string> messages = new List <string>(); for (int index = 0; index < clb_Patches.Items.Count; index++) { Color color = clb_Patches.BackColor; StringBuilder sbMessage = new StringBuilder(); object objPatch = clb_Patches.Items[index]; if (objPatch != null) { AsmPatch asmPatch = (AsmPatch)objPatch; int byteArrayIndex = 0; foreach (PatchedByteArray patchedByteArray in asmPatch) { if (byteArrayIndex >= (asmPatch.Count - asmPatch.Variables.Count)) { break; } bool canLoadBytes = true; byte[] bytes = null; try { bytes = patchedByteArray.GetBytes(); } catch (Exception) { canLoadBytes = false; } if (canLoadBytes) { UInt32 ramOffset = 0; try { PsxIso.FileToRamOffsets ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), patchedByteArray.Sector)); ramOffset = (UInt32)patchedByteArray.Offset + (UInt32)ftrOffset; } catch (Exception) { } ramOffset = ramOffset | 0x80000000; // KSEG0 bool markedAsData = asmPatch.isDataSectionList[byteArrayIndex]; if (!markedAsData) { ASMCheckResult result = asmUtility.CheckASMFromBytes(bytes, ramOffset, true, false, asmCheckConditions); if (result.IsASM) { if (!string.IsNullOrEmpty(result.ErrorText)) { color = Color.FromArgb(225, 125, 125); sbMessage.Append(result.ErrorText); } } } } byteArrayIndex++; } } bgColors.Add(color); messages.Add(sbMessage.ToString()); } clb_Patches.BackColors = bgColors.ToArray(); patchMessages = messages.ToArray(); }
public static IList <AsmPatch> GetPatches(XmlNode rootNode, string xmlFilename, ASMEncodingUtility asmUtility) { bool rootHideInDefault = false; XmlAttribute attrHideInDefault = rootNode.Attributes["hideInDefault"]; if (attrHideInDefault != null) { rootHideInDefault = (attrHideInDefault.InnerText.ToLower().Trim() == "true"); } bool rootIsHidden = false; XmlAttribute attrIsHidden = rootNode.Attributes["hidden"]; if (attrIsHidden != null) { rootIsHidden = (attrIsHidden.InnerText.ToLower().Trim() == "true"); } string shortXmlFilename = xmlFilename.Substring(xmlFilename.LastIndexOf("\\") + 1); XmlNodeList patchNodes = rootNode.SelectNodes("Patch"); List <AsmPatch> result = new List <AsmPatch>(patchNodes.Count); Context context = (asmUtility.EncodingMode == ASMEncodingMode.PSP) ? Context.US_PSP : Context.US_PSX; Type sectorType = ISOHelper.GetSectorType(context); Enum defaultSector = ISOHelper.GetSector(0, context); foreach (XmlNode node in patchNodes) { XmlAttribute ignoreNode = node.Attributes["ignore"]; if (ignoreNode != null && Boolean.Parse(ignoreNode.InnerText)) { continue; } bool hasDefaultSector = false; //PsxIso.Sectors defaultSector = (PsxIso.Sectors)0; //Enum defaultSector = (Enum)Enum.ToObject(sectorType, 0); XmlAttribute attrDefaultFile = node.Attributes["file"]; XmlAttribute attrDefaultSector = node.Attributes["sector"]; if (attrDefaultFile != null) { //defaultSector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), attrDefaultFile.InnerText); //defaultSector = (Enum)Enum.Parse(sectorType, attrDefaultFile.InnerText); defaultSector = ISOHelper.GetSector(attrDefaultFile.InnerText, context); hasDefaultSector = true; } else if (attrDefaultSector != null) { //defaultSector = (PsxIso.Sectors)Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber); //defaultSector = (Enum)Enum.ToObject(sectorType, Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber)); defaultSector = ISOHelper.GetSectorHex(attrDefaultSector.InnerText, context); hasDefaultSector = true; } StringBuilder sbPatchErrorText = new StringBuilder(); List <VariableType> variables = new List <VariableType>(); List <PatchedByteArray> includePatches = new List <PatchedByteArray>(); XmlNodeList includeNodes = node.SelectNodes("Include"); foreach (XmlNode includeNode in includeNodes) { XmlAttribute attrPatch = includeNode.Attributes["patch"]; if (attrPatch != null) { string patchName = attrPatch.InnerText.ToLower().Trim(); int foundPatchCount = 0; foreach (AsmPatch currentAsmPatch in result) { if (currentAsmPatch.Name.ToLower().Trim().Equals(patchName)) { foreach (VariableType variable in currentAsmPatch.Variables) { variables.Add(variable.Copy()); } for (int index = 0; index < currentAsmPatch.NonVariableCount; index++) { includePatches.Add(currentAsmPatch[index].Copy()); } foundPatchCount++; } } if (foundPatchCount == 0) { sbPatchErrorText.AppendLine("Error in patch XML: Missing dependent patch \"" + attrPatch.InnerText + "\"!"); } } } foreach (XmlNode varNode in node.SelectNodes("Variable")) { XmlAttribute numBytesAttr = varNode.Attributes["bytes"]; string strNumBytes = (numBytesAttr == null) ? "1" : numBytesAttr.InnerText; byte numBytes = (byte)(UInt32.Parse(strNumBytes) & 0xff); string varName = varNode.Attributes["name"].InnerText; XmlAttribute fileAttribute = varNode.Attributes["file"]; XmlAttribute sectorAttribute = varNode.Attributes["sector"]; XmlAttribute attrSpecific = varNode.Attributes["specific"]; XmlAttribute attrAlign = varNode.Attributes["align"]; //PsxIso.Sectors varSec = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), varNode.Attributes["file"].InnerText ); //UInt32 varOffset = UInt32.Parse( varNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber ); //string strOffsetAttr = varNode.Attributes["offset"].InnerText; XmlAttribute offsetAttribute = varNode.Attributes["offset"]; string strOffsetAttr = (offsetAttribute != null) ? offsetAttribute.InnerText : ""; string[] strOffsets = strOffsetAttr.Replace(" ", "").Split(','); bool ignoreOffsetMode = false; bool isSpecific = false; List <SpecificLocation> specifics = FillSpecificAttributeData(attrSpecific, defaultSector); int align = 0; if (attrAlign != null) { Int32.TryParse(sectorAttribute.InnerText, out align); if (align < 0) { align = 0; } } XmlAttribute symbolAttribute = varNode.Attributes["symbol"]; bool isSymbol = (symbolAttribute != null) && PatcherLib.Utilities.Utilities.ParseBool(symbolAttribute.InnerText); if (isSymbol) { strOffsets = new string[0]; } else if (specifics.Count > 0) { isSpecific = true; List <string> newStrOffsets = new List <string>(specifics.Count); foreach (SpecificLocation specific in specifics) { newStrOffsets.Add(specific.OffsetString); } strOffsets = newStrOffsets.ToArray(); } else if ((string.IsNullOrEmpty(strOffsetAttr)) && (variables.Count > 0) && (variables[variables.Count - 1].Content.Count > 0)) { // No offset defined -- offset is (last patch offset) + (last patch size) int lastIndex = variables[variables.Count - 1].Content.Count - 1; PatchedByteArray lastPatchedByteArray = variables[variables.Count - 1].Content[lastIndex]; long offset = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length; string strOffset = offset.ToString("X"); strOffsets = new string[1] { strOffset }; ignoreOffsetMode = true; // Advance offset to match up with alignment, if necessary if (align > 0) { int offsetAlign = (int)(offset % align); if (offsetAlign > 0) { offset += (align - offsetAlign); } } } //PsxIso.Sectors sector = (PsxIso.Sectors)0; Enum sector = ISOHelper.GetSector(0, context); // (Enum)Enum.ToObject(sectorType, 0); if (isSpecific) { sector = specifics[0].Sector; } else if (fileAttribute != null) { //sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText); //sector = (Enum)Enum.Parse(sectorType, fileAttribute.InnerText); sector = ISOHelper.GetSector(fileAttribute.InnerText, context); } else if (sectorAttribute != null) { //sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber); //sector = (Enum)Enum.ToObject(sectorType, Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber)); sector = ISOHelper.GetSectorHex(sectorAttribute.InnerText, context); } else if (hasDefaultSector) { sector = defaultSector; } else if ((variables.Count > 0) && (variables[variables.Count - 1].Content.Count > 0)) { int lastIndex = variables[variables.Count - 1].Content.Count - 1; //sector = (PsxIso.Sectors)(variables[variables.Count - 1].Content[lastIndex].Sector); //sector = (Enum)Enum.ToObject(sectorType, variables[variables.Count - 1].Content[lastIndex].Sector); sector = variables[variables.Count - 1].Content[lastIndex].SectorEnum; } else if (!isSymbol) { sbPatchErrorText.AppendLine("Error in patch XML: Invalid file/sector!"); } XmlAttribute offsetModeAttribute = varNode.Attributes["offsetMode"]; bool isRamOffset = false; if ((!ignoreOffsetMode) && (offsetModeAttribute != null)) { if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram") { isRamOffset = true; } } int ftrOffset = ISOHelper.GetFileToRamOffset(sector, context); XmlAttribute defaultAttr = varNode.Attributes["default"]; Byte[] byteArray = new Byte[numBytes]; UInt32 def = 0; if (defaultAttr != null) { def = UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber); for (int i = 0; i < numBytes; i++) { byteArray[i] = (Byte)((def >> (i * 8)) & 0xff); } } List <PatchedByteArray> patchedByteArrayList = new List <PatchedByteArray>(); int offsetIndex = 0; foreach (string strOffset in strOffsets) { UInt32 offset = UInt32.Parse(strOffset, System.Globalization.NumberStyles.HexNumber); //UInt32 ramOffset = offset; UInt32 fileOffset = offset; if (ftrOffset >= 0) { try { if (isRamOffset) { fileOffset -= (UInt32)ftrOffset; } //else // ramOffset += (UInt32)ftrOffset; } catch (Exception) { } } //ramOffset = ramOffset | PsxIso.KSeg0Mask; // KSEG0 patchedByteArrayList.Add(new PatchedByteArray(sector, fileOffset, byteArray)); offsetIndex++; if (offsetIndex < strOffsets.Length) { if (isSpecific) { sector = specifics[offsetIndex].Sector; ftrOffset = ISOHelper.GetFileToRamOffset(sector, context); } } } bool isReference = false; string referenceName = ""; string referenceOperatorSymbol = ""; uint referenceOperand = 0; XmlAttribute attrReference = varNode.Attributes["reference"]; XmlAttribute attrOperator = varNode.Attributes["operator"]; XmlAttribute attrOperand = varNode.Attributes["operand"]; if (attrReference != null) { isReference = true; referenceName = attrReference.InnerText; referenceOperatorSymbol = (attrOperator != null) ? attrOperator.InnerText : ""; if (attrOperand != null) { //UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber); uint.TryParse(attrOperand.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out referenceOperand); } } List <VariableType.VariablePreset> presetValueList = new List <VariableType.VariablePreset>(); XmlNodeList presetNodeList = varNode.SelectNodes("Preset"); string presetKey = null; XmlAttribute attrPreset = varNode.Attributes["preset"]; if (attrPreset != null) { presetKey = attrPreset.InnerText; if (!string.IsNullOrEmpty(presetKey)) { presetValueList = VariableType.VariablePreset.TypeMap[presetKey]; } } else if (presetNodeList != null) { foreach (XmlNode presetNode in presetNodeList) { XmlAttribute attrName = presetNode.Attributes["name"]; XmlAttribute attrValue = presetNode.Attributes["value"]; XmlAttribute attrModify = presetNode.Attributes["modify"]; UInt32 value = 0; byte[] valueBytes = new Byte[numBytes]; if (attrValue != null) { UInt32.TryParse(attrValue.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out value); for (int i = 0; i < numBytes; i++) { valueBytes[i] = (byte)((value >> (i * 8)) & 0xff); } } bool isModifiable = false; if (attrModify != null) { bool.TryParse(attrModify.InnerText, out isModifiable); } presetValueList.Add(new VariableType.VariablePreset(attrName.InnerText, value, valueBytes, isModifiable)); } } VariableType vType = new VariableType(); vType.NumBytes = numBytes; vType.ByteArray = byteArray; vType.Name = varName; vType.Content = patchedByteArrayList; vType.IsReference = isReference; vType.Reference = new VariableReference(); vType.Reference.Name = referenceName; vType.Reference.OperatorSymbol = referenceOperatorSymbol; vType.Reference.Operand = referenceOperand; vType.PresetValues = presetValueList; variables.Add(vType); } GetPatchResult getPatchResult = GetPatch(node, xmlFilename, asmUtility, variables); List <PatchedByteArray> patches = new List <PatchedByteArray>(includePatches.Count + getPatchResult.StaticPatches.Count); patches.AddRange(includePatches); patches.AddRange(getPatchResult.StaticPatches); AsmPatch asmPatch = new AsmPatch(getPatchResult.Name, shortXmlFilename, getPatchResult.Description, patches, (getPatchResult.HideInDefault | rootHideInDefault), (getPatchResult.IsHidden | rootIsHidden), variables); asmPatch.ErrorText = sbPatchErrorText.ToString() + getPatchResult.ErrorText; //asmPatch.Update(asmUtility); result.Add(asmPatch); } patchNodes = rootNode.SelectNodes("ImportFilePatch"); foreach (XmlNode node in patchNodes) { KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node); string name = nameDesc.Key; string description = nameDesc.Value; XmlNodeList fileNodes = node.SelectNodes("ImportFile"); if (fileNodes.Count != 1) { continue; } XmlNode theRealNode = fileNodes[0]; //PsxIso.Sectors sector = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), theRealNode.Attributes["file"].InnerText ); Enum sector = (Enum)Enum.Parse(sectorType, theRealNode.Attributes["file"].InnerText); UInt32 offset = UInt32.Parse(theRealNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber); UInt32 expectedLength = UInt32.Parse(theRealNode.Attributes["expectedLength"].InnerText, System.Globalization.NumberStyles.HexNumber); result.Add(new FileAsmPatch(name, shortXmlFilename, description, new InputFilePatch(sector, offset, expectedLength))); } return(result.AsReadOnly()); }
private static GetPatchResult GetPatch(XmlNode node, string xmlFileName, ASMEncodingUtility asmUtility, List <VariableType> variables) { KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node); bool hideInDefault = false; XmlAttribute attrHideInDefault = node.Attributes["hideInDefault"]; if (attrHideInDefault != null) { if (attrHideInDefault.InnerText.ToLower().Trim() == "true") { hideInDefault = true; } } bool isHidden = false; XmlAttribute attrIsHidden = node.Attributes["hidden"]; if (attrIsHidden != null) { if (attrIsHidden.InnerText.ToLower().Trim() == "true") { isHidden = true; } } bool hasDefaultSector = false; //PsxIso.Sectors defaultSector = (PsxIso.Sectors)0; Context context = (asmUtility.EncodingMode == ASMEncodingMode.PSP) ? Context.US_PSP : Context.US_PSX; Type sectorType = ISOHelper.GetSectorType(context); Enum defaultSector = ISOHelper.GetSector(0, context); // (Enum)Enum.ToObject(sectorType, 0); XmlAttribute attrDefaultFile = node.Attributes["file"]; XmlAttribute attrDefaultSector = node.Attributes["sector"]; if (attrDefaultFile != null) { //defaultSector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), attrDefaultFile.InnerText); //defaultSector = (Enum)Enum.Parse(sectorType, attrDefaultFile.InnerText); defaultSector = ISOHelper.GetSector(attrDefaultFile.InnerText, context); hasDefaultSector = true; } else if (attrDefaultSector != null) { //defaultSector = (PsxIso.Sectors)Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber); defaultSector = ISOHelper.GetSectorHex(attrDefaultSector.InnerText, context); hasDefaultSector = true; } XmlNodeList currentLocs = node.SelectNodes("Location"); List <PatchedByteArray> patches = new List <PatchedByteArray>(currentLocs.Count); StringBuilder sbOuterErrorText = new StringBuilder(); Dictionary <PatchedByteArray, string> replaceLabelsContentMap = new Dictionary <PatchedByteArray, string>(); foreach (XmlNode location in currentLocs) { //UInt32 offset = UInt32.Parse( location.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber ); XmlAttribute offsetAttribute = location.Attributes["offset"]; XmlAttribute fileAttribute = location.Attributes["file"]; XmlAttribute sectorAttribute = location.Attributes["sector"]; XmlAttribute modeAttribute = location.Attributes["mode"]; XmlAttribute offsetModeAttribute = location.Attributes["offsetMode"]; XmlAttribute inputFileAttribute = location.Attributes["inputFile"]; XmlAttribute replaceLabelsAttribute = location.Attributes["replaceLabels"]; XmlAttribute attrLabel = location.Attributes["label"]; XmlAttribute attrSpecific = location.Attributes["specific"]; XmlAttribute attrMovable = location.Attributes["movable"]; XmlAttribute attrAlign = location.Attributes["align"]; XmlAttribute attrStatic = location.Attributes["static"]; string strOffsetAttr = (offsetAttribute != null) ? offsetAttribute.InnerText : ""; string[] strOffsets = strOffsetAttr.Replace(" ", "").Split(','); bool ignoreOffsetMode = false; bool isSpecific = false; bool isSequentialOffset = false; List <SpecificLocation> specifics = FillSpecificAttributeData(attrSpecific, defaultSector); bool isAsmMode = false; bool markedAsData = false; if (modeAttribute != null) { string modeAttributeText = modeAttribute.InnerText.ToLower().Trim(); if (modeAttributeText == "asm") { isAsmMode = true; } else if (modeAttributeText == "data") { markedAsData = true; } } int align = 0; if (attrAlign != null) { Int32.TryParse(sectorAttribute.InnerText, out align); if (align < 0) { align = 0; } } else if (isAsmMode) { align = 4; } if (specifics.Count > 0) { isSpecific = true; List <string> newStrOffsets = new List <string>(specifics.Count); foreach (SpecificLocation specific in specifics) { newStrOffsets.Add(specific.OffsetString); } strOffsets = newStrOffsets.ToArray(); } else if ((string.IsNullOrEmpty(strOffsetAttr)) && (patches.Count > 0)) { // No offset defined -- offset is (last patch offset) + (last patch size) PatchedByteArray lastPatchedByteArray = patches[patches.Count - 1]; long offset = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length; ignoreOffsetMode = true; isSequentialOffset = true; // Advance offset to match up with alignment, if necessary if (align > 0) { int offsetAlign = (int)(offset % align); if (offsetAlign > 0) { offset += (align - offsetAlign); isSequentialOffset = false; } } string strOffset = offset.ToString("X"); strOffsets = new string[1] { strOffset }; } //PsxIso.Sectors sector = (PsxIso.Sectors)0; Enum sector = ISOHelper.GetSector(0, context); // (Enum)Enum.ToObject(sectorType, 0); if (isSpecific) { sector = specifics[0].Sector; } else if (fileAttribute != null) { //sector = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), fileAttribute.InnerText ); //sector = (Enum)Enum.Parse( sectorType, fileAttribute.InnerText ); sector = ISOHelper.GetSector(fileAttribute.InnerText, context); } else if (sectorAttribute != null) { //sector = (PsxIso.Sectors)Int32.Parse( sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber ); //sector = (Enum)Enum.ToObject(sectorType, Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber)); sector = ISOHelper.GetSectorHex(sectorAttribute.InnerText, context); } else if (hasDefaultSector) { sector = defaultSector; } else if (patches.Count > 0) { //sector = (PsxIso.Sectors)(patches[patches.Count - 1].Sector); //sector = (Enum)Enum.ToObject(sectorType, patches[patches.Count - 1].Sector); sector = patches[patches.Count - 1].SectorEnum; } else { sbOuterErrorText.AppendLine("Error in patch XML: Invalid file/sector!"); } bool isRamOffset = false; if ((!ignoreOffsetMode) && (offsetModeAttribute != null)) { if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram") { isRamOffset = true; } } string content = location.InnerText; if (inputFileAttribute != null) { try { string strMode = Enum.GetName(typeof(ASMEncodingMode), asmUtility.EncodingMode); string readPath = Path.Combine("Include", inputFileAttribute.InnerText); FileInfo fileInfo = new FileInfo(xmlFileName); readPath = Path.Combine(fileInfo.DirectoryName, readPath); using (StreamReader streamReader = new StreamReader(readPath, Encoding.UTF8)) { content = streamReader.ReadToEnd(); } } catch (Exception) { string readPath = inputFileAttribute.InnerText; using (StreamReader streamReader = new StreamReader(readPath, Encoding.UTF8)) { content = streamReader.ReadToEnd(); } } } bool replaceLabels = false; if (replaceLabelsAttribute != null) { if (replaceLabelsAttribute.InnerText.ToLower().Trim() == "true") { replaceLabels = true; } } if (replaceLabels) { StringBuilder sbLabels = new StringBuilder(); foreach (PatchedByteArray currentPatchedByteArray in patches) { if (!string.IsNullOrEmpty(currentPatchedByteArray.Label)) { sbLabels.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine)); } } asmUtility.EncodeASM(sbLabels.ToString(), 0); content = asmUtility.ReplaceLabelsInHex(content, true, true); } string label = ""; if (attrLabel != null) { label = attrLabel.InnerText.Replace(" ", ""); } bool isMoveSimple = isAsmMode; if (attrMovable != null) { bool.TryParse(attrMovable.InnerText, out isMoveSimple); } bool isStatic = false; if (attrStatic != null) { bool.TryParse(attrStatic.InnerText, out isStatic); } int ftrOffset = ISOHelper.GetFileToRamOffset(sector, context); int offsetIndex = 0; foreach (string strOffset in strOffsets) { UInt32 offset = UInt32.Parse(strOffset, System.Globalization.NumberStyles.HexNumber); UInt32 ramOffset = offset; UInt32 fileOffset = offset; if (ftrOffset >= 0) { try { if (isRamOffset) { fileOffset -= (UInt32)ftrOffset; } else { ramOffset += (UInt32)ftrOffset; } } catch (Exception) { } } if (context == Context.US_PSX) { ramOffset = ramOffset | PsxIso.KSeg0Mask; } byte[] bytes; string errorText = ""; if (isAsmMode) { string encodeContent = content; StringBuilder sbPrefix = new StringBuilder(); foreach (PatchedByteArray currentPatchedByteArray in patches) { if (!string.IsNullOrEmpty(currentPatchedByteArray.Label)) { sbPrefix.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine)); } } foreach (VariableType variable in variables) { sbPrefix.Append(String.Format(".eqv %{0}, {1}{2}", ASMStringHelper.RemoveSpaces(variable.Name).Replace(",", ""), PatcherLib.Utilities.Utilities.GetUnsignedByteArrayValue_LittleEndian(variable.ByteArray), Environment.NewLine)); } encodeContent = sbPrefix.ToString() + content; ASMEncoderResult result = asmUtility.EncodeASM(encodeContent, ramOffset, true); bytes = result.EncodedBytes; errorText = result.ErrorText; } else { AsmPatch.GetBytesResult result = AsmPatch.GetBytes(content, ramOffset, variables); bytes = result.Bytes; errorText = result.ErrorMessage; } /* * bool isCheckedAsm = false; * if (!markedAsData) * { * ASMCheckResult checkResult = asmUtility.CheckASMFromBytes(bytes, ramOffset, true, false, new HashSet<ASMCheckCondition>() { * ASMCheckCondition.LoadDelay, * ASMCheckCondition.UnalignedOffset, * ASMCheckCondition.MultCountdown, * ASMCheckCondition.StackPointerOffset4, * ASMCheckCondition.BranchInBranchDelaySlot * }); * * if (checkResult.IsASM) * { * isCheckedAsm = true; * if (!string.IsNullOrEmpty(checkResult.ErrorText)) * { * errorText += checkResult.ErrorText; * } * } * } */ //if (!string.IsNullOrEmpty(errorText)) // sbOuterErrorText.Append(errorText); PatchedByteArray patchedByteArray = new PatchedByteArray(sector, fileOffset, bytes); patchedByteArray.IsAsm = isAsmMode; patchedByteArray.MarkedAsData = markedAsData; patchedByteArray.IsCheckedAsm = false; // isCheckedAsm; patchedByteArray.IsSequentialOffset = isSequentialOffset; patchedByteArray.IsMoveSimple = isMoveSimple; //patchedByteArray.AsmText = isAsmMode ? content : ""; patchedByteArray.Text = content; patchedByteArray.RamOffset = ramOffset; patchedByteArray.ErrorText = errorText; patchedByteArray.Label = label; patchedByteArray.IsStatic = isStatic; if (replaceLabels) { replaceLabelsContentMap.Add(patchedByteArray, content); } patches.Add(patchedByteArray); offsetIndex++; if (offsetIndex < strOffsets.Length) { if (isSpecific) { sector = specifics[offsetIndex].Sector; ftrOffset = ISOHelper.GetFileToRamOffset(sector, context); } } } } StringBuilder sbEncodePrefix = new StringBuilder(); foreach (PatchedByteArray currentPatchedByteArray in patches) { if (!string.IsNullOrEmpty(currentPatchedByteArray.Label)) { sbEncodePrefix.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine)); } } foreach (VariableType variable in variables) { sbEncodePrefix.Append(String.Format(".eqv %{0}, {1}{2}", ASMStringHelper.RemoveSpaces(variable.Name).Replace(",", ""), PatcherLib.Utilities.Utilities.GetUnsignedByteArrayValue_LittleEndian(variable.ByteArray), Environment.NewLine)); } string strEncodePrefix = sbEncodePrefix.ToString(); asmUtility.EncodeASM(strEncodePrefix, 0); foreach (PatchedByteArray patchedByteArray in patches) { string errorText = string.Empty; string replaceLabelsContent; if (replaceLabelsContentMap.TryGetValue(patchedByteArray, out replaceLabelsContent)) { if (!string.IsNullOrEmpty(replaceLabelsContent)) { AsmPatch.GetBytesResult result = AsmPatch.GetBytes(asmUtility.ReplaceLabelsInHex(replaceLabelsContent, true, false), (uint)patchedByteArray.RamOffset, variables); patchedByteArray.SetBytes(result.Bytes); errorText += result.ErrorMessage; } } if (patchedByteArray.IsAsm) { string encodeContent = strEncodePrefix + patchedByteArray.Text; ASMEncoderResult result = asmUtility.EncodeASM(encodeContent, (uint)patchedByteArray.RamOffset); patchedByteArray.SetBytes(result.EncodedBytes); errorText += result.ErrorText; } if (!patchedByteArray.MarkedAsData) { HashSet <ASMCheckCondition> checkConditions = new HashSet <ASMCheckCondition>() { ASMCheckCondition.LoadDelay, ASMCheckCondition.UnalignedOffset, ASMCheckCondition.MultCountdown, ASMCheckCondition.StackPointerOffset4, ASMCheckCondition.BranchInBranchDelaySlot }; if (asmUtility.EncodingMode == ASMEncodingMode.PSP) { checkConditions.Remove(ASMCheckCondition.LoadDelay); } ASMCheckResult checkResult = asmUtility.CheckASMFromBytes(patchedByteArray.GetBytes(), (uint)patchedByteArray.RamOffset, true, false, checkConditions); if (checkResult.IsASM) { patchedByteArray.IsCheckedAsm = true; if (!string.IsNullOrEmpty(checkResult.ErrorText)) { errorText += checkResult.ErrorText; } } } if (!string.IsNullOrEmpty(errorText)) { sbOuterErrorText.Append(errorText); } } currentLocs = node.SelectNodes("STRLocation"); foreach (XmlNode location in currentLocs) { XmlAttribute fileAttribute = location.Attributes["file"]; XmlAttribute sectorAttribute = location.Attributes["sector"]; //PsxIso.Sectors sector = (PsxIso.Sectors)0; Enum sector = ISOHelper.GetSector(0, context); // (Enum)Enum.ToObject(sectorType, 0); if (fileAttribute != null) { //sector = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), fileAttribute.InnerText ); //sector = (Enum)Enum.Parse(sectorType, fileAttribute.InnerText); sector = ISOHelper.GetSector(fileAttribute.InnerText, context); } else if (sectorAttribute != null) { //sector = (PsxIso.Sectors)Int32.Parse( sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber ); //sector = (Enum)Enum.ToObject(sectorType, Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber)); sector = ISOHelper.GetSectorHex(sectorAttribute.InnerText, context); } else { throw new Exception(); } string filename = location.Attributes["input"].InnerText; filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(xmlFileName), filename); patches.Add(new STRPatchedByteArray(sector, filename)); } return(new GetPatchResult(nameDesc.Key, nameDesc.Value, patches.AsReadOnly(), hideInDefault, isHidden, sbOuterErrorText.ToString())); }
public static IList <AsmPatch> GetPatches(XmlNode rootNode, string xmlFilename, ASMEncodingUtility asmUtility) { bool rootHideInDefault = false; XmlAttribute attrHideInDefault = rootNode.Attributes["hideInDefault"]; if (attrHideInDefault != null) { rootHideInDefault = (attrHideInDefault.InnerText.ToLower().Trim() == "true"); } string shortXmlFilename = xmlFilename.Substring(xmlFilename.LastIndexOf("\\") + 1); XmlNodeList patchNodes = rootNode.SelectNodes("Patch"); List <AsmPatch> result = new List <AsmPatch>(patchNodes.Count); foreach (XmlNode node in patchNodes) { XmlAttribute ignoreNode = node.Attributes["ignore"]; if (ignoreNode != null && Boolean.Parse(ignoreNode.InnerText)) { continue; } bool hasDefaultSector = false; PsxIso.Sectors defaultSector = (PsxIso.Sectors) 0; XmlAttribute attrDefaultFile = node.Attributes["file"]; XmlAttribute attrDefaultSector = node.Attributes["sector"]; if (attrDefaultFile != null) { defaultSector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), attrDefaultFile.InnerText); hasDefaultSector = true; } else if (attrDefaultSector != null) { defaultSector = (PsxIso.Sectors)Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber); hasDefaultSector = true; } List <VariableType> variables = new List <VariableType>(); List <PatchedByteArray> includePatches = new List <PatchedByteArray>(); XmlNodeList includeNodes = node.SelectNodes("Include"); foreach (XmlNode includeNode in includeNodes) { XmlAttribute attrPatch = includeNode.Attributes["patch"]; if (attrPatch != null) { string patchName = attrPatch.InnerText.ToLower().Trim(); foreach (AsmPatch currentAsmPatch in result) { if (currentAsmPatch.Name.ToLower().Trim().Equals(patchName)) { foreach (VariableType variable in currentAsmPatch.Variables) { variables.Add(AsmPatch.CopyVariable(variable)); } for (int index = 0; index < currentAsmPatch.NonVariableCount; index++) { includePatches.Add(currentAsmPatch[index].Copy()); } } } } } foreach (XmlNode varNode in node.SelectNodes("Variable")) { XmlAttribute numBytesAttr = varNode.Attributes["bytes"]; string strNumBytes = (numBytesAttr == null) ? "1" : numBytesAttr.InnerText; byte numBytes = (byte)(UInt32.Parse(strNumBytes) & 0xff); string varName = varNode.Attributes["name"].InnerText; XmlAttribute fileAttribute = varNode.Attributes["file"]; XmlAttribute sectorAttribute = varNode.Attributes["sector"]; XmlAttribute attrSpecific = varNode.Attributes["specific"]; //PsxIso.Sectors varSec = (PsxIso.Sectors)Enum.Parse( typeof( PsxIso.Sectors ), varNode.Attributes["file"].InnerText ); //UInt32 varOffset = UInt32.Parse( varNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber ); //string strOffsetAttr = varNode.Attributes["offset"].InnerText; XmlAttribute offsetAttribute = varNode.Attributes["offset"]; string strOffsetAttr = (offsetAttribute != null) ? offsetAttribute.InnerText : ""; string[] strOffsets = strOffsetAttr.Replace(" ", "").Split(','); bool ignoreOffsetMode = false; bool isSpecific = false; List <SpecificLocation> specifics = FillSpecificAttributeData(attrSpecific, defaultSector); if (specifics.Count > 0) { isSpecific = true; List <string> newStrOffsets = new List <string>(specifics.Count); foreach (SpecificLocation specific in specifics) { newStrOffsets.Add(specific.OffsetString); } strOffsets = newStrOffsets.ToArray(); } else if ((string.IsNullOrEmpty(strOffsetAttr)) && (variables.Count > 0) && (variables[variables.Count - 1].content.Count > 0)) { // No offset defined -- offset is (last patch offset) + (last patch size) int lastIndex = variables[variables.Count - 1].content.Count - 1; PatchedByteArray lastPatchedByteArray = variables[variables.Count - 1].content[lastIndex]; long offset = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length; string strOffset = offset.ToString("X"); strOffsets = new string[1] { strOffset }; ignoreOffsetMode = true; } PsxIso.Sectors sector = (PsxIso.Sectors) 0; if (isSpecific) { sector = specifics[0].Sector; } else if (fileAttribute != null) { sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText); } else if (sectorAttribute != null) { sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber); } else if (hasDefaultSector) { sector = defaultSector; } else if ((variables.Count > 0) && (variables[variables.Count - 1].content.Count > 0)) { int lastIndex = variables[variables.Count - 1].content.Count - 1; sector = (PsxIso.Sectors)(variables[variables.Count - 1].content[lastIndex].Sector); } else { throw new Exception("Error in patch XML: Invalid file/sector!"); } XmlAttribute offsetModeAttribute = varNode.Attributes["offsetMode"]; bool isRamOffset = false; if ((!ignoreOffsetMode) && (offsetModeAttribute != null)) { if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram") { isRamOffset = true; } } Nullable <PsxIso.FileToRamOffsets> ftrOffset = null; try { ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), sector)); //ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + fileAttribute.InnerText); } catch (Exception) { ftrOffset = null; } XmlAttribute defaultAttr = varNode.Attributes["default"]; Byte[] byteArray = new Byte[numBytes]; UInt32 def = 0; if (defaultAttr != null) { def = UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber); for (int i = 0; i < numBytes; i++) { byteArray[i] = (Byte)((def >> (i * 8)) & 0xff); } } List <PatchedByteArray> patchedByteArrayList = new List <PatchedByteArray>(); int offsetIndex = 0; foreach (string strOffset in strOffsets) { UInt32 offset = UInt32.Parse(strOffset, System.Globalization.NumberStyles.HexNumber); //UInt32 ramOffset = offset; UInt32 fileOffset = offset; if (ftrOffset.HasValue) { try { if (isRamOffset) { fileOffset -= (UInt32)ftrOffset; } //else // ramOffset += (UInt32)ftrOffset; } catch (Exception) { } } //ramOffset = ramOffset | 0x80000000; // KSEG0 patchedByteArrayList.Add(new PatchedByteArray(sector, fileOffset, byteArray)); offsetIndex++; if (offsetIndex < strOffsets.Length) { if (isSpecific) { sector = specifics[offsetIndex].Sector; try { ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), sector)); } catch (Exception) { ftrOffset = null; } } } } bool isReference = false; string referenceName = ""; string referenceOperatorSymbol = ""; uint referenceOperand = 0; XmlAttribute attrReference = varNode.Attributes["reference"]; XmlAttribute attrOperator = varNode.Attributes["operator"]; XmlAttribute attrOperand = varNode.Attributes["operand"]; if (attrReference != null) { isReference = true; referenceName = attrReference.InnerText; referenceOperatorSymbol = (attrOperator != null) ? attrOperator.InnerText : ""; if (attrOperand != null) { //UInt32.Parse(defaultAttr.InnerText, System.Globalization.NumberStyles.HexNumber); uint.TryParse(attrOperand.InnerText, System.Globalization.NumberStyles.HexNumber, System.Globalization.CultureInfo.CurrentCulture, out referenceOperand); } } VariableType vType = new VariableType(); vType.numBytes = numBytes; vType.byteArray = byteArray; vType.name = varName; vType.content = patchedByteArrayList; vType.isReference = isReference; vType.reference = new VariableReference(); vType.reference.name = referenceName; vType.reference.operatorSymbol = referenceOperatorSymbol; vType.reference.operand = referenceOperand; variables.Add(vType); } GetPatchResult getPatchResult = GetPatch(node, xmlFilename, asmUtility, variables); List <PatchedByteArray> patches = new List <PatchedByteArray>(includePatches.Count + getPatchResult.StaticPatches.Count); patches.AddRange(includePatches); patches.AddRange(getPatchResult.StaticPatches); AsmPatch asmPatch = new AsmPatch(getPatchResult.Name, shortXmlFilename, getPatchResult.Description, patches, (getPatchResult.HideInDefault | rootHideInDefault), variables); asmPatch.ErrorText = getPatchResult.ErrorText; result.Add(asmPatch); } patchNodes = rootNode.SelectNodes("ImportFilePatch"); foreach (XmlNode node in patchNodes) { KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node); string name = nameDesc.Key; string description = nameDesc.Value; XmlNodeList fileNodes = node.SelectNodes("ImportFile"); if (fileNodes.Count != 1) { continue; } XmlNode theRealNode = fileNodes[0]; PsxIso.Sectors sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), theRealNode.Attributes["file"].InnerText); UInt32 offset = UInt32.Parse(theRealNode.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber); UInt32 expectedLength = UInt32.Parse(theRealNode.Attributes["expectedLength"].InnerText, System.Globalization.NumberStyles.HexNumber); result.Add(new FileAsmPatch(name, shortXmlFilename, description, new InputFilePatch(sector, offset, expectedLength))); } return(result.AsReadOnly()); }
private static GetPatchResult GetPatch(XmlNode node, string xmlFileName, ASMEncodingUtility asmUtility, List <VariableType> variables) { KeyValuePair <string, string> nameDesc = GetPatchNameAndDescription(node); bool hideInDefault = false; XmlAttribute attrHideInDefault = node.Attributes["hideInDefault"]; if (attrHideInDefault != null) { if (attrHideInDefault.InnerText.ToLower().Trim() == "true") { hideInDefault = true; } } bool hasDefaultSector = false; PsxIso.Sectors defaultSector = (PsxIso.Sectors) 0; XmlAttribute attrDefaultFile = node.Attributes["file"]; XmlAttribute attrDefaultSector = node.Attributes["sector"]; if (attrDefaultFile != null) { defaultSector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), attrDefaultFile.InnerText); hasDefaultSector = true; } else if (attrDefaultSector != null) { defaultSector = (PsxIso.Sectors)Int32.Parse(attrDefaultSector.InnerText, System.Globalization.NumberStyles.HexNumber); hasDefaultSector = true; } XmlNodeList currentLocs = node.SelectNodes("Location"); List <PatchedByteArray> patches = new List <PatchedByteArray>(currentLocs.Count); StringBuilder sbOuterErrorText = new StringBuilder(); foreach (XmlNode location in currentLocs) { //UInt32 offset = UInt32.Parse( location.Attributes["offset"].InnerText, System.Globalization.NumberStyles.HexNumber ); XmlAttribute offsetAttribute = location.Attributes["offset"]; XmlAttribute fileAttribute = location.Attributes["file"]; XmlAttribute sectorAttribute = location.Attributes["sector"]; XmlAttribute modeAttribute = location.Attributes["mode"]; XmlAttribute offsetModeAttribute = location.Attributes["offsetMode"]; XmlAttribute inputFileAttribute = location.Attributes["inputFile"]; XmlAttribute replaceLabelsAttribute = location.Attributes["replaceLabels"]; XmlAttribute attrLabel = location.Attributes["label"]; XmlAttribute attrSpecific = location.Attributes["specific"]; XmlAttribute attrMovable = location.Attributes["movable"]; string strOffsetAttr = (offsetAttribute != null) ? offsetAttribute.InnerText : ""; string[] strOffsets = strOffsetAttr.Replace(" ", "").Split(','); bool ignoreOffsetMode = false; bool isSpecific = false; bool isSequentialOffset = false; List <SpecificLocation> specifics = FillSpecificAttributeData(attrSpecific, defaultSector); if (specifics.Count > 0) { isSpecific = true; List <string> newStrOffsets = new List <string>(specifics.Count); foreach (SpecificLocation specific in specifics) { newStrOffsets.Add(specific.OffsetString); } strOffsets = newStrOffsets.ToArray(); } else if ((string.IsNullOrEmpty(strOffsetAttr)) && (patches.Count > 0)) { // No offset defined -- offset is (last patch offset) + (last patch size) PatchedByteArray lastPatchedByteArray = patches[patches.Count - 1]; long offset = lastPatchedByteArray.Offset + lastPatchedByteArray.GetBytes().Length; string strOffset = offset.ToString("X"); strOffsets = new string[1] { strOffset }; ignoreOffsetMode = true; isSequentialOffset = true; } PsxIso.Sectors sector = (PsxIso.Sectors) 0; if (isSpecific) { sector = specifics[0].Sector; } else if (fileAttribute != null) { sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText); } else if (sectorAttribute != null) { sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber); } else if (hasDefaultSector) { sector = defaultSector; } else if (patches.Count > 0) { sector = (PsxIso.Sectors)(patches[patches.Count - 1].Sector); } else { throw new Exception("Error in patch XML: Invalid file/sector!"); } bool asmMode = false; bool markedAsData = false; if (modeAttribute != null) { string modeAttributeText = modeAttribute.InnerText.ToLower().Trim(); if (modeAttributeText == "asm") { asmMode = true; } else if (modeAttributeText == "data") { markedAsData = true; } } bool isRamOffset = false; if ((!ignoreOffsetMode) && (offsetModeAttribute != null)) { if (offsetModeAttribute.InnerText.ToLower().Trim() == "ram") { isRamOffset = true; } } string content = location.InnerText; if (inputFileAttribute != null) { using (StreamReader streamReader = new StreamReader(inputFileAttribute.InnerText, Encoding.UTF8)) { content = streamReader.ReadToEnd(); } } bool replaceLabels = false; if (replaceLabelsAttribute != null) { if (replaceLabelsAttribute.InnerText.ToLower().Trim() == "true") { replaceLabels = true; } } if (replaceLabels) { foreach (PatchedByteArray currentPatchedByteArray in patches) { StringBuilder sbLabels = new StringBuilder(); if (!string.IsNullOrEmpty(currentPatchedByteArray.Label)) { sbLabels.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine)); } asmUtility.EncodeASM(sbLabels.ToString(), 0); } content = asmUtility.ReplaceLabelsInHex(content, true); } string label = ""; if (attrLabel != null) { label = attrLabel.InnerText.Replace(" ", ""); } bool isMoveSimple = asmMode; if (attrMovable != null) { bool.TryParse(attrMovable.InnerText, out isMoveSimple); } Nullable <PsxIso.FileToRamOffsets> ftrOffset = null; try { ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), sector)); } catch (Exception) { ftrOffset = null; } int offsetIndex = 0; foreach (string strOffset in strOffsets) { UInt32 offset = UInt32.Parse(strOffset, System.Globalization.NumberStyles.HexNumber); UInt32 ramOffset = offset; UInt32 fileOffset = offset; if (ftrOffset.HasValue) { try { if (isRamOffset) { fileOffset -= (UInt32)ftrOffset; } else { ramOffset += (UInt32)ftrOffset; } } catch (Exception) { } } ramOffset = ramOffset | 0x80000000; // KSEG0 byte[] bytes; string errorText = ""; if (asmMode) { string encodeContent = content; StringBuilder sbPrefix = new StringBuilder(); foreach (PatchedByteArray currentPatchedByteArray in patches) { if (!string.IsNullOrEmpty(currentPatchedByteArray.Label)) { sbPrefix.Append(String.Format(".label @{0}, {1}{2}", currentPatchedByteArray.Label, currentPatchedByteArray.RamOffset, Environment.NewLine)); } } foreach (VariableType variable in variables) { sbPrefix.Append(String.Format(".eqv %{0}, {1}{2}", ASMStringHelper.RemoveSpaces(variable.name).Replace(",", ""), AsmPatch.GetUnsignedByteArrayValue_LittleEndian(variable.byteArray), Environment.NewLine)); } encodeContent = sbPrefix.ToString() + content; ASMEncoderResult result = asmUtility.EncodeASM(encodeContent, ramOffset); bytes = result.EncodedBytes; errorText = result.ErrorText; } else { bytes = GetBytes(content); } bool isCheckedAsm = false; if (!markedAsData) { ASMCheckResult checkResult = asmUtility.CheckASMFromBytes(bytes, ramOffset, true, false, new HashSet <ASMCheckCondition>() { ASMCheckCondition.LoadDelay, ASMCheckCondition.UnalignedOffset, ASMCheckCondition.MultCountdown, ASMCheckCondition.StackPointerOffset4, ASMCheckCondition.BranchInBranchDelaySlot }); if (checkResult.IsASM) { isCheckedAsm = true; if (!string.IsNullOrEmpty(checkResult.ErrorText)) { errorText += checkResult.ErrorText; } } } if (!string.IsNullOrEmpty(errorText)) { sbOuterErrorText.Append(errorText); } PatchedByteArray patchedByteArray = new PatchedByteArray(sector, fileOffset, bytes); patchedByteArray.IsAsm = asmMode; patchedByteArray.MarkedAsData = markedAsData; patchedByteArray.IsCheckedAsm = isCheckedAsm; patchedByteArray.IsSequentialOffset = isSequentialOffset; patchedByteArray.IsMoveSimple = isMoveSimple; patchedByteArray.AsmText = asmMode ? content : ""; patchedByteArray.RamOffset = ramOffset; patchedByteArray.ErrorText = errorText; patchedByteArray.Label = label; patches.Add(patchedByteArray); offsetIndex++; if (offsetIndex < strOffsets.Length) { if (isSpecific) { sector = specifics[offsetIndex].Sector; try { ftrOffset = (PsxIso.FileToRamOffsets)Enum.Parse(typeof(PsxIso.FileToRamOffsets), "OFFSET_" + Enum.GetName(typeof(PsxIso.Sectors), sector)); } catch (Exception) { ftrOffset = null; } } } } } currentLocs = node.SelectNodes("STRLocation"); foreach (XmlNode location in currentLocs) { XmlAttribute fileAttribute = location.Attributes["file"]; XmlAttribute sectorAttribute = location.Attributes["sector"]; PsxIso.Sectors sector = (PsxIso.Sectors) 0; if (fileAttribute != null) { sector = (PsxIso.Sectors)Enum.Parse(typeof(PsxIso.Sectors), fileAttribute.InnerText); } else if (sectorAttribute != null) { sector = (PsxIso.Sectors)Int32.Parse(sectorAttribute.InnerText, System.Globalization.NumberStyles.HexNumber); } else { throw new Exception(); } string filename = location.Attributes["input"].InnerText; filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(xmlFileName), filename); patches.Add(new STRPatchedByteArray(sector, filename)); } return(new GetPatchResult(nameDesc.Key, nameDesc.Value, patches.AsReadOnly(), hideInDefault, sbOuterErrorText.ToString())); }