模拟器事件对象池化,去掉Xinput代码

This commit is contained in:
sin365 2025-01-07 17:01:37 +08:00
parent 81f6c03188
commit cc39c555f7
29 changed files with 897 additions and 341 deletions

View File

@ -1,12 +1,8 @@
using System; using System.Collections.Generic;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.Emulation.Audio namespace Essgee.Emulation.Audio
{ {
public partial class CGBAudio : DMGAudio, IAudio public partial class CGBAudio : DMGAudio, IAudio
{ {
public CGBAudio() public CGBAudio()
{ {

View File

@ -267,15 +267,19 @@ namespace Essgee.Emulation.Audio
} }
if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels)) if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels))
{ {
OnEnqueueSamples(new EnqueueSamplesEventArgs( EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
numChannels, numChannels,
channelSampleBuffer.Select(x => x.ToArray()).ToArray(), channelSampleBuffer.Select(x => x.ToArray()).ToArray(),
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable }, new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
mixedSampleBuffer.ToArray())); mixedSampleBuffer.ToArray());
OnEnqueueSamples(eventArgs);
FlushSamples(); FlushSamples();
}
eventArgs.Release();
}
if (frameCycleCount >= cyclesPerFrame) if (frameCycleCount >= cyclesPerFrame)
{ {

View File

@ -217,14 +217,19 @@ namespace Essgee.Emulation.Audio
if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels)) if (mixedSampleBuffer.Count >= (samplesPerFrame * numOutputChannels))
{ {
OnEnqueueSamples(new EnqueueSamplesEventArgs( EnqueueSamplesEventArgs eventArgs = EnqueueSamplesEventArgs.Create(
numChannels, numChannels,
channelSampleBuffer.Select(x => x.ToArray()).ToArray(), channelSampleBuffer.Select(x => x.ToArray()).ToArray(),
new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable }, new bool[] { !channel1ForceEnable, !channel2ForceEnable, !channel3ForceEnable, !channel4ForceEnable },
mixedSampleBuffer.ToArray())); mixedSampleBuffer.ToArray());
OnEnqueueSamples(eventArgs);
FlushSamples(); FlushSamples();
}
eventArgs.Release();
}
if (frameCycleCount >= cyclesPerFrame) if (frameCycleCount >= cyclesPerFrame)
{ {

View File

@ -252,8 +252,10 @@ namespace Essgee.Emulation.ExtDevices.Nintendo
if (packet.isCompressed) if (packet.isCompressed)
{ {
/* Decompress RLE first! */ /* Decompress RLE first! */
List<byte> decomp = new List<byte>(); //List<byte> decomp = new List<byte>();
int ofs = 0, numbytes = 0; List<byte> decomp = ObjectPoolAuto.AcquireList<byte>();
int ofs = 0, numbytes = 0;
while (ofs < packet.dataLen) while (ofs < packet.dataLen)
{ {
if ((packet.data[ofs] & 0x80) != 0) if ((packet.data[ofs] & 0x80) != 0)
@ -273,7 +275,9 @@ namespace Essgee.Emulation.ExtDevices.Nintendo
} }
packet.data = decomp.ToArray(); packet.data = decomp.ToArray();
packet.dataLen = (ushort)decomp.Count; packet.dataLen = (ushort)decomp.Count;
}
ObjectPoolAuto.Release(decomp);
}
imageData.AddRange(packet.data); imageData.AddRange(packet.data);
imageHeight += (packet.data.Length / 0x28); imageHeight += (packet.data.Length / 0x28);

View File

@ -129,10 +129,12 @@ namespace Essgee.Emulation.Machines
vdp.EndOfScanline += (s, e) => vdp.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
ParseInput(pollInputEventArgs); ParseInput(pollInputEventArgs);
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -177,8 +179,10 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate);
OnChangeViewport(new ChangeViewportEventArgs(vdp.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(vdp.Viewport);
} OnChangeViewport(eventArgs);
eventArgs.Release();
}
private void LoadBios() private void LoadBios()
{ {

View File

@ -148,10 +148,11 @@ namespace Essgee.Emulation.Machines
video.EndOfScanline += (s, e) => video.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
ParseInput(pollInputEventArgs); ParseInput(pollInputEventArgs);
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -211,9 +212,11 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate);
/* Announce viewport */ /* Announce viewport */
OnChangeViewport(new ChangeViewportEventArgs(video.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(video.Viewport);
} OnChangeViewport(eventArgs);
eventArgs.Release();
}
private void LoadBootstrap() private void LoadBootstrap()
{ {
@ -473,22 +476,22 @@ namespace Essgee.Emulation.Machines
inputsPressed |= JoypadInputs.Start; inputsPressed |= JoypadInputs.Start;
/* XInput controller */ /* XInput controller */
if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) //if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed())
inputsPressed |= JoypadInputs.Right; // inputsPressed |= JoypadInputs.Right;
if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) //if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed())
inputsPressed |= JoypadInputs.Left; // inputsPressed |= JoypadInputs.Left;
if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) //if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed())
inputsPressed |= JoypadInputs.Up; // inputsPressed |= JoypadInputs.Up;
if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) //if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed())
inputsPressed |= JoypadInputs.Down; // inputsPressed |= JoypadInputs.Down;
if (eventArgs.ControllerState.IsAPressed()) //if (eventArgs.ControllerState.IsAPressed())
inputsPressed |= JoypadInputs.A; // inputsPressed |= JoypadInputs.A;
if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) //if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed())
inputsPressed |= JoypadInputs.B; // inputsPressed |= JoypadInputs.B;
if (eventArgs.ControllerState.IsBackPressed()) //if (eventArgs.ControllerState.IsBackPressed())
inputsPressed |= JoypadInputs.Select; // inputsPressed |= JoypadInputs.Select;
if (eventArgs.ControllerState.IsStartPressed()) //if (eventArgs.ControllerState.IsStartPressed())
inputsPressed |= JoypadInputs.Start; // inputsPressed |= JoypadInputs.Start;
} }
private byte ReadMemory(ushort address) private byte ReadMemory(ushort address)

View File

@ -179,10 +179,11 @@ namespace Essgee.Emulation.Machines
video.EndOfScanline += (s, e) => video.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
ParseInput(pollInputEventArgs); ParseInput(pollInputEventArgs);
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -262,9 +263,11 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate);
/* Announce viewport */ /* Announce viewport */
OnChangeViewport(new ChangeViewportEventArgs(video.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(video.Viewport);
} OnChangeViewport(eventArgs);
eventArgs.Release();
}
private void LoadBootstrap() private void LoadBootstrap()
{ {
@ -591,14 +594,14 @@ namespace Essgee.Emulation.Machines
} }
/* XInput controller */ /* XInput controller */
if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) inputsPressed |= JoypadInputs.Right; //if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) inputsPressed |= JoypadInputs.Right;
if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) inputsPressed |= JoypadInputs.Left; //if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) inputsPressed |= JoypadInputs.Left;
if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) inputsPressed |= JoypadInputs.Up; //if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) inputsPressed |= JoypadInputs.Up;
if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) inputsPressed |= JoypadInputs.Down; //if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) inputsPressed |= JoypadInputs.Down;
if (eventArgs.ControllerState.IsAPressed()) inputsPressed |= JoypadInputs.A; //if (eventArgs.ControllerState.IsAPressed()) inputsPressed |= JoypadInputs.A;
if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) inputsPressed |= JoypadInputs.B; //if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) inputsPressed |= JoypadInputs.B;
if (eventArgs.ControllerState.IsBackPressed()) inputsPressed |= JoypadInputs.Select; //if (eventArgs.ControllerState.IsBackPressed()) inputsPressed |= JoypadInputs.Select;
if (eventArgs.ControllerState.IsStartPressed()) inputsPressed |= JoypadInputs.Start; //if (eventArgs.ControllerState.IsStartPressed()) inputsPressed |= JoypadInputs.Start;
} }
private byte ReadMemory(ushort address) private byte ReadMemory(ushort address)

View File

@ -138,10 +138,11 @@ namespace Essgee.Emulation.Machines
vdp.EndOfScanline += (s, e) => vdp.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
ParseInput(pollInputEventArgs); ParseInput(pollInputEventArgs);
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -186,8 +187,10 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / refreshRate);
OnChangeViewport(new ChangeViewportEventArgs(vdp.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(vdp.Viewport);
} OnChangeViewport(eventArgs);
eventArgs.Release();
}
private void LoadBootstrap() private void LoadBootstrap()
{ {
@ -373,13 +376,13 @@ namespace Essgee.Emulation.Machines
if (eventArgs.Keyboard.Contains(configuration.ControlsStart)) portCInputsPressed |= IOPortCInputs.Start; if (eventArgs.Keyboard.Contains(configuration.ControlsStart)) portCInputsPressed |= IOPortCInputs.Start;
/* XInput controller */ /* XInput controller */
if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortAUp; //if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortAUp;
if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortADown; //if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortADown;
if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortALeft; //if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortALeft;
if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortARight; //if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) portAInputsPressed |= IOPortABInputs.PortARight;
if (eventArgs.ControllerState.IsAPressed()) portAInputsPressed |= IOPortABInputs.PortATL; //if (eventArgs.ControllerState.IsAPressed()) portAInputsPressed |= IOPortABInputs.PortATL;
if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) portAInputsPressed |= IOPortABInputs.PortATR; //if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) portAInputsPressed |= IOPortABInputs.PortATR;
if (eventArgs.ControllerState.IsStartPressed()) portCInputsPressed |= IOPortCInputs.Start; //if (eventArgs.ControllerState.IsStartPressed()) portCInputsPressed |= IOPortCInputs.Start;
portIoAB |= (byte)(IOPortABInputs.PortAUp | IOPortABInputs.PortADown | IOPortABInputs.PortALeft | IOPortABInputs.PortARight | IOPortABInputs.PortATL | IOPortABInputs.PortATR | IOPortABInputs.PortBUp | IOPortABInputs.PortBDown); portIoAB |= (byte)(IOPortABInputs.PortAUp | IOPortABInputs.PortADown | IOPortABInputs.PortALeft | IOPortABInputs.PortARight | IOPortABInputs.PortATL | IOPortABInputs.PortATR | IOPortABInputs.PortBUp | IOPortABInputs.PortBDown);
portIoBMisc |= (byte)(IOPortBMiscInputs.PortBLeft | IOPortBMiscInputs.PortBRight | IOPortBMiscInputs.PortBTL | IOPortBMiscInputs.PortBTR | IOPortBMiscInputs.Reset | IOPortBMiscInputs.CartSlotCONTPin | IOPortBMiscInputs.PortATH | IOPortBMiscInputs.PortBTH); portIoBMisc |= (byte)(IOPortBMiscInputs.PortBLeft | IOPortBMiscInputs.PortBRight | IOPortBMiscInputs.PortBTL | IOPortBMiscInputs.PortBTR | IOPortBMiscInputs.Reset | IOPortBMiscInputs.CartSlotCONTPin | IOPortBMiscInputs.PortATH | IOPortBMiscInputs.PortBTH);

View File

@ -124,8 +124,8 @@ namespace Essgee.Emulation.Machines
public Configuration.MasterSystem configuration { get; private set; } public Configuration.MasterSystem configuration { get; private set; }
IEnumerable<MotionKey> lastKeysDown; List<MotionKey> lastKeysDown;
ControllerState lastControllerState; //ControllerState lastControllerState;
MouseButtons lastMouseButtons; MouseButtons lastMouseButtons;
(int x, int y) lastMousePosition; (int x, int y) lastMousePosition;
@ -146,20 +146,23 @@ namespace Essgee.Emulation.Machines
inputDevices[1] = InputDevice.None; inputDevices[1] = InputDevice.None;
lastKeysDown = new List<MotionKey>(); lastKeysDown = new List<MotionKey>();
lastControllerState = new ControllerState(); //lastControllerState = new ControllerState();
vdp.EndOfScanline += (s, e) => vdp.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
lastKeysDown = pollInputEventArgs.Keyboard; lastKeysDown.Clear();
lastControllerState = pollInputEventArgs.ControllerState; lastKeysDown.AddRange(pollInputEventArgs.Keyboard);
//lastControllerState = pollInputEventArgs.ControllerState;
lastMouseButtons = pollInputEventArgs.MouseButtons; lastMouseButtons = pollInputEventArgs.MouseButtons;
lastMousePosition = pollInputEventArgs.MousePosition; lastMousePosition = pollInputEventArgs.MousePosition;
HandlePauseButton(); HandlePauseButton();
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -215,9 +218,11 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / RefreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / RefreshRate);
OnChangeViewport(new ChangeViewportEventArgs(vdp.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(vdp.Viewport);
OnChangeViewport(eventArgs);
eventArgs.Release();
inputDevices[0] = configuration.Joypad1DeviceType; inputDevices[0] = configuration.Joypad1DeviceType;
inputDevices[1] = configuration.Joypad2DeviceType; inputDevices[1] = configuration.Joypad2DeviceType;
} }
@ -376,7 +381,7 @@ namespace Essgee.Emulation.Machines
private void HandlePauseButton() private void HandlePauseButton()
{ {
var pausePressed = lastKeysDown.Contains(configuration.InputPause) || lastControllerState.IsStartPressed(); var pausePressed = lastKeysDown.Contains(configuration.InputPause);// || lastControllerState.IsStartPressed();
var pauseButtonHeld = pauseButtonToggle && pausePressed; var pauseButtonHeld = pauseButtonToggle && pausePressed;
if (pausePressed) if (pausePressed)
{ {
@ -398,19 +403,32 @@ namespace Essgee.Emulation.Machines
break; break;
case InputDevice.Controller: case InputDevice.Controller:
if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Up : configuration.Joypad2Up) || (port == 0 && lastControllerState.IsAnyUpDirectionPressed() && !lastControllerState.IsAnyDownDirectionPressed())) if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Up : configuration.Joypad2Up))
state &= (byte)~ControllerInputs.Up; state &= (byte)~ControllerInputs.Up;
if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Down : configuration.Joypad2Down) || (port == 0 && lastControllerState.IsAnyDownDirectionPressed() && !lastControllerState.IsAnyUpDirectionPressed())) if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Down : configuration.Joypad2Down))
state &= (byte)~ControllerInputs.Down; state &= (byte)~ControllerInputs.Down;
if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Left : configuration.Joypad2Left) || (port == 0 && lastControllerState.IsAnyLeftDirectionPressed() && !lastControllerState.IsAnyRightDirectionPressed())) if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Left : configuration.Joypad2Left))
state &= (byte)~ControllerInputs.Left; state &= (byte)~ControllerInputs.Left;
if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Right : configuration.Joypad2Right) || (port == 0 && lastControllerState.IsAnyRightDirectionPressed() && !lastControllerState.IsAnyLeftDirectionPressed())) if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Right : configuration.Joypad2Right))
state &= (byte)~ControllerInputs.Right; state &= (byte)~ControllerInputs.Right;
if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Button1 : configuration.Joypad2Button1) || (port == 0 && lastControllerState.IsAPressed())) if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Button1 : configuration.Joypad2Button1))
state &= (byte)~ControllerInputs.TL; state &= (byte)~ControllerInputs.TL;
if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Button2 : configuration.Joypad2Button2) || (port == 0 && (lastControllerState.IsXPressed() || lastControllerState.IsBPressed()))) if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Button2 : configuration.Joypad2Button2))
state &= (byte)~ControllerInputs.TR; state &= (byte)~ControllerInputs.TR;
break;
//if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Up : configuration.Joypad2Up) || (port == 0 && lastControllerState.IsAnyUpDirectionPressed() && !lastControllerState.IsAnyDownDirectionPressed()))
// state &= (byte)~ControllerInputs.Up;
//if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Down : configuration.Joypad2Down) || (port == 0 && lastControllerState.IsAnyDownDirectionPressed() && !lastControllerState.IsAnyUpDirectionPressed()))
// state &= (byte)~ControllerInputs.Down;
//if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Left : configuration.Joypad2Left) || (port == 0 && lastControllerState.IsAnyLeftDirectionPressed() && !lastControllerState.IsAnyRightDirectionPressed()))
// state &= (byte)~ControllerInputs.Left;
//if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Right : configuration.Joypad2Right) || (port == 0 && lastControllerState.IsAnyRightDirectionPressed() && !lastControllerState.IsAnyLeftDirectionPressed()))
// state &= (byte)~ControllerInputs.Right;
//if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Button1 : configuration.Joypad2Button1) || (port == 0 && lastControllerState.IsAPressed()))
// state &= (byte)~ControllerInputs.TL;
//if (lastKeysDown.Contains(port == 0 ? configuration.Joypad1Button2 : configuration.Joypad2Button2) || (port == 0 && (lastControllerState.IsXPressed() || lastControllerState.IsBPressed())))
// state &= (byte)~ControllerInputs.TR;
break;
case InputDevice.Lightgun: case InputDevice.Lightgun:
if (GetIOControlDirection(port == 0 ? IOControlPort.A : IOControlPort.B, IOControlPin.TH, portIoControl) == IOControlDirection.Input) if (GetIOControlDirection(port == 0 ? IOControlPort.A : IOControlPort.B, IOControlPin.TH, portIoControl) == IOControlDirection.Input)

View File

@ -144,10 +144,11 @@ namespace Essgee.Emulation.Machines
vdp.EndOfScanline += (s, e) => vdp.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
ParseInput(pollInputEventArgs); ParseInput(pollInputEventArgs);
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -203,8 +204,10 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / RefreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / RefreshRate);
OnChangeViewport(new ChangeViewportEventArgs(vdp.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(vdp.Viewport);
} OnChangeViewport(eventArgs);
eventArgs.Release();
}
public void Startup() public void Startup()
{ {
@ -360,8 +363,11 @@ namespace Essgee.Emulation.Machines
{ {
keyboardMode = !keyboardMode; keyboardMode = !keyboardMode;
var modeString = (keyboardMode ? "keyboard" : "controller"); var modeString = (keyboardMode ? "keyboard" : "controller");
SendLogMessage(this, new SendLogMessageEventArgs($"Selected {modeString} mode.")); var logeventArgs = SendLogMessageEventArgs.Create($"Selected {modeString} mode.");
} SendLogMessage(this, logeventArgs);
logeventArgs.Release();
}
changeInputButtonPressed = keysDown.Contains(configuration.InputChangeMode); changeInputButtonPressed = keysDown.Contains(configuration.InputChangeMode);
/* Toggle tape playback */ /* Toggle tape playback */
@ -369,7 +375,9 @@ namespace Essgee.Emulation.Machines
{ {
isTapePlaying = !isTapePlaying; isTapePlaying = !isTapePlaying;
var playString = (isTapePlaying ? "playing" : "stopped"); var playString = (isTapePlaying ? "playing" : "stopped");
SendLogMessage(this, new SendLogMessageEventArgs($"Tape is {playString}.")); var logeventArgs = SendLogMessageEventArgs.Create($"Tape is {playString}.");
SendLogMessage(this, logeventArgs);
logeventArgs.Release();
} }
tapePlayButtonPressed = keysDown.Contains(configuration.InputPlayTape); tapePlayButtonPressed = keysDown.Contains(configuration.InputPlayTape);
@ -478,12 +486,12 @@ namespace Essgee.Emulation.Machines
if (keysDown.Contains(configuration.Joypad2Button2)) portBInputsPressed |= PortBInputs.P2Button2; if (keysDown.Contains(configuration.Joypad2Button2)) portBInputsPressed |= PortBInputs.P2Button2;
/* XInput controller */ /* XInput controller */
if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) portAInputsPressed |= PortAInputs.P1Up; //if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) portAInputsPressed |= PortAInputs.P1Up;
if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) portAInputsPressed |= PortAInputs.P1Down; //if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) portAInputsPressed |= PortAInputs.P1Down;
if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) portAInputsPressed |= PortAInputs.P1Left; //if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) portAInputsPressed |= PortAInputs.P1Left;
if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) portAInputsPressed |= PortAInputs.P1Right; //if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) portAInputsPressed |= PortAInputs.P1Right;
if (eventArgs.ControllerState.IsAPressed()) portAInputsPressed |= PortAInputs.P1Button1; //if (eventArgs.ControllerState.IsAPressed()) portAInputsPressed |= PortAInputs.P1Button1;
if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) portAInputsPressed |= PortAInputs.P1Button2; //if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) portAInputsPressed |= PortAInputs.P1Button2;
} }
} }

View File

@ -130,10 +130,11 @@ namespace Essgee.Emulation.Machines
vdp.EndOfScanline += (s, e) => vdp.EndOfScanline += (s, e) =>
{ {
PollInputEventArgs pollInputEventArgs = new PollInputEventArgs(); PollInputEventArgs pollInputEventArgs = PollInputEventArgs.Create();
OnPollInput(pollInputEventArgs); OnPollInput(pollInputEventArgs);
ParseInput(pollInputEventArgs); ParseInput(pollInputEventArgs);
}; pollInputEventArgs.Release();
};
} }
public void SetConfiguration(IConfiguration config) public void SetConfiguration(IConfiguration config)
@ -189,8 +190,11 @@ namespace Essgee.Emulation.Machines
currentMasterClockCyclesInFrame = 0; currentMasterClockCyclesInFrame = 0;
totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / RefreshRate); totalMasterClockCyclesInFrame = (int)Math.Round(masterClock / RefreshRate);
OnChangeViewport(new ChangeViewportEventArgs(vdp.Viewport)); var eventArgs = ChangeViewportEventArgs.Create(vdp.Viewport);
} OnChangeViewport(eventArgs);
eventArgs.Release();
}
public void Startup() public void Startup()
{ {
@ -346,12 +350,12 @@ namespace Essgee.Emulation.Machines
if (keysDown.Contains(configuration.Joypad2Button2)) portIoBMiscPressed |= PortIoBMiscValues.P2Button2; if (keysDown.Contains(configuration.Joypad2Button2)) portIoBMiscPressed |= PortIoBMiscValues.P2Button2;
/* XInput controller */ /* XInput controller */
if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) portIoABPressed |= PortIoABValues.P1Up; //if (eventArgs.ControllerState.IsAnyUpDirectionPressed() && !eventArgs.ControllerState.IsAnyDownDirectionPressed()) portIoABPressed |= PortIoABValues.P1Up;
if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) portIoABPressed |= PortIoABValues.P1Down; //if (eventArgs.ControllerState.IsAnyDownDirectionPressed() && !eventArgs.ControllerState.IsAnyUpDirectionPressed()) portIoABPressed |= PortIoABValues.P1Down;
if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) portIoABPressed |= PortIoABValues.P1Left; //if (eventArgs.ControllerState.IsAnyLeftDirectionPressed() && !eventArgs.ControllerState.IsAnyRightDirectionPressed()) portIoABPressed |= PortIoABValues.P1Left;
if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) portIoABPressed |= PortIoABValues.P1Right; //if (eventArgs.ControllerState.IsAnyRightDirectionPressed() && !eventArgs.ControllerState.IsAnyLeftDirectionPressed()) portIoABPressed |= PortIoABValues.P1Right;
if (eventArgs.ControllerState.IsAPressed()) portIoABPressed |= PortIoABValues.P1Button1; //if (eventArgs.ControllerState.IsAPressed()) portIoABPressed |= PortIoABValues.P1Button1;
if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) portIoABPressed |= PortIoABValues.P1Button2; //if (eventArgs.ControllerState.IsXPressed() || eventArgs.ControllerState.IsBPressed()) portIoABPressed |= PortIoABValues.P1Button2;
portIoBMiscPressed |= (PortIoBMiscValues.IC21Pin6 | PortIoBMiscValues.IC21Pin10 | PortIoBMiscValues.IC21Pin13); /* Unused, always 1 */ portIoBMiscPressed |= (PortIoBMiscValues.IC21Pin6 | PortIoBMiscValues.IC21Pin10 | PortIoBMiscValues.IC21Pin13); /* Unused, always 1 */
} }

View File

@ -387,7 +387,9 @@ namespace Essgee.Emulation.Video.Nintendo
if (cycleCount == clockCyclesPerLine) EndHBlank(); if (cycleCount == clockCyclesPerLine) EndHBlank();
} }
protected virtual void EndHBlank()
GCHandle? lasyRenderHandle;
protected virtual void EndHBlank()
{ {
/* End of scanline reached */ /* End of scanline reached */
OnEndOfScanline(EventArgs.Empty); OnEndOfScanline(EventArgs.Empty);
@ -409,14 +411,19 @@ namespace Essgee.Emulation.Video.Nintendo
if (skipFrames > 0) skipFrames--; if (skipFrames > 0) skipFrames--;
/* Submit screen for rendering */ /* Submit screen for rendering */
// 固定数组,防止垃圾回收器移动它 // 固定数组,防止垃圾回收器移动它
var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned); var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned);
// 获取数组的指针 // 获取数组的指针
IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject(); IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
OnRenderScreen(new RenderScreenEventArgs(displayActiveWidth, displayActiveHeight, mFrameDataPtr)); var eventArgs = RenderScreenEventArgs.Create(displayActiveWidth, displayActiveHeight, mFrameDataPtr);
OnRenderScreen(eventArgs);
eventArgs.Release();
if (lasyRenderHandle != null)
lasyRenderHandle.Value.Free();
lasyRenderHandle = bitmapcolorRect_handle;
//OnRenderScreen(new RenderScreenEventArgs(displayActiveWidth, displayActiveHeight, outputFramebuffer.Clone() as byte[])); //OnRenderScreen(new RenderScreenEventArgs(displayActiveWidth, displayActiveHeight, outputFramebuffer.Clone() as byte[]));
} }
else else

View File

@ -53,17 +53,23 @@ namespace Essgee.Emulation.Video
UpdateResolution(); UpdateResolution();
} }
protected override void PrepareRenderScreen() GCHandle? lasyRenderHandle;
{ protected override void PrepareRenderScreen()
{
// 固定数组,防止垃圾回收器移动它 // 固定数组,防止垃圾回收器移动它
var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned); var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned);
// 获取数组的指针 // 获取数组的指针
IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject(); IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, mFrameDataPtr));
var eventArgs = RenderScreenEventArgs.Create(numVisiblePixels, numVisibleScanlines, mFrameDataPtr);
OnRenderScreen(eventArgs);
eventArgs.Release();
if (lasyRenderHandle != null)
lasyRenderHandle.Value.Free();
lasyRenderHandle = bitmapcolorRect_handle;
//OnRenderScreen(new RenderScreenEventArgs(Viewport.Width, Viewport.Height, outputFramebuffer.Clone() as byte[])); //OnRenderScreen(new RenderScreenEventArgs(Viewport.Width, Viewport.Height, outputFramebuffer.Clone() as byte[]));
} }
private bool ModifyAndVerifyCoordinates(ref int x, ref int y) private bool ModifyAndVerifyCoordinates(ref int x, ref int y)
{ {

View File

@ -445,17 +445,23 @@ namespace Essgee.Emulation.Video
} }
} }
protected override void PrepareRenderScreen() GCHandle? lasyRenderHandle;
protected override void PrepareRenderScreen()
{ {
// 固定数组,防止垃圾回收器移动它 // 固定数组,防止垃圾回收器移动它
var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned); var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned);
// 获取数组的指针 // 获取数组的指针
IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject(); IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, mFrameDataPtr));
var eventArgs = RenderScreenEventArgs.Create(numVisiblePixels, numVisibleScanlines, mFrameDataPtr);
OnRenderScreen(eventArgs);
eventArgs.Release();
if (lasyRenderHandle != null)
lasyRenderHandle.Value.Free();
lasyRenderHandle = bitmapcolorRect_handle;
//OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, outputFramebuffer.Clone() as byte[])); //OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, outputFramebuffer.Clone() as byte[]));
} }
protected override byte ReadVram(ushort address) protected override byte ReadVram(ushort address)
{ {

View File

@ -304,9 +304,11 @@ namespace Essgee.Emulation.Video
pixelRightBorder = (pixelActiveDisplay + horizontalActiveDisplaySize); pixelRightBorder = (pixelActiveDisplay + horizontalActiveDisplaySize);
numVisiblePixels = (leftBorderSize + horizontalActiveDisplaySize + rightBorderSize); numVisiblePixels = (leftBorderSize + horizontalActiveDisplaySize + rightBorderSize);
var eventArgs = SizeScreenEventArgs.Create(numVisiblePixels, numVisibleScanlines);
OnSizeScreen(eventArgs);
eventArgs.Release();
OnSizeScreen(new SizeScreenEventArgs(numVisiblePixels, numVisibleScanlines)); }
}
public virtual void Step(int clockCyclesInStep) public virtual void Step(int clockCyclesInStep)
{ {
@ -341,15 +343,19 @@ namespace Essgee.Emulation.Video
} }
} }
protected virtual void PrepareRenderScreen() GCHandle? lasyRenderHandle;
protected virtual void PrepareRenderScreen()
{ {
// 固定数组,防止垃圾回收器移动它 // 固定数组,防止垃圾回收器移动它
var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned); var bitmapcolorRect_handle = GCHandle.Alloc(outputFramebuffer.Clone() as byte[], GCHandleType.Pinned);
// 获取数组的指针 // 获取数组的指针
IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject(); IntPtr mFrameDataPtr = bitmapcolorRect_handle.AddrOfPinnedObject();
OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, mFrameDataPtr)); var eventArgs = RenderScreenEventArgs.Create(numVisiblePixels, numVisibleScanlines, mFrameDataPtr);
OnRenderScreen(eventArgs);
eventArgs.Release();
if (lasyRenderHandle != null)
lasyRenderHandle.Value.Free();
lasyRenderHandle = bitmapcolorRect_handle;
//OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, outputFramebuffer.Clone() as byte[])); //OnRenderScreen(new RenderScreenEventArgs(numVisiblePixels, numVisibleScanlines, outputFramebuffer.Clone() as byte[]));
} }

View File

@ -1,3 +1,4 @@
using System;
using UnityEngine; using UnityEngine;
public interface IEssgeeLogger public interface IEssgeeLogger
@ -34,4 +35,11 @@ public static class EssgeeLogger
essgeeLogger.Warning(message); essgeeLogger.Warning(message);
} }
internal static void Assert(bool condition, string message)
{
if (!condition)
{
essgeeLogger.Debug(message);
}
}
} }

View File

@ -1,18 +1,28 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class ChangeViewportEventArgs : EventArgs public class ChangeViewportEventArgs : EventArgs
{ {
public (int X, int Y, int Width, int Height) Viewport { get; private set; } public (int X, int Y, int Width, int Height) Viewport { get; private set; }
public ChangeViewportEventArgs((int, int, int, int) viewport) //public ChangeViewportEventArgs((int, int, int, int) viewport)
{ //{
Viewport = viewport; // Viewport = viewport;
} //}
}
public static ChangeViewportEventArgs Create((int, int, int, int) viewport)
{
var eventArgs = ObjectPoolAuto.Acquire<ChangeViewportEventArgs>();
eventArgs.Viewport = viewport;
return eventArgs;
}
}
public static class ChangeViewportEventArgsEx
{
public static void Release(this ChangeViewportEventArgs eventArgs)
{
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -1,24 +1,41 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class EnqueueSamplesEventArgs : EventArgs public class EnqueueSamplesEventArgs : EventArgs
{ {
public int NumChannels { get; set; } public int NumChannels { get; set; }
public short[][] ChannelSamples { get; set; } public short[][] ChannelSamples { get; set; }
public bool[] IsChannelMuted { get; set; } public bool[] IsChannelMuted { get; set; }
public short[] MixedSamples { get; set; } public short[] MixedSamples { get; set; }
public EnqueueSamplesEventArgs(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples) //public EnqueueSamplesEventArgs(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
{ //{
NumChannels = numChannels; // NumChannels = numChannels;
ChannelSamples = channelSamples; // ChannelSamples = channelSamples;
IsChannelMuted = isMuted; // IsChannelMuted = isMuted;
MixedSamples = mixedSamples; // MixedSamples = mixedSamples;
} //}
}
public static EnqueueSamplesEventArgs Create(int numChannels, short[][] channelSamples, bool[] isMuted, short[] mixedSamples)
{
var eventArgs = ObjectPoolAuto.Acquire<EnqueueSamplesEventArgs>();
eventArgs.NumChannels = numChannels;
eventArgs.ChannelSamples = channelSamples;
eventArgs.IsChannelMuted = isMuted;
eventArgs.MixedSamples = mixedSamples;
return eventArgs;
}
}
public static class EnqueueSamplesEventArgsEx
{
public static void Release(this EnqueueSamplesEventArgs eventArgs)
{
eventArgs.NumChannels = 1;
eventArgs.ChannelSamples = null;
eventArgs.IsChannelMuted = null;
eventArgs.MixedSamples = null;
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -5,22 +5,49 @@ using System.Collections.Generic;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class PollInputEventArgs : EventArgs public class PollInputEventArgs : EventArgs
{ {
public IEnumerable<MotionKey> Keyboard { get; set; } public List<MotionKey> Keyboard { get; set; }
public MouseButtons MouseButtons { get; set; } public MouseButtons MouseButtons { get; set; }
public (int X, int Y) MousePosition { get; set; } public (int X, int Y) MousePosition { get; set; }
public ControllerState ControllerState { get; set; } //public ControllerState ControllerState { get; set; }
public PollInputEventArgs() //public PollInputEventArgs()
{ //{
Keyboard = new List<MotionKey>(); // Keyboard = new List<MotionKey>();
MouseButtons = MouseButtons.None; // MouseButtons = MouseButtons.None;
MousePosition = (0, 0); // MousePosition = (0, 0);
ControllerState = new ControllerState(); // ControllerState = new ControllerState();
} //}
}
public static PollInputEventArgs Create()
{
var eventArgs = ObjectPoolAuto.Acquire<PollInputEventArgs>();
//eventArgs.Keyboard = new List<MotionKey>();
eventArgs.Keyboard = ObjectPoolAuto.AcquireList<MotionKey>();
eventArgs.MouseButtons = MouseButtons.None;
eventArgs.MousePosition = (0, 0);
//eventArgs.ControllerState = new ControllerState();
//eventArgs.ControllerState = ObjectPoolAuto.Acquire<ControllerState>();
return eventArgs;
}
}
public static class PollInputEventArgsEx
{
public static void Release(this PollInputEventArgs eventArgs)
{
ObjectPoolAuto.Release(eventArgs.Keyboard);
eventArgs.Keyboard = null;
eventArgs.MouseButtons = MouseButtons.None;
eventArgs.MousePosition = (0, 0);
//ObjectPoolAuto.Release(eventArgs.ControllerState);
//eventArgs.ControllerState = null;
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -1,25 +1,37 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class RenderScreenEventArgs : EventArgs public class RenderScreenEventArgs : EventArgs
{ {
public int Width { get; private set; } public int Width { get; private set; }
public int Height { get; private set; } public int Height { get; private set; }
//public byte[] FrameData { get; private set; } //public byte[] FrameData { get; private set; }
public IntPtr FrameDataPtr { get; private set; } public IntPtr FrameDataPtr { get; private set; }
// public RenderScreenEventArgs(int width, int height, IntPtr ptr)
//{
// Width = width;
// Height = height;
// //FrameData = data;
// FrameDataPtr = ptr;
//}
public RenderScreenEventArgs(int width, int height, IntPtr ptr) public static RenderScreenEventArgs Create(int width, int height, IntPtr ptr)
{ {
Width = width; var eventArgs = ObjectPoolAuto.Acquire<RenderScreenEventArgs>();
Height = height; eventArgs.Width = width;
//FrameData = data; eventArgs.Height = height;
FrameDataPtr = ptr; //FrameData = data;
} eventArgs.FrameDataPtr = ptr;
} return eventArgs;
}
}
public static class RenderScreenEventArgsEx
{
public static void Release(this RenderScreenEventArgs eventArgs)
{
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -1,25 +1,29 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class SaveExtraDataEventArgs : EventArgs public class SaveExtraDataEventArgs : EventArgs
{ {
public ExtraDataTypes DataType { get; private set; } public ExtraDataTypes DataType { get; private set; }
public ExtraDataOptions Options { get; private set; } public ExtraDataOptions Options { get; private set; }
public string Description { get; private set; } public string Description { get; private set; }
public object Data { get; private set; } public object Data { get; private set; }
public SaveExtraDataEventArgs(ExtraDataTypes type, ExtraDataOptions option, string desc, object data) public static SaveExtraDataEventArgs Create(ExtraDataTypes type, ExtraDataOptions option, string desc, object data)
{ {
DataType = type; var eventArgs = ObjectPoolAuto.Acquire<SaveExtraDataEventArgs>();
Options = option; eventArgs.DataType = type;
Description = desc; eventArgs.Options = option;
Data = data; eventArgs.Description = desc;
} eventArgs.Data = data;
} return eventArgs;
}
}
public static class SaveExtraDataEventArgsEx
{
public static void Release(this SaveExtraDataEventArgs eventArgs)
{
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -1,18 +1,24 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class SendLogMessageEventArgs : EventArgs public class SendLogMessageEventArgs : EventArgs
{ {
public string Message { get; private set; } public string Message { get; private set; }
public SendLogMessageEventArgs(string message)
public static SendLogMessageEventArgs Create(string message)
{ {
Message = message; var eventArgs = ObjectPoolAuto.Acquire<SendLogMessageEventArgs>();
} eventArgs.Message = message;
} return eventArgs;
}
}
public static class SendLogMessageEventArgsEx
{
public static void Release(this SendLogMessageEventArgs eventArgs)
{
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -1,20 +1,25 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.EventArguments namespace Essgee.EventArguments
{ {
public class SizeScreenEventArgs : EventArgs public class SizeScreenEventArgs : EventArgs
{ {
public int Width { get; private set; } public int Width { get; private set; }
public int Height { get; private set; } public int Height { get; private set; }
public SizeScreenEventArgs(int width, int height) public static SizeScreenEventArgs Create(int width, int height)
{ {
Width = width; var eventArgs = ObjectPoolAuto.Acquire<SizeScreenEventArgs>();
Height = height; eventArgs.Width = width;
} eventArgs.Height = height;
} return eventArgs;
}
}
public static class SizeScreenEventArgsEx
{
public static void Release(this SizeScreenEventArgs eventArgs)
{
ObjectPoolAuto.Release(eventArgs);
}
}
} }

View File

@ -0,0 +1,399 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
internal static class ObjectPoolAuto
{
/************************************************************************************************************************/
/// <summary>
/// 获取或者创建一个新的
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
public static T Acquire<T>()
where T : class, new()
=> ObjectPool<T>.Acquire();
/// <summary>
/// 获取或者创建一个新的
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(T)"/> 需要回收参见这个</remarks>
public static void Acquire<T>(out T item)
where T : class, new()
=> item = ObjectPool<T>.Acquire();
/************************************************************************************************************************/
/// <summary>
/// 回收对象
/// </summary>
public static void Release<T>(T item)
where T : class, new()
=> ObjectPool<T>.Release(item);
/// <summary>
/// 回收对象
/// </summary>
public static void Release<T>(ref T item) where T : class, new()
{
if (item != null)
{
ObjectPool<T>.Release(item);
item = null;
}
}
/************************************************************************************************************************/
public const string
NotClearError = " They must be cleared before being released to the pool and not modified after that.";
/************************************************************************************************************************/
/// <summary>
/// 获取或创建List
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(List{T})"/> 回收参见此方法</remarks>
public static List<T> AcquireList<T>()
{
var list = ObjectPool<List<T>>.Acquire();
EssgeeLogger.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
return list;
}
/// <summary>
/// 回收List
/// </summary>
public static void Release<T>(List<T> list)
{
list.Clear();
ObjectPool<List<T>>.Release(list);
}
/************************************************************************************************************************/
/// <summary>
/// 获取或创建Queue
/// </summary>
/// <remarks>Remember to <see cref="Release{T}(Queue{T})"/> 回收参见此方法</remarks>
public static Queue<T> AcquireQueue<T>()
{
var queue = ObjectPool<Queue<T>>.Acquire();
EssgeeLogger.Assert(queue.Count == 0, "A pooled list is not empty." + NotClearError);
return queue;
}
/// <summary>
/// 回收Queue
/// </summary>
public static void Release<T>(Queue<T> list)
{
list.Clear();
ObjectPool<Queue<T>>.Release(list);
}
/************************************************************************************************************************/
/// <summary>
/// 获取或创建HashSet
/// </summary>
public static HashSet<T> AcquireSet<T>()
{
var set = ObjectPool<HashSet<T>>.Acquire();
EssgeeLogger.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
return set;
}
/// <summary>
/// 释放HashSet
/// </summary>
public static void Release<T>(HashSet<T> set)
{
set.Clear();
ObjectPool<HashSet<T>>.Release(set);
}
/************************************************************************************************************************/
/// <summary>
/// 获取一个字符串StringBuilder
/// </summary>
/// <remarks>Remember to <see cref="Release(StringBuilder)"/>回收参见这个</remarks>
public static StringBuilder AcquireStringBuilder()
{
var builder = ObjectPool<StringBuilder>.Acquire();
EssgeeLogger.Assert(builder.Length == 0, $"A pooled {nameof(StringBuilder)} is not empty." + NotClearError);
return builder;
}
/// <summary>
/// 回收 StringBuilder
/// </summary>
public static void Release(StringBuilder builder)
{
builder.Length = 0;
ObjectPool<StringBuilder>.Release(builder);
}
/// <summary>
/// 回收 StringBuilder
/// </summary>
public static string ReleaseToString(this StringBuilder builder)
{
var result = builder.ToString();
Release(builder);
return result;
}
/************************************************************************************************************************/
private static class Cache<T>
{
public static readonly Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>
Results = new Dictionary<MethodInfo, KeyValuePair<Func<T>, T>>();
}
/// <summary>
/// 此方法主要用于频繁绘制缓存比如说GUI绘制
/// </summary>
public static T GetCachedResult<T>(Func<T> function)
{
var method = function.Method;
if (!Cache<T>.Results.TryGetValue(method, out var result))
{
result = new KeyValuePair<Func<T>, T>(function, function());
Cache<T>.Results.Add(method, result);
}
else if (result.Key != function)
{
EssgeeLogger.WriteLine(
$"{nameof(GetCachedResult)}<{typeof(T).Name}>" +
$" was previously called on {method.Name} with a different target." +
" This likely means that a new delegate is being passed into every call" +
" so it can't actually return the same cached object.");
}
return result.Value;
}
/************************************************************************************************************************/
public static class Disposable
{
/************************************************************************************************************************/
/// <summary>
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
/// </summary>
public static IDisposable Acquire<T>(out T item)
where T : class, new()
=> ObjectPool<T>.Disposable.Acquire(out item);
/************************************************************************************************************************/
/// <summary>
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="List{T}"/> if
/// </summary>
public static IDisposable AcquireList<T>(out List<T> list)
{
var disposable = ObjectPool<List<T>>.Disposable.Acquire(out list, onRelease: (l) => l.Clear());
EssgeeLogger.Assert(list.Count == 0, "A pooled list is not empty." + NotClearError);
return disposable;
}
/************************************************************************************************************************/
/// <summary>
/// Calls <see cref="ObjectPool{T}.Disposable.Acquire"/> to get a spare <see cref="HashSet{T}"/> if
/// </summary>
public static IDisposable AcquireSet<T>(out HashSet<T> set)
{
var disposable = ObjectPool<HashSet<T>>.Disposable.Acquire(out set, onRelease: (s) => s.Clear());
EssgeeLogger.Assert(set.Count == 0, "A pooled set is not empty." + NotClearError);
return disposable;
}
/************************************************************************************************************************/
}
/************************************************************************************************************************/
}
public static class ObjectPool<T> where T : class, new()
{
/************************************************************************************************************************/
private static readonly List<T>
Items = new List<T>();
/************************************************************************************************************************/
/// <summary>The number of spare items currently in the pool.</summary>
public static int Count
{
get => Items.Count;
set
{
var count = Items.Count;
if (count < value)
{
if (Items.Capacity < value)
Items.Capacity = NextPowerOfTwo(value);
do
{
Items.Add(new T());
count++;
}
while (count < value);
}
else if (count > value)
{
Items.RemoveRange(value, count - value);
}
}
}
public static int NextPowerOfTwo(int value)
{
if (value <= 0)
{
throw new ArgumentException("Value must be greater than zero.");
}
int powerOfTwo = 1;
while (powerOfTwo < value)
{
powerOfTwo <<= 1; // equivalent to multiplying by 2
}
return powerOfTwo;
}
/************************************************************************************************************************/
/// <summary>
/// If the <see cref="Count"/> is less than the specified value, this method increases it to that value by
/// creating new objects.
/// </summary>
public static void SetMinCount(int count)
{
if (Count < count)
Count = count;
}
/************************************************************************************************************************/
/// <summary>The <see cref="List{T}.Capacity"/> of the internal list of spare items.</summary>
public static int Capacity
{
get => Items.Capacity;
set
{
if (Items.Count > value)
Items.RemoveRange(value, Items.Count - value);
Items.Capacity = value;
}
}
/************************************************************************************************************************/
/// <summary>Returns a spare item if there are any, or creates a new one.</summary>
/// <remarks>Remember to <see cref="Release(T)"/> it when you are done.</remarks>
public static T Acquire()
{
var count = Items.Count;
if (count == 0)
{
return new T();
}
else
{
count--;
var item = Items[count];
Items.RemoveAt(count);
return item;
}
}
/************************************************************************************************************************/
/// <summary>Adds the `item` to the list of spares so it can be reused.</summary>
public static void Release(T item)
{
Items.Add(item);
}
/************************************************************************************************************************/
/// <summary>Returns a description of the state of this pool.</summary>
public static string GetDetails()
{
return
$"{typeof(T).Name}" +
$" ({nameof(Count)} = {Items.Count}" +
$", {nameof(Capacity)} = {Items.Capacity}" +
")";
}
/************************************************************************************************************************/
/// <summary>
/// An <see cref="IDisposable"/> system to allow pooled objects to be acquired and released within <c>using</c>
/// statements instead of needing to manually release everything.
/// </summary>
public sealed class Disposable : IDisposable
{
/************************************************************************************************************************/
private static readonly List<Disposable> LazyStack = new List<Disposable>();
private static int _ActiveDisposables;
private T _Item;
private Action<T> _OnRelease;
/************************************************************************************************************************/
private Disposable() { }
/// <summary>
/// Calls <see cref="ObjectPool{T}.Acquire"/> to set the `item` and returns an <see cref="IDisposable"/>
/// that will call <see cref="Release(T)"/> on the `item` when disposed.
/// </summary>
public static IDisposable Acquire(out T item, Action<T> onRelease = null)
{
Disposable disposable;
if (LazyStack.Count <= _ActiveDisposables)
{
LazyStack.Add(disposable = new Disposable());
}
else
{
disposable = LazyStack[_ActiveDisposables];
}
_ActiveDisposables++;
disposable._Item = item = ObjectPool<T>.Acquire();
disposable._OnRelease = onRelease;
return disposable;
}
/************************************************************************************************************************/
void IDisposable.Dispose()
{
_OnRelease?.Invoke(_Item);
Release(_Item);
_ActiveDisposables--;
}
/************************************************************************************************************************/
}
}

View File

@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 401c483d18aba7c45b7ae47fc4a5b19a

View File

@ -1,12 +1,8 @@
using System; using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Essgee.Utilities.XInput namespace Essgee.Utilities.XInput
{ {
public class Controller public class Controller
{ {
XInputState inputStatesCurrent, inputStatesPrev; XInputState inputStatesCurrent, inputStatesPrev;
bool timedVibrationEnabled; bool timedVibrationEnabled;
@ -64,17 +60,17 @@ namespace Essgee.Utilities.XInput
throw new Exception(string.Format("Error code {0}", (int)result)); throw new Exception(string.Format("Error code {0}", (int)result));
} }
public ControllerState GetControllerState() //public ControllerState GetControllerState()
{ //{
return new ControllerState // return new ControllerState
{ // {
Buttons = inputStatesCurrent.Gamepad.Buttons, // Buttons = inputStatesCurrent.Gamepad.Buttons,
LeftThumbstick = new ThumbstickPosition(inputStatesCurrent.Gamepad.sThumbLX / 32768.0f, inputStatesCurrent.Gamepad.sThumbLY / 32768.0f), // 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), // RightThumbstick = new ThumbstickPosition(inputStatesCurrent.Gamepad.sThumbRX / 32768.0f, inputStatesCurrent.Gamepad.sThumbRY / 32768.0f),
LeftTrigger = (inputStatesCurrent.Gamepad.bLeftTrigger / 255.0f), // LeftTrigger = (inputStatesCurrent.Gamepad.bLeftTrigger / 255.0f),
RightTrigger = (inputStatesCurrent.Gamepad.bRightTrigger / 255.0f) // RightTrigger = (inputStatesCurrent.Gamepad.bRightTrigger / 255.0f)
}; // };
} //}
public bool IsDPadUpPressed() public bool IsDPadUpPressed()
{ {

View File

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

View File

@ -39,8 +39,8 @@ public class Essgeeinit : MonoBehaviour
{ {
instance = this; instance = this;
InitAll(Application.streamingAssetsPath, Application.persistentDataPath); InitAll(Application.streamingAssetsPath, Application.persistentDataPath);
LoadAndRunCartridge("G:/Ninja_Gaiden_(UE)_type_A_[!].sms"); //LoadAndRunCartridge("G:/Ninja_Gaiden_(UE)_type_A_[!].sms");
//LoadAndRunCartridge("G:/SML2.gb"); LoadAndRunCartridge("G:/SML2.gb");
} }
void OnDisable() void OnDisable()
@ -605,7 +605,8 @@ 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.MouseButtons = default; e.MouseButtons = default;
e.MousePosition = default; e.MousePosition = default;

View File

@ -1,6 +1,4 @@
using Essgee.Emulation.Configuration; using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using UnityEngine; using UnityEngine;
@ -173,7 +171,7 @@ public class KeyCodeCore
Joypad2Button2 = MotionKey.NumPad3; Joypad2Button2 = MotionKey.NumPad3;
*/ */
dictKeyCfgs.Add(KeyCode.F12, machine.configuration.InputReset); //dictKeyCfgs.Add(KeyCode.F12, machine.configuration.InputReset);
dictKeyCfgs.Add(KeyCode.F1, machine.configuration.InputChangeMode); dictKeyCfgs.Add(KeyCode.F1, machine.configuration.InputChangeMode);
dictKeyCfgs.Add(KeyCode.F2, machine.configuration.InputPlayTape); dictKeyCfgs.Add(KeyCode.F2, machine.configuration.InputPlayTape);
@ -226,8 +224,8 @@ public class KeyCodeCore
dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down); dictKeyCfgs.Add(KeyCode.DownArrow, machine.configuration.Joypad2Down);
dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left); dictKeyCfgs.Add(KeyCode.LeftArrow, machine.configuration.Joypad2Left);
dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right); dictKeyCfgs.Add(KeyCode.RightAlt, machine.configuration.Joypad2Right);
dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button1); dictKeyCfgs.Add(KeyCode.Alpha1, machine.configuration.Joypad2Button2);
dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button2); dictKeyCfgs.Add(KeyCode.Alpha2, machine.configuration.Joypad2Button1);
} }
CheckList = dictKeyCfgs.Keys.ToArray(); CheckList = dictKeyCfgs.Keys.ToArray();