mirror of
https://github.com/fadden/6502bench.git
synced 2024-12-24 22:31:56 +00:00
More progress on visualization
Implemented Apple II hi-res bitmap conversion. Supports B&W and color. Uses essentially the same algorithm as CiderPress. Experimented with displaying non-text items in ListView. I assumed it would work, since it's the sort of thing WPF is designed to do, but it's always wise to approach with caution. Visualization Sets now show a 64x64 button as a placeholder for the eventual thumbnail. Some things were being flaky, which turned out to be because I wasn't Prepare()ing the plugins before using them from Edit Visualization. To make this a deterministic failure I added an Unprepare() call that tells the plugin that we're all done. NOTE: this breaks all existing plugins.
This commit is contained in:
parent
9244ceda7c
commit
365864ccdf
@ -39,6 +39,11 @@ namespace PluginCommon {
|
|||||||
/// <param name="fileData">65xx code and data.</param>
|
/// <param name="fileData">65xx code and data.</param>
|
||||||
/// <param name="addrMap">Mapping between offsets and addresses.</param>
|
/// <param name="addrMap">Mapping between offsets and addresses.</param>
|
||||||
void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans);
|
void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tells the plugin that we're done talking to it for now.
|
||||||
|
/// </summary>
|
||||||
|
void Unprepare();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -138,7 +143,8 @@ namespace PluginCommon {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="descr">VisGen identifier.</param>
|
/// <param name="descr">VisGen identifier.</param>
|
||||||
/// <param name="parms">Parameter set.</param>
|
/// <param name="parms">Parameter set.</param>
|
||||||
/// <returns>2D visualization object reference.</returns>
|
/// <returns>2D visualization object reference, or null if something went
|
||||||
|
/// wrong (unknown ident, bad parameters, etc).</returns>
|
||||||
IVisualization2d Generate2d(VisDescr descr, Dictionary<string, object> parms);
|
IVisualization2d Generate2d(VisDescr descr, Dictionary<string, object> parms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,6 +169,16 @@ namespace PluginCommon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invokes the Unprepare() method on all active plugins.
|
||||||
|
/// </summary>
|
||||||
|
public void UnpreparePlugins() {
|
||||||
|
foreach (KeyValuePair<string, IPlugin> kvp in mActivePlugins) {
|
||||||
|
IPlugin ipl = kvp.Value;
|
||||||
|
ipl.Unprepare();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if any of the plugins report that the before or after label is
|
/// Returns true if any of the plugins report that the before or after label is
|
||||||
/// significant.
|
/// significant.
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using CommonUtil;
|
using CommonUtil;
|
||||||
|
|
||||||
namespace PluginCommon {
|
namespace PluginCommon {
|
||||||
@ -97,5 +97,23 @@ namespace PluginCommon {
|
|||||||
public static int MakeARGB(int a, int r, int g, int b) {
|
public static int MakeARGB(int a, int r, int g, int b) {
|
||||||
return (a << 24) | (r << 16) | (g << 8) | b;
|
return (a << 24) | (r << 16) | (g << 8) | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extracts a typed value from a dictionary with plain object values.
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">Type of value to retrieve.</typeparam>
|
||||||
|
/// <param name="dict">Dictionary with values.</param>
|
||||||
|
/// <param name="key">Entry to find.</param>
|
||||||
|
/// <param name="defVal">Default value.</param>
|
||||||
|
/// <returns>Value found, or the default if the key doesn't exist or the value has the
|
||||||
|
/// wrong type.</returns>
|
||||||
|
public static T GetFromObjDict<T>(Dictionary<string, object> dict, string key, T defVal) {
|
||||||
|
if (dict.TryGetValue(key, out object objVal)) {
|
||||||
|
if (objVal is T) {
|
||||||
|
return (T)objVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defVal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ namespace PluginCommon {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void SetPixelIndex(int x, int y, byte colorIndex) {
|
public void SetPixelIndex(int x, int y, byte colorIndex) {
|
||||||
if (x < 0 || x >= Width || y < 0 || y >= Width) {
|
if (x < 0 || x >= Width || y < 0 || y >= Height) {
|
||||||
throw new ArgumentException("Bad x/y: " + x + "," + y + " (width=" + Width +
|
throw new ArgumentException("Bad x/y: " + x + "," + y + " (width=" + Width +
|
||||||
" height=" + Height + ")");
|
" height=" + Height + ")");
|
||||||
}
|
}
|
||||||
@ -82,7 +82,18 @@ namespace PluginCommon {
|
|||||||
Debug.WriteLine("Palette is full");
|
Debug.WriteLine("Palette is full");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < mNextColor; i++) {
|
||||||
|
if (mPalette[i] == color) {
|
||||||
|
Debug.WriteLine("Color " + color.ToString("x6") +
|
||||||
|
" already exists in palette (" + i + ")");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
mPalette[mNextColor++] = color;
|
mPalette[mNextColor++] = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void AddColor(byte a, byte r, byte g, byte b) {
|
||||||
|
AddColor(Util.MakeARGB(a, r, g, b));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,6 +292,9 @@ namespace SourceGen {
|
|||||||
searchStart = FindFirstUnvisitedInstruction(searchStart);
|
searchStart = FindFirstUnvisitedInstruction(searchStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mScriptManager != null) {
|
||||||
|
mScriptManager.UnprepareScripts();
|
||||||
|
}
|
||||||
mScriptSupport.Shutdown();
|
mScriptSupport.Shutdown();
|
||||||
|
|
||||||
MarkUnexecutedEmbeddedCode();
|
MarkUnexecutedEmbeddedCode();
|
||||||
|
@ -2443,9 +2443,16 @@ namespace SourceGen {
|
|||||||
return bestSym;
|
return bestSym;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Punch-through functions; trying to avoid exposing ScriptManager for now.
|
||||||
public List<PluginCommon.IPlugin> GetActivePlugins() {
|
public List<PluginCommon.IPlugin> GetActivePlugins() {
|
||||||
return mScriptManager.GetActivePlugins();
|
return mScriptManager.GetActivePlugins();
|
||||||
}
|
}
|
||||||
|
public void PrepareScripts(PluginCommon.IApplication appRef) {
|
||||||
|
mScriptManager.PrepareScripts(appRef);
|
||||||
|
}
|
||||||
|
public void UnprepareScripts() {
|
||||||
|
mScriptManager.UnprepareScripts();
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For debugging purposes, get some information about the currently loaded
|
/// For debugging purposes, get some information about the currently loaded
|
||||||
|
@ -354,6 +354,7 @@ namespace SourceGen {
|
|||||||
public string Operand { get; private set; }
|
public string Operand { get; private set; }
|
||||||
public string Comment { get; private set; }
|
public string Comment { get; private set; }
|
||||||
public bool IsLongComment { get; private set; }
|
public bool IsLongComment { get; private set; }
|
||||||
|
public bool IsVisualizationSet { get; private set; }
|
||||||
public bool HasBackgroundColor { get; private set; }
|
public bool HasBackgroundColor { get; private set; }
|
||||||
public Brush BackgroundBrush { get; private set; }
|
public Brush BackgroundBrush { get; private set; }
|
||||||
|
|
||||||
@ -448,6 +449,13 @@ namespace SourceGen {
|
|||||||
return parts;
|
return parts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static FormattedParts CreateVisualizationSet(string summary) {
|
||||||
|
FormattedParts parts = new FormattedParts();
|
||||||
|
parts.Comment = summary;
|
||||||
|
parts.IsVisualizationSet = true;
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
public static FormattedParts AddSelectionHighlight(FormattedParts orig) {
|
public static FormattedParts AddSelectionHighlight(FormattedParts orig) {
|
||||||
FormattedParts newParts = Clone(orig);
|
FormattedParts newParts = Clone(orig);
|
||||||
newParts.HasAddrLabelHighlight = true;
|
newParts.HasAddrLabelHighlight = true;
|
||||||
|
@ -509,7 +509,7 @@ namespace SourceGen {
|
|||||||
// TODO(xyzzy)
|
// TODO(xyzzy)
|
||||||
mProject.VisualizationSets.TryGetValue(line.FileOffset,
|
mProject.VisualizationSets.TryGetValue(line.FileOffset,
|
||||||
out VisualizationSet visSet);
|
out VisualizationSet visSet);
|
||||||
parts = FormattedParts.CreateLongComment("!VISUALIZATION SET! " +
|
parts = FormattedParts.CreateVisualizationSet("!VISUALIZATION SET! " +
|
||||||
(visSet != null ? "VS:" + visSet.Count : "???"));
|
(visSet != null ? "VS:" + visSet.Count : "???"));
|
||||||
break;
|
break;
|
||||||
case Line.Type.Blank:
|
case Line.Type.Blank:
|
||||||
|
@ -54,7 +54,11 @@ namespace RuntimeData.Apple {
|
|||||||
|
|
||||||
mAppRef.DebugLog("GSOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("GSOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
//System.Diagnostics.Debugger.Break();
|
//System.Diagnostics.Debugger.Break();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||||
|
@ -47,6 +47,11 @@ namespace RuntimeData.Apple {
|
|||||||
mAppRef.DebugLog("IIgsToolbox(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("IIgsToolbox(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||||
// Extract the list of function name constants from the platform symbol file.
|
// Extract the list of function name constants from the platform symbol file.
|
||||||
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, TOOLBOX_FUNC_TAG, mAppRef);
|
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, TOOLBOX_FUNC_TAG, mAppRef);
|
||||||
|
@ -166,8 +166,14 @@ namespace RuntimeData.Apple {
|
|||||||
|
|
||||||
mAppRef.DebugLog("ProDOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("ProDOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
//System.Diagnostics.Debugger.Break();
|
//System.Diagnostics.Debugger.Break();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
mAddrTrans = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||||
// Extract the list of function name constants from the platform symbol file.
|
// Extract the list of function name constants from the platform symbol file.
|
||||||
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, P8_MLI_TAG, mAppRef);
|
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, P8_MLI_TAG, mAppRef);
|
||||||
|
@ -51,6 +51,11 @@ namespace RuntimeData.Apple {
|
|||||||
//System.Diagnostics.Debugger.Break();
|
//System.Diagnostics.Debugger.Break();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||||
// Extract the list of function name constants from the platform symbol file.
|
// Extract the list of function name constants from the platform symbol file.
|
||||||
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, SOS_MLI_TAG, mAppRef);
|
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, SOS_MLI_TAG, mAppRef);
|
||||||
|
@ -21,6 +21,7 @@ using PluginCommon;
|
|||||||
|
|
||||||
namespace RuntimeData.Apple {
|
namespace RuntimeData.Apple {
|
||||||
public class VisHiRes : MarshalByRefObject, IPlugin, IPlugin_Visualizer {
|
public class VisHiRes : MarshalByRefObject, IPlugin, IPlugin_Visualizer {
|
||||||
|
// IPlugin
|
||||||
public string Identifier {
|
public string Identifier {
|
||||||
get { return "Apple II Hi-Res Graphic Visualizer"; }
|
get { return "Apple II Hi-Res Graphic Visualizer"; }
|
||||||
}
|
}
|
||||||
@ -32,49 +33,71 @@ namespace RuntimeData.Apple {
|
|||||||
private const string VIS_GEN_BITMAP = "apple2-hi-res-bitmap";
|
private const string VIS_GEN_BITMAP = "apple2-hi-res-bitmap";
|
||||||
private const string VIS_GEN_MULTI_MAP = "apple2-hi-res-multi-map";
|
private const string VIS_GEN_MULTI_MAP = "apple2-hi-res-multi-map";
|
||||||
|
|
||||||
|
private const string P_OFFSET = "offset";
|
||||||
|
private const string P_BYTE_WIDTH = "byteWidth";
|
||||||
|
private const string P_HEIGHT = "height";
|
||||||
|
private const string P_COL_STRIDE = "colStride";
|
||||||
|
private const string P_ROW_STRIDE = "rowStride";
|
||||||
|
private const string P_IS_COLOR = "isColor";
|
||||||
|
private const string P_IS_FIRST_ODD = "isFirstOdd";
|
||||||
|
|
||||||
|
private const string P_ITEM_BYTE_WIDTH = "itemByteWidth";
|
||||||
|
private const string P_ITEM_HEIGHT = "itemHeight";
|
||||||
|
private const string P_COUNT = "count";
|
||||||
|
|
||||||
|
private const int MAX_DIM = 4096;
|
||||||
|
|
||||||
// Visualization descriptors.
|
// Visualization descriptors.
|
||||||
private VisDescr[] mDescriptors = new VisDescr[] {
|
private VisDescr[] mDescriptors = new VisDescr[] {
|
||||||
new VisDescr(VIS_GEN_BITMAP, "Apple II Hi-Res Bitmap", VisDescr.VisType.Bitmap,
|
new VisDescr(VIS_GEN_BITMAP, "Apple II Hi-Res Bitmap", VisDescr.VisType.Bitmap,
|
||||||
new VisParamDescr[] {
|
new VisParamDescr[] {
|
||||||
new VisParamDescr("File offset (hex)",
|
new VisParamDescr("File offset (hex)",
|
||||||
"offset", typeof(int), 0, 0x00ffffff, VisParamDescr.SpecialMode.Offset,
|
P_OFFSET, typeof(int), 0, 0x00ffffff, VisParamDescr.SpecialMode.Offset,
|
||||||
0x2000),
|
0x2000),
|
||||||
new VisParamDescr("Width (in bytes)",
|
new VisParamDescr("Width (in bytes)",
|
||||||
"byteWidth", typeof(int), 1, 40, 0, 1),
|
P_BYTE_WIDTH, typeof(int), 1, 40, 0, 1),
|
||||||
new VisParamDescr("Height",
|
new VisParamDescr("Height",
|
||||||
"height", typeof(int), 1, 192, 0, 1),
|
P_HEIGHT, typeof(int), 1, 192, 0, 1),
|
||||||
new VisParamDescr("Column stride (bytes)",
|
new VisParamDescr("Column stride (bytes)",
|
||||||
"colStride", typeof(int), 0, 256, 0, 0),
|
P_COL_STRIDE, typeof(int), 0, 256, 0, 0),
|
||||||
new VisParamDescr("Row stride (bytes)",
|
new VisParamDescr("Row stride (bytes)",
|
||||||
"rowStride", typeof(int), 0, 256, 0, 0),
|
P_ROW_STRIDE, typeof(int), 0, 256, 0, 0),
|
||||||
new VisParamDescr("Color",
|
new VisParamDescr("Color",
|
||||||
"color", typeof(bool), 0, 0, 0, true),
|
P_IS_COLOR, typeof(bool), 0, 0, 0, true),
|
||||||
new VisParamDescr("First byte odd",
|
new VisParamDescr("First col odd",
|
||||||
"firstOdd", typeof(bool), 0, 0, 0, false),
|
P_IS_FIRST_ODD, typeof(bool), 0, 0, 0, false),
|
||||||
new VisParamDescr("Test Float",
|
new VisParamDescr("Test Float",
|
||||||
"floaty", typeof(float), -5.0f, 5.0f, 0, 0.1f),
|
"floaty", typeof(float), -5.0f, 5.0f, 0, 0.1f),
|
||||||
}),
|
}),
|
||||||
new VisDescr(VIS_GEN_MULTI_MAP, "Apple II Hi-Res Multi-Map", VisDescr.VisType.Bitmap,
|
new VisDescr(VIS_GEN_MULTI_MAP, "Apple II Hi-Res Multi-Map", VisDescr.VisType.Bitmap,
|
||||||
new VisParamDescr[] {
|
new VisParamDescr[] {
|
||||||
new VisParamDescr("File offset (hex)",
|
new VisParamDescr("File offset (hex)",
|
||||||
"offset", typeof(int), 0, 0x00ffffff, VisParamDescr.SpecialMode.Offset,
|
P_OFFSET, typeof(int), 0, 0x00ffffff, VisParamDescr.SpecialMode.Offset,
|
||||||
0x1000),
|
0x1000),
|
||||||
new VisParamDescr("Item width (in bytes)",
|
new VisParamDescr("Item width (in bytes)",
|
||||||
"itemByteWidth", typeof(int), 1, 40, 0, 1),
|
P_ITEM_BYTE_WIDTH, typeof(int), 1, 40, 0, 1),
|
||||||
new VisParamDescr("Item height",
|
new VisParamDescr("Item height",
|
||||||
"itemHeight", typeof(int), 1, 192, 0, 8),
|
P_ITEM_HEIGHT, typeof(int), 1, 192, 0, 8),
|
||||||
new VisParamDescr("Number of items",
|
new VisParamDescr("Number of items",
|
||||||
"count", typeof(int), 1, 256, 0, 1),
|
P_COUNT, typeof(int), 1, 256, 0, 1),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// IPlugin
|
||||||
public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
|
public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
|
||||||
mAppRef = appRef;
|
mAppRef = appRef;
|
||||||
mFileData = fileData;
|
mFileData = fileData;
|
||||||
mAddrTrans = addrTrans;
|
mAddrTrans = addrTrans;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IPlugin
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
mAddrTrans = null;
|
||||||
|
}
|
||||||
|
|
||||||
// IPlugin_Visualizer
|
// IPlugin_Visualizer
|
||||||
public VisDescr[] GetVisGenDescrs() {
|
public VisDescr[] GetVisGenDescrs() {
|
||||||
return mDescriptors;
|
return mDescriptors;
|
||||||
@ -83,17 +106,241 @@ namespace RuntimeData.Apple {
|
|||||||
// IPlugin_Visualizer
|
// IPlugin_Visualizer
|
||||||
public IVisualization2d Generate2d(VisDescr descr,
|
public IVisualization2d Generate2d(VisDescr descr,
|
||||||
Dictionary<string, object> parms) {
|
Dictionary<string, object> parms) {
|
||||||
// TODO: replace with actual
|
switch (descr.Ident) {
|
||||||
VisBitmap8 vb = new VisBitmap8(16, 16);
|
case VIS_GEN_BITMAP:
|
||||||
vb.AddColor(Util.MakeARGB(0xff, 0x40, 0x40, 0x40));
|
return GenerateBitmap(parms);
|
||||||
vb.AddColor(Util.MakeARGB(0xff, 0xff, 0x00, 0x00));
|
case VIS_GEN_MULTI_MAP:
|
||||||
vb.AddColor(Util.MakeARGB(0xff, 0x00, 0xff, 0x80));
|
// TODO
|
||||||
|
return null;
|
||||||
|
default:
|
||||||
|
mAppRef.DebugLog("Unknown ident " + descr.Ident);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < 16; i++) {
|
private IVisualization2d GenerateBitmap(Dictionary<string, object> parms) {
|
||||||
vb.SetPixelIndex(i, i, 1);
|
int offset, byteWidth, height, colStride, rowStride;
|
||||||
vb.SetPixelIndex(15 - i, i, 2);
|
bool isColor, isFirstOdd;
|
||||||
|
|
||||||
|
offset = Util.GetFromObjDict(parms, P_OFFSET, 0);
|
||||||
|
byteWidth = Util.GetFromObjDict(parms, P_BYTE_WIDTH, 0); // width ignoring colStride
|
||||||
|
height = Util.GetFromObjDict(parms, P_HEIGHT, 0);
|
||||||
|
colStride = Util.GetFromObjDict(parms, P_COL_STRIDE, 0);
|
||||||
|
rowStride = Util.GetFromObjDict(parms, P_ROW_STRIDE, 0);
|
||||||
|
isColor = Util.GetFromObjDict(parms, P_IS_COLOR, true);
|
||||||
|
isFirstOdd = Util.GetFromObjDict(parms, P_IS_FIRST_ODD, false);
|
||||||
|
|
||||||
|
// We allow the stride entries to be zero to indicate a "dense" bitmap.
|
||||||
|
if (colStride == 0) {
|
||||||
|
colStride = 1;
|
||||||
|
}
|
||||||
|
if (rowStride == 0) {
|
||||||
|
rowStride = byteWidth * colStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < 0 || offset >= mFileData.Length ||
|
||||||
|
byteWidth <= 0 || byteWidth > MAX_DIM ||
|
||||||
|
height <= 0 || height > MAX_DIM ||
|
||||||
|
colStride <= 0 || colStride > MAX_DIM ||
|
||||||
|
rowStride < byteWidth * colStride - (colStride-1) || rowStride > MAX_DIM) {
|
||||||
|
mAppRef.DebugLog("Invalid parameter");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int lastOffset = offset + rowStride * height - (colStride - 1) - 1;
|
||||||
|
if (lastOffset >= mFileData.Length) {
|
||||||
|
mAppRef.DebugLog("Bitmap runs off end of file (lastOffset=" + lastOffset + ")");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
VisBitmap8 vb = new VisBitmap8(byteWidth * 7, height);
|
||||||
|
SetHiResPalette(vb);
|
||||||
|
|
||||||
|
if (!isColor) {
|
||||||
|
// B&W mode. Since we're not displaying this we don't need to worry about
|
||||||
|
// half-pixel shifts, and can just convert 7 bits to pixels.
|
||||||
|
int bx = 0;
|
||||||
|
int by = 0;
|
||||||
|
for (int row = 0; row < height; row++) {
|
||||||
|
int colIdx = 0;
|
||||||
|
for (int col = 0; col < byteWidth; col++) {
|
||||||
|
byte val = mFileData[offset + colIdx];
|
||||||
|
for (int bit = 0; bit < 7; bit++) {
|
||||||
|
vb.SetPixelIndex(bx, by, (byte)((val & 0x01) + 1)); // black or white
|
||||||
|
val >>= 1;
|
||||||
|
bx++;
|
||||||
|
}
|
||||||
|
colIdx += colStride;
|
||||||
|
}
|
||||||
|
bx = 0;
|
||||||
|
by++;
|
||||||
|
offset += rowStride;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int bx = 0;
|
||||||
|
int by = 0;
|
||||||
|
|
||||||
|
#if false
|
||||||
|
// Color mode. We treat the data as a strictly 140-mode bitmap, which doesn't
|
||||||
|
// quite match up with how the pixels will be displayed, but does allow a
|
||||||
|
// straightforward conversion between file formats. Color fringing is severe.
|
||||||
|
for (int row = 0; row < height; row++) {
|
||||||
|
int lastBit;
|
||||||
|
if (isFirstOdd) {
|
||||||
|
lastBit = 0; // pretend we already have one bit
|
||||||
|
} else {
|
||||||
|
lastBit = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int colByte = 0; colByte < byteWidth; colByte += colStride) {
|
||||||
|
byte val = mFileData[offset + colByte];
|
||||||
|
bool hiBitSet = (val & 0x80) != 0;
|
||||||
|
|
||||||
|
// Grab 3 or 4 pairs of bits.
|
||||||
|
int pairCount = (lastBit < 0) ? 3 : 4;
|
||||||
|
while (pairCount-- > 0) {
|
||||||
|
int twoBits;
|
||||||
|
if (lastBit >= 0) {
|
||||||
|
// merge with bit from previous byte
|
||||||
|
twoBits = (lastBit << 1) | (val & 0x01);
|
||||||
|
val >>= 1;
|
||||||
|
lastBit = -1;
|
||||||
|
} else {
|
||||||
|
// grab two bits
|
||||||
|
twoBits = (val & 0x03);
|
||||||
|
val >>= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hiBitSet) {
|
||||||
|
twoBits += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're in 140 mode, so set two adjacent pixels.
|
||||||
|
vb.SetPixelIndex(bx++, by, sHiResColorMap[twoBits]);
|
||||||
|
vb.SetPixelIndex(bx++, by, sHiResColorMap[twoBits]);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool thisEven = ((colByte & 0x01) == 0) ^ isFirstOdd;
|
||||||
|
if (thisEven) {
|
||||||
|
// started in even column we have one bit left over
|
||||||
|
lastBit = val & 0x01;
|
||||||
|
} else {
|
||||||
|
// started in odd column, all bits consumed
|
||||||
|
lastBit = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bx = 0;
|
||||||
|
by++;
|
||||||
|
offset += rowStride;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Color conversion similar to what CiderPress does, but without the half-pixel
|
||||||
|
// shift (we're trying to create a 1:1 bitmap).
|
||||||
|
bool[] lineBits = new bool[byteWidth * 7];
|
||||||
|
bool[] hiFlags = new bool[byteWidth * 7]; // overkill, but simplifies things
|
||||||
|
int[] colorBuf = new int[byteWidth * 7];
|
||||||
|
for (int row = 0; row < height; row++) {
|
||||||
|
// Unravel the bits.
|
||||||
|
int idx = 0;
|
||||||
|
int colIdx = 0;
|
||||||
|
for (int col = 0; col < byteWidth; col++) {
|
||||||
|
byte val = mFileData[offset + colIdx];
|
||||||
|
bool hiBitSet = (val & 0x80) != 0;
|
||||||
|
|
||||||
|
for (int bit = 0; bit < 7; bit++) {
|
||||||
|
hiFlags[idx] = hiBitSet;
|
||||||
|
lineBits[idx] = (val & 0x01) != 0;
|
||||||
|
idx++;
|
||||||
|
val >>= 1;
|
||||||
|
}
|
||||||
|
colIdx += colStride;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to color.
|
||||||
|
int lastBit = byteWidth * 7;
|
||||||
|
for (idx = 0; idx < lastBit; idx++) {
|
||||||
|
int colorShift = hiFlags[idx] ? 4 : 0;
|
||||||
|
if (!lineBits[idx]) {
|
||||||
|
// Bit not set, set pixel to black.
|
||||||
|
colorBuf[idx] = (int)HiResColors.Black0 + colorShift;
|
||||||
|
} else {
|
||||||
|
// Bit set, set pixel to white or color.
|
||||||
|
if (idx > 0 && colorBuf[idx - 1] != (int)HiResColors.Black0 &&
|
||||||
|
colorBuf[idx - 1] != (int)HiResColors.Black1) {
|
||||||
|
// previous bit was also set, this is white
|
||||||
|
colorBuf[idx] = (int)HiResColors.White0 + colorShift;
|
||||||
|
|
||||||
|
// the previous pixel is part of a run of white
|
||||||
|
colorBuf[idx - 1] = (int)HiResColors.White0 + colorShift;
|
||||||
|
} else {
|
||||||
|
// previous bit not set *or* was first pixel in line;
|
||||||
|
// set color based on whether this is even or odd pixel col
|
||||||
|
bool isOdd = ((idx & 0x01) != 0) ^ isFirstOdd;
|
||||||
|
if (isOdd) {
|
||||||
|
colorBuf[idx] = (int)HiResColors.Green + colorShift;
|
||||||
|
} else {
|
||||||
|
colorBuf[idx] = (int)HiResColors.Purple + colorShift;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we have a run of the same color? If so, smooth the color out.
|
||||||
|
// Note that white blends smoothly with everything.
|
||||||
|
if (idx > 1 && (colorBuf[idx - 2] == colorBuf[idx] ||
|
||||||
|
colorBuf[idx - 2] == (int)HiResColors.White0 ||
|
||||||
|
colorBuf[idx - 2] == (int)HiResColors.White1)) {
|
||||||
|
|
||||||
|
//if (colorBuf[idx - 1] != (int)HiResColors.Black0 &&
|
||||||
|
// colorBuf[idx - 1] != (int) HiResColors.Black1) {
|
||||||
|
// mAppRef.DebugLog("Unexpected color at row=" + by +
|
||||||
|
// " idx=" + idx + ": " + colorBuf[idx - 1]);
|
||||||
|
//}
|
||||||
|
|
||||||
|
colorBuf[idx - 1] = colorBuf[idx];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write to bitmap.
|
||||||
|
for (idx = 0; idx < lastBit; idx++) {
|
||||||
|
vb.SetPixelIndex(bx++, by, sHiResColorMap[colorBuf[idx]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// move to next row
|
||||||
|
bx = 0;
|
||||||
|
by++;
|
||||||
|
offset += rowStride;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
return vb;
|
return vb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private enum HiResColors {
|
||||||
|
Black0 = 0,
|
||||||
|
Green = 1,
|
||||||
|
Purple = 2,
|
||||||
|
White0 = 3,
|
||||||
|
Black1 = 4,
|
||||||
|
Orange = 5,
|
||||||
|
Blue = 6,
|
||||||
|
White1 = 7
|
||||||
|
}
|
||||||
|
|
||||||
|
// HiRes: black0, green, purple, white0, black1, orange, blue, white1
|
||||||
|
private static readonly byte[] sHiResColorMap = new byte[8] {
|
||||||
|
1, 3, 4, 2, 1, 5, 6, 2
|
||||||
|
};
|
||||||
|
|
||||||
|
private void SetHiResPalette(VisBitmap8 vb) {
|
||||||
|
// These don't match directly to hi-res color numbers because we want to
|
||||||
|
// avoid adding black/white twice.
|
||||||
|
vb.AddColor(0xff, 0xff, 0, 0); // 0=transparent (xyzzy: all 0)
|
||||||
|
vb.AddColor(0xff, 0x00, 0x00, 0x00); // 1=black0/black1
|
||||||
|
vb.AddColor(0xff, 0xff, 0xff, 0xff); // 2=white0/white1
|
||||||
|
vb.AddColor(0xff, 0x11, 0xdd, 0x00); // 3=green
|
||||||
|
vb.AddColor(0xff, 0xdd, 0x22, 0xdd); // 4=purple
|
||||||
|
vb.AddColor(0xff, 0xff, 0x66, 0x00); // 5=orange
|
||||||
|
vb.AddColor(0xff, 0x22, 0x22, 0xff); // 6=blue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,11 @@ namespace RuntimeData.Test2011 {
|
|||||||
mAppRef.DebugLog("Test2011(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("Test2011(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void CheckJsr(int offset, int operand, out bool noContinue) {
|
public void CheckJsr(int offset, int operand, out bool noContinue) {
|
||||||
int ADDR = 0x2456;
|
int ADDR = 0x2456;
|
||||||
|
|
||||||
|
@ -31,6 +31,12 @@ namespace RuntimeData.Test2022 {
|
|||||||
|
|
||||||
mAppRef.DebugLog("Test2022-A(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("Test2022-A(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||||
foreach (PlSymbol sym in plSyms) {
|
foreach (PlSymbol sym in plSyms) {
|
||||||
switch (sym.Label) {
|
switch (sym.Label) {
|
||||||
|
@ -26,6 +26,12 @@ namespace RuntimeData.Test2022 {
|
|||||||
mAppRef.DebugLog("Test2022-B(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("Test2022-B(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
mAddrTrans = null;
|
||||||
|
}
|
||||||
|
|
||||||
public void CheckBrk(int offset, bool twoByteBrk, out bool noContinue) {
|
public void CheckBrk(int offset, bool twoByteBrk, out bool noContinue) {
|
||||||
noContinue = true;
|
noContinue = true;
|
||||||
|
|
||||||
|
@ -173,6 +173,22 @@ namespace SourceGen.Sandbox {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Puts scripts back to sleep.
|
||||||
|
/// </summary>
|
||||||
|
public void UnprepareScripts() {
|
||||||
|
if (DomainMgr == null) {
|
||||||
|
foreach (KeyValuePair<string, IPlugin> kvp in mActivePlugins) {
|
||||||
|
IPlugin ipl = kvp.Value;
|
||||||
|
ipl.Unprepare();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
List<AddressMap.AddressMapEntry> addrEnts = mProject.AddrMap.GetEntryList();
|
||||||
|
DomainMgr.PluginMgr.UnpreparePlugins();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns true if any of the plugins report that the before or after label is
|
/// Returns true if any of the plugins report that the before or after label is
|
||||||
/// significant.
|
/// significant.
|
||||||
|
@ -38,15 +38,15 @@ namespace SourceGen {
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, object> VisGenParams { get; private set; }
|
public Dictionary<string, object> VisGenParams { get; private set; }
|
||||||
|
|
||||||
public double Thumbnail { get; } // TODO - 64x64(?) bitmap
|
private BitmapSource Thumbnail { get; set; } // TODO - 64x64(?) bitmap
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="tag"></param>
|
/// <param name="tag">Unique identifier.</param>
|
||||||
/// <param name="visGenIdent"></param>
|
/// <param name="visGenIdent">Visualization generator identifier.</param>
|
||||||
/// <param name="visGenParams"></param>
|
/// <param name="visGenParams">Parameters for visualization generator.</param>
|
||||||
public Visualization(string tag, string visGenIdent,
|
public Visualization(string tag, string visGenIdent,
|
||||||
Dictionary<string, object> visGenParams) {
|
Dictionary<string, object> visGenParams) {
|
||||||
Tag = tag;
|
Tag = tag;
|
||||||
@ -54,7 +54,12 @@ namespace SourceGen {
|
|||||||
VisGenParams = visGenParams;
|
VisGenParams = visGenParams;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BitmapSource CreateBitmapSource(IVisualization2d vis2d) {
|
/// <summary>
|
||||||
|
/// Converts an IVisualization2d to a BitmapSource for display.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="vis2d"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static BitmapSource ConvertToBitmapSource(IVisualization2d vis2d) {
|
||||||
// Create indexed color palette.
|
// Create indexed color palette.
|
||||||
int[] intPal = vis2d.GetPalette();
|
int[] intPal = vis2d.GetPalette();
|
||||||
List<Color> colors = new List<Color>(intPal.Length);
|
List<Color> colors = new List<Color>(intPal.Length);
|
||||||
|
@ -76,6 +76,38 @@ See also https://github.com/fadden/DisasmUiTest
|
|||||||
Width="{Binding LongCommentWidth}"/>
|
Width="{Binding LongCommentWidth}"/>
|
||||||
</GridViewColumnCollection>
|
</GridViewColumnCollection>
|
||||||
|
|
||||||
|
<GridViewColumnCollection x:Key="gvcc_vs">
|
||||||
|
<GridViewColumn DisplayMemberBinding="{Binding Offset}" Width="{Binding
|
||||||
|
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}
|
||||||
|
}, Path=View.Columns[0].ActualWidth}"/>
|
||||||
|
<GridViewColumn DisplayMemberBinding="{Binding Addr}" Width="{Binding
|
||||||
|
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}
|
||||||
|
}, Path=View.Columns[1].ActualWidth}"/>
|
||||||
|
<GridViewColumn DisplayMemberBinding="{Binding Bytes}" Width="{Binding
|
||||||
|
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}
|
||||||
|
}, Path=View.Columns[2].ActualWidth}"/>
|
||||||
|
<GridViewColumn DisplayMemberBinding="{Binding Flags}" Width="{Binding
|
||||||
|
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}
|
||||||
|
}, Path=View.Columns[3].ActualWidth}"/>
|
||||||
|
<GridViewColumn DisplayMemberBinding="{Binding Attr}" Width="{Binding
|
||||||
|
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}
|
||||||
|
}, Path=View.Columns[4].ActualWidth}"/>
|
||||||
|
<!-- This column holds the long comment. There's no easy way to set its width, so we
|
||||||
|
have to let the main window take care of that. (It's tempting to just make its width
|
||||||
|
very large, but that causes the GridView contents to horizontally scroll independently
|
||||||
|
of the GridView header when you reach the edge of the "normal" column set.) -->
|
||||||
|
<GridViewColumn Header="(visualization set)" Width="{Binding LongCommentWidth}">
|
||||||
|
<GridViewColumn.CellTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Text="{Binding Path=Comment}" VerticalAlignment="Center"/>
|
||||||
|
<Button Width="64" Height="64" Content="Whee"/>
|
||||||
|
</StackPanel>
|
||||||
|
</DataTemplate>
|
||||||
|
</GridViewColumn.CellTemplate>
|
||||||
|
</GridViewColumn>
|
||||||
|
</GridViewColumnCollection>
|
||||||
|
|
||||||
<!-- Base template for ListView items, derived from the system default. We have to define
|
<!-- Base template for ListView items, derived from the system default. We have to define
|
||||||
this fully so things don't turn into a big mess on long-comment lines. -->
|
this fully so things don't turn into a big mess on long-comment lines. -->
|
||||||
<ControlTemplate x:Key="baseListItemTemplate" TargetType="{x:Type ListViewItem}">
|
<ControlTemplate x:Key="baseListItemTemplate" TargetType="{x:Type ListViewItem}">
|
||||||
@ -199,6 +231,68 @@ See also https://github.com/fadden/DisasmUiTest
|
|||||||
</ControlTemplate.Triggers>
|
</ControlTemplate.Triggers>
|
||||||
</ControlTemplate>
|
</ControlTemplate>
|
||||||
|
|
||||||
|
<!-- yet another copy of the template, this one for VisualizationSet lines -->
|
||||||
|
<ControlTemplate x:Key="visualizationSetTemplate" TargetType="{x:Type ListViewItem}">
|
||||||
|
<StackPanel>
|
||||||
|
<Border BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
CornerRadius="2"
|
||||||
|
SnapsToDevicePixels="true">
|
||||||
|
<Border x:Name="InnerBorder" BorderThickness="1" CornerRadius="1">
|
||||||
|
<Grid>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition MaxHeight="11"/>
|
||||||
|
<RowDefinition/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Rectangle x:Name="UpperHighlight" Fill="#75ffffff" Visibility="Collapsed"/>
|
||||||
|
<GridViewRowPresenter Content="{TemplateBinding Content}"
|
||||||
|
Columns="{StaticResource gvcc_vs}"
|
||||||
|
Grid.RowSpan="2"
|
||||||
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- triggers for hover, selection, and activation effects -->
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="true">
|
||||||
|
<Setter Property="Background" Value="{StaticResource ListItemHoverFill}"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource Brush_MouseOverBorder}"/>
|
||||||
|
<Setter Property="Visibility" TargetName="UpperHighlight" Value="Visible"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsSelected" Value="true">
|
||||||
|
<Setter Property="Background" Value="{StaticResource ListItemSelectedFill}"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource Brush_SelectedBorder}"/>
|
||||||
|
<Setter Property="BorderBrush" TargetName="InnerBorder" Value="#80FFFFFF"/>
|
||||||
|
<Setter Property="Visibility" TargetName="UpperHighlight" Value="Visible"/>
|
||||||
|
<Setter Property="Fill" TargetName="UpperHighlight" Value="#40FFFFFF"/>
|
||||||
|
</Trigger>
|
||||||
|
<MultiTrigger>
|
||||||
|
<MultiTrigger.Conditions>
|
||||||
|
<Condition Property="IsSelected" Value="true"/>
|
||||||
|
<Condition Property="Selector.IsSelectionActive" Value="false"/>
|
||||||
|
</MultiTrigger.Conditions>
|
||||||
|
<Setter Property="Background" Value="{StaticResource ListItemSelectedInactiveFill}"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource Brush_SelectedActiveBorder}"/>
|
||||||
|
</MultiTrigger>
|
||||||
|
<MultiTrigger>
|
||||||
|
<MultiTrigger.Conditions>
|
||||||
|
<Condition Property="IsSelected" Value="true"/>
|
||||||
|
<Condition Property="IsMouseOver" Value="true"/>
|
||||||
|
</MultiTrigger.Conditions>
|
||||||
|
<Setter Property="Background" Value="{StaticResource ListItemSelectedHoverFill}"/>
|
||||||
|
<Setter Property="BorderBrush" Value="{DynamicResource Brush_SelectedMouseOverBorder}"/>
|
||||||
|
</MultiTrigger>
|
||||||
|
<Trigger Property="IsEnabled" Value="false">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
|
||||||
|
|
||||||
<!-- ListView style. We have to override the general foreground/background colors to
|
<!-- ListView style. We have to override the general foreground/background colors to
|
||||||
avoid making the whole thing look freakish. -->
|
avoid making the whole thing look freakish. -->
|
||||||
<Style x:Key="codeListStyle" TargetType="{x:Type ListView}">
|
<Style x:Key="codeListStyle" TargetType="{x:Type ListView}">
|
||||||
@ -225,6 +319,9 @@ See also https://github.com/fadden/DisasmUiTest
|
|||||||
<DataTrigger Binding="{Binding Path=IsLongComment}" Value="True">
|
<DataTrigger Binding="{Binding Path=IsLongComment}" Value="True">
|
||||||
<Setter Property="Template" Value="{StaticResource longCommentTemplate}"/>
|
<Setter Property="Template" Value="{StaticResource longCommentTemplate}"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
|
<DataTrigger Binding="{Binding Path=IsVisualizationSet}" Value="True">
|
||||||
|
<Setter Property="Template" Value="{StaticResource visualizationSetTemplate}"/>
|
||||||
|
</DataTrigger>
|
||||||
<DataTrigger Binding="{Binding Path=HasBackgroundColor}" Value="True">
|
<DataTrigger Binding="{Binding Path=HasBackgroundColor}" Value="True">
|
||||||
<Setter Property="Background" Value="{Binding Path=BackgroundBrush}"/>
|
<Setter Property="Background" Value="{Binding Path=BackgroundBrush}"/>
|
||||||
</DataTrigger>
|
</DataTrigger>
|
||||||
|
@ -25,7 +25,8 @@ limitations under the License.
|
|||||||
Title="Edit Visualization"
|
Title="Edit Visualization"
|
||||||
Width="460" SizeToContent="Height" ResizeMode="NoResize"
|
Width="460" SizeToContent="Height" ResizeMode="NoResize"
|
||||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||||
Loaded="Window_Loaded">
|
Loaded="Window_Loaded"
|
||||||
|
Closed="Window_Closed">
|
||||||
|
|
||||||
<Window.Resources>
|
<Window.Resources>
|
||||||
<!-- big thanks: http://drwpf.com/blog/2008/01/03/itemscontrol-d-is-for-datatemplate/ -->
|
<!-- big thanks: http://drwpf.com/blog/2008/01/03/itemscontrol-d-is-for-datatemplate/ -->
|
||||||
@ -125,7 +126,8 @@ limitations under the License.
|
|||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Border Grid.Row="1" BorderThickness="1"
|
<Border Grid.Row="1" BorderThickness="1"
|
||||||
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}">
|
BorderBrush="{DynamicResource {x:Static SystemColors.WindowFrameBrushKey}}"
|
||||||
|
Background="LightGray">
|
||||||
<Image Name="previewImage" Width="400" Height="400" Source="/Res/AboutImage.png"
|
<Image Name="previewImage" Width="400" Height="400" Source="/Res/AboutImage.png"
|
||||||
RenderOptions.BitmapScalingMode="NearestNeighbor"/>
|
RenderOptions.BitmapScalingMode="NearestNeighbor"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
@ -100,6 +100,21 @@ namespace SourceGen.WpfGui {
|
|||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ScriptSupport : MarshalByRefObject, PluginCommon.IApplication {
|
||||||
|
public ScriptSupport() { }
|
||||||
|
public void DebugLog(string msg) {
|
||||||
|
Debug.WriteLine("Vis plugin: " + msg);
|
||||||
|
}
|
||||||
|
public bool SetOperandFormat(int offset, DataSubType subType, string label) {
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
public bool SetInlineDataFormat(int offset, int length, DataType type,
|
||||||
|
DataSubType subType, string label) {
|
||||||
|
throw new InvalidOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private ScriptSupport mScriptSupport = new ScriptSupport();
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
@ -140,6 +155,7 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
// Set the selection. This should cause the sel change event to fire.
|
// Set the selection. This should cause the sel change event to fire.
|
||||||
visComboBox.SelectedIndex = visSelection;
|
visComboBox.SelectedIndex = visSelection;
|
||||||
|
mProject.PrepareScripts(mScriptSupport);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -188,6 +204,10 @@ namespace SourceGen.WpfGui {
|
|||||||
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
private void Window_Loaded(object sender, RoutedEventArgs e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Window_Closed(object sender, EventArgs e) {
|
||||||
|
mProject.UnprepareScripts();
|
||||||
|
}
|
||||||
|
|
||||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||||
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
|
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
|
||||||
Debug.Assert(item != null);
|
Debug.Assert(item != null);
|
||||||
@ -305,12 +325,27 @@ namespace SourceGen.WpfGui {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!IsValid) {
|
if (!IsValid) {
|
||||||
|
// TODO(xyzzy): default to a meaningful image
|
||||||
previewImage.Source = new BitmapImage(new Uri("pack://application:,,,/Res/Logo.png"));
|
previewImage.Source = new BitmapImage(new Uri("pack://application:,,,/Res/Logo.png"));
|
||||||
} else {
|
} else {
|
||||||
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
|
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
|
||||||
IVisualization2d vis2d = item.Plugin.Generate2d(item.VisDescriptor,
|
IVisualization2d vis2d;
|
||||||
|
try {
|
||||||
|
vis2d = item.Plugin.Generate2d(item.VisDescriptor,
|
||||||
CreateVisGenParams());
|
CreateVisGenParams());
|
||||||
previewImage.Source = Visualization.CreateBitmapSource(vis2d);
|
if (vis2d == null) {
|
||||||
|
Debug.WriteLine("Vis generator returned null");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
// TODO(xyzzy): use different image for failure
|
||||||
|
Debug.WriteLine("Vis generation failed: " + ex.Message);
|
||||||
|
vis2d = null;
|
||||||
|
}
|
||||||
|
if (vis2d == null) {
|
||||||
|
previewImage.Source = new BitmapImage(new Uri("pack://application:,,,/Res/Logo.png"));
|
||||||
|
} else {
|
||||||
|
previewImage.Source = Visualization.ConvertToBitmapSource(vis2d);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +98,9 @@ namespace SourceGen.WpfGui {
|
|||||||
|
|
||||||
private void EditButton_Click(object sender, RoutedEventArgs e) {
|
private void EditButton_Click(object sender, RoutedEventArgs e) {
|
||||||
Dictionary<string, object> testDict = new Dictionary<string, object>();
|
Dictionary<string, object> testDict = new Dictionary<string, object>();
|
||||||
testDict.Add("offset", 0x1234);
|
testDict.Add("offset", 0);
|
||||||
testDict.Add("height", 57);
|
testDict.Add("byteWidth", 2);
|
||||||
|
testDict.Add("height", 7);
|
||||||
EditVisualization dlg = new EditVisualization(this, mProject, mFormatter,
|
EditVisualization dlg = new EditVisualization(this, mProject, mFormatter,
|
||||||
new Visualization("arbitrary tag", "apple2-hi-res-bitmap", testDict));
|
new Visualization("arbitrary tag", "apple2-hi-res-bitmap", testDict));
|
||||||
if (dlg.ShowDialog() == true) {
|
if (dlg.ShowDialog() == true) {
|
||||||
|
Loading…
Reference in New Issue
Block a user