Exemplo n.º 1
0
        // If this is the kind of warp which points to another warp, return the
        // pointed warp, otherwise return null
        public WarpSourceData GetPointedWarp()
        {
            if (WarpSourceType != WarpSourceType.PointerWarp)
            {
                return(null);
            }

            WarpSourceData data = (WarpSourceData)Project.GetData(GetValue("Pointer"));

            return(data);
        }
Exemplo n.º 2
0
        // Returns the number of PointedWarps there are after and including
        // this one. This is the number of times (plus one) that you can call
        // GetNextWarp() before you get a null value.
        //
        // If called on a PointerWarp, it returns the corresponding value for
        // its PointedWarp.
        public int GetPointedChainLength()
        {
            if (WarpSourceType == WarpSourceType.PointerWarp)
            {
                return(GetPointedWarp().GetPointedChainLength());
            }

            WarpSourceData next = GetNextWarp();

            if (next == null)
            {
                return(1);
            }

            return(1 + next.GetPointedChainLength());
        }
Exemplo n.º 3
0
        protected void OnAddWarpButtonClicked(object sender, EventArgs e)
        {
            WarpSourceData data = new WarpSourceData(Project,
                                                     WarpSourceData.WarpCommands[(int)WarpSourceType.StandardWarp],
                                                     WarpSourceData.DefaultValues[(int)WarpSourceType.StandardWarp],
                                                     sourceGroup.FileParser,
                                                     new List <int> {
                -1
            });

            data.Map        = map;
            data.Transition = 4;

            sourceGroup.AddWarpSourceData(data);

            SetWarpIndex((int)indexSpinButton.Adjustment.Upper + 1);
        }
Exemplo n.º 4
0
        public bool SetNextWarp(WarpSourceData next)
        {
            if (!FileParser.InsertComponentAfter(this, next))
            {
                return(false);
            }

            this.Opcode &= ~0x80;
            if (next.GetNextWarp() == null)
            {
                next.Opcode |= 0x80;
            }
            else
            {
                next.Opcode &= 0x80;
            }
            return(true);
        }
Exemplo n.º 5
0
        internal WarpSourceGroup(Project p, int id) : base(p, id)
        {
            fileParser = Project.GetFileWithLabel("warpSourcesTable");
            Data   d     = fileParser.GetData("warpSourcesTable", id * 2);
            string label = d.GetValue(0);

            warpSourceDataList = new List <WarpSourceData>();
            WarpSourceData warpData = fileParser.GetData(label) as WarpSourceData;

            while (warpData != null && warpData.WarpSourceType != WarpSourceType.WarpSourcesEnd)
            {
                warpSourceDataList.Add(warpData);
                warpData = warpData.NextData as WarpSourceData;
            }
            if (warpData != null)
            {
                warpSourceDataList.Add(warpData); // WarpSourcesEnd
            }
        }
Exemplo n.º 6
0
        protected void OnAddSpecificWarpButtonClicked(object sender, EventArgs e)
        {
            // Check if a pointer warp already exists
            List <WarpSourceData> warps = sourceGroup.GetMapWarpSourceData(map);

            foreach (WarpSourceData sourceData in warps)
            {
                if (sourceData.WarpSourceType == WarpSourceType.PointerWarp)
                {
                    // Warning dialog
                    Gtk.MessageDialog d = new Gtk.MessageDialog(null,
                                                                DialogFlags.DestroyWithParent,
                                                                MessageType.Warning,
                                                                ButtonsType.YesNo,
                                                                "This map already has specific-position warp data; adding another would be redundant. Continue anyway?");
                    Gtk.ResponseType response = (ResponseType)d.Run();
                    d.Destroy();

                    if (response == ResponseType.Yes)
                    {
                        break;
                    }
                    else
                    {
                        return;
                    }
                }
            }

            WarpSourceData data = new WarpSourceData(Project,
                                                     WarpSourceData.WarpCommands[(int)WarpSourceType.PointerWarp],
                                                     WarpSourceData.DefaultValues[(int)WarpSourceType.PointerWarp],
                                                     sourceGroup.FileParser,
                                                     new List <int> {
                -1, 2
            });

            data.Map = map;

            sourceGroup.AddWarpSourceData(data);

            SetWarpIndex((int)indexSpinButton.Adjustment.Upper + 1);
        }
Exemplo n.º 7
0
        // Adds the given data to the end of the group and inserts the data
        // into the FileParser.
        public void AddWarpSourceData(WarpSourceData data)
        {
            if (warpSourceDataList.Contains(data))
            {
                return;
            }

            // Assumes the last element of warpSourceDataList is always the
            // m_WarpSourcesEnd command
            fileParser.InsertComponentBefore(EndData, data);
            warpSourceDataList.Insert(warpSourceDataList.Count - 1, data);

            if (data.WarpSourceType == WarpSourceType.PointerWarp && data.PointerString == ".")
            {
                // Create a unique pointer after m_WarpSourcesEnd
                int    nameIndex = 0;
                string name;
                do
                {
                    name = "customWarpSource" + nameIndex.ToString("d2");
                    nameIndex++;
                }while (Project.HasLabel(name));

                data.PointerString = name;

                Label newLabel = new Label(FileParser, name);
                // Insert label after m_WarpSourcesEnd
                FileParser.InsertComponentAfter(EndData, newLabel);

                // Create a blank PointedData to go after this label
                WarpSourceData pointedData = new WarpSourceData(Project,
                                                                WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp],
                                                                WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp],
                                                                FileParser,
                                                                new List <int> {
                    -1
                });
                pointedData.Opcode     = 0x80;
                pointedData.Transition = 4;
                FileParser.InsertComponentAfter(newLabel, pointedData);
            }
        }
Exemplo n.º 8
0
        // Adds the given data to the end of the group and inserts the data
        // into the FileParser.
        public void AddWarpSourceData(WarpSourceData data)
        {
            if (warpSourceDataList.Contains(data))
                return;

            // Assumes the last element of warpSourceDataList is always the
            // m_WarpSourcesEnd command
            fileParser.InsertComponentBefore(EndData, data);
            warpSourceDataList.Insert(warpSourceDataList.Count-1, data);

            if (data.WarpSourceType == WarpSourceType.PointerWarp && data.PointerString == ".") {
                // Create a unique pointer after m_WarpSourcesEnd
                int nameIndex = 0;
                string name;
                do {
                    name = "customWarpSource" + nameIndex.ToString("d2");
                    nameIndex++;
                }
                while (Project.HasLabel(name));

                data.PointerString = name;

                Label newLabel = new Label(FileParser, name);
                // Insert label after m_WarpSourcesEnd
                FileParser.InsertComponentAfter(EndData, newLabel);

                // Create a blank PointedData to go after this label
                WarpSourceData pointedData = new WarpSourceData(Project,
                        WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp],
                        WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp],
                        FileParser,
                        new List<int>{-1});
                pointedData.Opcode = 0x80;
                pointedData.Transition = 4;
                FileParser.InsertComponentAfter(newLabel, pointedData);
            }
        }
Exemplo n.º 9
0
        public void RemoveWarpSourceData(WarpSourceData data)
        {
            if (!warpSourceDataList.Contains(data))
            {
                return;
            }

            if (data.WarpSourceType == WarpSourceType.PointerWarp)
            {
                WarpSourceData pointedData = data.GetPointedWarp();
                // Delete label
                fileParser.RemoveFileComponent(fileParser.GetDataLabel(pointedData));
                // Delete after the label
                while (pointedData != null)
                {
                    WarpSourceData next = pointedData.GetNextWarp();
                    pointedData.FileParser.RemoveFileComponent(pointedData);
                    pointedData = next;
                }
            }

            data.FileParser.RemoveFileComponent(data);
            warpSourceDataList.Remove(data);
        }
Exemplo n.º 10
0
        public void RemoveWarpSourceData(WarpSourceData data)
        {
            if (!warpSourceDataList.Contains(data))
                return;

            if (data.WarpSourceType == WarpSourceType.PointerWarp) {
                WarpSourceData pointedData = data.GetPointedWarp();
                // Delete label
                fileParser.RemoveFileComponent(fileParser.GetDataLabel(pointedData));
                // Delete after the label
                while (pointedData != null) {
                    WarpSourceData next = pointedData.GetNextWarp();
                    pointedData.FileParser.RemoveFileComponent(pointedData);
                    pointedData = next;
                }
            }

            data.FileParser.RemoveFileComponent(data);
            warpSourceDataList.Remove(data);
        }
Exemplo n.º 11
0
        // Load the i'th warp in the current map.
        void SetWarpIndex(int i)
        {
            List <WarpSourceData> sourceDataList = sourceGroup.GetMapWarpSourceData(map);

            indexSpinButton.Adjustment.Lower = -1;
            indexSpinButton.Adjustment.Upper = sourceDataList.Count - 1;

            if (i > indexSpinButton.Adjustment.Upper)
            {
                i = (int)indexSpinButton.Adjustment.Upper;
            }

            indexSpinButton.Value = i;

            valueEditorContainer.Remove(valueEditorContainer.Child);

            if (i == -1)
            {
                SetDestIndex(-1, -1);
                return;
            }

            Gtk.HBox hbox = new Gtk.HBox();

            WarpSourceData warpSourceData = sourceDataList[i];

            if (warpSourceData.WarpSourceType == WarpSourceType.StandardWarp)
            {
                SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex);
            }

            sourceEditor = new ValueReferenceEditor(Project,
                                                    warpSourceData);

            Alignment a = new Alignment(0, 0, 0, 0);

            a.Add(sourceEditor);
            hbox.Add(a);

            if (warpSourceData.WarpSourceType == WarpSourceType.PointerWarp)
            {
                Table table = new Table(1, 1, false);
                table.ColumnSpacing = 6;
                table.RowSpacing    = 6;

                SpinButton pointerSpinButton = new SpinButton(0, 10, 1);

                EventHandler valueChangedHandler = delegate(object sender, EventArgs e) {
                    WarpSourceData pointedData = warpSourceData.GetPointedWarp();

                    pointerSpinButton.Adjustment.Lower = 0;
                    pointerSpinButton.Adjustment.Upper = warpSourceData.GetPointedChainLength() - 1;

                    if (pointerSpinButton.ValueAsInt > pointerSpinButton.Adjustment.Upper)
                    {
                        pointerSpinButton.Value = pointerSpinButton.Adjustment.Upper;
                    }
                    int index = pointerSpinButton.ValueAsInt;

                    while (index > 0)
                    {
                        pointedData = pointedData.GetNextWarp();
                        index--;
                    }

                    table.Remove(destEditor);

                    destEditor = new ValueReferenceEditor(Project, pointedData);

                    destEditor.AddDataModifiedHandler(delegate() {
                        SetDestIndex(pointedData.DestGroup, pointedData.DestIndex);
                    });

                    table.Attach(destEditor, 0, 2, 1, 2);

                    SetDestIndex(pointedData.DestGroup, pointedData.DestIndex);
                };

                pointerSpinButton.ValueChanged += valueChangedHandler;

                // Button which, when clicked, adds a new PointedData to the
                // "chain".
                Gtk.Button addPointedWarpButton =
                    new Gtk.Button(new Gtk.Image(Gtk.Stock.Add, Gtk.IconSize.Button));

                addPointedWarpButton.Clicked += delegate(object sender, EventArgs e) {
                    WarpSourceData pointedData = warpSourceData.GetPointedWarp();

                    while (pointedData.GetNextWarp() != null)
                    {
                        pointedData = pointedData.GetNextWarp();
                    }

                    WarpSourceData nextData = new WarpSourceData(Project,
                                                                 WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp],
                                                                 WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp],
                                                                 pointedData.FileParser,
                                                                 new List <int> {
                        -1
                    });
                    pointedData.SetNextWarp(nextData);

                    pointerSpinButton.Adjustment.Upper++;
                    pointerSpinButton.Value = warpSourceData.GetPointedChainLength() - 1;
                    valueChangedHandler(null, null);
                };

                // Button which removes a PointedData from the "chain", unless
                // there is only one remaining.
                Gtk.Button removePointedWarpButton =
                    new Gtk.Button(new Gtk.Image(Gtk.Stock.Remove, Gtk.IconSize.Button));

                removePointedWarpButton.Clicked += delegate(object sender, EventArgs e) {
                    int            index       = pointerSpinButton.ValueAsInt;
                    WarpSourceData pointedData = warpSourceData.GetPointedWarp();

                    if (pointedData.GetPointedChainLength() <= 1) // Don't delete the last one
                    {
                        return;
                    }

                    while (index > 0)
                    {
                        pointedData = pointedData.GetNextWarp();
                        index--;
                    }

                    pointedData.FileParser.RemoveFileComponent(pointedData);

                    valueChangedHandler(null, null);
                };

                table.Attach(new Gtk.Label("Pointer index"), 0, 1, 0, 1);
                table.Attach(pointerSpinButton, 1, 2, 0, 1);
                table.Attach(addPointedWarpButton, 2, 3, 0, 1);
                table.Attach(removePointedWarpButton, 3, 4, 0, 1);

                // Invoke handler
                valueChangedHandler(pointerSpinButton, null);

                Frame frame = new Frame(warpSourceData.PointerString);
                frame.Add(table);

                hbox.Add(frame);
            }
            else   // Not pointerWarp
            {
                sourceEditor.AddDataModifiedHandler(delegate() {
                    SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex);
                });
            }

            valueEditorContainer.Add(hbox);
            valueEditorContainer.ShowAll();
        }
Exemplo n.º 12
0
        protected void OnAddSpecificWarpButtonClicked(object sender, EventArgs e)
        {
            // Check if a pointer warp already exists
            List<WarpSourceData> warps = sourceGroup.GetMapWarpSourceData(map);

            foreach (WarpSourceData sourceData in warps) {
                if (sourceData.WarpSourceType == WarpSourceType.PointerWarp) {
                    // Warning dialog
                    Gtk.MessageDialog d = new Gtk.MessageDialog(null,
                            DialogFlags.DestroyWithParent,
                            MessageType.Warning,
                            ButtonsType.YesNo,
                            "This map already has specific-position warp data; adding another would be redundant. Continue anyway?");
                    Gtk.ResponseType response = (ResponseType)d.Run();
                    d.Destroy();

                    if (response == ResponseType.Yes)
                        break;
                    else
                        return;
                }
            }

            WarpSourceData data = new WarpSourceData(Project,
                    WarpSourceData.WarpCommands[(int)WarpSourceType.PointerWarp],
                    WarpSourceData.DefaultValues[(int)WarpSourceType.PointerWarp],
                    sourceGroup.FileParser,
                    new List<int>{-1,2});
            data.Map = map;

            sourceGroup.AddWarpSourceData(data);

            SetWarpIndex((int)indexSpinButton.Adjustment.Upper+1);
        }
Exemplo n.º 13
0
 public void RemoveReference(WarpSourceData data)
 {
     referenceSet.Remove(data);
 }
Exemplo n.º 14
0
 public void AddReference(WarpSourceData data)
 {
     referenceSet.Add(data);
 }
Exemplo n.º 15
0
        // Load the i'th warp in the current map.
        void SetWarpIndex(int i)
        {
            List<WarpSourceData> sourceDataList = sourceGroup.GetMapWarpSourceData(map);

            indexSpinButton.Adjustment.Lower = -1;
            indexSpinButton.Adjustment.Upper = sourceDataList.Count-1;

            if (i > indexSpinButton.Adjustment.Upper)
                i = (int)indexSpinButton.Adjustment.Upper;

            indexSpinButton.Value = i;

            valueEditorContainer.Remove(valueEditorContainer.Child);

            if (i == -1) {
                SetDestIndex(-1,-1);
                return;
            }

            Gtk.HBox hbox = new Gtk.HBox();

            WarpSourceData warpSourceData = sourceDataList[i];

            if (warpSourceData.WarpSourceType == WarpSourceType.StandardWarp)
                SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex);

            sourceEditor = new ValueReferenceEditor(Project,
                    warpSourceData);

            Alignment a = new Alignment(0,0,0,0);
            a.Add(sourceEditor);
            hbox.Add(a);

            if (warpSourceData.WarpSourceType == WarpSourceType.PointerWarp) {
                Table table = new Table(1, 1, false);
                table.ColumnSpacing = 6;
                table.RowSpacing = 6;

                SpinButton pointerSpinButton = new SpinButton(0,10,1);

                EventHandler valueChangedHandler = delegate(object sender, EventArgs e) {
                    WarpSourceData pointedData = warpSourceData.GetPointedWarp();

                    pointerSpinButton.Adjustment.Lower = 0;
                    pointerSpinButton.Adjustment.Upper = warpSourceData.GetPointedChainLength()-1;

                    if (pointerSpinButton.ValueAsInt > pointerSpinButton.Adjustment.Upper) {
                        pointerSpinButton.Value = pointerSpinButton.Adjustment.Upper;
                    }
                    int index = pointerSpinButton.ValueAsInt;

                    while (index > 0) {
                        pointedData = pointedData.GetNextWarp();
                        index--;
                    }

                    table.Remove(destEditor);

                    destEditor = new ValueReferenceEditor(Project, pointedData);

                    destEditor.AddDataModifiedHandler(delegate() {
                            SetDestIndex(pointedData.DestGroup, pointedData.DestIndex);
                        });

                    table.Attach(destEditor, 0, 2, 1, 2);

                    SetDestIndex(pointedData.DestGroup, pointedData.DestIndex);
                };

                pointerSpinButton.ValueChanged += valueChangedHandler;

                // Button which, when clicked, adds a new PointedData to the
                // "chain".
                Gtk.Button addPointedWarpButton =
                    new Gtk.Button(new Gtk.Image(Gtk.Stock.Add, Gtk.IconSize.Button));

                addPointedWarpButton.Clicked += delegate(object sender, EventArgs e) {
                    WarpSourceData pointedData = warpSourceData.GetPointedWarp();

                    while (pointedData.GetNextWarp() != null) {
                        pointedData = pointedData.GetNextWarp();
                    }

                    WarpSourceData nextData = new WarpSourceData(Project,
                            WarpSourceData.WarpCommands[(int)WarpSourceType.PointedWarp],
                            WarpSourceData.DefaultValues[(int)WarpSourceType.PointedWarp],
                            pointedData.FileParser,
                            new List<int>{-1});
                    pointedData.SetNextWarp(nextData);

                    pointerSpinButton.Adjustment.Upper++;
                    pointerSpinButton.Value = warpSourceData.GetPointedChainLength()-1;
                    valueChangedHandler(null, null);
                };

                // Button which removes a PointedData from the "chain", unless
                // there is only one remaining.
                Gtk.Button removePointedWarpButton =
                    new Gtk.Button(new Gtk.Image(Gtk.Stock.Remove, Gtk.IconSize.Button));

                removePointedWarpButton.Clicked += delegate(object sender, EventArgs e) {
                    int index = pointerSpinButton.ValueAsInt;
                    WarpSourceData pointedData = warpSourceData.GetPointedWarp();

                    if (pointedData.GetPointedChainLength() <= 1) // Don't delete the last one
                        return;

                    while (index > 0) {
                        pointedData = pointedData.GetNextWarp();
                        index--;
                    }

                    pointedData.FileParser.RemoveFileComponent(pointedData);

                    valueChangedHandler(null, null);
                };

                table.Attach(new Gtk.Label("Pointer index"), 0, 1, 0, 1);
                table.Attach(pointerSpinButton, 1, 2, 0, 1);
                table.Attach(addPointedWarpButton, 2, 3, 0, 1);
                table.Attach(removePointedWarpButton, 3, 4, 0, 1);

                // Invoke handler
                valueChangedHandler(pointerSpinButton, null);

                Frame frame = new Frame(warpSourceData.PointerString);
                frame.Add(table);

                hbox.Add(frame);
            }
            else { // Not pointerWarp
                sourceEditor.AddDataModifiedHandler(delegate() {
                        SetDestIndex(warpSourceData.DestGroup, warpSourceData.DestIndex);
                        });
            }

            valueEditorContainer.Add(hbox);
            valueEditorContainer.ShowAll();
        }
Exemplo n.º 16
0
        public bool SetNextWarp(WarpSourceData next)
        {
            if (!FileParser.InsertComponentAfter(this, next)) return false;

            this.Opcode &= ~0x80;
            if (next.GetNextWarp() == null)
                next.Opcode |= 0x80;
            else
                next.Opcode &= 0x80;
            return true;
        }
Exemplo n.º 17
0
        void ParseLine(string pureLine, int i, List<FileComponent> fileStructure, List<string> fileStructureComments)
        {
            string[] split = pureLine.Split(';');
            string line = split[0];
            string comment = pureLine.Substring(split[0].Length);
            string warningString = "WARNING while parsing \"" + Filename + "\": Line " + (i+1) + ": ";

            // Helper functions

            Action<FileComponent,string> AddComponent = (component, c) => {
                fileStructure.Add(component);
                fileStructureComments.Add(c);
                if (component is Label)
                    AddLabelToDictionaries(component as Label);
            };
            Action<Label> AddLabelAndPopFileStructure = (label) => {
                fileStructure.RemoveAt(fileStructure.Count-1);
                string c = fileStructureComments[fileStructureComments.Count-1];
                fileStructureComments.RemoveAt(fileStructureComments.Count-1);
                AddComponent(label, c);
            };
            Action<Data> AddDataAndPopFileStructure = (data) => {
                fileStructure.RemoveAt(fileStructure.Count-1);
                string c = fileStructureComments[fileStructureComments.Count-1];
                fileStructureComments.RemoveAt(fileStructureComments.Count-1);
                AddComponent(data, c);
            };
            Action PopFileStructure = () => {
                fileStructure.RemoveAt(fileStructure.Count-1);
                fileStructureComments.RemoveAt(fileStructureComments.Count-1);
            };

            // Sub-function: returns true if a meaning for the token was found.
            Func<string[],IList<int>,bool> ParseData = (fTokens,fSpacing) =>
            {
                List<string> standardValues = new List<string>();

                // Variables used for some of the goto's
                int size=-1;

                for (int j = 1; j < fTokens.Length; j++)
                    standardValues.Add(fTokens[j]);

                switch (fTokens[0].ToLower()) {
                    case ".incbin":
                        {
                            Data d = new Data(Project, fTokens[0], standardValues, -1,
                                    this, fSpacing);
                            AddDataAndPopFileStructure(d);
                        }
                        break;
                    case ".dw":
                        if (context == "RAMSECTION")
                            break;
                        if (fTokens.Length < 2) {
                            log.Warn(warningString + "Expected .DW to have a value.");
                            break;
                        }
                        size = 2;
                        goto arbitraryLengthData;
                    case ".db":
                        if (context == "RAMSECTION")
                            break;
                        if (fTokens.Length < 2) {
                            log.Warn(warningString + "Expected .DB to have a value.");
                            break;
                        }
                        size = 1;
                        goto arbitraryLengthData;
                    case "dwbe":
                        if (fTokens.Length < 2) {
                            log.Warn(warningString + "Expected dwbe to have a value.");
                            break;
                        }
                        size = 2;
                        goto arbitraryLengthData;
                    case "dbrev":
                        if (fTokens.Length < 2) {
                            log.Warn(warningString + "Expected dbrev to have a value.");
                            break;
                        }
                        size = 1;
                        goto arbitraryLengthData;
            arbitraryLengthData:
                        PopFileStructure();
                        for (int j=1; j<fTokens.Length; j++) { // Each value is added as individual data
                            string[] values = { fTokens[j] };
                            List<int> newfSpacing = new List<int> {fSpacing[0],fSpacing[j],0};
                            if (j == fTokens.Length-1)
                                newfSpacing[2] = fSpacing[j+1];

                            Data d = new Data(Project, fTokens[0], values, size,
                                    this, newfSpacing);
                            if (j != fTokens.Length-1)
                                d.EndsLine = false;
                            if (j != 1)
                                d.PrintCommand = false;
                            AddComponent(d, "");
                        }
                        break;
                    case "db":
                        if (context != "RAMSECTION")
                            goto default;
                        address++;
                        break;
                    case "dw":
                        if (context != "RAMSECTION")
                            goto default;
                        address+=2;
                        break;
                    case "dsb":
                        if (context != "RAMSECTION")
                            goto default;
                        address += Project.EvalToInt(fTokens[1]);
                        break;
                    case "dsw":
                        if (context != "RAMSECTION")
                            goto default;
                        address += Project.EvalToInt(fTokens[1])*2;
                        break;

                    case "m_animationloop":
                        {
                            Data d = new Data(Project, fTokens[0], standardValues, 2,
                                this, fSpacing);
                            AddDataAndPopFileStructure(d);
                            break;
                        }
                    case "m_rgb16":
                        if (fTokens.Length != 4) {
                            log.Warn(warningString + "Expected " + fTokens[0] + " to take 3 parameters");
                            break;
                        }
                        {
                            Data d = new RgbData(Project, fTokens[0], standardValues,
                                    this, fSpacing);
                            AddDataAndPopFileStructure(d);
                            break;
                        }
                    case "m_gfxheader":
                    case "m_gfxheaderforcemode":
                        if (fTokens.Length < 4 || fTokens.Length > 5) {
                            log.Warn(warningString + "Expected " + fTokens[0] + " to take 3-4 parameters");
                            break;
                        }
                        {
                            Data d = new GfxHeaderData(Project, fTokens[0], standardValues,
                                    this, fSpacing);
                            AddDataAndPopFileStructure(d);
                            break;
                        }
                    case "m_paletteheaderbg":
                    case "m_paletteheaderspr":
                        if (fTokens.Length != 5) {
                            log.Warn(warningString + "Expected " + fTokens[0] + " to take 4 parameters");
                            break;
                        }
                        {
                            Data d = new PaletteHeaderData(Project, fTokens[0], standardValues,
                                    this, fSpacing);
                            AddDataAndPopFileStructure(d);
                            break;
                        }
                    case "m_tilesetheader":
                        if (fTokens.Length != 6) {
                            log.Warn(warningString + "Expected " + fTokens[0] + " to take 5 parameters");
                            break;
                        }
                        {
                            Data d = new TilesetHeaderData(Project, fTokens[0], standardValues,
                                    this, fSpacing);
                            AddDataAndPopFileStructure(d);
                            break;
                        }
                    case "m_tilesetdata":
                        if (fTokens.Length != 2) {
                            log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter");
                            break;
                        }
                        {
                            Stream file = Project.GetBinaryFile("tilesets/" + fTokens[1] + ".bin");
                            Data d = new Data(Project, fTokens[0], standardValues,
                                    (Int32)file.Length, this, fSpacing);
                            AddDataAndPopFileStructure(d);
                            break;
                        }
                    case "m_roomlayoutdata":
                        if (fTokens.Length != 2) {
                            log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter");
                            break;
                        }
                        {
                            Label l = new Label(this, fTokens[1]);
                            l.Fake = true;
                            AddLabelAndPopFileStructure(l);
                            Data d = new Data(Project, fTokens[0], standardValues, -1,
                                    this, fSpacing);
                            AddComponent(d, "");
                            break;
                        }

                    default:
                        {
                            Data d = null;
                            // Try object commands
                            for (int j=0; j<ObjectGroup.ObjectCommands.Length; j++) {
                                string s = ObjectGroup.ObjectCommands[j];

                                if (s.ToLower() == fTokens[0].ToLower()) {
                                    int minParams = ObjectGroup.ObjectCommandMinParams[j];
                                    int maxParams = ObjectGroup.ObjectCommandMaxParams[j];

                                    if (minParams == -1) minParams = maxParams;
                                    if (maxParams == -1) maxParams = minParams;
                                    if (fTokens.Length-1 < minParams || fTokens.Length-1 > maxParams) {
                                      log.Warn(warningString + "Expected " + fTokens[0] + " to take " +
                                          minParams + "-" + maxParams + "parameter(s)");
                                      break;
                                    }

                                    var objectType = (ObjectType)j;

                                    d = new ObjectData(Project, fTokens[0], standardValues,
                                        this, fSpacing, objectType);
                                    break;
                                }
                            }
                            // Try warp sources
                            foreach (string s in WarpSourceData.WarpCommands) {
                                if (s.ToLower() == fTokens[0].ToLower()) {
                                    d = new WarpSourceData(Project, fTokens[0], standardValues,
                                            this, fSpacing);
                                }
                            }
                            // Try warp dest
                            if (WarpDestData.WarpCommand.ToLower() == fTokens[0].ToLower()) {
                                d = new WarpDestData(Project, fTokens[0], standardValues,
                                        this, fSpacing);
                            }

                            if (d != null) {
                                AddDataAndPopFileStructure(d);
                                break;
                            }
                            return false;
                        }
                }
                return true;
            };

            // Add raw string to file structure, it'll be removed if
            // a better representation is found
            fileStructure.Add(new StringFileComponent(this, line, null));
            fileStructureComments.Add(comment);

            if (line.Trim().Length == 0)
                return;

            // TODO: split tokens more intelligently, ie: recognize this as one token: $8000 | $03
            //string[] tokens = line.Split(new char[] { ' ', '\t'} );
            string[] tokens = Regex.Split(line.Trim(), @"\s+");

            List<int> spacing = new List<int>();
            int[] tokenStartIndices = new int[tokens.Length];
            {
                // Generate "spacing" list, keeps track of whitespace
                // between arguments (+'ve = spaces, -'ve = tabs)
                int index = 0;

                for (int j=0; j<tokens.Length+1; j++) {
                    int spaces=0;
                    while (index < line.Length && (line[index] == ' ' || line[index] == '\t')) {
                        if (line[index] == ' ' && spaces >= 0) spaces++;
                        else if (line[index] == '\t' && spaces <= 0) spaces--;
                        index++;
                    }
                    if (j<tokens.Length)
                        tokenStartIndices[j] = index;
                    spacing.Add(spaces);
                    while (index < line.Length && line[index] != ' ' && line[index] != '\t')
                        index++;
                }
            }

            string value;

            if (tokens.Length > 0) {
                switch (tokens[0].ToLower()) {
                    // Built-in directives
                    case ".ramsection":
                        {
                            context = "RAMSECTION";
                            // Find the last token which specifies the name
                            int tokenIndex = 1;
                            while (tokens[tokenIndex][tokens[tokenIndex].Length-1] != '"')
                                tokenIndex++;
                            tokenIndex++;

                            while (tokenIndex < tokens.Length) {
                                if (tokens[tokenIndex] == "BANK") {
                                    tokenIndex++;
                                    bank = Project.EvalToInt(tokens[tokenIndex++]);
                                }
                                else if (tokens[tokenIndex] == "SLOT") {
                                    tokenIndex++;
                                    string slotString = tokens[tokenIndex++];
                                    int slot = Project.EvalToInt(slotString);
                                    if (slot == 2)
                                        address = 0xc000;
                                    else { // Assuming slot >= 3
                                        address = 0xd000;
                                    }
                                }
                            }
                            break;
                        }
                    case ".ends":
                        if (context == "RAMSECTION")
                            context = "";
                        break;

                    case ".define":
                        if (tokens.Length < 3) {
                            log.Debug(warningString + "Expected .DEFINE to have a string and a value.");
                            break;
                        }
                        value = "";
                        for (int j = 2; j < tokens.Length; j++) {
                            value += tokens[j];
                            value += " ";
                        }
                        value = value.Trim();
                        AddDefinition(tokens[1], value);
                        break;

                    default:
                        if (tokens[0][tokens[0].Length - 1] == ':') {
                            // Label
                            string s = tokens[0].Substring(0, tokens[0].Length - 1);
                            FileComponent addedComponent;
                            if (context == "RAMSECTION") {
                                AddDefinition(s, address.ToString());
                                AddDefinition(":"+s, bank.ToString());
                                PopFileStructure();
                                StringFileComponent sc = new StringFileComponent(this, tokens[0], spacing);
                                fileStructure.Add(sc);
                                fileStructureComments.Add(comment);
                                addedComponent = sc;
                            }
                            else {
                                Label label = new Label(this,s,spacing);
                                AddLabelAndPopFileStructure(label);
                                addedComponent = label;
                            }
                            if (tokens.Length > 1) { // There may be data directly after the label
                                string[] tokens2 = new string[tokens.Length-1];
                                List<int> spacing2 = new List<int>();

                                addedComponent.EndsLine = false;

                                // Add raw string to file structure, it'll
                                // be removed if a better representation is
                                // found
                                fileStructure.Add(new StringFileComponent(
                                            this, line.Substring(tokenStartIndices[1]), spacing2));
                                fileStructureComments.Add(comment);

                                for (int j=1; j<tokens.Length; j++)
                                    tokens2[j-1] = tokens[j];
                                for (int j=1; j<spacing.Count; j++)
                                    spacing2.Add(spacing[j]);
                                if (!ParseData(tokens2, spacing2)) {
                                    log.Debug(warningString + "Error parsing line.");
                                }
                            }
                        } else {
                            if (!ParseData(tokens, spacing)) {
                                // Unknown data
                                log.Debug(warningString + "Did not understand \"" + tokens[0] + "\".");
                            }
                        }
                        break;
                }
            }
        }
Exemplo n.º 18
0
        void ParseLine(string pureLine, int i, List <FileComponent> fileStructure, List <string> fileStructureComments)
        {
            string[] split         = pureLine.Split(';');
            string   line          = split[0];
            string   comment       = pureLine.Substring(split[0].Length);
            string   warningString = "WARNING while parsing \"" + Filename + "\": Line " + (i + 1) + ": ";

            // Helper functions

            Action <FileComponent, string> AddComponent = (component, c) => {
                fileStructure.Add(component);
                fileStructureComments.Add(c);
                if (component is Label)
                {
                    AddLabelToDictionaries(component as Label);
                }
            };
            Action <Label> AddLabelAndPopFileStructure = (label) => {
                fileStructure.RemoveAt(fileStructure.Count - 1);
                string c = fileStructureComments[fileStructureComments.Count - 1];
                fileStructureComments.RemoveAt(fileStructureComments.Count - 1);
                AddComponent(label, c);
            };
            Action <Data> AddDataAndPopFileStructure = (data) => {
                fileStructure.RemoveAt(fileStructure.Count - 1);
                string c = fileStructureComments[fileStructureComments.Count - 1];
                fileStructureComments.RemoveAt(fileStructureComments.Count - 1);
                AddComponent(data, c);
            };
            Action PopFileStructure = () => {
                fileStructure.RemoveAt(fileStructure.Count - 1);
                fileStructureComments.RemoveAt(fileStructureComments.Count - 1);
            };

            // Sub-function: returns true if a meaning for the token was found.
            Func <string[], IList <int>, bool> ParseData = (fTokens, fSpacing) =>
            {
                List <string> standardValues = new List <string>();

                // Variables used for some of the goto's
                int size = -1;

                for (int j = 1; j < fTokens.Length; j++)
                {
                    standardValues.Add(fTokens[j]);
                }

                switch (fTokens[0].ToLower())
                {
                case ".incbin":
                {
                    Data d = new Data(Project, fTokens[0], standardValues, -1,
                                      this, fSpacing);
                    AddDataAndPopFileStructure(d);
                }
                break;

                case ".dw":
                    if (context == "RAMSECTION" || context == "ENUM")
                    {
                        break;
                    }
                    if (fTokens.Length < 2)
                    {
                        log.Warn(warningString + "Expected .DW to have a value.");
                        break;
                    }
                    size = 2;
                    goto arbitraryLengthData;

                case ".db":
                    if (context == "RAMSECTION" || context == "ENUM")
                    {
                        break;
                    }
                    if (fTokens.Length < 2)
                    {
                        log.Warn(warningString + "Expected .DB to have a value.");
                        break;
                    }
                    size = 1;
                    goto arbitraryLengthData;

                case "dwbe":
                    if (fTokens.Length < 2)
                    {
                        log.Warn(warningString + "Expected dwbe to have a value.");
                        break;
                    }
                    size = 2;
                    goto arbitraryLengthData;

                case "dbrev":
                    if (fTokens.Length < 2)
                    {
                        log.Warn(warningString + "Expected dbrev to have a value.");
                        break;
                    }
                    size = 1;
                    goto arbitraryLengthData;
arbitraryLengthData:
                    PopFileStructure();
                    for (int j = 1; j < fTokens.Length; j++)   // Each value is added as individual data
                    {
                        string[]   values      = { fTokens[j] };
                        List <int> newfSpacing = new List <int> {
                            fSpacing[0], fSpacing[j], 0
                        };
                        if (j == fTokens.Length - 1)
                        {
                            newfSpacing[2] = fSpacing[j + 1];
                        }

                        Data d = new Data(Project, fTokens[0], values, size,
                                          this, newfSpacing);
                        if (j != fTokens.Length - 1)
                        {
                            d.EndsLine = false;
                        }
                        if (j != 1)
                        {
                            d.PrintCommand = false;
                        }
                        AddComponent(d, "");
                    }
                    break;

                case "db":
                    if (context != "RAMSECTION" && context != "ENUM")
                    {
                        goto default;
                    }
                    address++;
                    break;

                case "dw":
                    if (context != "RAMSECTION" && context != "ENUM")
                    {
                        goto default;
                    }
                    address += 2;
                    break;

                case "dsb":
                    if (context != "RAMSECTION" && context != "ENUM")
                    {
                        goto default;
                    }
                    address += Project.EvalToInt(fTokens[1]);
                    break;

                case "dsw":
                    if (context != "RAMSECTION" && context != "ENUM")
                    {
                        goto default;
                    }
                    address += Project.EvalToInt(fTokens[1]) * 2;
                    break;

                case "m_animationloop":
                {
                    Data d = new Data(Project, fTokens[0], standardValues, 2,
                                      this, fSpacing);
                    AddDataAndPopFileStructure(d);
                    break;
                }

                case "m_rgb16":
                    if (fTokens.Length != 4)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 3 parameters");
                        break;
                    }
                    {
                        Data d = new RgbData(Project, fTokens[0], standardValues,
                                             this, fSpacing);
                        AddDataAndPopFileStructure(d);
                        break;
                    }

                case "m_gfxheader":
                case "m_gfxheaderforcemode":
                    if (fTokens.Length < 4 || fTokens.Length > 5)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 3-4 parameters");
                        break;
                    }
                    {
                        Data d = new GfxHeaderData(Project, fTokens[0], standardValues,
                                                   this, fSpacing);
                        AddDataAndPopFileStructure(d);
                        break;
                    }

                case "m_paletteheaderbg":
                case "m_paletteheaderspr":
                    if (fTokens.Length != 5)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 4 parameters");
                        break;
                    }
                    {
                        Data d = new PaletteHeaderData(Project, fTokens[0], standardValues,
                                                       this, fSpacing);
                        AddDataAndPopFileStructure(d);
                        break;
                    }

                case "m_tilesetheader":
                    if (fTokens.Length != 6)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 5 parameters");
                        break;
                    }
                    {
                        Data d = new TilesetHeaderData(Project, fTokens[0], standardValues,
                                                       this, fSpacing);
                        AddDataAndPopFileStructure(d);
                        break;
                    }

                case "m_tilesetdata":
                    if (fTokens.Length != 2)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter");
                        break;
                    }
                    {
                        Stream file = Project.GetBinaryFile("tilesets/" + Project.GameString + "/" + fTokens[1] + ".bin");
                        Data   d    = new Data(Project, fTokens[0], standardValues,
                                               (Int32)file.Length, this, fSpacing);
                        AddDataAndPopFileStructure(d);
                        break;
                    }

                case "m_roomlayoutdata":
                    if (fTokens.Length != 2)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter");
                        break;
                    }
                    {
                        Label l = new Label(this, fTokens[1]);
                        l.Fake = true;
                        AddLabelAndPopFileStructure(l);
                        Data d = new Data(Project, fTokens[0], standardValues, -1,
                                          this, fSpacing);
                        AddComponent(d, "");
                        break;
                    }

                case "m_seasonalarea":
                    // In season's "areas.s", the m_SeasonalArea macro points to a label which
                    // contains 4 area definitions (one for each season).
                    if (fTokens.Length != 2)
                    {
                        log.Warn(warningString + "Expected " + fTokens[0] + " to take 1 parameter");
                        break;
                    }
                    {
                        // Create a data object considered to have a size of 8 bytes
                        Data d = new Data(Project, fTokens[0], standardValues, 8,
                                          this, fSpacing);
                        AddDataAndPopFileStructure(d);
                        break;
                    }

                default:
                {
                    Data d = null;
                    // Try object commands
                    for (int j = 0; j < ObjectGroup.ObjectCommands.Length; j++)
                    {
                        string s = ObjectGroup.ObjectCommands[j];

                        if (s.ToLower() == fTokens[0].ToLower())
                        {
                            int minParams = ObjectGroup.ObjectCommandMinParams[j];
                            int maxParams = ObjectGroup.ObjectCommandMaxParams[j];

                            if (minParams == -1)
                            {
                                minParams = maxParams;
                            }
                            if (maxParams == -1)
                            {
                                maxParams = minParams;
                            }
                            if (fTokens.Length - 1 < minParams || fTokens.Length - 1 > maxParams)
                            {
                                log.Warn(warningString + "Expected " + fTokens[0] + " to take " +
                                         minParams + "-" + maxParams + "parameter(s)");
                                break;
                            }

                            var objectType = (ObjectType)j;

                            d = new ObjectData(Project, fTokens[0], standardValues,
                                               this, fSpacing, objectType);
                            break;
                        }
                    }
                    // Try warp sources
                    foreach (string s in WarpSourceData.WarpCommands)
                    {
                        if (s.ToLower() == fTokens[0].ToLower())
                        {
                            d = new WarpSourceData(Project, fTokens[0], standardValues,
                                                   this, fSpacing);
                        }
                    }
                    // Try warp dest
                    if (WarpDestData.WarpCommand.ToLower() == fTokens[0].ToLower())
                    {
                        d = new WarpDestData(Project, fTokens[0], standardValues,
                                             this, fSpacing);
                    }

                    if (d != null)
                    {
                        AddDataAndPopFileStructure(d);
                        break;
                    }
                    return(false);
                }
                }
                return(true);
            };

            // Add raw string to file structure, it'll be removed if
            // a better representation is found
            fileStructure.Add(new StringFileComponent(this, line, null));
            fileStructureComments.Add(comment);

            if (line.Trim().Length == 0)
            {
                return;
            }

            // TODO: split tokens more intelligently, ie: recognize this as one token: $8000 | $03
            //string[] tokens = line.Split(new char[] { ' ', '\t'} );
            string[] tokens = Regex.Split(line.Trim(), @"\s+");

            List <int> spacing = new List <int>();

            int[] tokenStartIndices = new int[tokens.Length];
            {
                // Generate "spacing" list, keeps track of whitespace
                // between arguments (+'ve = spaces, -'ve = tabs)
                int index = 0;

                for (int j = 0; j < tokens.Length + 1; j++)
                {
                    int spaces = 0;
                    while (index < line.Length && (line[index] == ' ' || line[index] == '\t'))
                    {
                        if (line[index] == ' ' && spaces >= 0)
                        {
                            spaces++;
                        }
                        else if (line[index] == '\t' && spaces <= 0)
                        {
                            spaces--;
                        }
                        index++;
                    }
                    if (j < tokens.Length)
                    {
                        tokenStartIndices[j] = index;
                    }
                    spacing.Add(spaces);
                    while (index < line.Length && line[index] != ' ' && line[index] != '\t')
                    {
                        index++;
                    }
                }
            }


            if (tokens.Length > 0)
            {
                // Check if we're currently skipping over stuff because of .ifdefs
                if (ifdefCondition == false)
                {
                    if (tokens[0].ToLower() == ".ifdef")
                    {
                        ifdefDepth++;
                    }
                    else if (tokens[0].ToLower() == ".else" && failedIfdefDepth == ifdefDepth - 1)
                    {
                        ifdefCondition = true;
                    }
                    else if (tokens[0].ToLower() == ".endif")
                    {
                        ifdefDepth--;
                        if (ifdefDepth == failedIfdefDepth)
                        {
                            ifdefCondition = true;
                        }
                    }

                    return;
                }

                switch (tokens[0].ToLower())
                {
                // Built-in directives
                case ".ramsection": {
                    context = "RAMSECTION";
                    // Find the last token which specifies the name
                    int tokenIndex = 1;
                    while (tokens[tokenIndex][tokens[tokenIndex].Length - 1] != '"')
                    {
                        tokenIndex++;
                    }
                    tokenIndex++;

                    while (tokenIndex < tokens.Length)
                    {
                        if (tokens[tokenIndex] == "BANK")
                        {
                            tokenIndex++;
                            bank = Project.EvalToInt(tokens[tokenIndex++]);
                        }
                        else if (tokens[tokenIndex] == "SLOT")
                        {
                            tokenIndex++;
                            string slotString = tokens[tokenIndex++];
                            int    slot       = Project.EvalToInt(slotString);
                            if (slot == 2)
                            {
                                address = 0xc000;
                            }
                            else       // Assuming slot >= 3
                            {
                                address = 0xd000;
                            }
                        }
                    }
                    break;
                }

                case ".ends":
                    if (context == "RAMSECTION")
                    {
                        context = "";
                    }
                    break;

                case ".enum":
                    context = "ENUM";
                    address = Project.EvalToInt(tokens[1]);
                    break;
                // Not supported: "DESC" (descreasing order)

                case ".ende":
                    if (context == "ENUM")
                    {
                        context = "";
                    }
                    break;

                case ".define":
                {
                    if (tokens.Length < 3)
                    {
                        log.Debug(warningString + "Expected .DEFINE to have a string and a value.");
                        break;
                    }
                    string value = "";
                    for (int j = 2; j < tokens.Length; j++)
                    {
                        value += tokens[j];
                        value += " ";
                    }
                    value = value.Trim();
                    AddDefinition(tokens[1], value);
                    break;
                }

                case ".ifdef":
                    if (tokens.Length < 2)
                    {
                        log.Warn(warningString + "Expected .IFDEF to have a value.");
                        break;
                    }
                    ifdefDepth++;
                    if (Project.GetDefinition(tokens[1]) != null)
                    {
                        ifdefCondition = true;
                    }
                    else
                    {
                        ifdefCondition   = false;
                        failedIfdefDepth = ifdefDepth - 1;
                    }
                    break;

                case ".else":
                    if (ifdefDepth == 0)
                    {
                        log.Warn(warningString + "Expected .IFDEF before .ENDIF.");
                        break;
                    }
                    ifdefCondition = false;
                    break;

                case ".endif":
                    if (ifdefDepth == 0)
                    {
                        log.Warn(warningString + "Expected .IFDEF before .ENDIF.");
                        break;
                    }
                    ifdefDepth--;
                    break;

                default:
                {
                    bool isData = ParseData(tokens, spacing);

                    // In ramsections or enums, assume any unidentifiable data is a label.
                    // Technically this should be the case in any context, but it's more
                    // useful for the parser to tell me what it doesn't understand.
                    if (!isData && (tokens[0][tokens[0].Length - 1] == ':' || context == "RAMSECTION" || context == "ENUM"))
                    {
                        // Label
                        string s = tokens[0];
                        if (tokens[0][tokens[0].Length - 1] == ':')
                        {
                            s = tokens[0].Substring(0, tokens[0].Length - 1);
                        }

                        FileComponent addedComponent;
                        if (context == "RAMSECTION" || context == "ENUM")
                        {
                            AddDefinition(s, address.ToString());
                            if (context == "RAMSECTION")
                            {
                                AddDefinition(":" + s, bank.ToString());
                            }
                            PopFileStructure();
                            StringFileComponent sc = new StringFileComponent(this, tokens[0], spacing);
                            fileStructure.Add(sc);
                            fileStructureComments.Add(comment);
                            addedComponent = sc;
                        }
                        else
                        {
                            Label label = new Label(this, s, spacing);
                            AddLabelAndPopFileStructure(label);
                            addedComponent = label;
                        }
                        if (tokens.Length > 1)           // There may be data directly after the label
                        {
                            string[]   tokens2  = new string[tokens.Length - 1];
                            List <int> spacing2 = new List <int>();

                            addedComponent.EndsLine = false;

                            // Add raw string to file structure, it'll be removed if a better
                            // representation is found
                            fileStructure.Add(new StringFileComponent(
                                                  this, line.Substring(tokenStartIndices[1]), spacing2));
                            fileStructureComments.Add(comment);

                            for (int j = 1; j < tokens.Length; j++)
                            {
                                tokens2[j - 1] = tokens[j];
                            }
                            for (int j = 1; j < spacing.Count; j++)
                            {
                                spacing2.Add(spacing[j]);
                            }
                            if (!ParseData(tokens2, spacing2))
                            {
                                log.Debug(warningString + "Error parsing line.");
                            }
                        }
                    }
                    else
                    {
                        // Unknown data
                        log.Debug(warningString + "Did not understand \"" + tokens[0] + "\".");
                    }
                }
                break;
                }
            }
        }
Exemplo n.º 19
0
 public void RemoveReference(WarpSourceData data)
 {
     referenceSet.Remove(data);
 }
Exemplo n.º 20
0
 public void AddReference(WarpSourceData data)
 {
     referenceSet.Add(data);
 }
Exemplo n.º 21
0
        public ValueReferenceEditor(Project p, ValueReferenceGroup vrg, int rows, string frameText = null)
            : base(1.0F, 1.0F, 1.0F, 1.0F)
        {
            Project = p;

            valueReferenceGroup  = vrg;
            maxBounds            = new int[valueReferenceGroup.GetNumValueReferences()];
            widgetPositions      = new Tuple <uint, uint> [maxBounds.Count];
            widgets              = new Gtk.Widget[maxBounds.Count];
            helpButtonContainers = new Gtk.Container[maxBounds.Count];

            table = new Gtk.Table(2, 2, false);
            uint x = 0, y = 0;

            int cnt = 0;

            foreach (ValueReference r in valueReferenceGroup.GetValueReferences())
            {
                int index = cnt;
                cnt++;

                if (y >= rows)
                {
                    y  = 0;
                    x += 3;
                }

                widgetPositions[index] = new Tuple <uint, uint>(x, y);

                // If it has a ConstantsMapping, use a combobox instead of anything else
                if (r.ConstantsMapping != null)
                {
                    ComboBoxFromConstants comboBox = new ComboBoxFromConstants(false);
                    comboBox.SetConstantsMapping(r.ConstantsMapping);

                    comboBox.Changed += delegate(object sender, EventArgs e) {
                        r.SetValue(comboBox.ActiveValue);
                        OnDataModifiedInternal();
                    };

                    dataModifiedExternalEvent += delegate() {
                        comboBox.ActiveValue = r.GetIntValue();
                    };

                    table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);
                    table.Attach(comboBox, x + 1, x + 2, y, y + 1);
                    widgets[index] = comboBox;

                    helpButtonContainers[index] = new Gtk.HBox();
                    table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);

                    goto loopEnd;
                }
                // ConstantsMapping == null

                switch (r.ValueType)
                {
                case DataValueType.String:
                default:
                {
                    table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);
                    Gtk.Entry entry = new Gtk.Entry();
                    if (!r.Editable)
                    {
                        entry.Sensitive = false;
                    }
                    dataModifiedExternalEvent += delegate() {
                        entry.Text = r.GetStringValue();
                        OnDataModifiedInternal();
                    };
                    table.Attach(entry, x + 1, x + 2, y, y + 1);
                    widgets[index] = entry;

                    helpButtonContainers[index] = new Gtk.HBox();
                    table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);
                    break;
                }

                case DataValueType.Byte:
                case DataValueType.HalfByte:
byteCase:
                    {
                        table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);
                        SpinButtonHexadecimal spinButton = new SpinButtonHexadecimal(0, 255);
                        if (!r.Editable)
                        {
                            spinButton.Sensitive = false;
                        }
                        if (r.ValueType == DataValueType.HalfByte)
                        {
                            spinButton.Digits           = 1;
                            spinButton.Adjustment.Upper = 15;
                        }
                        else
                        {
                            spinButton.Digits = 2;
                        }
                        spinButton.ValueChanged += delegate(object sender, EventArgs e) {
                            Gtk.SpinButton button = sender as Gtk.SpinButton;
                            if (maxBounds[index] == 0 || button.ValueAsInt <= maxBounds[index])
                            {
                                r.SetValue(button.ValueAsInt);
                            }
                            else
                            {
                                button.Value = maxBounds[index];
                            }
                            OnDataModifiedInternal();
                        };
                        dataModifiedExternalEvent += delegate() {
                            spinButton.Value = r.GetIntValue();
                        };
                        table.Attach(spinButton, x + 1, x + 2, y, y + 1);
                        widgets[index] = spinButton;

                        helpButtonContainers[index] = new Gtk.HBox();
                        table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);
                    }
                    break;

                case DataValueType.WarpDestIndex:
                {
                    Gtk.Button newDestButton = new Gtk.Button("New\nDestination");
                    newDestButton.Clicked += delegate(object sender, EventArgs e) {
                        WarpSourceData warpData  = (WarpSourceData)r.Data;
                        WarpDestGroup  destGroup = warpData.GetReferencedDestGroup();
                        // Check if there's unused destination data
                        // already
                        for (int i = 0; i < destGroup.GetNumWarpDests(); i++)
                        {
                            WarpDestData destData = destGroup.GetWarpDest(i);
                            if (destData.GetNumReferences() == 0)
                            {
                                Gtk.MessageDialog d = new Gtk.MessageDialog(null,
                                                                            Gtk.DialogFlags.DestroyWithParent,
                                                                            Gtk.MessageType.Warning,
                                                                            Gtk.ButtonsType.YesNo,
                                                                            "Destination index " + i.ToString("X2") + " is not used by any sources. Use this index?\n\n(\"No\" will create a new destination instead.)");
                                Gtk.ResponseType response = (Gtk.ResponseType)d.Run();
                                d.Destroy();

                                if (response == Gtk.ResponseType.Yes)
                                {
                                    warpData.SetDestData(destGroup.GetWarpDest(i));
                                }
                                else if (response == Gtk.ResponseType.No)
                                {
                                    warpData.SetDestData(destGroup.AddDestData());
                                }
                                break;
                            }
                        }
                    };
                    table.Attach(newDestButton, x + 2, x + 3, y, y + 2);
                }
                    goto byteCase;

                case DataValueType.Word:
                {
                    table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);
                    SpinButtonHexadecimal spinButton = new SpinButtonHexadecimal(0, 0xffff);
                    if (!r.Editable)
                    {
                        spinButton.Sensitive = false;
                    }
                    spinButton.Digits        = 4;
                    spinButton.ValueChanged += delegate(object sender, EventArgs e) {
                        Gtk.SpinButton button = sender as Gtk.SpinButton;
                        if (maxBounds[index] == 0 || button.ValueAsInt <= maxBounds[index])
                        {
                            r.SetValue(button.ValueAsInt);
                        }
                        else
                        {
                            button.Value = maxBounds[index];
                        }
                        OnDataModifiedInternal();
                    };
                    dataModifiedExternalEvent += delegate() {
                        spinButton.Value = r.GetIntValue();
                    };
                    table.Attach(spinButton, x + 1, x + 2, y, y + 1);
                    widgets[index] = spinButton;

                    helpButtonContainers[index] = new Gtk.HBox();
                    table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);
                }
                break;

                case DataValueType.ByteBit:
                {
                    table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);
                    Gtk.CheckButton checkButton = new Gtk.CheckButton();
                    checkButton.CanFocus = false;
                    if (!r.Editable)
                    {
                        checkButton.Sensitive = false;
                    }
                    checkButton.Toggled += delegate(object sender, EventArgs e) {
                        Gtk.CheckButton button = sender as Gtk.CheckButton;
                        r.SetValue(button.Active ? 1 : 0);
                        OnDataModifiedInternal();
                    };
                    dataModifiedExternalEvent += delegate() {
                        checkButton.Active = r.GetIntValue() == 1;
                    };
                    table.Attach(checkButton, x + 1, x + 2, y, y + 1);
                    widgets[index] = checkButton;

                    helpButtonContainers[index] = new Gtk.HBox();
                    table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);
                }
                break;

                case DataValueType.ByteBits:
                case DataValueType.WordBits:
                {
                    table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);
                    SpinButtonHexadecimal spinButton = new SpinButtonHexadecimal(0, r.MaxValue);
                    if (!r.Editable)
                    {
                        spinButton.Sensitive = false;
                    }
                    spinButton.Digits        = (uint)Math.Pow(r.MaxValue, ((double)1) / 16) + 1;
                    spinButton.ValueChanged += delegate(object sender, EventArgs e) {
                        Gtk.SpinButton button = sender as Gtk.SpinButton;
                        if (maxBounds[index] == 0 || button.ValueAsInt <= maxBounds[index])
                        {
                            r.SetValue(button.ValueAsInt);
                        }
                        else
                        {
                            button.Value = maxBounds[index];
                        }
                        OnDataModifiedInternal();
                    };
                    dataModifiedExternalEvent += delegate() {
                        spinButton.Value = r.GetIntValue();
                    };
                    table.Attach(spinButton, x + 1, x + 2, y, y + 1);
                    widgets[index] = spinButton;

                    helpButtonContainers[index] = new Gtk.HBox();
                    table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);
                }
                break;

                case DataValueType.ObjectPointer:
                {
                    table.Attach(new Gtk.Label(r.Name), x + 0, x + 1, y, y + 1);

                    Gtk.Entry entry = new Gtk.Entry();
                    if (!r.Editable)
                    {
                        entry.Sensitive = false;
                    }
                    entry.Changed += delegate(object sender, EventArgs e) {
                        UpdatePointerTextBox(sender as Gtk.Entry, r);
                        OnDataModifiedInternal();
                    };
                    table.Attach(entry, x + 1, x + 2, y, y + 1);
                    widgets[index] = entry;

                    pointerFrame             = new Gtk.Frame();
                    pointerFrame.Label       = "Pointer data (possibly shared)";
                    pointerFrame.BorderWidth = 5;

                    y++;
                    table.Attach(pointerFrame, x + 0, x + 2, y, y + 1);

                    dataModifiedExternalEvent += delegate() {
                        entry.Text = r.GetStringValue();
                        UpdatePointerTextBox(entry, r);
                    };

                    helpButtonContainers[index] = new Gtk.HBox();
                    table.Attach(helpButtonContainers[index], x + 2, x + 3, y, y + 1, 0, Gtk.AttachOptions.Fill, 0, 0);
                }
                break;
                }

loopEnd:
                y++;
            }

            table.ColumnSpacing = 6;

            if (frameText != null)
            {
                var frame = new Gtk.Frame(frameText);
                frame.Add(table);
                this.Add(frame);
            }
            else
            {
                this.Add(table);
            }

            this.ShowAll();

            Data lastData = null;

            foreach (ValueReference r in valueReferenceGroup.GetValueReferences())
            {
                if (lastData != r.Data)
                {
                    lastData = r.Data;
                    r.Data.AddDataModifiedHandler(OnDataModifiedExternal);
                    // Destroy handler
                    this.Destroyed += delegate(object sender, EventArgs e) {
                        r.Data.RemoveDataModifiedHandler(OnDataModifiedExternal);
                    };
                }
            }

            // Initial values
            if (dataModifiedExternalEvent != null)
            {
                dataModifiedExternalEvent();
            }

            UpdateHelpButtons();
        }
Exemplo n.º 22
0
        protected void OnAddWarpButtonClicked(object sender, EventArgs e)
        {
            WarpSourceData data = new WarpSourceData(Project,
                    WarpSourceData.WarpCommands[(int)WarpSourceType.StandardWarp],
                    WarpSourceData.DefaultValues[(int)WarpSourceType.StandardWarp],
                    sourceGroup.FileParser,
                    new List<int>{-1});
            data.Map = map;
            data.Transition = 4;

            sourceGroup.AddWarpSourceData(data);

            SetWarpIndex((int)indexSpinButton.Adjustment.Upper+1);
        }