新增GamePadManager类,用于管理Unity手柄连接相关功能

This commit is contained in:
Alienjack 2025-01-10 23:17:09 +08:00
parent 864b5879e1
commit 35a5f03a66
8 changed files with 641 additions and 477 deletions

View File

@ -1,249 +1,253 @@
using AxibugEmuOnline.Client.Manager; using AxibugEmuOnline.Client.Manager;
using AxibugEmuOnline.Client.Network; using AxibugEmuOnline.Client.Network;
using AxibugProtobuf; using AxibugProtobuf;
using System; using System;
using System.Collections; using System.Collections;
using System.IO; using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using UnityEngine; using UnityEngine;
using static AxibugEmuOnline.Client.HttpAPI; using static AxibugEmuOnline.Client.HttpAPI;
using static AxibugEmuOnline.Client.Manager.LogManager; using static AxibugEmuOnline.Client.Manager.LogManager;
namespace AxibugEmuOnline.Client.ClientCore namespace AxibugEmuOnline.Client.ClientCore
{ {
public static class App public static class App
{ {
public static string TokenStr; public static string TokenStr;
public static string IP; public static string IP;
public static int Port; public static int Port;
public static LogManager log; public static LogManager log;
public static NetworkHelper network; public static NetworkHelper network;
public static AppLogin login; public static AppLogin login;
public static AppChat chat; public static AppChat chat;
public static UserDataManager user; public static UserDataManager user;
//public static AppNetGame netgame; public static AppEmu emu;
public static AppEmu emu;
/// <summary> /// <summary>
/// nes Rom库 /// nes Rom库
/// </summary> /// </summary>
public static RomLib nesRomLib; public static RomLib nesRomLib;
/// <summary> /// <summary>
/// 收藏 Rom库 /// 收藏 Rom库
/// </summary> /// </summary>
public static RomLib starRomLib; public static RomLib starRomLib;
public static HttpAPI httpAPI; public static HttpAPI httpAPI;
public static CacheManager CacheMgr; public static CacheManager CacheMgr;
public static AppRoom roomMgr; public static AppRoom roomMgr;
public static AppSettings settings; public static AppSettings settings;
public static AppShare share; public static AppShare share;
private static object gameSavMgr; public static GamePadManager gamePadMgr;
static bool bTest; private static object gameSavMgr;
static string mTestSrvIP; static bool bTest;
#region Mono static string mTestSrvIP;
public static TickLoop tickLoop; #region Mono
private static CoroutineRunner coRunner; public static TickLoop tickLoop;
private static CoroutineRunner coRunner;
#if UNITY_PSP2
public static SonyVitaCommonDialog sonyVitaCommonDialog; #if UNITY_PSP2
#endif public static SonyVitaCommonDialog sonyVitaCommonDialog;
#endif
#endregion
#endregion
#if UNITY_PSP2 && !UNITY_EDITOR //PSV真机
public static string PersistentDataPath => "ux0:data/AxibugEmu"; #if UNITY_PSP2 && !UNITY_EDITOR //PSV真机
#else public static string PersistentDataPath => "ux0:data/AxibugEmu";
public static string PersistentDataPath => Application.persistentDataPath; #else
#endif public static string PersistentDataPath => Application.persistentDataPath;
public static void Init(bool isTest = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "") #endif
{ public static void Init(bool isTest = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "")
log = new LogManager(OnLogOut); {
log = new LogManager(OnLogOut);
//其他平台必要的初始化
if (UnityEngine.Application.platform == RuntimePlatform.PSP2) //其他平台必要的初始化
{ if (UnityEngine.Application.platform == RuntimePlatform.PSP2)
PSP2Init(); {
} PSP2Init();
}
settings = new AppSettings();
network = new NetworkHelper(); settings = new AppSettings();
login = new AppLogin(); network = new NetworkHelper();
chat = new AppChat(); login = new AppLogin();
user = new UserDataManager(); chat = new AppChat();
emu = new AppEmu(); user = new UserDataManager();
//netgame = new AppNetGame(); emu = new AppEmu();
httpAPI = new HttpAPI(); httpAPI = new HttpAPI();
if (bUseLocalWebApi) if (bUseLocalWebApi)
httpAPI.WebHost = mLocalWebApi; httpAPI.WebHost = mLocalWebApi;
nesRomLib = new RomLib(RomPlatformType.Nes); nesRomLib = new RomLib(RomPlatformType.Nes);
starRomLib = new RomLib(); starRomLib = new RomLib();
CacheMgr = new CacheManager(); CacheMgr = new CacheManager();
roomMgr = new AppRoom(); roomMgr = new AppRoom();
share = new AppShare(); share = new AppShare();
gameSavMgr = new AppGameSavMgr(); gameSavMgr = new AppGameSavMgr();
bTest = isTest; gamePadMgr = new GamePadManager();
mTestSrvIP = testSrvIP;
var go = new GameObject("[AppAxibugEmuOnline]"); bTest = isTest;
GameObject.DontDestroyOnLoad(go); mTestSrvIP = testSrvIP;
tickLoop = go.AddComponent<TickLoop>(); var go = new GameObject("[AppAxibugEmuOnline]");
coRunner = go.AddComponent<CoroutineRunner>(); GameObject.DontDestroyOnLoad(go);
tickLoop = go.AddComponent<TickLoop>();
coRunner = go.AddComponent<CoroutineRunner>();
var importNode = GameObject.Find("IMPORTENT");
if (importNode != null) GameObject.DontDestroyOnLoad(importNode);
var importNode = GameObject.Find("IMPORTENT");
StartCoroutine(AppTickFlow()); if (importNode != null) GameObject.DontDestroyOnLoad(importNode);
RePullNetInfo();
} StartCoroutine(AppTickFlow());
RePullNetInfo();
}
private static void PSP2Init()
{
//PSVita最好手动创建目录 private static void PSP2Init()
if (!Directory.Exists(PersistentDataPath)) {
Directory.CreateDirectory(PersistentDataPath); //PSVita最好手动创建目录
if (!Directory.Exists(PersistentDataPath))
#if UNITY_PSP2 Directory.CreateDirectory(PersistentDataPath);
//创建PSV弹窗UI
sonyVitaCommonDialog = new GameObject().AddComponent<SonyVitaCommonDialog>(); #if UNITY_PSP2
//释放解码 FMV的26M内存一般游戏用不上PSP才用那破玩意儿 //创建PSV弹窗UI
UnityEngine.PSVita.PSVitaVideoPlayer.TransferMemToMonoHeap(); sonyVitaCommonDialog = new GameObject().AddComponent<SonyVitaCommonDialog>();
#endif //释放解码 FMV的26M内存一般游戏用不上PSP才用那破玩意儿
UnityEngine.PSVita.PSVitaVideoPlayer.TransferMemToMonoHeap();
} #endif
private static IEnumerator AppTickFlow() }
{
while (true) private static IEnumerator AppTickFlow()
{ {
Tick(); while (true)
yield return null; {
} Tick();
} yield return null;
}
public static void RePullNetInfo() }
{
StartCoroutine(StartNetInit()); public static void RePullNetInfo()
} {
StartCoroutine(StartNetInit());
static IEnumerator StartNetInit() }
{
if (App.network.isConnected) static IEnumerator StartNetInit()
yield break; {
if (App.network.isConnected)
int platform = 0; yield break;
if (bTest)
{ int platform = 0;
yield return null; if (bTest)
Connect(mTestSrvIP, 10492); {
yield break; yield return null;
} Connect(mTestSrvIP, 10492);
yield break;
bool bHttpCheckDone = false; }
Resp_CheckStandInfo resp = null;
while (true) bool bHttpCheckDone = false;
{ Resp_CheckStandInfo resp = null;
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}"); while (true)
yield return request.SendWebRequest; {
if (!request.downloadHandler.isDone) AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}");
{ yield return request.SendWebRequest;
bHttpCheckDone = false; if (!request.downloadHandler.isDone)
} {
else if (request.downloadHandler.bHadErr) bHttpCheckDone = false;
{ }
bHttpCheckDone = false; else if (request.downloadHandler.bHadErr)
App.log.Error(request.downloadHandler.ErrInfo); {
} bHttpCheckDone = false;
else App.log.Error(request.downloadHandler.ErrInfo);
{ }
try else
{ {
resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text); try
bHttpCheckDone = true; {
} resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);
catch (Exception ex) bHttpCheckDone = true;
{ }
bHttpCheckDone = false; catch (Exception ex)
App.log.Error(ex.ToString()); {
} bHttpCheckDone = false;
} App.log.Error(ex.ToString());
}
//请求成功 }
if (bHttpCheckDone)
{ //请求成功
break; if (bHttpCheckDone)
} {
else break;
{ }
yield return new WaitForSeconds(1); else
App.log.Debug("请求失败重试请求API..."); {
} 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();
/*UnityWebRequest request = UnityWebRequest.Get($"{App.httpAPI.WebSiteApi}/CheckStandInfo?platform={platform}&version={Application.version}");
if (request.result != UnityWebRequest.Result.Success) yield return request.SendWebRequest();
yield break;
if (request.result != UnityWebRequest.Result.Success)
App.log.Debug($"ApiResp => {request.downloadHandler.text}"); yield break;
Resp_CheckStandInfo resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);*/
App.log.Debug($"ApiResp => {request.downloadHandler.text}");
//需要更新 Resp_CheckStandInfo resp = JsonUtility.FromJson<Resp_CheckStandInfo>(request.downloadHandler.text);*/
if (resp.needUpdateClient == 1)
{ //需要更新
//TODO if (resp.needUpdateClient == 1)
} {
//TODO
yield return null; }
//Connect("127.0.0.1", 10492);
Connect(resp.serverIp, resp.serverPort); yield return null;
} //Connect("127.0.0.1", 10492);
Connect(resp.serverIp, resp.serverPort);
private static void Tick() }
{
nesRomLib.ExecuteFetchRomInfo(); private static void Tick()
} {
nesRomLib.ExecuteFetchRomInfo();
public static Coroutine StartCoroutine(IEnumerator itor) starRomLib.ExecuteFetchRomInfo();
{
return coRunner.StartCoroutine(itor); gamePadMgr.Update();
} }
public static void StopCoroutine(Coroutine cor) public static Coroutine StartCoroutine(IEnumerator itor)
{ {
coRunner.StopCoroutine(cor); return coRunner.StartCoroutine(itor);
} }
public static void Connect(string IP, int port) public static void StopCoroutine(Coroutine cor)
{ {
Task task = new Task(() => coRunner.StopCoroutine(cor);
{ }
network.Init(IP, port);
}); public static void Connect(string IP, int port)
task.Start(); {
} Task task = new Task(() =>
{
public static void Close() network.Init(IP, port);
{ });
App.log.Info("停止"); task.Start();
} }
static void OnLogOut(int LogLevel, string msg)
{ public static void Close()
E_LogType logType = (E_LogType)LogLevel; {
switch (logType) App.log.Info("停止");
{ }
case E_LogType.Debug: static void OnLogOut(int LogLevel, string msg)
case E_LogType.Info: {
Debug.Log("[AxiNet]:" + msg); E_LogType logType = (E_LogType)LogLevel;
break; switch (logType)
case E_LogType.Warning: {
Debug.LogWarning("[AxiNet]:" + msg); case E_LogType.Debug:
break; case E_LogType.Info:
case E_LogType.Error: Debug.Log("[AxiNet]:" + msg);
Debug.LogError("[AxiNet]:" + msg); break;
break; case E_LogType.Warning:
} Debug.LogWarning("[AxiNet]:" + msg);
} break;
case E_LogType.Error:
} Debug.LogError("[AxiNet]:" + msg);
break;
}
}
}
} }

View File

@ -1,50 +1,51 @@
using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.ClientCore;
using UnityEngine; using System.Text;
using UnityEngine;
namespace AxibugEmuOnline.Client
{ namespace AxibugEmuOnline.Client
public class Initer : MonoBehaviour {
{ public class Initer : MonoBehaviour
static GlobalRef m_refs; {
public static CanvasGroup FilterPreview => m_refs.FilterPreview; static GlobalRef m_refs;
public static CanvasGroup XMBBg => m_refs.XMBBg; public static CanvasGroup FilterPreview => m_refs.FilterPreview;
public static CanvasGroup XMBBg => m_refs.XMBBg;
public static string dev_UUID;
public static string dev_UUID;
[SerializeField]
[SerializeField]
GameObject IMPORTENT; GameObject IMPORTENT;
#if UNITY_EDITOR #if UNITY_EDITOR
public bool bTestSkipWebApiToConServer = false; public bool bTestSkipWebApiToConServer = false;
public string mTestSrvIP = "192.168.0.47"; public string mTestSrvIP = "192.168.0.47";
public bool bUseLocalWebApi = false; public bool bUseLocalWebApi = false;
public string mLocalWebApi = "http://localhost:5051"; public string mLocalWebApi = "http://localhost:5051";
public bool bEditorUUID = false; public bool bEditorUUID = false;
#endif #endif
private void Awake() private void Awake()
{ {
#if UNITY_EDITOR #if UNITY_EDITOR
App.Init(bTestSkipWebApiToConServer, mTestSrvIP, bUseLocalWebApi,mLocalWebApi); App.Init(bTestSkipWebApiToConServer, mTestSrvIP, bUseLocalWebApi,mLocalWebApi);
dev_UUID = SystemInfo.deviceUniqueIdentifier; dev_UUID = SystemInfo.deviceUniqueIdentifier;
if (bEditorUUID) if (bEditorUUID)
{ {
dev_UUID += "_Editor"; dev_UUID += "_Editor";
} }
#else #else
App.Init(this); App.Init(this);
dev_UUID = SystemInfo.deviceUniqueIdentifier; dev_UUID = SystemInfo.deviceUniqueIdentifier;
#endif #endif
m_refs = Instantiate(IMPORTENT, transform).GetComponent<GlobalRef>(); m_refs = Instantiate(IMPORTENT, transform).GetComponent<GlobalRef>();
} }
private void Start() private void Start()
{ {
App.settings.Filter.ShutDownFilterPreview(); App.settings.Filter.ShutDownFilterPreview();
App.settings.Filter.ShutDownFilter(); App.settings.Filter.ShutDownFilter();
} }
} }
} }

View File

@ -1,160 +1,160 @@
using Assets.Script.AppMain.Filter; using Assets.Script.AppMain.Filter;
using AxibugEmuOnline.Client; using AxibugEmuOnline.Client;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
using UnityEngine.Experimental.Rendering; using UnityEngine.Experimental.Rendering;
public abstract class FilterChainEffect : FilterEffect public abstract class FilterChainEffect : FilterEffect
{ {
#region SealedForDisable #region SealedForDisable
protected sealed override string ShaderName => null; protected sealed override string ShaderName => null;
protected sealed override void OnInit(Material renderMat) { } protected sealed override void OnInit(Material renderMat) { }
public sealed override void Render(Texture src, RenderTexture result) public sealed override void Render(Texture src, RenderTexture result)
{ {
OnRenderer(src, result); OnRenderer(src, result);
} }
protected sealed override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { } protected sealed override void OnRenderer(Material renderMat, Texture src, RenderTexture result) { }
#endregion #endregion
List<PassDefine> m_passes = new List<PassDefine>(); List<PassDefine> m_passes = new List<PassDefine>();
static int Original; static int Original;
static int OriginalSize; static int OriginalSize;
static int Source; static int Source;
static int SourceSize; static int SourceSize;
static int FrameCount; static int FrameCount;
static int OutputSize; static int OutputSize;
List<int> m_passOutputTexNames = new List<int>(); List<int> m_passOutputTexNames = new List<int>();
List<int> m_passOutputTexSizes = new List<int>(); List<int> m_passOutputTexSizes = new List<int>();
static FilterChainEffect() static FilterChainEffect()
{ {
Original = Shader.PropertyToID(nameof(Original)); Original = Shader.PropertyToID(nameof(Original));
OriginalSize = Shader.PropertyToID(nameof(OriginalSize)); OriginalSize = Shader.PropertyToID(nameof(OriginalSize));
Source = Shader.PropertyToID(nameof(Source)); Source = Shader.PropertyToID(nameof(Source));
SourceSize = Shader.PropertyToID(nameof(SourceSize)); SourceSize = Shader.PropertyToID(nameof(SourceSize));
FrameCount = Shader.PropertyToID(nameof(FrameCount)); FrameCount = Shader.PropertyToID(nameof(FrameCount));
OutputSize = Shader.PropertyToID(nameof(OutputSize)); OutputSize = Shader.PropertyToID(nameof(OutputSize));
} }
protected sealed override void Init() protected sealed override void Init()
{ {
DefinePasses(ref m_passes); DefinePasses(ref m_passes);
for (int i = 0; i < m_passes.Count; i++) for (int i = 0; i < m_passes.Count; i++)
{ {
m_passes[i].Init(i); m_passes[i].Init(i);
m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].NormalOutputTextureName)); m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].NormalOutputTextureName));
m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].NormalOutputTextureName}Size")); m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].NormalOutputTextureName}Size"));
if (m_passes[i].AliasOutputTextureName != null) if (m_passes[i].AliasOutputTextureName != null)
{ {
m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].AliasOutputTextureName)); m_passOutputTexNames.Add(Shader.PropertyToID(m_passes[i].AliasOutputTextureName));
m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].AliasOutputTextureName}Size")); m_passOutputTexSizes.Add(Shader.PropertyToID($"{m_passes[i].AliasOutputTextureName}Size"));
} }
} }
} }
Dictionary<int, RenderTexture> m_outputCaches = new Dictionary<int, RenderTexture>(); Dictionary<int, RenderTexture> m_outputCaches = new Dictionary<int, RenderTexture>();
private void OnRenderer(Texture input, RenderTexture finalOut) private void OnRenderer(Texture input, RenderTexture finalOut)
{ {
m_outputCaches.Clear(); m_outputCaches.Clear();
Vector4 originalSize = new Vector4(input.width, input.height, 1f / input.width, 1f / input.height); Vector4 originalSize = new Vector4(input.width, input.height, 1f / input.width, 1f / input.height);
Texture lastoutput = input; Texture lastoutput = input;
for (int i = 0; i < m_passes.Count; i++) for (int i = 0; i < m_passes.Count; i++)
{ {
var pass = m_passes[i]; var pass = m_passes[i];
pass.OnRender(); pass.OnRender();
pass.Mat.SetTexture(Original, input); pass.Mat.SetTexture(Original, input);
pass.Mat.SetVector(OriginalSize, originalSize); pass.Mat.SetVector(OriginalSize, originalSize);
pass.Mat.SetTexture(Source, lastoutput); pass.Mat.SetTexture(Source, lastoutput);
pass.Mat.SetVector(SourceSize, new Vector4(lastoutput.width, lastoutput.height, 1f / lastoutput.width, 1f / lastoutput.height)); pass.Mat.SetVector(SourceSize, new Vector4(lastoutput.width, lastoutput.height, 1f / lastoutput.width, 1f / lastoutput.height));
pass.Mat.SetFloat(FrameCount, Time.frameCount); pass.Mat.SetFloat(FrameCount, Time.frameCount);
for (int index = 0; index < m_passOutputTexNames.Count; index++) for (int index = 0; index < m_passOutputTexNames.Count; index++)
{ {
var existoutput = m_passOutputTexNames[index]; var existoutput = m_passOutputTexNames[index];
var existoutputSize = m_passOutputTexSizes[index]; var existoutputSize = m_passOutputTexSizes[index];
if (m_outputCaches.TryGetValue(existoutput, out var passOutput)) if (m_outputCaches.TryGetValue(existoutput, out var passOutput))
{ {
if (pass.Mat.HasTexture(existoutput)) if (pass.Mat.HasTexture(existoutput))
pass.Mat.SetTexture(existoutput, passOutput); pass.Mat.SetTexture(existoutput, passOutput);
if (pass.Mat.HasVector(existoutputSize)) 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); var output = pass.GetOutput(input, lastoutput, finalOut);
pass.Mat.SetVector(OutputSize, new Vector4(output.width, output.height, 1f / output.width, 1f / output.height)); pass.Mat.SetVector(OutputSize, new Vector4(output.width, output.height, 1f / output.width, 1f / output.height));
m_outputCaches[pass.NormalOutputTextureName_PID] = output; m_outputCaches[pass.NormalOutputTextureName_PID] = output;
if (pass.AliasOutputTextureName != null) m_outputCaches[pass.AliasOutputTextureName_PID] = output; if (pass.AliasOutputTextureName != null) m_outputCaches[pass.AliasOutputTextureName_PID] = output;
Graphics.Blit(lastoutput, output, pass.Mat); Graphics.Blit(lastoutput, output, pass.Mat);
lastoutput = output; lastoutput = output;
} }
Graphics.Blit(lastoutput, finalOut); Graphics.Blit(lastoutput, finalOut);
foreach (var rt in m_outputCaches.Values) foreach (var rt in m_outputCaches.Values)
RenderTexture.ReleaseTemporary(rt); RenderTexture.ReleaseTemporary(rt);
} }
protected abstract void DefinePasses(ref List<PassDefine> passes); protected abstract void DefinePasses(ref List<PassDefine> passes);
public class PassDefine public class PassDefine
{ {
public string ShaderName { get; private set; } public string ShaderName { get; private set; }
public FilterMode FilterMode { get; private set; } public FilterMode FilterMode { get; private set; }
public TextureWrapMode WrapMode { get; private set; } public TextureWrapMode WrapMode { get; private set; }
public EnumScaleMode ScaleModeX { get; private set; } public EnumScaleMode ScaleModeX { get; private set; }
public EnumScaleMode ScaleModeY { get; private set; } public EnumScaleMode ScaleModeY { get; private set; }
public float ScaleX { get; private set; } public float ScaleX { get; private set; }
public float ScaleY { get; private set; } public float ScaleY { get; private set; }
public string AliasOutputTextureName { get; private set; } public string AliasOutputTextureName { get; private set; }
public int AliasOutputTextureName_PID { get; private set; } public int AliasOutputTextureName_PID { get; private set; }
public string NormalOutputTextureName { get; private set; } public string NormalOutputTextureName { get; private set; }
public int NormalOutputTextureName_PID { get; private set; } public int NormalOutputTextureName_PID { get; private set; }
public bool sRGB { get; private set; } public bool sRGB { get; private set; }
private PassDefine() { } private PassDefine() { }
public static PassDefine Create( public static PassDefine Create(
string shaderName, string shaderName,
FilterMode filterMode = FilterMode.Point, FilterMode filterMode = FilterMode.Point,
TextureWrapMode wrapMode = TextureWrapMode.Clamp, TextureWrapMode wrapMode = TextureWrapMode.Clamp,
EnumScaleMode scaleModeX = EnumScaleMode.Source, EnumScaleMode scaleModeY = EnumScaleMode.Source, float scaleX = 1f, float scaleY = 1f, EnumScaleMode scaleModeX = EnumScaleMode.Source, EnumScaleMode scaleModeY = EnumScaleMode.Source, float scaleX = 1f, float scaleY = 1f,
string outputAlias = null, string outputAlias = null,
bool sRGB = false bool sRGB = false
) )
{ {
return new PassDefine() return new PassDefine()
{ {
ShaderName = shaderName, ShaderName = shaderName,
FilterMode = filterMode, FilterMode = filterMode,
WrapMode = wrapMode, WrapMode = wrapMode,
ScaleModeX = scaleModeX, ScaleModeX = scaleModeX,
ScaleModeY = scaleModeY, ScaleModeY = scaleModeY,
ScaleX = scaleX, ScaleX = scaleX,
ScaleY = scaleY, ScaleY = scaleY,
AliasOutputTextureName = outputAlias, AliasOutputTextureName = outputAlias,
sRGB = sRGB, sRGB = sRGB,
}; };
} }
private Dictionary<string, FilterParameter> m_linkingParams = new Dictionary<string, FilterParameter>(); private Dictionary<string, FilterParameter> m_linkingParams = new Dictionary<string, FilterParameter>();
public PassDefine SetParameters(string shaderValName, FilterParameter para) public PassDefine SetParameters(string shaderValName, FilterParameter para)
{ {
m_linkingParams[shaderValName] = para; m_linkingParams[shaderValName] = para;
return this; return this;
} }
public int PassIndex { get; private set; } public int PassIndex { get; private set; }
public Material Mat { get; private set; } public Material Mat { get; private set; }
public void OnRender() public void OnRender()
@ -167,63 +167,63 @@ public abstract class FilterChainEffect : FilterEffect
if (valType == typeof(float)) if (valType == typeof(float))
Mat.SetFloat(paraName, (float)val); Mat.SetFloat(paraName, (float)val);
} }
} }
internal void Init(int passIndex) internal void Init(int passIndex)
{ {
Mat = new Material(Shader.Find(ShaderName)); Mat = new Material(Shader.Find(ShaderName));
PassIndex = passIndex; PassIndex = passIndex;
NormalOutputTextureName = $"PassOutput{passIndex}"; NormalOutputTextureName = $"PassOutput{passIndex}";
NormalOutputTextureName_PID = Shader.PropertyToID(NormalOutputTextureName); NormalOutputTextureName_PID = Shader.PropertyToID(NormalOutputTextureName);
if (AliasOutputTextureName != null) AliasOutputTextureName_PID = Shader.PropertyToID(AliasOutputTextureName); if (AliasOutputTextureName != null) AliasOutputTextureName_PID = Shader.PropertyToID(AliasOutputTextureName);
} }
internal RenderTexture GetOutput(Texture original, Texture source, Texture final) internal RenderTexture GetOutput(Texture original, Texture source, Texture final)
{ {
int width = 0; int width = 0;
switch (ScaleModeX) switch (ScaleModeX)
{ {
case EnumScaleMode.Viewport: case EnumScaleMode.Viewport:
width = (int)(final.width * ScaleX); width = (int)(final.width * ScaleX);
break; break;
case EnumScaleMode.Source: case EnumScaleMode.Source:
width = (int)(source.width * ScaleX); width = (int)(source.width * ScaleX);
break; break;
case EnumScaleMode.Absolute: case EnumScaleMode.Absolute:
width = (int)ScaleX; width = (int)ScaleX;
break; break;
} }
int height = 0; int height = 0;
switch (ScaleModeY) switch (ScaleModeY)
{ {
case EnumScaleMode.Viewport: case EnumScaleMode.Viewport:
height = (int)(final.height * ScaleY); height = (int)(final.height * ScaleY);
break; break;
case EnumScaleMode.Source: case EnumScaleMode.Source:
height = (int)(source.height * ScaleY); height = (int)(source.height * ScaleY);
break; break;
case EnumScaleMode.Absolute: case EnumScaleMode.Absolute:
height = (int)ScaleY; height = (int)ScaleY;
break; break;
} }
//if (sRGB) format = GraphicsFormat.R8G8B8A8_SRGB; //if (sRGB) format = GraphicsFormat.R8G8B8A8_SRGB;
var rt = RenderTexture.GetTemporary(width, height, 0, GraphicsFormat.R8G8B8A8_UNorm, 1); var rt = RenderTexture.GetTemporary(width, height, 0, GraphicsFormat.R8G8B8A8_UNorm, 1);
rt.wrapMode = WrapMode; rt.wrapMode = WrapMode;
rt.filterMode = FilterMode; rt.filterMode = FilterMode;
return rt; return rt;
} }
} }
public enum EnumScaleMode public enum EnumScaleMode
{ {
/// <summary> 以输入源为缩放基准 </summary /// <summary> 以输入源为缩放基准 </summary
Source, Source,
/// <summary> 以分辨率作为缩放基准 </summary /// <summary> 以分辨率作为缩放基准 </summary
Viewport, Viewport,
/// <summary> 以固定值定义尺寸 </summary /// <summary> 以固定值定义尺寸 </summary
Absolute Absolute
} }
} }

View File

@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 5fe26f58ab822c44888b86305c5326e0
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -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)}";
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: c2c0a06020f65a747af5490a6112361b

View File

@ -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;
}
}
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: ce4d215abea527e4a8cf1103cbfecf6b