进一步接入Essgss.Unity,键值和即时存档

This commit is contained in:
sin365 2025-02-17 17:48:48 +08:00
parent 6b5b5931c1
commit 3bda78d3e5
85 changed files with 2449 additions and 971 deletions

View File

@ -1,7 +1,4 @@
using Essgee.Emulation.Configuration; using Essgee.Emulation.Configuration;
using Essgee.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 267425c59f2efba48a44a3b55a5eb01d guid: 289897a5723c6484ca800ed09fb528f5
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: ab3f0235ad62cb046ac1518f29d21e81 guid: 957a410fe17ff6242ab46d90146f525d
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,6 +1,4 @@
using System.Collections.Generic; namespace Essgee.Emulation.Audio
namespace Essgee.Emulation.Audio
{ {
public partial class CGBAudio : DMGAudio, IAudio public partial class CGBAudio : DMGAudio, IAudio
{ {

View File

@ -2,8 +2,6 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
namespace Essgee.Emulation.Audio namespace Essgee.Emulation.Audio
@ -130,6 +128,24 @@ namespace Essgee.Emulation.Audio
channel4ForceEnable = true; channel4ForceEnable = true;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
sampleCycleCount = BitConverter.ToInt32(data.MemberData[nameof(sampleCycleCount)]);
frameCycleCount = BitConverter.ToInt32(data.MemberData[nameof(frameCycleCount)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(sampleCycleCount)] = BitConverter.GetBytes(sampleCycleCount);
data.MemberData[nameof(frameCycleCount)] = BitConverter.GetBytes(frameCycleCount);
return data;
}
#endregion
public object GetRuntimeOption(string name) public object GetRuntimeOption(string name)
{ {
switch (name) switch (name)

View File

@ -3,7 +3,7 @@ using System;
namespace Essgee.Emulation.Audio namespace Essgee.Emulation.Audio
{ {
interface IAudio interface IAudio : IAxiStatus
{ {
event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples; event EventHandler<EnqueueSamplesEventArgs> EnqueueSamples;
void OnEnqueueSamples(EnqueueSamplesEventArgs e); void OnEnqueueSamples(EnqueueSamplesEventArgs e);

View File

@ -2,7 +2,6 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
@ -157,6 +156,46 @@ namespace Essgee.Emulation.Audio
channel4ForceEnable = true; channel4ForceEnable = true;
} }
#region AxiState
public virtual void LoadAxiStatus(AxiEssgssStatusData data)
{
volumeRegisters = data.MemberData[nameof(volumeRegisters)].ToUShortArray();
toneRegisters = data.MemberData[nameof(toneRegisters)].ToUShortArray();
channelCounters = data.MemberData[nameof(channelCounters)].ToUShortArray();
channelOutput = data.MemberData[nameof(channelOutput)].ToBoolArray();
latchedChannel = data.MemberData[nameof(latchedChannel)].First();
latchedType = data.MemberData[nameof(latchedType)].First();
noiseLfsr = BitConverter.ToUInt16(data.MemberData[nameof(noiseLfsr)]);
sampleCycleCount = BitConverter.ToInt32(data.MemberData[nameof(sampleCycleCount)]);
frameCycleCount = BitConverter.ToInt32(data.MemberData[nameof(frameCycleCount)]);
dividerCount = BitConverter.ToInt32(data.MemberData[nameof(dividerCount)]);
}
public virtual AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(volumeRegisters)] = volumeRegisters.ToByteArray();
data.MemberData[nameof(toneRegisters)] = toneRegisters.ToByteArray();
data.MemberData[nameof(channelCounters)] = channelCounters.ToByteArray();
data.MemberData[nameof(channelOutput)] = channelOutput.ToByteArray();
data.MemberData[nameof(latchedChannel)] = BitConverter.GetBytes(latchedChannel);
data.MemberData[nameof(latchedType)] = BitConverter.GetBytes(latchedType);
data.MemberData[nameof(noiseLfsr)] = BitConverter.GetBytes(noiseLfsr);
data.MemberData[nameof(sampleCycleCount)] = BitConverter.GetBytes(sampleCycleCount);
data.MemberData[nameof(frameCycleCount)] = BitConverter.GetBytes(frameCycleCount);
data.MemberData[nameof(dividerCount)] = BitConverter.GetBytes(dividerCount);
return data;
}
#endregion
public object GetRuntimeOption(string name) public object GetRuntimeOption(string name)
{ {
switch (name) switch (name)

View File

@ -15,5 +15,20 @@
noiseLfsr = 0x8000; noiseLfsr = 0x8000;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
base.LoadAxiStatus(data);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = base.SaveAxiStatus();
return data;
}
#endregion
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 11616634c9d44b541b8505293e437778 guid: ac5ab16607ba9574992b980c27ee0bba
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,6 +1,6 @@
namespace Essgee.Emulation.CPU namespace Essgee.Emulation.CPU
{ {
interface ICPU interface ICPU : IAxiStatus
{ {
void Startup(); void Startup();
void Shutdown(); void Shutdown();

View File

@ -20,6 +20,10 @@ namespace Essgee.Emulation.CPU
[FieldOffset(0)] [FieldOffset(0)]
public ushort Word; public ushort Word;
[FieldOffset(0)]
public ushort axi_AllData;
} }
} }
} }

View File

@ -74,6 +74,51 @@ namespace Essgee.Emulation.CPU
} }
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
af.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(af)]);
bc.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(bc)]);
de.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(de)]);
hl.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(hl)]);
sp = BitConverter.ToUInt16(data.MemberData[nameof(sp)]);
pc = BitConverter.ToUInt16(data.MemberData[nameof(pc)]);
ime = BitConverter.ToBoolean(data.MemberData[nameof(ime)]);
imeDelay = BitConverter.ToBoolean(data.MemberData[nameof(imeDelay)]);
halt = BitConverter.ToBoolean(data.MemberData[nameof(halt)]);
doHaltBug = BitConverter.ToBoolean(data.MemberData[nameof(doHaltBug)]);
op = data.MemberData[nameof(op)].First();
currentCycles = BitConverter.ToInt32(data.MemberData[nameof(currentCycles)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(af)] = BitConverter.GetBytes(af.axi_AllData);
data.MemberData[nameof(bc)] = BitConverter.GetBytes(bc.axi_AllData);
data.MemberData[nameof(de)] = BitConverter.GetBytes(de.axi_AllData);
data.MemberData[nameof(hl)] = BitConverter.GetBytes(hl.axi_AllData);
data.MemberData[nameof(sp)] = BitConverter.GetBytes(sp);
data.MemberData[nameof(pc)] = BitConverter.GetBytes(pc);
data.MemberData[nameof(ime)] = BitConverter.GetBytes(ime);
data.MemberData[nameof(imeDelay)] = BitConverter.GetBytes(imeDelay);
data.MemberData[nameof(halt)] = BitConverter.GetBytes(halt);
data.MemberData[nameof(doHaltBug)] = BitConverter.GetBytes(doHaltBug);
data.MemberData[nameof(op)] = BitConverter.GetBytes(op);
data.MemberData[nameof(currentCycles)] = BitConverter.GetBytes(currentCycles);
return data;
}
#endregion
public virtual void Startup() public virtual void Startup()
{ {
Reset(); Reset();

View File

@ -20,6 +20,10 @@ namespace Essgee.Emulation.CPU
[FieldOffset(0)] [FieldOffset(0)]
public ushort Word; public ushort Word;
[FieldOffset(0)]
public ushort axi_AllData;
} }
} }
} }

View File

@ -1,6 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
namespace Essgee.Emulation.CPU namespace Essgee.Emulation.CPU
@ -71,6 +72,80 @@ namespace Essgee.Emulation.CPU
portWriteDelegate = portWrite; portWriteDelegate = portWrite;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
af.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(af)]);
bc.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(bc)]);
de.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(de)]);
hl.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(hl)]);
af_.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(af_)]);
bc_.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(bc_)]);
de_.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(de_)]);
hl_.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(hl_)]);
ix.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(ix)]);
iy.axi_AllData = BitConverter.ToUInt16(data.MemberData[nameof(iy)]);
i = data.MemberData[nameof(i)].First();
r = data.MemberData[nameof(r)].First();
sp = BitConverter.ToUInt16(data.MemberData[nameof(sp)]);
pc = BitConverter.ToUInt16(data.MemberData[nameof(pc)]);
iff1 = BitConverter.ToBoolean(data.MemberData[nameof(iff1)]);
iff2 = BitConverter.ToBoolean(data.MemberData[nameof(iff2)]);
eiDelay = BitConverter.ToBoolean(data.MemberData[nameof(eiDelay)]);
halt = BitConverter.ToBoolean(data.MemberData[nameof(halt)]);
im = data.MemberData[nameof(im)].First();
op = data.MemberData[nameof(op)].First();
intState = data.MemberData[nameof(intState)].ToEnum<InterruptState>();
nmiState = data.MemberData[nameof(nmiState)].ToEnum<InterruptState>();
currentCycles = BitConverter.ToInt32(data.MemberData[nameof(currentCycles)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(af)] = BitConverter.GetBytes(af.axi_AllData);
data.MemberData[nameof(bc)] = BitConverter.GetBytes(bc.axi_AllData);
data.MemberData[nameof(de)] = BitConverter.GetBytes(de.axi_AllData);
data.MemberData[nameof(hl)] = BitConverter.GetBytes(hl.axi_AllData);
data.MemberData[nameof(af_)] = BitConverter.GetBytes(af_.axi_AllData);
data.MemberData[nameof(bc_)] = BitConverter.GetBytes(bc_.axi_AllData);
data.MemberData[nameof(de_)] = BitConverter.GetBytes(de_.axi_AllData);
data.MemberData[nameof(hl_)] = BitConverter.GetBytes(hl_.axi_AllData);
data.MemberData[nameof(i)] = BitConverter.GetBytes(i);
data.MemberData[nameof(r)] = BitConverter.GetBytes(r);
data.MemberData[nameof(ix)] = BitConverter.GetBytes(ix.axi_AllData);
data.MemberData[nameof(iy)] = BitConverter.GetBytes(iy.axi_AllData);
data.MemberData[nameof(sp)] = BitConverter.GetBytes(sp);
data.MemberData[nameof(pc)] = BitConverter.GetBytes(pc);
data.MemberData[nameof(iff1)] = BitConverter.GetBytes(iff1);
data.MemberData[nameof(iff2)] = BitConverter.GetBytes(iff2);
data.MemberData[nameof(eiDelay)] = BitConverter.GetBytes(eiDelay);
data.MemberData[nameof(halt)] = BitConverter.GetBytes(halt);
data.MemberData[nameof(im)] = BitConverter.GetBytes(im);
data.MemberData[nameof(op)] = BitConverter.GetBytes(op);
data.MemberData[nameof(intState)] = intState.ToByteArray();
data.MemberData[nameof(nmiState)] = nmiState.ToByteArray();
data.MemberData[nameof(currentCycles)] = BitConverter.GetBytes(currentCycles);
return data;
}
#endregion
public virtual void Startup() public virtual void Startup()
{ {
Reset(); Reset();

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: fd37849c4f2dfbb4fa2e82cdc6fc36e3 guid: fc75a07f5083eef408264c31457c5131
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3f9cb94bc81a41e45a844926b14f89eb guid: 1185c3d60bd11204ead23f542a5c6427
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -8,6 +8,18 @@ namespace Essgee.Emulation.Cartridges.Coleco
byte[] romData; byte[] romData;
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public ColecoCartridge(int romSize, int ramSize) public ColecoCartridge(int romSize, int ramSize)
{ {
romData = new byte[romSize]; romData = new byte[romSize];

View File

@ -1,6 +1,6 @@
namespace Essgee.Emulation.Cartridges namespace Essgee.Emulation.Cartridges
{ {
public interface ICartridge internal interface ICartridge : IAxiStatus
{ {
void LoadRom(byte[] data); void LoadRom(byte[] data);
void LoadRam(byte[] data); void LoadRam(byte[] data);

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3eb99a6b5fa5ea348b79aa6dfc080f12 guid: eea6a30841878a34286f04f99571c050
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -65,6 +65,20 @@ namespace Essgee.Emulation.Cartridges.Nintendo
hasBattery = false; hasBattery = false;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -1,6 +1,6 @@
namespace Essgee.Emulation.Cartridges.Nintendo namespace Essgee.Emulation.Cartridges.Nintendo
{ {
public interface IGameBoyCartridge : ICartridge internal interface IGameBoyCartridge : ICartridge
{ {
void SetCartridgeConfig(bool battery, bool rtc, bool rumble); void SetCartridgeConfig(bool battery, bool rtc, bool rumble);
} }

View File

@ -27,6 +27,18 @@ namespace Essgee.Emulation.Cartridges.Nintendo
hasBattery = false; hasBattery = false;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -21,6 +21,18 @@ namespace Essgee.Emulation.Cartridges.Nintendo
hasBattery = false; hasBattery = false;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {

View File

@ -32,6 +32,8 @@ namespace Essgee.Emulation.Cartridges.Nintendo
IsLatched = false; IsLatched = false;
} }
public void FromSaveData(byte[] ramData) public void FromSaveData(byte[] ramData)
{ {
var rtcOffset = ramData.Length - 0x30; var rtcOffset = ramData.Length - 0x30;
@ -129,6 +131,18 @@ namespace Essgee.Emulation.Cartridges.Nintendo
rtc = new RTC(); rtc = new RTC();
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));
@ -257,5 +271,6 @@ namespace Essgee.Emulation.Cartridges.Nintendo
ramData[(ramBank << 13) | (address & 0x1FFF)] = value; ramData[(ramBank << 13) | (address & 0x1FFF)] = value;
} }
} }
} }
} }

View File

@ -30,6 +30,18 @@ namespace Essgee.Emulation.Cartridges.Nintendo
hasRumble = false; hasRumble = false;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -13,6 +13,18 @@ namespace Essgee.Emulation.Cartridges.Nintendo
ramData = new byte[ramSize]; ramData = new byte[ramSize];
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -5,7 +5,7 @@ namespace Essgee.Emulation.Cartridges.Nintendo
{ {
public static class SpecializedLoader public static class SpecializedLoader
{ {
public static IGameBoyCartridge CreateCartridgeInstance(byte[] romData, byte[] ramData, Type mapperType) internal static IGameBoyCartridge CreateCartridgeInstance(byte[] romData, byte[] ramData, Type mapperType)
{ {
var romSize = -1; var romSize = -1;
switch (romData[0x0148]) switch (romData[0x0148])

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: ce378fe5a7c0ff14e8ffd0ad6c86ac65 guid: 9dbf1dc8385034e4082468ce1f21dca0
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,6 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
namespace Essgee.Emulation.Cartridges.Sega namespace Essgee.Emulation.Cartridges.Sega
{ {
@ -11,14 +12,39 @@ namespace Essgee.Emulation.Cartridges.Sega
[StateRequired] [StateRequired]
byte[] ramData; byte[] ramData;
[StateRequired] [StateRequired]//TODO 感觉不用保存 保留readonly
readonly byte[] pagingRegisters; byte[] pagingRegisters;
[StateRequired] //readonly byte[] pagingRegisters;
readonly byte bankMask; [StateRequired]//TODO 感觉不用保存 保留readonly
byte bankMask;
//readonly byte bankMask;
[StateRequired] [StateRequired]
bool isRamEnabled; bool isRamEnabled;
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
ramData = data.MemberData[nameof(ramData)];
pagingRegisters = data.MemberData[nameof(pagingRegisters)];
bankMask = data.MemberData[nameof(bankMask)].First();
isRamEnabled = BitConverter.ToBoolean(data.MemberData[nameof(isRamEnabled)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(ramData)] = ramData;
data.MemberData[nameof(pagingRegisters)] = pagingRegisters;
data.MemberData[nameof(bankMask)] = BitConverter.GetBytes(bankMask);
data.MemberData[nameof(isRamEnabled)] = BitConverter.GetBytes(isRamEnabled);
return data;
}
#endregion
public CodemastersCartridge(int romSize, int ramSize) public CodemastersCartridge(int romSize, int ramSize)
{ {
pagingRegisters = new byte[3]; pagingRegisters = new byte[3];
@ -116,5 +142,6 @@ namespace Essgee.Emulation.Cartridges.Sega
if (isRamEnabled && ((address & 0xF000) == 0xA000 || (address & 0xF000) == 0xB000)) if (isRamEnabled && ((address & 0xF000) == 0xA000 || (address & 0xF000) == 0xB000))
ramData[address & 0x1FFF] = value; ramData[address & 0x1FFF] = value;
} }
} }
} }

View File

@ -1,6 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
namespace Essgee.Emulation.Cartridges.Sega namespace Essgee.Emulation.Cartridges.Sega
{ {
@ -8,8 +9,10 @@ namespace Essgee.Emulation.Cartridges.Sega
{ {
byte[] romData; byte[] romData;
[StateRequired]
readonly byte[] pagingRegisters; [StateRequired]//TODO 感觉不用保存 保留readonly
byte[] pagingRegisters;
//readonly byte[] pagingRegisters;
[StateRequired] [StateRequired]
byte bankMask; byte bankMask;
@ -21,6 +24,25 @@ namespace Essgee.Emulation.Cartridges.Sega
romData = new byte[romSize]; romData = new byte[romSize];
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
pagingRegisters = data.MemberData[nameof(pagingRegisters)];
bankMask = data.MemberData[nameof(bankMask)].First();
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(pagingRegisters)] = pagingRegisters;
data.MemberData[nameof(bankMask)] = BitConverter.GetBytes(bankMask);
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -1,6 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
namespace Essgee.Emulation.Cartridges.Sega namespace Essgee.Emulation.Cartridges.Sega
{ {
@ -11,6 +12,27 @@ namespace Essgee.Emulation.Cartridges.Sega
[StateRequired] [StateRequired]
byte bankMask, pagingRegister; byte bankMask, pagingRegister;
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
bankMask = data.MemberData[nameof(bankMask)].First();
pagingRegister = data.MemberData[nameof(pagingRegister)].First();
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(bankMask)] = BitConverter.GetBytes(bankMask);
data.MemberData[nameof(pagingRegister)] = BitConverter.GetBytes(pagingRegister);
return data;
}
#endregion
public KoreanMapperCartridge(int romSize, int ramSize) public KoreanMapperCartridge(int romSize, int ramSize)
{ {
pagingRegister = 0x02; pagingRegister = 0x02;

View File

@ -1,6 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
namespace Essgee.Emulation.Cartridges.Sega namespace Essgee.Emulation.Cartridges.Sega
@ -17,8 +18,10 @@ namespace Essgee.Emulation.Cartridges.Sega
[StateRequired] [StateRequired]
byte[] ramData; byte[] ramData;
[StateRequired]
readonly byte[] pagingRegisters; [StateRequired]//TODO 感觉不用保存 保留readonly
byte[] pagingRegisters;
//readonly byte[] pagingRegisters;
[StateRequired] [StateRequired]
byte romBankMask; byte romBankMask;
@ -52,6 +55,31 @@ namespace Essgee.Emulation.Cartridges.Sega
isBitReverseBank1 = isBitReverseBank2 = false; isBitReverseBank1 = isBitReverseBank2 = false;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
ramData = data.MemberData[nameof(ramData)];
pagingRegisters = data.MemberData[nameof(pagingRegisters)];
romBankMask = data.MemberData[nameof(romBankMask)].First();
hasCartRam = BitConverter.ToBoolean(data.MemberData[nameof(hasCartRam)]);
isBitReverseBank1 = BitConverter.ToBoolean(data.MemberData[nameof(isBitReverseBank1)]);
isBitReverseBank2 = BitConverter.ToBoolean(data.MemberData[nameof(isBitReverseBank2)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(ramData)] = ramData;
data.MemberData[nameof(pagingRegisters)] = pagingRegisters;
data.MemberData[nameof(romBankMask)] = BitConverter.GetBytes(romBankMask);
data.MemberData[nameof(hasCartRam)] = BitConverter.GetBytes(hasCartRam);
data.MemberData[nameof(isBitReverseBank1)] = BitConverter.GetBytes(isBitReverseBank1);
data.MemberData[nameof(isBitReverseBank2)] = BitConverter.GetBytes(isBitReverseBank2);
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -10,8 +10,9 @@ namespace Essgee.Emulation.Cartridges.Sega
{ {
byte[] romData; byte[] romData;
[StateRequired] [StateRequired]//TODO 感觉不用保存 保留readonly
readonly int romMask; int romMask;
//readonly int romMask;
[StateRequired] [StateRequired]
int romBank0, romBank1, romBank2; int romBank0, romBank1, romBank2;
@ -27,6 +28,26 @@ namespace Essgee.Emulation.Cartridges.Sega
romBank0 = romBank1 = romBank2 = 0; romBank0 = romBank1 = romBank2 = 0;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
romMask = BitConverter.ToInt32(data.MemberData[nameof(romMask)]);
romBank0 = BitConverter.ToInt32(data.MemberData[nameof(romBank0)]);
romBank1 = BitConverter.ToInt32(data.MemberData[nameof(romBank1)]);
romBank2 = BitConverter.ToInt32(data.MemberData[nameof(romBank2)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(romMask)] = BitConverter.GetBytes(romMask);
data.MemberData[nameof(romBank0)] = BitConverter.GetBytes(romBank0);
data.MemberData[nameof(romBank1)] = BitConverter.GetBytes(romBank1);
data.MemberData[nameof(romBank2)] = BitConverter.GetBytes(romBank2);
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -1,6 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
namespace Essgee.Emulation.Cartridges.Sega namespace Essgee.Emulation.Cartridges.Sega
@ -13,7 +14,7 @@ namespace Essgee.Emulation.Cartridges.Sega
byte[] ramData; byte[] ramData;
[StateRequired] [StateRequired]
readonly byte[] pagingRegisters; byte[] pagingRegisters;
[StateRequired] [StateRequired]
byte romBankMask; byte romBankMask;
@ -27,6 +28,7 @@ namespace Essgee.Emulation.Cartridges.Sega
int romBank1 { get { return pagingRegisters[2]; } } int romBank1 { get { return pagingRegisters[2]; } }
int romBank2 { get { return pagingRegisters[3]; } } int romBank2 { get { return pagingRegisters[3]; } }
public SegaMapperCartridge(int romSize, int ramSize) public SegaMapperCartridge(int romSize, int ramSize)
{ {
pagingRegisters = new byte[0x04]; pagingRegisters = new byte[0x04];
@ -44,6 +46,27 @@ namespace Essgee.Emulation.Cartridges.Sega
hasCartRam = false; hasCartRam = false;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
ramData = data.MemberData[nameof(ramData)];
pagingRegisters = data.MemberData[nameof(pagingRegisters)];
romBankMask = data.MemberData[nameof(romBankMask)].First();
hasCartRam = BitConverter.ToBoolean(data.MemberData[nameof(hasCartRam)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(ramData)] = ramData;
data.MemberData[nameof(pagingRegisters)] = pagingRegisters;
data.MemberData[nameof(romBankMask)] = BitConverter.GetBytes(romBankMask);
data.MemberData[nameof(hasCartRam)] = BitConverter.GetBytes(hasCartRam);
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));
@ -143,5 +166,6 @@ namespace Essgee.Emulation.Cartridges.Sega
/* Otherwise ignore writes to ROM, as some games seem to be doing that? (ex. Gunstar Heroes GG to 0000) */ /* Otherwise ignore writes to ROM, as some games seem to be doing that? (ex. Gunstar Heroes GG to 0000) */
} }
} }
} }

View File

@ -1,5 +1,6 @@
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Linq;
namespace Essgee.Emulation.Cartridges.Sega namespace Essgee.Emulation.Cartridges.Sega
{ {
@ -10,8 +11,9 @@ namespace Essgee.Emulation.Cartridges.Sega
[StateRequired] [StateRequired]
byte[] ramData; byte[] ramData;
[StateRequired] [StateRequired]//TODO 感觉不用保存 保留readonly
readonly int romMask, ramMask; int romMask, ramMask;
//readonly int romMask, ramMask;
public SegaSGCartridge(int romSize, int ramSize) public SegaSGCartridge(int romSize, int ramSize)
{ {
@ -25,6 +27,25 @@ namespace Essgee.Emulation.Cartridges.Sega
ramMask = (ramSize - 1); ramMask = (ramSize - 1);
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
ramData = data.MemberData[nameof(romMask)];
romMask = data.MemberData[nameof(romMask)].First();
ramMask = data.MemberData[nameof(ramMask)].First();
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(ramData)] = ramData;
data.MemberData[nameof(romMask)] = BitConverter.GetBytes(romMask);
data.MemberData[nameof(ramMask)] = BitConverter.GetBytes(ramMask);
return data;
}
#endregion
public void LoadRom(byte[] data) public void LoadRom(byte[] data)
{ {
Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length)); Buffer.BlockCopy(data, 0, romData, 0, Math.Min(data.Length, romData.Length));

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: f8270d4162b9c6a42afbed3387a40a37 guid: 9359d9b379638da42a314af0f095fe0c
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,6 +1,4 @@
using Essgee.Utilities; using Essgee.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Essgee.Emulation.Configuration namespace Essgee.Emulation.Configuration
{ {

View File

@ -2,7 +2,6 @@
using Essgee.Emulation.ExtDevices.Nintendo; using Essgee.Emulation.ExtDevices.Nintendo;
using Essgee.Utilities; using Essgee.Utilities;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System; using System;
namespace Essgee.Emulation.Configuration namespace Essgee.Emulation.Configuration

View File

@ -2,7 +2,6 @@
using Essgee.Emulation.ExtDevices.Nintendo; using Essgee.Emulation.ExtDevices.Nintendo;
using Essgee.Utilities; using Essgee.Utilities;
using Newtonsoft.Json; using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System; using System;
namespace Essgee.Emulation.Configuration namespace Essgee.Emulation.Configuration

View File

@ -1,6 +1,4 @@
using Essgee.Utilities; using Essgee.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Essgee.Emulation.Configuration namespace Essgee.Emulation.Configuration
{ {

View File

@ -1,6 +1,4 @@
using Essgee.Utilities; using Essgee.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace Essgee.Emulation.Configuration namespace Essgee.Emulation.Configuration
{ {

View File

@ -1,7 +1,4 @@
using Newtonsoft.Json; namespace Essgee.Emulation.Configuration
using Newtonsoft.Json.Converters;
namespace Essgee.Emulation.Configuration
{ {
//todo Unity [ElementPriority(1)] //todo Unity [ElementPriority(1)]
public class SC3000 : IConfiguration public class SC3000 : IConfiguration

View File

@ -1,7 +1,4 @@
using Newtonsoft.Json; namespace Essgee.Emulation.Configuration
using Newtonsoft.Json.Converters;
namespace Essgee.Emulation.Configuration
{ {
//todo Unity [ElementPriority(0)] //todo Unity [ElementPriority(0)]
public class SG1000 : IConfiguration public class SG1000 : IConfiguration

View File

@ -5,7 +5,6 @@ using Essgee.Metadata;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
@ -204,7 +203,7 @@ namespace Essgee.Emulation
} }
} }
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
return emulator.GetDebugInformation(); return emulator.GetDebugInformation();
} }
@ -255,115 +254,148 @@ namespace Essgee.Emulation
} }
private void ThreadMainLoop() //private void ThreadMainLoop()
//{
// // TODO: rework fps limiter/counter - AGAIN - because the counter is inaccurate at sampleTimespan=0.25 and the limiter CAN cause sound crackling at sampleTimespan>0.25
// // try this maybe? https://stackoverflow.com/a/34839411
// var stopWatch = Stopwatch.StartNew();
// TimeSpan accumulatedTime = TimeSpan.Zero, lastStartTime = TimeSpan.Zero, lastEndTime = TimeSpan.Zero;
// var frameCounter = 0;
// var sampleTimespan = TimeSpan.FromSeconds(0.5);
// try
// {
// while (true)
// {
// if (!emulationThreadRunning)
// break;
// if (stateLoadRequested && stateNumber != -1)
// {
// var statePath = GetSaveStateFilename(stateNumber);
// if (File.Exists(statePath))
// {
// using (var stream = new FileStream(statePath, FileMode.Open))
// {
// emulator.SetState(SaveStateHandler.Load(stream, emulator.GetType().Name));
// }
// }
// stateLoadRequested = false;
// stateNumber = -1;
// }
// var refreshRate = emulator.RefreshRate;
// var targetElapsedTime = TimeSpan.FromTicks((long)Math.Round(TimeSpan.TicksPerSecond / refreshRate));
// var startTime = stopWatch.Elapsed;
// while (pauseStateChangesRequested.Count > 0)
// {
// var newPauseState = pauseStateChangesRequested.Dequeue();
// emulationThreadPaused = newPauseState;
// PauseChanged?.Invoke(this, EventArgs.Empty);
// }
// if (!emulationThreadPaused)
// {
// if (limitFps)
// {
// var elapsedTime = (startTime - lastStartTime);
// lastStartTime = startTime;
// if (elapsedTime < targetElapsedTime)
// {
// accumulatedTime += elapsedTime;
// while (accumulatedTime >= targetElapsedTime)
// {
// emulator.RunFrame();
// frameCounter++;
// accumulatedTime -= targetElapsedTime;
// }
// }
// }
// else
// {
// emulator.RunFrame();
// frameCounter++;
// }
// if ((stopWatch.Elapsed - lastEndTime) >= sampleTimespan)
// {
// FramesPerSecond = (int)((frameCounter * 1000.0) / sampleTimespan.TotalMilliseconds);
// frameCounter = 0;
// lastEndTime = stopWatch.Elapsed;
// }
// }
// else
// {
// lastEndTime = stopWatch.Elapsed;
// }
// if (configChangeRequested)
// {
// emulator.SetConfiguration(newConfiguration);
// configChangeRequested = false;
// }
// if (stateSaveRequested && stateNumber != -1)
// {
// var statePath = GetSaveStateFilename(stateNumber);
// using (var stream = new FileStream(statePath, FileMode.OpenOrCreate))
// {
// SaveStateHandler.Save(stream, emulator.GetType().Name, emulator.GetState());
// }
// stateSaveRequested = false;
// stateNumber = -1;
// }
// }
// }
// catch (Exception ex) when (!AppEnvironment.DebugMode)
// {
// ex.Data.Add("Thread", Thread.CurrentThread.Name);
// exceptionHandler(ex);
// }
//}
public void SaveSnapShotToFile(int stateNumber)
{ {
// TODO: rework fps limiter/counter - AGAIN - because the counter is inaccurate at sampleTimespan=0.25 and the limiter CAN cause sound crackling at sampleTimespan>0.25 var statePath = GetSaveStateFilename(stateNumber);
// try this maybe? https://stackoverflow.com/a/34839411 using (var stream = new FileStream(statePath, FileMode.OpenOrCreate))
var stopWatch = Stopwatch.StartNew();
TimeSpan accumulatedTime = TimeSpan.Zero, lastStartTime = TimeSpan.Zero, lastEndTime = TimeSpan.Zero;
var frameCounter = 0;
var sampleTimespan = TimeSpan.FromSeconds(0.5);
try
{ {
while (true) //SaveStateHandler.Save(stream, emulator.GetType().Name, emulator.GetState());
SaveStateHandler.Save(stream, emulator.GetType().Name, emulator.SaveAxiStatus());
}
}
public void LoadSnapShotFromFile(int stateNumber)
{
var statePath = GetSaveStateFilename(stateNumber);
if (File.Exists(statePath))
{
using (var stream = new FileStream(statePath, FileMode.Open))
{ {
if (!emulationThreadRunning) //emulator.SetState(SaveStateHandler.Load(stream, emulator.GetType().Name));
break; emulator.LoadAxiStatus(SaveStateHandler.LoadAxiStatus(stream, emulator.GetType().Name));
if (stateLoadRequested && stateNumber != -1)
{
var statePath = GetSaveStateFilename(stateNumber);
if (File.Exists(statePath))
{
using (var stream = new FileStream(statePath, FileMode.Open))
{
emulator.SetState(SaveStateHandler.Load(stream, emulator.GetType().Name));
}
}
stateLoadRequested = false;
stateNumber = -1;
}
var refreshRate = emulator.RefreshRate;
var targetElapsedTime = TimeSpan.FromTicks((long)Math.Round(TimeSpan.TicksPerSecond / refreshRate));
var startTime = stopWatch.Elapsed;
while (pauseStateChangesRequested.Count > 0)
{
var newPauseState = pauseStateChangesRequested.Dequeue();
emulationThreadPaused = newPauseState;
PauseChanged?.Invoke(this, EventArgs.Empty);
}
if (!emulationThreadPaused)
{
if (limitFps)
{
var elapsedTime = (startTime - lastStartTime);
lastStartTime = startTime;
if (elapsedTime < targetElapsedTime)
{
accumulatedTime += elapsedTime;
while (accumulatedTime >= targetElapsedTime)
{
emulator.RunFrame();
frameCounter++;
accumulatedTime -= targetElapsedTime;
}
}
}
else
{
emulator.RunFrame();
frameCounter++;
}
if ((stopWatch.Elapsed - lastEndTime) >= sampleTimespan)
{
FramesPerSecond = (int)((frameCounter * 1000.0) / sampleTimespan.TotalMilliseconds);
frameCounter = 0;
lastEndTime = stopWatch.Elapsed;
}
}
else
{
lastEndTime = stopWatch.Elapsed;
}
if (configChangeRequested)
{
emulator.SetConfiguration(newConfiguration);
configChangeRequested = false;
}
if (stateSaveRequested && stateNumber != -1)
{
var statePath = GetSaveStateFilename(stateNumber);
using (var stream = new FileStream(statePath, FileMode.OpenOrCreate))
{
SaveStateHandler.Save(stream, emulator.GetType().Name, emulator.GetState());
}
stateSaveRequested = false;
stateNumber = -1;
}
} }
} }
catch (Exception ex) when (!AppEnvironment.DebugMode) }
{
ex.Data.Add("Thread", Thread.CurrentThread.Name); public byte[] GetStateData()
exceptionHandler(ex); {
} return emulator.SaveAxiStatus().ToByteArray();
}
public void SetStateData(byte[] data)
{
emulator.LoadAxiStatus(data.ToAxiEssgssStatusData());
} }
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 380af0157665736438ef805bfda57a98 guid: 32a6b746a89ac5242be599fa472bab1b
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: b00fddc211d9d854580cc2b110c5e524 guid: a09bb4257e29ab646b70aba3720660e1
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 5c3c1bb41ecdcb043ac9083b76f8dee4 guid: e77364449233a0e4b8f13621ff8ee825
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -219,44 +219,79 @@ namespace Essgee.Emulation.Machines
} }
//public void SetState(Dictionary<string, dynamic> state) //public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state) //public void SetState(Dictionary<string, object> state)
//{
// SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
// wram = (byte[])state[nameof(wram)];
// SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
// SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
// SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
// portControls1 = (ushort)state[nameof(portControls1)];
// portControls2 = (ushort)state[nameof(portControls2)];
// controlsReadMode = (byte)state[nameof(controlsReadMode)];
// isNmi = (bool)state[nameof(isNmi)];
// isNmiPending = (bool)state[nameof(isNmiPending)];
// ReconfigureSystem();
//}
//public Dictionary<string, object> GetState()
//{
// return new Dictionary<string, object>
// {
// [nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
// [nameof(wram)] = wram,
// [nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
// [nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
// [nameof(psg)] = SaveStateHandler.PerformGetState(psg),
// [nameof(portControls1)] = portControls1,
// [nameof(portControls2)] = portControls2,
// [nameof(controlsReadMode)] = controlsReadMode,
// [nameof(isNmi)] = isNmi,
// [nameof(isNmiPending)] = isNmiPending
// };
//}
#region
public void LoadAxiStatus(AxiEssgssStatusData data)
{ {
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]); cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)]; wram = data.MemberData[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]); cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]); vdp.LoadAxiStatus(data.ClassData[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]); psg.LoadAxiStatus(data.ClassData[nameof(psg)]);
portControls1 = (ushort)state[nameof(portControls1)]; portControls1 = BitConverter.ToUInt16(data.MemberData[nameof(portControls1)]);
portControls2 = (ushort)state[nameof(portControls2)]; portControls2 = BitConverter.ToUInt16(data.MemberData[nameof(portControls2)]);
controlsReadMode = (byte)state[nameof(controlsReadMode)]; controlsReadMode = data.MemberData[nameof(controlsReadMode)].First();
isNmi = (bool)state[nameof(isNmi)]; isNmi = BitConverter.ToBoolean(data.MemberData[nameof(isNmi)]);
isNmiPending = (bool)state[nameof(isNmiPending)]; isNmiPending = BitConverter.ToBoolean(data.MemberData[nameof(isNmiPending)]);
ReconfigureSystem();
} }
public Dictionary<string, dynamic> GetState() public AxiEssgssStatusData SaveAxiStatus()
{ {
return new Dictionary<string, dynamic> AxiEssgssStatusData data = new AxiEssgssStatusData();
{ data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
[nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge), data.MemberData[nameof(wram)] = wram;
[nameof(wram)] = wram, data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
[nameof(cpu)] = SaveStateHandler.PerformGetState(cpu), data.ClassData[nameof(vdp)] = vdp.SaveAxiStatus();
[nameof(vdp)] = SaveStateHandler.PerformGetState(vdp), data.ClassData[nameof(psg)] = psg.SaveAxiStatus();
[nameof(psg)] = SaveStateHandler.PerformGetState(psg),
data.MemberData[nameof(portControls1)] = BitConverter.GetBytes(portControls1);
data.MemberData[nameof(portControls2)] = BitConverter.GetBytes(portControls2);
data.MemberData[nameof(controlsReadMode)] = BitConverter.GetBytes(controlsReadMode);
data.MemberData[nameof(isNmi)] = BitConverter.GetBytes(isNmi);
data.MemberData[nameof(isNmiPending)] = BitConverter.GetBytes(isNmiPending);
return data;
[nameof(portControls1)] = portControls1,
[nameof(portControls2)] = portControls2,
[nameof(controlsReadMode)] = controlsReadMode,
[nameof(isNmi)] = isNmi,
[nameof(isNmiPending)] = isNmiPending
};
} }
#endregion
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };

View File

@ -131,6 +131,20 @@ namespace Essgee.Emulation.Machines
public GameBoy() { } public GameBoy() { }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void Initialize() public void Initialize()
{ {
bootstrap = null; bootstrap = null;
@ -306,19 +320,19 @@ namespace Essgee.Emulation.Machines
audio?.Shutdown(); audio?.Shutdown();
} }
public void SetState(Dictionary<string, dynamic> state) public void SetState(Dictionary<string, object> state)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Dictionary<string, dynamic> GetState() public Dictionary<string, object> GetState()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };

View File

@ -162,6 +162,18 @@ namespace Essgee.Emulation.Machines
public GameBoyColor() { } public GameBoyColor() { }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
return data;
}
#endregion
public void Initialize() public void Initialize()
{ {
bootstrap = null; bootstrap = null;
@ -363,19 +375,19 @@ namespace Essgee.Emulation.Machines
audio?.Shutdown(); audio?.Shutdown();
} }
public void SetState(Dictionary<string, dynamic> state) public void SetState(Dictionary<string, object> state)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Dictionary<string, dynamic> GetState() public Dictionary<string, object> GetState()
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };

View File

@ -241,64 +241,119 @@ namespace Essgee.Emulation.Machines
} }
//public void SetState(Dictionary<string, dynamic> state) //public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state) //public void SetState(Dictionary<string, object> state)
//{
// configuration.Region = (Region)state[nameof(configuration.Region)];
// SaveStateHandler.PerformSetState(bootstrap, (Dictionary<string, object>)state[nameof(bootstrap)]);
// SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
// wram = (byte[])state[nameof(wram)];
// SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
// SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
// SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
// portMemoryControl = (byte)state[nameof(portMemoryControl)];
// portIoControl = (byte)state[nameof(portIoControl)];
// hCounterLatched = (byte)state[nameof(hCounterLatched)];
// portIoAB = (byte)state[nameof(portIoAB)];
// portIoBMisc = (byte)state[nameof(portIoBMisc)];
// portIoC = (byte)state[nameof(portIoC)];
// portParallelData = (byte)state[nameof(portParallelData)];
// portDataDirNMI = (byte)state[nameof(portDataDirNMI)];
// portTxBuffer = (byte)state[nameof(portTxBuffer)];
// portRxBuffer = (byte)state[nameof(portRxBuffer)];
// portSerialControl = (byte)state[nameof(portSerialControl)];
// ReconfigureSystem();
//}
//public Dictionary<string, object> GetState()
//{
// return new Dictionary<string, object>
// {
// [nameof(configuration.Region)] = configuration.Region,
// [nameof(bootstrap)] = SaveStateHandler.PerformGetState(bootstrap),
// [nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
// [nameof(wram)] = wram,
// [nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
// [nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
// [nameof(psg)] = SaveStateHandler.PerformGetState(psg),
// [nameof(portMemoryControl)] = portMemoryControl,
// [nameof(portIoControl)] = portIoControl,
// [nameof(hCounterLatched)] = hCounterLatched,
// [nameof(portIoAB)] = portIoAB,
// [nameof(portIoBMisc)] = portIoBMisc,
// [nameof(portIoC)] = portIoC,
// [nameof(portParallelData)] = portParallelData,
// [nameof(portDataDirNMI)] = portDataDirNMI,
// [nameof(portTxBuffer)] = portTxBuffer,
// [nameof(portRxBuffer)] = portRxBuffer,
// [nameof(portSerialControl)] = portSerialControl
// };
//}
public void LoadAxiStatus(AxiEssgssStatusData data)
{ {
configuration.Region = (Region)state[nameof(configuration.Region)]; configuration.Region = data.MemberData[nameof(configuration.Region)].ToEnum<Region>();
SaveStateHandler.PerformSetState(bootstrap, (Dictionary<string, object>)state[nameof(bootstrap)]); bootstrap.LoadAxiStatus(data.ClassData[nameof(bootstrap)]);
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]); cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)]; wram = data.MemberData[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]); cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]); vdp.LoadAxiStatus(data.ClassData[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]); psg.LoadAxiStatus(data.ClassData[nameof(psg)]);
portMemoryControl = (byte)state[nameof(portMemoryControl)]; portMemoryControl = data.MemberData[nameof(portMemoryControl)].First();
portIoControl = (byte)state[nameof(portIoControl)]; portIoControl = data.MemberData[nameof(portIoControl)].First();
hCounterLatched = (byte)state[nameof(hCounterLatched)]; hCounterLatched = data.MemberData[nameof(hCounterLatched)].First();
portIoAB = (byte)state[nameof(portIoAB)]; portIoAB = data.MemberData[nameof(portIoAB)].First();
portIoBMisc = (byte)state[nameof(portIoBMisc)]; portIoBMisc = data.MemberData[nameof(portIoBMisc)].First();
portIoC = (byte)state[nameof(portIoC)]; portIoC = data.MemberData[nameof(portIoC)].First();
portParallelData = (byte)state[nameof(portParallelData)]; portParallelData = data.MemberData[nameof(portParallelData)].First();
portDataDirNMI = (byte)state[nameof(portDataDirNMI)]; portDataDirNMI = data.MemberData[nameof(portDataDirNMI)].First();
portTxBuffer = (byte)state[nameof(portTxBuffer)]; portTxBuffer = data.MemberData[nameof(portTxBuffer)].First();
portRxBuffer = (byte)state[nameof(portRxBuffer)]; portRxBuffer = data.MemberData[nameof(portRxBuffer)].First();
portSerialControl = (byte)state[nameof(portSerialControl)]; portSerialControl = data.MemberData[nameof(portSerialControl)].First();
ReconfigureSystem();
} }
public Dictionary<string, dynamic> GetState() public AxiEssgssStatusData SaveAxiStatus()
{ {
return new Dictionary<string, dynamic> AxiEssgssStatusData data = new AxiEssgssStatusData();
{ data.MemberData[nameof(configuration.Region)] = configuration.Region.ToByteArray();
[nameof(configuration.Region)] = configuration.Region,
[nameof(bootstrap)] = SaveStateHandler.PerformGetState(bootstrap), data.ClassData[nameof(bootstrap)] = bootstrap.SaveAxiStatus();
[nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge), data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
[nameof(wram)] = wram, data.MemberData[nameof(wram)] = wram;
[nameof(cpu)] = SaveStateHandler.PerformGetState(cpu), data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
[nameof(vdp)] = SaveStateHandler.PerformGetState(vdp), data.ClassData[nameof(vdp)] = vdp.SaveAxiStatus();
[nameof(psg)] = SaveStateHandler.PerformGetState(psg), data.ClassData[nameof(psg)] = psg.SaveAxiStatus();
[nameof(portMemoryControl)] = portMemoryControl, data.MemberData[nameof(portMemoryControl)] = BitConverter.GetBytes(portMemoryControl);
[nameof(portIoControl)] = portIoControl, data.MemberData[nameof(portIoControl)] = BitConverter.GetBytes(portIoControl);
[nameof(hCounterLatched)] = hCounterLatched, data.MemberData[nameof(hCounterLatched)] = BitConverter.GetBytes(hCounterLatched);
[nameof(portIoAB)] = portIoAB, data.MemberData[nameof(portIoAB)] = BitConverter.GetBytes(portIoAB);
[nameof(portIoBMisc)] = portIoBMisc, data.MemberData[nameof(portIoBMisc)] = BitConverter.GetBytes(portIoBMisc);
data.MemberData[nameof(portIoC)] = BitConverter.GetBytes(portIoC);
data.MemberData[nameof(portParallelData)] = BitConverter.GetBytes(portParallelData);
data.MemberData[nameof(portDataDirNMI)] = BitConverter.GetBytes(portDataDirNMI);
data.MemberData[nameof(portTxBuffer)] = BitConverter.GetBytes(portTxBuffer);
data.MemberData[nameof(portRxBuffer)] = BitConverter.GetBytes(portRxBuffer);
data.MemberData[nameof(portSerialControl)] = BitConverter.GetBytes(portSerialControl);
return data;
[nameof(portIoC)] = portIoC,
[nameof(portParallelData)] = portParallelData,
[nameof(portDataDirNMI)] = portDataDirNMI,
[nameof(portTxBuffer)] = portTxBuffer,
[nameof(portRxBuffer)] = portRxBuffer,
[nameof(portSerialControl)] = portSerialControl
};
} }
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };
@ -509,5 +564,6 @@ namespace Essgee.Emulation.Machines
break; break;
} }
} }
} }
} }

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace Essgee.Emulation.Machines namespace Essgee.Emulation.Machines
{ {
public interface IMachine public interface IMachine : IAxiStatus
{ {
event EventHandler<SendLogMessageEventArgs> SendLogMessage; event EventHandler<SendLogMessageEventArgs> SendLogMessage;
event EventHandler<EventArgs> EmulationReset; event EventHandler<EventArgs> EmulationReset;
@ -26,7 +26,7 @@ namespace Essgee.Emulation.Machines
double PixelAspectRatio { get; } double PixelAspectRatio { get; }
(string Name, string Description)[] RuntimeOptions { get; } (string Name, string Description)[] RuntimeOptions { get; }
Dictionary<string, dynamic> GetDebugInformation(); Dictionary<string, object> GetDebugInformation();
void SetConfiguration(IConfiguration config); void SetConfiguration(IConfiguration config);
@ -38,8 +38,9 @@ namespace Essgee.Emulation.Machines
void Reset(); void Reset();
void Shutdown(); void Shutdown();
void SetState(Dictionary<string, dynamic> state); //void SetState(Dictionary<string, object> state);
Dictionary<string, dynamic> GetState(); //Dictionary<string, object> GetState();
void Load(byte[] romData, byte[] ramData, Type mapperType); void Load(byte[] romData, byte[] ramData, Type mapperType);
byte[] GetCartridgeRam(); byte[] GetCartridgeRam();

View File

@ -268,54 +268,124 @@ namespace Essgee.Emulation.Machines
} }
//public void SetState(Dictionary<string, dynamic> state) //public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state) //public void SetState(Dictionary<string, object> state)
//{
// configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)];
// configuration.Region = (Region)state[nameof(configuration.Region)];
// SaveStateHandler.PerformSetState(bootstrap, (Dictionary<string, object>)state[nameof(bootstrap)]);
// SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
// wram = (byte[])state[nameof(wram)];
// SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
// SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
// SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
// inputDevices = (InputDevice[])state[nameof(inputDevices)];
// lightgunLatched = (bool)state[nameof(lightgunLatched)];
// portMemoryControl = (byte)state[nameof(portMemoryControl)];
// portIoControl = (byte)state[nameof(portIoControl)];
// hCounterLatched = (byte)state[nameof(hCounterLatched)];
// ReconfigureSystem();
//}
public void LoadAxiStatus(AxiEssgssStatusData data)
{ {
configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)]; configuration.TVStandard = data.MemberData[nameof(configuration.TVStandard)].ToEnum<TVStandard>();
configuration.Region = (Region)state[nameof(configuration.Region)]; configuration.Region = data.MemberData[nameof(configuration.Region)].ToEnum<Region>();
SaveStateHandler.PerformSetState(bootstrap, (Dictionary<string, object>)state[nameof(bootstrap)]); if (data.ClassData.ContainsKey(nameof(bootstrap)))
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]); bootstrap.LoadAxiStatus(data.ClassData[nameof(bootstrap)]);
wram = (byte[])state[nameof(wram)]; cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]); wram = data.MemberData[nameof(wram)];
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]); cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]); vdp.LoadAxiStatus(data.ClassData[nameof(vdp)]);
psg.LoadAxiStatus(data.ClassData[nameof(psg)]);
inputDevices = (InputDevice[])state[nameof(inputDevices)]; inputDevices = data.MemberData[nameof(inputDevices)].ToEnumArray<InputDevice>();
lightgunLatched = (bool)state[nameof(lightgunLatched)]; lightgunLatched = BitConverter.ToBoolean(data.MemberData[nameof(lightgunLatched)]);
portMemoryControl = (byte)state[nameof(portMemoryControl)]; portMemoryControl = data.MemberData[nameof(portMemoryControl)].First();
portIoControl = (byte)state[nameof(portIoControl)]; portIoControl = data.MemberData[nameof(portIoControl)].First();
hCounterLatched = (byte)state[nameof(hCounterLatched)]; hCounterLatched = data.MemberData[nameof(hCounterLatched)].First();
ReconfigureSystem(); ReconfigureSystem();
} }
public Dictionary<string, dynamic> GetState() //public Dictionary<string, object> GetState()
//{
// return new Dictionary<string, object>
// {
// [nameof(configuration.TVStandard)] = configuration.TVStandard,
// [nameof(configuration.Region)] = configuration.Region,
// [nameof(bootstrap)] = SaveStateHandler.PerformGetState(bootstrap),
// [nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
// [nameof(wram)] = wram,
// [nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
// [nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
// [nameof(psg)] = SaveStateHandler.PerformGetState(psg),
// [nameof(inputDevices)] = inputDevices,
// [nameof(lightgunLatched)] = lightgunLatched,
// [nameof(portMemoryControl)] = portMemoryControl,
// [nameof(portIoControl)] = portIoControl,
// [nameof(hCounterLatched)] = hCounterLatched
// };
//}
public AxiEssgssStatusData SaveAxiStatus()
{ {
return new Dictionary<string, dynamic> AxiEssgssStatusData data = new AxiEssgssStatusData();
{ data.MemberData[nameof(configuration.TVStandard)] = configuration.TVStandard.ToByteArray();
[nameof(configuration.TVStandard)] = configuration.TVStandard, data.MemberData[nameof(configuration.Region)] = configuration.Region.ToByteArray();
[nameof(configuration.Region)] = configuration.Region,
[nameof(bootstrap)] = SaveStateHandler.PerformGetState(bootstrap), if (bootstrap != null)
[nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge), data.ClassData[nameof(bootstrap)] = bootstrap.SaveAxiStatus();
[nameof(wram)] = wram,
[nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
[nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
[nameof(psg)] = SaveStateHandler.PerformGetState(psg),
[nameof(inputDevices)] = inputDevices, data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
[nameof(lightgunLatched)] = lightgunLatched, data.MemberData[nameof(wram)] = wram;
data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
data.ClassData[nameof(vdp)] = vdp.SaveAxiStatus();
data.ClassData[nameof(psg)] = psg.SaveAxiStatus();
[nameof(portMemoryControl)] = portMemoryControl, data.MemberData[nameof(inputDevices)] = inputDevices.ToByteArray();
[nameof(portIoControl)] = portIoControl, data.MemberData[nameof(lightgunLatched)] = BitConverter.GetBytes(lightgunLatched);
[nameof(hCounterLatched)] = hCounterLatched
}; data.MemberData[nameof(portMemoryControl)] = BitConverter.GetBytes((int)portMemoryControl);
data.MemberData[nameof(portIoControl)] = BitConverter.GetBytes((int)portIoControl);
data.MemberData[nameof(hCounterLatched)] = BitConverter.GetBytes(hCounterLatched);
return data;
//return new Dictionary<string, object>
//{
// [nameof(configuration.TVStandard)] = configuration.TVStandard,
// [nameof(configuration.Region)] = configuration.Region,
// [nameof(bootstrap)] = SaveStateHandler.PerformGetState(bootstrap),
// [nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
// [nameof(wram)] = wram,
// [nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
// [nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
// [nameof(psg)] = SaveStateHandler.PerformGetState(psg),
// [nameof(inputDevices)] = inputDevices,
// [nameof(lightgunLatched)] = lightgunLatched,
// [nameof(portMemoryControl)] = portMemoryControl,
// [nameof(portIoControl)] = portIoControl,
// [nameof(hCounterLatched)] = hCounterLatched
//};
} }
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };

View File

@ -245,40 +245,75 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown(); psg?.Shutdown();
} }
//public void SetState(Dictionary<string, dynamic> state) ////public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state) //public void SetState(Dictionary<string, object> state)
{ //{
configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)]; // configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)];
// SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
// wram = (byte[])state[nameof(wram)];
// SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
// SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
// SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
// SaveStateHandler.PerformSetState(ppi, (Dictionary<string, object>)state[nameof(ppi)]);
// keyboard = (bool[,])(state[nameof(keyboard)]);
// ReconfigureSystem();
//}
//public Dictionary<string, object> GetState()
//{
// return new Dictionary<string, object>
// {
// [nameof(configuration.TVStandard)] = configuration.TVStandard,
// [nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
// [nameof(wram)] = wram,
// [nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
// [nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
// [nameof(psg)] = SaveStateHandler.PerformGetState(psg),
// [nameof(ppi)] = SaveStateHandler.PerformGetState(ppi),
// [nameof(keyboard)] = keyboard
// };
//}
#region
public void LoadAxiStatus(AxiEssgssStatusData data)
{
configuration.TVStandard = data.MemberData[nameof(configuration.TVStandard)].ToEnum<TVStandard>();
cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
wram = data.MemberData[nameof(wram)];
cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
vdp.LoadAxiStatus(data.ClassData[nameof(vdp)]);
psg.LoadAxiStatus(data.ClassData[nameof(psg)]);
ppi.LoadAxiStatus(data.ClassData[nameof(ppi)]);
//TODO keyboard 怕是不用保存哦
//keyboard.LoadAxiStatus(data.ClassData[nameof(ppi)]);
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
SaveStateHandler.PerformSetState(ppi, (Dictionary<string, object>)state[nameof(ppi)]);
keyboard = (bool[,])(state[nameof(keyboard)]);
ReconfigureSystem();
} }
public Dictionary<string, dynamic> GetState() public AxiEssgssStatusData SaveAxiStatus()
{ {
return new Dictionary<string, dynamic> AxiEssgssStatusData data = new AxiEssgssStatusData();
{ data.MemberData[nameof(configuration.TVStandard)] = configuration.TVStandard.ToByteArray();
[nameof(configuration.TVStandard)] = configuration.TVStandard,
data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
data.MemberData[nameof(wram)] = wram;
data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
data.ClassData[nameof(vdp)] = vdp.SaveAxiStatus();
data.ClassData[nameof(psg)] = psg.SaveAxiStatus();
data.ClassData[nameof(ppi)] = ppi.SaveAxiStatus();
//TODO keyboard 怕是不用保存哦
//keyboard
return data;
[nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
[nameof(wram)] = wram,
[nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
[nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
[nameof(psg)] = SaveStateHandler.PerformGetState(psg),
[nameof(ppi)] = SaveStateHandler.PerformGetState(ppi),
[nameof(keyboard)] = keyboard
};
} }
#endregion
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };

View File

@ -221,37 +221,66 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown(); psg?.Shutdown();
} }
//public void SetState(Dictionary<string, dynamic> state) ////public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state) //public void SetState(Dictionary<string, object> state)
//{
// configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)];
// SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
// wram = (byte[])state[nameof(wram)];
// SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
// SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
// SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
// ReconfigureSystem();
//}
//public Dictionary<string, object> GetState()
//{
// return new Dictionary<string, object>
// {
// [nameof(configuration.TVStandard)] = configuration.TVStandard,
// [nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
// [nameof(wram)] = wram,
// [nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
// [nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
// [nameof(psg)] = SaveStateHandler.PerformGetState(psg)
// };
//}
#region
public void LoadAxiStatus(AxiEssgssStatusData data)
{ {
configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)]; configuration.TVStandard = data.MemberData[nameof(configuration.TVStandard)].ToEnum<TVStandard>();
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]); cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)]; wram = data.MemberData[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]); cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]); vdp.LoadAxiStatus(data.ClassData[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]); psg.LoadAxiStatus(data.ClassData[nameof(psg)]);
ReconfigureSystem();
} }
public Dictionary<string, dynamic> GetState() public AxiEssgssStatusData SaveAxiStatus()
{ {
return new Dictionary<string, dynamic> AxiEssgssStatusData data = new AxiEssgssStatusData();
{ data.MemberData[nameof(configuration.TVStandard)] = configuration.TVStandard.ToByteArray();
[nameof(configuration.TVStandard)] = configuration.TVStandard,
data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
data.MemberData[nameof(wram)] = wram;
data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
data.ClassData[nameof(vdp)] = vdp.SaveAxiStatus();
data.ClassData[nameof(psg)] = psg.SaveAxiStatus();
return data;
[nameof(cartridge)] = SaveStateHandler.PerformGetState(cartridge),
[nameof(wram)] = wram,
[nameof(cpu)] = SaveStateHandler.PerformGetState(cpu),
[nameof(vdp)] = SaveStateHandler.PerformGetState(vdp),
[nameof(psg)] = SaveStateHandler.PerformGetState(psg)
};
} }
#endregion
public Dictionary<string, dynamic> GetDebugInformation() public Dictionary<string, object> GetDebugInformation()
{ {
var dict = new Dictionary<string, dynamic> var dict = new Dictionary<string, object>
{ {
{ "CyclesInFrame", currentMasterClockCyclesInFrame }, { "CyclesInFrame", currentMasterClockCyclesInFrame },
}; };

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 565e2e3b2a9ae8a4d843b313678a1165 guid: 53ebe1049b81852448c0a7671f0d499f
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,6 +1,6 @@
namespace Essgee.Emulation.Peripherals namespace Essgee.Emulation.Peripherals
{ {
interface IPeripheral interface IPeripheral : IAxiStatus
{ {
void Startup(); void Startup();
void Shutdown(); void Shutdown();

View File

@ -1,5 +1,7 @@
using Essgee.Exceptions; using Essgee.Exceptions;
using Essgee.Utilities; using Essgee.Utilities;
using System;
using System.Linq;
namespace Essgee.Emulation.Peripherals namespace Essgee.Emulation.Peripherals
{ {
@ -32,6 +34,39 @@ namespace Essgee.Emulation.Peripherals
public Intel8255() { } public Intel8255() { }
#region AxiState
public virtual void LoadAxiStatus(AxiEssgssStatusData data)
{
PortAInput = data.MemberData[nameof(PortAInput)].First();
PortBInput = data.MemberData[nameof(PortBInput)].First();
PortCInput = data.MemberData[nameof(PortCInput)].First();
PortAOutput = data.MemberData[nameof(PortAOutput)].First();
PortBOutput = data.MemberData[nameof(PortBOutput)].First();
PortCOutput = data.MemberData[nameof(PortCOutput)].First();
configByte = data.MemberData[nameof(configByte)].First();
setResetControlByte = data.MemberData[nameof(setResetControlByte)].First();
}
public virtual AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
PortAInput = data.MemberData[nameof(PortAInput)].First();
PortBInput = data.MemberData[nameof(PortBInput)].First();
PortCInput = data.MemberData[nameof(PortCInput)].First();
data.MemberData[nameof(PortAInput)] = BitConverter.GetBytes(PortAInput);
data.MemberData[nameof(PortBInput)] = BitConverter.GetBytes(PortBInput);
data.MemberData[nameof(PortCInput)] = BitConverter.GetBytes(PortCInput);
data.MemberData[nameof(PortAOutput)] = BitConverter.GetBytes(PortAOutput);
data.MemberData[nameof(PortBOutput)] = BitConverter.GetBytes(PortBOutput);
data.MemberData[nameof(PortCOutput)] = BitConverter.GetBytes(PortCOutput);
data.MemberData[nameof(configByte)] = BitConverter.GetBytes(configByte);
data.MemberData[nameof(setResetControlByte)] = BitConverter.GetBytes(setResetControlByte);
return data;
}
#endregion
public void Startup() public void Startup()
{ {
// //

View File

@ -1,149 +1,159 @@
using Essgee.Exceptions; using System.IO;
using Essgee.Utilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
namespace Essgee.Emulation namespace Essgee.Emulation
{ {
public static class SaveStateHandler public static class SaveStateHandler
{ {
public static string ExpectedVersion = $"ESGST{new Version(EmuStandInfo.ProductVersion).Major:D3}"; //public static string ExpectedVersion = $"ESGST{new Version(EmuStandInfo.ProductVersion).Major:D3}";
public static Dictionary<string, dynamic> Load(Stream stream, string machineName) //public static Dictionary<string, object> Load(Stream stream, string machineName)
//{
// stream.Position = 0;
// using (var reader = new BinaryReader(stream))
// {
// /* Read and check version string */
// var version = Encoding.ASCII.GetString(reader.ReadBytes(ExpectedVersion.Length));
// if (version != ExpectedVersion) throw new EmulationException("Unsupported savestate version");
// /* Read and check filesize */
// var filesize = reader.ReadUInt32();
// if (filesize != reader.BaseStream.Length) throw new EmulationException("Savestate filesize mismatch");
// /* Read CRC32 */
// var crc32 = reader.ReadUInt32();
// /* Read and check machine ID */
// var machineId = Encoding.ASCII.GetString(reader.ReadBytes(16));
// if (machineId != GenerateMachineIdString(machineName)) throw new EmulationException("Savestate machine mismatch");
// /* Check CRC32 */
// using (var stateStream = new MemoryStream())
// {
// reader.BaseStream.CopyTo(stateStream);
// stateStream.Position = 0;
// var expectedCrc32 = Crc32.Calculate(stateStream);
// if (crc32 != expectedCrc32) throw new EmulationException("Savestate checksum error");
// /* Read state data */
// var binaryFormatter = new BinaryFormatter();
// return (binaryFormatter.Deserialize(stateStream) as Dictionary<string, object>);
// }
// }
//}
public static AxiEssgssStatusData LoadAxiStatus(Stream stream, string machineName)
{ {
stream.Position = 0;
using (var reader = new BinaryReader(stream)) using (var reader = new BinaryReader(stream))
{ {
/* Read and check version string */
var version = Encoding.ASCII.GetString(reader.ReadBytes(ExpectedVersion.Length));
if (version != ExpectedVersion) throw new EmulationException("Unsupported savestate version");
/* Read and check filesize */
var filesize = reader.ReadUInt32();
if (filesize != reader.BaseStream.Length) throw new EmulationException("Savestate filesize mismatch");
/* Read CRC32 */
var crc32 = reader.ReadUInt32();
/* Read and check machine ID */
var machineId = Encoding.ASCII.GetString(reader.ReadBytes(16));
if (machineId != GenerateMachineIdString(machineName)) throw new EmulationException("Savestate machine mismatch");
/* Check CRC32 */ /* Check CRC32 */
using (var stateStream = new MemoryStream()) using (var stateStream = new MemoryStream())
{ {
reader.BaseStream.CopyTo(stateStream); reader.BaseStream.CopyTo(stateStream);
stateStream.Position = 0; return stateStream.ToArray().ToAxiEssgssStatusData();
var expectedCrc32 = Crc32.Calculate(stateStream);
if (crc32 != expectedCrc32) throw new EmulationException("Savestate checksum error");
/* Read state data */
var binaryFormatter = new BinaryFormatter();
return (binaryFormatter.Deserialize(stateStream) as Dictionary<string, dynamic>);
} }
} }
} }
public static void Save(Stream stream, string machineName, Dictionary<string, dynamic> state) //public static void Save(Stream stream, string machineName, Dictionary<string, object> state)
//{
// using (var writer = new BinaryWriter(new MemoryStream()))
// {
// /* Write version string */
// writer.Write(Encoding.ASCII.GetBytes(ExpectedVersion));
// /* Write filesize placeholder */
// var filesizePosition = writer.BaseStream.Position;
// writer.Write(uint.MaxValue);
// /* Write CRC32 placeholder */
// var crc32Position = writer.BaseStream.Position;
// writer.Write(uint.MaxValue);
// /* Write machine ID */
// writer.Write(Encoding.ASCII.GetBytes(GenerateMachineIdString(machineName)));
// /* Current position is end of header, store for later */
// var headerSize = writer.BaseStream.Position;
// /* Write state data */
// var binaryFormatter = new BinaryFormatter();
// binaryFormatter.Serialize(writer.BaseStream, state);
// /* Write filesize */
// var lastOffset = writer.BaseStream.Position;
// writer.BaseStream.Position = filesizePosition;
// writer.Write((uint)writer.BaseStream.Length);
// writer.BaseStream.Position = lastOffset;
// /* Calculate CRC32 for state data, then write CRC32 */
// lastOffset = writer.BaseStream.Position;
// writer.BaseStream.Position = 0;
// var crc32 = Crc32.Calculate(writer.BaseStream, (int)headerSize, (int)(writer.BaseStream.Length - headerSize));
// writer.BaseStream.Position = crc32Position;
// writer.Write(crc32);
// writer.BaseStream.Position = lastOffset;
// /* Copy to file */
// writer.BaseStream.Position = 0;
// writer.BaseStream.CopyTo(stream);
// }
//}
public static void Save(Stream stream, string machineName, AxiEssgssStatusData state)
{ {
using (var writer = new BinaryWriter(new MemoryStream())) byte[] data = state.ToByteArray();
{ stream.Write(data, 0, data.Length);
/* Write version string */
writer.Write(Encoding.ASCII.GetBytes(ExpectedVersion));
/* Write filesize placeholder */
var filesizePosition = writer.BaseStream.Position;
writer.Write(uint.MaxValue);
/* Write CRC32 placeholder */
var crc32Position = writer.BaseStream.Position;
writer.Write(uint.MaxValue);
/* Write machine ID */
writer.Write(Encoding.ASCII.GetBytes(GenerateMachineIdString(machineName)));
/* Current position is end of header, store for later */
var headerSize = writer.BaseStream.Position;
/* Write state data */
var binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(writer.BaseStream, state);
/* Write filesize */
var lastOffset = writer.BaseStream.Position;
writer.BaseStream.Position = filesizePosition;
writer.Write((uint)writer.BaseStream.Length);
writer.BaseStream.Position = lastOffset;
/* Calculate CRC32 for state data, then write CRC32 */
lastOffset = writer.BaseStream.Position;
writer.BaseStream.Position = 0;
var crc32 = Crc32.Calculate(writer.BaseStream, (int)headerSize, (int)(writer.BaseStream.Length - headerSize));
writer.BaseStream.Position = crc32Position;
writer.Write(crc32);
writer.BaseStream.Position = lastOffset;
/* Copy to file */
writer.BaseStream.Position = 0;
writer.BaseStream.CopyTo(stream);
}
} }
//private static string GenerateMachineIdString(string machineId)
//{
// return machineId.Substring(0, Math.Min(machineId.Length, 16)).PadRight(16);
//}
private static string GenerateMachineIdString(string machineId) ////public static void PerformSetState(object obj, Dictionary<string, dynamic> state)
{
return machineId.Substring(0, Math.Min(machineId.Length, 16)).PadRight(16);
}
//public static void PerformSetState(object obj, Dictionary<string, dynamic> state) //public static void PerformSetState(object obj, Dictionary<string, object> state)
//{
// if (obj != null)
// {
// /* Restore property values from state */
// foreach (var prop in obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0))
// {
// prop.SetValue(obj, state[prop.Name]);
// }
public static void PerformSetState(object obj, Dictionary<string, object> state) // /* Restore field values from state */
{ // foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0))
if (obj != null) // {
{ // field.SetValue(obj, state[field.Name]);
/* Restore property values from state */ // }
foreach (var prop in obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0)) // }
{ //}
prop.SetValue(obj, state[prop.Name]);
}
/* Restore field values from state */ ////public static Dictionary<string, dynamic> PerformGetState(object obj)
foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0)) //public static Dictionary<string, object> PerformGetState(object obj)
{ //{
field.SetValue(obj, state[field.Name]); // //var state = new Dictionary<string, dynamic>();
} // var state = new Dictionary<string, object>();
}
}
//public static Dictionary<string, dynamic> PerformGetState(object obj) // if (obj != null)
public static Dictionary<string, object> PerformGetState(object obj) // {
{ // /* Copy property values to state */
//var state = new Dictionary<string, dynamic>(); // foreach (var prop in obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0))
var state = new Dictionary<string, object>(); // {
// state.Add(prop.Name, prop.GetValue(obj));
// }
if (obj != null) // /* Copy field values to state */
{ // foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0))
/* Copy property values to state */ // {
foreach (var prop in obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0)) // state.Add(field.Name, field.GetValue(obj));
{ // }
state.Add(prop.Name, prop.GetValue(obj)); // }
}
/* Copy field values to state */ // return state;
foreach (var field in obj.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0)) //}
{
state.Add(field.Name, field.GetValue(obj));
}
}
return state;
}
} }
} }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: a26b509fa7ea461489c1010e81e82d7f guid: 38fa5b2e38bbb7b4695789da71a3506b
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -3,7 +3,7 @@ using System;
namespace Essgee.Emulation.Video namespace Essgee.Emulation.Video
{ {
interface IVideo interface IVideo : IAxiStatus
{ {
(int X, int Y, int Width, int Height) Viewport { get; } (int X, int Y, int Width, int Height) Viewport { get; }

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 3eda1878d76837140be1b0e89f93f37a guid: 1ddba906f8855dd40bb9666a7106c3b9
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -64,6 +64,20 @@ namespace Essgee.Emulation.Video.Nintendo
objPaletteData = new byte[64]; objPaletteData = new byte[64];
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
base.LoadAxiStatus(data);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = base.SaveAxiStatus();
return data;
}
#endregion
public override void Reset() public override void Reset()
{ {
base.Reset(); base.Reset();
@ -94,6 +108,7 @@ namespace Essgee.Emulation.Video.Nintendo
hdmaBytesLeft = 0; hdmaBytesLeft = 0;
} }
// //
protected override void StepHBlank() protected override void StepHBlank()

View File

@ -145,6 +145,22 @@ namespace Essgee.Emulation.Video.Nintendo
layerSpritesForceEnable = true; layerSpritesForceEnable = true;
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
vram = data.Array2DMemberData[nameof(vram)].Get2DArrayBytesData();
oam = data.MemberData[nameof(oam)];
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.Array2DMemberData[nameof(vram)] = new AxiEssgssStatusData_2DArray(vram);
data.MemberData[nameof(oam)] = oam;
return data;
}
#endregion
public object GetRuntimeOption(string name) public object GetRuntimeOption(string name)
{ {
switch (name) switch (name)

View File

@ -1,7 +1,6 @@
using Essgee.EventArguments; using Essgee.EventArguments;
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Runtime.InteropServices;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
namespace Essgee.Emulation.Video namespace Essgee.Emulation.Video

View File

@ -2,6 +2,7 @@
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
@ -358,6 +359,39 @@ namespace Essgee.Emulation.Video
for (int i = 0; i < spriteBuffer.Length; i++) spriteBuffer[i] = new (int Number, int Y, int X, int Pattern, int Attribute)[NumSpritesPerLineMode4]; for (int i = 0; i < spriteBuffer.Length; i++) spriteBuffer[i] = new (int Number, int Y, int X, int Pattern, int Attribute)[NumSpritesPerLineMode4];
} }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
base.LoadAxiStatus(data);
cram_set = data.MemberData[nameof(cram)];
vCounter = BitConverter.ToInt32(data.MemberData[nameof(vCounter)]);
hCounter = BitConverter.ToInt32(data.MemberData[nameof(hCounter)]);
lineInterruptCounter = BitConverter.ToInt32(data.MemberData[nameof(lineInterruptCounter)]);
isLineInterruptPending = BitConverter.ToBoolean(data.MemberData[nameof(isLineInterruptPending)]);
horizontalScrollLatched = data.MemberData[nameof(horizontalScrollLatched)].First();
verticalScrollLatched = data.MemberData[nameof(verticalScrollLatched)].First();
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = base.SaveAxiStatus();
data.MemberData[nameof(cram)] = cram_src;
data.MemberData[nameof(vCounter)] = BitConverter.GetBytes(vCounter);
data.MemberData[nameof(hCounter)] = BitConverter.GetBytes(hCounter);
data.MemberData[nameof(lineInterruptCounter)] = BitConverter.GetBytes(lineInterruptCounter);
data.MemberData[nameof(isLineInterruptPending)] = BitConverter.GetBytes(isLineInterruptPending);
data.MemberData[nameof(horizontalScrollLatched)] = BitConverter.GetBytes(horizontalScrollLatched);
data.MemberData[nameof(verticalScrollLatched)] = BitConverter.GetBytes(verticalScrollLatched);
return data;
}
#endregion
public override void Reset() public override void Reset()
{ {
base.Reset(); base.Reset();

View File

@ -2,6 +2,7 @@
using Essgee.Utilities; using Essgee.Utilities;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using static Essgee.Emulation.Utilities; using static Essgee.Emulation.Utilities;
@ -90,6 +91,82 @@ namespace Essgee.Emulation.Video
[StateRequired] [StateRequired]
protected (int Number, int Y, int X, int Pattern, int Attribute)[][] spriteBuffer; protected (int Number, int Y, int X, int Pattern, int Attribute)[][] spriteBuffer;
// 序列化方法
public byte[] spriteBuffer_Serialize()
{
// 首先,我们需要计算序列化后的总字节数
int totalBytes = 0;
foreach (var row in spriteBuffer)
{
if (row != null)
{
totalBytes += row.Length * 5 * sizeof(int); // 每个元组有5个int每个int占4个字节
}
}
// 分配一个足够大的字节数组
byte[] data = new byte[totalBytes];
int offset = 0;
// 填充字节数组
foreach (var row in spriteBuffer)
{
if (row != null)
{
foreach (var tuple in row)
{
Buffer.BlockCopy(BitConverter.GetBytes(tuple.Number), 0, data, offset, sizeof(int));
offset += sizeof(int);
Buffer.BlockCopy(BitConverter.GetBytes(tuple.Y), 0, data, offset, sizeof(int));
offset += sizeof(int);
Buffer.BlockCopy(BitConverter.GetBytes(tuple.X), 0, data, offset, sizeof(int));
offset += sizeof(int);
Buffer.BlockCopy(BitConverter.GetBytes(tuple.Pattern), 0, data, offset, sizeof(int));
offset += sizeof(int);
Buffer.BlockCopy(BitConverter.GetBytes(tuple.Attribute), 0, data, offset, sizeof(int));
offset += sizeof(int);
}
}
}
return data;
}
// 反序列化方法
public void spriteBuffer_SetData(byte[] data)
{
// 假设我们已经知道spriteBuffer的维度这通常需要在序列化时保存并在反序列化时读取
// 为了简化这里假设维度是已知的并且与原始spriteBuffer相同
int rowCount = spriteBuffer.Length;
int[] columnCounts = new int[rowCount];
for (int i = 0; i < rowCount; i++)
{
if (spriteBuffer[i] != null)
{
columnCounts[i] = spriteBuffer[i].Length;
}
}
int offset = 0;
spriteBuffer = new (int, int, int, int, int)[rowCount][];
for (int i = 0; i < rowCount; i++)
{
spriteBuffer[i] = new (int, int, int, int, int)[columnCounts[i]];
for (int j = 0; j < columnCounts[i]; j++)
{
spriteBuffer[i][j] = (
BitConverter.ToInt32(data, offset),
BitConverter.ToInt32(data, offset + sizeof(int)),
BitConverter.ToInt32(data, offset + 2 * sizeof(int)),
BitConverter.ToInt32(data, offset + 3 * sizeof(int)),
BitConverter.ToInt32(data, offset + 4 * sizeof(int))
);
offset += 5 * sizeof(int);
}
}
}
//protected ushort vramMask16k => 0x3FFF; //protected ushort vramMask16k => 0x3FFF;
//protected ushort vramMask4k => 0x0FFF; //protected ushort vramMask4k => 0x0FFF;
protected const ushort vramMask16k = 0x3FFF; protected const ushort vramMask16k = 0x3FFF;
@ -103,7 +180,7 @@ namespace Essgee.Emulation.Video
protected byte readBuffer; protected byte readBuffer;
protected byte codeRegister => (byte)((controlWord >> 14) & 0x03); protected byte codeRegister => (byte)((controlWord >> 14) & 0x03);
protected ushort addressRegister protected ushort addressRegister
{ {
get { return (ushort)(controlWord & 0x3FFF); } get { return (ushort)(controlWord & 0x3FFF); }
@ -246,6 +323,43 @@ namespace Essgee.Emulation.Video
layerBordersForceEnable = true; layerBordersForceEnable = true;
} }
#region AxiState
public virtual void LoadAxiStatus(AxiEssgssStatusData data)
{
registers_set = data.MemberData[nameof(registers)];
vram_set = data.MemberData[nameof(vram)];
spriteBuffer_SetData(data.MemberData[nameof(spriteBuffer)]);
isSecondControlWrite = BitConverter.ToBoolean(data.MemberData[nameof(isSecondControlWrite)]);
controlWord = BitConverter.ToUInt16(data.MemberData[nameof(controlWord)]);
readBuffer = data.MemberData[nameof(readBuffer)].First();
statusFlags = data.MemberData[nameof(statusFlags)].ToEnum<StatusFlags>();
InterruptLine = data.MemberData[nameof(InterruptLine)].ToEnum<InterruptState>();
currentScanline = BitConverter.ToInt32(data.MemberData[nameof(currentScanline)]);
screenUsage = data.MemberData[nameof(screenUsage)];
cycleCount = BitConverter.ToInt32(data.MemberData[nameof(cycleCount)]);
}
public virtual AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(registers)] = registers_src;
data.MemberData[nameof(vram)] = vram_src;
data.MemberData[nameof(spriteBuffer)] = spriteBuffer_Serialize();
data.MemberData[nameof(isSecondControlWrite)] = BitConverter.GetBytes(isSecondControlWrite);
data.MemberData[nameof(controlWord)] = BitConverter.GetBytes(controlWord);
data.MemberData[nameof(readBuffer)] = BitConverter.GetBytes(readBuffer);
data.MemberData[nameof(statusFlags)] = statusFlags.ToByteArray();
data.MemberData[nameof(InterruptLine)] = InterruptLine.ToByteArray();
data.MemberData[nameof(currentScanline)] = BitConverter.GetBytes(currentScanline);
data.MemberData[nameof(screenUsage)] = screenUsage;
data.MemberData[nameof(cycleCount)] = BitConverter.GetBytes(cycleCount);
return data;
}
#endregion
public object GetRuntimeOption(string name) public object GetRuntimeOption(string name)
{ {
switch (name) switch (name)

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 9ebca929cde32f948ae9c370636aa6d2 guid: 281db18b9e0f1054e8b4abae8427ba41
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -20,7 +20,7 @@ namespace Essgee.EventArguments
//} //}
//public static EnqueueSamplesEventArgs Create(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples) //public static EnqueueSamplesEventArgs Create(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
public static EnqueueSamplesEventArgs Create(int numChannels, short*[] channelSamples, bool[] isMuted, short* mixedSamples,int mixedSamplesLength) public static EnqueueSamplesEventArgs Create(int numChannels, short*[] channelSamples, bool[] isMuted, short* mixedSamples, int mixedSamplesLength)
{ {
var eventArgs = ObjectPoolAuto.Acquire<EnqueueSamplesEventArgs>(); var eventArgs = ObjectPoolAuto.Acquire<EnqueueSamplesEventArgs>();
eventArgs.NumChannels = numChannels; eventArgs.NumChannels = numChannels;

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: d1c46752ccd1bc9458481cc6745a9d00 guid: f1e895bd77f41874fad666b2f480f482
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: 2558194e2eb5320458689c46b71d51d5 guid: 1be95ab09a576dd4db60392be7d5f9f0
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -0,0 +1,222 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
[Serializable]
public class AxiEssgssStatusData
{
public Dictionary<string, byte[]> MemberData = new Dictionary<string, byte[]>();
public Dictionary<string, AxiEssgssStatusData_2DArray> Array2DMemberData = new Dictionary<string, AxiEssgssStatusData_2DArray>();
public Dictionary<string, AxiEssgssStatusData> ClassData = new Dictionary<string, AxiEssgssStatusData>();
}
[Serializable]
public class AxiEssgssStatusData_2DArray
{
public int rows;
public int cols;
public byte[] array1D;
public AxiEssgssStatusData_2DArray(byte[,] data2D)
{
rows = data2D.GetLength(0);
cols = data2D.GetLength(1);
array1D = data2D.FlattenByteArray2D();
}
public byte[,] Get2DArrayBytesData()
{
return array1D.CreateByteArray2D(rows, cols);
}
}
public static class AxiEssgssStatusDataExtention
{
public static byte[] ToByteArray(this AxiEssgssStatusData data)
{
using (MemoryStream ms = new MemoryStream())
{
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(ms, data);
return ms.ToArray();
}
}
public static AxiEssgssStatusData ToAxiEssgssStatusData(this byte[] byteArray)
{
using (MemoryStream ms = new MemoryStream(byteArray))
{
BinaryFormatter formatter = new BinaryFormatter();
return (AxiEssgssStatusData)formatter.Deserialize(ms);
}
}
}
public interface IAxiStatus
{
public void LoadAxiStatus(AxiEssgssStatusData data);
public AxiEssgssStatusData SaveAxiStatus();
}
internal static class AxiStatus
{
// 将任意枚举数组转换为byte[]
public static byte[] ToByteArray<TEnum>(this TEnum[] enumArray) where TEnum : struct, Enum
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
// 获取枚举的基础类型通常是Int32
Type enumUnderlyingType = Enum.GetUnderlyingType(typeof(TEnum));
if (enumUnderlyingType != typeof(byte)) // 检查基础类型是否为byte如果不是则需要进行额外的处理
{
// 如果基础类型不是byte我们需要决定如何处理。这里我们假设基础类型是int并将其转换为byte数组
// 但要注意这可能会导致数据丢失如果枚举值超出了byte的范围
// 一个更安全的方法是使用更大的数据类型如int[])作为中间表示。
// 但为了简化示例我们将继续并假设所有枚举值都可以安全地转换为byte。
// 警告:这个假设可能不适用于所有情况!
// 由于我们假设基础类型是int这是最常见的枚举基础类型我们可以直接转换每个枚举值为int
// 然后检查它们是否可以安全地转换为byte。如果不能这里将抛出异常。
return enumArray.Select(e =>
{
int intValue = Convert.ToInt32(e);
if (intValue < byte.MinValue || intValue > byte.MaxValue)
throw new OverflowException($"Enum value {e} ({intValue}) is out of range for byte.");
return (byte)intValue;
}).ToArray();
}
else
{
// 如果基础类型已经是byte则直接转换
return Array.ConvertAll(enumArray, e => Convert.ToByte(e));
}
}
// 从byte[]转换为任意枚举数组
public static TEnum[] ToEnumArray<TEnum>(this byte[] byteArray) where TEnum : struct, Enum
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
// 直接转换每个byte为枚举值
return Array.ConvertAll(byteArray, b => (TEnum)Enum.ToObject(typeof(TEnum), b));
}
// 将单个枚举转换为byte[](通常这个转换不太常见,因为结果将只有一个字节,但我们还是实现它)
public static byte[] ToByteArray<TEnum>(this TEnum enumValue) where TEnum : struct, Enum
{
if (!typeof(TEnum).IsEnum) throw new ArgumentException("TEnum must be an enumerated type");
// 获取枚举的基础类型
Type enumUnderlyingType = Enum.GetUnderlyingType(typeof(TEnum));
// 检查基础类型是否为byte如果不是则进行转换这里我们假设可以安全地转换为byte但通常枚举的基础类型是int
if (enumUnderlyingType == typeof(byte))
{
// 如果基础类型已经是byte则直接返回包含该字节的数组
return new[] { Convert.ToByte(enumValue) };
}
else if (enumUnderlyingType == typeof(int)) // 最常见的枚举基础类型
{
// 将枚举值转换为int然后检查是否可以安全地转换为byte
int intValue = Convert.ToInt32(enumValue);
if (intValue < byte.MinValue || intValue > byte.MaxValue)
throw new OverflowException($"Enum value {enumValue} ({intValue}) is out of range for byte.");
// 返回包含转换后的字节的数组
return new[] { (byte)intValue };
}
else
{
// 如果基础类型不是byte或int则抛出异常或者你可以添加更多的类型检查和处理逻辑
throw new NotSupportedException($"The underlying type of the enum {typeof(TEnum).Name} is not supported.");
}
}
// 从byte[]转换为单个枚举假设byte[]只有一个字节)
public static TEnum ToEnum<TEnum>(this byte[] byteArray) where TEnum : struct, Enum
{
if (byteArray == null || byteArray.Length != 1)
throw new ArgumentException("The byte array must contain exactly one byte.");
// 直接从字节转换为枚举值
return (TEnum)Enum.ToObject(typeof(TEnum), byteArray[0]);
}
// ushort[] 转 byte[]
public static byte[] ToByteArray(this ushort[] ushortArray)
{
byte[] byteArray = new byte[ushortArray.Length * 2];
Buffer.BlockCopy(ushortArray, 0, byteArray, 0, byteArray.Length);
return byteArray;
}
// byte[] 转 ushort[]
public static ushort[] ToUShortArray(this byte[] byteArray)
{
if (byteArray.Length % 2 != 0)
throw new ArgumentException("byte数组长度必须是偶数");
ushort[] ushortArray = new ushort[byteArray.Length / 2];
Buffer.BlockCopy(byteArray, 0, ushortArray, 0, byteArray.Length);
return ushortArray;
}
public static byte[] ToByteArray(this bool[] boolArr)
{
byte[] byteArray = new byte[boolArr.Length];
for (int i = 0; i < byteArray.Length; i++)
{
byteArray[i] = (byte)(boolArr[i] ? 1 : 0);
}
return byteArray;
}
public static bool[] ToBoolArray(this byte[] byteArray)
{
bool[] boolArr = new bool[byteArray.Length];
for (int i = 0; i < byteArray.Length; i++)
{
boolArr[i] = byteArray[i] == 0 ? false : true;
}
return boolArr;
}
public static byte[] FlattenByteArray2D(this byte[,] array2D)
{
int rows = array2D.GetLength(0);
int cols = array2D.GetLength(1);
byte[] array1D = new byte[rows * cols];
int index = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array1D[index++] = array2D[i, j];
}
}
return array1D;
}
public static byte[,] CreateByteArray2D(this byte[] array1D, int rows, int cols)
{
if (array1D.Length != rows * cols)
{
throw new ArgumentException("The length of the 1D array does not match the specified dimensions for the 2D array.");
}
byte[,] array2D = new byte[rows, cols];
int index = 0;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
array2D[i, j] = array1D[index++];
}
}
return array2D;
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 40ed20a1384827f45b7f187a4ccb4740

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: ae0b7e73691b4fd448b102af0875a373 guid: 5b91d039db189d445a206d1852ae838a
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -18,7 +18,7 @@ namespace Essgee.Metadata
public interface IGameMetaReources public interface IGameMetaReources
{ {
public bool GetCartMetadataDatabase(out string loadedData); public bool GetCartMetadataDatabase(out string loadedData);
public bool GetDatBytes(string DatName,out byte[] loadedData); public bool GetDatBytes(string DatName, out byte[] loadedData);
} }
public class GameMetadataHandler public class GameMetadataHandler
@ -37,7 +37,7 @@ namespace Essgee.Metadata
{ {
gameMetaReources = metaresources; gameMetaReources = metaresources;
if(!gameMetaReources.GetCartMetadataDatabase(out string loadedData)) if (!gameMetaReources.GetCartMetadataDatabase(out string loadedData))
throw new HandlerException("CartMetadataDatabase file not found"); throw new HandlerException("CartMetadataDatabase file not found");
cartMetadataDatabase = JsonConvert.DeserializeObject<List<CartridgeJSON>>(loadedData); cartMetadataDatabase = JsonConvert.DeserializeObject<List<CartridgeJSON>>(loadedData);

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: fd20bf051feed2649a0b54c1c23246b0 guid: efbb7663b0390d544a2f62d060d8441d
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,5 +1,5 @@
fileFormatVersion: 2 fileFormatVersion: 2
guid: e7cd06ff5a47d6b49b280e1f99c667e4 guid: 37b3e1d7093e0f545807ab54c1209c8b
folderAsset: yes folderAsset: yes
DefaultImporter: DefaultImporter:
externalObjects: {} externalObjects: {}

View File

@ -1,3 +1,5 @@
using AxibugEmuOnline.Client;
using AxibugProtobuf;
using Essgee; using Essgee;
using Essgee.Emulation; using Essgee.Emulation;
using Essgee.Emulation.Configuration; using Essgee.Emulation.Configuration;
@ -13,13 +15,25 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using UnityEngine; using UnityEngine;
using UnityEngine.UI;
public class Essgeeinit : MonoBehaviour public class Essgeeinit : MonoBehaviour, IEmuCore
{ {
static Essgeeinit instance; public static Essgeeinit instance;
public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew(); public static System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
public static bool bInGame => instance?.emulatorHandler?.IsRunning == true ? true : false; public static bool bInGame => instance?.emulatorHandler?.IsRunning == true ? true : false;
public RomPlatformType Platform => mPlatform;
public uint Frame => throw new NotImplementedException();
public Texture OutputPixel => graphicsHandler.rawBufferWarper;
public RawImage DrawCanvas => graphicsHandler.DrawCanvas;
public static bool bLogicUpdatePause { get; private set; }
#region #region
UEGVideoPlayer graphicsHandler; UEGVideoPlayer graphicsHandler;
UEGSoundPlayer soundHandler; UEGSoundPlayer soundHandler;
GameMetadataHandler gameMetadataHandler; GameMetadataHandler gameMetadataHandler;
@ -29,22 +43,19 @@ public class Essgeeinit : MonoBehaviour
UEGLog uegLog; UEGLog uegLog;
bool lastUserPauseState; bool lastUserPauseState;
(int x, int y, int width, int height) currentViewport;
double currentPixelAspectRatio; double currentPixelAspectRatio;
byte[] lastFramebufferData;
(int width, int height) lastFramebufferSize;
private UEGKeyboard mUniKeyboard; private UEGKeyboard mUniKeyboard;
private RomPlatformType mPlatform = RomPlatformType.MasterSystem;
#endregion #endregion
void Awake() void Awake()
{ {
instance = this; instance = this;
uegResources = new UEGResources(); uegResources = new UEGResources();
uegLog = new UEGLog(); uegLog = new UEGLog();
InitAll(uegResources, Application.persistentDataPath); InitAll(uegResources, Application.persistentDataPath);
LoadAndRunCartridge("G:/psjapa.sms"); //LoadAndRunCartridge("G:/psjapa.sms");
//LoadAndRunCartridge("G:/Ninja_Gaiden_(UE)_type_A_[!].sms"); //LoadAndRunCartridge("G:/Ninja_Gaiden_(UE)_type_A_[!].sms");
//LoadAndRunCartridge("G:/SML2.gb"); //LoadAndRunCartridge("G:/SML2.gb");
} }
@ -55,16 +66,96 @@ public class Essgeeinit : MonoBehaviour
Dispose(false); Dispose(false);
} }
private void Update()
{
if (!emulatorHandler.IsRunning)
return;
mUniKeyboard.UpdateInputKey();
emulatorHandler.Update_Frame(); #region EmuCore接入实现
public object GetState()
{
return emulatorHandler.GetStateData();
} }
void InitAll(IGameMetaReources metaresources,string CustonDataDir) public byte[] GetStateBytes()
{
return emulatorHandler.GetStateData();
}
public void LoadState(object state)
{
Application.targetFrameRate = 60;
emulatorHandler.SetStateData((byte[])state);
}
public void LoadStateFromBytes(byte[] data)
{
emulatorHandler.SetStateData(data);
}
public void Pause()
{
bLogicUpdatePause = false;
}
public void Resume()
{
bLogicUpdatePause = true;
}
public MsgBool StartGame(RomFile romFile)
{
mPlatform = romFile.Platform;
bLogicUpdatePause = true;
//保存当前正在进行的游戏存档
if (!emulatorHandler.IsRunning)
{
emulatorHandler.SaveCartridge();
}
if (LoadAndRunCartridge(romFile.FileName))
return true;
else
return "Rom加载失败";
}
public void Dispose()
{
if (!emulatorHandler.IsRunning)
{
emulatorHandler.SaveCartridge();
}
ShutdownEmulation();
}
public void DoReset()
{
emulatorHandler.SaveCartridge();
emulatorHandler.Reset();
}
public IControllerSetuper GetControllerSetuper()
{
return mUniKeyboard.ControllerMapper;
}
public bool PushEmulatorFrame()
{
if (!emulatorHandler.IsRunning) return false;
if (!bLogicUpdatePause) return false;
//采集本帧Input
bool bhadNext = mUniKeyboard.SampleInput();
//如果未收到Input数据,核心帧不推进
if (!bhadNext) return false;
emulatorHandler.Update_Frame();
return true;
}
public void AfterPushFrame()
{
}
#endregion
void InitAll(IGameMetaReources metaresources, string CustonDataDir)
{ {
//初始化配置 //初始化配置
InitAppEnvironment(CustonDataDir); InitAppEnvironment(CustonDataDir);
@ -344,11 +435,11 @@ public class Essgeeinit : MonoBehaviour
} }
private void LoadAndRunCartridge(string fileName) private bool LoadAndRunCartridge(string fileName)
{ {
Application.targetFrameRate = 60;
try try
{ {
var (machineType, romData) = CartridgeLoader.Load(fileName, "ROM image"); var (machineType, romData) = CartridgeLoader.Load(fileName, "ROM image");
//TODO IsRecording?? 可能需要实现 //TODO IsRecording?? 可能需要实现
@ -389,10 +480,13 @@ public class Essgeeinit : MonoBehaviour
//SetWindowTitleAndStatus(); //SetWindowTitleAndStatus();
EssgeeLogger.EnqueueMessage($"Loaded '{lastGameMetadata?.KnownName ?? "unrecognized game"}'."); EssgeeLogger.EnqueueMessage($"Loaded '{lastGameMetadata?.KnownName ?? "unrecognized game"}'.");
return true;
} }
catch (Exception ex) when (!AppEnvironment.DebugMode) catch (Exception ex) when (!AppEnvironment.DebugMode)
{ {
ExceptionHandler(ex); ExceptionHandler(ex);
return false;
} }
} }
private void InitializeEmulation(Type machineType) private void InitializeEmulation(Type machineType)
@ -549,8 +643,6 @@ public class Essgeeinit : MonoBehaviour
emulatorHandler = null; emulatorHandler = null;
GC.Collect(); GC.Collect();
//graphicsHandler?.FlushTextures();
EssgeeLogger.WriteLine("Emulation stopped."); EssgeeLogger.WriteLine("Emulation stopped.");
} }
#endregion #endregion
@ -618,7 +710,7 @@ public class Essgeeinit : MonoBehaviour
//TODO Input实现 //TODO Input实现
//e.Keyboard = mUniKeyboard.mKeyCodeCore.GetPressedKeys(); //e.Keyboard = mUniKeyboard.mKeyCodeCore.GetPressedKeys();
e.Keyboard.AddRange(mUniKeyboard.mKeyCodeCore.GetPressedKeys()); e.Keyboard.AddRange(mUniKeyboard.GetPressedKeys());
e.MouseButtons = default; e.MouseButtons = default;
e.MousePosition = default; e.MousePosition = default;
@ -721,6 +813,7 @@ public class Essgeeinit : MonoBehaviour
//soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamples.Length); //soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamples.Length);
soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamplesLength); soundHandler.SubmitSamples(e.MixedSamples, e.ChannelSamples, e.MixedSamplesLength);
} }
#endregion #endregion
} }

View File

@ -1,418 +0,0 @@
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class KeyCodeCore
{
//public Dictionary<KeyCode, EssgeeMotionKey> dictKeyCfgs = new Dictionary<KeyCode, EssgeeMotionKey>();
public Dictionary<ulong, EssgeeMotionKey> dictKey2Motion = new Dictionary<ulong, EssgeeMotionKey>();
public Dictionary<ulong, KeyCode> dictMotion2RealKey = new Dictionary<ulong, KeyCode>()
{
{ EssgeeUnityKey.P1_UP,KeyCode.W},
{ EssgeeUnityKey.P1_DOWN,KeyCode.S},
{ EssgeeUnityKey.P1_LEFT,KeyCode.A},
{ EssgeeUnityKey.P1_RIGHT,KeyCode.D},
{ EssgeeUnityKey.P1_BTN_1,KeyCode.J},
{ EssgeeUnityKey.P1_BTN_2,KeyCode.K},
{ EssgeeUnityKey.P1_BTN_3,KeyCode.U},
{ EssgeeUnityKey.P1_BTN_4,KeyCode.I},
{ EssgeeUnityKey.P1_POTION_1,KeyCode.Return},
{ EssgeeUnityKey.P1_POTION_2,KeyCode.RightShift},
{ EssgeeUnityKey.P2_UP,KeyCode.UpArrow},
{ EssgeeUnityKey.P2_DOWN,KeyCode.DownArrow},
{ EssgeeUnityKey.P2_LEFT,KeyCode.LeftArrow},
{ EssgeeUnityKey.P2_RIGHT,KeyCode.RightArrow},
{ EssgeeUnityKey.P2_BTN_1,KeyCode.Keypad1},
{ EssgeeUnityKey.P2_BTN_2,KeyCode.Keypad2},
{ EssgeeUnityKey.P2_BTN_3,KeyCode.Keypad4},
{ EssgeeUnityKey.P2_BTN_4,KeyCode.Keypad5},
{ EssgeeUnityKey.P2_POTION_1,KeyCode.Keypad0},
{ EssgeeUnityKey.P2_POTION_2,KeyCode.KeypadPeriod},
{ EssgeeUnityKey.P3_UP,KeyCode.F12},
{ EssgeeUnityKey.P3_DOWN,KeyCode.F12},
{ EssgeeUnityKey.P3_LEFT,KeyCode.F12},
{ EssgeeUnityKey.P3_RIGHT,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_1,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_2,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_3,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_4,KeyCode.F12},
{ EssgeeUnityKey.P3_POTION_1,KeyCode.F12},
{ EssgeeUnityKey.P3_POTION_2,KeyCode.F12},
{ EssgeeUnityKey.P4_UP,KeyCode.F12},
{ EssgeeUnityKey.P4_DOWN,KeyCode.F12},
{ EssgeeUnityKey.P4_LEFT,KeyCode.F12},
{ EssgeeUnityKey.P4_RIGHT,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_1,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_2,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_3,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_4,KeyCode.F12},
{ EssgeeUnityKey.P4_POTION_1,KeyCode.F12},
{ EssgeeUnityKey.P4_POTION_2,KeyCode.F12},
};
public ulong[] CheckList;
public EssgeeMotionKey[] mCurrKey = new EssgeeMotionKey[0];
List<EssgeeMotionKey> temp = new List<EssgeeMotionKey>();
ulong tempInputAllData = 0;
UEGKeyboard mUniKeyboard;
ulong last_CurryInpuAllData_test = 0;
public static class EssgeeUnityKey
{
public const ulong NONE = 0;
public const ulong P1_UP = 1;
public const ulong P1_DOWN = 1 << 1;
public const ulong P1_LEFT = 1 << 2;
public const ulong P1_RIGHT = 1 << 3;
public const ulong P1_BTN_1 = 1 << 4;
public const ulong P1_BTN_2 = 1 << 5;
public const ulong P1_BTN_3 = 1 << 6;
public const ulong P1_BTN_4 = 1 << 7;
public const ulong P1_POTION_1 = 1 << 8;
public const ulong P1_POTION_2 = 1 << 9;
public const ulong P2_UP = 65536;
public const ulong P2_DOWN = 65536 << 1;
public const ulong P2_LEFT = 65536 << 2;
public const ulong P2_RIGHT = 65536 << 3;
public const ulong P2_BTN_1 = 65536 << 4;
public const ulong P2_BTN_2 = 65536 << 5;
public const ulong P2_BTN_3 = 65536 << 6;
public const ulong P2_BTN_4 = 65536 << 7;
public const ulong P2_POTION_1 = 65536 << 8;
public const ulong P2_POTION_2 = 65536 << 9;
public const ulong P3_UP = 4294967296;
public const ulong P3_DOWN = 4294967296 << 1;
public const ulong P3_LEFT = 4294967296 << 2;
public const ulong P3_RIGHT = 4294967296 << 3;
public const ulong P3_BTN_1 = 4294967296 << 4;
public const ulong P3_BTN_2 = 4294967296 << 5;
public const ulong P3_BTN_3 = 4294967296 << 6;
public const ulong P3_BTN_4 = 654294967296536 << 7;
public const ulong P3_POTION_1 = 4294967296 << 8;
public const ulong P3_POTION_2 = 4294967296 << 9;
public const ulong P4_UP = 281474976710656;
public const ulong P4_DOWN = 281474976710656 << 1;
public const ulong P4_LEFT = 281474976710656 << 2;
public const ulong P4_RIGHT = 281474976710656 << 3;
public const ulong P4_BTN_1 = 281474976710656 << 4;
public const ulong P4_BTN_2 = 281474976710656 << 5;
public const ulong P4_BTN_3 = 281474976710656 << 6;
public const ulong P4_BTN_4 = 281474976710656 << 7;
public const ulong P4_POTION_1 = 281474976710656 << 8;
public const ulong P4_POTION_2 = 281474976710656 << 9;
}
public EssgeeMotionKey[] GetPressedKeys()
{
return mCurrKey;
}
public void SetRePlay(bool IsReplay)
{
//bReplayMode = IsReplay;
}
public void Init(Essgee.Emulation.Machines.IMachine Machine, UEGKeyboard uniKeyboard, bool IsReplay)
{
mUniKeyboard = uniKeyboard;
//dictKeyCfgs.Clear();
dictKey2Motion.Clear();
if (Machine is Essgee.Emulation.Machines.MasterSystem)
{
var machine = (Essgee.Emulation.Machines.MasterSystem)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.Joypad1Up);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.Joypad1Down);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.Joypad1Left);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.Joypad1Right);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.Joypad1Button1);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.Joypad1Button2);
//dictKeyCfgs.Add(KeyCode.UpArrow, machine.configuration.Joypad2Up);
//dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
//dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
//dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
//dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button1);
//dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.Joypad1Button1);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P2_UP, machine.configuration.Joypad2Up);
dictKey2Motion.Add(EssgeeUnityKey.P2_DOWN, machine.configuration.Joypad2Down);
dictKey2Motion.Add(EssgeeUnityKey.P2_LEFT, machine.configuration.Joypad2Left);
dictKey2Motion.Add(EssgeeUnityKey.P2_RIGHT, machine.configuration.Joypad2Right);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_1, machine.configuration.Joypad2Button1);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_2, machine.configuration.Joypad2Button2);
}
else if (Machine is Essgee.Emulation.Machines.GameBoy)
{
var machine = (Essgee.Emulation.Machines.GameBoy)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.ControlsUp);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.ControlsDown);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.ControlsLeft);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.ControlsRight);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.ControlsB);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.ControlsA);
//dictKeyCfgs.Add(KeyCode.Return, machine.configuration.ControlsStart);
//dictKeyCfgs.Add(KeyCode.RightShift, machine.configuration.ControlsSelect);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.ControlsUp);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.ControlsDown);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.ControlsLeft);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.ControlsRight);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.ControlsB);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.ControlsA);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.ControlsStart);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_2, machine.configuration.ControlsSelect);
}
else if (Machine is Essgee.Emulation.Machines.GameBoyColor)
{
var machine = (Essgee.Emulation.Machines.GameBoyColor)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.ControlsUp);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.ControlsDown);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.ControlsLeft);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.ControlsRight);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.ControlsB);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.ControlsA);
//dictKeyCfgs.Add(KeyCode.Return, machine.configuration.ControlsStart);
//dictKeyCfgs.Add(KeyCode.RightShift, machine.configuration.ControlsSelect);
//dictKeyCfgs.Add(KeyCode.Space, machine.configuration.ControlsSendIR);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.ControlsUp);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.ControlsDown);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.ControlsLeft);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.ControlsRight);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.ControlsA);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.ControlsB);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_3, machine.configuration.ControlsSendIR);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.ControlsStart);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_2, machine.configuration.ControlsSelect);
}
else if (Machine is Essgee.Emulation.Machines.GameGear)
{
var machine = (Essgee.Emulation.Machines.GameGear)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.ControlsUp);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.ControlsDown);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.ControlsLeft);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.ControlsRight);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.ControlsButton2);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.ControlsButton1);
//dictKeyCfgs.Add(KeyCode.Return, machine.configuration.ControlsStart);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.ControlsUp);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.ControlsDown);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.ControlsLeft);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.ControlsRight);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.ControlsButton2);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.ControlsButton1);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.ControlsStart);
}
else if (Machine is Essgee.Emulation.Machines.SC3000)
{
var machine = (Essgee.Emulation.Machines.SC3000)Machine;
/*
* InputReset = MotionKey.F12;
InputChangeMode = MotionKey.F1;
InputPlayTape = MotionKey.F2;
Joypad1Up = MotionKey.Up;
Joypad1Down = MotionKey.Down;
Joypad1Left = MotionKey.Left;
Joypad1Right = MotionKey.Right;
Joypad1Button1 = MotionKey.A;
Joypad1Button2 = MotionKey.S;
Joypad2Up = MotionKey.NumPad8;
Joypad2Down = MotionKey.NumPad2;
Joypad2Left = MotionKey.NumPad4;
Joypad2Right = MotionKey.NumPad6;
Joypad2Button1 = MotionKey.NumPad1;
Joypad2Button2 = MotionKey.NumPad3;
*/
//dictKeyCfgs.Add(KeyCode.F12, machine.configuration.InputReset);
//dictKeyCfgs.Add(KeyCode.F1, machine.configuration.InputChangeMode);
//dictKeyCfgs.Add(KeyCode.F2, machine.configuration.InputPlayTape);
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.Joypad1Up);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.Joypad1Down);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.Joypad1Left);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.Joypad1Right);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.Joypad1Button2);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.Joypad1Button1);
//dictKeyCfgs.Add(KeyCode.UpArrow, machine.configuration.Joypad2Up);
//dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
//dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
//dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
//dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button1);
//dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.InputChangeMode);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_2, machine.configuration.InputPlayTape);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.Joypad1Button1);
dictKey2Motion.Add(EssgeeUnityKey.P2_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P2_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P2_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P2_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_2, machine.configuration.Joypad1Button1);
}
else if (Machine is Essgee.Emulation.Machines.SG1000)
{
var machine = (Essgee.Emulation.Machines.SG1000)Machine;
/*
TVStandard = TVStandard.NTSC;
InputPause = MotionKey.Space;
Joypad1Up = MotionKey.Up;
Joypad1Down = MotionKey.Down;
Joypad1Left = MotionKey.Left;
Joypad1Right = MotionKey.Right;
Joypad1Button1 = MotionKey.A;
Joypad1Button2 = MotionKey.S;
Joypad2Up = MotionKey.NumPad8;
Joypad2Down = MotionKey.NumPad2;
Joypad2Left = MotionKey.NumPad4;
Joypad2Right = MotionKey.NumPad6;
Joypad2Button1 = MotionKey.NumPad1;
Joypad2Button2 = MotionKey.NumPad3;
*/
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.Joypad1Up);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.Joypad1Down);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.Joypad1Left);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.Joypad1Right);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.Joypad1Button2);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.Joypad1Button1);
//dictKeyCfgs.Add(KeyCode.UpArrow, machine.configuration.Joypad2Up);
//dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
//dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
//dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
//dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button2);
//dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button1);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.Joypad1Button1);
dictKey2Motion.Add(EssgeeUnityKey.P2_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P2_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P2_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P2_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_2, machine.configuration.Joypad1Button1);
}
CheckList = dictKey2Motion.Keys.ToArray();
//mUniKeyboard.btnP1.Key = new long[] { (long)MotionKey.P1_GAMESTART };
//mUniKeyboard.btnCoin1.Key = new long[] { (long)MotionKey.P1_INSERT_COIN };
//mUniKeyboard.btnA.Key = new long[] { (long)MotionKey.P1_BTN_1 };
//mUniKeyboard.btnB.Key = new long[] { (long)MotionKey.P1_BTN_2 };
//mUniKeyboard.btnC.Key = new long[] { (long)MotionKey.P1_BTN_3 };
//mUniKeyboard.btnD.Key = new long[] { (long)MotionKey.P1_BTN_4 };
////mUniKeyboard.btnE.Key = new long[] { (long)MotionKey.P1_BTN_5 };
////mUniKeyboard.btnF.Key = new long[] { (long)MotionKey.P1_BTN_6 };
//mUniKeyboard.btnAB.Key = new long[] { (long)MotionKey.P1_BTN_1, (long)MotionKey.P1_BTN_2 };
//mUniKeyboard.btnCD.Key = new long[] { (long)MotionKey.P1_BTN_3, (long)MotionKey.P1_BTN_4 };
//mUniKeyboard.btnABC.Key = new long[] { (long)MotionKey.P1_BTN_1, (long)MotionKey.P1_BTN_2, (long)MotionKey.P1_BTN_3 };
}
public void UpdateLogic()
{
tempInputAllData = 0;
temp.Clear();
for (int i = 0; i < CheckList.Length; i++)
{
ulong key = CheckList[i];
if (Input.GetKey(dictMotion2RealKey[key]))
{
EssgeeMotionKey mk = dictKey2Motion[key];
temp.Add(mk);
tempInputAllData |= (ulong)mk;
}
}
mCurrKey = temp.ToArray();
//if (bReplayMode) return;
//tempInputAllData = 0;
//temp.Clear();
//for (int i = 0; i < CheckList.Length; i++)
//{
// if (Input.GetKey(CheckList[i]))
// {
// EssgeeMotionKey mk = dictKeyCfgs[CheckList[i]];
// temp.Add(mk);
// tempInputAllData |= (ulong)mk;
// }
//}
//mCurrKey = temp.ToArray();
//for (int i = 0; i < mUniKeyboard.mUIBtns.Count; i++)
//{
// if (mUniKeyboard.mUIBtns[i].bHotKey)
// {
// for (int j = 0; j < mUniKeyboard.mUIBtns[i].Key.Length; j++)
// {
// MotionKey mk = (MotionKey)mUniKeyboard.mUIBtns[i].Key[j];
// temp.Add(mk);
// tempInputAllData |= (ulong)mk;
// }
// }
//}
//Vector2Int inputV2 = mUniKeyboard.mJoystick.RawInputV2;
////Debug.Log($"{inputV2.x},{inputV2.y}");
//if (inputV2.x > 0)
//{
// temp.Add(MotionKey.P1_RIGHT);
// tempInputAllData |= (ulong)MotionKey.P1_RIGHT;
//}
//else if (inputV2.x < 0)
//{
// temp.Add(MotionKey.P1_LEFT);
// tempInputAllData |= (ulong)MotionKey.P1_LEFT;
//}
//if (inputV2.y > 0)
//{
// temp.Add(MotionKey.P1_UP);
// tempInputAllData |= (ulong)MotionKey.P1_UP;
//}
//else if (inputV2.y < 0)
//{
// temp.Add(MotionKey.P1_DOWN);
// tempInputAllData |= (ulong)MotionKey.P1_DOWN;
//}
//CurryInpuAllData = tempInputAllData;
//mCurrKey = temp.ToArray();
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 3054336185b15f84d9543bdafb49907f

View File

@ -1,77 +1,718 @@
using AxibugEmuOnline.Client;
using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Event;
using AxiReplay;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine; using UnityEngine;
public class UEGKeyboard : MonoBehaviour public class UEGKeyboard : MonoBehaviour
{ {
public KeyCodeCore mKeyCodeCore = new KeyCodeCore(); public EssgeeControllerMapper ControllerMapper { get; private set; }
#region public Dictionary<ulong, EssgeeMotionKey> dictKey2Motion = new Dictionary<ulong, EssgeeMotionKey>();
//public UILongClickButton btnP1; public Dictionary<ulong, KeyCode> dictMotion2RealKey = new Dictionary<ulong, KeyCode>()
//public UILongClickButton btnCoin1; {
//public UILongClickButton btnA; { EssgeeUnityKey.P1_UP,KeyCode.W},
//public UILongClickButton btnB; { EssgeeUnityKey.P1_DOWN,KeyCode.S},
//public UILongClickButton btnC; { EssgeeUnityKey.P1_LEFT,KeyCode.A},
//public UILongClickButton btnD; { EssgeeUnityKey.P1_RIGHT,KeyCode.D},
////public UILongClickButton btnE; { EssgeeUnityKey.P1_BTN_1,KeyCode.J},
////public UILongClickButton btnF; { EssgeeUnityKey.P1_BTN_2,KeyCode.K},
//public UILongClickButton btnAB; { EssgeeUnityKey.P1_BTN_3,KeyCode.U},
//public UILongClickButton btnCD; { EssgeeUnityKey.P1_BTN_4,KeyCode.I},
//public UILongClickButton btnABC; { EssgeeUnityKey.P1_POTION_1,KeyCode.Return},
//public Transform tfKeyPad; { EssgeeUnityKey.P1_POTION_2,KeyCode.RightShift},
//public FloatingJoystick mJoystick; { EssgeeUnityKey.P2_UP,KeyCode.UpArrow},
#endregion { EssgeeUnityKey.P2_DOWN,KeyCode.DownArrow},
{ EssgeeUnityKey.P2_LEFT,KeyCode.LeftArrow},
//public List<UILongClickButton> mUIBtns = new List<UILongClickButton>(); { EssgeeUnityKey.P2_RIGHT,KeyCode.RightArrow},
{ EssgeeUnityKey.P2_BTN_1,KeyCode.Keypad1},
{ EssgeeUnityKey.P2_BTN_2,KeyCode.Keypad2},
{ EssgeeUnityKey.P2_BTN_3,KeyCode.Keypad4},
{ EssgeeUnityKey.P2_BTN_4,KeyCode.Keypad5},
{ EssgeeUnityKey.P2_POTION_1,KeyCode.Keypad0},
{ EssgeeUnityKey.P2_POTION_2,KeyCode.KeypadPeriod},
{ EssgeeUnityKey.P3_UP,KeyCode.F12},
{ EssgeeUnityKey.P3_DOWN,KeyCode.F12},
{ EssgeeUnityKey.P3_LEFT,KeyCode.F12},
{ EssgeeUnityKey.P3_RIGHT,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_1,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_2,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_3,KeyCode.F12},
{ EssgeeUnityKey.P3_BTN_4,KeyCode.F12},
{ EssgeeUnityKey.P3_POTION_1,KeyCode.F12},
{ EssgeeUnityKey.P3_POTION_2,KeyCode.F12},
{ EssgeeUnityKey.P4_UP,KeyCode.F12},
{ EssgeeUnityKey.P4_DOWN,KeyCode.F12},
{ EssgeeUnityKey.P4_LEFT,KeyCode.F12},
{ EssgeeUnityKey.P4_RIGHT,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_1,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_2,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_3,KeyCode.F12},
{ EssgeeUnityKey.P4_BTN_4,KeyCode.F12},
{ EssgeeUnityKey.P4_POTION_1,KeyCode.F12},
{ EssgeeUnityKey.P4_POTION_2,KeyCode.F12},
};
public ulong[] CheckList;
public EssgeeMotionKey[] mCurrKey = new EssgeeMotionKey[0];
List<EssgeeMotionKey> temp = new List<EssgeeMotionKey>();
public ulong CurrRemoteInpuAllData = 0;
public ulong CurrLocalInpuAllData { get; private set; }
void Awake() void Awake()
{ {
//mJoystick = GameObject.Find("tfJoystick").GetComponent<FloatingJoystick>();
//tfKeyPad = GameObject.Find("tfKeyPad").transform;
//btnP1 = GameObject.Find("btnP1").GetComponent<UILongClickButton>();
//btnCoin1 = GameObject.Find("btnCoin1").GetComponent<UILongClickButton>();
//btnA = GameObject.Find("btnA").GetComponent<UILongClickButton>();
//btnB = GameObject.Find("btnB").GetComponent<UILongClickButton>();
//btnC = GameObject.Find("btnC").GetComponent<UILongClickButton>();
//btnD = GameObject.Find("btnD").GetComponent<UILongClickButton>();
////btnE = GameObject.Find("btnE")?.GetComponent<UILongClickButton>();
////btnF = GameObject.Find("btnF")?.GetComponent<UILongClickButton>();
//btnAB = GameObject.Find("btnAB").GetComponent<UILongClickButton>();
//btnCD = GameObject.Find("btnCD").GetComponent<UILongClickButton>();
//btnABC = GameObject.Find("btnABC").GetComponent<UILongClickButton>();
//mUIBtns.Add(btnP1);
//mUIBtns.Add(btnCoin1);
//mUIBtns.Add(btnA);
//mUIBtns.Add(btnB);
//mUIBtns.Add(btnC);
//mUIBtns.Add(btnD);
//mUIBtns.Add(btnAB);
//mUIBtns.Add(btnCD);
//mUIBtns.Add(btnABC);
//if (btnE != null)
//{
// mUIBtns.Add(btnE);
// btnE.gameObject.SetActive(false);
//}
//else
//{
// mUIBtns.Add(btnF);
// btnF.gameObject.SetActive(false);
//}
#if UNITY_STANDALONE_WIN || UNITY_EDITOR
//tfKeyPad.gameObject.SetActive(false);
#endif
} }
public void Init(Essgee.Emulation.Machines.IMachine Machine) public void Init(Essgee.Emulation.Machines.IMachine Machine)
{ {
mKeyCodeCore.Init(Machine, this, false); ControllerMapper = new EssgeeControllerMapper();
Init(Machine, false);
} }
public void UpdateInputKey() public EssgeeMotionKey[] GetPressedKeys()
{ {
mKeyCodeCore.UpdateLogic(); return mCurrKey;
}
public void SetRePlay(bool IsReplay)
{
//bReplayMode = IsReplay;
}
void Init(Essgee.Emulation.Machines.IMachine Machine, bool IsReplay)
{
dictKey2Motion.Clear();
if (Machine is Essgee.Emulation.Machines.MasterSystem)
{
var machine = (Essgee.Emulation.Machines.MasterSystem)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.Joypad1Up);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.Joypad1Down);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.Joypad1Left);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.Joypad1Right);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.Joypad1Button1);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.Joypad1Button2);
//dictKeyCfgs.Add(KeyCode.UpArrow, machine.configuration.Joypad2Up);
//dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
//dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
//dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
//dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button1);
//dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.Joypad1Button1);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P2_UP, machine.configuration.Joypad2Up);
dictKey2Motion.Add(EssgeeUnityKey.P2_DOWN, machine.configuration.Joypad2Down);
dictKey2Motion.Add(EssgeeUnityKey.P2_LEFT, machine.configuration.Joypad2Left);
dictKey2Motion.Add(EssgeeUnityKey.P2_RIGHT, machine.configuration.Joypad2Right);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_1, machine.configuration.Joypad2Button1);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_2, machine.configuration.Joypad2Button2);
}
else if (Machine is Essgee.Emulation.Machines.GameBoy)
{
var machine = (Essgee.Emulation.Machines.GameBoy)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.ControlsUp);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.ControlsDown);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.ControlsLeft);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.ControlsRight);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.ControlsB);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.ControlsA);
//dictKeyCfgs.Add(KeyCode.Return, machine.configuration.ControlsStart);
//dictKeyCfgs.Add(KeyCode.RightShift, machine.configuration.ControlsSelect);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.ControlsUp);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.ControlsDown);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.ControlsLeft);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.ControlsRight);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.ControlsB);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.ControlsA);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.ControlsStart);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_2, machine.configuration.ControlsSelect);
}
else if (Machine is Essgee.Emulation.Machines.GameBoyColor)
{
var machine = (Essgee.Emulation.Machines.GameBoyColor)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.ControlsUp);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.ControlsDown);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.ControlsLeft);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.ControlsRight);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.ControlsB);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.ControlsA);
//dictKeyCfgs.Add(KeyCode.Return, machine.configuration.ControlsStart);
//dictKeyCfgs.Add(KeyCode.RightShift, machine.configuration.ControlsSelect);
//dictKeyCfgs.Add(KeyCode.Space, machine.configuration.ControlsSendIR);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.ControlsUp);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.ControlsDown);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.ControlsLeft);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.ControlsRight);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.ControlsA);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.ControlsB);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_3, machine.configuration.ControlsSendIR);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.ControlsStart);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_2, machine.configuration.ControlsSelect);
}
else if (Machine is Essgee.Emulation.Machines.GameGear)
{
var machine = (Essgee.Emulation.Machines.GameGear)Machine;
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.ControlsUp);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.ControlsDown);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.ControlsLeft);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.ControlsRight);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.ControlsButton2);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.ControlsButton1);
//dictKeyCfgs.Add(KeyCode.Return, machine.configuration.ControlsStart);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.ControlsUp);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.ControlsDown);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.ControlsLeft);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.ControlsRight);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.ControlsButton2);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.ControlsButton1);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.ControlsStart);
}
else if (Machine is Essgee.Emulation.Machines.SC3000)
{
var machine = (Essgee.Emulation.Machines.SC3000)Machine;
/*
* InputReset = MotionKey.F12;
InputChangeMode = MotionKey.F1;
InputPlayTape = MotionKey.F2;
Joypad1Up = MotionKey.Up;
Joypad1Down = MotionKey.Down;
Joypad1Left = MotionKey.Left;
Joypad1Right = MotionKey.Right;
Joypad1Button1 = MotionKey.A;
Joypad1Button2 = MotionKey.S;
Joypad2Up = MotionKey.NumPad8;
Joypad2Down = MotionKey.NumPad2;
Joypad2Left = MotionKey.NumPad4;
Joypad2Right = MotionKey.NumPad6;
Joypad2Button1 = MotionKey.NumPad1;
Joypad2Button2 = MotionKey.NumPad3;
*/
//dictKeyCfgs.Add(KeyCode.F12, machine.configuration.InputReset);
//dictKeyCfgs.Add(KeyCode.F1, machine.configuration.InputChangeMode);
//dictKeyCfgs.Add(KeyCode.F2, machine.configuration.InputPlayTape);
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.Joypad1Up);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.Joypad1Down);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.Joypad1Left);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.Joypad1Right);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.Joypad1Button2);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.Joypad1Button1);
//dictKeyCfgs.Add(KeyCode.UpArrow, machine.configuration.Joypad2Up);
//dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
//dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
//dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
//dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button1);
//dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_1, machine.configuration.InputChangeMode);
dictKey2Motion.Add(EssgeeUnityKey.P1_POTION_2, machine.configuration.InputPlayTape);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.Joypad1Button1);
dictKey2Motion.Add(EssgeeUnityKey.P2_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P2_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P2_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P2_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_2, machine.configuration.Joypad1Button1);
}
else if (Machine is Essgee.Emulation.Machines.SG1000)
{
var machine = (Essgee.Emulation.Machines.SG1000)Machine;
/*
TVStandard = TVStandard.NTSC;
InputPause = MotionKey.Space;
Joypad1Up = MotionKey.Up;
Joypad1Down = MotionKey.Down;
Joypad1Left = MotionKey.Left;
Joypad1Right = MotionKey.Right;
Joypad1Button1 = MotionKey.A;
Joypad1Button2 = MotionKey.S;
Joypad2Up = MotionKey.NumPad8;
Joypad2Down = MotionKey.NumPad2;
Joypad2Left = MotionKey.NumPad4;
Joypad2Right = MotionKey.NumPad6;
Joypad2Button1 = MotionKey.NumPad1;
Joypad2Button2 = MotionKey.NumPad3;
*/
//dictKeyCfgs.Add(KeyCode.W, machine.configuration.Joypad1Up);
//dictKeyCfgs.Add(KeyCode.S, machine.configuration.Joypad1Down);
//dictKeyCfgs.Add(KeyCode.A, machine.configuration.Joypad1Left);
//dictKeyCfgs.Add(KeyCode.D, machine.configuration.Joypad1Right);
//dictKeyCfgs.Add(KeyCode.J, machine.configuration.Joypad1Button2);
//dictKeyCfgs.Add(KeyCode.K, machine.configuration.Joypad1Button1);
//dictKeyCfgs.Add(KeyCode.UpArrow, machine.configuration.Joypad2Up);
//dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
//dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
//dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
//dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button2);
//dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button1);
dictKey2Motion.Add(EssgeeUnityKey.P1_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P1_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P1_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P1_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P1_BTN_2, machine.configuration.Joypad1Button1);
dictKey2Motion.Add(EssgeeUnityKey.P2_UP, machine.configuration.Joypad1Up);
dictKey2Motion.Add(EssgeeUnityKey.P2_DOWN, machine.configuration.Joypad1Down);
dictKey2Motion.Add(EssgeeUnityKey.P2_LEFT, machine.configuration.Joypad1Left);
dictKey2Motion.Add(EssgeeUnityKey.P2_RIGHT, machine.configuration.Joypad1Right);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_1, machine.configuration.Joypad1Button2);
dictKey2Motion.Add(EssgeeUnityKey.P2_BTN_2, machine.configuration.Joypad1Button1);
}
CheckList = dictKey2Motion.Keys.ToArray();
//mUniKeyboard.btnP1.Key = new long[] { (long)MotionKey.P1_GAMESTART };
//mUniKeyboard.btnCoin1.Key = new long[] { (long)MotionKey.P1_INSERT_COIN };
//mUniKeyboard.btnA.Key = new long[] { (long)MotionKey.P1_BTN_1 };
//mUniKeyboard.btnB.Key = new long[] { (long)MotionKey.P1_BTN_2 };
//mUniKeyboard.btnC.Key = new long[] { (long)MotionKey.P1_BTN_3 };
//mUniKeyboard.btnD.Key = new long[] { (long)MotionKey.P1_BTN_4 };
////mUniKeyboard.btnE.Key = new long[] { (long)MotionKey.P1_BTN_5 };
////mUniKeyboard.btnF.Key = new long[] { (long)MotionKey.P1_BTN_6 };
//mUniKeyboard.btnAB.Key = new long[] { (long)MotionKey.P1_BTN_1, (long)MotionKey.P1_BTN_2 };
//mUniKeyboard.btnCD.Key = new long[] { (long)MotionKey.P1_BTN_3, (long)MotionKey.P1_BTN_4 };
//mUniKeyboard.btnABC.Key = new long[] { (long)MotionKey.P1_BTN_1, (long)MotionKey.P1_BTN_2, (long)MotionKey.P1_BTN_3 };
}
public bool SampleInput()
{
//Net模式
if (InGameUI.Instance.IsNetPlay)
{
bool bHadNetData = false;
int targetFrame; ReplayStep replayData; int frameDiff; bool inputDiff;
if (App.roomMgr.netReplay.TryGetNextFrame((int)Essgeeinit.instance.Frame, out replayData, out frameDiff, out inputDiff))
{
if (inputDiff)
{
App.log.Debug($"{DateTime.Now.ToString("hh:mm:ss.fff")} TryGetNextFrame remoteFrame->{App.roomMgr.netReplay.mRemoteFrameIdx} diff->{frameDiff} " +
$"frame=>{replayData.FrameStartID} InPut=>{replayData.InPut}");
}
CurrRemoteInpuAllData = replayData.InPut;
SetCurrKeyArr(CurrRemoteInpuAllData);
bHadNetData = true;
}
else//无输入
{
CurrRemoteInpuAllData = 0;
}
//发送本地操作
App.roomMgr.SendRoomSingelPlayerInput(Essgeeinit.instance.Frame,
DoLocalPressedKeys());
return bHadNetData;
}
//单机模式
else
{
ulong inputData = DoLocalPressedKeys();
SetCurrKeyArr(inputData);
return true;
}
}
void SetCurrKeyArr(ulong inputData)
{
temp.Clear();
for (int i = 0; i < CheckList.Length; i++)
{
ulong key = CheckList[i];
if ((inputData & key) > 0)
{
EssgeeMotionKey mk = dictKey2Motion[key];
temp.Add(mk);
}
}
mCurrKey = temp.ToArray();
}
ulong DoLocalPressedKeys()
{
//tempInputAllData = 0;
//for (int i = 0; i < CheckList.Length; i++)
//{
// ulong key = CheckList[i];
// if (Input.GetKey(dictMotion2RealKey[key]))
// {
// EssgeeMotionKey mk = dictKey2Motion[key];
// tempInputAllData |= (ulong)mk;
// }
//}
//return tempInputAllData;
ulong tempLocalInputAllData = 0;
tempLocalInputAllData |= ControllerMapper.Controller0.GetSingleAllInput();
tempLocalInputAllData |= ControllerMapper.Controller1.GetSingleAllInput();
tempLocalInputAllData |= ControllerMapper.Controller2.GetSingleAllInput();
tempLocalInputAllData |= ControllerMapper.Controller3.GetSingleAllInput();
#if UNITY_EDITOR
if (CurrLocalInpuAllData != tempLocalInputAllData)
{
string ShowKeyNames = string.Empty;
}
#endif
CurrLocalInpuAllData = tempLocalInputAllData;
CheckPlayerSlotChanged();
return CurrLocalInpuAllData;
}
void CheckPlayerSlotChanged()
{
if (!ControllerMapper.Controller0.ConnectSlot.HasValue && ControllerMapper.Controller0.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 0);
if (!ControllerMapper.Controller1.ConnectSlot.HasValue && ControllerMapper.Controller1.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 1);
if (!ControllerMapper.Controller2.ConnectSlot.HasValue && ControllerMapper.Controller2.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 2);
if (!ControllerMapper.Controller3.ConnectSlot.HasValue && ControllerMapper.Controller3.AnyButtonDown())
Eventer.Instance.PostEvent(EEvent.OnLocalJoyDesireInvert, 3);
}
}
public static class EssgeeUnityKey
{
public const ulong NONE = 0;
public const ulong P1_UP = 1;
public const ulong P1_DOWN = 1 << 1;
public const ulong P1_LEFT = 1 << 2;
public const ulong P1_RIGHT = 1 << 3;
public const ulong P1_BTN_1 = 1 << 4;
public const ulong P1_BTN_2 = 1 << 5;
public const ulong P1_BTN_3 = 1 << 6;
public const ulong P1_BTN_4 = 1 << 7;
public const ulong P1_POTION_1 = 1 << 8;
public const ulong P1_POTION_2 = 1 << 9;
public const ulong P2_UP = 65536;
public const ulong P2_DOWN = 65536 << 1;
public const ulong P2_LEFT = 65536 << 2;
public const ulong P2_RIGHT = 65536 << 3;
public const ulong P2_BTN_1 = 65536 << 4;
public const ulong P2_BTN_2 = 65536 << 5;
public const ulong P2_BTN_3 = 65536 << 6;
public const ulong P2_BTN_4 = 65536 << 7;
public const ulong P2_POTION_1 = 65536 << 8;
public const ulong P2_POTION_2 = 65536 << 9;
public const ulong P3_UP = 4294967296;
public const ulong P3_DOWN = 4294967296 << 1;
public const ulong P3_LEFT = 4294967296 << 2;
public const ulong P3_RIGHT = 4294967296 << 3;
public const ulong P3_BTN_1 = 4294967296 << 4;
public const ulong P3_BTN_2 = 4294967296 << 5;
public const ulong P3_BTN_3 = 4294967296 << 6;
public const ulong P3_BTN_4 = 654294967296536 << 7;
public const ulong P3_POTION_1 = 4294967296 << 8;
public const ulong P3_POTION_2 = 4294967296 << 9;
public const ulong P4_UP = 281474976710656;
public const ulong P4_DOWN = 281474976710656 << 1;
public const ulong P4_LEFT = 281474976710656 << 2;
public const ulong P4_RIGHT = 281474976710656 << 3;
public const ulong P4_BTN_1 = 281474976710656 << 4;
public const ulong P4_BTN_2 = 281474976710656 << 5;
public const ulong P4_BTN_3 = 281474976710656 << 6;
public const ulong P4_BTN_4 = 281474976710656 << 7;
public const ulong P4_POTION_1 = 281474976710656 << 8;
public const ulong P4_POTION_2 = 281474976710656 << 9;
public const ulong FinalKey = 281474976710656 << 10;
}
public class EssgeeControllerMapper : IControllerSetuper
{
public EssgssSingleController Controller0 = new EssgssSingleController(0);
public EssgssSingleController Controller1 = new EssgssSingleController(1);
public EssgssSingleController Controller2 = new EssgssSingleController(2);
public EssgssSingleController Controller3 = new EssgssSingleController(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)
{
EssgssSingleController 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);
}
}
public class EssgssSingleController : IController
{
public KeyCode UP, DOWN, LEFT, RIGHT, BTN_1, BTN_2, BTN_3, BTN_4, OPTION_1, OPTION_2;
public ulong tg_UP, tg_DOWN, tg_LEFT, tg_RIGHT, tg_BTN_1, tg_BTN_2, tg_BTN_3, tg_BTN_4, tg_OPTION_1, tg_OPTION_2;
public ulong CurrLocalSingleAllInput { get; private set; }
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 EssgssSingleController(int controllerIndex)
{
ControllerIndex = controllerIndex;
}
public bool AnyButtonDown()
{
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_1)) return true;
if (Input.GetKeyDown(BTN_2)) return true;
if (Input.GetKeyDown(BTN_3)) return true;
if (Input.GetKeyDown(BTN_4)) return true;
if (Input.GetKeyDown(OPTION_1)) return true;
if (Input.GetKeyDown(OPTION_2)) return true;
return false;
}
public ulong GetSingleAllInput()
{
if (!ConnectSlot.HasValue)
return 0;
CurrLocalSingleAllInput = 0;
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_1)) CurrLocalSingleAllInput |= (ulong)tg_BTN_1;
if (Input.GetKey(BTN_2)) CurrLocalSingleAllInput |= (ulong)tg_BTN_2;
if (Input.GetKey(BTN_3)) CurrLocalSingleAllInput |= (ulong)tg_BTN_3;
if (Input.GetKey(BTN_4)) CurrLocalSingleAllInput |= (ulong)tg_BTN_4;
if (Input.GetKey(OPTION_1)) CurrLocalSingleAllInput |= (ulong)tg_OPTION_1;
if (Input.GetKey(OPTION_2)) CurrLocalSingleAllInput |= (ulong)tg_OPTION_1;
return CurrLocalSingleAllInput;
}
}
public static class EssgssSingleControllerSetter
{
public static void LoadControlKeyForConfig(this EssgssSingleController singlecontrol)
{
//TODO 等待支持配置,或统一
switch (singlecontrol.ControllerIndex)
{
case 0:
singlecontrol.UP = KeyCode.W;
singlecontrol.DOWN = KeyCode.S;
singlecontrol.LEFT = KeyCode.A;
singlecontrol.RIGHT = KeyCode.D;
singlecontrol.BTN_1 = KeyCode.J;
singlecontrol.BTN_2 = KeyCode.K;
singlecontrol.BTN_3 = KeyCode.L;
singlecontrol.BTN_4 = KeyCode.U;
singlecontrol.OPTION_1 = KeyCode.Return;
singlecontrol.OPTION_2 = KeyCode.LeftShift;
break;
case 1:
singlecontrol.UP = KeyCode.UpArrow;
singlecontrol.DOWN = KeyCode.DownArrow;
singlecontrol.LEFT = KeyCode.LeftArrow;
singlecontrol.RIGHT = KeyCode.RightArrow;
singlecontrol.BTN_1 = KeyCode.Keypad1;
singlecontrol.BTN_2 = KeyCode.Keypad2;
singlecontrol.BTN_3 = KeyCode.Keypad3;
singlecontrol.BTN_4 = KeyCode.Keypad4;
singlecontrol.OPTION_1 = KeyCode.Keypad0;
singlecontrol.OPTION_2 = KeyCode.KeypadPeriod;
break;
case 2:
break;
case 3:
break;
}
}
public static void ResetTargetMotionKey(this EssgssSingleController singlecontrol)
{
if (!singlecontrol.ConnectSlot.HasValue)
{
singlecontrol.tg_UP
= singlecontrol.tg_DOWN
= singlecontrol.tg_LEFT
= singlecontrol.tg_RIGHT
= singlecontrol.tg_BTN_1
= singlecontrol.tg_BTN_2
= singlecontrol.tg_BTN_3
= singlecontrol.tg_BTN_4
= singlecontrol.tg_OPTION_1
= singlecontrol.tg_OPTION_2
= EssgeeUnityKey.FinalKey;
return;
}
switch (singlecontrol.ConnectSlot.Value)
{
case 0:
singlecontrol.tg_UP = EssgeeUnityKey.P1_UP;
singlecontrol.tg_DOWN = EssgeeUnityKey.P1_DOWN;
singlecontrol.tg_LEFT = EssgeeUnityKey.P1_LEFT;
singlecontrol.tg_RIGHT = EssgeeUnityKey.P1_RIGHT;
singlecontrol.tg_BTN_1 = EssgeeUnityKey.P1_BTN_1;
singlecontrol.tg_BTN_2 = EssgeeUnityKey.P1_BTN_2;
singlecontrol.tg_BTN_3 = EssgeeUnityKey.P1_BTN_3;
singlecontrol.tg_BTN_4 = EssgeeUnityKey.P1_BTN_4;
singlecontrol.tg_OPTION_1 = EssgeeUnityKey.P1_POTION_1;
singlecontrol.tg_OPTION_2 = EssgeeUnityKey.P1_POTION_2;
break;
case 1:
singlecontrol.tg_UP = EssgeeUnityKey.P2_UP;
singlecontrol.tg_DOWN = EssgeeUnityKey.P2_DOWN;
singlecontrol.tg_LEFT = EssgeeUnityKey.P2_LEFT;
singlecontrol.tg_RIGHT = EssgeeUnityKey.P2_RIGHT;
singlecontrol.tg_BTN_1 = EssgeeUnityKey.P2_BTN_1;
singlecontrol.tg_BTN_2 = EssgeeUnityKey.P2_BTN_2;
singlecontrol.tg_BTN_3 = EssgeeUnityKey.P2_BTN_3;
singlecontrol.tg_BTN_4 = EssgeeUnityKey.P2_BTN_4;
singlecontrol.tg_OPTION_1 = EssgeeUnityKey.P2_POTION_1;
singlecontrol.tg_OPTION_2 = EssgeeUnityKey.P2_POTION_2;
break;
//后续修改后 支持P3 P4
case 2:
singlecontrol.tg_UP = EssgeeUnityKey.P3_UP;
singlecontrol.tg_DOWN = EssgeeUnityKey.P3_DOWN;
singlecontrol.tg_LEFT = EssgeeUnityKey.P3_LEFT;
singlecontrol.tg_RIGHT = EssgeeUnityKey.P3_RIGHT;
singlecontrol.tg_BTN_1 = EssgeeUnityKey.P3_BTN_1;
singlecontrol.tg_BTN_2 = EssgeeUnityKey.P3_BTN_2;
singlecontrol.tg_BTN_3 = EssgeeUnityKey.P3_BTN_3;
singlecontrol.tg_BTN_4 = EssgeeUnityKey.P3_BTN_4;
singlecontrol.tg_OPTION_1 = EssgeeUnityKey.P3_POTION_1;
singlecontrol.tg_OPTION_2 = EssgeeUnityKey.P3_POTION_2;
break;
case 3:
singlecontrol.tg_UP = EssgeeUnityKey.P4_UP;
singlecontrol.tg_DOWN = EssgeeUnityKey.P4_DOWN;
singlecontrol.tg_LEFT = EssgeeUnityKey.P4_LEFT;
singlecontrol.tg_RIGHT = EssgeeUnityKey.P4_RIGHT;
singlecontrol.tg_BTN_1 = EssgeeUnityKey.P4_BTN_1;
singlecontrol.tg_BTN_2 = EssgeeUnityKey.P4_BTN_2;
singlecontrol.tg_BTN_3 = EssgeeUnityKey.P4_BTN_3;
singlecontrol.tg_BTN_4 = EssgeeUnityKey.P4_BTN_4;
singlecontrol.tg_OPTION_1 = EssgeeUnityKey.P4_POTION_1;
singlecontrol.tg_OPTION_2 = EssgeeUnityKey.P4_POTION_2;
break;
}
} }
} }

View File

@ -1,17 +1,19 @@
using AxibugEmuOnline.Client.ClientCore;
public class UEGLog : IEssgeeLogger public class UEGLog : IEssgeeLogger
{ {
public void Debug(string message) public void Debug(string message)
{ {
App.log.Debug(message);
UnityEngine.Debug.Log(message); UnityEngine.Debug.Log(message);
} }
public void Warning(string message) public void Warning(string message)
{ {
UnityEngine.Debug.LogWarning(message); App.log.Warning(message);
} }
public void Err(string message) public void Err(string message)
{ {
UnityEngine.Debug.LogError(message); App.log.Error(message);
} }
} }

View File

@ -18,6 +18,8 @@ public class UEGVideoPlayer : MonoBehaviour
private RectTransform m_drawCanvasrect; private RectTransform m_drawCanvasrect;
//byte[] mFrameData; //byte[] mFrameData;
IntPtr mFrameDataPtr; IntPtr mFrameDataPtr;
public Texture2D rawBufferWarper => m_rawBufferWarper;
public RawImage DrawCanvas => m_drawCanvas;
private TimeSpan lastElapsed; private TimeSpan lastElapsed;
public double videoFPS { get; private set; } public double videoFPS { get; private set; }

View File

@ -1,6 +1,5 @@
using AxibugEmuOnline.Client; using AxibugEmuOnline.Client;
using AxibugEmuOnline.Client.ClientCore; using AxibugEmuOnline.Client.ClientCore;
using AxibugEmuOnline.Client.Network;
using AxibugProtobuf; using AxibugProtobuf;
using AxiReplay; using AxiReplay;
using MAME.Core; using MAME.Core;

View File

@ -7,9 +7,6 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
using static AxibugEmuOnline.Client.NesControllerMapper;
using static UnityEditor.VersionControl.Asset;
using VirtualNes.Core;
public class UniKeyboard : MonoBehaviour, IKeyboard public class UniKeyboard : MonoBehaviour, IKeyboard
{ {