Merge pull request #987 from Tastyfish/sms-controllers

Adds Sega Master System paddle support
This commit is contained in:
alyosha-tas 2017-08-31 10:08:06 -04:00 committed by GitHub
commit a8555c39ca
7 changed files with 228 additions and 14 deletions

View File

@ -743,6 +743,13 @@
"P2 B1": "",
"P2 B2": ""
},
"SMS Paddle Controller": {
"P1 Left": "LeftArrow, J1 POV1L",
"P1 Right": "RightArrow, J1 POV1R",
"P1 B1": "Z, J1 B1, X1 X",
"Reset": "J1 B9, X1 Back",
"Pause": "J1 B10, X1 Start",
},
"GG Controller": {
"P1 Up": "UpArrow, J1 POV1U, X1 DpadUp, X1 LStickUp",
"P1 Down": "DownArrow, J1 POV1D, X1 DpadDown, X1 LStickDown",
@ -1567,6 +1574,13 @@
"Mult": 1.0,
"Deadzone": 0.1
}
},
"SMS Paddle Controller": {
"P1 Paddle": {
"Value": "X1 LeftThumbX",
"Mult": 1.0,
"Deadzone": 0.1
}
}
}
}

View File

@ -442,6 +442,9 @@
this.ShowMenuContextMenuSeparator = new System.Windows.Forms.ToolStripSeparator();
this.ShowMenuContextMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.timerMouseIdle = new System.Windows.Forms.Timer(this.components);
this.SMSControllerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SMSControllerStandardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.SMSControllerPaddleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.MainformMenu.SuspendLayout();
this.MainStatusBar.SuspendLayout();
this.MainFormContextMenu.SuspendLayout();
@ -2475,6 +2478,7 @@
this.SMSSubMenu.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SMSregionToolStripMenuItem,
this.SMSdisplayToolStripMenuItem,
this.SMSControllerToolStripMenuItem,
this.SMStoolStripMenuItem2,
this.SMSenableBIOSToolStripMenuItem,
this.SMSEnableFMChipMenuItem,
@ -2542,6 +2546,26 @@
this.SMSdisplayNtscToolStripMenuItem.Text = "NTSC";
this.SMSdisplayNtscToolStripMenuItem.Click += new System.EventHandler(this.SMS_DisplayNTSC_Click);
//
// SMSControllerToolStripMenuItem
//
this.SMSControllerToolStripMenuItem.Name = "SMSControllerToolStripMenuItem";
this.SMSControllerToolStripMenuItem.Text = "&Controller Type";
this.SMSControllerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SMSControllerStandardToolStripMenuItem,
this.SMSControllerPaddleToolStripMenuItem});
//
// SMSControllerStandardToolStripMenuItem
//
this.SMSControllerStandardToolStripMenuItem.Name = "SMSControllerStandardToolStripMenuItem";
this.SMSControllerStandardToolStripMenuItem.Text = "Standard";
this.SMSControllerStandardToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerStandardToolStripMenuItem_Click);
//
// SMSControllerPaddleToolStripMenuItem
//
this.SMSControllerPaddleToolStripMenuItem.Name = "SMSControllerPaddleToolStripMenuItem";
this.SMSControllerPaddleToolStripMenuItem.Text = "Paddle";
this.SMSControllerPaddleToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerPaddleToolStripMenuItem_Click);
//
// SMSdisplayPalToolStripMenuItem
//
this.SMSdisplayPalToolStripMenuItem.Name = "SMSdisplayPalToolStripMenuItem";
@ -4368,5 +4392,8 @@
private System.Windows.Forms.ToolStripMenuItem SgbSameBoyMenuItem;
private System.Windows.Forms.ToolStripMenuItem pCFXToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem preferencesToolStripMenuItem3;
private System.Windows.Forms.ToolStripMenuItem SMSControllerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerStandardToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerPaddleToolStripMenuItem;
}
}

View File

@ -1745,6 +1745,8 @@ namespace BizHawk.Client.EmuHawk
SMSdisplayNtscToolStripMenuItem.Checked = ss.DisplayType == "NTSC";
SMSdisplayPalToolStripMenuItem.Checked = ss.DisplayType == "PAL";
SMSdisplayAutoToolStripMenuItem.Checked = ss.DisplayType == "Auto";
SMSControllerStandardToolStripMenuItem.Checked = s.ControllerType == "Standard";
SMSControllerPaddleToolStripMenuItem.Checked = s.ControllerType == "Paddle";
SMSenableBIOSToolStripMenuItem.Checked = ss.UseBIOS;
SMSEnableFMChipMenuItem.Checked = ss.EnableFM;
SMSOverclockMenuItem.Checked = ss.AllowOverlock;
@ -1899,6 +1901,20 @@ namespace BizHawk.Client.EmuHawk
GlobalWin.Tools.Load<SmsVDPViewer>();
}
private void SMSControllerStandardToolStripMenuItem_Click(object sender, EventArgs e)
{
var s = ((SMS)Emulator).GetSettings();
s.ControllerType = "Standard";
PutCoreSettings(s);
}
private void SMSControllerPaddleToolStripMenuItem_Click(object sender, EventArgs e)
{
var s = ((SMS)Emulator).GetSettings();
s.ControllerType = "Paddle";
PutCoreSettings(s);
}
#endregion
#region TI83

View File

@ -15,7 +15,13 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return GGController;
}
return SmsController;
switch(Settings.ControllerType)
{
case "Paddle":
return SMSPaddleController;
default:
return SmsController;
}
}
}

View File

@ -38,6 +38,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
public bool SpriteLimit = false;
public bool Fix3D = true;
public bool DisplayOverscan = false;
public string ControllerType = "Standard";
// GG settings
public bool ShowClippedRegions = false;

View File

@ -71,6 +71,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
ser.Sync("Port02", ref Port02);
ser.Sync("Port3E", ref Port3E);
ser.Sync("Port3F", ref Port3F);
ser.Sync("Paddle1High", ref Paddle1High);
ser.Sync("Paddle2High", ref Paddle2High);
if (SaveRAM != null)
{

View File

@ -1,4 +1,6 @@
using BizHawk.Emulation.Common;
using System;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Sega.MasterSystem
{
@ -25,21 +27,123 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
};
public static readonly ControllerDefinition SMSPaddleController = new ControllerDefinition
{
Name = "SMS Paddle Controller",
BoolButtons =
{
"Reset", "Pause",
"P1 Left", "P1 Right", "P1 B1",
"P2 Left", "P2 Right", "P2 B1",
},
FloatControls =
{
"P1 Paddle",
"P2 Paddle"
},
FloatRanges =
{
new ControllerDefinition.FloatRange(0, 128, 255),
new ControllerDefinition.FloatRange(0, 128, 255)
}
};
// The paddles have a nibble select state
bool Paddle1High = false;
bool Paddle2High = false;
const int PaddleMin = 0;
const int PaddleMax = 255;
private byte ReadControls1()
{
InputCallbacks.Call();
_lagged = false;
byte value = 0xFF;
if (_controller.IsPressed("P1 Up")) value &= 0xFE;
if (_controller.IsPressed("P1 Down")) value &= 0xFD;
if (_controller.IsPressed("P1 Left")) value &= 0xFB;
if (_controller.IsPressed("P1 Right")) value &= 0xF7;
if (_controller.IsPressed("P1 B1")) value &= 0xEF;
if (_controller.IsPressed("P1 B2")) value &= 0xDF;
switch (Settings.ControllerType)
{
case "Paddle":
// use analog values from a controller, see http://www.smspower.org/Development/Paddle
if (_controller.IsPressed("P2 Up")) value &= 0xBF;
if (_controller.IsPressed("P2 Down")) value &= 0x7F;
int paddle1Pos;
if (_controller.IsPressed("P1 Left"))
paddle1Pos = PaddleMin;
else if (_controller.IsPressed("P1 Right"))
paddle1Pos = PaddleMax;
else
paddle1Pos = (int)_controller.GetFloat("P1 Paddle");
int paddle2Pos;
if (_controller.IsPressed("P2 Left"))
paddle2Pos = PaddleMin;
else if (_controller.IsPressed("P2 Right"))
paddle2Pos = PaddleMax;
else
paddle2Pos = (int)_controller.GetFloat("P2 Paddle");
// The 3F port's TH slot is also used on games in some games in Export BIOS to clock the paddle state
// Yes it's silly considering the paddle was never released outside Japan but the games think otherwise
if (_region != "Japan")
{
if ((Port3F & 0x02) == 0x00)
{
Paddle1High = (Port3F & 0x20) != 0;
}
if ((Port3F & 0x08) == 0x00)
{
Paddle2High = (Port3F & 0x80) != 0;
}
}
if (Paddle1High)
{
if ((paddle1Pos & 0x10) == 0) value &= 0xFE;
if ((paddle1Pos & 0x20) == 0) value &= 0xFD;
if ((paddle1Pos & 0x40) == 0) value &= 0xFB;
if ((paddle1Pos & 0x80) == 0) value &= 0xF7;
}
else
{
if ((paddle1Pos & 0x01) == 0) value &= 0xFE;
if ((paddle1Pos & 0x02) == 0) value &= 0xFD;
if ((paddle1Pos & 0x04) == 0) value &= 0xFB;
if ((paddle1Pos & 0x08) == 0) value &= 0xF7;
}
if (_controller.IsPressed("P1 B1")) value &= 0xEF;
if (!Paddle1High) value &= 0xDF;
if (Paddle2High)
{
if ((paddle2Pos & 0x10) == 0) value &= 0xBF;
if ((paddle2Pos & 0x20) == 0) value &= 0x7F;
}
else
{
if ((paddle2Pos & 0x01) == 0) value &= 0xBF;
if ((paddle2Pos & 0x02) == 0) value &= 0x7F;
}
// toggle state for Japanese region controllers
Paddle1High = !Paddle1High;
break;
default:
// Normal controller
if (_controller.IsPressed("P1 Up")) value &= 0xFE;
if (_controller.IsPressed("P1 Down")) value &= 0xFD;
if (_controller.IsPressed("P1 Left")) value &= 0xFB;
if (_controller.IsPressed("P1 Right")) value &= 0xF7;
if (_controller.IsPressed("P1 B1")) value &= 0xEF;
if (_controller.IsPressed("P1 B2")) value &= 0xDF;
if (_controller.IsPressed("P2 Up")) value &= 0xBF;
if (_controller.IsPressed("P2 Down")) value &= 0x7F;
break;
}
return value;
}
@ -50,10 +154,54 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
_lagged = false;
byte value = 0xFF;
if (_controller.IsPressed("P2 Left")) value &= 0xFE;
if (_controller.IsPressed("P2 Right")) value &= 0xFD;
if (_controller.IsPressed("P2 B1")) value &= 0xFB;
if (_controller.IsPressed("P2 B2")) value &= 0xF7;
switch (Settings.ControllerType)
{
case "Paddle":
// use analog values from a controller, see http://www.smspower.org/Development/Paddle
int paddle2Pos;
if (_controller.IsPressed("P2 Left"))
paddle2Pos = PaddleMin;
else if (_controller.IsPressed("P2 Right"))
paddle2Pos = PaddleMax;
else
paddle2Pos = (int)_controller.GetFloat("P2 Paddle");
if (_region != "Japan")
{
if ((Port3F & 0x08) == 0x00)
{
Paddle2High = (Port3F & 0x80) != 0;
}
}
if (Paddle2High)
{
if ((paddle2Pos & 0x40) == 0) value &= 0xFE;
if ((paddle2Pos & 0x80) == 0) value &= 0xFD;
}
else
{
if ((paddle2Pos & 0x04) == 0) value &= 0xFE;
if ((paddle2Pos & 0x08) == 0) value &= 0xFD;
}
if (_controller.IsPressed("P2 B1")) value &= 0xFB;
if (!Paddle2High) value &= 0xF7;
Paddle2High = !Paddle2High;
break;
default:
// Normal controller
if (_controller.IsPressed("P2 Left")) value &= 0xFE;
if (_controller.IsPressed("P2 Right")) value &= 0xFD;
if (_controller.IsPressed("P2 B1")) value &= 0xFB;
if (_controller.IsPressed("P2 B2")) value &= 0xF7;
break;
}
if (_controller.IsPressed("Reset")) value &= 0xEF;