SMS Light Phaser support

This commit is contained in:
Tastyfish 2017-08-31 12:58:27 -04:00
parent 40ec613982
commit d0fdc75a1e
8 changed files with 117 additions and 9 deletions

View File

@ -748,7 +748,12 @@
"P1 Right": "RightArrow, J1 POV1R",
"P1 B1": "Z, J1 B1, X1 X",
"Reset": "J1 B9, X1 Back",
"Pause": "J1 B10, X1 Start",
"Pause": "J1 B10, X1 Start"
},
"SMS Light Phaser Controller": {
"P1 Trigger": "Z, J1 B1, X1 X, WMouse L",
"Reset": "J1 B9, X1 Back",
"Pause": "J1 B10, X1 Start"
},
"GG Controller": {
"P1 Up": "UpArrow, J1 POV1U, X1 DpadUp, X1 LStickUp",
@ -1581,6 +1586,18 @@
"Mult": 1.0,
"Deadzone": 0.1
}
},
"SMS Light Phaser Controller": {
"P1 X": {
"Value": "WMouse X",
"Mult": 1.0,
"Deadzone": 0.0
},
"P1 Y": {
"Value": "WMouse Y",
"Mult": 1.0,
"Deadzone": 0.0
}
}
}
}

View File

@ -445,6 +445,7 @@
this.SMSControllerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
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.MainStatusBar.SuspendLayout();
this.MainFormContextMenu.SuspendLayout();
@ -2552,7 +2553,8 @@
this.SMSControllerToolStripMenuItem.Text = "&Controller Type";
this.SMSControllerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.SMSControllerStandardToolStripMenuItem,
this.SMSControllerPaddleToolStripMenuItem});
this.SMSControllerPaddleToolStripMenuItem,
this.SMSControllerLightPhaserToolStripMenuItem});
//
// SMSControllerStandardToolStripMenuItem
//
@ -2566,6 +2568,12 @@
this.SMSControllerPaddleToolStripMenuItem.Text = "Paddle";
this.SMSControllerPaddleToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerPaddleToolStripMenuItem_Click);
//
// SMSControllerLightPhaserToolStripMenuItem
//
this.SMSControllerLightPhaserToolStripMenuItem.Name = "SMSControllerLightPhaserToolStripMenuItem";
this.SMSControllerLightPhaserToolStripMenuItem.Text = "Light Phaser";
this.SMSControllerLightPhaserToolStripMenuItem.Click += new System.EventHandler(this.SMSControllerLightPhaserToolStripMenuItem_Click);
//
// SMSdisplayPalToolStripMenuItem
//
this.SMSdisplayPalToolStripMenuItem.Name = "SMSdisplayPalToolStripMenuItem";
@ -4395,5 +4403,6 @@
private System.Windows.Forms.ToolStripMenuItem SMSControllerToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerStandardToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerPaddleToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem SMSControllerLightPhaserToolStripMenuItem;
}
}

View File

@ -1747,6 +1747,7 @@ namespace BizHawk.Client.EmuHawk
SMSdisplayAutoToolStripMenuItem.Checked = ss.DisplayType == "Auto";
SMSControllerStandardToolStripMenuItem.Checked = s.ControllerType == "Standard";
SMSControllerPaddleToolStripMenuItem.Checked = s.ControllerType == "Paddle";
SMSControllerLightPhaserToolStripMenuItem.Checked = s.ControllerType == "Light Phaser";
SMSenableBIOSToolStripMenuItem.Checked = ss.UseBIOS;
SMSEnableFMChipMenuItem.Checked = ss.EnableFM;
SMSOverclockMenuItem.Checked = ss.AllowOverlock;
@ -1915,6 +1916,13 @@ namespace BizHawk.Client.EmuHawk
PutCoreSettings(s);
}
private void SMSControllerLightPhaserToolStripMenuItem_Click(object sender, EventArgs e)
{
var s = ((SMS)Emulator).GetSettings();
s.ControllerType = "Light Phaser";
PutCoreSettings(s);
}
#endregion
#region TI83

View File

@ -19,6 +19,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
{
case "Paddle":
return SMSPaddleController;
case "Light Phaser":
// scale the vertical to the display mode
SMSLightPhaserController.FloatRanges[1] = new ControllerDefinition.FloatRange(0, Vdp.FrameHeight / 2, Vdp.FrameHeight - 1);
return SMSLightPhaserController;
default:
return SmsController;
}

View File

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

View File

@ -7,15 +7,15 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
public partial class SMS
{
public static readonly ControllerDefinition SmsController = new ControllerDefinition
{
Name = "SMS Controller",
BoolButtons =
{
Name = "SMS Controller",
BoolButtons =
{
"Reset", "Pause",
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 B1", "P1 B2",
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 B1", "P2 B2"
}
};
};
public static readonly ControllerDefinition GGController = new ControllerDefinition
{
@ -48,6 +48,25 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
};
public static readonly ControllerDefinition SMSLightPhaserController = new ControllerDefinition
{
Name = "SMS Light Phaser Controller",
BoolButtons =
{
"Reset", "Pause",
"P1 Trigger",
},
FloatControls =
{
"P1 X", "P1 Y",
},
FloatRanges =
{
new ControllerDefinition.FloatRange(0, 64, 127),
new ControllerDefinition.FloatRange(0, 500, 1000)
}
};
// The paddles have a nibble select state
bool Paddle1High = false;
bool Paddle2High = false;
@ -55,6 +74,8 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
const int PaddleMin = 0;
const int PaddleMax = 255;
bool LatchLightPhaser = false;
private byte ReadControls1()
{
InputCallbacks.Call();
@ -131,6 +152,10 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
break;
case "Light Phaser":
if (_controller.IsPressed("P1 Trigger")) value &= 0xEF;
break;
default:
// Normal controller
@ -194,6 +219,14 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
break;
case "Light Phaser":
if (LatchLightPhaser)
{
value &= 0xBF;
LatchLightPhaser = false;
}
break;
default:
// Normal controller
@ -224,6 +257,33 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
return value;
}
internal void ProcessLineControls()
{
const int phaserRadius = 4;
// specifically lightgun needs to do things on a per-line basis
if (Settings.ControllerType == "Light Phaser")
{
byte phaserX = (byte)(_controller.GetFloat("P1 X") + 20);
int phaserY = (int)_controller.GetFloat("P1 Y");
int scanline = Vdp.ScanLine;
if (!LatchLightPhaser && phaserY >= scanline - phaserRadius && phaserY <= scanline + phaserRadius)
{
if (scanline >= Vdp.FrameHeight)
return;
// latch HCounter via TH
Vdp.HCounter = phaserX;
LatchLightPhaser = true;
}
else
{
LatchLightPhaser = false;
}
}
}
byte ReadPort0()
{
if (IsGameGear == false)

View File

@ -8,9 +8,9 @@ using BizHawk.Emulation.Cores.Components.Z80;
/*****************************************************
TODO:
+ HCounter
+ 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
+ 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)
**********************************************************/
@ -281,7 +281,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
if ((port & 1) == 0)
return Vdp.ReadVLineCounter();
else
return 0x50; // TODO Vdp.ReadHLineCounter();
return Vdp.ReadHLineCounter();
}
if (port < 0xC0) // VDP data/control ports
{

View File

@ -47,6 +47,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
public int FrameHeight = 192;
public int ScanLine;
public byte HCounter = 0x90;
public int[] FrameBuffer = new int[256 * 192];
public int[] GameGearFrameBuffer = new int[160 * 144];
public int[] OverscanFrameBuffer = null;
@ -136,6 +137,11 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
}
}
public byte ReadHLineCounter()
{
return HCounter;
}
public void WriteVdpControl(byte value)
{
if (VdpWaitingForLatchByte)
@ -375,6 +381,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
ProcessFrameInterrupt();
ProcessLineInterrupt();
Sms.ProcessLineControls();
Cpu.ExecuteCycles(IPeriod);
@ -428,6 +435,7 @@ namespace BizHawk.Emulation.Cores.Sega.MasterSystem
ser.Sync("Registers", ref Registers, false);
ser.Sync("CRAM", ref CRAM, false);
ser.Sync("VRAM", ref VRAM, false);
ser.Sync("HCounter", ref HCounter);
ser.EndSection();
if (ser.IsReader)