新增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.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;
}
}
}
}

View File

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

View File

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

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