新增GamePadManager类,用于管理Unity手柄连接相关功能
This commit is contained in:
parent
864b5879e1
commit
35a5f03a66
@ -1,249 +1,253 @@
|
||||
using AxibugEmuOnline.Client.Manager;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using static AxibugEmuOnline.Client.HttpAPI;
|
||||
using static AxibugEmuOnline.Client.Manager.LogManager;
|
||||
|
||||
namespace AxibugEmuOnline.Client.ClientCore
|
||||
{
|
||||
public static class App
|
||||
{
|
||||
public static string TokenStr;
|
||||
public static string IP;
|
||||
public static int Port;
|
||||
public static LogManager log;
|
||||
public static NetworkHelper network;
|
||||
public static AppLogin login;
|
||||
public static AppChat chat;
|
||||
public static UserDataManager user;
|
||||
//public static AppNetGame netgame;
|
||||
public static AppEmu emu;
|
||||
using AxibugEmuOnline.Client.Manager;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using UnityEngine;
|
||||
using static AxibugEmuOnline.Client.HttpAPI;
|
||||
using static AxibugEmuOnline.Client.Manager.LogManager;
|
||||
|
||||
namespace AxibugEmuOnline.Client.ClientCore
|
||||
{
|
||||
public static class App
|
||||
{
|
||||
public static string TokenStr;
|
||||
public static string IP;
|
||||
public static int Port;
|
||||
public static LogManager log;
|
||||
public static NetworkHelper network;
|
||||
public static AppLogin login;
|
||||
public static AppChat chat;
|
||||
public static UserDataManager user;
|
||||
public static AppEmu emu;
|
||||
/// <summary>
|
||||
/// nes Rom库
|
||||
/// </summary>
|
||||
public static RomLib nesRomLib;
|
||||
/// </summary>
|
||||
public static RomLib nesRomLib;
|
||||
/// <summary>
|
||||
/// 收藏 Rom库
|
||||
/// </summary>
|
||||
public static RomLib starRomLib;
|
||||
public static HttpAPI httpAPI;
|
||||
public static CacheManager CacheMgr;
|
||||
public static AppRoom roomMgr;
|
||||
public static AppSettings settings;
|
||||
public static AppShare share;
|
||||
private static object gameSavMgr;
|
||||
static bool bTest;
|
||||
static string mTestSrvIP;
|
||||
#region Mono
|
||||
public static TickLoop tickLoop;
|
||||
private static CoroutineRunner coRunner;
|
||||
|
||||
#if UNITY_PSP2
|
||||
public static SonyVitaCommonDialog sonyVitaCommonDialog;
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#if UNITY_PSP2 && !UNITY_EDITOR //PSV真机
|
||||
public static string PersistentDataPath => "ux0:data/AxibugEmu";
|
||||
#else
|
||||
public static string PersistentDataPath => Application.persistentDataPath;
|
||||
#endif
|
||||
public static void Init(bool isTest = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "")
|
||||
{
|
||||
log = new LogManager(OnLogOut);
|
||||
|
||||
//其他平台必要的初始化
|
||||
if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
|
||||
{
|
||||
PSP2Init();
|
||||
}
|
||||
|
||||
settings = new AppSettings();
|
||||
network = new NetworkHelper();
|
||||
login = new AppLogin();
|
||||
chat = new AppChat();
|
||||
user = new UserDataManager();
|
||||
emu = new AppEmu();
|
||||
//netgame = new AppNetGame();
|
||||
httpAPI = new HttpAPI();
|
||||
if (bUseLocalWebApi)
|
||||
httpAPI.WebHost = mLocalWebApi;
|
||||
nesRomLib = new RomLib(RomPlatformType.Nes);
|
||||
starRomLib = new RomLib();
|
||||
CacheMgr = new CacheManager();
|
||||
roomMgr = new AppRoom();
|
||||
share = new AppShare();
|
||||
gameSavMgr = new AppGameSavMgr();
|
||||
bTest = isTest;
|
||||
mTestSrvIP = testSrvIP;
|
||||
var go = new GameObject("[AppAxibugEmuOnline]");
|
||||
GameObject.DontDestroyOnLoad(go);
|
||||
tickLoop = go.AddComponent<TickLoop>();
|
||||
coRunner = go.AddComponent<CoroutineRunner>();
|
||||
|
||||
|
||||
var importNode = GameObject.Find("IMPORTENT");
|
||||
if (importNode != null) GameObject.DontDestroyOnLoad(importNode);
|
||||
|
||||
StartCoroutine(AppTickFlow());
|
||||
RePullNetInfo();
|
||||
}
|
||||
|
||||
|
||||
private static void PSP2Init()
|
||||
{
|
||||
//PSVita最好手动创建目录
|
||||
if (!Directory.Exists(PersistentDataPath))
|
||||
Directory.CreateDirectory(PersistentDataPath);
|
||||
|
||||
#if UNITY_PSP2
|
||||
//创建PSV弹窗UI
|
||||
sonyVitaCommonDialog = new GameObject().AddComponent<SonyVitaCommonDialog>();
|
||||
//释放解码 FMV的26M内存,一般游戏用不上(PSP才用那破玩意儿)
|
||||
UnityEngine.PSVita.PSVitaVideoPlayer.TransferMemToMonoHeap();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private static IEnumerator AppTickFlow()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Tick();
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RePullNetInfo()
|
||||
{
|
||||
StartCoroutine(StartNetInit());
|
||||
}
|
||||
|
||||
static IEnumerator StartNetInit()
|
||||
{
|
||||
if (App.network.isConnected)
|
||||
yield break;
|
||||
|
||||
int platform = 0;
|
||||
if (bTest)
|
||||
{
|
||||
yield return null;
|
||||
Connect(mTestSrvIP, 10492);
|
||||
yield break;
|
||||
}
|
||||
|
||||
bool bHttpCheckDone = false;
|
||||
Resp_CheckStandInfo resp = null;
|
||||
while (true)
|
||||
{
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}");
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
bHttpCheckDone = false;
|
||||
}
|
||||
else if (request.downloadHandler.bHadErr)
|
||||
{
|
||||
bHttpCheckDone = false;
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);
|
||||
bHttpCheckDone = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
bHttpCheckDone = false;
|
||||
App.log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
//请求成功
|
||||
if (bHttpCheckDone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WaitForSeconds(1);
|
||||
App.log.Debug("请求失败,重试请求API...");
|
||||
}
|
||||
}
|
||||
|
||||
/*UnityWebRequest request = UnityWebRequest.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
yield break;
|
||||
|
||||
App.log.Debug($"ApiResp => {request.downloadHandler.text}");
|
||||
Resp_CheckStandInfo resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);*/
|
||||
|
||||
//需要更新
|
||||
if (resp.needUpdateClient == 1)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
yield return null;
|
||||
//Connect("127.0.0.1", 10492);
|
||||
Connect(resp.serverIp, resp.serverPort);
|
||||
}
|
||||
|
||||
private static void Tick()
|
||||
{
|
||||
nesRomLib.ExecuteFetchRomInfo();
|
||||
}
|
||||
|
||||
public static Coroutine StartCoroutine(IEnumerator itor)
|
||||
{
|
||||
return coRunner.StartCoroutine(itor);
|
||||
}
|
||||
|
||||
public static void StopCoroutine(Coroutine cor)
|
||||
{
|
||||
coRunner.StopCoroutine(cor);
|
||||
}
|
||||
|
||||
public static void Connect(string IP, int port)
|
||||
{
|
||||
Task task = new Task(() =>
|
||||
{
|
||||
network.Init(IP, port);
|
||||
});
|
||||
task.Start();
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
App.log.Info("停止");
|
||||
}
|
||||
static void OnLogOut(int LogLevel, string msg)
|
||||
{
|
||||
E_LogType logType = (E_LogType)LogLevel;
|
||||
switch (logType)
|
||||
{
|
||||
case E_LogType.Debug:
|
||||
case E_LogType.Info:
|
||||
Debug.Log("[AxiNet]:" + msg);
|
||||
break;
|
||||
case E_LogType.Warning:
|
||||
Debug.LogWarning("[AxiNet]:" + msg);
|
||||
break;
|
||||
case E_LogType.Error:
|
||||
Debug.LogError("[AxiNet]:" + msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/// </summary>
|
||||
public static RomLib starRomLib;
|
||||
public static HttpAPI httpAPI;
|
||||
public static CacheManager CacheMgr;
|
||||
public static AppRoom roomMgr;
|
||||
public static AppSettings settings;
|
||||
public static AppShare share;
|
||||
public static GamePadManager gamePadMgr;
|
||||
private static object gameSavMgr;
|
||||
static bool bTest;
|
||||
static string mTestSrvIP;
|
||||
#region Mono
|
||||
public static TickLoop tickLoop;
|
||||
private static CoroutineRunner coRunner;
|
||||
|
||||
#if UNITY_PSP2
|
||||
public static SonyVitaCommonDialog sonyVitaCommonDialog;
|
||||
#endif
|
||||
|
||||
#endregion
|
||||
|
||||
#if UNITY_PSP2 && !UNITY_EDITOR //PSV真机
|
||||
public static string PersistentDataPath => "ux0:data/AxibugEmu";
|
||||
#else
|
||||
public static string PersistentDataPath => Application.persistentDataPath;
|
||||
#endif
|
||||
public static void Init(bool isTest = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "")
|
||||
{
|
||||
log = new LogManager(OnLogOut);
|
||||
|
||||
//其他平台必要的初始化
|
||||
if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
|
||||
{
|
||||
PSP2Init();
|
||||
}
|
||||
|
||||
settings = new AppSettings();
|
||||
network = new NetworkHelper();
|
||||
login = new AppLogin();
|
||||
chat = new AppChat();
|
||||
user = new UserDataManager();
|
||||
emu = new AppEmu();
|
||||
httpAPI = new HttpAPI();
|
||||
if (bUseLocalWebApi)
|
||||
httpAPI.WebHost = mLocalWebApi;
|
||||
nesRomLib = new RomLib(RomPlatformType.Nes);
|
||||
starRomLib = new RomLib();
|
||||
CacheMgr = new CacheManager();
|
||||
roomMgr = new AppRoom();
|
||||
share = new AppShare();
|
||||
gameSavMgr = new AppGameSavMgr();
|
||||
gamePadMgr = new GamePadManager();
|
||||
|
||||
bTest = isTest;
|
||||
mTestSrvIP = testSrvIP;
|
||||
var go = new GameObject("[AppAxibugEmuOnline]");
|
||||
GameObject.DontDestroyOnLoad(go);
|
||||
tickLoop = go.AddComponent<TickLoop>();
|
||||
coRunner = go.AddComponent<CoroutineRunner>();
|
||||
|
||||
|
||||
var importNode = GameObject.Find("IMPORTENT");
|
||||
if (importNode != null) GameObject.DontDestroyOnLoad(importNode);
|
||||
|
||||
StartCoroutine(AppTickFlow());
|
||||
RePullNetInfo();
|
||||
}
|
||||
|
||||
|
||||
private static void PSP2Init()
|
||||
{
|
||||
//PSVita最好手动创建目录
|
||||
if (!Directory.Exists(PersistentDataPath))
|
||||
Directory.CreateDirectory(PersistentDataPath);
|
||||
|
||||
#if UNITY_PSP2
|
||||
//创建PSV弹窗UI
|
||||
sonyVitaCommonDialog = new GameObject().AddComponent<SonyVitaCommonDialog>();
|
||||
//释放解码 FMV的26M内存,一般游戏用不上(PSP才用那破玩意儿)
|
||||
UnityEngine.PSVita.PSVitaVideoPlayer.TransferMemToMonoHeap();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
private static IEnumerator AppTickFlow()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
Tick();
|
||||
yield return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void RePullNetInfo()
|
||||
{
|
||||
StartCoroutine(StartNetInit());
|
||||
}
|
||||
|
||||
static IEnumerator StartNetInit()
|
||||
{
|
||||
if (App.network.isConnected)
|
||||
yield break;
|
||||
|
||||
int platform = 0;
|
||||
if (bTest)
|
||||
{
|
||||
yield return null;
|
||||
Connect(mTestSrvIP, 10492);
|
||||
yield break;
|
||||
}
|
||||
|
||||
bool bHttpCheckDone = false;
|
||||
Resp_CheckStandInfo resp = null;
|
||||
while (true)
|
||||
{
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}");
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
bHttpCheckDone = false;
|
||||
}
|
||||
else if (request.downloadHandler.bHadErr)
|
||||
{
|
||||
bHttpCheckDone = false;
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);
|
||||
bHttpCheckDone = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
bHttpCheckDone = false;
|
||||
App.log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
//请求成功
|
||||
if (bHttpCheckDone)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
yield return new WaitForSeconds(1);
|
||||
App.log.Debug("请求失败,重试请求API...");
|
||||
}
|
||||
}
|
||||
|
||||
/*UnityWebRequest request = UnityWebRequest.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
yield break;
|
||||
|
||||
App.log.Debug($"ApiResp => {request.downloadHandler.text}");
|
||||
Resp_CheckStandInfo resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);*/
|
||||
|
||||
//需要更新
|
||||
if (resp.needUpdateClient == 1)
|
||||
{
|
||||
//TODO
|
||||
}
|
||||
|
||||
yield return null;
|
||||
//Connect("127.0.0.1", 10492);
|
||||
Connect(resp.serverIp, resp.serverPort);
|
||||
}
|
||||
|
||||
private static void Tick()
|
||||
{
|
||||
nesRomLib.ExecuteFetchRomInfo();
|
||||
starRomLib.ExecuteFetchRomInfo();
|
||||
|
||||
gamePadMgr.Update();
|
||||
}
|
||||
|
||||
public static Coroutine StartCoroutine(IEnumerator itor)
|
||||
{
|
||||
return coRunner.StartCoroutine(itor);
|
||||
}
|
||||
|
||||
public static void StopCoroutine(Coroutine cor)
|
||||
{
|
||||
coRunner.StopCoroutine(cor);
|
||||
}
|
||||
|
||||
public static void Connect(string IP, int port)
|
||||
{
|
||||
Task task = new Task(() =>
|
||||
{
|
||||
network.Init(IP, port);
|
||||
});
|
||||
task.Start();
|
||||
}
|
||||
|
||||
public static void Close()
|
||||
{
|
||||
App.log.Info("停止");
|
||||
}
|
||||
static void OnLogOut(int LogLevel, string msg)
|
||||
{
|
||||
E_LogType logType = (E_LogType)LogLevel;
|
||||
switch (logType)
|
||||
{
|
||||
case E_LogType.Debug:
|
||||
case E_LogType.Info:
|
||||
Debug.Log("[AxiNet]:" + msg);
|
||||
break;
|
||||
case E_LogType.Warning:
|
||||
Debug.LogWarning("[AxiNet]:" + msg);
|
||||
break;
|
||||
case E_LogType.Error:
|
||||
Debug.LogError("[AxiNet]:" + msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,50 +1,51 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class Initer : MonoBehaviour
|
||||
{
|
||||
static GlobalRef m_refs;
|
||||
public static CanvasGroup FilterPreview => m_refs.FilterPreview;
|
||||
public static CanvasGroup XMBBg => m_refs.XMBBg;
|
||||
|
||||
public static string dev_UUID;
|
||||
|
||||
[SerializeField]
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class Initer : MonoBehaviour
|
||||
{
|
||||
static GlobalRef m_refs;
|
||||
public static CanvasGroup FilterPreview => m_refs.FilterPreview;
|
||||
public static CanvasGroup XMBBg => m_refs.XMBBg;
|
||||
|
||||
public static string dev_UUID;
|
||||
|
||||
[SerializeField]
|
||||
GameObject IMPORTENT;
|
||||
|
||||
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public bool bTestSkipWebApiToConServer = false;
|
||||
public string mTestSrvIP = "192.168.0.47";
|
||||
public bool bUseLocalWebApi = false;
|
||||
public string mLocalWebApi = "http://localhost:5051";
|
||||
public bool bEditorUUID = false;
|
||||
#endif
|
||||
|
||||
private void Awake()
|
||||
#if UNITY_EDITOR
|
||||
public bool bTestSkipWebApiToConServer = false;
|
||||
public string mTestSrvIP = "192.168.0.47";
|
||||
public bool bUseLocalWebApi = false;
|
||||
public string mLocalWebApi = "http://localhost:5051";
|
||||
public bool bEditorUUID = false;
|
||||
#endif
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
App.Init(bTestSkipWebApiToConServer, mTestSrvIP, bUseLocalWebApi,mLocalWebApi);
|
||||
dev_UUID = SystemInfo.deviceUniqueIdentifier;
|
||||
#if UNITY_EDITOR
|
||||
App.Init(bTestSkipWebApiToConServer, mTestSrvIP, bUseLocalWebApi,mLocalWebApi);
|
||||
dev_UUID = SystemInfo.deviceUniqueIdentifier;
|
||||
if (bEditorUUID)
|
||||
{
|
||||
dev_UUID += "_Editor";
|
||||
}
|
||||
#else
|
||||
App.Init(this);
|
||||
dev_UUID = SystemInfo.deviceUniqueIdentifier;
|
||||
#endif
|
||||
|
||||
{
|
||||
dev_UUID += "_Editor";
|
||||
}
|
||||
#else
|
||||
App.Init(this);
|
||||
dev_UUID = SystemInfo.deviceUniqueIdentifier;
|
||||
#endif
|
||||
|
||||
m_refs = Instantiate(IMPORTENT, transform).GetComponent<GlobalRef>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
App.settings.Filter.ShutDownFilterPreview();
|
||||
App.settings.Filter.ShutDownFilter();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,160 +1,160 @@
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using AxibugEmuOnline.Client;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
public abstract class FilterChainEffect : FilterEffect
|
||||
{
|
||||
#region SealedForDisable
|
||||
protected sealed override string ShaderName => null;
|
||||
protected sealed override void OnInit(Material renderMat) { }
|
||||
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using AxibugEmuOnline.Client;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
|
||||
public abstract class FilterChainEffect : FilterEffect
|
||||
{
|
||||
#region SealedForDisable
|
||||
protected sealed override string ShaderName => null;
|
||||
protected sealed override void OnInit(Material renderMat) { }
|
||||
|
||||
public sealed override void Render(Texture src, RenderTexture result)
|
||||
{
|
||||
OnRenderer(src, result);
|
||||
}
|
||||
protected sealed override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { }
|
||||
#endregion
|
||||
|
||||
List<PassDefine> m_passes = new List<PassDefine>();
|
||||
|
||||
static int Original;
|
||||
static int OriginalSize;
|
||||
static int Source;
|
||||
static int SourceSize;
|
||||
static int FrameCount;
|
||||
static int OutputSize;
|
||||
|
||||
List<int> m_passOutputTexNames = new List<int>();
|
||||
List<int> m_passOutputTexSizes = new List<int>();
|
||||
|
||||
static FilterChainEffect()
|
||||
{
|
||||
Original = Shader.PropertyToID(nameof(Original));
|
||||
OriginalSize = Shader.PropertyToID(nameof(OriginalSize));
|
||||
Source = Shader.PropertyToID(nameof(Source));
|
||||
SourceSize = Shader.PropertyToID(nameof(SourceSize));
|
||||
FrameCount = Shader.PropertyToID(nameof(FrameCount));
|
||||
OutputSize = Shader.PropertyToID(nameof(OutputSize));
|
||||
}
|
||||
|
||||
protected sealed override void Init()
|
||||
{
|
||||
DefinePasses(ref m_passes);
|
||||
for (int i = 0; i < m_passes.Count; i++)
|
||||
{
|
||||
m_passes[i].Init(i);
|
||||
m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].NormalOutputTextureName));
|
||||
m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].NormalOutputTextureName}Size"));
|
||||
OnRenderer(src, result);
|
||||
}
|
||||
protected sealed override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { }
|
||||
#endregion
|
||||
|
||||
List<PassDefine> m_passes = new List<PassDefine>();
|
||||
|
||||
static int Original;
|
||||
static int OriginalSize;
|
||||
static int Source;
|
||||
static int SourceSize;
|
||||
static int FrameCount;
|
||||
static int OutputSize;
|
||||
|
||||
List<int> m_passOutputTexNames = new List<int>();
|
||||
List<int> m_passOutputTexSizes = new List<int>();
|
||||
|
||||
static FilterChainEffect()
|
||||
{
|
||||
Original = Shader.PropertyToID(nameof(Original));
|
||||
OriginalSize = Shader.PropertyToID(nameof(OriginalSize));
|
||||
Source = Shader.PropertyToID(nameof(Source));
|
||||
SourceSize = Shader.PropertyToID(nameof(SourceSize));
|
||||
FrameCount = Shader.PropertyToID(nameof(FrameCount));
|
||||
OutputSize = Shader.PropertyToID(nameof(OutputSize));
|
||||
}
|
||||
|
||||
protected sealed override void Init()
|
||||
{
|
||||
DefinePasses(ref m_passes);
|
||||
for (int i = 0; i < m_passes.Count; i++)
|
||||
{
|
||||
m_passes[i].Init(i);
|
||||
m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].NormalOutputTextureName));
|
||||
m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].NormalOutputTextureName}Size"));
|
||||
if (m_passes[i].AliasOutputTextureName != null)
|
||||
{
|
||||
m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].AliasOutputTextureName));
|
||||
m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].AliasOutputTextureName}Size"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<int, RenderTexture> m_outputCaches = new Dictionary<int, RenderTexture>();
|
||||
private void OnRenderer(Texture input, RenderTexture finalOut)
|
||||
{
|
||||
m_outputCaches.Clear();
|
||||
|
||||
Vector4 originalSize = new Vector4(input.width, input.height, 1f / input.width, 1f / input.height);
|
||||
|
||||
Texture lastoutput = input;
|
||||
for (int i = 0; i < m_passes.Count; i++)
|
||||
{
|
||||
var pass = m_passes[i];
|
||||
pass.OnRender();
|
||||
|
||||
pass.Mat.SetTexture(Original, input);
|
||||
pass.Mat.SetVector(OriginalSize, originalSize);
|
||||
pass.Mat.SetTexture(Source, lastoutput);
|
||||
m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].AliasOutputTextureName}Size"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dictionary<int, RenderTexture> m_outputCaches = new Dictionary<int, RenderTexture>();
|
||||
private void OnRenderer(Texture input, RenderTexture finalOut)
|
||||
{
|
||||
m_outputCaches.Clear();
|
||||
|
||||
Vector4 originalSize = new Vector4(input.width, input.height, 1f / input.width, 1f / input.height);
|
||||
|
||||
Texture lastoutput = input;
|
||||
for (int i = 0; i < m_passes.Count; i++)
|
||||
{
|
||||
var pass = m_passes[i];
|
||||
pass.OnRender();
|
||||
|
||||
pass.Mat.SetTexture(Original, input);
|
||||
pass.Mat.SetVector(OriginalSize, originalSize);
|
||||
pass.Mat.SetTexture(Source, lastoutput);
|
||||
pass.Mat.SetVector(SourceSize, new Vector4(lastoutput.width, lastoutput.height, 1f / lastoutput.width, 1f / lastoutput.height));
|
||||
pass.Mat.SetFloat(FrameCount, Time.frameCount);
|
||||
|
||||
for (int index = 0; index < m_passOutputTexNames.Count; index++)
|
||||
{
|
||||
var existoutput = m_passOutputTexNames[index];
|
||||
var existoutputSize = m_passOutputTexSizes[index];
|
||||
pass.Mat.SetFloat(FrameCount, Time.frameCount);
|
||||
|
||||
for (int index = 0; index < m_passOutputTexNames.Count; index++)
|
||||
{
|
||||
var existoutput = m_passOutputTexNames[index];
|
||||
var existoutputSize = m_passOutputTexSizes[index];
|
||||
if (m_outputCaches.TryGetValue(existoutput, out var passOutput))
|
||||
{
|
||||
if (pass.Mat.HasTexture(existoutput))
|
||||
pass.Mat.SetTexture(existoutput, passOutput);
|
||||
if (pass.Mat.HasVector(existoutputSize))
|
||||
pass.Mat.SetVector(existoutputSize, new Vector4(passOutput.width, passOutput.height, 1f / passOutput.width, 1f / passOutput.height));
|
||||
}
|
||||
}
|
||||
|
||||
pass.Mat.SetVector(existoutputSize, new Vector4(passOutput.width, passOutput.height, 1f / passOutput.width, 1f / passOutput.height));
|
||||
}
|
||||
}
|
||||
|
||||
var output = pass.GetOutput(input, lastoutput, finalOut);
|
||||
|
||||
pass.Mat.SetVector(OutputSize, new Vector4(output.width, output.height, 1f / output.width, 1f / output.height));
|
||||
|
||||
m_outputCaches[pass.NormalOutputTextureName_PID] = output;
|
||||
if (pass.AliasOutputTextureName != null) m_outputCaches[pass.AliasOutputTextureName_PID] = output;
|
||||
|
||||
Graphics.Blit(lastoutput, output, pass.Mat);
|
||||
|
||||
lastoutput = output;
|
||||
}
|
||||
|
||||
Graphics.Blit(lastoutput, finalOut);
|
||||
|
||||
foreach (var rt in m_outputCaches.Values)
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
|
||||
protected abstract void DefinePasses(ref List<PassDefine> passes);
|
||||
|
||||
public class PassDefine
|
||||
pass.Mat.SetVector(OutputSize, new Vector4(output.width, output.height, 1f / output.width, 1f / output.height));
|
||||
|
||||
m_outputCaches[pass.NormalOutputTextureName_PID] = output;
|
||||
if (pass.AliasOutputTextureName != null) m_outputCaches[pass.AliasOutputTextureName_PID] = output;
|
||||
|
||||
Graphics.Blit(lastoutput, output, pass.Mat);
|
||||
|
||||
lastoutput = output;
|
||||
}
|
||||
|
||||
Graphics.Blit(lastoutput, finalOut);
|
||||
|
||||
foreach (var rt in m_outputCaches.Values)
|
||||
RenderTexture.ReleaseTemporary(rt);
|
||||
}
|
||||
|
||||
protected abstract void DefinePasses(ref List<PassDefine> passes);
|
||||
|
||||
public class PassDefine
|
||||
{
|
||||
public string ShaderName { get; private set; }
|
||||
public FilterMode FilterMode { get; private set; }
|
||||
public TextureWrapMode WrapMode { get; private set; }
|
||||
public string ShaderName { get; private set; }
|
||||
public FilterMode FilterMode { get; private set; }
|
||||
public TextureWrapMode WrapMode { get; private set; }
|
||||
public EnumScaleMode ScaleModeX { get; private set; }
|
||||
public EnumScaleMode ScaleModeY { get; private set; }
|
||||
public float ScaleX { get; private set; }
|
||||
public float ScaleY { get; private set; }
|
||||
public string AliasOutputTextureName { get; private set; }
|
||||
public int AliasOutputTextureName_PID { get; private set; }
|
||||
public string NormalOutputTextureName { get; private set; }
|
||||
public int NormalOutputTextureName_PID { get; private set; }
|
||||
public EnumScaleMode ScaleModeY { get; private set; }
|
||||
public float ScaleX { get; private set; }
|
||||
public float ScaleY { get; private set; }
|
||||
public string AliasOutputTextureName { get; private set; }
|
||||
public int AliasOutputTextureName_PID { get; private set; }
|
||||
public string NormalOutputTextureName { get; private set; }
|
||||
public int NormalOutputTextureName_PID { get; private set; }
|
||||
public bool sRGB { get; private set; }
|
||||
|
||||
private PassDefine() { }
|
||||
|
||||
public static PassDefine Create(
|
||||
string shaderName,
|
||||
FilterMode filterMode = FilterMode.Point,
|
||||
TextureWrapMode wrapMode = TextureWrapMode.Clamp,
|
||||
EnumScaleMode scaleModeX = EnumScaleMode.Source, EnumScaleMode scaleModeY = EnumScaleMode.Source, float scaleX = 1f, float scaleY = 1f,
|
||||
string outputAlias = null,
|
||||
bool sRGB = false
|
||||
)
|
||||
{
|
||||
return new PassDefine()
|
||||
{
|
||||
ShaderName = shaderName,
|
||||
FilterMode = filterMode,
|
||||
WrapMode = wrapMode,
|
||||
ScaleModeX = scaleModeX,
|
||||
ScaleModeY = scaleModeY,
|
||||
ScaleX = scaleX,
|
||||
ScaleY = scaleY,
|
||||
AliasOutputTextureName = outputAlias,
|
||||
sRGB = sRGB,
|
||||
};
|
||||
}
|
||||
|
||||
private Dictionary<string, FilterParameter> m_linkingParams = new Dictionary<string, FilterParameter>();
|
||||
|
||||
private PassDefine() { }
|
||||
|
||||
public static PassDefine Create(
|
||||
string shaderName,
|
||||
FilterMode filterMode = FilterMode.Point,
|
||||
TextureWrapMode wrapMode = TextureWrapMode.Clamp,
|
||||
EnumScaleMode scaleModeX = EnumScaleMode.Source, EnumScaleMode scaleModeY = EnumScaleMode.Source, float scaleX = 1f, float scaleY = 1f,
|
||||
string outputAlias = null,
|
||||
bool sRGB = false
|
||||
)
|
||||
{
|
||||
return new PassDefine()
|
||||
{
|
||||
ShaderName = shaderName,
|
||||
FilterMode = filterMode,
|
||||
WrapMode = wrapMode,
|
||||
ScaleModeX = scaleModeX,
|
||||
ScaleModeY = scaleModeY,
|
||||
ScaleX = scaleX,
|
||||
ScaleY = scaleY,
|
||||
AliasOutputTextureName = outputAlias,
|
||||
sRGB = sRGB,
|
||||
};
|
||||
}
|
||||
|
||||
private Dictionary<string, FilterParameter> m_linkingParams = new Dictionary<string, FilterParameter>();
|
||||
public PassDefine SetParameters(string shaderValName, FilterParameter para)
|
||||
{
|
||||
m_linkingParams[shaderValName] = para;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int PassIndex { get; private set; }
|
||||
}
|
||||
|
||||
public int PassIndex { get; private set; }
|
||||
public Material Mat { get; private set; }
|
||||
|
||||
public void OnRender()
|
||||
@ -167,63 +167,63 @@ public abstract class FilterChainEffect : FilterEffect
|
||||
if (valType == typeof(float))
|
||||
Mat.SetFloat(paraName, (float)val);
|
||||
}
|
||||
}
|
||||
internal void Init(int passIndex)
|
||||
{
|
||||
Mat = new Material(Shader.Find(ShaderName));
|
||||
PassIndex = passIndex;
|
||||
NormalOutputTextureName = $"PassOutput{passIndex}";
|
||||
NormalOutputTextureName_PID = Shader.PropertyToID(NormalOutputTextureName);
|
||||
|
||||
if (AliasOutputTextureName != null) AliasOutputTextureName_PID = Shader.PropertyToID(AliasOutputTextureName);
|
||||
}
|
||||
|
||||
internal RenderTexture GetOutput(Texture original, Texture source, Texture final)
|
||||
{
|
||||
int width = 0;
|
||||
switch (ScaleModeX)
|
||||
{
|
||||
case EnumScaleMode.Viewport:
|
||||
width = (int)(final.width * ScaleX);
|
||||
break;
|
||||
case EnumScaleMode.Source:
|
||||
width = (int)(source.width * ScaleX);
|
||||
break;
|
||||
case EnumScaleMode.Absolute:
|
||||
width = (int)ScaleX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
internal void Init(int passIndex)
|
||||
{
|
||||
Mat = new Material(Shader.Find(ShaderName));
|
||||
PassIndex = passIndex;
|
||||
NormalOutputTextureName = $"PassOutput{passIndex}";
|
||||
NormalOutputTextureName_PID = Shader.PropertyToID(NormalOutputTextureName);
|
||||
|
||||
if (AliasOutputTextureName != null) AliasOutputTextureName_PID = Shader.PropertyToID(AliasOutputTextureName);
|
||||
}
|
||||
|
||||
internal RenderTexture GetOutput(Texture original, Texture source, Texture final)
|
||||
{
|
||||
int width = 0;
|
||||
switch (ScaleModeX)
|
||||
{
|
||||
case EnumScaleMode.Viewport:
|
||||
width = (int)(final.width * ScaleX);
|
||||
break;
|
||||
case EnumScaleMode.Source:
|
||||
width = (int)(source.width * ScaleX);
|
||||
break;
|
||||
case EnumScaleMode.Absolute:
|
||||
width = (int)ScaleX;
|
||||
break;
|
||||
}
|
||||
int height = 0;
|
||||
switch (ScaleModeY)
|
||||
{
|
||||
case EnumScaleMode.Viewport:
|
||||
height = (int)(final.height * ScaleY);
|
||||
break;
|
||||
case EnumScaleMode.Source:
|
||||
height = (int)(source.height * ScaleY);
|
||||
break;
|
||||
case EnumScaleMode.Absolute:
|
||||
height = (int)ScaleY;
|
||||
break;
|
||||
}
|
||||
|
||||
//if (sRGB) format = GraphicsFormat.R8G8B8A8_SRGB;
|
||||
switch (ScaleModeY)
|
||||
{
|
||||
case EnumScaleMode.Viewport:
|
||||
height = (int)(final.height * ScaleY);
|
||||
break;
|
||||
case EnumScaleMode.Source:
|
||||
height = (int)(source.height * ScaleY);
|
||||
break;
|
||||
case EnumScaleMode.Absolute:
|
||||
height = (int)ScaleY;
|
||||
break;
|
||||
}
|
||||
|
||||
//if (sRGB) format = GraphicsFormat.R8G8B8A8_SRGB;
|
||||
var rt = RenderTexture.GetTemporary(width, height, 0, GraphicsFormat.R8G8B8A8_UNorm, 1);
|
||||
|
||||
rt.wrapMode = WrapMode;
|
||||
rt.filterMode = FilterMode;
|
||||
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
|
||||
public enum EnumScaleMode
|
||||
{
|
||||
/// <summary> 以输入源为缩放基准 </summary
|
||||
Source,
|
||||
/// <summary> 以分辨率作为缩放基准 </summary
|
||||
Viewport,
|
||||
/// <summary> 以固定值定义尺寸 </summary
|
||||
Absolute
|
||||
}
|
||||
}
|
||||
rt.wrapMode = WrapMode;
|
||||
rt.filterMode = FilterMode;
|
||||
|
||||
return rt;
|
||||
}
|
||||
}
|
||||
|
||||
public enum EnumScaleMode
|
||||
{
|
||||
/// <summary> 以输入源为缩放基准 </summary
|
||||
Source,
|
||||
/// <summary> 以分辨率作为缩放基准 </summary
|
||||
Viewport,
|
||||
/// <summary> 以固定值定义尺寸 </summary
|
||||
Absolute
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5fe26f58ab822c44888b86305c5326e0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,26 @@
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
public partial class GamePadManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 被Unity所识别的通用GamePad类
|
||||
/// </summary>
|
||||
public class GamePad
|
||||
{
|
||||
internal GamePadInfo m_info;
|
||||
public int Index => m_info.Index;
|
||||
public string Name => m_info.Name;
|
||||
public bool Offline { get; internal set; }
|
||||
|
||||
internal GamePad(GamePadInfo info)
|
||||
{
|
||||
m_info = info;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{Index}:{Name}{(Offline ? "(Offline)" : string.Empty)}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c2c0a06020f65a747af5490a6112361b
|
@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
public partial class GamePadManager
|
||||
{
|
||||
#region Events
|
||||
public delegate void GamePadConnectedHandle(GamePad newConnectGamePad);
|
||||
/// <summary> 当一个手柄连接时触发 </summary>
|
||||
public event GamePadConnectedHandle OnGamePadConnected;
|
||||
|
||||
public delegate void GamePadDisConnectedHandle(GamePad disConnectGamePad);
|
||||
/// <summary> 当一个手柄断开时触发 </summary>
|
||||
public event GamePadDisConnectedHandle OnGamePadDisConnected;
|
||||
#endregion
|
||||
|
||||
Dictionary<GamePadInfo, GamePad> m_gamePads = new Dictionary<GamePadInfo, GamePad>();
|
||||
HashSet<GamePadInfo> m_temp = new HashSet<GamePadInfo>();
|
||||
|
||||
public void Update()
|
||||
{
|
||||
m_temp.Clear();
|
||||
foreach (var info in m_gamePads.Keys)
|
||||
m_temp.Add(info); //记录需要被移除的手柄
|
||||
|
||||
var devices = Input.GetJoystickNames();
|
||||
for (int i = 0; i < devices.Length; i++)
|
||||
{
|
||||
var info = new GamePadInfo { Index = i, Name = devices[i] };
|
||||
m_temp.Remove(info);
|
||||
|
||||
if (!m_gamePads.ContainsKey(info))
|
||||
{
|
||||
m_gamePads[info] = new GamePad(info);
|
||||
OnGamePadConnected?.Invoke(m_gamePads[info]);
|
||||
};
|
||||
}
|
||||
|
||||
foreach (var info in m_temp)
|
||||
{
|
||||
if (m_gamePads.TryGetValue(info, out GamePad gp))
|
||||
{
|
||||
m_gamePads.Remove(info);
|
||||
gp.Offline = true;
|
||||
OnGamePadDisConnected?.Invoke(gp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有已连接的手柄,返回的结果顺序与手柄序号无关
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public GamePad[] GetGamePads()
|
||||
{
|
||||
return m_gamePads.Values.ToArray();
|
||||
}
|
||||
|
||||
internal struct GamePadInfo : IEquatable<GamePadInfo>, IComparable<GamePadInfo>
|
||||
{
|
||||
internal int Index;
|
||||
internal string Name;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is GamePadInfo)
|
||||
{
|
||||
return Equals((GamePadInfo)obj);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Equals(GamePadInfo other)
|
||||
{
|
||||
return Index == other.Index && Name == other.Name;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// Custom hash code implementation without HashCombine
|
||||
int hash = 17;
|
||||
hash = hash * 31 + Index.GetHashCode();
|
||||
hash = hash * 31 + (Name != null ? Name.GetHashCode() : 0);
|
||||
return hash;
|
||||
}
|
||||
|
||||
public int CompareTo(GamePadInfo other)
|
||||
{
|
||||
int indexComparison = Index.CompareTo(other.Index);
|
||||
if (indexComparison != 0)
|
||||
{
|
||||
return indexComparison;
|
||||
}
|
||||
return string.Compare(Name, other.Name, StringComparison.Ordinal);
|
||||
}
|
||||
|
||||
public static bool operator ==(GamePadInfo left, GamePadInfo right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(GamePadInfo left, GamePadInfo right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
public static bool operator <(GamePadInfo left, GamePadInfo right)
|
||||
{
|
||||
return left.CompareTo(right) < 0;
|
||||
}
|
||||
|
||||
public static bool operator >(GamePadInfo left, GamePadInfo right)
|
||||
{
|
||||
return left.CompareTo(right) > 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ce4d215abea527e4a8cf1103cbfecf6b
|
Loading…
Reference in New Issue
Block a user