2600: more stuff towards PAL support

This commit is contained in:
goyuken 2014-05-23 15:47:48 +00:00
parent 59440c1d4d
commit 2f7ad6a676
5 changed files with 67 additions and 15 deletions

View File

@ -34,10 +34,17 @@ namespace BizHawk.Emulation.Common
public bool NotInDatabase = true;
public string FirmwareHash;
readonly Dictionary<string, string> Options = new Dictionary<string, string>();
Dictionary<string, string> Options = new Dictionary<string, string>();
public GameInfo() { }
public GameInfo Clone()
{
var ret = (GameInfo)MemberwiseClone();
ret.Options = new Dictionary<string, string>(Options);
return ret;
}
public static GameInfo GetNullGame()
{
return new GameInfo

View File

@ -71,6 +71,7 @@
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.Numerics" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq">
<RequiredTargetFramework>3.5</RequiredTargetFramework>

View File

@ -279,7 +279,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
OnExecFetch = this.ExecFetch
};
_tia = new TIA(this);
// TODO: add to game db so we only run DetectPal() on unknown games
bool pal;
if (_game["PAL"])
pal = true;
else if (_game["NTSC"])
pal = false;
else
pal = DetectPal(_game, Rom);
_tia = new TIA(this, pal);
_tia.GetFrameRate(out CoreComm.VsyncNum, out CoreComm.VsyncDen);
// dcfilter coefficent is from real observed hardware behavior: a latched "1" will fully decay by ~170 or so tia sound cycles
_dcfilter = DCFilter.AsISoundProvider(_tia, 256);
@ -326,7 +336,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
_islag = true;
_tia.LineCount = 0;
_tia.BeginAudioFrame();
while (_tia.LineCount < 262) // will be 312 for PAL
while (_tia.LineCount < _tia.NominalNumScanlines)
{
CycleAdvance();
}

View File

@ -255,10 +255,17 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private static bool DetectPal(GameInfo game, byte[] rom)
{
// force NTSC mode for the new core we instantiate
var newgame = game.Clone();
if (newgame["PAL"])
newgame.RemoveOption("PAL");
if (!newgame["NTSC"])
newgame.AddOption("NTSC");
// give the emu a minimal of input\output connections so it doesn't crash
var comm = new CoreComm(null, null);
comm.InputCallback = new InputCallbackSystem();
using (Atari2600 emu = new Atari2600(new CoreComm(null, null), game, rom, null, null))
using (Atari2600 emu = new Atari2600(new CoreComm(null, null), newgame, rom, null, null))
{
emu.Controller = new NullController();
@ -267,8 +274,9 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
for (int i = 0; i < 71; i++) // run for 71 * 262 lines, since we're in NTSC mode
emu.FrameAdvance(false, false);
int numpal = framecounts.Count((i) => i > 287);
Console.WriteLine("{0} PAL", numpal);
return numpal >= 25;
bool pal = numpal >= 25;
Console.WriteLine("PAL Detection: {0} lines, {1}", numpal, pal);
return pal;
}
}
}

View File

@ -2,6 +2,7 @@
using System.Collections.Generic;
using BizHawk.Common;
using BizHawk.Emulation.Common;
using System.Numerics;
namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
@ -143,6 +144,29 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
#endregion
// in all cases, the TIA has 228 clocks per scanline
// the NTSC TIA has a clock rate of 3579575hz
// the PAL/SECAM TIA has a clock rate of 3546894hz
private bool _pal;
public int NominalNumScanlines
{
get
{
return _pal ? 312 : 262;
}
}
public void GetFrameRate(out int num, out int den)
{
int clockrate = _pal ? 3546894 : 3579575;
int clocksperframe = 228 * NominalNumScanlines;
int gcd = (int)BigInteger.GreatestCommonDivisor(clockrate, clocksperframe);
num = clockrate / gcd;
den = clocksperframe / gcd;
}
private const int ScreenWidth = 160;
private const int MaxScreenHeight = 312;
@ -156,7 +180,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
private readonly Atari2600 _core;
private int[] _scanlinebuffer = new int[ScreenWidth * MaxScreenHeight];
private readonly int[] _palette = NTSCPalette; // todo: make this NTSC or PAL, obviously
private readonly int[] _palette;
private byte _hsyncCnt;
private int _capChargeStart;
@ -173,11 +197,13 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public Audio[] AUD = { new Audio(), new Audio() };
public TIA(Atari2600 core)
public TIA(Atari2600 core, bool pal)
{
_core = core;
_player0.ScanCnt = 8;
_player1.ScanCnt = 8;
_pal = pal;
_palette = _pal ? PALPalette : NTSCPalette;
}
public int CurrentScanLine
@ -209,6 +235,7 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
public int VirtualWidth
{
// TODO: PAL?
get { return 275; } // 275 comes from NTSC specs and the actual pixel clock of a 2600 TIA
}
@ -226,11 +253,10 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
{
get
{
// TODO PAL support
//if (false)
// return _core.Settings.PALBottomLine - _core.Settings.PALTopLine;
//else
return _core.Settings.NTSCBottomLine - _core.Settings.NTSCTopLine;
if (_pal)
return _core.Settings.PALBottomLine - _core.Settings.PALTopLine;
else
return _core.Settings.NTSCBottomLine - _core.Settings.NTSCTopLine;
}
}
@ -595,8 +621,8 @@ namespace BizHawk.Emulation.Cores.Atari.Atari2600
void OutputFrame(int validlines)
{
int topLine = _core.Settings.NTSCTopLine;
int bottomLine = _core.Settings.NTSCBottomLine;
int topLine = _pal ? _core.Settings.PALTopLine : _core.Settings.NTSCTopLine;
int bottomLine = _pal ? _core.Settings.PALBottomLine : _core.Settings.NTSCBottomLine;
// if vsync occured unexpectedly early, black out the remainer
for (; validlines < bottomLine; validlines++)