Adds SEGA Sports Pad for SMS support, also make controller syncsetting
This commit is contained in:
parent
03dcc63467
commit
9693d812d2
|
@ -754,6 +754,22 @@
|
|||
"P1 Trigger": "Z, J1 B1, X1 X, WMouse L",
|
||||
"Reset": "J1 B9, X1 Back",
|
||||
"Pause": "J1 B10, X1 Start"
|
||||
},
|
||||
"SMS Sports Pad Controller": {
|
||||
"P1 Up": "UpArrow, J1 POV1U",
|
||||
"P1 Down": "DownArrow, J1 POV1D",
|
||||
"P1 Left": "LeftArrow, J1 POV1L",
|
||||
"P1 Right": "RightArrow, J1 POV1R",
|
||||
"P1 B1": "Z, J1 B1, X1 X",
|
||||
"P1 B2": "X, J1 B2, X1 A",
|
||||
"Reset": "J1 B9, X1 Back",
|
||||
"Pause": "J1 B10, X1 Start",
|
||||
"P2 Up": "",
|
||||
"P2 Down": "",
|
||||
"P2 Left": "",
|
||||
"P2 Right": "",
|
||||
"P2 B1": "",
|
||||
"P2 B2": ""
|
||||
},
|
||||
"GG Controller": {
|
||||
"P1 Up": "UpArrow, J1 POV1U, X1 DpadUp, X1 LStickUp",
|
||||
|
@ -1598,6 +1614,28 @@
|
|||
"Mult": 1.0,
|
||||
"Deadzone": 0.0
|
||||
}
|
||||
},
|
||||
"SMS Sports Pad Controller": {
|
||||
"P1 X": {
|
||||
"Value": "X1 LeftThumbX",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P1 Y": {
|
||||
"Value": "X1 LeftThumbY",
|
||||
"Mult": -1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P2 X": {
|
||||
"Value": "X2 LeftThumbX",
|
||||
"Mult": 1.0,
|
||||
"Deadzone": 0.1
|
||||
},
|
||||
"P2 Y": {
|
||||
"Value": "X2 LeftThumbY",
|
||||
"Mult": -1.0,
|
||||
"Deadzone": 0.1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -446,7 +446,8 @@
|
|||
this.SMSControllerStandardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SMSControllerPaddleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.SMSControllerLightPhaserToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MainformMenu.SuspendLayout();
|
||||
this.SMSControllerSportsPadToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||
this.MainformMenu.SuspendLayout();
|
||||
this.MainStatusBar.SuspendLayout();
|
||||
this.MainFormContextMenu.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
|
@ -2480,7 +2481,7 @@
|
|||
this.SMSregionToolStripMenuItem,
|
||||
this.SMSdisplayToolStripMenuItem,
|
||||
this.SMSControllerToolStripMenuItem,
|
||||
this.SMStoolStripMenuItem2,
|
||||
this.SMStoolStripMenuItem2,
|
||||
this.SMSenableBIOSToolStripMenuItem,
|
||||
this.SMSEnableFMChipMenuItem,
|
||||
this.SMSOverclockMenuItem,
|
||||
|
@ -2554,7 +2555,8 @@
|
|||
this.SMSControllerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
|
||||
this.SMSControllerStandardToolStripMenuItem,
|
||||
this.SMSControllerPaddleToolStripMenuItem,
|
||||
this.SMSControllerLightPhaserToolStripMenuItem});
|
||||
this.SMSControllerLightPhaserToolStripMenuItem,
|
||||
this.SMSControllerSportsPadToolStripMenuItem});
|
||||
//
|
||||
// SMSControllerStandardToolStripMenuItem
|
||||
//
|
||||
|
@ -2573,10 +2575,17 @@
|
|||
this.SMSControllerLightPhaserToolStripMenuItem.Name = "SMSControllerLightPhaserToolStripMenuItem";
|
||||
this.SMSControllerLightPhaserToolStripMenuItem.Text = "Light Phaser";
|
||||
this.SMSControllerLightPhaserToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerLightPhaserToolStripMenuItem_Click);
|
||||
//
|
||||
// SMSdisplayPalToolStripMenuItem
|
||||
//
|
||||
this.SMSdisplayPalToolStripMenuItem.Name = "SMSdisplayPalToolStripMenuItem";
|
||||
//
|
||||
// SMSControllerSportsPadToolStripMenuItem
|
||||
//
|
||||
this.SMSControllerSportsPadToolStripMenuItem.Name = "SMSControllerSportsPadToolStripMenuItem";
|
||||
this.SMSControllerSportsPadToolStripMenuItem.Text = "Sports Pad";
|
||||
this.SMSControllerSportsPadToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerSportsPadToolStripMenuItem_Click);
|
||||
|
||||
//
|
||||
// SMSdisplayPalToolStripMenuItem
|
||||
//
|
||||
this.SMSdisplayPalToolStripMenuItem.Name = "SMSdisplayPalToolStripMenuItem";
|
||||
this.SMSdisplayPalToolStripMenuItem.Size = new System.Drawing.Size(104, 22);
|
||||
this.SMSdisplayPalToolStripMenuItem.Text = "PAL";
|
||||
this.SMSdisplayPalToolStripMenuItem.Click += new System.EventHandler(this.SMS_DisplayPAL_Click);
|
||||
|
@ -4404,5 +4413,6 @@
|
|||
private System.Windows.Forms.ToolStripMenuItem SMSControllerStandardToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerPaddleToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerLightPhaserToolStripMenuItem;
|
||||
private System.Windows.Forms.ToolStripMenuItem SMSControllerSportsPadToolStripMenuItem;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1745,9 +1745,10 @@ 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";
|
||||
SMSControllerLightPhaserToolStripMenuItem.Checked = s.ControllerType == "Light Phaser";
|
||||
SMSControllerStandardToolStripMenuItem.Checked = ss.ControllerType == "Standard";
|
||||
SMSControllerPaddleToolStripMenuItem.Checked = ss.ControllerType == "Paddle";
|
||||
SMSControllerLightPhaserToolStripMenuItem.Checked = ss.ControllerType == "Light Phaser";
|
||||
SMSControllerSportsPadToolStripMenuItem.Checked = ss.ControllerType == "Sports Pad";
|
||||
SMSenableBIOSToolStripMenuItem.Checked = ss.UseBIOS;
|
||||
SMSEnableFMChipMenuItem.Checked = ss.EnableFM;
|
||||
SMSOverclockMenuItem.Checked = ss.AllowOverlock;
|
||||
|
@ -1904,23 +1905,30 @@ namespace BizHawk.Client.EmuHawk
|
|||
|
||||
private void SMSControllerStandardToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Standard";
|
||||
PutCoreSettings(s);
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void SMSControllerPaddleToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Paddle";
|
||||
PutCoreSettings(s);
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void SMSControllerLightPhaserToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSettings();
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Light Phaser";
|
||||
PutCoreSettings(s);
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
private void SMSControllerSportsPadToolStripMenuItem_Click(object sender, EventArgs e)
|
||||
{
|
||||
var s = ((SMS)Emulator).GetSyncSettings();
|
||||
s.ControllerType = "Sports Pad";
|
||||
PutCoreSyncSettings(s);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
|
|
@ -9,10 +9,6 @@ Korean games currently not booting:
|
|||
|
||||
* Desert Strike - you can enter the map screen but cannot leave.
|
||||
|
||||
- Light Gun emulation
|
||||
- Paddle emulation
|
||||
- Sports pad emulation?
|
||||
|
||||
======= Game Gear compatibility issues =======
|
||||
|
||||
* Outrun has raster effect on the wrong line. I've been able to modify interrupt code to
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
return GGController;
|
||||
}
|
||||
|
||||
switch(Settings.ControllerType)
|
||||
switch(SyncSettings.ControllerType)
|
||||
{
|
||||
case "Paddle":
|
||||
return SMSPaddleController;
|
||||
|
@ -24,6 +24,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
SMSLightPhaserController.FloatRanges[1] = new ControllerDefinition.FloatRange(0, Vdp.FrameHeight / 2, Vdp.FrameHeight - 1);
|
||||
|
||||
return SMSLightPhaserController;
|
||||
case "Sports Pad":
|
||||
return SMSSportsPadController;
|
||||
default:
|
||||
return SmsController;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@ 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;
|
||||
|
@ -66,6 +65,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
public bool UseBIOS = true;
|
||||
public string ConsoleRegion = "Export";
|
||||
public string DisplayType = "NTSC";
|
||||
public string ControllerType = "Standard";
|
||||
|
||||
public SMSSyncSettings Clone()
|
||||
{
|
||||
|
@ -79,7 +79,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
x.AllowOverlock != y.AllowOverlock ||
|
||||
x.UseBIOS != y.UseBIOS ||
|
||||
x.ConsoleRegion != y.ConsoleRegion ||
|
||||
x.DisplayType != y.DisplayType;
|
||||
x.DisplayType != y.DisplayType ||
|
||||
x.ControllerType != y.ControllerType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,8 +65,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);
|
||||
ser.Sync("Controller1SelectHigh", ref Controller1SelectHigh);
|
||||
ser.Sync("ControllerSelect2High", ref Controller2SelectHigh);
|
||||
ser.Sync("LatchLightPhaser", ref LatchLightPhaser);
|
||||
|
||||
if (SaveRAM != null)
|
||||
|
|
|
@ -67,95 +67,262 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
}
|
||||
};
|
||||
|
||||
// The paddles have a nibble select state
|
||||
bool Paddle1High = false;
|
||||
bool Paddle2High = false;
|
||||
public static readonly ControllerDefinition SMSSportsPadController = new ControllerDefinition
|
||||
{
|
||||
Name = "SMS Sports Pad Controller",
|
||||
BoolButtons =
|
||||
{
|
||||
"Reset", "Pause",
|
||||
"P1 Left", "P1 Right", "P1 Up", "P1 Down", "P1 B1", "P1 B2",
|
||||
"P2 Left", "P2 Right", "P2 Up", "P2 Down", "P2 B1", "P2 B2"
|
||||
},
|
||||
FloatControls =
|
||||
{
|
||||
"P1 X", "P1 Y",
|
||||
"P2 X", "P2 Y"
|
||||
},
|
||||
FloatRanges =
|
||||
{
|
||||
new ControllerDefinition.FloatRange(-64, 0, 63),
|
||||
new ControllerDefinition.FloatRange(-64, 0, 63),
|
||||
new ControllerDefinition.FloatRange(-64, 0, 63),
|
||||
new ControllerDefinition.FloatRange(-64, 0, 63)
|
||||
}
|
||||
};
|
||||
|
||||
const int PaddleMin = 0;
|
||||
const int PaddleMax = 255;
|
||||
const int SportsPadMin = -64;
|
||||
const int SportsPadMax = 63;
|
||||
|
||||
// The paddles and sports pads have data select states
|
||||
bool Controller1SelectHigh = true;
|
||||
bool Controller2SelectHigh = true;
|
||||
|
||||
bool LatchLightPhaser = false;
|
||||
|
||||
|
||||
// further state value for sports pad, may be useful for other controllers in future
|
||||
int Controller1State = 3;
|
||||
int Controller2State = 3;
|
||||
int ControllerTick = 0; // for timing in japan
|
||||
|
||||
private byte ReadControls1()
|
||||
{
|
||||
InputCallbacks.Call();
|
||||
_lagged = false;
|
||||
byte value = 0xFF;
|
||||
|
||||
switch (Settings.ControllerType)
|
||||
switch (SyncSettings.ControllerType)
|
||||
{
|
||||
case "Paddle":
|
||||
// use analog values from a controller, see http://www.smspower.org/Development/Paddle
|
||||
|
||||
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)
|
||||
// use analog values from a controller, see http://www.smspower.org/Development/Paddle
|
||||
|
||||
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");
|
||||
|
||||
PresetControllerState(1);
|
||||
// Hard-wired together?
|
||||
Controller2SelectHigh = Controller1SelectHigh;
|
||||
|
||||
if (Controller1SelectHigh)
|
||||
{
|
||||
Paddle1High = (Port3F & 0x20) != 0;
|
||||
Paddle2High = 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;
|
||||
}
|
||||
if ((Port3F & 0x08) == 0x00)
|
||||
else
|
||||
{
|
||||
Paddle2High = (Port3F & 0x80) != 0;
|
||||
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 (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 (!Controller1SelectHigh) value &= 0xDF;
|
||||
|
||||
if (_controller.IsPressed("P1 B1")) value &= 0xEF;
|
||||
if (!Paddle1High) value &= 0xDF;
|
||||
if (Controller2SelectHigh)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (Paddle2High)
|
||||
{
|
||||
if ((paddle2Pos & 0x10) == 0) value &= 0xBF;
|
||||
if ((paddle2Pos & 0x20) == 0) value &= 0x7F;
|
||||
PostsetControllerState(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((paddle2Pos & 0x01) == 0) value &= 0xBF;
|
||||
if ((paddle2Pos & 0x02) == 0) value &= 0x7F;
|
||||
}
|
||||
|
||||
// toggle state for Japanese region controllers
|
||||
Paddle1High = !Paddle1High;
|
||||
|
||||
break;
|
||||
|
||||
case "Light Phaser":
|
||||
if (_controller.IsPressed("P1 Trigger")) value &= 0xEF;
|
||||
break;
|
||||
|
||||
case "Sports Pad":
|
||||
{
|
||||
int p1X;
|
||||
if (_controller.IsPressed("P1 Left"))
|
||||
p1X = SportsPadMin;
|
||||
else if (_controller.IsPressed("P1 Right"))
|
||||
p1X = SportsPadMax;
|
||||
else
|
||||
p1X = (int)_controller.GetFloat("P1 X");
|
||||
|
||||
int p1Y;
|
||||
if (_controller.IsPressed("P1 Up"))
|
||||
p1Y = SportsPadMin;
|
||||
else if (_controller.IsPressed("P1 Down"))
|
||||
p1Y = SportsPadMax;
|
||||
else
|
||||
p1Y = (int)_controller.GetFloat("P1 Y");
|
||||
|
||||
int p2X;
|
||||
if (_controller.IsPressed("P2 Left"))
|
||||
p2X = SportsPadMin;
|
||||
else if (_controller.IsPressed("P2 Right"))
|
||||
p2X = SportsPadMax;
|
||||
else
|
||||
p2X = (int)_controller.GetFloat("P2 X");
|
||||
|
||||
int p2Y;
|
||||
if (_controller.IsPressed("P2 Up"))
|
||||
p2Y = SportsPadMin;
|
||||
else if (_controller.IsPressed("P2 Down"))
|
||||
p2Y = SportsPadMax;
|
||||
else
|
||||
p2Y = (int)_controller.GetFloat("P2 Y");
|
||||
|
||||
if(_region == "Japan")
|
||||
{
|
||||
p1X += 128;
|
||||
p1Y += 128;
|
||||
p2X += 128;
|
||||
p2Y += 128;
|
||||
} else
|
||||
{
|
||||
p1X *= -1;
|
||||
p1Y *= -1;
|
||||
p2X *= -1;
|
||||
p2Y *= -1;
|
||||
}
|
||||
|
||||
PresetControllerState(1);
|
||||
|
||||
// advance state
|
||||
if (Controller1SelectHigh && (Controller1State % 2 == 0))
|
||||
{
|
||||
++Controller1State;
|
||||
}
|
||||
else if (!Controller1SelectHigh && (Controller1State % 2 == 1))
|
||||
{
|
||||
if (++Controller1State == (_region == "Japan" ? 6 : 4))
|
||||
Controller1State = 0;
|
||||
}
|
||||
if (Controller2SelectHigh && (Controller2State % 2 == 0))
|
||||
{
|
||||
++Controller2State;
|
||||
}
|
||||
else if (!Controller2SelectHigh && (Controller2State % 2 == 1))
|
||||
{
|
||||
if (++Controller2State == (_region == "Japan" ? 6 : 4))
|
||||
Controller2State = 0;
|
||||
}
|
||||
|
||||
switch (Controller1State)
|
||||
{
|
||||
case 0:
|
||||
if ((p1X & 0x10) == 0) value &= 0xFE;
|
||||
if ((p1X & 0x20) == 0) value &= 0xFD;
|
||||
if ((p1X & 0x40) == 0) value &= 0xFB;
|
||||
if ((p1X & 0x80) == 0) value &= 0xF7;
|
||||
break;
|
||||
case 1:
|
||||
if ((p1X & 0x01) == 0) value &= 0xFE;
|
||||
if ((p1X & 0x02) == 0) value &= 0xFD;
|
||||
if ((p1X & 0x04) == 0) value &= 0xFB;
|
||||
if ((p1X & 0x08) == 0) value &= 0xF7;
|
||||
break;
|
||||
case 2:
|
||||
if ((p1Y & 0x10) == 0) value &= 0xFE;
|
||||
if ((p1Y & 0x20) == 0) value &= 0xFD;
|
||||
if ((p1Y & 0x40) == 0) value &= 0xFB;
|
||||
if ((p1Y & 0x80) == 0) value &= 0xF7;
|
||||
break;
|
||||
case 3:
|
||||
if ((p1Y & 0x01) == 0) value &= 0xFE;
|
||||
if ((p1Y & 0x02) == 0) value &= 0xFD;
|
||||
if ((p1Y & 0x04) == 0) value &= 0xFB;
|
||||
if ((p1Y & 0x08) == 0) value &= 0xF7;
|
||||
break;
|
||||
case 4:
|
||||
// specific to Japan: sync via TR
|
||||
value &= 0xDF;
|
||||
break;
|
||||
case 5:
|
||||
// specific to Japan: buttons
|
||||
if (_controller.IsPressed("P1 B1")) value &= 0xFE;
|
||||
if (_controller.IsPressed("P1 B2")) value &= 0xFD;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_region != "Japan")
|
||||
{
|
||||
// Buttons like normal in Export
|
||||
if (_controller.IsPressed("P1 B1")) value &= 0xEF;
|
||||
if (_controller.IsPressed("P1 B2")) value &= 0xDF;
|
||||
}
|
||||
else
|
||||
{
|
||||
// In Japan, it contains selectHigh
|
||||
if (!Controller1SelectHigh) value &= 0xEF;
|
||||
}
|
||||
|
||||
switch (Controller2State)
|
||||
{
|
||||
case 0:
|
||||
if ((p2X & 0x10) == 0) value &= 0xBF;
|
||||
if ((p2X & 0x20) == 0) value &= 0x7F;
|
||||
break;
|
||||
case 1:
|
||||
if ((p2X & 0x01) == 0) value &= 0xBF;
|
||||
if ((p2X & 0x02) == 0) value &= 0x7F;
|
||||
break;
|
||||
case 2:
|
||||
if ((p2Y & 0x10) == 0) value &= 0xBF;
|
||||
if ((p2Y & 0x20) == 0) value &= 0x7F;
|
||||
break;
|
||||
case 3:
|
||||
if ((p2Y & 0x01) == 0) value &= 0xBF;
|
||||
if ((p2Y & 0x02) == 0) value &= 0x7F;
|
||||
break;
|
||||
case 5:
|
||||
// specific to Japan: buttons
|
||||
if (_controller.IsPressed("P2 B1")) value &= 0xBF;
|
||||
if (_controller.IsPressed("P2 B2")) value &= 0x7F;
|
||||
break;
|
||||
}
|
||||
|
||||
PostsetControllerState(1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Normal controller
|
||||
|
||||
|
@ -180,43 +347,38 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
_lagged = false;
|
||||
byte value = 0xFF;
|
||||
|
||||
switch (Settings.ControllerType)
|
||||
switch (SyncSettings.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)
|
||||
// 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");
|
||||
|
||||
PresetControllerState(2);
|
||||
|
||||
if (Controller2SelectHigh)
|
||||
{
|
||||
Paddle2High = (Port3F & 0x80) != 0;
|
||||
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 (!Controller2SelectHigh) value &= 0xF7;
|
||||
|
||||
PostsetControllerState(2);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
case "Light Phaser":
|
||||
|
@ -227,6 +389,81 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
}
|
||||
break;
|
||||
|
||||
case "Sports Pad":
|
||||
{
|
||||
int p2X;
|
||||
if (_controller.IsPressed("P2 Left"))
|
||||
p2X = SportsPadMin;
|
||||
else if (_controller.IsPressed("P2 Right"))
|
||||
p2X = SportsPadMax;
|
||||
else
|
||||
p2X = (int)_controller.GetFloat("P2 X");
|
||||
|
||||
int p2Y;
|
||||
if (_controller.IsPressed("P2 Down"))
|
||||
p2Y = SportsPadMin;
|
||||
else if (_controller.IsPressed("P2 Up"))
|
||||
p2Y = SportsPadMax;
|
||||
else
|
||||
p2Y = (int)_controller.GetFloat("P2 Y");
|
||||
|
||||
if (_region == "Japan")
|
||||
{
|
||||
p2X += 128;
|
||||
p2Y += 128;
|
||||
}
|
||||
else
|
||||
{
|
||||
p2X *= -1;
|
||||
p2Y *= -1;
|
||||
}
|
||||
|
||||
PresetControllerState(2);
|
||||
|
||||
if (Controller2SelectHigh && (Controller2State % 2 == 0))
|
||||
{
|
||||
++Controller2State;
|
||||
}
|
||||
else if (!Controller2SelectHigh && (Controller2State % 2 == 1))
|
||||
{
|
||||
if (++Controller2State == (_region == "Japan" ? 6 : 4))
|
||||
Controller2State = 0;
|
||||
}
|
||||
|
||||
switch (Controller2State)
|
||||
{
|
||||
case 0:
|
||||
if ((p2X & 0x40) == 0) value &= 0xFE;
|
||||
if ((p2X & 0x80) == 0) value &= 0xFD;
|
||||
break;
|
||||
case 1:
|
||||
if ((p2X & 0x04) == 0) value &= 0xFE;
|
||||
if ((p2X & 0x08) == 0) value &= 0xFD;
|
||||
break;
|
||||
case 2:
|
||||
if ((p2Y & 0x40) == 0) value &= 0xFE;
|
||||
if ((p2Y & 0x80) == 0) value &= 0xFD;
|
||||
break;
|
||||
case 3:
|
||||
if ((p2Y & 0x04) == 0) value &= 0xFE;
|
||||
if ((p2Y & 0x08) == 0) value &= 0xFD;
|
||||
break;
|
||||
}
|
||||
if (_region != "Japan")
|
||||
{
|
||||
// Buttons like normal in Export
|
||||
if (_controller.IsPressed("P2 B1")) value &= 0xFB;
|
||||
if (_controller.IsPressed("P2 B2")) value &= 0xF7;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Controller2SelectHigh) value &= 0xF7;
|
||||
}
|
||||
|
||||
PostsetControllerState(2);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
// Normal controller
|
||||
|
||||
|
@ -262,7 +499,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
const int phaserRadius = 4;
|
||||
|
||||
// specifically lightgun needs to do things on a per-line basis
|
||||
if (Settings.ControllerType == "Light Phaser")
|
||||
if (SyncSettings.ControllerType == "Light Phaser")
|
||||
{
|
||||
byte phaserX = (byte)(_controller.GetFloat("P1 X") + 20);
|
||||
int phaserY = (int)_controller.GetFloat("P1 Y");
|
||||
|
@ -305,5 +542,49 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
|
|||
|
||||
return value;
|
||||
}
|
||||
|
||||
private void PresetControllerState(int pin)
|
||||
{
|
||||
// The 3F port's TH slot is also used on games in some games in Export BIOS to clock the paddle state
|
||||
// Re: the paddle: Yes it's silly considering the paddle was never released outside Japan but the games think otherwise
|
||||
|
||||
if (_region != "Japan")
|
||||
{
|
||||
if ((Port3F & 0x02) == 0x00)
|
||||
{
|
||||
Controller1SelectHigh = (Port3F & 0x20) != 0;
|
||||
|
||||
// resync
|
||||
Controller2State = 3;
|
||||
}
|
||||
|
||||
if ((Port3F & 0x08) == 0x00)
|
||||
{
|
||||
Controller2SelectHigh = (Port3F & 0x80) != 0;
|
||||
|
||||
// resync
|
||||
Controller1State = 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PostsetControllerState(int pin)
|
||||
{
|
||||
// for the benefit of the Japan region
|
||||
if (_region == "Japan" && (++ControllerTick) == 2)
|
||||
{
|
||||
ControllerTick = 0;
|
||||
|
||||
if (pin == 1)
|
||||
{
|
||||
Controller1SelectHigh ^= true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Controller1SelectHigh = false;
|
||||
Controller2SelectHigh ^= true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ using BizHawk.Emulation.Cores.Components.Z80A;
|
|||
TODO:
|
||||
+ HCounter (Manually set for light phaser emulation... should be only case it's polled)
|
||||
+ Try to clean up the organization of the source code.
|
||||
+ Lightgun/Paddle/etc if I get really bored (first 2 done!)
|
||||
+ Mode 1 not implemented in VDP TMS modes. (I dont have a test case in SG1000 or Coleco)
|
||||
|
||||
**********************************************************/
|
||||
|
|
Loading…
Reference in New Issue