183 lines
6.3 KiB
C#
183 lines
6.3 KiB
C#
using Cryville.Audio;
|
|
using Cryville.Audio.Source;
|
|
using Cryville.Common.Font;
|
|
using Cryville.Common.Logging;
|
|
using Cryville.Common.Unity;
|
|
using Cryville.Common.Unity.UI;
|
|
using Cryville.Input;
|
|
using Cryville.Input.Unity;
|
|
using Cryville.Input.Unity.Android;
|
|
using FFmpeg.AutoGen;
|
|
using Ionic.Zip;
|
|
using Newtonsoft.Json;
|
|
using System;
|
|
using System.IO;
|
|
using UnityEngine;
|
|
using Logger = Cryville.Common.Logging.Logger;
|
|
using unity = UnityEngine;
|
|
|
|
namespace Cryville.Crtr {
|
|
public static class Game {
|
|
public static string GameDataPath {
|
|
get;
|
|
private set;
|
|
}
|
|
public static readonly string FileProtocolPrefix
|
|
#if UNITY_STANDALONE_WIN
|
|
= "file:///";
|
|
#elif UNITY_ANDROID
|
|
= "file://";
|
|
#else
|
|
#error No file protocol prefix is defined.
|
|
#endif
|
|
public static IAudioDeviceManager AudioManager;
|
|
public static AudioClient AudioClient;
|
|
public static SimpleSequencerSource AudioSequencer;
|
|
public static SimpleSequencerSession AudioSession;
|
|
public static InputManager InputManager;
|
|
public static readonly NetworkTaskWorker NetworkTaskWorker = new NetworkTaskWorker();
|
|
|
|
public static readonly JsonSerializerSettings GlobalJsonSerializerSettings
|
|
= new JsonSerializerSettings() {
|
|
DefaultValueHandling = DefaultValueHandling.Ignore,
|
|
};
|
|
|
|
public static BufferedLogger MainLogger { get; private set; }
|
|
|
|
static bool _init;
|
|
public static void Init() {
|
|
if (_init) return;
|
|
_init = true;
|
|
|
|
bool _bcflag = new Version(Settings.Default.LastRunVersion) < new Version("0.4");
|
|
if (_bcflag) Settings.Default.Reset();
|
|
|
|
Logger.SetLogPath(Settings.Default.GameDataPath + "/logs");
|
|
MainLogger = new BufferedLogger();
|
|
Application.logMessageReceivedThreaded += OnLog;
|
|
Logger.Create("main", MainLogger);
|
|
|
|
if (_bcflag) Logger.Log("main", 2, "Game", "Reset all settings");
|
|
|
|
GameDataPath = Settings.Default.GameDataPath;
|
|
|
|
unity::Input.simulateMouseWithTouches = false;
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidAccelerometerHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidAccelerometerUncalibratedHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidGameRotationVectorHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidGravityHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidGyroscopeHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidLinearAccelerationHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidMagneticFieldHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidMagneticFieldUncalibratedHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidRotationVectorHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(AndroidTouchHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(UnityGuiInputHandler<UnityKeyReceiver>));
|
|
InputManager.HandlerRegistries.Add(typeof(UnityGuiInputHandler<UnityMouseReceiver>));
|
|
InputManager.HandlerRegistries.Add(typeof(UnityMouseHandler));
|
|
InputManager.HandlerRegistries.Add(typeof(UnityTouchHandler));
|
|
InputManager = new InputManager();
|
|
|
|
#if UNITY_EDITOR_WIN
|
|
ffmpeg.RootPath = Application.dataPath + "/Plugins/Windows";
|
|
#elif UNITY_STANDALONE_WIN
|
|
ffmpeg.RootPath = Application.dataPath + "/Plugins/x86_64";
|
|
#elif UNITY_ANDROID
|
|
ffmpeg.RootPath = "";
|
|
#else
|
|
#error No FFmpeg search path.
|
|
#endif
|
|
while (true) {
|
|
try {
|
|
AudioManager = EngineBuilder.Create();
|
|
if (AudioManager == null) {
|
|
Popup.Create("Cannot initialize audio engine");
|
|
Logger.Log("main", 5, "Audio", "Cannot initialize audio engine");
|
|
}
|
|
else {
|
|
Logger.Log("main", 1, "Audio", "Using audio API: {0}", AudioManager.GetType().Namespace);
|
|
AudioClient = AudioManager.GetDefaultDevice(DataFlow.Out).Connect();
|
|
AudioClient.Init(AudioClient.DefaultFormat);
|
|
AudioClient.Source = AudioSequencer = new SimpleSequencerSource();
|
|
AudioSession = AudioSequencer.NewSession();
|
|
AudioSequencer.Playing = true;
|
|
AudioClient.Start();
|
|
}
|
|
break;
|
|
}
|
|
catch (Exception ex) {
|
|
Logger.Log("main", 4, "Audio", "An error occurred when initializing the audio engine: {0}", ex);
|
|
Logger.Log("main", 2, "Audio", "Trying to use fallback audio engines");
|
|
EngineBuilder.Engines.Remove(AudioManager.GetType());
|
|
}
|
|
}
|
|
|
|
var dir = new DirectoryInfo(Settings.Default.GameDataPath + "/charts");
|
|
if (!dir.Exists || Settings.Default.LastRunVersion != Application.version) {
|
|
Directory.CreateDirectory(dir.FullName);
|
|
var defaultData = Resources.Load<TextAsset>("default");
|
|
using (var zip = ZipFile.Read(defaultData.bytes)) {
|
|
zip.ExtractExistingFile = ExtractExistingFileAction.OverwriteSilently;
|
|
zip.ExtractAll(Settings.Default.GameDataPath);
|
|
}
|
|
}
|
|
|
|
Settings.Default.LastRunVersion = Application.version;
|
|
Settings.Default.Save();
|
|
|
|
Logger.Log("main", 1, "UI", "Initializing font manager");
|
|
#if UNITY_EDITOR_WIN || UNITY_STANDALONE_WIN
|
|
var fontMatcher = new FallbackListFontMatcher(new FontManagerWindows());
|
|
fontMatcher.LoadDefaultWindowsFallbackList();
|
|
TMPAutoFont.FontMatcher = fontMatcher;
|
|
TMPAutoFont.DefaultShader = Resources.Load<Shader>("TextMesh Pro/Shaders/TMP_SDF SSD");
|
|
#elif UNITY_ANDROID
|
|
var fontMatcher = new FallbackListFontMatcher(new FontManagerAndroid());
|
|
fontMatcher.LoadDefaultAndroidFallbackList();
|
|
TMPAutoFont.FontMatcher = fontMatcher;
|
|
TMPAutoFont.DefaultShader = Resources.Load<Shader>("TextMesh Pro/Shaders/TMP_SDF-Mobile SSD");
|
|
#else
|
|
#error No font manager initialization logic.
|
|
#endif
|
|
|
|
Logger.Log("main", 1, "Game", "Initialized");
|
|
}
|
|
|
|
static bool _shutdown;
|
|
public static void Shutdown() {
|
|
if (_shutdown) return;
|
|
_shutdown = true;
|
|
|
|
Logger.Log("main", 1, "Game", "Shutting down");
|
|
try {
|
|
AudioClient.Dispose();
|
|
AudioSequencer.Dispose();
|
|
AudioManager.Dispose();
|
|
}
|
|
catch (Exception ex) {
|
|
LogException("Game", "An error occurred while shutting down", ex);
|
|
}
|
|
finally {
|
|
Logger.Close();
|
|
}
|
|
}
|
|
|
|
public static void LogException(string module, string prefix, Exception ex) {
|
|
Logger.Log("main", 4, module, "{0}: {1}", prefix, ex);
|
|
}
|
|
|
|
static void OnLog(string condition, string stackTrace, LogType type) {
|
|
int l;
|
|
switch (type) {
|
|
case LogType.Log: l = 1; break;
|
|
case LogType.Assert: l = 2; break;
|
|
case LogType.Warning: l = 3; break;
|
|
case LogType.Error:
|
|
case LogType.Exception: l = 4; break;
|
|
default: l = 1; break;
|
|
}
|
|
Logger.Log("main", l, "Internal", "{0}\n{1}", condition, stackTrace);
|
|
}
|
|
}
|
|
}
|