移除EssGee的Xinput依赖

This commit is contained in:
sin365 2025-03-07 18:23:18 +08:00
parent b13763ebee
commit 374d496d67
44 changed files with 737 additions and 713 deletions

View File

@ -19,5 +19,19 @@
samplesPerFrame = cyclesPerFrame = cyclesPerSample = -1;
}
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
base.LoadAxiStatus(data);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = base.SaveAxiStatus();
return data;
}
#endregion
}
}

View File

@ -133,15 +133,60 @@ namespace Essgee.Emulation.Audio
public void LoadAxiStatus(AxiEssgssStatusData data)
{
volumeRightLeft = data.MemberData[nameof(volumeRightLeft)];
vinEnableRightLeft = data.MemberData[nameof(vinEnableRightLeft)].ToBoolArray();
clockRate = BitConverter.ToDouble(data.MemberData[nameof(clockRate)]);
refreshRate = BitConverter.ToDouble(data.MemberData[nameof(refreshRate)]);
channel1Enable = data.MemberData[nameof(channel1Enable)].ToBoolArray();
channel2Enable = data.MemberData[nameof(channel2Enable)].ToBoolArray();
channel3Enable = data.MemberData[nameof(channel3Enable)].ToBoolArray();
channel4Enable = data.MemberData[nameof(channel4Enable)].ToBoolArray();
isSoundHwEnabled = BitConverter.ToBoolean(data.MemberData[nameof(isSoundHwEnabled)]);
samplesPerFrame = BitConverter.ToInt32(data.MemberData[nameof(samplesPerFrame)]);
cyclesPerFrame = BitConverter.ToInt32(data.MemberData[nameof(cyclesPerFrame)]);
cyclesPerSample = BitConverter.ToInt32(data.MemberData[nameof(cyclesPerSample)]);
sampleCycleCount = BitConverter.ToInt32(data.MemberData[nameof(sampleCycleCount)]);
frameCycleCount = BitConverter.ToInt32(data.MemberData[nameof(frameCycleCount)]);
channel1ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel1ForceEnable)]);
channel2ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel2ForceEnable)]);
channel3ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel3ForceEnable)]);
channel4ForceEnable = BitConverter.ToBoolean(data.MemberData[nameof(channel4ForceEnable)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(volumeRightLeft)] = volumeRightLeft;
data.MemberData[nameof(vinEnableRightLeft)] = vinEnableRightLeft.ToByteArray();
data.MemberData[nameof(clockRate)] = BitConverter.GetBytes(clockRate);
data.MemberData[nameof(refreshRate)] = BitConverter.GetBytes(refreshRate);
data.MemberData[nameof(channel1Enable)] = channel1Enable.ToByteArray();
data.MemberData[nameof(channel2Enable)] = channel2Enable.ToByteArray();
data.MemberData[nameof(channel3Enable)] = channel3Enable.ToByteArray();
data.MemberData[nameof(channel4Enable)] = channel4Enable.ToByteArray();
data.MemberData[nameof(isSoundHwEnabled)] = BitConverter.GetBytes(isSoundHwEnabled);
data.MemberData[nameof(samplesPerFrame)] = BitConverter.GetBytes(samplesPerFrame);
data.MemberData[nameof(cyclesPerFrame)] = BitConverter.GetBytes(cyclesPerFrame);
data.MemberData[nameof(cyclesPerSample)] = BitConverter.GetBytes(cyclesPerSample);
data.MemberData[nameof(sampleCycleCount)] = BitConverter.GetBytes(sampleCycleCount);
data.MemberData[nameof(frameCycleCount)] = BitConverter.GetBytes(frameCycleCount);
data.MemberData[nameof(channel1ForceEnable)] = BitConverter.GetBytes(channel1ForceEnable);
data.MemberData[nameof(channel2ForceEnable)] = BitConverter.GetBytes(channel2ForceEnable);
data.MemberData[nameof(channel3ForceEnable)] = BitConverter.GetBytes(channel3ForceEnable);
data.MemberData[nameof(channel4ForceEnable)] = BitConverter.GetBytes(channel4ForceEnable);
return data;
}
#endregion

View File

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

View File

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

View File

@ -1,4 +1,9 @@
namespace Essgee.Emulation.CPU
using Essgee.Emulation.Cartridges;
using Essgee.Emulation.Video;
using System;
using UnityEngine.UIElements;
namespace Essgee.Emulation.CPU
{
public class SM83CGB : SM83
{
@ -7,6 +12,21 @@
public SM83CGB(MemoryReadDelegate memoryRead, MemoryWriteDelegate memoryWrite) : base(memoryRead, memoryWrite) { }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
base.LoadAxiStatus(data);
IsDoubleSpeed = BitConverter.ToBoolean(data.MemberData[nameof(IsDoubleSpeed)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = base.SaveAxiStatus();
data.MemberData[nameof(IsDoubleSpeed)] = BitConverter.GetBytes(IsDoubleSpeed);
return data;
}
#endregion
protected override void EnterHaltState()
{
if (ime)

View File

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

View File

@ -70,12 +70,25 @@ namespace Essgee.Emulation.Cartridges.Nintendo
public void LoadAxiStatus(AxiEssgssStatusData data)
{
//TODO GB相机暂时不实现
ramData = data.MemberData[nameof(ramData)];
hasBattery = BitConverter.ToBoolean(data.MemberData[nameof(hasBattery)]);
romBank = data.MemberData[nameof(romBank)].First();
ramBank = data.MemberData[nameof(ramBank)].First();
ramEnable = BitConverter.ToBoolean(data.MemberData[nameof(ramEnable)]);
cameraCycles = BitConverter.ToInt32(data.MemberData[nameof(cameraCycles)]);
camClocksLeft = BitConverter.ToInt32(data.MemberData[nameof(camClocksLeft)]);
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
data.MemberData[nameof(ramData)] = ramData;
data.MemberData[nameof(hasBattery)] = BitConverter.GetBytes(hasBattery);
data.MemberData[nameof(romBank)] = BitConverter.GetBytes(romBank);
data.MemberData[nameof(ramBank)] = BitConverter.GetBytes(ramBank);
data.MemberData[nameof(ramEnable)] = BitConverter.GetBytes(ramEnable);
data.MemberData[nameof(cameraCycles)] = BitConverter.GetBytes(cameraCycles);
data.MemberData[nameof(camClocksLeft)] = BitConverter.GetBytes(camClocksLeft);
return data;
}
#endregion

View File

@ -1,7 +1,6 @@
using Essgee.Emulation.Cartridges.Nintendo;
using Essgee.Emulation.ExtDevices.Nintendo;
using Essgee.Utilities;
using Newtonsoft.Json;
using System;
namespace Essgee.Emulation.Configuration
@ -26,7 +25,7 @@ namespace Essgee.Emulation.Configuration
//todo Unity [FileBrowserControl("General", "Bootstrap Path", "Game Boy Bootstrap ROM (*.gb;*.bin;*.zip)|*.gb;*.bin;*.zip")]
public string BootstrapRom { get; set; }
//todo Unity [DropDownControl("General", "Serial Device", typeof(ISerialDevice))]
[JsonConverter(typeof(TypeNameJsonConverter), "Essgee.Emulation.ExtDevices.Nintendo")]
//[JsonConverter(typeof(TypeNameJsonConverter), "Essgee.Emulation.ExtDevices.Nintendo")]
public Type SerialDevice { get; set; }
//todo Unity [DropDownControl("GB Camera", "Camera Source", typeof(GBCameraCartridge.ImageSources))]

View File

@ -1,7 +1,6 @@
using Essgee.Emulation.Cartridges.Nintendo;
using Essgee.Emulation.ExtDevices.Nintendo;
using Essgee.Utilities;
using Newtonsoft.Json;
using System;
namespace Essgee.Emulation.Configuration
@ -15,7 +14,7 @@ namespace Essgee.Emulation.Configuration
//todo Unity [FileBrowserControl("General", "Bootstrap Path", "Game Boy Color Bootstrap ROM (*.gbc;*.bin;*.zip)|*.gbc;*.bin;*.zip")]
public string BootstrapRom { get; set; }
//todo Unity [DropDownControl("General", "Serial Device", typeof(ISerialDevice))]
[JsonConverter(typeof(TypeNameJsonConverter), "Essgee.Emulation.ExtDevices.Nintendo")]
//[JsonConverter(typeof(TypeNameJsonConverter), "Essgee.Emulation.ExtDevices.Nintendo")]
public Type SerialDevice { get; set; }
//todo Unity [DropDownControl("GB Camera", "Camera Source", typeof(GBCameraCartridge.ImageSources))]

View File

@ -402,15 +402,6 @@ namespace Essgee.Emulation.Machines
audio?.Shutdown();
}
public void SetState(Dictionary<string, object> state)
{
throw new NotImplementedException();
}
public Dictionary<string, object> GetState()
{
throw new NotImplementedException();
}
public Dictionary<string, object> GetDebugInformation()
{

View File

@ -162,18 +162,129 @@ namespace Essgee.Emulation.Machines
public GameBoyColor() { }
#region AxiState
public void LoadAxiStatus(AxiEssgssStatusData data)
{
//config 暂时不需要存什么?
//configuration. = data.MemberData[nameof(configuration.)].ToEnum<TVStandard>();
if (data.MemberData.ContainsKey(nameof(bootstrap)))
bootstrap = data.MemberData[nameof(bootstrap)];
cartridge.LoadAxiStatus(data.ClassData[nameof(cartridge)]);
wram = data.Array2DMemberData[nameof(wram)].Get2DArrayBytesData();
hram = data.MemberData[nameof(hram)];
ie = data.MemberData[nameof(ie)].First();
cpu.LoadAxiStatus(data.ClassData[nameof(cpu)]);
video.LoadAxiStatus(data.ClassData[nameof(video)]);
audio.LoadAxiStatus(data.ClassData[nameof(audio)]);
//看是否还需要补存储字段
joypadRegister = data.MemberData[nameof(joypadRegister)].First();
serialData = data.MemberData[nameof(serialData)].First();
serialUseInternalClock = BitConverter.ToBoolean(data.MemberData[nameof(serialUseInternalClock)]);
serialFastClockSpeed = BitConverter.ToBoolean(data.MemberData[nameof(serialFastClockSpeed)]);
serialTransferInProgress = BitConverter.ToBoolean(data.MemberData[nameof(serialTransferInProgress)]);
divider = data.MemberData[nameof(divider)].First();
timerCounter = data.MemberData[nameof(timerCounter)].First();
clockCycleCount = BitConverter.ToUInt16(data.MemberData[nameof(clockCycleCount)]);
timerModulo = data.MemberData[nameof(timerModulo)].First();
timerRunning = BitConverter.ToBoolean(data.MemberData[nameof(timerRunning)]);
timerInputClock = data.MemberData[nameof(timerInputClock)].First();
timerOverflow = BitConverter.ToBoolean(data.MemberData[nameof(timerOverflow)]);
timerLoading = BitConverter.ToBoolean(data.MemberData[nameof(timerLoading)]);
irqVBlank = BitConverter.ToBoolean(data.MemberData[nameof(irqVBlank)]);
irqLCDCStatus = BitConverter.ToBoolean(data.MemberData[nameof(irqLCDCStatus)]);
irqTimerOverflow = BitConverter.ToBoolean(data.MemberData[nameof(irqTimerOverflow)]);
irqSerialIO = BitConverter.ToBoolean(data.MemberData[nameof(irqSerialIO)]);
irqKeypad = BitConverter.ToBoolean(data.MemberData[nameof(irqKeypad)]);
speedIsDouble = BitConverter.ToBoolean(data.MemberData[nameof(speedIsDouble)]);
speedSwitchPending = BitConverter.ToBoolean(data.MemberData[nameof(speedSwitchPending)]);
bootstrapDisabled = BitConverter.ToBoolean(data.MemberData[nameof(bootstrapDisabled)]);
irSendingSignal = BitConverter.ToBoolean(data.MemberData[nameof(irSendingSignal)]);
irNotReceivingSignal = BitConverter.ToBoolean(data.MemberData[nameof(irNotReceivingSignal)]);
irReadEnableA = BitConverter.ToBoolean(data.MemberData[nameof(irReadEnableA)]);
irReadEnableB = BitConverter.ToBoolean(data.MemberData[nameof(irReadEnableB)]);
serialBitsCounter = BitConverter.ToInt32(data.MemberData[nameof(serialBitsCounter)]);
serialCycles = BitConverter.ToInt32(data.MemberData[nameof(serialCycles)]);
currentMasterClockCyclesInFrame = BitConverter.ToInt32(data.MemberData[nameof(currentMasterClockCyclesInFrame)]);
totalMasterClockCyclesInFrame = BitConverter.ToInt32(data.MemberData[nameof(totalMasterClockCyclesInFrame)]);
ReconfigureSystem();
}
public AxiEssgssStatusData SaveAxiStatus()
{
AxiEssgssStatusData data = new AxiEssgssStatusData();
//config 暂时不需要存什么?
//data.MemberData[nameof(configuration.TVStandard)] = configuration.TVStandard.ToByteArray();
if (bootstrap != null)
data.MemberData[nameof(bootstrap)] = bootstrap;
data.ClassData[nameof(cartridge)] = cartridge.SaveAxiStatus();
data.Array2DMemberData[nameof(wram)] = new AxiEssgssStatusData_2DArray(wram);
data.MemberData[nameof(hram)] = hram;
data.MemberData[nameof(ie)] = BitConverter.GetBytes(ie);
data.ClassData[nameof(cpu)] = cpu.SaveAxiStatus();
data.ClassData[nameof(video)] = video.SaveAxiStatus();
data.ClassData[nameof(audio)] = audio.SaveAxiStatus();
//看是否还需要补存储字段
data.MemberData[nameof(joypadRegister)] = BitConverter.GetBytes(joypadRegister);
data.MemberData[nameof(serialData)] = BitConverter.GetBytes(serialData);
data.MemberData[nameof(serialUseInternalClock)] = BitConverter.GetBytes(serialUseInternalClock);
data.MemberData[nameof(serialFastClockSpeed)] = BitConverter.GetBytes(serialFastClockSpeed);
data.MemberData[nameof(serialTransferInProgress)] = BitConverter.GetBytes(serialTransferInProgress);
data.MemberData[nameof(divider)] = BitConverter.GetBytes(divider);
data.MemberData[nameof(timerCounter)] = BitConverter.GetBytes(timerCounter);
data.MemberData[nameof(clockCycleCount)] = BitConverter.GetBytes(clockCycleCount);
data.MemberData[nameof(timerModulo)] = BitConverter.GetBytes(timerModulo);
data.MemberData[nameof(timerRunning)] = BitConverter.GetBytes(timerRunning);
data.MemberData[nameof(timerInputClock)] = BitConverter.GetBytes(timerInputClock);
data.MemberData[nameof(timerOverflow)] = BitConverter.GetBytes(timerOverflow);
data.MemberData[nameof(timerLoading)] = BitConverter.GetBytes(timerLoading);
data.MemberData[nameof(irqVBlank)] = BitConverter.GetBytes(irqVBlank);
data.MemberData[nameof(irqLCDCStatus)] = BitConverter.GetBytes(irqLCDCStatus);
data.MemberData[nameof(irqTimerOverflow)] = BitConverter.GetBytes(irqTimerOverflow);
data.MemberData[nameof(irqSerialIO)] = BitConverter.GetBytes(irqSerialIO);
data.MemberData[nameof(irqKeypad)] = BitConverter.GetBytes(irqKeypad);
data.MemberData[nameof(speedIsDouble)] = BitConverter.GetBytes(speedIsDouble);
data.MemberData[nameof(speedSwitchPending)] = BitConverter.GetBytes(speedSwitchPending);
data.MemberData[nameof(bootstrapDisabled)] = BitConverter.GetBytes(bootstrapDisabled);
data.MemberData[nameof(irSendingSignal)] = BitConverter.GetBytes(irSendingSignal);
data.MemberData[nameof(irNotReceivingSignal)] = BitConverter.GetBytes(irNotReceivingSignal);
data.MemberData[nameof(irReadEnableA)] = BitConverter.GetBytes(irReadEnableA);
data.MemberData[nameof(irReadEnableB)] = BitConverter.GetBytes(irReadEnableB);
//看是否需要记录这部分
//ushort[] irDatabase;
//int irDatabaseBaseIndex, irDatabaseStep;
//int irDatabaseCurrentIndex, irCycles;
//bool irExternalTransferActive;
data.MemberData[nameof(serialBitsCounter)] = BitConverter.GetBytes(serialBitsCounter);
data.MemberData[nameof(serialCycles)] = BitConverter.GetBytes(serialCycles);
data.MemberData[nameof(currentMasterClockCyclesInFrame)] = BitConverter.GetBytes(currentMasterClockCyclesInFrame);
data.MemberData[nameof(totalMasterClockCyclesInFrame)] = BitConverter.GetBytes(totalMasterClockCyclesInFrame);
return data;
}
#endregion
public void Initialize()
{
bootstrap = null;

View File

@ -5,7 +5,7 @@ using System.Collections.Generic;
namespace Essgee.Emulation.Machines
{
public interface IMachine : IAxiStatus
public interface IMachine : IAxiEssgssStatus
{
event EventHandler<SendLogMessageEventArgs> SendLogMessage;
event EventHandler<EventArgs> EmulationReset;

View File

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

View File

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

View File

@ -1,34 +1,33 @@
using Newtonsoft.Json;
using System.IO;
//using System.IO;
namespace Essgee.Extensions
{
public static class SerializationExtensionMethods
{
public static void SerializeToFile(this object obj, string jsonFileName)
{
SerializeToFile(obj, jsonFileName, new JsonSerializerSettings());
}
//namespace Essgee.Extensions
//{
// public static class SerializationExtensionMethods
// {
// public static void SerializeToFile(this object obj, string jsonFileName)
// {
// SerializeToFile(obj, jsonFileName, new JsonSerializerSettings());
// }
static void SerializeToFile(this object obj, string jsonFileName, JsonSerializerSettings serializerSettings)
{
using (var writer = new StreamWriter(jsonFileName))
{
writer.Write(JsonConvert.SerializeObject(obj, Formatting.Indented, serializerSettings));
}
}
// static void SerializeToFile(this object obj, string jsonFileName, JsonSerializerSettings serializerSettings)
// {
// using (var writer = new StreamWriter(jsonFileName))
// {
// writer.Write(JsonConvert.SerializeObject(obj, Formatting.Indented, serializerSettings));
// }
// }
public static T DeserializeFromFile<T>(this string jsonFileName)
{
using (var reader = new StreamReader(jsonFileName))
{
return (T)JsonConvert.DeserializeObject(reader.ReadToEnd(), typeof(T), new JsonSerializerSettings() { Formatting = Formatting.Indented });
}
}
// public static T DeserializeFromFile<T>(this string jsonFileName)
// {
// using (var reader = new StreamReader(jsonFileName))
// {
// return (T)JsonConvert.DeserializeObject(reader.ReadToEnd(), typeof(T), new JsonSerializerSettings() { Formatting = Formatting.Indented });
// }
// }
public static T DeserializeObject<T>(this string jsonString)
{
return (T)JsonConvert.DeserializeObject(jsonString, typeof(T), new JsonSerializerSettings() { Formatting = Formatting.Indented });
}
}
}
// public static T DeserializeObject<T>(this string jsonString)
// {
// return (T)JsonConvert.DeserializeObject(jsonString, typeof(T), new JsonSerializerSettings() { Formatting = Formatting.Indented });
// }
// }
//}

View File

@ -43,7 +43,7 @@ internal static class AxiEssgssStatusDataExtention
return AxiStatus.saveCover.ToAxiEssgssStatusData(byteArray);
}
}
public interface IAxiStatus
public interface IAxiEssgssStatus
{
public void LoadAxiStatus(AxiEssgssStatusData data);
public AxiEssgssStatusData SaveAxiStatus();
@ -222,4 +222,50 @@ internal static class AxiStatus
return array2D;
}
public static byte[] FlattenByteArray3D(this byte[,,] array3D)
{
int layer = array3D.GetLength(0);
int rows = array3D.GetLength(1);
int cols = array3D.GetLength(2);
byte[] array1D = new byte[layer * rows * cols];
int index = 0;
for (int i = 0; i < layer; i++)
{
for (int j = 0; j < rows; j++)
{
for (int k = 0; k < cols; k++)
{
array1D[index++] = array3D[i, j, k];
}
}
}
return array1D;
}
public static byte[,,] CreateByteArray3D(this byte[] array1D, int layer, int rows, int cols)
{
if (array1D.Length != layer * rows * cols)
{
throw new ArgumentException("The length of the 1D array does not match the specified dimensions for the 3D array.");
}
byte[,,] array3D = new byte[layer, rows, cols];
int index = 0;
for (int i = 0; i < layer; i++)
{
for (int j = 0; j < rows; j++)
{
for (int k = 0; k < cols; k++)
{
array3D[i, j, k] = array1D[index++];
}
}
}
return array3D;
}
}

View File

@ -1,11 +1,7 @@
using Essgee.Emulation;
using Essgee.Exceptions;
using Essgee.Utilities;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Xml.Serialization;
@ -37,11 +33,305 @@ namespace Essgee.Metadata
{
gameMetaReources = metaresources;
if (!gameMetaReources.GetCartMetadataDatabase(out string loadedData))
throw new HandlerException("CartMetadataDatabase file not found");
cartMetadataDatabase = JsonConvert.DeserializeObject<List<CartridgeJSON>>(loadedData);
//if (!gameMetaReources.GetCartMetadataDatabase(out string loadedData))
// throw new HandlerException("CartMetadataDatabase file not found");
//cartMetadataDatabase = JsonConvert.DeserializeObject<List<CartridgeJSON>>(loadedData);
cartMetadataDatabase = new List<CartridgeJSON>()
{
new CartridgeJSON(){
Name = "The Castle (SG-1000)",
Notes = "8k volatile RAM",
Crc32 = 0x092F29D6,
RomSize = 32768,
RamSize = 8192
},
new CartridgeJSON(){
Name = "Othello (SG-1000)",
Notes = "2k volatile RAM",
Crc32 = 0xAF4F14BC,
RomSize = 32768,
RamSize = 2048
},
new CartridgeJSON(){
Name = "Sega Basic Level II (SC-3000)",
Notes = "2k volatile RAM (for Level IIb)",
Crc32 = 0xF691F9C7,
RomSize = 32768,
RamSize = 2048
},
new CartridgeJSON(){
Name = "Sega Basic Level III (SC-3000)",
Notes = "32k volatile RAM (for Level IIIb)",
Crc32 = 0x5D9F11CA,
RomSize = 32768,
RamSize = 32768
},
new CartridgeJSON(){
Name = "Back to the Future 2 (SMS)",
Notes = "PAL only",
Crc32 = 0xE5FF50D8,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Back to the Future 3 (SMS)",
Notes = "PAL only",
Crc32 = 0x2D48C1D3,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "California Games 2 (SMS, Europe)",
Notes = "PAL only",
Crc32 = 0xC0E25D62,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Chase HQ (SMS)",
Notes = "PAL only",
Crc32 = 0x85CFC9C9,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Cosmic Spacehead (SMS)",
Notes = "Codemasters mapper & PAL only",
Crc32 = 0x29822980,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Dinobasher (SMS)",
Notes = "Codemasters mapper",
Crc32 = 0xEA5C3A6F,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Excellent Dizzy Collection (SMS)",
Notes = "Codemasters mapper & PAL only",
Crc32 = 0x8813514B,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Fantastic Dizzy (SMS)",
Notes = "Codemasters mapper & PAL only",
Crc32 = 0xB9664AE1,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Home Alone (SMS)",
Notes = "PAL only",
Crc32 = 0xC9DBF936,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Micro Machines (SMS)",
Notes = "Codemasters mapper & PAL only",
Crc32 = 0xA577CE46,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "NewZealand Story (SMS)",
Notes = "PAL only",
Crc32 = 0xC660FF34,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Power Strike 2 (SMS)",
Notes = "PAL only",
Crc32 = 0xA109A6FE,
RomSize = 524288,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Predator 2 (SMS, Europe)",
Notes = "PAL only",
Crc32 = 0x0047B615,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Sonic the Hedgehog 2 (SMS)",
Notes = "PAL only",
Crc32 = 0x5B3B922C,
RomSize = 524288,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Sonic the Hedgehog 2 (SMS, Revision 1)",
Notes = "PAL only",
Crc32 = 0xD6F2BFCA,
RomSize = 524288,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Space Harrier (SMS, Europe)",
Notes = "PAL only",
Crc32 = 0xCA1D3752,
RomSize = 262144,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "CJ Elephant Fugitive (GG)",
Notes = "Codemasters mapper",
Crc32 = 0x72981057,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Cosmic Spacehead (GG)",
Notes = "Codemasters mapper",
Crc32 = 0x6CAA625B,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Dropzone (GG)",
Notes = "Codemasters mapper",
Crc32 = 0x152F0DCC,
RomSize = 131072,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Ernie Els Golf (GG)",
Notes = "Codemasters mapper & 8k volatile RAM",
Crc32 = 0x5E53C7F7,
RomSize = 262144,
RamSize = 8192,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Micro Machines (GG)",
Notes = "Codemasters mapper",
Crc32 = 0xF7C524F6,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Micro Machines 2: Turbo Tournament (GG)",
Notes = "Codemasters mapper",
Crc32 = 0xDBE8895C,
RomSize = 524288,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Pete Sampras Tennis (GG)",
Notes = "Codemasters mapper",
Crc32 = 0xC1756BEE,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Pop Breaker (GG, Japan)",
Notes = "Domestic/Japan only",
Crc32 = 0x71DEBA5A,
RomSize = 131072,
PreferredRegion = Region.Domestic
},
new CartridgeJSON(){
Name = "S.S. Lucifer: Man Overboard (GG)",
Notes = "Codemasters mapper",
Crc32 = 0xD9A7F170,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.CodemastersCartridge),
},
new CartridgeJSON(){
Name = "Sonic Chaos (SMS, Jun 30 1993 Prototype)",
Notes = "Disallow memory control",
Crc32 = 0xD3AD67FA,
RomSize = 524288,
AllowMemoryControl = false
},
new CartridgeJSON(){
Name = "94 Super World Cup Soccer (SMS)",
Notes = "Korean mapper",
Crc32 = 0x060D6A7C,
RomSize = 262144,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMapperCartridge),
},
new CartridgeJSON(){
Name = "Jang Pung II (SMS)",
Notes = "Korean mapper",
Crc32 = 0x929222C4,
RomSize = 524288,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMapperCartridge),
},
new CartridgeJSON(){
Name = "Jang Pung 3 (SMS)",
Notes = "Korean mapper",
Crc32 = 0x18FB98A3,
RomSize = 1048576,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMapperCartridge),
},
new CartridgeJSON(){
Name = "Janggun-ui Adeul (SMS)",
Notes = "Korean sprite-flip mapper",
Crc32 = 0x192949D5,
RomSize = 524288,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanSpriteMapperCartridge),
},
new CartridgeJSON(){
Name = "Sangokushi 3 (SMS)",
Notes = "Korean mapper",
Crc32 = 0x97D03541,
RomSize = 1048576,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMapperCartridge),
},
new CartridgeJSON(){
Name = "4 Pak All Action (SMS)",
Notes = "4 Pak mapper",
Crc32 = 0xA67F2A5C,
RomSize = 1048576,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.Multicart4PakAllActionCartridge),
},
new CartridgeJSON(){
Name = "Cyborg Z (SMS)",
Notes = "Korean MSX 8k mapper",
Crc32 = 0x77EFE84A,
RomSize = 131072,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMSX8kMapperCartridge),
},
new CartridgeJSON(){
Name = "Street Master (SMS)",
Notes = "Korean MSX 8k mapper",
Crc32 = 0x83F0EEDE,
RomSize = 131072,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMSX8kMapperCartridge),
},
new CartridgeJSON(){
Name = "Wonsiin (SMS)",
Notes = "Korean MSX 8k mapper",
Crc32 = 0xA05258F5,
RomSize = 131072,
Mapper = typeof(Essgee.Emulation.Cartridges.Sega.KoreanMSX8kMapperCartridge),
},
new CartridgeJSON(){
Name = "SMS Bad Apple 1.00 (SMS)",
Notes = "PAL only",
Crc32 = 0x38434560,
RomSize = 4194304,
PreferredTVStandard = TVStandard.PAL
},
new CartridgeJSON(){
Name = "Be No Sqr 1.01 (SMS)",
Notes = "PAL only",
Crc32 = 0xEE701BE6,
RomSize = 524288,
PreferredTVStandard = TVStandard.PAL
}
};
//改为接口直接读取
//XmlRootAttribute root;
@ -126,34 +416,34 @@ namespace Essgee.Metadata
public class CartridgeJSON
{
[JsonProperty(Required = Required.Always)]
//[JsonProperty(Required = Required.Always)]
public string Name { get; set; } = string.Empty;
[JsonProperty(Required = Required.Always)]
//[JsonProperty(Required = Required.Always)]
public string Notes { get; set; } = string.Empty;
[JsonProperty(Required = Required.Always), JsonConverter(typeof(HexadecimalJsonConverter))]
//[JsonProperty(Required = Required.Always), JsonConverter(typeof(HexadecimalJsonConverter))]
public uint Crc32 { get; set; } = 0xFFFFFFFF;
[JsonProperty(Required = Required.Always)]
//[JsonProperty(Required = Required.Always)]
public int RomSize { get; set; } = 0;
[JsonProperty(Required = Required.Default), DefaultValue(0)]
//[JsonProperty(Required = Required.Default), DefaultValue(0)]
public int RamSize { get; set; } = 0;
[JsonProperty(Required = Required.Default), JsonConverter(typeof(TypeNameJsonConverter), "Essgee.Emulation.Cartridges"), DefaultValue(null)]
//[JsonProperty(Required = Required.Default), JsonConverter(typeof(TypeNameJsonConverter), "Essgee.Emulation.Cartridges"), DefaultValue(null)]
public Type Mapper { get; set; } = null;
[JsonProperty(Required = Required.Default), DefaultValue(false)]
//[JsonProperty(Required = Required.Default), DefaultValue(false)]
public bool HasNonVolatileRam { get; set; } = false;
[JsonProperty(Required = Required.Default), JsonConverter(typeof(StringEnumConverter)), DefaultValue(TVStandard.Auto)]
//[JsonProperty(Required = Required.Default), JsonConverter(typeof(StringEnumConverter)), DefaultValue(TVStandard.Auto)]
public TVStandard PreferredTVStandard { get; set; } = TVStandard.Auto;
[JsonProperty(Required = Required.Default), JsonConverter(typeof(StringEnumConverter)), DefaultValue(Region.Auto)]
//[JsonProperty(Required = Required.Default), JsonConverter(typeof(StringEnumConverter)), DefaultValue(Region.Auto)]
public Region PreferredRegion { get; set; } = Region.Auto;
[JsonProperty(Required = Required.Default), DefaultValue(true)]
//[JsonProperty(Required = Required.Default), DefaultValue(true)]
public bool AllowMemoryControl { get; set; } = true;
}

View File

@ -1,47 +1,47 @@
using Newtonsoft.Json;
using System;
//using Newtonsoft.Json;
//using System;
namespace Essgee.Utilities
{
public class HexadecimalJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
// TODO: maybe actually check things?
return true;
}
//namespace Essgee.Utilities
//{
// public class HexadecimalJsonConverter : JsonConverter
// {
// public override bool CanConvert(Type objectType)
// {
// // TODO: maybe actually check things?
// return true;
// }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
switch (Type.GetTypeCode(value.GetType()))
{
case TypeCode.Byte:
case TypeCode.SByte:
writer.WriteValue($"0x{value:X2}");
break;
case TypeCode.UInt16:
case TypeCode.Int16:
writer.WriteValue($"0x{value:X4}");
break;
case TypeCode.UInt32:
case TypeCode.Int32:
writer.WriteValue($"0x{value:X8}");
break;
case TypeCode.UInt64:
case TypeCode.Int64:
writer.WriteValue($"0x{value:X16}");
break;
default:
throw new JsonSerializationException();
}
}
// public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
// {
// switch (Type.GetTypeCode(value.GetType()))
// {
// case TypeCode.Byte:
// case TypeCode.SByte:
// writer.WriteValue($"0x{value:X2}");
// break;
// case TypeCode.UInt16:
// case TypeCode.Int16:
// writer.WriteValue($"0x{value:X4}");
// break;
// case TypeCode.UInt32:
// case TypeCode.Int32:
// writer.WriteValue($"0x{value:X8}");
// break;
// case TypeCode.UInt64:
// case TypeCode.Int64:
// writer.WriteValue($"0x{value:X16}");
// break;
// default:
// throw new JsonSerializationException();
// }
// }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if ((reader.Value is string value) && value.StartsWith("0x"))
return Convert.ChangeType(Convert.ToUInt64(value, 16), objectType);
else
throw new JsonSerializationException();
}
}
}
// public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
// {
// if ((reader.Value is string value) && value.StartsWith("0x"))
// return Convert.ChangeType(Convert.ToUInt64(value, 16), objectType);
// else
// throw new JsonSerializationException();
// }
// }
//}

View File

@ -1,44 +1,42 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Reflection;
namespace Essgee.Utilities
{
public class InterfaceDictionaryConverter<TInterface> : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(TInterface));
}
//namespace Essgee.Utilities
//{
// public class InterfaceDictionaryConverter<TInterface> : JsonConverter
// {
// public override bool CanConvert(Type objectType)
// {
// return (objectType == typeof(TInterface));
// }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (!objectType.IsGenericType || objectType.GetGenericTypeDefinition() != typeof(Dictionary<,>)) throw new InvalidOperationException("Can only deserialize dictionaries");
// public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
// {
// if (!objectType.IsGenericType || objectType.GetGenericTypeDefinition() != typeof(Dictionary<,>)) throw new InvalidOperationException("Can only deserialize dictionaries");
var dictionary = (System.Collections.IDictionary)Activator.CreateInstance(objectType);
//不再读取配置
var jObject = JObject.Load(reader);
foreach (var child in jObject.Children())
{
Type type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(y => typeof(TInterface).IsAssignableFrom(y) && !y.IsInterface && !y.IsAbstract && y.Name == child.Path);
if (type != null)
dictionary.Add(child.Path, JsonConvert.DeserializeObject(child.First.ToString(), type));
}
// var dictionary = (System.Collections.IDictionary)Activator.CreateInstance(objectType);
// //不再读取配置
// var jObject = JObject.Load(reader);
// foreach (var child in jObject.Children())
// {
// Type type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(y => typeof(TInterface).IsAssignableFrom(y) && !y.IsInterface && !y.IsAbstract && y.Name == child.Path);
// if (type != null)
// dictionary.Add(child.Path, JsonConvert.DeserializeObject(child.First.ToString(), type));
// }
return dictionary;
}
// return dictionary;
// }
public override bool CanWrite
{
get { return false; }
}
// public override bool CanWrite
// {
// get { return false; }
// }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
}
// public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
// {
// throw new NotImplementedException();
// }
// }
//}

View File

@ -1,40 +1,40 @@
using Newtonsoft.Json;
using System;
//using Newtonsoft.Json;
//using System;
namespace Essgee.Utilities
{
public class TypeNameJsonConverter : JsonConverter
{
readonly string searchNamespace;
//namespace Essgee.Utilities
//{
// public class TypeNameJsonConverter : JsonConverter
// {
// readonly string searchNamespace;
public TypeNameJsonConverter(string searchNamespace)
{
this.searchNamespace = searchNamespace;
}
// public TypeNameJsonConverter(string searchNamespace)
// {
// this.searchNamespace = searchNamespace;
// }
public override bool CanConvert(Type objectType)
{
// TODO: maybe actually check things?
return true;
}
// public override bool CanConvert(Type objectType)
// {
// // TODO: maybe actually check things?
// return true;
// }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value is Type)
{
var type = (value as Type);
if (type.Namespace != searchNamespace) throw new JsonSerializationException();
writer.WriteValue(type.Name);
}
else
throw new JsonSerializationException();
}
// public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
// {
// if (value is Type)
// {
// var type = (value as Type);
// if (type.Namespace != searchNamespace) throw new JsonSerializationException();
// writer.WriteValue(type.Name);
// }
// else
// throw new JsonSerializationException();
// }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var type = Type.GetType($"{searchNamespace}.{reader.Value}");
if (type != null) return type;
else throw new JsonSerializationException();
}
}
}
// public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
// {
// var type = Type.GetType($"{searchNamespace}.{reader.Value}");
// if (type != null) return type;
// else throw new JsonSerializationException();
// }
// }
//}

View File

@ -1,8 +0,0 @@
fileFormatVersion: 2
guid: 37b3e1d7093e0f545807ab54c1209c8b
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@ -1,178 +0,0 @@
using System;
namespace Essgee.Utilities.XInput
{
public class Controller
{
XInputState inputStatesCurrent, inputStatesPrev;
bool timedVibrationEnabled;
DateTime vibrationStopTime;
public bool IsConnected { get; private set; }
public int UserIndex { get; private set; }
public Controller(int index)
{
inputStatesCurrent = inputStatesPrev = new XInputState();
timedVibrationEnabled = false;
vibrationStopTime = DateTime.Now;
IsConnected = false;
UserIndex = index;
}
public void Update()
{
XInputState newInputState = new XInputState();
Errors result = (Errors)NativeMethods.GetState(UserIndex, ref newInputState);
if (result == Errors.Success)
{
IsConnected = true;
inputStatesPrev = inputStatesCurrent;
inputStatesCurrent = newInputState;
if ((inputStatesCurrent.Gamepad.sThumbLX < XInputGamepad.LeftThumbDeadzone && inputStatesCurrent.Gamepad.sThumbLX > -XInputGamepad.LeftThumbDeadzone) &&
(inputStatesCurrent.Gamepad.sThumbLY < XInputGamepad.LeftThumbDeadzone && inputStatesCurrent.Gamepad.sThumbLY > -XInputGamepad.LeftThumbDeadzone))
{
inputStatesCurrent.Gamepad.sThumbLX = inputStatesCurrent.Gamepad.sThumbLY = 0;
}
if ((inputStatesCurrent.Gamepad.sThumbRX < XInputGamepad.RightThumbDeadzone && inputStatesCurrent.Gamepad.sThumbRX > -XInputGamepad.RightThumbDeadzone) &&
(inputStatesCurrent.Gamepad.sThumbRY < XInputGamepad.RightThumbDeadzone && inputStatesCurrent.Gamepad.sThumbRY > -XInputGamepad.RightThumbDeadzone))
{
inputStatesCurrent.Gamepad.sThumbRX = inputStatesCurrent.Gamepad.sThumbRY = 0;
}
if (inputStatesCurrent.Gamepad.bLeftTrigger < XInputGamepad.TriggerThreshold) inputStatesCurrent.Gamepad.bLeftTrigger = 0;
if (inputStatesCurrent.Gamepad.bRightTrigger < XInputGamepad.TriggerThreshold) inputStatesCurrent.Gamepad.bRightTrigger = 0;
if (timedVibrationEnabled && DateTime.Now >= vibrationStopTime)
{
timedVibrationEnabled = false;
Vibrate(0.0f, 0.0f);
}
}
else if (result == Errors.DeviceNotConnected)
{
IsConnected = false;
}
else
throw new Exception(string.Format("Error code {0}", (int)result));
}
//public ControllerState GetControllerState()
//{
// return new ControllerState
// {
// Buttons = inputStatesCurrent.Gamepad.Buttons,
// LeftThumbstick = new ThumbstickPosition(inputStatesCurrent.Gamepad.sThumbLX / 32768.0f, inputStatesCurrent.Gamepad.sThumbLY / 32768.0f),
// RightThumbstick = new ThumbstickPosition(inputStatesCurrent.Gamepad.sThumbRX / 32768.0f, inputStatesCurrent.Gamepad.sThumbRY / 32768.0f),
// LeftTrigger = (inputStatesCurrent.Gamepad.bLeftTrigger / 255.0f),
// RightTrigger = (inputStatesCurrent.Gamepad.bRightTrigger / 255.0f)
// };
//}
public bool IsDPadUpPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.DPadUp);
}
public bool IsDPadDownPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.DPadDown);
}
public bool IsDPadLeftPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.DPadLeft);
}
public bool IsDPadRightPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.DPadRight);
}
public bool IsStartPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.Start);
}
public bool IsBackPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.Back);
}
public bool IsLeftThumbPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.LeftThumb);
}
public bool IsRightThumbPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.RightThumb);
}
public bool IsLeftShoulderPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.LeftShoulder);
}
public bool IsRightShoulderPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.RightShoulder);
}
public bool IsAPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.A);
}
public bool IsBPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.B);
}
public bool IsXPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.X);
}
public bool IsYPressed()
{
return inputStatesCurrent.Gamepad.Buttons.HasFlag(Buttons.Y);
}
public void Vibrate(float leftMotor, float rightMotor)
{
XInputVibration vibrationState = new XInputVibration();
vibrationState.wLeftMotorSpeed = (ushort)(leftMotor * 65535.0f);
vibrationState.wRightMotorSpeed = (ushort)(rightMotor * 65535.0f);
NativeMethods.SetState(UserIndex, ref vibrationState);
}
public void Vibrate(float leftMotor, float rightMotor, TimeSpan duration)
{
Vibrate(leftMotor, rightMotor);
vibrationStopTime = DateTime.Now.Add(duration);
timedVibrationEnabled = true;
}
}
public class ThumbstickPosition
{
public float X { get; private set; }
public float Y { get; private set; }
public ThumbstickPosition(float x, float y)
{
X = x;
Y = y;
}
public override string ToString()
{
return string.Format(System.Globalization.CultureInfo.InvariantCulture, "({0}, {1})", X, Y);
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 208c78465e149914e92390762f768a04

View File

@ -1,30 +0,0 @@
using System;
namespace Essgee.Utilities.XInput
{
public static class ControllerManager
{
const int maxControllers = 4;
static Controller[] controllers;
static ControllerManager()
{
controllers = new Controller[maxControllers];
for (int i = 0; i < controllers.Length; i++)
controllers[i] = new Controller(i);
}
public static Controller GetController(int index)
{
if (index < 0 || index >= maxControllers) throw new Exception("Controller index out of range");
return controllers[index];
}
public static void Update()
{
for (int i = 0; i < controllers.Length; i++)
controllers[i].Update();
}
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: d3b109e035af2d0488fee85624c9a90b

View File

@ -1,116 +0,0 @@
//namespace Essgee.Utilities.XInput
//{
// public class ControllerState
// {
// public Buttons Buttons { get; set; }
// public ThumbstickPosition LeftThumbstick { get; set; }
// public ThumbstickPosition RightThumbstick { get; set; }
// public float LeftTrigger { get; set; }
// public float RightTrigger { get; set; }
// public bool IsConnected { get; set; }
// public int UserIndex { get; set; }
// public ControllerState()
// {
// Buttons = Buttons.None;
// LeftThumbstick = new ThumbstickPosition(0.0f, 0.0f);
// RightThumbstick = new ThumbstickPosition(0.0f, 0.0f);
// LeftTrigger = 0.0f;
// RightTrigger = 0.0f;
// IsConnected = false;
// UserIndex = -1;
// }
// public bool IsAnyUpDirectionPressed()
// {
// return IsDPadUpPressed() || LeftThumbstick.Y > 0.5f;
// }
// public bool IsAnyDownDirectionPressed()
// {
// return IsDPadDownPressed() || LeftThumbstick.Y < -0.5f;
// }
// public bool IsAnyLeftDirectionPressed()
// {
// return IsDPadLeftPressed() || LeftThumbstick.X < -0.5f;
// }
// public bool IsAnyRightDirectionPressed()
// {
// return IsDPadRightPressed() || LeftThumbstick.X > 0.5f;
// }
// public bool IsDPadUpPressed()
// {
// return Buttons.HasFlag(Buttons.DPadUp);
// }
// public bool IsDPadDownPressed()
// {
// return Buttons.HasFlag(Buttons.DPadDown);
// }
// public bool IsDPadLeftPressed()
// {
// return Buttons.HasFlag(Buttons.DPadLeft);
// }
// public bool IsDPadRightPressed()
// {
// return Buttons.HasFlag(Buttons.DPadRight);
// }
// public bool IsStartPressed()
// {
// return Buttons.HasFlag(Buttons.Start);
// }
// public bool IsBackPressed()
// {
// return Buttons.HasFlag(Buttons.Back);
// }
// public bool IsLeftThumbPressed()
// {
// return Buttons.HasFlag(Buttons.LeftThumb);
// }
// public bool IsRightThumbPressed()
// {
// return Buttons.HasFlag(Buttons.RightThumb);
// }
// public bool IsLeftShoulderPressed()
// {
// return Buttons.HasFlag(Buttons.LeftShoulder);
// }
// public bool IsRightShoulderPressed()
// {
// return Buttons.HasFlag(Buttons.RightShoulder);
// }
// public bool IsAPressed()
// {
// return Buttons.HasFlag(Buttons.A);
// }
// public bool IsBPressed()
// {
// return Buttons.HasFlag(Buttons.B);
// }
// public bool IsXPressed()
// {
// return Buttons.HasFlag(Buttons.X);
// }
// public bool IsYPressed()
// {
// return Buttons.HasFlag(Buttons.Y);
// }
// }
//}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 62cf2ece5ee5c44458ac5646bb2f8af8

View File

@ -1,25 +0,0 @@
using System.Runtime.InteropServices;
namespace Essgee.Utilities.XInput
{
static class NativeMethods
{
const string dllName = "xinput9_1_0.dll";
public const int FlagGamepad = 0x00000001;
[DllImport(dllName, EntryPoint = "XInputGetState")]
public static extern int GetState(int dwUserIndex, ref XInputState pState);
[DllImport(dllName, EntryPoint = "XInputSetState")]
public static extern int SetState(int dwUserIndex, ref XInputVibration pVibration);
[DllImport(dllName, EntryPoint = "XInputGetCapabilities")]
public static extern int GetCapabilities(int dwUserIndex, int dwFlags, ref XInputCapabilities pCapabilities);
}
public enum Errors
{
Success = 0x00000000,
BadArguments = 0x000000A0,
DeviceNotConnected = 0x0000048F
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 2f4639905082c50448ca8a1477b55057

View File

@ -1,47 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace Essgee.Utilities.XInput
{
/* https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_capabilities%28v=vs.85%29.aspx */
[StructLayout(LayoutKind.Explicit)]
public struct XInputCapabilities
{
[FieldOffset(0)]
byte type;
[FieldOffset(1)]
byte subType;
[FieldOffset(2)]
ushort flags;
[FieldOffset(4)]
public XInputGamepad Gamepad;
[FieldOffset(16)]
public XInputVibration Vibration;
public DeviceType Type { get { return (DeviceType)type; } }
public DeviceSubType SubType { get { return (DeviceSubType)subType; } }
public DeviceFlags Flags { get { return (DeviceFlags)flags; } }
}
public enum DeviceType
{
Gamepad = 0x01
}
public enum DeviceSubType
{
Gamepad = 0x01,
Wheel = 0x02,
ArcadeStick = 0x03,
FlightStick = 0x04,
DancePad = 0x05,
Guitar = 0x06,
DrumKit = 0x08
}
[Flags]
public enum DeviceFlags
{
VoiceSupported = 0x0004
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 400677b412126194caf14f5d627b34a2

View File

@ -1,51 +0,0 @@
using System;
using System.Runtime.InteropServices;
namespace Essgee.Utilities.XInput
{
/* https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_gamepad%28v=vs.85%29.aspx */
[StructLayout(LayoutKind.Explicit)]
public struct XInputGamepad
{
[FieldOffset(0)]
ushort wButtons;
[FieldOffset(2)]
public byte bLeftTrigger;
[FieldOffset(3)]
public byte bRightTrigger;
[FieldOffset(4)]
public short sThumbLX;
[FieldOffset(6)]
public short sThumbLY;
[FieldOffset(8)]
public short sThumbRX;
[FieldOffset(10)]
public short sThumbRY;
public const int LeftThumbDeadzone = 7849;
public const int RightThumbDeadzone = 8689;
public const int TriggerThreshold = 30;
public Buttons Buttons { get { return (Buttons)wButtons; } }
}
[Flags]
public enum Buttons
{
None = 0x0000,
DPadUp = 0x0001,
DPadDown = 0x0002,
DPadLeft = 0x0004,
DPadRight = 0x0008,
Start = 0x0010,
Back = 0x0020,
LeftThumb = 0x0040,
RightThumb = 0x0080,
LeftShoulder = 0x0100,
RightShoulder = 0x0200,
A = 0x1000,
B = 0x2000,
X = 0x4000,
Y = 0x8000
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: dee5c4630dd189049abf4d41bd4348d8

View File

@ -1,14 +0,0 @@
using System.Runtime.InteropServices;
namespace Essgee.Utilities.XInput
{
/* https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_state%28v=vs.85%29.aspx */
[StructLayout(LayoutKind.Explicit)]
public struct XInputState
{
[FieldOffset(0)]
public uint dwPacketNumber;
[FieldOffset(4)]
public XInputGamepad Gamepad;
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: b18170cd37fc33d4ba897ffbe7198deb

View File

@ -1,14 +0,0 @@
using System.Runtime.InteropServices;
namespace Essgee.Utilities.XInput
{
/* https://msdn.microsoft.com/en-us/library/windows/desktop/microsoft.directx_sdk.reference.xinput_vibration%28v=vs.85%29.aspx */
[StructLayout(LayoutKind.Explicit)]
public struct XInputVibration
{
[FieldOffset(0)]
public ushort wLeftMotorSpeed;
[FieldOffset(2)]
public ushort wRightMotorSpeed;
}
}

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 66e6171736477a944b9299a66469f407

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 1a58e3ab1bbec0a4998d14ae26c5651d

View File

@ -896,7 +896,7 @@ GameObject:
- component: {fileID: 3557960759775635435}
- component: {fileID: 3223371122505490051}
m_Layer: 5
m_Name: btnCoin1
m_Name: btnSelect
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -920,7 +920,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
m_AnchoredPosition: {x: 0, y: 78.75}
m_SizeDelta: {x: 171.9867, y: 85.772705}
m_SizeDelta: {x: 130, y: 85.772705}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &3557960759775635432
CanvasRenderer:
@ -1004,7 +1004,7 @@ MonoBehaviour:
m_OnClick:
m_PersistentCalls:
m_Calls: []
axiBtnTypeList: 0a
axiBtnTypeList: 0b
--- !u!1 &3557960759789586675
GameObject:
m_ObjectHideFlags: 0
@ -1018,7 +1018,7 @@ GameObject:
- component: {fileID: 3557960759789586678}
- component: {fileID: 4570849136174787956}
m_Layer: 5
m_Name: btnP1
m_Name: btnSTART
m_TagString: Untagged
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
@ -1041,8 +1041,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
m_AnchoredPosition: {x: -200, y: 78.75}
m_SizeDelta: {x: 178.85925, y: 85.772705}
m_AnchoredPosition: {x: -150, y: 78.75}
m_SizeDelta: {x: 130, y: 85.772705}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &3557960759789586679
CanvasRenderer:
@ -1126,7 +1126,7 @@ MonoBehaviour:
m_OnClick:
m_PersistentCalls:
m_Calls: []
axiBtnTypeList: 0b
axiBtnTypeList: 0a
--- !u!1 &3557960759893428088
GameObject:
m_ObjectHideFlags: 0
@ -1352,10 +1352,10 @@ MonoBehaviour:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: 33a3bdf8f6bd1ec4eba7c4bc58183212, type: 3}
m_FontSize: 59
m_FontSize: 25
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MinSize: 0
m_MaxSize: 107
m_Alignment: 4
m_AlignByGeometry: 0
@ -1363,7 +1363,7 @@ MonoBehaviour:
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: P1
m_Text: START
--- !u!1 &3557960760383323518
GameObject:
m_ObjectHideFlags: 0
@ -1431,10 +1431,10 @@ MonoBehaviour:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: 33a3bdf8f6bd1ec4eba7c4bc58183212, type: 3}
m_FontSize: 59
m_FontSize: 25
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MinSize: 0
m_MaxSize: 107
m_Alignment: 4
m_AlignByGeometry: 0
@ -1442,9 +1442,7 @@ MonoBehaviour:
m_HorizontalOverflow: 0
m_VerticalOverflow: 0
m_LineSpacing: 1
m_Text: 'Coin
'
m_Text: SELECT
--- !u!1 &3557960760441770047
GameObject:
m_ObjectHideFlags: 0
@ -2426,8 +2424,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0}
m_AnchorMax: {x: 0.5, y: 0}
m_AnchoredPosition: {x: 200, y: 78.75}
m_SizeDelta: {x: 178.85925, y: 85.772705}
m_AnchoredPosition: {x: 150, y: 78.75}
m_SizeDelta: {x: 130, y: 85.772705}
m_Pivot: {x: 0.5, y: 0}
--- !u!222 &5178997240577738822
CanvasRenderer:
@ -2733,10 +2731,10 @@ MonoBehaviour:
m_Calls: []
m_FontData:
m_Font: {fileID: 12800000, guid: 33a3bdf8f6bd1ec4eba7c4bc58183212, type: 3}
m_FontSize: 59
m_FontSize: 25
m_FontStyle: 0
m_BestFit: 0
m_MinSize: 1
m_MinSize: 0
m_MaxSize: 107
m_Alignment: 4
m_AlignByGeometry: 0

View File

@ -9,7 +9,6 @@ using Essgee.Exceptions;
using Essgee.Extensions;
using Essgee.Metadata;
using Essgee.Utilities;
using Essgee.Utilities.XInput;
using System;
using System.Collections.Generic;
using System.IO;
@ -395,7 +394,8 @@ public class UEssgee : MonoBehaviour, IEmuCore
}
public static void SaveConfiguration()
{
EmuStandInfo.Configuration.SerializeToFile(EmuStandInfo.programConfigPath);
//不用保存这个配置
//EmuStandInfo.Configuration.SerializeToFile(EmuStandInfo.programConfigPath);
}
#endregion
@ -690,7 +690,7 @@ public class UEssgee : MonoBehaviour, IEmuCore
graphicsHandler.SubmitVideo(e.Width, e.Height, e.FrameDataPtr, 0);
// TODO: create emulation "EndOfFrame" event for this?
ControllerManager.Update();
//ControllerManager.Update();
//});
}
@ -786,8 +786,8 @@ public class UEssgee : MonoBehaviour, IEmuCore
private void EmulatorHandler_EnableRumble(object sender, EventArgs e)
{
if (EmuStandInfo.Configuration.EnableXInput && EmuStandInfo.Configuration.EnableRumble)
ControllerManager.GetController(0).Vibrate(0.0f, 0.5f, TimeSpan.FromSeconds(0.1f));
//if (EmuStandInfo.Configuration.EnableXInput && EmuStandInfo.Configuration.EnableRumble)
// ControllerManager.GetController(0).Vibrate(0.0f, 0.5f, TimeSpan.FromSeconds(0.1f));
}
private void EmulatorHandler_PauseChanged(object sender, EventArgs e)

View File

@ -35,7 +35,7 @@ namespace AxibugEmuOnline.Client
GameObject.DontDestroyOnLoad(debugger);
bool UseJoyStack = false;
if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.WindowsEditor)
if (Application.platform == RuntimePlatform.Android && Application.platform != RuntimePlatform.WindowsEditor)
{
UseJoyStack = true;
}

View File

@ -30,6 +30,8 @@ namespace AxibugEmuOnline.Client
LoopAction_3s += Ping;
SetFrameRate(60);
#if UNITY_EDITOR
UnityEditor.EditorApplication.playModeStateChanged += (state) =>
{