A7800Hawk: Add Light Gun Support

-Needs testing
This commit is contained in:
alyosha-tas 2017-07-26 09:28:14 -04:00 committed by GitHub
parent 6bc1befc5b
commit efcb73615b
6 changed files with 175 additions and 4 deletions

View File

@ -32,6 +32,15 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
public bool right_was_pressed;
public bool p1_is_2button;
public bool p2_is_2button;
public bool p1_is_lightgun;
public bool p2_is_lightgun;
public float p1_lightgun_x;
public float p1_lightgun_y;
public float p2_lightgun_x;
public float p2_lightgun_y;
public bool lg_counting_down;
public bool lg_trigger_hit;
public int lg_target;
// there are 4 maria cycles in a CPU cycle (fast access, both NTSC and PAL)
// if the 6532 or TIA are accessed (PC goes to one of those addresses) the next access will be slower by 1/2 a CPU cycle
@ -66,6 +75,10 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
GetControllerState(controller);
GetConsoleState(controller);
//reset lightgun detection
lg_counting_down = false;
lg_trigger_hit = false;
maria.RunFrame();
if (_islag)
@ -160,6 +173,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
p2_fire_2x = _controllerDeck.ReadFire2_2x(controller);
p1_is_2button = _controllerDeck.Is_2_button1(controller);
p2_is_2button = _controllerDeck.Is_2_button2(controller);
p1_is_lightgun = _controllerDeck.Is_LightGun1(controller, out p1_lightgun_x, out p1_lightgun_y);
p2_is_lightgun = _controllerDeck.Is_LightGun2(controller, out p2_lightgun_x, out p2_lightgun_y);
}
public void GetConsoleState(IController controller)
@ -212,6 +227,53 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
con_state = result;
}
public byte getLightGunState(int p_x)
{
float x = p_x == 1 ? p1_lightgun_x : p2_lightgun_x;
float y = p_x == 1 ? p1_lightgun_y : p2_lightgun_y;
if ((maria.scanline - 21) == y)
{
if (maria.cycle >= (133 + x) && !lg_counting_down)
{
// return true 60 cycles into the future
lg_counting_down = true;
lg_target = (int)(133 + x) + 60;
}
}
else if ((maria.scanline - 21) == (y + 1) && !lg_counting_down && !lg_trigger_hit)
{
// return true 60 cycles into the future
lg_counting_down = true;
lg_target = 53;
}
if (lg_counting_down)
{
if (((maria.scanline - 21) == y) && (maria.cycle >= lg_target))
{
lg_trigger_hit = true;
lg_counting_down = false;
}
else if (((maria.scanline - 21) == (y + 1)) && (maria.cycle >= (lg_target % 453)))
{
//Console.WriteLine(maria.cycle);
lg_trigger_hit = true;
lg_counting_down = false;
}
}
if (lg_trigger_hit)
{
return 0x0;
}
else
{
return 0x80;
}
}
public int Frame => _frame;
public string SystemId => "A7800";

View File

@ -233,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
ser.Register<ITraceable>(_tracer);
SetupMemoryDomains();
HardReset();
HardReset();
}
public DisplayType Region => _isPAL ? DisplayType.PAL : DisplayType.NTSC;

View File

@ -90,6 +90,16 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
return Port2.Is_2_button(c);
}
public bool Is_LightGun1(IController c, out float lightgun_x, out float lightgun_y)
{
return Port1.Is_LightGun(c, out lightgun_x, out lightgun_y);
}
public bool Is_LightGun2(IController c, out float lightgun_x, out float lightgun_y)
{
return Port2.Is_LightGun(c, out lightgun_x, out lightgun_y);
}
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)

View File

@ -21,6 +21,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
bool Is_2_button(IController c);
bool Is_LightGun(IController c, out float x, out float y);
ControllerDefinition Definition { get; }
void SyncState(Serializer ser);
@ -60,6 +62,13 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
return false;
}
public bool Is_LightGun(IController c, out float x, out float y)
{
x = -1;
y = -1;
return false;
}
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
@ -126,6 +135,13 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
return false;
}
public bool Is_LightGun(IController c, out float x, out float y)
{
x = -1;
y = -1;
return false;
}
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
@ -212,6 +228,13 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
return true;
}
public bool Is_LightGun(IController c, out float x, out float y)
{
x = -1;
y = -1;
return false;
}
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
@ -232,4 +255,75 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
0x0, // Right
};
}
}
[DisplayName("Light Gun Controller")]
public class LightGunController : IPort
{
public LightGunController(int portNum)
{
PortNum = portNum;
Definition = new ControllerDefinition
{
Name = "Light Gun Controller",
BoolButtons = BaseDefinition
.Select(b => "P" + PortNum + " " + b)
.ToList(),
FloatControls = { "P" + PortNum + " X", "P" + PortNum + " Y" },
FloatRanges = { new[] { 1.0f, 160, 320.0f }, new[] { 1.0f, 121, 242.0f } }
};
}
public int PortNum { get; }
public byte Read(IController c)
{
byte result = 0xE;
if (c.IsPressed(Definition.BoolButtons[0]))
{
result |= 0x1;
}
if (PortNum == 1)
{
result = (byte)(result << 4);
}
return result;
}
public byte ReadFire(IController c)
{
return 0x80;
}
public byte ReadFire2x(IController c)
{
return 0; // only applicable for 2 button mode
}
public bool Is_2_button(IController c)
{
return false;
}
public bool Is_LightGun(IController c, out float x, out float y)
{
x = c.GetFloat(Definition.FloatControls[0]);
y = c.GetFloat(Definition.FloatControls[1]);
return true;
}
public ControllerDefinition Definition { get; }
public void SyncState(Serializer ser)
{
// Nothing todo, I think
}
private static readonly string[] BaseDefinition =
{
"Trigger"
};
}
}

View File

@ -506,6 +506,11 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
}
}
}
if (graphics_read_time == 0)
{
graphics_read_time = 3;
}
}
else
{

View File

@ -107,7 +107,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
// return TIA registers or control register if it is still unlocked
if ((A7800_control_register & 0x1) == 0)
{
A7800_control_register = value;
A7800_control_register = value;
}
else
{
@ -133,8 +133,8 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk
Console.Write(Maria_regs[i]);
Console.Write(" ");
}
Console.WriteLine(maria.scanline);
*/
}
else
{