Skip to content

Commit

Permalink
Add SBPR_Fix_ResourceUnloadOptimizations (#38)
Browse files Browse the repository at this point in the history
  • Loading branch information
GeBo1 authored Jul 2, 2022
1 parent 7918f71 commit 239c9ee
Show file tree
Hide file tree
Showing 7 changed files with 196 additions and 7 deletions.
9 changes: 9 additions & 0 deletions IllusionFixes.sln
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KKS_Fix_PersonalityCorrecto
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Core_Fix_PersonalityCorrector", "src\Core_Fix_PersonalityCorrector\Core_Fix_PersonalityCorrector.shproj", "{7A9F7BD1-FC29-4D40-BE21-66BBA1845D35}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SBPR_Fix_ResourceUnloadOptimizations", "src\SBPR_Fix_ResourceUnloadOptimizations\SBPR_Fix_ResourceUnloadOptimizations.csproj", "{09D5D602-4CFD-43C3-AD7E-58E5072E8127}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Common\Common.projitems*{00e09fd0-9862-41b3-bd2c-7094a16c97f7}*SharedItemsImports = 4
Expand All @@ -312,6 +314,8 @@ Global
src\Common\Common.projitems*{08a43f46-904c-4add-86cf-7170f1b1f087}*SharedItemsImports = 4
src\Common\Common.projitems*{091fd8bf-29a8-4d03-93b1-4ceb8753315e}*SharedItemsImports = 4
src\Core_Fix_WetAccessories\Core_Fix_WetAccessories.projitems*{091fd8bf-29a8-4d03-93b1-4ceb8753315e}*SharedItemsImports = 4
src\Common\Common.projitems*{09d5d602-4cfd-43c3-ad7e-58e5072e8127}*SharedItemsImports = 4
src\Core_Fix_ResourceUnloadOptimizations\Core_Fix_ResourceUnloadOptimizations.projitems*{09d5d602-4cfd-43c3-ad7e-58e5072e8127}*SharedItemsImports = 4
src\Common\Common.projitems*{09ebe942-19bb-445a-a1d4-06f185d7f518}*SharedItemsImports = 4
src\Common\Common.projitems*{0c5a556c-af80-4562-ab56-c103e48ddce9}*SharedItemsImports = 4
src\Core_Fix_ModdedHeadEyeliner\Core_Fix_ModdedHeadEyeliner.projitems*{14973826-75a9-4194-a9ec-2a1de3d20c36}*SharedItemsImports = 13
Expand Down Expand Up @@ -900,6 +904,10 @@ Global
{1F49B69E-9C3C-4A0F-B0EB-28A8E907E6D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1F49B69E-9C3C-4A0F-B0EB-28A8E907E6D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1F49B69E-9C3C-4A0F-B0EB-28A8E907E6D6}.Release|Any CPU.Build.0 = Release|Any CPU
{09D5D602-4CFD-43C3-AD7E-58E5072E8127}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{09D5D602-4CFD-43C3-AD7E-58E5072E8127}.Debug|Any CPU.Build.0 = Debug|Any CPU
{09D5D602-4CFD-43C3-AD7E-58E5072E8127}.Release|Any CPU.ActiveCfg = Release|Any CPU
{09D5D602-4CFD-43C3-AD7E-58E5072E8127}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1012,6 +1020,7 @@ Global
{DB6D687E-C491-44EA-8FC8-A96D3C62D2CA} = {D3136A19-617D-4426-827A-00A51D84925F}
{1F49B69E-9C3C-4A0F-B0EB-28A8E907E6D6} = {40715440-0FF3-47D1-BC1F-96AC7FDAF26E}
{7A9F7BD1-FC29-4D40-BE21-66BBA1845D35} = {40715440-0FF3-47D1-BC1F-96AC7FDAF26E}
{09D5D602-4CFD-43C3-AD7E-58E5072E8127} = {47CA3E45-1672-4D71-ABD2-8621D4C74003}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {D3F10C8B-FD6C-43DA-94B4-1D9688BBE11B}
Expand Down
4 changes: 4 additions & 0 deletions src/Common/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ internal static class Constants
internal const string GameProcessName = "KoikatsuSunshine";
internal const string StudioProcessName = "CharaStudio";
internal const string VRProcessName = "KoikatsuSunshine_VR";
#elif SBPR
internal static bool InsideStudio => false;
internal const string GameProcessName = "SexyBeachPR_64";
internal const string GameProcessName32bit = "SexyBeachPR_32";
#endif
}
}
14 changes: 12 additions & 2 deletions src/Common/Utilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ internal static class Utilities
public const string ConfigSectionFixes = "Bug Fixes";
public const string ConfigSectionTweaks = "Tweaks";

public static bool InsideStudio { get; } = Application.productName == "CharaStudio" || Application.productName == "StudioNEOV2";
public static bool InsideStudio { get; } =
#if !SBPR
Application.productName == "CharaStudio" || Application.productName == "StudioNEOV2";
#else
false;
#endif

public static bool InsideKoikatsuParty { get; } = Application.productName == "Koikatsu Party";
public static bool InsideKoikatsuParty { get; } =
#if !SBPR
Application.productName == "Koikatsu Party";
#else
false;
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@ public partial class ResourceUnloadOptimizations
public static ConfigEntry<bool> OptimizeMemoryUsage { get; private set; }
public static ConfigEntry<int> PercentMemoryThreshold { get; private set; }
public static ConfigEntry<int> PercentMemoryThresholdDuringLoad { get; private set; }

internal void Awake()
{
DisableUnload = Config.Bind(Utilities.ConfigSectionTweaks, "Disable Resource Unload", false, new ConfigDescription("Disables all resource unloading. Requires large amounts of RAM or will likely crash your game.", null, new ConfigurationManagerAttributes { IsAdvanced = true }));
OptimizeMemoryUsage = Config.Bind(Utilities.ConfigSectionTweaks, "Optimize Memory Usage", true, new ConfigDescription("Use more memory (if available) in order to load the game faster and reduce random stutter."));
PercentMemoryThreshold = Config.Bind(Utilities.ConfigSectionTweaks, "Optimize Memory Threshold", 75, new ConfigDescription("Minimum amount of memory to be used before resource unloading will run.", null, new ConfigurationManagerAttributes {IsAdvanced = true}));
PercentMemoryThresholdDuringLoad = Config.Bind(Utilities.ConfigSectionTweaks, "Optimize Memory Threshold During Load", 65, new ConfigDescription("Minimum amount of memory to be used during load before resource unloading will run (should be lower than 'Percent Memory Threshold').", null, new ConfigurationManagerAttributes {IsAdvanced = true}));
#if !SBPR
PercentMemoryThresholdDuringLoad = Config.Bind(Utilities.ConfigSectionTweaks, "Optimize Memory Threshold During Load", 65, new ConfigDescription($"Minimum amount of memory to be used during load before resource unloading will run (should be lower than 'Optimize Memory Threshold').", null, new ConfigurationManagerAttributes {IsAdvanced = true}));
#else
PercentMemoryThresholdDuringLoad = Config.Bind(Utilities.ConfigSectionTweaks, "Optimize Memory Threshold During Load", 80, new ConfigDescription($"Minimum amount of memory to be used during load before resource unloading will run (should be higher than 'Optimize Memory Threshold').", null, new ConfigurationManagerAttributes { IsAdvanced = true }));
#endif
StartCoroutine(CleanupCo());

InstallHooks();
Expand Down Expand Up @@ -120,6 +124,14 @@ private static bool GetIsNowLoadingFade()
return Manager.Scene.IsNowLoadingFade;
#elif PH
return true;
#elif SBPR
if (Constants.InsideStudio) return false;
// SBPR main game loading detection is a bit more convoluted since large async loads
// happen at during live game play
return !Manager.Scene.IsInstance() || !Manager.Map.IsInstance() || !Manager.MapScene.IsInstance() ||
Manager.Map.Instance.NowLoading || Manager.MapScene.Instance.MapSceneClass == null ||
Manager.MapScene.Instance.MapSceneClass.IsNowLoading || Manager.Scene.Instance.sceneFade == null ||
Manager.Scene.Instance.sceneFade.IsFadeNow;
#else
return !Manager.Scene.IsInstance() || Manager.Scene.Instance.IsNowLoadingFade;
#endif
Expand All @@ -143,7 +155,7 @@ private static IEnumerator SceneLoadComplete()
_sceneLoadedOrReset = true;
}

private static class Hooks
private static partial class Hooks
{
[HarmonyPrefix]
[HarmonyPatch(typeof(GC), nameof(GC.Collect), new Type[0])]
Expand All @@ -164,12 +176,12 @@ public static AsyncOperation UnloadUnusedAssetsHook()
return RunUnloadAssets();
}

#if !EC
#if !EC && !SBPR
[HarmonyPrefix]
[HarmonyPatch(typeof(Studio.Studio), nameof(Studio.Studio.LoadScene))]
[HarmonyPatch(typeof(Studio.Studio), nameof(Studio.Studio.ImportScene))]
[HarmonyPatch(typeof(Studio.Studio), nameof(Studio.Studio.InitScene))]
#if !HS && !PH
#if !HS && !PH && !SBPR
[HarmonyPatch(typeof(Studio.Studio), nameof(Studio.Studio.LoadSceneCoroutine))]
#endif
public static void LoadScenePrefix()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using BepInEx;
using Common;
using HarmonyLib;
using System;
using System.Collections;
using UnityEngine;

namespace IllusionFixes
{
[BepInProcess(Constants.GameProcessName)]
[BepInProcess(Constants.GameProcessName32bit)]
[BepInPlugin(GUID, PluginName, Constants.PluginsVersion)]
public partial class ResourceUnloadOptimizations : BaseUnityPlugin
{
public const string GUID = "SBPR_Fix_ResourceUnloadOptimizations";

private static Coroutine _currentCleanupAfterLoading = null;

private static IEnumerator CleanupAfterAsyncLoading()
{
yield return null;
while (GetIsNowLoadingFade())
{
yield return null;
}

// force a single unload once large load operation finishes
while (_currentOperation != null && !_currentOperation.isDone)
{
yield return null;
}
_currentOperation = _originalUnload();
yield return null;
// force GC
GC.Collect(GC.MaxGeneration);
_currentCleanupAfterLoading = null;
}

partial class Hooks
{
// deploy happens when:
// - main game save is loaded
// - Time of day changes
// - entering main game map from another scene (h-scene, changing room, etc.)
[HarmonyPostfix]
[HarmonyPatch(typeof(SexyBeach.MapScene), nameof(SexyBeach.MapScene.Deploy))]
public static void DeployPostfix(SexyBeach.MapScene __instance)
{
if (!OptimizeMemoryUsage.Value || __instance == null) return;
if (_currentCleanupAfterLoading != null) __instance.StopCoroutine(_currentCleanupAfterLoading);
_currentCleanupAfterLoading = __instance.StartCoroutine(CleanupAfterAsyncLoading());
}

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>IllusionFixes</RootNamespace>
<AssemblyName>SBPR_Fix_ResourceUnloadOptimizations</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<ProjectGuid>{09D5D602-4CFD-43C3-AD7E-58E5072E8127}</ProjectGuid>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\bin\BepInEx\plugins\IllusionFixes\</OutputPath>
<DefineConstants>TRACE;DEBUG;SBPR</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>embedded</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\bin\BepInEx\plugins\IllusionFixes\</OutputPath>
<DefineConstants>TRACE;SBPR</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DebugSymbols>true</DebugSymbols>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony, Version=2.5.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\IllusionLibs.BepInEx.Harmony.2.5.4\lib\net35\0Harmony.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="Assembly-CSharp, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\IllusionLibs\packaging\SexyBeachPR\libraries\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="BepInEx, Version=5.4.15.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\IllusionLibs.BepInEx.5.4.15\lib\net35\BepInEx.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MonoMod.RuntimeDetour, Version=21.8.5.1, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\IllusionLibs.BepInEx.MonoMod.21.8.5.1\lib\net35\MonoMod.RuntimeDetour.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="MonoMod.Utils, Version=21.8.5.1, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\IllusionLibs.BepInEx.MonoMod.21.8.5.1\lib\net35\MonoMod.Utils.dll</HintPath>
<Private>False</Private>
</Reference>
<Reference Include="System.Core" />
<Reference Include="UnityEngine, Version=0.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\IllusionLibs\packaging\SexyBeachPR\libraries\UnityEngine.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="SBPR.ResourceUnloadOptimizations.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="..\Common\Common.projitems" Label="Shared" />
<Import Project="..\Core_Fix_ResourceUnloadOptimizations\Core_Fix_ResourceUnloadOptimizations.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>IF EXIST $(SolutionDir)PostBuild.bat CALL "$(SolutionDir)PostBuild.bat" $(TargetPath) SBPR</PostBuildEvent>
</PropertyGroup>
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\IllusionLibs.BepInEx.Harmony.2.5.4\build\IllusionLibs.BepInEx.Harmony.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\IllusionLibs.BepInEx.Harmony.2.5.4\build\IllusionLibs.BepInEx.Harmony.targets'))" />
<Error Condition="!Exists('..\..\packages\IllusionLibs.BepInEx.MonoMod.21.8.5.1\build\IllusionLibs.BepInEx.MonoMod.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\IllusionLibs.BepInEx.MonoMod.21.8.5.1\build\IllusionLibs.BepInEx.MonoMod.targets'))" />
</Target>
<Import Project="..\..\packages\IllusionLibs.BepInEx.Harmony.2.5.4\build\IllusionLibs.BepInEx.Harmony.targets" Condition="Exists('..\..\packages\IllusionLibs.BepInEx.Harmony.2.5.4\build\IllusionLibs.BepInEx.Harmony.targets')" />
<Import Project="..\..\packages\IllusionLibs.BepInEx.MonoMod.21.8.5.1\build\IllusionLibs.BepInEx.MonoMod.targets" Condition="Exists('..\..\packages\IllusionLibs.BepInEx.MonoMod.21.8.5.1\build\IllusionLibs.BepInEx.MonoMod.targets')" />
</Project>
9 changes: 9 additions & 0 deletions src/SBPR_Fix_ResourceUnloadOptimizations/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="IllusionLibs.BepInEx" version="5.4.15" targetFramework="net35" developmentDependency="true" />
<package id="IllusionLibs.BepInEx.Harmony" version="2.5.4" targetFramework="net35" developmentDependency="true" />
<package id="IllusionLibs.BepInEx.MonoMod" version="21.8.5.1" targetFramework="net35" developmentDependency="true" />
<package id="Mono.Cecil" version="0.10.4" targetFramework="net35" />
<package id="MonoMod.RuntimeDetour" version="19.8.2.3" targetFramework="net35" />
<package id="MonoMod.Utils" version="19.8.2.3" targetFramework="net35" />
</packages>

0 comments on commit 239c9ee

Please sign in to comment.