misc. cleanups in atari 7800

This commit is contained in:
adelikat 2017-04-24 10:32:45 -05:00
parent 2964585401
commit c628557912
6 changed files with 157 additions and 110 deletions

View File

@ -60,14 +60,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
get { throw new NotImplementedException(); }
}
public bool CanStep(StepType type) { return false; }
public bool CanStep(StepType type)
{
return false;
}
[FeatureNotImplemented]
public void Step(StepType type) { throw new NotImplementedException(); }
public int TotalExecutedCycles
public void Step(StepType type)
{
get { return (int)theMachine.CPU.Clock; }
throw new NotImplementedException();
}
public int TotalExecutedCycles => (int)theMachine.CPU.Clock;
}
}

View File

@ -16,7 +16,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
set { _islag = value; }
}
public IInputCallbackSystem InputCallbacks { get; private set; }
public IInputCallbackSystem InputCallbacks { get; } = new InputCallbackSystem();
private bool _islag = true;
private int _lagcount;

View File

@ -10,17 +10,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
{
return (byte[])hsram.Clone();
}
public void StoreSaveRam(byte[] data)
{
Buffer.BlockCopy(data, 0, hsram, 0, data.Length);
}
public bool SaveRamModified
{
get
{
return GameInfo.MachineType == MachineType.A7800PAL || GameInfo.MachineType == MachineType.A7800NTSC;
}
}
public bool SaveRamModified => GameInfo.MachineType == MachineType.A7800PAL
|| GameInfo.MachineType == MachineType.A7800NTSC;
}
}

View File

@ -8,7 +8,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
{
public partial class Atari7800 : IStatable
{
public bool BinarySaveStatesPreferred { get { return true; } }
public bool BinarySaveStatesPreferred => true;
public void SaveStateText(TextWriter writer)
{

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using EMU7800.Core;
@ -14,25 +12,34 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
isPorted: true,
isReleased: true,
portedVersion: "v1.5",
portedUrl: "http://emu7800.sourceforge.net/"
)]
portedUrl: "http://emu7800.sourceforge.net/")]
[ServiceNotApplicable(typeof(ISettable<,>), typeof(IDriveLight))]
public partial class Atari7800 : IEmulator, ISaveRam, IDebuggable, IStatable, IInputPollable, IRegionable
{
// TODO:
// some things don't work when you try to plug in a 2600 game
static Atari7800()
{
// add alpha bits to palette tables
for (int i = 0; i < TIATables.NTSCPalette.Length; i++)
{
TIATables.NTSCPalette[i] |= unchecked((int)0xff000000);
}
for (int i = 0; i < TIATables.PALPalette.Length; i++)
{
TIATables.PALPalette[i] |= unchecked((int)0xff000000);
}
for (int i = 0; i < MariaTables.NTSCPalette.Length; i++)
{
MariaTables.NTSCPalette[i] |= unchecked((int)0xff000000);
}
for (int i = 0; i < MariaTables.PALPalette.Length; i++)
{
MariaTables.PALPalette[i] |= unchecked((int)0xff000000);
}
}
public Atari7800(CoreComm comm, GameInfo game, byte[] rom, string GameDBfn)
@ -40,7 +47,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
ServiceProvider = new BasicServiceProvider(this);
(ServiceProvider as BasicServiceProvider).Register<IVideoProvider>(avProvider);
(ServiceProvider as BasicServiceProvider).Register<ISoundProvider>(avProvider);
InputCallbacks = new InputCallbackSystem();
CoreComm = comm;
byte[] highscoreBIOS = comm.CoreFileProvider.GetFirmware("A78", "Bios_HSC", false, "Some functions may not work without the high score BIOS.");
byte[] pal_bios = comm.CoreFileProvider.GetFirmware("A78", "Bios_PAL", false, "The game will not run if the correct region BIOS is not available.");
@ -58,6 +65,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
Buffer.BlockCopy(rom, 128, newrom, 0, newrom.Length);
rom = newrom;
}
GameInfo = EMU7800.Win.GameProgramLibrary.EMU7800DB.TryRecognizeRom(rom);
CoreComm.RomStatusDetails = GameInfo.ToString();
Console.WriteLine("Rom Determiniation from 7800DB:");
@ -79,18 +87,19 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
public IEmulatorServiceProvider ServiceProvider { get; private set; }
public byte[] rom;
public byte[] hsbios;
public byte[] bios;
Cart cart;
MachineBase theMachine;
EMU7800.Win.GameProgram GameInfo;
public byte[] hsram = new byte[2048];
private readonly byte[] rom;
public readonly byte[] hsbios;
public readonly byte[] bios;
private Cart cart;
private MachineBase theMachine;
private readonly EMU7800.Win.GameProgram GameInfo;
public readonly byte[] hsram = new byte[2048];
public string SystemId => "A78"; // TODO 2600?
public string SystemId { get { return "A78"; } } // TODO 2600?
public GameInfo game;
public string BoardName { get { return null; } }
public string BoardName => null;
public void FrameAdvance(bool render, bool rendersound)
{
@ -114,13 +123,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
}
avProvider.FillFrameBuffer();
}
public CoreComm CoreComm { get; private set; }
public CoreComm CoreComm { get; }
public bool DeterministicEmulation { get; set; }
public int Frame { get { return _frame; } set { _frame = value; } }
public int Frame => _frame;
private int _frame = 0;
public void Dispose()
@ -145,7 +154,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
public IController Controller { get; set; }
class ConsoleLogger : ILogger
private class ConsoleLogger : ILogger
{
public void WriteLine(string format, params object[] args)
{
@ -169,12 +178,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
}
private bool _pal;
public DisplayType Region
{
get { return _pal ? DisplayType.PAL : DisplayType.NTSC; }
}
public DisplayType Region => _pal ? DisplayType.PAL : DisplayType.NTSC;
void HardReset()
private void HardReset()
{
cart = Cart.Create(rom, GameInfo.CartType);
ILogger logger = new ConsoleLogger();
@ -202,6 +208,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
ControllerDefinition = ControlAdapter.ControlType;
avProvider.ConnectToMachine(theMachine, GameInfo);
// to sync exactly with audio as this emulator creates and times it, the frame rate should be exactly 60:1 or 50:1
CoreComm.VsyncNum = theMachine.FrameHZ;
CoreComm.VsyncDen = 1;
@ -211,9 +218,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
#region audio\video
MyAVProvider avProvider = new MyAVProvider();
private MyAVProvider avProvider = new MyAVProvider();
class MyAVProvider : IVideoProvider, ISoundProvider, IDisposable
private class MyAVProvider : IVideoProvider, ISoundProvider, IDisposable
{
public FrameBuffer framebuffer { get; private set; }
public void ConnectToMachine(MachineBase m, EMU7800.Win.GameProgram g)
@ -233,6 +240,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
samplerate = newsamplerate;
dcfilter = new DCFilter(256);
}
if (g.MachineType == MachineType.A2600PAL)
palette = TIATables.PALPalette;
else if (g.MachineType == MachineType.A7800PAL)
@ -243,11 +251,11 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
palette = MariaTables.NTSCPalette;
}
uint samplerate;
int[] vidbuffer;
SpeexResampler resampler;
DCFilter dcfilter;
int[] palette;
private uint samplerate;
private int[] vidbuffer;
private SpeexResampler resampler;
private DCFilter dcfilter;
private int[] palette;
public void FillFrameBuffer()
{
@ -272,18 +280,15 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
return vidbuffer;
}
public int VirtualWidth { get { return 275; } }
public int VirtualHeight { get { return BufferHeight; } }
public int VirtualWidth => 275;
public int VirtualHeight => BufferHeight;
public int BufferWidth { get; private set; }
public int BufferHeight { get; private set; }
public int BackgroundColor { get { return unchecked((int)0xff000000); } }
public int BackgroundColor => unchecked((int)0xff000000);
#region ISoundProvider
public bool CanProvideAsync
{
get { return false; }
}
public bool CanProvideAsync => false;
public void GetSamplesSync(out short[] samples, out int nsamp)
{
@ -306,10 +311,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
dcfilter.PushThroughSamples(samples, nsamp * 2);
}
public SyncSoundMode SyncMode
{
get { return SyncSoundMode.Sync; }
}
public SyncSoundMode SyncMode => SyncSoundMode.Sync;
public void SetSyncMode(SyncSoundMode mode)
{
@ -326,8 +328,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
public void DiscardSamples()
{
if (resampler != null)
resampler.DiscardSamples();
resampler?.DiscardSamples();
}
#endregion

View File

@ -7,37 +7,42 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
{
public class Atari7800Control
{
public static ControllerDefinition Joystick = new ControllerDefinition
private static readonly ControllerDefinition Joystick = new ControllerDefinition
{
Name = "Atari 7800 Joystick Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"BW", // should be "Color"??
"Left Difficulty", // better not put P# on these as they might not correspond to player numbers
"Right Difficulty",
// ports
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Trigger",
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Trigger"
}
};
public static ControllerDefinition Paddles = new ControllerDefinition
private static readonly ControllerDefinition Paddles = new ControllerDefinition
{
Name = "Atari 7800 Paddle Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"BW", // should be "Color"??
"Left Difficulty", // better not put P# on these as they might not correspond to player numbers
"Right Difficulty",
// ports
"P1 Trigger",
"P2 Trigger",
@ -54,25 +59,28 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
FloatRanges =
{
// what is the center point supposed to be here?
new[] {0.0f, 0.0f, 700000.0f},
new[] {0.0f, 0.0f, 700000.0f},
new[] {0.0f, 0.0f, 700000.0f},
new[] {0.0f, 0.0f, 700000.0f}
new[] { 0.0f, 0.0f, 700000.0f },
new[] { 0.0f, 0.0f, 700000.0f },
new[] { 0.0f, 0.0f, 700000.0f },
new[] { 0.0f, 0.0f, 700000.0f }
}
};
public static ControllerDefinition Keypad = new ControllerDefinition
private static readonly ControllerDefinition Keypad = new ControllerDefinition
{
Name = "Atari 7800 Keypad Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"BW", // should be "Color"??
"Toggle Left Difficulty", // better not put P# on these as they might not correspond to player numbers
"Toggle Right Difficulty",
// ports
"P1 Keypad1", "P1 Keypad2", "P1 Keypad3",
"P1 Keypad4", "P1 Keypad5", "P1 Keypad6",
@ -92,19 +100,22 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
"P4 KeypadA", "P4 Keypad0", "P4 KeypadP"
}
};
public static ControllerDefinition Driving = new ControllerDefinition
private static readonly ControllerDefinition Driving = new ControllerDefinition
{
Name = "Atari 7800 Driving Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"BW", // should be "Color"??
"Toggle Left Difficulty", // better not put P# on these as they might not correspond to player numbers
"Toggle Right Difficulty",
// ports
"P1 Trigger",
"P2 Trigger"
@ -116,59 +127,68 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
},
FloatRanges =
{
new[] {0.0f, 0.0f, 3.0f},
new[] {0.0f, 0.0f, 3.0f},
new[] {0.0f, 0.0f, 3.0f}
new[] { 0.0f, 0.0f, 3.0f },
new[] { 0.0f, 0.0f, 3.0f },
new[] { 0.0f, 0.0f, 3.0f }
}
};
public static ControllerDefinition BoosterGrip = new ControllerDefinition
private static readonly ControllerDefinition BoosterGrip = new ControllerDefinition
{
Name = "Atari 7800 Booster Grip Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"BW", // should be "Color"??
"Toggle Left Difficulty", // better not put P# on these as they might not correspond to player numbers
"Toggle Right Difficulty",
// ports
// NB: as referenced by the emu, p1t2 = p1t2, p1t3 = p2t2, p2t2 = p3t2, p2t3 = p4t2
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Trigger", "P1 Trigger 2", "P1 Trigger 3",
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Trigger", "P2 Trigger 2", "P2 Trigger 3"
}
};
public static ControllerDefinition ProLineJoystick = new ControllerDefinition
private static readonly ControllerDefinition ProLineJoystick = new ControllerDefinition
{
Name = "Atari 7800 ProLine Joystick Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"Pause",
"Toggle Left Difficulty", // better not put P# on these as they might not correspond to player numbers
"Toggle Right Difficulty",
// ports
"P1 Up", "P1 Down", "P1 Left", "P1 Right", "P1 Trigger", "P1 Trigger 2",
"P2 Up", "P2 Down", "P2 Left", "P2 Right", "P2 Trigger", "P2 Trigger 2"
}
};
public static ControllerDefinition Lightgun = new ControllerDefinition
private static readonly ControllerDefinition Lightgun = new ControllerDefinition
{
Name = "Atari 7800 Light Gun Controller",
BoolButtons =
{
// hard reset, not passed to EMU7800
"Power",
// on the console
"Reset",
"Select",
"Pause",
// ports
"P1 Trigger",
"P2 Trigger"
@ -181,29 +201,30 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
FloatRanges =
{
// how many scanlines are there again??
new[] {0.0f, 0.0f, 240.0f},
new[] {0.0f, 0.0f, 319.0f},
new[] {0.0f, 0.0f, 240.0f},
new[] {0.0f, 0.0f, 319.0f}
new[] { 0.0f, 0.0f, 240.0f },
new[] { 0.0f, 0.0f, 319.0f },
new[] { 0.0f, 0.0f, 240.0f },
new[] { 0.0f, 0.0f, 319.0f }
}
};
struct ControlAdapter
private struct ControlAdapter
{
public ControllerDefinition Type;
public Controller Left;
public Controller Right;
public Action<IController, InputState> Convert;
public ControlAdapter(ControllerDefinition Type, Controller Left, Controller Right, Action<IController, InputState> Convert)
public readonly ControllerDefinition Type;
public readonly Controller Left;
public readonly Controller Right;
public readonly Action<IController, InputState> Convert;
public ControlAdapter(ControllerDefinition type, Controller left, Controller right, Action<IController, InputState> convert)
{
this.Type = Type;
this.Left = Left;
this.Right = Right;
this.Convert = Convert;
Type = type;
Left = left;
Right = right;
Convert = convert;
}
}
static readonly ControlAdapter[] Adapters = new[]
private static readonly ControlAdapter[] Adapters =
{
new ControlAdapter(Joystick, Controller.Joystick, Controller.Joystick, ConvertJoystick),
new ControlAdapter(Paddles, Controller.Paddles, Controller.Paddles, ConvertPaddles),
@ -214,37 +235,54 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
new ControlAdapter(Lightgun, Controller.Lightgun, Controller.Lightgun, ConvertLightgun),
};
static void ConvertConsoleButtons(IController c, InputState s)
private static void ConvertConsoleButtons(IController c, InputState s)
{
s.RaiseInput(0, MachineInput.Reset, c.IsPressed("Reset"));
s.RaiseInput(0, MachineInput.Select, c.IsPressed("Select"));
s.RaiseInput(0, MachineInput.Color, c.IsPressed("BW"));
if (c.IsPressed("Toggle Left Difficulty")) { s.RaiseInput(0, MachineInput.LeftDifficulty, c.IsPressed("Toggle Left Difficulty")); }
if (c.IsPressed("Toggle Right Difficulty")) { s.RaiseInput(0, MachineInput.RightDifficulty, c.IsPressed("Toggle Right Difficulty")); }
if (c.IsPressed("Toggle Left Difficulty"))
{
s.RaiseInput(0, MachineInput.LeftDifficulty, c.IsPressed("Toggle Left Difficulty"));
}
if (c.IsPressed("Toggle Right Difficulty"))
{
s.RaiseInput(0, MachineInput.RightDifficulty, c.IsPressed("Toggle Right Difficulty"));
}
}
static void ConvertConsoleButtons7800(IController c, InputState s)
private static void ConvertConsoleButtons7800(IController c, InputState s)
{
s.RaiseInput(0, MachineInput.Reset, c.IsPressed("Reset"));
s.RaiseInput(0, MachineInput.Select, c.IsPressed("Select"));
s.RaiseInput(0, MachineInput.Color, c.IsPressed("Pause"));
if (c.IsPressed("Toggle Left Difficulty")) { s.RaiseInput(0, MachineInput.LeftDifficulty, c.IsPressed("Toggle Left Difficulty")); }
if (c.IsPressed("Toggle Right Difficulty")) { s.RaiseInput(0, MachineInput.RightDifficulty, c.IsPressed("Toggle Right Difficulty")); }
if (c.IsPressed("Toggle Left Difficulty"))
{
s.RaiseInput(0, MachineInput.LeftDifficulty, c.IsPressed("Toggle Left Difficulty"));
}
if (c.IsPressed("Toggle Right Difficulty"))
{
s.RaiseInput(0, MachineInput.RightDifficulty, c.IsPressed("Toggle Right Difficulty"));
}
}
static void ConvertDirections(IController c, InputState s, int p)
private static void ConvertDirections(IController c, InputState s, int p)
{
string ps = string.Format("P{0} ", p + 1);
string ps = $"P{p + 1} ";
s.RaiseInput(p, MachineInput.Up, c.IsPressed(ps + "Up"));
s.RaiseInput(p, MachineInput.Down, c.IsPressed(ps + "Down"));
s.RaiseInput(p, MachineInput.Left, c.IsPressed(ps + "Left"));
s.RaiseInput(p, MachineInput.Right, c.IsPressed(ps + "Right"));
}
static void ConvertTrigger(IController c, InputState s, int p)
private static void ConvertTrigger(IController c, InputState s, int p)
{
string ps = string.Format("P{0} ", p + 1);
string ps = $"P{p + 1} ";
s.RaiseInput(p, MachineInput.Fire, c.IsPressed(ps + "Trigger"));
}
static void ConvertJoystick(IController c, InputState s)
private static void ConvertJoystick(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons(c, s);
@ -253,24 +291,26 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
ConvertTrigger(c, s, 0);
ConvertTrigger(c, s, 1);
}
static void ConvertPaddles(IController c, InputState s)
private static void ConvertPaddles(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons(c, s);
for (int i = 0; i < 4; i++)
{
string ps = string.Format("P{0} ", i + 1);
string ps = $"P{i + 1} ";
ConvertTrigger(c, s, i);
s.RaisePaddleInput(i, 700000, (int)c.GetFloat(ps + "Trigger"));
}
}
static void ConvertKeypad(IController c, InputState s)
private static void ConvertKeypad(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons(c, s);
for (int i = 0; i < 4; i++)
{
string ps = string.Format("P{0} ", i + 1);
string ps = $"P{i + 1} ";
s.RaiseInput(i, MachineInput.NumPad1, c.IsPressed(ps + "Keypad1"));
s.RaiseInput(i, MachineInput.NumPad2, c.IsPressed(ps + "Keypad2"));
s.RaiseInput(i, MachineInput.NumPad3, c.IsPressed(ps + "Keypad3"));
@ -285,28 +325,32 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
s.RaiseInput(i, MachineInput.NumPadHash, c.IsPressed(ps + "KeypadP"));
}
}
static MachineInput[] drvlut = new[]
private static readonly MachineInput[] Drvlut =
{
MachineInput.Driving0,
MachineInput.Driving1,
MachineInput.Driving2,
MachineInput.Driving3
};
static void ConvertDriving(IController c, InputState s)
private static void ConvertDriving(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons(c, s);
ConvertTrigger(c, s, 0);
ConvertTrigger(c, s, 1);
s.RaiseInput(0, drvlut[(int)c.GetFloat("P1 Driving")], true);
s.RaiseInput(1, drvlut[(int)c.GetFloat("P2 Driving")], true);
s.RaiseInput(0, Drvlut[(int)c.GetFloat("P1 Driving")], true);
s.RaiseInput(1, Drvlut[(int)c.GetFloat("P2 Driving")], true);
}
static void ConvertBoosterGrip(IController c, InputState s)
private static void ConvertBoosterGrip(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons(c, s);
ConvertDirections(c, s, 0);
ConvertDirections(c, s, 1);
// weird mapping is intentional
s.RaiseInput(0, MachineInput.Fire, c.IsPressed("P1 Trigger"));
s.RaiseInput(0, MachineInput.Fire2, c.IsPressed("P1 Trigger 2"));
@ -315,7 +359,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
s.RaiseInput(2, MachineInput.Fire2, c.IsPressed("P2 Trigger 2"));
s.RaiseInput(3, MachineInput.Fire2, c.IsPressed("P2 Trigger 3"));
}
static void ConvertProLineJoystick(IController c, InputState s)
private static void ConvertProLineJoystick(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons7800(c, s);
@ -326,7 +371,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
s.RaiseInput(1, MachineInput.Fire, c.IsPressed("P2 Trigger"));
s.RaiseInput(1, MachineInput.Fire2, c.IsPressed("P2 Trigger 2"));
}
static void ConvertLightgun(IController c, InputState s)
private static void ConvertLightgun(IController c, InputState s)
{
s.ClearControllerInput();
ConvertConsoleButtons7800(c, s);
@ -354,7 +400,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari7800
return;
}
}
throw new Exception(string.Format("Couldn't connect Atari 7800 controls \"{0}\" and \"{1}\"", l.ToString(), r.ToString()));
throw new Exception($"Couldn't connect Atari 7800 controls \"{l}\" and \"{r}\"");
}
}
}