Beispiel #1
0
        public void UpdateWorldImage(RectI area, bool isRenderedLayer = false, string renderMsg = "Render Update Complete.", WriteableBitmap img = null)
        {
            // validate area
            area.Rebound(_world.Header.WorldBounds);

            int    width             = area.Width;
            int    height            = area.Height;
            int    rts               = isRenderedLayer ? 8 : 1;
            string renderProgressMsg = isRenderedLayer ? "Rendering Textured World..." : "Rendering Pixel World...";

            if (img == null)
            {
                img = isRenderedLayer ? _worldImage.Rendered : _worldImage.Image;
            }
            var pixels = new BytePixels(area.Size * rts, 4);
            var stride = img.PixelWidth * img.Format.BitsPerPixel / 8;

            for (int x = area.X; x <= area.Right; x++)
            {
                int dx = x - area.X;
                if (renderMsg != null)
                {
                    OnProgressChanged(this, dx, width, renderProgressMsg);
                }

                for (int y = area.Y; y <= area.Bottom; y++)
                {
                    int  dy   = y - area.Y;
                    Tile tile = _world.Tiles[x, y];
                    if (tile != null)
                    {
                        var xy = (new PointInt32(x, y) - area.TopLeft) * rts;
                        var bp = isRenderedLayer ? GetTexture(y, tile) : GetTextureLayer("TilePixel", y, tile);
                        bp.PutData(pixels, xy);
                    }
                }
            }

            SizeInt32 ts       = new SizeInt32(rts, rts);
            var       realArea = isRenderedLayer ? new RectI(new PointInt32(), area.Size * ts) : area; // Rendered layer starts at 0,0

            img.Lock();
            img.WritePixels(realArea, pixels.GetData(), stride, 0);
            if (!isRenderedLayer)
            {
                img.AddDirtyRect(realArea);
            }
            img.Unlock();

            if (renderMsg != null)
            {
                OnProgressChanged(this, 100, 100, renderMsg);
            }
        }
Beispiel #2
0
        private BytePixels GetTextureLayer(string layerType, int y, Tile tile)
        {
            var    size   = 8;
            var    sizeI  = new SizeInt32(size, size);
            var    pixels = new BytePixels(sizeI, 4);
            var    rect00 = new RectI(0, 0, sizeI);
            string key    = String.Empty;

            switch (layerType)
            {
            case "TilePixel":
                Color c = GetTileColor(y, tile);

                var b = new byte[4];
                b[0]   = c.B;
                b[1]   = c.G;
                b[2]   = c.R;
                b[3]   = c.A;
                pixels = new BytePixels(1, 1, b);
                break;

            case "Wall":
                key = GetTileKey(y, tile, 'W');
                if (textureCache.Contains(key))
                {
                    return((BytePixels)textureCache.Get(key));
                }

                // FIXME: A complete wall is actually 16x16 big, with 3x3 variations, depending how many tiles exist //
                if (tile.Wall > 0)
                {
                    pixels = WorldSettings.Walls[tile.Wall].Texture.GetData(new RectI(166, 58, sizeI));      // tile with most coverage (will be eventually replaced per FIXME)
                }
                else
                {
                    // FIXME: These are actually pretty large bitmaps //
                    // Might need to go on a WallsBack layer... //

                    if (y >= _world.Header.WorldBounds.Bottom - 192)
                    {
                        pixels = WorldSettings.GlobalColors["Hell"].Texture.GetData(rect00);
                    }
                    else if (y > _world.Header.WorldRockLayer)
                    {
                        pixels = WorldSettings.GlobalColors["Rock"].Texture.GetData(rect00);
                    }
                    else if (y > _world.Header.WorldSurface)
                    {
                        pixels = WorldSettings.GlobalColors["Earth"].Texture.GetData(rect00);
                    }
                    else
                    {
                        pixels = WorldSettings.GlobalColors["Sky"].Texture.GetData(rect00);
                    }
                }
                break;

            case "TileBack":
                key = GetTileKey(y, tile, 'T');
                if (textureCache.Contains(key))
                {
                    return((BytePixels)textureCache.Get(key));
                }

                // FIXME: Need XML property for larger than 8x8 sizes
                if (tile.IsActive && !WorldSettings.Tiles[tile.Type].IsSolid)
                {
                    var rect = (WorldSettings.Tiles[tile.Type].IsFramed) ?
                               new RectI(tile.Frame.X / 2, tile.Frame.Y / 2, sizeI) :
                               rect00;
                    pixels = WorldSettings.Tiles[tile.Type].Texture.GetData(rect);
                }
                break;

            // FIXME: NPC layer would go here... //

            case "TileFront":
                key = GetTileKey(y, tile, 'T');
                if (textureCache.Contains(key))
                {
                    return((BytePixels)textureCache.Get(key));
                }

                // FIXME: Need XML property for larger than 8x8 sizes
                if (tile.IsActive && WorldSettings.Tiles[tile.Type].IsSolid)
                {
                    var rect = (WorldSettings.Tiles[tile.Type].IsFramed) ?
                               new RectI(tile.Frame.X / 2, tile.Frame.Y / 2, sizeI) :
                               rect00;
                    pixels = WorldSettings.Tiles[tile.Type].Texture.GetData(rect);
                }
                break;

            case "Liquid":
                key = GetTileKey(y, tile, 'L');
                if (textureCache.Contains(key))
                {
                    return((BytePixels)textureCache.Get(key));
                }

                if (tile.Liquid > 0)
                {
                    // Should use Liquid levels to determine final height //
                    // Actually, bottom 4x4 should be for 255, and top 4x4 for anything else //
                    if (tile.IsLava)
                    {
                        pixels = WorldSettings.GlobalColors["Lava"].Texture.GetData(rect00);
                    }
                    else
                    {
                        pixels = WorldSettings.GlobalColors["Water"].Texture.GetData(rect00);
                    }
                }
                break;
            }

            // Cache policy for new cache items
            var cachePolicy = new CacheItemPolicy();

            cachePolicy.SlidingExpiration = new TimeSpan(0, 5, 0);  // 5 minute duration if not used
            if (shortKeyRegEx.IsMatch(key))
            {
                cachePolicy.Priority = CacheItemPriority.NotRemovable;                              // single unframed tiles and walls get perma-cached
            }
            textureCache.Add(key, pixels, cachePolicy);
            return(pixels);
        }