Add() публичный Метод

public Add ( Bitmap src ) : Sprite
src System.Drawing.Bitmap
Результат Sprite
Пример #1
0
        public Theater(TileSet tileset)
        {
            var allocated = false;
            Func<Sheet> allocate = () =>
            {
                if (allocated)
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                allocated = true;

                return new Sheet(new Size(tileset.SheetSize, tileset.SheetSize), true);
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            templates = new Dictionary<ushort, Sprite[]>();

            var frameCache = new FrameCache(Game.modData.SpriteLoaders, tileset.Extensions);
            foreach (var t in tileset.Templates)
            {
                var allFrames = frameCache[t.Value.Image];
                var frames = t.Value.Frames != null ? t.Value.Frames.Select(f => allFrames[f]).ToArray() : allFrames;
                templates.Add(t.Value.Id, frames.Select(f => sheetBuilder.Add(f)).ToArray());
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #2
0
        Sprite[] LoadTemplate(string filename, string[] exts, Dictionary <string, ISpriteSource> sourceCache, int[] frames)
        {
            ISpriteSource source;

            if (!sourceCache.ContainsKey(filename))
            {
                using (var s = GlobalFileSystem.OpenWithExts(filename, exts))
                    source = SpriteSource.LoadSpriteSource(s, filename);

                if (source.CacheWhenLoadingTileset)
                {
                    sourceCache.Add(filename, source);
                }
            }
            else
            {
                source = sourceCache[filename];
            }

            if (frames != null)
            {
                var ret       = new List <Sprite>();
                var srcFrames = source.Frames.ToArray();
                foreach (var i in frames)
                {
                    ret.Add(sheetBuilder.Add(srcFrames[i]));
                }

                return(ret.ToArray());
            }

            return(source.Frames.Select(f => sheetBuilder.Add(f)).ToArray());
        }
Пример #3
0
        public Theater(TileSet tileset)
        {
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize), true));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            templates    = new Dictionary <ushort, Sprite[]>();

            var frameCache = new FrameCache(Game.modData.SpriteLoaders, tileset.Extensions);

            foreach (var t in tileset.Templates)
            {
                var allFrames = frameCache[t.Value.Image];
                var frames    = t.Value.Frames != null?t.Value.Frames.Select(f => allFrames[f]).ToArray() : allFrames;

                templates.Add(t.Value.Id, frames.Select(f => sheetBuilder.Add(f)).ToArray());
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #4
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            random       = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames = frameCache[i];
                    var frames    = t.Value.Frames != null?t.Value.Frames.Select(f => allFrames[f]).ToArray() : allFrames;

                    variants.Add(frames.Select(f => sheetBuilder.Add(f)).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, float2.Zero, s.Channel, s.BlendMode));
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #5
0
        public Theater(TileSet tileset)
        {
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize), true));
            };

            var sourceCache = new Dictionary <string, ISpriteSource>();

            templates    = new Dictionary <ushort, Sprite[]>();
            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            foreach (var t in tileset.Templates)
            {
                templates.Add(t.Value.Id, LoadTemplate(t.Value.Image, tileset.Extensions, sourceCache, t.Value.Frames));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #6
0
        public Theater(TileSet tileset)
        {
            var          allocated = false;
            Func <Sheet> allocate  = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            var r8Cache = new Cache <string, R8Reader>(s => new R8Reader(FileSystem.OpenWithExts(s, ".R8")));

            templates    = new Dictionary <ushort, Sprite[]>();
            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            foreach (var t in tileset.Templates)
            {
                templates.Add(t.Value.Id, LoadTemplate(t.Value.Image, tileset.Extensions, r8Cache, t.Value.Frames));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));
        }
Пример #7
0
        public HardwareCursor(CursorProvider cursorProvider)
        {
            this.cursorProvider = cursorProvider;

            paletteReferences = new Cache <string, PaletteReference>(CreatePaletteReference);
            foreach (var p in cursorProvider.Palettes)
            {
                hardwarePalette.AddPalette(p.Key, p.Value, false);
            }

            hardwarePalette.Initialize();

            sheetBuilder = new SheetBuilder(SheetType.Indexed);
            foreach (var kv in cursorProvider.Cursors)
            {
                var palette = cursorProvider.Palettes[kv.Value.Palette];
                var hc      = kv.Value.Frames
                              .Select(f => CreateCursor(f, palette, kv.Key, kv.Value))
                              .ToArray();

                hardwareCursors.Add(kv.Key, hc);

                var s = kv.Value.Frames.Select(a => sheetBuilder.Add(a)).ToArray();
                sprites.Add(kv.Key, s);
            }

            sheetBuilder.Current.ReleaseBuffer();

            Update();
        }
Пример #8
0
 Sprite[] CacheSpriteFrames(string filename)
 {
     using (var stream = GlobalFileSystem.OpenWithExts(filename, exts))
         return(SpriteSource.LoadSpriteSource(stream, filename).Frames
                .Select(a => SheetBuilder.Add(a))
                .ToArray());
 }
Пример #9
0
        public HardwareCursor(CursorProvider cursorProvider)
        {
            this.cursorProvider = cursorProvider;

            paletteReferences = new Cache <string, PaletteReference>(CreatePaletteReference);
            foreach (var p in cursorProvider.Palettes)
            {
                hardwarePalette.AddPalette(p.Key, p.Value, false);
            }

            hardwarePalette.Initialize();
            sheetBuilder = new SheetBuilder(SheetType.Indexed);
            foreach (var kv in cursorProvider.Cursors)
            {
                var frames  = kv.Value.Frames;
                var palette = cursorProvider.Palettes[kv.Value.Palette];

                // Hardware cursors have a number of odd platform-specific bugs/limitations.
                // Reduce the number of edge cases by padding the individual frames such that:
                // - the hotspot is inside the frame bounds (enforced by SDL)
                // - all frames within a sequence have the same size (needed for macOS 10.15)
                // - the frame size is a multiple of 8 (needed for Windows)
                var sequenceBounds = Rectangle.FromLTRB(0, 0, 1, 1);
                var frameHotspots  = new int2[frames.Length];
                for (var i = 0; i < frames.Length; i++)
                {
                    // Hotspot relative to the center of the frame
                    frameHotspots[i] = kv.Value.Hotspot - frames[i].Offset.ToInt2() + new int2(frames[i].Size) / 2;

                    // Bounds relative to the hotspot
                    sequenceBounds = Rectangle.Union(sequenceBounds, new Rectangle(-frameHotspots[i], frames[i].Size));
                }

                // Pad bottom-right edge to make the frame size a multiple of 8
                var paddedSize = 8 * new int2((sequenceBounds.Width + 7) / 8, (sequenceBounds.Height + 7) / 8);

                var cursors      = new IHardwareCursor[frames.Length];
                var frameSprites = new Sprite[frames.Length];
                for (var i = 0; i < frames.Length; i++)
                {
                    // Software rendering is used when the cursor is locked
                    frameSprites[i] = sheetBuilder.Add(frames[i].Data, frames[i].Size, 0, frames[i].Offset);

                    // Calculate the padding to position the frame within sequenceBounds
                    var paddingTL = -(sequenceBounds.Location + frameHotspots[i]);
                    var paddingBR = paddedSize - new int2(frames[i].Size) - paddingTL;
                    cursors[i] = CreateCursor(kv.Key, frames[i], palette, paddingTL, paddingBR, -sequenceBounds.Location);
                }

                hardwareCursors.Add(kv.Key, cursors);
                sprites.Add(kv.Key, frameSprites);
            }

            sheetBuilder.Current.ReleaseBuffer();

            Update();
        }
Пример #10
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var allocated = false;
            Func<Sheet> allocate = () =>
            {
                if (allocated)
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                allocated = true;

                return new Sheet(new Size(tileset.SheetSize, tileset.SheetSize));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            random = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.SpriteLoaders);
            foreach (var t in tileset.Templates)
            {
                var variants = new List<Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames = frameCache[i];
                    var frames = t.Value.Frames != null ? t.Value.Frames.Select(f => allFrames[f]).ToArray() : allFrames;
                    variants.Add(frames.Select(f => sheetBuilder.Add(f)).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, float2.Zero, s.Channel, s.BlendMode));

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #11
0
        public CursorManager(CursorProvider cursorProvider)
        {
            hardwareCursorsDisabled = Game.Settings.Graphics.DisableHardwareCursors;

            graphicSettings = Game.Settings.Graphics;
            sheetBuilder    = new SheetBuilder(SheetType.BGRA);
            foreach (var kv in cursorProvider.Cursors)
            {
                var frames  = kv.Value.Frames;
                var palette = !string.IsNullOrEmpty(kv.Value.Palette) ? cursorProvider.Palettes[kv.Value.Palette] : null;

                var c = new Cursor
                {
                    Name   = kv.Key,
                    Bounds = Rectangle.FromLTRB(0, 0, 1, 1),

                    Length  = 0,
                    Sprites = new Sprite[frames.Length],
                    Cursors = new IHardwareCursor[frames.Length]
                };

                // Hardware cursors have a number of odd platform-specific bugs/limitations.
                // Reduce the number of edge cases by padding the individual frames such that:
                // - the hotspot is inside the frame bounds (enforced by SDL)
                // - all frames within a sequence have the same size (needed for macOS 10.15)
                // - the frame size is a multiple of 8 (needed for Windows)
                foreach (var f in frames)
                {
                    // Hotspot is specified relative to the center of the frame
                    var hotspot = f.Offset.ToInt2() - kv.Value.Hotspot - new int2(f.Size) / 2;

                    // SheetBuilder expects data in BGRA
                    var data = FrameToBGRA(kv.Key, f, palette);
                    c.Sprites[c.Length++] = sheetBuilder.Add(data, f.Size, 0, hotspot);

                    // Bounds relative to the hotspot
                    c.Bounds = Rectangle.Union(c.Bounds, new Rectangle(hotspot, f.Size));
                }

                // Pad bottom-right edge to make the frame size a multiple of 8
                c.PaddedSize = 8 * new int2((c.Bounds.Width + 7) / 8, (c.Bounds.Height + 7) / 8);

                cursors.Add(kv.Key, c);
            }

            CreateOrUpdateHardwareCursors();

            foreach (var s in sheetBuilder.AllSheets)
            {
                s.ReleaseBuffer();
            }

            Update();
        }
Пример #12
0
        /// <summary>
        /// Returns the first set of sprites with the given filename.
        /// If getUsedFrames is defined then the indices returned by the function call
        /// are guaranteed to be loaded.  The value of other indices in the returned
        /// array are undefined and should never be accessed.
        /// </summary>
        public Sprite[] this[string filename, Func <int, IEnumerable <int> > getUsedFrames = null]
        {
            get
            {
                var allSprites = sprites.GetOrAdd(filename);
                var sprite     = allSprites.FirstOrDefault();

                ISpriteFrame[] unloaded;
                if (!unloadedFrames.TryGetValue(filename, out unloaded))
                {
                    unloaded = null;
                }

                // This is the first time that the file has been requested
                // Load all of the frames into the unused buffer and initialize
                // the loaded cache (initially empty)
                if (sprite == null)
                {
                    TypeDictionary fileMetadata = null;
                    unloaded = FrameLoader.GetFrames(fileSystem, filename, loaders, out fileMetadata);
                    unloadedFrames[filename] = unloaded;
                    metadata[filename]       = fileMetadata;

                    sprite = new Sprite[unloaded.Length];
                    allSprites.Add(sprite);
                }

                // HACK: The sequency code relies on side-effects from getUsedFrames
                var indices = getUsedFrames != null?getUsedFrames(sprite.Length) :
                                  Enumerable.Range(0, sprite.Length);

                // Load any unused frames into the SheetBuilder
                if (unloaded != null)
                {
                    foreach (var i in indices)
                    {
                        if (unloaded[i] != null)
                        {
                            sprite[i]   = SheetBuilder.Add(unloaded[i]);
                            unloaded[i] = null;
                        }
                    }

                    // All frames have been loaded
                    if (unloaded.All(f => f == null))
                    {
                        unloadedFrames.Remove(filename);
                    }
                }

                return(sprite);
            }
        }
Пример #13
0
        Sprite[] LoadSprites(string filename)
        {
            // TODO: Cleanly abstract file type detection
            if (filename.ToLower().EndsWith("r8"))
            {
                var r8 = new R8Reader(FileSystem.Open(filename));
                return(r8.Select(a => SheetBuilder.Add(a.Image, a.Size, a.Offset)).ToArray());
            }

            BinaryReader reader = new BinaryReader(FileSystem.OpenWithExts(filename, exts));

            var ImageCount = reader.ReadUInt16();

            if (ImageCount == 0)
            {
                var shp = new ShpTSReader(FileSystem.OpenWithExts(filename, exts));
                return(shp.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray());
            }
            else
            {
                var shp = new ShpReader(FileSystem.OpenWithExts(filename, exts));
                return(shp.Frames.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray());
            }
        }
Пример #14
0
        Sprite[] LoadTemplate(string filename, string[] exts, Cache <string, R8Reader> r8Cache, int[] frames)
        {
            if (exts.Contains(".R8") && FileSystem.Exists(filename + ".R8"))
            {
                return(frames.Select(f =>
                {
                    if (f < 0)
                    {
                        return null;
                    }

                    var image = r8Cache[filename][f];
                    return sheetBuilder.Add(image.Image, new Size(image.Size.Width, image.Size.Height));
                }).ToArray());
            }

            using (var s = FileSystem.OpenWithExts(filename, exts))
            {
                var t = new Terrain(s);
                return(t.TileBitmapBytes
                       .Select(b => b != null ? sheetBuilder.Add(b, new Size(t.Width, t.Height)) : null)
                       .ToArray());
            }
        }
Пример #15
0
        public SoftwareCursor(CursorProvider cursorProvider)
        {
            this.cursorProvider = cursorProvider;

            paletteReferences = new Cache<string, PaletteReference>(CreatePaletteReference);
            foreach (var p in cursorProvider.Palettes)
                palette.AddPalette(p.Key, p.Value, false);

            palette.Initialize();

            sheetBuilder = new SheetBuilder(SheetType.Indexed);
            foreach (var kv in cursorProvider.Cursors)
            {
                var s = kv.Value.Frames.Select(a => sheetBuilder.Add(a)).ToArray();
                sprites.Add(kv.Key, s);
            }

            sheetBuilder.Current.ReleaseBuffer();

            Game.Renderer.Device.SetHardwareCursor(null);
        }
Пример #16
0
        public Theater(TileSet tileset)
        {
            var allocated = false;
            Func<Sheet> allocate = () =>
            {
                if (allocated)
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                allocated = true;

                return new Sheet(new Size(tileset.SheetSize, tileset.SheetSize));
            };

            var sourceCache = new Dictionary<string, ISpriteSource>();
            templates = new Dictionary<ushort, Sprite[]>();
            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            foreach (var t in tileset.Templates)
                templates.Add(t.Value.Id, LoadTemplate(t.Value.Image, tileset.Extensions, sourceCache, t.Value.Frames));

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));
        }
Пример #17
0
        public SoftwareCursor(CursorProvider cursorProvider)
        {
            this.cursorProvider = cursorProvider;

            paletteReferences = new Cache <string, PaletteReference>(CreatePaletteReference);
            foreach (var p in cursorProvider.Palettes)
            {
                palette.AddPalette(p.Key, p.Value, false);
            }

            palette.Initialize();

            sheetBuilder = new SheetBuilder(SheetType.Indexed);
            foreach (var kv in cursorProvider.Cursors)
            {
                var s = kv.Value.Frames.Select(a => sheetBuilder.Add(a)).ToArray();
                sprites.Add(kv.Key, s);
            }

            sheetBuilder.Current.ReleaseBuffer();

            Game.Renderer.Window.SetHardwareCursor(null);
        }
Пример #18
0
 public static Sprite[] GetSprites(string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
 {
     return(GetFrames(filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray());
 }
Пример #19
0
        public override void Init(ModData modData, Dictionary<string, string> info)
        {
            // Avoid standard loading mechanisms so we
            // can display the loadscreen as early as possible
            r = Game.Renderer;
            if (r == null)
                return;

            if (info.ContainsKey("Text"))
                messages = info["Text"].Split(',');

            if (info.ContainsKey("Palette"))
            {
                using (var stream = modData.DefaultFileSystem.Open(info["Palette"]))
                {
                    palette = new ImmutablePalette(stream, new int[] { });
                }

                hardwarePalette = new HardwarePalette();
                hardwarePalette.AddPalette("loadscreen", palette, false);
                hardwarePalette.Initialize();
                r.SetPalette(hardwarePalette);
            }

            if (info.ContainsKey("Image"))
            {
                using (var stream = modData.DefaultFileSystem.Open(info["Image"]))
                {
                    CpsD2Loader loader = new CpsD2Loader();
                    if (!loader.TryParseSprite(stream, out frames))
                        return;
                }

                if (frames.Length == 0)
                    return;

                sheetBuilder = new SheetBuilder(SheetType.Indexed, 512);
                logo = sheetBuilder.Add(frames[0]);

                logoPos = new float2((r.Resolution.Width - logo.Size.X) / 2, (r.Resolution.Height - logo.Size.Y) / 2);
            }
        }
Пример #20
0
 public static Sprite[] GetSprites(IReadOnlyFileSystem fileSystem, string filename, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
 {
     return GetFrames(fileSystem, filename, loaders).Select(a => sheetBuilder.Add(a)).ToArray();
 }
Пример #21
0
        public Theater(TileSet tileset, Action <uint, string> onMissingImage = null)
        {
            this.tileset = tileset;
            var allocated = false;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            random = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    ISpriteFrame[] allFrames;
                    if (onMissingImage != null)
                    {
                        try
                        {
                            allFrames = frameCache[i];
                        }
                        catch (FileNotFoundException)
                        {
                            onMissingImage(t.Key, i);
                            continue;
                        }
                    }
                    else
                    {
                        allFrames = frameCache[i];
                    }

                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = t.Value.Frames != null ? t.Value.Frames : Exts.MakeArray(t.Value.TilesCount, j => j);

                    var start = indices.Min();
                    var end   = indices.Max();
                    if (start < 0 || end >= frameCount)
                    {
                        throw new YamlException("Template `{0}` uses frames [{1}..{2}] of {3}, but only [0..{4}] actually exist"
                                                .F(t.Key, start, end, i, frameCount - 1));
                    }

                    variants.Add(indices.Select(j =>
                    {
                        var f    = allFrames[j];
                        var tile = t.Value.Contains(j) ? t.Value[j] : null;

                        // The internal z axis is inverted from expectation (negative is closer)
                        var zOffset = tile != null ? -tile.ZOffset : 0;
                        var zRamp   = tile != null ? tile.ZRamp : 1f;
                        var offset  = new float3(f.Offset, zOffset);
                        var type    = SheetBuilder.FrameTypeToSheetType(f.Type);

                        // Defer SheetBuilder creation until we know what type of frames we are loading!
                        // TODO: Support mixed indexed and BGRA frames
                        if (sheetBuilder == null)
                        {
                            sheetBuilder = new SheetBuilder(SheetBuilder.FrameTypeToSheetType(f.Type), allocate);
                        }
                        else if (type != sheetBuilder.Type)
                        {
                            throw new YamlException("Sprite type mismatch. Terrain sprites must all be either Indexed or RGBA.");
                        }

                        var s = sheetBuilder.Allocate(f.Size, zRamp, offset);
                        Util.FastCopyIntoChannel(s, f.Data);

                        if (tileset.EnableDepth)
                        {
                            var ss = sheetBuilder.Allocate(f.Size, zRamp, offset);
                            Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data);

                            // s and ss are guaranteed to use the same sheet
                            // because of the custom terrain sheet allocation
                            s = new SpriteWithSecondaryData(s, s.Sheet, ss.Bounds, ss.Channel);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode));
                }

                if (onMissingImage != null && !variants.Any())
                {
                    continue;
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[sheetBuilder.Type == SheetType.BGRA ? 4 : 1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #22
0
		public ModBrowserLogic(Widget widget)
		{
			modChooserPanel = widget;
			loadButton = modChooserPanel.Get<ButtonWidget>("LOAD_BUTTON");
			loadButton.OnClick = () => LoadMod(selectedMod);
			loadButton.IsDisabled = () => selectedMod.Id == Game.ModData.Manifest.Mod.Id;

			modChooserPanel.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

			modList = modChooserPanel.Get("MOD_LIST");
			modTemplate = modList.Get<ButtonWidget>("MOD_TEMPLATE");

			modChooserPanel.Get<LabelWidget>("MOD_DESC").GetText = () => selectedDescription;
			modChooserPanel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Title;
			modChooserPanel.Get<LabelWidget>("MOD_AUTHOR").GetText = () => selectedAuthor;
			modChooserPanel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;

			var prevMod = modChooserPanel.Get<ButtonWidget>("PREV_MOD");
			prevMod.OnClick = () => { modOffset -= 1; RebuildModList(); };
			prevMod.IsVisible = () => modOffset > 0;

			var nextMod = modChooserPanel.Get<ButtonWidget>("NEXT_MOD");
			nextMod.OnClick = () => { modOffset += 1; RebuildModList(); };
			nextMod.IsVisible = () => modOffset + 5 < allMods.Length;

			modChooserPanel.Get<RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
			{
				Sprite ret = null;
				previews.TryGetValue(selectedMod.Id, out ret);
				return ret;
			};

			sheetBuilder = new SheetBuilder(SheetType.BGRA);
			allMods = ModMetadata.AllMods.Values.Where(m => !m.Hidden)
				.OrderBy(m => m.Title)
				.ToArray();

			// Load preview images, and eat any errors
			foreach (var mod in allMods)
			{
				try
				{
					using (var preview = new Bitmap(Platform.ResolvePath(".", "mods", mod.Id, "preview.png")))
						if (preview.Width == 296 && preview.Height == 196)
							previews.Add(mod.Id, sheetBuilder.Add(preview));
				}
				catch (Exception) { }

				try
				{
					using (var logo = new Bitmap(Platform.ResolvePath(".", "mods", mod.Id, "logo.png")))
						if (logo.Width == 96 && logo.Height == 96)
							logos.Add(mod.Id, sheetBuilder.Add(logo));
				}
				catch (Exception) { }
			}

			modInstallStatus = new Cache<ModMetadata, bool>(IsModInstalled);

			ModMetadata initialMod;
			ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
			SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : ModMetadata.AllMods["ra"]);

			RebuildModList();
		}
Пример #23
0
		public Theater(TileSet tileset)
		{
			this.tileset = tileset;
			var allocated = false;
			var type = tileset.EnableDepth ? SheetType.DualIndexed : SheetType.Indexed;

			Func<Sheet> allocate = () =>
			{
				if (allocated)
					throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
				allocated = true;

				return new Sheet(type, new Size(tileset.SheetSize, tileset.SheetSize));
			};

			sheetBuilder = new SheetBuilder(type, allocate);
			random = new MersenneTwister();

			var frameCache = new FrameCache(Game.ModData.SpriteLoaders);
			foreach (var t in tileset.Templates)
			{
				var variants = new List<Sprite[]>();

				foreach (var i in t.Value.Images)
				{
					var allFrames = frameCache[i];
					var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
					var indices = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount);
					variants.Add(indices.Select(j =>
					{
						var f = allFrames[j];
						var s = sheetBuilder.Allocate(f.Size, f.Offset);
						Util.FastCopyIntoChannel(s, 0, f.Data);

						if (tileset.EnableDepth)
							Util.FastCopyIntoChannel(s, 1, allFrames[j + frameCount].Data);

						return s;
					}).ToArray());
				}

				var allSprites = variants.SelectMany(s => s);

				// Ignore the offsets baked into R8 sprites
				if (tileset.IgnoreTileSpriteOffsets)
					allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, float2.Zero, s.Channel, s.BlendMode));

				templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
			}

			// 1x1px transparent tile
			missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

			Sheet.ReleaseBuffer();
		}
Пример #24
0
        public ModBrowserLogic(Widget widget)
        {
            var panel = widget;
            var loadButton = panel.Get<ButtonWidget>("LOAD_BUTTON");
            loadButton.OnClick = () => LoadMod(selectedMod);
            loadButton.IsDisabled = () => selectedMod.Id == Game.modData.Manifest.Mod.Id;

            panel.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            modList = panel.Get("MOD_LIST");
            modTemplate = modList.Get<ButtonWidget>("MOD_TEMPLATE");

            panel.Get<LabelWidget>("MOD_DESC").GetText = () => selectedDescription;
            panel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Title;
            panel.Get<LabelWidget>("MOD_AUTHOR").GetText = () => selectedAuthor;
            panel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;

            var prevMod = panel.Get<ButtonWidget>("PREV_MOD");
            prevMod.OnClick = () => { modOffset -= 1; RebuildModList(); };
            prevMod.IsVisible = () => modOffset > 0;

            var nextMod = panel.Get<ButtonWidget>("NEXT_MOD");
            nextMod.OnClick = () => { modOffset += 1; RebuildModList(); };
            nextMod.IsVisible = () => modOffset + 5 < allMods.Length;

            panel.Get<RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
            {
                Sprite ret = null;
                previews.TryGetValue(selectedMod.Id, out ret);
                return ret;
            };

            var sheetBuilder = new SheetBuilder(SheetType.BGRA);
            previews = new Dictionary<string, Sprite>();
            logos = new Dictionary<string, Sprite>();
            allMods = ModMetadata.AllMods.Values.Where(m => m.Id != "modchooser")
                .OrderBy(m => m.Title)
                .ToArray();

            // Load preview images, and eat any errors
            foreach (var mod in allMods)
            {
                try
                {
                    var preview = new Bitmap(new[] { "mods", mod.Id, "preview.png" }.Aggregate(Path.Combine));
                    if (preview.Width != 296 || preview.Height != 196)
                        continue;

                    previews.Add(mod.Id, sheetBuilder.Add(preview));
                }
                catch (Exception) { }

                try
                {
                    var logo = new Bitmap(new[] { "mods", mod.Id, "logo.png" }.Aggregate(Path.Combine));
                    if (logo.Width != 96 || logo.Height != 96)
                        continue;

                    logos.Add(mod.Id, sheetBuilder.Add(logo));
                }
                catch (Exception) { }
            }

            ModMetadata initialMod = null;
            ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
            SelectMod(initialMod ?? ModMetadata.AllMods["ra"]);

            RebuildModList();
        }
Пример #25
0
        Sprite[] LoadSprites(string filename)
        {
            var shp = new ShpReader(FileSystem.OpenWithExts(filename, exts));

            return(shp.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray());
        }
Пример #26
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var allocated = false;

            Func<Sheet> allocate = () =>
            {
                if (allocated)
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                allocated = true;

                return new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            random = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);
            foreach (var t in tileset.Templates)
            {
                var variants = new List<Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames = frameCache[i];
                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount);
                    variants.Add(indices.Select(j =>
                    {
                        var f = allFrames[j];
                        var tile = t.Value.Contains(j) ? t.Value[j] : null;

                        // The internal z axis is inverted from expectation (negative is closer)
                        var zOffset = tile != null ? -tile.ZOffset : 0;
                        var zRamp = tile != null ? tile.ZRamp : 1f;
                        var offset = new float3(f.Offset, zOffset);
                        var s = sheetBuilder.Allocate(f.Size, zRamp, offset);
                        Util.FastCopyIntoChannel(s, f.Data);

                        if (tileset.EnableDepth)
                        {
                            var ss = sheetBuilder.Allocate(f.Size, zRamp, offset);
                            Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data);

                            // s and ss are guaranteed to use the same sheet
                            // because of the custom terrain sheet allocation
                            s = new SpriteWithSecondaryData(s, ss.Bounds, ss.Channel);
                        }

                        return s;
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode));

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #27
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var allocated = false;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(SheetType.Indexed, new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            sheetBuilder = new SheetBuilder(SheetType.Indexed, allocate);
            random       = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames  = frameCache[i];
                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount);
                    variants.Add(indices.Select(j =>
                    {
                        var f    = allFrames[j];
                        var tile = t.Value.Contains(j) ? t.Value[j] : null;

                        // The internal z axis is inverted from expectation (negative is closer)
                        var zOffset = tile != null ? -tile.ZOffset : 0;
                        var zRamp   = tile != null ? tile.ZRamp : 1f;
                        var offset  = new float3(f.Offset, zOffset);
                        var s       = sheetBuilder.Allocate(f.Size, zRamp, offset);
                        Util.FastCopyIntoChannel(s, f.Data);

                        if (tileset.EnableDepth)
                        {
                            var ss = sheetBuilder.Allocate(f.Size, zRamp, offset);
                            Util.FastCopyIntoChannel(ss, allFrames[j + frameCount].Data);

                            // s and ss are guaranteed to use the same sheet
                            // because of the custom terrain sheet allocation
                            s = new SpriteWithSecondaryData(s, ss.Bounds, ss.Channel);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode));
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #28
0
        public ModBrowserLogic(Widget widget, ModData modData)
        {
            modChooserPanel = widget;
            loadButton = modChooserPanel.Get<ButtonWidget>("LOAD_BUTTON");
            loadButton.OnClick = () => LoadMod(selectedMod);
            loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Id;

            var contentButton = modChooserPanel.Get<ButtonWidget>("CONFIGURE_BUTTON");
            contentButton.OnClick = () =>
            {
                var widgetArgs = new WidgetArgs
                {
                    { "mod", selectedMod },
                    { "content", content[selectedMod] },
                    { "onCancel", () => { } }
                };

                Ui.OpenWindow("CONTENT_PANEL", widgetArgs);
            };

            modChooserPanel.Get<ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            modList = modChooserPanel.Get("MOD_LIST");
            modTemplate = modList.Get<ButtonWidget>("MOD_TEMPLATE");

            modChooserPanel.Get<LabelWidget>("MOD_DESC").GetText = () => selectedDescription;
            modChooserPanel.Get<LabelWidget>("MOD_TITLE").GetText = () => selectedMod.Metadata.Title;
            modChooserPanel.Get<LabelWidget>("MOD_AUTHOR").GetText = () => selectedAuthor;
            modChooserPanel.Get<LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Metadata.Version;

            var prevMod = modChooserPanel.Get<ButtonWidget>("PREV_MOD");
            prevMod.OnClick = () => { modOffset -= 1; RebuildModList(); };
            prevMod.IsVisible = () => modOffset > 0;

            var nextMod = modChooserPanel.Get<ButtonWidget>("NEXT_MOD");
            nextMod.OnClick = () => { modOffset += 1; RebuildModList(); };
            nextMod.IsVisible = () => modOffset + 5 < allMods.Length;

            modChooserPanel.Get<RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
            {
                Sprite ret = null;
                previews.TryGetValue(selectedMod.Id, out ret);
                return ret;
            };

            sheetBuilder = new SheetBuilder(SheetType.BGRA);
            allMods = Game.Mods.Values.Where(m => !m.Metadata.Hidden)
                .OrderBy(m => m.Metadata.Title)
                .ToArray();

            // Load preview images, and eat any errors
            foreach (var mod in allMods)
            {
                try
                {
                    using (var stream = mod.Package.GetStream("preview.png"))
                        using (var preview = new Bitmap(stream))
                            if (preview.Width == 296 && preview.Height == 196)
                                previews.Add(mod.Id, sheetBuilder.Add(preview));
                }
                catch (Exception) { }

                try
                {
                    using (var stream = mod.Package.GetStream("logo.png"))
                        using (var logo = new Bitmap(stream))
                            if (logo.Width == 96 && logo.Height == 96)
                                logos.Add(mod.Id, sheetBuilder.Add(logo));
                }
                catch (Exception) { }
            }

            Manifest initialMod;
            Game.Mods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
            SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : Game.Mods["ra"]);

            RebuildModList();
        }
Пример #29
0
        public Theater(TileSet tileset)
        {
            this.tileset = tileset;
            var allocated = false;
            var type      = tileset.EnableDepth ? SheetType.DualIndexed : SheetType.Indexed;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(type, new Size(tileset.SheetSize, tileset.SheetSize)));
            };

            sheetBuilder = new SheetBuilder(type, allocate);
            random       = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in tileset.Templates)
            {
                var variants = new List <Sprite[]>();

                foreach (var i in t.Value.Images)
                {
                    var allFrames  = frameCache[i];
                    var frameCount = tileset.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = t.Value.Frames != null ? t.Value.Frames : Enumerable.Range(0, frameCount);
                    variants.Add(indices.Select(j =>
                    {
                        var f = allFrames[j];
                        var s = sheetBuilder.Allocate(f.Size, f.Offset);
                        Util.FastCopyIntoChannel(s, 0, f.Data);

                        if (tileset.EnableDepth)
                        {
                            Util.FastCopyIntoChannel(s, 1, allFrames[j + frameCount].Data);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (tileset.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, float2.Zero, s.Channel, s.BlendMode));
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), t.Value.Images.Length));
            }

            // 1x1px transparent tile
            missingTile = sheetBuilder.Add(new byte[1], new Size(1, 1));

            Sheet.ReleaseBuffer();
        }
Пример #30
0
 public static Sprite[] GetSprites(string filename, string[] exts, ISpriteLoader[] loaders, SheetBuilder sheetBuilder)
 {
     return GetFrames(filename, exts, loaders).Select(a => sheetBuilder.Add(a)).ToArray();
 }