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); }
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)); } }
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); }