/* * Copyright 2018 faddenSoft * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Collections.Generic; namespace PluginCommon { /// /// Extension script "plugins" must implement this interface. /// public interface IPlugin { /// /// Identification string. Contents are arbitrary, but should briefly identify the /// purpose of the plugin, e.g. "Apple II ProDOS 8 MLI call handler". It may /// contain version information, but should not be expected to be machine-readable. /// string Identifier { get; } /// /// Prepares the plugin for action. Called at the start of every code analysis pass. /// /// In the current implementation, the file data will be the same every time, /// because it doesn't change after the project is opened. However, this could /// change if we add a descramble feature. /// /// Reference to application interface. /// 65xx code and data. /// Mapping between offsets and addresses. void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans); } /// /// Extension scripts that want to receive the list of symbols must implement this interface. /// public interface IPlugin_SymbolList { /// /// Receives a list of the currently defined platform, project, and user symbols. /// The list does not include auto-generated labels or local variables. /// /// This is called immediately after Prepare(), before any other interfaces are /// invoked, at the start of every code analysis pass. /// /// Symbols available to plugins, in no particular order. void UpdateSymbolList(List plSyms); /// /// Handles a notification that a user symbol has been added, edited, or removed. If the /// label is of interest to the plugin, e.g. it changes how the plugin formats code or /// data, the app needs to know. /// /// /// The application does a full re-analysis when project properties change, but not /// when labels are edited. The CheckJsr/Jsl/Brk methods are only called during code /// analysis, so if their behavior changes based on the presence or absence of a user /// label then we need to tell the application that a full re-analysis is needed. /// /// Plugins that don't care about user symbols, e.g. that just use tagged platform /// symbols, can simply return false. (Changes to user labels that overlap with /// project/platform symbols are detected by the app.) /// /// The label before the change, or empty if this is a /// newly-added label. /// The label after the change, or empty if the label was /// removed. /// True if the label change could affect the plugin's actions. bool IsLabelSignificant(string beforeLabel, string afterLabel); } /// /// Extension scripts that want to handle inline JSRs must implement this interface. /// public interface IPlugin_InlineJsr { /// /// Checks to see if code/data near a JSR instruction should be formatted. /// /// The file data is guaranteed to hold all bytes of the JSR (offset + 2). /// /// Offset of the JSR instruction. /// 16-bit JSR operand. /// Set to true if the JSR doesn't actually return. void CheckJsr(int offset, int operand, out bool noContinue); } /// /// Extension scripts that want to handle inline JSLs must implement this interface. /// public interface IPlugin_InlineJsl { /// /// Checks to see if code/data near a JSL instruction should be formatted. /// /// The file data is guaranteed to hold all bytes of the JSL (offset + 3). /// /// Offset of the JSL instruction. /// 24-bit JSL operand. /// Set to true if the JSL doesn't actually return. void CheckJsl(int offset, int operand, out bool noContinue); } /// /// Extension scripts that want to handle inline BRKs must implement this interface. /// public interface IPlugin_InlineBrk { /// /// Checks to see if code/data near a BRK instruction should be formatted. /// /// The file data is only guaranteed to hold the BRK opcode byte. /// /// Offset of the BRK instruction. /// True if the CPU is configured for two-byte BRKs. /// Set to true if the BRK doesn't actually return. void CheckBrk(int offset, bool isTwoBytes, out bool noContinue); } /// /// Extension scripts that want to generate visualizations must implement this interface. /// public interface IPlugin_Visualizer { /// /// Retrieves a list of descriptors for visualization generators implemented by this /// plugin. The caller must not modify the contents. /// VisDescr[] GetVisGenDescrs(); /// /// Executes the specified visualization generator with the supplied parameters. /// /// VisGen identifier. /// Parameter set. /// 2D visualization object reference. IVisualization2d Generate2d(VisDescr descr, Dictionary parms); } [Serializable] public class VisDescr { /// /// Unique identifier. This is stored in the project file. /// public string Ident { get; private set; } /// /// Human-readable string describing the visualizer. Used for combo boxes and /// other UI elements. /// public string UiName { get; private set; } public enum VisType { Unknown = 0, Bitmap, // 2D bitmap } /// /// Visualization type. /// public VisType VisualizationType { get; private set; } /// /// Visualization parameter descriptors. /// public VisParamDescr[] VisParamDescrs { get; private set; } public VisDescr(string ident, string uiName, VisType type, VisParamDescr[] descrs) { Ident = ident; UiName = uiName; VisualizationType = type; VisParamDescrs = descrs; } } /// /// Visualization parameter descriptor. /// [Serializable] public class VisParamDescr { public enum SpecialMode { None = 0, Offset } public string UiLabel { get; private set; } public string Name { get; private set; } public Type CsType { get; private set; } // Min/Max values for ints and floats. Could also be length for strings. // NOTE: ideally we'd provide a "verify" function that tested individual fields and // could also see other fields, e.g. to confirm that Stride >= Width. public object Min { get; private set; } public object Max { get; private set; } public SpecialMode Special { get; private set; } public object DefaultValue { get; private set; } public VisParamDescr(string uiLabel, string name, Type csType, object min, object max, SpecialMode special, object defVal) { UiLabel = uiLabel; Name = name; CsType = csType; Min = min; Max = max; Special = special; DefaultValue = defVal; } } /// /// Rendered 2D visualization. The object represents the "raw" form of the data, /// without scaling or filtering. /// public interface IVisualization2d { int GetWidth(); int GetHeight(); int GetPixel(int x, int y); // returns ARGB value // TODO(maybe): pixel aspect ratio } /// /// Interfaces provided by the application for use by plugins. An IApplication instance /// is passed to the plugin as an argument Prepare(). /// public interface IApplication { /// /// Sends a debug message to the application. This can be useful when debugging scripts. /// (Use DEBUG > Show Analyzer Output to view it.) /// /// Message to send. void DebugLog(string msg); /// /// Specifies operand formatting. /// /// File offset of opcode. /// Sub-type. Must be appropriate for NumericLE. /// Optional symbolic label. /// True if the change was made, false if it was rejected. bool SetOperandFormat(int offset, DataSubType subType, string label); /// /// Formats file data as inline data. /// /// File offset. /// Length of item. /// Type of item. Must be NumericLE, NumericBE, or Dense. /// Sub-type. Must be appropriate for type. /// Optional symbolic label. /// True if the change was made, false if it was rejected (e.g. because /// the area is already formatted, or contains code). /// If something is really wrong, e.g. data runs /// off end of file. bool SetInlineDataFormat(int offset, int length, DataType type, DataSubType subType, string label); } /// /// Data format type. /// /// /// Essentially a clone of FormatDescriptor.Type. /// public enum DataType { Unknown = 0, NumericLE, NumericBE, StringGeneric, StringReverse, StringNullTerm, StringL8, StringL16, StringDci, Dense, Fill } /// /// Data format sub-type. /// /// /// Essentially a clone of FormatDescriptor.SubType. /// public enum DataSubType { // No sub-type specified. None = 0, // For NumericLE/BE Hex, Decimal, Binary, Address, Symbol, // Strings and NumericLE/BE (single character) Ascii, HighAscii, C64Petscii, C64Screen } }