From efcb73615b641088bc04285ca8ad09afc1ca3b75 Mon Sep 17 00:00:00 2001 From: alyosha-tas Date: Wed, 26 Jul 2017 09:28:14 -0400 Subject: [PATCH] A7800Hawk: Add Light Gun Support -Needs testing --- .../Atari/A7800Hawk/A7800Hawk.IEmulator.cs | 62 ++++++++++++ .../Consoles/Atari/A7800Hawk/A7800Hawk.cs | 2 +- .../A7800Hawk/A7800HawkControllerDeck.cs | 10 ++ .../Atari/A7800Hawk/A7800HawkControllers.cs | 96 ++++++++++++++++++- .../Consoles/Atari/A7800Hawk/Maria.cs | 5 + .../Consoles/Atari/A7800Hawk/MemoryMap.cs | 4 +- 6 files changed, 175 insertions(+), 4 deletions(-) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs index f6f7ca33c1..b95af16f87 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.IEmulator.cs @@ -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"; diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs index 06117d1246..0ffa92e67d 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800Hawk.cs @@ -233,7 +233,7 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk ser.Register(_tracer); SetupMemoryDomains(); - HardReset(); + HardReset(); } public DisplayType Region => _isPAL ? DisplayType.PAL : DisplayType.NTSC; diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs index 1514aa52ef..3d9d21dd23 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllerDeck.cs @@ -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) diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs index fa9c239972..4bb7f50438 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/A7800HawkControllers.cs @@ -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" + }; + } +} \ No newline at end of file diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Maria.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Maria.cs index 3f483c343d..7872b81538 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Maria.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/Maria.cs @@ -506,6 +506,11 @@ namespace BizHawk.Emulation.Cores.Atari.A7800Hawk } } } + if (graphics_read_time == 0) + { + graphics_read_time = 3; + } + } else { diff --git a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/MemoryMap.cs b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/MemoryMap.cs index 7dd3e34cf5..bc1d31ed44 100644 --- a/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/MemoryMap.cs +++ b/BizHawk.Emulation.Cores/Consoles/Atari/A7800Hawk/MemoryMap.cs @@ -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 {