Skip to content

Commit

Permalink
Add latest bfres and byml libs from tile branch
Browse files Browse the repository at this point in the history
  • Loading branch information
KillzXGaming committed Dec 10, 2023
1 parent 65387e1 commit 5d542ad
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 23 deletions.
81 changes: 81 additions & 0 deletions Fushigi.Bfres/Common/SubStream.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.IO;

namespace Fushigi
{
//From
//https://github.com/IcySon55/Kuriimu/blob/master/src/Kontract/IO/SubStream.cs

/// <summary>
/// Represenents a stream taked from another given an offset and length
/// Used for archives with streams left open
/// </summary>
public class SubStream : Stream
{
Stream baseStream;
readonly long length;
readonly long baseOffset;
public SubStream(Stream baseStream, long offset, long length)
{
if (baseStream == null) throw new ArgumentNullException("baseStream");
if (!baseStream.CanRead) throw new ArgumentException("baseStream.CanRead is false");
if (!baseStream.CanSeek) throw new ArgumentException("baseStream.CanSeek is false");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (offset + length > baseStream.Length) throw new ArgumentOutOfRangeException("length");

this.baseStream = baseStream;
this.length = length;
baseOffset = offset;
}

public SubStream(Stream baseStream, long offset)
{
long length = baseStream.Length - offset;

if (baseStream == null) throw new ArgumentNullException("baseStream");
if (!baseStream.CanRead) throw new ArgumentException("baseStream.CanRead is false");
if (!baseStream.CanSeek) throw new ArgumentException("baseStream.CanSeek is false");
if (offset < 0) throw new ArgumentOutOfRangeException("offset");
if (offset + length > baseStream.Length) throw new ArgumentOutOfRangeException("length");

this.baseStream = baseStream;
this.length = length;
baseOffset = offset;
}

public override int Read(byte[] buffer, int offset, int count)
{
baseStream.Position = baseOffset + offset + Position;
int read = baseStream.Read(buffer, offset, (int)Math.Min(count, length - Position));
Position += read;
return read;
}

public override long Length => length;
public override bool CanRead => true;
public override bool CanWrite => false;
public override bool CanSeek => true;
public override long Position { get; set; }
public override void Flush() => baseStream.Flush();

public override long Seek(long offset, SeekOrigin origin)
{
switch (origin)
{
case SeekOrigin.Begin: return Position = offset;
case SeekOrigin.Current: return Position += offset;
case SeekOrigin.End: return Position = length + offset;
}
throw new ArgumentException("origin is invalid");
}

public override void SetLength(long value)
{
throw new NotSupportedException();
}
public override void Write(byte[] buffer, int offset, int count)
{
throw new NotSupportedException();
}
}
}
Binary file not shown.
Binary file not shown.
38 changes: 15 additions & 23 deletions Fushigi.Bfres/Shaders/BfshaFile.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
using Fushigi.Bfres.Common;
using Ryujinx.Common.Logging;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
using static Fushigi.Bfres.BfshaFile;
using static System.Runtime.InteropServices.JavaScript.JSType;


namespace Fushigi.Bfres
{
Expand Down Expand Up @@ -69,8 +58,12 @@ public class ShaderModel : IResData

private ShaderModelHeader header;

private Stream Stream;

public void Read(BinaryReader reader)
{
Stream = reader.BaseStream;

reader.BaseStream.Read(Utils.AsSpan(ref header));
long pos = reader.BaseStream.Position;

Expand Down Expand Up @@ -110,22 +103,21 @@ public void Read(BinaryReader reader)
reader.SeekBegin((long)header.BnshOffset + 0x1C);
var bnshSize = (int)reader.ReadUInt32();

reader.SeekBegin((long)header.BnshOffset);
byte[] data = reader.ReadBytes(bnshSize);
BnshFile = new BnshFile(new MemoryStream(data));

reader.SeekBegin(pos);
}

public BnshFile.ShaderVariation GetShaderVariation(ShaderProgram program)
{
foreach (var var in BnshFile.Variations)
{
//Todo this is kinda dumb. It would be better if I read the variation from here by offset
if (var.Position + (long)header.BnshOffset == (long)program.VariationOffset)
return var;
}
return null;
Stream.Position = 0;

var sub = new SubStream(Stream, (long)header.BnshOffset);
var reader = sub.AsBinaryReader();

reader.SeekBegin((long)program.VariationOffset - (long)header.BnshOffset);

var v = new BnshFile.ShaderVariation();
v.Read(reader);
return v;
}

public int GetProgramIndex(Dictionary<string, string> options)
Expand Down
2 changes: 2 additions & 0 deletions Fushigi.Bfres/Shaders/ShaderUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ public static byte[] GenerateShaderParamBuffer(ShaderModel shaderModel, Material
writer.Write((int)matParam.DataValue);
else if (matParam.DataValue is uint)
writer.Write((uint)matParam.DataValue);
else if (matParam.DataValue is bool)
writer.Write((bool)matParam.DataValue);
else
throw new Exception($"Unsupported render type! {matParam.Type}");
}
Expand Down
29 changes: 29 additions & 0 deletions Fushigi.Byml/Serializer/BymlSerialize.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
Expand Down Expand Up @@ -132,6 +133,21 @@ static void SetValues(object property, Type type, object section, dynamic value)

SetValue(property, section, dict);
}
else if (IsByStringDictionaryType(type, out Type? valueType))
{
var values = value as BymlHashTable;


var dict = (IDictionary)CreateInstance(type);
foreach (var pair in values.Pairs)
{
var instance = CreateInstance(valueType);
Deserialize(instance, pair.Value);
dict.Add(pair.Name, instance);
}

SetValue(property, section, dict);
}
else
{
var instance = CreateInstance(type);
Expand All @@ -143,6 +159,19 @@ static void SetValues(object property, Type type, object section, dynamic value)
SetValue(property, section, value.Data);
}

static bool IsByStringDictionaryType(Type type, [NotNullWhen(true)] out Type? valueType)
{
valueType = null;
if(!type.IsGenericType)
return false;

if(!type.GetGenericTypeDefinition().Equals(typeof(Dictionary<,>)))
return false;

valueType = type.GetGenericArguments()[1];
return true;
}

static void SetValue(object property, object instance, object value)
{
if (property is PropertyInfo)
Expand Down

0 comments on commit 5d542ad

Please sign in to comment.