public void ExtendingTableWithLengthMinusOneFromParentOnlyAddsOneElement()
        {
            var data  = new byte[0x200];
            var model = new PokemonModel(data);
            var token = new ModelDelta();

            // Arrange - 2 tables, a parent and a child. The child is one shorter than the parent.
            ArrayRun.TryParse(model, "[element:]10", 0x20, null, out var parent);
            model.ObserveAnchorWritten(token, "parent", parent);
            ArrayRun.TryParse(model, "[element:]parent-1", 0x40, null, out var child);
            model.ObserveAnchorWritten(token, "child", child);
            Assert.Equal(9, child.ElementCount);

            // Adding via the child should extend the child by 1.
            child = model.GetTable("child");
            var errorInfo = model.CompleteArrayExtension(token, 1, ref child);

            Assert.Equal(ErrorInfo.NoError, errorInfo);
            Assert.Equal(10, child.ElementCount);

            // Adding via the parent should extend the child by 1.
            parent    = model.GetTable("parent");
            errorInfo = model.CompleteArrayExtension(token, 1, ref parent);
            child     = model.GetTable("child");
            Assert.Equal(ErrorInfo.NoError, errorInfo);
            Assert.Equal(11, child.ElementCount);
        }
Exemple #2
0
        // example serialized pokemon:
        //
        // 50 Butterfree (31)@"Silk Powder"
        // - "Stun Spore"
        // - "Super Sonic"
        // - "Aerial Ace"
        // - "Silver Wind"

        public IStreamRun DeserializeRun(string content, ModelDelta token)
        {
            var lines = content.Split(Environment.NewLine).Select(line => line.Trim()).ToArray();

            // step 1: parse it into some data containers
            var data = new TeamData(ModelCacheScope.GetCache(model), lines);

            // step 2: figure out what I need based on the data
            var elementLength = data.MovesIncluded ? 16 : 8;
            var totalLength   = elementLength * data.Pokemon.Count;
            var workingRun    = this;

            if (totalLength > workingRun.Length)
            {
                workingRun = (TrainerPokemonTeamRun)model.RelocateForExpansion(token, workingRun, totalLength);
            }

            // step 3: write the run data
            WriteData(token, workingRun.Start, data);

            // step 4: write the parent data
            var structType = (data.ItemsIncluded ? INCLUDE_ITEM : 0) ^ (data.MovesIncluded ? INCLUDE_MOVES : 0);

            UpdateParents(token, structType, data.Pokemon.Count, workingRun.PointerSources);

            return(new TrainerPokemonTeamRun(model, workingRun.Start, workingRun.PointerSources));
        }
Exemple #3
0
        public void PointerModelFindsPointersInRange()
        {
            var rnd    = new Random(0xCafe);
            var buffer = new byte[0x10000]; // 64KB

            rnd.NextBytes(buffer);
            for (int i = 0; i < buffer.Length; i++)
            {
                if (buffer[i] == 0x08)
                {
                    buffer[i] = 0x10;
                }
            }

            // write two specific pointers
            var model = new PokemonModel(buffer);
            var token = new ModelDelta();

            model.WritePointer(token, 0x204, 0x4050);
            model.WritePointer(token, 0x4070, 0x101C);
            model = new PokemonModel(buffer);

            Assert.Equal(0x204, model.GetNextRun(0).Start);
            Assert.IsType <PointerRun>(model.GetNextRun(0x206));

            Assert.IsType <NoInfoRun>(model.GetNextRun(0x208));
            Assert.Single(model.GetNextRun(0x400).PointerSources);

            Assert.Equal(0x4050, model.GetNextRun(0x4050).Start);
            Assert.Equal(4, model.GetNextRun(0x4071).Length);
        }
Exemple #4
0
        public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int page, int[,] pixels)
        {
            var data = Decompress(model, Start, allowLengthErrors: true);

            page %= Pages;

            var pageLength = SpriteFormat.TileWidth * SpriteFormat.TileHeight * 8 * SpriteFormat.BitsPerPixel;

            SpriteRun.SetPixels(data, page * pageLength, pixels, SpriteFormat.BitsPerPixel);

            var newModelData = Compress(data, 0, data.Length);
            var newRun       = (ISpriteRun)model.RelocateForExpansion(token, this, newModelData.Count);

            for (int i = 0; i < newModelData.Count; i++)
            {
                token.ChangeData(model, newRun.Start + i, newModelData[i]);
            }
            for (int i = newModelData.Count; i < Length; i++)
            {
                token.ChangeData(model, newRun.Start + i, 0xFF);
            }
            newRun = new LzSpriteRun(SpriteFormat, model, newRun.Start, newRun.PointerSources);
            model.ObserveRunWritten(token, newRun);
            return(newRun);
        }
Exemple #5
0
        public override void UpdateNewRunFromPointerFormat(IDataModel model, ModelDelta token, string name, ref IFormattedRun run)
        {
            var runAttempt = new TrainerPokemonTeamRun(model, run.Start, run.PointerSources);

            model.ClearFormat(token, run.Start, runAttempt.Length);
            run = runAttempt;
        }
Exemple #6
0
        public override void UpdateNewRunFromPointerFormat(IDataModel model, ModelDelta token, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex, ref IFormattedRun run)
        {
            var runAttempt = new TrainerPokemonTeamRun(model, run.Start, run.PointerSources);

            model.ClearFormat(token, run.Start, runAttempt.Length);
            run = runAttempt;
        }
        private TableStreamRun DeserializeSingleElementStream(string content, ModelDelta token, out IReadOnlyList <int> changedOffsets)
        {
            Debug.Assert(endStream is FixedLengthStreamStrategy flss && flss.Count == 1);
            var fields          = content.SplitLines();
            int segmentOffset   = 0;
            int fieldIndex      = 0;
            var changeAddresses = new List <int>();

            for (int j = 0; j < ElementContent.Count; j++)
            {
                while (fieldIndex < fields.Length && string.IsNullOrWhiteSpace(fields[fieldIndex]))
                {
                    fieldIndex += 1;
                }
                if (fieldIndex >= fields.Length)
                {
                    break;
                }
                var data = j < fields.Length ? fields[fieldIndex].Split(new[] { ':' }, 2).Last() : string.Empty;
                if (ElementContent[j].Write(model, token, Start + segmentOffset, ref data))
                {
                    changeAddresses.Add(Start + segmentOffset);
                }
                segmentOffset += ElementContent[j].Length;
                fieldIndex    += 1;
            }
            changedOffsets = changeAddresses;
            return(this);
        }
        public void EditingMainContentUpdatesTableTool()
        {
            Model[0x42] = 3; // sat
            var changeToken = new ModelDelta();

            var(model, viewPort) = (Model, ViewPort);

            // arrange: setup the anchor used for the enums
            WriteStrings(model.RawData, 0x00, "cat", "bat", "bat", "sat");
            var error = ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var arrayRun);

            model.ObserveAnchorWritten(changeToken, "sample", arrayRun);

            // act: setup a viewmodel and show table tool
            ViewPort.Refresh();
            viewPort.Tools.SelectedIndex = 1;

            // act: change the table contents
            viewPort.SelectionStart = new Point(1, 0);
            viewPort.Edit("u");

            // assert: main view was updated
            var element = (FieldArrayElementViewModel)viewPort.Tools.TableTool.Children.Single(child => child is FieldArrayElementViewModel faevm && faevm.Name == "name");

            Assert.Equal("cut", element.Content);
        }
        public static ITilemapRun SetPixels(ITilemapRun run, IDataModel model, ModelDelta token, int page, int[,] pixels, ref int arrayTilesetAddress, Func <byte[], ModelDelta, ITilemapRun> replaceData)
        {
            var tileData       = Tilize(pixels, run.Format.BitsPerPixel);
            var tiles          = GetUniqueTiles(tileData, run.BytesPerTile == 2);
            var tilesetAddress = model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, run.Format.MatchingTileset);
            var tileset        = model.GetNextRun(tilesetAddress) as ITilesetRun;

            if (tileset == null)
            {
                FindMatchingTileset(run, model, ref arrayTilesetAddress);
                tileset = model.GetNextRun(arrayTilesetAddress) as ITilesetRun;
            }

            var tilesToKeep       = new HashSet <int>((tileset.DecompressedLength / tileset.TilesetFormat.BitsPerPixel / 8).Range());
            var originalUsedTiles = GetUsedTiles(run).ToHashSet();

            foreach (var tile in originalUsedTiles)
            {
                tilesToKeep.Remove(tile);
            }
            foreach (var tilemap in tileset.FindDependentTilemaps(model).Except(run))
            {
                tilesToKeep.AddRange(GetUsedTiles(tilemap));
            }
            var oldTileDataRaw = tileset.GetData();
            var previousTiles  = Tilize(oldTileDataRaw, run.Format.BitsPerPixel);

            tiles = MergeTilesets(previousTiles, tilesToKeep, tiles, run.BytesPerTile == 2);
            tileset.SetPixels(model, token, tiles);
            var mapData = run.GetTilemapData();

            var tileWidth  = tileData.GetLength(0);
            var tileHeight = tileData.GetLength(1);

            for (int y = 0; y < tileHeight; y++)
            {
                for (int x = 0; x < tileWidth; x++)
                {
                    var i = y * tileWidth + x;
                    var(tile, paletteIndex)   = tileData[x, y];
                    var(tileIndex, matchType) = FindMatch(tile, tiles, run.BytesPerTile == 2);
                    if (tileIndex == -1)
                    {
                        tileIndex = 0;
                    }
                    if (run.BytesPerTile == 2)
                    {
                        var mapping = PackMapping(paletteIndex, matchType, tileIndex);
                        mapData[i * 2 + 0] = (byte)mapping;
                        mapData[i * 2 + 1] = (byte)(mapping >> 8);
                    }
                    else
                    {
                        mapData[i] = (byte)tileIndex;
                    }
                }
            }

            return(replaceData(mapData, token));
        }
        public void ArraysSupportEnums()
        {
            var changeToken = new ModelDelta();

            var(model, viewPort) = (Model, ViewPort);

            // arrange: setup the anchor used for the enums
            WriteStrings(model.RawData, 0x00, "cat", "bat", "hat", "sat");
            ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var arrayRun);
            model.ObserveAnchorWritten(changeToken, "sample", arrayRun);

            // arrange: setup the anchor with the data
            ArrayRun.TryParse(model, "[option:sample]4", 0x40, null, out arrayRun);
            model.ObserveAnchorWritten(changeToken, "data", arrayRun);

            changeToken.ChangeData(model, 0x42, 2);

            // act: see that the arrayRun can parse according to the enum
            arrayRun = (ArrayRun)model.GetNextRun(0x40);
            Assert.Equal("cat", arrayRun.ElementContent[0].ToText(model, 0x40));
            Assert.Equal("hat", arrayRun.ElementContent[0].ToText(model, 0x42));

            viewPort.Refresh();
            var enumViewModel = (IntegerEnum)((Anchor)viewPort[0, 4].Format).OriginalFormat;

            Assert.Equal("cat", enumViewModel.Value);
        }
        public void ViewModelReturnsErrorWhenEnumIsNotValidValue()
        {
            Model[0x42] = 2; // hat
            var changeToken = new ModelDelta();

            var(model, viewPort) = (Model, ViewPort);

            // arrange: setup the anchor used for the enums
            WriteStrings(model.RawData, 0x00, "cat", "bat", "hat", "sat");
            var error = ArrayRun.TryParse(model, "^[name\"\"4]4", 0x00, null, out var arrayRun);

            model.ObserveAnchorWritten(changeToken, "sample", arrayRun);

            // arrange: setup the anchor with the data
            error = ArrayRun.TryParse(model, "[option.sample]4", 0x40, null, out arrayRun);
            model.ObserveAnchorWritten(changeToken, "data", arrayRun);

            // act: use a viewmodel to try to change 41 to 'pat' (invalid)
            ViewPort.Refresh();
            viewPort.SelectionStart = new Point(1, 4); // select space 0x41
            var errors = new List <string>();

            viewPort.OnError += (sender, e) => errors.Add(e);

            viewPort.Edit("pat ");
            Assert.Single(errors);
        }
        public void CanRemovePointerToWithinArray()
        {
            var data        = new byte[0x200];
            var changeToken = new ModelDelta();

            // arrange: setup data with a bunch of pointers pointing into an array of strings
            var model = new PokemonModel(data);

            model.WritePointer(changeToken, 0x00, 0x80);
            model.ObserveRunWritten(changeToken, new PointerRun(0x00));
            model.WritePointer(changeToken, 0x08, 0x84);
            model.ObserveRunWritten(changeToken, new PointerRun(0x08));
            model.WritePointer(changeToken, 0x10, 0x88);
            model.ObserveRunWritten(changeToken, new PointerRun(0x10));
            model.WritePointer(changeToken, 0x18, 0x8C);
            model.ObserveRunWritten(changeToken, new PointerRun(0x18));

            // arrange: setup the array of strings
            WriteStrings(data, 0x80, "cat", "bat", "hat", "sat");
            var existingAnchor = model.GetNextAnchor(0x80);

            ArrayRun.TryParse(model, "^[name\"\"4]4", 0x80, existingAnchor.PointerSources, out var arrayRun);
            model.ObserveAnchorWritten(changeToken, "sample", arrayRun);

            // act: clear the pointer
            model.ClearFormat(changeToken, 0x08, 4);

            // assert: array doesn't have pointer anymore
            var array = (ArrayRun)model.GetNextAnchor(0x80);

            Assert.Empty(array.PointerSourcesForInnerElements[1]);
        }
        public void AddingToAnArrayWithFixedLengthUpdatesTheAnchorFormat()
        {
            // arrange
            var(model, viewPort) = (Model, ViewPort);
            var delta    = new ModelDelta();
            var errors   = new List <string>();
            var elements = new[] { "123", "alice", "candy land", "hello world", "fortify" };

            for (int i = 0; i < elements.Length; i++)
            {
                var content = PCSString.Convert(elements[i]);
                while (content.Count < 0x10)
                {
                    content.Add(0x00);
                }
                Array.Copy(content.ToArray(), 0, model.RawData, 0x10 * i + 0x20, 0x10);
            }
            model.WritePointer(delta, 0x00, 0x20);
            model.ObserveRunWritten(delta, new PointerRun(0x00));
            model.WritePointer(delta, 0x04, 0x90);
            model.ObserveRunWritten(delta, new PointerRun(0x04)); // the anchor at 0x90 should prevent a paste overwrite
            viewPort.SelectionStart = new Point(0, 2);
            viewPort.Edit("^testdata[name\"\"16]5 ");
            viewPort.Goto.Execute("000000");
            viewPort.OnError += (sender, message) => errors.Add(message);

            // act -> add an element
            viewPort.SelectionStart = new Point(0, 7);
            viewPort.Edit("+\"crab\"");

            // assert -> length changed
            viewPort.SelectionStart = new Point(0, 2);
            Assert.True(viewPort.AnchorTextVisible);
            Assert.Equal("^testdata[name\"\"16]6", viewPort.AnchorText);
        }
        public void ArrayIsRecognizedByStringTool()
        {
            var changeToken = new ModelDelta();

            var(model, viewPort) = (Model, ViewPort);
            WriteStrings(model.RawData, 100, "bobb", "tomm", "samm", "carr", "pall", "eggg");

            model.WritePointer(changeToken, 200, 100);
            model.ObserveRunWritten(changeToken, new PointerRun(200));

            ArrayRun.TryParse(model, "[word\"\"5]", 100, null, out var arrayRun);
            model.ObserveAnchorWritten(new ModelDelta(), "words", arrayRun);

            viewPort.FollowLink(0, 7); // 7*16 = 112, right in the middle of our data
            // note that this will change our width to 15, because we're linking to data of width 5 when our maxwidth is 16.

            Assert.Equal(viewPort.Tools.IndexOf(viewPort.Tools.StringTool), viewPort.Tools.SelectedIndex); // string tool is selected
            Assert.Equal(100, viewPort.Tools.StringTool.Address);
            var lineCount = viewPort.Tools.StringTool.Content.Split(Environment.NewLine).Length;

            Assert.Equal(6, lineCount);

            viewPort.Tools.StringTool.ContentIndex = viewPort.Tools.StringTool.Content.IndexOf("pall");
            Assert.Equal(new Point(120 % 16, 120 / 16), viewPort.SelectionStart);
        }
Exemple #15
0
        public static ITilesetRun SetPixels(ITilesetRun run, IDataModel model, ModelDelta token, IReadOnlyList <int[, ]> tiles, Func <int, SortedSpan <int>, ITilesetRun> construct)
        {
            var tileSize = 8 * run.TilesetFormat.BitsPerPixel;
            var data     = new byte[tiles.Count * tileSize];

            for (int i = 0; i < tiles.Count; i++)
            {
                SpriteRun.SetPixels(data, i * tileSize, tiles[i], run.TilesetFormat.BitsPerPixel);
            }

            var newModelData = Compress(data, 0, data.Length);
            var newRun       = model.RelocateForExpansion(token, run, newModelData.Count);

            for (int i = 0; i < newModelData.Count; i++)
            {
                token.ChangeData(model, newRun.Start + i, newModelData[i]);
            }
            for (int i = newModelData.Count; i < run.Length; i++)
            {
                token.ChangeData(model, newRun.Start + i, 0xFF);
            }
            newRun = construct(newRun.Start, newRun.PointerSources);
            model.ObserveRunWritten(token, newRun);
            return(newRun);
        }
        public ITableRun Append(ModelDelta token, int length)
        {
            var parent = PointerSources[0];

            model.WriteMultiByteValue(parent + 4, 2, token, ElementCount + length);
            return(UpdateFromParent(token, 1, parent, out var _));
        }
Exemple #17
0
 public bool UpdateLimiter(ModelDelta token) {
    if (PointerSources?.Count != 2) return false;
    var address = PointerSources.Last() - 4;
    var limiter = Length / 2 - 2;
    model.WriteMultiByteValue(address, 4, token, limiter);
    return true;
 }
Exemple #18
0
      public IStreamRun DeserializeRun(string content, ModelDelta token) {
         var cache = ModelCacheScope.GetCache(model);
         var cachedPokenames = cache.GetOptions(PokemonNameTable);
         var cachedMovenames = cache.GetOptions(MoveNamesTable);

         var data = new List<int>();
         var pokemonNames = cachedPokenames.Select(name => $"{GroupStart}{name.Trim('"').ToLower()}{GroupEnd}").ToList();
         var moveNames = cachedMovenames.Select(name => name.Trim('"').ToLower()).ToList();
         var lines = content.ToLower().Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
         foreach (var line in lines) {
            var index = pokemonNames.IndexOf(line);
            if (index != -1) { data.Add(index + MagicNumber); continue; }
            index = moveNames.IndexOf(line);
            if (index != -1) { data.Add(index); continue; }

            // didn't find an exact match... look for a partial pokemon match
            var matchFound = false;
            for (int i = 0; i < pokemonNames.Count; i++) {
               if (pokemonNames[i].Contains(line)) { data.Add(i + MagicNumber); matchFound = true; break; }
            }
            if (matchFound) continue;

            // look for a partial move match
            for (int i = 0; i < moveNames.Count; i++) {
               if (moveNames[i].Contains(line)) { data.Add(i); break; }
            }
         }
         var run = model.RelocateForExpansion(token, this, data.Count * 2 + 2);
         for (int i = 0; i < data.Count; i++) model.WriteMultiByteValue(run.Start + i * 2, 2, token, data[i]);
         model.WriteMultiByteValue(run.Start + data.Count * 2, 2, token, EndStream); // write the new end token
         for (int i = data.Count + 2; i < Length / 2; i++) model.WriteMultiByteValue(run.Start + i * 2, 2, token, EndStream); // fill any remaining old space with FF
         return new EggMoveRun(model, run.Start);
      }
        public ArrayRun AddSourcesPointingWithinArray(ModelDelta changeToken)
        {
            if (ElementCount < 2)
            {
                return(this);
            }

            var destinations = new int[ElementCount - 1];

            for (int i = 1; i < ElementCount; i++)
            {
                destinations[i - 1] = Start + ElementLength * i;
            }

            var sources = owner.SearchForPointersToAnchor(changeToken, destinations);

            var results = new List <List <int> >();

            results.Add(PointerSources?.ToList() ?? new List <int>());
            for (int i = 1; i < ElementCount; i++)
            {
                results.Add(new List <int>());
            }

            foreach (var source in sources)
            {
                var destination      = owner.ReadPointer(source);
                int destinationIndex = (destination - Start) / ElementLength;
                results[destinationIndex].Add(source);
            }

            var pointerSourcesForInnerElements = results.Cast <IReadOnlyList <int> >().ToList();

            return(new ArrayRun(owner, FormatString, LengthFromAnchor, Start, ElementCount, ElementContent, PointerSources, pointerSourcesForInnerElements));
        }
        public void WriteNewFormat(IDataModel owner, ModelDelta token, int source, int destination, IReadOnlyList <ArrayRunElementSegment> sourceSegments)
        {
            owner.WritePointer(token, source, destination);
            var newRun = Factory.GetStrategy(InnerFormat).WriteNewRun(owner, token, source, destination, Name, sourceSegments);

            owner.ObserveRunWritten(token, newRun.MergeAnchor(new SortedSpan <int>(source)));
        }
        public TableStreamRun Append(TableStreamRun run, ModelDelta token, int length)
        {
            var naturalLength = run.Length - EndCode.Count;
            var newRun        = model.RelocateForExpansion(token, run, naturalLength + length * run.ElementLength + EndCode.Count);

            if (naturalLength == 0)
            {
                for (int i = 0; i < run.ElementLength * length; i++)
                {
                    token.ChangeData(model, newRun.Start + naturalLength + i, 0);
                }
            }
            else
            {
                for (int i = 0; i < run.ElementLength * length; i++)
                {
                    token.ChangeData(model, newRun.Start + naturalLength + i, model[newRun.Start + naturalLength + i - run.ElementLength]);
                }
            }
            for (int i = naturalLength + length * run.ElementLength; i < naturalLength; i++)
            {
                if (model[newRun.Start + i] != 0xFF)
                {
                    token.ChangeData(model, newRun.Start + i, 0xFF);
                }
            }
            for (int i = 0; i < EndCode.Count; i++)
            {
                token.ChangeData(model, newRun.Start + naturalLength + length * run.ElementLength + i, EndCode[i]);
            }
            return(new TableStreamRun(model, newRun.Start, run.PointerSources, run.FormatString, run.ElementContent, this, run.ElementCount + length));
        }
        public override bool Write(IDataModel model, ModelDelta token, int start, ref string data)
        {
            if (data.StartsWith("(") && data.EndsWith(")"))
            {
                data = data.Substring(1, data.Length - 2);
            }
            var tokens    = TableStreamRun.Tokenize(data);
            var remainder = ", ".Join(tokens.Skip(1));

            if (tokens.Count == 0)
            {
                return(false);
            }
            data = tokens[0];
            bool result;

            if (!TryParse(model, data, out int value))
            {
                result = base.Write(model, token, start, ref data);
            }
            else
            {
                data   = value.ToString();
                result = base.Write(model, token, start, ref data);
            }

            data = remainder;
            return(result);
        }
Exemple #23
0
        public override void UpdateNewRunFromPointerFormat(IDataModel model, ModelDelta token, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex, ref IFormattedRun run)
        {
            var newRun = new TilemapRun(model, run.Start, format, run.PointerSources);

            model.ClearFormat(token, newRun.Start, newRun.Length);
            run = newRun;
        }
        public override bool Write(IDataModel model, ModelDelta token, int start, ref string data)
        {
            if (data.StartsWith("(") && data.EndsWith(")"))
            {
                data = data.Substring(1, data.Length - 2);
            }
            var remainder = string.Empty;

            if (Type != ElementContentType.PCS)
            {
                var tokens = TableStreamRun.Tokenize(data);
                remainder = ", ".Join(tokens.Skip(1));
                data      = tokens[0];
            }

            data = data.Trim();
            if (data.StartsWith("0x"))
            {
                data = data.Substring(2);
            }
            if (!int.TryParse(data, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out var intValue))
            {
                intValue = 0;
            }
            data = remainder;
            return(model.WriteMultiByteValue(start, Length, token, intValue));
        }
Exemple #25
0
 public void Clear(IDataModel model, ModelDelta changeToken, int start, int length)
 {
     for (int i = 0; i < length; i++)
     {
         changeToken.ChangeData(model, start + i, 0x00);
     }
 }
Exemple #26
0
        public IStreamRun DeserializeRun(string content, ModelDelta token)
        {
            var uncompressed = new List <byte>();

            foreach (var textByte in content.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (byte.TryParse(textByte, NumberStyles.HexNumber, CultureInfo.CurrentCulture, out byte value))
                {
                    uncompressed.Add(value);
                }
            }
            var        compressed = Compress(uncompressed, 0, uncompressed.Count);
            IStreamRun run        = this;

            if (compressed.Count > Length)
            {
                run = (IStreamRun)Model.RelocateForExpansion(token, this, compressed.Count);
            }
            for (int i = 0; i < compressed.Count; i++)
            {
                token.ChangeData(Model, run.Start + i, compressed[i]);
            }
            for (int i = compressed.Count; i < Length; i++)
            {
                token.ChangeData(Model, run.Start + i, 0xFF);
            }
            return((LZRun)Duplicate(run.Start, PointerSources));
        }
Exemple #27
0
        public void ViewPortWarnsIfLoadedMatchedWordValueDoesNotMatch()
        {
            // Arrange
            var data   = new byte[0x200];
            var model  = new PokemonModel(data);
            var change = new ModelDelta();

            ArrayRun.TryParse(model, "[a:]8", 0x10, null, out var table);
            model.ObserveAnchorWritten(change, "table", table);
            change.AddMatchedWord(model, 0, "table");
            model.ObserveRunWritten(change, new WordRun(0, "table"));

            fileSystem.MetadataFor = name => model.ExportMetadata().Serialize();
            fileSystem.OpenFile    = (name, extensions) => new LoadedFile(name, data);
            var editor = new EditorViewModel(fileSystem);

            // change the data so that the viewPort will notice something weird
            change.ChangeData(model, 0, 4);

            // Act
            editor.Open.Execute("text.gba");

            // Assert
            Assert.True(editor.ShowMessage);
        }
Exemple #28
0
        public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int page, int[,] pixels)
        {
            // TODO handle the fact that pixels[,] may contain a different number of tiles compared to the existing tileset
            var data = Decompress(model, Start);

            for (int x = 0; x < pixels.GetLength(0); x++)
            {
                for (int y = 0; y < pixels.GetLength(1); y++)
                {
                    pixels[x, y] %= (int)Math.Pow(2, TilesetFormat.BitsPerPixel);
                }
            }
            SpriteRun.SetPixels(data, 0, pixels, TilesetFormat.BitsPerPixel);
            var newModelData = Compress(data, 0, data.Length);
            var newRun       = model.RelocateForExpansion(token, this, newModelData.Count);

            for (int i = 0; i < newModelData.Count; i++)
            {
                token.ChangeData(model, newRun.Start + i, newModelData[i]);
            }
            for (int i = newModelData.Count; i < Length; i++)
            {
                token.ChangeData(model, newRun.Start + i, 0xFF);
            }
            newRun = new LzTilesetRun(TilesetFormat, model, newRun.Start, newRun.PointerSources);
            model.ObserveRunWritten(token, newRun);
            return(newRun);
        }
Exemple #29
0
        public void AddingAnchorShouldSearchForPointersToThatLocation()
        {
            var data   = new byte[0x200];
            var model  = new PokemonModel(data);
            var change = new ModelDelta();

            model.WritePointer(change, 0x23, 0x050); // a pointer that isn't 4-byte aligned, pointing to data that is
            model.WritePointer(change, 0x10, 0x087); // a pointer that is 4-byte aligned, but pointing to something that isn't
            model.WritePointer(change, 2, 0xA2);     // a pointer that isn't 4-byte aligned, pointing to something not 4-byte aligned
            var viewPort = new ViewPort("file.txt", model)
            {
                Width = 0x10, Height = 0x10
            };

            // got to 50 and write an anchor
            viewPort.SelectionStart = new Point(0x0, 0x5);
            viewPort.Edit("^test1 ");
            Assert.IsType <Pointer>(viewPort[0x3, 0x2].Format);
            Assert.Single(((Anchor)viewPort[0x0, 0x5].Format).Sources);

            // go to 87 and write an anchor
            viewPort.SelectionStart = new Point(0x7, 0x8);
            viewPort.Edit("^test2 ");
            Assert.IsType <Pointer>(viewPort[0x0, 0x1].Format);
            Assert.Single(((Anchor)viewPort[0x7, 0x8].Format).Sources);

            // go to A2 and write an anchor
            viewPort.SelectionStart = new Point(0x2, 0xA);
            viewPort.Edit("^test3 ");
            Assert.IsType <Pointer>(viewPort[0x2, 0x0].Format);
            Assert.Single(((Anchor)viewPort[0x2, 0xA].Format).Sources);
        }
        public TableStreamRun Append(TableStreamRun run, ModelDelta token, int length)
        {
            var parentIndex = GetParentIndex(run.PointerSources);
            var parent      = model.GetNextRun(parentIndex) as ITableRun;

            if (parent == null)
            {
                return(run);
            }
            var segmentIndex = GetSegmentIndex(parent.ElementContent, parentFieldForLength);

            if (segmentIndex == -1)
            {
                return(run);
            }

            UpdateParents(token, parent, segmentIndex, run.ElementCount + length, run.PointerSources);

            var naturalLength = run.Length;
            var newRun        = (TableStreamRun)model.RelocateForExpansion(token, run, naturalLength + length * run.ElementLength);

            for (int i = 0; i < run.ElementLength * length; i++)
            {
                token.ChangeData(model, newRun.Start + naturalLength + i, 0x00);
            }
            for (int i = naturalLength + length * run.ElementLength; i < naturalLength; i++)
            {
                if (model[newRun.Start + i] != 0xFF)
                {
                    token.ChangeData(model, newRun.Start + i, 0xFF);
                }
            }
            return(new TableStreamRun(model, newRun.Start, run.PointerSources, run.FormatString, run.ElementContent, this));
        }