diff --git a/PluginCommon/VisBitmap8.cs b/PluginCommon/VisBitmap8.cs
index 6de27d0..ca738ef 100644
--- a/PluginCommon/VisBitmap8.cs
+++ b/PluginCommon/VisBitmap8.cs
@@ -55,6 +55,8 @@ namespace PluginCommon {
mNextColorIdx = 0;
}
+ // TODO: add GetPixelIndex, which returns the index we passed into SetPixelIndex
+
public int GetPixel(int x, int y) {
byte pix = mData[x + y * Width];
return mPalette[pix];
diff --git a/SourceGen/DisplayList.cs b/SourceGen/DisplayList.cs
index 13c6762..699e3f3 100644
--- a/SourceGen/DisplayList.cs
+++ b/SourceGen/DisplayList.cs
@@ -369,6 +369,10 @@ namespace SourceGen {
// examined by a data trigger in CodeListItemStyle.xaml.
public bool HasAddrLabelHighlight { get; private set; }
+ // Set to true if we want to highlight the operand field. This is
+ // examined by a data trigger in CodeListItemStyle.xaml.
+ public bool HasOperandHighlight { get; private set; }
+
// Set to true if the Flags field has been modified.
public bool HasModifiedFlags {
get { return (mPartFlags & PartFlags.HasModifiedFlags) != 0; }
@@ -502,18 +506,30 @@ namespace SourceGen {
return parts;
}
- public static FormattedParts AddSelectionHighlight(FormattedParts orig) {
+ public static FormattedParts AddSelectionAddrHighlight(FormattedParts orig) {
FormattedParts newParts = Clone(orig);
newParts.HasAddrLabelHighlight = true;
return newParts;
}
- public static FormattedParts RemoveSelectionHighlight(FormattedParts orig) {
+ public static FormattedParts RemoveSelectionAddrHighlight(FormattedParts orig) {
FormattedParts newParts = Clone(orig);
newParts.HasAddrLabelHighlight = false;
return newParts;
}
+ public static FormattedParts AddSelectionOperHighlight(FormattedParts orig) {
+ FormattedParts newParts = Clone(orig);
+ newParts.HasOperandHighlight = true;
+ return newParts;
+ }
+
+ public static FormattedParts RemoveSelectionOperHighlight(FormattedParts orig) {
+ FormattedParts newParts = Clone(orig);
+ newParts.HasOperandHighlight = false;
+ return newParts;
+ }
+
public override string ToString() {
return "[Parts: index=" + ListIndex + " off=" + Offset + "]";
}
diff --git a/SourceGen/MainController.cs b/SourceGen/MainController.cs
index 0cd1787..5a24a13 100644
--- a/SourceGen/MainController.cs
+++ b/SourceGen/MainController.cs
@@ -181,6 +181,11 @@ namespace SourceGen {
///
private int mTargetHighlightIndex = -1;
+ ///
+ /// Tracks the operands we have highlighted.
+ ///
+ private List mOperandHighlights = new List();
+
///
/// Code list color scheme.
///
@@ -879,8 +884,20 @@ namespace SourceGen {
CodeLineList, mMainWin.CodeDisplayList.SelectedIndices, topItemIndex);
//savedSel.DebugDump();
- // Clear this so we don't try to fiddle with it later.
+ // Clear the addr/label highlight index.
+ // (Certain changes will blow away the CodeDisplayList and affect the selection,
+ // which will cause the selection-changed handler to try to un-highlight something
+ // that doesn't exist. We want to clear the index here, but we probably also want
+ // to clear the highlighting before we do it. As it happens, changes will either
+ // be big enough to wipe out our highlight, or small enough that we immediately
+ // re-highlight the thing that's already highlighted, so it doesn't really matter.
+ // If we start to see vestigial highlighting after a change, we'll need to be
+ // more rigorous here.)
mTargetHighlightIndex = -1;
+
+ // Clear operand highlighting indices as well.
+ mOperandHighlights.Clear();
+
mReanalysisTimer.EndTask("Save selection");
mReanalysisTimer.StartTask("Apply changes");
@@ -1404,7 +1421,11 @@ namespace SourceGen {
}
mDataPathName = null;
mProjectPathName = null;
+
+ // We may get a "selection changed" message as things are being torn down. Clear
+ // these so we don't try to remove the highlight from something that doesn't exist.
mTargetHighlightIndex = -1;
+ mOperandHighlights.Clear();
mMainWin.ShowCodeListView = false;
mMainWin.ProjectClosing();
@@ -3405,16 +3426,19 @@ namespace SourceGen {
private bool mUpdatingSelectionHighlight; // recursion guard for next method
///
- /// Updates the selection highlight. When a code item with an operand offset is
+ /// Updates the selection highlights. When a code or data item with an operand offset is
/// selected, such as a branch, we want to highlight the address and label of the
- /// target.
+ /// target. When a code or data item is referenced by another instruction, such as a
+ /// branch, we want to highlight the operands of all such instructions.
///
private void UpdateSelectionHighlight() {
if (mUpdatingSelectionHighlight) {
return;
}
+ mUpdatingSelectionHighlight = true;
- int targetIndex = FindSelectionHighlight();
+ int targetIndex = FindSelectionAddrHighlight(out bool isSingleCodeData,
+ out int selIndex);
if (mTargetHighlightIndex != targetIndex) {
Debug.WriteLine("Target highlight moving from " + mTargetHighlightIndex +
" to " + targetIndex);
@@ -3429,25 +3453,47 @@ namespace SourceGen {
// it will be the selected line while we're doing this little dance. When the
// calls below update the selection, this method will be called again. This
// turns into infinite recursion.
- mUpdatingSelectionHighlight = true;
- mMainWin.CodeListView_RemoveSelectionHighlight(mTargetHighlightIndex);
- mMainWin.CodeListView_AddSelectionHighlight(targetIndex);
- mUpdatingSelectionHighlight = false;
+ mMainWin.CodeListView_RemoveSelectionAddrHighlight(mTargetHighlightIndex);
+ mMainWin.CodeListView_AddSelectionAddrHighlight(targetIndex);
mTargetHighlightIndex = targetIndex;
}
+
+ if (mOperandHighlights.Count > 0) {
+ foreach (int index in mOperandHighlights) {
+ mMainWin.CodeListView_RemoveSelectionOperHighlight(index);
+ }
+ mOperandHighlights.Clear();
+ }
+ if (isSingleCodeData) {
+ LineListGen.Line line = CodeLineList[selIndex];
+ XrefSet xrefs = mProject.GetXrefSet(line.FileOffset);
+ if (xrefs != null) {
+ foreach (XrefSet.Xref xr in xrefs) {
+ int refIndex = CodeLineList.FindCodeDataIndexByOffset(xr.Offset);
+ mMainWin.CodeListView_AddSelectionOperHighlight(refIndex);
+ mOperandHighlights.Add(refIndex);
+ }
+ }
+ }
+
+ mUpdatingSelectionHighlight = false;
}
- private int FindSelectionHighlight() {
+ private int FindSelectionAddrHighlight(out bool isSingleCodeData, out int selIndex) {
if (mMainWin.CodeListView_GetSelectionCount() != 1) {
+ isSingleCodeData = false;
+ selIndex = -1;
return -1;
}
- int selIndex = mMainWin.CodeListView_GetFirstSelectedIndex();
+ selIndex = mMainWin.CodeListView_GetFirstSelectedIndex();
LineListGen.Line line = CodeLineList[selIndex];
if (!line.IsCodeOrData) {
+ isSingleCodeData = false;
return -1;
}
Debug.Assert(line.FileOffset >= 0);
+ isSingleCodeData = true;
// Does this have an operand with an in-file target offset?
// TODO: may not work correctly with reloc data?
diff --git a/SourceGen/WpfGui/CodeListItemStyle.xaml b/SourceGen/WpfGui/CodeListItemStyle.xaml
index aa6e30d..9b32fd2 100644
--- a/SourceGen/WpfGui/CodeListItemStyle.xaml
+++ b/SourceGen/WpfGui/CodeListItemStyle.xaml
@@ -407,4 +407,22 @@ See also https://github.com/fadden/DisasmUiTest
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/SourceGen/WpfGui/MainWindow.xaml b/SourceGen/WpfGui/MainWindow.xaml
index 94bd636..55ec836 100644
--- a/SourceGen/WpfGui/MainWindow.xaml
+++ b/SourceGen/WpfGui/MainWindow.xaml
@@ -771,7 +771,7 @@ limitations under the License.
+ CellTemplate="{StaticResource operandHighlightTemplate}"/>
diff --git a/SourceGen/WpfGui/MainWindow.xaml.cs b/SourceGen/WpfGui/MainWindow.xaml.cs
index fba729c..bd60035 100644
--- a/SourceGen/WpfGui/MainWindow.xaml.cs
+++ b/SourceGen/WpfGui/MainWindow.xaml.cs
@@ -981,24 +981,48 @@ namespace SourceGen.WpfGui {
/// Adds an address/label selection highlight to the specified line.
///
/// Line index. If < 0, method has no effect.
- public void CodeListView_AddSelectionHighlight(int index) {
+ public void CodeListView_AddSelectionAddrHighlight(int index) {
if (index < 0) {
return;
}
CodeListView_ReplaceEntry(index,
- DisplayList.FormattedParts.AddSelectionHighlight(CodeDisplayList[index]));
+ DisplayList.FormattedParts.AddSelectionAddrHighlight(CodeDisplayList[index]));
}
///
/// Removes an address/label selection highlight from the specified line.
///
/// Line index. If < 0, method has no effect.
- public void CodeListView_RemoveSelectionHighlight(int index) {
+ public void CodeListView_RemoveSelectionAddrHighlight(int index) {
if (index < 0) {
return;
}
CodeListView_ReplaceEntry(index,
- DisplayList.FormattedParts.RemoveSelectionHighlight(CodeDisplayList[index]));
+ DisplayList.FormattedParts.RemoveSelectionAddrHighlight(CodeDisplayList[index]));
+ }
+
+ ///
+ /// Adds an operand selection highlight to the specified line.
+ ///
+ public void CodeListView_AddSelectionOperHighlight(int index) {
+ Debug.Assert(index >= 0);
+ CodeListView_ReplaceEntry(index,
+ DisplayList.FormattedParts.AddSelectionOperHighlight(CodeDisplayList[index]));
+ }
+
+ ///
+ /// Removes an operand selection highlight from the specified line.
+ ///
+ public void CodeListView_RemoveSelectionOperHighlight(int index) {
+ Debug.Assert(index >= 0);
+ if (index >= CodeDisplayList.Count) {
+ // Shouldn't happen unless we resize the list without clearing the highlights.
+ Debug.WriteLine("NOTE: selection oper high index exceeds count (" +
+ index + " vs. " + CodeDisplayList.Count + ")");
+ return;
+ }
+ CodeListView_ReplaceEntry(index,
+ DisplayList.FormattedParts.RemoveSelectionOperHighlight(CodeDisplayList[index]));
}
///