Example #1
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);
        }
Example #2
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);
        }
Example #3
0
        public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int[][,] tiles)
        {
            var tileSize = 8 * Format.BitsPerPixel;
            var data     = new byte[tiles.Length * tileSize];

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

            var newModelData = Compress(data, 0, data.Length);
            var newRun       = (LzTilesetRun)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(Format, model, newRun.Start, newRun.PointerSources);
            model.ObserveRunWritten(token, newRun);
            return(newRun);
        }
        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)));
        }
Example #5
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);
        }
Example #6
0
        public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex)
        {
            var newRun = new TilemapRun(owner, destination, format);

            if (!(token is NoDataChangeDeltaModel))
            {
                owner.ObserveRunWritten(token, newRun);
            }
            return(true);
        }
Example #7
0
        public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex)
        {
            var run = new ASERun(destination, new SortedSpan <int>(source));

            if (run.Length < 1)
            {
                return(false);
            }
            owner.ClearFormat(token, run.Start, run.Length);
            owner.ObserveRunWritten(token, run);
            return(true);
        }
Example #8
0
 public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments)
 {
     if (TableStreamRun.TryParseTableStream(owner, destination, new SortedSpan <int>(source), name, Format, sourceSegments, out var tsRun))
     {
         if (!(token is NoDataChangeDeltaModel))
         {
             owner.ObserveRunWritten(token, tsRun);
         }
         return(true);
     }
     return(false);
 }
Example #9
0
 public void Visit(StreamEndDecorator decorator, byte data)
 {
     if (CurrentText == "[]")
     {
         var run = (TableStreamRun)Model.GetNextRun(memoryLocation);
         var newDesiredElementCount = (memoryLocation - run.Start) / run.ElementLength;
         var newRun = run.Append(CurrentChange, newDesiredElementCount - run.ElementCount);
         Model.ObserveRunWritten(CurrentChange, newRun);
         for (int i = newRun.Length; i < run.Length; i++)
         {
             CurrentChange.ChangeData(Model, newRun.Start + i, 0xFF);
         }
         var endTokenLength = run.Length - run.ElementLength * run.ElementCount;
         NewDataIndex = memoryLocation + endTokenLength;
         Result       = true;
     }
     else
     {
         decorator.OriginalFormat.Visit(this, data);
     }
 }
        public ISpriteRun SetPixels(IDataModel model, ModelDelta token, int page, int[,] pixels)
        {
            var tileData       = Tilize(pixels);
            var tiles          = GetUniqueTiles(tileData);
            var tilesetAddress = model.GetAddressFromAnchor(new NoDataChangeDeltaModel(), -1, Format.MatchingTileset);
            var tileset        = model.GetNextRun(tilesetAddress) as LzTilesetRun;

            if (tileset == null)
            {
                tileset = model.GetNextRun(arrayTilesetAddress) as LzTilesetRun;
            }
            tileset.SetPixels(model, token, tiles);
            if (tiles.Length > 0x400)
            {
                // TODO fail: too many unique tiles
                return(this);
            }
            var mapData = Decompress(model, Start);

            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);
                    var mapping = PackMapping(paletteIndex, matchType, tileIndex);
                    mapData[i * 2 + 0] = (byte)mapping;
                    mapData[i * 2 + 1] = (byte)(mapping >> 8);
                }
            }

            var newModelData = Compress(mapData, 0, mapData.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 LzTilemapRun(Format, model, newRun.Start, newRun.PointerSources);
            model.ObserveRunWritten(token, newRun);
            return(newRun);
        }
Example #11
0
        public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex)
        {
            var plmRun = new PLMRun(owner, destination);
            var length = plmRun.Length;

            if (length < 2)
            {
                return(false);
            }

            if (!(token is NoDataChangeDeltaModel))
            {
                owner.ObserveRunWritten(token, plmRun);
            }

            return(true);
        }
Example #12
0
        public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments)
        {
            var teamRun = new TrainerPokemonTeamRun(owner, destination, new SortedSpan <int>(source));
            var length  = teamRun.Length;

            if (length < 2)
            {
                return(false);
            }

            if (!(token is NoDataChangeDeltaModel))
            {
                owner.ObserveRunWritten(token, teamRun);
            }

            return(true);
        }
Example #13
0
        public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments)
        {
            var length = PCSString.ReadString(owner, destination, true);

            if (length < 1)
            {
                return(false);
            }

            // our token will be a no-change token if we're in the middle of exploring the data.
            // If so, don't actually add the run. It's enough to know that we _can_ add the run.
            if (!(token is NoDataChangeDeltaModel))
            {
                owner.ObserveRunWritten(token, new PCSRun(owner, destination, length));
            }

            // even if we didn't add the format, we're _capable_ of adding it... so return true
            return(true);
        }
Example #14
0
 public override bool TryAddFormatAtDestination(IDataModel owner, ModelDelta token, int source, int destination, string name, IReadOnlyList <ArrayRunElementSegment> sourceSegments, int parentIndex)
 {
     if (TableStreamRun.TryParseTableStream(owner, destination, new SortedSpan <int>(source), name, Format, sourceSegments, out var tsRun))
     {
         if (token is not NoDataChangeDeltaModel)
         {
             // we know that the data format matches, but there may already be a run there that starts sooner
             if (owner.GetNextRun(tsRun.Start) is ITableRun existingTable && existingTable.Start < tsRun.Start)
             {
                 // there is already a format that starts sooner: do nothing, but return true because the format matches
             }
             else
             {
                 owner.ClearFormat(token, tsRun.Start + 1, tsRun.Length - 1);
                 owner.ObserveRunWritten(token, tsRun);
             }
         }
         return(true);
     }
 public MapAnimationTilesRun UpdateFromParent(ModelDelta token, int segmentIndex, int pointerSource, out bool childrenMoved)
 {
     childrenMoved = false;
     if (segmentIndex == 1)
     {
         var newTableCount = model.ReadMultiByteValue(pointerSource + 4, 2);
         var self          = model.RelocateForExpansion(token, this, newTableCount * 4);
         for (int i = ElementCount; i < newTableCount; i++)
         {
             model.WritePointer(token, self.Start + 4 * i, Pointer.NULL);
         }
         return(new MapAnimationTilesRun(model, self.Start, self.PointerSources));
     }
     else if (segmentIndex == 3)
     {
         var newTileCount  = model[pointerSource + 7];
         var tilesetFormat = new TilesetFormat(4, newTileCount, -1, default);
         for (int i = 0; i < ElementCount; i++)
         {
             var destination = model.ReadPointer(Start + ElementLength * i);
             if (destination == Pointer.NULL)
             {
                 continue;
             }
             var child    = (ISpriteRun)model.GetNextRun(destination);
             var newChild = model.RelocateForExpansion(token, child, newTileCount * 32);
             if (newChild.Start != child.Start)
             {
                 childrenMoved = true;
             }
             model.ObserveRunWritten(token, new TilesetRun(tilesetFormat, model, newChild.Start, newChild.PointerSources));
         }
         return(this);
     }
     else
     {
         return(this);
     }
 }
        public IPaletteRun SetPalette(IDataModel model, ModelDelta token, int page, IReadOnlyList <short> colors)
        {
            var data       = Decompress(model, Start);
            var colorCount = (int)Math.Pow(2, PaletteFormat.Bits);
            var pageLength = colorCount * 2;

            page %= Pages;
            PaletteRun.SetPalette(data, page * pageLength, colors);

            var newModelData = Compress(data, 0, data.Length);
            var newRun       = (IPaletteRun)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 LzPaletteRun(PaletteFormat, model, newRun.Start, newRun.PointerSources);
            model.ObserveRunWritten(token, newRun);
            return(newRun);
        }
Example #17
0
        public void Visit(PlmItem item, byte data)
        {
            var memoryLocation = this.memoryLocation;
            var run            = (PLMRun)Model.GetNextRun(memoryLocation);

            // part 1: contraction (if they entered the end token)
            if (CurrentText == EggMoveRun.GroupStart + EggMoveRun.GroupEnd)
            {
                for (int i = this.memoryLocation; i < run.Start + run.Length; i += 2)
                {
                    Model.WriteMultiByteValue(i, 2, CurrentChange, 0xFFFF);
                }
                Model.ObserveRunWritten(CurrentChange, new PLMRun(Model, run.Start));
                return;
            }

            // part 2: validation
            if (!CurrentText.Contains(" "))
            {
                return;
            }
            var quoteCount = CurrentText.Count(c => c == StringDelimeter);

            if (quoteCount % 2 != 0)
            {
                return;
            }
            if (!CurrentText.EndsWith(StringDelimeter.ToString()) && !CurrentText.EndsWith(" "))
            {
                return;
            }
            ErrorText = ValidatePlmText(run, quoteCount, out var level, out var move);
            if (ErrorText != null || move == -1)
            {
                return;
            }

            // part 3: write to the model
            NewDataIndex = memoryLocation + 2;
            Result       = true;
            var value            = (level << 9) + move;
            var initialItemValue = Model.ReadMultiByteValue(memoryLocation, 2);

            Model.WriteMultiByteValue(memoryLocation, 2, CurrentChange, value);

            // part 4: expansion
            if (initialItemValue == 0xFFFF)
            {
                var newRun = Model.RelocateForExpansion(CurrentChange, run, run.Length + 2);
                if (newRun.Start != run.Start)
                {
                    MessageText     = $"Level Up Moves were automatically moved to {newRun.Start.ToString("X6")}. Pointers were updated.";
                    memoryLocation += newRun.Start - run.Start;
                    NewDataIndex    = memoryLocation + 2;
                    DataMoved       = true;
                }
                Model.WriteMultiByteValue(memoryLocation + 2, 2, CurrentChange, 0xFFFF);
                var lvlRun = new PLMRun(Model, newRun.Start);
                Model.ObserveRunWritten(CurrentChange, lvlRun);
            }
        }