1
0
mirror of synced 2024-11-30 18:24:39 +01:00

Add LZARC support and a few random fixes.

This commit is contained in:
KillzXGaming 2019-06-14 17:23:02 -04:00
parent d2e1018db9
commit a8698a2ef4
24 changed files with 273 additions and 57 deletions

Binary file not shown.

View File

@ -0,0 +1,113 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Switch_Toolbox;
using System.Windows.Forms;
using Switch_Toolbox.Library;
using Switch_Toolbox.Library.IO;
namespace FirstPlugin
{
public class LZARC : IArchiveFile, IFileFormat
{
public FileType FileType { get; set; } = FileType.Archive;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "LZARC" };
public string[] Extension { get; set; } = new string[] { "*.lzarc" };
public string FileName { get; set; }
public string FilePath { get; set; }
public IFileInfo IFileInfo { get; set; }
public bool CanAddFiles { get; set; }
public bool CanRenameFiles { get; set; }
public bool CanReplaceFiles { get; set; }
public bool CanDeleteFiles { get; set; }
public bool Identify(System.IO.Stream stream)
{
using (var reader = new Switch_Toolbox.Library.IO.FileReader(stream, true))
{
return Utils.GetExtension(FileName) == ".lzarc";
}
}
public Type[] Types
{
get
{
List<Type> types = new List<Type>();
return types.ToArray();
}
}
public List<FileEntry> files = new List<FileEntry>();
public IEnumerable<ArchiveFileInfo> Files => files;
public void Load(System.IO.Stream stream)
{
using (var reader = new FileReader(stream))
{
reader.ByteOrder = Syroot.BinaryData.ByteOrder.BigEndian;
uint FileSize = reader.ReadUInt32();
uint Unknown = reader.ReadUInt32();
uint FileCount = reader.ReadUInt32();
for (int i = 0; i < FileCount; i++)
{
var file = new FileEntry();
file.Read(reader);
files.Add(file);
}
}
}
public void Unload()
{
}
public byte[] Save()
{
return null;
}
public bool AddFile(ArchiveFileInfo archiveFileInfo)
{
return false;
}
public bool DeleteFile(ArchiveFileInfo archiveFileInfo)
{
return false;
}
public class FileEntry : ArchiveFileInfo
{
public uint Unknown { get; set; }
public uint CompressedSize;
public uint DecompressedSize;
public void Read(FileReader reader)
{
char[] name = reader.ReadChars(128);
FileName = new string(name);
uint Offset = reader.ReadUInt32();
CompressedSize = reader.ReadUInt32();
uint Unknown = reader.ReadUInt32();
uint Unknown2 = reader.ReadUInt32();
DecompressedSize = reader.ReadUInt32();
using (reader.TemporarySeek((int)Offset, System.IO.SeekOrigin.Begin))
{
FileData = reader.ReadBytes((int)CompressedSize);
// STLibraryCompression.LZSS.Decompress(FileData, DecompressedSize);
}
}
}
}
}

View File

@ -393,21 +393,12 @@ namespace FirstPlugin
private void OpenFormDialog(IFileFormat fileFormat)
{
UserControl form = GetEditorForm(fileFormat);
form.Text = (((IFileFormat)fileFormat).FileName);
STForm form = GetEditorForm(fileFormat);
var parentForm = LibraryGUI.Instance.GetActiveForm();
GenericEditorForm editorForm = new GenericEditorForm(true, form);
editorForm.FormClosing += (sender, e) => FormClosing(sender, e, fileFormat);
if (editorForm.ShowDialog() == DialogResult.OK)
{
if (fileFormat.CanSave)
{
Data = fileFormat.Save();
UpdateHexView();
}
}
form.Text = (((IFileFormat)fileFormat).FileName);
form.FormClosing += (sender, e) => FormClosing(sender, e, fileFormat);
form.Show(parentForm);
}
private void FormClosing(object sender, EventArgs args, IFileFormat fileFormat)
@ -422,7 +413,7 @@ namespace FirstPlugin
}
}
private UserControl GetEditorForm(IFileFormat fileFormat)
private STForm GetEditorForm(IFileFormat fileFormat)
{
Type objectType = fileFormat.GetType();
foreach (var inter in objectType.GetInterfaces())
@ -430,7 +421,7 @@ namespace FirstPlugin
if (inter.IsGenericType && inter.GetGenericTypeDefinition() == typeof(IEditor<>))
{
System.Reflection.MethodInfo method = objectType.GetMethod("OpenForm");
return (UserControl)method.Invoke(fileFormat, new object[0]);
return (STForm)method.Invoke(fileFormat, new object[0]);
}
}
return null;

View File

@ -110,15 +110,15 @@ namespace FirstPlugin
fileList = FilePaths.ToArray();
// Parse the file list into a TreeNode collection
// TreeNode node = GetNodes(new TreeNode(), fileList);
// Nodes.Add(node); // Add the new nodes
TreeNode node = GetNodes(new TreeNode(), fileList);
Nodes.Add(node); // Add the new nodes
// Copy the new nodes to an array
// int nodeCount = node.Nodes.Count;
// TreeNode[] nodes = new TreeNode[nodeCount];
// node.Nodes.CopyTo(nodes, 0);
int nodeCount = node.Nodes.Count;
TreeNode[] nodes = new TreeNode[nodeCount];
node.Nodes.CopyTo(nodes, 0);
// Nodes.AddRange(nodes); // Add the new nodes
Nodes.AddRange(nodes); // Add the new nodes
}
private TreeNode GetNodes(TreeNode parent, string[] fileList)
@ -228,7 +228,7 @@ namespace FirstPlugin
public void ParseNames(FileReader reader, string Name = "")
{
if (!Name.Contains("dummy"))
if (!Name.Contains("dummy") && FilePaths.Count < 200)
FilePaths.Add(Name);
char ch = reader.ReadChar();
@ -238,7 +238,7 @@ namespace FirstPlugin
if (ch >= 1 && ch <= 0x1f) //string part
{
while (ch-- != 0)
while (ch-- > 0)
{
Name += reader.ReadChar();
}
@ -249,8 +249,9 @@ namespace FirstPlugin
int var = Convert.ToInt32(ch - 'A');
ch = Convert.ToChar(var);
int count1 = ch >> 7;
int count1 = ch & 7;
int flag1 = (ch >> 3) & 1;
// int flag1 = ch & 8;
if (count1 != 0)
{
@ -263,15 +264,25 @@ namespace FirstPlugin
for (int chunkIndex = 0; chunkIndex < count1; chunkIndex++)
{
byte ch3 = reader.ReadByte();
if (ch3 == 0)
{
break;
}
int compressedSizeByteCount = (ch3 & 3) + 1;
int packageOffsetByteCount = (ch3 >> 2) & 7;
int hasCompression = (ch3 >> 5) & 1;
bool hasCompression = ((ch3 >> 5) & 1) != 0;
ulong decompressedSize = readVariadicInteger(compressedSizeByteCount, reader);
ulong decompressedSize =0;
ulong compressedSize = 0;
ulong packageOffset = 0;
long fileId = -1;
if (hasCompression != 0)
if (compressedSizeByteCount > 0)
{
decompressedSize = readVariadicInteger(compressedSizeByteCount, reader);
}
if (hasCompression)
{
compressedSize = readVariadicInteger(compressedSizeByteCount, reader);
}
@ -279,13 +290,21 @@ namespace FirstPlugin
{
packageOffset = readVariadicInteger(packageOffsetByteCount, reader);
}
ulong packageId = readVariadicInteger(2, reader);
if (packageId >= Header.Block1Count)
{
throw new InvalidDataException("SDF Package ID outside of TOC range");
}
List<ulong> compSizeArray = new List<ulong>();
if (hasCompression != 0)
if (hasCompression)
{
ulong pageCount = (decompressedSize + 0xffff) >> 16;
ulong pageCount = (decompressedSize + 0xffff) >> 16;
// var pageCount = NextMultiple(decompressedSize, 0x10000) / 0x10000;
if (pageCount > 1)
{
for (ulong page = 0; page < pageCount; page++)
@ -296,21 +315,24 @@ namespace FirstPlugin
}
}
ulong fileId = readVariadicInteger(4, reader);
if (Header.Version <= 0x16)
{
fileId = (long)readVariadicInteger(4, reader);
}
if (compSizeArray.Count == 0 && hasCompression != 0)
if (compSizeArray.Count == 0 && hasCompression)
compSizeArray.Add(compressedSize);
DumpFile(Name, packageId, packageOffset, decompressedSize, compSizeArray, DdsType, chunkIndex != 0, byteCount != 0 && chunkIndex == 0);
}
}
if (flag1 != 0)
if ((ch & 8) != 0) //flag1
{
byte ch3 = reader.ReadByte();
while (ch3-- != 0)
while (ch3-- > 0)
{
byte ch3_1 = reader.ReadByte();
byte ch3_2 = reader.ReadByte();
reader.ReadByte();
reader.ReadByte();
}
}
}
@ -323,10 +345,31 @@ namespace FirstPlugin
}
}
public static ulong NextMultiple(ulong value, ulong multiple) => NextMultiple((long)value, multiple);
public static ulong NextMultiple(long value, ulong multiple)
{
return (ulong)Math.Ceiling(value / (double)multiple) * multiple;
}
public void DumpFile(string Name, ulong packageId, ulong packageOffset, ulong decompresedSize,
List<ulong> compressedSize, ulong ddsType, bool Append, bool UseDDS)
{
string PathFolder = Path.GetDirectoryName(FileName);
string layer;
Console.WriteLine(Name + " " + packageId + " " + packageOffset + " " + decompresedSize + " " + ddsType + " " + UseDDS);
if (packageId < 1000)
{
layer = "A";
}
else if (packageId < 2000)
{
layer = "B";
}
else
{
layer = "C";
}
}

View File

@ -13,7 +13,7 @@ namespace FirstPlugin
public FileType FileType { get; set; } = FileType.Archive;
public bool CanSave { get; set; }
public string[] Description { get; set; } = new string[] { "Sonic Team Racing Archive" };
public string[] Description { get; set; } = new string[] { "Team Sonic Racing Archive" };
public string[] Extension { get; set; } = new string[] { "*.sp2" };
public string FileName { get; set; }
public string FilePath { get; set; }

View File

@ -148,10 +148,9 @@ namespace Bfres.Structs
public override STGenericTexture GetActiveTexture(int index)
{
string name = GetActiveTextureNameByIndex(index);
foreach (var ftexFolder in PluginRuntime.ftexContainers)
{
string name = GetActiveTextureNameByIndex(index);
if (ftexFolder.ResourceNodes.ContainsKey(name))
return (STGenericTexture)ftexFolder.ResourceNodes[name];
}

View File

@ -617,6 +617,8 @@ namespace FirstPlugin
{
if (ftexCont.ResourceNodes.ContainsKey(activeTex))
{
Console.WriteLine("BINDING tex.animatedTexName " + activeTex + " " + tex.Type);
BindFTEX(ftexCont, tex, shader, activeTex);
return tex.textureUnit + 1;
}
@ -627,6 +629,8 @@ namespace FirstPlugin
{
if (ftexContainer.ResourceNodes.ContainsKey(activeTex))
{
Console.WriteLine("BINDING tex.animatedTexName " + activeTex + " " + tex.Type);
BindFTEX(ftexContainer, tex, shader, activeTex);
return tex.textureUnit + 1;
}

View File

@ -389,7 +389,9 @@ namespace FirstPlugin.Forms
{
if (activeSampler != null)
{
var tex = activeSampler.GetActiveTexture(Frame);
var keyFrame = activeSampler.GetKeyFrame(Frame);
var tex = activeSampler.GetActiveTexture((int)keyFrame.Value);
if (tex != null)
{
if (Images.ContainsKey(Frame))
@ -398,7 +400,9 @@ namespace FirstPlugin.Forms
}
if (activeSampleU != null)
{
var tex = activeSampleU.GetActiveTexture(Frame);
var keyFrame = activeSampleU.GetKeyFrame(Frame);
var tex = activeSampleU.GetActiveTexture((int)keyFrame.Value);
if (tex != null)
{
if (Images.ContainsKey(Frame))

View File

@ -313,8 +313,9 @@ namespace FirstPlugin
Formats.Add(typeof(SP2));
Formats.Add(typeof(NUSHDB));
Formats.Add(typeof(MKGPDX_PAC));
Formats.Add(typeof(LZARC));
Formats.Add(typeof(Turbo.Course_MapCamera_bin));
Formats.Add(typeof(Turbo.PartsBIN));

View File

@ -198,6 +198,7 @@
<Compile Include="Config.cs" />
<Compile Include="FileFormats\AAMP\AAMP.cs" />
<Compile Include="FileFormats\Archives\APAK.cs" />
<Compile Include="FileFormats\Archives\LZARC.cs" />
<Compile Include="FileFormats\Archives\MKGPDX_PAC.cs" />
<Compile Include="FileFormats\Archives\NXARC.cs" />
<Compile Include="FileFormats\Archives\RARC.cs" />

View File

@ -86,6 +86,9 @@ namespace Switch_Toolbox.Library.Forms
public UserControl GetEditorForm(IFileFormat fileFormat)
{
if (fileFormat == null)
return new STUserControl() { Dock = DockStyle.Fill };
Type objectType = fileFormat.GetType();
foreach (var inter in objectType.GetInterfaces())
{

View File

@ -5,6 +5,9 @@ using OpenTK;
using K4os.Compression.LZ4.Streams;
using System.Windows.Forms;
using ICSharpCode.SharpZipLib.Zip.Compression.Streams;
using System.Collections.Generic;
using System.Linq;
using System;
namespace Switch_Toolbox.Library.IO
{
@ -108,6 +111,46 @@ namespace Switch_Toolbox.Library.IO
}
}
public class LZSS
{
//From https://github.com/IcySon55/Kuriimu/blob/f670c2719affc1eaef8b4c40e40985881247acc7/src/Kontract/Compression/LZSS.cs
//Todo does not work with Paper Mario Color Splash
public static byte[] Decompress(byte[] data, uint decompressedLength)
{
using (FileReader reader = new FileReader(new MemoryStream(data), true))
{
List<byte> result = new List<byte>();
for (int i = 0, flags = 0; ; i++)
{
if (i % 8 == 0) flags = reader.ReadByte();
if ((flags & 0x80) == 0) result.Add(reader.ReadByte());
else
{
int lengthDist = BitConverter.ToUInt16(reader.ReadBytes(2).Reverse().ToArray(), 0);
int offs = lengthDist % 4096 + 1;
int length = lengthDist / 4096 + 3;
while (length > 0)
{
result.Add(result[result.Count - offs]);
length--;
}
}
if (result.Count == decompressedLength)
{
return result.ToArray();
}
else if (result.Count > decompressedLength)
{
throw new InvalidDataException("Went past the end of the stream");
}
flags <<= 1;
}
}
}
}
public class LZ77
{
/// <summary>

View File

@ -194,8 +194,8 @@ namespace Switch_Toolbox.Library.IO
if (!LeaveStreamOpen)
{
// stream.Close();
// stream.Dispose();
// stream.Close();
// stream.Dispose();
}
return fileFormat;

View File

@ -0,0 +1,11 @@
using System;
using System.IO;
using System.Text;
namespace Switch_Toolbox.Library.IO
{
public static class StreamReaderExtensions
{
}
}

View File

@ -34,6 +34,8 @@ namespace Switch_Toolbox.Library
}
public class ArchiveFileInfo
{
public STContextMenuStrip STContextMenuStrip;
public virtual STToolStripItem[] Menus { get; set; }
public FileType FileDataType = FileType.Default;

View File

@ -605,6 +605,7 @@
<Compile Include="IO\Matrix4x4.cs" />
<Compile Include="IO\STFileLoader.cs" />
<Compile Include="IO\STFileSaver.cs" />
<Compile Include="IO\StreamReaderExtensions.cs" />
<Compile Include="IO\StringExtension.cs" />
<Compile Include="IO\STStream.cs" />
<Compile Include="Maths\Math.cs" />

View File

@ -770,6 +770,8 @@ namespace Switch_Toolbox.Library
dataOffset += ArrayImageize;
mipDataOffset += ArrayMipImageize;
break;
}
return result;

View File

@ -194,17 +194,18 @@ void main()
float halfLambert = dot(difLightDirection, N) * 0.5 + 0.5;
vec4 diffuseMapColor = vec4(texture(DiffuseMap, f_texcoord0).rgba);
vec4 albedo = vec4(0);
//Comp Selectors
diffuseMapColor.r = GetComponent(RedChannel, diffuseMapColor);
diffuseMapColor.g = GetComponent(GreenChannel, diffuseMapColor);
diffuseMapColor.b = GetComponent(BlueChannel, diffuseMapColor);
diffuseMapColor.a = GetComponent(AlphaChannel, diffuseMapColor);
albedo.r = GetComponent(RedChannel, diffuseMapColor);
albedo.g = GetComponent(GreenChannel, diffuseMapColor);
albedo.b = GetComponent(BlueChannel, diffuseMapColor);
albedo.a = GetComponent(AlphaChannel, diffuseMapColor);
//Texture Overlay (Like an emblem in mk8)
if (UseMultiTexture == 1 && HasDiffuseLayer == 1)
{
vec4 AlbLayer = vec4(texture(DiffuseLayer, f_texcoord3).rgba);
diffuseMapColor.rgb = mix(diffuseMapColor.rgb, AlbLayer.rgb, AlbLayer.a);
albedo.rgb = mix(albedo.rgb, AlbLayer.rgb, AlbLayer.a);
}
// Default Shader
@ -217,8 +218,7 @@ void main()
alpha *= 0.5;
}
//vec4 diffuseMapColor = vec4(1);
diffuseMapColor *= halfLambert;
albedo *= halfLambert;
vec3 LightingDiffuse = vec3(0);
if (HasLightMap == 1)
@ -241,12 +241,11 @@ void main()
AoPass *= 1.0 - aoBlend * ao_density * 0.6;
}
diffuseMapColor.rgb += LightingDiffuse;
albedo.rgb += LightingDiffuse;
vec3 LightDiffuse = vec3(0.03);
//diffuseMapColor.rgb += mix(LightingDiffuse, diffuseMapColor.rgb, vec3(ShadowBake.shadowIntensity) );
fragColor.rgb += diffuseMapColor.rgb;
fragColor.rgb += albedo.rgb;
fragColor.rgb *= ShadowPass;
fragColor.rgb *= AoPass;
@ -263,13 +262,12 @@ void main()
if (HasEmissionMap == 1 || enable_emission == 1) //Can be without texture map
fragColor.rgb += EmissionPass(EmissionMap, emission_intensity, vert, 0, emission_color);
fragColor.rgb += SpecularPass(I, N, HasSpecularMap, SpecularMap, specular_color, vert, 0, UseSpecularColor);
fragColor.rgb += ReflectionPass(N, I, diffuseMapColor, specular, AoPass, tintColor, vert);
fragColor.rgb += ReflectionPass(N, I, albedo, specular, AoPass, tintColor, vert);
fragColor.rgb *= pickingColor.rgb;
if (isTransparent == 1)
fragColor.a *= texture(DiffuseMap, f_texcoord0).a;
fragColor.a *= albedo.a;
fragColor.rgb *= min(boneWeightsColored, vec3(1));

View File

@ -376,7 +376,7 @@ void main()
// Alpha calculations.
float alpha = GetComponent(AlphaChannel, texture(DiffuseMap, f_texcoord0));
fragColor.a = alpha;
fragColor.a = alpha;
if (RenderAsLighting)
{