Adds SEGA Sports Pad for SMS support, also make controller syncsetting

This commit is contained in:
Tastyfish 2017-10-27 19:57:18 -04:00 committed by nattthebear
parent 03dcc63467
commit 9693d812d2
9 changed files with 454 additions and 119 deletions

View File

@ -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
}
}
}
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
}
}

View File

@ -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)

View File

@ -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;
}
}
}
}
}

View File

@ -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)
**********************************************************/