/// <summary> /// Search and return the correct <see cref="ScTexture" /> according to the given <see cref="ScInfo" /> file, and the /// specified resolution. /// </summary> /// <param name="Path">The path.</param> /// <param name="HighRes">The resolution.</param> public static ScTexture GetScTextureFile(ScInfo ScInfo, bool HighRes) { ScTexture ScFile = ScFiles.Textures.Find(T => ScInfo.ScName == T.ScName && T.IsHighRes == HighRes); if (ScFile != null) { return(ScFile); } return(null); }
/// <summary> /// Search and return the correct <see cref="ScTexture" /> according to the given <see cref="ScInfo" /> file, and the /// specified resolution. /// </summary> /// <param name="Path">The path.</param> public static ScTexture GetScTextureFile(ScInfo ScInfo) { ScTexture ScFile = ScFiles.Textures.Find(T => ScInfo.ScName == T.ScName); if (ScFile != null) { return(ScFile); } return(null); }
/// <summary> /// Initializes this instance. /// </summary> public static void Initialize() { if (ScFiles.Initialized) { return; } string[] Files = Directory.GetFiles("Gamefiles/sc/", "*.sc"); ScFiles.Textures = new List <ScTexture>(Files.Length); ScFiles.Infos = new List <ScInfo>(Files.Length); foreach (string FilePath in Files) { FileInfo File = new FileInfo(FilePath); if (FilePath.EndsWith("_tex.sc")) { ScFiles.Textures.Add(new ScTexture(File)); } else { ScFiles.Infos.Add(new ScInfo(File)); } } Task.Run(() => { foreach (ScTexture ScTexture in ScFiles.Textures) { ScTexture.Read(); } foreach (ScInfo ScInfo in ScFiles.Infos) { ScInfo.Read(); } }); ScFiles.Initialized = true; Logging.Info(typeof(ScFiles), "Loaded " + Files.Length + " SC files."); }
/// <summary> /// Reads this instance. /// </summary> public override async Task Read() { using (BinaryReader Stream = new BinaryReader(this.File.OpenRead())) { byte[] Header = Stream.ReadBytes(2); if (Header[0] == (byte)'S' || Header[1] == (byte)'C') { // Logging.Warning(this.GetType(), "The SC file is compressed, aborting."); return; } Stream.BaseStream.Position = 0; this.Statistics.Decode(Stream); for (int i = 0; i < this.Statistics.StringsCount; i++) { short Identifier = Stream.ReadInt16(); if (this.Identifiers.Find(T => T == Identifier) != 0) { Logging.Warning(this.GetType(), "Text #" + Identifier + " already in list."); } this.Identifiers.Add(Identifier); } for (int i = 0; i < this.Statistics.StringsCount; i++) { string Name = Stream.ReadAscii(); if (string.IsNullOrEmpty(Name)) { Logging.Warning(this.GetType(), "Text #" + i + " was either null or empty."); } this.Names.Add(Name); } while (Stream.BaseStream.Position < Stream.BaseStream.Length) { byte BlockType = Stream.ReadByte(); int BlockLength = Stream.ReadInt32(); long BlockBegin = Stream.BaseStream.Position; switch (BlockType) { case 0x01: // Sheets { byte Format = Stream.ReadByte(); short Width = Stream.ReadInt16(); short height = Stream.ReadInt16(); if (BlockLength > 5) { Logging.Warning(this.GetType(), "BlockLength > 5 at 0x01."); } ScTexture ScTexture = ScFiles.GetScTextureFile(this); if (ScTexture != null) { Bitmap Texture = ScTexture.GetImage(this.ReadedSheets++); if (Texture != null) { this.Sheets.Add(Texture); } else { Logging.Error(this.GetType(), "Texture == null at 0x01."); } } else { Logging.Error(this.GetType(), "ScTexture == null at 0x01."); } break; } case 0x08: { float[] Points = new float[6]; for (int i = 0; i < 6; i++) { Points[i] = Stream.ReadInt32(); } const double val1 = 0.00097656; const double val2 = -20; double[,] matrixArrayD = { { Points[0] * val1, Points[1] * val1, Points[2] * val1 }, { Points[3] * val1, Points[4] / val2, Points[5] / val2 } }; //Matrix<double> Matrix = Matrix<double>.Build.DenseOfArray(matrixArrayD); break; } case 0x09: { // Logging.Warning(this.GetType(), BitConverter.ToString(Stream.ReadBytes(BlockLength))); break; } case 0x0C: { // Logging.Warning(this.GetType(), BitConverter.ToString(Stream.ReadBytes(BlockLength))); break; } case 0x12: // Spirites { ScSpirite ScSpirite = new ScSpirite(this, BlockType); ScSpirite.Decode(Stream); this.Spirites.Add(ScSpirite); break; } default: { Stream.ReadBytes(BlockLength); break; } } long BlockEnd = Stream.BaseStream.Position; long BlockLeft = BlockEnd - BlockBegin; if (BlockLeft != BlockLength) { if (BlockLeft > 0) { Logging.Error(this.GetType(), "We still have " + BlockLeft + " bytes to read !"); } else { Logging.Error(this.GetType(), "We are reading " + BlockLeft + " more bytes than we had to !"); } } } } }
/// <summary> /// Decodes the sub block using the specified reader. /// </summary> /// <param name="Stream">The stream.</param> internal void DecodeSubBlock(BinaryReader Stream) { byte BlockType = Stream.ReadByte(); int BlockLength = Stream.ReadInt32(); long BlockStart = Stream.BaseStream.Position; // Logging.Info(this.GetType(), " -- SubBlock Type : 0x" + BlockType.ToString("X").PadLeft(2, '0') + "."); if (BlockLength > 0) { byte SheetId = Stream.ReadByte(); byte Vertex = (byte)(BlockType == 0x04 ? 0x04 : Stream.ReadByte()); ScTexture ScSheet = ScFiles.GetScTextureFile((ScInfo)this.ScFile); if (ScSheet == null) { throw new Exception("ScSheet == null at DecodeSubBlock(BinaryReader Reader)."); } Bitmap Sheet = ScSheet.GetImage(SheetId); if (Sheet == null) { throw new Exception("Sheet == null at DecodeSubBlock(BinaryReader Reader)."); } this.PointsXY = new List <PointF>(Vertex); for (int i = 0; i < Vertex; i++) { float X = (float)Stream.ReadInt32() / -20; float Y = (float)Stream.ReadInt32() / 20; this.PointsXY.Add(new PointF(X, Y)); } this.PointsUV = new List <PointF>(Vertex); for (int i = 0; i < Vertex; i++) { float U = (float)Stream.ReadInt16() / ushort.MaxValue * Sheet.Width; float V = (float)Stream.ReadInt16() / ushort.MaxValue * Sheet.Height; this.PointsUV.Add(new PointF(U, V)); } this.Polygon = new GraphicsPath(); this.Polygon.AddPolygon(this.PointsUV.ToArray()); RectangleF Bounds = this.Polygon.GetBounds(); Rectangle BndRect = Rectangle.Round(Bounds); if (BndRect.IsEmpty == false) { Bitmap ShrunkSheet = new Bitmap(BndRect.Width, BndRect.Height); using (Graphics Graphic = Graphics.FromImage(ShrunkSheet)) { // this.Polygon.Transform(new Matrix(1, 0, 0, 1, -BndRect.X, -BndRect.Y)); Graphic.SetClip(this.Polygon); Graphic.DrawImage(Sheet, -BndRect.X, -BndRect.Y); } this.Image = ShrunkSheet; } else { Logging.Warning(this.GetType(), "BndRect.IsEmpty == true at DecodeSubBlock(BinaryReader Reader)."); } } else { Logging.Warning(this.GetType(), "BlockLength == 0 at DecodeSubBlock(BinaryReader Reader)."); } long BlockEnd = Stream.BaseStream.Position; long BlockLeft = BlockEnd - BlockStart; if (BlockLeft == BlockLength) { // Logging.Info(this.GetType(), "BlockLeft == BlockLength at DecodeSubBlock(BinaryReader Reader)."); } else { Logging.Error(this.GetType(), "BlockLeft != BlockLength at DecodeSubBlock(BinaryReader Reader)."); } }