diff --git a/1.4/Assemblies/PerformanceFish.dll b/1.4/Assemblies/PerformanceFish.dll index 195b13e..a6ced95 100644 Binary files a/1.4/Assemblies/PerformanceFish.dll and b/1.4/Assemblies/PerformanceFish.dll differ diff --git a/1.4/Assemblies/PerformanceFish.pdb b/1.4/Assemblies/PerformanceFish.pdb index 7efb133..7ca2efb 100644 Binary files a/1.4/Assemblies/PerformanceFish.pdb and b/1.4/Assemblies/PerformanceFish.pdb differ diff --git a/1.5/Assemblies/PerformanceFish.dll b/1.5/Assemblies/PerformanceFish.dll index 52459c0..7619f59 100644 Binary files a/1.5/Assemblies/PerformanceFish.dll and b/1.5/Assemblies/PerformanceFish.dll differ diff --git a/1.5/Assemblies/PerformanceFish.pdb b/1.5/Assemblies/PerformanceFish.pdb index c1b3851..e3874ec 100644 Binary files a/1.5/Assemblies/PerformanceFish.pdb and b/1.5/Assemblies/PerformanceFish.pdb differ diff --git a/Source/PerformanceFish/Directory.Build.Props b/Source/PerformanceFish/Directory.Build.Props index c6c15c3..56e0845 100644 --- a/Source/PerformanceFish/Directory.Build.Props +++ b/Source/PerformanceFish/Directory.Build.Props @@ -4,7 +4,7 @@ PerformanceFish PerformanceFish bradson - 0.6.0.0 + 0.6.0.1 LICENSE net48 preview diff --git a/Source/PerformanceFish/ModCompatibility/ActiveMods.cs b/Source/PerformanceFish/ModCompatibility/ActiveMods.cs index e3e721b..33f138e 100644 --- a/Source/PerformanceFish/ModCompatibility/ActiveMods.cs +++ b/Source/PerformanceFish/ModCompatibility/ActiveMods.cs @@ -104,6 +104,8 @@ public static class ActiveMods { if (FisheryLib.FisheryLib.VERSION > FisheryLib.FisheryLib.CurrentlyLoadedVersion) ErrorForOutdatedModDependency(nameof(Fishery)); + else + CheckDependencyVersion(nameof(Fishery), typeof(FisheryLib.FisheryLib), "1Fishery"); } private static void CheckHarmonyVersion() @@ -112,16 +114,57 @@ public static class ActiveMods private static void CheckDependencyVersion(string dependencyName, Type dependencyType, string dependencyAssemblyName) { - if (typeof(PerformanceFishMod).Assembly.GetReferencedAssemblyVersion(dependencyAssemblyName) - > dependencyType.Assembly.GetLoadedVersion()) - { - ErrorForOutdatedModDependency(dependencyName); - } + var expectedVersion = typeof(PerformanceFishMod).Assembly.GetReferencedAssemblyVersion(dependencyAssemblyName); + var loadedAssembly = dependencyType.Assembly; + if (expectedVersion > loadedAssembly.GetLoadedVersion()) + LogForOutdatedModDependency(dependencyName, expectedVersion, loadedAssembly); } private static void ErrorForIncorrectLoadOrder(string dependencyName) => Log.Error($"Incorrect load order detected. {dependencyName} must be loaded before any mod depending on it."); + private static void LogForOutdatedModDependency(string modName, Version expected, Assembly loaded) + { + var loadedVersion = loaded.GetLoadedVersion(); + var modMessage = $"Outdated {modName} mod detected. Expected {expected}, loaded is { + loadedVersion} from path \"{TryGetAssemblyLocation(loaded)}\". {modName} "; + var beUpdated = " be updated for Performance Fish to work correctly"; + + if (loadedVersion.Major >= expected.Major && loadedVersion.Minor >= expected.Minor) + Log.Warning($"{modMessage}may need to{beUpdated}"); + else + Log.Error($"{modMessage}must{beUpdated}"); + } + + private static string TryGetAssemblyLocation(Assembly assembly) + { + var location = assembly.Location; + if (!location.NullOrEmpty()) + return location; + + var assemblyName = assembly.GetName().Name; + var firstFoundAssemblyDir = default(string); + var allMods = LoadedModManager.RunningModsListForReading; + var count = allMods.Count; + for (var i = 0; i < count; i++) + { + var mod = allMods[i]; + if (mod.TryGetAssembly(assemblyName) is not { } foundAssembly) + continue; + + if (foundAssembly == assembly) + return mod.RootDir; + + if (firstFoundAssemblyDir != null) + continue; + + var foundAssemblyLocation = foundAssembly.Location; + firstFoundAssemblyDir = !foundAssemblyLocation.NullOrEmpty() ? foundAssemblyLocation : mod.RootDir; + } + + return firstFoundAssemblyDir ?? "Unknown"; + } + private static void ErrorForOutdatedModDependency(string modName) => Log.Error($"Outdated {modName} mod detected. { modName} must be updated for Performance Fish to work correctly"); diff --git a/Source/PerformanceFish/Rendering/PrintImprovements.cs b/Source/PerformanceFish/Rendering/PrintImprovements.cs new file mode 100644 index 0000000..de3176c --- /dev/null +++ b/Source/PerformanceFish/Rendering/PrintImprovements.cs @@ -0,0 +1,124 @@ +// Copyright (c) 2023 bradson +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at https://mozilla.org/MPL/2.0/. + +using Mono.Cecil; +using Mono.Cecil.Cil; +using Mono.Cecil.Rocks; +using MonoMod.Utils; +using PerformanceFish.Prepatching; + +namespace PerformanceFish.Rendering; + +public sealed class PrintImprovements : ClassWithFishPrepatches +{ + public sealed class PrintPlanePatch : FishPrepatch + { + public override string? Description { get; } + = "Attempt at fixing the clipping between textures by slightly adjusting their angle to have the top left " + + "placed closer to the camera than the bottom right"; + + public override MethodBase TargetMethodBase { get; } = methodof(Printer_Plane.PrintPlane); + + public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module) + { + var codes = ilProcessor.instructions; + + var altitudeBiasParameter = ilProcessor.GetParameter("topVerticesAltitudeBias"); + var sizeParameter = ilProcessor.GetParameter("size"); + + var altitudeBiasIndex = codes.FirstIndexOf(code => code.Operand == altitudeBiasParameter); + + LoadSizeAtAndCall(altitudeBiasIndex, TopLeftAdjustment); + + while (codes[++altitudeBiasIndex].Operand != altitudeBiasParameter) + ; + + LoadSizeAtAndCall(altitudeBiasIndex, TopRightAdjustment); + + while (codes[--altitudeBiasIndex].Operand is not 0f) + ; + + LoadSizeAtAndCall(altitudeBiasIndex, BottomLeftAdjustment); + + while (codes[++altitudeBiasIndex].Operand is not 0f) + ; + + LoadSizeAtAndCall(altitudeBiasIndex, BottomRightAdjustment); + + void LoadSizeAtAndCall(int instructionIndex, Delegate method) + { + codes[instructionIndex].OpCode = OpCodes.Ldarga; + codes[instructionIndex].Operand = sizeParameter; + ilProcessor.InsertAt(instructionIndex + 1, (OpCodes.Call, method.Method)); + } + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float TopLeftAdjustment(in Vector2 size) + => (size.y * 0.0048f) + (size.x * 0.0002f); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float TopRightAdjustment(in Vector2 size) + => (size.y * 0.0048f) - (size.x * 0.0002f); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float BottomLeftAdjustment(in Vector2 size) + => (size.y * -0.0048f) + (size.x * 0.0002f); + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static float BottomRightAdjustment(in Vector2 size) + => (size.y * -0.0048f) - (size.x * 0.0002f); + } + + public sealed class PlantPatch : FishPrepatch + { + public override string? Description { get; } + = "Fix for plants sometimes rendering behind hydroponics"; + + public override MethodBase TargetMethodBase { get; } + = AccessTools.DeclaredMethod(typeof(Plant), nameof(Plant.Print)); + + public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module) + { + var body = ilProcessor.Body; + body.SimplifyMacros(); + + try + { + var codes = ilProcessor.instructions; + var printPlaneMethod = methodof(Printer_Plane.PrintPlane); + var printPlaneIndex = codes.FirstIndexOf(code + => code.Operand is MethodReference method && method.Is(printPlaneMethod)); + Guard.IsGreaterThanOrEqualTo(printPlaneIndex, 0); + + while (--printPlaneIndex >= 0 && codes[printPlaneIndex] is var code + && (code.Operand is not VariableDefinition variable || !variable.VariableType.Is(typeof(Vector3)))) + ; + + if (printPlaneIndex < 0) + { + throw new InvalidOperationException( + "Failed to find center variable load instruction for PrintPlane call"); + } + + ilProcessor.InsertAt(printPlaneIndex + 1, (OpCodes.Call, methodof(AdjustCenter))); + } + finally + { + body.OptimizeMacros(); + } + } + + public static Vector3 AdjustCenter(Vector3 center) + { + if (Math.Abs(center.y - LowPlantAltitude) <= 0.001f) + center.y += 0.005f; + + return center; + } + + public static readonly float LowPlantAltitude = AltitudeLayer.LowPlant.AltitudeFor(); + } +} \ No newline at end of file diff --git a/Source/PerformanceFish/Utility/CollectionExtensions.cs b/Source/PerformanceFish/Utility/CollectionExtensions.cs index 6fa0a43..679b9d2 100644 --- a/Source/PerformanceFish/Utility/CollectionExtensions.cs +++ b/Source/PerformanceFish/Utility/CollectionExtensions.cs @@ -312,14 +312,13 @@ public static class CollectionExtensions public static List AsOrToList(this IEnumerable enumerable) => enumerable as List ?? enumerable.ToList(); public static unsafe ref T GetReference(this NativeArray nativeArray, int index) where T : struct - => ref Unsafe.AsRef(Unsafe.Add(NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(nativeArray), - index)); + => ref Unsafe.AsRef((T*)NativeArrayUnsafeUtility.GetUnsafeBufferPointerWithoutChecks(nativeArray) + index); public static void UnwrapArray(this List list, out T[] array, out int count) { array = list._items; count = list._size; - Guard.IsLessThanOrEqualTo(count, array.Length); + Guard.IsLessThanOrEqualTo((uint)count, (uint)array.Length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] diff --git a/Source/PerformanceFish/UtilityPrepatches.cs b/Source/PerformanceFish/UtilityPrepatches.cs index ddddbb4..7387a39 100644 --- a/Source/PerformanceFish/UtilityPrepatches.cs +++ b/Source/PerformanceFish/UtilityPrepatches.cs @@ -39,65 +39,6 @@ public sealed class UtilityPrepatches : ClassWithFishPrepatches } } - public sealed class BetterPrinting : FishPrepatch - { - public override string? Description { get; } - = "Attempt at fixing the clipping between textures by slightly adjusting their angle to have the top left " - + "placed closer to the camera than the bottom right"; - - public override MethodBase TargetMethodBase { get; } = methodof(Printer_Plane.PrintPlane); - - public override void Transpiler(ILProcessor ilProcessor, ModuleDefinition module) - { - var codes = ilProcessor.instructions; - - var altitudeBiasParameter = ilProcessor.GetParameter("topVerticesAltitudeBias"); - var sizeParameter = ilProcessor.GetParameter("size"); - - var altitudeBiasIndex = codes.FirstIndexOf(code => code.Operand == altitudeBiasParameter); - - LoadSizeAtAndCall(altitudeBiasIndex, TopLeftAdjustment); - - while (codes[++altitudeBiasIndex].Operand != altitudeBiasParameter) - ; - - LoadSizeAtAndCall(altitudeBiasIndex, TopRightAdjustment); - - while (codes[--altitudeBiasIndex].Operand is not 0f) - ; - - LoadSizeAtAndCall(altitudeBiasIndex, BottomLeftAdjustment); - - while (codes[++altitudeBiasIndex].Operand is not 0f) - ; - - LoadSizeAtAndCall(altitudeBiasIndex, BottomRightAdjustment); - - void LoadSizeAtAndCall(int instructionIndex, Delegate method) - { - codes[instructionIndex].OpCode = OpCodes.Ldarga; - codes[instructionIndex].Operand = sizeParameter; - ilProcessor.InsertAt(instructionIndex + 1, (OpCodes.Call, method.Method)); - } - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float TopLeftAdjustment(in Vector2 size) - => (size.y * 0.0045f) + (size.x * 0.0005f); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float TopRightAdjustment(in Vector2 size) - => (size.y * 0.0045f) - (size.x * 0.0005f); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float BottomLeftAdjustment(in Vector2 size) - => (size.y * -0.0045f) + (size.x * 0.0005f); - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float BottomRightAdjustment(in Vector2 size) - => (size.y * -0.0045f) - (size.x * 0.0005f); - } - public sealed class NoSteamLogWarning : FishPrepatch { public override string? Description { get; }