Represents a 2D sprite in the game.
Example #1
0
        public void Draw(_2DSprite sprite)
        {
            sprite.AbsoluteDestRect      = new Rectangle((int)(sprite.DestRect.X + PxOffset.X), (int)(sprite.DestRect.Y + PxOffset.Y), sprite.DestRect.Width, sprite.DestRect.Height);
            sprite.AbsoluteWorldPosition = sprite.WorldPosition + WorldOffset;
            sprite.AbsoluteTilePosition  = sprite.TilePosition + TileOffset;
            sprite.ObjectID  = ObjectID;
            sprite.DrawOrder = DrawOrder;

            bool added = false;
            int  i     = 0;

            while (!added)
            {
                if (i >= Sprites.Count)
                {
                    Sprites.Add(new _2DSpriteGroup(FSOEnvironment.SoftwareDepth));
                }
                if (FSOEnvironment.SoftwareDepth && Sprites[i].SprRectangles.SearchForIntersect(sprite.AbsoluteDestRect))
                {
                    i++; //intersects with a sprite in this list. advance to next.
                }
                else
                {
                    if (FSOEnvironment.SoftwareDepth)
                    {
                        Sprites[i].SprRectangles.Add(sprite.AbsoluteDestRect);
                    }
                    Sprites[i].Sprites[sprite.RenderMode].Add(sprite);
                    added = true;
                }
            }

            DrawOrder++;
        }
Example #2
0
        public void DrawScrollBuffer(ScrollBuffer buffer, Vector2 offset, Vector3 tileOffset, WorldState state)
        {
            var offsetDiff = buffer.PxOffset - offset;
            var tOff       = buffer.WorldPosition - tileOffset;
            var spr        = new _2DSprite
            {
                RenderMode = (buffer.Depth == null) ? _2DBatchRenderMode.NO_DEPTH : _2DBatchRenderMode.RESTORE_DEPTH,
                Pixel      = buffer.Pixel,
                Depth      = buffer.Depth,
                SrcRect    = new Rectangle(0, 0, buffer.Pixel.Width, buffer.Pixel.Height),
                DestRect   = new Rectangle((int)offsetDiff.X - 2, (int)offsetDiff.Y, buffer.Pixel.Width, buffer.Pixel.Height),
            };

            this.Draw(spr);
            spr.AbsoluteWorldPosition = tOff * new Vector3(1, 1.23f, 1) * WorldSpace.WorldUnitsPerTile;
            if (state.Rotation == WorldRotation.TopRight || state.Rotation == WorldRotation.BottomRight)
            {
                spr.AbsoluteWorldPosition.Y *= -1;
            }
            //why does this even work???
            //i added the 1.23 scaling factor on the y direction because at 1 it was shifting slightly
            //it's still not perfect, which leads me to believe there is a bigger problem...
            //after that I flip the offset if we're looking at it the other way, which inverts the z offset and corrects it somehow...
            //i mean, techically this should work with NO multipliers at all!
        }
Example #3
0
 public void Draw(_2DSprite sprite)
 {
     sprite.AbsoluteDestRect      = new Rectangle((int)(sprite.DestRect.X + PxOffset.X), (int)(sprite.DestRect.Y + PxOffset.Y), sprite.DestRect.Width, sprite.DestRect.Height);
     sprite.AbsoluteWorldPosition = sprite.WorldPosition + WorldOffset;
     sprite.AbsoluteTilePosition  = sprite.TilePosition + TileOffset;
     sprite.ObjectID  = ObjectID;
     sprite.DrawOrder = DrawOrder;
     Sprites[sprite.RenderMode].Add(sprite);
     DrawOrder++;
 }
Example #4
0
 public _2DSprite NewSprite(_2DBatchRenderMode mode)
 {
     if (SpriteIndex >= SpritePool.Count)
     {
         var spr = new _2DSprite()
         {
             RenderMode = mode
         };
         SpritePool.Add(spr);
         SpriteIndex++;
         return(spr);
     }
     else
     {
         var spr = SpritePool[SpriteIndex++];
         spr.Repurpose();
         spr.RenderMode = mode;
         return(spr);
     }
 }
Example #5
0
        public void DrawScrollBuffer(ScrollBuffer buffer, Vector2 offset, Vector3 tileOffset, WorldState state)
        {
            var offsetDiff = (buffer.PxOffset - offset) * state.PreciseZoom;
            var tOff       = buffer.WorldPosition - tileOffset;
            var spr        = new _2DSprite
            {
                RenderMode = (buffer.Depth == null) ? _2DBatchRenderMode.NO_DEPTH : _2DBatchRenderMode.RESTORE_DEPTH,
                Pixel      = buffer.Pixel,
                Depth      = buffer.Depth,
                SrcRect    = new Rectangle(0, 0, buffer.Pixel.Width, buffer.Pixel.Height),
                DestRect   = new Rectangle((int)offsetDiff.X - 2, (int)offsetDiff.Y, buffer.Pixel.Width, buffer.Pixel.Height),
            };

            this.Draw(spr);
            spr.AbsoluteWorldPosition = tOff * WorldSpace.WorldUnitsPerTile;
            var y = spr.AbsoluteWorldPosition.Z;

            spr.AbsoluteWorldPosition.Z = spr.AbsoluteWorldPosition.Y;
            spr.AbsoluteWorldPosition.Y = y;
        }
Example #6
0
        public virtual void ValidateSprite(WorldState world)
        {
            if (DrawGroup == null)
            {
                return;
            }
            if (_Dirty)
            {
                if (_TextureDirty)
                {
                    Items.Clear();
                    var direction = (uint)_Direction;

                    /** Compute the direction **/
                    var image = DrawGroup.GetImage(direction, (uint)world.Zoom, (uint)world.Rotation);
                    if (image != null)
                    {
                        foreach (var sprite in image.Sprites)
                        {
                            if (sprite == null)
                            {
                                continue;
                            }
                            var texture = world._2D.GetWorldTexture(sprite);
                            if (texture == null || texture.ZBuffer == null)
                            {
                                continue;
                            }

                            var isDynamic = sprite.SpriteID >= DynamicSpriteBaseID && sprite.SpriteID < (DynamicSpriteBaseID + NumDynamicSprites);
                            if (isDynamic)
                            {
                                var dynamicIndex = (ushort)(sprite.SpriteID - DynamicSpriteBaseID);

                                var isVisible = (dynamicIndex > 63) ? ((DynamicSpriteFlags2 & ((ulong)0x1 << (dynamicIndex - 64))) > 0):
                                                ((DynamicSpriteFlags & ((ulong)0x1 << dynamicIndex)) > 0);
                                if (!isVisible)
                                {
                                    continue;
                                }
                            }
                            var item = new _2DSprite(); //do not use sprite pool for DGRP, since we can reliably remember our own sprites.
                            item.Pixel = texture.Pixel;
                            item.Depth = texture.ZBuffer;
                            if (texture.ZBuffer != null)
                            {
                                item.RenderMode    = _2DBatchRenderMode.Z_BUFFER;
                                item.WorldPosition = sprite.ObjectOffset;
                            }
                            else
                            {
                                item.RenderMode = _2DBatchRenderMode.NO_DEPTH;
                            }

                            var pt = ((TextureInfo)item.Pixel.Tag).Size;
                            item.SrcRect          = new Rectangle(0, 0, pt.X, pt.Y);
                            item.DestRect         = new Rectangle(0, 0, pt.X, pt.Y);
                            item.FlipHorizontally = sprite.Flip;

                            Items.Add(new DGRPRendererItem {
                                Sprite = item, DGRPSprite = sprite
                            });
                        }
                    }

                    _TextureDirty = false;
                }

                int maxX = int.MinValue, maxY = int.MinValue;
                int minX = int.MaxValue, minY = int.MaxValue;
                foreach (var item in Items)
                {
                    var sprite     = item.Sprite;
                    var dgrpSprite = item.DGRPSprite;

                    var pxX = (world.WorldSpace.CadgeWidth / 2.0f) + dgrpSprite.SpriteOffset.X;
                    var pxY = (world.WorldSpace.CadgeBaseLine - item.Sprite.DestRect.Height) + dgrpSprite.SpriteOffset.Y;

                    if (dgrpSprite.ObjectOffset != Vector3.Zero)
                    {
                    }
                    var centerRelative = dgrpSprite.ObjectOffset * new Vector3(1f / 16f, 1f / 16f, 1f / 5f);
                    centerRelative = Vector3.Transform(centerRelative, Matrix.CreateRotationZ(RadianDirection));

                    var pxOff = world.WorldSpace.GetScreenFromTile(centerRelative);

                    sprite.DestRect.X = (int)(pxX + pxOff.X);
                    sprite.DestRect.Y = (int)(pxY + pxOff.Y);

                    if (sprite.DestRect.X < minX)
                    {
                        minX = sprite.DestRect.X;
                    }
                    if (sprite.DestRect.Y < minY)
                    {
                        minY = sprite.DestRect.Y;
                    }
                    if (sprite.DestRect.X + sprite.Pixel.Width > maxX)
                    {
                        maxX = sprite.DestRect.X + sprite.Pixel.Width;
                    }
                    if (sprite.DestRect.Y + sprite.Pixel.Height > maxY)
                    {
                        maxY = sprite.DestRect.Y + sprite.Pixel.Height;
                    }

                    sprite.WorldPosition = centerRelative * 3f;
                    var y = sprite.WorldPosition.Z;
                    sprite.WorldPosition.Z = sprite.WorldPosition.Y;
                    sprite.WorldPosition.Y = y;
                    sprite.Room            = ((dgrpSprite.Flags & DGRPSpriteFlags.Luminous) > 0 && Room != 65534 && Room != 65533)?(ushort)65535:Room;
                    sprite.Floor           = Level;
                }
                Bounding = new Rectangle(minX, minY, maxX - minX, maxY - minY);

                _Dirty = false;
            }
        }
Example #7
0
 private _2DSprite GetWallSprite(Wall pattern, WallStyle style, int rotation, bool down, WorldState world)
 {
     var _Sprite = new _2DSprite()
     {
         RenderMode = _2DBatchRenderMode.WALL
     };
     SPR sprite = null;
     SPR mask = null;
     switch (world.Zoom)
     {
         case WorldZoom.Far:
             sprite = pattern.Far;
             if (style != null) mask = (down) ? style.WallsDownFar : style.WallsUpFar;
             _Sprite.DestRect = DESTINATION_FAR[rotation];
             _Sprite.Depth = WallZBuffers[rotation+8];
             break;
         case WorldZoom.Medium:
             sprite = pattern.Medium;
             if (style != null) mask = (down) ? style.WallsDownMedium : style.WallsUpMedium;
             _Sprite.DestRect = DESTINATION_MED[rotation];
             _Sprite.Depth = WallZBuffers[rotation+4];
             break;
         case WorldZoom.Near:
             sprite = pattern.Near;
             if (style != null) mask = (down) ? style.WallsDownNear : style.WallsUpNear;
             _Sprite.DestRect = DESTINATION_NEAR[rotation];
             _Sprite.Depth = WallZBuffers[rotation];
             break;
         }
     if (sprite != null)
     {
         if (mask == null) mask = sprite;
         _Sprite.Pixel = world._2D.GetTexture(sprite.Frames[rotation]);
         _Sprite.Mask = world._2D.GetTexture(mask.Frames[rotation]);
         _Sprite.SrcRect = new Microsoft.Xna.Framework.Rectangle(0, 0, _Sprite.Pixel.Width, _Sprite.Pixel.Height);
     }
     return _Sprite;
 }
Example #8
0
        //Gets a floor sprite. Used to draw floors cut in half by walls.
        private _2DSprite GetFloorSprite(Floor pattern, int rotation, WorldState world, byte cut)
        {
            var _Sprite = new _2DSprite()
            {
                RenderMode = _2DBatchRenderMode.Z_BUFFER
            };
            if (pattern == null) return _Sprite;
            SPR2 sprite = null;
            switch (world.Zoom)
            {
                case WorldZoom.Far:
                    sprite = pattern.Far;
                    _Sprite.DestRect = FLRDEST_FAR;
                    _Sprite.Depth = WallZBuffers[14];
                    break;
                case WorldZoom.Medium:
                    sprite = pattern.Medium;
                    _Sprite.DestRect = FLRDEST_MED;
                    _Sprite.Depth = WallZBuffers[13];
                    break;
                case WorldZoom.Near:
                    sprite = pattern.Near;
                    _Sprite.DestRect = FLRDEST_NEAR;
                    _Sprite.Depth = WallZBuffers[12];
                    break;
            }
            if (sprite != null)
            {
                _Sprite.Pixel = world._2D.GetTexture(sprite.Frames[rotation]);
                _Sprite.SrcRect = new Microsoft.Xna.Framework.Rectangle(0, 0, _Sprite.Pixel.Width, _Sprite.Pixel.Height);
            }

            switch (cut)
            {
                case 0: //vertical cut, left side
                    _Sprite.DestRect.Width /= 2;
                    _Sprite.SrcRect.Width /= 2;
                    break;
                case 1: //vertical cut, right side
                    _Sprite.DestRect.X += _Sprite.DestRect.Width / 2;
                    _Sprite.DestRect.Width /= 2;
                    _Sprite.SrcRect.X += _Sprite.SrcRect.Width / 2;
                    _Sprite.SrcRect.Width /= 2;
                    break;
                case 2: //horizontal cut, top side
                    _Sprite.DestRect.Height /= 2;
                    _Sprite.SrcRect.Height /= 2;
                    break;
                case 3:
                    _Sprite.DestRect.Y += _Sprite.DestRect.Height / 2;
                    _Sprite.DestRect.Height /= 2;
                    _Sprite.SrcRect.Y += _Sprite.SrcRect.Height / 2;
                    _Sprite.SrcRect.Height /= 2;
                    break;
            }

            return _Sprite;
        }
Example #9
0
 private _2DSprite CopySprite(_2DSprite _Sprite)
 {
     return new _2DSprite()
     {
         DestRect = _Sprite.DestRect,
         SrcRect = _Sprite.SrcRect,
         RenderMode = _2DBatchRenderMode.WALL,
         Pixel = _Sprite.Pixel,
         Depth = _Sprite.Depth
     };
 }
Example #10
0
        public override void Draw(GraphicsDevice device, WorldState world)
        {
            var timer = new System.Diagnostics.Stopwatch();
            timer.Start();

            if (WallZBuffers == null) WallZBuffers = TextureGenerator.GetWallZBuffer(device);

            var pxOffset = world.WorldSpace.GetScreenOffset();
            var wallContent = Content.Content.Get().WorldWalls;
            var floorContent = Content.Content.Get().WorldFloors;

            //draw walls

            for (sbyte level = 1; level <= world.Level; level++)
            {
                int off = 0;
                bool canCut = !(level < world.Level);
                GenerateWallData(blueprint.Walls[level-1], blueprint.WallsAt[level-1], canCut);
                for (short y = 0; y < blueprint.Height; y++)
                { //ill decide on a reasonable system for components when it's finished ok pls :(
                    for (short x = 0; x < blueprint.Height; x++)
                    {

                        var comp = blueprint.GetWall(x, y, level);
                        if (comp.Segments != 0)
                        {
                            comp = RotateWall(world.Rotation, comp, x, y, level);
                            var tilePosition = new Vector3(x, y, (level-1) * 2.95f);
                            world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition) + pxOffset);
                            world._2D.OffsetTile(tilePosition);
                            var myCuts = Cuts[off];
                            var cDown = canCut && WallsDownAt(x, y);

                            if ((byte)comp.Segments < 16) myCuts = RotateCuts(world.Rotation, myCuts, x, y);
                            else if ((int)world.Rotation > 1) //for diagonals, just flip cuts on two furthest rotations
                            {
                                if (myCuts.TLCut == WallCut.DownRightUpLeft) myCuts.TLCut = WallCut.DownLeftUpRight;
                                else if (myCuts.TLCut == WallCut.DownLeftUpRight) myCuts.TLCut = WallCut.DownRightUpLeft;
                                if (myCuts.TRCut == WallCut.DownRightUpLeft) myCuts.TRCut = WallCut.DownLeftUpRight;
                                else if (myCuts.TRCut == WallCut.DownLeftUpRight) myCuts.TRCut = WallCut.DownRightUpLeft;
                            }

                            if ((comp.Segments & WallSegments.TopLeft) == WallSegments.TopLeft && !(myCuts.TLCut > 0 && comp.TopLeftDoor))
                            {
                                //draw top left and top right relative to this rotation
                                var tlPattern = GetPattern(comp.TopLeftPattern);

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TLCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopLeftStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopLeftStyle != 1) styleID = comp.TopLeftStyle;
                                        else if (comp.ObjSetTLStyle != 0) styleID = comp.ObjSetTLStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var tlStyle = GetStyle(styleID);

                                var _Sprite = GetWallSprite(tlPattern, tlStyle, 0, down, world);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    //draw overlay if exists

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 0, down, world));

                                    var contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(0, -1, 0));

                                    if (comp.TopLeftThick)
                                    {
                                        //check far side of wall for continuation. if there is none, round this part off
                                        if (!comp.TopRightThick && OffsetValid(contOff, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopLeftThick)
                                            {
                                                _Sprite = CopySprite(_Sprite);
                                                tlStyle = GetStyle(comp.TopLeftStyle); //return to normal if cutaway
                                                var tilePosition2 = contOff;

                                                world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2) + pxOffset);
                                                world._2D.OffsetTile(tilePosition2);
                                                int newWidth = 0;
                                                bool downAtCont = canCut && WallsDownAt((short)(contOff.X), (short)(contOff.Y));

                                                SPR mask = null;
                                                switch (world.Zoom)
                                                {
                                                    case WorldZoom.Far:
                                                        newWidth = 3;
                                                        mask = downAtCont ? tlStyle.WallsDownFar : tlStyle.WallsUpFar;
                                                        break;
                                                    case WorldZoom.Medium:
                                                        newWidth = 6;
                                                        mask = downAtCont ? tlStyle.WallsDownMedium : tlStyle.WallsUpMedium;
                                                        break;
                                                    case WorldZoom.Near:
                                                        newWidth = 12;
                                                        mask = downAtCont ? tlStyle.WallsDownNear : tlStyle.WallsUpNear;
                                                        break;
                                                }
                                                if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[0]);
                                                if (x > 0 && (blueprint.GetWall((short)(x - 1), (short)(y - 1), level).Segments & WallSegments.VerticalDiag) == WallSegments.VerticalDiag) newWidth = (newWidth * 2) / 3;
                                                //if there is a diagonal behind the extension, make it a bit shorter.
                                                _Sprite.SrcRect.Width = newWidth;
                                                _Sprite.DestRect.Width = newWidth;
                                                world._2D.Draw(_Sprite);
                                            }
                                        }

                                        //check close side of wall for continuation
                                        contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(0, 1, 0)); //so we can check the most things with the least impact
                                        var contOff2 = tilePosition + RotateOffset(world.Rotation, new Vector3(-1, 1, 0)); //last check, unfortunately required
                                        if (OffsetValid(contOff, blueprint) && OffsetValid(contOff2, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopLeftThick && !comp2.TopRightThick)
                                            {
                                                var comp3 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff2.X), (short)(contOff2.Y), level), (short)(contOff2.X), (short)(contOff2.Y), level);
                                                if (!comp3.TopRightThick)
                                                {
                                                    _Sprite = GetWallSprite(tlPattern, tlStyle, 1, down, world);
                                                    var tilePosition2 = tilePosition + RotateOffset(world.Rotation, new Vector3(-1, 1, 0));
                                                    bool downAtCont = canCut && WallsDownAt((int)tilePosition.X, (int)tilePosition.Y) && styleID != 8;
                                                    tlStyle = GetStyle(comp.TopLeftStyle);

                                                    world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2) + pxOffset);
                                                    world._2D.OffsetTile(tilePosition2);
                                                    int newWidth = 0;

                                                    SPR mask = null;
                                                    switch (world.Zoom)
                                                    {
                                                        case WorldZoom.Far:
                                                            newWidth = 3;
                                                            mask = downAtCont ? tlStyle.WallsDownFar : tlStyle.WallsUpFar;
                                                            break;
                                                        case WorldZoom.Medium:
                                                            newWidth = 6;
                                                            mask = downAtCont ? tlStyle.WallsDownMedium : tlStyle.WallsUpMedium;
                                                            break;
                                                        case WorldZoom.Near:
                                                            newWidth = 12;
                                                            mask = downAtCont ? tlStyle.WallsDownNear : tlStyle.WallsUpNear;
                                                            break;
                                                    }
                                                    if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[1]);
                                                    _Sprite.SrcRect.X += _Sprite.SrcRect.Width - newWidth;
                                                    _Sprite.DestRect.X += _Sprite.DestRect.Width - newWidth;
                                                    _Sprite.SrcRect.Width = newWidth;
                                                    _Sprite.DestRect.Width = newWidth;
                                                    world._2D.Draw(_Sprite);
                                                }
                                            }
                                        }
                                        world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition) + pxOffset);
                                        world._2D.OffsetTile(tilePosition);
                                    }
                                }
                            }
                            //top right

                            if ((comp.Segments & WallSegments.TopRight) == WallSegments.TopRight && !(myCuts.TRCut > 0 && comp.TopRightDoor))
                            {

                                var trPattern = GetPattern(comp.TopRightPattern);

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TRCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopRightStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopRightStyle != 1) styleID = comp.TopRightStyle;
                                        else if (comp.ObjSetTRStyle != 0) styleID = comp.ObjSetTRStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var trStyle = GetStyle(styleID);

                                var _Sprite = GetWallSprite(trPattern, trStyle, 1, down, world);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 1, down, world));
                                    var contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(-1, 0, 0));
                                    if (comp.TopRightThick)
                                    {
                                        //check far side of wall for continuation. if there is none, round this part off
                                        if (!comp.TopLeftThick && OffsetValid(contOff, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopRightThick)
                                            {
                                                _Sprite = CopySprite(_Sprite);
                                                trStyle = GetStyle(comp.TopRightStyle); //return to normal if cutaway

                                                var tilePosition2 = contOff;
                                                world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2) + pxOffset);
                                                world._2D.OffsetTile(tilePosition2);
                                                int newWidth = 0;
                                                bool downAtCont = canCut && WallsDownAt((short)(contOff.X), (short)(contOff.Y));

                                                SPR mask = null;
                                                switch (world.Zoom)
                                                {
                                                    case WorldZoom.Far:
                                                        newWidth = 3;
                                                        mask = downAtCont ? trStyle.WallsDownFar : trStyle.WallsUpFar;
                                                        break;
                                                    case WorldZoom.Medium:
                                                        newWidth = 6;
                                                        mask = downAtCont ? trStyle.WallsDownMedium : trStyle.WallsUpMedium;
                                                        break;
                                                    case WorldZoom.Near:
                                                        newWidth = 12;
                                                        mask = downAtCont ? trStyle.WallsDownNear : trStyle.WallsUpNear;
                                                        break;
                                                }
                                                if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[1]);
                                                if (y > 0 && (blueprint.GetWall((short)(x - 1), (short)(y - 1), level).Segments & WallSegments.VerticalDiag) == WallSegments.VerticalDiag) newWidth = (newWidth * 2) / 3;
                                                //if there is a diagonal behind the extension, make it a bit shorter.
                                                _Sprite.SrcRect.X += _Sprite.SrcRect.Width - newWidth;
                                                _Sprite.DestRect.X += _Sprite.DestRect.Width - newWidth;
                                                _Sprite.SrcRect.Width = newWidth;
                                                _Sprite.DestRect.Width = newWidth;
                                                world._2D.Draw(_Sprite);
                                            }
                                        }

                                        //check close side of wall for continuation
                                        contOff = tilePosition + RotateOffset(world.Rotation, new Vector3(1, 0, 0)); //so we can check the most things with the least impact
                                        var contOff2 = tilePosition + RotateOffset(world.Rotation, new Vector3(1, -1, 0)); //last check, unfortunately required
                                        if (OffsetValid(contOff, blueprint) && OffsetValid(contOff2, blueprint))
                                        {
                                            var comp2 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff.X), (short)(contOff.Y), level), (short)(contOff.X), (short)(contOff.Y), level);
                                            if (!comp2.TopLeftThick && !comp2.TopRightThick)
                                            {
                                                var comp3 = RotateWall(world.Rotation, blueprint.GetWall((short)(contOff2.X), (short)(contOff2.Y), level), (short)(contOff2.X), (short)(contOff2.Y), level);
                                                if (!comp3.TopLeftThick)
                                                {
                                                    _Sprite = GetWallSprite(trPattern, trStyle, 0, down, world);
                                                    var tilePosition2 = tilePosition + RotateOffset(world.Rotation, new Vector3(1, -1, 0));
                                                    bool downAtCont = canCut && WallsDownAt((int)tilePosition.X, (int)tilePosition.Y) && styleID != 8;
                                                    trStyle = GetStyle(comp.TopRightStyle);

                                                    world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition2) + pxOffset);
                                                    world._2D.OffsetTile(tilePosition2);
                                                    int newWidth = 0;

                                                    SPR mask = null;
                                                    switch (world.Zoom)
                                                    {
                                                        case WorldZoom.Far:
                                                            newWidth = 3;
                                                            mask = downAtCont ? trStyle.WallsDownFar : trStyle.WallsUpFar;
                                                            break;
                                                        case WorldZoom.Medium:
                                                            newWidth = 6;
                                                            mask = downAtCont ? trStyle.WallsDownMedium : trStyle.WallsUpMedium;
                                                            break;
                                                        case WorldZoom.Near:
                                                            newWidth = 12;
                                                            mask = downAtCont ? trStyle.WallsDownNear : trStyle.WallsUpNear;
                                                            break;
                                                    }
                                                    if (mask != null) _Sprite.Mask = world._2D.GetTexture(mask.Frames[0]);
                                                    _Sprite.SrcRect.Width = newWidth;
                                                    _Sprite.DestRect.Width = newWidth;
                                                    world._2D.Draw(_Sprite);
                                                }
                                            }
                                        }
                                        world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition) + pxOffset);
                                        world._2D.OffsetTile(tilePosition);
                                    }
                                }
                            }

                            //horizontal diag

                            if (comp.Segments == WallSegments.HorizontalDiag)
                            {

                                var trPattern = GetPattern(comp.BottomRightPattern); //bottom left is facing other way.

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TRCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopRightStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopRightStyle != 1) styleID = comp.TopRightStyle;
                                        else if (comp.ObjSetTRStyle != 0) styleID = comp.ObjSetTRStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var trStyle = GetStyle(styleID);

                                var _Sprite = GetWallSprite(trPattern, trStyle, 2, down, world);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 2, down, world));

                                    //draw diagonally cut floors
                                    if (comp.TopLeftPattern != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftPattern), 0, world, 3);
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                    if (comp.TopLeftStyle != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftStyle), 0, world, 2);
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                }
                            }

                            if (comp.Segments == WallSegments.VerticalDiag)
                            {

                                var trPattern = GetPattern(comp.BottomRightPattern); //choose right one here, not sure which is chosen in real game

                                ushort styleID = 1;
                                ushort overlayID = 0;
                                bool down = false;

                                switch (myCuts.TRCut)
                                {
                                    case WallCut.Down:
                                        styleID = comp.TopRightStyle;
                                        down = true; break;
                                    case WallCut.DownLeftUpRight:
                                        styleID = 7;
                                        overlayID = 252; break;
                                    case WallCut.DownRightUpLeft:
                                        styleID = 8;
                                        overlayID = 253; break;
                                    default:
                                        if (comp.TopRightStyle != 1) styleID = comp.TopRightStyle;
                                        else if (comp.ObjSetTRStyle != 0) styleID = comp.ObjSetTRStyle; //use custom style set by object if no cut
                                        else styleID = 1;
                                        break;
                                }

                                var trStyle = GetStyle(styleID);

                                var _Sprite = GetWallSprite(trPattern, trStyle, 3, down, world);
                                if (_Sprite.Pixel != null)
                                {
                                    world._2D.Draw(_Sprite);

                                    if (overlayID != 0) world._2D.Draw(GetWallSprite(GetPattern(overlayID), null, 3, down, world));

                                    //draw diagonally cut floors
                                    if (comp.TopLeftPattern != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftPattern), 0, world, 1);
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                    if (comp.TopLeftStyle != 0)
                                    {
                                        var floor = GetFloorSprite(floorContent.Get(comp.TopLeftStyle), 0, world, 0);
                                        if (floor.Pixel != null) world._2D.Draw(floor);
                                    }
                                }
                            }
                        }

                        //draw junctions (part of this iteration to simplify things)

                        JunctionFlags flags;

                        float yOff;
                        if (UpJunctions[off] == 0)
                        {
                            flags = DownJunctions[off];
                            yOff = 0.3f + (level - 1) * 2.95f; ;
                        }
                        else
                        {
                            flags = UpJunctions[off];
                            yOff = level * 2.95f;
                        }

                        if (flags > 0 && JunctionMap.ContainsKey(flags)) //there is a junction here! if the junction map contains the unrotated junction, it will contain the rotated junction.
                        {
                            flags = RotateJunction(world.Rotation, flags);
                            var tilePosition = new Vector3(x - 0.5f, y - 0.5f, yOff); //2.95 for walls up, 0.3 for walls down
                            world._2D.OffsetPixel(world.WorldSpace.GetScreenFromTile(tilePosition) + pxOffset);
                            world._2D.OffsetTile(tilePosition);

                            var _Sprite = new _2DSprite()
                            {
                                RenderMode = _2DBatchRenderMode.Z_BUFFER
                            };

                            var Junctions = wallContent.Junctions;

                            SPR sprite = null;
                            switch (world.Zoom)
                            {
                                case WorldZoom.Far:
                                    sprite = Junctions.Far;
                                    _Sprite.DestRect = JUNCDEST_FAR;
                                    _Sprite.Depth = WallZBuffers[20];
                                    break;
                                case WorldZoom.Medium:
                                    sprite = Junctions.Medium;
                                    _Sprite.DestRect = JUNCDEST_MED;
                                    _Sprite.Depth = WallZBuffers[19];
                                    break;
                                case WorldZoom.Near:
                                    sprite = Junctions.Near;
                                    _Sprite.DestRect = JUNCDEST_NEAR;
                                    _Sprite.Depth = WallZBuffers[18];
                                    break;
                            }
                            _Sprite.Pixel = world._2D.GetTexture(sprite.Frames[JunctionMap[flags]]);
                            _Sprite.SrcRect = new Microsoft.Xna.Framework.Rectangle(0, 0, _Sprite.Pixel.Width, _Sprite.Pixel.Height);
                            world._2D.Draw(_Sprite);
                        }

                        off++;
                    }
                }
            }
            timer.Stop();
            //System.Diagnostics.Debug.WriteLine("Drawing walls took " + timer.ElapsedMilliseconds.ToString() + " ms");
        }
Example #11
0
        private _2DSprite GetAirSprite(WorldState world)
        {
            var _Sprite = new _2DSprite()
            {
                RenderMode = _2DBatchRenderMode.Z_BUFFER
            };
            var airTiles = TextureGenerator.GetAirTiles(world.Device);
            Texture2D sprite = null;
            switch (world.Zoom)
            {
                case WorldZoom.Far:
                    sprite = airTiles[2];
                    _Sprite.DestRect = FLOORDEST_FAR;
                    _Sprite.Depth = ArchZBuffers[14];
                    break;
                case WorldZoom.Medium:
                    sprite = airTiles[1];
                    _Sprite.DestRect = FLOORDEST_MED;
                    _Sprite.Depth = ArchZBuffers[13];
                    break;
                case WorldZoom.Near:
                    sprite = airTiles[0];
                    _Sprite.DestRect = FLOORDEST_NEAR;
                    _Sprite.Depth = ArchZBuffers[12];
                    break;
            }

            _Sprite.Pixel = sprite;
            _Sprite.SrcRect = new Microsoft.Xna.Framework.Rectangle(0, 0, _Sprite.Pixel.Width, _Sprite.Pixel.Height);

            return _Sprite;
        }
Example #12
0
        private _2DSprite GetFloorSprite(Floor pattern, int rotation, WorldState world)
        {
            var _Sprite = new _2DSprite()
            {
                RenderMode = _2DBatchRenderMode.Z_BUFFER
            };
            if (pattern == null) return _Sprite;
            SPR2 sprite = null;
            bool vertFlip = world.Rotation == WorldRotation.TopRight || world.Rotation == WorldRotation.BottomRight;
            int bufOff = (vertFlip) ? 3 : 0;
            switch (world.Zoom)
            {
                case WorldZoom.Far:
                    sprite = pattern.Far;
                    _Sprite.DestRect = FLOORDEST_FAR;
                    _Sprite.Depth = ArchZBuffers[14+bufOff];
                    break;
                case WorldZoom.Medium:
                    sprite = pattern.Medium;
                    _Sprite.DestRect = FLOORDEST_MED;
                    _Sprite.Depth = ArchZBuffers[13 + bufOff];
                    break;
                case WorldZoom.Near:
                    sprite = pattern.Near;
                    _Sprite.DestRect = FLOORDEST_NEAR;
                    _Sprite.Depth = ArchZBuffers[12 + bufOff];
                    break;
            }
            if (sprite != null)
            {
                _Sprite.Pixel = world._2D.GetTexture(sprite.Frames[rotation]);
                _Sprite.SrcRect = new Microsoft.Xna.Framework.Rectangle(0, 0, _Sprite.Pixel.Width, _Sprite.Pixel.Height);

                if (vertFlip) _Sprite.FlipVertically = true;
                if ((int)world.Rotation > 1) _Sprite.FlipHorizontally = true;
            }

            return _Sprite;
        }
Example #13
0
        public void ValidateSprite(WorldState world)
        {
            if (DrawGroup == null) return;
            if (_Dirty)
            {
                if (_TextureDirty)
                {
                    Items.Clear();
                    var direction = (uint)_Direction;

                    /** Compute the direction **/
                    var image = DrawGroup.GetImage(direction, (uint)world.Zoom, (uint)world.Rotation);
                    if (image != null)
                    {
                        foreach (var sprite in image.Sprites)
                        {
                            if (sprite == null) continue;
                            var texture = world._2D.GetWorldTexture(sprite);
                            if (texture == null || texture.ZBuffer == null) { continue; }

                            var isDynamic = sprite.SpriteID >= DynamicSpriteBaseID && sprite.SpriteID < (DynamicSpriteBaseID + NumDynamicSprites);
                            if (isDynamic)
                            {
                                var dynamicIndex = (ushort)(sprite.SpriteID - DynamicSpriteBaseID);

                                var isVisible = (dynamicIndex > 63) ? ((DynamicSpriteFlags2 & ((ulong)0x1 << (dynamicIndex-64))) > 0):
                                    ((DynamicSpriteFlags & ((ulong)0x1 << dynamicIndex)) > 0);
                                if (!isVisible)
                                {
                                    continue;
                                }
                            }
                            var item = new _2DSprite(); //do not use sprite pool for DGRP, since we can reliably remember our own sprites.
                            item.Pixel = texture.Pixel;
                            item.Depth = texture.ZBuffer;
                            if (texture.ZBuffer != null)
                            {
                                item.RenderMode = _2DBatchRenderMode.Z_BUFFER;
                                item.WorldPosition = sprite.ObjectOffset;
                            }
                            else
                            {
                                item.RenderMode = _2DBatchRenderMode.NO_DEPTH;
                            }

                            item.SrcRect = new Rectangle(0, 0, item.Pixel.Width, item.Pixel.Height);
                            item.DestRect = new Rectangle(0, 0, item.Pixel.Width, item.Pixel.Height);
                            item.FlipHorizontally = sprite.Flip;

                            Items.Add(new DGRPRendererItem { Sprite = item, DGRPSprite = sprite });
                        }
                    }

                    _TextureDirty = false;
                }

                int maxX = int.MinValue, maxY = int.MinValue;
                int minX = int.MaxValue, minY = int.MaxValue;
                foreach (var item in Items)
                {
                    var sprite = item.Sprite;
                    var dgrpSprite = item.DGRPSprite;

                    var pxX = (world.WorldSpace.CadgeWidth / 2.0f) + dgrpSprite.SpriteOffset.X;
                    var pxY = (world.WorldSpace.CadgeBaseLine - sprite.Pixel.Height) + dgrpSprite.SpriteOffset.Y;

                    var centerRelative = dgrpSprite.ObjectOffset * new Vector3(1f / 16f, 1f / 16f, 1f / 5f);
                    centerRelative = Vector3.Transform(centerRelative, Matrix.CreateRotationZ(RadianDirection));

                    var pxOff = world.WorldSpace.GetScreenFromTile(centerRelative);

                    sprite.DestRect.X = (int)(pxX + pxOff.X);
                    sprite.DestRect.Y = (int)(pxY + pxOff.Y);

                    if (sprite.DestRect.X < minX) minX = sprite.DestRect.X;
                    if (sprite.DestRect.Y < minY) minY = sprite.DestRect.Y;
                    if (sprite.DestRect.X + sprite.Pixel.Width > maxX) maxX = sprite.DestRect.X + sprite.Pixel.Width;
                    if (sprite.DestRect.Y + sprite.Pixel.Height > maxY) maxY = sprite.DestRect.Y + sprite.Pixel.Height;

                    sprite.WorldPosition = centerRelative * 3f;
                    sprite.Room = Room;
                }
                Bounding = new Rectangle(minX, minY, maxX - minX, maxY - minY);

                _Dirty = false;
            }
        }
Example #14
0
        public void Draw(WorldState world)
        {
            if (_Dirty)
            {
                if (_TextureDirty)
                {
                    Items.Clear();
                    var direction = (uint)_Direction;

                    /** Compute the direction **/
                    var image = DrawGroup.GetImage(direction, (uint)world.Zoom, (uint)world.Rotation);
                    if (image != null)
                    {
                        foreach (var sprite in image.Sprites)
                        {
                            var texture = world._2D.GetWorldTexture(sprite);
                            if (texture == null || texture.ZBuffer == null) { continue; }

                            var isDynamic = sprite.SpriteID >= DynamicSpriteBaseID && sprite.SpriteID < (DynamicSpriteBaseID + NumDynamicSprites);
                            if (isDynamic){
                                var dynamicIndex = (ushort)(sprite.SpriteID - DynamicSpriteBaseID);

                                var isVisible = (DynamicSpriteFlags & (0x1 << dynamicIndex)) > 0;
                                if (!isVisible){
                                    continue;
                                }
                            }
                            var item = new _2DSprite();
                            item.Pixel = texture.Pixel;
                            item.Depth = texture.ZBuffer;
                            if (texture.ZBuffer != null){
                                item.RenderMode = _2DBatchRenderMode.Z_BUFFER;
                                item.WorldPosition = sprite.ObjectOffset;
                            }else{
                                item.RenderMode = _2DBatchRenderMode.NO_DEPTH;
                            }

                            item.SrcRect = new Rectangle(0, 0, item.Pixel.Width, item.Pixel.Height);
                            item.DestRect = new Rectangle(0, 0, item.Pixel.Width, item.Pixel.Height);
                            item.FlipHorizontally = sprite.Flip;

                            Items.Add(new DGRPRendererItem { Sprite = item, DGRPSprite = sprite });
                        }
                    }

                    _TextureDirty = false;
                }

                foreach (var item in Items)
                {
                    var sprite = item.Sprite;
                    var dgrpSprite = item.DGRPSprite;

                    var pxX = (world.WorldSpace.CadgeWidth / 2.0f) + dgrpSprite.SpriteOffset.X;
                    var pxY = (world.WorldSpace.CadgeBaseLine - sprite.Pixel.Height) + dgrpSprite.SpriteOffset.Y;

                    var centerRelative = dgrpSprite.ObjectOffset * new Vector3(1f/16f, 1f/16f, 1f/5f);
                    centerRelative = Vector3.Transform(centerRelative, Matrix.CreateRotationZ(RadianDirection));

                    var pxOff = world.WorldSpace.GetScreenFromTile(centerRelative);

                    sprite.DestRect.X = (int)(pxX+pxOff.X);
                    sprite.DestRect.Y = (int)(pxY+pxOff.Y);

                    sprite.WorldPosition = centerRelative * 3f;
                }

                _Dirty = false;
            }

            foreach (var item in Items)
            {
                world._2D.Draw(item.Sprite);
            }
        }
Example #15
0
 private _2DSprite CopySprite(WorldState world, _2DSprite _Sprite)
 {
     var spr = world._2D.NewSprite(_2DBatchRenderMode.WALL);
     spr.DestRect = _Sprite.DestRect;
     spr.SrcRect = _Sprite.SrcRect;
     spr.Pixel = _Sprite.Pixel;
     spr.Depth = _Sprite.Depth;
     spr.Room = _Sprite.Room;
     return spr;
 }
Example #16
0
        public void ValidateSprite(WorldState world)
        {
            if (DrawGroup == null)
            {
                return;
            }
            if (_Dirty)
            {
                if (_TextureDirty)
                {
                    Items.Clear();
                    var direction = (uint)_Direction;

                    /** Compute the direction **/
                    var image = DrawGroup.GetImage(direction, (uint)world.Zoom, (uint)world.Rotation);
                    if (image != null)
                    {
                        foreach (var sprite in image.Sprites)
                        {
                            if (sprite == null)
                            {
                                continue;
                            }
                            var texture = world._2D.GetWorldTexture(sprite);
                            if (texture == null || texture.ZBuffer == null)
                            {
                                continue;
                            }

                            var isDynamic = sprite.SpriteID >= DynamicSpriteBaseID && sprite.SpriteID < (DynamicSpriteBaseID + NumDynamicSprites);
                            if (isDynamic)
                            {
                                var dynamicIndex = (ushort)(sprite.SpriteID - DynamicSpriteBaseID);

                                var isVisible = (DynamicSpriteFlags & (0x1 << dynamicIndex)) > 0;
                                if (!isVisible)
                                {
                                    continue;
                                }
                            }
                            var item = new _2DSprite();
                            item.Pixel = texture.Pixel;
                            item.Depth = texture.ZBuffer;
                            if (texture.ZBuffer != null)
                            {
                                item.RenderMode    = _2DBatchRenderMode.Z_BUFFER;
                                item.WorldPosition = sprite.ObjectOffset;
                            }
                            else
                            {
                                item.RenderMode = _2DBatchRenderMode.NO_DEPTH;
                            }

                            item.SrcRect          = new Rectangle(0, 0, item.Pixel.Width, item.Pixel.Height);
                            item.DestRect         = new Rectangle(0, 0, item.Pixel.Width, item.Pixel.Height);
                            item.FlipHorizontally = sprite.Flip;

                            Items.Add(new DGRPRendererItem {
                                Sprite = item, DGRPSprite = sprite
                            });
                        }
                    }

                    _TextureDirty = false;
                }


                int maxX = int.MinValue, maxY = int.MinValue;
                int minX = int.MaxValue, minY = int.MaxValue;
                foreach (var item in Items)
                {
                    var sprite     = item.Sprite;
                    var dgrpSprite = item.DGRPSprite;

                    var pxX = (world.WorldSpace.CadgeWidth / 2.0f) + dgrpSprite.SpriteOffset.X;
                    var pxY = (world.WorldSpace.CadgeBaseLine - sprite.Pixel.Height) + dgrpSprite.SpriteOffset.Y;

                    var centerRelative = dgrpSprite.ObjectOffset * new Vector3(1f / 16f, 1f / 16f, 1f / 5f);
                    centerRelative = Vector3.Transform(centerRelative, Matrix.CreateRotationZ(RadianDirection));

                    var pxOff = world.WorldSpace.GetScreenFromTile(centerRelative);

                    sprite.DestRect.X = (int)(pxX + pxOff.X);
                    sprite.DestRect.Y = (int)(pxY + pxOff.Y);

                    if (sprite.DestRect.X < minX)
                    {
                        minX = sprite.DestRect.X;
                    }
                    if (sprite.DestRect.Y < minY)
                    {
                        minY = sprite.DestRect.Y;
                    }
                    if (sprite.DestRect.X + sprite.Pixel.Width > maxX)
                    {
                        maxX = sprite.DestRect.X + sprite.Pixel.Width;
                    }
                    if (sprite.DestRect.Y + sprite.Pixel.Height > maxY)
                    {
                        maxY = sprite.DestRect.Y + sprite.Pixel.Height;
                    }

                    sprite.WorldPosition = centerRelative * 3f;
                    sprite.Room          = Room;
                }
                Bounding = new Rectangle(minX, minY, maxX - minX, maxY - minY);

                _Dirty = false;
            }
        }