diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..a975f0c
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,76 @@
+[*.cs]
+
+# CS8618: Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
+
+error_prone.large_struct_threshold = 128
+csharp_indent_labels = one_less_than_current
+csharp_using_directive_placement = outside_namespace:silent
+csharp_prefer_simple_using_statement = true:suggestion
+csharp_prefer_braces = true:silent
+csharp_style_namespace_declarations = block_scoped:silent
+csharp_style_prefer_method_group_conversion = true:silent
+csharp_style_prefer_top_level_statements = true:silent
+csharp_style_prefer_primary_constructors = true:suggestion
+csharp_style_expression_bodied_methods = false:silent
+csharp_style_expression_bodied_constructors = false:silent
+csharp_style_expression_bodied_operators = false:silent
+csharp_style_expression_bodied_properties = true:silent
+csharp_style_expression_bodied_indexers = true:silent
+csharp_style_expression_bodied_accessors = true:silent
+csharp_style_expression_bodied_lambdas = true:silent
+csharp_style_expression_bodied_local_functions = false:silent
+[*.{cs,vb}]
+dotnet_style_operator_placement_when_wrapping = beginning_of_line
+tab_width = 4
+indent_size = 4
+end_of_line = crlf
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
+[*.{cs,vb}]
+#### Naming styles ####
+
+# Naming rules
+
+dotnet_naming_rule.interface_should_be_begins_with_i.severity = suggestion
+dotnet_naming_rule.interface_should_be_begins_with_i.symbols = interface
+dotnet_naming_rule.interface_should_be_begins_with_i.style = begins_with_i
+
+dotnet_naming_rule.types_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.types_should_be_pascal_case.symbols = types
+dotnet_naming_rule.types_should_be_pascal_case.style = pascal_case
+
+dotnet_naming_rule.non_field_members_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.non_field_members_should_be_pascal_case.symbols = non_field_members
+dotnet_naming_rule.non_field_members_should_be_pascal_case.style = pascal_case
+
+# Symbol specifications
+
+dotnet_naming_symbols.interface.applicable_kinds = interface
+dotnet_naming_symbols.interface.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.interface.required_modifiers =
+
+dotnet_naming_symbols.types.applicable_kinds = class, struct, interface, enum
+dotnet_naming_symbols.types.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.types.required_modifiers =
+
+dotnet_naming_symbols.non_field_members.applicable_kinds = property, event, method
+dotnet_naming_symbols.non_field_members.applicable_accessibilities = public, internal, private, protected, protected_internal, private_protected
+dotnet_naming_symbols.non_field_members.required_modifiers =
+
+# Naming styles
+
+dotnet_naming_style.begins_with_i.required_prefix = I
+dotnet_naming_style.begins_with_i.required_suffix =
+dotnet_naming_style.begins_with_i.word_separator =
+dotnet_naming_style.begins_with_i.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
+
+dotnet_naming_style.pascal_case.required_prefix =
+dotnet_naming_style.pascal_case.required_suffix =
+dotnet_naming_style.pascal_case.word_separator =
+dotnet_naming_style.pascal_case.capitalization = pascal_case
diff --git a/CodeWalker.Benchmarks/Benchmarks.cs b/CodeWalker.Benchmarks/Benchmarks.cs
index acf4ff9..6aa2e6c 100644
--- a/CodeWalker.Benchmarks/Benchmarks.cs
+++ b/CodeWalker.Benchmarks/Benchmarks.cs
@@ -1,189 +1,199 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
+using BenchmarkDotNet.Diagnosers;
+using BenchmarkDotNet.Disassemblers;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using CodeWalker.Core.Utils;
using CodeWalker.GameFiles;
+using Collections.Pooled;
+using CommunityToolkit.HighPerformance;
+using SharpDX;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
using System.Linq;
+using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
+using System.Runtime.Intrinsics;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Xml;
using System.Xml.Linq;
+using static System.Net.Mime.MediaTypeNames;
namespace CodeWalker.Benchmarks
{
+ //[InProcess]
+ [ShortRunJob]
[MemoryDiagnoser]
public class Benchmarks
{
- public const string markup = @"
- vehshare
-
-
- -
- brabusgt600brabusgt600
- brabusgt600
- GT 600
- BRABUS
- null
- null
- null
- null
-
- null
- ta176m177
- LAYOUT_LOW
- BULLET_COVER_OFFSET_INFO
- EXPLOSION_INFO_DEFAULT
-
- DEFAULT_FOLLOW_VEHICLE_CAMERA
- MID_BOX_VEHICLE_AIM_CAMERA
- VEHICLE_BONNET_CAMERA_NEAR_EXTRA_HIGH
- DEFAULT_POV_CAMERA
-
-
-
-
-
-
-
-
-
-
-
-
-
- VFXVEHICLEINFO_CAR_BULLET
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 60.000000
- 80.000000
- 100.000000
- 120.000000
- 500.000000
- 500.000000
-
-
-
-
-
-
-
-
-
-
- SWANKNESS_3
-
- FLAG_SPORTS FLAG_RICH_CAR FLAG_NO_BROKEN_DOWN_SCENARIO FLAG_RECESSED_TAILLIGHT_CORONAS FLAG_NO_HEAVY_BRAKE_ANIMATION
- VEHICLE_TYPE_CAR
- VPT_FRONT_AND_BACK_PLATES
- VDT_BANSHEE
- VC_SPORT
- VWT_HIEND
-
-
- docktrailer
- - trailers
- - trailers2
- - trailers3
- - trailers4
- - tanker
- - trailerlogs
- - tr2
- - trflat
-
-
-
- -
- S_M_Y_Cop_01
-
-
-
-
-
-
-
-
-
-
-
- - WHEEL_FRONT_RIGHT_CAMERA
- - WHEEL_FRONT_LEFT_CAMERA
- - WHEEL_REAR_RIGHT_CAMERA
- - WHEEL_REAR_LEFT_CAMERA
-
-
-
-
-
-
-
-
-
-
- - LOW_BULLET_FRONT_LEFT
- - LOW_BULLET_FRONT_RIGHT
-
-
-
+ //private class Config : ManualConfig
+ //{
+ // public Config()
+ // {
+ // AddDiagnoser(new MemoryDiagnoser(new MemoryDiagnoserConfig(true)));
+ // AddDiagnoser(new DisassemblyDiagnoser(new DisassemblyDiagnoserConfig()));
+
+
+ // }
+ //}
+ private static string markup = "\r\n ";
+ private List listClass;
+ private List listStruct;
+ private PooledList pooledListClass;
+ private PooledList pooledListStruct;
+
+ public class SimpleType
+ {
+ public int Value1;
+ }
+
+ public class SimpleType2 : SimpleType
+ {
+ public int Value2;
+ }
+
+ public class SimpleType3
+ {
+ public long Value1;
+ public long Value2;
+ public long Value3;
+
+ public SimpleType3()
+ {
+ Value1 = random.Next();
+ Value2 = random.Next();
+ Value3 = random.Next();
+ }
+ }
+
+ private SimpleType[] intArr;
+ private List intList;
+ private static Random random = new Random(42);
+ public struct BigStruct
+ {
+ public long Value1;
+ public long Value2;
+ public long Value3;
+ public long Value4;
+ public long Value5;
+ public long Value6;
+ public long Value7;
+ public long Value8;
+ public BigStruct()
+ {
+ Value1 = random.Next();
+ Value2 = random.Next();
+ Value3 = random.Next();
+ Value4 = random.Next();
+ Value5 = random.Next();
+ Value6 = random.Next();
+ Value7 = random.Next();
+ Value8 = random.Next();
+ }
+ public BigStruct(long value1, long value2, long value3, long value4, long value5, long value6, long value7, long value8)
+ {
+ Value1 = value1;
+ Value2 = value2;
+ Value3 = value3;
+ Value4 = value4;
+ Value5 = value5;
+ Value6 = value6;
+ Value7 = value7;
+ Value8 = value8;
+ }
+ public static BigStruct operator +(in BigStruct left, in BigStruct right)
+ {
+ return new BigStruct(
+ left.Value1 + right.Value1,
+ left.Value2 + right.Value2,
+ left.Value3 + right.Value3,
+ left.Value4 + right.Value4,
+ left.Value5 + right.Value5,
+ left.Value6 + right.Value6,
+ left.Value7 + right.Value7,
+ left.Value8 + right.Value8
+ );
+ }
+ }
+ [Params(10, 100, 1000)]
+ public int Length { get; set; } = 10000;
+ [Params(100)]
+ public int Chance { get; set; } = 25;
+ public ArrayOfChars64 chars64;
+ private BigStruct[] vectors = new BigStruct[0];
+ private BigStruct vector;
-
-
- -
- vehicles_banshee_interior
- brabusgt600
-
+ private byte valueByte;
+ private uint valueUint;
+ private uint[] data;
+ private MetaName[] Values;
-
-
-";
+ private int randomValue;
- private byte[] data;
- private RpfFileEntry fileEntry;
+ private uint[] ushorts = new uint[0];
+
+ private string Str = "iakslgbhfibnrihbderpiugaehigoI BIHGVUIVDSOUFVBOUADGBOIUYfgiuywetrg872q13rh9872`134tgyihsbaopuJGUIYODGBFIOUFgvbouailksdbhnfp";
[GlobalSetup]
public void Setup()
{
- data = new byte[2048];
- var random = new Random(42);
- for (int i = 0; i < data.Length; i++)
+ random = new Random(42);
+
+ valueByte = 0;
+ valueUint = 0;
+
+ ushorts = new uint[Length];
+
+ for (int i = 0; i < Length; i++)
{
- data[i] = (byte)random.Next(byte.MinValue, byte.MaxValue);
+ ushorts[i] = (uint)random.Next(0, int.MaxValue);
}
- GTA5Keys.LoadFromPath("C:\\Program Files\\Rockstar Games\\Grand Theft Auto V", "");
+
+ var hashes = MemoryMarshal.Cast(ushorts);
+
+ for (int i = 0; i < Length; i++)
+ {
+ Console.WriteLine($"{ushorts[i]} -> {hashes[i]}");
+ }
+
+ //Console.WriteLine("Setup done");
+
+ //XElement? result = null;
+ //var _doc = new XmlDocument();
+ //_doc.LoadXml(markup);
+
+ //var doc = XDocument.Load(new XmlNodeReader(_doc));
+ //Console.WriteLine(doc.Root);
+
+ //data = new byte[2048];
+ //var random = new Random(42);
+ //for (int i = 0; i < data.Length; i++)
+ //{
+ // data[i] = (byte)random.Next(byte.MinValue, byte.MaxValue);
+ //}
+ //GTA5Keys.LoadFromPath("C:\\Program Files\\Rockstar Games\\Grand Theft Auto V", "");
+
+ //rotation = new Quaternion(random.NextFloat(-1.0f, 1.0f), random.NextFloat(-1.0f, 1.0f), random.NextFloat(-1.0f, 1.0f), random.NextFloat(-1.0f, 1.0f));
+ //translation = new Vector3(random.NextFloat(-1.0f, 1.0f), random.NextFloat(-1.0f, 1.0f), random.NextFloat(-1.0f, 1.0f));
+ //scale = random.NextFloat(-1.0f, 1.0f);
+ //matrix = Matrix.AffineTransformation(scale, rotation, translation);
}
//[Benchmark(Baseline = true)]
@@ -200,16 +210,155 @@ namespace CodeWalker.Benchmarks
// vehiclesFile.Load(data, fileEntry);
//}
- [Benchmark]
- public void DecryptNGSpan()
+ //[Benchmark(Baseline = true)]
+ //public uint SwapBytes()
+ //{
+ // var result = test;
+ // for (int i = 0; i < 1000; i++)
+ // {
+ // result = MetaTypes.SwapBytes(result);
+ // }
+ // return result;
+ //}
+
+ //[Benchmark]
+ //public uint ReverseEndianness()
+ //{
+ // var result = test;
+ // for (int i = 0; i < 1000; i++)
+ // {
+ // result = BinaryPrimitives.ReverseEndianness(result);
+ // }
+
+ // return result;
+ //}
+
+ //[Benchmark]
+ //public int IndexOf()
+ //{
+ // return Str.IndexOf('\0');
+ //}
+
+ //[Benchmark]
+ //public int IndexOfAsSpan()
+ //{
+ // return Str.AsSpan().IndexOf('\0');
+ //}
+
+ private PooledList getPooledListClass()
{
- GTACrypto.DecryptNG(data.AsSpan(), "kaas", 2048);
+ var list = new PooledList();
+ for (int i = 0; i < Length; i++)
+ {
+ list.Add(new SimpleType3());
+ }
+
+ return list;
+ }
+
+ private PooledList getPooledListStruct()
+ {
+ var list = new PooledList();
+ for (int i = 0; i < Length; i++)
+ {
+ list.Add(new BigStruct());
+ }
+
+ return list;
+ }
+
+ private List getListClass()
+ {
+ var list = new List();
+ for (int i = 0; i < Length; i++)
+ {
+ list.Add(new SimpleType3());
+ }
+
+ return list;
+ }
+
+ private List getListStruct()
+ {
+ var list = new List();
+ for (int i = 0; i < Length; i++)
+ {
+ list.Add(new BigStruct());
+ }
+
+ return list;
+ }
+
+ [MethodImpl(MethodImplOptions.NoInlining)]
+ private void inVectorOperator()
+ {
+ var vect = Vector256.Create(data.AsSpan());
+ var shiftVect = Vector256.Create(10);
+ var leftShiftVect = Vector256.Create(6);
+
+
+ }
+
+ private uint joaatLower(Span span)
+ {
+ uint h = 0;
+ for (int i = 0; i < span.Length; i++)
+ {
+ h += toLower(span[i]);
+ h += h << 10;
+ h ^= h >> 6;
+ }
+
+ return h;
+ }
+
+ private uint joaat(Span span)
+ {
+ uint h = 0;
+ for (int i = 0; i < span.Length; i++)
+ {
+ h += span[i];
+ h += h << 10;
+ h ^= h >> 6;
+ }
+
+ return h;
+ }
+
+ private void toLowerVectorized(Span span)
+ {
+ Ascii.ToLowerInPlace(span, out _);
+ }
+
+ private char toLower(char c)
+ {
+ return ('A' <= c && c <= 'Z') ? (char)(c | 0x20) : c;
+ }
+
+ private void toLowerPleb(Span span)
+ {
+ for (int i = 0; i < span.Length; i++)
+ {
+ span[i] = toLower(span[i]);
+ }
+ }
+
+
+
+ [Benchmark]
+ public void ReverseEndianness()
+ {
+ //BinaryPrimitives.ReverseEndianness(MemoryMarshal.Cast(ushorts), MemoryMarshal.Cast(ushorts));
}
[Benchmark]
- public void DecryptNG()
+ public void SwapBytes()
{
- GTACrypto.DecryptNG(data, "kaas", 2048);
+ var _ushorts = ushorts;
+ for (int i = 0; i < _ushorts.Length; i++)
+ {
+ _ushorts[i] = MetaTypes.SwapBytes(_ushorts[i]);
+ }
}
}
}
diff --git a/CodeWalker.Benchmarks/CodeWalker.Benchmarks.csproj b/CodeWalker.Benchmarks/CodeWalker.Benchmarks.csproj
index 69ad967..abffe71 100644
--- a/CodeWalker.Benchmarks/CodeWalker.Benchmarks.csproj
+++ b/CodeWalker.Benchmarks/CodeWalker.Benchmarks.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Exe
false
CodeWalker.Benchmarks
@@ -8,8 +8,12 @@
Copyright © 2023
1.0.0.0
1.0.0.0
- latest
- true
+ latest
+ true
+ enable
+ AnyCPU
+ pdbonly
+ true
@@ -19,37 +23,37 @@
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/CodeWalker.Benchmarks/Program.cs b/CodeWalker.Benchmarks/Program.cs
index 4966c50..1267ce1 100644
--- a/CodeWalker.Benchmarks/Program.cs
+++ b/CodeWalker.Benchmarks/Program.cs
@@ -16,6 +16,10 @@ namespace CodeWalker.Benchmarks
static void Main(string[] args)
{
+#if DEBUG
+ var benchmarks = new Benchmarks();
+ benchmarks.Setup();
+
//var benchmarks = new Benchmarks();
//benchmarks.Setup();
@@ -28,8 +32,9 @@ namespace CodeWalker.Benchmarks
//benchmarks.GlobalCleanup();
//ParseBuffer();
-
+#else
BenchmarkRunner.Run();
+#endif
}
}
}
diff --git a/CodeWalker.Core/CodeWalker.Core.csproj b/CodeWalker.Core/CodeWalker.Core.csproj
index b5b3626..83a03f1 100644
--- a/CodeWalker.Core/CodeWalker.Core.csproj
+++ b/CodeWalker.Core/CodeWalker.Core.csproj
@@ -1,22 +1,28 @@
- net6.0
+ net8.0
latest
true
- annotations
+ enable
+
+
+
-
+
-
- all
- runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
+ all
+ runtime; build; native; contentfiles; analyzers
+
+
diff --git a/CodeWalker.Core/GameFiles/FileTypes/AwcFile.cs b/CodeWalker.Core/GameFiles/FileTypes/AwcFile.cs
index 0ed6b34..58db58a 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/AwcFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/AwcFile.cs
@@ -8,6 +8,7 @@ using TC = System.ComponentModel.TypeConverterAttribute;
using EXP = System.ComponentModel.ExpandableObjectConverter;
using System.Xml;
using System.Runtime.InteropServices;
+using CodeWalker.Core.Utils;
namespace CodeWalker.GameFiles
{
@@ -345,7 +346,8 @@ namespace CodeWalker.GameFiles
}
public static void WriteXmlNode(AwcFile f, StringBuilder sb, int indent, string wavfolder, string name = "AudioWaveContainer")
{
- if (f == null) return;
+ if (f == null)
+ return;
AwcXml.OpenTag(sb, indent, name);
f.WriteXml(sb, indent + 1, wavfolder);
AwcXml.CloseTag(sb, indent, name);
@@ -1014,7 +1016,7 @@ namespace CodeWalker.GameFiles
{
var export = !string.IsNullOrEmpty(wavfolder);
var fname = Name?.Replace("/", "")?.Replace("\\", "") ?? "0x0";
- byte[] fdata = null;
+ byte[] fdata;
if (MidiChunk != null)
{
fname += ".midi";
@@ -1038,8 +1040,10 @@ namespace CodeWalker.GameFiles
File.WriteAllBytes(filepath, fdata);
}
}
- catch
- { }
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
}
if (StreamFormat != null)
{
@@ -1107,8 +1111,10 @@ namespace CodeWalker.GameFiles
}
}
}
- catch
- { }
+ catch(Exception ex)
+ {
+ Console.WriteLine(ex);
+ }
}
@@ -1363,7 +1369,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- var hash = "0x" + (StreamInfo?.Id.ToString("X") ?? "0").PadLeft(8, '0') + ": ";
+ var hash = "0x" + (StreamInfo?.Id.ToString("X8") ?? "0000000") + ": ";
if (FormatChunk != null)
{
return hash + FormatChunk?.ToString() ?? "AwcAudio";
@@ -1876,7 +1882,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Id.ToString() + ", " + Codec.ToString() + ": " + Samples.ToString() + " samples, " + SamplesPerSecond.ToString() + " samples/sec, headroom: " + Headroom.ToString();
+ return $"{Id}, {Codec}: {Samples} samples, {SamplesPerSecond} samples/sec, headroom: {Headroom}";
}
}
@@ -1905,7 +1911,7 @@ namespace CodeWalker.GameFiles
resentry.SystemFlags = BitConverter.ToUInt32(data, 8);
resentry.GraphicsFlags = BitConverter.ToUInt32(data, 12);
- if (rsc7 != 0x37435352)
+ if (rsc7 != (uint)FileHeader.RSC7)
{ } //testing..
if (version != 46) //46 is Clip Dictionary...
{ }
@@ -2163,7 +2169,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return "gesture: " + (Gestures?.Length ?? 0).ToString() + " items";
+ return $"gesture: {Gestures?.Length ?? 0} items";
}
}
@@ -2198,32 +2204,26 @@ namespace CodeWalker.GameFiles
public void WriteLine(StringBuilder sb)
{
sb.Append(UnkUint1.ToString());
- sb.Append(" ");
+ sb.Append(' ');
sb.Append(FloatUtil.ToString(UnkFloat1));
- sb.Append(" ");
+ sb.Append(' ');
sb.Append(UnkUshort1.ToString());
- sb.Append(" ");
+ sb.Append(' ');
sb.Append(UnkUshort2.ToString());
sb.AppendLine();
}
public void ReadLine(string s)
{
- var split = s.Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
- var list = new List();
- foreach (var str in split)
+ Span ranges = stackalloc Range[5];
+ var span = s.AsSpan();
+ span.Split(ranges, ' ', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
+
+ if (ranges.Length >= 4)
{
- var tstr = str.Trim();
- if (!string.IsNullOrEmpty(tstr))
- {
- list.Add(tstr);
- }
- }
- if (list.Count >= 4)
- {
- uint.TryParse(list[0], out uint u1);
- FloatUtil.TryParse(list[1], out float f1);
- ushort.TryParse(list[2], out ushort s1);
- ushort.TryParse(list[3], out ushort s2);
+ uint.TryParse(span[ranges[0]], out uint u1);
+ FloatUtil.TryParse(span[ranges[1]], out float f1);
+ ushort.TryParse(span[ranges[2]], out ushort s1);
+ ushort.TryParse(span[ranges[3]], out ushort s2);
UnkUint1 = u1;
UnkFloat1 = f1;
UnkUshort1 = s1;
@@ -2247,7 +2247,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return UnkUint1.ToString() + ", " + UnkFloat1.ToString() + ", " + UnkUshort1.ToString() + ", " + UnkUshort2.ToString();
+ return $"{UnkUint1}, {UnkFloat1}, {UnkUshort1}, {UnkUshort2}";
}
}
@@ -2326,7 +2326,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return "granulargrains: " + (GranularGrains?.Length ?? 0).ToString() + " items";
+ return $"granulargrains: {(GranularGrains?.Length ?? 0)} items";
}
}
@@ -2410,7 +2410,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Identifier.ToString() + ": " + UnkUint1.ToString() + ": " + GrainCount.ToString() + " items";
+ return $"{Identifier}: {UnkUint1}: {GrainCount} items";
}
}
@@ -2456,7 +2456,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return "granularloops: " + (GranularLoops?.Length ?? 0).ToString() + " items";
+ return $"granularloops: {GranularLoops?.Length ?? 0} items";
}
}
@@ -2576,7 +2576,7 @@ namespace CodeWalker.GameFiles
break;
}
- return Name.ToString() + ": " + valstr + ", " + SampleOffset.ToString() + ", " + Unused.ToString();
+ return $"{Name}: {valstr}, {SampleOffset}, {Unused}";
}
}
@@ -3029,15 +3029,22 @@ namespace CodeWalker.GameFiles
public static string GetXml(AwcFile awc, string outputFolder = "")
{
- StringBuilder sb = new StringBuilder();
- sb.AppendLine(XmlHeader);
-
- if (awc != null)
+ StringBuilder sb = StringBuilderPool.Get();
+ try
{
- AwcFile.WriteXmlNode(awc, sb, 0, outputFolder);
- }
+ sb.AppendLine(XmlHeader);
- return sb.ToString();
+ if (awc != null)
+ {
+ AwcFile.WriteXmlNode(awc, sb, 0, outputFolder);
+ }
+
+ return sb.ToString();
+ }
+ finally
+ {
+ StringBuilderPool.Return(sb);
+ }
}
}
diff --git a/CodeWalker.Core/GameFiles/FileTypes/Builders/YnvBuilder.cs b/CodeWalker.Core/GameFiles/FileTypes/Builders/YnvBuilder.cs
index 37c97ec..0363214 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/Builders/YnvBuilder.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/Builders/YnvBuilder.cs
@@ -109,10 +109,10 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
foreach (var poly in polys) //split along borders
{
var verts = poly.Vertices;
- if (verts == null)
- { continue; }//ignore empty polys..
+ if (verts is null)
+ continue;//ignore empty polys..
if (verts.Length < 3)
- { continue; }//not enough verts for a triangle!
+ continue;//not enough verts for a triangle!
Vector2I gprev = NavGrid.GetCellPos(verts[0]);
int split1 = 0;
@@ -156,13 +156,18 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
verts1.Clear();
verts2.Clear();
- for (int i = 0; i < split1; i++) verts1.Add(verts[i]);
+ for (int i = 0; i < split1; i++)
+ verts1.Add(verts[i]);
+
verts1.Add(sp1);
verts1.Add(sp2);
- for (int i = split2end; i < verts.Length; i++) verts1.Add(verts[i]);
+
+ for (int i = split2end; i < verts.Length; i++)
+ verts1.Add(verts[i]);
verts2.Add(sp1);
- for (int i = split1; i < split2end; i++) verts2.Add(verts[i]);
+ for (int i = split1; i < split2end; i++)
+ verts2.Add(verts[i]);
verts2.Add(sp2);
poly1.Vertices = verts1.ToArray();
@@ -203,9 +208,9 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
var verts = poly.Vertices;
var ec = edges?.Length ?? 0;
if (ec <= 0)
- { continue; }//shouldn't happen - no edges?
+ continue;//shouldn't happen - no edges?
if (ec != poly.Vertices?.Length)
- { continue; }//shouldn't happen
+ continue;//shouldn't happen
var split1beg = polysplit.Split1 - 1;
var split1end = polysplit.Split1;
@@ -256,22 +261,22 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
foreach (var poly in newpolys) //fix any untouched edges that joined to split polys
{
- if (poly.Edges?.Length != poly.Vertices?.Length)
- { continue; }//shouldn't happen (no edges?)
+ if (poly.Edges is null || poly.Vertices is null || poly.Edges.Length != poly.Vertices.Length)
+ continue;//shouldn't happen (no edges?)
+
for (int i = 0; i < poly.Edges.Length; i++)
{
var edge = poly.Edges[i];
var vert = poly.Vertices[i];
if (edge == null)
- { continue; }//shouldn't happen
+ continue;//shouldn't happen
if (edge.Poly1 != edge.Poly2)
- { continue; }//shouldn't happen?
+ continue;//shouldn't happen?
if (edge.Poly1 == null)
- { continue; }//probably this edge joins to nothing
+ continue;//probably this edge joins to nothing
- YnvPolySplit polysplit;
- if (polysplits.TryGetValue(edge.Poly1, out polysplit))
+ if (polysplits.TryGetValue(edge.Poly1, out var polysplit))
{
var newpoly = polysplit.GetNearest(vert);
if (newpoly == null)
@@ -287,7 +292,7 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
return newpolys;
}
- private Vector3 GetSplitPos(Vector3 a, Vector3 b, bool xaxis)
+ private Vector3 GetSplitPos(in Vector3 a, in Vector3 b, bool xaxis)
{
Vector3 ca = NavGrid.GetCellRel(a);
Vector3 cb = NavGrid.GetCellRel(b);
@@ -311,19 +316,19 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
return a + (b - a) * Math.Min(Math.Max(f, 0.0f), 1.0f);
}
- private bool IsValidSplit(Vector3 s1, Vector3 s2, Vector3 v1a, Vector3 v1b, Vector3 v2a, Vector3 v2b)
+ private bool IsValidSplit(in Vector3 s1, in Vector3 s2, in Vector3 v1a, in Vector3 v1b, in Vector3 v2a, in Vector3 v2b)
{
- if (XYEqual(s1, s2)) return false;
- if (XYEqual(s1, v1a)) return false;
- if (XYEqual(s1, v1b)) return false;
- if (XYEqual(s2, v2a)) return false;
- if (XYEqual(s2, v2b)) return false;
+ if (XYEqual(in s1, in s2)) return false;
+ if (XYEqual(in s1, in v1a)) return false;
+ if (XYEqual(in s1, in v1b)) return false;
+ if (XYEqual(in s2, in v2a)) return false;
+ if (XYEqual(in s2, in v2b)) return false;
return true;
}
- private bool XYEqual(Vector3 v1, Vector3 v2)
+ private bool XYEqual(in Vector3 v1, in Vector3 v2)
{
- return ((v1.X == v2.X) && (v1.Y == v2.Y));
+ return v1.X == v2.X && v1.Y == v2.Y;
}
private class YnvPolySplit
@@ -335,8 +340,8 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
public int Split2;
public YnvPoly GetNearest(Vector3 v)
{
- if (New1?.Vertices == null) return New2;
- if (New2?.Vertices == null) return New1;
+ if (New1?.Vertices is null) return New2;
+ if (New2?.Vertices is null) return New1;
float len1 = float.MaxValue;
float len2 = float.MaxValue;
for (int i = 0; i < New1.Vertices.Length; i++)
@@ -357,11 +362,11 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
return New1;
}
}
- private YnvPolySplit TryGetSplit(Dictionary polysplits, YnvPoly poly)
+ private YnvPolySplit? TryGetSplit(Dictionary polysplits, YnvPoly poly)
{
- if (poly == null) return null;
- YnvPolySplit r = null;
- polysplits.TryGetValue(poly, out r);
+ if (poly == null)
+ return null;
+ _ = polysplits.TryGetValue(poly, out var r);
return r;
}
@@ -379,7 +384,7 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
if (ynv == null)
{
ynv = new YnvFile();
- ynv.Name = "navmesh[" + cell.FileX.ToString() + "][" + cell.FileY.ToString() + "]";
+ ynv.Name = $"navmesh[{cell.FileX}][{cell.FileY}]";
ynv.Nav = new NavMesh();
ynv.Nav.SetDefaults(false);
ynv.Nav.AABBSize = new Vector3(NavGrid.CellSize, NavGrid.CellSize, 0.0f);
@@ -411,14 +416,13 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
foreach (var poly in polys)
{
poly.CalculatePosition();
- var pos = poly.Position;
var verts = poly.Vertices;
- if (verts != null)
+ if (verts is not null)
{
- foreach (var vert in verts)
+ foreach (ref var vert in verts.AsSpan())
{
- bbmin = Vector3.Min(bbmin, vert);
- bbmax = Vector3.Max(bbmax, vert);
+ Vector3.Min(ref bbmin, ref vert, out bbmin);
+ Vector3.Max(ref bbmax, ref vert, out bbmax);
}
}
}
@@ -460,7 +464,9 @@ namespace CodeWalker.Core.GameFiles.FileTypes.Builders
float zmax = float.MinValue;
foreach (var poly in ynv.Polys)
{
- foreach (var vert in poly.Vertices)
+ if (poly.Vertices is null)
+ continue;
+ foreach (ref var vert in poly.Vertices.AsSpan())
{
zmin = Math.Min(zmin, vert.Z);
zmax = Math.Max(zmax, vert.Z);
diff --git a/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs
index 7ff9866..7b78075 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CacheDatFile.cs
@@ -1,4 +1,5 @@
-using SharpDX;
+using Collections.Pooled;
+using SharpDX;
using System;
using System.Collections.Generic;
using System.ComponentModel;
@@ -28,6 +29,7 @@ namespace CodeWalker.GameFiles
public CInteriorProxy[] AllCInteriorProxies { get; set; }
public BoundsStoreItem[] AllBoundsStoreItems { get; set; }
+ [SkipLocalsInit]
public void Load(byte[] data, RpfFileEntry entry)
{
FileEntry = entry;
@@ -36,6 +38,7 @@ namespace CodeWalker.GameFiles
using BinaryReader br = new BinaryReader(ms);
Span charArr = stackalloc char[100];
+
var length = 0;
for (int i = 0; (i < 100) && (i < data.Length); i++)
{
@@ -56,10 +59,10 @@ namespace CodeWalker.GameFiles
uint structcount = 0;
uint modlen;
bool indates = false;
- var dates = new List();
- var allMapNodes = new List();
- var allCInteriorProxies = new List();
- var allBoundsStoreItems = new List();
+ using var dates = new PooledList();
+ using var allMapNodes = new PooledList();
+ using var allCInteriorProxies = new PooledList();
+ using var allBoundsStoreItems = new PooledList();
for (int i = 100; i < data.Length; i++)
{
byte b = data[i];
@@ -68,7 +71,6 @@ namespace CodeWalker.GameFiles
if (b == 0xA)
{
lastn = i;
- string line = new string(charArr.Slice(0, length));
switch (charArr.Slice(0, length))
{
case "":
@@ -125,6 +127,7 @@ namespace CodeWalker.GameFiles
{ } //just testing
else
{
+ string line = new string(charArr.Slice(0, length));
dates.Add(new CacheFileDate(line));//eg: 2740459947 (hash of: platform:/data/cdimages/scaleform_frontend.rpf) 130680580712018938 8944
}
break;
@@ -204,7 +207,6 @@ namespace CodeWalker.GameFiles
mapnode.InteriorProxyListToArray();
}
-
br.Dispose();
ms.Dispose();
@@ -407,7 +409,7 @@ namespace CodeWalker.GameFiles
public string ToCacheFileString()
{
- return FileName.Hash.ToString() + " " + TimeStamp.ToFileTimeUtc().ToString() + " " + FileID.ToString();
+ return $"{FileName.Hash} {TimeStamp.ToFileTimeUtc()} {FileID}";
}
public void WriteXml(StringBuilder sb, int indent)
@@ -425,7 +427,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return FileName.ToString() + ", " + TimeStamp.ToString() + ", " + FileID.ToString();
+ return $"{FileName}, {TimeStamp}, {FileID}";
}
}
@@ -478,10 +480,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Name.ToString() + ", " +
- Min.ToString() + ", " +
- Max.ToString() + ", " +
- Layer.ToString();
+ return $"{Name}, {Min}, {Max}, {Layer}";
}
}
@@ -775,19 +774,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Unk01.ToString() + ", " +
- Unk02.ToString() + ", " +
- Unk03.ToString() + ", " +
- Name.ToString() + ", " +
- Parent.ToString() + ", " +
- Position.ToString() + ", " +
- Orientation.ToString() + ", " +
- BBMin.ToString() + ", " +
- BBMax.ToString() + ", " +
- Unk11.ToString() + ", " +
- Unk12.ToString() + ", " +
- Unk13.ToString() + ", " +
- Unk14.ToString();
+ return $"{Unk01}, {Unk02}, {Unk03}, {Name}, {Parent}, {Position}, {Orientation}, {BBMin}, {BBMax}, {Unk11}, {Unk12}, {Unk13}, {Unk14}";
}
}
@@ -796,10 +783,10 @@ namespace CodeWalker.GameFiles
public MetaHash Name { get; set; }
public MetaHash ParentName { get; set; }
public uint ContentFlags { get; set; }
- public Vector3 streamingExtentsMin { get; set; }
- public Vector3 streamingExtentsMax { get; set; }
- public Vector3 entitiesExtentsMin { get; set; }
- public Vector3 entitiesExtentsMax { get; set; }
+ public Vector3 streamingExtentsMin;
+ public Vector3 streamingExtentsMax;
+ public Vector3 entitiesExtentsMin;
+ public Vector3 entitiesExtentsMax;
public byte Unk1 { get; set; }
public byte Unk2 { get; set; }
public byte Unk3 { get; set; }
@@ -912,15 +899,12 @@ namespace CodeWalker.GameFiles
public void AddChildToList(MapDataStoreNode child)
{
- if (ChildrenList == null)
- {
- ChildrenList = new List();
- }
+ ChildrenList ??= new List();
ChildrenList.Add(child);
}
public void ChildrenListToArray()
{
- if (ChildrenList != null)
+ if (ChildrenList is not null)
{
Children = ChildrenList.ToArray();
ChildrenList = null; //plz get this GC
@@ -928,15 +912,12 @@ namespace CodeWalker.GameFiles
}
public void AddInteriorToList(CInteriorProxy iprx)
{
- if (InteriorProxyList == null)
- {
- InteriorProxyList = new List();
- }
+ InteriorProxyList ??= new List();
InteriorProxyList.Add(iprx);
}
public void InteriorProxyListToArray()
{
- if (InteriorProxyList != null)
+ if (InteriorProxyList is not null)
{
InteriorProxies = InteriorProxyList.ToArray();
InteriorProxyList = null; //plz get this GC
@@ -945,13 +926,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Name.ToString() + ", " +
- ParentName.ToString() + ", " +
- ContentFlags.ToString() + ", " +
- streamingExtentsMin.ToString() + ", " +
- streamingExtentsMax.ToString() + ", " +
- entitiesExtentsMin.ToString() + ", " +
- entitiesExtentsMax.ToString();// + ", " +
+ return $"{Name}, {ParentName}, {ContentFlags}, {streamingExtentsMin}, {streamingExtentsMax}, {entitiesExtentsMin}, {entitiesExtentsMax}";// + ", " +
}
}
@@ -972,16 +947,24 @@ namespace CodeWalker.GameFiles
{
get
{
- StringBuilder sb = new StringBuilder();
- if (Unk02 != null)
+ if (Unk02 is null)
+ return string.Empty;
+
+ StringBuilder sb = MetaXmlBase.StringBuilderPool.Get();
+ try
{
- for (int i = 0; i < Unk02.Length; i++)
+ foreach (var b in Unk02)
{
- if (Unk02[i] == 0) break;
- sb.Append((char)Unk02[i]);
+ if (b == 0)
+ break;
+ sb.Append((char)b);
}
+ return sb.ToString();
+ }
+ finally
+ {
+ MetaXmlBase.StringBuilderPool.Return(sb);
}
- return sb.ToString();
}
}
@@ -1027,7 +1010,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Unk01.ToString() + ", " + Unk02str;
+ return $"{Unk01}, {Unk02str}";
}
}
@@ -1038,21 +1021,28 @@ namespace CodeWalker.GameFiles
public static string GetXml(CacheDatFile cdf)
{
- StringBuilder sb = new StringBuilder();
- sb.AppendLine(XmlHeader);
-
- if (cdf != null)
+ StringBuilder sb = StringBuilderPool.Get();
+ try
{
- var name = "CacheFile";
+ sb.AppendLine(XmlHeader);
- OpenTag(sb, 0, name);
+ if (cdf != null)
+ {
+ var name = "CacheFile";
- cdf.WriteXml(sb, 1);
+ OpenTag(sb, 0, name);
- CloseTag(sb, 0, name);
+ cdf.WriteXml(sb, 1);
+
+ CloseTag(sb, 0, name);
+ }
+
+ return sb.ToString();
+ }
+ finally
+ {
+ StringBuilderPool.Return(sb);
}
-
- return sb.ToString();
}
diff --git a/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs
index 689ce78..654dee3 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CarColsFile.cs
@@ -35,8 +35,7 @@ namespace CodeWalker.GameFiles
//can be PSO .ymt or XML .meta
- MemoryStream ms = new MemoryStream(data);
- if (PsoFile.IsPSO(ms))
+ if (PsoFile.IsPSO(data.AsSpan(0, 4)))
{
Pso = new PsoFile();
Pso.Load(data);
@@ -59,8 +58,6 @@ namespace CodeWalker.GameFiles
var msg = ex.Message;
}
}
- else
- { }
if (xdoc.DocumentElement != null)
diff --git a/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs
index b092b39..6325e7b 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CarVariationsFile.cs
@@ -10,6 +10,7 @@ using System.Xml;
using TC = System.ComponentModel.TypeConverterAttribute;
using EXP = System.ComponentModel.ExpandableObjectConverter;
+using CodeWalker.Core.Utils;
namespace CodeWalker.GameFiles
{
@@ -78,12 +79,11 @@ namespace CodeWalker.GameFiles
public CVehicleModelInfoVariation(XmlNode node)
{
- XmlNode cnode;
- cnode = node.SelectSingleNode("variationData");
- if (cnode != null)
+ var variationNode = node.SelectSingleNode("variationData");
+ if (variationNode is not null)
{
- var items = cnode.SelectNodes("Item");
- if (items.Count > 0)
+ var items = variationNode.SelectNodes("Item");
+ if (items is not null && items.Count > 0)
{
variationData = new CVehicleModelInfoVariation_418053801[items.Count];
for (int i = 0; i < items.Count; i++)
@@ -107,12 +107,11 @@ namespace CodeWalker.GameFiles
public CVehicleModelInfoVariation_418053801(XmlNode node)
{
modelName = Xml.GetChildInnerText(node, "modelName");
- XmlNode cnode;
- cnode = node.SelectSingleNode("colors");
- if (cnode != null)
+ var colorsNode = node.SelectSingleNode("colors");
+ if (colorsNode is not null)
{
- var items = cnode.SelectNodes("Item");
- if (items.Count > 0)
+ var items = colorsNode.SelectNodes("Item");
+ if (items is not null && items.Count > 0)
{
colors = new CVehicleModelInfoVariation_2575850962[items.Count];
for (int i = 0; i < items.Count; i++)
@@ -121,11 +120,11 @@ namespace CodeWalker.GameFiles
}
}
}
- cnode = node.SelectSingleNode("kits");
- if (cnode != null)
+ var kitsNode = node.SelectSingleNode("kits");
+ if (kitsNode is not null)
{
- var items = cnode.SelectNodes("Item");
- if (items.Count > 0)
+ var items = kitsNode.SelectNodes("Item");
+ if (items is not null && items.Count > 0)
{
kits = new MetaHash[items.Count];
for (int i = 0; i < items.Count; i++)
@@ -134,11 +133,11 @@ namespace CodeWalker.GameFiles
}
}
}
- cnode = node.SelectSingleNode("windowsWithExposedEdges");
- if (cnode != null)
+ var windowsNodes = node.SelectSingleNode("windowsWithExposedEdges");
+ if (windowsNodes is not null)
{
- var items = cnode.SelectNodes("Item");
- if (items.Count > 0)
+ var items = windowsNodes.SelectNodes("Item");
+ if (items is not null && items.Count > 0)
{
windowsWithExposedEdges = new MetaHash[items.Count];
for (int i = 0; i < items.Count; i++)
@@ -147,10 +146,10 @@ namespace CodeWalker.GameFiles
}
}
}
- cnode = node.SelectSingleNode("plateProbabilities");
- if (cnode != null)
+ var plateProbabilitiesNode = node.SelectSingleNode("plateProbabilities");
+ if (plateProbabilitiesNode is not null)
{
- plateProbabilities = new PlateProbabilities(cnode);
+ plateProbabilities = new PlateProbabilities(plateProbabilitiesNode);
}
lightSettings = (byte)Xml.GetChildIntAttribute(node, "lightSettings", "value");
sirenSettings = (byte)Xml.GetChildIntAttribute(node, "sirenSettings", "value");
@@ -168,28 +167,25 @@ namespace CodeWalker.GameFiles
public CVehicleModelInfoVariation_2575850962(XmlNode node)
{
- XmlNode cnode;
- cnode = node.SelectSingleNode("indices");
- if (cnode != null)
+ var indicesNode = node.SelectSingleNode("indices");
+ if (indicesNode is not null)
{
- var astr = cnode.InnerText;
- var arrr = astr.Split(new[] { '\n', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
+ var astr = indicesNode.InnerText;
var alist = new List();
- foreach (var item in arrr)
+ foreach (var item in astr.EnumerateSplitAny(['\n', ' ', '\t']))
{
var titem = item.Trim();
- byte v;
- if (byte.TryParse(titem, out v))
+ if (byte.TryParse(titem, out var v))
{
alist.Add(v);
}
}
indices = alist.ToArray();
}
- cnode = node.SelectSingleNode("liveries");
- if (cnode != null)
+ var liveriesNode = node.SelectSingleNode("liveries");
+ if (liveriesNode is not null)
{
- var items = cnode.SelectNodes("Item");
+ var items = liveriesNode.SelectNodes("Item");
if (items.Count > 0)
{
liveries = new bool[items.Count];
@@ -200,14 +196,12 @@ namespace CodeWalker.GameFiles
}
else
{
- var astr = cnode.InnerText;
- var arrr = astr.Split(new[] { '\n', ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
+ var astr = liveriesNode.InnerText;
var alist = new List();
- foreach (var item in arrr)
+ foreach (var item in astr.EnumerateSplitAny(['\n', ' ', '\t']))
{
var titem = item.Trim();
- byte v;
- if (byte.TryParse(titem, out v))
+ if (byte.TryParse(titem, out var v))
{
alist.Add(v > 0);
}
@@ -254,7 +248,7 @@ namespace CodeWalker.GameFiles
public override string ToString()
{
- return Name.ToString() + ": " + Value.ToString();
+ return $"{Name}: {Value}";
}
}
diff --git a/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs b/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs
index 627c871..fbbc1ee 100644
--- a/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs
+++ b/CodeWalker.Core/GameFiles/FileTypes/CutFile.cs
@@ -9,6 +9,7 @@ using System.Xml;
using TC = System.ComponentModel.TypeConverterAttribute;
using EXP = System.ComponentModel.ExpandableObjectConverter;
+using Collections.Pooled;
namespace CodeWalker.GameFiles
{
@@ -33,12 +34,10 @@ namespace CodeWalker.GameFiles
{
FileEntry = entry;
- MemoryStream ms = new MemoryStream(data);
-
- if (PsoFile.IsPSO(ms))
+ if (PsoFile.IsPSO(data.AsSpan(0, 4)))
{
Pso = new PsoFile();
- Pso.Load(ms);
+ Pso.Load(data);
var xml = PsoXml.GetXml(Pso);
XmlDocument doc = new XmlDocument();
@@ -48,10 +47,6 @@ namespace CodeWalker.GameFiles
CutsceneFile2 = new CutsceneFile2();
CutsceneFile2.ReadXml(node);
- }
- else
- {
-
}
}
@@ -228,7 +223,7 @@ namespace CodeWalker.GameFiles
- public static CutBase ConstructObject(string type)
+ public static CutBase? ConstructObject(string type)
{
switch (type)
{
@@ -279,7 +274,7 @@ namespace CodeWalker.GameFiles
default: return null;
}
}
- public static T ReadObject(XmlNode node, string name) where T : IMetaXmlItem, new()
+ public static T? ReadObject(XmlNode node, string name) where T : IMetaXmlItem, new()
{
var onode = node.SelectSingleNode(name);
if (onode != null)
@@ -288,7 +283,7 @@ namespace CodeWalker.GameFiles
o.ReadXml(onode);
return o;
}
- return default(T);
+ return default;
}
public static object[] ReadObjectArray(XmlNode node, string name)
{
@@ -298,7 +293,7 @@ namespace CodeWalker.GameFiles
var inodes = aNode.SelectNodes("Item");
if (inodes?.Count > 0)
{
- var oList = new List