Input mapping support + Fourscore support + Turbo buttons

This commit is contained in:
Souryo 2015-07-10 21:07:24 -04:00
parent 0c91a15fa0
commit e70448820c
37 changed files with 2205 additions and 158 deletions

View file

@ -230,7 +230,7 @@ void Console::Run()
}
if(fpsTimer.GetElapsedMS() > 1000) {
uint32_t frameCount = _ppu->GetFrameCount();
uint32_t frameCount = PPU::GetFrameCount();
if((int32_t)frameCount - (int32_t)lastFrameCount < 0) {
Console::CurrentFPS = 0;
} else {

View file

@ -1,6 +1,8 @@
#include "stdafx.h"
#include "ControlManager.h"
unique_ptr<IKeyManager> ControlManager::_keyManager = nullptr;
IControlDevice* ControlManager::ControlDevices[] = { nullptr, nullptr, nullptr, nullptr };
IControlDevice* ControlManager::OriginalControlDevices[] = { nullptr, nullptr, nullptr, nullptr };
IGameBroadcaster* ControlManager::GameBroadcaster = nullptr;
@ -11,6 +13,43 @@ ControlManager::ControlManager()
}
void ControlManager::RegisterKeyManager(IKeyManager* keyManager)
{
_keyManager.reset(keyManager);
}
bool ControlManager::IsKeyPressed(uint32_t keyCode)
{
if(_keyManager != nullptr) {
return _keyManager->IsKeyPressed(keyCode);
}
return false;
}
uint32_t ControlManager::GetPressedKey()
{
if(_keyManager != nullptr) {
return _keyManager->GetPressedKey();
}
return 0;
}
wchar_t* ControlManager::GetKeyName(uint32_t keyCode)
{
if(_keyManager != nullptr) {
return _keyManager->GetKeyName(keyCode);
}
return 0;
}
uint32_t ControlManager::GetKeyCode(wchar_t* keyName)
{
if(_keyManager != nullptr) {
return _keyManager->GetKeyCode(keyName);
}
return 0;
}
void ControlManager::RegisterBroadcaster(IGameBroadcaster* gameBroadcaster)
{
ControlManager::GameBroadcaster = gameBroadcaster;
@ -68,43 +107,69 @@ void ControlManager::RefreshAllPorts()
{
RefreshStateBuffer(0);
RefreshStateBuffer(1);
RefreshStateBuffer(2);
RefreshStateBuffer(3);
}
void ControlManager::RefreshStateBuffer(uint8_t port)
uint8_t ControlManager::GetControllerState(uint8_t controllerID)
{
if(port >= 4) {
throw exception("Invalid port");
}
ControlManager::ControllerLock[port].Acquire();
IControlDevice* controlDevice = ControlManager::ControlDevices[port];
ControlManager::ControllerLock[controllerID].Acquire();
IControlDevice* controlDevice = ControlManager::ControlDevices[controllerID];
uint8_t state;
if(Movie::Playing()) {
state = Movie::Instance->GetState(port);
state = Movie::Instance->GetState(controllerID);
} else {
if(controlDevice) {
_keyManager->RefreshState();
state = controlDevice->GetButtonState().ToByte();
} else {
state = 0x00;
}
}
ControlManager::ControllerLock[port].Release();
ControlManager::ControllerLock[controllerID].Release();
//Used when recording movies
Movie::Instance->RecordState(port, state);
Movie::Instance->RecordState(controllerID, state);
if(ControlManager::GameBroadcaster) {
ControlManager::GameBroadcaster->BroadcastInput(state, port);
//Used when acting as a game server
ControlManager::GameBroadcaster->BroadcastInput(state, controllerID);
}
return state;
}
bool ControlManager::HasFourScoreAdapter()
{
return ControlManager::ControlDevices[2] != nullptr || ControlManager::ControlDevices[3] != nullptr;
}
void ControlManager::RefreshStateBuffer(uint8_t port)
{
if(port >= 2) {
throw exception("Invalid port");
}
//First 8 bits : Gamepad 1/2
uint32_t state = GetControllerState(port);
if(HasFourScoreAdapter()) {
//Next 8 bits = Gamepad 3/4
state |= GetControllerState(port + 2) << 8;
//Last 8 bits = signature
//Signature for port 0 = 0x10, reversed bit order => 0x08
//Signature for port 1 = 0x20, reversed bit order => 0x04
state |= (port == 0 ? 0x08 : 0x04) << 16;
} else {
//"All subsequent reads will return D=1 on an authentic controller but may return D=0 on third party controllers."
state |= 0xFFFF00;
}
_stateBuffer[port] = state;
}
uint8_t ControlManager::GetPortValue(uint8_t port)
{
if(port >= 4) {
if(port >= 2) {
throw exception("Invalid port");
}
@ -116,7 +181,7 @@ uint8_t ControlManager::GetPortValue(uint8_t port)
_stateBuffer[port] >>= 1;
//"All subsequent reads will return D=1 on an authentic controller but may return D=0 on third party controllers."
_stateBuffer[port] |= 0x80;
_stateBuffer[port] |= 0x800000;
//"In the NES and Famicom, the top three (or five) bits are not driven, and so retain the bits of the previous byte on the bus.
//Usually this is the most significant byte of the address of the controller port - 0x40.
@ -152,6 +217,6 @@ void ControlManager::WriteRAM(uint16_t addr, uint8_t value)
void ControlManager::StreamState(bool saving)
{
StreamArray<uint8_t>(_stateBuffer, 4);
StreamArray<uint32_t>(_stateBuffer, 2);
Stream<bool>(_refreshState);
}

View file

@ -7,19 +7,23 @@
#include "IGameBroadcaster.h"
#include "Snapshotable.h"
#include "../Utilities/SimpleLock.h"
#include "IKeyManager.h"
class ControlManager : public Snapshotable, public IMemoryHandler
{
private:
static unique_ptr<IKeyManager> _keyManager;
static IControlDevice* ControlDevices[4];
static IControlDevice* OriginalControlDevices[4];
static IGameBroadcaster* GameBroadcaster;
static SimpleLock ControllerLock[4];
bool _refreshState = false;
uint8_t _stateBuffer[4];
uint32_t _stateBuffer[2];
void RefreshAllPorts();
uint8_t GetControllerState(uint8_t port);
bool ControlManager::HasFourScoreAdapter();
void RefreshStateBuffer(uint8_t port);
uint8_t GetPortValue(uint8_t port);
@ -32,6 +36,12 @@ class ControlManager : public Snapshotable, public IMemoryHandler
static void RegisterBroadcaster(IGameBroadcaster* gameBroadcaster);
static void UnregisterBroadcaster(IGameBroadcaster* gameBroadcaster);
static void RegisterKeyManager(IKeyManager* keyManager);
static bool IsKeyPressed(uint32_t keyCode);
static uint32_t GetPressedKey();
static wchar_t* GetKeyName(uint32_t keyCode);
static uint32_t GetKeyCode(wchar_t* keyName);
static void BackupControlDevices();
static void RestoreControlDevices();
static IControlDevice* GetControlDevice(uint8_t port);

View file

@ -275,11 +275,13 @@
<ClInclude Include="IAudioDevice.h" />
<ClInclude Include="IControlDevice.h" />
<ClInclude Include="IGameBroadcaster.h" />
<ClInclude Include="IKeyManager.h" />
<ClInclude Include="IMemoryHandler.h" />
<ClInclude Include="Console.h" />
<ClInclude Include="IMessageManager.h" />
<ClInclude Include="INotificationListener.h" />
<ClInclude Include="InputDataMessage.h" />
<ClInclude Include="StandardController.h" />
<ClInclude Include="MessageManager.h" />
<ClInclude Include="MessageType.h" />
<ClInclude Include="MMC2.h" />
@ -330,6 +332,7 @@
<ClCompile Include="GameConnection.cpp" />
<ClCompile Include="GameServer.cpp" />
<ClCompile Include="GameServerConnection.cpp" />
<ClCompile Include="StandardController.cpp" />
<ClCompile Include="MapperFactory.cpp" />
<ClCompile Include="MemoryManager.cpp" />
<ClCompile Include="MessageManager.cpp" />

View file

@ -218,6 +218,12 @@
<ClInclude Include="CheatManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IKeyManager.h">
<Filter>Header Files\Interfaces</Filter>
</ClInclude>
<ClInclude Include="StandardController.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="CPU.cpp">
@ -286,5 +292,8 @@
<ClCompile Include="CheatManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="StandardController.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

13
Core/IKeyManager.h Normal file
View file

@ -0,0 +1,13 @@
#pragma once
#include "stdafx.h"
class IKeyManager
{
public:
virtual void RefreshState() = 0;
virtual bool IsKeyPressed(uint32_t keyCode) = 0;
virtual uint32_t GetPressedKey() = 0;
virtual wchar_t* GetKeyName(uint32_t keyCode) = 0;
virtual uint32_t GetKeyCode(wchar_t* keyName) = 0;
};

View file

@ -204,9 +204,9 @@ class PPU : public IMemoryHandler, public Snapshotable
return _outputBuffer;
}
uint32_t GetFrameCount()
static uint32_t GetFrameCount()
{
return _frameCount;
return PPU::Instance->_frameCount;
}
static uint32_t GetFrameCycle()

View file

@ -0,0 +1,54 @@
#include "stdafx.h"
#include "StandardController.h"
#include "ControlManager.h"
#include "PPU.h"
StandardController::StandardController(uint8_t port)
{
ControlManager::RegisterControlDevice(this, port);
}
StandardController::~StandardController()
{
ControlManager::UnregisterControlDevice(this);
}
void StandardController::AddKeyMappings(KeyMapping keyMapping)
{
_keyMappings.push_back(keyMapping);
}
void StandardController::ClearKeyMappings()
{
_keyMappings.clear();
}
ButtonState StandardController::GetButtonState()
{
ButtonState state;
for(int i = 0, len = _keyMappings.size(); i < len; i++) {
KeyMapping keyMapping = _keyMappings[i];
state.A |= ControlManager::IsKeyPressed(keyMapping.A);
state.B |= ControlManager::IsKeyPressed(keyMapping.B);
state.Select |= ControlManager::IsKeyPressed(keyMapping.Select);
state.Start |= ControlManager::IsKeyPressed(keyMapping.Start);
state.Up |= ControlManager::IsKeyPressed(keyMapping.Up);
state.Down |= ControlManager::IsKeyPressed(keyMapping.Down);
state.Left |= ControlManager::IsKeyPressed(keyMapping.Left);
state.Right |= ControlManager::IsKeyPressed(keyMapping.Right);
//Turbo buttons - need to be applied for at least 2 reads in a row (some games require this)
uint8_t turboFreq = 1 << (4 - keyMapping.TurboSpeed);
bool turboOn = PPU::GetFrameCount() % turboFreq < turboFreq / 2;
if(turboOn) {
state.A |= ControlManager::IsKeyPressed(keyMapping.TurboA);
state.B |= ControlManager::IsKeyPressed(keyMapping.TurboB);
state.Start |= ControlManager::IsKeyPressed(keyMapping.TurboStart);
state.Select |= ControlManager::IsKeyPressed(keyMapping.TurboSelect);
}
}
return state;
}

37
Core/StandardController.h Normal file
View file

@ -0,0 +1,37 @@
#pragma once
#include "stdafx.h"
#include "IControlDevice.h"
struct KeyMapping
{
uint32_t A;
uint32_t B;
uint32_t Up;
uint32_t Down;
uint32_t Left;
uint32_t Right;
uint32_t Start;
uint32_t Select;
uint32_t TurboA;
uint32_t TurboB;
uint32_t TurboStart;
uint32_t TurboSelect;
uint32_t TurboSpeed;
};
class StandardController : public IControlDevice
{
private:
vector<KeyMapping> _keyMappings;
public:
StandardController(uint8_t port);
~StandardController();
void AddKeyMappings(KeyMapping keyMapping);
void ClearKeyMappings();
ButtonState GetButtonState();
};

View file

@ -17,6 +17,7 @@ namespace Mesen.GUI.Config
public ServerInfo ServerInfo;
public List<string> RecentFiles;
public List<CheatInfo> Cheats;
public List<ControllerInfo> Controllers;
public bool ShowOnlyCheatsForCurrentGame;
public Configuration()
@ -25,8 +26,18 @@ namespace Mesen.GUI.Config
ClientConnectionInfo = new ClientConnectionInfo();
ServerInfo = new ServerInfo();
RecentFiles = new List<string>();
Controllers = new List<ControllerInfo>();
}
private void InitializeDefaults()
{
while(Controllers.Count < 4) {
var controllerInfo = new ControllerInfo();
controllerInfo.ControllerType = Controllers.Count < 2 ? ControllerType.StandardController : ControllerType.None;
Controllers.Add(controllerInfo);
}
}
public void AddRecentFile(string filepath)
{
if(RecentFiles.Contains(filepath)) {
@ -41,10 +52,14 @@ namespace Mesen.GUI.Config
public static Configuration Deserialize(string configFile)
{
Configuration config;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Configuration));
using(TextReader textReader = new StreamReader(configFile)) {
return (Configuration)xmlSerializer.Deserialize(textReader);
config = (Configuration)xmlSerializer.Deserialize(textReader);
}
config.InitializeDefaults();
return config;
}
public void Serialize(string configFile)

View file

@ -0,0 +1,70 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Mesen.GUI.Config
{
public enum ControllerType
{
None = 0,
StandardController = 1,
}
public class KeyMappings
{
public string A = "A";
public string B = "B";
public string Select = "W";
public string Start = "Q";
public string Up = "Up Arrow";
public string Down = "Down Arrow";
public string Left = "Left Arrow";
public string Right = "Right Arrow";
public string TurboA = "Z";
public string TurboB = "X";
public string TurboStart = "";
public string TurboSelect = "";
public UInt32 TurboSpeed;
public InteropEmu.KeyMapping ToInteropMapping()
{
InteropEmu.KeyMapping mapping = new InteropEmu.KeyMapping();
mapping.A = InteropEmu.GetKeyCode(A);
mapping.B = InteropEmu.GetKeyCode(B);
mapping.Start = InteropEmu.GetKeyCode(Start);
mapping.Select = InteropEmu.GetKeyCode(Select);
mapping.Up = InteropEmu.GetKeyCode(Up);
mapping.Down = InteropEmu.GetKeyCode(Down);
mapping.Left = InteropEmu.GetKeyCode(Left);
mapping.Right = InteropEmu.GetKeyCode(Right);
mapping.TurboA = InteropEmu.GetKeyCode(TurboA);
mapping.TurboB = InteropEmu.GetKeyCode(TurboB);
mapping.TurboStart = InteropEmu.GetKeyCode(TurboStart);
mapping.TurboSelect = InteropEmu.GetKeyCode(TurboSelect);
mapping.TurboSpeed = TurboSpeed;
return mapping;
}
}
public class ControllerInfo
{
public ControllerType ControllerType = ControllerType.StandardController;
public KeyMappings Keys = new KeyMappings();
public static void ApplyConfig()
{
for(int i = 0; i < 4; i++) {
InteropEmu.ClearKeyMappings(i);
if(ConfigManager.Config.Controllers[i].ControllerType != ControllerType.None) {
InteropEmu.AddKeyMappings(i, ConfigManager.Config.Controllers[i].Keys.ToInteropMapping());
}
}
}
}
}

View file

@ -0,0 +1,106 @@
namespace Mesen.GUI.Forms.Config
{
partial class ctrlInputPortConfig
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.lblControllerType = new System.Windows.Forms.Label();
this.cboControllerType = new System.Windows.Forms.ComboBox();
this.ctrlStandardController = new Mesen.GUI.Forms.Config.ctrlStandardController();
this.tableLayoutPanel1.SuspendLayout();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 2;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Controls.Add(this.lblControllerType, 0, 0);
this.tableLayoutPanel1.Controls.Add(this.ctrlStandardController, 0, 1);
this.tableLayoutPanel1.Controls.Add(this.cboControllerType, 1, 0);
this.tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 2;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(618, 353);
this.tableLayoutPanel1.TabIndex = 1;
//
// lblControllerType
//
this.lblControllerType.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblControllerType.AutoSize = true;
this.lblControllerType.Location = new System.Drawing.Point(3, 7);
this.lblControllerType.Name = "lblControllerType";
this.lblControllerType.Size = new System.Drawing.Size(81, 13);
this.lblControllerType.TabIndex = 1;
this.lblControllerType.Text = "Controller Type:";
//
// cboControllerType
//
this.cboControllerType.Dock = System.Windows.Forms.DockStyle.Top;
this.cboControllerType.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.cboControllerType.FormattingEnabled = true;
this.cboControllerType.Items.AddRange(new object[] {
"None",
"Standard NES Controller"});
this.cboControllerType.Location = new System.Drawing.Point(90, 3);
this.cboControllerType.Name = "cboControllerType";
this.cboControllerType.Size = new System.Drawing.Size(525, 21);
this.cboControllerType.TabIndex = 2;
this.cboControllerType.SelectedIndexChanged += new System.EventHandler(this.cboControllerType_SelectedIndexChanged);
//
// ctrlStandardController
//
this.tableLayoutPanel1.SetColumnSpan(this.ctrlStandardController, 2);
this.ctrlStandardController.Location = new System.Drawing.Point(3, 30);
this.ctrlStandardController.Name = "ctrlStandardController";
this.ctrlStandardController.Size = new System.Drawing.Size(611, 320);
this.ctrlStandardController.TabIndex = 3;
//
// ctrlInputPortConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "ctrlInputPortConfig";
this.Size = new System.Drawing.Size(618, 353);
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.Label lblControllerType;
private System.Windows.Forms.ComboBox cboControllerType;
private ctrlStandardController ctrlStandardController;
}
}

View file

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
namespace Mesen.GUI.Forms.Config
{
public partial class ctrlInputPortConfig : UserControl
{
private ControllerInfo _controllerInfo;
public ctrlInputPortConfig()
{
InitializeComponent();
}
public void Initialize(ControllerInfo controllerInfo)
{
_controllerInfo = controllerInfo;
ctrlStandardController.Initialize(controllerInfo.Keys);
cboControllerType.SelectedIndex = (int)_controllerInfo.ControllerType;
}
public void UpdateConfig()
{
_controllerInfo.Keys = ctrlStandardController.GetKeyMappings();
_controllerInfo.ControllerType = (ControllerType)cboControllerType.SelectedIndex;
}
private void cboControllerType_SelectedIndexChanged(object sender, EventArgs e)
{
ctrlStandardController.Visible = ((ControllerType)cboControllerType.SelectedIndex == ControllerType.StandardController);
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -0,0 +1,292 @@
namespace Mesen.GUI.Forms.Config
{
partial class ctrlStandardController
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ctrlStandardController));
this.btnTurboB = new System.Windows.Forms.Button();
this.btnSelect = new System.Windows.Forms.Button();
this.btnTurboA = new System.Windows.Forms.Button();
this.btnStart = new System.Windows.Forms.Button();
this.btnDown = new System.Windows.Forms.Button();
this.btnA = new System.Windows.Forms.Button();
this.btnUp = new System.Windows.Forms.Button();
this.btnB = new System.Windows.Forms.Button();
this.btnLeft = new System.Windows.Forms.Button();
this.btnRight = new System.Windows.Forms.Button();
this.picControllerLayout = new System.Windows.Forms.PictureBox();
this.tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
this.trkTurboSpeed = new System.Windows.Forms.TrackBar();
this.lblTurboSpeed = new System.Windows.Forms.Label();
this.panel1 = new System.Windows.Forms.Panel();
this.lblSlow = new System.Windows.Forms.Label();
this.lblTurboFast = new System.Windows.Forms.Label();
this.panel2 = new System.Windows.Forms.Panel();
((System.ComponentModel.ISupportInitialize)(this.picControllerLayout)).BeginInit();
this.tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.trkTurboSpeed)).BeginInit();
this.panel1.SuspendLayout();
this.panel2.SuspendLayout();
this.SuspendLayout();
//
// btnTurboB
//
this.btnTurboB.Location = new System.Drawing.Point(417, 43);
this.btnTurboB.Name = "btnTurboB";
this.btnTurboB.Size = new System.Drawing.Size(61, 59);
this.btnTurboB.TabIndex = 21;
this.btnTurboB.Text = "B";
this.btnTurboB.UseVisualStyleBackColor = true;
this.btnTurboB.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnSelect
//
this.btnSelect.Location = new System.Drawing.Point(234, 166);
this.btnSelect.Name = "btnSelect";
this.btnSelect.Size = new System.Drawing.Size(61, 37);
this.btnSelect.TabIndex = 12;
this.btnSelect.Text = "Q";
this.btnSelect.UseVisualStyleBackColor = true;
this.btnSelect.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnTurboA
//
this.btnTurboA.Location = new System.Drawing.Point(499, 43);
this.btnTurboA.Name = "btnTurboA";
this.btnTurboA.Size = new System.Drawing.Size(61, 59);
this.btnTurboA.TabIndex = 20;
this.btnTurboA.Text = "A";
this.btnTurboA.UseVisualStyleBackColor = true;
this.btnTurboA.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnStart
//
this.btnStart.Location = new System.Drawing.Point(315, 166);
this.btnStart.Name = "btnStart";
this.btnStart.Size = new System.Drawing.Size(61, 37);
this.btnStart.TabIndex = 13;
this.btnStart.Text = "W";
this.btnStart.UseVisualStyleBackColor = true;
this.btnStart.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnDown
//
this.btnDown.Location = new System.Drawing.Point(88, 177);
this.btnDown.Name = "btnDown";
this.btnDown.Size = new System.Drawing.Size(50, 35);
this.btnDown.TabIndex = 19;
this.btnDown.Text = "Down";
this.btnDown.UseVisualStyleBackColor = true;
this.btnDown.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnA
//
this.btnA.Location = new System.Drawing.Point(499, 155);
this.btnA.Name = "btnA";
this.btnA.Size = new System.Drawing.Size(61, 59);
this.btnA.TabIndex = 14;
this.btnA.Text = "A";
this.btnA.UseVisualStyleBackColor = true;
this.btnA.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnUp
//
this.btnUp.Location = new System.Drawing.Point(88, 95);
this.btnUp.Name = "btnUp";
this.btnUp.Size = new System.Drawing.Size(50, 35);
this.btnUp.TabIndex = 18;
this.btnUp.Text = "Up";
this.btnUp.UseVisualStyleBackColor = true;
this.btnUp.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnB
//
this.btnB.Location = new System.Drawing.Point(417, 155);
this.btnB.Name = "btnB";
this.btnB.Size = new System.Drawing.Size(61, 59);
this.btnB.TabIndex = 15;
this.btnB.Text = "B";
this.btnB.UseVisualStyleBackColor = true;
this.btnB.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnLeft
//
this.btnLeft.Location = new System.Drawing.Point(53, 136);
this.btnLeft.Name = "btnLeft";
this.btnLeft.Size = new System.Drawing.Size(50, 35);
this.btnLeft.TabIndex = 17;
this.btnLeft.Text = "Left";
this.btnLeft.UseVisualStyleBackColor = true;
this.btnLeft.Click += new System.EventHandler(this.btnMapping_Click);
//
// btnRight
//
this.btnRight.Location = new System.Drawing.Point(123, 136);
this.btnRight.Name = "btnRight";
this.btnRight.Size = new System.Drawing.Size(50, 35);
this.btnRight.TabIndex = 16;
this.btnRight.Text = "Right";
this.btnRight.UseVisualStyleBackColor = true;
this.btnRight.Click += new System.EventHandler(this.btnMapping_Click);
//
// picControllerLayout
//
this.picControllerLayout.Image = ((System.Drawing.Image)(resources.GetObject("picControllerLayout.Image")));
this.picControllerLayout.Location = new System.Drawing.Point(-8, -12);
this.picControllerLayout.Name = "picControllerLayout";
this.picControllerLayout.Size = new System.Drawing.Size(629, 292);
this.picControllerLayout.TabIndex = 11;
this.picControllerLayout.TabStop = false;
//
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 3;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.tableLayoutPanel1.Controls.Add(this.trkTurboSpeed, 2, 1);
this.tableLayoutPanel1.Controls.Add(this.lblTurboSpeed, 1, 1);
this.tableLayoutPanel1.Controls.Add(this.panel1, 2, 2);
this.tableLayoutPanel1.Controls.Add(this.panel2, 0, 0);
this.tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.tableLayoutPanel1.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 3;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 32F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.tableLayoutPanel1.Size = new System.Drawing.Size(613, 316);
this.tableLayoutPanel1.TabIndex = 22;
//
// trkTurboSpeed
//
this.trkTurboSpeed.LargeChange = 2;
this.trkTurboSpeed.Location = new System.Drawing.Point(493, 272);
this.trkTurboSpeed.Maximum = 3;
this.trkTurboSpeed.Name = "trkTurboSpeed";
this.trkTurboSpeed.Size = new System.Drawing.Size(117, 26);
this.trkTurboSpeed.TabIndex = 0;
//
// lblTurboSpeed
//
this.lblTurboSpeed.Anchor = System.Windows.Forms.AnchorStyles.Left;
this.lblTurboSpeed.AutoSize = true;
this.lblTurboSpeed.Location = new System.Drawing.Point(415, 278);
this.lblTurboSpeed.Name = "lblTurboSpeed";
this.lblTurboSpeed.Size = new System.Drawing.Size(72, 13);
this.lblTurboSpeed.TabIndex = 1;
this.lblTurboSpeed.Text = "Turbo Speed:";
//
// panel1
//
this.panel1.Controls.Add(this.lblTurboFast);
this.panel1.Controls.Add(this.lblSlow);
this.panel1.Location = new System.Drawing.Point(490, 301);
this.panel1.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.panel1.Name = "panel1";
this.panel1.Size = new System.Drawing.Size(120, 15);
this.panel1.TabIndex = 2;
//
// lblSlow
//
this.lblSlow.AutoSize = true;
this.lblSlow.Location = new System.Drawing.Point(3, 0);
this.lblSlow.Name = "lblSlow";
this.lblSlow.Size = new System.Drawing.Size(30, 13);
this.lblSlow.TabIndex = 0;
this.lblSlow.Text = "Slow";
//
// lblTurboFast
//
this.lblTurboFast.AutoSize = true;
this.lblTurboFast.Location = new System.Drawing.Point(90, 0);
this.lblTurboFast.Name = "lblTurboFast";
this.lblTurboFast.Size = new System.Drawing.Size(27, 13);
this.lblTurboFast.TabIndex = 1;
this.lblTurboFast.Text = "Fast";
//
// panel2
//
this.tableLayoutPanel1.SetColumnSpan(this.panel2, 3);
this.panel2.Controls.Add(this.btnTurboB);
this.panel2.Controls.Add(this.btnRight);
this.panel2.Controls.Add(this.btnSelect);
this.panel2.Controls.Add(this.btnLeft);
this.panel2.Controls.Add(this.btnTurboA);
this.panel2.Controls.Add(this.btnB);
this.panel2.Controls.Add(this.btnStart);
this.panel2.Controls.Add(this.btnUp);
this.panel2.Controls.Add(this.btnDown);
this.panel2.Controls.Add(this.btnA);
this.panel2.Controls.Add(this.picControllerLayout);
this.panel2.Dock = System.Windows.Forms.DockStyle.Fill;
this.panel2.Location = new System.Drawing.Point(0, 0);
this.panel2.Margin = new System.Windows.Forms.Padding(0, 0, 0, 0);
this.panel2.Name = "panel2";
this.panel2.Size = new System.Drawing.Size(613, 269);
this.panel2.TabIndex = 3;
//
// ctrlStandardController
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel1);
this.Name = "ctrlStandardController";
this.Size = new System.Drawing.Size(612, 317);
((System.ComponentModel.ISupportInitialize)(this.picControllerLayout)).EndInit();
this.tableLayoutPanel1.ResumeLayout(false);
this.tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.trkTurboSpeed)).EndInit();
this.panel1.ResumeLayout(false);
this.panel1.PerformLayout();
this.panel2.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.Button btnTurboB;
private System.Windows.Forms.Button btnSelect;
private System.Windows.Forms.Button btnTurboA;
private System.Windows.Forms.Button btnStart;
private System.Windows.Forms.Button btnDown;
private System.Windows.Forms.Button btnA;
private System.Windows.Forms.Button btnUp;
private System.Windows.Forms.Button btnB;
private System.Windows.Forms.Button btnLeft;
private System.Windows.Forms.Button btnRight;
private System.Windows.Forms.PictureBox picControllerLayout;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.TrackBar trkTurboSpeed;
private System.Windows.Forms.Label lblTurboSpeed;
private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Label lblTurboFast;
private System.Windows.Forms.Label lblSlow;
private System.Windows.Forms.Panel panel2;
}
}

View file

@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
namespace Mesen.GUI.Forms.Config
{
public partial class ctrlStandardController : UserControl
{
public ctrlStandardController()
{
InitializeComponent();
}
public void Initialize(KeyMappings mappings)
{
btnA.Text = mappings.A;
btnB.Text = mappings.B;
btnStart.Text = mappings.Start;
btnSelect.Text = mappings.Select;
btnUp.Text = mappings.Up;
btnDown.Text = mappings.Down;
btnLeft.Text = mappings.Left;
btnRight.Text = mappings.Right;
btnTurboA.Text = mappings.TurboA;
btnTurboB.Text = mappings.TurboB;
trkTurboSpeed.Value = (Int32)mappings.TurboSpeed;
trkTurboSpeed.BackColor = Color.FromArgb(255, trkTurboSpeed.Parent.BackColor);
}
private void btnMapping_Click(object sender, EventArgs e)
{
frmGetKey frm = new frmGetKey();
frm.ShowDialog();
((Button)sender).Text = frm.BindedKey;
}
public KeyMappings GetKeyMappings()
{
KeyMappings mappings = new KeyMappings() {
A = btnA.Text,
B = btnB.Text,
Start = btnStart.Text,
Select = btnSelect.Text,
Up = btnUp.Text,
Down = btnDown.Text,
Left = btnLeft.Text,
Right = btnRight.Text,
TurboA = btnTurboA.Text,
TurboB = btnTurboB.Text,
TurboSelect = string.Empty,
TurboStart = string.Empty,
TurboSpeed = (UInt32)trkTurboSpeed.Value
};
return mappings;
}
}
}

View file

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="picControllerLayout.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
KuYPLuZfrE1Fv6zbg29c3E9TB6/Ycn7XMM8nMZlMim9BhabuMeNhm7pW8damo+LDaur6ityf09ylrlH2
3NT1y8m9xv0yc1+dfH7v4Nl93mjqKvr9in0V9em9bxV9nz9d3KfX5s/Lv62v6vW/L34IokJTB6/Ycn7X
MM8nMZlMim9BxfPmnuZfAxHj+Xl/uvUBIq3tXlW8temoODYDfzzzo7P5XrNrTV03Jeef+9ll7j/KG+8R
Syp23dS1in55+dulG7BuvF78QEpFr+NlU/e18tzEVbxxVbWi16bXtd9L1++765deP3+cP7ufpg5eseX8
rmGeT2IymRTfggpN3WPGQzd1rSI2HRXHZqD/PXp+X1fF+zV1/cMS55/7sWWum5GHaeqOKvonibuB/vlF
PjV1vXb9XPQ6HvVL1s9XP3vc+bPbPyu/P94+y/fa90BTB6/Qcn7XMM8nMZlMim9BhabuMePhm7qjihdN
R8VTM3B+n3MV79fUve3l1++Wh3j59VLFz8svL3IvmrqK/pUu3cB1vn9w5aivpPbVz48u97ts6o4/UPGV
Y27Ja+rgFVvO7xrm+SQmk0nxLah43tzT/GsgYjw/70+3PkCktX0tKp6bjooPq6n7YunBq/5BiYr+6dVu
YD+93O6Xursp+87F/Xodz5uzvmrazfXle+M+WXrwteX2G2tT8btyeSVQUwev2HJ+1zDPJzGZTIpvQYWm
7jHjYZu6iqtNR8VzM3Dh+MuHe826+Tife/rlwBXd1PXLgedz538poef7a/UVqH6/2GdK13t+z95yvz03
df19dZPVN1pfffthuF9/3+dNXb8/7unXzFyq+FX5xTJOTd03S3+dj5/ljk20pg5eoeX8rmGeT2IymRTf
gornzT3NvwYixvPz/nTrA0Ra2z2quNp0VHSTd5w793SFraKvKF3O/WqZ+8VZ7uj/n9Xun+7sH5joN/cf
57uZefrFxmf368blqeZeVRz/QsbTy6YA71LF0/+hl/lrYjKZFN+CCk3dY8bDNnVHFXdtOir6vXy7+vNf
AFtR0R9qmOeTmEwmxbegQlP3mPHwTR0A+9Xb0mFryvNJTCaT4ltQoal7zNDUAbBbvS0dtqY8n8RkMim+
BRWauscMTR0Au9Xb0mFryvNJTCaT4ltQoal7zNDUAbBbvS0dtqY8n8RkMim+BRWauscMTR0Au9Xb0mFr
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
</value>
</data>
</root>

View file

@ -0,0 +1,83 @@
namespace Mesen.GUI.Forms.Config
{
partial class frmGetKey
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.lblSetKeyMessage = new System.Windows.Forms.Label();
this.tmrCheckKey = new System.Windows.Forms.Timer(this.components);
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
this.groupBox1.Controls.Add(this.lblSetKeyMessage);
this.groupBox1.Location = new System.Drawing.Point(4, -1);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(369, 102);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
//
// lblSetKeyMessage
//
this.lblSetKeyMessage.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblSetKeyMessage.Location = new System.Drawing.Point(3, 16);
this.lblSetKeyMessage.Name = "lblSetKeyMessage";
this.lblSetKeyMessage.Size = new System.Drawing.Size(363, 83);
this.lblSetKeyMessage.TabIndex = 0;
this.lblSetKeyMessage.Text = "Press any key on your keyboard or controller to set a new binding.";
this.lblSetKeyMessage.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// tmrCheckKey
//
this.tmrCheckKey.Enabled = true;
this.tmrCheckKey.Interval = 10;
this.tmrCheckKey.Tick += new System.EventHandler(this.tmrCheckKey_Tick);
//
// frmGetKey
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(377, 104);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "frmGetKey";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Set key binding...";
this.groupBox1.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label lblSetKeyMessage;
private System.Windows.Forms.Timer tmrCheckKey;
}
}

View file

@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Mesen.GUI.Forms.Config
{
public partial class frmGetKey : BaseForm
{
public frmGetKey()
{
InitializeComponent();
}
public string BindedKey { get; set; }
private void tmrCheckKey_Tick(object sender, EventArgs e)
{
string pressedKey = InteropEmu.GetKeyName(InteropEmu.GetPressedKey());
if(!string.IsNullOrWhiteSpace(pressedKey)) {
BindedKey = pressedKey;
this.Close();
}
}
}
}

View file

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="tmrCheckKey.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View file

@ -0,0 +1,177 @@
namespace Mesen.GUI.Forms.Config
{
partial class frmInputConfig
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if(disposing && (components != null)) {
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.tabMain = new System.Windows.Forms.TabControl();
this.tpgPort1 = new System.Windows.Forms.TabPage();
this.ctrlInputPortConfig1 = new Mesen.GUI.Forms.Config.ctrlInputPortConfig();
this.tpgPort2 = new System.Windows.Forms.TabPage();
this.ctrlInputPortConfig2 = new Mesen.GUI.Forms.Config.ctrlInputPortConfig();
this.tpgPort3 = new System.Windows.Forms.TabPage();
this.ctrlInputPortConfig3 = new Mesen.GUI.Forms.Config.ctrlInputPortConfig();
this.tpgPort4 = new System.Windows.Forms.TabPage();
this.ctrlInputPortConfig4 = new Mesen.GUI.Forms.Config.ctrlInputPortConfig();
this.tpgEmulatorKeys = new System.Windows.Forms.TabPage();
this.tabMain.SuspendLayout();
this.tpgPort1.SuspendLayout();
this.tpgPort2.SuspendLayout();
this.tpgPort3.SuspendLayout();
this.tpgPort4.SuspendLayout();
this.SuspendLayout();
//
// tabMain
//
this.tabMain.Controls.Add(this.tpgPort1);
this.tabMain.Controls.Add(this.tpgPort2);
this.tabMain.Controls.Add(this.tpgPort3);
this.tabMain.Controls.Add(this.tpgPort4);
this.tabMain.Controls.Add(this.tpgEmulatorKeys);
this.tabMain.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabMain.Location = new System.Drawing.Point(0, 0);
this.tabMain.Name = "tabMain";
this.tabMain.SelectedIndex = 0;
this.tabMain.Size = new System.Drawing.Size(633, 376);
this.tabMain.TabIndex = 11;
//
// tpgPort1
//
this.tpgPort1.Controls.Add(this.ctrlInputPortConfig1);
this.tpgPort1.Location = new System.Drawing.Point(4, 22);
this.tpgPort1.Name = "tpgPort1";
this.tpgPort1.Size = new System.Drawing.Size(625, 350);
this.tpgPort1.TabIndex = 0;
this.tpgPort1.Text = "Port 1";
this.tpgPort1.UseVisualStyleBackColor = true;
//
// ctrlInputPortConfig1
//
this.ctrlInputPortConfig1.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlInputPortConfig1.Location = new System.Drawing.Point(0, 0);
this.ctrlInputPortConfig1.Margin = new System.Windows.Forms.Padding(0);
this.ctrlInputPortConfig1.Name = "ctrlInputPortConfig1";
this.ctrlInputPortConfig1.Size = new System.Drawing.Size(625, 350);
this.ctrlInputPortConfig1.TabIndex = 0;
//
// tpgPort2
//
this.tpgPort2.Controls.Add(this.ctrlInputPortConfig2);
this.tpgPort2.Location = new System.Drawing.Point(4, 22);
this.tpgPort2.Name = "tpgPort2";
this.tpgPort2.Size = new System.Drawing.Size(625, 359);
this.tpgPort2.TabIndex = 1;
this.tpgPort2.Text = "Port 2";
this.tpgPort2.UseVisualStyleBackColor = true;
//
// ctrlInputPortConfig2
//
this.ctrlInputPortConfig2.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlInputPortConfig2.Location = new System.Drawing.Point(0, 0);
this.ctrlInputPortConfig2.Name = "ctrlInputPortConfig2";
this.ctrlInputPortConfig2.Size = new System.Drawing.Size(625, 359);
this.ctrlInputPortConfig2.TabIndex = 1;
//
// tpgPort3
//
this.tpgPort3.Controls.Add(this.ctrlInputPortConfig3);
this.tpgPort3.Location = new System.Drawing.Point(4, 22);
this.tpgPort3.Name = "tpgPort3";
this.tpgPort3.Size = new System.Drawing.Size(625, 359);
this.tpgPort3.TabIndex = 2;
this.tpgPort3.Text = "Port 3";
this.tpgPort3.UseVisualStyleBackColor = true;
//
// ctrlInputPortConfig3
//
this.ctrlInputPortConfig3.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlInputPortConfig3.Location = new System.Drawing.Point(0, 0);
this.ctrlInputPortConfig3.Name = "ctrlInputPortConfig3";
this.ctrlInputPortConfig3.Size = new System.Drawing.Size(625, 359);
this.ctrlInputPortConfig3.TabIndex = 1;
//
// tpgPort4
//
this.tpgPort4.Controls.Add(this.ctrlInputPortConfig4);
this.tpgPort4.Location = new System.Drawing.Point(4, 22);
this.tpgPort4.Name = "tpgPort4";
this.tpgPort4.Size = new System.Drawing.Size(625, 359);
this.tpgPort4.TabIndex = 3;
this.tpgPort4.Text = "Port 4";
this.tpgPort4.UseVisualStyleBackColor = true;
//
// ctrlInputPortConfig4
//
this.ctrlInputPortConfig4.Dock = System.Windows.Forms.DockStyle.Fill;
this.ctrlInputPortConfig4.Location = new System.Drawing.Point(0, 0);
this.ctrlInputPortConfig4.Margin = new System.Windows.Forms.Padding(0);
this.ctrlInputPortConfig4.Name = "ctrlInputPortConfig4";
this.ctrlInputPortConfig4.Size = new System.Drawing.Size(625, 359);
this.ctrlInputPortConfig4.TabIndex = 1;
//
// tpgEmulatorKeys
//
this.tpgEmulatorKeys.Location = new System.Drawing.Point(4, 22);
this.tpgEmulatorKeys.Name = "tpgEmulatorKeys";
this.tpgEmulatorKeys.Size = new System.Drawing.Size(625, 359);
this.tpgEmulatorKeys.TabIndex = 4;
this.tpgEmulatorKeys.Text = "Emulator Keys";
this.tpgEmulatorKeys.UseVisualStyleBackColor = true;
//
// frmInputConfig
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(633, 406);
this.Controls.Add(this.tabMain);
this.Name = "frmInputConfig";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Input Settings";
this.Controls.SetChildIndex(this.tabMain, 0);
this.tabMain.ResumeLayout(false);
this.tpgPort1.ResumeLayout(false);
this.tpgPort2.ResumeLayout(false);
this.tpgPort3.ResumeLayout(false);
this.tpgPort4.ResumeLayout(false);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.TabControl tabMain;
private System.Windows.Forms.TabPage tpgPort2;
private System.Windows.Forms.TabPage tpgPort3;
private System.Windows.Forms.TabPage tpgPort4;
private System.Windows.Forms.TabPage tpgEmulatorKeys;
private System.Windows.Forms.TabPage tpgPort1;
private ctrlInputPortConfig ctrlInputPortConfig1;
private ctrlInputPortConfig ctrlInputPortConfig2;
private ctrlInputPortConfig ctrlInputPortConfig3;
private ctrlInputPortConfig ctrlInputPortConfig4;
}
}

View file

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Mesen.GUI.Config;
namespace Mesen.GUI.Forms.Config
{
public partial class frmInputConfig : BaseConfigForm
{
public frmInputConfig()
{
InitializeComponent();
ctrlInputPortConfig1.Initialize(ConfigManager.Config.Controllers[0]);
ctrlInputPortConfig2.Initialize(ConfigManager.Config.Controllers[1]);
ctrlInputPortConfig3.Initialize(ConfigManager.Config.Controllers[2]);
ctrlInputPortConfig4.Initialize(ConfigManager.Config.Controllers[3]);
}
protected override void UpdateConfig()
{
ctrlInputPortConfig1.UpdateConfig();
ctrlInputPortConfig2.UpdateConfig();
ctrlInputPortConfig3.UpdateConfig();
ctrlInputPortConfig4.UpdateConfig();
ControllerInfo.ApplyConfig();
}
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -51,7 +51,7 @@
this.mnuLimitFPS = new System.Windows.Forms.ToolStripMenuItem();
this.mnuShowFPS = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();
this.mnuInputDevices = new System.Windows.Forms.ToolStripMenuItem();
this.mnuInput = new System.Windows.Forms.ToolStripMenuItem();
this.mnuVideoConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuAudioConfig = new System.Windows.Forms.ToolStripMenuItem();
this.mnuTools = new System.Windows.Forms.ToolStripMenuItem();
@ -114,49 +114,49 @@
//
this.mnuOpen.Name = "mnuOpen";
this.mnuOpen.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.O)));
this.mnuOpen.Size = new System.Drawing.Size(152, 22);
this.mnuOpen.Size = new System.Drawing.Size(146, 22);
this.mnuOpen.Text = "Open";
this.mnuOpen.Click += new System.EventHandler(this.mnuOpen_Click);
//
// toolStripMenuItem4
//
this.toolStripMenuItem4.Name = "toolStripMenuItem4";
this.toolStripMenuItem4.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem4.Size = new System.Drawing.Size(143, 6);
//
// mnuSaveState
//
this.mnuSaveState.Name = "mnuSaveState";
this.mnuSaveState.Size = new System.Drawing.Size(152, 22);
this.mnuSaveState.Size = new System.Drawing.Size(146, 22);
this.mnuSaveState.Text = "Save State";
this.mnuSaveState.DropDownOpening += new System.EventHandler(this.mnuSaveState_DropDownOpening);
//
// mnuLoadState
//
this.mnuLoadState.Name = "mnuLoadState";
this.mnuLoadState.Size = new System.Drawing.Size(152, 22);
this.mnuLoadState.Size = new System.Drawing.Size(146, 22);
this.mnuLoadState.Text = "Load State";
this.mnuLoadState.DropDownOpening += new System.EventHandler(this.mnuLoadState_DropDownOpening);
//
// toolStripMenuItem7
//
this.toolStripMenuItem7.Name = "toolStripMenuItem7";
this.toolStripMenuItem7.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem7.Size = new System.Drawing.Size(143, 6);
//
// mnuRecentFiles
//
this.mnuRecentFiles.Name = "mnuRecentFiles";
this.mnuRecentFiles.Size = new System.Drawing.Size(152, 22);
this.mnuRecentFiles.Size = new System.Drawing.Size(146, 22);
this.mnuRecentFiles.Text = "Recent Files";
//
// toolStripMenuItem6
//
this.toolStripMenuItem6.Name = "toolStripMenuItem6";
this.toolStripMenuItem6.Size = new System.Drawing.Size(149, 6);
this.toolStripMenuItem6.Size = new System.Drawing.Size(143, 6);
//
// mnuExit
//
this.mnuExit.Name = "mnuExit";
this.mnuExit.Size = new System.Drawing.Size(152, 22);
this.mnuExit.Size = new System.Drawing.Size(146, 22);
this.mnuExit.Text = "Exit";
this.mnuExit.Click += new System.EventHandler(this.mnuExit_Click);
//
@ -201,7 +201,7 @@
this.mnuLimitFPS,
this.mnuShowFPS,
this.toolStripMenuItem1,
this.mnuInputDevices,
this.mnuInput,
this.mnuVideoConfig,
this.mnuAudioConfig});
this.mnuOptions.Name = "mnuOptions";
@ -214,7 +214,7 @@
this.mnuLimitFPS.CheckState = System.Windows.Forms.CheckState.Checked;
this.mnuLimitFPS.Name = "mnuLimitFPS";
this.mnuLimitFPS.ShortcutKeys = System.Windows.Forms.Keys.F9;
this.mnuLimitFPS.Size = new System.Drawing.Size(150, 22);
this.mnuLimitFPS.Size = new System.Drawing.Size(152, 22);
this.mnuLimitFPS.Text = "Limit FPS";
this.mnuLimitFPS.Click += new System.EventHandler(this.mnuLimitFPS_Click);
//
@ -222,27 +222,27 @@
//
this.mnuShowFPS.Name = "mnuShowFPS";
this.mnuShowFPS.ShortcutKeys = System.Windows.Forms.Keys.F10;
this.mnuShowFPS.Size = new System.Drawing.Size(150, 22);
this.mnuShowFPS.Size = new System.Drawing.Size(152, 22);
this.mnuShowFPS.Text = "Show FPS";
this.mnuShowFPS.Click += new System.EventHandler(this.mnuShowFPS_Click);
//
// toolStripMenuItem1
//
this.toolStripMenuItem1.Name = "toolStripMenuItem1";
this.toolStripMenuItem1.Size = new System.Drawing.Size(147, 6);
this.toolStripMenuItem1.Size = new System.Drawing.Size(149, 6);
//
// mnuInputDevices
// mnuInput
//
this.mnuInputDevices.Enabled = false;
this.mnuInputDevices.Name = "mnuInputDevices";
this.mnuInputDevices.Size = new System.Drawing.Size(150, 22);
this.mnuInputDevices.Text = "Input Devices";
this.mnuInput.Name = "mnuInput";
this.mnuInput.Size = new System.Drawing.Size(152, 22);
this.mnuInput.Text = "Input";
this.mnuInput.Click += new System.EventHandler(this.mnuInput_Click);
//
// mnuVideoConfig
//
this.mnuVideoConfig.Enabled = false;
this.mnuVideoConfig.Name = "mnuVideoConfig";
this.mnuVideoConfig.Size = new System.Drawing.Size(150, 22);
this.mnuVideoConfig.Size = new System.Drawing.Size(152, 22);
this.mnuVideoConfig.Text = "Video";
this.mnuVideoConfig.Click += new System.EventHandler(this.mnuVideoConfig_Click);
//
@ -250,7 +250,7 @@
//
this.mnuAudioConfig.Enabled = false;
this.mnuAudioConfig.Name = "mnuAudioConfig";
this.mnuAudioConfig.Size = new System.Drawing.Size(150, 22);
this.mnuAudioConfig.Size = new System.Drawing.Size(152, 22);
this.mnuAudioConfig.Text = "Audio";
//
// mnuTools
@ -471,7 +471,7 @@
private System.Windows.Forms.ToolStripMenuItem mnuLimitFPS;
private System.Windows.Forms.ToolStripMenuItem mnuShowFPS;
private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;
private System.Windows.Forms.ToolStripMenuItem mnuInputDevices;
private System.Windows.Forms.ToolStripMenuItem mnuInput;
private System.Windows.Forms.ToolStripMenuItem mnuVideoConfig;
private System.Windows.Forms.ToolStripMenuItem mnuAudioConfig;
private System.Windows.Forms.ToolStripMenuItem mnuTools;

View file

@ -12,6 +12,7 @@ using System.Windows.Forms;
using Mesen.GUI.Config;
using Mesen.GUI.Debugger;
using Mesen.GUI.Forms.Cheats;
using Mesen.GUI.Forms.Config;
using Mesen.GUI.Forms.NetPlay;
namespace Mesen.GUI.Forms
@ -48,8 +49,10 @@ namespace Mesen.GUI.Forms
foreach(string romPath in ConfigManager.Config.RecentFiles) {
InteropEmu.AddKnowGameFolder(System.IO.Path.GetDirectoryName(romPath).ToLowerInvariant());
}
InteropEmu.SetFlags((int)EmulationFlags.LimitFPS);
ControllerInfo.ApplyConfig();
InteropEmu.SetFlags((int)EmulationFlags.LimitFPS);
}
void Application_ThreadException(object sender, ThreadExceptionEventArgs e)
@ -381,5 +384,11 @@ namespace Mesen.GUI.Forms
CheatInfo.ApplyCheats();
};
}
private void mnuInput_Click(object sender, EventArgs e)
{
frmInputConfig frm = new frmInputConfig();
frm.ShowDialog();
}
}
}

View file

@ -75,6 +75,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Config\CheatInfo.cs" />
<Compile Include="Config\ControllerInfo.cs" />
<Compile Include="Config\ClientConnection.cs" />
<Compile Include="Config\Configuration.cs" />
<Compile Include="Config\ImageExtensions.cs" />
@ -132,6 +133,30 @@
<Compile Include="Forms\Cheats\frmCheat.Designer.cs">
<DependentUpon>frmCheat.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Config\ctrlInputPortConfig.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Forms\Config\ctrlInputPortConfig.Designer.cs">
<DependentUpon>ctrlInputPortConfig.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Config\ctrlStandardController.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Forms\Config\ctrlStandardController.Designer.cs">
<DependentUpon>ctrlStandardController.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Config\frmGetKey.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Config\frmGetKey.Designer.cs">
<DependentUpon>frmGetKey.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Config\frmInputConfig.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Forms\Config\frmInputConfig.Designer.cs">
<DependentUpon>frmInputConfig.cs</DependentUpon>
</Compile>
<Compile Include="Forms\Config\frmVideoConfig.cs">
<SubType>Form</SubType>
</Compile>
@ -189,6 +214,18 @@
<EmbeddedResource Include="Forms\Cheats\frmCheat.resx">
<DependentUpon>frmCheat.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\ctrlInputPortConfig.resx">
<DependentUpon>ctrlInputPortConfig.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\ctrlStandardController.resx">
<DependentUpon>ctrlStandardController.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\frmGetKey.resx">
<DependentUpon>frmGetKey.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\frmInputConfig.resx">
<DependentUpon>frmInputConfig.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\Config\frmVideoConfig.resx">
<DependentUpon>frmVideoConfig.cs</DependentUpon>
</EmbeddedResource>

View file

@ -18,6 +18,12 @@ namespace Mesen.GUI
[DllImport(DLLPath)] public static extern void LoadROM([MarshalAs(UnmanagedType.LPWStr)]string filename);
[DllImport(DLLPath)] public static extern void AddKnowGameFolder([MarshalAs(UnmanagedType.LPWStr)]string folder);
[DllImport(DLLPath)] public static extern void AddKeyMappings(int port, KeyMapping mapping);
[DllImport(DLLPath)] public static extern void ClearKeyMappings(int port);
[DllImport(DLLPath)] public static extern UInt32 GetPressedKey();
[DllImport(DLLPath)] public static extern UInt32 GetKeyCode([MarshalAs(UnmanagedType.LPWStr)]string keyName);
[DllImport(DLLPath, EntryPoint="GetKeyName")] private static extern IntPtr GetKeyNameWrapper(UInt32 key);
[DllImport(DLLPath)] public static extern void Run();
[DllImport(DLLPath)] public static extern void Pause();
[DllImport(DLLPath)] public static extern void Resume();
@ -73,6 +79,7 @@ namespace Mesen.GUI
public static string GetROMPath() { return Marshal.PtrToStringAuto(InteropEmu.GetROMPathWrapper()); }
public static string GetKeyName(UInt32 key) { return Marshal.PtrToStringAuto(InteropEmu.GetKeyNameWrapper(key)); }
public enum ConsoleNotificationType
@ -86,6 +93,23 @@ namespace Mesen.GUI
CodeBreak = 6,
}
public struct KeyMapping
{
public UInt32 A;
public UInt32 B;
public UInt32 Up;
public UInt32 Down;
public UInt32 Left;
public UInt32 Right;
public UInt32 Start;
public UInt32 Select;
public UInt32 TurboA;
public UInt32 TurboB;
public UInt32 TurboStart;
public UInt32 TurboSelect;
public UInt32 TurboSpeed;
}
public class NotificationEventArgs
{
public ConsoleNotificationType NotificationType;

View file

@ -4,16 +4,17 @@
#include "../Core/Console.h"
#include "../Windows/Renderer.h"
#include "../Windows/SoundManager.h"
#include "../Windows/InputManager.h"
#include "../Windows/WindowsKeyManager.h"
#include "../Core/GameServer.h"
#include "../Core/GameClient.h"
#include "../Core/ClientConnectionData.h"
#include "../Core/SaveStateManager.h"
#include "../Core/CheatManager.h"
#include "../Core/StandardController.h"
static NES::Renderer *_renderer = nullptr;
static SoundManager *_soundManager = nullptr;
static InputManager *_inputManager = nullptr;
static vector<shared_ptr<StandardController>> _inputDevices;
static HWND _windowHandle = nullptr;
static HWND _viewerHandle = nullptr;
static wstring _romFilename;
@ -49,13 +50,24 @@ namespace InteropEmu {
_renderer->SetFlags(NES::UIFlags::ShowFPS);
_soundManager = new SoundManager(_windowHandle);
_inputManager = new InputManager(_windowHandle, 0);
ControlManager::RegisterKeyManager(new WindowsKeyManager(_windowHandle));
for(int i = 0; i < 4; i++) {
_inputDevices.push_back(shared_ptr<StandardController>(new StandardController(i)));
}
}
DllExport void __stdcall LoadROM(wchar_t* filename) { Console::LoadROM(filename); }
DllExport void __stdcall AddKnowGameFolder(wchar_t* folder) { FolderUtilities::AddKnowGameFolder(folder); }
DllExport void __stdcall AddKeyMappings(uint32_t port, KeyMapping mapping) { _inputDevices[port]->AddKeyMappings(mapping); }
DllExport void __stdcall ClearKeyMappings(uint32_t port) { _inputDevices[port]->ClearKeyMappings(); }
DllExport uint32_t __stdcall GetPressedKey() { return ControlManager::GetPressedKey(); }
DllExport wchar_t* __stdcall GetKeyName(uint32_t keyCode) { return ControlManager::GetKeyName(keyCode); }
DllExport uint32_t __stdcall GetKeyCode(wchar_t* keyName) { return ControlManager::GetKeyCode(keyName); }
DllExport void __stdcall Run()
{
if(Console::GetInstance()) {
@ -115,7 +127,6 @@ namespace InteropEmu {
MessageManager::RegisterMessageManager(nullptr);
delete _renderer;
delete _soundManager;
delete _inputManager;
}
DllExport void __stdcall Render() { _renderer->Render(); }

View file

@ -141,7 +141,7 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;</AdditionalDependencies>
<AdditionalDependencies>Xinput9_1_0.lib;d3d11.lib;d3dcompiler.lib;dxguid.lib;winmm.lib;comctl32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">

View file

@ -3,34 +3,39 @@
GamePad::GamePad()
{
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
_gamePadStates.push_back(shared_ptr<XINPUT_STATE>(new XINPUT_STATE()));
}
}
bool GamePad::RefreshState()
void GamePad::RefreshState()
{
int controllerId = -1;
for(DWORD i = 0; i < XUSER_MAX_COUNT && controllerId == -1; i++) {
ZeroMemory(&_state, sizeof(XINPUT_STATE));
if(XInputGetState(i, &_state) == ERROR_SUCCESS) {
controllerId = i;
for(DWORD i = 0; i < XUSER_MAX_COUNT; i++) {
if(_gamePadStates[i] != nullptr) {
ZeroMemory(_gamePadStates[i].get(), sizeof(XINPUT_STATE));
if(XInputGetState(i, _gamePadStates[i].get()) != ERROR_SUCCESS) {
//XInputGetState is incredibly slow when no controller is plugged in
//TODO: Periodically detect if a controller has been plugged in to allow controllers to be plugged in after the emu is started
_gamePadStates[i] = nullptr;
}
}
}
return controllerId != -1;
}
bool GamePad::IsPressed(WORD button)
bool GamePad::IsPressed(uint8_t gamepadPort, WORD button)
{
RefreshState();
if(button == XINPUT_GAMEPAD_DPAD_LEFT && _state.Gamepad.sThumbLX < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_state.Gamepad.wButtons |= button;
} else if(button == XINPUT_GAMEPAD_DPAD_RIGHT && _state.Gamepad.sThumbLX > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_state.Gamepad.wButtons |= button;
} else if(button == XINPUT_GAMEPAD_DPAD_UP && _state.Gamepad.sThumbLY > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_state.Gamepad.wButtons |= button;
} else if(button == XINPUT_GAMEPAD_DPAD_DOWN && _state.Gamepad.sThumbLY < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_state.Gamepad.wButtons |= button;
if(_gamePadStates[gamepadPort] != nullptr) {
if(button == XINPUT_GAMEPAD_DPAD_LEFT && _gamePadStates[gamepadPort]->Gamepad.sThumbLX < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_gamePadStates[gamepadPort]->Gamepad.wButtons |= button;
} else if(button == XINPUT_GAMEPAD_DPAD_RIGHT && _gamePadStates[gamepadPort]->Gamepad.sThumbLX > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_gamePadStates[gamepadPort]->Gamepad.wButtons |= button;
} else if(button == XINPUT_GAMEPAD_DPAD_UP && _gamePadStates[gamepadPort]->Gamepad.sThumbLY > XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_gamePadStates[gamepadPort]->Gamepad.wButtons |= button;
} else if(button == XINPUT_GAMEPAD_DPAD_DOWN && _gamePadStates[gamepadPort]->Gamepad.sThumbLY < -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
_gamePadStates[gamepadPort]->Gamepad.wButtons |= button;
}
return (_gamePadStates[gamepadPort]->Gamepad.wButtons & button) != 0;
} else {
return false;
}
return (_state.Gamepad.wButtons & button) != 0;
}

View file

@ -6,12 +6,11 @@
class GamePad
{
private:
XINPUT_STATE _state;
bool RefreshState();
vector<shared_ptr<XINPUT_STATE>> _gamePadStates;
public:
GamePad();
bool IsPressed(WORD button);
void RefreshState();
bool IsPressed(uint8_t gamepadPort, WORD button);
};

View file

@ -1,54 +0,0 @@
#include "stdafx.h"
#include "InputManager.h"
#include "../Core/ControlManager.h"
InputManager::InputManager(HWND hWnd, uint8_t port)
{
_hWnd = hWnd;
_port = port;
ControlManager::RegisterControlDevice(this, port);
}
InputManager::~InputManager()
{
ControlManager::UnregisterControlDevice(this);
}
bool InputManager::IsKeyPressed(int key)
{
return (GetAsyncKeyState(key) & 0x8000) == 0x8000;
}
bool InputManager::WindowHasFocus()
{
return GetForegroundWindow() == _hWnd;
}
ButtonState InputManager::GetButtonState()
{
ButtonState state;
if(WindowHasFocus()) {
if(_port == 0) {
state.A = IsKeyPressed('A') || _gamePad.IsPressed(XINPUT_GAMEPAD_A);
state.B = IsKeyPressed('S') || _gamePad.IsPressed(XINPUT_GAMEPAD_X);
state.Select = IsKeyPressed('W') || _gamePad.IsPressed(XINPUT_GAMEPAD_BACK);
state.Start = IsKeyPressed('Q') || _gamePad.IsPressed(XINPUT_GAMEPAD_START);
state.Up = IsKeyPressed(VK_UP) || _gamePad.IsPressed(XINPUT_GAMEPAD_DPAD_UP);
state.Down = IsKeyPressed(VK_DOWN) || _gamePad.IsPressed(XINPUT_GAMEPAD_DPAD_DOWN);
state.Left = IsKeyPressed(VK_LEFT) || _gamePad.IsPressed(XINPUT_GAMEPAD_DPAD_LEFT);
state.Right = IsKeyPressed(VK_RIGHT) || _gamePad.IsPressed(XINPUT_GAMEPAD_DPAD_RIGHT);
} else {
state.A = IsKeyPressed('D');
state.B = IsKeyPressed('F');
state.Select = IsKeyPressed('R');
state.Start = IsKeyPressed('E');
state.Up = IsKeyPressed('U');
state.Down = IsKeyPressed('J');
state.Left = IsKeyPressed('H');
state.Right = IsKeyPressed('K');
}
}
return state;
}

View file

@ -1,21 +0,0 @@
#pragma once
#include "stdafx.h"
#include "..\Core\IControlDevice.h"
#include "GamePad.h"
class InputManager : public IControlDevice
{
private:
GamePad _gamePad;
HWND _hWnd;
uint8_t _port;
bool IsKeyPressed(int key);
bool WindowHasFocus();
public:
InputManager(HWND hWnd, uint8_t port);
~InputManager();
ButtonState GetButtonState();
};

View file

@ -225,7 +225,7 @@
<ClInclude Include="DirectXTK\WICTextureLoader.h" />
<ClInclude Include="DirectXTK\XboxDDSTextureLoader.h" />
<ClInclude Include="GamePad.h" />
<ClInclude Include="InputManager.h" />
<ClInclude Include="WindowsKeyManager.h" />
<ClInclude Include="Renderer.h" />
<ClInclude Include="SoundManager.h" />
<ClInclude Include="stdafx.h" />
@ -233,7 +233,7 @@
</ItemGroup>
<ItemGroup>
<ClCompile Include="GamePad.cpp" />
<ClCompile Include="InputManager.cpp">
<ClCompile Include="WindowsKeyManager.cpp">
<DeploymentContent>false</DeploymentContent>
</ClCompile>
<ClCompile Include="Renderer.cpp" />

View file

@ -27,9 +27,6 @@
<ClInclude Include="GamePad.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="InputManager.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Renderer.h">
<Filter>Header Files</Filter>
</ClInclude>
@ -81,6 +78,9 @@
<ClInclude Include="DirectXTK\XboxDDSTextureLoader.h">
<Filter>Header Files\DirectXTK</Filter>
</ClInclude>
<ClInclude Include="WindowsKeyManager.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="stdafx.cpp">
@ -89,15 +89,15 @@
<ClCompile Include="GamePad.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="InputManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Renderer.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="SoundManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="WindowsKeyManager.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="DirectXTK\SimpleMath.inl">

View file

@ -0,0 +1,78 @@
#include "stdafx.h"
#include "WindowsKeyManager.h"
#include "../Core/ControlManager.h"
WindowsKeyManager::WindowsKeyManager(HWND hWnd)
{
_hWnd = hWnd;
}
WindowsKeyManager::~WindowsKeyManager()
{
}
bool WindowsKeyManager::WindowHasFocus()
{
return GetForegroundWindow() == _hWnd;
}
void WindowsKeyManager::RefreshState()
{
_gamePad.RefreshState();
}
bool WindowsKeyManager::IsKeyPressed(uint32_t key)
{
if(WindowHasFocus()) {
if(key >= 0x10000) {
//XInput key
uint8_t gamepadPort = (key - 0xFFFF) / 0x100;
uint8_t gamepadButton = (key - 0xFFFF) % 0x100;
return _gamePad.IsPressed(gamepadPort, 1 << (gamepadButton - 1));
} else {
return (GetAsyncKeyState(key) & 0x8000) == 0x8000;
}
}
return false;
}
uint32_t WindowsKeyManager::GetPressedKey()
{
_gamePad.RefreshState();
for(int i = 0; i < XUSER_MAX_COUNT; i++) {
for(int j = 1; j <= 16; j++) {
if(_gamePad.IsPressed(i, 1 << (j - 1))) {
return 0xFFFF + i * 0x100 + j;
}
}
}
for(int i = 0; i < 0xFF; i++) {
if((GetAsyncKeyState(i) & 0x8000) == 0x8000) {
return i;
}
}
return 0;
}
wchar_t* WindowsKeyManager::GetKeyName(uint32_t key)
{
for(KeyDefinition keyDef : _keyDefinitions) {
if(keyDef.keyCode == key) {
return keyDef.description;
}
}
return nullptr;
}
uint32_t WindowsKeyManager::GetKeyCode(wchar_t* keyName)
{
wstring name(keyName);
for(KeyDefinition keyDef : _keyDefinitions) {
if(name.compare(keyDef.description) == 0) {
return keyDef.keyCode;
}
}
return 0;
}

243
Windows/WindowsKeyManager.h Normal file
View file

@ -0,0 +1,243 @@
#pragma once
#include "stdafx.h"
#include "..\Core\IKeyManager.h"
#include "GamePad.h"
struct KeyDefinition {
char* name;
uint32_t keyCode;
wchar_t* description;
};
const KeyDefinition _keyDefinitions[] = {
//{ "VK_LBUTTON", 0x01, L"Left mouse button" },
//{ "VK_RBUTTON", 0x02, L"Right mouse button" },
{ "VK_CANCEL", 0x03, L"Control-break processing" },
//{ "VK_MBUTTON", 0x04, L"Middle mouse button (three-button mouse)" },
//{ "VK_XBUTTON1", 0x05, L"X1 mouse button" },
//{ "VK_XBUTTON2", 0x06, L"X2 mouse button" },
{ "-", 0x07, L"Undefined" },
{ "VK_BACK", 0x08, L"Backspace" },
{ "VK_TAB", 0x09, L"Tab" },
//{ "-", 0x0A - 0B, L"Reserved" },
{ "VK_CLEAR", 0x0C, L"Clear" },
{ "VK_RETURN", 0x0D, L"Enter" },
//{ "-", 0x0E - 0F, L"Undefined" },
{ "VK_SHIFT", 0x10, L"Shift" },
{ "VK_CONTROL", 0x11, L"Ctrl" },
{ "VK_MENU", 0x12, L"Alt" },
{ "VK_PAUSE", 0x13, L"Pause" },
{ "VK_CAPITAL", 0x14, L"Caps Lock" },
{ "VK_KANA", 0x15, L"IME Kana mode" },
{ "VK_HANGUEL", 0x15, L"IME Hanguel mode" },
{ "VK_HANGUL", 0x15, L"IME Hangul mode" },
//{ "-", 0x16, L"Undefined" },
{ "VK_JUNJA", 0x17, L"IME Junja mode" },
{ "VK_FINAL", 0x18, L"IME final mode" },
{ "VK_HANJA", 0x19, L"IME Hanja mode" },
{ "VK_KANJI", 0x19, L"IME Kanji mode" },
//{ "-", 0x1A, L"Undefined" },
{ "VK_ESCAPE", 0x1B, L"Esc" },
{ "VK_CONVERT", 0x1C, L"IME convert" },
{ "VK_NONCONVERT", 0x1D, L"IME nonconvert" },
{ "VK_ACCEPT", 0x1E, L"IME accept" },
{ "VK_MODECHANGE", 0x1F, L"IME mode change request" },
{ "VK_SPACE", 0x20, L"Spacebar" },
{ "VK_PRIOR", 0x21, L"Page Up" },
{ "VK_NEXT", 0x22, L"Page Down" },
{ "VK_END", 0x23, L"End" },
{ "VK_HOME", 0x24, L"Home" },
{ "VK_LEFT", 0x25, L"Left Arrow" },
{ "VK_UP", 0x26, L"Up Arrow" },
{ "VK_RIGHT", 0x27, L"Right Arrow" },
{ "VK_DOWN", 0x28, L"Down Arrow" },
{ "VK_SELECT", 0x29, L"Select" },
{ "VK_PRINT", 0x2A, L"Print" },
{ "VK_EXECUTE", 0x2B, L"Execute" },
{ "VK_SNAPSHOT", 0x2C, L"Print Screen" },
{ "VK_INSERT", 0x2D, L"Ins" },
{ "VK_DELETE", 0x2E, L"Del" },
{ "VK_HELP", 0x2F, L"Help" },
{ "0", 0x30, L"0" },
{ "1", 0x31, L"1" },
{ "2", 0x32, L"2" },
{ "3", 0x33, L"3" },
{ "4", 0x34, L"4" },
{ "5", 0x35, L"5" },
{ "6", 0x36, L"6" },
{ "7", 0x37, L"7" },
{ "8", 0x38, L"8" },
{ "9", 0x39, L"9" },
//{ "undefined", 0x3A - 40, L"undefined" },
{ "A", 0x41, L"A" },
{ "B", 0x42, L"B" },
{ "C", 0x43, L"C" },
{ "D", 0x44, L"D" },
{ "E", 0x45, L"E" },
{ "F", 0x46, L"F" },
{ "G", 0x47, L"G" },
{ "H", 0x48, L"H" },
{ "I", 0x49, L"I" },
{ "J", 0x4A, L"J" },
{ "K", 0x4B, L"K" },
{ "L", 0x4C, L"L" },
{ "M", 0x4D, L"M" },
{ "N", 0x4E, L"N" },
{ "O", 0x4F, L"O" },
{ "P", 0x50, L"P" },
{ "Q", 0x51, L"Q" },
{ "R", 0x52, L"R" },
{ "S", 0x53, L"S" },
{ "T", 0x54, L"T" },
{ "U", 0x55, L"U" },
{ "V", 0x56, L"V" },
{ "W", 0x57, L"W" },
{ "X", 0x58, L"X" },
{ "Y", 0x59, L"Y" },
{ "Z", 0x5A, L"Z" },
{ "VK_LWIN", 0x5B, L"Left Windows" },
{ "VK_RWIN", 0x5C, L"Right Windows" },
{ "VK_APPS", 0x5D, L"Applications Key" },
//{ "-", 0x5E, L"Reserved" },
{ "VK_SLEEP", 0x5F, L"Computer Sleep" },
{ "VK_NUMPAD0", 0x60, L"Keypad 0" },
{ "VK_NUMPAD1", 0x61, L"Keypad 1" },
{ "VK_NUMPAD2", 0x62, L"Keypad 2" },
{ "VK_NUMPAD3", 0x63, L"Keypad 3" },
{ "VK_NUMPAD4", 0x64, L"Keypad 4" },
{ "VK_NUMPAD5", 0x65, L"Keypad 5" },
{ "VK_NUMPAD6", 0x66, L"Keypad 6" },
{ "VK_NUMPAD7", 0x67, L"Keypad 7" },
{ "VK_NUMPAD8", 0x68, L"Keypad 8" },
{ "VK_NUMPAD9", 0x69, L"Keypad 9" },
{ "VK_MULTIPLY", 0x6A, L"Multiply" },
{ "VK_ADD", 0x6B, L"Add" },
{ "VK_SEPARATOR", 0x6C, L"Separator" },
{ "VK_SUBTRACT", 0x6D, L"Subtract" },
{ "VK_DECIMAL", 0x6E, L"Decimal" },
{ "VK_DIVIDE", 0x6F, L"Divide" },
{ "VK_F1", 0x70, L"F1" },
{ "VK_F2", 0x71, L"F2" },
{ "VK_F3", 0x72, L"F3" },
{ "VK_F4", 0x73, L"F4" },
{ "VK_F5", 0x74, L"F5" },
{ "VK_F6", 0x75, L"F6" },
{ "VK_F7", 0x76, L"F7" },
{ "VK_F8", 0x77, L"F8" },
{ "VK_F9", 0x78, L"F9" },
{ "VK_F10", 0x79, L"F10" },
{ "VK_F11", 0x7A, L"F11" },
{ "VK_F12", 0x7B, L"F12" },
{ "VK_F13", 0x7C, L"F13" },
{ "VK_F14", 0x7D, L"F14" },
{ "VK_F15", 0x7E, L"F15" },
{ "VK_F16", 0x7F, L"F16" },
{ "VK_F17", 0x80, L"F17" },
{ "VK_F18", 0x81, L"F18" },
{ "VK_F19", 0x82, L"F19" },
{ "VK_F20", 0x83, L"F20" },
{ "VK_F21", 0x84, L"F21" },
{ "VK_F22", 0x85, L"F22" },
{ "VK_F23", 0x86, L"F23" },
{ "VK_F24", 0x87, L"F24" },
//{ "-", 0x88 - 8F, L"Unassigned" },
{ "VK_NUMLOCK", 0x90, L"Num Lock" },
{ "VK_SCROLL", 0x91, L"Scroll Lock" },
//{"-", 0x92-96,"OEM specific"},
//{ "-", 0x97 - 9F, L"Unassigned" },
{ "VK_LSHIFT", 0xA0, L"Left Shift" },
{ "VK_RSHIFT", 0xA1, L"Right Shift" },
{ "VK_LCONTROL", 0xA2, L"Left Control" },
{ "VK_RCONTROL", 0xA3, L"Right Control" },
{ "VK_LMENU", 0xA4, L"Left Menu" },
{ "VK_RMENU", 0xA5, L"Right Menu" },
{ "VK_BROWSER_BACK", 0xA6, L"Browser Back" },
{ "VK_BROWSER_FORWARD", 0xA7, L"Browser Forward" },
{ "VK_BROWSER_REFRESH", 0xA8, L"Browser Refresh" },
{ "VK_BROWSER_STOP", 0xA9, L"Browser Stop" },
{ "VK_BROWSER_SEARCH", 0xAA, L"Browser Search" },
{ "VK_BROWSER_FAVORITES", 0xAB, L"Browser Favorites" },
{ "VK_BROWSER_HOME", 0xAC, L"Browser Start and Home" },
{ "VK_VOLUME_MUTE", 0xAD, L"Volume Mute" },
{ "VK_VOLUME_DOWN", 0xAE, L"Volume Down" },
{ "VK_VOLUME_UP", 0xAF, L"Volume Up" },
{ "VK_MEDIA_NEXT_TRACK", 0xB0, L"Next Track" },
{ "VK_MEDIA_PREV_TRACK", 0xB1, L"Previous Track" },
{ "VK_MEDIA_STOP", 0xB2, L"Stop Media" },
{ "VK_MEDIA_PLAY_PAUSE", 0xB3, L"Play/Pause Media" },
{ "VK_LAUNCH_MAIL", 0xB4, L"Start Mail" },
{ "VK_LAUNCH_MEDIA_SELECT", 0xB5, L"Select Media" },
{ "VK_LAUNCH_APP1", 0xB6, L"Start Application 1" },
{ "VK_LAUNCH_APP2", 0xB7, L"Start Application 2" },
//{ "-", 0xB8 - B9, L"Reserved" },
{ "VK_OEM_1", 0xBA, L"Used for miscellaneous characters; it can vary by keyboard. For the US standard keyboard, the \';:\' key VK_OEM_PLUS" },
{ "VK_OEM_PLUS", 0xBB, L"+" },
{ "VK_OEM_COMMA", 0xBC, L"," },
{ "VK_OEM_MINUS", 0xBD, L"-" },
{ "VK_OEM_PERIOD", 0xBE, L"." },
{ "VK_OEM_2", 0xBF, L"/" },
{ "VK_OEM_3", 0xC0, L"`" },
//{ "-", 0xC1 - D7, L"Reserved" },
//{ "-", 0xD8 - DA, L"Unassigned" },
{ "VK_OEM_4", 0xDB, L"[" },
{ "VK_OEM_5", 0xDC, L"\\" },
{ "VK_OEM_6", 0xDD, L"]" },
{ "VK_OEM_7", 0xDE, L"'" },
{ "VK_OEM_8", 0xDF, L"Used for miscellaneous characters; it can vary by keyboard." },
//{ "-", 0xE0, L"Reserved" },
//{ "-", 0xE1, L"OEM specific" },
{ "VK_OEM_102", 0xE2, L"Either the angle bracket key or the backslash key on the RT 102-key keyboard" },
//{ "-", 0xE3 - E4, L"OEM specific" },
{ "VK_PROCESSKEY", 0xE5, L"IME PROCESS" },
//{ "-", 0xE6, L"OEM specific" },
{ "VK_PACKET", 0xE7, L"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
//{ "-", 0xE8, L"Unassigned" },
// {"-",0xE6,"OEM specific"},
{ "VK_PACKET", 0xE7, L"Used to pass Unicode characters as if they were keystrokes. The VK_PACKET key is the low word of a 32-bit Virtual Key value used for non-keyboard input methods. For more information, see Remark in KEYBDINPUT, SendInput, WM_KEYDOWN, and WM_KEYUP" },
// {"-",0xE8,"Unassigned"},
//{ "-", 0xE9 - F5, L"OEM specific" },
{ "VK_ATTN", 0xF6, L"Attn" },
{ "VK_CRSEL", 0xF7, L"CrSel" },
{ "VK_EXSEL", 0xF8, L"ExSel" },
{ "VK_EREOF", 0xF9, L"Erase EOF" },
{ "VK_PLAY", 0xFA, L"Play" },
{ "VK_ZOOM", 0xFB, L"Zoom" },
{ "VK_NONAME", 0xFC, L"Reserved" },
{ "VK_PA1", 0xFD, L"PA1" },
{ "VK_OEM_CLEAR", 0xFE, L"Clear" },
{ "", 0xFFFF + 0x01, L"Pad1 Up" },
{ "", 0xFFFF + 0x02, L"Pad1 Down" },
{ "", 0xFFFF + 0x03, L"Pad1 Left" },
{ "", 0xFFFF + 0x04, L"Pad1 Right" },
{ "", 0xFFFF + 0x05, L"Pad1 Start" },
{ "", 0xFFFF + 0x06, L"Pad1 Back" },
{ "", 0xFFFF + 0x07, L"Pad1 Left Thumb" },
{ "", 0xFFFF + 0x08, L"Pad1 Right Thumb" },
{ "", 0xFFFF + 0x09, L"Pad1 Left Bumper" },
{ "", 0xFFFF + 0x0A, L"Pad1 Right Bumper" },
{ "", 0xFFFF + 0x0D, L"Pad1 A" },
{ "", 0xFFFF + 0x0E, L"Pad1 B" },
{ "", 0xFFFF + 0x0F, L"Pad1 X" },
{ "", 0xFFFF + 0x10, L"Pad1 Y" }
};
class WindowsKeyManager : public IKeyManager
{
private:
GamePad _gamePad;
HWND _hWnd;
bool WindowHasFocus();
public:
WindowsKeyManager(HWND hWnd);
~WindowsKeyManager();
void RefreshState();
bool IsKeyPressed(uint32_t key);
uint32_t GetPressedKey();
wchar_t* GetKeyName(uint32_t key);
uint32_t GetKeyCode(wchar_t* keyName);
};