123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261 |
- using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Globalization;
- using System.IO;
- using System.Reflection;
- using ExIni;
- using UnityEngine;
- using UnityInjector;
- using UnityInjector.Attributes;
- namespace CM3D2.ToukaScreenShot.Plugin
- {
- [PluginVersion("0.1.2.0")]
- [PluginName("Com3d2.ToukaScreenShot.Plugin")]
- [PluginFilter("COM3D2x64")]
- public class ToukaScreenShot : PluginBase
- {
- private readonly HashSet<int> defaultVisibleLayers = new HashSet<int>
- {
- 0,
- 1,
- 10
- };
-
- private readonly FieldInfo fBloom =
- typeof(CameraMain).GetField("m_gcBloom", BindingFlags.Instance | BindingFlags.NonPublic);
- private int layerMask = 0;
- private bool altKey;
- private bool bgActiveBack = true;
- private Color bgColorBack = Color.black;
- private bool bgVisible = true;
- private bool bloomBack;
- private bool bloomOff = true;
- private bool ctrlKey = true;
- private string fileNameEnd = "";
- private string fileNameHead = "img";
- private string folderName = "ScreenShot";
- private Camera mainCamera;
- private int maskBack;
- private bool noConfigFlg;
- private bool shiftKey;
- private string triggerKey = "s";
- private string photoShootKey = "d";
- private void Start()
- {
- for (var i = 0; i < sizeof(int) * 8; i++)
- if (GetValueIni("Visible", $"Layer{i}", defaultVisibleLayers.Contains(i)))
- layerMask |= 1 << i;
- folderName = GetValueIni("File", "Folder", "ScreenShot");
- fileNameHead = GetValueIni("File", "Head", "img");
- fileNameEnd = GetValueIni("File", "End", "");
- bgVisible = GetValueIni("Visible", "BG", false);
- bloomOff = GetValueIni("Effect", "BloomOff", true);
- altKey = GetValueIni("Command", "Alt", false);
- ctrlKey = GetValueIni("Command", "Ctrl", true);
- shiftKey = GetValueIni("Command", "Shift", false);
- triggerKey = GetValueIni("Command", "Trigger", "s");
- photoShootKey = GetValueIni("Command", "Trigger", "d");
- if (noConfigFlg) SaveConfig();
- }
- private T GetValueIni<T>(string section, string key, T @default)
- {
- bool TryParse(string value, out T resultVal)
- {
- try
- {
- resultVal = (T) Convert.ChangeType(value, typeof(T), CultureInfo.InvariantCulture);
- return true;
- }
- catch (Exception e)
- {
- Debug.LogWarning($"Failed to parse {section} => {key} value {value} because {e.Message}");
- resultVal = default;
- return false;
- }
- }
-
- var iniKey = Preferences[section][key];
- if (iniKey != null && !string.IsNullOrEmpty(iniKey.Value) &&
- TryParse(iniKey.Value, out var result)) return result;
- iniKey.Value = Convert.ToString(@default, CultureInfo.InvariantCulture);
- result = @default;
- noConfigFlg = true;
- return result;
- }
- private void Update()
- {
- var pressedAlt = Input.GetKey(KeyCode.LeftAlt) || Input.GetKey(KeyCode.RightAlt);
- var pressedCtrl = Input.GetKey(KeyCode.LeftControl) || Input.GetKey(KeyCode.RightControl);
- var pressedShift = Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift);
- if (altKey == pressedAlt && ctrlKey == pressedCtrl && shiftKey == pressedShift && Input.GetKeyDown(triggerKey))
- StartCoroutine(ExecScreenShot());
- else if (altKey == pressedAlt && ctrlKey == pressedCtrl && shiftKey == pressedShift && Input.GetKeyDown(photoShootKey))
- StartCoroutine(StartPhotoShoot());
- }
- private IEnumerator StartPhotoShoot()
- {
- yield return new WaitForEndOfFrame();
- var activeMaidCount = GameMain.Instance.CharacterMgr.GetMaidCount();
- Maid activeMaid = null;
- for (var i = 0; i < activeMaidCount; i++)
- if ((activeMaid = GameMain.Instance.CharacterMgr.GetMaid(i)).Visible)
- break;
- if (activeMaid == null)
- {
- Debug.Log("No maid found!");
- yield break;
- }
-
- var poseList =
- Directory.GetFiles(Path.Combine(UTY.gameProjectPath, Path.Combine("PhotoModeData", "MyPose")));
-
- Debug.Log($"Maid to use: {activeMaid.name}");
- Debug.Log($"Pose count: {poseList.Length}");
- for (var poseNum = 0; poseNum < poseList.Length; poseNum++)
- {
- Debug.Log($"{poseNum + 1} / {poseList.Length}");
- var poseFile = poseList[poseNum];
- PhotoMotionData.AddMyPose(poseFile).Apply(activeMaid);
- yield return ExecScreenShot();
- }
- Debug.Log("Done!");
- }
- private IEnumerator ExecScreenShot()
- {
- yield return new WaitForEndOfFrame();
- mainCamera = Camera.main;
- BackUpCamera();
-
- var ss = GetToukaScreenShot();
- File.WriteAllBytes(GetTimeFileName(), ss.EncodeToPNG());
-
- Destroy(ss);
-
-
- yield return Resources.UnloadUnusedAssets();
- GC.Collect();
-
- GameMain.Instance.SoundMgr.PlaySe("se022.ogg", false);
- }
-
- private Texture2D GetToukaScreenShot()
- {
- var ss = GameMain.Instance.CMSystem.ScreenShotSuperSize switch
- {
- CMSystem.SSSuperSizeType.X1 => 1,
- CMSystem.SSSuperSizeType.X2 => 2,
- CMSystem.SSSuperSizeType.X4 => 4,
- _ => 1
- };
- var aa = GameMain.Instance.CMSystem.Antialias switch
- {
- CMSystem.AntiAliasType.None => 0,
- CMSystem.AntiAliasType.X2 => 2,
- CMSystem.AntiAliasType.X4 => 4,
- CMSystem.AntiAliasType.X8 => 8,
- _ => 8,
- };
- var w = Screen.width * ss;
- var h = Screen.height * ss;
- var rt = RenderTexture.GetTemporary(w, h, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.sRGB, aa);
- rt.filterMode = FilterMode.Bilinear;
- SetCameraMask();
-
- mainCamera.backgroundColor = new Color(0f, 0f, 0f, 1f);
- var blackBgTex = RenderScreenShot(rt, w, h);
-
- mainCamera.backgroundColor = new Color(1f, 1f, 1f, 1f);
- var whiteBgTex = RenderScreenShot(rt, w, h);
-
- ResetCamera();
- mainCamera.targetTexture = null;
- RenderTexture.ReleaseTemporary(rt);
-
- var blackPix = blackBgTex.GetPixels32();
- var whitePix = whiteBgTex.GetPixels32();
- var resultPix = new Color32[blackPix.Length];
-
- for (var i = 0; i < resultPix.Length; i++)
- {
- var wp = whitePix[i];
- var bp = blackPix[i];
- var diff = wp.r - bp.r;
- if (diff < 0) diff = 0;
- resultPix[i] = new Color32((byte)((wp.r + bp.r) >> 1), (byte)((wp.g + bp.g) >> 1), (byte)((wp.b + bp.b) >> 1), (byte) ~diff);
- }
-
- var result = new Texture2D(w, h);
- result.SetPixels32(resultPix);
-
-
- Destroy(blackBgTex);
- Destroy(whiteBgTex);
- return result;
- }
- private string GetTimeFileName()
- {
- var targetFolder = Path.Combine(UTY.gameProjectPath, folderName);
- if (!Directory.Exists(targetFolder)) Directory.CreateDirectory(targetFolder);
- return Path.Combine(targetFolder, $"{fileNameHead}{DateTime.Now:yyyyMMddHHmmss}{fileNameEnd}.png");
- }
- private void BackUpCamera()
- {
- maskBack = mainCamera.cullingMask;
- bgColorBack = mainCamera.backgroundColor;
- if (!bgVisible) bgActiveBack = GameMain.Instance.BgMgr.current_bg_object.activeSelf;
- if (!bloomOff) return;
- var bloom = (Bloom) fBloom.GetValue(GameMain.Instance.MainCamera);
- bloomBack = bloom.enabled;
- }
- private void ResetCamera()
- {
- mainCamera.cullingMask = maskBack;
- mainCamera.backgroundColor = bgColorBack;
- if (!bgVisible) GameMain.Instance.BgMgr.current_bg_object.SetActive(bgActiveBack);
- if (!bloomOff) return;
- var bloom = (Bloom) fBloom.GetValue(GameMain.Instance.MainCamera);
- bloom.enabled = bloomBack;
- }
- private void SetCameraMask()
- {
- mainCamera.cullingMask = layerMask;
- if (!bgVisible) GameMain.Instance.BgMgr.current_bg_object.SetActive(false);
- if (!bloomOff) return;
- var bloom = (Bloom) fBloom.GetValue(GameMain.Instance.MainCamera);
- bloom.enabled = false;
- }
- private Texture2D RenderScreenShot(RenderTexture rt, int w, int h)
- {
- mainCamera.targetTexture = rt;
- mainCamera.Render();
- var texture2D = new Texture2D(w, h, TextureFormat.ARGB32, false);
- var prev = RenderTexture.active;
- RenderTexture.active = rt;
- texture2D.ReadPixels(new Rect(0f, 0f, w, h), 0, 0, false);
- RenderTexture.active = prev;
- return texture2D;
- }
- }
- }
|