diff --git a/AquaMai/AquaMai.csproj b/AquaMai/AquaMai.csproj
index 441f26a7..64f202c7 100644
--- a/AquaMai/AquaMai.csproj
+++ b/AquaMai/AquaMai.csproj
@@ -13,6 +13,7 @@
512
true
+ 12
false
@@ -281,6 +282,7 @@
+
diff --git a/AquaMai/AquaMai.toml b/AquaMai/AquaMai.toml
index 470baa96..aa311867 100644
--- a/AquaMai/AquaMai.toml
+++ b/AquaMai/AquaMai.toml
@@ -22,6 +22,9 @@ SkipToMusicSelection=false
CustomVersionString=""
# Load Jacket image from folder "LocalAssets" and filename "{MusicID}.png" for self-made charts
LoadJacketPng=true
+# Use the png jacket above as BGA if BGA is not found for self-made charts
+# Use together with `LoadJacketPng`
+LoadLocalBga=true
# Press key "7" for 1 second to skip to next step or restart current song
QuickSkip=true
# Add ".ab" image resources without the need of rebuilding a manifest
@@ -42,4 +45,4 @@ ImmediateSave=true
[Performance]
# Disable some useless delays to speed up the game boot process
-ImproveLoadSpeed=false
\ No newline at end of file
+ImproveLoadSpeed=false
diff --git a/AquaMai/Config.cs b/AquaMai/Config.cs
index 95f0f8a8..fdbe1dda 100644
--- a/AquaMai/Config.cs
+++ b/AquaMai/Config.cs
@@ -29,6 +29,7 @@ namespace AquaMai
public bool ExtendTimer { get; set; }
public bool SkipEventInfo { get; set; }
public bool ImmediateSave { get; set; }
+ public bool LoadLocalBga { get; set; }
public string CustomVersionString { get; set; }
public string ExecOnIdle { get; set; }
public string ExecOnEntry { get; set; }
diff --git a/AquaMai/UX/LoadJacketPng.cs b/AquaMai/UX/LoadJacketPng.cs
index 4f728380..7d606a2b 100644
--- a/AquaMai/UX/LoadJacketPng.cs
+++ b/AquaMai/UX/LoadJacketPng.cs
@@ -5,7 +5,6 @@ using System.Reflection;
using HarmonyLib;
using UnityEngine;
using System.Text.RegularExpressions;
-using MelonLoader;
namespace AquaMai.UX
{
@@ -27,26 +26,49 @@ namespace AquaMai.UX
}
var id = matches[0].Groups[1].Value;
- foreach (var ext in new[] { ".jpg", ".png", ".webp", ".bmp", ".gif" })
- {
- if (File.Exists(Path.Combine(Environment.CurrentDirectory, "LocalAssets", id + ext)))
- {
- filename = id + ext;
- }
- }
- var localPath = Path.Combine(Environment.CurrentDirectory, "LocalAssets", filename);
- if (File.Exists(localPath))
+ var texture = GetJacketTexture2D(id);
+ if (texture is null)
{
- __result = new Texture2D(1, 1);
- ImageConversion.LoadImage(__result, File.ReadAllBytes(localPath));
+ __result = __instance.LoadAsset($"Jacket/UI_Jacket_{id}.png");
}
else
{
- __result = __instance.LoadAsset($"Jacket/UI_Jacket_{id}.png");
+ __result = texture;
}
return false;
}
+
+ private static string GetJacketPath(string id)
+ {
+ foreach (var ext in new[] { ".jpg", ".png", ".webp", ".bmp", ".gif" })
+ {
+ if (File.Exists(Path.Combine(Environment.CurrentDirectory, "LocalAssets", id + ext)))
+ {
+ return Path.Combine(Environment.CurrentDirectory, "LocalAssets", id + ext);
+ }
+ }
+
+ return null;
+ }
+
+ public static Texture2D GetJacketTexture2D(string id)
+ {
+ var path = GetJacketPath(id);
+ if (path == null)
+ {
+ return null;
+ }
+
+ var texture = new Texture2D(1, 1);
+ texture.LoadImage(File.ReadAllBytes(path));
+ return texture;
+ }
+
+ public static Texture2D GetJacketTexture2D(int id)
+ {
+ return GetJacketTexture2D($"{id:000000}");
+ }
}
-}
\ No newline at end of file
+}
diff --git a/AquaMai/UX/LoadLocalBga.cs b/AquaMai/UX/LoadLocalBga.cs
new file mode 100644
index 00000000..5cb789e7
--- /dev/null
+++ b/AquaMai/UX/LoadLocalBga.cs
@@ -0,0 +1,43 @@
+using System.Linq;
+using HarmonyLib;
+using MAI2.Util;
+using Manager;
+using MelonLoader;
+using Monitor.Game;
+using UnityEngine;
+
+namespace AquaMai.UX;
+
+public class LoadLocalBga
+{
+ [HarmonyPostfix]
+ [HarmonyPatch(typeof(GameCtrl), "IsReady")]
+ public static void LoadLocalBgaAwake(GameObject ____movieMaskObj)
+ {
+ var components = ____movieMaskObj.GetComponentsInChildren(false);
+ var movie = components.FirstOrDefault(it => it.name == "Movie");
+ if (movie is null) return;
+
+ var music = Singleton.Instance.GetMusic(GameManager.SelectMusicID[0]);
+ var moviePath = string.Format(Singleton.Instance.GetMovieDataPath($"{music.movieName.id:000000}") + ".dat");
+ if (!moviePath.Contains("dummy")) return;
+
+ var jacket = LoadJacketPng.GetJacketTexture2D(music.movieName.id);
+ if (jacket is null)
+ {
+ MelonLogger.Msg("No jacket found for music " + music);
+ }
+ else
+ {
+ // If I create a new RawImage component, the jacket will be not be displayed
+ // I think it will be difficult to make it work with RawImage
+ // So I change the material that plays video to default sprite material
+ // The original player is actually a sprite renderer and plays video with a custom material
+ var sprite = movie.GetComponent();
+ sprite.sprite = Sprite.Create(jacket, new Rect(0, 0, jacket.width, jacket.height), new Vector2(0.5f, 0.5f));
+ sprite.material = new Material(Shader.Find("Sprites/Default"));
+ }
+
+ // movie.gameObject.SetActive(false);
+ }
+}