Beispiel #1
0
        private static Block LoadBlock(byte[] data)
        {
            var block = new Block();
            var outerStream = new BitStream(data);
            var buf = new byte[4];
            outerStream.Read(buf, 32);  // total wrapper data size
            outerStream.Read(buf, 32);
            var inflatedSize = Util.MakeI32(buf);
            outerStream.Read(buf, 16);
            block.X = Util.MakeI16(buf);
            outerStream.Read(buf, 16);
            block.Y = Util.MakeI16(buf);
            outerStream.Read(buf, 16);  // ignored
            outerStream.Read(buf, 16);
            var sliceCount = Util.MakeU16(buf);
            outerStream.Read(buf, 8);
            var extraEagerSlice = buf[0] != 0;

            Trace("block {0:X4} {1:X4} {2}", block.X, block.Y, extraEagerSlice);

            // in the original source it's 17, which is the total of the sizes of the fields read above.
            // however, here we pass 19 instead of 17 so as to skip the 2-byte zlib header of 78 9C
            if (data[17] != 0x78 || data[18] != 0x9c)
                throw new InvalidDataException();
            var deflate = new DeflateStream(new MemoryStream(data, 19, data.Length - 19), CompressionMode.Decompress);
            var innerData = new byte[inflatedSize];
            deflate.Read(innerData, 0, inflatedSize);

            //            var innerStream = new BitStream(innerData);
            //            innerStream.Read(buf, 32);
            //            var innerDataSize = Util.MakeI32(buf);
            //            innerStream.Read(buf, 16);
            //            var more = Util.MakeU16(buf) > 4;
            //            innerStream.Read(buf, 8);
            //            var something3 = buf[0];
            //            innerStream.Read(buf, 8);
            //            var something4 = buf[0];
            //            innerStream.Read(buf, 8);  // ignored
            //            if (more) {
            //                innerStream.Read(buf, 32);
            //                innerStream.Read(buf, 16);
            //                innerStream.Read(buf, 16);
            //            }

            //            Trace("{0:X4} {1:X4} {2:X4} | {3}", something1, something2, somethingCount, Hexify(innerData));

            var innerStream = new BitStream(innerData);
            var innerDataPos = 0;

            for (var i = 0; i <= sliceCount; ++i) {
                if (i == sliceCount && !extraEagerSlice)
                    break;
                var innerDataSize = Util.MakeI32(innerData, innerDataPos);
                innerStream.BitPosition = innerDataPos * 8;
                // the game streams in all but the optional last slice. uncomment
                // this conditional to match the actual game's loading order
                //if (i >= sliceCount)
                block.Slices.Add(LoadSlice(innerStream));
                innerDataPos += innerDataSize;
            }

            return block;
        }
Beispiel #2
0
        private void DrawProp(Graphics canvas, Block block, Slice slice, Prop prop)
        {
            //Console.WriteLine("{0} {1} {2}", prop.PropGroup, prop.Y, y);
            var sprite = sprites.LoadProp(prop.PropSet, prop.PropGroup, prop.PropIndex, prop.Palette);
            if (sprite == null)
                return;

            var dstRect = new Rectangle((int) prop.X, (int) prop.Y, sprite.Hitbox.Width, sprite.Hitbox.Height);

            // no idea what the deal with this is. it isn't perfect, but it's at least closer than just using the raw numbers, usually…
            // no idea what significance the constants have.
            dstRect.Y += (dstRect.Y / 232) * 32;
            dstRect.X -= (dstRect.X / 286) * 32;

            if (prop.LayerGroup <= 5) {
                dstRect.X = (int) (dstRect.X * (0.05 * prop.LayerGroup));  // multiply the position by the layer's parallax
                dstRect.Y = (int) (dstRect.Y * (0.05 * prop.LayerGroup));
                dstRect.Width *= 2;
                dstRect.Height *= 2;
            }

            if (prop.FlipHorz)
            //                dstRect = new Rectangle(dstRect.Left                 - sprite.Hitbox.Left, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left - dstRect.Width - sprite.Hitbox.Left, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left                 - sprite.Hitbox.Left - sprite.Hitbox.Right, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left - dstRect.Width - sprite.Hitbox.Left - sprite.Hitbox.Right, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left                , dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left + dstRect.Width, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left                 - sprite.Hitbox.Left, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left + dstRect.Width - sprite.Hitbox.Left, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left                 - sprite.Hitbox.Right, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left + dstRect.Width - sprite.Hitbox.Right, dstRect.Top, -dstRect.Width, dstRect.Height);
            //                dstRect = new Rectangle(dstRect.Left                 - sprite.Hitbox.Left - sprite.Hitbox.Right, dstRect.Top, -dstRect.Width, dstRect.Height);
                dstRect = new Rectangle(dstRect.Right - sprite.Hitbox.Left - sprite.Hitbox.Right, dstRect.Top, -dstRect.Width, dstRect.Height);
            if (prop.FlipVert)
                dstRect = new Rectangle(dstRect.Left, dstRect.Bottom - sprite.Hitbox.Top - sprite.Hitbox.Bottom, dstRect.Width, -dstRect.Height);

            //var attrs = new ImageAttributes();
            //attrs.SetColorMatrix(MakeFogMatrix(prop.LayerGroup));

            dstRect.X += sprite.Hitbox.Left;
            dstRect.Y += sprite.Hitbox.Top;
            dstRect.X -= (block.X * App.SlicesPerBlock + slice.Header.X) * App.PixelsPerSlice;
            dstRect.Y -= (block.Y * App.SlicesPerBlock + slice.Header.Y) * App.PixelsPerSlice;
            dstRect.X += sliceOverdraw;
            dstRect.Y += sliceOverdraw;
            canvas.DrawImage(sprite.Image, dstRect, 0, 0, sprite.Hitbox.Width, sprite.Hitbox.Height, GraphicsUnit.Pixel);
        }
Beispiel #3
0
        private bool DrawProps(Graphics canvas, Block block, Slice slice, int layer)
        {
            var drewAnything = false;

            //            foreach (var prop in slice.Props) {
            //                if (prop.LayerGroup == layer) {
            //                    DrawProp(canvas, block, slice, prop);
            //                    drewAnything = true;
            //                }
            //            }

            // TODO: this is garbage; optimize this
            foreach (var b in level.Blocks)
                foreach (var s in b.Slices)
                    foreach (var p in s.Props)
                        if (p.LayerGroup == layer) {
                            DrawProp(canvas, block, slice, p);
                            drewAnything = true;
                        }

            return drewAnything;
        }
Beispiel #4
0
        private void DrawBlock(Block block)
        {
            foreach (var slicesByPos in block.Slices.GroupBy(s => Tuple.Create(s.Header.X, s.Header.Y))) {
                var sliceX = slicesByPos.Key.Item1;
                var sliceY = slicesByPos.Key.Item2;

                for (byte layer = 1; layer <= App.NumLayers; ++layer) {
                    using (var image = new Bitmap(App.PixelsPerSlice + sliceOverdraw * 2, App.PixelsPerSlice + sliceOverdraw * 2))
                    using (var canvas = Graphics.FromImage(image)) {
                        bool drewAnything = false;
                        foreach (var slice in slicesByPos)
                            drewAnything |= DrawTiles(canvas, slice, layer);
                        if (!drewAnything)
                            continue;

                        var x = ((block.X * App.SlicesPerBlock) + sliceX) * App.PixelsPerSlice;
                        var y = ((block.Y * App.SlicesPerBlock) + sliceY) * App.PixelsPerSlice;
                        var path = Path.Combine(App.IntermediatePath, name,
                            string.Format("{0}_{1}_{2}.png", layer, x, y));
                        using (var file = File.Open(path, FileMode.Create, FileAccess.Write)) {
                            image.Save(file, ImageFormat.Png);
                        }

                        var area = new Rectangle(x - sliceOverdraw, y - sliceOverdraw, App.PixelsPerSlice, App.PixelsPerSlice);
                        result.Tiles.Add(new RenderedTiles(level, path, area, layer));
                    }
                }
            }
        }