Merge pull request 'master' (#92) from Alienjack/AxibugEmuOnline:master into master
Reviewed-on: #92
This commit is contained in:
commit
62c6854172
@ -0,0 +1,55 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace AxiReplay
|
||||||
|
{
|
||||||
|
public partial class FrameProfiler
|
||||||
|
{
|
||||||
|
private int m_headFrame;
|
||||||
|
private int m_cacheCount;
|
||||||
|
private int m_targetFrameRate;
|
||||||
|
private RingBuffer<double> m_timePoints;
|
||||||
|
private double m_lastTime;
|
||||||
|
|
||||||
|
private Stopwatch sw;
|
||||||
|
|
||||||
|
public void InputHead(int headFrame)
|
||||||
|
{
|
||||||
|
m_headFrame = headFrame;
|
||||||
|
var currentTimeMs = GetCurrTime();
|
||||||
|
|
||||||
|
if (m_timePoints.Available() == 60)
|
||||||
|
CalcCacheCount();
|
||||||
|
m_timePoints.Write(currentTimeMs - m_lastTime);
|
||||||
|
|
||||||
|
m_lastTime = currentTimeMs;
|
||||||
|
}
|
||||||
|
public void Reset(int targetFrameRate = 60)
|
||||||
|
{
|
||||||
|
if (sw != null) sw.Stop();
|
||||||
|
|
||||||
|
sw = Stopwatch.StartNew();
|
||||||
|
m_timePoints = new RingBuffer<double>(targetFrameRate);
|
||||||
|
m_lastTime = 0;
|
||||||
|
m_targetFrameRate = targetFrameRate;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CalcCacheCount()
|
||||||
|
{
|
||||||
|
double deltaMax = 0;
|
||||||
|
while (m_timePoints.TryRead(out double delta))
|
||||||
|
{
|
||||||
|
deltaMax = Math.Max(deltaMax, delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
int minCacheCount = (int)Math.Ceiling(deltaMax * m_targetFrameRate);
|
||||||
|
m_cacheCount = minCacheCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
double GetCurrTime()
|
||||||
|
{
|
||||||
|
if (sw == null) return 0;
|
||||||
|
return sw.Elapsed.TotalMilliseconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: cfd4511a83ff0bf4ea7615b87e7d09aa
|
@ -0,0 +1,78 @@
|
|||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace AxiReplay
|
||||||
|
{
|
||||||
|
public partial class FrameProfiler
|
||||||
|
{
|
||||||
|
internal class RingBuffer<T>
|
||||||
|
{
|
||||||
|
private readonly T[] buffer;
|
||||||
|
private readonly int capacity;
|
||||||
|
private int writePos;
|
||||||
|
private int readPos;
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
public RingBuffer(int capacity)
|
||||||
|
{
|
||||||
|
this.capacity = capacity;
|
||||||
|
this.buffer = new T[capacity];
|
||||||
|
this.writePos = 0;
|
||||||
|
this.readPos = 0;
|
||||||
|
this.count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Write(T item)
|
||||||
|
{
|
||||||
|
int localWritePos;
|
||||||
|
int localReadPos;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
localWritePos = Volatile.Read(ref writePos);
|
||||||
|
localReadPos = Volatile.Read(ref readPos);
|
||||||
|
|
||||||
|
int nextWritePos = (localWritePos + 1) % capacity;
|
||||||
|
|
||||||
|
if (nextWritePos == localReadPos)
|
||||||
|
{
|
||||||
|
// 缓冲区已满,覆盖最旧的未读数据
|
||||||
|
Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (Interlocked.CompareExchange(ref writePos, (localWritePos + 1) % capacity, localWritePos) != localWritePos);
|
||||||
|
|
||||||
|
buffer[localWritePos] = item;
|
||||||
|
Interlocked.Increment(ref count);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryRead(out T item)
|
||||||
|
{
|
||||||
|
item = default(T);
|
||||||
|
|
||||||
|
int localReadPos;
|
||||||
|
int localWritePos;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
localReadPos = Volatile.Read(ref readPos);
|
||||||
|
localWritePos = Volatile.Read(ref writePos);
|
||||||
|
|
||||||
|
if (localReadPos == localWritePos)
|
||||||
|
{
|
||||||
|
return false; // 缓冲区为空
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (Interlocked.CompareExchange(ref readPos, (localReadPos + 1) % capacity, localReadPos) != localReadPos);
|
||||||
|
|
||||||
|
item = buffer[localReadPos];
|
||||||
|
Interlocked.Decrement(ref count);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Available()
|
||||||
|
{
|
||||||
|
return Volatile.Read(ref count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b17d83b69bd47094594c32fcff9715f4
|
@ -34,6 +34,8 @@ namespace AxiReplay
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
ReplayStep mNextReplay;
|
ReplayStep mNextReplay;
|
||||||
|
|
||||||
|
FrameProfiler frameProfiler = new FrameProfiler();
|
||||||
|
|
||||||
bool bNetInit = false;
|
bool bNetInit = false;
|
||||||
public NetReplay()
|
public NetReplay()
|
||||||
{
|
{
|
||||||
@ -45,6 +47,8 @@ namespace AxiReplay
|
|||||||
mCurrReplay = default(ReplayStep);
|
mCurrReplay = default(ReplayStep);
|
||||||
mCurrReplay.FrameStartID = int.MinValue;
|
mCurrReplay.FrameStartID = int.MinValue;
|
||||||
bNetInit = false;
|
bNetInit = false;
|
||||||
|
|
||||||
|
frameProfiler.Reset();
|
||||||
}
|
}
|
||||||
public void InData(ReplayStep inputData, int ServerFrameIdx, uint ServerForwardCount)
|
public void InData(ReplayStep inputData, int ServerFrameIdx, uint ServerForwardCount)
|
||||||
{
|
{
|
||||||
@ -57,7 +61,10 @@ namespace AxiReplay
|
|||||||
bNetInit = true;
|
bNetInit = true;
|
||||||
mNextReplay = mNetReplayQueue.Dequeue();
|
mNextReplay = mNetReplayQueue.Dequeue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
frameProfiler.InputHead(inputData.FrameStartID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool TryGetNextFrame(out ReplayStep data, out int frameDiff, out bool inputDiff)
|
public bool TryGetNextFrame(out ReplayStep data, out int frameDiff, out bool inputDiff)
|
||||||
{
|
{
|
||||||
if (!bNetInit)
|
if (!bNetInit)
|
||||||
@ -93,13 +100,15 @@ namespace AxiReplay
|
|||||||
{
|
{
|
||||||
bool result;
|
bool result;
|
||||||
inputDiff = false;
|
inputDiff = false;
|
||||||
|
|
||||||
|
|
||||||
//if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0)
|
//if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count > 0)
|
||||||
if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count >= mRemoteForwardCount)
|
if (targetFrame == mNextReplay.FrameStartID && targetFrame <= mRemoteFrameIdx && mNetReplayQueue.Count >= mRemoteForwardCount)
|
||||||
{
|
{
|
||||||
//当前帧追加
|
//当前帧追加
|
||||||
mCurrClientFrameIdx = targetFrame;
|
mCurrClientFrameIdx = targetFrame;
|
||||||
ulong oldInput = mCurrReplay.InPut;
|
ulong oldInput = mCurrReplay.InPut;
|
||||||
mCurrReplay = mNextReplay;
|
mCurrReplay = mNextReplay;
|
||||||
if (oldInput != mCurrReplay.InPut)
|
if (oldInput != mCurrReplay.InPut)
|
||||||
inputDiff = true;
|
inputDiff = true;
|
||||||
mNextReplay = mNetReplayQueue.Dequeue();
|
mNextReplay = mNetReplayQueue.Dequeue();
|
||||||
|
@ -47,7 +47,7 @@ public class UMAME : MonoBehaviour, IEmuCore
|
|||||||
|
|
||||||
|
|
||||||
//设为60帧
|
//设为60帧
|
||||||
Application.targetFrameRate = 120;
|
Application.targetFrameRate = 60;
|
||||||
// 强制横屏
|
// 强制横屏
|
||||||
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
Screen.orientation = ScreenOrientation.LandscapeLeft;
|
||||||
instance = this;
|
instance = this;
|
||||||
|
@ -331,7 +331,6 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, newJoin);
|
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, newJoin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool bChangeSlot = false;
|
|
||||||
for (int i = 0; i < 4; i++)
|
for (int i = 0; i < 4; i++)
|
||||||
{
|
{
|
||||||
var oldSlot = oldslotArr[i];
|
var oldSlot = oldslotArr[i];
|
||||||
@ -344,68 +343,65 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
oldSlot.PlayerLocalJoyIdx != newSlot.PlayerLocalJoyIdx
|
oldSlot.PlayerLocalJoyIdx != newSlot.PlayerLocalJoyIdx
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
bChangeSlot = true;
|
|
||||||
if (newSlot.PlayerUID > 0)
|
if (newSlot.PlayerUID > 0)
|
||||||
{
|
{
|
||||||
OverlayManager.PopTip($"[{newSlot.PlayerNickName}]使用:P{i}");
|
OverlayManager.PopTip($"[{newSlot.PlayerNickName}]使用:P{i}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bChangeSlot)
|
Eventer.Instance.PostEvent(EEvent.OnRoomSlotDataChanged);
|
||||||
{
|
|
||||||
Eventer.Instance.PostEvent(EEvent.OnRoomSlotDataChanged);
|
|
||||||
}
|
//for (int i = 0; i < 4; i++)
|
||||||
|
//{
|
||||||
//for (int i = 0; i < 4; i++)
|
// long OldPlayer = oldRoomPlayer[i];
|
||||||
//{
|
// long NewPlayer = newRoomPlayer[i];
|
||||||
// long OldPlayer = oldRoomPlayer[i];
|
// if (OldPlayer == NewPlayer)
|
||||||
// long NewPlayer = newRoomPlayer[i];
|
// continue;
|
||||||
// if (OldPlayer == NewPlayer)
|
|
||||||
// continue;
|
// //位置之前有人,但是离开了
|
||||||
|
// if (OldPlayer > 0)
|
||||||
// //位置之前有人,但是离开了
|
// {
|
||||||
// if (OldPlayer > 0)
|
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
||||||
// {
|
// UserDataBase oldplayer = App.user.GetUserByUid(OldPlayer);
|
||||||
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
// string oldPlayName = oldplayer != null ? oldplayer.NickName : "Player";
|
||||||
// UserDataBase oldplayer = App.user.GetUserByUid(OldPlayer);
|
// OverlayManager.PopTip($"[{oldPlayName}]离开房间,手柄位:P{i}");
|
||||||
// string oldPlayName = oldplayer != null ? oldplayer.NickName : "Player";
|
// if (NewPlayer > 0)//而且害换了一个玩家
|
||||||
// OverlayManager.PopTip($"[{oldPlayName}]离开房间,手柄位:P{i}");
|
// {
|
||||||
// if (NewPlayer > 0)//而且害换了一个玩家
|
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||||
// {
|
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
||||||
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
||||||
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
// }
|
||||||
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
// }
|
||||||
// }
|
// else //之前没人
|
||||||
// }
|
// {
|
||||||
// else //之前没人
|
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||||
// {
|
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
||||||
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
||||||
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
// }
|
||||||
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
|
||||||
// }
|
// //位置之前有人,但是离开了
|
||||||
|
// if (OldPlayer > 0)
|
||||||
// //位置之前有人,但是离开了
|
// {
|
||||||
// if (OldPlayer > 0)
|
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
||||||
// {
|
// UserDataBase oldplayer = App.user.GetUserByUid(OldPlayer);
|
||||||
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
// string oldPlayName = oldplayer != null ? oldplayer.NickName : "Player";
|
||||||
// UserDataBase oldplayer = App.user.GetUserByUid(OldPlayer);
|
// OverlayManager.PopTip($"[{oldPlayName}]离开房间,手柄位:P{i}");
|
||||||
// string oldPlayName = oldplayer != null ? oldplayer.NickName : "Player";
|
// if (NewPlayer > 0)//而且害换了一个玩家
|
||||||
// OverlayManager.PopTip($"[{oldPlayName}]离开房间,手柄位:P{i}");
|
// {
|
||||||
// if (NewPlayer > 0)//而且害换了一个玩家
|
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||||
// {
|
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
||||||
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
||||||
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
// }
|
||||||
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
// }
|
||||||
// }
|
// else //之前没人
|
||||||
// }
|
// {
|
||||||
// else //之前没人
|
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||||
// {
|
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
||||||
// Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
||||||
// mineRoomMiniInfo.GetPlayerNameByPlayerIdx((uint)i, out string PlayerName);
|
// }
|
||||||
// OverlayManager.PopTip($"[{PlayerName}]进入房间,手柄位:P{i}");
|
//}
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
Loading…
Reference in New Issue
Block a user