public static Obj FromUshort(ushort attr0, ushort attr1, ushort attr2) { Obj obj = new Obj(); // Attribute 0 obj.CoordY = (sbyte) ((attr0 >> 00) & 0x00FF); obj.RotSca = ((attr0 >> 08) & 0x0001) == 1; obj.Mode = (ObjMode) ((attr0 >> 10) & 0x0003); obj.IsMosaic = ((attr0 >> 12) & 0x0001) == 1; obj.PaletteMode = (PaletteMode)((attr0 >> 13) & 0x0001); obj.Shape = (ObjShape) ((attr0 >> 14) & 0x0003); // Attribute 1 ushort tempX = (ushort)((attr1 >> 00) & 0x001FF); // 9-bit signed (two's complement) value if ((tempX >> 8) == 0) obj.CoordX = (short)tempX; else obj.CoordX = (short)(((tempX ^ 0x1FF) + 1) * -1); // (9-bit negation) + 1 obj.SizeMode = (byte) ((attr1 >> 14) & 0x0003); // Attribute 2 obj.tileNumber = (ushort)((attr2 >> 00) & 0x003FF); // I don't use the property since is the raw value obj.ObjPriority = (byte) ((attr2 >> 10) & 0x0003); obj.PaletteIndex = (byte) ((attr2 >> 12) & 0x000F); // Rotation / Scaling mode if (obj.RotSca) { obj.DoubleSize = ((attr0 >> 09) & 0x0001) == 1; obj.RotScaGroup = (byte)((attr1 >> 09) & 0x001F); } else { obj.IsDisabled = ((attr0 >> 09) & 0x0001) == 1; obj.HorizontalFlip = ((attr1 >> 12) & 0x0001) == 1; obj.VerticalFlip = ((attr1 >> 13) & 0x0001) == 1; } return obj; }
private void CreateObjects(EmguImage frame, List<Obj> objList, int x, int y, int maxHeight) { // Go to first non-transparent pixel int newX = SearchNoTransparentPoint(frame, 1, x, y, yEnd: y + maxHeight); int newY = SearchNoTransparentPoint(frame, 0, x, y, yEnd: y + maxHeight); if (newY == -1 || newX == -1) return; int diffX = newX - x; diffX -= diffX % 8; x = diffX + x; int diffY = newY - y; diffY -= diffY % 8; y = diffY + y; int width = 0; int height = 0; this.GetObjectSize(frame, x, y, frame.Width, maxHeight, out width, out height); if (width != 0 && height != 0) { // Create object Obj obj = new Obj(); obj.Id = (ushort)objList.Count; obj.CoordX = (short)(x - 256); obj.CoordY = (sbyte)(y - 128); obj.SetSize(width, height); objList.Add(obj); } else { // If everything is transparent width = this.splitMode[0, 1]; // Max width height = this.splitMode[0, 1]; // Max height } // Go to right if (frame.Width - (x + width) > 0) this.CreateObjects(frame, objList, x + width, y, height); // Go to down int newMaxHeight = maxHeight - (height + diffY); if (newMaxHeight > 0) this.CreateObjects(frame, objList, x, y + height, newMaxHeight); }
public void SetObjects(Obj[] objs) { this.objects = (Obj[])objs.Clone(); }
protected override void ReadData(Stream strIn) { BinaryReader br = new BinaryReader(strIn); long blockStart = strIn.Position; ushort numFrames = br.ReadUInt16(); this.TypeFrame = br.ReadUInt16(); uint frameOffset = br.ReadUInt32(); this.TileSize = 1 << (5 + (int)(br.ReadUInt32() & 0xFF)); int frameInfoSize = ((this.TypeFrame & 1) != 0) ? 0x10 : 0x08; this.UnknownOffset1 = br.ReadUInt32(); // Offset to unknown block this.Unknown = br.ReadUInt32(); // Unknown this.UnknownOffset2 = br.ReadUInt32(); // Unknown offset #if VERBOSE if (this.UnknownOffset1 != 0) Console.WriteLine("\t* UnknownOffset1 -> {0:x8}", this.UnknownOffset1); if (this.Unknown != 0) Console.WriteLine("\t* Unknown -> {0:x8}", this.Unknown); if (this.UnknownOffset2 != 0) Console.WriteLine("\t* UnknownOffset2 -> {0:X8}", this.UnknownOffset2); #endif this.Frames = new Frame[numFrames]; for (int i = 0; i < numFrames; i++) { strIn.Position = blockStart + frameOffset + i * frameInfoSize; Frame frame = new Frame(); frame.TileSize = this.TileSize; ushort numObjs = br.ReadUInt16(); ushort areaInfo = br.ReadUInt16(); uint objOffset = br.ReadUInt32(); // Get area info bool squareSizeFlag = ((areaInfo >> 11) & 1) == 0; Rectangle frameArea = new Rectangle(); if ((this.TypeFrame & 1) != 0 && !squareSizeFlag) { short xend = br.ReadInt16(); short yend = br.ReadInt16(); short xstart = br.ReadInt16(); short ystart = br.ReadInt16(); frameArea.Location = new Point(xstart, ystart); frameArea.Width = xend - xstart; frameArea.Height = yend - ystart; } else if (!squareSizeFlag) { throw new FormatException("Obj area info is square but areaInfo is set"); } else { int squareSize = (areaInfo & 0x3F) << 2; squareSize *= 2; frameArea.Width = squareSize; frameArea.Height = squareSize; } // Read Objs strIn.Position = blockStart + frameOffset + numFrames * frameInfoSize + objOffset; Obj[] objs = new Obj[numObjs]; for (int j = 0; j < numObjs; j++) { objs[j] = Obj.FromUshort(br.ReadUInt16(), br.ReadUInt16(), br.ReadUInt16()); objs[j].Id = (ushort)j; } // TODO: Detect frame position for square size frame.SetObjects(objs); frame.VisibleArea = frameArea; this.Frames[i] = frame; } }