[ChannelFHawk] More accurate rates
This commit is contained in:
parent
6d05b9874c
commit
81043839c1
|
@ -78,6 +78,9 @@ namespace BizHawk.Client.Common
|
|||
["O2_PAL"] = 89478485.0 / 1800319, // 49.70146124103561646574857011
|
||||
|
||||
["TIC80"] = 60,
|
||||
|
||||
["ChannelF"] = 60.5307257846, // (3579545 * 8 / 7) / (256 * 264)
|
||||
["ChannelF_PAL"] = 50.0801282051, // 4000000 / (256 * 312)
|
||||
};
|
||||
|
||||
public static double GetFrameRate(string systemId, bool pal)
|
||||
|
|
|
@ -12,14 +12,31 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
|
||||
public bool DeterministicEmulation { get; set; }
|
||||
|
||||
private double cpuFreq => region == RegionType.NTSC ? 1.7897725 : 2.000000;
|
||||
private double refreshRate => region == RegionType.NTSC ? 60 : 50;
|
||||
private double cpuFreq;
|
||||
private double refreshRate => region == RegionType.NTSC ? 60.5307257846 : 50.0801282051;
|
||||
|
||||
public int ClockPerFrame;
|
||||
public int FrameClock = 0;
|
||||
|
||||
private void CalcClock()
|
||||
{
|
||||
// CPU speeds from https://en.wikipedia.org/wiki/Fairchild_Channel_F
|
||||
if (Region == DisplayType.NTSC)
|
||||
{
|
||||
cpuFreq = 1.7897725;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (version == ConsoleVersion.ChannelF)
|
||||
{
|
||||
cpuFreq = 2.0;
|
||||
}
|
||||
else if (version == ConsoleVersion.ChannelF_II)
|
||||
{
|
||||
cpuFreq = 1.9704972;
|
||||
}
|
||||
}
|
||||
|
||||
var c = ((cpuFreq * 1000000) / refreshRate);
|
||||
ClockPerFrame = (int) c;
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
[DefaultValue(RegionType.NTSC)]
|
||||
public RegionType Region { get; set; }
|
||||
[DisplayName("Version")]
|
||||
[Description("Both versions are the same from an emulation perspective. Channel F II has a very slightly different BIOS to Channel F")]
|
||||
[Description("Channel F II has a very slightly different BIOS to Channel F and a slightly slower CPU in the PAL version compared to v1")]
|
||||
[DefaultValue(ConsoleVersion.ChannelF)]
|
||||
public ConsoleVersion Version { get; set; }
|
||||
|
||||
|
|
|
@ -39,9 +39,18 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
private int latch_x;
|
||||
private int latch_y;
|
||||
|
||||
private readonly int[] frameBuffer = new int[128 * 64];
|
||||
private int scanlineRepeats;
|
||||
private int[] frameBuffer;
|
||||
private int[] outputBuffer;
|
||||
|
||||
private void BuildFrame()
|
||||
public void SetupVideo()
|
||||
{
|
||||
scanlineRepeats = Region == DisplayType.NTSC ? 4 : 5;
|
||||
frameBuffer = new int[128 * 64];
|
||||
outputBuffer = new int[128 * 2 * 64 * scanlineRepeats];
|
||||
}
|
||||
|
||||
private void BuildFrameFromRAM()
|
||||
{
|
||||
for (int r = 0; r < 64; r++)
|
||||
{
|
||||
|
@ -59,42 +68,66 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
}
|
||||
}
|
||||
|
||||
private void ExpandFrame()
|
||||
{
|
||||
int initialWidth = 128;
|
||||
int initialHeight = 64;
|
||||
|
||||
//public int _frameHz => region == RegionType.NTSC ? 60 : 50;
|
||||
public int[] CroppedBuffer = new int[102 * 58];
|
||||
public int VirtualWidth => BufferWidth * 4;
|
||||
public int VirtualHeight => (int)(BufferHeight * 1.43) * 4;
|
||||
public int BufferWidth => 102; //128
|
||||
public int BufferHeight => 58; //64
|
||||
for (int lines = 0; lines < initialHeight; lines++)
|
||||
{
|
||||
for (int i = 0; i < scanlineRepeats; i++)
|
||||
{
|
||||
for (int x = 0; x < initialWidth; x++)
|
||||
{
|
||||
for (int j = 0; j < 2; j++)
|
||||
{
|
||||
outputBuffer[(lines * scanlineRepeats + i) * initialWidth * 2 + x * 2 + j] = FPalette[frameBuffer[lines * initialWidth + x]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public int lBorder => 8;
|
||||
public int rBorder => 52;
|
||||
public int tBorder => 8;
|
||||
public int bBorder => 4;
|
||||
|
||||
public int VirtualWidth => (int)((BufferWidth - lBorder - rBorder) * 2.2);
|
||||
public int VirtualHeight => Region == DisplayType.NTSC ? BufferHeight - tBorder - bBorder : (int)((BufferHeight - tBorder - bBorder) * 0.8);
|
||||
public int BufferWidth => 256 - lBorder - rBorder;
|
||||
public int BufferHeight => (64 * scanlineRepeats) - tBorder - bBorder;
|
||||
public int BackgroundColor => Colors.ARGB(0xFF, 0xFF, 0xFF);
|
||||
public int VsyncNumerator => (int)refreshRate;
|
||||
public int VsyncDenominator => 1;
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
public int[] TrimOutputBuffer(int[] buff, int leftTrim, int topTrim, int rightTrim, int bottomTrim)
|
||||
{
|
||||
BuildFrame();
|
||||
int initialWidth = 128 * 2;
|
||||
int initialHeight = 64 * scanlineRepeats;
|
||||
int newWidth = initialWidth - leftTrim - rightTrim;
|
||||
int newHeight = initialHeight - topTrim - bottomTrim;
|
||||
|
||||
var lBorderWidth = 4;
|
||||
var rBorderWidth = 128 - 102 - lBorderWidth;
|
||||
var tBorderHeight = 4;
|
||||
var bBorderHeight = 64 - 58 - tBorderHeight;
|
||||
var startP = 128 * tBorderHeight;
|
||||
var endP = 128 * bBorderHeight;
|
||||
int[] trimmedBuffer = new int[newWidth * newHeight];
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (int i = startP; i < frameBuffer.Length - endP; i += 128)
|
||||
for (int y = 0; y < newHeight; y++)
|
||||
{
|
||||
for (int p = lBorderWidth; p < 128 - rBorderWidth; p++)
|
||||
for (int x = 0; x < newWidth; x++)
|
||||
{
|
||||
if (index == CroppedBuffer.Length)
|
||||
break;
|
||||
|
||||
CroppedBuffer[index++] = FPalette[frameBuffer[i + p]];
|
||||
trimmedBuffer[y * newWidth + x] = buff[(y + topTrim) * initialWidth + (x + leftTrim)];
|
||||
}
|
||||
}
|
||||
|
||||
return CroppedBuffer;
|
||||
return trimmedBuffer;
|
||||
}
|
||||
|
||||
|
||||
public int[] GetVideoBuffer()
|
||||
{
|
||||
BuildFrameFromRAM();
|
||||
ExpandFrame();
|
||||
return TrimOutputBuffer(outputBuffer, lBorder, tBorder, rBorder, bBorder);
|
||||
}
|
||||
|
||||
public DisplayType Region => region == RegionType.NTSC ? DisplayType.NTSC : DisplayType.PAL;
|
||||
|
|
|
@ -57,6 +57,7 @@ namespace BizHawk.Emulation.Cores.Consoles.ChannelF
|
|||
//Array.Copy(rom, 0, Rom, 0, rom.Length);
|
||||
|
||||
CalcClock();
|
||||
SetupVideo();
|
||||
|
||||
ser.Register<IVideoProvider>(this);
|
||||
ser.Register<ITraceable>(_tracer);
|
||||
|
|
Loading…
Reference in New Issue