Browse Source

Modify getting screenshot for scene

Adds a InMemory and Texture properties to ScreenshotEventArgs that tell
MPS to read pixel data directly and notifies subscribers with the new
texture.

Prevents having to deal with IO errors when trying to wait for the
screenshot to be written to a file.
habeebweeb 4 years ago
parent
commit
e37b286a5d

+ 19 - 22
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/Managers/SceneManager.cs

@@ -11,12 +11,13 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
     public class SceneManager : IManager
     {
         public static bool Busy { get; private set; }
-        public bool Initialized { get; private set; }
         public static readonly Vector2 sceneDimensions = new Vector2(480, 270);
+        private static readonly ConfigEntry<bool> sortDescending;
+        private static readonly ConfigEntry<SortMode> currentSortMode;
         private readonly MeidoPhotoStudio meidoPhotoStudio;
         private int SortDirection => SortDescending ? -1 : 1;
+        public bool Initialized { get; private set; }
         public bool KankyoMode { get; set; }
-        private static readonly ConfigEntry<bool> sortDescending;
         public bool SortDescending
         {
             get => sortDescending.Value;
@@ -30,7 +31,6 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public string CurrentBasePath => KankyoMode ? Constants.kankyoPath : Constants.scenesPath;
         public string CurrentScenesDirectory
             => CurrentDirectoryIndex == 0 ? CurrentBasePath : Path.Combine(CurrentBasePath, CurrentDirectoryName);
-        private static readonly ConfigEntry<SortMode> currentSortMode;
         public SortMode CurrentSortMode
         {
             get => currentSortMode.Value;
@@ -111,8 +111,19 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public void SaveScene(bool overwrite = false)
         {
             if (Busy) return;
+            Busy = true;
+
             if (!Directory.Exists(CurrentScenesDirectory)) Directory.CreateDirectory(CurrentScenesDirectory);
-            meidoPhotoStudio.StartCoroutine(SaveSceneToFile(overwrite));
+
+            MeidoPhotoStudio.NotifyRawScreenshot += SaveScene;
+
+            MeidoPhotoStudio.TakeScreenshot(new ScreenshotEventArgs() { InMemory = true });
+
+            void SaveScene(object sender, ScreenshotEventArgs args)
+            {
+                MeidoPhotoStudio.NotifyRawScreenshot -= SaveScene;
+                meidoPhotoStudio.StartCoroutine(SaveSceneToFile(args.Screenshot, overwrite));
+            }
         }
 
         public void SelectDirectory(int directoryIndex)
@@ -255,7 +266,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             meidoPhotoStudio.ApplyScene(Path.Combine(Constants.configPath, "mpstempscene"));
         }
 
-        private System.Collections.IEnumerator SaveSceneToFile(bool overwrite = false)
+        private System.Collections.IEnumerator SaveSceneToFile(Texture2D screenshot, bool overwrite = false)
         {
             Busy = true;
 
@@ -263,29 +274,14 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             if (sceneData != null)
             {
-                string screenshotPath = Utility.TempScreenshotFilename();
-
-                MeidoPhotoStudio.TakeScreenshot(screenshotPath, 1, KankyoMode);
-
-                do yield return new WaitForSecondsRealtime(0.2f);
-                while (!File.Exists(screenshotPath));
-
                 string scenePrefix = KankyoMode ? "mpskankyo" : "mpsscene";
                 string fileName = $"{scenePrefix}{Utility.Timestamp}.png";
                 string savePath = Path.Combine(CurrentScenesDirectory, fileName);
 
-                if (overwrite && CurrentScene != null)
-                {
-                    savePath = CurrentScene.FileInfo.FullName;
-                }
+                if (overwrite && CurrentScene != null) savePath = CurrentScene.FileInfo.FullName;
                 else overwrite = false;
 
-                Texture2D screenshot = new Texture2D(1, 1, TextureFormat.ARGB32, false);
-                screenshot.LoadImage(File.ReadAllBytes(screenshotPath));
-
-                int sceneWidth = (int)sceneDimensions.x;
-                int sceneHeight = (int)sceneDimensions.y;
-                Utility.ResizeToFit(screenshot, sceneWidth, sceneHeight);
+                Utility.ResizeToFit(screenshot, (int)sceneDimensions.x, (int)sceneDimensions.y);
 
                 using (FileStream fileStream = File.Create(savePath))
                 {
@@ -308,6 +304,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
             }
 
             Busy = false;
+            yield break;
         }
 
         public class Scene

+ 22 - 9
COM3D2.MeidoPhotoStudio.Plugin/MeidoPhotoStudio/MeidoPhotoStudio.cs

@@ -22,6 +22,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public const int kankyoMagic = -765;
         public static string pluginString = $"{pluginName} {pluginVersion}";
         public static bool EditMode => currentScene == Constants.Scene.Edit;
+        public static event EventHandler<ScreenshotEventArgs> NotifyRawScreenshot;
         private WindowManager windowManager;
         private SceneManager sceneManager;
         private MeidoManager meidoManager;
@@ -300,17 +301,27 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
 
             yield return new WaitForEndOfFrame();
 
-            // Take Screenshot
-            int[] defaultSuperSize = new[] { 1, 2, 4 };
-            int selectedSuperSize = args.SuperSize < 1
-                ? defaultSuperSize[(int)GameMain.Instance.CMSystem.ScreenShotSuperSize]
-                : args.SuperSize;
+            if (args.InMemory)
+            {
+                Texture2D rawScreenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.ARGB32, false);
+                rawScreenshot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0, false);
+                rawScreenshot.Apply();
+                NotifyRawScreenshot?.Invoke(null, new ScreenshotEventArgs() { Screenshot = rawScreenshot });
+            }
+            else
+            {
+                // Take Screenshot
+                int[] defaultSuperSize = new[] { 1, 2, 4 };
+                int selectedSuperSize = args.SuperSize < 1
+                    ? defaultSuperSize[(int)GameMain.Instance.CMSystem.ScreenShotSuperSize]
+                    : args.SuperSize;
 
-            string path = string.IsNullOrEmpty(args.Path)
-                ? Utility.ScreenshotFilename()
-                : args.Path;
+                string path = string.IsNullOrEmpty(args.Path)
+                    ? Utility.ScreenshotFilename()
+                    : args.Path;
 
-            Application.CaptureScreenshot(path, selectedSuperSize);
+                Application.CaptureScreenshot(path, selectedSuperSize);
+            }
             GameMain.Instance.SoundMgr.PlaySe("se022.ogg", false);
 
             yield return new WaitForEndOfFrame();
@@ -496,5 +507,7 @@ namespace COM3D2.MeidoPhotoStudio.Plugin
         public string Path { get; set; } = string.Empty;
         public int SuperSize { get; set; } = -1;
         public bool HideMaids { get; set; }
+        public bool InMemory { get; set; } = false;
+        public Texture2D Screenshot { get; set; }
     }
 }