合并Switch版本修改
This commit is contained in:
parent
ccf2279947
commit
a1aa816426
@ -90,9 +90,14 @@ namespace AxibugEmuOnline.Client.ClientCore
|
||||
public static void Init(bool isTest = false, bool isUseGUIButton = false, string testSrvIP = "", bool bUseLocalWebApi = false, string mLocalWebApi = "")
|
||||
{
|
||||
log = new LogManager(OnLogOut);
|
||||
|
||||
//其他平台必要的初始化
|
||||
if (UnityEngine.Application.platform == RuntimePlatform.PSP2) PSP2Init();
|
||||
#if UNITY_PSP2
|
||||
PSP2Init();
|
||||
#endif
|
||||
|
||||
#if UNITY_SWITCH
|
||||
SwitchInit();
|
||||
#endif
|
||||
|
||||
input = new InputDevicesManager();
|
||||
FileDownloader = new FileDownloader();
|
||||
@ -153,11 +158,18 @@ namespace AxibugEmuOnline.Client.ClientCore
|
||||
sonyVitaCommonDialog = new GameObject().AddComponent<SonyVitaCommonDialog>();
|
||||
#endif
|
||||
|
||||
#if UNITY_SWITCH
|
||||
//创建创建Switch
|
||||
switchCommon = new GameObject().AddComponent<SwitchCommon>();
|
||||
#endif
|
||||
|
||||
}
|
||||
private static void SwitchInit()
|
||||
{
|
||||
#if UNITY_SWITCH
|
||||
AxiNS.instance.Init();
|
||||
if (!AxiIO.Directory.Exists(App.PersistentDataRootPath()))
|
||||
AxiIO.Directory.CreateDirectory(App.PersistentDataRootPath());
|
||||
switchCommon = new GameObject().AddComponent<SwitchCommon>();
|
||||
switchCommon.gameObject.name = "[SwitchCommon]";
|
||||
GameObject.DontDestroyOnLoad(switchCommon);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxiInputSP.UGUI
|
||||
{
|
||||
public class AxiScreenGamepad : MonoBehaviour
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxiInputSP.UGUI
|
||||
{
|
||||
public class AxiScreenGamepad : MonoBehaviour
|
||||
{
|
||||
public delegate void OnAxiScreenGamepadActiveHandle(AxiScreenGamepad sender);
|
||||
public delegate void OnAxiScreenGamepadDisactiveHandle(AxiScreenGamepad sender);
|
||||
@ -58,5 +58,5 @@ namespace AxiInputSP.UGUI
|
||||
{
|
||||
OnGamepadDisactive?.Invoke(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ public class DebuggerByGUI : MonoBehaviour
|
||||
private Vector2 _scrollLogView = Vector2.zero;
|
||||
private Vector2 _scrollCurrentLogView = Vector2.zero;
|
||||
private Vector2 _scrollSystemView = Vector2.zero;
|
||||
private bool _expansion = false;
|
||||
private bool _expansion = false;
|
||||
private Rect _windowRect = new Rect(0, 0, 100, 60);
|
||||
|
||||
private int _fps = 0;
|
||||
@ -32,9 +32,26 @@ public class DebuggerByGUI : MonoBehaviour
|
||||
private int _frameNumber = 0;
|
||||
private float _lastShowFPSTime = 0f;
|
||||
|
||||
private void Start()
|
||||
public bool OpenHubOnStart = false;
|
||||
public bool AutoShowLastLogLine = false;
|
||||
public bool OnlyShowErrOnStart = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
DontDestroyOnLoad(this.gameObject);
|
||||
if (OpenHubOnStart)
|
||||
{
|
||||
_expansion = true;
|
||||
_windowRect.width = 1000;
|
||||
_windowRect.height = 600;
|
||||
}
|
||||
|
||||
if (OnlyShowErrOnStart)
|
||||
{
|
||||
_showInfoLog = false;
|
||||
_showWarningLog = false;
|
||||
}
|
||||
|
||||
DontDestroyOnLoad(this.gameObject);
|
||||
if (AllowDebugging)
|
||||
{
|
||||
Application.logMessageReceived += LogHandler;
|
||||
@ -237,16 +254,22 @@ public class DebuggerByGUI : MonoBehaviour
|
||||
GUILayout.Label(_logInformations[i].message);
|
||||
GUILayout.FlexibleSpace();
|
||||
GUI.contentColor = Color.white;
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
|
||||
_scrollCurrentLogView = GUILayout.BeginScrollView(_scrollCurrentLogView, "Box", GUILayout.Height(100));
|
||||
if (_currentLogIndex != -1)
|
||||
|
||||
if (AutoShowLastLogLine)
|
||||
{
|
||||
_scrollLogView.y = Mathf.Lerp(_scrollLogView.y, float.MaxValue, 0.1f);
|
||||
}
|
||||
|
||||
if (_currentLogIndex != -1)
|
||||
{
|
||||
GUILayout.Label(_logInformations[_currentLogIndex].message + "\r\n\r\n" + _logInformations[_currentLogIndex].stackTrace);
|
||||
}
|
||||
}
|
||||
GUILayout.EndScrollView();
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -1,69 +1,69 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public abstract class EmuCore : MonoBehaviour
|
||||
{
|
||||
public abstract class EmuCore : MonoBehaviour
|
||||
{
|
||||
/// <summary> 获得模拟器核心中的状态快照对象 </summary>
|
||||
public abstract object GetState();
|
||||
public abstract object GetState();
|
||||
/// <summary> 获得模拟器核心中的状态快照字节数据 </summary>
|
||||
public abstract byte[] GetStateBytes();
|
||||
public abstract byte[] GetStateBytes();
|
||||
/// <summary> 加载状态快照 </summary>
|
||||
/// <param name="state">该对象应该来自核心的<see cref="GetState"/>方法的返回值,或是从<see cref="GetStateBytes"/>返回的byte数组构建</param>
|
||||
public abstract void LoadState(object state);
|
||||
/// <param name="state">该对象应该来自核心的<see cref="GetState"/>方法的返回值,或是从<see cref="GetStateBytes"/>返回的byte数组构建</param>
|
||||
public abstract void LoadState(object state);
|
||||
/// <summary> 加载状态快照 </summary>
|
||||
/// <param name="data">该对象应该来自核心的<see cref="GetStateBytes"/>返回的byte数组</param>
|
||||
public abstract void LoadStateFromBytes(byte[] data);
|
||||
/// <summary> 暂停核心推帧 </summary>
|
||||
public abstract void Pause();
|
||||
/// <summary> 恢复核心推帧(从Pause状态恢复) </summary>
|
||||
public abstract void Resume();
|
||||
/// <summary> 启动模拟器逻辑 </summary>
|
||||
public abstract MsgBool StartGame(RomFile romFile);
|
||||
/// <summary> 释放模拟器核心 </summary>
|
||||
public abstract void Dispose();
|
||||
/// <summary> 重置核心,通常由模拟器核心提供的功能 </summary>
|
||||
/// <param name="data">该对象应该来自核心的<see cref="GetStateBytes"/>返回的byte数组</param>
|
||||
public abstract void LoadStateFromBytes(byte[] data);
|
||||
/// <summary> 暂停核心推帧 </summary>
|
||||
public abstract void Pause();
|
||||
/// <summary> 恢复核心推帧(从Pause状态恢复) </summary>
|
||||
public abstract void Resume();
|
||||
/// <summary> 启动模拟器逻辑 </summary>
|
||||
public abstract MsgBool StartGame(RomFile romFile);
|
||||
/// <summary> 释放模拟器核心 </summary>
|
||||
public abstract void Dispose();
|
||||
/// <summary> 重置核心,通常由模拟器核心提供的功能 </summary>
|
||||
public abstract void DoReset();
|
||||
/// <summary> 获得模拟器核心的控制器设置器 </summary>
|
||||
/// <returns></returns>
|
||||
public abstract IControllerSetuper GetControllerSetuper();
|
||||
/// <summary> 核心所属平台 </summary>
|
||||
public abstract RomPlatformType Platform { get; }
|
||||
public abstract RomPlatformType Platform { get; }
|
||||
/// <summary> 获取当前模拟器帧序号,在加载快照和Reset后,应当重置为0 </summary>
|
||||
public abstract uint Frame { get; }
|
||||
|
||||
public abstract void PushEmulatorFrame();
|
||||
public abstract uint Frame { get; }
|
||||
|
||||
public abstract void PushEmulatorFrame();
|
||||
/// <summary> 模拟器核心推帧结束 </summary>
|
||||
protected abstract void AfterPushFrame();
|
||||
public abstract void GetAudioParams(out int frequency, out int channels);
|
||||
public abstract Texture OutputPixel { get; }
|
||||
public abstract void GetAudioParams(out int frequency, out int channels);
|
||||
public abstract Texture OutputPixel { get; }
|
||||
public abstract RawImage DrawCanvas { get; }
|
||||
|
||||
|
||||
/// <summary> 指示该游戏实例是否处于联机模式 </summary>
|
||||
public bool IsNetPlay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!App.user.IsLoggedIn) return false;
|
||||
if (App.roomMgr.mineRoomMiniInfo == null) return false;
|
||||
if (App.roomMgr.RoomState <= RoomGameState.OnlyHost) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/// <summary> 指示该游戏实例是否处于联机模式 </summary>
|
||||
public bool IsNetPlay
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!App.user.IsLoggedIn) return false;
|
||||
if (App.roomMgr.mineRoomMiniInfo == null) return false;
|
||||
if (App.roomMgr.RoomState <= RoomGameState.OnlyHost) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <typeparam name="INPUTDATA">输入数据类型</typeparam>
|
||||
public abstract class EmuCore<INPUTDATA> : EmuCore
|
||||
{
|
||||
protected virtual bool EnableRollbackNetCode => false;
|
||||
|
||||
{
|
||||
protected virtual bool EnableRollbackNetCode => false;
|
||||
|
||||
public sealed override void PushEmulatorFrame()
|
||||
{
|
||||
if (!TryPushEmulatorFrame()) return;
|
||||
@ -115,28 +115,28 @@ namespace AxibugEmuOnline.Client
|
||||
bool result = false;
|
||||
inputData = default(INPUTDATA);
|
||||
|
||||
if (IsNetPlay)
|
||||
{
|
||||
if (App.roomMgr.netReplay.TryGetNextFrame((int)Frame, EnableRollbackNetCode ? true : false, out m_replayData, out m_frameDiff, out m_inputDiff))
|
||||
if (IsNetPlay)
|
||||
{
|
||||
if (App.roomMgr.netReplay.TryGetNextFrame((int)Frame, EnableRollbackNetCode ? true : false, out m_replayData, out m_frameDiff, out m_inputDiff))
|
||||
{
|
||||
if (m_inputDiff)
|
||||
{
|
||||
App.log.Debug($"{DateTime.Now.ToString("hh:mm:ss.fff")} TryGetNextFrame remoteFrame->{App.roomMgr.netReplay.mRemoteFrameIdx} diff->{m_frameDiff} " +
|
||||
$"frame=>{m_replayData.FrameStartID} InPut=>{m_replayData.InPut}");
|
||||
}
|
||||
|
||||
inputData = ConvertInputDataFromNet(m_replayData);
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
inputData = ConvertInputDataFromNet(m_replayData);
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
else//单机模式
|
||||
{
|
||||
inputData = GetLocalInput();
|
||||
result = true;
|
||||
else//单机模式
|
||||
{
|
||||
inputData = GetLocalInput();
|
||||
result = true;
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -147,5 +147,5 @@ namespace AxibugEmuOnline.Client
|
||||
protected abstract ulong InputDataToNet(INPUTDATA inputData);
|
||||
/// <summary> 模拟器核心推帧 </summary>
|
||||
protected abstract bool OnPushEmulatorFrame(INPUTDATA InputData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,161 +1,161 @@
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UMAME : EmuCore<ulong>
|
||||
{
|
||||
public static UMAME instance { get; private set; }
|
||||
public MAMEEmu emu { get; private set; }
|
||||
UniLog mUniLog;
|
||||
UniMouse mUniMouse;
|
||||
[HideInInspector]
|
||||
public UniVideoPlayer mUniVideoPlayer;
|
||||
UniSoundPlayer mUniSoundPlayer;
|
||||
UniKeyboard mUniKeyboard;
|
||||
UniResources mUniResources;
|
||||
UniIO mUniIO;
|
||||
|
||||
public Text mFPS;
|
||||
private Canvas mCanvas;
|
||||
public List<RomInfo> HadGameList = new List<RomInfo>();
|
||||
string mChangeRomName = string.Empty;
|
||||
public UniTimeSpan mTimeSpan;
|
||||
public bool bQuickTestRom = false;
|
||||
public string mQuickTestRom = string.Empty;
|
||||
public ReplayWriter mReplayWriter;
|
||||
public ReplayReader mReplayReader;
|
||||
public long currEmuFrame => emu.currEmuFrame;
|
||||
public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
public static bool bInGame { get; private set; }
|
||||
public static bool bLogicUpdatePause { get; private set; }
|
||||
public string EmuDataPath { get { return App.PersistentDataPath(Platform); } }
|
||||
public string RomPath => EmuDataPath + "/RemoteRoms/";
|
||||
public string SavePath => EmuDataPath + "/sav/";
|
||||
public override RomPlatformType Platform { get { return mPlatform; } }
|
||||
RomPlatformType mPlatform = RomPlatformType.Cps1;
|
||||
public override uint Frame => (uint)emu.currEmuFrame;
|
||||
void Awake()
|
||||
{
|
||||
instance = this;
|
||||
mFPS = GameObject.Find("FPS").GetComponent<Text>();
|
||||
mCanvas = GameObject.Find("Canvas").GetComponent<Canvas>();
|
||||
mCanvas.worldCamera = Camera.main;
|
||||
emu = new MAMEEmu();
|
||||
mUniLog = new UniLog();
|
||||
mUniMouse = this.gameObject.AddComponent<UniMouse>();
|
||||
mUniVideoPlayer = this.gameObject.AddComponent<UniVideoPlayer>();
|
||||
mUniSoundPlayer = GameObject.Find("Audio").transform.GetComponent<UniSoundPlayer>();
|
||||
mUniKeyboard = this.gameObject.AddComponent<UniKeyboard>();
|
||||
mUniResources = new UniResources();
|
||||
mUniIO = new UniIO();
|
||||
mChangeRomName = string.Empty;
|
||||
mTimeSpan = new UniTimeSpan();
|
||||
emu.Init(RomPath, mUniLog, mUniResources, mUniVideoPlayer, mUniSoundPlayer, mUniKeyboard, mUniMouse, mTimeSpan, mUniIO);
|
||||
}
|
||||
void OnEnable()
|
||||
{
|
||||
}
|
||||
void OnDisable()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
#region 实现接口
|
||||
public override object GetState()
|
||||
{
|
||||
return SaveState();
|
||||
}
|
||||
public override byte[] GetStateBytes()
|
||||
{
|
||||
return SaveState();
|
||||
}
|
||||
public override void LoadState(object state)
|
||||
{
|
||||
LoadState((byte[])state);
|
||||
}
|
||||
public override void LoadStateFromBytes(byte[] data)
|
||||
{
|
||||
LoadState(data);
|
||||
}
|
||||
public override void Pause()
|
||||
{
|
||||
bLogicUpdatePause = false;
|
||||
}
|
||||
public override void Resume()
|
||||
{
|
||||
bLogicUpdatePause = true;
|
||||
}
|
||||
public override MsgBool StartGame(RomFile romFile)
|
||||
{
|
||||
mPlatform = romFile.Platform;
|
||||
mTimeSpan.InitStandTime();
|
||||
if (LoadGame(romFile.FileName))
|
||||
return true;
|
||||
else
|
||||
return "Rom加载失败";
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
public override void DoReset()
|
||||
{
|
||||
StopGame();
|
||||
LoadGame(mChangeRomName);
|
||||
}
|
||||
public override IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return mUniKeyboard.ControllerMapper;
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class UMAME : EmuCore<ulong>
|
||||
{
|
||||
public static UMAME instance { get; private set; }
|
||||
public MAMEEmu emu { get; private set; }
|
||||
UniLog mUniLog;
|
||||
UniMouse mUniMouse;
|
||||
[HideInInspector]
|
||||
public UniVideoPlayer mUniVideoPlayer;
|
||||
UniSoundPlayer mUniSoundPlayer;
|
||||
UniKeyboard mUniKeyboard;
|
||||
UniResources mUniResources;
|
||||
UniIO mUniIO;
|
||||
|
||||
public Text mFPS;
|
||||
private Canvas mCanvas;
|
||||
public List<RomInfo> HadGameList = new List<RomInfo>();
|
||||
string mChangeRomName = string.Empty;
|
||||
public UniTimeSpan mTimeSpan;
|
||||
public bool bQuickTestRom = false;
|
||||
public string mQuickTestRom = string.Empty;
|
||||
public ReplayWriter mReplayWriter;
|
||||
public ReplayReader mReplayReader;
|
||||
public long currEmuFrame => emu.currEmuFrame;
|
||||
public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
public static bool bInGame { get; private set; }
|
||||
public static bool bLogicUpdatePause { get; private set; }
|
||||
public string EmuDataPath { get { return App.PersistentDataPath(Platform); } }
|
||||
public string RomPath => EmuDataPath + "/RemoteRoms/";
|
||||
public string SavePath => EmuDataPath + "/sav/";
|
||||
public override RomPlatformType Platform { get { return mPlatform; } }
|
||||
RomPlatformType mPlatform = RomPlatformType.Cps1;
|
||||
public override uint Frame => (uint)emu.currEmuFrame;
|
||||
void Awake()
|
||||
{
|
||||
instance = this;
|
||||
mFPS = GameObject.Find("FPS").GetComponent<Text>();
|
||||
mCanvas = GameObject.Find("Canvas").GetComponent<Canvas>();
|
||||
mCanvas.worldCamera = Camera.main;
|
||||
emu = new MAMEEmu();
|
||||
mUniLog = new UniLog();
|
||||
mUniMouse = this.gameObject.AddComponent<UniMouse>();
|
||||
mUniVideoPlayer = this.gameObject.AddComponent<UniVideoPlayer>();
|
||||
mUniSoundPlayer = GameObject.Find("Audio").transform.GetComponent<UniSoundPlayer>();
|
||||
mUniKeyboard = this.gameObject.AddComponent<UniKeyboard>();
|
||||
mUniResources = new UniResources();
|
||||
mUniIO = new UniIO();
|
||||
mChangeRomName = string.Empty;
|
||||
mTimeSpan = new UniTimeSpan();
|
||||
emu.Init(RomPath, mUniLog, mUniResources, mUniVideoPlayer, mUniSoundPlayer, mUniKeyboard, mUniMouse, mTimeSpan, mUniIO);
|
||||
}
|
||||
void OnEnable()
|
||||
{
|
||||
}
|
||||
void OnDisable()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
#region 实现接口
|
||||
public override object GetState()
|
||||
{
|
||||
return SaveState();
|
||||
}
|
||||
public override byte[] GetStateBytes()
|
||||
{
|
||||
return SaveState();
|
||||
}
|
||||
public override void LoadState(object state)
|
||||
{
|
||||
LoadState((byte[])state);
|
||||
}
|
||||
public override void LoadStateFromBytes(byte[] data)
|
||||
{
|
||||
LoadState(data);
|
||||
}
|
||||
public override void Pause()
|
||||
{
|
||||
bLogicUpdatePause = false;
|
||||
}
|
||||
public override void Resume()
|
||||
{
|
||||
bLogicUpdatePause = true;
|
||||
}
|
||||
public override MsgBool StartGame(RomFile romFile)
|
||||
{
|
||||
mPlatform = romFile.Platform;
|
||||
mTimeSpan.InitStandTime();
|
||||
if (LoadGame(romFile.FileName))
|
||||
return true;
|
||||
else
|
||||
return "Rom加载失败";
|
||||
}
|
||||
public override void Dispose()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
public override void DoReset()
|
||||
{
|
||||
StopGame();
|
||||
LoadGame(mChangeRomName);
|
||||
}
|
||||
public override IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return mUniKeyboard.ControllerMapper;
|
||||
}
|
||||
|
||||
|
||||
public override void GetAudioParams(out int frequency, out int channels)
|
||||
{
|
||||
mUniSoundPlayer.GetAudioParams(out frequency, out channels);
|
||||
}
|
||||
|
||||
#endregion
|
||||
bool LoadGame(string loadRom)
|
||||
{
|
||||
emu.ResetRomRoot(RomPath);
|
||||
//Application.targetFrameRate = 60;
|
||||
mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8);
|
||||
mChangeRomName = loadRom;
|
||||
StopGame();
|
||||
//读取ROM
|
||||
emu.LoadRom(mChangeRomName);
|
||||
//读取成功
|
||||
if (emu.bRom)
|
||||
{
|
||||
|
||||
//读取ROM之后获得宽高初始化画面
|
||||
int _width; int _height; IntPtr _framePtr;
|
||||
emu.GetGameScreenSize(out _width, out _height, out _framePtr);
|
||||
App.log.Debug($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}");
|
||||
mUniVideoPlayer.Initialize(_width, _height, _framePtr);
|
||||
//初始化音频
|
||||
mUniSoundPlayer.Initialize();
|
||||
//开始游戏
|
||||
emu.StartGame();
|
||||
bInGame = true;
|
||||
bLogicUpdatePause = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.log.Debug($"ROM加载失败");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
bool LoadGame(string loadRom)
|
||||
{
|
||||
emu.ResetRomRoot(RomPath);
|
||||
//Application.targetFrameRate = 60;
|
||||
mReplayWriter = new ReplayWriter(mChangeRomName, "fuck", ReplayData.ReplayFormat.FM32IP64, Encoding.UTF8);
|
||||
mChangeRomName = loadRom;
|
||||
StopGame();
|
||||
//读取ROM
|
||||
emu.LoadRom(mChangeRomName);
|
||||
//读取成功
|
||||
if (emu.bRom)
|
||||
{
|
||||
|
||||
//读取ROM之后获得宽高初始化画面
|
||||
int _width; int _height; IntPtr _framePtr;
|
||||
emu.GetGameScreenSize(out _width, out _height, out _framePtr);
|
||||
App.log.Debug($"_width->{_width}, _height->{_height}, _framePtr->{_framePtr}");
|
||||
mUniVideoPlayer.Initialize(_width, _height, _framePtr);
|
||||
//初始化音频
|
||||
mUniSoundPlayer.Initialize();
|
||||
//开始游戏
|
||||
emu.StartGame();
|
||||
bInGame = true;
|
||||
bLogicUpdatePause = true;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.log.Debug($"ROM加载失败");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
protected override bool OnPushEmulatorFrame(ulong InputData)
|
||||
{
|
||||
if (!bInGame) return false;
|
||||
if (!bInGame) return false;
|
||||
if (!bLogicUpdatePause) return false;
|
||||
|
||||
mUniKeyboard.SyncInput(InputData);
|
||||
@ -181,53 +181,53 @@ public class UMAME : EmuCore<ulong>
|
||||
|
||||
protected override void AfterPushFrame()
|
||||
{
|
||||
mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")} ,Idx:{App.roomMgr.netReplay?.mCurrClientFrameIdx},RIdx:{App.roomMgr.netReplay?.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay?.mRemoteForwardCount} ,RD:{App.roomMgr.netReplay?.mRemoteForwardCount} ,D:{App.roomMgr.netReplay?.mDiffFrameCount} ,Q:{App.roomMgr.netReplay?.mNetReplayQueue.Count}");
|
||||
}
|
||||
public void SaveReplay()
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".rp";
|
||||
string dbgPath = SavePath + Machine.sName + ".rpwrite";
|
||||
mReplayWriter.SaveData(Path, true, dbgPath);
|
||||
}
|
||||
public void StopGame()
|
||||
{
|
||||
if (bInGame)
|
||||
{
|
||||
emu.StopGame();
|
||||
mUniVideoPlayer.StopVideo();
|
||||
mUniSoundPlayer.StopPlay();
|
||||
bInGame = false;
|
||||
bLogicUpdatePause = false;
|
||||
}
|
||||
}
|
||||
byte[] SaveState()
|
||||
{
|
||||
if (!AxiIO.Directory.Exists(SavePath))
|
||||
AxiIO.Directory.CreateDirectory(SavePath);
|
||||
|
||||
System.IO.MemoryStream ms = new System.IO.MemoryStream();
|
||||
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(ms);
|
||||
emu.SaveState(bw);
|
||||
byte[] data = ms.ToArray();
|
||||
bw.Close();
|
||||
ms.Close();
|
||||
|
||||
return data;
|
||||
|
||||
|
||||
//byte[] screenData = UMAME.instance.mUniVideoPlayer.GetScreenImg();
|
||||
|
||||
//FileStream fsImg = new FileStream(SavePath + Machine.sName + ".jpg", FileMode.Create);
|
||||
//fsImg.Write(screenData, 0, screenData.Length);
|
||||
//fsImg.Close();
|
||||
}
|
||||
void LoadState(byte[] data)
|
||||
{
|
||||
System.IO.MemoryStream fs = new System.IO.MemoryStream(data);
|
||||
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
|
||||
emu.LoadState(br);
|
||||
br.Close();
|
||||
fs.Close();
|
||||
mFPS.text = ($"fpsv {mUniVideoPlayer.videoFPS.ToString("F2")} fpsa {mUniSoundPlayer.audioFPS.ToString("F2")} ,Idx:{App.roomMgr.netReplay?.mCurrClientFrameIdx},RIdx:{App.roomMgr.netReplay?.mRemoteFrameIdx},RForward:{App.roomMgr.netReplay?.mRemoteForwardCount} ,RD:{App.roomMgr.netReplay?.mRemoteForwardCount} ,D:{App.roomMgr.netReplay?.mDiffFrameCount} ,Q:{App.roomMgr.netReplay?.mNetReplayQueue.Count}");
|
||||
}
|
||||
public void SaveReplay()
|
||||
{
|
||||
string Path = SavePath + Machine.sName + ".rp";
|
||||
string dbgPath = SavePath + Machine.sName + ".rpwrite";
|
||||
mReplayWriter.SaveData(Path, true, dbgPath);
|
||||
}
|
||||
public void StopGame()
|
||||
{
|
||||
if (bInGame)
|
||||
{
|
||||
emu.StopGame();
|
||||
mUniVideoPlayer.StopVideo();
|
||||
mUniSoundPlayer.StopPlay();
|
||||
bInGame = false;
|
||||
bLogicUpdatePause = false;
|
||||
}
|
||||
}
|
||||
byte[] SaveState()
|
||||
{
|
||||
if (!AxiIO.Directory.Exists(SavePath))
|
||||
AxiIO.Directory.CreateDirectory(SavePath);
|
||||
|
||||
System.IO.MemoryStream ms = new System.IO.MemoryStream();
|
||||
System.IO.BinaryWriter bw = new System.IO.BinaryWriter(ms);
|
||||
emu.SaveState(bw);
|
||||
byte[] data = ms.ToArray();
|
||||
bw.Close();
|
||||
ms.Close();
|
||||
|
||||
return data;
|
||||
|
||||
|
||||
//byte[] screenData = UMAME.instance.mUniVideoPlayer.GetScreenImg();
|
||||
|
||||
//FileStream fsImg = new FileStream(SavePath + Machine.sName + ".jpg", FileMode.Create);
|
||||
//fsImg.Write(screenData, 0, screenData.Length);
|
||||
//fsImg.Close();
|
||||
}
|
||||
void LoadState(byte[] data)
|
||||
{
|
||||
System.IO.MemoryStream fs = new System.IO.MemoryStream(data);
|
||||
System.IO.BinaryReader br = new System.IO.BinaryReader(fs);
|
||||
emu.LoadState(br);
|
||||
br.Close();
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1,111 +1,111 @@
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using AxiReplay;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniKeyboard : MonoBehaviour, IKeyboard
|
||||
{
|
||||
public MameControllerMapper ControllerMapper { get; private set; }
|
||||
PlayMode mPlayMode;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
ControllerMapper = new MameControllerMapper();
|
||||
Init();
|
||||
}
|
||||
|
||||
public ulong GetPressedKeys()
|
||||
{
|
||||
return mPlayMode.GetPressedKeys();
|
||||
}
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using AxiReplay;
|
||||
using MAME.Core;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
public class UniKeyboard : MonoBehaviour, IKeyboard
|
||||
{
|
||||
public MameControllerMapper ControllerMapper { get; private set; }
|
||||
PlayMode mPlayMode;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
ControllerMapper = new MameControllerMapper();
|
||||
Init();
|
||||
}
|
||||
|
||||
public ulong GetPressedKeys()
|
||||
{
|
||||
return mPlayMode.GetPressedKeys();
|
||||
}
|
||||
public void SyncInput(ulong inputData)
|
||||
{
|
||||
mPlayMode.CurrLocalInpuAllData = inputData;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ulong DoLocalPressedKeys()
|
||||
{
|
||||
return mPlayMode.DoLocalPressedKeys();
|
||||
}
|
||||
|
||||
#region
|
||||
|
||||
|
||||
public void Init()
|
||||
{
|
||||
mPlayMode = new PlayMode(this);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetInputpDataToMotionKey(ulong inputdata)
|
||||
{
|
||||
if (inputdata == 0)
|
||||
yield break;
|
||||
for (int i = 0; i < MotionKey.AllNeedCheckList.Length; i++)
|
||||
{
|
||||
if ((inputdata & MotionKey.AllNeedCheckList[i]) > 0)
|
||||
yield return MotionKey.GetKeyName(MotionKey.AllNeedCheckList[i]);
|
||||
}
|
||||
}
|
||||
public class PlayMode
|
||||
{
|
||||
UniKeyboard mUniKeyboard;
|
||||
public ulong CurrLocalInpuAllData = 0;
|
||||
public ulong CurrRemoteInpuAllData = 0;
|
||||
|
||||
public PlayMode(UniKeyboard uniKeyboard)
|
||||
{
|
||||
this.mUniKeyboard = uniKeyboard;
|
||||
}
|
||||
|
||||
public ulong GetPressedKeys()
|
||||
{
|
||||
if (InGameUI.Instance.Core.IsNetPlay)
|
||||
return CurrRemoteInpuAllData;
|
||||
else
|
||||
return CurrLocalInpuAllData;
|
||||
}
|
||||
|
||||
public ulong DoLocalPressedKeys()
|
||||
{
|
||||
ulong tempLocalInputAllData = 0;
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller0.GetSingleAllInput();
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller1.GetSingleAllInput();
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller2.GetSingleAllInput();
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller3.GetSingleAllInput();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (CurrLocalInpuAllData != tempLocalInputAllData)
|
||||
{
|
||||
string ShowKeyNames = string.Empty;
|
||||
foreach (string keyname in GetInputpDataToMotionKey(CurrLocalInpuAllData))
|
||||
{
|
||||
ShowKeyNames += keyname + " |";
|
||||
}
|
||||
Debug.Log("GetPressedKeys=>" + ShowKeyNames);
|
||||
}
|
||||
#endif
|
||||
|
||||
CurrLocalInpuAllData = tempLocalInputAllData;
|
||||
//写入replay
|
||||
UMAME.instance.mReplayWriter.NextFramebyFrameIdx((int)UMAME.instance.mUniVideoPlayer.mFrame, CurrLocalInpuAllData);
|
||||
|
||||
CheckPlayerSlotChanged();
|
||||
|
||||
return CurrLocalInpuAllData;
|
||||
}
|
||||
|
||||
|
||||
void CheckPlayerSlotChanged()
|
||||
{
|
||||
}
|
||||
|
||||
#region
|
||||
|
||||
|
||||
public void Init()
|
||||
{
|
||||
mPlayMode = new PlayMode(this);
|
||||
}
|
||||
|
||||
public static IEnumerable<string> GetInputpDataToMotionKey(ulong inputdata)
|
||||
{
|
||||
if (inputdata == 0)
|
||||
yield break;
|
||||
for (int i = 0; i < MotionKey.AllNeedCheckList.Length; i++)
|
||||
{
|
||||
if ((inputdata & MotionKey.AllNeedCheckList[i]) > 0)
|
||||
yield return MotionKey.GetKeyName(MotionKey.AllNeedCheckList[i]);
|
||||
}
|
||||
}
|
||||
public class PlayMode
|
||||
{
|
||||
UniKeyboard mUniKeyboard;
|
||||
public ulong CurrLocalInpuAllData = 0;
|
||||
public ulong CurrRemoteInpuAllData = 0;
|
||||
|
||||
public PlayMode(UniKeyboard uniKeyboard)
|
||||
{
|
||||
this.mUniKeyboard = uniKeyboard;
|
||||
}
|
||||
|
||||
public ulong GetPressedKeys()
|
||||
{
|
||||
if (InGameUI.Instance.Core.IsNetPlay)
|
||||
return CurrRemoteInpuAllData;
|
||||
else
|
||||
return CurrLocalInpuAllData;
|
||||
}
|
||||
|
||||
public ulong DoLocalPressedKeys()
|
||||
{
|
||||
ulong tempLocalInputAllData = 0;
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller0.GetSingleAllInput();
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller1.GetSingleAllInput();
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller2.GetSingleAllInput();
|
||||
tempLocalInputAllData |= mUniKeyboard.ControllerMapper.Controller3.GetSingleAllInput();
|
||||
|
||||
#if UNITY_EDITOR
|
||||
if (CurrLocalInpuAllData != tempLocalInputAllData)
|
||||
{
|
||||
string ShowKeyNames = string.Empty;
|
||||
foreach (string keyname in GetInputpDataToMotionKey(CurrLocalInpuAllData))
|
||||
{
|
||||
ShowKeyNames += keyname + " |";
|
||||
}
|
||||
Debug.Log("GetPressedKeys=>" + ShowKeyNames);
|
||||
}
|
||||
#endif
|
||||
|
||||
CurrLocalInpuAllData = tempLocalInputAllData;
|
||||
//写入replay
|
||||
UMAME.instance.mReplayWriter.NextFramebyFrameIdx((int)UMAME.instance.mUniVideoPlayer.mFrame, CurrLocalInpuAllData);
|
||||
|
||||
CheckPlayerSlotChanged();
|
||||
|
||||
return CurrLocalInpuAllData;
|
||||
}
|
||||
|
||||
|
||||
void CheckPlayerSlotChanged()
|
||||
{
|
||||
if (!mUniKeyboard.ControllerMapper.Controller0.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller0.AnyButtonDown())
|
||||
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0);
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0);
|
||||
|
||||
if (!mUniKeyboard.ControllerMapper.Controller1.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller1.AnyButtonDown())
|
||||
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 1);
|
||||
|
||||
@ -113,340 +113,340 @@ public class UniKeyboard : MonoBehaviour, IKeyboard
|
||||
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 2);
|
||||
|
||||
if (!mUniKeyboard.ControllerMapper.Controller3.ConnectSlot.HasValue && mUniKeyboard.ControllerMapper.Controller3.AnyButtonDown())
|
||||
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 3);
|
||||
}
|
||||
|
||||
}
|
||||
public class ReplayMode
|
||||
{
|
||||
ulong currInputData;
|
||||
|
||||
public ReplayMode()
|
||||
{
|
||||
}
|
||||
|
||||
public ulong GetPressedKeys()
|
||||
{
|
||||
int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame;
|
||||
AxiReplay.ReplayStep stepData;
|
||||
//有变化
|
||||
if (UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out stepData))
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
string ShowKeyNames = string.Empty;
|
||||
foreach (string keyname in GetInputpDataToMotionKey(currInputData))
|
||||
{
|
||||
ShowKeyNames += keyname + " |";
|
||||
}
|
||||
Debug.Log("GetPressedKeys=>" + ShowKeyNames);
|
||||
#endif
|
||||
currInputData = stepData.InPut;
|
||||
}
|
||||
return currInputData;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class MameControllerMapper : IControllerSetuper
|
||||
{
|
||||
public MameSingleConoller Controller0 = new MameSingleConoller(0);
|
||||
public MameSingleConoller Controller1 = new MameSingleConoller(1);
|
||||
public MameSingleConoller Controller2 = new MameSingleConoller(2);
|
||||
public MameSingleConoller Controller3 = new MameSingleConoller(3);
|
||||
|
||||
ulong mCurrAllInput;
|
||||
|
||||
public void SetConnect(uint? con0ToSlot = null,
|
||||
uint? con1ToSlot = null,
|
||||
uint? con2ToSlot = null,
|
||||
uint? con3ToSlot = null)
|
||||
{
|
||||
Controller0.ConnectSlot = con0ToSlot;
|
||||
Controller1.ConnectSlot = con1ToSlot;
|
||||
Controller2.ConnectSlot = con2ToSlot;
|
||||
Controller3.ConnectSlot = con3ToSlot;
|
||||
}
|
||||
public int? GetSlotConnectingControllerIndex(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return 0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return 1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return 2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return 3;
|
||||
else return null;
|
||||
}
|
||||
public IController GetSlotConnectingController(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return Controller0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return Controller1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return Controller2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return Controller3;
|
||||
else return null;
|
||||
}
|
||||
static HashSet<uint> s_temp = new HashSet<uint>();
|
||||
public uint? GetFreeSlotIndex()
|
||||
{
|
||||
s_temp.Clear();
|
||||
s_temp.Add(0);
|
||||
s_temp.Add(1);
|
||||
s_temp.Add(2);
|
||||
s_temp.Add(3);
|
||||
|
||||
if (Controller0.ConnectSlot.HasValue) s_temp.Remove(Controller0.ConnectSlot.Value);
|
||||
if (Controller1.ConnectSlot.HasValue) s_temp.Remove(Controller1.ConnectSlot.Value);
|
||||
if (Controller2.ConnectSlot.HasValue) s_temp.Remove(Controller2.ConnectSlot.Value);
|
||||
if (Controller3.ConnectSlot.HasValue) s_temp.Remove(Controller3.ConnectSlot.Value);
|
||||
|
||||
if (s_temp.Count > 0) return s_temp.First();
|
||||
else return null;
|
||||
}
|
||||
public void LetControllerConnect(int conIndex, uint slotIndex)
|
||||
{
|
||||
MameSingleConoller targetController;
|
||||
switch (conIndex)
|
||||
{
|
||||
case 0: targetController = Controller0; break;
|
||||
case 1: targetController = Controller1; break;
|
||||
case 2: targetController = Controller2; break;
|
||||
case 3: targetController = Controller3; break;
|
||||
default:
|
||||
throw new System.Exception($"Not Allowed conIndex Range: {conIndex}");
|
||||
break;
|
||||
}
|
||||
if (targetController.ConnectSlot.HasValue) return;
|
||||
|
||||
targetController.ConnectSlot = slotIndex;
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MAME控制器
|
||||
/// </summary>
|
||||
public class MameSingleConoller : IController
|
||||
{
|
||||
//public KeyCode INSERT_COIN, GAMESTART,
|
||||
//UP, DOWN, LEFT, RIGHT,
|
||||
//BTN_A, BTN_B, BTN_C, BTN_D, BTN_E, BTN_F;
|
||||
|
||||
public ulong tg_INSERT_COIN, tg_GAMESTART,
|
||||
tg_UP, tg_DOWN, tg_LEFT, tg_RIGHT,
|
||||
tg_BTN_A, tg_BTN_B, tg_BTN_C, tg_BTN_D, tg_BTN_E, tg_BTN_F;
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 3);
|
||||
}
|
||||
|
||||
}
|
||||
public class ReplayMode
|
||||
{
|
||||
ulong currInputData;
|
||||
|
||||
public ReplayMode()
|
||||
{
|
||||
}
|
||||
|
||||
public ulong GetPressedKeys()
|
||||
{
|
||||
int targetFrame = (int)UMAME.instance.mUniVideoPlayer.mFrame;
|
||||
AxiReplay.ReplayStep stepData;
|
||||
//有变化
|
||||
if (UMAME.instance.mReplayReader.NextFramebyFrameIdx(targetFrame, out stepData))
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
string ShowKeyNames = string.Empty;
|
||||
foreach (string keyname in GetInputpDataToMotionKey(currInputData))
|
||||
{
|
||||
ShowKeyNames += keyname + " |";
|
||||
}
|
||||
Debug.Log("GetPressedKeys=>" + ShowKeyNames);
|
||||
#endif
|
||||
currInputData = stepData.InPut;
|
||||
}
|
||||
return currInputData;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class MameControllerMapper : IControllerSetuper
|
||||
{
|
||||
public MameSingleConoller Controller0 = new MameSingleConoller(0);
|
||||
public MameSingleConoller Controller1 = new MameSingleConoller(1);
|
||||
public MameSingleConoller Controller2 = new MameSingleConoller(2);
|
||||
public MameSingleConoller Controller3 = new MameSingleConoller(3);
|
||||
|
||||
ulong mCurrAllInput;
|
||||
|
||||
public void SetConnect(uint? con0ToSlot = null,
|
||||
uint? con1ToSlot = null,
|
||||
uint? con2ToSlot = null,
|
||||
uint? con3ToSlot = null)
|
||||
{
|
||||
Controller0.ConnectSlot = con0ToSlot;
|
||||
Controller1.ConnectSlot = con1ToSlot;
|
||||
Controller2.ConnectSlot = con2ToSlot;
|
||||
Controller3.ConnectSlot = con3ToSlot;
|
||||
}
|
||||
public int? GetSlotConnectingControllerIndex(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return 0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return 1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return 2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return 3;
|
||||
else return null;
|
||||
}
|
||||
public IController GetSlotConnectingController(int slotIndex)
|
||||
{
|
||||
if (Controller0.ConnectSlot.HasValue && Controller0.ConnectSlot.Value == slotIndex) return Controller0;
|
||||
else if (Controller1.ConnectSlot.HasValue && Controller1.ConnectSlot.Value == slotIndex) return Controller1;
|
||||
else if (Controller2.ConnectSlot.HasValue && Controller2.ConnectSlot.Value == slotIndex) return Controller2;
|
||||
else if (Controller3.ConnectSlot.HasValue && Controller3.ConnectSlot.Value == slotIndex) return Controller3;
|
||||
else return null;
|
||||
}
|
||||
static HashSet<uint> s_temp = new HashSet<uint>();
|
||||
public uint? GetFreeSlotIndex()
|
||||
{
|
||||
s_temp.Clear();
|
||||
s_temp.Add(0);
|
||||
s_temp.Add(1);
|
||||
s_temp.Add(2);
|
||||
s_temp.Add(3);
|
||||
|
||||
if (Controller0.ConnectSlot.HasValue) s_temp.Remove(Controller0.ConnectSlot.Value);
|
||||
if (Controller1.ConnectSlot.HasValue) s_temp.Remove(Controller1.ConnectSlot.Value);
|
||||
if (Controller2.ConnectSlot.HasValue) s_temp.Remove(Controller2.ConnectSlot.Value);
|
||||
if (Controller3.ConnectSlot.HasValue) s_temp.Remove(Controller3.ConnectSlot.Value);
|
||||
|
||||
if (s_temp.Count > 0) return s_temp.First();
|
||||
else return null;
|
||||
}
|
||||
public void LetControllerConnect(int conIndex, uint slotIndex)
|
||||
{
|
||||
MameSingleConoller targetController;
|
||||
switch (conIndex)
|
||||
{
|
||||
case 0: targetController = Controller0; break;
|
||||
case 1: targetController = Controller1; break;
|
||||
case 2: targetController = Controller2; break;
|
||||
case 3: targetController = Controller3; break;
|
||||
default:
|
||||
throw new System.Exception($"Not Allowed conIndex Range: {conIndex}");
|
||||
break;
|
||||
}
|
||||
if (targetController.ConnectSlot.HasValue) return;
|
||||
|
||||
targetController.ConnectSlot = slotIndex;
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// MAME控制器
|
||||
/// </summary>
|
||||
public class MameSingleConoller : IController
|
||||
{
|
||||
//public KeyCode INSERT_COIN, GAMESTART,
|
||||
//UP, DOWN, LEFT, RIGHT,
|
||||
//BTN_A, BTN_B, BTN_C, BTN_D, BTN_E, BTN_F;
|
||||
|
||||
public ulong tg_INSERT_COIN, tg_GAMESTART,
|
||||
tg_UP, tg_DOWN, tg_LEFT, tg_RIGHT,
|
||||
tg_BTN_A, tg_BTN_B, tg_BTN_C, tg_BTN_D, tg_BTN_E, tg_BTN_F;
|
||||
|
||||
public ulong CurrLocalSingleAllInput { get; private set; }
|
||||
|
||||
private MAMEKeyBinding m_keyMapper;
|
||||
int mControllerIndex;
|
||||
uint? mConnectSlot;
|
||||
|
||||
/// <summary>
|
||||
/// 指示该手柄连接的手柄插槽
|
||||
/// <para><c>这个值代表了该手柄在实际游戏中控制的Player</c></para>
|
||||
/// <value>[0,3] 例外:为空代表未连接</value>
|
||||
/// </summary>
|
||||
public uint? ConnectSlot
|
||||
{
|
||||
get { return mConnectSlot; }
|
||||
set { mConnectSlot = value; this.ResetTargetMotionKey(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控制器编号
|
||||
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
|
||||
/// <value>[0,3]</value>
|
||||
/// </summary>
|
||||
public int ControllerIndex
|
||||
{
|
||||
get { return mControllerIndex; }
|
||||
private MAMEKeyBinding m_keyMapper;
|
||||
int mControllerIndex;
|
||||
uint? mConnectSlot;
|
||||
|
||||
/// <summary>
|
||||
/// 指示该手柄连接的手柄插槽
|
||||
/// <para><c>这个值代表了该手柄在实际游戏中控制的Player</c></para>
|
||||
/// <value>[0,3] 例外:为空代表未连接</value>
|
||||
/// </summary>
|
||||
public uint? ConnectSlot
|
||||
{
|
||||
get { return mConnectSlot; }
|
||||
set { mConnectSlot = value; this.ResetTargetMotionKey(); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 控制器编号
|
||||
/// <para><c>此编号并非对应游戏中的player1,player2,player3,player4,仅仅作为本地4个手柄的实例</c></para>
|
||||
/// <value>[0,3]</value>
|
||||
/// </summary>
|
||||
public int ControllerIndex
|
||||
{
|
||||
get { return mControllerIndex; }
|
||||
set
|
||||
{
|
||||
mControllerIndex = value;
|
||||
//this.LoadControlKeyForConfig();
|
||||
//走统一配置
|
||||
}
|
||||
}
|
||||
public MameSingleConoller(int controllerIndex)
|
||||
{
|
||||
ControllerIndex = controllerIndex;
|
||||
m_keyMapper = App.settings.KeyMapper.GetBinder<MAMEKeyBinding>(UMAME.instance.Platform);
|
||||
}
|
||||
|
||||
public bool AnyButtonDown()
|
||||
{
|
||||
return m_keyMapper.AnyKeyDown(ControllerIndex);
|
||||
//if (Input.GetKeyDown(INSERT_COIN)) return true;
|
||||
//if (Input.GetKeyDown(GAMESTART)) return true;
|
||||
//if (Input.GetKeyDown(UP)) return true;
|
||||
//if (Input.GetKeyDown(DOWN)) return true;
|
||||
//if (Input.GetKeyDown(LEFT)) return true;
|
||||
//if (Input.GetKeyDown(RIGHT)) return true;
|
||||
//if (Input.GetKeyDown(BTN_A)) return true;
|
||||
//if (Input.GetKeyDown(BTN_B)) return true;
|
||||
//if (Input.GetKeyDown(BTN_C)) return true;
|
||||
//if (Input.GetKeyDown(BTN_D)) return true;
|
||||
//if (Input.GetKeyDown(BTN_E)) return true;
|
||||
//if (Input.GetKeyDown(BTN_F)) return true;
|
||||
//return false;
|
||||
}
|
||||
public ulong GetSingleAllInput()
|
||||
{
|
||||
if (!ConnectSlot.HasValue)
|
||||
return 0;
|
||||
CurrLocalSingleAllInput = 0;
|
||||
|
||||
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.INSERT_COIN, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.GAMESTART, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.UP, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_UP;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.DOWN, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.LEFT, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.RIGHT, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_A, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_A;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_B, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_B;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_C, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_C;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_D, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_D;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_E, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_E;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_F, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_F;
|
||||
|
||||
//if (Input.GetKey(INSERT_COIN)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
|
||||
//if (Input.GetKey(GAMESTART)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
|
||||
//if (Input.GetKey(UP)) CurrLocalSingleAllInput |= (ulong)tg_UP;
|
||||
//if (Input.GetKey(DOWN)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
|
||||
//if (Input.GetKey(LEFT)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
|
||||
//if (Input.GetKey(RIGHT)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
|
||||
//if (Input.GetKey(BTN_A)) CurrLocalSingleAllInput |= (ulong)tg_BTN_A;
|
||||
//if (Input.GetKey(BTN_B)) CurrLocalSingleAllInput |= (ulong)tg_BTN_B;
|
||||
//if (Input.GetKey(BTN_C)) CurrLocalSingleAllInput |= (ulong)tg_BTN_C;
|
||||
//if (Input.GetKey(BTN_D)) CurrLocalSingleAllInput |= (ulong)tg_BTN_D;
|
||||
//if (Input.GetKey(BTN_E)) CurrLocalSingleAllInput |= (ulong)tg_BTN_E;
|
||||
//if (Input.GetKey(BTN_F)) CurrLocalSingleAllInput |= (ulong)tg_BTN_F;
|
||||
|
||||
return CurrLocalSingleAllInput;
|
||||
}
|
||||
|
||||
}
|
||||
public static class MameSingleControllSetter
|
||||
{
|
||||
//不再需要
|
||||
//public static void LoadControlKeyForConfig(this MameSingleConoller singlecontrol)
|
||||
//{
|
||||
// //TODO 等待支持配置,或统一
|
||||
// switch (singlecontrol.ControllerIndex)
|
||||
// {
|
||||
// case 0:
|
||||
// singlecontrol.INSERT_COIN = KeyCode.Alpha5;
|
||||
// singlecontrol.GAMESTART = KeyCode.Alpha1;
|
||||
// singlecontrol.UP = KeyCode.W;
|
||||
// singlecontrol.DOWN = KeyCode.S;
|
||||
// singlecontrol.LEFT = KeyCode.A;
|
||||
// singlecontrol.RIGHT = KeyCode.D;
|
||||
// singlecontrol.BTN_A = KeyCode.J;
|
||||
// singlecontrol.BTN_B = KeyCode.K;
|
||||
// singlecontrol.BTN_C = KeyCode.L;
|
||||
// singlecontrol.BTN_D = KeyCode.U;
|
||||
// singlecontrol.BTN_E = KeyCode.I;
|
||||
// singlecontrol.BTN_F = KeyCode.O;
|
||||
// break;
|
||||
// case 1:
|
||||
// singlecontrol.INSERT_COIN = KeyCode.KeypadMultiply;
|
||||
// singlecontrol.GAMESTART = KeyCode.KeypadDivide;
|
||||
// singlecontrol.UP = KeyCode.UpArrow;
|
||||
// singlecontrol.DOWN = KeyCode.DownArrow;
|
||||
// singlecontrol.LEFT = KeyCode.LeftArrow;
|
||||
// singlecontrol.RIGHT = KeyCode.RightArrow;
|
||||
// singlecontrol.BTN_A = KeyCode.Keypad1;
|
||||
// singlecontrol.BTN_B = KeyCode.Keypad2;
|
||||
// singlecontrol.BTN_C = KeyCode.Keypad3;
|
||||
// singlecontrol.BTN_D = KeyCode.Keypad4;
|
||||
// singlecontrol.BTN_E = KeyCode.Keypad5;
|
||||
// singlecontrol.BTN_F = KeyCode.Keypad6;
|
||||
// break;
|
||||
// case 2:
|
||||
// break;
|
||||
// case 3:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
public static void ResetTargetMotionKey(this MameSingleConoller singlecontrol)
|
||||
{
|
||||
if (!singlecontrol.ConnectSlot.HasValue)
|
||||
{
|
||||
singlecontrol.tg_INSERT_COIN
|
||||
= singlecontrol.tg_GAMESTART
|
||||
= singlecontrol.tg_UP
|
||||
= singlecontrol.tg_DOWN
|
||||
= singlecontrol.tg_LEFT
|
||||
= singlecontrol.tg_RIGHT
|
||||
= singlecontrol.tg_BTN_A
|
||||
= singlecontrol.tg_BTN_B
|
||||
= singlecontrol.tg_BTN_C
|
||||
= singlecontrol.tg_BTN_D
|
||||
= singlecontrol.tg_BTN_E
|
||||
= singlecontrol.tg_BTN_F
|
||||
= MotionKey.FinalKey;
|
||||
return;
|
||||
}
|
||||
switch (singlecontrol.ConnectSlot.Value)
|
||||
{
|
||||
case 0:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.P1_INSERT_COIN;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.P1_GAMESTART;
|
||||
singlecontrol.tg_UP = MotionKey.P1_UP;
|
||||
singlecontrol.tg_DOWN = MotionKey.P1_DOWN;
|
||||
singlecontrol.tg_LEFT = MotionKey.P1_LEFT;
|
||||
singlecontrol.tg_RIGHT = MotionKey.P1_RIGHT;
|
||||
singlecontrol.tg_BTN_A = MotionKey.P1_BTN_1;
|
||||
singlecontrol.tg_BTN_B = MotionKey.P1_BTN_2;
|
||||
singlecontrol.tg_BTN_C = MotionKey.P1_BTN_3;
|
||||
singlecontrol.tg_BTN_D = MotionKey.P1_BTN_4;
|
||||
singlecontrol.tg_BTN_E = MotionKey.P1_BTN_5;
|
||||
singlecontrol.tg_BTN_F = MotionKey.P1_BTN_6;
|
||||
break;
|
||||
case 1:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.P2_INSERT_COIN;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.P2_GAMESTART;
|
||||
singlecontrol.tg_UP = MotionKey.P2_UP;
|
||||
singlecontrol.tg_DOWN = MotionKey.P2_DOWN;
|
||||
singlecontrol.tg_LEFT = MotionKey.P2_LEFT;
|
||||
singlecontrol.tg_RIGHT = MotionKey.P2_RIGHT;
|
||||
singlecontrol.tg_BTN_A = MotionKey.P2_BTN_1;
|
||||
singlecontrol.tg_BTN_B = MotionKey.P2_BTN_2;
|
||||
singlecontrol.tg_BTN_C = MotionKey.P2_BTN_3;
|
||||
singlecontrol.tg_BTN_D = MotionKey.P2_BTN_4;
|
||||
singlecontrol.tg_BTN_E = MotionKey.P2_BTN_5;
|
||||
singlecontrol.tg_BTN_F = MotionKey.P2_BTN_6;
|
||||
break;
|
||||
//后续修改后 支持P3 P4
|
||||
case 2:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.FinalKey;
|
||||
singlecontrol.tg_UP = MotionKey.FinalKey;
|
||||
singlecontrol.tg_DOWN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_LEFT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_RIGHT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_A = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_B = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_C = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_D = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_E = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_F = MotionKey.FinalKey;
|
||||
break;
|
||||
case 3:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.FinalKey;
|
||||
singlecontrol.tg_UP = MotionKey.FinalKey;
|
||||
singlecontrol.tg_DOWN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_LEFT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_RIGHT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_A = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_B = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_C = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_D = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_E = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_F = MotionKey.FinalKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
public MameSingleConoller(int controllerIndex)
|
||||
{
|
||||
ControllerIndex = controllerIndex;
|
||||
m_keyMapper = App.settings.KeyMapper.GetBinder<MAMEKeyBinding>(UMAME.instance.Platform);
|
||||
}
|
||||
|
||||
public bool AnyButtonDown()
|
||||
{
|
||||
return m_keyMapper.AnyKeyDown(ControllerIndex);
|
||||
//if (Input.GetKeyDown(INSERT_COIN)) return true;
|
||||
//if (Input.GetKeyDown(GAMESTART)) return true;
|
||||
//if (Input.GetKeyDown(UP)) return true;
|
||||
//if (Input.GetKeyDown(DOWN)) return true;
|
||||
//if (Input.GetKeyDown(LEFT)) return true;
|
||||
//if (Input.GetKeyDown(RIGHT)) return true;
|
||||
//if (Input.GetKeyDown(BTN_A)) return true;
|
||||
//if (Input.GetKeyDown(BTN_B)) return true;
|
||||
//if (Input.GetKeyDown(BTN_C)) return true;
|
||||
//if (Input.GetKeyDown(BTN_D)) return true;
|
||||
//if (Input.GetKeyDown(BTN_E)) return true;
|
||||
//if (Input.GetKeyDown(BTN_F)) return true;
|
||||
//return false;
|
||||
}
|
||||
public ulong GetSingleAllInput()
|
||||
{
|
||||
if (!ConnectSlot.HasValue)
|
||||
return 0;
|
||||
CurrLocalSingleAllInput = 0;
|
||||
|
||||
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.INSERT_COIN, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.GAMESTART, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.UP, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_UP;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.DOWN, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.LEFT, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.RIGHT, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_A, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_A;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_B, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_B;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_C, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_C;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_D, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_D;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_E, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_E;
|
||||
if (m_keyMapper.GetKey(UMAMEKSingleKey.BTN_F, ControllerIndex)) CurrLocalSingleAllInput |= (ulong)tg_BTN_F;
|
||||
|
||||
//if (Input.GetKey(INSERT_COIN)) CurrLocalSingleAllInput |= (ulong)tg_INSERT_COIN;
|
||||
//if (Input.GetKey(GAMESTART)) CurrLocalSingleAllInput |= (ulong)tg_GAMESTART;
|
||||
//if (Input.GetKey(UP)) CurrLocalSingleAllInput |= (ulong)tg_UP;
|
||||
//if (Input.GetKey(DOWN)) CurrLocalSingleAllInput |= (ulong)tg_DOWN;
|
||||
//if (Input.GetKey(LEFT)) CurrLocalSingleAllInput |= (ulong)tg_LEFT;
|
||||
//if (Input.GetKey(RIGHT)) CurrLocalSingleAllInput |= (ulong)tg_RIGHT;
|
||||
//if (Input.GetKey(BTN_A)) CurrLocalSingleAllInput |= (ulong)tg_BTN_A;
|
||||
//if (Input.GetKey(BTN_B)) CurrLocalSingleAllInput |= (ulong)tg_BTN_B;
|
||||
//if (Input.GetKey(BTN_C)) CurrLocalSingleAllInput |= (ulong)tg_BTN_C;
|
||||
//if (Input.GetKey(BTN_D)) CurrLocalSingleAllInput |= (ulong)tg_BTN_D;
|
||||
//if (Input.GetKey(BTN_E)) CurrLocalSingleAllInput |= (ulong)tg_BTN_E;
|
||||
//if (Input.GetKey(BTN_F)) CurrLocalSingleAllInput |= (ulong)tg_BTN_F;
|
||||
|
||||
return CurrLocalSingleAllInput;
|
||||
}
|
||||
|
||||
}
|
||||
public static class MameSingleControllSetter
|
||||
{
|
||||
//不再需要
|
||||
//public static void LoadControlKeyForConfig(this MameSingleConoller singlecontrol)
|
||||
//{
|
||||
// //TODO 等待支持配置,或统一
|
||||
// switch (singlecontrol.ControllerIndex)
|
||||
// {
|
||||
// case 0:
|
||||
// singlecontrol.INSERT_COIN = KeyCode.Alpha5;
|
||||
// singlecontrol.GAMESTART = KeyCode.Alpha1;
|
||||
// singlecontrol.UP = KeyCode.W;
|
||||
// singlecontrol.DOWN = KeyCode.S;
|
||||
// singlecontrol.LEFT = KeyCode.A;
|
||||
// singlecontrol.RIGHT = KeyCode.D;
|
||||
// singlecontrol.BTN_A = KeyCode.J;
|
||||
// singlecontrol.BTN_B = KeyCode.K;
|
||||
// singlecontrol.BTN_C = KeyCode.L;
|
||||
// singlecontrol.BTN_D = KeyCode.U;
|
||||
// singlecontrol.BTN_E = KeyCode.I;
|
||||
// singlecontrol.BTN_F = KeyCode.O;
|
||||
// break;
|
||||
// case 1:
|
||||
// singlecontrol.INSERT_COIN = KeyCode.KeypadMultiply;
|
||||
// singlecontrol.GAMESTART = KeyCode.KeypadDivide;
|
||||
// singlecontrol.UP = KeyCode.UpArrow;
|
||||
// singlecontrol.DOWN = KeyCode.DownArrow;
|
||||
// singlecontrol.LEFT = KeyCode.LeftArrow;
|
||||
// singlecontrol.RIGHT = KeyCode.RightArrow;
|
||||
// singlecontrol.BTN_A = KeyCode.Keypad1;
|
||||
// singlecontrol.BTN_B = KeyCode.Keypad2;
|
||||
// singlecontrol.BTN_C = KeyCode.Keypad3;
|
||||
// singlecontrol.BTN_D = KeyCode.Keypad4;
|
||||
// singlecontrol.BTN_E = KeyCode.Keypad5;
|
||||
// singlecontrol.BTN_F = KeyCode.Keypad6;
|
||||
// break;
|
||||
// case 2:
|
||||
// break;
|
||||
// case 3:
|
||||
// break;
|
||||
// }
|
||||
//}
|
||||
public static void ResetTargetMotionKey(this MameSingleConoller singlecontrol)
|
||||
{
|
||||
if (!singlecontrol.ConnectSlot.HasValue)
|
||||
{
|
||||
singlecontrol.tg_INSERT_COIN
|
||||
= singlecontrol.tg_GAMESTART
|
||||
= singlecontrol.tg_UP
|
||||
= singlecontrol.tg_DOWN
|
||||
= singlecontrol.tg_LEFT
|
||||
= singlecontrol.tg_RIGHT
|
||||
= singlecontrol.tg_BTN_A
|
||||
= singlecontrol.tg_BTN_B
|
||||
= singlecontrol.tg_BTN_C
|
||||
= singlecontrol.tg_BTN_D
|
||||
= singlecontrol.tg_BTN_E
|
||||
= singlecontrol.tg_BTN_F
|
||||
= MotionKey.FinalKey;
|
||||
return;
|
||||
}
|
||||
switch (singlecontrol.ConnectSlot.Value)
|
||||
{
|
||||
case 0:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.P1_INSERT_COIN;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.P1_GAMESTART;
|
||||
singlecontrol.tg_UP = MotionKey.P1_UP;
|
||||
singlecontrol.tg_DOWN = MotionKey.P1_DOWN;
|
||||
singlecontrol.tg_LEFT = MotionKey.P1_LEFT;
|
||||
singlecontrol.tg_RIGHT = MotionKey.P1_RIGHT;
|
||||
singlecontrol.tg_BTN_A = MotionKey.P1_BTN_1;
|
||||
singlecontrol.tg_BTN_B = MotionKey.P1_BTN_2;
|
||||
singlecontrol.tg_BTN_C = MotionKey.P1_BTN_3;
|
||||
singlecontrol.tg_BTN_D = MotionKey.P1_BTN_4;
|
||||
singlecontrol.tg_BTN_E = MotionKey.P1_BTN_5;
|
||||
singlecontrol.tg_BTN_F = MotionKey.P1_BTN_6;
|
||||
break;
|
||||
case 1:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.P2_INSERT_COIN;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.P2_GAMESTART;
|
||||
singlecontrol.tg_UP = MotionKey.P2_UP;
|
||||
singlecontrol.tg_DOWN = MotionKey.P2_DOWN;
|
||||
singlecontrol.tg_LEFT = MotionKey.P2_LEFT;
|
||||
singlecontrol.tg_RIGHT = MotionKey.P2_RIGHT;
|
||||
singlecontrol.tg_BTN_A = MotionKey.P2_BTN_1;
|
||||
singlecontrol.tg_BTN_B = MotionKey.P2_BTN_2;
|
||||
singlecontrol.tg_BTN_C = MotionKey.P2_BTN_3;
|
||||
singlecontrol.tg_BTN_D = MotionKey.P2_BTN_4;
|
||||
singlecontrol.tg_BTN_E = MotionKey.P2_BTN_5;
|
||||
singlecontrol.tg_BTN_F = MotionKey.P2_BTN_6;
|
||||
break;
|
||||
//后续修改后 支持P3 P4
|
||||
case 2:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.FinalKey;
|
||||
singlecontrol.tg_UP = MotionKey.FinalKey;
|
||||
singlecontrol.tg_DOWN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_LEFT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_RIGHT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_A = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_B = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_C = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_D = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_E = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_F = MotionKey.FinalKey;
|
||||
break;
|
||||
case 3:
|
||||
singlecontrol.tg_INSERT_COIN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_GAMESTART = MotionKey.FinalKey;
|
||||
singlecontrol.tg_UP = MotionKey.FinalKey;
|
||||
singlecontrol.tg_DOWN = MotionKey.FinalKey;
|
||||
singlecontrol.tg_LEFT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_RIGHT = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_A = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_B = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_C = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_D = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_E = MotionKey.FinalKey;
|
||||
singlecontrol.tg_BTN_F = MotionKey.FinalKey;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,135 +1,135 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using VirtualNes.Core;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CoreSupporter : ISupporterImpl
|
||||
{
|
||||
|
||||
public System.IO.Stream OpenRom(string fname)
|
||||
{
|
||||
try
|
||||
{
|
||||
var romFile = App.GetRomLib(RomPlatformType.Nes).GetRomFile(fname);
|
||||
var bytes = romFile.GetRomFileData();
|
||||
Debug.Log($"Open {romFile.Alias}");
|
||||
return new System.IO.MemoryStream(bytes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetRomPathInfo(string fname, out string fullPath, out string directPath)
|
||||
{
|
||||
var romFile = App.GetRomLib(RomPlatformType.Nes).GetRomFile(fname);
|
||||
UnityEngine.Debug.Assert(romFile != null);
|
||||
|
||||
fullPath = romFile.LocalFilePath;
|
||||
directPath = System.IO.Path.GetDirectoryName(fullPath);
|
||||
}
|
||||
|
||||
public System.IO.Stream OpenFile_DISKSYS()
|
||||
{
|
||||
return new System.IO.MemoryStream(Resources.Load<TextAsset>("NES/Disksys.rom").bytes);
|
||||
}
|
||||
|
||||
public void SaveSRAMToFile(byte[] sramContent, string romName)
|
||||
{
|
||||
string sramDirectoryPath = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{Config.path.szSavePath}";
|
||||
AxiIO.Directory.CreateDirectory(sramDirectoryPath);
|
||||
romName = System.IO.Path.GetFileNameWithoutExtension(romName);
|
||||
AxiIO.File.WriteAllBytes($"{sramDirectoryPath}/{romName}.sav", sramContent);
|
||||
}
|
||||
|
||||
public void SaveDISKToFile(byte[] diskFileContent, string romName)
|
||||
{
|
||||
string diskFileDirectoryPath = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/dsv";
|
||||
AxiIO.Directory.CreateDirectory(diskFileDirectoryPath);
|
||||
romName = System.IO.Path.GetFileNameWithoutExtension(romName);
|
||||
AxiIO.File.WriteAllBytes($"{diskFileDirectoryPath}/{romName}.dsv", diskFileContent);
|
||||
}
|
||||
|
||||
public EmulatorConfig Config { get; private set; } = new EmulatorConfig();
|
||||
public void PrepareDirectory(string directPath)
|
||||
{
|
||||
AxiIO.Directory.CreateDirectory($"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{directPath}");
|
||||
}
|
||||
|
||||
public void SaveFile(byte[] fileData, string directPath, string fileName)
|
||||
{
|
||||
PrepareDirectory(directPath);
|
||||
|
||||
var fileFullpath = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{directPath}/{fileName}";
|
||||
AxiIO.File.WriteAllBytes(fileFullpath, fileData);
|
||||
}
|
||||
|
||||
public System.IO.Stream OpenFile(string directPath, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{directPath}/{fileName}";
|
||||
var data = AxiIO.File.ReadAllBytes(path);
|
||||
if (data == null) return null;
|
||||
return new System.IO.MemoryStream(data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetMapperNo(ROM rom, out int mapperNo)
|
||||
{
|
||||
var db = Resources.Load<RomDB>("NES/ROMDB");
|
||||
return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo);
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using System.Runtime.InteropServices;
|
||||
using UnityEngine;
|
||||
using VirtualNes.Core;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CoreSupporter : ISupporterImpl
|
||||
{
|
||||
|
||||
public System.IO.Stream OpenRom(string fname)
|
||||
{
|
||||
try
|
||||
{
|
||||
var romFile = App.GetRomLib(RomPlatformType.Nes).GetRomFile(fname);
|
||||
var bytes = romFile.GetRomFileData();
|
||||
Debug.Log($"Open {romFile.Alias}");
|
||||
return new System.IO.MemoryStream(bytes);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.LogError(ex);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void GetRomPathInfo(string fname, out string fullPath, out string directPath)
|
||||
{
|
||||
var romFile = App.GetRomLib(RomPlatformType.Nes).GetRomFile(fname);
|
||||
UnityEngine.Debug.Assert(romFile != null);
|
||||
|
||||
fullPath = romFile.LocalFilePath;
|
||||
directPath = System.IO.Path.GetDirectoryName(fullPath);
|
||||
}
|
||||
|
||||
public System.IO.Stream OpenFile_DISKSYS()
|
||||
{
|
||||
return new System.IO.MemoryStream(Resources.Load<TextAsset>("NES/Disksys.rom").bytes);
|
||||
}
|
||||
|
||||
public void SaveSRAMToFile(byte[] sramContent, string romName)
|
||||
{
|
||||
string sramDirectoryPath = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{Config.path.szSavePath}";
|
||||
AxiIO.Directory.CreateDirectory(sramDirectoryPath);
|
||||
romName = System.IO.Path.GetFileNameWithoutExtension(romName);
|
||||
AxiIO.File.WriteAllBytes($"{sramDirectoryPath}/{romName}.sav", sramContent);
|
||||
}
|
||||
|
||||
public void SaveDISKToFile(byte[] diskFileContent, string romName)
|
||||
{
|
||||
string diskFileDirectoryPath = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/dsv";
|
||||
AxiIO.Directory.CreateDirectory(diskFileDirectoryPath);
|
||||
romName = System.IO.Path.GetFileNameWithoutExtension(romName);
|
||||
AxiIO.File.WriteAllBytes($"{diskFileDirectoryPath}/{romName}.dsv", diskFileContent);
|
||||
}
|
||||
|
||||
public EmulatorConfig Config { get; private set; } = new EmulatorConfig();
|
||||
public void PrepareDirectory(string directPath)
|
||||
{
|
||||
AxiIO.Directory.CreateDirectory($"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{directPath}");
|
||||
}
|
||||
|
||||
public void SaveFile(byte[] fileData, string directPath, string fileName)
|
||||
{
|
||||
PrepareDirectory(directPath);
|
||||
|
||||
var fileFullpath = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{directPath}/{fileName}";
|
||||
AxiIO.File.WriteAllBytes(fileFullpath, fileData);
|
||||
}
|
||||
|
||||
public System.IO.Stream OpenFile(string directPath, string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var path = $"{App.PersistentDataPath(AxibugProtobuf.RomPlatformType.Nes)}/{directPath}/{fileName}";
|
||||
var data = AxiIO.File.ReadAllBytes(path);
|
||||
if (data == null) return null;
|
||||
return new System.IO.MemoryStream(data);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public bool TryGetMapperNo(ROM rom, out int mapperNo)
|
||||
{
|
||||
var db = Resources.Load<RomDB>("NES/ROMDB");
|
||||
return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo);
|
||||
}
|
||||
|
||||
|
||||
public ControllerState FromNet(AxiReplay.ReplayStep step)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
var result = new ControllerState();
|
||||
temp.all = step.InPut;
|
||||
result.raw0 = temp.p1;
|
||||
result.raw1 = temp.p2;
|
||||
result.raw2 = temp.p3;
|
||||
result.raw3 = temp.p4;
|
||||
result.valid = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public uint ToNet(ControllerState state)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
temp.p1 = (byte)state.raw0;
|
||||
temp.p2 = (byte)state.raw1;
|
||||
temp.p3 = (byte)state.raw2;
|
||||
temp.p4 = (byte)state.raw3;
|
||||
return (uint)temp.all;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 8)]
|
||||
struct ServerInputSnapShot
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public UInt64 all;
|
||||
[FieldOffset(0)]
|
||||
public byte p1;
|
||||
[FieldOffset(1)]
|
||||
public byte p2;
|
||||
[FieldOffset(2)]
|
||||
public byte p3;
|
||||
[FieldOffset(3)]
|
||||
public byte p4;
|
||||
}
|
||||
}
|
||||
}
|
||||
public ControllerState FromNet(AxiReplay.ReplayStep step)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
var result = new ControllerState();
|
||||
temp.all = step.InPut;
|
||||
result.raw0 = temp.p1;
|
||||
result.raw1 = temp.p2;
|
||||
result.raw2 = temp.p3;
|
||||
result.raw3 = temp.p4;
|
||||
result.valid = true;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public uint ToNet(ControllerState state)
|
||||
{
|
||||
var temp = new ServerInputSnapShot();
|
||||
temp.p1 = (byte)state.raw0;
|
||||
temp.p2 = (byte)state.raw1;
|
||||
temp.p3 = (byte)state.raw2;
|
||||
temp.p4 = (byte)state.raw3;
|
||||
return (uint)temp.all;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Explicit, Size = 8)]
|
||||
struct ServerInputSnapShot
|
||||
{
|
||||
[FieldOffset(0)]
|
||||
public UInt64 all;
|
||||
[FieldOffset(0)]
|
||||
public byte p1;
|
||||
[FieldOffset(1)]
|
||||
public byte p2;
|
||||
[FieldOffset(2)]
|
||||
public byte p3;
|
||||
[FieldOffset(3)]
|
||||
public byte p4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,137 +1,137 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VirtualNes.Core;
|
||||
using VirtualNes.Core.Debug;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class NesEmulator : EmuCore<ControllerState>
|
||||
{
|
||||
public VideoProvider VideoProvider;
|
||||
public AudioProvider AudioProvider;
|
||||
|
||||
//模拟器核心实例化对象
|
||||
public NES NesCore { get; private set; }
|
||||
|
||||
/// <summary> 是否暂停 </summary>
|
||||
public bool IsPause { get; private set; }
|
||||
public NesControllerMapper ControllerMapper { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
ControllerMapper = new NesControllerMapper();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
App.tick.SetFrameRate(60);
|
||||
VideoProvider.NesEmu = this;
|
||||
AudioProvider.NesEmu = this;
|
||||
}
|
||||
|
||||
public override RomPlatformType Platform => RomPlatformType.Nes;
|
||||
private CoreSupporter m_coreSupporter;
|
||||
/// <summary>
|
||||
/// 指定ROM开始游戏
|
||||
/// </summary>
|
||||
public override MsgBool StartGame(RomFile rom)
|
||||
{
|
||||
StopGame();
|
||||
|
||||
m_coreSupporter = new CoreSupporter();
|
||||
Supporter.Setup(m_coreSupporter);
|
||||
Debuger.Setup(new CoreDebuger());
|
||||
|
||||
App.GetRomLib(RomPlatformType.Nes).AddRomFile(rom);
|
||||
|
||||
try
|
||||
{
|
||||
NesCore = new NES(rom.FileName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NesCore = null;
|
||||
App.log.Error(ex.ToString());
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Pause()
|
||||
{
|
||||
IsPause = true;
|
||||
}
|
||||
|
||||
public override void Resume()
|
||||
{
|
||||
IsPause = false;
|
||||
}
|
||||
|
||||
|
||||
public override void DoReset()
|
||||
{
|
||||
NesCore.Reset();
|
||||
}
|
||||
|
||||
public override void LoadState(object state)
|
||||
{
|
||||
NesCore.LoadState((State)state);
|
||||
}
|
||||
|
||||
public override object GetState()
|
||||
{
|
||||
return NesCore.GetState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取即时存档
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override byte[] GetStateBytes()
|
||||
{
|
||||
return NesCore.GetState().ToBytes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载即时存档
|
||||
/// </summary>
|
||||
/// <param
|
||||
/// name="data">
|
||||
/// </param>
|
||||
public override void LoadStateFromBytes(byte[] data)
|
||||
{
|
||||
var st = new State();
|
||||
st.FromByte(data);
|
||||
NesCore.LoadState(st);
|
||||
}
|
||||
|
||||
public override uint Frame => NesCore.FrameCount;
|
||||
|
||||
/// <summary>
|
||||
/// 停止游戏
|
||||
/// </summary>
|
||||
public void StopGame()
|
||||
{
|
||||
NesCore?.Dispose();
|
||||
NesCore = null;
|
||||
}
|
||||
|
||||
//推进帧
|
||||
protected override bool OnPushEmulatorFrame(ControllerState inputData)
|
||||
{
|
||||
if (NesCore == null || IsPause) return false;
|
||||
|
||||
NesCore.pad.Sync(inputData);
|
||||
NesCore.EmulateFrame(true);
|
||||
|
||||
return true;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using AxiReplay;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Xml.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using VirtualNes.Core;
|
||||
using VirtualNes.Core.Debug;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class NesEmulator : EmuCore<ControllerState>
|
||||
{
|
||||
public VideoProvider VideoProvider;
|
||||
public AudioProvider AudioProvider;
|
||||
|
||||
//模拟器核心实例化对象
|
||||
public NES NesCore { get; private set; }
|
||||
|
||||
/// <summary> 是否暂停 </summary>
|
||||
public bool IsPause { get; private set; }
|
||||
public NesControllerMapper ControllerMapper { get; private set; }
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
ControllerMapper = new NesControllerMapper();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
App.tick.SetFrameRate(60);
|
||||
VideoProvider.NesEmu = this;
|
||||
AudioProvider.NesEmu = this;
|
||||
}
|
||||
|
||||
public override RomPlatformType Platform => RomPlatformType.Nes;
|
||||
private CoreSupporter m_coreSupporter;
|
||||
/// <summary>
|
||||
/// 指定ROM开始游戏
|
||||
/// </summary>
|
||||
public override MsgBool StartGame(RomFile rom)
|
||||
{
|
||||
StopGame();
|
||||
|
||||
m_coreSupporter = new CoreSupporter();
|
||||
Supporter.Setup(m_coreSupporter);
|
||||
Debuger.Setup(new CoreDebuger());
|
||||
|
||||
App.GetRomLib(RomPlatformType.Nes).AddRomFile(rom);
|
||||
|
||||
try
|
||||
{
|
||||
NesCore = new NES(rom.FileName);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
NesCore = null;
|
||||
App.log.Error(ex.ToString());
|
||||
return ex.Message;
|
||||
}
|
||||
}
|
||||
|
||||
public override void Pause()
|
||||
{
|
||||
IsPause = true;
|
||||
}
|
||||
|
||||
public override void Resume()
|
||||
{
|
||||
IsPause = false;
|
||||
}
|
||||
|
||||
|
||||
public override void DoReset()
|
||||
{
|
||||
NesCore.Reset();
|
||||
}
|
||||
|
||||
public override void LoadState(object state)
|
||||
{
|
||||
NesCore.LoadState((State)state);
|
||||
}
|
||||
|
||||
public override object GetState()
|
||||
{
|
||||
return NesCore.GetState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取即时存档
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override byte[] GetStateBytes()
|
||||
{
|
||||
return NesCore.GetState().ToBytes();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载即时存档
|
||||
/// </summary>
|
||||
/// <param
|
||||
/// name="data">
|
||||
/// </param>
|
||||
public override void LoadStateFromBytes(byte[] data)
|
||||
{
|
||||
var st = new State();
|
||||
st.FromByte(data);
|
||||
NesCore.LoadState(st);
|
||||
}
|
||||
|
||||
public override uint Frame => NesCore.FrameCount;
|
||||
|
||||
/// <summary>
|
||||
/// 停止游戏
|
||||
/// </summary>
|
||||
public void StopGame()
|
||||
{
|
||||
NesCore?.Dispose();
|
||||
NesCore = null;
|
||||
}
|
||||
|
||||
//推进帧
|
||||
protected override bool OnPushEmulatorFrame(ControllerState inputData)
|
||||
{
|
||||
if (NesCore == null || IsPause) return false;
|
||||
|
||||
NesCore.pad.Sync(inputData);
|
||||
NesCore.EmulateFrame(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override ControllerState ConvertInputDataFromNet(ReplayStep step)
|
||||
@ -153,16 +153,16 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
var screenBuffer = NesCore.ppu.GetScreenPtr();
|
||||
VideoProvider.SetDrawData(screenBuffer);
|
||||
}
|
||||
|
||||
public override IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
|
||||
public override IControllerSetuper GetControllerSetuper()
|
||||
{
|
||||
return ControllerMapper;
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
StopGame();
|
||||
}
|
||||
|
||||
public override Texture OutputPixel => VideoProvider.OutputPixel;
|
||||
@ -170,37 +170,37 @@ namespace AxibugEmuOnline.Client
|
||||
public override void GetAudioParams(out int frequency, out int channels)
|
||||
{
|
||||
AudioProvider.GetAudioParams(out frequency, out channels);
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// 编辑器用
|
||||
/// </summary>
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[ContextMenu("ImportNesDB")]
|
||||
public void ImportNesDB()
|
||||
{
|
||||
var db = Resources.Load<RomDB>("NES/ROMDB");
|
||||
db.Clear();
|
||||
|
||||
var xmlStr = System.IO.File.ReadAllText("nes20db.xml");
|
||||
var xml = XDocument.Parse(xmlStr);
|
||||
var games = xml.Element("nes20db")?.Elements("game");
|
||||
System.Diagnostics.Debug.Assert(games != null, nameof(games) + " != null");
|
||||
foreach (var game in games)
|
||||
{
|
||||
var crcStr = game.Element("rom")?.Attribute("crc32")?.Value;
|
||||
var crc = uint.Parse($"{crcStr}", NumberStyles.HexNumber);
|
||||
|
||||
var mapper = int.Parse($"{game.Element("pcb")?.Attribute("mapper")?.Value}");
|
||||
|
||||
if (mapper > 255) continue;
|
||||
db.AddInfo(new RomDB.RomInfo { CRC = crc, Mapper = mapper });
|
||||
}
|
||||
|
||||
UnityEditor.EditorUtility.SetDirty(db);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
/// <summary>
|
||||
/// 编辑器用
|
||||
/// </summary>
|
||||
[Conditional("UNITY_EDITOR")]
|
||||
[ContextMenu("ImportNesDB")]
|
||||
public void ImportNesDB()
|
||||
{
|
||||
var db = Resources.Load<RomDB>("NES/ROMDB");
|
||||
db.Clear();
|
||||
|
||||
var xmlStr = System.IO.File.ReadAllText("nes20db.xml");
|
||||
var xml = XDocument.Parse(xmlStr);
|
||||
var games = xml.Element("nes20db")?.Elements("game");
|
||||
System.Diagnostics.Debug.Assert(games != null, nameof(games) + " != null");
|
||||
foreach (var game in games)
|
||||
{
|
||||
var crcStr = game.Element("rom")?.Attribute("crc32")?.Value;
|
||||
var crc = uint.Parse($"{crcStr}", NumberStyles.HexNumber);
|
||||
|
||||
var mapper = int.Parse($"{game.Element("pcb")?.Attribute("mapper")?.Value}");
|
||||
|
||||
if (mapper > 255) continue;
|
||||
db.AddInfo(new RomDB.RomInfo { CRC = crc, Mapper = mapper });
|
||||
}
|
||||
|
||||
UnityEditor.EditorUtility.SetDirty(db);
|
||||
UnityEditor.AssetDatabase.SaveAssets();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,73 +1,73 @@
|
||||
namespace AxibugEmuOnline.Client.Event
|
||||
{
|
||||
public enum EEvent
|
||||
{
|
||||
// 添加你自己需要的事件类型
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 登录成功
|
||||
/// </summary>
|
||||
OnLoginSucceed,
|
||||
namespace AxibugEmuOnline.Client.Event
|
||||
{
|
||||
public enum EEvent
|
||||
{
|
||||
// 添加你自己需要的事件类型
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 登录成功
|
||||
/// </summary>
|
||||
OnLoginSucceed,
|
||||
/// <summary>
|
||||
/// 当登录被置为false时
|
||||
/// </summary>
|
||||
OnLossLoginState,
|
||||
/// <summary>
|
||||
/// 登录失败
|
||||
/// </summary>
|
||||
OnLoginFailed,
|
||||
|
||||
OnChatMsg,
|
||||
|
||||
//自己的信息更新(比如改名更新)
|
||||
OnSelfInfoUpdate,
|
||||
//更新其他用户信息
|
||||
OnOtherUserInfoUpdate,
|
||||
|
||||
|
||||
//用户列表,登录和离开
|
||||
OnUserListAllUpdate,
|
||||
OnUserLogin,
|
||||
OnUserLoginOut,
|
||||
|
||||
OnRoomListAllUpdate,//房间列表全量刷新
|
||||
OnRoomListSingleAdd,//房间列表中新增房间
|
||||
OnRoomListSingleUpdate,//房间列表中单个更新
|
||||
OnRoomListSingleClose,//房间关闭
|
||||
OnRoomGetRoomScreen,//获取到房间数据
|
||||
|
||||
/// <summary>
|
||||
/// 我的房间创建成功
|
||||
/// </summary>
|
||||
OnMineRoomCreated,
|
||||
/// <summary>
|
||||
/// 我进入房间
|
||||
/// </summary>
|
||||
OnMineJoinRoom,
|
||||
/// <summary>
|
||||
/// 我离开房间
|
||||
/// </summary>
|
||||
OnMineLeavnRoom,
|
||||
|
||||
/// <summary>
|
||||
/// 其他人进入房间
|
||||
/// </summary>
|
||||
OnOtherPlayerJoinRoom,
|
||||
|
||||
/// <summary>
|
||||
/// 其他人离开房间
|
||||
/// </summary>
|
||||
OnOtherPlayerLeavnRoom,
|
||||
|
||||
/// <summary>
|
||||
/// 服务器等待Step更新
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
OnLossLoginState,
|
||||
/// <summary>
|
||||
/// 登录失败
|
||||
/// </summary>
|
||||
OnLoginFailed,
|
||||
|
||||
OnChatMsg,
|
||||
|
||||
//自己的信息更新(比如改名更新)
|
||||
OnSelfInfoUpdate,
|
||||
//更新其他用户信息
|
||||
OnOtherUserInfoUpdate,
|
||||
|
||||
|
||||
//用户列表,登录和离开
|
||||
OnUserListAllUpdate,
|
||||
OnUserLogin,
|
||||
OnUserLoginOut,
|
||||
|
||||
OnRoomListAllUpdate,//房间列表全量刷新
|
||||
OnRoomListSingleAdd,//房间列表中新增房间
|
||||
OnRoomListSingleUpdate,//房间列表中单个更新
|
||||
OnRoomListSingleClose,//房间关闭
|
||||
OnRoomGetRoomScreen,//获取到房间数据
|
||||
|
||||
/// <summary>
|
||||
/// 我的房间创建成功
|
||||
/// </summary>
|
||||
OnMineRoomCreated,
|
||||
/// <summary>
|
||||
/// 我进入房间
|
||||
/// </summary>
|
||||
OnMineJoinRoom,
|
||||
/// <summary>
|
||||
/// 我离开房间
|
||||
/// </summary>
|
||||
OnMineLeavnRoom,
|
||||
|
||||
/// <summary>
|
||||
/// 其他人进入房间
|
||||
/// </summary>
|
||||
OnOtherPlayerJoinRoom,
|
||||
|
||||
/// <summary>
|
||||
/// 其他人离开房间
|
||||
/// </summary>
|
||||
OnOtherPlayerLeavnRoom,
|
||||
|
||||
/// <summary>
|
||||
/// 服务器等待Step更新
|
||||
/// </summary>
|
||||
OnRoomWaitStepChange,
|
||||
|
||||
/// <summary>
|
||||
/// 当房间中手柄位信息发生任何变化时触发,进入房间后也应该触发
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 当房间中手柄位信息发生任何变化时触发,进入房间后也应该触发
|
||||
/// </summary>
|
||||
OnRoomSlotDataChanged,
|
||||
/// <summary>
|
||||
/// 当手柄连接设置发生变化时触发
|
||||
@ -92,5 +92,5 @@
|
||||
/// 网络即时存档删除
|
||||
/// </summary>
|
||||
OnNetGameSavDeleted,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,66 +1,66 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
public class AppEmu
|
||||
{
|
||||
/// <summary>
|
||||
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
|
||||
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
|
||||
/// </summary>
|
||||
private EmuCore m_emuCore;
|
||||
|
||||
private IControllerSetuper m_controllerSetuper;
|
||||
|
||||
/// <summary>
|
||||
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
|
||||
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
|
||||
/// </summary>
|
||||
public EmuCore Core => m_emuCore;
|
||||
|
||||
public AppEmu()
|
||||
{
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnMineJoinRoom, OnSelfJoinRoom);
|
||||
}
|
||||
|
||||
private void OnSelfJoinRoom()
|
||||
{
|
||||
//如果当前正在游戏中,就先结束游戏
|
||||
if (m_emuCore != null) StopGame();
|
||||
|
||||
var roomInfo = App.roomMgr.mineRoomMiniInfo;
|
||||
roomInfo.FetchRomFileInRoomInfo((_, romFile) =>
|
||||
{
|
||||
if (!romFile.RomReady) //这个rom并没有下载,所以取消进入房间
|
||||
{
|
||||
App.roomMgr.SendLeavnRoom();
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginGame(romFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void BeginGame(RomFile romFile)
|
||||
{
|
||||
if (m_emuCore != null) return;
|
||||
|
||||
switch (romFile.Platform)
|
||||
{
|
||||
case RomPlatformType.Nes:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("NES/NesEmulator")).GetComponent<EmuCore>();
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
public class AppEmu
|
||||
{
|
||||
/// <summary>
|
||||
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
|
||||
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
|
||||
/// </summary>
|
||||
private EmuCore m_emuCore;
|
||||
|
||||
private IControllerSetuper m_controllerSetuper;
|
||||
|
||||
/// <summary>
|
||||
/// unity的c#实现有bug,以接口类型保存的monobehaviour引用,!=和==运算符没有调用到monobehaviour重写过的运算符
|
||||
/// 但是Equals方法可以,所以,这个接口判断为空请使用Equals
|
||||
/// </summary>
|
||||
public EmuCore Core => m_emuCore;
|
||||
|
||||
public AppEmu()
|
||||
{
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnMineJoinRoom, OnSelfJoinRoom);
|
||||
}
|
||||
|
||||
private void OnSelfJoinRoom()
|
||||
{
|
||||
//如果当前正在游戏中,就先结束游戏
|
||||
if (m_emuCore != null) StopGame();
|
||||
|
||||
var roomInfo = App.roomMgr.mineRoomMiniInfo;
|
||||
roomInfo.FetchRomFileInRoomInfo((_, romFile) =>
|
||||
{
|
||||
if (!romFile.RomReady) //这个rom并没有下载,所以取消进入房间
|
||||
{
|
||||
App.roomMgr.SendLeavnRoom();
|
||||
}
|
||||
else
|
||||
{
|
||||
BeginGame(romFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void BeginGame(RomFile romFile)
|
||||
{
|
||||
if (m_emuCore != null) return;
|
||||
|
||||
switch (romFile.Platform)
|
||||
{
|
||||
case RomPlatformType.Nes:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("NES/NesEmulator")).GetComponent<EmuCore>();
|
||||
break;
|
||||
case RomPlatformType.Cps1:
|
||||
case RomPlatformType.Cps2:
|
||||
case RomPlatformType.Igs:
|
||||
case RomPlatformType.Neogeo:
|
||||
case RomPlatformType.ArcadeOld:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("MAME/UMAME")).GetComponent<EmuCore>();
|
||||
case RomPlatformType.ArcadeOld:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("MAME/UMAME")).GetComponent<EmuCore>();
|
||||
break;
|
||||
case RomPlatformType.MasterSystem:
|
||||
case RomPlatformType.GameGear:
|
||||
@ -68,22 +68,22 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
case RomPlatformType.GameBoyColor:
|
||||
case RomPlatformType.ColecoVision:
|
||||
case RomPlatformType.Sc3000:
|
||||
case RomPlatformType.Sg1000:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("EssgeeUnity/EssgeeUnity")).GetComponent<EmuCore>();
|
||||
case RomPlatformType.Sg1000:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("EssgeeUnity/EssgeeUnity")).GetComponent<EmuCore>();
|
||||
break;
|
||||
case RomPlatformType.WonderSwan:
|
||||
case RomPlatformType.WonderSwan:
|
||||
case RomPlatformType.WonderSwanColor:
|
||||
m_emuCore = GameObject.Instantiate(Resources.Load<GameObject>("StoicGooseUnity/StoicGooseUnity")).GetComponent<EmuCore>();
|
||||
break;
|
||||
}
|
||||
|
||||
var result = m_emuCore.StartGame(romFile);
|
||||
}
|
||||
|
||||
var result = m_emuCore.StartGame(romFile);
|
||||
if (result)
|
||||
{
|
||||
LaunchUI.Instance.HideMainMenu();
|
||||
InGameUI.Instance.Show(romFile, m_emuCore);
|
||||
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Gaming;
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Gaming;
|
||||
|
||||
m_controllerSetuper = m_emuCore.GetControllerSetuper();
|
||||
|
||||
@ -91,17 +91,17 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
m_controllerSetuper.SetConnect(con0ToSlot: 0);
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnRoomSlotDataChanged, OnSlotDataChanged);
|
||||
}
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnRoomSlotDataChanged, OnSlotDataChanged);
|
||||
}
|
||||
else
|
||||
{
|
||||
StopGame();
|
||||
OverlayManager.PopTip(result);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSlotDataChanged()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSlotDataChanged()
|
||||
{
|
||||
long selfUID = App.user.userdata.UID;
|
||||
uint? con0Slot;
|
||||
uint? con1Slot;
|
||||
@ -113,29 +113,29 @@ namespace AxibugEmuOnline.Client.Manager
|
||||
App.roomMgr.mineRoomMiniInfo.GetPlayerSlotIdxByUid(selfUID, 2, out con2Slot);
|
||||
App.roomMgr.mineRoomMiniInfo.GetPlayerSlotIdxByUid(selfUID, 3, out con3Slot);
|
||||
|
||||
m_controllerSetuper.SetConnect(con0Slot, con1Slot, con2Slot, con3Slot);
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
}
|
||||
|
||||
public void StopGame()
|
||||
{
|
||||
if (m_emuCore == null) return;
|
||||
m_emuCore.Dispose();
|
||||
GameObject.Destroy(m_emuCore.gameObject);
|
||||
m_emuCore = null;
|
||||
|
||||
InGameUI.Instance.Hide();
|
||||
LaunchUI.Instance.ShowMainMenu();
|
||||
m_controllerSetuper = null;
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnRoomSlotDataChanged, OnSlotDataChanged);
|
||||
}
|
||||
|
||||
public void ResetGame()
|
||||
{
|
||||
if (m_emuCore == null) return;
|
||||
|
||||
m_emuCore.DoReset();
|
||||
}
|
||||
}
|
||||
m_controllerSetuper.SetConnect(con0Slot, con1Slot, con2Slot, con3Slot);
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnControllerConnectChanged);
|
||||
}
|
||||
|
||||
public void StopGame()
|
||||
{
|
||||
if (m_emuCore == null) return;
|
||||
m_emuCore.Dispose();
|
||||
GameObject.Destroy(m_emuCore.gameObject);
|
||||
m_emuCore = null;
|
||||
|
||||
InGameUI.Instance.Hide();
|
||||
LaunchUI.Instance.ShowMainMenu();
|
||||
m_controllerSetuper = null;
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnRoomSlotDataChanged, OnSlotDataChanged);
|
||||
}
|
||||
|
||||
public void ResetGame()
|
||||
{
|
||||
if (m_emuCore == null) return;
|
||||
|
||||
m_emuCore.DoReset();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,24 +1,24 @@
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class AppSettings
|
||||
{
|
||||
/// <summary> 背景颜色设定 </summary>
|
||||
public BgColorSettings BgColor { get; private set; }
|
||||
/// <summary> 滤镜设置 </summary>
|
||||
public FilterManager Filter { get; private set; }
|
||||
/// <summary> 画面比例设置 </summary>
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class AppSettings
|
||||
{
|
||||
/// <summary> 背景颜色设定 </summary>
|
||||
public BgColorSettings BgColor { get; private set; }
|
||||
/// <summary> 滤镜设置 </summary>
|
||||
public FilterManager Filter { get; private set; }
|
||||
/// <summary> 画面比例设置 </summary>
|
||||
public ScreenScaler ScreenScaler { get; private set; }
|
||||
/// <summary> 键位设置 </summary>
|
||||
/// <summary> 键位设置 </summary>
|
||||
public KeyMapperSetting KeyMapper { get; private set; }
|
||||
|
||||
public AppSettings()
|
||||
{
|
||||
BgColor = new BgColorSettings();
|
||||
Filter = new FilterManager();
|
||||
ScreenScaler = new ScreenScaler();
|
||||
KeyMapper = new KeyMapperSetting();
|
||||
}
|
||||
}
|
||||
}
|
||||
Filter = new FilterManager();
|
||||
ScreenScaler = new ScreenScaler();
|
||||
KeyMapper = new KeyMapperSetting();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Filters
|
||||
{
|
||||
public class Filter1990_esque : FilterEffect
|
||||
{
|
||||
public override string Name => "1990-esque";
|
||||
|
||||
protected override string ShaderName => "Filter/1990-esque";
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
Graphics.Blit(src, result, renderMat, 1);
|
||||
}
|
||||
}
|
||||
{
|
||||
public class Filter1990_esque : FilterEffect
|
||||
{
|
||||
public override string Name => "1990-esque";
|
||||
|
||||
protected override string ShaderName => "Filter/1990-esque";
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
Graphics.Blit(src, result, renderMat, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,139 +1,139 @@
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public abstract class FilterEffect
|
||||
{
|
||||
public bool Enable { get; set; }
|
||||
|
||||
[Range(0.1f, 4f)]
|
||||
public FloatParameter RenderScale;
|
||||
|
||||
public abstract string Name { get; }
|
||||
public IReadOnlyCollection<EditableParamerter> EditableParam => m_editableParamList.AsReadOnly();
|
||||
|
||||
List<EditableParamerter> m_editableParamList;
|
||||
Material m_material;
|
||||
protected virtual float m_defaultRenderScale { get => 1f; }
|
||||
protected abstract string ShaderName { get; }
|
||||
private static int m_iResolutionID = Shader.PropertyToID("_iResolution");
|
||||
|
||||
public FilterEffect()
|
||||
{
|
||||
RenderScale = new FloatParameter(m_defaultRenderScale);
|
||||
GetEditableFilterParamters();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public abstract class FilterEffect
|
||||
{
|
||||
public bool Enable { get; set; }
|
||||
|
||||
[Range(0.1f, 4f)]
|
||||
public FloatParameter RenderScale;
|
||||
|
||||
public abstract string Name { get; }
|
||||
public IReadOnlyCollection<EditableParamerter> EditableParam => m_editableParamList.AsReadOnly();
|
||||
|
||||
List<EditableParamerter> m_editableParamList;
|
||||
Material m_material;
|
||||
protected virtual float m_defaultRenderScale { get => 1f; }
|
||||
protected abstract string ShaderName { get; }
|
||||
private static int m_iResolutionID = Shader.PropertyToID("_iResolution");
|
||||
|
||||
public FilterEffect()
|
||||
{
|
||||
RenderScale = new FloatParameter(m_defaultRenderScale);
|
||||
GetEditableFilterParamters();
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
protected virtual void Init()
|
||||
{
|
||||
if (ShaderName != null)
|
||||
{
|
||||
var shader = Shader.Find(ShaderName);
|
||||
if (shader != null) m_material = new Material(Shader.Find(ShaderName));
|
||||
if (shader != null) m_material = new Material(Shader.Find(ShaderName));
|
||||
}
|
||||
|
||||
|
||||
OnInit(m_material);
|
||||
}
|
||||
|
||||
protected virtual void OnInit(Material renderMat) { }
|
||||
|
||||
void GetEditableFilterParamters()
|
||||
{
|
||||
var parameters = (from t in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
where t.FieldType.IsSubclassOf(typeof(FilterParameter))
|
||||
orderby t.MetadataToken
|
||||
select t);
|
||||
|
||||
m_editableParamList = new List<EditableParamerter>();
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
var paramObj = (FilterParameter)param.GetValue(this);
|
||||
var rangeAtt = param.GetCustomAttribute<RangeAttribute>();
|
||||
float min = 0;
|
||||
float max = 10;
|
||||
}
|
||||
|
||||
protected virtual void OnInit(Material renderMat) { }
|
||||
|
||||
void GetEditableFilterParamters()
|
||||
{
|
||||
var parameters = (from t in GetType().GetFields(BindingFlags.Instance | BindingFlags.Public)
|
||||
where t.FieldType.IsSubclassOf(typeof(FilterParameter))
|
||||
orderby t.MetadataToken
|
||||
select t);
|
||||
|
||||
m_editableParamList = new List<EditableParamerter>();
|
||||
foreach (var param in parameters)
|
||||
{
|
||||
var paramObj = (FilterParameter)param.GetValue(this);
|
||||
var rangeAtt = param.GetCustomAttribute<RangeAttribute>();
|
||||
float min = 0;
|
||||
float max = 10;
|
||||
if (rangeAtt != null) { min = rangeAtt.min; max = rangeAtt.max; }
|
||||
|
||||
var descrip = param.GetCustomAttribute<DescriptionAttribute>();
|
||||
string name = descrip != null ? descrip.Description : param.Name;
|
||||
|
||||
var editableParam = new EditableParamerter(name, paramObj, min, max);
|
||||
m_editableParamList.Add(editableParam);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Render(Texture src, RenderTexture result)
|
||||
{
|
||||
if (m_material != null) m_material.SetVector(m_iResolutionID, new Vector4(result.width, result.height));
|
||||
OnRenderer(m_material, src, result);
|
||||
}
|
||||
|
||||
protected abstract void OnRenderer(Material renderMat, Texture src, RenderTexture result);
|
||||
|
||||
public class EditableParamerter
|
||||
{
|
||||
private FilterParameter m_paramObject;
|
||||
|
||||
public Type ValueType => m_paramObject.ValueType;
|
||||
public string Name { get; private set; }
|
||||
public object Value
|
||||
{
|
||||
get => m_paramObject.Value;
|
||||
set => m_paramObject.Value = value;
|
||||
}
|
||||
|
||||
public object MinValue { get; private set; }
|
||||
public object MaxValue { get; private set; }
|
||||
|
||||
public EditableParamerter(string name, FilterParameter paramObject, float minValue, float maxValue)
|
||||
{
|
||||
m_paramObject = paramObject;
|
||||
Name = name;
|
||||
|
||||
var paramType = paramObject.GetType();
|
||||
|
||||
var descrip = param.GetCustomAttribute<DescriptionAttribute>();
|
||||
string name = descrip != null ? descrip.Description : param.Name;
|
||||
|
||||
var editableParam = new EditableParamerter(name, paramObj, min, max);
|
||||
m_editableParamList.Add(editableParam);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Render(Texture src, RenderTexture result)
|
||||
{
|
||||
if (m_material != null) m_material.SetVector(m_iResolutionID, new Vector4(result.width, result.height));
|
||||
OnRenderer(m_material, src, result);
|
||||
}
|
||||
|
||||
protected abstract void OnRenderer(Material renderMat, Texture src, RenderTexture result);
|
||||
|
||||
public class EditableParamerter
|
||||
{
|
||||
private FilterParameter m_paramObject;
|
||||
|
||||
public Type ValueType => m_paramObject.ValueType;
|
||||
public string Name { get; private set; }
|
||||
public object Value
|
||||
{
|
||||
get => m_paramObject.Value;
|
||||
set => m_paramObject.Value = value;
|
||||
}
|
||||
|
||||
public object MinValue { get; private set; }
|
||||
public object MaxValue { get; private set; }
|
||||
|
||||
public EditableParamerter(string name, FilterParameter paramObject, float minValue, float maxValue)
|
||||
{
|
||||
m_paramObject = paramObject;
|
||||
Name = name;
|
||||
|
||||
var paramType = paramObject.GetType();
|
||||
|
||||
if (paramObject.ValueType == typeof(int))
|
||||
{
|
||||
MinValue = (int)minValue;
|
||||
MaxValue = (int)maxValue;
|
||||
}
|
||||
MaxValue = (int)maxValue;
|
||||
}
|
||||
else if (paramObject.ValueType == typeof(float))
|
||||
{
|
||||
MinValue = minValue;
|
||||
MaxValue = maxValue;
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetToDefault() => m_paramObject.Value = null;
|
||||
|
||||
|
||||
public void Apply(object overrideValue)
|
||||
{
|
||||
Value = overrideValue;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
internal class StripAttribute : Attribute
|
||||
{
|
||||
HashSet<RuntimePlatform> m_stripPlats;
|
||||
/// <summary>
|
||||
/// 指示一个滤镜是否会在指定的平台被剔除
|
||||
/// </summary>
|
||||
/// <param name="strip">会被剔除的平台</param>
|
||||
public StripAttribute(params RuntimePlatform[] stripPlatform)
|
||||
{
|
||||
m_stripPlats = new HashSet<RuntimePlatform>(stripPlatform);
|
||||
}
|
||||
|
||||
public bool NeedStrip => m_stripPlats.Contains(Application.platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ResetToDefault() => m_paramObject.Value = null;
|
||||
|
||||
|
||||
public void Apply(object overrideValue)
|
||||
{
|
||||
Value = overrideValue;
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
internal class StripAttribute : Attribute
|
||||
{
|
||||
HashSet<RuntimePlatform> m_stripPlats;
|
||||
/// <summary>
|
||||
/// 指示一个滤镜是否会在指定的平台被剔除
|
||||
/// </summary>
|
||||
/// <param name="strip">会被剔除的平台</param>
|
||||
public StripAttribute(params RuntimePlatform[] stripPlatform)
|
||||
{
|
||||
m_stripPlats = new HashSet<RuntimePlatform>(stripPlatform);
|
||||
}
|
||||
|
||||
public bool NeedStrip => m_stripPlats.Contains(Application.platform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static AxibugEmuOnline.Client.FilterEffect;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Settings
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static AxibugEmuOnline.Client.FilterEffect;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Settings
|
||||
{
|
||||
public class FilterManager
|
||||
{
|
||||
@ -17,9 +17,9 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
|
||||
private AlphaWraper m_previewFilterWraper;
|
||||
FilterRomSetting m_filterRomSetting;
|
||||
/// <summary>
|
||||
/// 滤镜列表
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 滤镜列表
|
||||
/// </summary>
|
||||
public IReadOnlyList<Filter> Filters => m_filters;
|
||||
|
||||
public FilterManager()
|
||||
@ -104,24 +104,24 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
}
|
||||
|
||||
|
||||
/// <summary> 关闭滤镜预览 </summary>
|
||||
/// <summary> 关闭滤镜预览 </summary>
|
||||
public void ShutDownFilterPreview()
|
||||
{
|
||||
if (m_previewFilterWraper == null) m_previewFilterWraper = new AlphaWraper(Initer.XMBBg, Initer.FilterPreview, false);
|
||||
m_previewFilterWraper.On = false;
|
||||
}
|
||||
|
||||
/// <summary> 开启滤镜预览 </summary>
|
||||
/// <summary> 开启滤镜预览 </summary>
|
||||
public void EnableFilterPreview()
|
||||
{
|
||||
if (m_previewFilterWraper == null) m_previewFilterWraper = new AlphaWraper(Initer.XMBBg, Initer.FilterPreview, false);
|
||||
m_previewFilterWraper.On = true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 打开滤镜
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
/// <summary>
|
||||
/// 打开滤镜
|
||||
/// </summary>
|
||||
/// <param name="filter"></param>
|
||||
public void EnableFilter(Filter filter)
|
||||
{
|
||||
foreach (var selfFiler in Filters)
|
||||
@ -131,9 +131,9 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭滤镜效果
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 关闭滤镜效果
|
||||
/// </summary>
|
||||
public void ShutDownFilter()
|
||||
{
|
||||
//关闭所有后处理效果
|
||||
@ -141,12 +141,12 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
filter.m_setting.Enable = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 为指定rom设置滤镜以及滤镜的预设
|
||||
/// </summary>
|
||||
/// <param name="rom">rom对象</param>
|
||||
/// <param name="filter">滤镜</param>
|
||||
/// <param name="preset">滤镜预设</param>
|
||||
/// <summary>
|
||||
/// 为指定rom设置滤镜以及滤镜的预设
|
||||
/// </summary>
|
||||
/// <param name="rom">rom对象</param>
|
||||
/// <param name="filter">滤镜</param>
|
||||
/// <param name="preset">滤镜预设</param>
|
||||
public void SetupFilter(RomFile rom, Filter filter, FilterPreset preset)
|
||||
{
|
||||
m_filterRomSetting.Setup(rom, filter, preset);
|
||||
@ -155,11 +155,11 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
AxiPlayerPrefs.SetString(nameof(FilterRomSetting), json);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定rom配置的滤镜设置
|
||||
/// </summary>
|
||||
/// <param name="rom">rom对象</param>
|
||||
/// <returns>此元组任意内任意成员都有可能为空</returns>
|
||||
/// <summary>
|
||||
/// 获得指定rom配置的滤镜设置
|
||||
/// </summary>
|
||||
/// <param name="rom">rom对象</param>
|
||||
/// <returns>此元组任意内任意成员都有可能为空</returns>
|
||||
public GetFilterSetting_result GetFilterSetting(RomFile rom)
|
||||
{
|
||||
var value = m_filterRomSetting.Get(rom);
|
||||
@ -198,9 +198,9 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
{
|
||||
public string Name => m_setting.Name;
|
||||
public IReadOnlyCollection<EditableParamerter> Paramerters => m_setting.EditableParam;
|
||||
/// <summary> 滤镜预设 </summary>
|
||||
/// <summary> 滤镜预设 </summary>
|
||||
public List<FilterPreset> Presets = new List<FilterPreset>();
|
||||
/// <summary> 滤镜默认预设 </summary>
|
||||
/// <summary> 滤镜默认预设 </summary>
|
||||
public FilterPreset DefaultPreset = new FilterPreset("DEFAULT");
|
||||
|
||||
internal FilterEffect m_setting;
|
||||
@ -445,5 +445,5 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
public string PresetName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,33 +1,33 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Script.AppMain.Filter
|
||||
{
|
||||
public abstract class FilterParameter
|
||||
{
|
||||
public abstract Type ValueType { get; }
|
||||
|
||||
object m_overrideValue;
|
||||
protected object m_defaultValue;
|
||||
public object Value
|
||||
{
|
||||
get => m_overrideValue ?? m_defaultValue;
|
||||
set => m_overrideValue = value;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Assets.Script.AppMain.Filter
|
||||
{
|
||||
public abstract class FilterParameter
|
||||
{
|
||||
public abstract Type ValueType { get; }
|
||||
|
||||
object m_overrideValue;
|
||||
protected object m_defaultValue;
|
||||
public object Value
|
||||
{
|
||||
get => m_overrideValue ?? m_defaultValue;
|
||||
set => m_overrideValue = value;
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterParameter<T> : FilterParameter
|
||||
{
|
||||
public override Type ValueType => typeof(T);
|
||||
public void Override(T value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
public T GetValue() => (T)Value;
|
||||
|
||||
public FilterParameter(T defaultValue)
|
||||
{
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public class FilterParameter<T> : FilterParameter
|
||||
{
|
||||
public override Type ValueType => typeof(T);
|
||||
public void Override(T value)
|
||||
{
|
||||
Value = value;
|
||||
}
|
||||
public T GetValue() => (T)Value;
|
||||
|
||||
public FilterParameter(T defaultValue)
|
||||
{
|
||||
m_defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public static implicit operator T(FilterParameter<T> value)
|
||||
@ -38,26 +38,26 @@ namespace Assets.Script.AppMain.Filter
|
||||
public static implicit operator FilterParameter<T>(T value)
|
||||
{
|
||||
return new FilterParameter<T>(value);
|
||||
}
|
||||
}
|
||||
|
||||
public class BoolParameter : FilterParameter<bool>
|
||||
{
|
||||
public BoolParameter(bool defaultValue) : base(defaultValue) { }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class BoolParameter : FilterParameter<bool>
|
||||
{
|
||||
public BoolParameter(bool defaultValue) : base(defaultValue) { }
|
||||
|
||||
public static implicit operator bool(BoolParameter value)
|
||||
{
|
||||
return value.GetValue();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static implicit operator BoolParameter(bool value)
|
||||
{
|
||||
return new BoolParameter(value);
|
||||
}
|
||||
}
|
||||
|
||||
public class Vector2Parameter : FilterParameter<Vector2>
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class Vector2Parameter : FilterParameter<Vector2>
|
||||
{
|
||||
public Vector2Parameter(Vector2 defaultValue) : base(defaultValue) { }
|
||||
|
||||
public static implicit operator Vector2(Vector2Parameter value)
|
||||
@ -68,13 +68,13 @@ namespace Assets.Script.AppMain.Filter
|
||||
public static implicit operator Vector2Parameter(Vector2 value)
|
||||
{
|
||||
return new Vector2Parameter(value);
|
||||
}
|
||||
}
|
||||
|
||||
public class FloatParameter : FilterParameter<float>
|
||||
{
|
||||
public FloatParameter(float defaultValue) : base(defaultValue) { }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class FloatParameter : FilterParameter<float>
|
||||
{
|
||||
public FloatParameter(float defaultValue) : base(defaultValue) { }
|
||||
|
||||
public static implicit operator float(FloatParameter value)
|
||||
{
|
||||
return value.GetValue();
|
||||
@ -83,9 +83,9 @@ namespace Assets.Script.AppMain.Filter
|
||||
public static implicit operator FloatParameter(float value)
|
||||
{
|
||||
return new FloatParameter(value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class IntParameter : FilterParameter<int>
|
||||
{
|
||||
public IntParameter(int defaultValue) : base(defaultValue) { }
|
||||
@ -99,5 +99,5 @@ namespace Assets.Script.AppMain.Filter
|
||||
{
|
||||
return new IntParameter(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,16 +1,16 @@
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Filters
|
||||
{
|
||||
public sealed class LCDPostEffect : FilterEffect
|
||||
{
|
||||
public override string Name => nameof(LCDPostEffect);
|
||||
|
||||
protected override string ShaderName => "Filter/LCDPostEffect";
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
Graphics.Blit(src, result, renderMat);
|
||||
}
|
||||
}
|
||||
{
|
||||
public sealed class LCDPostEffect : FilterEffect
|
||||
{
|
||||
public override string Name => nameof(LCDPostEffect);
|
||||
|
||||
protected override string ShaderName => "Filter/LCDPostEffect";
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
Graphics.Blit(src, result, renderMat);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using AxibugEmuOnline.Client;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using AxibugEmuOnline.Client;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Filters
|
||||
{
|
||||
public sealed class MattiasCRT : FilterEffect
|
||||
{
|
||||
public override string Name => nameof(MattiasCRT);
|
||||
|
||||
protected override string ShaderName => "Filter/MattiasCRT";
|
||||
|
||||
public sealed class MattiasCRT : FilterEffect
|
||||
{
|
||||
public override string Name => nameof(MattiasCRT);
|
||||
|
||||
protected override string ShaderName => "Filter/MattiasCRT";
|
||||
|
||||
public FilterParameter<EnumQuality> Quality = new FilterParameter<EnumQuality>(EnumQuality.High);
|
||||
private LocalKeyword _kw_qualityLow;
|
||||
private LocalKeyword _kw_qualityMid;
|
||||
@ -18,31 +18,31 @@ namespace AxibugEmuOnline.Client.Filters
|
||||
|
||||
protected override void OnInit(Material renderMat)
|
||||
{
|
||||
_kw_qualityLow = new LocalKeyword(renderMat.shader, "_QUALITY_LOW");
|
||||
_kw_qualityLow = new LocalKeyword(renderMat.shader, "_QUALITY_LOW");
|
||||
_kw_qualityMid = new LocalKeyword(renderMat.shader, "_QUALITY_MID");
|
||||
_kw_qualityHigh = new LocalKeyword(renderMat.shader, "_QUALITY_HIGH");
|
||||
}
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
renderMat.DisableKeyword(_kw_qualityLow);
|
||||
renderMat.DisableKeyword(_kw_qualityMid);
|
||||
renderMat.DisableKeyword(_kw_qualityHigh);
|
||||
}
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
renderMat.DisableKeyword(_kw_qualityLow);
|
||||
renderMat.DisableKeyword(_kw_qualityMid);
|
||||
renderMat.DisableKeyword(_kw_qualityHigh);
|
||||
switch (Quality.GetValue())
|
||||
{
|
||||
case EnumQuality.Low: renderMat.EnableKeyword(_kw_qualityLow); break;
|
||||
case EnumQuality.Mid: renderMat.EnableKeyword(_kw_qualityMid); break;
|
||||
case EnumQuality.High: renderMat.EnableKeyword(_kw_qualityHigh); break;
|
||||
}
|
||||
|
||||
Graphics.Blit(src, result, renderMat);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Graphics.Blit(src, result, renderMat);
|
||||
}
|
||||
|
||||
public enum EnumQuality
|
||||
{
|
||||
Low,
|
||||
Mid,
|
||||
High
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,71 +1,71 @@
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
using Assets.Script.AppMain.Filter;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Filters
|
||||
{
|
||||
[Strip(RuntimePlatform.PSP2)]
|
||||
public class RetroArchMattiasCRTGlow : FilterEffect
|
||||
{
|
||||
public override string Name => nameof(RetroArchMattiasCRTGlow);
|
||||
protected override string ShaderName => "Filter/RetroArch/MattiasCRTWithGlow";
|
||||
|
||||
[Range(0.02f, 20f)]
|
||||
public FloatParameter InputGamma = new FloatParameter(11);
|
||||
[Range(0.02f, 1f)]
|
||||
public FloatParameter GaussianWidth = new FloatParameter(0.4f);
|
||||
[Range(0.02f, 1f)]
|
||||
public FloatParameter ColorBoost = new FloatParameter(0.4f);
|
||||
[Range(0.02f, 1f)]
|
||||
public FloatParameter GlowWhitePoint = new FloatParameter(0.4f);
|
||||
[Range(0.1f, 6f)]
|
||||
public FloatParameter GlowRolloff = new FloatParameter(2.2f);
|
||||
[Range(0.05f, 0.8f)]
|
||||
public FloatParameter GlowStrength = new FloatParameter(0.45f);
|
||||
[Range(0.02f, 2.6f)]
|
||||
public FloatParameter MonitorGamma = new FloatParameter(2.2f);
|
||||
|
||||
int m_gamma_ID = Shader.PropertyToID("_gamma");
|
||||
int m_horiz_gauss_width_ID = Shader.PropertyToID("_horiz_gauss_width");
|
||||
int m_BOOST_ID = Shader.PropertyToID("_BOOST");
|
||||
int m_GLOW_WHITEPOINT_ID = Shader.PropertyToID("_GLOW_WHITEPOINT");
|
||||
int m_GLOW_ROLLOFF_ID = Shader.PropertyToID("_GLOW_ROLLOFF");
|
||||
int m_BLOOM_STRENGTH_ID = Shader.PropertyToID("_BLOOM_STRENGTH");
|
||||
int m_OUTPUT_GAMMA_ID = Shader.PropertyToID("_OUTPUT_GAMMA");
|
||||
|
||||
|
||||
CommandBuffer m_multipPassCmd;
|
||||
int m_wrapRT;
|
||||
|
||||
protected override void OnInit(Material renderMat)
|
||||
{
|
||||
m_multipPassCmd = new CommandBuffer();
|
||||
m_wrapRT = Shader.PropertyToID($"{Name}.WrapRT");
|
||||
}
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
m_multipPassCmd.Clear();
|
||||
|
||||
m_multipPassCmd.GetTemporaryRT(m_wrapRT, result.width, result.height);
|
||||
|
||||
renderMat.SetFloat(m_gamma_ID, InputGamma.GetValue());
|
||||
renderMat.SetFloat(m_horiz_gauss_width_ID, GaussianWidth.GetValue());
|
||||
renderMat.SetFloat(m_BOOST_ID, ColorBoost.GetValue());
|
||||
renderMat.SetFloat(m_GLOW_WHITEPOINT_ID, GlowWhitePoint.GetValue());
|
||||
renderMat.SetFloat(m_GLOW_ROLLOFF_ID, GlowRolloff.GetValue());
|
||||
renderMat.SetFloat(m_BLOOM_STRENGTH_ID, GlowStrength.GetValue());
|
||||
renderMat.SetFloat(m_OUTPUT_GAMMA_ID, MonitorGamma.GetValue());
|
||||
|
||||
m_multipPassCmd.Blit(src, result);
|
||||
for (int i = 0; i < renderMat.shader.passCount; i++)
|
||||
{
|
||||
m_multipPassCmd.Blit(result, m_wrapRT, renderMat, i);
|
||||
m_multipPassCmd.Blit(m_wrapRT, result);
|
||||
}
|
||||
|
||||
m_multipPassCmd.ReleaseTemporaryRT(m_wrapRT);
|
||||
Graphics.ExecuteCommandBuffer(m_multipPassCmd);
|
||||
}
|
||||
}
|
||||
{
|
||||
[Strip(RuntimePlatform.PSP2)]
|
||||
public class RetroArchMattiasCRTGlow : FilterEffect
|
||||
{
|
||||
public override string Name => nameof(RetroArchMattiasCRTGlow);
|
||||
protected override string ShaderName => "Filter/RetroArch/MattiasCRTWithGlow";
|
||||
|
||||
[Range(0.02f, 20f)]
|
||||
public FloatParameter InputGamma = new FloatParameter(11);
|
||||
[Range(0.02f, 1f)]
|
||||
public FloatParameter GaussianWidth = new FloatParameter(0.4f);
|
||||
[Range(0.02f, 1f)]
|
||||
public FloatParameter ColorBoost = new FloatParameter(0.4f);
|
||||
[Range(0.02f, 1f)]
|
||||
public FloatParameter GlowWhitePoint = new FloatParameter(0.4f);
|
||||
[Range(0.1f, 6f)]
|
||||
public FloatParameter GlowRolloff = new FloatParameter(2.2f);
|
||||
[Range(0.05f, 0.8f)]
|
||||
public FloatParameter GlowStrength = new FloatParameter(0.45f);
|
||||
[Range(0.02f, 2.6f)]
|
||||
public FloatParameter MonitorGamma = new FloatParameter(2.2f);
|
||||
|
||||
int m_gamma_ID = Shader.PropertyToID("_gamma");
|
||||
int m_horiz_gauss_width_ID = Shader.PropertyToID("_horiz_gauss_width");
|
||||
int m_BOOST_ID = Shader.PropertyToID("_BOOST");
|
||||
int m_GLOW_WHITEPOINT_ID = Shader.PropertyToID("_GLOW_WHITEPOINT");
|
||||
int m_GLOW_ROLLOFF_ID = Shader.PropertyToID("_GLOW_ROLLOFF");
|
||||
int m_BLOOM_STRENGTH_ID = Shader.PropertyToID("_BLOOM_STRENGTH");
|
||||
int m_OUTPUT_GAMMA_ID = Shader.PropertyToID("_OUTPUT_GAMMA");
|
||||
|
||||
|
||||
CommandBuffer m_multipPassCmd;
|
||||
int m_wrapRT;
|
||||
|
||||
protected override void OnInit(Material renderMat)
|
||||
{
|
||||
m_multipPassCmd = new CommandBuffer();
|
||||
m_wrapRT = Shader.PropertyToID($"{Name}.WrapRT");
|
||||
}
|
||||
|
||||
protected override void OnRenderer(Material renderMat, Texture src, RenderTexture result)
|
||||
{
|
||||
m_multipPassCmd.Clear();
|
||||
|
||||
m_multipPassCmd.GetTemporaryRT(m_wrapRT, result.width, result.height);
|
||||
|
||||
renderMat.SetFloat(m_gamma_ID, InputGamma.GetValue());
|
||||
renderMat.SetFloat(m_horiz_gauss_width_ID, GaussianWidth.GetValue());
|
||||
renderMat.SetFloat(m_BOOST_ID, ColorBoost.GetValue());
|
||||
renderMat.SetFloat(m_GLOW_WHITEPOINT_ID, GlowWhitePoint.GetValue());
|
||||
renderMat.SetFloat(m_GLOW_ROLLOFF_ID, GlowRolloff.GetValue());
|
||||
renderMat.SetFloat(m_BLOOM_STRENGTH_ID, GlowStrength.GetValue());
|
||||
renderMat.SetFloat(m_OUTPUT_GAMMA_ID, MonitorGamma.GetValue());
|
||||
|
||||
m_multipPassCmd.Blit(src, result);
|
||||
for (int i = 0; i < renderMat.shader.passCount; i++)
|
||||
{
|
||||
m_multipPassCmd.Blit(result, m_wrapRT, renderMat, i);
|
||||
m_multipPassCmd.Blit(m_wrapRT, result);
|
||||
}
|
||||
|
||||
m_multipPassCmd.ReleaseTemporaryRT(m_wrapRT);
|
||||
Graphics.ExecuteCommandBuffer(m_multipPassCmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -147,6 +147,25 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
controller.SetBinding(EssgeeSingleKey.LEFT, device.JOYSTICK.Left, 1);
|
||||
controller.SetBinding(EssgeeSingleKey.RIGHT, device.JOYSTICK.Right, 1);
|
||||
}
|
||||
|
||||
public override void Bind(SwitchJoyCon_D device, ControllerBinder controller)
|
||||
{
|
||||
controller.SetBinding(EssgeeSingleKey.OPTION_1, device.Plus, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.OPTION_2, device.Minus, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.UP, device.Up, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.DOWN, device.Down, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.LEFT, device.Left, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.RIGHT, device.Right, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.BTN_1, device.A, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.BTN_2, device.B, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.BTN_3, device.X, 0);
|
||||
controller.SetBinding(EssgeeSingleKey.BTN_4, device.Y, 0);
|
||||
|
||||
controller.SetBinding(EssgeeSingleKey.UP, device.LeftStick.Up, 1);
|
||||
controller.SetBinding(EssgeeSingleKey.DOWN, device.LeftStick.Down, 1);
|
||||
controller.SetBinding(EssgeeSingleKey.LEFT, device.LeftStick.Left, 1);
|
||||
controller.SetBinding(EssgeeSingleKey.RIGHT, device.LeftStick.Right, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class MasterSystemKeyBinding : EssgeeKeyBinding
|
||||
|
||||
@ -158,6 +158,27 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
controller.SetBinding(UMAMEKSingleKey.LEFT, device.JOYSTICK.Left, 1);
|
||||
controller.SetBinding(UMAMEKSingleKey.RIGHT, device.JOYSTICK.Right, 1);
|
||||
}
|
||||
|
||||
public override void Bind(SwitchJoyCon_D device, ControllerBinder controller)
|
||||
{
|
||||
controller.SetBinding(UMAMEKSingleKey.INSERT_COIN, device.Minus, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.GAMESTART, device.Plus, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.UP, device.Up, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.DOWN, device.Down, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.LEFT, device.Left, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.RIGHT, device.Right, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.BTN_A, device.A, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.BTN_B, device.B, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.BTN_C, device.X, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.BTN_D, device.Y, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.BTN_E, device.LeftSL, 0);
|
||||
controller.SetBinding(UMAMEKSingleKey.BTN_F, device.RightSL, 0);
|
||||
|
||||
controller.SetBinding(UMAMEKSingleKey.UP, device.LeftStick.Up, 1);
|
||||
controller.SetBinding(UMAMEKSingleKey.DOWN, device.LeftStick.Down, 1);
|
||||
controller.SetBinding(UMAMEKSingleKey.LEFT, device.LeftStick.Left, 1);
|
||||
controller.SetBinding(UMAMEKSingleKey.RIGHT, device.LeftStick.Right, 1);
|
||||
}
|
||||
}
|
||||
|
||||
public class NEOGEOKeyBinding : MAMEKeyBinding
|
||||
|
||||
@ -16,7 +16,8 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
|
||||
IDeviceBinder<T, DualShockController_D>,
|
||||
IDeviceBinder<T, XboxController_D>,
|
||||
IDeviceBinder<T, PSVController_D>,
|
||||
IDeviceBinder<T, ScreenGamepad_D>
|
||||
IDeviceBinder<T, ScreenGamepad_D>,
|
||||
IDeviceBinder<T, SwitchJoyCon_D>
|
||||
where T : Enum
|
||||
{
|
||||
//每一个实例代表一个对应模拟器平台的控制器索引
|
||||
@ -83,6 +84,7 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
|
||||
else if (device is XboxController_D xbC) Bind(xbC, binding);
|
||||
else if (device is PSVController_D psvC) Bind(psvC, binding);
|
||||
else if (device is ScreenGamepad_D screenGamepad) Bind(screenGamepad, binding);
|
||||
else if (device is SwitchJoyCon_D nsJoyCon) Bind(nsJoyCon, binding);
|
||||
else throw new NotImplementedException($"{device.GetType()}");
|
||||
}
|
||||
|
||||
@ -305,4 +307,5 @@ public abstract class EmuCoreBinder<T> : InternalEmuCoreBinder,
|
||||
public abstract void Bind(XboxController_D device, ControllerBinder controller);
|
||||
public abstract void Bind(PSVController_D device, ControllerBinder controller);
|
||||
public abstract void Bind(ScreenGamepad_D device, ControllerBinder controller);
|
||||
public abstract void Bind(SwitchJoyCon_D device, ControllerBinder controller);
|
||||
}
|
||||
@ -121,5 +121,22 @@ namespace AxibugEmuOnline.Client.Settings
|
||||
controller.SetBinding(EnumButtonType.UP, device.JOYSTICK.Up, 1);
|
||||
controller.SetBinding(EnumButtonType.DOWN, device.JOYSTICK.Down, 1);
|
||||
}
|
||||
public override void Bind(SwitchJoyCon_D device, ControllerBinder controller)
|
||||
{
|
||||
controller.SetBinding(EnumButtonType.LEFT, device.Left, 0);
|
||||
controller.SetBinding(EnumButtonType.RIGHT, device.Right, 0);
|
||||
controller.SetBinding(EnumButtonType.UP, device.Up, 0);
|
||||
controller.SetBinding(EnumButtonType.DOWN, device.Down, 0);
|
||||
controller.SetBinding(EnumButtonType.A, device.A, 0);
|
||||
controller.SetBinding(EnumButtonType.B, device.B, 0);
|
||||
controller.SetBinding(EnumButtonType.SELECT, device.Minus, 0);
|
||||
controller.SetBinding(EnumButtonType.START, device.Plus, 0);
|
||||
controller.SetBinding(EnumButtonType.MIC, device.RightSL, 0);
|
||||
|
||||
controller.SetBinding(EnumButtonType.LEFT, device.LeftStick.Left, 1);
|
||||
controller.SetBinding(EnumButtonType.RIGHT, device.LeftStick.Right, 1);
|
||||
controller.SetBinding(EnumButtonType.UP, device.LeftStick.Up, 1);
|
||||
controller.SetBinding(EnumButtonType.DOWN, device.LeftStick.Down, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -112,5 +112,20 @@ namespace AxibugEmuOnline.Client
|
||||
controller.SetBinding(EnumCommand.SelectItemRight, device.JOYSTICK.Right, 1);
|
||||
controller.SetBinding(EnumCommand.SelectItemUp, device.JOYSTICK.Up, 1);
|
||||
}
|
||||
public override void Bind(SwitchJoyCon_D device, ControllerBinder controller)
|
||||
{
|
||||
controller.SetBinding(EnumCommand.Back, device.A, 0);
|
||||
controller.SetBinding(EnumCommand.Enter, device.B, 0);
|
||||
controller.SetBinding(EnumCommand.OptionMenu, device.Plus, 0);
|
||||
controller.SetBinding(EnumCommand.SelectItemDown, device.Down, 0);
|
||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.Left, 0);
|
||||
controller.SetBinding(EnumCommand.SelectItemRight, device.Right, 0);
|
||||
controller.SetBinding(EnumCommand.SelectItemUp, device.Up, 0);
|
||||
|
||||
controller.SetBinding(EnumCommand.SelectItemDown, device.LeftStick.Down, 1);
|
||||
controller.SetBinding(EnumCommand.SelectItemLeft, device.LeftStick.Left, 1);
|
||||
controller.SetBinding(EnumCommand.SelectItemRight, device.LeftStick.Right, 1);
|
||||
controller.SetBinding(EnumCommand.SelectItemUp, device.LeftStick.Up, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,136 +1,136 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CacheManager
|
||||
{
|
||||
static readonly string CacheDirPath = $"{App.PersistentDataRoot()}/Caches";
|
||||
static readonly string TextureCacheDirPath = $"{CacheDirPath}/Texture";
|
||||
|
||||
public void GetSpriteCache(string url, Action<Sprite, string> callback)
|
||||
{
|
||||
GetCacheData(url, TextureCacheDirPath, callback);
|
||||
}
|
||||
|
||||
/// <summary> 移除文件缓存 </summary>
|
||||
public void ClearCaches()
|
||||
{
|
||||
if (AxiIO.Directory.Exists(CacheDirPath))
|
||||
AxiIO.Directory.Delete(CacheDirPath, true);
|
||||
}
|
||||
|
||||
IEnumerator DownloadFromURL(string url, string path, Action<byte[]> callback)
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CacheManager
|
||||
{
|
||||
static readonly string CacheDirPath = $"{App.PersistentDataRoot()}/Caches";
|
||||
static readonly string TextureCacheDirPath = $"{CacheDirPath}/Texture";
|
||||
|
||||
public void GetSpriteCache(string url, Action<Sprite, string> callback)
|
||||
{
|
||||
AxiHttpProxy.SendDownLoadProxy request = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{url}");
|
||||
|
||||
while (!request.downloadHandler.isDone)
|
||||
{
|
||||
yield return null;
|
||||
//Debug.Log($"下载进度:{respInfo.DownLoadPr} ->{respInfo.loadedLenght}/{respInfo.NeedloadedLenght}");
|
||||
}
|
||||
GetCacheData(url, TextureCacheDirPath, callback);
|
||||
}
|
||||
|
||||
/// <summary> 移除文件缓存 </summary>
|
||||
public void ClearCaches()
|
||||
{
|
||||
if (AxiIO.Directory.Exists(CacheDirPath))
|
||||
AxiIO.Directory.Delete(CacheDirPath, true);
|
||||
}
|
||||
|
||||
IEnumerator DownloadFromURL(string url, string path, Action<byte[]> callback)
|
||||
{
|
||||
AxiHttpProxy.SendDownLoadProxy request = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{url}");
|
||||
|
||||
while (!request.downloadHandler.isDone)
|
||||
{
|
||||
yield return null;
|
||||
//Debug.Log($"下载进度:{respInfo.DownLoadPr} ->{respInfo.loadedLenght}/{respInfo.NeedloadedLenght}");
|
||||
}
|
||||
AxiHttpProxy.ShowAxiHttpDebugInfo(request.downloadHandler);
|
||||
|
||||
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
AxiIO.Directory.CreateDirectory(path);
|
||||
AxiIO.File.WriteAllBytes($"{path}/{url.GetHashCode()}", request.downloadHandler.data, false);
|
||||
callback.Invoke(request.downloadHandler.data);
|
||||
}
|
||||
AxiIO.File.WriteAllBytes($"{path}/{url.GetHashCode()}", request.downloadHandler.data, false);
|
||||
callback.Invoke(request.downloadHandler.data);
|
||||
}
|
||||
else
|
||||
{
|
||||
callback.Invoke(null);
|
||||
}
|
||||
|
||||
/*
|
||||
var request = UnityWebRequest.Get($"{App.httpAPI.WebHost}/{url}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
File.WriteAllBytes($"{path}/{url.GetHashCode()}", request.downloadHandler.data);
|
||||
callback.Invoke(request.downloadHandler.data);
|
||||
}
|
||||
else
|
||||
callback.Invoke(null);
|
||||
*/
|
||||
}
|
||||
|
||||
private Dictionary<string, object> cachesInMemory = new Dictionary<string, object>();
|
||||
callback.Invoke(null);
|
||||
}
|
||||
|
||||
/*
|
||||
var request = UnityWebRequest.Get($"{App.httpAPI.WebHost}/{url}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result == UnityWebRequest.Result.Success)
|
||||
{
|
||||
Directory.CreateDirectory(path);
|
||||
File.WriteAllBytes($"{path}/{url.GetHashCode()}", request.downloadHandler.data);
|
||||
callback.Invoke(request.downloadHandler.data);
|
||||
}
|
||||
else
|
||||
callback.Invoke(null);
|
||||
*/
|
||||
}
|
||||
|
||||
private Dictionary<string, object> cachesInMemory = new Dictionary<string, object>();
|
||||
void GetCacheData<T>(string url, string path, Action<T, string> callback) where T : class
|
||||
{
|
||||
{
|
||||
object cacheObj;
|
||||
|
||||
if (cachesInMemory.TryGetValue(url, out cacheObj) && cacheObj is T)
|
||||
{
|
||||
if (cachesInMemory.TryGetValue(url, out cacheObj) && cacheObj is T)
|
||||
{
|
||||
T obj = (T)cacheObj;
|
||||
callback.Invoke(obj, url);
|
||||
return;
|
||||
}
|
||||
|
||||
var fileName = $"{url.GetHashCode()}";
|
||||
byte[] rawData = null;
|
||||
|
||||
var filePath = $"{path}/{fileName}";
|
||||
if (AxiIO.File.Exists(filePath))
|
||||
{
|
||||
rawData = AxiIO.File.ReadAllBytes(filePath);
|
||||
var @out = RawDataConvert<T>(rawData);
|
||||
cachesInMemory[url] = @out;
|
||||
callback.Invoke(@out, url);
|
||||
}
|
||||
else
|
||||
{
|
||||
App.StartCoroutine(DownloadFromURL(url, path, (data) =>
|
||||
{
|
||||
var @out = RawDataConvert<T>(data);
|
||||
cachesInMemory[url] = @out;
|
||||
callback.Invoke(@out, url);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Type t_texture2d = typeof(Texture2D);
|
||||
Type t_sprite = typeof(Sprite);
|
||||
Type t_byteArray = typeof(byte[]);
|
||||
Type t_object = typeof(object);
|
||||
|
||||
T RawDataConvert<T>(byte[] data) where T : class
|
||||
{
|
||||
var vt = typeof(T);
|
||||
|
||||
if (vt == t_texture2d || vt == t_sprite)
|
||||
{
|
||||
Texture2D texture = new Texture2D(2, 2);
|
||||
callback.Invoke(obj, url);
|
||||
return;
|
||||
}
|
||||
|
||||
var fileName = $"{url.GetHashCode()}";
|
||||
byte[] rawData = null;
|
||||
|
||||
var filePath = $"{path}/{fileName}";
|
||||
if (AxiIO.File.Exists(filePath))
|
||||
{
|
||||
rawData = AxiIO.File.ReadAllBytes(filePath);
|
||||
var @out = RawDataConvert<T>(rawData);
|
||||
cachesInMemory[url] = @out;
|
||||
callback.Invoke(@out, url);
|
||||
}
|
||||
else
|
||||
{
|
||||
App.StartCoroutine(DownloadFromURL(url, path, (data) =>
|
||||
{
|
||||
var @out = RawDataConvert<T>(data);
|
||||
cachesInMemory[url] = @out;
|
||||
callback.Invoke(@out, url);
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
Type t_texture2d = typeof(Texture2D);
|
||||
Type t_sprite = typeof(Sprite);
|
||||
Type t_byteArray = typeof(byte[]);
|
||||
Type t_object = typeof(object);
|
||||
|
||||
T RawDataConvert<T>(byte[] data) where T : class
|
||||
{
|
||||
var vt = typeof(T);
|
||||
|
||||
if (vt == t_texture2d || vt == t_sprite)
|
||||
{
|
||||
Texture2D texture = new Texture2D(2, 2);
|
||||
if (data == null)
|
||||
{
|
||||
var errorSpr = Resources.Load<Sprite>("UIImage/error");
|
||||
if (vt == t_texture2d) return errorSpr.texture as T;
|
||||
else return errorSpr as T;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
texture.LoadImage(data);
|
||||
|
||||
if (vt == t_texture2d) return texture as T;
|
||||
else return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)) as T;
|
||||
}
|
||||
}
|
||||
else if (vt == t_byteArray)
|
||||
{
|
||||
return data as T;
|
||||
}
|
||||
else
|
||||
{
|
||||
return data as T;
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"{vt.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else return Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f)) as T;
|
||||
}
|
||||
}
|
||||
else if (vt == t_byteArray)
|
||||
{
|
||||
return data as T;
|
||||
}
|
||||
else
|
||||
{
|
||||
return data as T;
|
||||
}
|
||||
|
||||
throw new NotImplementedException($"{vt.Name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,298 +1,298 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class HttpAPI
|
||||
{
|
||||
public string WebHost = "http://emu.axibug.com";
|
||||
public string WebSiteApi => WebHost + "/api";
|
||||
|
||||
public delegate void GetRomListAPI(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType Platform, int page, int pageSize = 10);
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class HttpAPI
|
||||
{
|
||||
public string WebHost = "http://emu.axibug.com";
|
||||
public string WebSiteApi => WebHost + "/api";
|
||||
|
||||
public delegate void GetRomListAPI(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType Platform, int page, int pageSize = 10);
|
||||
public delegate void SearchRomListAPI(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType Platform, string searchKey, int page, int pageSize = 10);
|
||||
public delegate void GetStarRomListAPI(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, int page, int pageSize = 10);
|
||||
|
||||
public void GetRomList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(GetRomListFlow(platform, page, pageSize, callback));
|
||||
}
|
||||
public void SearchRomList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(SearchRomListFlow(platform, searchKey, page, pageSize, callback));
|
||||
}
|
||||
private IEnumerator SearchRomListFlow(AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchKey))
|
||||
{
|
||||
string oldsearch = searchKey;
|
||||
//searchKey = System.Net.WebUtility.UrlEncode(searchKey);
|
||||
searchKey = AxiHttp.UrlEncode(searchKey);
|
||||
App.log.Info($"search->{oldsearch} ->{searchKey}");
|
||||
//searchKey = HttpUtility.UrlDecode(searchKey);
|
||||
}
|
||||
//避免特殊字符和个别文字编码问题
|
||||
//byte[] gb2312Bytes = Encoding.Default.GetBytes(searchKey);
|
||||
//byte[] utf8Bytes = Encoding.Convert(Encoding.Default, Encoding.UTF8, gb2312Bytes);
|
||||
//// 将UTF-8编码的字节数组转换回字符串(此时是UTF-8编码的字符串)
|
||||
//string utf8String = Encoding.UTF8.GetString(utf8Bytes);
|
||||
//searchKey = UrlEncode(utf8String);
|
||||
//App.log.Info($"search->{utf8String} ->{searchKey}");
|
||||
string url = $"{WebSiteApi}/RomList?Page={page}&PageSize={pageSize}&PType={(int)platform}&SearchKey={searchKey}&Token={App.user.Token}";
|
||||
App.log.Info($"GetRomList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}&SearchKey={searchKey}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}*/
|
||||
|
||||
}
|
||||
private IEnumerator GetRomListFlow(AxibugProtobuf.RomPlatformType platform, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
string url = $"{WebSiteApi}/RomList?Page={page}&PageSize={pageSize}&PType={(int)platform}&Token={App.user.Token}";
|
||||
App.log.Info($"GetRomList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//请求成功
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
*/
|
||||
public void GetRomList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(GetRomListFlow(platform, page, pageSize, callback));
|
||||
}
|
||||
public void SearchRomList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(SearchRomListFlow(platform, searchKey, page, pageSize, callback));
|
||||
}
|
||||
private IEnumerator SearchRomListFlow(AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchKey))
|
||||
{
|
||||
string oldsearch = searchKey;
|
||||
//searchKey = System.Net.WebUtility.UrlEncode(searchKey);
|
||||
searchKey = AxiHttp.UrlEncode(searchKey);
|
||||
App.log.Info($"search->{oldsearch} ->{searchKey}");
|
||||
//searchKey = HttpUtility.UrlDecode(searchKey);
|
||||
}
|
||||
//避免特殊字符和个别文字编码问题
|
||||
//byte[] gb2312Bytes = Encoding.Default.GetBytes(searchKey);
|
||||
//byte[] utf8Bytes = Encoding.Convert(Encoding.Default, Encoding.UTF8, gb2312Bytes);
|
||||
//// 将UTF-8编码的字节数组转换回字符串(此时是UTF-8编码的字符串)
|
||||
//string utf8String = Encoding.UTF8.GetString(utf8Bytes);
|
||||
//searchKey = UrlEncode(utf8String);
|
||||
//App.log.Info($"search->{utf8String} ->{searchKey}");
|
||||
string url = $"{WebSiteApi}/RomList?Page={page}&PageSize={pageSize}&PType={(int)platform}&SearchKey={searchKey}&Token={App.user.Token}";
|
||||
App.log.Info($"GetRomList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}&SearchKey={searchKey}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}*/
|
||||
|
||||
}
|
||||
private IEnumerator GetRomListFlow(AxibugProtobuf.RomPlatformType platform, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
string url = $"{WebSiteApi}/RomList?Page={page}&PageSize={pageSize}&PType={(int)platform}&Token={App.user.Token}";
|
||||
App.log.Info($"GetRomList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//请求成功
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public void GetMarkList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(GetMarkListFlow(platform, page, pageSize, callback));
|
||||
}
|
||||
public void SearchMarkList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(SearchMarkListFlow(platform, searchKey, page, pageSize, callback));
|
||||
}
|
||||
private IEnumerator SearchMarkListFlow(AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchKey))
|
||||
{
|
||||
string oldsearch = searchKey;
|
||||
//searchKey = System.Net.WebUtility.UrlEncode(searchKey);
|
||||
searchKey = AxiHttp.UrlEncode(searchKey);
|
||||
App.log.Info($"search->{oldsearch} ->{searchKey}");
|
||||
//searchKey = HttpUtility.UrlDecode(searchKey);
|
||||
}
|
||||
//避免特殊字符和个别文字编码问题
|
||||
//byte[] gb2312Bytes = Encoding.Default.GetBytes(searchKey);
|
||||
//byte[] utf8Bytes = Encoding.Convert(Encoding.Default, Encoding.UTF8, gb2312Bytes);
|
||||
//// 将UTF-8编码的字节数组转换回字符串(此时是UTF-8编码的字符串)
|
||||
//string utf8String = Encoding.UTF8.GetString(utf8Bytes);
|
||||
//searchKey = UrlEncode(utf8String);
|
||||
//App.log.Info($"search->{utf8String} ->{searchKey}");
|
||||
string url = $"{WebSiteApi}/MarkList?Page={page}&PageSize={pageSize}&SearchKey={searchKey}&Token={App.user.Token}";
|
||||
App.log.Info($"MarkList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}&SearchKey={searchKey}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}*/
|
||||
|
||||
}
|
||||
private IEnumerator GetMarkListFlow(AxibugProtobuf.RomPlatformType platform, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
string url = $"{WebSiteApi}/MarkList?Page={page}&PageSize={pageSize}&PType={(int)platform}&Token={App.user.Token}";
|
||||
App.log.Info($"MarkList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//请求成功
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public IEnumerator GetRomInfo(int RomID, Action<Resp_RomInfo> callback)
|
||||
{
|
||||
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get($"{WebSiteApi}/RomInfo?RomID={RomID}&Token={App.user.Token}");
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//成功
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_RomInfo>(request.downloadHandler.text);
|
||||
callback.Invoke(resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(null);
|
||||
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/RomInfo?PType={PlatformType.Nes}&RomID={RomID}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
enum GameType : byte
|
||||
{
|
||||
NONE = 0,
|
||||
ACT,
|
||||
ARPG,
|
||||
AVG,
|
||||
ETC,
|
||||
FTG,
|
||||
PUZ,
|
||||
RAC,
|
||||
RPG,
|
||||
SLG,
|
||||
SPG,
|
||||
SRPG,
|
||||
STG,
|
||||
TAB,
|
||||
/// <summary>
|
||||
/// 合卡
|
||||
/// </summary>
|
||||
ALLINONE,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Resp_GameList
|
||||
{
|
||||
public int page;
|
||||
public int maxPage;
|
||||
public int resultAllCount;
|
||||
public List<Resp_RomInfo> gameList;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Resp_RomInfo
|
||||
{
|
||||
public void GetMarkList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(GetMarkListFlow(platform, page, pageSize, callback));
|
||||
}
|
||||
public void SearchMarkList(Action<int, Resp_GameList> callback, AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize = 10)
|
||||
{
|
||||
App.StartCoroutine(SearchMarkListFlow(platform, searchKey, page, pageSize, callback));
|
||||
}
|
||||
private IEnumerator SearchMarkListFlow(AxibugProtobuf.RomPlatformType platform, string searchKey, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(searchKey))
|
||||
{
|
||||
string oldsearch = searchKey;
|
||||
//searchKey = System.Net.WebUtility.UrlEncode(searchKey);
|
||||
searchKey = AxiHttp.UrlEncode(searchKey);
|
||||
App.log.Info($"search->{oldsearch} ->{searchKey}");
|
||||
//searchKey = HttpUtility.UrlDecode(searchKey);
|
||||
}
|
||||
//避免特殊字符和个别文字编码问题
|
||||
//byte[] gb2312Bytes = Encoding.Default.GetBytes(searchKey);
|
||||
//byte[] utf8Bytes = Encoding.Convert(Encoding.Default, Encoding.UTF8, gb2312Bytes);
|
||||
//// 将UTF-8编码的字节数组转换回字符串(此时是UTF-8编码的字符串)
|
||||
//string utf8String = Encoding.UTF8.GetString(utf8Bytes);
|
||||
//searchKey = UrlEncode(utf8String);
|
||||
//App.log.Info($"search->{utf8String} ->{searchKey}");
|
||||
string url = $"{WebSiteApi}/MarkList?Page={page}&PageSize={pageSize}&SearchKey={searchKey}&Token={App.user.Token}";
|
||||
App.log.Info($"MarkList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}&SearchKey={searchKey}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}*/
|
||||
|
||||
}
|
||||
private IEnumerator GetMarkListFlow(AxibugProtobuf.RomPlatformType platform, int page, int pageSize, Action<int, Resp_GameList> callback)
|
||||
{
|
||||
string url = $"{WebSiteApi}/MarkList?Page={page}&PageSize={pageSize}&PType={(int)platform}&Token={App.user.Token}";
|
||||
App.log.Info($"MarkList=>{url}");
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get(url);
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(page, null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//请求成功
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_GameList>(request.downloadHandler.text);
|
||||
callback.Invoke(page, resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(page, null);
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/NesRomList?Page={page}&PageSize={pageSize}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
public IEnumerator GetRomInfo(int RomID, Action<Resp_RomInfo> callback)
|
||||
{
|
||||
|
||||
AxiHttpProxy.SendWebRequestProxy request = AxiHttpProxy.Get($"{WebSiteApi}/RomInfo?RomID={RomID}&Token={App.user.Token}");
|
||||
yield return request.SendWebRequest;
|
||||
if (!request.downloadHandler.isDone)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}
|
||||
|
||||
//成功
|
||||
if (!request.downloadHandler.bHadErr)
|
||||
{
|
||||
var resp = JsonUtility.FromJson<Resp_RomInfo>(request.downloadHandler.text);
|
||||
callback.Invoke(resp);
|
||||
yield break;
|
||||
}
|
||||
|
||||
App.log.Error(request.downloadHandler.ErrInfo);
|
||||
callback.Invoke(null);
|
||||
|
||||
/*
|
||||
UnityWebRequest request = UnityWebRequest.Get($"{WebSiteApi}/RomInfo?PType={PlatformType.Nes}&RomID={RomID}");
|
||||
yield return request.SendWebRequest();
|
||||
|
||||
if (request.result != UnityWebRequest.Result.Success)
|
||||
{
|
||||
callback.Invoke(null);
|
||||
yield break;
|
||||
}*/
|
||||
|
||||
}
|
||||
|
||||
enum GameType : byte
|
||||
{
|
||||
NONE = 0,
|
||||
ACT,
|
||||
ARPG,
|
||||
AVG,
|
||||
ETC,
|
||||
FTG,
|
||||
PUZ,
|
||||
RAC,
|
||||
RPG,
|
||||
SLG,
|
||||
SPG,
|
||||
SRPG,
|
||||
STG,
|
||||
TAB,
|
||||
/// <summary>
|
||||
/// 合卡
|
||||
/// </summary>
|
||||
ALLINONE,
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Resp_GameList
|
||||
{
|
||||
public int page;
|
||||
public int maxPage;
|
||||
public int resultAllCount;
|
||||
public List<Resp_RomInfo> gameList;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class Resp_RomInfo
|
||||
{
|
||||
public int orderid;
|
||||
public int id;
|
||||
//TODO 后续根据ptype,启动游戏时选择核心。和列表设计和UI分组解耦,比如无视平台搜索列表,收藏列表
|
||||
public int ptype;
|
||||
public string romName;
|
||||
public string gType;
|
||||
public string desc;
|
||||
public string url;
|
||||
public string imgUrl;
|
||||
public string hash;
|
||||
public int id;
|
||||
//TODO 后续根据ptype,启动游戏时选择核心。和列表设计和UI分组解耦,比如无视平台搜索列表,收藏列表
|
||||
public int ptype;
|
||||
public string romName;
|
||||
public string gType;
|
||||
public string desc;
|
||||
public string url;
|
||||
public string imgUrl;
|
||||
public string hash;
|
||||
public int stars;
|
||||
/// <summary>
|
||||
/// 游玩计数
|
||||
/// </summary>
|
||||
public int playcount;
|
||||
public int playcount;
|
||||
/// <summary>
|
||||
/// 是否收藏
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public int isStar;
|
||||
public List<int> parentRomIdsList;
|
||||
}
|
||||
[Serializable]
|
||||
public class Resp_CheckStandInfo
|
||||
{
|
||||
public int needUpdateClient;
|
||||
public string serverIp;
|
||||
public ushort serverPort;
|
||||
public string clientVersion;
|
||||
public string downLoadUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
public List<int> parentRomIdsList;
|
||||
}
|
||||
[Serializable]
|
||||
public class Resp_CheckStandInfo
|
||||
{
|
||||
public int needUpdateClient;
|
||||
public string serverIp;
|
||||
public ushort serverPort;
|
||||
public string clientVersion;
|
||||
public string downLoadUrl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,32 +73,48 @@ namespace AxibugEmuOnline.Client.InputDevices
|
||||
{
|
||||
return m_devices.Values;
|
||||
}
|
||||
|
||||
List<string> templog = new List<string>();
|
||||
/// <summary> 由外部驱动的逻辑更新入口 </summary>
|
||||
public void Update()
|
||||
{
|
||||
foreach (var device in m_devices.Values) device.Update();
|
||||
|
||||
DebugInputSystem();
|
||||
}
|
||||
//string HadDrive = "";
|
||||
//foreach (var device in InputSystem.devices)
|
||||
//{
|
||||
// if (device is Mouse)
|
||||
// continue;
|
||||
// bool bhadflag = false;
|
||||
|
||||
private static void DebugInputSystem()
|
||||
{
|
||||
return;
|
||||
#if ENABLE_INPUT_SYSTEM
|
||||
foreach (var device in InputSystem.devices)
|
||||
{
|
||||
if (device is Mouse)
|
||||
continue;
|
||||
for (int i = 0; i < device.allControls.Count; i++)
|
||||
{
|
||||
if (device.allControls[i].IsPressed(0))
|
||||
{
|
||||
Debug.Log($"{device.displayName}| {device.allControls[i].displayName}|{device.allControls[i].name}");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// templog.Clear();
|
||||
// for (int i = 0; i < device.allControls.Count; i++)
|
||||
// {
|
||||
// if (device.allControls[i].IsPressed(0))
|
||||
// {
|
||||
// if (device.allControls[i].name.ToLower() == "anykey")
|
||||
// continue;
|
||||
// bhadflag = true;
|
||||
// string keyname = $"{device.allControls[i].GetType().FullName}|{device.allControls[i].name},";
|
||||
// templog.Add(keyname);
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (bhadflag)
|
||||
// {
|
||||
// HadDrive += $" D:{device.GetType().FullName}|{device.GetType().BaseType.FullName}|{device.name}, K:";
|
||||
// foreach (var s in templog)
|
||||
// {
|
||||
// HadDrive += s;
|
||||
// }
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
//if (!string.IsNullOrEmpty(HadDrive))
|
||||
//{
|
||||
// Debug.Log($"Had Drive: {HadDrive}");
|
||||
//}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,22 +1,22 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomFile
|
||||
{
|
||||
private HttpAPI.Resp_RomInfo webData;
|
||||
/// <summary> 依赖的Rom文件 </summary>
|
||||
private List<RomFile> dependencies = new List<RomFile>();
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomFile
|
||||
{
|
||||
private HttpAPI.Resp_RomInfo webData;
|
||||
/// <summary> 依赖的Rom文件 </summary>
|
||||
private List<RomFile> dependencies = new List<RomFile>();
|
||||
RomPlatformType m_defaultPlatform;
|
||||
|
||||
/// <summary> 指示该Rom是否是多文件Rom </summary>
|
||||
|
||||
/// <summary> 指示该Rom是否是多文件Rom </summary>
|
||||
public bool MultiFileRom
|
||||
{
|
||||
get
|
||||
@ -41,10 +41,10 @@ namespace AxibugEmuOnline.Client
|
||||
default: throw new NotImplementedException($"未实现的平台{Platform}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public string FileExtentionName
|
||||
{
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Platform)
|
||||
@ -63,10 +63,10 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
default: throw new NotImplementedException($"未实现的平台{Platform}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool m_hasLocalFile;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_hasLocalFile;
|
||||
public bool HasLocalFile
|
||||
{
|
||||
get
|
||||
@ -80,12 +80,12 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> 指示该Rom文件的存放路径 </summary>
|
||||
public string LocalFilePath => $"{App.PersistentDataPath(Platform)}/RemoteRoms/{FileName}";
|
||||
|
||||
/// <summary> 指示该Rom文件是否已下载完毕 </summary>
|
||||
}
|
||||
|
||||
/// <summary> 指示该Rom文件的存放路径 </summary>
|
||||
public string LocalFilePath => $"{App.PersistentDataPath(Platform)}/RemoteRoms/{FileName}";
|
||||
|
||||
/// <summary> 指示该Rom文件是否已下载完毕 </summary>
|
||||
public bool RomReady
|
||||
{
|
||||
get
|
||||
@ -99,8 +99,8 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/// <summary> 指示是否正在下载Rom文件 </summary>
|
||||
}
|
||||
/// <summary> 指示是否正在下载Rom文件 </summary>
|
||||
public bool IsDownloading
|
||||
{
|
||||
get
|
||||
@ -141,10 +141,10 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
return progress / (dependencies.Count + 1);
|
||||
}
|
||||
}
|
||||
|
||||
public RomPlatformType Platform => webData != null ? (RomPlatformType)webData.ptype : m_defaultPlatform;
|
||||
/// <summary> 指示该Rom信息是否已填充 </summary>
|
||||
}
|
||||
|
||||
public RomPlatformType Platform => webData != null ? (RomPlatformType)webData.ptype : m_defaultPlatform;
|
||||
/// <summary> 指示该Rom信息是否已填充 </summary>
|
||||
public bool InfoReady
|
||||
{
|
||||
get
|
||||
@ -158,23 +158,23 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
/// <summary> 唯一标识 </summary>
|
||||
public int ID => webData != null ? webData.id : -1;
|
||||
/// <summary> 别名 </summary>
|
||||
public string Alias => webData.romName;
|
||||
/// <summary> 描述 </summary>
|
||||
public string Descript => webData.desc;
|
||||
/// <summary> 游戏类型 </summary>
|
||||
public string GameTypeDes => webData.gType;
|
||||
/// <summary> 小图URL </summary>
|
||||
public string ImageURL => webData.imgUrl;
|
||||
|
||||
/// <summary> 文件名 </summary>
|
||||
public string FileName { get; private set; }
|
||||
/// <summary> 在查询结果中的索引 </summary>
|
||||
public int Index { get; private set; }
|
||||
/// <summary> 在查询结果中的所在页 </summary>
|
||||
}
|
||||
/// <summary> 唯一标识 </summary>
|
||||
public int ID => webData != null ? webData.id : -1;
|
||||
/// <summary> 别名 </summary>
|
||||
public string Alias => webData.romName;
|
||||
/// <summary> 描述 </summary>
|
||||
public string Descript => webData.desc;
|
||||
/// <summary> 游戏类型 </summary>
|
||||
public string GameTypeDes => webData.gType;
|
||||
/// <summary> 小图URL </summary>
|
||||
public string ImageURL => webData.imgUrl;
|
||||
|
||||
/// <summary> 文件名 </summary>
|
||||
public string FileName { get; private set; }
|
||||
/// <summary> 在查询结果中的索引 </summary>
|
||||
public int Index { get; private set; }
|
||||
/// <summary> 在查询结果中的所在页 </summary>
|
||||
public int Page { get; private set; }
|
||||
|
||||
public string Hash => webData != null ? webData.hash : string.Empty;
|
||||
@ -189,16 +189,16 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
}
|
||||
|
||||
public event Action<RomFile> OnDownloadOver;
|
||||
public event Action OnInfoFilled;
|
||||
|
||||
public RomFile(int index, int insidePage, RomPlatformType defaultPlatform)
|
||||
{
|
||||
Index = index;
|
||||
Page = insidePage;
|
||||
m_defaultPlatform = defaultPlatform;
|
||||
}
|
||||
|
||||
public event Action<RomFile> OnDownloadOver;
|
||||
public event Action OnInfoFilled;
|
||||
|
||||
public RomFile(int index, int insidePage, RomPlatformType defaultPlatform)
|
||||
{
|
||||
Index = index;
|
||||
Page = insidePage;
|
||||
m_defaultPlatform = defaultPlatform;
|
||||
}
|
||||
|
||||
public void CheckLocalFileState()
|
||||
{
|
||||
if (webData == null) m_hasLocalFile = false;
|
||||
@ -215,22 +215,22 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
foreach (var depRom in dependencies)
|
||||
depRom.CheckLocalFileState();
|
||||
}
|
||||
|
||||
public void BeginDownload()
|
||||
{
|
||||
if (RomReady) return;
|
||||
if (IsDownloading) return;
|
||||
|
||||
//检查依赖Rom的下载情况
|
||||
}
|
||||
|
||||
public void BeginDownload()
|
||||
{
|
||||
if (RomReady) return;
|
||||
if (IsDownloading) return;
|
||||
|
||||
//检查依赖Rom的下载情况
|
||||
foreach (var depRom in dependencies)
|
||||
{
|
||||
depRom.BeginDownload();
|
||||
}
|
||||
}
|
||||
App.FileDownloader.BeginDownload(webData.url, (bytes) =>
|
||||
{
|
||||
HandleRomFilePostProcess(bytes);
|
||||
});
|
||||
HandleRomFilePostProcess(bytes);
|
||||
});
|
||||
}
|
||||
|
||||
private void HandleRomFilePostProcess(byte[] bytes)
|
||||
@ -244,23 +244,23 @@ namespace AxibugEmuOnline.Client
|
||||
var zip = new ZipInputStream(new System.IO.MemoryStream(bytes));
|
||||
|
||||
List<string> depth0Files = new List<string>();
|
||||
while (true)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
var currentEntry = zip.GetNextEntry();
|
||||
if (currentEntry == null) break;
|
||||
|
||||
if (currentEntry.IsDirectory) continue;
|
||||
|
||||
var buffer = new byte[1024];
|
||||
System.IO.MemoryStream output = new System.IO.MemoryStream();
|
||||
while (true)
|
||||
{
|
||||
var size = zip.Read(buffer, 0, buffer.Length);
|
||||
if (size == 0) break;
|
||||
else output.Write(buffer, 0, size);
|
||||
}
|
||||
output.Flush();
|
||||
unzipFiles[$"{LocalFilePath}/{currentEntry.Name}"] = output.ToArray();
|
||||
if (currentEntry == null) break;
|
||||
|
||||
if (currentEntry.IsDirectory) continue;
|
||||
|
||||
var buffer = new byte[1024];
|
||||
System.IO.MemoryStream output = new System.IO.MemoryStream();
|
||||
while (true)
|
||||
{
|
||||
var size = zip.Read(buffer, 0, buffer.Length);
|
||||
if (size == 0) break;
|
||||
else output.Write(buffer, 0, size);
|
||||
}
|
||||
output.Flush();
|
||||
unzipFiles[$"{LocalFilePath}/{currentEntry.Name}"] = output.ToArray();
|
||||
}
|
||||
|
||||
string rootDirName = null;
|
||||
@ -289,50 +289,50 @@ namespace AxibugEmuOnline.Client
|
||||
OnDownloadOver?.Invoke(this);
|
||||
}
|
||||
|
||||
public byte[] GetRomFileData()
|
||||
{
|
||||
Debug.Assert(!MultiFileRom, "仅供单文件Rom使用的接口");
|
||||
|
||||
if (webData == null) throw new Exception("Not Valid Rom");
|
||||
if (!RomReady) throw new Exception("Rom File Not Downloaded");
|
||||
|
||||
var bytes = AxiIO.File.ReadAllBytes(LocalFilePath);
|
||||
if (System.IO.Path.GetExtension(LocalFilePath).ToLower() == ".zip")
|
||||
{
|
||||
public byte[] GetRomFileData()
|
||||
{
|
||||
Debug.Assert(!MultiFileRom, "仅供单文件Rom使用的接口");
|
||||
|
||||
if (webData == null) throw new Exception("Not Valid Rom");
|
||||
if (!RomReady) throw new Exception("Rom File Not Downloaded");
|
||||
|
||||
var bytes = AxiIO.File.ReadAllBytes(LocalFilePath);
|
||||
if (System.IO.Path.GetExtension(LocalFilePath).ToLower() == ".zip")
|
||||
{
|
||||
var zip = new ZipInputStream(new System.IO.MemoryStream(bytes));
|
||||
while (true)
|
||||
{
|
||||
var currentEntry = zip.GetNextEntry();
|
||||
if (currentEntry == null) break;
|
||||
while (true)
|
||||
{
|
||||
var currentEntry = zip.GetNextEntry();
|
||||
if (currentEntry == null) break;
|
||||
|
||||
//当前平台单文件rom扩展名判断
|
||||
if (!currentEntry.Name.ToLower().EndsWith(FileExtentionName)) continue;
|
||||
|
||||
var buffer = new byte[1024];
|
||||
System.IO.MemoryStream output = new System.IO.MemoryStream();
|
||||
while (true)
|
||||
{
|
||||
var size = zip.Read(buffer, 0, buffer.Length);
|
||||
if (size == 0) break;
|
||||
else output.Write(buffer, 0, size);
|
||||
}
|
||||
output.Flush();
|
||||
return output.ToArray();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return bytes;
|
||||
}
|
||||
|
||||
throw new Exception("Not Valid Rom Data");
|
||||
if (!currentEntry.Name.ToLower().EndsWith(FileExtentionName)) continue;
|
||||
|
||||
var buffer = new byte[1024];
|
||||
System.IO.MemoryStream output = new System.IO.MemoryStream();
|
||||
while (true)
|
||||
{
|
||||
var size = zip.Read(buffer, 0, buffer.Length);
|
||||
if (size == 0) break;
|
||||
else output.Write(buffer, 0, size);
|
||||
}
|
||||
output.Flush();
|
||||
return output.ToArray();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return bytes;
|
||||
}
|
||||
|
||||
throw new Exception("Not Valid Rom Data");
|
||||
}
|
||||
|
||||
public void SetWebData(HttpAPI.Resp_RomInfo resp_RomInfo)
|
||||
{
|
||||
webData = resp_RomInfo;
|
||||
FileName = MultiFileRom ? System.IO.Path.GetFileNameWithoutExtension(webData.url) : System.IO.Path.GetFileName(webData.url);
|
||||
FileName = System.Net.WebUtility.UrlDecode(FileName);
|
||||
public void SetWebData(HttpAPI.Resp_RomInfo resp_RomInfo)
|
||||
{
|
||||
webData = resp_RomInfo;
|
||||
FileName = MultiFileRom ? System.IO.Path.GetFileNameWithoutExtension(webData.url) : System.IO.Path.GetFileName(webData.url);
|
||||
FileName = System.Net.WebUtility.UrlDecode(FileName);
|
||||
|
||||
//收集依赖Rom
|
||||
if (webData.parentRomIdsList != null)
|
||||
@ -349,9 +349,9 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
}
|
||||
|
||||
CheckLocalFileState();
|
||||
|
||||
App.StartCoroutine(WaitInfoReady());
|
||||
CheckLocalFileState();
|
||||
|
||||
App.StartCoroutine(WaitInfoReady());
|
||||
}
|
||||
|
||||
private IEnumerator WaitInfoReady()
|
||||
@ -359,6 +359,6 @@ namespace AxibugEmuOnline.Client
|
||||
while (!InfoReady) yield return null;
|
||||
|
||||
OnInfoFilled?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,20 +1,20 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static AxibugEmuOnline.Client.HttpAPI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static AxibugEmuOnline.Client.HttpAPI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomLib
|
||||
{
|
||||
/// <summary> Rom请求,一页的大小 </summary>
|
||||
/// <summary> Rom请求,一页的大小 </summary>
|
||||
private const int PAGE_SIZE = 10;
|
||||
|
||||
/// <summary> 请求指令 </summary>
|
||||
/// <summary> 请求指令 </summary>
|
||||
private HashSet<int> FetchPageCmd = new HashSet<int>();
|
||||
private RomFile[] RomFetchList;
|
||||
private Dictionary<int, RomFile> RomFileIdMapper = new Dictionary<int, RomFile>();
|
||||
@ -57,23 +57,23 @@ namespace AxibugEmuOnline.Client
|
||||
return romFile;
|
||||
}
|
||||
|
||||
/// <summary> 清除所有下载的Rom文件 </summary>
|
||||
/// <summary> 清除所有下载的Rom文件 </summary>
|
||||
public void ClearRomFile()
|
||||
{
|
||||
var path = $"{App.PersistentDataPath(m_platform)}/RemoteRoms";
|
||||
if (AxiIO.Directory.Exists(path)) AxiIO.Directory.Delete(path, true);
|
||||
}
|
||||
|
||||
/// <summary> 移除一个已下载的Rom </summary>
|
||||
/// <summary> 移除一个已下载的Rom </summary>
|
||||
public void RemoveOneRomFile(RomFile romFile)
|
||||
{
|
||||
if (romFile.RomReady)
|
||||
AxiIO.File.Delete(romFile.LocalFilePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得所有Rom文件
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 获得所有Rom文件
|
||||
/// </summary>
|
||||
public void FetchRomCount(Action<RomFile[]> callback, string searchKey = null)
|
||||
{
|
||||
lastSearchKey = searchKey;
|
||||
@ -186,5 +186,5 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
RomFileNameMapper[rom.FileName] = rom;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,126 +1,126 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 负责存档的云端保存和获取功能
|
||||
/// </summary>
|
||||
public class SavCloudApi
|
||||
{
|
||||
public delegate void OnFetchGameSavListHandle(int romID, Protobuf_Mine_GameSavInfo[] savSlotData);
|
||||
public event OnFetchGameSavListHandle OnFetchGameSavList;
|
||||
public delegate void OnUploadedSavDataHandle(int romID, int slotIndex, Protobuf_Mine_GameSavInfo savInfo);
|
||||
public event OnUploadedSavDataHandle OnUploadedSavData;
|
||||
|
||||
public SavCloudApi()
|
||||
{
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavGetGameSavList, RecvGetGameSavList);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavDelGameSav, RecvDelGameSavList);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavUploadGameSav, RecvUpLoadGameSav);
|
||||
}
|
||||
|
||||
private HashSet<int> m_fetchingRomIDs = new HashSet<int>();
|
||||
/// <summary>
|
||||
/// 发送请求即时存档列表
|
||||
/// </summary>
|
||||
/// <param name="RomID"></param>
|
||||
public void SendGetGameSavList(int RomID)
|
||||
{
|
||||
if (m_fetchingRomIDs.Contains(RomID)) return;
|
||||
|
||||
Protobuf_Mine_GetGameSavList req = new Protobuf_Mine_GetGameSavList()
|
||||
{
|
||||
RomID = RomID,
|
||||
};
|
||||
App.log.Info($"SendGetGameSavList");
|
||||
App.network.SendToServer((int)CommandID.CmdGamesavGetGameSavList, ProtoBufHelper.Serizlize(req));
|
||||
}
|
||||
|
||||
void RecvGetGameSavList(byte[] reqData)
|
||||
{
|
||||
/// </summary>
|
||||
public class SavCloudApi
|
||||
{
|
||||
public delegate void OnFetchGameSavListHandle(int romID, Protobuf_Mine_GameSavInfo[] savSlotData);
|
||||
public event OnFetchGameSavListHandle OnFetchGameSavList;
|
||||
public delegate void OnUploadedSavDataHandle(int romID, int slotIndex, Protobuf_Mine_GameSavInfo savInfo);
|
||||
public event OnUploadedSavDataHandle OnUploadedSavData;
|
||||
|
||||
public SavCloudApi()
|
||||
{
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavGetGameSavList, RecvGetGameSavList);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavDelGameSav, RecvDelGameSavList);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdGamesavUploadGameSav, RecvUpLoadGameSav);
|
||||
}
|
||||
|
||||
private HashSet<int> m_fetchingRomIDs = new HashSet<int>();
|
||||
/// <summary>
|
||||
/// 发送请求即时存档列表
|
||||
/// </summary>
|
||||
/// <param name="RomID"></param>
|
||||
public void SendGetGameSavList(int RomID)
|
||||
{
|
||||
if (m_fetchingRomIDs.Contains(RomID)) return;
|
||||
|
||||
Protobuf_Mine_GetGameSavList req = new Protobuf_Mine_GetGameSavList()
|
||||
{
|
||||
RomID = RomID,
|
||||
};
|
||||
App.log.Info($"SendGetGameSavList");
|
||||
App.network.SendToServer((int)CommandID.CmdGamesavGetGameSavList, ProtoBufHelper.Serizlize(req));
|
||||
}
|
||||
|
||||
void RecvGetGameSavList(byte[] reqData)
|
||||
{
|
||||
Protobuf_Mine_GetGameSavList_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_GetGameSavList_RESP>(reqData);
|
||||
|
||||
if (m_fetchingRomIDs.Remove(msg.RomID)) return;
|
||||
|
||||
Protobuf_Mine_GameSavInfo[] savArr = new Protobuf_Mine_GameSavInfo[4];
|
||||
for (int i = 0; i < savArr.Length; i++)
|
||||
{
|
||||
Protobuf_Mine_GameSavInfo info = msg.SavDataList.FirstOrDefault(w => w.SavDataIdx == i);
|
||||
savArr[i] = info;
|
||||
}
|
||||
OnFetchGameSavList?.Invoke(msg.RomID, savArr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送删除即时存档
|
||||
/// </summary>
|
||||
/// <param name="RomID"></param>
|
||||
/// <param name="SavDataIdx"></param>
|
||||
public void SendDelGameSavList(int RomID, int SavDataIdx)
|
||||
{
|
||||
Protobuf_Mine_DelGameSav req = new Protobuf_Mine_DelGameSav()
|
||||
{
|
||||
RomID = RomID,
|
||||
SavDataIdx = SavDataIdx
|
||||
};
|
||||
App.log.Info($"SendDelGameSavList");
|
||||
App.network.SendToServer((int)CommandID.CmdGamesavDelGameSav, ProtoBufHelper.Serizlize(req));
|
||||
}
|
||||
|
||||
void RecvDelGameSavList(byte[] reqData)
|
||||
{
|
||||
Protobuf_Mine_DelGameSav_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_DelGameSav_RESP>(reqData);
|
||||
Eventer.Instance.PostEvent(EEvent.OnNetGameSavDeleted, msg.RomID, msg.SavDataIdx);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传即时存档
|
||||
/// </summary>
|
||||
/// <param name="RomID"></param>
|
||||
/// <param name="SavDataIdx"></param>
|
||||
public void SendUpLoadGameSav(int RomID, int SavDataIdx, uint sequence, byte[] RawData, byte[] SavImgData)
|
||||
{
|
||||
//压缩
|
||||
byte[] compressRawData = Helper.CompressByteArray(RawData);
|
||||
|
||||
//压缩
|
||||
byte[] compressImgData = Helper.CompressByteArray(SavImgData);
|
||||
|
||||
Protobuf_Mine_UpLoadGameSav req = new Protobuf_Mine_UpLoadGameSav()
|
||||
{
|
||||
RomID = RomID,
|
||||
SavDataIdx = SavDataIdx,
|
||||
StateRaw = Google.Protobuf.ByteString.CopyFrom(compressRawData),
|
||||
if (m_fetchingRomIDs.Remove(msg.RomID)) return;
|
||||
|
||||
Protobuf_Mine_GameSavInfo[] savArr = new Protobuf_Mine_GameSavInfo[4];
|
||||
for (int i = 0; i < savArr.Length; i++)
|
||||
{
|
||||
Protobuf_Mine_GameSavInfo info = msg.SavDataList.FirstOrDefault(w => w.SavDataIdx == i);
|
||||
savArr[i] = info;
|
||||
}
|
||||
OnFetchGameSavList?.Invoke(msg.RomID, savArr);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送删除即时存档
|
||||
/// </summary>
|
||||
/// <param name="RomID"></param>
|
||||
/// <param name="SavDataIdx"></param>
|
||||
public void SendDelGameSavList(int RomID, int SavDataIdx)
|
||||
{
|
||||
Protobuf_Mine_DelGameSav req = new Protobuf_Mine_DelGameSav()
|
||||
{
|
||||
RomID = RomID,
|
||||
SavDataIdx = SavDataIdx
|
||||
};
|
||||
App.log.Info($"SendDelGameSavList");
|
||||
App.network.SendToServer((int)CommandID.CmdGamesavDelGameSav, ProtoBufHelper.Serizlize(req));
|
||||
}
|
||||
|
||||
void RecvDelGameSavList(byte[] reqData)
|
||||
{
|
||||
Protobuf_Mine_DelGameSav_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_DelGameSav_RESP>(reqData);
|
||||
Eventer.Instance.PostEvent(EEvent.OnNetGameSavDeleted, msg.RomID, msg.SavDataIdx);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传即时存档
|
||||
/// </summary>
|
||||
/// <param name="RomID"></param>
|
||||
/// <param name="SavDataIdx"></param>
|
||||
public void SendUpLoadGameSav(int RomID, int SavDataIdx, uint sequence, byte[] RawData, byte[] SavImgData)
|
||||
{
|
||||
//压缩
|
||||
byte[] compressRawData = Helper.CompressByteArray(RawData);
|
||||
|
||||
//压缩
|
||||
byte[] compressImgData = Helper.CompressByteArray(SavImgData);
|
||||
|
||||
Protobuf_Mine_UpLoadGameSav req = new Protobuf_Mine_UpLoadGameSav()
|
||||
{
|
||||
RomID = RomID,
|
||||
SavDataIdx = SavDataIdx,
|
||||
StateRaw = Google.Protobuf.ByteString.CopyFrom(compressRawData),
|
||||
SavImg = Google.Protobuf.ByteString.CopyFrom(compressImgData),
|
||||
Sequence = (int)sequence
|
||||
};
|
||||
|
||||
App.log.Info($"SendDelGameSavList");
|
||||
App.log.Info($"上传即时存档数据 原数据大小:{RawData.Length},压缩后;{compressRawData.Length}");
|
||||
App.log.Info($"上传截图 原数据大小:{SavImgData.Length},压缩后;{compressImgData.Length}");
|
||||
|
||||
App.network.SendToServer((int)CommandID.CmdGamesavUploadGameSav, ProtoBufHelper.Serizlize(req));
|
||||
}
|
||||
|
||||
void RecvUpLoadGameSav(byte[] reqData)
|
||||
{
|
||||
Protobuf_Mine_UpLoadGameSav_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_UpLoadGameSav_RESP>(reqData);
|
||||
OnUploadedSavData?.Invoke(msg.RomID, msg.SavDataIdx, msg.UploadSevInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即时存档或网络截图下载完成之后,需要先解压再使用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] UnGzipData(byte[] data)
|
||||
{
|
||||
return Helper.DecompressByteArray(data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
App.log.Info($"SendDelGameSavList");
|
||||
App.log.Info($"上传即时存档数据 原数据大小:{RawData.Length},压缩后;{compressRawData.Length}");
|
||||
App.log.Info($"上传截图 原数据大小:{SavImgData.Length},压缩后;{compressImgData.Length}");
|
||||
|
||||
App.network.SendToServer((int)CommandID.CmdGamesavUploadGameSav, ProtoBufHelper.Serizlize(req));
|
||||
}
|
||||
|
||||
void RecvUpLoadGameSav(byte[] reqData)
|
||||
{
|
||||
Protobuf_Mine_UpLoadGameSav_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Mine_UpLoadGameSav_RESP>(reqData);
|
||||
OnUploadedSavData?.Invoke(msg.RomID, msg.SavDataIdx, msg.UploadSevInfo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 即时存档或网络截图下载完成之后,需要先解压再使用
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public byte[] UnGzipData(byte[] data)
|
||||
{
|
||||
return Helper.DecompressByteArray(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,6 +172,8 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
public unsafe void Save(uint sequence, byte[] savData, byte[] screenShotData)
|
||||
{
|
||||
if (IsBusy) return;
|
||||
|
||||
var filePath = FilePath;
|
||||
|
||||
var header = new Header
|
||||
|
||||
@ -26,8 +26,8 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
|
||||
m_sequece = (uint)netData.Sequence;
|
||||
m_downloadTask = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavUrl}?v={m_sequece}");
|
||||
m_downloadTaskImg = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavImgUrl}?v={m_sequece}");
|
||||
m_downloadTask = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavUrl}");
|
||||
m_downloadTaskImg = AxiHttpProxy.GetDownLoad($"{App.httpAPI.WebHost}/{netData.SavImgUrl}");
|
||||
|
||||
Host.SetSavingFlag();
|
||||
}
|
||||
@ -52,25 +52,14 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
if (m_downloadTaskImg.downloadHandler.bHadErr) //下载失败
|
||||
{
|
||||
FSM.GetState<SyncFailedState>().Error = m_downloadTaskImg.downloadHandler.ErrInfo;
|
||||
FSM.ChangeState<SyncFailedState>();
|
||||
FSM.ChangeState<IdleState>();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var savData = Host.CloudAPI.UnGzipData(m_downloadTask.downloadHandler.data);
|
||||
var imgData = m_downloadTaskImg.downloadHandler.data; //图片数据已被服务器解压
|
||||
|
||||
Host.Save(m_sequece, savData, imgData);
|
||||
FSM.ChangeState<SyncedState>();
|
||||
}
|
||||
catch
|
||||
{
|
||||
FSM.GetState<SyncFailedState>().Error = "云存档解压失败";
|
||||
FSM.ChangeState<SyncFailedState>();
|
||||
return;
|
||||
}
|
||||
var savData = Host.CloudAPI.UnGzipData(m_downloadTask.downloadHandler.data);
|
||||
var imgData = Host.CloudAPI.UnGzipData(m_downloadTaskImg.downloadHandler.data);
|
||||
Host.Save(m_sequece, savData, imgData);
|
||||
FSM.ChangeState<SyncedState>();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,225 +1,225 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
public class UserDataBase
|
||||
{
|
||||
public long UID { get; set; }
|
||||
public string Account { get; set; }
|
||||
public string NickName { get; set; }
|
||||
}
|
||||
|
||||
public class MainUserDataBase : UserDataBase
|
||||
{
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Common;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Manager
|
||||
{
|
||||
public class UserDataBase
|
||||
{
|
||||
public long UID { get; set; }
|
||||
public string Account { get; set; }
|
||||
public string NickName { get; set; }
|
||||
}
|
||||
|
||||
public class MainUserDataBase : UserDataBase
|
||||
{
|
||||
public bool IsLoggedIn { get; set; } = false;
|
||||
public string Token { get; set; }
|
||||
}
|
||||
|
||||
public class UserDataManager
|
||||
{
|
||||
public UserDataManager()
|
||||
{
|
||||
//注册重连成功事件,以便后续自动登录
|
||||
App.network.OnReConnected += OnReConnected;
|
||||
|
||||
//网络事件注册
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserOnlinelist, RecvUserOnlinelist);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserJoin, RecvCmdUserJoin);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserLeave, RecvGetUserLeave);
|
||||
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdModifyNickName, RecvModifyNickName);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUpdateSelfUserInfo, RecvUpdateSelfUserInfo);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUpdateOtherUserInfo, RecvUpdateOtherUserInfo);
|
||||
}
|
||||
|
||||
public MainUserDataBase userdata { get; private set; } = new MainUserDataBase();
|
||||
public bool IsLoggedIn => userdata.IsLoggedIn;
|
||||
public string Token => userdata.IsLoggedIn ? userdata.Token : string.Empty;
|
||||
Dictionary<long, UserDataBase> DictUID2User = new Dictionary<long, UserDataBase>();
|
||||
public int OnlinePlayerCount => DictUID2User.Count;
|
||||
public void InitMainUserData(string UName, long UID, string token)
|
||||
{
|
||||
userdata.NickName = UName;
|
||||
userdata.IsLoggedIn = true;
|
||||
userdata.UID = UID;
|
||||
}
|
||||
|
||||
public class UserDataManager
|
||||
{
|
||||
public UserDataManager()
|
||||
{
|
||||
//注册重连成功事件,以便后续自动登录
|
||||
App.network.OnReConnected += OnReConnected;
|
||||
|
||||
//网络事件注册
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserOnlinelist, RecvUserOnlinelist);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserJoin, RecvCmdUserJoin);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUserLeave, RecvGetUserLeave);
|
||||
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdModifyNickName, RecvModifyNickName);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUpdateSelfUserInfo, RecvUpdateSelfUserInfo);
|
||||
NetMsg.Instance.RegNetMsgEvent((int)CommandID.CmdUpdateOtherUserInfo, RecvUpdateOtherUserInfo);
|
||||
}
|
||||
|
||||
public MainUserDataBase userdata { get; private set; } = new MainUserDataBase();
|
||||
public bool IsLoggedIn => userdata.IsLoggedIn;
|
||||
public string Token => userdata.IsLoggedIn ? userdata.Token : string.Empty;
|
||||
Dictionary<long, UserDataBase> DictUID2User = new Dictionary<long, UserDataBase>();
|
||||
public int OnlinePlayerCount => DictUID2User.Count;
|
||||
public void InitMainUserData(string UName, long UID, string token)
|
||||
{
|
||||
userdata.NickName = UName;
|
||||
userdata.IsLoggedIn = true;
|
||||
userdata.UID = UID;
|
||||
userdata.Token = token;
|
||||
#if UNITY_EDITOR
|
||||
App.log.Debug($"收到登录token:{token}");
|
||||
#endif
|
||||
#if UNITY_EDITOR
|
||||
App.log.Debug($"收到登录token:{token}");
|
||||
#endif
|
||||
//以及其他数据初始化
|
||||
//...
|
||||
}
|
||||
/// <summary>
|
||||
/// 登出
|
||||
/// </summary>
|
||||
public void LoginOutData()
|
||||
{
|
||||
userdata.IsLoggedIn = false;
|
||||
//以及其他数据清理
|
||||
//...
|
||||
}
|
||||
/// <summary>
|
||||
/// 当重连成功
|
||||
/// </summary>
|
||||
public void OnReConnected()
|
||||
{
|
||||
//如果之前已登录,则重新登录
|
||||
if (userdata.IsLoggedIn)
|
||||
{
|
||||
App.login.Login();
|
||||
}
|
||||
}
|
||||
|
||||
#region 角色管理
|
||||
public void UpdateOrAddUser(UserMiniInfo minfo, out bool isNewUser)
|
||||
{
|
||||
lock (DictUID2User)
|
||||
{
|
||||
if (!DictUID2User.ContainsKey(minfo.UID))
|
||||
{
|
||||
DictUID2User[minfo.UID] = new UserDataBase()
|
||||
{
|
||||
UID = minfo.UID,
|
||||
NickName = minfo.NickName,
|
||||
Account = "",
|
||||
};
|
||||
isNewUser = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isNewUser = false;
|
||||
DictUID2User[minfo.UID].NickName = minfo.NickName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveUser(long UID)
|
||||
{
|
||||
bool bflag = false;
|
||||
string UName = "";
|
||||
lock (DictUID2User)
|
||||
{
|
||||
if (DictUID2User.ContainsKey(UID))
|
||||
{
|
||||
UName = DictUID2User[UID].NickName;
|
||||
DictUID2User.Remove(UID);
|
||||
bflag = true;
|
||||
}
|
||||
}
|
||||
if (bflag)
|
||||
{
|
||||
//抛出用户离开事件
|
||||
Eventer.Instance.PostEvent(EEvent.OnUserLoginOut, UID, UName);
|
||||
}
|
||||
}
|
||||
public UserDataBase GetUserByUid(long UID)
|
||||
{
|
||||
lock (DictUID2User)
|
||||
{
|
||||
if (DictUID2User.ContainsKey(UID))
|
||||
{
|
||||
return DictUID2User[UID];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public UserDataBase[] GetUserList()
|
||||
{
|
||||
UserDataBase[] ulist = new UserDataBase[DictUID2User.Count];
|
||||
long[] UIDs = DictUID2User.Keys.ToArray();
|
||||
for (int i = 0; i < UIDs.Length; i++)
|
||||
{
|
||||
ulist[i] = DictUID2User[UIDs[i]];
|
||||
}
|
||||
return ulist;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 请求拉取房间列表
|
||||
/// </summary>
|
||||
public void Send_GetUserList()
|
||||
{
|
||||
Protobuf_UserList msg = new Protobuf_UserList()
|
||||
{
|
||||
};
|
||||
App.network.SendToServer((int)CommandID.CmdUserOnlinelist, ProtoBufHelper.Serizlize(msg));
|
||||
}
|
||||
|
||||
public void RecvUserOnlinelist(byte[] reqData)
|
||||
{
|
||||
Protobuf_UserList_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserList_RESP>(reqData);
|
||||
DictUID2User.Clear();
|
||||
for (int i = 0; i < msg.UserList.Count; i++)
|
||||
{
|
||||
UserMiniInfo mi = msg.UserList[i];
|
||||
bool isNewUser;
|
||||
UpdateOrAddUser(mi, out isNewUser);
|
||||
}
|
||||
Eventer.Instance.PostEvent(EEvent.OnUserListAllUpdate);
|
||||
}
|
||||
public void RecvCmdUserJoin(byte[] reqData)
|
||||
{
|
||||
Protobuf_UserJoin_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserJoin_RESP>(reqData);
|
||||
bool isNewUser;
|
||||
UpdateOrAddUser(msg.UserInfo, out isNewUser);
|
||||
if (isNewUser)
|
||||
}
|
||||
/// <summary>
|
||||
/// 登出
|
||||
/// </summary>
|
||||
public void LoginOutData()
|
||||
{
|
||||
userdata.IsLoggedIn = false;
|
||||
//以及其他数据清理
|
||||
//...
|
||||
}
|
||||
/// <summary>
|
||||
/// 当重连成功
|
||||
/// </summary>
|
||||
public void OnReConnected()
|
||||
{
|
||||
//如果之前已登录,则重新登录
|
||||
if (userdata.IsLoggedIn)
|
||||
{
|
||||
Eventer.Instance.PostEvent(EEvent.OnUserLogin, msg.UserInfo.UID, msg.UserInfo.NickName);
|
||||
OverlayManager.PopTip($"玩家[{msg.UserInfo.NickName}]上线了");
|
||||
}
|
||||
}
|
||||
|
||||
public void RecvGetUserLeave(byte[] reqData)
|
||||
{
|
||||
Protobuf_UserLeave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserLeave_RESP>(reqData);
|
||||
RemoveUser(msg.UID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送修改昵称请求
|
||||
/// </summary>
|
||||
/// <param name="NickName"></param>
|
||||
public void Send_ModifyNickName(string NickName)
|
||||
{
|
||||
Protobuf_Modify_NickName msg = new Protobuf_Modify_NickName()
|
||||
{
|
||||
NickName = NickName
|
||||
};
|
||||
App.network.SendToServer((int)CommandID.CmdModifyNickName, ProtoBufHelper.Serizlize(msg));
|
||||
}
|
||||
|
||||
void RecvModifyNickName(byte[] reqData)
|
||||
{
|
||||
Protobuf_Modify_NickName_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Modify_NickName_RESP>(reqData);
|
||||
}
|
||||
|
||||
private void RecvUpdateSelfUserInfo(byte[] reqData)
|
||||
{
|
||||
Protobuf_Update_UserInfo_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Update_UserInfo_RESP>(reqData);
|
||||
userdata.NickName = msg.UserInfo.NickName;
|
||||
Eventer.Instance.PostEvent(EEvent.OnSelfInfoUpdate);
|
||||
}
|
||||
|
||||
private void RecvUpdateOtherUserInfo(byte[] reqData)
|
||||
{
|
||||
Protobuf_Update_OtherUserInfo_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Update_OtherUserInfo_RESP>(reqData);
|
||||
UserDataBase userdata = GetUserByUid(msg.UID);
|
||||
if (userdata == null)
|
||||
return;
|
||||
userdata.NickName = msg.UserInfo.NickName;
|
||||
|
||||
App.roomMgr.ChangeCurrRoomPlayerName(msg.UID);
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnOtherUserInfoUpdate, msg.UID);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
App.login.Login();
|
||||
}
|
||||
}
|
||||
|
||||
#region 角色管理
|
||||
public void UpdateOrAddUser(UserMiniInfo minfo, out bool isNewUser)
|
||||
{
|
||||
lock (DictUID2User)
|
||||
{
|
||||
if (!DictUID2User.ContainsKey(minfo.UID))
|
||||
{
|
||||
DictUID2User[minfo.UID] = new UserDataBase()
|
||||
{
|
||||
UID = minfo.UID,
|
||||
NickName = minfo.NickName,
|
||||
Account = "",
|
||||
};
|
||||
isNewUser = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
isNewUser = false;
|
||||
DictUID2User[minfo.UID].NickName = minfo.NickName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveUser(long UID)
|
||||
{
|
||||
bool bflag = false;
|
||||
string UName = "";
|
||||
lock (DictUID2User)
|
||||
{
|
||||
if (DictUID2User.ContainsKey(UID))
|
||||
{
|
||||
UName = DictUID2User[UID].NickName;
|
||||
DictUID2User.Remove(UID);
|
||||
bflag = true;
|
||||
}
|
||||
}
|
||||
if (bflag)
|
||||
{
|
||||
//抛出用户离开事件
|
||||
Eventer.Instance.PostEvent(EEvent.OnUserLoginOut, UID, UName);
|
||||
}
|
||||
}
|
||||
public UserDataBase GetUserByUid(long UID)
|
||||
{
|
||||
lock (DictUID2User)
|
||||
{
|
||||
if (DictUID2User.ContainsKey(UID))
|
||||
{
|
||||
return DictUID2User[UID];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public UserDataBase[] GetUserList()
|
||||
{
|
||||
UserDataBase[] ulist = new UserDataBase[DictUID2User.Count];
|
||||
long[] UIDs = DictUID2User.Keys.ToArray();
|
||||
for (int i = 0; i < UIDs.Length; i++)
|
||||
{
|
||||
ulist[i] = DictUID2User[UIDs[i]];
|
||||
}
|
||||
return ulist;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 请求拉取房间列表
|
||||
/// </summary>
|
||||
public void Send_GetUserList()
|
||||
{
|
||||
Protobuf_UserList msg = new Protobuf_UserList()
|
||||
{
|
||||
};
|
||||
App.network.SendToServer((int)CommandID.CmdUserOnlinelist, ProtoBufHelper.Serizlize(msg));
|
||||
}
|
||||
|
||||
public void RecvUserOnlinelist(byte[] reqData)
|
||||
{
|
||||
Protobuf_UserList_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserList_RESP>(reqData);
|
||||
DictUID2User.Clear();
|
||||
for (int i = 0; i < msg.UserList.Count; i++)
|
||||
{
|
||||
UserMiniInfo mi = msg.UserList[i];
|
||||
bool isNewUser;
|
||||
UpdateOrAddUser(mi, out isNewUser);
|
||||
}
|
||||
Eventer.Instance.PostEvent(EEvent.OnUserListAllUpdate);
|
||||
}
|
||||
public void RecvCmdUserJoin(byte[] reqData)
|
||||
{
|
||||
Protobuf_UserJoin_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserJoin_RESP>(reqData);
|
||||
bool isNewUser;
|
||||
UpdateOrAddUser(msg.UserInfo, out isNewUser);
|
||||
if (isNewUser)
|
||||
{
|
||||
Eventer.Instance.PostEvent(EEvent.OnUserLogin, msg.UserInfo.UID, msg.UserInfo.NickName);
|
||||
OverlayManager.PopTip($"玩家[{msg.UserInfo.NickName}]上线了");
|
||||
}
|
||||
}
|
||||
|
||||
public void RecvGetUserLeave(byte[] reqData)
|
||||
{
|
||||
Protobuf_UserLeave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_UserLeave_RESP>(reqData);
|
||||
RemoveUser(msg.UID);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 发送修改昵称请求
|
||||
/// </summary>
|
||||
/// <param name="NickName"></param>
|
||||
public void Send_ModifyNickName(string NickName)
|
||||
{
|
||||
Protobuf_Modify_NickName msg = new Protobuf_Modify_NickName()
|
||||
{
|
||||
NickName = NickName
|
||||
};
|
||||
App.network.SendToServer((int)CommandID.CmdModifyNickName, ProtoBufHelper.Serizlize(msg));
|
||||
}
|
||||
|
||||
void RecvModifyNickName(byte[] reqData)
|
||||
{
|
||||
Protobuf_Modify_NickName_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Modify_NickName_RESP>(reqData);
|
||||
}
|
||||
|
||||
private void RecvUpdateSelfUserInfo(byte[] reqData)
|
||||
{
|
||||
Protobuf_Update_UserInfo_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Update_UserInfo_RESP>(reqData);
|
||||
userdata.NickName = msg.UserInfo.NickName;
|
||||
Eventer.Instance.PostEvent(EEvent.OnSelfInfoUpdate);
|
||||
}
|
||||
|
||||
private void RecvUpdateOtherUserInfo(byte[] reqData)
|
||||
{
|
||||
Protobuf_Update_OtherUserInfo_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Update_OtherUserInfo_RESP>(reqData);
|
||||
UserDataBase userdata = GetUserByUid(msg.UID);
|
||||
if (userdata == null)
|
||||
return;
|
||||
userdata.NickName = msg.UserInfo.NickName;
|
||||
|
||||
App.roomMgr.ChangeCurrRoomPlayerName(msg.UID);
|
||||
|
||||
Eventer.Instance.PostEvent(EEvent.OnOtherUserInfoUpdate, msg.UID);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,39 +1,39 @@
|
||||
/// <summary>
|
||||
/// String和Bool的缝合怪
|
||||
/// </summary>
|
||||
public struct MsgBool
|
||||
{
|
||||
public string ErrorMsg;
|
||||
/// <summary>
|
||||
/// String和Bool的缝合怪
|
||||
/// </summary>
|
||||
public struct MsgBool
|
||||
{
|
||||
public string ErrorMsg;
|
||||
public bool Value;
|
||||
|
||||
//low C# readonly
|
||||
//public override readonly string ToString()
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value)
|
||||
{
|
||||
return true.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ErrorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator MsgBool(string errorMsg)
|
||||
{
|
||||
return new MsgBool { Value = false, ErrorMsg = errorMsg };
|
||||
}
|
||||
|
||||
public static implicit operator MsgBool(bool value)
|
||||
{
|
||||
return new MsgBool { Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator bool(MsgBool msgBool)
|
||||
{
|
||||
return msgBool.Value;
|
||||
public override string ToString()
|
||||
{
|
||||
if (Value)
|
||||
{
|
||||
return true.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return ErrorMsg;
|
||||
}
|
||||
}
|
||||
|
||||
public static implicit operator MsgBool(string errorMsg)
|
||||
{
|
||||
return new MsgBool { Value = false, ErrorMsg = errorMsg };
|
||||
}
|
||||
|
||||
public static implicit operator MsgBool(bool value)
|
||||
{
|
||||
return new MsgBool { Value = value };
|
||||
}
|
||||
|
||||
public static implicit operator bool(MsgBool msgBool)
|
||||
{
|
||||
return msgBool.Value;
|
||||
}
|
||||
|
||||
//low C#
|
||||
@ -42,8 +42,8 @@ public struct MsgBool
|
||||
// return (msgBool.Value, msgBool.ErrorMsg);
|
||||
//}
|
||||
|
||||
public static implicit operator string(MsgBool msgBool)
|
||||
{
|
||||
return msgBool.ToString();
|
||||
}
|
||||
}
|
||||
public static implicit operator string(MsgBool msgBool)
|
||||
{
|
||||
return msgBool.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,102 +1,102 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client.Network
|
||||
{
|
||||
|
||||
public class NetMsg
|
||||
{
|
||||
private static NetMsg instance = new NetMsg();
|
||||
public static NetMsg Instance { get { return instance; } }
|
||||
|
||||
private Dictionary<int, List<Delegate>> netEventDic = new Dictionary<int, List<Delegate>>(128);
|
||||
|
||||
private Queue<ValueTuple<int, int, byte[]>> queueNetMsg = new Queue<ValueTuple<int, int, byte[]>>();
|
||||
public static object lockQueueNetMsg = new object();
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
private Queue<Action> queueEventFromNet = new Queue<Action>();
|
||||
namespace AxibugEmuOnline.Client.Network
|
||||
{
|
||||
|
||||
public class NetMsg
|
||||
{
|
||||
private static NetMsg instance = new NetMsg();
|
||||
public static NetMsg Instance { get { return instance; } }
|
||||
|
||||
private Dictionary<int, List<Delegate>> netEventDic = new Dictionary<int, List<Delegate>>(128);
|
||||
|
||||
private Queue<ValueTuple<int, int, byte[]>> queueNetMsg = new Queue<ValueTuple<int, int, byte[]>>();
|
||||
public static object lockQueueNetMsg = new object();
|
||||
|
||||
private Queue<Action> queueEventFromNet = new Queue<Action>();
|
||||
public static object lockQueueEventFromNet = new object();
|
||||
|
||||
|
||||
private NetMsg() { }
|
||||
|
||||
|
||||
|
||||
#region RegisterMsgEvent
|
||||
|
||||
public void RegNetMsgEvent(int cmd, Action<byte[]> callback)
|
||||
{
|
||||
InterRegNetMsgEvent(cmd, callback);
|
||||
}
|
||||
|
||||
private void InterRegNetMsgEvent(int cmd, Delegate callback)
|
||||
{
|
||||
if (netEventDic.ContainsKey(cmd))
|
||||
{
|
||||
if (netEventDic[cmd].IndexOf(callback) < 0)
|
||||
{
|
||||
netEventDic[cmd].Add(callback);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
netEventDic.Add(cmd, new List<Delegate>() { callback });
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UnregisterCMD
|
||||
|
||||
public void UnregisterCMD(int evt, Action<byte[]> callback)
|
||||
{
|
||||
Delegate tempDelegate = callback;
|
||||
InterUnregisterCMD(evt, tempDelegate);
|
||||
}
|
||||
|
||||
private void InterUnregisterCMD(int cmd, Delegate callback)
|
||||
{
|
||||
if (netEventDic.ContainsKey(cmd))
|
||||
{
|
||||
netEventDic[cmd].Remove(callback);
|
||||
if (netEventDic[cmd].Count == 0) netEventDic.Remove(cmd);
|
||||
}
|
||||
|
||||
|
||||
private NetMsg() { }
|
||||
|
||||
|
||||
|
||||
#region RegisterMsgEvent
|
||||
|
||||
public void RegNetMsgEvent(int cmd, Action<byte[]> callback)
|
||||
{
|
||||
InterRegNetMsgEvent(cmd, callback);
|
||||
}
|
||||
#endregion
|
||||
|
||||
private void InterRegNetMsgEvent(int cmd, Delegate callback)
|
||||
{
|
||||
if (netEventDic.ContainsKey(cmd))
|
||||
{
|
||||
if (netEventDic[cmd].IndexOf(callback) < 0)
|
||||
{
|
||||
netEventDic[cmd].Add(callback);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
netEventDic.Add(cmd, new List<Delegate>() { callback });
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UnregisterCMD
|
||||
|
||||
public void UnregisterCMD(int evt, Action<byte[]> callback)
|
||||
{
|
||||
Delegate tempDelegate = callback;
|
||||
InterUnregisterCMD(evt, tempDelegate);
|
||||
}
|
||||
|
||||
private void InterUnregisterCMD(int cmd, Delegate callback)
|
||||
{
|
||||
if (netEventDic.ContainsKey(cmd))
|
||||
{
|
||||
netEventDic[cmd].Remove(callback);
|
||||
if (netEventDic[cmd].Count == 0) netEventDic.Remove(cmd);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
public void NextNetEvent()
|
||||
{
|
||||
DequeueNesMsg();
|
||||
DequeueEventFromNet();
|
||||
{
|
||||
DequeueNesMsg();
|
||||
DequeueEventFromNet();
|
||||
}
|
||||
|
||||
#region PostEventFromNet
|
||||
|
||||
public void EnqueueEventFromNet(Action act)
|
||||
{
|
||||
lock (lockQueueEventFromNet)
|
||||
{
|
||||
queueEventFromNet.Enqueue(act);
|
||||
}
|
||||
}
|
||||
|
||||
public void DequeueEventFromNet()
|
||||
{
|
||||
lock (lockQueueEventFromNet)
|
||||
{
|
||||
while (queueEventFromNet.Count > 0)
|
||||
#region PostEventFromNet
|
||||
|
||||
public void EnqueueEventFromNet(Action act)
|
||||
{
|
||||
lock (lockQueueEventFromNet)
|
||||
{
|
||||
queueEventFromNet.Enqueue(act);
|
||||
}
|
||||
}
|
||||
|
||||
public void DequeueEventFromNet()
|
||||
{
|
||||
lock (lockQueueEventFromNet)
|
||||
{
|
||||
while (queueEventFromNet.Count > 0)
|
||||
{
|
||||
var msgData = queueEventFromNet.Dequeue();
|
||||
PostNetEventFromNet(msgData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostNetEventFromNet(Action act)
|
||||
var msgData = queueEventFromNet.Dequeue();
|
||||
PostNetEventFromNet(msgData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PostNetEventFromNet(Action act)
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -106,73 +106,73 @@ namespace AxibugEmuOnline.Client.Network
|
||||
{
|
||||
App.log.Error(ex.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PostNetMsg
|
||||
|
||||
public void EnqueueNetMsg(int cmd, int ERRCODE, byte[] arg)
|
||||
{
|
||||
lock (lockQueueNetMsg)
|
||||
{
|
||||
queueNetMsg.Enqueue(new ValueTuple<int, int, byte[]>(cmd, ERRCODE, arg));
|
||||
}
|
||||
}
|
||||
|
||||
public void DequeueNesMsg()
|
||||
{
|
||||
lock (lockQueueNetMsg)
|
||||
{
|
||||
while (queueNetMsg.Count > 0)
|
||||
#region PostNetMsg
|
||||
|
||||
public void EnqueueNetMsg(int cmd, int ERRCODE, byte[] arg)
|
||||
{
|
||||
lock (lockQueueNetMsg)
|
||||
{
|
||||
queueNetMsg.Enqueue(new ValueTuple<int, int, byte[]>(cmd, ERRCODE, arg));
|
||||
}
|
||||
}
|
||||
|
||||
public void DequeueNesMsg()
|
||||
{
|
||||
lock (lockQueueNetMsg)
|
||||
{
|
||||
while (queueNetMsg.Count > 0)
|
||||
{
|
||||
var msgData = queueNetMsg.Dequeue();
|
||||
PostNetMsgEvent(msgData.Item1, msgData.Item2, msgData.Item3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostNetMsgEvent(int cmd, int ERRCODE, byte[] arg)
|
||||
{
|
||||
ErrorCode err = ((ErrorCode)ERRCODE);
|
||||
if (err != ErrorCode.ErrorOk)
|
||||
{
|
||||
OverlayManager.PopTip("错误:" + err.ToString());
|
||||
}
|
||||
|
||||
List<Delegate> eventList = GetNetEventDicList(cmd);
|
||||
if (eventList != null)
|
||||
{
|
||||
foreach (Delegate callback in eventList)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Action<byte[]>)callback)(arg);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.log.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有事件
|
||||
/// </summary>
|
||||
/// <param name="cmd"></param>
|
||||
/// <returns></returns>
|
||||
private List<Delegate> GetNetEventDicList(int cmd)
|
||||
{
|
||||
if (netEventDic.ContainsKey(cmd))
|
||||
{
|
||||
List<Delegate> tempList = netEventDic[cmd];
|
||||
if (null != tempList)
|
||||
{
|
||||
return tempList;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
var msgData = queueNetMsg.Dequeue();
|
||||
PostNetMsgEvent(msgData.Item1, msgData.Item2, msgData.Item3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void PostNetMsgEvent(int cmd, int ERRCODE, byte[] arg)
|
||||
{
|
||||
ErrorCode err = ((ErrorCode)ERRCODE);
|
||||
if (err != ErrorCode.ErrorOk)
|
||||
{
|
||||
OverlayManager.PopTip("错误:" + err.ToString());
|
||||
}
|
||||
|
||||
List<Delegate> eventList = GetNetEventDicList(cmd);
|
||||
if (eventList != null)
|
||||
{
|
||||
foreach (Delegate callback in eventList)
|
||||
{
|
||||
try
|
||||
{
|
||||
((Action<byte[]>)callback)(arg);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
App.log.Error(e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有事件
|
||||
/// </summary>
|
||||
/// <param name="cmd"></param>
|
||||
/// <returns></returns>
|
||||
private List<Delegate> GetNetEventDicList(int cmd)
|
||||
{
|
||||
if (netEventDic.ContainsKey(cmd))
|
||||
{
|
||||
List<Delegate> tempList = netEventDic[cmd];
|
||||
if (null != tempList)
|
||||
{
|
||||
return tempList;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using UnityEngine;
|
||||
public class SwitchCommon : MonoBehaviour
|
||||
{
|
||||
void Start()
|
||||
{
|
||||
Debug.Log("SwitchCommon Start");
|
||||
TickLoop.LoopAction_15s += ApplyCommit;
|
||||
}
|
||||
|
||||
|
||||
@ -1,35 +1,35 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class ScreenScalerListMenuItem : VirtualSubMenuItem
|
||||
{
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
App.settings.Filter.EnableFilterPreview();
|
||||
|
||||
return base.OnEnterItem();
|
||||
}
|
||||
|
||||
public override bool OnExitItem()
|
||||
{
|
||||
App.settings.Filter.ShutDownFilterPreview();
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class ScreenScalerListMenuItem : VirtualSubMenuItem
|
||||
{
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
App.settings.Filter.EnableFilterPreview();
|
||||
|
||||
return base.OnEnterItem();
|
||||
}
|
||||
|
||||
public override bool OnExitItem()
|
||||
{
|
||||
App.settings.Filter.ShutDownFilterPreview();
|
||||
|
||||
return base.OnExitItem();
|
||||
}
|
||||
|
||||
protected override void GetVirtualListDatas(VirtualListDataHandle callback)
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
}
|
||||
|
||||
protected override void GetVirtualListDatas(VirtualListDataHandle callback)
|
||||
{
|
||||
List<object> list = new List<object>();
|
||||
foreach (var enumValue in Enum.GetValues(typeof(ScreenScaler.EnumScalerMode))) list.Add(enumValue);
|
||||
|
||||
var select = list.IndexOf(App.settings.ScreenScaler.GlobalMode);
|
||||
if (select == -1) select = 0;
|
||||
|
||||
callback.Invoke(list, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
callback.Invoke(list, select);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,104 +1,104 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 背景颜色设置UI
|
||||
/// </summary>
|
||||
public class UI_BgSettingItem_Color : MenuItem, IVirtualItem
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public BgColorSettings Datacontext { get; private set; }
|
||||
|
||||
public void SetData(object data)
|
||||
{
|
||||
Datacontext = (BgColorSettings)data;
|
||||
Datacontext.OnColorChanged += Setting_OnColorChanged;
|
||||
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void Setting_OnColorChanged(XMBColor color)
|
||||
{
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
var color = Datacontext.CurrentColor;
|
||||
Icon.GetMaterial().SetColor("_Color1", color.color1);
|
||||
Icon.GetMaterial().SetColor("_Color2", color.color2);
|
||||
SetBaseInfo("主题色", "设置主题色", color.Name);
|
||||
}
|
||||
|
||||
public void SetDependencyProperty(object data)
|
||||
{
|
||||
SetSelectState(data is ThirdMenuRoot && ((ThirdMenuRoot)data).SelectIndex == Index);
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
Datacontext.OnColorChanged -= Setting_OnColorChanged;
|
||||
}
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
var options = Datacontext.Presets.Select(preset => new ColorOption(preset)).ToList();
|
||||
var currentColor = Datacontext.CurrentColor;
|
||||
var index = options.FindIndex(op => op.Color.GetHashCode() == currentColor.GetHashCode());
|
||||
OverlayManager.PopSideBar(options, Mathf.Clamp(index, 0, options.Count - 1));
|
||||
return false;
|
||||
}
|
||||
|
||||
public class ColorOption : ExecuteMenu
|
||||
{
|
||||
public XMBColor Color;
|
||||
public override string Name => Color.Name;
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 背景颜色设置UI
|
||||
/// </summary>
|
||||
public class UI_BgSettingItem_Color : MenuItem, IVirtualItem
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public BgColorSettings Datacontext { get; private set; }
|
||||
|
||||
public void SetData(object data)
|
||||
{
|
||||
Datacontext = (BgColorSettings)data;
|
||||
Datacontext.OnColorChanged += Setting_OnColorChanged;
|
||||
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void Setting_OnColorChanged(XMBColor color)
|
||||
{
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
var color = Datacontext.CurrentColor;
|
||||
Icon.GetMaterial().SetColor("_Color1", color.color1);
|
||||
Icon.GetMaterial().SetColor("_Color2", color.color2);
|
||||
SetBaseInfo("主题色", "设置主题色", color.Name);
|
||||
}
|
||||
|
||||
public void SetDependencyProperty(object data)
|
||||
{
|
||||
SetSelectState(data is ThirdMenuRoot && ((ThirdMenuRoot)data).SelectIndex == Index);
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
Datacontext.OnColorChanged -= Setting_OnColorChanged;
|
||||
}
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
var options = Datacontext.Presets.Select(preset => new ColorOption(preset)).ToList();
|
||||
var currentColor = Datacontext.CurrentColor;
|
||||
var index = options.FindIndex(op => op.Color.GetHashCode() == currentColor.GetHashCode());
|
||||
OverlayManager.PopSideBar(options, Mathf.Clamp(index, 0, options.Count - 1));
|
||||
return false;
|
||||
}
|
||||
|
||||
public class ColorOption : ExecuteMenu
|
||||
{
|
||||
public XMBColor Color;
|
||||
public override string Name => Color.Name;
|
||||
|
||||
public ColorOption(XMBColor color)
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public override void OnShow(OptionUI_MenuItem ui)
|
||||
{
|
||||
ui.IconUI.gameObject.SetActiveEx(true);
|
||||
ui.IconUI.SetMaterial(Resources.Load<Material>("Materials/XMBBackGroundPreview"));
|
||||
ui.IconUI.GetMaterial().SetColor("_Color1", Color.color1);
|
||||
ui.IconUI.GetMaterial().SetColor("_Color2", Color.color2);
|
||||
}
|
||||
|
||||
private static TweenerCore<float, float, FloatOptions> s_colorChangeTween;
|
||||
public override void OnFocus()
|
||||
{
|
||||
float progress = 0;
|
||||
XMBColor start = App.settings.BgColor.CurrentColor;
|
||||
XMBColor endColor = Color;
|
||||
|
||||
if (s_colorChangeTween != null)
|
||||
{
|
||||
s_colorChangeTween.Kill();
|
||||
s_colorChangeTween = null;
|
||||
}
|
||||
s_colorChangeTween = DOTween.To(() => progress, (x) =>
|
||||
{
|
||||
progress = x;
|
||||
var lerpColor = XMBColor.Lerp(start, endColor, x);
|
||||
App.settings.BgColor.CurrentColor = lerpColor;
|
||||
}, 1, 1f).SetEase(Ease.OutCubic);
|
||||
s_colorChangeTween.onComplete = () =>
|
||||
{
|
||||
s_colorChangeTween = null;
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
Color = color;
|
||||
}
|
||||
|
||||
public override void OnShow(OptionUI_MenuItem ui)
|
||||
{
|
||||
ui.IconUI.gameObject.SetActiveEx(true);
|
||||
ui.IconUI.SetMaterial(Resources.Load<Material>("Materials/XMBBackGroundPreview"));
|
||||
ui.IconUI.GetMaterial().SetColor("_Color1", Color.color1);
|
||||
ui.IconUI.GetMaterial().SetColor("_Color2", Color.color2);
|
||||
}
|
||||
|
||||
private static TweenerCore<float, float, FloatOptions> s_colorChangeTween;
|
||||
public override void OnFocus()
|
||||
{
|
||||
float progress = 0;
|
||||
XMBColor start = App.settings.BgColor.CurrentColor;
|
||||
XMBColor endColor = Color;
|
||||
|
||||
if (s_colorChangeTween != null)
|
||||
{
|
||||
s_colorChangeTween.Kill();
|
||||
s_colorChangeTween = null;
|
||||
}
|
||||
s_colorChangeTween = DOTween.To(() => progress, (x) =>
|
||||
{
|
||||
progress = x;
|
||||
var lerpColor = XMBColor.Lerp(start, endColor, x);
|
||||
App.settings.BgColor.CurrentColor = lerpColor;
|
||||
}, 1, 1f).SetEase(Ease.OutCubic);
|
||||
s_colorChangeTween.onComplete = () =>
|
||||
{
|
||||
s_colorChangeTween = null;
|
||||
};
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using static AxibugEmuOnline.Client.Settings.FilterManager;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using static AxibugEmuOnline.Client.Settings.FilterManager;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 滤镜预览UI
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 滤镜预览UI
|
||||
/// </summary>
|
||||
public class UI_FilterItem : MenuItem, IVirtualItem
|
||||
{
|
||||
public int Index { get; set; }
|
||||
@ -199,5 +199,5 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Settings;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 画面比例模式选项UI
|
||||
/// </summary>
|
||||
/// <summary>
|
||||
/// 画面比例模式选项UI
|
||||
/// </summary>
|
||||
public class UI_ScalerModeItem : MenuItem, IVirtualItem
|
||||
{
|
||||
public int Index { get; set; }
|
||||
@ -52,5 +52,5 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,118 +1,118 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CommandDispatcher : MonoBehaviour
|
||||
{
|
||||
public static CommandDispatcher Instance { get; private set; }
|
||||
|
||||
/// <summary> 平级注册对象,都会响应指令 </summary>
|
||||
List<CommandExecuter> m_register = new List<CommandExecuter>();
|
||||
/// <summary> 独占注册对象,指令会被列表中最后一个对象独占 </summary>
|
||||
List<CommandExecuter> m_registerHigh = new List<CommandExecuter>();
|
||||
|
||||
CommandListener m_listener;
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CommandDispatcher : MonoBehaviour
|
||||
{
|
||||
public static CommandDispatcher Instance { get; private set; }
|
||||
|
||||
/// <summary> 平级注册对象,都会响应指令 </summary>
|
||||
List<CommandExecuter> m_register = new List<CommandExecuter>();
|
||||
/// <summary> 独占注册对象,指令会被列表中最后一个对象独占 </summary>
|
||||
List<CommandExecuter> m_registerHigh = new List<CommandExecuter>();
|
||||
|
||||
CommandListener m_listener;
|
||||
|
||||
CommandListener.ScheduleType? m_waitMapperSetting = null;
|
||||
public CommandListener.ScheduleType Mode
|
||||
{
|
||||
get => m_listener.Schedule;
|
||||
set => m_waitMapperSetting = value;
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
//初始化command监视器
|
||||
m_listener = new CommandListener();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
public bool IsRegisted(CommandExecuter commandExecuter)
|
||||
{
|
||||
return m_register.Contains(commandExecuter) || m_registerHigh.Contains(commandExecuter);
|
||||
}
|
||||
|
||||
public void RegistController(CommandExecuter controller)
|
||||
{
|
||||
if (!controller.AloneMode)
|
||||
{
|
||||
if (m_register.Contains(controller)) { return; }
|
||||
|
||||
m_register.Add(controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_registerHigh.Contains(controller)) { return; }
|
||||
|
||||
m_registerHigh.Add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnRegistController(CommandExecuter menuItemController)
|
||||
{
|
||||
if (!menuItemController.AloneMode)
|
||||
m_register.Remove(menuItemController);
|
||||
else
|
||||
m_registerHigh.Remove(menuItemController);
|
||||
}
|
||||
|
||||
readonly List<CommandExecuter> oneFrameRegister = new List<CommandExecuter>();
|
||||
private void Update()
|
||||
{
|
||||
if (!InputUI.IsInputing)
|
||||
{
|
||||
peekRegister(oneFrameRegister);
|
||||
m_listener.Update(oneFrameRegister);
|
||||
}
|
||||
|
||||
//键位映射在按键响应的堆栈结束后处理,防止迭代器修改问题
|
||||
if (m_waitMapperSetting != null)
|
||||
{
|
||||
m_listener.Schedule = m_waitMapperSetting.Value;
|
||||
m_waitMapperSetting = null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<CommandExecuter> peekRegister(List<CommandExecuter> results)
|
||||
{
|
||||
results.Clear();
|
||||
|
||||
if (m_registerHigh.Count > 0)
|
||||
{
|
||||
for (int i = m_registerHigh.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var controller = m_registerHigh[i];
|
||||
if (controller.Enable)
|
||||
{
|
||||
results.Add(controller);
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var controller in m_register)
|
||||
{
|
||||
if (!controller.Enable) continue;
|
||||
|
||||
results.Add(controller);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public void GetRegisters(out IReadOnlyList<CommandExecuter> normal, out IReadOnlyList<CommandExecuter> alone)
|
||||
{
|
||||
normal = m_register;
|
||||
alone = m_registerHigh;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
|
||||
//初始化command监视器
|
||||
m_listener = new CommandListener();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
}
|
||||
|
||||
public bool IsRegisted(CommandExecuter commandExecuter)
|
||||
{
|
||||
return m_register.Contains(commandExecuter) || m_registerHigh.Contains(commandExecuter);
|
||||
}
|
||||
|
||||
public void RegistController(CommandExecuter controller)
|
||||
{
|
||||
if (!controller.AloneMode)
|
||||
{
|
||||
if (m_register.Contains(controller)) { return; }
|
||||
|
||||
m_register.Add(controller);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_registerHigh.Contains(controller)) { return; }
|
||||
|
||||
m_registerHigh.Add(controller);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnRegistController(CommandExecuter menuItemController)
|
||||
{
|
||||
if (!menuItemController.AloneMode)
|
||||
m_register.Remove(menuItemController);
|
||||
else
|
||||
m_registerHigh.Remove(menuItemController);
|
||||
}
|
||||
|
||||
readonly List<CommandExecuter> oneFrameRegister = new List<CommandExecuter>();
|
||||
private void Update()
|
||||
{
|
||||
if (!InputUI.IsInputing)
|
||||
{
|
||||
peekRegister(oneFrameRegister);
|
||||
m_listener.Update(oneFrameRegister);
|
||||
}
|
||||
|
||||
//键位映射在按键响应的堆栈结束后处理,防止迭代器修改问题
|
||||
if (m_waitMapperSetting != null)
|
||||
{
|
||||
m_listener.Schedule = m_waitMapperSetting.Value;
|
||||
m_waitMapperSetting = null;
|
||||
}
|
||||
}
|
||||
|
||||
private List<CommandExecuter> peekRegister(List<CommandExecuter> results)
|
||||
{
|
||||
results.Clear();
|
||||
|
||||
if (m_registerHigh.Count > 0)
|
||||
{
|
||||
for (int i = m_registerHigh.Count - 1; i >= 0; i--)
|
||||
{
|
||||
var controller = m_registerHigh[i];
|
||||
if (controller.Enable)
|
||||
{
|
||||
results.Add(controller);
|
||||
return results;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var controller in m_register)
|
||||
{
|
||||
if (!controller.Enable) continue;
|
||||
|
||||
results.Add(controller);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
public void GetRegisters(out IReadOnlyList<CommandExecuter> normal, out IReadOnlyList<CommandExecuter> alone)
|
||||
{
|
||||
normal = m_register;
|
||||
alone = m_registerHigh;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CommandListener
|
||||
{
|
||||
EnumCommand[] m_checkCmds;
|
||||
List<CommandState> m_commands = new List<CommandState>();
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class CommandListener
|
||||
{
|
||||
EnumCommand[] m_checkCmds;
|
||||
List<CommandState> m_commands = new List<CommandState>();
|
||||
long CheckFrame = -1;
|
||||
XMBKeyBinding m_keyBinder;
|
||||
public ScheduleType Schedule { get; set; }
|
||||
@ -17,16 +17,16 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
m_keyBinder = App.settings.KeyMapper.GetBinder<XMBKeyBinding>();
|
||||
m_checkCmds = Enum.GetValues(typeof(EnumCommand)) as EnumCommand[];
|
||||
}
|
||||
|
||||
IEnumerable<CommandState> GetCommand()
|
||||
{
|
||||
if (CheckFrame == Time.frameCount)
|
||||
return m_commands;
|
||||
CheckFrame = Time.frameCount;
|
||||
|
||||
m_commands.Clear();
|
||||
|
||||
}
|
||||
|
||||
IEnumerable<CommandState> GetCommand()
|
||||
{
|
||||
if (CheckFrame == Time.frameCount)
|
||||
return m_commands;
|
||||
CheckFrame = Time.frameCount;
|
||||
|
||||
m_commands.Clear();
|
||||
|
||||
int controllerIndex = (int)Schedule;
|
||||
|
||||
foreach (var cmd in m_checkCmds)
|
||||
@ -36,25 +36,25 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
|
||||
|
||||
return m_commands;
|
||||
}
|
||||
|
||||
public void Update(IEnumerable<CommandExecuter> executers)
|
||||
{
|
||||
foreach (var cmd in GetCommand())
|
||||
{
|
||||
foreach (var executer in executers)
|
||||
{
|
||||
//App.log.Debug($"CommandListener GetCommand | {Time.frameCount}|{executer.name}| {cmd.Cmd}|{cmd.Cancel}");
|
||||
executer.ExecuteCommand(cmd.Cmd, cmd.Cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_commands;
|
||||
}
|
||||
|
||||
public void Update(IEnumerable<CommandExecuter> executers)
|
||||
{
|
||||
foreach (var cmd in GetCommand())
|
||||
{
|
||||
foreach (var executer in executers)
|
||||
{
|
||||
//App.log.Debug($"CommandListener GetCommand | {Time.frameCount}|{executer.name}| {cmd.Cmd}|{cmd.Cancel}");
|
||||
executer.ExecuteCommand(cmd.Cmd, cmd.Cancel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ScheduleType
|
||||
{
|
||||
Normal,
|
||||
Gaming
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,45 +1,45 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using Coffee.UIExtensions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomItem : MenuItem, IVirtualItem
|
||||
{
|
||||
[SerializeField]
|
||||
Image m_romImage;
|
||||
|
||||
[SerializeField]
|
||||
GameObject DownloadingFlag;
|
||||
[SerializeField]
|
||||
Slider DownProgress;
|
||||
[SerializeField]
|
||||
GameObject FileReadyFlag;
|
||||
[SerializeField]
|
||||
UIShiny DownloadComplete;
|
||||
[SerializeField]
|
||||
GameObject Star;
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using Coffee.UIExtensions;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomItem : MenuItem, IVirtualItem
|
||||
{
|
||||
[SerializeField]
|
||||
Image m_romImage;
|
||||
|
||||
[SerializeField]
|
||||
GameObject DownloadingFlag;
|
||||
[SerializeField]
|
||||
Slider DownProgress;
|
||||
[SerializeField]
|
||||
GameObject FileReadyFlag;
|
||||
[SerializeField]
|
||||
UIShiny DownloadComplete;
|
||||
[SerializeField]
|
||||
GameObject Star;
|
||||
|
||||
public int Index { get; set; }
|
||||
|
||||
public bool IsStar
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_romfile != null && m_romfile.InfoReady ? m_romfile.Star : false;
|
||||
}
|
||||
}
|
||||
public int RomID { get { return m_romfile != null && m_romfile.InfoReady ? m_romfile.ID : -1; } }
|
||||
|
||||
}
|
||||
public int RomID { get { return m_romfile != null && m_romfile.InfoReady ? m_romfile.ID : -1; } }
|
||||
|
||||
private RomLib m_romlib => App.GetRomLib(m_romfile.Platform);
|
||||
|
||||
public bool RomInfoReady => m_romfile != null && m_romfile.InfoReady;
|
||||
|
||||
private RomFile m_romfile;
|
||||
|
||||
private RomFile m_romfile;
|
||||
|
||||
protected override void OnEnable()
|
||||
{
|
||||
Eventer.Instance.RegisterEvent<int>(EEvent.OnRomFileDownloaded, OnRomDownloaded);
|
||||
@ -59,103 +59,103 @@ namespace AxibugEmuOnline.Client
|
||||
DownloadComplete.Play();
|
||||
}
|
||||
|
||||
public void SetData(object data)
|
||||
{
|
||||
Reset();
|
||||
|
||||
m_romfile = (RomFile)data;
|
||||
m_romfile.OnInfoFilled += OnRomInfoFilled;
|
||||
m_romImage.sprite = null;
|
||||
|
||||
UpdateView();
|
||||
|
||||
if (!m_romfile.InfoReady)
|
||||
{
|
||||
m_romlib.BeginFetchRomInfo(m_romfile);
|
||||
}
|
||||
|
||||
SetSelectState(data is ThirdMenuRoot && ((ThirdMenuRoot)data).SelectIndex == Index);
|
||||
}
|
||||
|
||||
public void SetDependencyProperty(object data)
|
||||
{
|
||||
SetSelectState(data is ThirdMenuRoot && ((ThirdMenuRoot)data).SelectIndex == Index);
|
||||
}
|
||||
|
||||
public void SetData(object data)
|
||||
{
|
||||
Reset();
|
||||
|
||||
m_romfile = (RomFile)data;
|
||||
m_romfile.OnInfoFilled += OnRomInfoFilled;
|
||||
m_romImage.sprite = null;
|
||||
|
||||
UpdateView();
|
||||
|
||||
if (!m_romfile.InfoReady)
|
||||
{
|
||||
m_romlib.BeginFetchRomInfo(m_romfile);
|
||||
}
|
||||
|
||||
SetSelectState(data is ThirdMenuRoot && ((ThirdMenuRoot)data).SelectIndex == Index);
|
||||
}
|
||||
|
||||
public void SetDependencyProperty(object data)
|
||||
{
|
||||
SetSelectState(data is ThirdMenuRoot && ((ThirdMenuRoot)data).SelectIndex == Index);
|
||||
}
|
||||
|
||||
protected override void OnSelected(float progress)
|
||||
{
|
||||
base.OnSelected(progress);
|
||||
|
||||
if (m_romImage.sprite == null) LaunchUI.Instance.HideRomPreview();
|
||||
else LaunchUI.Instance.SetRomPreview(m_romImage.sprite);
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
m_romfile.OnInfoFilled -= OnRomInfoFilled;
|
||||
}
|
||||
|
||||
private void OnRomInfoFilled()
|
||||
{
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
if (!m_romfile.InfoReady)
|
||||
{
|
||||
SetBaseInfo("正在拉取", "---", "---");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBaseInfo(m_romfile.Alias, m_romfile.Descript, m_romfile.GameTypeDes);
|
||||
App.CacheMgr.GetSpriteCache(m_romfile.ImageURL, (img, url) =>
|
||||
{
|
||||
if (!m_romfile.InfoReady || url != m_romfile.ImageURL) return;
|
||||
|
||||
m_romImage.sprite = img;
|
||||
if (m_select) LaunchUI.Instance.SetRomPreview(img);
|
||||
});
|
||||
Star.SetActiveEx(m_romfile.Star);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
if (!m_romfile.RomReady)
|
||||
{
|
||||
m_romfile.BeginDownload();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.emu.BeginGame(m_romfile);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
DownloadingFlag.SetActiveEx(false);
|
||||
FileReadyFlag.SetActiveEx(false);
|
||||
Star.SetActiveEx(IsStar);
|
||||
|
||||
if (m_romfile == null) return;
|
||||
if (!m_romfile.InfoReady) return;
|
||||
|
||||
if (m_romfile.IsDownloading)
|
||||
{
|
||||
DownloadingFlag.SetActiveEx(true);
|
||||
DownProgress.value = m_romfile.Progress;
|
||||
}
|
||||
else if (m_romfile.RomReady)
|
||||
{
|
||||
FileReadyFlag.SetActiveEx(true);
|
||||
}
|
||||
|
||||
base.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Release()
|
||||
{
|
||||
m_romfile.OnInfoFilled -= OnRomInfoFilled;
|
||||
}
|
||||
|
||||
private void OnRomInfoFilled()
|
||||
{
|
||||
UpdateView();
|
||||
}
|
||||
|
||||
private void UpdateView()
|
||||
{
|
||||
if (!m_romfile.InfoReady)
|
||||
{
|
||||
SetBaseInfo("正在拉取", "---", "---");
|
||||
}
|
||||
else
|
||||
{
|
||||
SetBaseInfo(m_romfile.Alias, m_romfile.Descript, m_romfile.GameTypeDes);
|
||||
App.CacheMgr.GetSpriteCache(m_romfile.ImageURL, (img, url) =>
|
||||
{
|
||||
if (!m_romfile.InfoReady || url != m_romfile.ImageURL) return;
|
||||
|
||||
m_romImage.sprite = img;
|
||||
if (m_select) LaunchUI.Instance.SetRomPreview(img);
|
||||
});
|
||||
Star.SetActiveEx(m_romfile.Star);
|
||||
}
|
||||
}
|
||||
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
if (!m_romfile.RomReady)
|
||||
{
|
||||
m_romfile.BeginDownload();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.emu.BeginGame(m_romfile);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
DownloadingFlag.SetActiveEx(false);
|
||||
FileReadyFlag.SetActiveEx(false);
|
||||
Star.SetActiveEx(IsStar);
|
||||
|
||||
if (m_romfile == null) return;
|
||||
if (!m_romfile.InfoReady) return;
|
||||
|
||||
if (m_romfile.IsDownloading)
|
||||
{
|
||||
DownloadingFlag.SetActiveEx(true);
|
||||
DownProgress.value = m_romfile.Progress;
|
||||
}
|
||||
else if (m_romfile.RomReady)
|
||||
{
|
||||
FileReadyFlag.SetActiveEx(true);
|
||||
}
|
||||
|
||||
base.Update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,109 +1,109 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomListMenuItem : VirtualSubMenuItem
|
||||
{
|
||||
[SerializeField]
|
||||
protected bool StarRom;
|
||||
[SerializeField]
|
||||
protected RomPlatformType Platform;
|
||||
|
||||
private RomLib RomLib
|
||||
{
|
||||
get
|
||||
{
|
||||
if (StarRom) return App.starRomLib;
|
||||
else return App.GetRomLib(Platform);
|
||||
}
|
||||
}
|
||||
|
||||
private List<InternalOptionMenu> m_options;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_options = new List<InternalOptionMenu>()
|
||||
{
|
||||
new OptMenu_Search(this),
|
||||
new OptMenu_ShowAll(this),
|
||||
new OptMenu_Fav(this),
|
||||
};
|
||||
}
|
||||
|
||||
public string SearchKey;
|
||||
protected override void GetVirtualListDatas(VirtualListDataHandle callback)
|
||||
{
|
||||
RomLib.FetchRomCount((roms) => callback.Invoke(roms, 0), SearchKey);
|
||||
}
|
||||
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
var res = base.OnEnterItem();
|
||||
if (res) CommandDispatcher.Instance.RegistController(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnExitItem()
|
||||
{
|
||||
var res = base.OnExitItem();
|
||||
if (res) CommandDispatcher.Instance.UnRegistController(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnCmdOptionMenu()
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RomListMenuItem : VirtualSubMenuItem
|
||||
{
|
||||
[SerializeField]
|
||||
protected bool StarRom;
|
||||
[SerializeField]
|
||||
protected RomPlatformType Platform;
|
||||
|
||||
private RomLib RomLib
|
||||
{
|
||||
OverlayManager.PopSideBar(m_options);
|
||||
}
|
||||
|
||||
public class OptMenu_Search : ExecuteMenu
|
||||
{
|
||||
private RomListMenuItem m_romListUI;
|
||||
public override string Name => "搜索";
|
||||
|
||||
get
|
||||
{
|
||||
if (StarRom) return App.starRomLib;
|
||||
else return App.GetRomLib(Platform);
|
||||
}
|
||||
}
|
||||
|
||||
private List<InternalOptionMenu> m_options;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
m_options = new List<InternalOptionMenu>()
|
||||
{
|
||||
new OptMenu_Search(this),
|
||||
new OptMenu_ShowAll(this),
|
||||
new OptMenu_Fav(this),
|
||||
};
|
||||
}
|
||||
|
||||
public string SearchKey;
|
||||
protected override void GetVirtualListDatas(VirtualListDataHandle callback)
|
||||
{
|
||||
RomLib.FetchRomCount((roms) => callback.Invoke(roms, 0), SearchKey);
|
||||
}
|
||||
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
var res = base.OnEnterItem();
|
||||
if (res) CommandDispatcher.Instance.RegistController(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public override bool OnExitItem()
|
||||
{
|
||||
var res = base.OnExitItem();
|
||||
if (res) CommandDispatcher.Instance.UnRegistController(this);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
protected override void OnCmdOptionMenu()
|
||||
{
|
||||
OverlayManager.PopSideBar(m_options);
|
||||
}
|
||||
|
||||
public class OptMenu_Search : ExecuteMenu
|
||||
{
|
||||
private RomListMenuItem m_romListUI;
|
||||
public override string Name => "搜索";
|
||||
|
||||
public OptMenu_Search(RomListMenuItem romListUI)
|
||||
{
|
||||
m_romListUI = romListUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
OverlayManager.Input(OnSearchCommit, "输入Rom名称", m_romListUI.SearchKey);
|
||||
}
|
||||
|
||||
private void OnSearchCommit(string text)
|
||||
{
|
||||
m_romListUI.SearchKey = text;
|
||||
m_romListUI.RefreshUI();
|
||||
}
|
||||
}
|
||||
|
||||
public class OptMenu_ShowAll : ExecuteMenu
|
||||
{
|
||||
private RomListMenuItem m_ui;
|
||||
|
||||
public override string Name => "显示全部";
|
||||
public override bool Visible => !string.IsNullOrWhiteSpace(m_ui.SearchKey);
|
||||
|
||||
public OptMenu_ShowAll(RomListMenuItem romListUI)
|
||||
{
|
||||
m_ui = romListUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
m_ui.SearchKey = null;
|
||||
m_ui.RefreshUI();
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
m_romListUI = romListUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
OverlayManager.Input(OnSearchCommit, "输入Rom名称", m_romListUI.SearchKey);
|
||||
}
|
||||
|
||||
private void OnSearchCommit(string text)
|
||||
{
|
||||
m_romListUI.SearchKey = text;
|
||||
m_romListUI.RefreshUI();
|
||||
}
|
||||
}
|
||||
|
||||
public class OptMenu_ShowAll : ExecuteMenu
|
||||
{
|
||||
private RomListMenuItem m_ui;
|
||||
|
||||
public override string Name => "显示全部";
|
||||
public override bool Visible => !string.IsNullOrWhiteSpace(m_ui.SearchKey);
|
||||
|
||||
public OptMenu_ShowAll(RomListMenuItem romListUI)
|
||||
{
|
||||
m_ui = romListUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
m_ui.SearchKey = null;
|
||||
m_ui.RefreshUI();
|
||||
}
|
||||
}
|
||||
|
||||
public class OptMenu_Fav : ExecuteMenu
|
||||
{
|
||||
private RomListMenuItem m_romListUI;
|
||||
@ -129,6 +129,6 @@ namespace AxibugEmuOnline.Client
|
||||
else
|
||||
App.share.SendGameStar(romItem.RomID, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,45 +1,45 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI : CommandExecuter
|
||||
{
|
||||
private bool m_delayCreateRoom;
|
||||
private object m_state;
|
||||
private StepPerformer m_stepPerformer;
|
||||
|
||||
private readonly List<InternalOptionMenu> menus = new List<InternalOptionMenu>();
|
||||
public static InGameUI Instance { get; private set; }
|
||||
|
||||
public RomFile RomFile { get; private set; }
|
||||
|
||||
public override bool Enable => gameObject.activeInHierarchy;
|
||||
|
||||
public EmuCore Core { get; private set; }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
gameObject.SetActiveEx(false);
|
||||
|
||||
m_stepPerformer = new StepPerformer(this);
|
||||
|
||||
menus.Add(new InGameUI_FilterSetting(this));
|
||||
menus.Add(new InGameUI_Scaler(this));
|
||||
menus.Add(new InGameUI_Reset(this));
|
||||
menus.Add(new InGameUI_SaveStateQuick(this));
|
||||
menus.Add(new InGameUI_LoadStateQuick(this));
|
||||
menus.Add(new InGameUI_SaveStateMenu(this));
|
||||
menus.Add(new InGameUI_QuitGame(this));
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Network;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI : CommandExecuter
|
||||
{
|
||||
private bool m_delayCreateRoom;
|
||||
private object m_state;
|
||||
private StepPerformer m_stepPerformer;
|
||||
|
||||
private readonly List<InternalOptionMenu> menus = new List<InternalOptionMenu>();
|
||||
public static InGameUI Instance { get; private set; }
|
||||
|
||||
public RomFile RomFile { get; private set; }
|
||||
|
||||
public override bool Enable => gameObject.activeInHierarchy;
|
||||
|
||||
public EmuCore Core { get; private set; }
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
gameObject.SetActiveEx(false);
|
||||
|
||||
m_stepPerformer = new StepPerformer(this);
|
||||
|
||||
menus.Add(new InGameUI_FilterSetting(this));
|
||||
menus.Add(new InGameUI_Scaler(this));
|
||||
menus.Add(new InGameUI_Reset(this));
|
||||
menus.Add(new InGameUI_SaveStateQuick(this));
|
||||
menus.Add(new InGameUI_LoadStateQuick(this));
|
||||
menus.Add(new InGameUI_SaveStateMenu(this));
|
||||
menus.Add(new InGameUI_QuitGame(this));
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
base.Update();
|
||||
@ -48,8 +48,8 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
App.settings.Filter.ExecuteFilterRender(Core.OutputPixel, Core.DrawCanvas);
|
||||
App.settings.ScreenScaler.CalcScale(Core.DrawCanvas, Core.Platform);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void PushCoreFrame()
|
||||
{
|
||||
if (Core == null) return;
|
||||
@ -57,70 +57,70 @@ namespace AxibugEmuOnline.Client
|
||||
NetMsg.Instance.DequeueNesMsg();
|
||||
|
||||
Core.PushEmulatorFrame();
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
/// <summary> 保存快速快照 </summary>
|
||||
public void SaveQuickState(object state)
|
||||
{
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取快速快照
|
||||
/// </summary>
|
||||
public object GetQuickState()
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
public void Show(RomFile currentRom, EmuCore core)
|
||||
{
|
||||
m_delayCreateRoom = false;
|
||||
m_state = null; //清空游戏快照
|
||||
CommandDispatcher.Instance.RegistController(this);
|
||||
|
||||
RomFile = currentRom;
|
||||
Core = core;
|
||||
m_stepPerformer.Reset();
|
||||
|
||||
if (!App.roomMgr.InRoom)
|
||||
{
|
||||
if (App.user.IsLoggedIn)
|
||||
{
|
||||
App.roomMgr.SendCreateRoom(RomFile.ID, RomFile.Hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_delayCreateRoom = true;
|
||||
OverlayManager.PopTip("稍后将会建立房间");
|
||||
}
|
||||
}
|
||||
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnLoginSucceed, OnLoggedIn);
|
||||
Eventer.Instance.RegisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnMineRoomCreated, OnRoomCreated);
|
||||
|
||||
gameObject.SetActiveEx(true);
|
||||
|
||||
var filterSetting = App.settings.Filter.GetFilterSetting(currentRom);
|
||||
if (filterSetting.filter != null)
|
||||
{
|
||||
var filter = filterSetting.filter;
|
||||
var preset = filterSetting.preset ?? filter.DefaultPreset;
|
||||
|
||||
filter.ApplyPreset(preset);
|
||||
App.settings.Filter.EnableFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomCreated()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnDestroy()
|
||||
{
|
||||
Instance = null;
|
||||
base.OnDestroy();
|
||||
}
|
||||
|
||||
/// <summary> 保存快速快照 </summary>
|
||||
public void SaveQuickState(object state)
|
||||
{
|
||||
m_state = state;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取快速快照
|
||||
/// </summary>
|
||||
public object GetQuickState()
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
public void Show(RomFile currentRom, EmuCore core)
|
||||
{
|
||||
m_delayCreateRoom = false;
|
||||
m_state = null; //清空游戏快照
|
||||
CommandDispatcher.Instance.RegistController(this);
|
||||
|
||||
RomFile = currentRom;
|
||||
Core = core;
|
||||
m_stepPerformer.Reset();
|
||||
|
||||
if (!App.roomMgr.InRoom)
|
||||
{
|
||||
if (App.user.IsLoggedIn)
|
||||
{
|
||||
App.roomMgr.SendCreateRoom(RomFile.ID, RomFile.Hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_delayCreateRoom = true;
|
||||
OverlayManager.PopTip("稍后将会建立房间");
|
||||
}
|
||||
}
|
||||
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnLoginSucceed, OnLoggedIn);
|
||||
Eventer.Instance.RegisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
||||
Eventer.Instance.RegisterEvent(EEvent.OnMineRoomCreated, OnRoomCreated);
|
||||
|
||||
gameObject.SetActiveEx(true);
|
||||
|
||||
var filterSetting = App.settings.Filter.GetFilterSetting(currentRom);
|
||||
if (filterSetting.filter != null)
|
||||
{
|
||||
var filter = filterSetting.filter;
|
||||
var preset = filterSetting.preset ?? filter.DefaultPreset;
|
||||
|
||||
filter.ApplyPreset(preset);
|
||||
App.settings.Filter.EnableFilter(filter);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnRoomCreated()
|
||||
{
|
||||
if (m_delayCreateRoom)
|
||||
{
|
||||
m_delayCreateRoom = false;
|
||||
@ -138,48 +138,48 @@ namespace AxibugEmuOnline.Client
|
||||
}
|
||||
App.roomMgr.SendChangePlaySlotIdxWithJoyIdx(temp);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoggedIn()
|
||||
{
|
||||
if (m_delayCreateRoom) App.roomMgr.SendCreateRoom(RomFile.ID, RomFile.Hash);
|
||||
}
|
||||
|
||||
private void OnServerStepUpdate(int step)
|
||||
{
|
||||
m_stepPerformer.Perform(step);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
CommandDispatcher.Instance.UnRegistController(this);
|
||||
gameObject.SetActiveEx(false);
|
||||
|
||||
App.settings.Filter.ShutDownFilter();
|
||||
}
|
||||
|
||||
protected override void OnCmdOptionMenu()
|
||||
{
|
||||
OverlayManager.PopSideBar(menus, 0, PopMenu_OnHide);
|
||||
|
||||
if (!Core.IsNetPlay) //单人模式暂停模拟器
|
||||
Core.Pause();
|
||||
}
|
||||
|
||||
//菜单关闭时候
|
||||
private void PopMenu_OnHide()
|
||||
{
|
||||
if (!Core.IsNetPlay) //单人模式恢复模拟器的暂停
|
||||
Core.Resume();
|
||||
}
|
||||
|
||||
public void QuitGame()
|
||||
{
|
||||
Eventer.Instance.UnregisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnLoginSucceed, OnLoggedIn);
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnMineRoomCreated, OnRoomCreated);
|
||||
App.roomMgr.SendLeavnRoom();
|
||||
App.emu.StopGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnLoggedIn()
|
||||
{
|
||||
if (m_delayCreateRoom) App.roomMgr.SendCreateRoom(RomFile.ID, RomFile.Hash);
|
||||
}
|
||||
|
||||
private void OnServerStepUpdate(int step)
|
||||
{
|
||||
m_stepPerformer.Perform(step);
|
||||
}
|
||||
|
||||
public void Hide()
|
||||
{
|
||||
CommandDispatcher.Instance.UnRegistController(this);
|
||||
gameObject.SetActiveEx(false);
|
||||
|
||||
App.settings.Filter.ShutDownFilter();
|
||||
}
|
||||
|
||||
protected override void OnCmdOptionMenu()
|
||||
{
|
||||
OverlayManager.PopSideBar(menus, 0, PopMenu_OnHide);
|
||||
|
||||
if (!Core.IsNetPlay) //单人模式暂停模拟器
|
||||
Core.Pause();
|
||||
}
|
||||
|
||||
//菜单关闭时候
|
||||
private void PopMenu_OnHide()
|
||||
{
|
||||
if (!Core.IsNetPlay) //单人模式恢复模拟器的暂停
|
||||
Core.Resume();
|
||||
}
|
||||
|
||||
public void QuitGame()
|
||||
{
|
||||
Eventer.Instance.UnregisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnLoginSucceed, OnLoggedIn);
|
||||
Eventer.Instance.UnregisterEvent(EEvent.OnMineRoomCreated, OnRoomCreated);
|
||||
App.roomMgr.SendLeavnRoom();
|
||||
App.emu.StopGame();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,28 +1,28 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static AxibugEmuOnline.Client.Settings.FilterManager;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using static AxibugEmuOnline.Client.Settings.FilterManager;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI_FilterSetting : ExpandMenu
|
||||
{
|
||||
private InGameUI m_gameUI;
|
||||
public override string Name => "滤镜";
|
||||
|
||||
public class InGameUI_FilterSetting : ExpandMenu
|
||||
{
|
||||
private InGameUI m_gameUI;
|
||||
public override string Name => "滤镜";
|
||||
|
||||
public InGameUI_FilterSetting(InGameUI gameUI)
|
||||
{
|
||||
m_gameUI = gameUI;
|
||||
}
|
||||
|
||||
protected override List<InternalOptionMenu> GetOptionMenus()
|
||||
{
|
||||
List<InternalOptionMenu> menus = new List<InternalOptionMenu>();
|
||||
menus.Add(new FilterNone(m_gameUI.RomFile));
|
||||
menus.AddRange(App.settings.Filter.Filters.Select(f => new FilterMenu(m_gameUI.RomFile, f) as InternalOptionMenu));
|
||||
return menus;
|
||||
}
|
||||
|
||||
{
|
||||
m_gameUI = gameUI;
|
||||
}
|
||||
|
||||
protected override List<InternalOptionMenu> GetOptionMenus()
|
||||
{
|
||||
List<InternalOptionMenu> menus = new List<InternalOptionMenu>();
|
||||
menus.Add(new FilterNone(m_gameUI.RomFile));
|
||||
menus.AddRange(App.settings.Filter.Filters.Select(f => new FilterMenu(m_gameUI.RomFile, f) as InternalOptionMenu));
|
||||
return menus;
|
||||
}
|
||||
|
||||
public class FilterNone : ExecuteMenu
|
||||
{
|
||||
private RomFile m_rom;
|
||||
@ -36,16 +36,16 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
App.settings.Filter.ShutDownFilter();
|
||||
App.settings.Filter.ShutDownFilter();
|
||||
App.settings.Filter.SetupFilter(m_rom, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterMenu : ExpandMenu
|
||||
{
|
||||
private Filter m_filter;
|
||||
private List<InternalOptionMenu> m_presetsMenuItems;
|
||||
|
||||
}
|
||||
|
||||
public class FilterMenu : ExpandMenu
|
||||
{
|
||||
private Filter m_filter;
|
||||
private List<InternalOptionMenu> m_presetsMenuItems;
|
||||
|
||||
public override bool IsApplied
|
||||
{
|
||||
get
|
||||
@ -57,27 +57,27 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public override string Name => m_filter.Name;
|
||||
public FilterMenu(RomFile rom, Filter filter)
|
||||
{
|
||||
m_filter = filter;
|
||||
m_presetsMenuItems = new List<InternalOptionMenu> { new FilterPresetMenu(rom, m_filter, m_filter.DefaultPreset) };
|
||||
m_presetsMenuItems.AddRange(m_filter.Presets.Select(preset => new FilterPresetMenu(rom, m_filter, preset)));
|
||||
}
|
||||
|
||||
protected override List<InternalOptionMenu> GetOptionMenus()
|
||||
{
|
||||
return m_presetsMenuItems;
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterPresetMenu : ExecuteMenu
|
||||
{
|
||||
private FilterPreset m_preset;
|
||||
private RomFile m_rom;
|
||||
private Filter m_filter;
|
||||
|
||||
}
|
||||
public override string Name => m_filter.Name;
|
||||
public FilterMenu(RomFile rom, Filter filter)
|
||||
{
|
||||
m_filter = filter;
|
||||
m_presetsMenuItems = new List<InternalOptionMenu> { new FilterPresetMenu(rom, m_filter, m_filter.DefaultPreset) };
|
||||
m_presetsMenuItems.AddRange(m_filter.Presets.Select(preset => new FilterPresetMenu(rom, m_filter, preset)));
|
||||
}
|
||||
|
||||
protected override List<InternalOptionMenu> GetOptionMenus()
|
||||
{
|
||||
return m_presetsMenuItems;
|
||||
}
|
||||
}
|
||||
|
||||
public class FilterPresetMenu : ExecuteMenu
|
||||
{
|
||||
private FilterPreset m_preset;
|
||||
private RomFile m_rom;
|
||||
private Filter m_filter;
|
||||
|
||||
public override bool IsApplied
|
||||
{
|
||||
get
|
||||
@ -89,19 +89,19 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
public override string Name => m_preset.Name;
|
||||
public FilterPresetMenu(RomFile rom, Filter filter, FilterPreset preset)
|
||||
{
|
||||
m_preset = preset;
|
||||
m_rom = rom;
|
||||
m_filter = filter;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
m_filter.ApplyPreset(m_preset);
|
||||
App.settings.Filter.EnableFilter(m_filter);
|
||||
|
||||
App.settings.Filter.SetupFilter(m_rom, m_filter, m_preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
m_preset = preset;
|
||||
m_rom = rom;
|
||||
m_filter = filter;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
m_filter.ApplyPreset(m_preset);
|
||||
App.settings.Filter.EnableFilter(m_filter);
|
||||
|
||||
App.settings.Filter.SetupFilter(m_rom, m_filter, m_preset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI_LoadStateQuick : ExecuteMenu
|
||||
{
|
||||
private InGameUI m_gameUI;
|
||||
public override bool Visible => !m_gameUI.Core.IsNetPlay && m_gameUI.GetQuickState() != null;
|
||||
public override string Name => "快速读取";
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI_LoadStateQuick : ExecuteMenu
|
||||
{
|
||||
private InGameUI m_gameUI;
|
||||
public override bool Visible => !m_gameUI.Core.IsNetPlay && m_gameUI.GetQuickState() != null;
|
||||
public override string Name => "快速读取";
|
||||
|
||||
public InGameUI_LoadStateQuick(InGameUI gameUI)
|
||||
{
|
||||
m_gameUI = gameUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (m_gameUI.Core.IsNetPlay) return;
|
||||
|
||||
object state = m_gameUI.GetQuickState();
|
||||
if (state != null)
|
||||
{
|
||||
m_gameUI.Core.LoadState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
m_gameUI = gameUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (m_gameUI.Core.IsNetPlay) return;
|
||||
|
||||
object state = m_gameUI.GetQuickState();
|
||||
if (state != null)
|
||||
{
|
||||
m_gameUI.Core.LoadState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,25 +1,25 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI_Reset : ExecuteMenu
|
||||
{
|
||||
private InGameUI m_gameUI;
|
||||
public override string Name => "复位";
|
||||
public override bool Visible => !m_gameUI.Core.IsNetPlay || App.roomMgr.IsHost;
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class InGameUI_Reset : ExecuteMenu
|
||||
{
|
||||
private InGameUI m_gameUI;
|
||||
public override string Name => "复位";
|
||||
public override bool Visible => !m_gameUI.Core.IsNetPlay || App.roomMgr.IsHost;
|
||||
|
||||
public InGameUI_Reset(InGameUI gameUI)
|
||||
{
|
||||
m_gameUI = gameUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (!m_gameUI.Core.IsNetPlay)
|
||||
{
|
||||
App.emu.ResetGame();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
m_gameUI = gameUI;
|
||||
}
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (!m_gameUI.Core.IsNetPlay)
|
||||
{
|
||||
App.emu.ResetGame();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -92,16 +92,18 @@ namespace AxibugEmuOnline.Client
|
||||
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (m_savFile.IsBusy) //取消同步进程
|
||||
if (m_savFile.IsBusy)
|
||||
{
|
||||
m_savFile.FSM.ChangeState<SaveFile.IdleState>();
|
||||
OverlayManager.PopTip("存档正在同步中");
|
||||
cancelHide = true;
|
||||
return;
|
||||
}
|
||||
|
||||
var stateData = m_ingameUI.Core.GetStateBytes();
|
||||
var tex = m_ingameUI.Core.OutputPixel;
|
||||
var screenData = tex.ToJPG(m_ingameUI.Core.DrawCanvas.transform.localScale);
|
||||
|
||||
m_savFile.Save(m_savFile.Sequecen + 1, stateData, screenData);
|
||||
m_savFile.Save(m_savFile.Sequecen, stateData, screenData);
|
||||
}
|
||||
}
|
||||
|
||||
@ -165,6 +167,7 @@ namespace AxibugEmuOnline.Client
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (m_savFile.GetCurrentState() is not SaveFile.ConflictState) return;
|
||||
cancelHide = true;
|
||||
m_savFile.FSM.ChangeState<SaveFile.DownloadingState>();
|
||||
}
|
||||
}
|
||||
@ -184,6 +187,7 @@ namespace AxibugEmuOnline.Client
|
||||
public override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
if (m_savFile.GetCurrentState() is not SaveFile.ConflictState) return;
|
||||
cancelHide = true;
|
||||
m_savFile.FSM.ChangeState<SaveFile.UploadingState>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,59 +1,59 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public static class GameObjectPool
|
||||
{
|
||||
private static GameObject PoolAttach;
|
||||
private static Dictionary<GameObject, Queue<GameObject>> s_poolMap = new Dictionary<GameObject, Queue<GameObject>>();
|
||||
private static Dictionary<GameObject, GameObject> s_instanceToSrc = new Dictionary<GameObject, GameObject>();
|
||||
public static GameObject GetInstance(GameObject prefabSrc, Transform parent)
|
||||
{
|
||||
if (PoolAttach == null)
|
||||
{
|
||||
PoolAttach = new GameObject("[GameObjectPool]");
|
||||
PoolAttach.transform.localScale = Vector3.zero;
|
||||
GameObject.DontDestroyOnLoad(PoolAttach);
|
||||
}
|
||||
|
||||
if (!s_poolMap.ContainsKey(prefabSrc)) s_poolMap[prefabSrc] = new Queue<GameObject>();
|
||||
|
||||
GameObject instance = null;
|
||||
var pool = s_poolMap[prefabSrc];
|
||||
if (pool.Count > 0)
|
||||
{
|
||||
instance = pool.Dequeue();
|
||||
instance.transform.SetParent(parent, true);
|
||||
instance.transform.localScale = prefabSrc.transform.localScale;
|
||||
instance.transform.localRotation = prefabSrc.transform.localRotation;
|
||||
instance.transform.localPosition = prefabSrc.transform.localPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = GameObject.Instantiate(prefabSrc, parent);
|
||||
s_instanceToSrc[instance] = prefabSrc;
|
||||
}
|
||||
|
||||
//instance.SetActive(true);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void Release(GameObject instance)
|
||||
{
|
||||
GameObject src;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public static class GameObjectPool
|
||||
{
|
||||
private static GameObject PoolAttach;
|
||||
private static Dictionary<GameObject, Queue<GameObject>> s_poolMap = new Dictionary<GameObject, Queue<GameObject>>();
|
||||
private static Dictionary<GameObject, GameObject> s_instanceToSrc = new Dictionary<GameObject, GameObject>();
|
||||
public static GameObject GetInstance(GameObject prefabSrc, Transform parent)
|
||||
{
|
||||
if (PoolAttach == null)
|
||||
{
|
||||
PoolAttach = new GameObject("[GameObjectPool]");
|
||||
PoolAttach.transform.localScale = Vector3.zero;
|
||||
GameObject.DontDestroyOnLoad(PoolAttach);
|
||||
}
|
||||
|
||||
if (!s_poolMap.ContainsKey(prefabSrc)) s_poolMap[prefabSrc] = new Queue<GameObject>();
|
||||
|
||||
GameObject instance = null;
|
||||
var pool = s_poolMap[prefabSrc];
|
||||
if (pool.Count > 0)
|
||||
{
|
||||
instance = pool.Dequeue();
|
||||
instance.transform.SetParent(parent, true);
|
||||
instance.transform.localScale = prefabSrc.transform.localScale;
|
||||
instance.transform.localRotation = prefabSrc.transform.localRotation;
|
||||
instance.transform.localPosition = prefabSrc.transform.localPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
instance = GameObject.Instantiate(prefabSrc, parent);
|
||||
s_instanceToSrc[instance] = prefabSrc;
|
||||
}
|
||||
|
||||
//instance.SetActive(true);
|
||||
return instance;
|
||||
}
|
||||
|
||||
public static void Release(GameObject instance)
|
||||
{
|
||||
GameObject src;
|
||||
Queue<GameObject> pool;
|
||||
s_instanceToSrc.TryGetValue(instance, out src);
|
||||
if (src != null && s_poolMap.TryGetValue(src, out pool))
|
||||
{
|
||||
pool.Enqueue(instance);
|
||||
//instance.SetActive(false);
|
||||
if (instance == null) return;
|
||||
if (PoolAttach == null) return;
|
||||
|
||||
instance.transform.SetParent(PoolAttach.transform, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject.Destroy(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
s_instanceToSrc.TryGetValue(instance, out src);
|
||||
if (src != null && s_poolMap.TryGetValue(src, out pool))
|
||||
{
|
||||
pool.Enqueue(instance);
|
||||
//instance.SetActive(false);
|
||||
if (instance == null) return;
|
||||
if (PoolAttach == null) return;
|
||||
|
||||
instance.transform.SetParent(PoolAttach.transform, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
GameObject.Destroy(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,11 +1,11 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
|
||||
public interface IVirtualLayout
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
|
||||
|
||||
public interface IVirtualLayout
|
||||
{
|
||||
Dictionary<GameObject, ScripteInterface> CacheItemScripts { get; }
|
||||
List<object> DataList { get; }
|
||||
@ -18,10 +18,10 @@ public interface IVirtualLayout
|
||||
void UpdateProxyVisualState();
|
||||
void UpdateDependencyProperty(object dp);
|
||||
void SetData(IEnumerable dataList);
|
||||
void MoveToScrollViewCenter(ScrollRect scrollRect, int dataIndex);
|
||||
}
|
||||
|
||||
public class ItemProxy
|
||||
void MoveToScrollViewCenter(ScrollRect scrollRect, int dataIndex);
|
||||
}
|
||||
|
||||
public class ItemProxy
|
||||
{
|
||||
public bool IsDestroyed;
|
||||
public bool Visible = true;
|
||||
@ -207,10 +207,10 @@ public class ItemProxy
|
||||
GameObject.DestroyImmediate(_runtimeInstance.gameObject);
|
||||
_runtimeInstance = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ScripteInterface
|
||||
}
|
||||
}
|
||||
|
||||
public class ScripteInterface
|
||||
{
|
||||
private IVirtualItem _itemInstance;
|
||||
public IVirtualItem ItemInstance => _itemInstance;
|
||||
@ -237,15 +237,15 @@ public class ScripteInterface
|
||||
if (_itemInstance == null) return;
|
||||
|
||||
_itemInstance.SetDependencyProperty(dependencyProperty);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IVirtualItem
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface IVirtualItem
|
||||
{
|
||||
GameObject gameObject { get; }
|
||||
int Index { get; set; }
|
||||
void SetData(object data);
|
||||
void SetDependencyProperty(object data);
|
||||
void Release();
|
||||
}
|
||||
void Release();
|
||||
}
|
||||
|
||||
@ -1,131 +1,131 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using Coffee.UIExtensions;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class LaunchUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
RectTransform MainMenuRoot;
|
||||
[SerializeField]
|
||||
MainMenuController MainMenu;
|
||||
[SerializeField]
|
||||
Image XMBBackground;
|
||||
[SerializeField]
|
||||
Image RomPreviewBigPic;
|
||||
[SerializeField]
|
||||
CanvasGroup XMBCG_For_RomPreviewBigPic;
|
||||
|
||||
Vector2 m_mainLayoutPosition;
|
||||
[SerializeField]
|
||||
float m_detailLayoutPosition_x = 55;
|
||||
[SerializeField]
|
||||
float m_LayoutChangeSpeed = 10;
|
||||
|
||||
public static LaunchUI Instance { get; private set; }
|
||||
|
||||
TweenerCore<Vector2, Vector2, VectorOptions> m_layoutTween;
|
||||
AlphaWraper romPreviewWraper;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
m_mainLayoutPosition = MainMenuRoot.anchoredPosition;
|
||||
MainMenu.ListenControlAction = true;
|
||||
|
||||
romPreviewWraper = new AlphaWraper(XMBCG_For_RomPreviewBigPic, RomPreviewBigPic.GetComponent<CanvasGroup>(), false);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (CommandDispatcher.Instance.Mode == CommandListener.ScheduleType.Gaming && App.emu.Core == null)
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
|
||||
}
|
||||
|
||||
public void HideMainMenu()
|
||||
{
|
||||
XMBBackground.gameObject.SetActiveEx(false);
|
||||
MainMenuRoot.gameObject.SetActiveEx(false);
|
||||
RomPreviewBigPic.gameObject.SetActiveEx(false);
|
||||
}
|
||||
|
||||
public void ShowMainMenu()
|
||||
{
|
||||
XMBBackground.gameObject.SetActiveEx(true);
|
||||
MainMenuRoot.gameObject.SetActiveEx(true);
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using Coffee.UIExtensions;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class LaunchUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField]
|
||||
RectTransform MainMenuRoot;
|
||||
[SerializeField]
|
||||
MainMenuController MainMenu;
|
||||
[SerializeField]
|
||||
Image XMBBackground;
|
||||
[SerializeField]
|
||||
Image RomPreviewBigPic;
|
||||
[SerializeField]
|
||||
CanvasGroup XMBCG_For_RomPreviewBigPic;
|
||||
|
||||
Vector2 m_mainLayoutPosition;
|
||||
[SerializeField]
|
||||
float m_detailLayoutPosition_x = 55;
|
||||
[SerializeField]
|
||||
float m_LayoutChangeSpeed = 10;
|
||||
|
||||
public static LaunchUI Instance { get; private set; }
|
||||
|
||||
TweenerCore<Vector2, Vector2, VectorOptions> m_layoutTween;
|
||||
AlphaWraper romPreviewWraper;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
Instance = this;
|
||||
m_mainLayoutPosition = MainMenuRoot.anchoredPosition;
|
||||
MainMenu.ListenControlAction = true;
|
||||
|
||||
romPreviewWraper = new AlphaWraper(XMBCG_For_RomPreviewBigPic, RomPreviewBigPic.GetComponent<CanvasGroup>(), false);
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (CommandDispatcher.Instance.Mode == CommandListener.ScheduleType.Gaming && App.emu.Core == null)
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
|
||||
}
|
||||
|
||||
public void HideMainMenu()
|
||||
{
|
||||
XMBBackground.gameObject.SetActiveEx(false);
|
||||
MainMenuRoot.gameObject.SetActiveEx(false);
|
||||
RomPreviewBigPic.gameObject.SetActiveEx(false);
|
||||
}
|
||||
|
||||
public void ShowMainMenu()
|
||||
{
|
||||
XMBBackground.gameObject.SetActiveEx(true);
|
||||
MainMenuRoot.gameObject.SetActiveEx(true);
|
||||
|
||||
if (romPreviewWraper.On)
|
||||
{
|
||||
XMBCG_For_RomPreviewBigPic.gameObject.SetActive(false);
|
||||
RomPreviewBigPic.gameObject.SetActive(true);
|
||||
}
|
||||
}
|
||||
else if (!romPreviewWraper.On)
|
||||
{
|
||||
XMBCG_For_RomPreviewBigPic.gameObject.SetActive(true);
|
||||
XMBCG_For_RomPreviewBigPic.alpha = 1;
|
||||
RomPreviewBigPic.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void HideRomPreview()
|
||||
{
|
||||
romPreviewWraper.On = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetRomPreview(Sprite sp)
|
||||
{
|
||||
if (MainMenu.ListenControlAction) return;
|
||||
|
||||
RomPreviewBigPic.sprite = sp;
|
||||
romPreviewWraper.On = true;
|
||||
}
|
||||
|
||||
public void ToDetailMenuLayout()
|
||||
{
|
||||
if (m_layoutTween != null)
|
||||
{
|
||||
m_layoutTween.Kill();
|
||||
m_layoutTween = null;
|
||||
}
|
||||
m_layoutTween = DOTween
|
||||
.To(
|
||||
() => MainMenuRoot.anchoredPosition,
|
||||
(x) => MainMenuRoot.anchoredPosition = x,
|
||||
new Vector2(m_detailLayoutPosition_x, MainMenuRoot.anchoredPosition.y),
|
||||
m_LayoutChangeSpeed)
|
||||
.SetSpeedBased();
|
||||
MainMenu.ListenControlAction = false;
|
||||
MainMenu.EnterDetailState();
|
||||
}
|
||||
|
||||
public void ToMainMenuLayout()
|
||||
{
|
||||
if (m_layoutTween != null)
|
||||
{
|
||||
m_layoutTween.Kill();
|
||||
m_layoutTween = null;
|
||||
}
|
||||
m_layoutTween = DOTween.To(
|
||||
() => MainMenuRoot.anchoredPosition,
|
||||
(x) => MainMenuRoot.anchoredPosition = x,
|
||||
m_mainLayoutPosition,
|
||||
m_LayoutChangeSpeed)
|
||||
.SetSpeedBased();
|
||||
MainMenu.ListenControlAction = true;
|
||||
MainMenu.ExitDetailState();
|
||||
|
||||
HideRomPreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ToDetailMenuLayout()
|
||||
{
|
||||
if (m_layoutTween != null)
|
||||
{
|
||||
m_layoutTween.Kill();
|
||||
m_layoutTween = null;
|
||||
}
|
||||
m_layoutTween = DOTween
|
||||
.To(
|
||||
() => MainMenuRoot.anchoredPosition,
|
||||
(x) => MainMenuRoot.anchoredPosition = x,
|
||||
new Vector2(m_detailLayoutPosition_x, MainMenuRoot.anchoredPosition.y),
|
||||
m_LayoutChangeSpeed)
|
||||
.SetSpeedBased();
|
||||
MainMenu.ListenControlAction = false;
|
||||
MainMenu.EnterDetailState();
|
||||
}
|
||||
|
||||
public void ToMainMenuLayout()
|
||||
{
|
||||
if (m_layoutTween != null)
|
||||
{
|
||||
m_layoutTween.Kill();
|
||||
m_layoutTween = null;
|
||||
}
|
||||
m_layoutTween = DOTween.To(
|
||||
() => MainMenuRoot.anchoredPosition,
|
||||
(x) => MainMenuRoot.anchoredPosition = x,
|
||||
m_mainLayoutPosition,
|
||||
m_LayoutChangeSpeed)
|
||||
.SetSpeedBased();
|
||||
MainMenu.ListenControlAction = true;
|
||||
MainMenu.ExitDetailState();
|
||||
|
||||
HideRomPreview();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,334 +1,332 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI : CommandExecuter
|
||||
{
|
||||
[SerializeField]
|
||||
RectTransform MenuRoot;
|
||||
[SerializeField]
|
||||
Selector SelectBorder;
|
||||
|
||||
Dictionary<Type, OptionUI_MenuItem> m_menuUI_templates = new Dictionary<Type, OptionUI_MenuItem>();
|
||||
|
||||
private OptionUI m_child;
|
||||
private OptionUI m_parent;
|
||||
|
||||
public override bool AloneMode => true;
|
||||
public override bool Enable => m_bPoped && (!m_child || !m_child.m_bPoped);
|
||||
|
||||
private bool m_bPoped;
|
||||
private readonly List<OptionUI_MenuItem> m_runtimeMenuItems = new List<OptionUI_MenuItem>();
|
||||
|
||||
private int m_selectIndex = -1;
|
||||
public int SelectIndex
|
||||
{
|
||||
get => m_selectIndex;
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp(value, 0, m_runtimeMenuItems.Count - 1);
|
||||
if (m_selectIndex == value) return;
|
||||
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI : CommandExecuter
|
||||
{
|
||||
[SerializeField]
|
||||
RectTransform MenuRoot;
|
||||
[SerializeField]
|
||||
Selector SelectBorder;
|
||||
|
||||
Dictionary<Type, OptionUI_MenuItem> m_menuUI_templates = new Dictionary<Type, OptionUI_MenuItem>();
|
||||
|
||||
private OptionUI m_child;
|
||||
private OptionUI m_parent;
|
||||
|
||||
public override bool AloneMode => true;
|
||||
public override bool Enable => m_bPoped && (!m_child || !m_child.m_bPoped);
|
||||
|
||||
private bool m_bPoped;
|
||||
private readonly List<OptionUI_MenuItem> m_runtimeMenuItems = new List<OptionUI_MenuItem>();
|
||||
|
||||
private int m_selectIndex = -1;
|
||||
public int SelectIndex
|
||||
{
|
||||
get => m_selectIndex;
|
||||
set
|
||||
{
|
||||
value = Mathf.Clamp(value, 0, m_runtimeMenuItems.Count - 1);
|
||||
if (m_selectIndex == value) return;
|
||||
|
||||
var gap = value - m_selectIndex;
|
||||
|
||||
var temp = value;
|
||||
while (!m_runtimeMenuItems[value].Visible)
|
||||
{
|
||||
if (gap > 0)
|
||||
{
|
||||
var temp = value;
|
||||
while (!m_runtimeMenuItems[value].Visible)
|
||||
{
|
||||
if (gap > 0)
|
||||
{
|
||||
temp++;
|
||||
if (temp >= m_runtimeMenuItems.Count) return;
|
||||
}
|
||||
else
|
||||
{
|
||||
temp--;
|
||||
if (temp < 0) return;
|
||||
}
|
||||
|
||||
if (temp >= 0 && temp < m_runtimeMenuItems.Count)
|
||||
value = temp;
|
||||
}
|
||||
|
||||
m_selectIndex = value;
|
||||
|
||||
OptionUI_MenuItem optionUI_MenuItem = m_runtimeMenuItems[m_selectIndex];
|
||||
optionUI_MenuItem.OnFocus();
|
||||
var itemUIRect = optionUI_MenuItem.transform as RectTransform;
|
||||
SelectBorder.Target = itemUIRect;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
temp--;
|
||||
if (temp < 0) return;
|
||||
}
|
||||
|
||||
if (temp >= 0 && temp < m_runtimeMenuItems.Count)
|
||||
value = temp;
|
||||
}
|
||||
|
||||
m_selectIndex = value;
|
||||
|
||||
OptionUI_MenuItem optionUI_MenuItem = m_runtimeMenuItems[m_selectIndex];
|
||||
optionUI_MenuItem.OnFocus();
|
||||
var itemUIRect = optionUI_MenuItem.transform as RectTransform;
|
||||
SelectBorder.Target = itemUIRect;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
foreach (var templateIns in GetComponentsInChildren<OptionUI_MenuItem>(true))
|
||||
{
|
||||
m_menuUI_templates[templateIns.GetType()] = templateIns;
|
||||
templateIns.gameObject.SetActiveEx(false);
|
||||
}
|
||||
|
||||
SelectBorder.gameObject.SetActiveEx(false);
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
SelectBorder.Active = Enable;
|
||||
UpdateMenuState();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
private void UpdateMenuState()
|
||||
{
|
||||
if (!m_bPoped) return;
|
||||
|
||||
if (checkDirty())
|
||||
}
|
||||
|
||||
SelectBorder.gameObject.SetActiveEx(false);
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
SelectBorder.Active = Enable;
|
||||
UpdateMenuState();
|
||||
|
||||
base.Update();
|
||||
}
|
||||
|
||||
private void UpdateMenuState()
|
||||
{
|
||||
if (!m_bPoped) return;
|
||||
|
||||
if (checkDirty())
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
var topParent = FindTopOptionUI();
|
||||
var totalWidth = GetTotalWidth(topParent);
|
||||
|
||||
Vector2 end = new Vector2(-totalWidth, MenuRoot.anchoredPosition.y);
|
||||
|
||||
if (m_popTween != null)
|
||||
{
|
||||
Vector2 end = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
|
||||
m_popTween.ChangeEndValue(end, false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
topParent.MenuRoot.anchoredPosition = end;
|
||||
Vector2 end = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
|
||||
var topParent = m_parent;
|
||||
while (topParent != null && topParent.m_parent != null)
|
||||
{
|
||||
topParent = topParent.m_parent;
|
||||
}
|
||||
if (topParent != null)
|
||||
{
|
||||
topParent.MenuRoot.anchoredPosition = end;
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuRoot.anchoredPosition = end;
|
||||
}
|
||||
}
|
||||
RebuildSelectIndex();
|
||||
}
|
||||
}
|
||||
|
||||
private void RebuildSelectIndex()
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
SelectIndex = Mathf.Clamp(SelectIndex, 0, m_runtimeMenuItems.Count - 1);
|
||||
var selectItem = m_runtimeMenuItems[SelectIndex];
|
||||
|
||||
if (selectItem.Visible == false)
|
||||
{
|
||||
bool find = false;
|
||||
int currentSelect = SelectIndex;
|
||||
while (currentSelect > 0)
|
||||
{
|
||||
currentSelect--;
|
||||
if (m_runtimeMenuItems[currentSelect].Visible)
|
||||
{
|
||||
find = true;
|
||||
}
|
||||
}
|
||||
if (!find)
|
||||
{
|
||||
currentSelect = SelectIndex;
|
||||
while (currentSelect < m_runtimeMenuItems.Count)
|
||||
{
|
||||
if (m_runtimeMenuItems[currentSelect].Visible)
|
||||
{
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
currentSelect++;
|
||||
}
|
||||
}
|
||||
|
||||
if (find)
|
||||
SelectIndex = currentSelect;
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemUIRect = selectItem.transform as RectTransform;
|
||||
SelectBorder.Target = itemUIRect;
|
||||
}
|
||||
}
|
||||
|
||||
private bool checkDirty()
|
||||
{
|
||||
bool dirty = false;
|
||||
foreach (var menuItem in m_runtimeMenuItems)
|
||||
{
|
||||
if (menuItem.gameObject.activeSelf != menuItem.Visible)
|
||||
{
|
||||
dirty = true;
|
||||
menuItem.gameObject.SetActive(menuItem.Visible);
|
||||
}
|
||||
}
|
||||
|
||||
return dirty;
|
||||
RebuildSelectIndex();
|
||||
}
|
||||
}
|
||||
|
||||
private TweenerCore<Vector2, Vector2, VectorOptions> m_popTween;
|
||||
private TweenerCore<Vector2, Vector2, VectorOptions> m_hideTween;
|
||||
CommandListener.ScheduleType? m_lastCS;
|
||||
private Action m_onClose;
|
||||
|
||||
/// <summary>
|
||||
/// 当菜单弹出时,动态添加一个菜单选项
|
||||
/// </summary>
|
||||
/// <param name="menu"></param>
|
||||
public void AddOptionMenuWhenPoping(InternalOptionMenu menu)
|
||||
{
|
||||
if (!m_bPoped) return;
|
||||
|
||||
CreateRuntimeMenuItem(menu);
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
OptionUI_MenuItem optionUI_MenuItem = m_runtimeMenuItems[m_selectIndex];
|
||||
SelectBorder.Target = null;
|
||||
SelectBorder.Target = optionUI_MenuItem.transform as RectTransform;
|
||||
}
|
||||
|
||||
|
||||
public void Pop<T>(List<T> menus, int defaultIndex = 0, Action onClose = null) where T : InternalOptionMenu
|
||||
private void RebuildSelectIndex()
|
||||
{
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
SelectIndex = Mathf.Clamp(SelectIndex, 0, m_runtimeMenuItems.Count - 1);
|
||||
var selectItem = m_runtimeMenuItems[SelectIndex];
|
||||
|
||||
if (selectItem.Visible == false)
|
||||
{
|
||||
bool find = false;
|
||||
int currentSelect = SelectIndex;
|
||||
while (currentSelect > 0)
|
||||
{
|
||||
currentSelect--;
|
||||
if (m_runtimeMenuItems[currentSelect].Visible)
|
||||
{
|
||||
find = true;
|
||||
}
|
||||
}
|
||||
if (!find)
|
||||
{
|
||||
currentSelect = SelectIndex;
|
||||
while (currentSelect < m_runtimeMenuItems.Count)
|
||||
{
|
||||
if (m_runtimeMenuItems[currentSelect].Visible)
|
||||
{
|
||||
find = true;
|
||||
break;
|
||||
}
|
||||
currentSelect++;
|
||||
}
|
||||
}
|
||||
|
||||
if (find)
|
||||
SelectIndex = currentSelect;
|
||||
}
|
||||
else
|
||||
{
|
||||
var itemUIRect = selectItem.transform as RectTransform;
|
||||
SelectBorder.Target = itemUIRect;
|
||||
}
|
||||
}
|
||||
|
||||
private bool checkDirty()
|
||||
{
|
||||
bool dirty = false;
|
||||
foreach (var menuItem in m_runtimeMenuItems)
|
||||
{
|
||||
if (menuItem.gameObject.activeSelf != menuItem.Visible)
|
||||
{
|
||||
dirty = true;
|
||||
menuItem.gameObject.SetActive(menuItem.Visible);
|
||||
}
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
private TweenerCore<Vector2, Vector2, VectorOptions> m_popTween;
|
||||
private TweenerCore<Vector2, Vector2, VectorOptions> m_hideTween;
|
||||
CommandListener.ScheduleType? m_lastCS;
|
||||
private Action m_onClose;
|
||||
|
||||
/// <summary>
|
||||
/// 当菜单弹出时,动态添加一个菜单选项
|
||||
/// </summary>
|
||||
/// <param name="menu"></param>
|
||||
public void AddOptionMenuWhenPoping(InternalOptionMenu menu)
|
||||
{
|
||||
if (!m_bPoped) return;
|
||||
|
||||
CreateRuntimeMenuItem(menu);
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
OptionUI_MenuItem optionUI_MenuItem = m_runtimeMenuItems[m_selectIndex];
|
||||
SelectBorder.Target = null;
|
||||
SelectBorder.Target = optionUI_MenuItem.transform as RectTransform;
|
||||
}
|
||||
|
||||
|
||||
public void Pop<T>(List<T> menus, int defaultIndex = 0, Action onClose = null) where T : InternalOptionMenu
|
||||
{
|
||||
if (m_hideTween != null)
|
||||
{
|
||||
m_hideTween.Kill(true);
|
||||
}
|
||||
|
||||
m_onClose = onClose;
|
||||
ReleaseRuntimeMenus();
|
||||
foreach (var menu in menus) CreateRuntimeMenuItem(menu);
|
||||
CommandDispatcher.Instance.RegistController(this);
|
||||
SelectBorder.gameObject.SetActiveEx(true);
|
||||
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
m_selectIndex = defaultIndex;
|
||||
OptionUI_MenuItem optionUI_MenuItem = m_runtimeMenuItems[defaultIndex];
|
||||
optionUI_MenuItem.OnFocus();
|
||||
|
||||
var itemUIRect = optionUI_MenuItem.transform as RectTransform;
|
||||
SelectBorder.Target = itemUIRect;
|
||||
SelectBorder.RefreshPosition();
|
||||
|
||||
if (!m_bPoped)
|
||||
{
|
||||
m_bPoped = true;
|
||||
Vector2 start = new Vector2(0, MenuRoot.anchoredPosition.y);
|
||||
Vector2 end = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
|
||||
m_popTween = DOTween.To(
|
||||
() => start,
|
||||
(value) =>
|
||||
{
|
||||
var moveDelta = value - start;
|
||||
start = value;
|
||||
|
||||
var topParent = FindTopOptionUI();
|
||||
topParent.MenuRoot.anchoredPosition += moveDelta;
|
||||
},
|
||||
end,
|
||||
0.3f
|
||||
).SetEase(Ease.OutCubic);
|
||||
m_popTween.onComplete = () => m_popTween = null;
|
||||
|
||||
m_lastCS = CommandDispatcher.Instance.Mode;
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
|
||||
}
|
||||
}
|
||||
|
||||
OptionUI FindTopOptionUI()
|
||||
{
|
||||
if (m_parent == null) return this;
|
||||
}
|
||||
|
||||
var topParent = m_parent;
|
||||
while (topParent != null && topParent.m_parent != null)
|
||||
m_onClose = onClose;
|
||||
ReleaseRuntimeMenus();
|
||||
foreach (var menu in menus) CreateRuntimeMenuItem(menu);
|
||||
CommandDispatcher.Instance.RegistController(this);
|
||||
SelectBorder.gameObject.SetActiveEx(true);
|
||||
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
m_selectIndex = defaultIndex;
|
||||
OptionUI_MenuItem optionUI_MenuItem = m_runtimeMenuItems[defaultIndex];
|
||||
optionUI_MenuItem.OnFocus();
|
||||
|
||||
var itemUIRect = optionUI_MenuItem.transform as RectTransform;
|
||||
SelectBorder.Target = itemUIRect;
|
||||
SelectBorder.RefreshPosition();
|
||||
|
||||
if (!m_bPoped)
|
||||
{
|
||||
topParent = topParent.m_parent;
|
||||
}
|
||||
|
||||
return topParent;
|
||||
}
|
||||
|
||||
static float GetTotalWidth(OptionUI root)
|
||||
{
|
||||
float totalWidth = root.MenuRoot.rect.width;
|
||||
if (root.m_child != null)
|
||||
{
|
||||
totalWidth += GetTotalWidth(root.m_child);
|
||||
}
|
||||
|
||||
return totalWidth;
|
||||
}
|
||||
|
||||
|
||||
m_bPoped = true;
|
||||
Vector2 start = new Vector2(0, MenuRoot.anchoredPosition.y);
|
||||
Vector2 end = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
|
||||
m_popTween = DOTween.To(
|
||||
() => start,
|
||||
(value) =>
|
||||
{
|
||||
var moveDelta = value - start;
|
||||
start = value;
|
||||
|
||||
var topParent = m_parent;
|
||||
while (topParent != null && topParent.m_parent != null)
|
||||
{
|
||||
topParent = topParent.m_parent;
|
||||
}
|
||||
if (topParent != null)
|
||||
{
|
||||
topParent.MenuRoot.anchoredPosition += moveDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuRoot.anchoredPosition += moveDelta;
|
||||
}
|
||||
},
|
||||
end,
|
||||
0.3f
|
||||
).SetEase(Ease.OutCubic);
|
||||
m_popTween.onComplete = () => m_popTween = null;
|
||||
|
||||
m_lastCS = CommandDispatcher.Instance.Mode;
|
||||
CommandDispatcher.Instance.Mode = CommandListener.ScheduleType.Normal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关闭这个侧边栏选项UI
|
||||
/// </summary>
|
||||
public void Hide()
|
||||
{
|
||||
if (m_bPoped)
|
||||
{
|
||||
public void Hide()
|
||||
{
|
||||
if (m_bPoped)
|
||||
{
|
||||
if (m_child != null)
|
||||
{
|
||||
m_child.Hide();
|
||||
}
|
||||
|
||||
Vector2 start = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
|
||||
Vector2 end = new Vector2(0, MenuRoot.anchoredPosition.y);
|
||||
|
||||
SelectBorder.gameObject.SetActiveEx(false);
|
||||
|
||||
CommandDispatcher.Instance.UnRegistController(this);
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
}
|
||||
|
||||
Vector2 start = new Vector2(-MenuRoot.rect.width, MenuRoot.anchoredPosition.y);
|
||||
Vector2 end = new Vector2(0, MenuRoot.anchoredPosition.y);
|
||||
|
||||
SelectBorder.gameObject.SetActiveEx(false);
|
||||
|
||||
CommandDispatcher.Instance.UnRegistController(this);
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
if (m_popTween != null)
|
||||
{
|
||||
m_popTween.Kill(true);
|
||||
}
|
||||
|
||||
m_hideTween = DOTween.To(
|
||||
() => start,
|
||||
(value) =>
|
||||
{
|
||||
var moveDelta = value - start;
|
||||
start = value;
|
||||
|
||||
var topParent = m_parent;
|
||||
while (topParent != null && topParent.m_parent != null)
|
||||
{
|
||||
topParent = topParent.m_parent;
|
||||
}
|
||||
if (topParent != null)
|
||||
{
|
||||
topParent.MenuRoot.anchoredPosition += moveDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuRoot.anchoredPosition += moveDelta;
|
||||
}
|
||||
},
|
||||
end,
|
||||
0.3f
|
||||
).SetEase(Ease.OutCubic);
|
||||
m_popTween.Kill(true);
|
||||
}
|
||||
|
||||
m_hideTween = DOTween.To(
|
||||
() => start,
|
||||
(value) =>
|
||||
{
|
||||
var moveDelta = value - start;
|
||||
start = value;
|
||||
|
||||
var topParent = m_parent;
|
||||
while (topParent != null && topParent.m_parent != null)
|
||||
{
|
||||
topParent = topParent.m_parent;
|
||||
}
|
||||
if (topParent != null)
|
||||
{
|
||||
topParent.MenuRoot.anchoredPosition += moveDelta;
|
||||
}
|
||||
else
|
||||
{
|
||||
MenuRoot.anchoredPosition += moveDelta;
|
||||
}
|
||||
},
|
||||
end,
|
||||
0.3f
|
||||
).SetEase(Ease.OutCubic);
|
||||
m_hideTween.onComplete = () =>
|
||||
{
|
||||
ReleaseRuntimeMenus();
|
||||
m_runtimeMenuItems.Clear();
|
||||
m_hideTween = null;
|
||||
};
|
||||
|
||||
m_bPoped = false;
|
||||
|
||||
CommandDispatcher.Instance.Mode = m_lastCS.Value;
|
||||
|
||||
m_onClose?.Invoke();
|
||||
m_onClose = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateRuntimeMenuItem(InternalOptionMenu menuData)
|
||||
{
|
||||
m_menuUI_templates.TryGetValue(menuData.MenuUITemplateType, out var template);
|
||||
};
|
||||
|
||||
m_bPoped = false;
|
||||
|
||||
CommandDispatcher.Instance.Mode = m_lastCS.Value;
|
||||
|
||||
m_onClose?.Invoke();
|
||||
m_onClose = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CreateRuntimeMenuItem(InternalOptionMenu menuData)
|
||||
{
|
||||
m_menuUI_templates.TryGetValue(menuData.MenuUITemplateType, out var template);
|
||||
if (template == null)
|
||||
{
|
||||
throw new NotImplementedException($"{menuData.GetType().Name}指定的MenuUI类型实例未在OptionUI中找到");
|
||||
@ -338,158 +336,158 @@ namespace AxibugEmuOnline.Client
|
||||
menuUI.gameObject.SetActive(true);
|
||||
menuUI.SetData(this, menuData);
|
||||
m_runtimeMenuItems.Add(menuUI);
|
||||
}
|
||||
|
||||
private void ReleaseRuntimeMenus()
|
||||
{
|
||||
foreach (var item in m_runtimeMenuItems)
|
||||
{
|
||||
item.OnHide();
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
m_runtimeMenuItems.Clear();
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemDown()
|
||||
}
|
||||
|
||||
private void ReleaseRuntimeMenus()
|
||||
{
|
||||
foreach (var item in m_runtimeMenuItems)
|
||||
{
|
||||
item.OnHide();
|
||||
Destroy(item.gameObject);
|
||||
}
|
||||
m_runtimeMenuItems.Clear();
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemDown()
|
||||
{
|
||||
int old = SelectIndex;
|
||||
SelectIndex++;
|
||||
if (old != SelectIndex)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemUp()
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemUp()
|
||||
{
|
||||
int old = SelectIndex;
|
||||
SelectIndex--;
|
||||
if (old != SelectIndex)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
}
|
||||
|
||||
protected override void OnCmdBack()
|
||||
{
|
||||
Hide();
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cancel);
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemLeft()
|
||||
{
|
||||
var executer = m_runtimeMenuItems[SelectIndex];
|
||||
if (executer)
|
||||
{
|
||||
executer.OnLeft();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemRight()
|
||||
{
|
||||
var executer = m_runtimeMenuItems[SelectIndex];
|
||||
if (!executer.IsExpandMenu)
|
||||
{
|
||||
executer.OnRight();
|
||||
return;
|
||||
}
|
||||
|
||||
OnCmdEnter();
|
||||
}
|
||||
|
||||
protected override bool OnCmdEnter()
|
||||
{
|
||||
var executer = m_runtimeMenuItems[SelectIndex];
|
||||
bool cancelHide = false;
|
||||
executer.OnExecute(this, ref cancelHide);
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
}
|
||||
|
||||
protected override void OnCmdBack()
|
||||
{
|
||||
Hide();
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cancel);
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemLeft()
|
||||
{
|
||||
var executer = m_runtimeMenuItems[SelectIndex];
|
||||
if (executer)
|
||||
{
|
||||
executer.OnLeft();
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemRight()
|
||||
{
|
||||
var executer = m_runtimeMenuItems[SelectIndex];
|
||||
if (!executer.IsExpandMenu)
|
||||
{
|
||||
executer.OnRight();
|
||||
return;
|
||||
}
|
||||
|
||||
OnCmdEnter();
|
||||
}
|
||||
|
||||
protected override bool OnCmdEnter()
|
||||
{
|
||||
var executer = m_runtimeMenuItems[SelectIndex];
|
||||
bool cancelHide = false;
|
||||
executer.OnExecute(this, ref cancelHide);
|
||||
if (!cancelHide) Hide();
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 展开下级菜单
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="menus"></param>
|
||||
/// <param name="defaultIndex"></param>
|
||||
/// <param name="onClose"></param>
|
||||
public void ExpandSubMenu<T>(List<T> menus, int defaultIndex = 0, Action onClose = null) where T : InternalOptionMenu
|
||||
{
|
||||
if (m_child == null)
|
||||
{
|
||||
var sourcePrefab = Resources.Load<GameObject>("UIPrefabs/OptionUI");
|
||||
m_child = Instantiate(sourcePrefab, transform).GetComponent<OptionUI>();
|
||||
m_child.name = $"{name}_Sub";
|
||||
m_child.m_parent = this;
|
||||
}
|
||||
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
m_child.Pop(menus, 0, onClose);
|
||||
}
|
||||
|
||||
public void RemoveItem(OptionUI_MenuItem ui)
|
||||
{
|
||||
var index = m_runtimeMenuItems.IndexOf(ui);
|
||||
if (index == -1) return;
|
||||
|
||||
m_runtimeMenuItems.Remove(ui);
|
||||
ui.OnHide();
|
||||
Destroy(ui.gameObject);
|
||||
|
||||
RebuildSelectIndex();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带有执行行为的菜单
|
||||
/// </summary>
|
||||
public abstract class ExecuteMenu : InternalOptionMenu
|
||||
{
|
||||
public override Type MenuUITemplateType => typeof(OptionUI_ExecuteItem);
|
||||
/// <summary> 设置这个值以控制菜单中显示"已应用"标记 </summary>
|
||||
public virtual bool IsApplied { get; }
|
||||
|
||||
public abstract void OnExcute(OptionUI optionUI, ref bool cancelHide);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带有展开行为的可执行菜单
|
||||
/// </summary>
|
||||
public abstract class ExpandMenu : ExecuteMenu
|
||||
{
|
||||
protected ExpandMenu() : base() { }
|
||||
|
||||
public sealed override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
cancelHide = true;
|
||||
optionUI.ExpandSubMenu(GetOptionMenus());
|
||||
}
|
||||
|
||||
protected abstract List<InternalOptionMenu> GetOptionMenus();
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 展开下级菜单
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="menus"></param>
|
||||
/// <param name="defaultIndex"></param>
|
||||
/// <param name="onClose"></param>
|
||||
public void ExpandSubMenu<T>(List<T> menus, int defaultIndex = 0, Action onClose = null) where T : InternalOptionMenu
|
||||
{
|
||||
if (m_child == null)
|
||||
{
|
||||
var sourcePrefab = Resources.Load<GameObject>("UIPrefabs/OptionUI");
|
||||
m_child = Instantiate(sourcePrefab, transform).GetComponent<OptionUI>();
|
||||
m_child.name = $"{name}_Sub";
|
||||
m_child.m_parent = this;
|
||||
}
|
||||
|
||||
Canvas.ForceUpdateCanvases();
|
||||
|
||||
m_child.Pop(menus, 0, onClose);
|
||||
}
|
||||
|
||||
public void RemoveItem(OptionUI_MenuItem ui)
|
||||
{
|
||||
var index = m_runtimeMenuItems.IndexOf(ui);
|
||||
if (index == -1) return;
|
||||
|
||||
m_runtimeMenuItems.Remove(ui);
|
||||
ui.OnHide();
|
||||
Destroy(ui.gameObject);
|
||||
|
||||
RebuildSelectIndex();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 带有值类型显示和编辑的菜单
|
||||
/// </summary>
|
||||
public abstract class ValueSetMenu : InternalOptionMenu
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 带有执行行为的菜单
|
||||
/// </summary>
|
||||
public abstract class ExecuteMenu : InternalOptionMenu
|
||||
{
|
||||
public override Type MenuUITemplateType => typeof(OptionUI_ExecuteItem);
|
||||
/// <summary> 设置这个值以控制菜单中显示"已应用"标记 </summary>
|
||||
public virtual bool IsApplied { get; }
|
||||
|
||||
public abstract void OnExcute(OptionUI optionUI, ref bool cancelHide);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 带有展开行为的可执行菜单
|
||||
/// </summary>
|
||||
public abstract class ExpandMenu : ExecuteMenu
|
||||
{
|
||||
protected ExpandMenu() : base() { }
|
||||
|
||||
public sealed override void OnExcute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
cancelHide = true;
|
||||
optionUI.ExpandSubMenu(GetOptionMenus());
|
||||
}
|
||||
|
||||
protected abstract List<InternalOptionMenu> GetOptionMenus();
|
||||
}
|
||||
/// <summary>
|
||||
/// 带有值类型显示和编辑的菜单
|
||||
/// </summary>
|
||||
public abstract class ValueSetMenu : InternalOptionMenu
|
||||
{
|
||||
public override Type MenuUITemplateType => typeof(OptionUI_ValueEditItem);
|
||||
protected ValueSetMenu() : base() { }
|
||||
|
||||
public abstract Type ValueType { get; }
|
||||
public abstract object ValueRaw { get; }
|
||||
public abstract void OnValueChanged(object newValue);
|
||||
public abstract object Min { get; }
|
||||
public abstract object Max { get; }
|
||||
}
|
||||
|
||||
/// <summary> 不要直接继承这个类 </summary>
|
||||
public abstract class InternalOptionMenu
|
||||
{
|
||||
public abstract Type MenuUITemplateType { get; }
|
||||
public abstract string Name { get; }
|
||||
public virtual Sprite Icon { get; }
|
||||
public virtual bool Visible => true;
|
||||
|
||||
public virtual void OnFocus() { }
|
||||
public virtual void OnShow(OptionUI_MenuItem ui) { }
|
||||
protected ValueSetMenu() : base() { }
|
||||
|
||||
public abstract Type ValueType { get; }
|
||||
public abstract object ValueRaw { get; }
|
||||
public abstract void OnValueChanged(object newValue);
|
||||
public abstract object Min { get; }
|
||||
public abstract object Max { get; }
|
||||
}
|
||||
|
||||
/// <summary> 不要直接继承这个类 </summary>
|
||||
public abstract class InternalOptionMenu
|
||||
{
|
||||
public abstract Type MenuUITemplateType { get; }
|
||||
public abstract string Name { get; }
|
||||
public virtual Sprite Icon { get; }
|
||||
public virtual bool Visible => true;
|
||||
|
||||
public virtual void OnFocus() { }
|
||||
public virtual void OnShow(OptionUI_MenuItem ui) { }
|
||||
public virtual void OnHide() { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,28 +1,28 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_ExecuteItem : OptionUI_MenuItem<ExecuteMenu>
|
||||
{
|
||||
public GameObject ExpandFlag;
|
||||
public GameObject ApplyFlag;
|
||||
|
||||
protected override void OnSetData(InternalOptionMenu menuData)
|
||||
{
|
||||
base.OnSetData(menuData);
|
||||
|
||||
ExpandFlag.SetActiveEx(IsExpandMenu);
|
||||
ApplyFlag.SetActiveEx(IsApplied);
|
||||
}
|
||||
|
||||
public override void OnExecute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
MenuData.OnExcute(optionUI, ref cancelHide);
|
||||
}
|
||||
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_ExecuteItem : OptionUI_MenuItem<ExecuteMenu>
|
||||
{
|
||||
public GameObject ExpandFlag;
|
||||
public GameObject ApplyFlag;
|
||||
|
||||
protected override void OnSetData(InternalOptionMenu menuData)
|
||||
{
|
||||
base.OnSetData(menuData);
|
||||
|
||||
ExpandFlag.SetActiveEx(IsExpandMenu);
|
||||
ApplyFlag.SetActiveEx(IsApplied);
|
||||
}
|
||||
|
||||
public override void OnExecute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
MenuData.OnExcute(optionUI, ref cancelHide);
|
||||
}
|
||||
|
||||
protected override void Update()
|
||||
{
|
||||
ApplyFlag.SetActiveEx(IsApplied);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
using AxibugEmuOnline.Client.Tools;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static AxibugEmuOnline.Client.InGameUI_SaveStateMenu;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_SavSlotItem : OptionUI_MenuItem<SaveSlotMenu>
|
||||
using AxibugEmuOnline.Client.Tools;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using static AxibugEmuOnline.Client.InGameUI_SaveStateMenu;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_SavSlotItem : OptionUI_MenuItem<SaveSlotMenu>
|
||||
{
|
||||
public RawImage UI_ScreenShot;
|
||||
public Image UI_Empty;
|
||||
@ -113,5 +113,5 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
MenuData.OnExcute(optionUI, ref cancelHide);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,84 +1,84 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_ValueEditItem : OptionUI_MenuItem<ValueSetMenu>
|
||||
{
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_FloatEdit com_floatEdit;
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_IntEdit com_intEdit;
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_BoolEdit com_boolEdit;
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_EnumEdit com_enumEdit;
|
||||
|
||||
IValueEditControl m_currentCom;
|
||||
|
||||
protected override void OnSetData(InternalOptionMenu menuData)
|
||||
{
|
||||
com_floatEdit.gameObject.SetActive(false);
|
||||
com_intEdit.gameObject.SetActive(false);
|
||||
com_boolEdit.gameObject.SetActive(false);
|
||||
com_enumEdit.gameObject.SetActive(false);
|
||||
|
||||
if (menuData is ValueSetMenu)
|
||||
{
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_ValueEditItem : OptionUI_MenuItem<ValueSetMenu>
|
||||
{
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_FloatEdit com_floatEdit;
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_IntEdit com_intEdit;
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_BoolEdit com_boolEdit;
|
||||
[SerializeField]
|
||||
OptionUI_ValueEditItem_EnumEdit com_enumEdit;
|
||||
|
||||
IValueEditControl m_currentCom;
|
||||
|
||||
protected override void OnSetData(InternalOptionMenu menuData)
|
||||
{
|
||||
com_floatEdit.gameObject.SetActive(false);
|
||||
com_intEdit.gameObject.SetActive(false);
|
||||
com_boolEdit.gameObject.SetActive(false);
|
||||
com_enumEdit.gameObject.SetActive(false);
|
||||
|
||||
if (menuData is ValueSetMenu)
|
||||
{
|
||||
var valueMenu = (ValueSetMenu)menuData;
|
||||
if (valueMenu.ValueType == typeof(float))
|
||||
{
|
||||
m_currentCom = com_floatEdit;
|
||||
}
|
||||
if (valueMenu.ValueType == typeof(float))
|
||||
{
|
||||
m_currentCom = com_floatEdit;
|
||||
}
|
||||
else if (valueMenu.ValueType == typeof(int))
|
||||
{
|
||||
m_currentCom = com_intEdit;
|
||||
}
|
||||
}
|
||||
else if (valueMenu.ValueType == typeof(bool))
|
||||
{
|
||||
m_currentCom = com_boolEdit;
|
||||
}
|
||||
else if (valueMenu.ValueType.IsEnum)
|
||||
{
|
||||
m_currentCom = com_enumEdit;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.log.Error($"尚未支持的数据类型:{valueMenu.ValueType}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_currentCom.gameObject.SetActiveEx(true);
|
||||
m_currentCom.SetData(valueMenu);
|
||||
}
|
||||
|
||||
base.OnSetData(menuData);
|
||||
}
|
||||
|
||||
public override void OnExecute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
cancelHide = true;
|
||||
m_currentCom?.OnExecute();
|
||||
}
|
||||
|
||||
public override void OnLeft()
|
||||
{
|
||||
m_currentCom?.OnLeft();
|
||||
}
|
||||
|
||||
public override void OnRight()
|
||||
{
|
||||
m_currentCom?.OnRight();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IValueEditControl
|
||||
{
|
||||
void SetData(ValueSetMenu valueMenu);
|
||||
GameObject gameObject { get; }
|
||||
void OnLeft();
|
||||
void OnRight();
|
||||
void OnExecute();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (valueMenu.ValueType.IsEnum)
|
||||
{
|
||||
m_currentCom = com_enumEdit;
|
||||
}
|
||||
else
|
||||
{
|
||||
App.log.Error($"尚未支持的数据类型:{valueMenu.ValueType}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_currentCom.gameObject.SetActiveEx(true);
|
||||
m_currentCom.SetData(valueMenu);
|
||||
}
|
||||
|
||||
base.OnSetData(menuData);
|
||||
}
|
||||
|
||||
public override void OnExecute(OptionUI optionUI, ref bool cancelHide)
|
||||
{
|
||||
cancelHide = true;
|
||||
m_currentCom?.OnExecute();
|
||||
}
|
||||
|
||||
public override void OnLeft()
|
||||
{
|
||||
m_currentCom?.OnLeft();
|
||||
}
|
||||
|
||||
public override void OnRight()
|
||||
{
|
||||
m_currentCom?.OnRight();
|
||||
}
|
||||
}
|
||||
|
||||
public interface IValueEditControl
|
||||
{
|
||||
void SetData(ValueSetMenu valueMenu);
|
||||
GameObject gameObject { get; }
|
||||
void OnLeft();
|
||||
void OnRight();
|
||||
void OnExecute();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,37 +1,37 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_ValueEditItem_BoolEdit : MonoBehaviour, IValueEditControl
|
||||
{
|
||||
[SerializeField]
|
||||
Text txt_value;
|
||||
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class OptionUI_ValueEditItem_BoolEdit : MonoBehaviour, IValueEditControl
|
||||
{
|
||||
[SerializeField]
|
||||
Text txt_value;
|
||||
|
||||
private ValueSetMenu m_valueMenu;
|
||||
|
||||
public void SetData(ValueSetMenu valueMenu)
|
||||
{
|
||||
m_valueMenu = valueMenu;
|
||||
txt_value.text = valueMenu.ValueRaw.ToString();
|
||||
}
|
||||
|
||||
public void OnLeft()
|
||||
{
|
||||
OnExecute();
|
||||
}
|
||||
|
||||
public void OnRight()
|
||||
{
|
||||
OnExecute();
|
||||
}
|
||||
|
||||
public void OnExecute()
|
||||
public void SetData(ValueSetMenu valueMenu)
|
||||
{
|
||||
m_valueMenu = valueMenu;
|
||||
txt_value.text = valueMenu.ValueRaw.ToString();
|
||||
}
|
||||
|
||||
public void OnLeft()
|
||||
{
|
||||
OnExecute();
|
||||
}
|
||||
|
||||
public void OnRight()
|
||||
{
|
||||
OnExecute();
|
||||
}
|
||||
|
||||
public void OnExecute()
|
||||
{
|
||||
var value = (bool)m_valueMenu.ValueRaw;
|
||||
value = !value;
|
||||
txt_value.text = value.ToString();
|
||||
m_valueMenu.OnValueChanged(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
value = !value;
|
||||
txt_value.text = value.ToString();
|
||||
m_valueMenu.OnValueChanged(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Manager;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using AxibugProtobuf;
|
||||
using Coffee.UIExtensions;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Debug = System.Diagnostics.Debug;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.Event;
|
||||
using AxibugEmuOnline.Client.Manager;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using AxibugProtobuf;
|
||||
using Coffee.UIExtensions;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Debug = System.Diagnostics.Debug;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class RoomItem : MenuItem, IVirtualItem
|
||||
{
|
||||
@ -17,7 +17,7 @@ namespace AxibugEmuOnline.Client
|
||||
[SerializeField] Slider m_downloadProgress;
|
||||
[SerializeField] GameObject m_downloadingFlag;
|
||||
[SerializeField] GameObject m_romReadyFlag;
|
||||
[SerializeField]
|
||||
[SerializeField]
|
||||
UIShiny DownloadComplete;
|
||||
|
||||
private RomFile m_romFile;
|
||||
@ -172,5 +172,5 @@ namespace AxibugEmuOnline.Client
|
||||
{
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,235 +1,235 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class SubMenuItemGroup : MenuItemController<MenuData>
|
||||
{
|
||||
[SerializeField]
|
||||
MenuItem SubMenuItemTemplate;
|
||||
[SerializeField]
|
||||
CanvasGroup alphaGroup;
|
||||
private TweenerCore<float, float, FloatOptions> selectTween;
|
||||
|
||||
private bool m_selected;
|
||||
|
||||
private TweenerCore<int, int, NoOptions> rollTween;
|
||||
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
m_selected = false;
|
||||
if (alphaGroup != null) alphaGroup.alpha = 0;
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
public override void Init(List<MenuData> menuDataList)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
while (transform.childCount > 0)
|
||||
{
|
||||
DestroyImmediate(transform.GetChild(0).gameObject);
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < transform.childCount; i++)
|
||||
{
|
||||
Destroy(transform.GetChild(i).gameObject);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_runtimeMenuUI.Clear();
|
||||
foreach (MenuData menuData in menuDataList)
|
||||
{
|
||||
var template = menuData.OverrideTemplate != null ? menuData.OverrideTemplate : SubMenuItemTemplate;
|
||||
|
||||
var item = Clone(template, transform);
|
||||
item.SetData(menuData);
|
||||
m_runtimeMenuUI.Add(item);
|
||||
}
|
||||
|
||||
calcItemPosition();
|
||||
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
var needPos = m_itemUIPosition[i];
|
||||
item.Rect.anchoredPosition = needPos;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnCmdEnter()
|
||||
{
|
||||
base.OnCmdEnter();
|
||||
|
||||
LaunchUI.Instance.ToDetailMenuLayout();
|
||||
var item = GetItemUIByIndex(SelectIndex);
|
||||
item.SetSelectState(false);
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnCmdBack()
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public class SubMenuItemGroup : MenuItemController<MenuData>
|
||||
{
|
||||
[SerializeField]
|
||||
MenuItem SubMenuItemTemplate;
|
||||
[SerializeField]
|
||||
CanvasGroup alphaGroup;
|
||||
private TweenerCore<float, float, FloatOptions> selectTween;
|
||||
|
||||
private bool m_selected;
|
||||
|
||||
private TweenerCore<int, int, NoOptions> rollTween;
|
||||
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
if (m_enteredItem != null)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cancel);
|
||||
|
||||
base.OnCmdBack();
|
||||
|
||||
LaunchUI.Instance.ToMainMenuLayout();
|
||||
var item = GetItemUIByIndex(SelectIndex);
|
||||
m_selected = false;
|
||||
if (alphaGroup != null) alphaGroup.alpha = 0;
|
||||
|
||||
base.Awake();
|
||||
}
|
||||
|
||||
public override void Init(List<MenuData> menuDataList)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
while (transform.childCount > 0)
|
||||
{
|
||||
DestroyImmediate(transform.GetChild(0).gameObject);
|
||||
}
|
||||
#else
|
||||
for (int i = 0; i < transform.childCount; i++)
|
||||
{
|
||||
Destroy(transform.GetChild(i).gameObject);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_runtimeMenuUI.Clear();
|
||||
foreach (MenuData menuData in menuDataList)
|
||||
{
|
||||
var template = menuData.OverrideTemplate != null ? menuData.OverrideTemplate : SubMenuItemTemplate;
|
||||
|
||||
var item = Clone(template, transform);
|
||||
item.SetData(menuData);
|
||||
m_runtimeMenuUI.Add(item);
|
||||
}
|
||||
|
||||
calcItemPosition();
|
||||
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
var needPos = m_itemUIPosition[i];
|
||||
item.Rect.anchoredPosition = needPos;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool OnCmdEnter()
|
||||
{
|
||||
base.OnCmdEnter();
|
||||
|
||||
LaunchUI.Instance.ToDetailMenuLayout();
|
||||
var item = GetItemUIByIndex(SelectIndex);
|
||||
item.SetSelectState(false);
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void OnCmdBack()
|
||||
{
|
||||
if (m_enteredItem != null)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cancel);
|
||||
|
||||
base.OnCmdBack();
|
||||
|
||||
LaunchUI.Instance.ToMainMenuLayout();
|
||||
var item = GetItemUIByIndex(SelectIndex);
|
||||
item.SetSelectState(true);
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemUp()
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemUp()
|
||||
{
|
||||
if (m_enteredItem == null)
|
||||
{
|
||||
int old = SelectIndex;
|
||||
SelectIndex--;
|
||||
if (old != SelectIndex)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cursor);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemDown()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemDown()
|
||||
{
|
||||
if (m_enteredItem == null)
|
||||
{
|
||||
int old = SelectIndex;
|
||||
SelectIndex++;
|
||||
if (old != SelectIndex)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cursor);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetSelect(bool select)
|
||||
{
|
||||
if (m_selected == select) return;
|
||||
m_selected = select;
|
||||
|
||||
if (selectTween != null)
|
||||
{
|
||||
selectTween.Kill();
|
||||
selectTween = null;
|
||||
}
|
||||
|
||||
if (select)
|
||||
{
|
||||
selectTween = DOTween.To(() => alphaGroup.alpha, (x) => alphaGroup.alpha = x, 1, 10).SetSpeedBased();
|
||||
}
|
||||
else
|
||||
{
|
||||
selectTween = DOTween.To(() => alphaGroup.alpha, (x) => alphaGroup.alpha = x, 0, 10).SetSpeedBased();
|
||||
}
|
||||
|
||||
ListenControlAction = m_selected;
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemLeft()
|
||||
{
|
||||
if(m_enteredItem != null)
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void SetSelect(bool select)
|
||||
{
|
||||
if (m_selected == select) return;
|
||||
m_selected = select;
|
||||
|
||||
if (selectTween != null)
|
||||
{
|
||||
selectTween.Kill();
|
||||
selectTween = null;
|
||||
}
|
||||
|
||||
if (select)
|
||||
{
|
||||
selectTween = DOTween.To(() => alphaGroup.alpha, (x) => alphaGroup.alpha = x, 1, 10).SetSpeedBased();
|
||||
}
|
||||
else
|
||||
{
|
||||
selectTween = DOTween.To(() => alphaGroup.alpha, (x) => alphaGroup.alpha = x, 0, 10).SetSpeedBased();
|
||||
}
|
||||
|
||||
ListenControlAction = m_selected;
|
||||
}
|
||||
|
||||
protected override void OnCmdSelectItemLeft()
|
||||
{
|
||||
if(m_enteredItem != null)
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Cancel);
|
||||
else
|
||||
App.audioMgr.PlaySFX(AudioMgr.E_SFXTYPE.Option);
|
||||
|
||||
base.OnCmdSelectItemLeft();
|
||||
OnCmdBack();
|
||||
}
|
||||
|
||||
protected override void OnSelectMenuChanged()
|
||||
{
|
||||
if (rollTween != null) { rollTween.Kill(); rollTween = null; }
|
||||
|
||||
float duration = 0.5f;
|
||||
|
||||
calcItemPosition();
|
||||
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
bool isSelectItem = i == SelectIndex;
|
||||
item.SetSelectState(isSelectItem);
|
||||
}
|
||||
|
||||
rollTween = DOTween.To(() => 1, (x) => { }, 1, duration).OnUpdate(() =>
|
||||
{
|
||||
var tweenProgress = rollTween.position / rollTween.Duration();
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
var needPos = m_itemUIPosition[i];
|
||||
item.Rect.anchoredPosition = Vector2.Lerp(item.Rect.anchoredPosition, needPos, tweenProgress);
|
||||
}
|
||||
}).OnComplete(() =>
|
||||
{
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
var needPos = m_itemUIPosition[i];
|
||||
item.Rect.anchoredPosition = needPos;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_selectItemPosition = new Vector2(50, -51);
|
||||
[SerializeField]
|
||||
float step = 50f;
|
||||
[SerializeField]
|
||||
float splitStep = 200f;
|
||||
|
||||
List<Vector2> m_itemUIPosition = new List<Vector2>();
|
||||
private void calcItemPosition()
|
||||
{
|
||||
m_itemUIPosition.Clear();
|
||||
for (int i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var gap = SelectIndex - i;
|
||||
var start = m_selectItemPosition;
|
||||
start.y += step * gap;
|
||||
if (i < SelectIndex) start.y += splitStep;
|
||||
|
||||
m_itemUIPosition.Add(start);
|
||||
}
|
||||
}
|
||||
|
||||
private MenuItem Clone(MenuItem template, Transform parent)
|
||||
OnCmdBack();
|
||||
}
|
||||
|
||||
protected override void OnSelectMenuChanged()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
if (rollTween != null) { rollTween.Kill(); rollTween = null; }
|
||||
|
||||
float duration = 0.5f;
|
||||
|
||||
calcItemPosition();
|
||||
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
bool isSelectItem = i == SelectIndex;
|
||||
item.SetSelectState(isSelectItem);
|
||||
}
|
||||
|
||||
rollTween = DOTween.To(() => 1, (x) => { }, 1, duration).OnUpdate(() =>
|
||||
{
|
||||
var tweenProgress = rollTween.position / rollTween.Duration();
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
var needPos = m_itemUIPosition[i];
|
||||
item.Rect.anchoredPosition = Vector2.Lerp(item.Rect.anchoredPosition, needPos, tweenProgress);
|
||||
}
|
||||
}).OnComplete(() =>
|
||||
{
|
||||
for (var i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var item = m_runtimeMenuUI[i];
|
||||
var needPos = m_itemUIPosition[i];
|
||||
item.Rect.anchoredPosition = needPos;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[SerializeField]
|
||||
Vector2 m_selectItemPosition = new Vector2(50, -51);
|
||||
[SerializeField]
|
||||
float step = 50f;
|
||||
[SerializeField]
|
||||
float splitStep = 200f;
|
||||
|
||||
List<Vector2> m_itemUIPosition = new List<Vector2>();
|
||||
private void calcItemPosition()
|
||||
{
|
||||
m_itemUIPosition.Clear();
|
||||
for (int i = 0; i < m_runtimeMenuUI.Count; i++)
|
||||
{
|
||||
var gap = SelectIndex - i;
|
||||
var start = m_selectItemPosition;
|
||||
start.y += step * gap;
|
||||
if (i < SelectIndex) start.y += splitStep;
|
||||
|
||||
m_itemUIPosition.Add(start);
|
||||
}
|
||||
}
|
||||
|
||||
private MenuItem Clone(MenuItem template, Transform parent)
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
|
||||
//========================套娃宏========================
|
||||
#if UNITY_2019_1_OR_NEWER //新版Unity,因UNITY2018.2用不了这玩意儿,编辑器也罢
|
||||
#if UNITY_2019_1_OR_NEWER //新版Unity,因UNITY2018.2用不了这玩意儿,编辑器也罢
|
||||
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
var item = GameObject.Instantiate(template.gameObject, parent).GetComponent<MenuItem>();
|
||||
item.transform.localPosition = Vector3.zero;
|
||||
return item;
|
||||
}
|
||||
else
|
||||
{
|
||||
var clone = UnityEditor.PrefabUtility.InstantiatePrefab(template.gameObject, parent) as GameObject;
|
||||
clone.transform.localPosition = Vector3.zero;
|
||||
return clone.GetComponent<MenuItem>();
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
var item = GameObject.Instantiate(template.gameObject, parent).GetComponent<MenuItem>();
|
||||
item.transform.localPosition = Vector3.zero;
|
||||
return item;
|
||||
}
|
||||
#else
|
||||
var item = GameObject.Instantiate(template.gameObject, parent).GetComponent<MenuItem>();
|
||||
item.transform.localPosition = Vector3.zero;
|
||||
return item;
|
||||
#endif
|
||||
else
|
||||
{
|
||||
var clone = UnityEditor.PrefabUtility.InstantiatePrefab(template.gameObject, parent) as GameObject;
|
||||
clone.transform.localPosition = Vector3.zero;
|
||||
return clone.GetComponent<MenuItem>();
|
||||
}
|
||||
#else
|
||||
var item = GameObject.Instantiate(template.gameObject, parent).GetComponent<MenuItem>();
|
||||
item.transform.localPosition = Vector3.zero;
|
||||
return item;
|
||||
#endif
|
||||
//========================套娃宏 End========================
|
||||
|
||||
|
||||
|
||||
#else
|
||||
return GameObject.Instantiate(SubMenuItemTemplate.gameObject, parent).GetComponent<MenuItem>();
|
||||
#endif
|
||||
#else
|
||||
return GameObject.Instantiate(SubMenuItemTemplate.gameObject, parent).GetComponent<MenuItem>();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,94 +1,94 @@
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于指定一对CanvasGroup,做透明度切换
|
||||
/// </summary>
|
||||
public class AlphaWraper
|
||||
{
|
||||
private bool m_on;
|
||||
private CanvasGroup m_offUI;
|
||||
private CanvasGroup m_onUI;
|
||||
private TweenerCore<float, float, FloatOptions> m_onTween;
|
||||
private TweenerCore<float, float, FloatOptions> m_offTween;
|
||||
|
||||
public bool On
|
||||
{
|
||||
get => m_on;
|
||||
set
|
||||
{
|
||||
if (m_on == value) return;
|
||||
|
||||
m_on = value;
|
||||
|
||||
if (m_onTween != null)
|
||||
{
|
||||
m_onTween.Kill();
|
||||
m_onTween = null;
|
||||
}
|
||||
if (m_offTween != null)
|
||||
{
|
||||
m_offTween.Kill();
|
||||
m_offTween = null;
|
||||
}
|
||||
m_onUI.gameObject.SetActiveEx(true);
|
||||
m_offUI.gameObject.SetActiveEx(true);
|
||||
|
||||
if (On)
|
||||
{
|
||||
float progress = 0f;
|
||||
m_onTween = DOTween.To(() => progress, (x) =>
|
||||
{
|
||||
progress = x;
|
||||
m_onUI.alpha = progress;
|
||||
m_offUI.alpha = 1 - progress;
|
||||
}, 1f, 0.3f);
|
||||
m_onTween.onComplete = () =>
|
||||
{
|
||||
m_offUI.gameObject.SetActiveEx(false);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
float progress = 0f;
|
||||
m_offTween = DOTween.To(() => progress, (x) =>
|
||||
{
|
||||
progress = x;
|
||||
m_onUI.alpha = 1 - progress;
|
||||
m_offUI.alpha = progress;
|
||||
}, 1f, 0.3f);
|
||||
m_offTween.onComplete = () =>
|
||||
{
|
||||
m_onUI.gameObject.SetActiveEx(false);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AlphaWraper(CanvasGroup offUI, CanvasGroup onUI, bool defaultOn)
|
||||
{
|
||||
m_offUI = offUI;
|
||||
m_onUI = onUI;
|
||||
|
||||
m_on = defaultOn;
|
||||
if (On)
|
||||
{
|
||||
onUI.alpha = 1;
|
||||
onUI.gameObject.SetActiveEx(true);
|
||||
offUI.alpha = 0;
|
||||
offUI.gameObject.SetActiveEx(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
onUI.alpha = 0;
|
||||
onUI.gameObject.SetActiveEx(false);
|
||||
offUI.alpha = 1;
|
||||
offUI.gameObject.SetActiveEx(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// </summary>
|
||||
public class AlphaWraper
|
||||
{
|
||||
private bool m_on;
|
||||
private CanvasGroup m_offUI;
|
||||
private CanvasGroup m_onUI;
|
||||
private TweenerCore<float, float, FloatOptions> m_onTween;
|
||||
private TweenerCore<float, float, FloatOptions> m_offTween;
|
||||
|
||||
public bool On
|
||||
{
|
||||
get => m_on;
|
||||
set
|
||||
{
|
||||
if (m_on == value) return;
|
||||
|
||||
m_on = value;
|
||||
|
||||
if (m_onTween != null)
|
||||
{
|
||||
m_onTween.Kill();
|
||||
m_onTween = null;
|
||||
}
|
||||
if (m_offTween != null)
|
||||
{
|
||||
m_offTween.Kill();
|
||||
m_offTween = null;
|
||||
}
|
||||
m_onUI.gameObject.SetActiveEx(true);
|
||||
m_offUI.gameObject.SetActiveEx(true);
|
||||
|
||||
if (On)
|
||||
{
|
||||
float progress = 0f;
|
||||
m_onTween = DOTween.To(() => progress, (x) =>
|
||||
{
|
||||
progress = x;
|
||||
m_onUI.alpha = progress;
|
||||
m_offUI.alpha = 1 - progress;
|
||||
}, 1f, 0.3f);
|
||||
m_onTween.onComplete = () =>
|
||||
{
|
||||
m_offUI.gameObject.SetActiveEx(false);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
float progress = 0f;
|
||||
m_offTween = DOTween.To(() => progress, (x) =>
|
||||
{
|
||||
progress = x;
|
||||
m_onUI.alpha = 1 - progress;
|
||||
m_offUI.alpha = progress;
|
||||
}, 1f, 0.3f);
|
||||
m_offTween.onComplete = () =>
|
||||
{
|
||||
m_onUI.gameObject.SetActiveEx(false);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public AlphaWraper(CanvasGroup offUI, CanvasGroup onUI, bool defaultOn)
|
||||
{
|
||||
m_offUI = offUI;
|
||||
m_onUI = onUI;
|
||||
|
||||
m_on = defaultOn;
|
||||
if (On)
|
||||
{
|
||||
onUI.alpha = 1;
|
||||
onUI.gameObject.SetActiveEx(true);
|
||||
offUI.alpha = 0;
|
||||
offUI.gameObject.SetActiveEx(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
onUI.alpha = 0;
|
||||
onUI.gameObject.SetActiveEx(false);
|
||||
offUI.alpha = 1;
|
||||
offUI.gameObject.SetActiveEx(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
/// <summary>
|
||||
/// 自动根据canvasgroup的alpha控制blocksRaycasts的开启状态
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
public class AutoRaycastCanvasGroup : MonoBehaviour
|
||||
{
|
||||
private CanvasGroup canvasGroup;
|
||||
private void Update()
|
||||
{
|
||||
if (canvasGroup == null) canvasGroup = gameObject.GetComponent<CanvasGroup>();
|
||||
|
||||
canvasGroup.blocksRaycasts = canvasGroup.alpha == 0 ? false : true;
|
||||
}
|
||||
}
|
||||
}
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(CanvasGroup))]
|
||||
public class AutoRaycastCanvasGroup : MonoBehaviour
|
||||
{
|
||||
private CanvasGroup canvasGroup;
|
||||
private void Update()
|
||||
{
|
||||
if (canvasGroup == null) canvasGroup = gameObject.GetComponent<CanvasGroup>();
|
||||
|
||||
canvasGroup.blocksRaycasts = canvasGroup.alpha == 0 ? false : true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,62 +1,62 @@
|
||||
using System;
|
||||
|
||||
namespace AxibugEmuOnline.Client.UI
|
||||
{
|
||||
using System;
|
||||
|
||||
namespace AxibugEmuOnline.Client.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于周期性触发回调的工具,带有触发周期和延迟触发的参数可调
|
||||
/// </summary>
|
||||
public class PulseInvoker
|
||||
{
|
||||
private Action _action;
|
||||
private float _interval;
|
||||
private float _delay;
|
||||
private float _elapsedTime;
|
||||
private bool _isActive;
|
||||
/// </summary>
|
||||
public class PulseInvoker
|
||||
{
|
||||
private Action _action;
|
||||
private float _interval;
|
||||
private float _delay;
|
||||
private float _elapsedTime;
|
||||
private bool _isActive;
|
||||
private bool _isDelayed;
|
||||
|
||||
public PulseInvoker(Action action, float delay, float interval)
|
||||
{
|
||||
_action = action;
|
||||
|
||||
_delay = delay;
|
||||
_interval = interval;
|
||||
}
|
||||
|
||||
public void SetActive()
|
||||
{
|
||||
_elapsedTime = 0f;
|
||||
_isActive = true;
|
||||
_isDelayed = true;
|
||||
}
|
||||
|
||||
public void DisActive()
|
||||
{
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!_isActive) return;
|
||||
|
||||
_elapsedTime += deltaTime;
|
||||
|
||||
if (_isDelayed)
|
||||
{
|
||||
if (_elapsedTime >= _delay)
|
||||
{
|
||||
_elapsedTime -= _delay;
|
||||
_isDelayed = false;
|
||||
_action?.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_elapsedTime >= _interval)
|
||||
{
|
||||
_elapsedTime -= _interval;
|
||||
_action?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public PulseInvoker(Action action, float delay, float interval)
|
||||
{
|
||||
_action = action;
|
||||
|
||||
_delay = delay;
|
||||
_interval = interval;
|
||||
}
|
||||
|
||||
public void SetActive()
|
||||
{
|
||||
_elapsedTime = 0f;
|
||||
_isActive = true;
|
||||
_isDelayed = true;
|
||||
}
|
||||
|
||||
public void DisActive()
|
||||
{
|
||||
_isActive = false;
|
||||
}
|
||||
|
||||
public void Update(float deltaTime)
|
||||
{
|
||||
if (!_isActive) return;
|
||||
|
||||
_elapsedTime += deltaTime;
|
||||
|
||||
if (_isDelayed)
|
||||
{
|
||||
if (_elapsedTime >= _delay)
|
||||
{
|
||||
_elapsedTime -= _delay;
|
||||
_isDelayed = false;
|
||||
_action?.Invoke();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_elapsedTime >= _interval)
|
||||
{
|
||||
_elapsedTime -= _interval;
|
||||
_action?.Invoke();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,6 +21,8 @@ namespace AxibugEmuOnline.Client
|
||||
get => m_target;
|
||||
set
|
||||
{
|
||||
if (m_target == value) return;
|
||||
|
||||
m_target = value;
|
||||
if (m_target == null)
|
||||
{
|
||||
|
||||
@ -1,38 +1,38 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public static class UITool
|
||||
{
|
||||
private static Dictionary<Graphic, Material> _caches = new Dictionary<Graphic, Material>();
|
||||
public static Material GetMaterial(this Graphic graphic)
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public static class UITool
|
||||
{
|
||||
private static Dictionary<Graphic, Material> _caches = new Dictionary<Graphic, Material>();
|
||||
public static Material GetMaterial(this Graphic graphic)
|
||||
{
|
||||
Material material;
|
||||
if (_caches.TryGetValue(graphic, out material))
|
||||
{
|
||||
return material;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cloneMat = Material.Instantiate(graphic.material);
|
||||
_caches[graphic] = cloneMat;
|
||||
graphic.material = cloneMat;
|
||||
return cloneMat;
|
||||
}
|
||||
}
|
||||
public static void SetMaterial(this Graphic graphic, Material material)
|
||||
{
|
||||
graphic.material = material;
|
||||
_caches.Remove(graphic);
|
||||
}
|
||||
|
||||
public static void SetAlpha(this Graphic graphic, float alpha)
|
||||
{
|
||||
var temp = graphic.color;
|
||||
temp.a = alpha;
|
||||
graphic.color = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_caches.TryGetValue(graphic, out material))
|
||||
{
|
||||
return material;
|
||||
}
|
||||
else
|
||||
{
|
||||
var cloneMat = Material.Instantiate(graphic.material);
|
||||
_caches[graphic] = cloneMat;
|
||||
graphic.material = cloneMat;
|
||||
return cloneMat;
|
||||
}
|
||||
}
|
||||
public static void SetMaterial(this Graphic graphic, Material material)
|
||||
{
|
||||
graphic.material = material;
|
||||
_caches.Remove(graphic);
|
||||
}
|
||||
|
||||
public static void SetAlpha(this Graphic graphic, float alpha)
|
||||
{
|
||||
var temp = graphic.color;
|
||||
temp.a = alpha;
|
||||
graphic.color = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,102 +1,102 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public abstract class VirtualSubMenuItem : MenuItem
|
||||
{
|
||||
[SerializeField]
|
||||
protected CanvasGroup RomGroupRoot;
|
||||
|
||||
private TweenerCore<float, float, FloatOptions> m_showTween;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
RomGroupRoot.gameObject.SetActive(false);
|
||||
RomGroupRoot.alpha = 0;
|
||||
}
|
||||
|
||||
public override void SetSelectState(bool selected)
|
||||
{
|
||||
if (m_select == selected) return;
|
||||
|
||||
m_select = selected;
|
||||
|
||||
if (ShadowIcon != null) ShadowIcon.gameObject.SetActiveEx(selected);
|
||||
|
||||
if (progressTween != null) { progressTween.Kill(); progressTween = null; }
|
||||
|
||||
progressTween = DOTween.To(() => m_progress, (x) => m_progress = x, m_select ? 1 : 0, 5)
|
||||
.SetSpeedBased().OnUpdate(() =>
|
||||
{
|
||||
if (InfoNode != null) InfoNode.alpha = m_progress;
|
||||
|
||||
Root.localScale = Vector3.one * Mathf.Lerp(UnSelectScale, SelectScale, m_progress);
|
||||
});
|
||||
}
|
||||
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
RomGroupRoot.gameObject.SetActive(true);
|
||||
RomGroupRoot.alpha = 0;
|
||||
|
||||
if (m_showTween != null)
|
||||
{
|
||||
m_showTween.Kill();
|
||||
m_showTween = null;
|
||||
}
|
||||
m_showTween = DOTween.To(() => RomGroupRoot.alpha, (x) => RomGroupRoot.alpha = x, 1, 0.2f);
|
||||
|
||||
var thirdMenuGroup = SubMenuItemGroup as ThirdMenuRoot;
|
||||
thirdMenuGroup.itemGroup.Clear();
|
||||
|
||||
RefreshUI();
|
||||
|
||||
if (SubMenuItemGroup != null) SubMenuItemGroup.SetSelect(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public delegate void VirtualListDataHandle(IEnumerable data, int initialIndex);
|
||||
|
||||
|
||||
protected void RefreshUI()
|
||||
{
|
||||
GetVirtualListDatas((datas, initialIndex) =>
|
||||
{
|
||||
var thirdMenuGroup = SubMenuItemGroup as ThirdMenuRoot;
|
||||
thirdMenuGroup.itemGroup.UpdateDependencyProperty(thirdMenuGroup);
|
||||
thirdMenuGroup.itemGroup.SetData(datas);
|
||||
thirdMenuGroup.itemGroup.UpdateProxyVisualState();
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugEmuOnline.Client.UI;
|
||||
using DG.Tweening;
|
||||
using DG.Tweening.Core;
|
||||
using DG.Tweening.Plugins.Options;
|
||||
using System.Collections;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public abstract class VirtualSubMenuItem : MenuItem
|
||||
{
|
||||
[SerializeField]
|
||||
protected CanvasGroup RomGroupRoot;
|
||||
|
||||
private TweenerCore<float, float, FloatOptions> m_showTween;
|
||||
|
||||
protected override void Awake()
|
||||
{
|
||||
base.Awake();
|
||||
|
||||
RomGroupRoot.gameObject.SetActive(false);
|
||||
RomGroupRoot.alpha = 0;
|
||||
}
|
||||
|
||||
public override void SetSelectState(bool selected)
|
||||
{
|
||||
if (m_select == selected) return;
|
||||
|
||||
m_select = selected;
|
||||
|
||||
if (ShadowIcon != null) ShadowIcon.gameObject.SetActiveEx(selected);
|
||||
|
||||
if (progressTween != null) { progressTween.Kill(); progressTween = null; }
|
||||
|
||||
progressTween = DOTween.To(() => m_progress, (x) => m_progress = x, m_select ? 1 : 0, 5)
|
||||
.SetSpeedBased().OnUpdate(() =>
|
||||
{
|
||||
if (InfoNode != null) InfoNode.alpha = m_progress;
|
||||
|
||||
Root.localScale = Vector3.one * Mathf.Lerp(UnSelectScale, SelectScale, m_progress);
|
||||
});
|
||||
}
|
||||
|
||||
public override bool OnEnterItem()
|
||||
{
|
||||
RomGroupRoot.gameObject.SetActive(true);
|
||||
RomGroupRoot.alpha = 0;
|
||||
|
||||
if (m_showTween != null)
|
||||
{
|
||||
m_showTween.Kill();
|
||||
m_showTween = null;
|
||||
}
|
||||
m_showTween = DOTween.To(() => RomGroupRoot.alpha, (x) => RomGroupRoot.alpha = x, 1, 0.2f);
|
||||
|
||||
var thirdMenuGroup = SubMenuItemGroup as ThirdMenuRoot;
|
||||
thirdMenuGroup.itemGroup.Clear();
|
||||
|
||||
RefreshUI();
|
||||
|
||||
if (SubMenuItemGroup != null) SubMenuItemGroup.SetSelect(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public delegate void VirtualListDataHandle(IEnumerable data, int initialIndex);
|
||||
|
||||
|
||||
protected void RefreshUI()
|
||||
{
|
||||
GetVirtualListDatas((datas, initialIndex) =>
|
||||
{
|
||||
var thirdMenuGroup = SubMenuItemGroup as ThirdMenuRoot;
|
||||
thirdMenuGroup.itemGroup.UpdateDependencyProperty(thirdMenuGroup);
|
||||
thirdMenuGroup.itemGroup.SetData(datas);
|
||||
thirdMenuGroup.itemGroup.UpdateProxyVisualState();
|
||||
thirdMenuGroup.ResetToIndex(initialIndex);
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void GetVirtualListDatas(VirtualListDataHandle callback);
|
||||
|
||||
public override bool OnExitItem()
|
||||
{
|
||||
if (m_showTween != null)
|
||||
{
|
||||
m_showTween.Kill();
|
||||
m_showTween = null;
|
||||
}
|
||||
m_showTween = DOTween.To(() => RomGroupRoot.alpha, (x) => RomGroupRoot.alpha = x, 0, 0.2f)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
RomGroupRoot.gameObject.SetActive(false);
|
||||
});
|
||||
|
||||
if (SubMenuItemGroup != null) SubMenuItemGroup.SetSelect(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void GetVirtualListDatas(VirtualListDataHandle callback);
|
||||
|
||||
public override bool OnExitItem()
|
||||
{
|
||||
if (m_showTween != null)
|
||||
{
|
||||
m_showTween.Kill();
|
||||
m_showTween = null;
|
||||
}
|
||||
m_showTween = DOTween.To(() => RomGroupRoot.alpha, (x) => RomGroupRoot.alpha = x, 0, 0.2f)
|
||||
.OnComplete(() =>
|
||||
{
|
||||
RomGroupRoot.gameObject.SetActive(false);
|
||||
});
|
||||
|
||||
if (SubMenuItemGroup != null) SubMenuItemGroup.SetSelect(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,137 +1,137 @@
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class XMBInfoBar : MonoBehaviour
|
||||
{
|
||||
public Text txtDateTime;
|
||||
public Image imgPowerRoot;
|
||||
public Image imgPower1;
|
||||
public Image imgPower2;
|
||||
public Image imgPower3;
|
||||
public Text DelayValue;
|
||||
public Text OnlinePlayerCount;
|
||||
public Text FPS;
|
||||
public GameObject ControlSlotInfoNode;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
TickLoop.LoopAction_1s += RefreshAll;
|
||||
RefreshAll();
|
||||
}
|
||||
|
||||
using AxibugEmuOnline.Client;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class XMBInfoBar : MonoBehaviour
|
||||
{
|
||||
public Text txtDateTime;
|
||||
public Image imgPowerRoot;
|
||||
public Image imgPower1;
|
||||
public Image imgPower2;
|
||||
public Image imgPower3;
|
||||
public Text DelayValue;
|
||||
public Text OnlinePlayerCount;
|
||||
public Text FPS;
|
||||
public GameObject ControlSlotInfoNode;
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
TickLoop.LoopAction_1s += RefreshAll;
|
||||
RefreshAll();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
ControlSlotInfoNode.SetActiveEx(App.emu.Core != null);
|
||||
}
|
||||
|
||||
void OnDisable()
|
||||
{
|
||||
TickLoop.LoopAction_1s -= RefreshAll;
|
||||
}
|
||||
|
||||
void RefreshAll()
|
||||
{
|
||||
RefreshTime();
|
||||
RefreshPower();
|
||||
RefreshDelay();
|
||||
RefreshFps();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (uint lastFrame, float lastTime)
|
||||
/// </summary>
|
||||
ValueTuple<uint, float> m_lastFrameInfo;
|
||||
private void RefreshFps()
|
||||
{
|
||||
if (App.emu.Core == null)
|
||||
FPS.gameObject.SetActiveEx(false);
|
||||
else
|
||||
{
|
||||
void OnDisable()
|
||||
{
|
||||
TickLoop.LoopAction_1s -= RefreshAll;
|
||||
}
|
||||
|
||||
void RefreshAll()
|
||||
{
|
||||
RefreshTime();
|
||||
RefreshPower();
|
||||
RefreshDelay();
|
||||
RefreshFps();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// (uint lastFrame, float lastTime)
|
||||
/// </summary>
|
||||
ValueTuple<uint, float> m_lastFrameInfo;
|
||||
private void RefreshFps()
|
||||
{
|
||||
if (App.emu.Core == null)
|
||||
FPS.gameObject.SetActiveEx(false);
|
||||
else
|
||||
{
|
||||
FPS.gameObject.SetActiveEx(true);
|
||||
//var gap = App.emu.Core.Frame - m_lastFrameInfo.lastFrame;
|
||||
//var time = Time.realtimeSinceStartup - m_lastFrameInfo.lastTime;
|
||||
var gap = App.emu.Core.Frame - m_lastFrameInfo.Item1;
|
||||
var time = Time.realtimeSinceStartup - m_lastFrameInfo.Item2;
|
||||
var fps = gap / time;
|
||||
var fps = gap / time;
|
||||
FPS.text = $"FPS:{fps:.#}";
|
||||
|
||||
//m_lastFrameInfo.lastFrame = App.emu.Core.Frame;
|
||||
//m_lastFrameInfo.lastTime = Time.realtimeSinceStartup;
|
||||
m_lastFrameInfo.Item1 = App.emu.Core.Frame;
|
||||
m_lastFrameInfo.Item2 = Time.realtimeSinceStartup;
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshDelay()
|
||||
{
|
||||
if (App.user == null)
|
||||
{
|
||||
DelayValue.text = $"-";
|
||||
OnlinePlayerCount.text = $"-";
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (App.user.IsLoggedIn)
|
||||
{
|
||||
DelayValue.text = $"{App.tick.AveNetDelay * 1000:0}ms";
|
||||
OnlinePlayerCount.text = App.user.OnlinePlayerCount.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
DelayValue.text = "-";
|
||||
OnlinePlayerCount.text = $"-";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshTime()
|
||||
{
|
||||
txtDateTime.text = DateTime.Now.ToString("MM/dd HH:mm");
|
||||
}
|
||||
|
||||
void RefreshPower()
|
||||
{
|
||||
float battery = SystemInfo.batteryLevel;
|
||||
|
||||
if (Application.platform == RuntimePlatform.WindowsPlayer
|
||||
||
|
||||
Application.platform == RuntimePlatform.WindowsEditor
|
||||
||
|
||||
Application.platform == RuntimePlatform.OSXPlayer
|
||||
||
|
||||
Application.platform == RuntimePlatform.OSXEditor
|
||||
)
|
||||
{
|
||||
battery = 1f;
|
||||
}
|
||||
|
||||
if (battery > 0.80f)
|
||||
{
|
||||
imgPower1.gameObject.SetActive(true);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
}
|
||||
else if (battery > 0.50f)
|
||||
{
|
||||
imgPower1.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
}
|
||||
else if (battery > 0.20f)
|
||||
{
|
||||
imgPower1.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
imgPower1.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void RefreshDelay()
|
||||
{
|
||||
if (App.user == null)
|
||||
{
|
||||
DelayValue.text = $"-";
|
||||
OnlinePlayerCount.text = $"-";
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (App.user.IsLoggedIn)
|
||||
{
|
||||
DelayValue.text = $"{App.tick.AveNetDelay * 1000:0}ms";
|
||||
OnlinePlayerCount.text = App.user.OnlinePlayerCount.ToString();
|
||||
}
|
||||
else
|
||||
{
|
||||
DelayValue.text = "-";
|
||||
OnlinePlayerCount.text = $"-";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RefreshTime()
|
||||
{
|
||||
txtDateTime.text = DateTime.Now.ToString("MM/dd HH:mm");
|
||||
}
|
||||
|
||||
void RefreshPower()
|
||||
{
|
||||
float battery = SystemInfo.batteryLevel;
|
||||
|
||||
if (Application.platform == RuntimePlatform.WindowsPlayer
|
||||
||
|
||||
Application.platform == RuntimePlatform.WindowsEditor
|
||||
||
|
||||
Application.platform == RuntimePlatform.OSXPlayer
|
||||
||
|
||||
Application.platform == RuntimePlatform.OSXEditor
|
||||
)
|
||||
{
|
||||
battery = 1f;
|
||||
}
|
||||
|
||||
if (battery > 0.80f)
|
||||
{
|
||||
imgPower1.gameObject.SetActive(true);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
}
|
||||
else if (battery > 0.50f)
|
||||
{
|
||||
imgPower1.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
}
|
||||
else if (battery > 0.20f)
|
||||
{
|
||||
imgPower1.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
imgPower1.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(false);
|
||||
imgPower2.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,47 +1,47 @@
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public static class Utility
|
||||
{
|
||||
public static void SetActiveEx(this GameObject go, bool active)
|
||||
{
|
||||
if (active && go.activeSelf) return;
|
||||
if (!active && !go.activeSelf) return;
|
||||
|
||||
go.SetActive(active);
|
||||
}
|
||||
|
||||
public static string GetHostNickName(this Protobuf_Room_MiniInfo roomInfo)
|
||||
{
|
||||
var hostUID = roomInfo.HostPlayerUID;
|
||||
Protobuf_Room_GamePlaySlot slotdata = roomInfo.GamePlaySlotList.FirstOrDefault(w => w.PlayerUID == hostUID);
|
||||
if (slotdata != null)
|
||||
return slotdata.PlayerNickName;
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static void GetRoomPlayers(this Protobuf_Room_MiniInfo roomInfo, out int current, out int max)
|
||||
{
|
||||
current = 0; max = 4;
|
||||
current = roomInfo.GamePlaySlotList.Count(w => w.PlayerUID > 0);
|
||||
}
|
||||
|
||||
private static Dictionary<int, RomFile> s_RomFileCahcesInRoomInfo = new Dictionary<int, RomFile>();
|
||||
public static void FetchRomFileInRoomInfo(this Protobuf_Room_MiniInfo roomInfo, Action<Protobuf_Room_MiniInfo, RomFile> callback)
|
||||
{
|
||||
RomFile romFile;
|
||||
|
||||
if (s_RomFileCahcesInRoomInfo.TryGetValue(roomInfo.GameRomID, out romFile))
|
||||
{
|
||||
callback.Invoke(roomInfo, romFile);
|
||||
return;
|
||||
using AxibugEmuOnline.Client.ClientCore;
|
||||
using AxibugProtobuf;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AxibugEmuOnline.Client
|
||||
{
|
||||
public static class Utility
|
||||
{
|
||||
public static void SetActiveEx(this GameObject go, bool active)
|
||||
{
|
||||
if (active && go.activeSelf) return;
|
||||
if (!active && !go.activeSelf) return;
|
||||
|
||||
go.SetActive(active);
|
||||
}
|
||||
|
||||
public static string GetHostNickName(this Protobuf_Room_MiniInfo roomInfo)
|
||||
{
|
||||
var hostUID = roomInfo.HostPlayerUID;
|
||||
Protobuf_Room_GamePlaySlot slotdata = roomInfo.GamePlaySlotList.FirstOrDefault(w => w.PlayerUID == hostUID);
|
||||
if (slotdata != null)
|
||||
return slotdata.PlayerNickName;
|
||||
else
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
public static void GetRoomPlayers(this Protobuf_Room_MiniInfo roomInfo, out int current, out int max)
|
||||
{
|
||||
current = 0; max = 4;
|
||||
current = roomInfo.GamePlaySlotList.Count(w => w.PlayerUID > 0);
|
||||
}
|
||||
|
||||
private static Dictionary<int, RomFile> s_RomFileCahcesInRoomInfo = new Dictionary<int, RomFile>();
|
||||
public static void FetchRomFileInRoomInfo(this Protobuf_Room_MiniInfo roomInfo, Action<Protobuf_Room_MiniInfo, RomFile> callback)
|
||||
{
|
||||
RomFile romFile;
|
||||
|
||||
if (s_RomFileCahcesInRoomInfo.TryGetValue(roomInfo.GameRomID, out romFile))
|
||||
{
|
||||
callback.Invoke(roomInfo, romFile);
|
||||
return;
|
||||
}
|
||||
|
||||
App.StartCoroutine(App.httpAPI.GetRomInfo(roomInfo.GameRomID, (romWebData) =>
|
||||
@ -51,17 +51,17 @@ namespace AxibugEmuOnline.Client
|
||||
s_RomFileCahcesInRoomInfo[roomInfo.GameRomID] = _romFile;
|
||||
|
||||
callback.Invoke(roomInfo, _romFile);
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
}));
|
||||
|
||||
}
|
||||
|
||||
public static byte[] ToJPG(this Texture texture, Vector2 scale)
|
||||
{
|
||||
Texture2D outputTex = ConvertFromRenderTexture(texture, scale);
|
||||
|
||||
return outputTex.EncodeToJPG();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static Texture2D ConvertFromRenderTexture(Texture src, Vector2 scale)
|
||||
{
|
||||
float offsetX = (scale.x < 0) ? 1 : 0;
|
||||
@ -83,6 +83,6 @@ namespace AxibugEmuOnline.Client
|
||||
RenderTexture.active = null;
|
||||
RenderTexture.ReleaseTemporary(tempRT);
|
||||
return tex;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user