Mesen-X/GUI.NET/Forms/Config/frmInputConfig.cs
2017-09-17 01:29:17 -04:00

319 lines
10 KiB
C#

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();
tlpControllers.Enabled = !InteropEmu.MoviePlaying() && !InteropEmu.MovieRecording();
InteropEmu.UpdateInputDevices();
Entity = ConfigManager.Config.InputInfo;
for(int i = 0; i < 4; i++) {
ConfigManager.Config.InputInfo.Controllers[i].ControllerType = InteropEmu.GetControllerType(i);
}
ConfigManager.Config.InputInfo.ExpansionPortDevice = InteropEmu.GetExpansionDevice();
ConfigManager.Config.InputInfo.ConsoleType = InteropEmu.GetConsoleType();
ConfigManager.Config.InputInfo.UseFourScore = InteropEmu.HasFourScore();
AddBinding("ExpansionPortDevice", cboExpansionPort);
AddBinding("ConsoleType", cboConsoleType);
AddBinding("UseFourScore", chkFourScore);
AddBinding("AutoConfigureInput", chkAutoConfigureInput);
AddBinding("DisplayInputPort1", chkDisplayPort1);
AddBinding("DisplayInputPort2", chkDisplayPort2);
AddBinding("DisplayInputPort3", chkDisplayPort3);
AddBinding("DisplayInputPort4", chkDisplayPort4);
AddBinding("DisplayInputPosition", cboDisplayInputPosition);
AddBinding("DisplayInputHorizontally", chkDisplayInputHorizontally);
UpdateConflictWarning();
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
base.OnFormClosed(e);
InputInfo.ApplyConfig();
}
protected override void AfterUpdateUI()
{
base.AfterUpdateUI();
this.UpdateInterface();
}
private void UpdateAvailableControllerTypes()
{
bool isNes = ((InputInfo)Entity).ConsoleType == ConsoleType.Nes;
bool p3and4visible = (isNes && chkFourScore.Checked) || (!isNes && ((InputInfo)Entity).ExpansionPortDevice == InteropEmu.ExpansionPortDevice.FourPlayerAdapter);
List<InteropEmu.ControllerType> controllerTypes = new List<InteropEmu.ControllerType>(new InteropEmu.ControllerType[] { InteropEmu.ControllerType.StandardController });
SetAvailableControllerTypes(cboPlayer3, controllerTypes.ToArray(), false);
SetAvailableControllerTypes(cboPlayer4, controllerTypes.ToArray(), false);
if(isNes && !chkFourScore.Checked) {
controllerTypes.Add(InteropEmu.ControllerType.Zapper);
controllerTypes.Add(InteropEmu.ControllerType.ArkanoidController);
}
bool isOriginalFamicom = !isNes && !ConfigManager.Config.EmulationInfo.UseNes101Hvc101Behavior;
SetAvailableControllerTypes(cboPlayer1, controllerTypes.ToArray(), isOriginalFamicom);
SetAvailableControllerTypes(cboPlayer2, controllerTypes.ToArray(), isOriginalFamicom);
}
private void SetAvailableControllerTypes(ComboBox comboBox, InteropEmu.ControllerType[] controllerTypes, bool forceController)
{
comboBox.Items.Clear();
if(!forceController) {
comboBox.Items.Add(ResourceHelper.GetEnumText(InteropEmu.ControllerType.None));
}
foreach(InteropEmu.ControllerType type in controllerTypes) {
comboBox.Items.Add(ResourceHelper.GetEnumText(type));
}
InputInfo inputInfo = (InputInfo)Entity;
string currentSelection = null;
if(comboBox == cboPlayer1) {
currentSelection = ResourceHelper.GetEnumText(inputInfo.Controllers[0].ControllerType);
} else if(comboBox == cboPlayer2) {
currentSelection = ResourceHelper.GetEnumText(inputInfo.Controllers[1].ControllerType);
} else if(comboBox == cboPlayer3) {
currentSelection = ResourceHelper.GetEnumText(inputInfo.Controllers[2].ControllerType);
} else if(comboBox == cboPlayer4) {
currentSelection = ResourceHelper.GetEnumText(inputInfo.Controllers[3].ControllerType);
}
if(currentSelection != null && comboBox.Items.Contains(currentSelection)) {
comboBox.SelectedItem = currentSelection;
} else {
comboBox.SelectedIndex = 0;
}
}
protected override void UpdateConfig()
{
InputInfo inputInfo = (InputInfo)Entity;
inputInfo.Controllers[0].ControllerType = cboPlayer1.GetEnumValue<InteropEmu.ControllerType>();
inputInfo.Controllers[1].ControllerType = cboPlayer2.GetEnumValue<InteropEmu.ControllerType>();
inputInfo.Controllers[2].ControllerType = cboPlayer3.GetEnumValue<InteropEmu.ControllerType>();
inputInfo.Controllers[3].ControllerType = cboPlayer4.GetEnumValue<InteropEmu.ControllerType>();
}
private void UpdateInterface()
{
if(!this.Updating) {
bool isNes = ((InputInfo)Entity).ConsoleType == ConsoleType.Nes;
cboExpansionPort.Visible = !isNes;
lblExpansionPort.Visible = !isNes;
btnSetupExp.Visible = !isNes;
chkFourScore.Visible = isNes;
UpdatePlayer3And4Visibility();
UpdateAvailableControllerTypes();
if(ConfigManager.Config.PreferenceInfo.DisableGameDatabase) {
//This option requires the game DB to be active
chkAutoConfigureInput.Enabled = false;
chkAutoConfigureInput.Checked = false;
}
UpdateConflictWarning();
}
}
private bool FourScoreAttached
{
get
{
bool isNes = ((InputInfo)Entity).ConsoleType == ConsoleType.Nes;
return (isNes && chkFourScore.Checked) || (!isNes && ((InputInfo)Entity).ExpansionPortDevice == InteropEmu.ExpansionPortDevice.FourPlayerAdapter);
}
}
private void UpdatePlayer3And4Visibility()
{
bool visible = this.FourScoreAttached;
if(lblPlayer3.Visible != visible) {
lblPlayer3.Visible = visible;
lblPlayer4.Visible = visible;
cboPlayer3.Visible = visible;
cboPlayer4.Visible = visible;
btnSetupP3.Visible = visible;
btnSetupP4.Visible = visible;
}
}
private void cboNesType_SelectedIndexChanged(object sender, EventArgs e)
{
if(!this.Updating) {
UpdateObject();
UpdateInterface();
}
}
private void chkFourScore_CheckedChanged(object sender, EventArgs e)
{
if(!this.Updating) {
UpdateObject();
UpdateInterface();
}
}
private void cboExpansionPort_SelectedIndexChanged(object sender, EventArgs e)
{
if(!this.Updating) {
UpdateObject();
UpdateInterface();
}
btnSetupExp.Enabled = cboExpansionPort.SelectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ExpansionPortDevice.Zapper));
}
private void cboPlayerController_SelectedIndexChanged(object sender, EventArgs e)
{
object selectedItem = ((ComboBox)sender).SelectedItem;
bool enableButton = selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ControllerType.StandardController)) ||
selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ControllerType.Zapper));
if(sender == cboPlayer1) {
btnSetupP1.Enabled = enableButton;
} else if(sender == cboPlayer2) {
btnSetupP2.Enabled = enableButton;
} else if(sender == cboPlayer3) {
btnSetupP3.Enabled = enableButton;
} else if(sender == cboPlayer4) {
btnSetupP4.Enabled = enableButton;
}
UpdateConflictWarning();
}
private void btnSetup_Click(object sender, EventArgs e)
{
int index = 0;
object selectedItem = null;
if(sender == btnSetupP1) {
selectedItem = cboPlayer1.SelectedItem;
index = 0;
} else if(sender == btnSetupP2) {
selectedItem = cboPlayer2.SelectedItem;
index = 1;
} else if(sender == btnSetupP3) {
selectedItem = cboPlayer3.SelectedItem;
index = 2;
} else if(sender == btnSetupP4) {
selectedItem = cboPlayer4.SelectedItem;
index = 3;
} else if(sender == btnSetupExp) {
selectedItem = cboExpansionPort.SelectedItem;
index = 0;
}
Form frm = null;
InputInfo inputInfo = (InputInfo)Entity;
if(selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ControllerType.StandardController))) {
frm = new frmControllerConfig(inputInfo.Controllers[index], index, cboConsoleType.GetEnumValue<ConsoleType>());
} else if(selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ControllerType.Zapper))) {
frm = new frmZapperConfig(inputInfo.Zapper);
} else if(selectedItem.Equals(ResourceHelper.GetEnumText(InteropEmu.ExpansionPortDevice.Zapper))) {
frm = new frmZapperConfig(inputInfo.Zapper);
}
if(frm != null) {
Button btn = (Button)sender;
Point point = btn.PointToScreen(new Point(0, btn.Height));
Rectangle screen = Screen.FromControl(btn).Bounds;
if(frm.Height + point.Y > screen.Bottom) {
//Show on top instead
point.Y -= btn.Height + frm.Height;
}
if(frm.Width + point.X > screen.Right) {
//Show on left instead
point.X -= frm.Width - btn.Width;
}
frm.StartPosition = FormStartPosition.Manual;
frm.Top = point.Y;
frm.Left = point.X;
if(frm.ShowDialog(this) == DialogResult.OK) {
UpdateConflictWarning();
}
frm.Dispose();
}
}
private void UpdateConflictWarning()
{
bool needWarning = false;
bool[] portConflicts = new bool[4];
Dictionary<uint, int> mappedKeys = new Dictionary<uint, int>();
Action<int, uint> countMapping = (int port, uint keyCode) => {
if(keyCode > 0) {
if(mappedKeys.ContainsKey(keyCode)) {
needWarning = true;
portConflicts[port] = true;
portConflicts[mappedKeys[keyCode]] = true;
} else {
mappedKeys.Add(keyCode, port);
}
}
};
for(int i = 0; i < 4; i++) {
if(i < 2 || this.FourScoreAttached && ((i == 2 && btnSetupP3.Enabled) || (i == 3 && btnSetupP4.Enabled))) {
foreach(KeyMappings mappings in ((InputInfo)Entity).Controllers[i].Keys) {
countMapping(i, mappings.A);
countMapping(i, mappings.B);
countMapping(i, mappings.Select);
countMapping(i, mappings.Start);
countMapping(i, mappings.TurboA);
countMapping(i, mappings.TurboB);
countMapping(i, mappings.TurboSelect);
countMapping(i, mappings.TurboStart);
countMapping(i, mappings.Up);
countMapping(i, mappings.Down);
countMapping(i, mappings.Left);
countMapping(i, mappings.Right);
}
}
}
if(pnlConflictWarning.Visible != needWarning) {
pnlConflictWarning.Visible = needWarning;
btnSetupP1.Image = portConflicts[0] ? Properties.Resources.Warning : null;
btnSetupP2.Image = portConflicts[1] ? Properties.Resources.Warning : null;
btnSetupP3.Image = portConflicts[2] ? Properties.Resources.Warning : null;
btnSetupP4.Image = portConflicts[3] ? Properties.Resources.Warning : null;
this.Height = (int)((needWarning ? 360 : 310) * _yFactor);
}
}
float _yFactor = 1;
protected override void ScaleControl(SizeF factor, BoundsSpecified specified)
{
_yFactor = factor.Height;
base.ScaleControl(factor, specified);
}
}
}