Compare commits
No commits in common. "7aa07500b28acdc120f01117e450105a16284154" and "e0d6e0542da69f24ecf0e32d1fa4e7ad42c03a7f" have entirely different histories.
7aa07500b2
...
e0d6e0542d
@ -5,7 +5,7 @@ namespace AxiReplay
|
|||||||
public class NetReplay
|
public class NetReplay
|
||||||
{
|
{
|
||||||
int MaxInFrame = 0;
|
int MaxInFrame = 0;
|
||||||
public int mCurrPlayFrame = -1;
|
int mCurrPlayFrame = -1;
|
||||||
Queue<ReplayStep> mQueueReplay;
|
Queue<ReplayStep> mQueueReplay;
|
||||||
ReplayStep mNextReplay;
|
ReplayStep mNextReplay;
|
||||||
ReplayStep mCurrReplay;
|
ReplayStep mCurrReplay;
|
||||||
|
|||||||
@ -229,7 +229,7 @@ RectTransform:
|
|||||||
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0.5, y: 0.5}
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
m_AnchorMax: {x: 0.5, y: 0.5}
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
m_AnchoredPosition: {x: 204, y: 488}
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
m_SizeDelta: {x: 100, y: 100}
|
m_SizeDelta: {x: 100, y: 100}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!222 &2800056879890978085
|
--- !u!222 &2800056879890978085
|
||||||
|
|||||||
@ -174,9 +174,53 @@ PrefabInstance:
|
|||||||
propertyPath: m_LocalEulerAnglesHint.z
|
propertyPath: m_LocalEulerAnglesHint.z
|
||||||
value: 0
|
value: 0
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521131536012, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: RomName
|
||||||
|
value: mario.nes
|
||||||
|
objectReference: {fileID: 0}
|
||||||
- target: {fileID: 4232056521131536013, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
- target: {fileID: 4232056521131536013, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
propertyPath: m_Name
|
propertyPath: m_Name
|
||||||
value: NesEmulator
|
value: NesEmulator
|
||||||
objectReference: {fileID: 0}
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_Enabled
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_Texture
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880274, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_Material
|
||||||
|
value:
|
||||||
|
objectReference: {fileID: 2100000, guid: 07e28fcb992bc124e986f9d8ff3beb97, type: 2}
|
||||||
|
- target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_AnchorMax.x
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_AnchorMax.y
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_AnchorMin.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_AnchorMin.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_SizeDelta.x
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880275, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_SizeDelta.y
|
||||||
|
value: 0
|
||||||
|
objectReference: {fileID: 0}
|
||||||
|
- target: {fileID: 4232056521759880276, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
propertyPath: m_IsActive
|
||||||
|
value: 1
|
||||||
|
objectReference: {fileID: 0}
|
||||||
m_RemovedComponents: []
|
m_RemovedComponents: []
|
||||||
m_SourcePrefab: {fileID: 100100000, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
m_SourcePrefab: {fileID: 100100000, guid: f8bea3f8aa351bb46ada33b2274729ea, type: 3}
|
||||||
|
|||||||
@ -29,14 +29,14 @@ namespace AxibugEmuOnline.Client.Event
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class Eventer
|
public class EventSystem
|
||||||
{
|
{
|
||||||
private static Eventer instance = new Eventer();
|
private static EventSystem instance = new EventSystem();
|
||||||
public static Eventer Instance { get { return instance; } }
|
public static EventSystem Instance { get { return instance; } }
|
||||||
|
|
||||||
private Dictionary<EEvent, List<Delegate>> eventDic = new Dictionary<EEvent, List<Delegate>>(128);
|
private Dictionary<EEvent, List<Delegate>> eventDic = new Dictionary<EEvent, List<Delegate>>(128);
|
||||||
|
|
||||||
private Eventer() { }
|
private EventSystem() { }
|
||||||
|
|
||||||
|
|
||||||
#region RegisterEvent
|
#region RegisterEvent
|
||||||
|
|||||||
@ -26,7 +26,7 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
public void RecvChatMsg(byte[] reqData)
|
public void RecvChatMsg(byte[] reqData)
|
||||||
{
|
{
|
||||||
Protobuf_ChatMsg_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg_RESP>(reqData);
|
Protobuf_ChatMsg_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_ChatMsg_RESP>(reqData);
|
||||||
Eventer.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg);
|
EventSystem.Instance.PostEvent(EEvent.OnChatMsg, msg.NickName, msg.ChatMsg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,33 +5,34 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
{
|
{
|
||||||
public class AppEmu
|
public class AppEmu
|
||||||
{
|
{
|
||||||
private GameObject m_emuInstance;
|
|
||||||
|
|
||||||
public void BeginGame(RomFile romFile)
|
public void BeginGame(RomFile romFile)
|
||||||
{
|
{
|
||||||
if (m_emuInstance != null) return;
|
if (InGameUI.Instance.Enable) return;
|
||||||
|
|
||||||
switch (romFile.Platform)
|
switch (romFile.Platform)
|
||||||
{
|
{
|
||||||
case EnumPlatform.NES:
|
case EnumPlatform.NES:
|
||||||
var nesEmu = GameObject.Instantiate(Resources.Load<GameObject>("NES/NesEmulator")).GetComponent<NesEmulator>();
|
App.SceneLoader.BeginLoad("Scene/Emu_NES", () =>
|
||||||
m_emuInstance = nesEmu.gameObject;
|
{
|
||||||
|
var nesEmu = GameObject.FindObjectOfType<NesEmulator>();
|
||||||
|
nesEmu.StartGame(romFile);
|
||||||
|
|
||||||
nesEmu.StartGame(romFile);
|
LaunchUI.Instance.HideMainMenu();
|
||||||
LaunchUI.Instance.HideMainMenu();
|
InGameUI.Instance.Show(romFile, nesEmu);
|
||||||
InGameUI.Instance.Show(romFile, nesEmu);
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StopGame()
|
public void StopGame()
|
||||||
{
|
{
|
||||||
if (m_emuInstance == null) return;
|
if (!InGameUI.Instance.enabled) return;
|
||||||
GameObject.Destroy(m_emuInstance);
|
|
||||||
m_emuInstance = null;
|
|
||||||
|
|
||||||
InGameUI.Instance.Hide();
|
App.SceneLoader.BeginLoad("Scene/AxibugEmuOnline.Client", () =>
|
||||||
LaunchUI.Instance.ShowMainMenu();
|
{
|
||||||
|
InGameUI.Instance.Hide();
|
||||||
|
LaunchUI.Instance.ShowMainMenu();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,9 +5,9 @@ using AxibugEmuOnline.Client.Network;
|
|||||||
using AxibugProtobuf;
|
using AxibugProtobuf;
|
||||||
using AxiReplay;
|
using AxiReplay;
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client.Manager
|
namespace AxibugEmuOnline.Client.Manager
|
||||||
{
|
{
|
||||||
@ -182,7 +182,7 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
Protobuf_Room_List_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_List_RESP>(reqData);
|
Protobuf_Room_List_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_List_RESP>(reqData);
|
||||||
for (int i = 0; i < msg.RoomMiniInfoList.Count; i++)
|
for (int i = 0; i < msg.RoomMiniInfoList.Count; i++)
|
||||||
AddOrUpdateRoomList(msg.RoomMiniInfoList[i]);
|
AddOrUpdateRoomList(msg.RoomMiniInfoList[i]);
|
||||||
Eventer.Instance.PostEvent(EEvent.OnRoomListAllUpdate);
|
EventSystem.Instance.PostEvent(EEvent.OnRoomListAllUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -194,7 +194,7 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
App.log.Debug("单个房间状态更新");
|
App.log.Debug("单个房间状态更新");
|
||||||
Protobuf_Room_Update_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Update_RESP>(reqData);
|
Protobuf_Room_Update_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Update_RESP>(reqData);
|
||||||
AddOrUpdateRoomList(msg.RoomMiniInfo);
|
AddOrUpdateRoomList(msg.RoomMiniInfo);
|
||||||
Eventer.Instance.PostEvent(EEvent.OnRoomListSingleUpdate, msg.RoomMiniInfo.GameRomID);
|
EventSystem.Instance.PostEvent(EEvent.OnRoomListSingleUpdate, msg.RoomMiniInfo.GameRomID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -247,18 +247,16 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
Protobuf_Room_Join_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Join_RESP>(reqData);
|
Protobuf_Room_Join_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Join_RESP>(reqData);
|
||||||
mineRoomMiniInfo = msg.RoomMiniInfo;
|
mineRoomMiniInfo = msg.RoomMiniInfo;
|
||||||
InitRePlay();
|
InitRePlay();
|
||||||
Eventer.Instance.PostEvent(EEvent.OnMineJoinRoom);
|
EventSystem.Instance.PostEvent(EEvent.OnMineJoinRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 离开房间
|
/// 离开房间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="RoomID"></param>
|
/// <param name="RoomID"></param>
|
||||||
public void SendLeavnRoom()
|
public void SendLeavnRoom(int RoomID)
|
||||||
{
|
{
|
||||||
if (!InRoom)
|
_Protobuf_Room_Leave.RoomID = RoomID;
|
||||||
return;
|
|
||||||
_Protobuf_Room_Leave.RoomID = mineRoomMiniInfo.RoomID;
|
|
||||||
App.log.Info($"创建房间");
|
App.log.Info($"创建房间");
|
||||||
App.network.SendToServer((int)CommandID.CmdRoomLeave, ProtoBufHelper.Serizlize(_Protobuf_Room_Leave));
|
App.network.SendToServer((int)CommandID.CmdRoomLeave, ProtoBufHelper.Serizlize(_Protobuf_Room_Leave));
|
||||||
}
|
}
|
||||||
@ -273,7 +271,7 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
Protobuf_Room_Leave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Leave_RESP>(reqData);
|
Protobuf_Room_Leave_RESP msg = ProtoBufHelper.DeSerizlize<Protobuf_Room_Leave_RESP>(reqData);
|
||||||
ReleaseRePlay();
|
ReleaseRePlay();
|
||||||
mineRoomMiniInfo = null;
|
mineRoomMiniInfo = null;
|
||||||
Eventer.Instance.PostEvent(EEvent.OnMineLeavnRoom);
|
EventSystem.Instance.PostEvent(EEvent.OnMineLeavnRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RecvRoomMyRoomStateChange(byte[] reqData)
|
void RecvRoomMyRoomStateChange(byte[] reqData)
|
||||||
@ -291,12 +289,12 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
//位置之前有人,但是离开了
|
//位置之前有人,但是离开了
|
||||||
if (OldPlayer > 0)
|
if (OldPlayer > 0)
|
||||||
{
|
{
|
||||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerLeavnRoom, i, OldPlayer);
|
||||||
if (NewPlayer > 0)//而且害换了一个玩家
|
if (NewPlayer > 0)//而且害换了一个玩家
|
||||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||||
}
|
}
|
||||||
else //之前没人
|
else //之前没人
|
||||||
Eventer.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
EventSystem.Instance.PostEvent(EEvent.OnOtherPlayerJoinRoom, i, NewPlayer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +320,7 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
if (WaitStep != msg.WaitStep)
|
if (WaitStep != msg.WaitStep)
|
||||||
{
|
{
|
||||||
WaitStep = msg.WaitStep;
|
WaitStep = msg.WaitStep;
|
||||||
Eventer.Instance.PostEvent(EEvent.OnRoomWaitStepChange, WaitStep);
|
EventSystem.Instance.PostEvent(EEvent.OnRoomWaitStepChange, WaitStep);
|
||||||
if (WaitStep == 1)
|
if (WaitStep == 1)
|
||||||
{
|
{
|
||||||
byte[] decompressRawData = Helper.DecompressByteArray(msg.LoadStateRaw.ToByteArray());
|
byte[] decompressRawData = Helper.DecompressByteArray(msg.LoadStateRaw.ToByteArray());
|
||||||
@ -378,11 +376,6 @@ namespace AxibugEmuOnline.Client.Manager
|
|||||||
Protobuf_Screnn_Frame msg = ProtoBufHelper.DeSerizlize<Protobuf_Screnn_Frame>(reqData);
|
Protobuf_Screnn_Frame msg = ProtoBufHelper.DeSerizlize<Protobuf_Screnn_Frame>(reqData);
|
||||||
//解压
|
//解压
|
||||||
byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray());
|
byte[] data = Helper.DecompressByteArray(msg.RawBitmap.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void SendHostRaw(byte[] stateRaw)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
public int Index { get; private set; }
|
public int Index { get; private set; }
|
||||||
/// <summary> 在查询结果中的所在页 </summary>
|
/// <summary> 在查询结果中的所在页 </summary>
|
||||||
public int Page { get; private set; }
|
public int Page { get; private set; }
|
||||||
public string Hash => webData != null ? webData.hash : string.Empty;
|
|
||||||
|
|
||||||
public event Action OnDownloadOver;
|
public event Action OnDownloadOver;
|
||||||
public event Action OnInfoFilled;
|
public event Action OnInfoFilled;
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
using AxibugEmuOnline.Client.ClientCore;
|
||||||
using AxiReplay;
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using VirtualNes.Core;
|
using VirtualNes.Core;
|
||||||
|
|
||||||
@ -92,79 +90,10 @@ namespace AxibugEmuOnline.Client
|
|||||||
return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo);
|
return db.GetMapperNo(rom.GetPROM_CRC(), out mapperNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ControllerState m_sampledState;
|
|
||||||
public ControllerState GetControllerState()
|
public ControllerState GetControllerState()
|
||||||
{
|
{
|
||||||
if (!InGameUI.Instance.IsOnline)
|
var mapper = NesControllerMapper.Get();
|
||||||
{
|
return mapper.CreateState();
|
||||||
return m_sampledState;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//todo : 从服务器获取帧输入数据
|
|
||||||
return default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void SampleInput()
|
|
||||||
{
|
|
||||||
if (InGameUI.Instance.IsOnline)
|
|
||||||
{
|
|
||||||
if (App.roomMgr.netReplay.NextFrame(out var replayData, out int _))
|
|
||||||
{
|
|
||||||
m_sampledState = FromNet(replayData);
|
|
||||||
var localState = NesControllerMapper.Get().CreateState();
|
|
||||||
var rawData = ToNet(localState);
|
|
||||||
App.roomMgr.SendRoomSingelPlayerInput((uint)App.roomMgr.netReplay.mCurrPlayFrame, rawData);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sampledState = default;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sampledState = NesControllerMapper.Get().CreateState();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -87,8 +87,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
public Mapper START = new Mapper(EnumButtonType.START);
|
public Mapper START = new Mapper(EnumButtonType.START);
|
||||||
public Mapper MIC = new Mapper(EnumButtonType.MIC);
|
public Mapper MIC = new Mapper(EnumButtonType.MIC);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public EnumButtonType GetButtons()
|
public EnumButtonType GetButtons()
|
||||||
{
|
{
|
||||||
EnumButtonType res = 0;
|
EnumButtonType res = 0;
|
||||||
|
|||||||
@ -8,13 +8,14 @@ using VirtualNes.Core.Debug;
|
|||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
namespace AxibugEmuOnline.Client
|
||||||
{
|
{
|
||||||
|
|
||||||
public class NesEmulator : MonoBehaviour
|
public class NesEmulator : MonoBehaviour
|
||||||
{
|
{
|
||||||
public NES NesCore { get; private set; }
|
public NES NesCore { get; private set; }
|
||||||
|
|
||||||
public VideoProvider VideoProvider;
|
public VideoProvider VideoProvider;
|
||||||
public AudioProvider AudioProvider;
|
public AudioProvider AudioProvider;
|
||||||
public bool m_bPause;
|
|
||||||
|
|
||||||
private void Start()
|
private void Start()
|
||||||
{
|
{
|
||||||
@ -49,16 +50,9 @@ namespace AxibugEmuOnline.Client
|
|||||||
|
|
||||||
private void Update()
|
private void Update()
|
||||||
{
|
{
|
||||||
if (m_bPause) return;
|
|
||||||
|
|
||||||
if (NesCore != null)
|
if (NesCore != null)
|
||||||
{
|
{
|
||||||
Supporter.SampleInput();
|
|
||||||
var controlState = Supporter.GetControllerState();
|
var controlState = Supporter.GetControllerState();
|
||||||
|
|
||||||
//如果未收到Input数据,核心帧不推进
|
|
||||||
if (!controlState.valid) return;
|
|
||||||
|
|
||||||
NesCore.pad.Sync(controlState);
|
NesCore.pad.Sync(controlState);
|
||||||
NesCore.EmulateFrame(true);
|
NesCore.EmulateFrame(true);
|
||||||
|
|
||||||
@ -68,17 +62,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Pause()
|
|
||||||
{
|
|
||||||
m_bPause = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Resume()
|
|
||||||
{
|
|
||||||
m_bPause = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if UNITY_EDITOR
|
#if UNITY_EDITOR
|
||||||
[ContextMenu("ImportNesDB")]
|
[ContextMenu("ImportNesDB")]
|
||||||
public void ImportNesDB()
|
public void ImportNesDB()
|
||||||
|
|||||||
@ -441,10 +441,10 @@ RectTransform:
|
|||||||
m_Father: {fileID: 4232056520494431727}
|
m_Father: {fileID: 4232056520494431727}
|
||||||
m_RootOrder: 0
|
m_RootOrder: 0
|
||||||
m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0}
|
m_LocalEulerAnglesHint: {x: 180, y: 0, z: 0}
|
||||||
m_AnchorMin: {x: 0, y: 0}
|
m_AnchorMin: {x: 0.5, y: 0.5}
|
||||||
m_AnchorMax: {x: 1, y: 1}
|
m_AnchorMax: {x: 0.5, y: 0.5}
|
||||||
m_AnchoredPosition: {x: 0, y: 0}
|
m_AnchoredPosition: {x: 0, y: 0}
|
||||||
m_SizeDelta: {x: 0, y: 0}
|
m_SizeDelta: {x: 272, y: 240}
|
||||||
m_Pivot: {x: 0.5, y: 0.5}
|
m_Pivot: {x: 0.5, y: 0.5}
|
||||||
--- !u!222 &4232056521759880273
|
--- !u!222 &4232056521759880273
|
||||||
CanvasRenderer:
|
CanvasRenderer:
|
||||||
@ -466,7 +466,7 @@ MonoBehaviour:
|
|||||||
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
|
m_Script: {fileID: 11500000, guid: 1344c3c82d62a2a41a3576d8abb8e3ea, type: 3}
|
||||||
m_Name:
|
m_Name:
|
||||||
m_EditorClassIdentifier:
|
m_EditorClassIdentifier:
|
||||||
m_Material: {fileID: 2100000, guid: 07e28fcb992bc124e986f9d8ff3beb97, type: 2}
|
m_Material: {fileID: 0}
|
||||||
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
m_Color: {r: 1, g: 1, b: 1, a: 1}
|
||||||
m_RaycastTarget: 1
|
m_RaycastTarget: 1
|
||||||
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
|
||||||
@ -474,7 +474,7 @@ MonoBehaviour:
|
|||||||
m_OnCullStateChanged:
|
m_OnCullStateChanged:
|
||||||
m_PersistentCalls:
|
m_PersistentCalls:
|
||||||
m_Calls: []
|
m_Calls: []
|
||||||
m_Texture: {fileID: 0}
|
m_Texture: {fileID: 8400000, guid: ffe34aaf87e4b9942b4c2ac05943d444, type: 2}
|
||||||
m_UVRect:
|
m_UVRect:
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
x: 0
|
x: 0
|
||||||
@ -1,9 +1,5 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
|
||||||
using AxibugEmuOnline.Client.Event;
|
|
||||||
using AxibugEmuOnline.Client.Manager;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using VirtualNes.Core;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
namespace AxibugEmuOnline.Client
|
||||||
{
|
{
|
||||||
@ -13,28 +9,17 @@ namespace AxibugEmuOnline.Client
|
|||||||
|
|
||||||
public RomFile RomFile => m_rom;
|
public RomFile RomFile => m_rom;
|
||||||
public override bool Enable => gameObject.activeInHierarchy;
|
public override bool Enable => gameObject.activeInHierarchy;
|
||||||
|
|
||||||
/// <summary> 指示该游戏实例是否处于联网模式 </summary>
|
|
||||||
public bool IsOnline => App.roomMgr.RoomState > AxibugProtobuf.RoomGameState.OnlyHost;
|
|
||||||
|
|
||||||
private RomFile m_rom;
|
private RomFile m_rom;
|
||||||
private object m_core;
|
private object m_core;
|
||||||
private object m_state;
|
private object m_state;
|
||||||
|
|
||||||
private List<OptionMenu> menus = new List<OptionMenu>();
|
private InGameUI_SaveState m_saveStateMenu;
|
||||||
private StepPerformer m_stepPerformer;
|
private InGameUI_LoadState m_loadStateMenu;
|
||||||
|
|
||||||
protected override void Awake()
|
protected override void Awake()
|
||||||
{
|
{
|
||||||
Instance = this;
|
Instance = this;
|
||||||
gameObject.SetActiveEx(false);
|
gameObject.SetActiveEx(false);
|
||||||
|
|
||||||
m_stepPerformer = new StepPerformer(this);
|
|
||||||
|
|
||||||
menus.Add(new InGameUI_SaveState(this));
|
|
||||||
menus.Add(new InGameUI_LoadState(this));
|
|
||||||
menus.Add(new InGameUI_QuitGame(this));
|
|
||||||
|
|
||||||
base.Awake();
|
base.Awake();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,31 +56,22 @@ namespace AxibugEmuOnline.Client
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Show(RomFile currentRom, object core)
|
public void Show(RomFile currentRom, object core)
|
||||||
{
|
{
|
||||||
CommandDispatcher.Instance.RegistController(this);
|
CommandDispatcher.Instance.RegistController(this);
|
||||||
|
|
||||||
|
m_saveStateMenu = new InGameUI_SaveState(this);
|
||||||
|
m_loadStateMenu = new InGameUI_LoadState(this);
|
||||||
|
|
||||||
m_rom = currentRom;
|
m_rom = currentRom;
|
||||||
m_core = core;
|
m_core = core;
|
||||||
m_stepPerformer.Reset();
|
|
||||||
|
|
||||||
if (App.user.IsLoggedIn)
|
|
||||||
{
|
|
||||||
App.roomMgr.SendCreateRoom(m_rom.ID, 0, m_rom.Hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
Eventer.Instance.RegisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
|
||||||
|
|
||||||
gameObject.SetActiveEx(true);
|
gameObject.SetActiveEx(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnServerStepUpdate(int step)
|
|
||||||
{
|
|
||||||
m_stepPerformer.Perform(step);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Hide()
|
public void Hide()
|
||||||
{
|
{
|
||||||
CommandDispatcher.Instance.UnRegistController(this);
|
CommandDispatcher.Instance.UnRegistController(this);
|
||||||
@ -105,14 +81,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
|
|
||||||
protected override void OnCmdOptionMenu()
|
protected override void OnCmdOptionMenu()
|
||||||
{
|
{
|
||||||
OptionUI.Instance.Pop(menus);
|
OptionUI.Instance.Pop(new List<OptionMenu> { m_saveStateMenu, m_loadStateMenu });
|
||||||
}
|
|
||||||
|
|
||||||
public void QuitGame()
|
|
||||||
{
|
|
||||||
Eventer.Instance.UnregisterEvent<int>(EEvent.OnRoomWaitStepChange, OnServerStepUpdate);
|
|
||||||
App.roomMgr.SendLeavnRoom();
|
|
||||||
App.emu.StopGame();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
public class InGameUI_LoadState : ExecuteMenu
|
public class InGameUI_LoadState : ExecuteMenu
|
||||||
{
|
{
|
||||||
private InGameUI m_gameUI;
|
private InGameUI m_gameUI;
|
||||||
public override bool Visible => !m_gameUI.IsOnline;
|
|
||||||
|
|
||||||
public InGameUI_LoadState(InGameUI gameUI) : base("뗍혤우亮", null)
|
public InGameUI_LoadState(InGameUI gameUI) : base("뗍혤우亮", null)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,18 +0,0 @@
|
|||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public class InGameUI_QuitGame : ExecuteMenu
|
|
||||||
{
|
|
||||||
private InGameUI m_gameUI;
|
|
||||||
|
|
||||||
|
|
||||||
public InGameUI_QuitGame(InGameUI gameUI) : base("ÍËłö", null)
|
|
||||||
{
|
|
||||||
m_gameUI = gameUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void OnExcute()
|
|
||||||
{
|
|
||||||
m_gameUI.QuitGame();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 7689fa8f7ddd5654f914b93a4f0efada
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -1,7 +1,5 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
using AxibugEmuOnline.Client.ClientCore;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
namespace AxibugEmuOnline.Client
|
||||||
{
|
{
|
||||||
@ -9,8 +7,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
{
|
{
|
||||||
private InGameUI m_gameUI;
|
private InGameUI m_gameUI;
|
||||||
|
|
||||||
public override bool Visible => !m_gameUI.IsOnline;
|
|
||||||
|
|
||||||
public InGameUI_SaveState(InGameUI gameUI) : base("ąŁ´ćżěŐŐ", null)
|
public InGameUI_SaveState(InGameUI gameUI) : base("ąŁ´ćżěŐŐ", null)
|
||||||
{
|
{
|
||||||
m_gameUI = gameUI;
|
m_gameUI = gameUI;
|
||||||
@ -24,6 +20,7 @@ namespace AxibugEmuOnline.Client
|
|||||||
case EnumPlatform.NES:
|
case EnumPlatform.NES:
|
||||||
var state = m_gameUI.GetCore<NesEmulator>().NesCore.GetState();
|
var state = m_gameUI.GetCore<NesEmulator>().NesCore.GetState();
|
||||||
m_gameUI.SaveQuickState(state);
|
m_gameUI.SaveQuickState(state);
|
||||||
|
App.log.Info($"{m_gameUI.RomFile.Platform}===>快照大小{state.ToBytes().Length}");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
sw.Stop();
|
sw.Stop();
|
||||||
|
|||||||
@ -1,75 +0,0 @@
|
|||||||
using AxibugEmuOnline.Client.ClientCore;
|
|
||||||
using System;
|
|
||||||
using VirtualNes.Core;
|
|
||||||
|
|
||||||
namespace AxibugEmuOnline.Client
|
|
||||||
{
|
|
||||||
public class StepPerformer
|
|
||||||
{
|
|
||||||
private InGameUI m_inGameUI;
|
|
||||||
private int m_step = -1;
|
|
||||||
|
|
||||||
public StepPerformer(InGameUI inGameUI)
|
|
||||||
{
|
|
||||||
m_inGameUI = inGameUI;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Perform(int step)
|
|
||||||
{
|
|
||||||
m_step = step;
|
|
||||||
|
|
||||||
|
|
||||||
switch (m_step)
|
|
||||||
{
|
|
||||||
//等待主机上报快照
|
|
||||||
case 0:
|
|
||||||
PauseCore();
|
|
||||||
if (App.roomMgr.IsHost)
|
|
||||||
{
|
|
||||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
|
||||||
{
|
|
||||||
var stateRaw = m_inGameUI.GetCore<NesEmulator>().NesCore.GetState().ToBytes();
|
|
||||||
App.roomMgr.SendHostRaw(stateRaw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
//加载存档并发送Ready通知
|
|
||||||
case 1:
|
|
||||||
PauseCore();
|
|
||||||
var state = new State();
|
|
||||||
state.FromByte(App.roomMgr.RawData);
|
|
||||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
|
||||||
{
|
|
||||||
m_inGameUI.GetCore<NesEmulator>().NesCore.LoadState(state);
|
|
||||||
}
|
|
||||||
App.roomMgr.SendRoomPlayerReady();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
m_step = -1;
|
|
||||||
ResumeCore();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void PauseCore()
|
|
||||||
{
|
|
||||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
|
||||||
{
|
|
||||||
m_inGameUI.GetCore<NesEmulator>().Pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ResumeCore()
|
|
||||||
{
|
|
||||||
if (m_inGameUI.RomFile.Platform == EnumPlatform.NES)
|
|
||||||
{
|
|
||||||
m_inGameUI.GetCore<NesEmulator>().Resume();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void Reset()
|
|
||||||
{
|
|
||||||
m_step = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6e5033cf98f86804bb50f84e3bbc956a
|
|
||||||
MonoImporter:
|
|
||||||
externalObjects: {}
|
|
||||||
serializedVersion: 2
|
|
||||||
defaultReferences: []
|
|
||||||
executionOrder: 0
|
|
||||||
icon: {instanceID: 0}
|
|
||||||
userData:
|
|
||||||
assetBundleName:
|
|
||||||
assetBundleVariant:
|
|
||||||
@ -62,54 +62,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
MenuRoot.anchoredPosition = temp;
|
MenuRoot.anchoredPosition = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
|
||||||
{
|
|
||||||
UpdateMenuState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateMenuState()
|
|
||||||
{
|
|
||||||
bool dirty = false;
|
|
||||||
foreach (var menuItem in m_runtimeMenuItems)
|
|
||||||
{
|
|
||||||
if (menuItem.gameObject.activeSelf != menuItem.Visible)
|
|
||||||
{
|
|
||||||
dirty = true;
|
|
||||||
menuItem.gameObject.SetActive(menuItem.Visible);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (dirty)
|
|
||||||
{
|
|
||||||
if (m_runtimeMenuItems[SelectIndex].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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (find)
|
|
||||||
SelectIndex = currentSelect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Pop(List<OptionMenu> menus, int defaultIndex = 0)
|
public void Pop(List<OptionMenu> menus, int defaultIndex = 0)
|
||||||
{
|
{
|
||||||
ReleaseRuntimeMenus();
|
ReleaseRuntimeMenus();
|
||||||
@ -131,7 +83,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
if (!m_bPoped)
|
if (!m_bPoped)
|
||||||
{
|
{
|
||||||
m_bPoped = true;
|
m_bPoped = true;
|
||||||
|
|
||||||
DOTween.To(
|
DOTween.To(
|
||||||
() => MenuRoot.anchoredPosition.x,
|
() => MenuRoot.anchoredPosition.x,
|
||||||
(value) =>
|
(value) =>
|
||||||
@ -143,7 +94,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
0,
|
0,
|
||||||
0.3f
|
0.3f
|
||||||
).SetEase(Ease.OutCubic);
|
).SetEase(Ease.OutCubic);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,11 +101,10 @@ namespace AxibugEmuOnline.Client
|
|||||||
{
|
{
|
||||||
if (m_bPoped)
|
if (m_bPoped)
|
||||||
{
|
{
|
||||||
m_runtimeMenuItems.Clear();
|
|
||||||
|
|
||||||
SelectBorder.gameObject.SetActiveEx(false);
|
SelectBorder.gameObject.SetActiveEx(false);
|
||||||
|
|
||||||
CommandDispatcher.Instance.UnRegistController(this);
|
CommandDispatcher.Instance.UnRegistController(this);
|
||||||
|
m_bPoped = false;
|
||||||
Canvas.ForceUpdateCanvases();
|
Canvas.ForceUpdateCanvases();
|
||||||
var width = MenuRoot.rect.width;
|
var width = MenuRoot.rect.width;
|
||||||
DOTween.To(
|
DOTween.To(
|
||||||
@ -169,8 +118,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
width,
|
width,
|
||||||
0.3f
|
0.3f
|
||||||
).SetEase(Ease.OutCubic);
|
).SetEase(Ease.OutCubic);
|
||||||
|
|
||||||
m_bPoped = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,8 +12,6 @@ namespace AxibugEmuOnline.Client
|
|||||||
[SerializeField] Text m_MenuNameTxt;
|
[SerializeField] Text m_MenuNameTxt;
|
||||||
[SerializeField] Image m_Icon;
|
[SerializeField] Image m_Icon;
|
||||||
|
|
||||||
public bool Visible => m_Menu.Visible;
|
|
||||||
|
|
||||||
protected OptionMenu m_Menu;
|
protected OptionMenu m_Menu;
|
||||||
|
|
||||||
public void SetData(OptionMenu menuData)
|
public void SetData(OptionMenu menuData)
|
||||||
|
|||||||
@ -1,8 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Runtime.Serialization.Formatters.Binary;
|
|
||||||
|
|
||||||
namespace VirtualNes.Core
|
namespace VirtualNes.Core
|
||||||
{
|
{
|
||||||
@ -46,25 +42,20 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
HEADER.SaveState(buffer);
|
HEADER.SaveState(buffer);
|
||||||
|
|
||||||
buffer.Write(WRAM != null ? WRAM.Length : 0);
|
|
||||||
buffer.Write(CPU_MEM_BANK != null ? CPU_MEM_BANK.Count : 0);
|
|
||||||
buffer.Write(VRAM != null ? VRAM.Length : 0);
|
|
||||||
buffer.Write(CRAM != null ? CRAM.Count : 0);
|
|
||||||
buffer.Write(dskdata != null ? dskdata.Count : 0);
|
|
||||||
|
|
||||||
if (regBLOCK.Valid)
|
if (regBLOCK.Valid)
|
||||||
{
|
{
|
||||||
regBLOCK.SaveState(buffer);
|
regBLOCK.SaveState(buffer);
|
||||||
reg.SaveState(buffer);
|
reg.SaveState(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ramBLOCK.Valid)
|
if (regBLOCK.Valid)
|
||||||
{
|
{
|
||||||
ramBLOCK.SaveState(buffer);
|
ramBLOCK.SaveState(buffer);
|
||||||
ram.SaveState(buffer);
|
ram.SaveState(buffer);
|
||||||
if (WRAM != null) buffer.Write(WRAM);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (WRAM != null) buffer.Write(WRAM);
|
||||||
|
|
||||||
if (mmuBLOCK.Valid)
|
if (mmuBLOCK.Valid)
|
||||||
{
|
{
|
||||||
mmuBLOCK.SaveState(buffer);
|
mmuBLOCK.SaveState(buffer);
|
||||||
@ -110,69 +101,5 @@ namespace VirtualNes.Core
|
|||||||
|
|
||||||
return buffer.Data.ToArray();
|
return buffer.Data.ToArray();
|
||||||
}
|
}
|
||||||
public void FromByte(byte[] data)
|
|
||||||
{
|
|
||||||
StateReader buffer = new StateReader(data);
|
|
||||||
|
|
||||||
HEADER.LoadState(buffer);
|
|
||||||
|
|
||||||
var WRAM_Length = buffer.Read_int();
|
|
||||||
var CPU_MEM_BANK_Length = buffer.Read_int();
|
|
||||||
var VRAM_Length = buffer.Read_int();
|
|
||||||
var CRAM_Length = buffer.Read_int();
|
|
||||||
var dskdata_Length = buffer.Read_int();
|
|
||||||
|
|
||||||
while (buffer.Remain > 0)
|
|
||||||
{
|
|
||||||
BLOCKHDR block = new BLOCKHDR();
|
|
||||||
block.LoadState(buffer);
|
|
||||||
|
|
||||||
switch (block.ID)
|
|
||||||
{
|
|
||||||
case "REG DATA":
|
|
||||||
regBLOCK = block;
|
|
||||||
reg.LoadState(buffer);
|
|
||||||
break;
|
|
||||||
case "RAM DATA":
|
|
||||||
ramBLOCK = block;
|
|
||||||
ram.LoadState(buffer);
|
|
||||||
if (WRAM_Length > 0)
|
|
||||||
WRAM = buffer.Read_bytes(WRAM_Length);
|
|
||||||
break;
|
|
||||||
case "MMU DATA":
|
|
||||||
mmuBLOCK = block;
|
|
||||||
mmu.LoadState(buffer);
|
|
||||||
if (CPU_MEM_BANK_Length > 0)
|
|
||||||
CPU_MEM_BANK = new List<byte>(buffer.Read_bytes(CPU_MEM_BANK_Length));
|
|
||||||
if (VRAM_Length > 0)
|
|
||||||
VRAM = buffer.Read_bytes(VRAM_Length);
|
|
||||||
if (CRAM_Length > 0)
|
|
||||||
CRAM = new List<byte>(buffer.Read_bytes(CRAM_Length));
|
|
||||||
break;
|
|
||||||
case "MMC DATA":
|
|
||||||
mmcBLOCK = block;
|
|
||||||
mmc.LoadState(buffer);
|
|
||||||
break;
|
|
||||||
case "CTR DATA":
|
|
||||||
ctrBLOCK = block;
|
|
||||||
ctr.LoadState(buffer);
|
|
||||||
break;
|
|
||||||
case "SND DATA":
|
|
||||||
sndBLOCK = block;
|
|
||||||
snd.LoadState(buffer);
|
|
||||||
break;
|
|
||||||
case "DISKDATA":
|
|
||||||
dskBLOCK = block;
|
|
||||||
dsk.LoadState(buffer);
|
|
||||||
if (dskdata_Length > 0)
|
|
||||||
dskdata = new List<uint>(buffer.Read_uints(dskdata_Length));
|
|
||||||
break;
|
|
||||||
case "EXCTRDAT":
|
|
||||||
exctrBLOCK = block;
|
|
||||||
exctr.LoadState(buffer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,9 +85,6 @@ namespace VirtualNes.Core
|
|||||||
public class StateReader
|
public class StateReader
|
||||||
{
|
{
|
||||||
private MemoryStream m_dataStream;
|
private MemoryStream m_dataStream;
|
||||||
|
|
||||||
public long Remain => m_dataStream.Length - 1 - m_dataStream.Position;
|
|
||||||
|
|
||||||
public StateReader(byte[] bytes)
|
public StateReader(byte[] bytes)
|
||||||
{
|
{
|
||||||
m_dataStream = new MemoryStream(bytes);
|
m_dataStream = new MemoryStream(bytes);
|
||||||
@ -128,10 +125,10 @@ namespace VirtualNes.Core
|
|||||||
ushort[] result = new ushort[length];
|
ushort[] result = new ushort[length];
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
TEMP[0] = (byte)m_dataStream.ReadByte();
|
int byte1 = m_dataStream.ReadByte();
|
||||||
TEMP[1] = (byte)m_dataStream.ReadByte();
|
int byte2 = m_dataStream.ReadByte();
|
||||||
|
|
||||||
result[i] = BitConverter.ToUInt16(TEMP, 0);
|
result[i] = (ushort)(byte1 << 8 | byte2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -141,12 +138,12 @@ namespace VirtualNes.Core
|
|||||||
int[] result = new int[length];
|
int[] result = new int[length];
|
||||||
for (int i = 0; i < length; i++)
|
for (int i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
TEMP[0] = (byte)m_dataStream.ReadByte();
|
int byte1 = m_dataStream.ReadByte();
|
||||||
TEMP[1] = (byte)m_dataStream.ReadByte();
|
int byte2 = m_dataStream.ReadByte();
|
||||||
TEMP[2] = (byte)m_dataStream.ReadByte();
|
int byte3 = m_dataStream.ReadByte();
|
||||||
TEMP[3] = (byte)m_dataStream.ReadByte();
|
int byte4 = m_dataStream.ReadByte();
|
||||||
|
|
||||||
result[i] = BitConverter.ToInt32(TEMP, 0);
|
result[i] = byte1 << 24 | byte2 << 16 | byte3 << 8 | byte4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -163,23 +160,21 @@ namespace VirtualNes.Core
|
|||||||
var result = Read_bytes(4);
|
var result = Read_bytes(4);
|
||||||
return BitConverter.ToDouble(result, 0);
|
return BitConverter.ToDouble(result, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] TEMP = new byte[8];
|
|
||||||
|
|
||||||
public ushort Read_ushort()
|
public ushort Read_ushort()
|
||||||
{
|
{
|
||||||
TEMP[0] = Read_byte();
|
var b1 = Read_byte();
|
||||||
TEMP[1] = Read_byte();
|
var b2 = Read_byte();
|
||||||
return BitConverter.ToUInt16(TEMP, 0);
|
return (ushort)(b1 << 8 | b2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int Read_int()
|
public int Read_int()
|
||||||
{
|
{
|
||||||
TEMP[0] = Read_byte();
|
var b1 = Read_byte();
|
||||||
TEMP[1] = Read_byte();
|
var b2 = Read_byte();
|
||||||
TEMP[2] = Read_byte();
|
var b3 = Read_byte();
|
||||||
TEMP[3] = Read_byte();
|
var b4 = Read_byte();
|
||||||
return BitConverter.ToInt32(TEMP, 0);
|
|
||||||
|
return b1 << 24 | b2 << 16 | b3 << 8 | b4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public sbyte Read_sbyte(sbyte value)
|
public sbyte Read_sbyte(sbyte value)
|
||||||
@ -188,32 +183,22 @@ namespace VirtualNes.Core
|
|||||||
}
|
}
|
||||||
public long Read_long()
|
public long Read_long()
|
||||||
{
|
{
|
||||||
TEMP[0] = Read_byte();
|
var b1 = Read_byte();
|
||||||
TEMP[1] = Read_byte();
|
var b2 = Read_byte();
|
||||||
TEMP[2] = Read_byte();
|
var b3 = Read_byte();
|
||||||
TEMP[3] = Read_byte();
|
var b4 = Read_byte();
|
||||||
TEMP[4] = Read_byte();
|
var b5 = Read_byte();
|
||||||
TEMP[5] = Read_byte();
|
var b6 = Read_byte();
|
||||||
TEMP[6] = Read_byte();
|
var b7 = Read_byte();
|
||||||
TEMP[7] = Read_byte();
|
var b8 = Read_byte();
|
||||||
|
|
||||||
return BitConverter.ToInt64(TEMP, 0);
|
return b1 << 56 | b2 << 48 | b3 << 40 | b4 << 32 | b5 << 24 | b6 << 16 | b7 << 8 | b8;
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint Read_uint()
|
public uint Read_uint()
|
||||||
{
|
{
|
||||||
return (uint)Read_int();
|
return (uint)Read_int();
|
||||||
}
|
}
|
||||||
|
|
||||||
public uint[] Read_uints(int length)
|
|
||||||
{
|
|
||||||
uint[] ret = new uint[length];
|
|
||||||
for (int i = 0; i < length; i++)
|
|
||||||
{
|
|
||||||
ret[i] = Read_uint();
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IStateBufferObject
|
public interface IStateBufferObject
|
||||||
|
|||||||
@ -4,12 +4,10 @@ namespace VirtualNes.Core
|
|||||||
{
|
{
|
||||||
public struct ControllerState
|
public struct ControllerState
|
||||||
{
|
{
|
||||||
public uint raw0;
|
private uint raw0;
|
||||||
public uint raw1;
|
private uint raw1;
|
||||||
public uint raw2;
|
private uint raw2;
|
||||||
public uint raw3;
|
private uint raw3;
|
||||||
|
|
||||||
public bool valid;
|
|
||||||
|
|
||||||
public ControllerState(
|
public ControllerState(
|
||||||
EnumButtonType player0_buttons,
|
EnumButtonType player0_buttons,
|
||||||
@ -21,7 +19,6 @@ namespace VirtualNes.Core
|
|||||||
raw1 = (uint)player1_buttons;
|
raw1 = (uint)player1_buttons;
|
||||||
raw2 = (uint)player2_buttons;
|
raw2 = (uint)player2_buttons;
|
||||||
raw3 = (uint)player3_buttons;
|
raw3 = (uint)player3_buttons;
|
||||||
valid = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool HasButton(int player, EnumButtonType button)
|
public bool HasButton(int player, EnumButtonType button)
|
||||||
|
|||||||
@ -59,11 +59,6 @@ namespace VirtualNes.Core
|
|||||||
return s_support.GetControllerState();
|
return s_support.GetControllerState();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void SampleInput()
|
|
||||||
{
|
|
||||||
s_support.SampleInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static EmulatorConfig Config => s_support.Config;
|
public static EmulatorConfig Config => s_support.Config;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,6 +76,5 @@ namespace VirtualNes.Core
|
|||||||
Stream OpenFile(string directPath, string fileName);
|
Stream OpenFile(string directPath, string fileName);
|
||||||
bool TryGetMapperNo(ROM rom, out int mapperNo);
|
bool TryGetMapperNo(ROM rom, out int mapperNo);
|
||||||
ControllerState GetControllerState();
|
ControllerState GetControllerState();
|
||||||
void SampleInput();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,7 +34,7 @@ enum CommandID
|
|||||||
// 主机玩家 上行 CMD_Room_HostPlayer_UpdateStateRaw消息,上传即时存档
|
// 主机玩家 上行 CMD_Room_HostPlayer_UpdateStateRaw消息,上传即时存档
|
||||||
// 主机玩家上传完毕之后,服务器会通知进入Step1
|
// 主机玩家上传完毕之后,服务器会通知进入Step1
|
||||||
//
|
//
|
||||||
// Step1:服务器广播"等待-全员加载即时存档" CMD_Room_WaitStep WaitStep=[1] 附带即时存档 ---> 客户端:全员等待
|
// Step1:服务器广播"等待-全员加载即时存档" CMD_Room_WaitStep WaitStep=[1] 附带即时存档 ---> 客户端:全员等待(主机玩家一人上传)
|
||||||
// 所有玩家确保加载ROM和即时存档,并保持模拟器暂停,准备完毕后 发送 CMD_Room_Player_Ready
|
// 所有玩家确保加载ROM和即时存档,并保持模拟器暂停,准备完毕后 发送 CMD_Room_Player_Ready
|
||||||
// 所有玩家Ready之后,服务器会根据所有玩家延迟提前跑若干Frame,通知进入Step2
|
// 所有玩家Ready之后,服务器会根据所有玩家延迟提前跑若干Frame,通知进入Step2
|
||||||
//
|
//
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user