Exemple #1
0
        public override Sprite GetSprite(ObjectEntry obj)
        {
            var count = obj.SubType & 0x7F;

            if (count > 16)
            {
                var unknown = ObjectHelper.UnknownObject;
                unknown.Flip(obj.XFlip, obj.YFlip);
                return(unknown);
            }

            var truncated = count & 0x1E;
            var horz      = truncated;
            var vert      = truncated;

            if (count < 8)
            {
                horz = 8;
                vert = count < 1 ? 1 : count;
            }

            var offset = (obj.SubType & 0x80) == 0 ? 0 : slope;
            var bitmap = new BitmapBits(16 * horz, 16 + offset * vert);

            var index = 0;

            while (index < count)
            {
                bitmap.DrawSprite(sprite, 16 * index, offset * index++);
            }
            while (index < 8)
            {
                bitmap.DrawSprite(sprite, 16 * index++, 0);
            }

            return(new Sprite(bitmap, priority, -8 * (truncated + 1), -8));
        }
        public override Sprite GetDebugOverlay(ObjectEntry obj)
        {
            if (obj.SubType != 0 && obj.SubType < 0x80)
            {
                var sprite = unknownSprite[(obj.XFlip ? 1 : 0) | (obj.YFlip ? 2 : 0)];
                var height = obj.SubType << 1;
                if (height < 16)
                {
                    return(sprite);
                }

                var bitmap = new BitmapBits(16, height);
                bitmap.DrawRectangle(LevelData.ColorWhite, 0, 0, 15, height - 1);
                bitmap.DrawSprite(sprite, 8, obj.SubType);
                return(new Sprite(bitmap, -8, -obj.SubType));
            }

            return(null);
        }
Exemple #3
0
        private Sprite BuildPath(params ushort[] pathData)
        {
            var sprites = new LinkedList <Tuple <int, int, int> >();
            var routine = Routine.Setup;
            int spawnTimer = 7, index = 0;

            decimal xpos = pathData[index++], xvel = 0.0m;
            decimal ypos = pathData[index++], yvel = 0.0m;
            int     xorigin = 0, yorigin = 0;
            byte    angle = 0;

            while (true)
            {
                switch (routine)
                {
                case Routine.Done:
                    var first = sprites.First.Value;
                    int minX = first.Item1, maxX = first.Item1, minY = first.Item2, maxY = first.Item2;

                    foreach (var s in sprites)
                    {
                        if (s.Item1 < minX)
                        {
                            minX = s.Item1;
                        }
                        else if (s.Item1 > maxX)
                        {
                            maxX = s.Item1;
                        }
                        if (s.Item2 < minY)
                        {
                            minY = s.Item2;
                        }
                        else if (s.Item2 > maxY)
                        {
                            maxY = s.Item2;
                        }
                    }

                    var bitmap = new BitmapBits(maxX - minX + 49, maxY - minY + 49);
                    foreach (var s in sprites)
                    {
                        bitmap.DrawSprite(paths[s.Item3], s.Item1 - minX + 24, s.Item2 - minY + 24);
                    }

                    return(new Sprite(bitmap, minX - 24, minY - 24));

                case Routine.Line:
                    if (--xorigin > 0)
                    {
                        xpos += xvel;
                        ypos += yvel;
                        break;
                    }

                    xpos = pathData[index++];
                    ypos = pathData[index++];
                    goto case Routine.CheckDone;

                case Routine.CheckDone:
                    if (index == pathData.Length)
                    {
                        routine = Routine.Done;
                        break;
                    }

                    if ((short)pathData[index] >= 0)
                    {
                        goto case Routine.NextWaypoint;
                    }

                    routine    = ((pathData[index] >> 8) & 0x7F) + Routine.CircleLarge;
                    spawnTimer = routine == Routine.CircleSmall ? 0 : 1;
                    angle      = (byte)(pathData[index + 1] >> 8);
                    {
                        var radians     = Math.PI * ((angle + 0x20) & 0xC0) / 128.0;
                        var scalefactor = routine == Routine.CircleSmall ? -64.0 : -128.0;
                        xorigin = (int)decimal.Floor(xpos) + (int)(Math.Sin(radians) * scalefactor);

                        if (routine == Routine.CircleLarge || routine == Routine.CircleSmall)
                        {
                            yorigin = (int)decimal.Floor(ypos) + (int)(Math.Cos(radians) * scalefactor);
                        }
                    }
                    break;

                case Routine.CircleLarge:
                case Routine.CircleSmall:
                {
                    var radians     = Math.PI * angle / 128.0;
                    var scalefactor = (5 - (int)routine) * 64.0;
                    var sin         = (int)(Math.Sin(radians) * scalefactor) + xorigin;
                    var cos         = (int)(Math.Cos(radians) * scalefactor) + yorigin;

                    xvel = (sin - (int)decimal.Floor(xpos)) * 256;
                    yvel = (cos - (int)decimal.Floor(ypos)) * 256;
                    xpos = sin;
                    ypos = cos;
                }
                    goto case Routine.CheckAngle;

                case Routine.SineDown:
                    yvel = 3.0m;
                    goto case Routine.Sine;

                case Routine.SineUp:
                    yvel = -3.0m;
                    goto case Routine.Sine;

                case Routine.Sine:
                {
                    var radians = Math.PI * angle / 128.0;
                    var sin     = (int)(Math.Sin(radians) * 128.0) + xorigin;

                    xvel  = (sin - (int)decimal.Floor(xpos)) * 256;
                    xpos  = sin;
                    ypos += yvel;
                }
                    goto case Routine.CheckAngle;

                case Routine.CheckAngle:
                    if (angle == (byte)pathData[index + 1])
                    {
                        routine = Routine.Line;
                        index  += 2;
                        goto case Routine.CheckDone;
                    }

                    angle += (byte)pathData[index];
                    break;

                case Routine.Setup:
                    routine = Routine.Line;
                    goto case Routine.NextWaypoint;

                case Routine.NextWaypoint:
                    var xoffset = pathData[index] - xpos;
                    var yoffset = pathData[index + 1] - ypos;
                    var xfactor = xoffset < 0 ? -xoffset : xoffset;
                    var yfactor = yoffset < 0 ? -yoffset : yoffset;

                    if (xfactor < yfactor)
                    {
                        yvel    = yoffset < 0 ? -12.0m : 12.0m;
                        yfactor = yoffset / yvel;
                        xvel    = xoffset == 0 ? 0 : (xoffset / yfactor);
                        xorigin = (int)(yfactor < 0 ? -yfactor : yfactor) & 0xFF;
                    }
                    else
                    {
                        xvel    = xoffset < 0 ? -12.0m : 12.0m;
                        xfactor = xoffset / xvel;
                        yvel    = yoffset == 0 ? 0 : (yoffset / xfactor);
                        xorigin = (int)(xfactor < 0 ? -xfactor : xfactor) & 0xFF;
                    }
                    break;
                }

                if (spawnTimer-- > 0)
                {
                    continue;
                }
                spawnTimer = 1;

                var xoff  = (int)decimal.Floor(xpos);
                var yoff  = (int)decimal.Floor(ypos);
                var frame = routine == Routine.SineDown || routine == Routine.SineUp
                                        ? (((angle - (byte)pathData[index] + 8) >> 4) & 7) + 8 : xvel == 0.0m ? 4
                                        : ((int)(Math.Atan((double)(yvel / xvel)) * 128.0 / Math.PI + 8) >> 4) & 7;

                sprites.AddFirst(new Tuple <int, int, int>(xoff, yoff, frame));
            }
        }
Exemple #4
0
        public override Sprite GetDebugOverlay(ObjectEntry obj)
        {
            var jumps = obj.SubType & 0x0F;

            if (jumps == 0 || (obj.SubType & 0x30) != 0)
            {
                return(null);
            }

            var bitmap = new BitmapBits(64, 65);

            bitmap.DrawCircle(LevelData.ColorWhite, 65, 1, 63);
            bitmap.DrawLine(LevelData.ColorWhite, 63, 0x00, 63, 0x07);
            bitmap.DrawLine(LevelData.ColorWhite, 63, 0x10, 63, 0x17);
            bitmap.DrawLine(LevelData.ColorWhite, 63, 0x20, 63, 0x27);
            bitmap.DrawLine(LevelData.ColorWhite, 63, 0x30, 63, 0x37);

            var y      = 142;
            var swings = obj.SubType >> 6;
            var width  = swings == 0 ? 128 : swings * 512;
            var height = (swings == 0 ? 1 : swings) * jumps * 128 + y;

            var overlay = new Sprite(bitmap, -64, height - 64);

            bitmap = new BitmapBits(width, height + 1);
            bitmap.DrawLine(LevelData.ColorWhite, 12, 0, 12, y);

            if (swings == 0)
            {
                while (y != height)
                {
                    bitmap.DrawEllipse(LevelData.ColorWhite, -128, y, 127, y += 128);
                }
            }
            else
            {
                var path = new BitmapBits(272, 65);
                path.DrawEllipse(LevelData.ColorWhite, -272, 0, 271, 96);
                var right = new Sprite(path);
                right = new Sprite(new Sprite(right, 512, 129, true, true), right);
                var left = new Sprite(right, true, false);

                var curLeft = false;
                for (var x = 0; y != height; y += 128)
                {
                    bitmap.DrawSprite(curLeft ? left : right, x, y);
                    curLeft = curLeft ? (x -= 512) != 0 : (x += 512) == width;
                }

                if (curLeft)
                {
                    overlay.Flip(true, false);
                    overlay.Offset(width, 0);
                }
            }

            overlay = new Sprite(new Sprite(bitmap), overlay);
            overlay.Offset(-12, 50);
            overlay.Flip(!obj.XFlip, false);
            return(overlay);
        }