From 0658b93b3384a4471a17b5143b328cb40fd2cdfc Mon Sep 17 00:00:00 2001 From: Benito Palacios Sanchez Date: Tue, 14 Jan 2020 19:29:44 +0100 Subject: [PATCH] :sparkles: Implement missing sections of mat1 --- Clypo.Console/Clypo.Console.csproj | 1 + Clypo/Binary2Clyt.cs | 57 +++++++++++++++++++++--------- Clypo/Clyt2Binary.cs | 37 ++++++++++++++++--- Clypo/Layout/AlphaCompare.cs | 28 +++++++++++++++ Clypo/Layout/BlendMode.cs | 32 +++++++++++++++++ Clypo/Layout/Material.cs | 8 +++++ Clypo/Layout/TevStage.cs | 30 ++++++++++++++++ README.md | 4 ++- 8 files changed, 176 insertions(+), 21 deletions(-) create mode 100644 Clypo/Layout/AlphaCompare.cs create mode 100644 Clypo/Layout/BlendMode.cs create mode 100644 Clypo/Layout/TevStage.cs diff --git a/Clypo.Console/Clypo.Console.csproj b/Clypo.Console/Clypo.Console.csproj index 8245ed7..c906da8 100644 --- a/Clypo.Console/Clypo.Console.csproj +++ b/Clypo.Console/Clypo.Console.csproj @@ -5,6 +5,7 @@ Clypo.Console netcoreapp3.1 + win-x64 true true diff --git a/Clypo/Binary2Clyt.cs b/Clypo/Binary2Clyt.cs index 511b2e0..910a6c7 100644 --- a/Clypo/Binary2Clyt.cs +++ b/Clypo/Binary2Clyt.cs @@ -159,22 +159,14 @@ void ReadMaterial() uint numTexMatrix = (flags >> 2) & 0x3; uint numTexCoordGen = (flags >> 4) & 0x3; uint numTevStage = (flags >> 6) & 0x7; - uint hasAlphaCompare = (flags >> 9) & 0x01; - uint hasBlendMode = (flags >> 10) & 0x01; + bool hasAlphaCompare = ((flags >> 9) & 0x01) == 1; + bool hasBlendMode = ((flags >> 10) & 0x01) == 1; material.UseTextureOnly = ((flags >> 11) & 0x01) == 1; - uint separateBlendMode = (flags >> 12) & 0x01; - uint hasIndirectParam = (flags >> 13) & 0x01; + bool separateBlendMode = ((flags >> 12) & 0x01) == 1; + bool hasIndirectParam = ((flags >> 13) & 0x01) == 1; uint numProjTexGenParam = (flags >> 14) & 0x03; - uint hasFontShadowParam = (flags >> 16) & 0x01; + bool hasFontShadowParam = ((flags >> 16) & 0x01) == 1; - uint texMapOffset = 0x34; - uint texMatrixOffset = texMapOffset + (numTexMap * 4); - uint texCoordGenOffset = texMatrixOffset + (numTexMatrix * 0x14); - uint tevStageOffset = texCoordGenOffset + (numTexCoordGen * 4); - uint alphaCompareOffset = tevStageOffset + (numTevStage * 0xC); - uint blendModeOffset = alphaCompareOffset + 0x8; - - reader.Stream.Seek(offset + texMapOffset); for (int i = 0; i < numTexMap; i++) { var entry = new TextureMapEntry(); entry.Index = reader.ReadUInt16(); @@ -189,7 +181,6 @@ void ReadMaterial() material.TexMapEntries.Add(entry); } - reader.Stream.Seek(offset + texMatrixOffset); for (int i = 0; i < numTexMatrix; i++) { var entry = new TextureMatrixEntry(); entry.Translation = new Vector2(reader.ReadSingle(), reader.ReadSingle()); @@ -199,12 +190,46 @@ void ReadMaterial() material.TexMatrixEntries.Add(entry); } - reader.Stream.Seek(offset + texCoordGenOffset); for (int i = 0; i < numTexCoordGen; i++) { material.TextureCoordGen.Add(reader.ReadSingle()); } - // TODO: Find a bclyt with the rest of sections + for (int i = 0; i < numTevStage; i++) { + var stage = new TevStage(); + stage.Param1 = reader.ReadUInt32(); + stage.Param2 = reader.ReadUInt32(); + stage.Param3 = reader.ReadUInt32(); + material.TevStages.Add(stage); + } + + if (hasAlphaCompare) { + material.AlphaCompare = new AlphaCompare { + Function = reader.ReadUInt32(), + Reference = reader.ReadSingle(), + }; + } + + if (hasBlendMode) { + material.ColorBlendMode = new BlendMode { + BlendOperator = reader.ReadByte(), + SourceFactor = reader.ReadByte(), + DestinationFactor = reader.ReadByte(), + LogicOperator = reader.ReadByte(), + }; + } + + if (separateBlendMode) { + material.AlphaBlendMode = new BlendMode { + BlendOperator = reader.ReadByte(), + SourceFactor = reader.ReadByte(), + DestinationFactor = reader.ReadByte(), + LogicOperator = reader.ReadByte(), + }; + } + + if (hasIndirectParam || numProjTexGenParam > 0 || hasFontShadowParam) { + Console.WriteLine($"WARN: Material ({material.Name}) with unknown sections."); + } clyt.Materials.Add(material); reader.Stream.PopPosition(); diff --git a/Clypo/Clyt2Binary.cs b/Clypo/Clyt2Binary.cs index 0146207..152c509 100644 --- a/Clypo/Clyt2Binary.cs +++ b/Clypo/Clyt2Binary.cs @@ -220,9 +220,13 @@ void WriteMaterials(Collection materials) int flag = 0x00; flag |= mat.TexMapEntries.Count; - flag |= (mat.TexMatrixEntries.Count << 2); - flag |= (mat.TextureCoordGen.Count << 4); - flag |= ((mat.UseTextureOnly ? 1 : 0) << 11); + flag |= mat.TexMatrixEntries.Count << 2; + flag |= mat.TextureCoordGen.Count << 4; + flag |= mat.TevStages.Count << 6; + flag |= ((mat.AlphaCompare != null) ? 1 : 0) << 9; + flag |= ((mat.ColorBlendMode != null) ? 1 : 0) << 10; + flag |= (mat.UseTextureOnly ? 1 : 0) << 11; + flag |= ((mat.AlphaBlendMode != null) ? 1 : 0) << 12; // TODO: Find a bclyt with the rest of sections writer.Write(flag); @@ -250,6 +254,31 @@ void WriteMaterials(Collection materials) foreach (var coord in mat.TextureCoordGen) { writer.Write(coord); } + + foreach (var tev in mat.TevStages) { + writer.Write(tev.Param1); + writer.Write(tev.Param2); + writer.Write(tev.Param3); + } + + if (mat.AlphaCompare != null) { + writer.Write(mat.AlphaCompare.Function); + writer.Write(mat.AlphaCompare.Reference); + } + + if (mat.ColorBlendMode != null) { + writer.Write(mat.ColorBlendMode.BlendOperator); + writer.Write(mat.ColorBlendMode.SourceFactor); + writer.Write(mat.ColorBlendMode.DestinationFactor); + writer.Write(mat.ColorBlendMode.LogicOperator); + } + + if (mat.AlphaBlendMode != null) { + writer.Write(mat.AlphaBlendMode.BlendOperator); + writer.Write(mat.AlphaBlendMode.SourceFactor); + writer.Write(mat.AlphaBlendMode.DestinationFactor); + writer.Write(mat.AlphaBlendMode.LogicOperator); + } } } @@ -258,7 +287,7 @@ void WriteGroup(Group group) writer.Write(group.Name, 0x10); writer.Write((uint)group.Panels.Count); foreach (var panel in group.Panels) { - writer.Write(panel, 0x10); + writer.Write(panel, 0x10, false); } } diff --git a/Clypo/Layout/AlphaCompare.cs b/Clypo/Layout/AlphaCompare.cs new file mode 100644 index 0000000..eaaed83 --- /dev/null +++ b/Clypo/Layout/AlphaCompare.cs @@ -0,0 +1,28 @@ +// Copyright (c) 2019 SceneGate + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +namespace Clypo.Layout +{ + public class AlphaCompare + { + public uint Function { get; set; } + + public float Reference { get; set; } + } +} diff --git a/Clypo/Layout/BlendMode.cs b/Clypo/Layout/BlendMode.cs new file mode 100644 index 0000000..43dda81 --- /dev/null +++ b/Clypo/Layout/BlendMode.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2019 SceneGate + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +namespace Clypo.Layout +{ + public class BlendMode + { + public byte BlendOperator { get; set; } + + public byte SourceFactor { get; set; } + + public byte DestinationFactor { get; set; } + + public byte LogicOperator { get; set; } + } +} diff --git a/Clypo/Layout/Material.cs b/Clypo/Layout/Material.cs index e0a2fd1..f7076b5 100644 --- a/Clypo/Layout/Material.cs +++ b/Clypo/Layout/Material.cs @@ -34,5 +34,13 @@ public class Material public Collection TexMatrixEntries { get; } = new Collection(); public Collection TextureCoordGen { get; } = new Collection(); + + public Collection TevStages { get; } = new Collection(); + + public AlphaCompare AlphaCompare { get; set; } + + public BlendMode ColorBlendMode { get; set; } + + public BlendMode AlphaBlendMode { get; set; } } } diff --git a/Clypo/Layout/TevStage.cs b/Clypo/Layout/TevStage.cs new file mode 100644 index 0000000..2b47c19 --- /dev/null +++ b/Clypo/Layout/TevStage.cs @@ -0,0 +1,30 @@ +// Copyright (c) 2019 SceneGate + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +namespace Clypo.Layout +{ + public class TevStage + { + public uint Param1 { get; set; } + + public uint Param2 { get; set; } + + public uint Param3 { get; set; } + } +} diff --git a/README.md b/README.md index 9a70a19..27dfd5e 100644 --- a/README.md +++ b/README.md @@ -37,4 +37,6 @@ Clypo.Console.exe import-dir original input output This software is license under the [MIT](https://choosealicense.com/licenses/mit/) license. The specification of the BCLYT is based on assembly research in the game -_Attack of the Friday Monsters_ and information from [3dbrew](https://www.3dbrew.org/wiki/CLYT_format) +_Attack of the Friday Monsters_, information from [3dbrew](https://www.3dbrew.org/wiki/CLYT_format) +and part of the material section from [Every File Explorer](https://github.com/Gericom/EveryFileExplorer) +by Gericom.