NEShawk - break up into separate files

This commit is contained in:
adelikat 2015-01-15 19:19:43 +00:00
parent bd74041cde
commit 95dcae132f
10 changed files with 490 additions and 343 deletions

View File

@ -259,19 +259,19 @@
<Compile Include="Consoles\Atari\lynx\LibLynx.cs" />
<Compile Include="Consoles\Atari\lynx\Lynx.cs" />
<Compile Include="Consoles\Atari\lynx\Lynx.IInputPollable.cs">
<DependentUpon>Lynx.cs</DependentUpon>
<DependentUpon>Lynx.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Atari\lynx\Lynx.IMemoryDomains.cs">
<DependentUpon>Lynx.cs</DependentUpon>
<DependentUpon>Lynx.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Atari\lynx\Lynx.ISaveRam.cs">
<DependentUpon>Lynx.cs</DependentUpon>
<DependentUpon>Lynx.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Atari\lynx\Lynx.IStatable.cs">
<DependentUpon>Lynx.cs</DependentUpon>
<DependentUpon>Lynx.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Atari\lynx\Lynx.IVideoProvider.cs">
<DependentUpon>Lynx.cs</DependentUpon>
<DependentUpon>Lynx.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Coleco\ColecoVision.cs" />
<Compile Include="Consoles\Coleco\ColecoVision.IDebuggable.cs">
@ -517,7 +517,30 @@
<Compile Include="Consoles\Nintendo\NES\iNES.cs" />
<Compile Include="Consoles\Nintendo\NES\INESPPUViewable.cs" />
<Compile Include="Consoles\Nintendo\NES\NES.cs" />
<Compile Include="Consoles\Nintendo\NES\NES.INESPPUViewable.cs" />
<Compile Include="Consoles\Nintendo\NES\NES.IDebuggable.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.IDriveLight.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.IInputPollable.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.IMemoryDomains.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.INESPPUViewable.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.ISaveRam.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.ISettable.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NES.IStatable.cs">
<DependentUpon>NES.cs</DependentUpon>
</Compile>
<Compile Include="Consoles\Nintendo\NES\NESControllers.cs" />
<Compile Include="Consoles\Nintendo\NES\Palettes.cs" />
<Compile Include="Consoles\Nintendo\NES\PPU.cs" />

View File

@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES : IDebuggable
{
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
return new Dictionary<string, RegisterValue>
{
{ "A", cpu.A },
{ "X", cpu.X },
{ "Y", cpu.Y },
{ "S", cpu.S },
{ "PC", cpu.PC },
{ "Flag C", cpu.FlagC },
{ "Flag Z", cpu.FlagZ },
{ "Flag I", cpu.FlagI },
{ "Flag D", cpu.FlagD },
{ "Flag B", cpu.FlagB },
{ "Flag V", cpu.FlagV },
{ "Flag N", cpu.FlagN },
{ "Flag T", cpu.FlagT }
};
}
public void SetCpuRegister(string register, int value)
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
cpu.A = (byte)value;
break;
case "X":
cpu.X = (byte)value;
break;
case "Y":
cpu.Y = (byte)value;
break;
case "S":
cpu.S = (byte)value;
break;
case "PC":
cpu.PC = (ushort)value;
break;
case "Flag I":
cpu.FlagI = value > 0;
break;
}
}
public bool CanStep(StepType type)
{
return false;
}
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
[FeatureNotImplemented]
public void Step(StepType type) { throw new NotImplementedException(); }
}
}

View File

@ -0,0 +1,11 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES : IDriveLight
{
public bool DriveLightEnabled { get; private set; }
public bool DriveLightOn { get; private set; }
}
}

View File

@ -0,0 +1,29 @@
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES : IInputPollable
{
public int LagCount
{
get { return _lagcount; }
set { _lagcount = value; }
}
public bool IsLagFrame
{
get { return islag; }
}
public IInputCallbackSystem InputCallbacks
{
get { return _inputCallbacks; }
}
private int _lagcount;
private bool lagged = true;
private bool islag = false;
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
}
}

View File

@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES
{
private MemoryDomainList _memoryDomains;
private void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>();
var RAM = new MemoryDomain("RAM", 0x800, MemoryDomain.Endian.Little,
addr => ram[addr], (addr, value) => ram[addr] = value);
var SystemBus = new MemoryDomain("System Bus", 0x10000, MemoryDomain.Endian.Little,
addr => PeekMemory((ushort)addr), (addr, value) => ApplySystemBusPoke(addr, value));
var PPUBus = new MemoryDomain("PPU Bus", 0x4000, MemoryDomain.Endian.Little,
addr => ppu.ppubus_peek(addr), (addr, value) => ppu.ppubus_write(addr, value));
var CIRAMdomain = new MemoryDomain("CIRAM (nametables)", 0x800, MemoryDomain.Endian.Little,
addr => CIRAM[addr], (addr, value) => CIRAM[addr] = value);
var OAMdoman = new MemoryDomain("OAM", 64 * 4, MemoryDomain.Endian.Unknown,
addr => ppu.OAM[addr], (addr, value) => ppu.OAM[addr] = value);
domains.Add(RAM);
domains.Add(SystemBus);
domains.Add(PPUBus);
domains.Add(CIRAMdomain);
domains.Add(OAMdoman);
if (!(board is FDS) && board.SaveRam != null)
{
var BatteryRam = new MemoryDomain("Battery RAM", board.SaveRam.Length, MemoryDomain.Endian.Little,
addr => board.SaveRam[addr], (addr, value) => board.SaveRam[addr] = value);
domains.Add(BatteryRam);
}
var PRGROM = new MemoryDomain("PRG ROM", cart.prg_size * 1024, MemoryDomain.Endian.Little,
addr => board.ROM[addr], (addr, value) => board.ROM[addr] = value);
domains.Add(PRGROM);
if (board.VROM != null)
{
var CHRROM = new MemoryDomain("CHR VROM", cart.chr_size * 1024, MemoryDomain.Endian.Little,
addr => board.VROM[addr], (addr, value) => board.VROM[addr] = value);
domains.Add(CHRROM);
}
if (board.VRAM != null)
{
var VRAM = new MemoryDomain("VRAM", board.VRAM.Length, MemoryDomain.Endian.Little,
addr => board.VRAM[addr], (addr, value) => board.VRAM[addr] = value);
domains.Add(VRAM);
}
if (board.WRAM != null)
{
var WRAM = new MemoryDomain("WRAM", board.WRAM.Length, MemoryDomain.Endian.Little,
addr => board.WRAM[addr], (addr, value) => board.WRAM[addr] = value);
domains.Add(WRAM);
}
// if there were more boards with special ram sets, we'd want to do something more general
if (board is FDS)
{
domains.Add((board as FDS).GetDiskPeeker());
}
else if (board is ExROM)
{
domains.Add((board as ExROM).GetExRAM());
}
_memoryDomains = new MemoryDomainList(domains);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(_memoryDomains);
}
}
}

View File

@ -84,7 +84,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
public MemoryDomain GetCHRROM()
{
return memoryDomains["CHR VROM"];
return _memoryDomains["CHR VROM"];
}

View File

@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES : ISaveRam
{
public bool SaveRamModified
{
get
{
if (board == null) return false;
if (board is FDS) return true;
if (board.SaveRam == null) return false;
return true;
}
}
public byte[] CloneSaveRam()
{
if (board is FDS)
return (board as FDS).ReadSaveRam();
if (board == null || board.SaveRam == null)
return null;
return (byte[])board.SaveRam.Clone();
}
public void StoreSaveRam(byte[] data)
{
if (board is FDS)
{
(board as FDS).StoreSaveRam(data);
return;
}
if (board == null || board.SaveRam == null)
return;
Array.Copy(data, board.SaveRam, data.Length);
}
}
}

View File

@ -0,0 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES : IStatable
{
public NESSettings GetSettings()
{
return Settings.Clone();
}
public NESSyncSettings GetSyncSettings()
{
return SyncSettings.Clone();
}
public bool PutSettings(NESSettings o)
{
Settings = o;
if (Settings.ClipLeftAndRight)
{
videoProvider.left = 8;
videoProvider.right = 247;
}
else
{
videoProvider.left = 0;
videoProvider.right = 255;
}
CoreComm.ScreenLogicalOffsetX = videoProvider.left;
CoreComm.ScreenLogicalOffsetY = DisplayType == DisplayType.NTSC ? Settings.NTSC_TopLine : Settings.PAL_TopLine;
SetPalette(Settings.Palette);
apu.Square1V = Settings.Square1;
apu.Square2V = Settings.Square2;
apu.TriangleV = Settings.Triangle;
apu.NoiseV = Settings.Noise;
apu.DMCV = Settings.DMC;
return false;
}
public bool PutSyncSettings(NESSyncSettings o)
{
bool ret = NESSyncSettings.NeedsReboot(SyncSettings, o);
SyncSettings = o;
return ret;
}
private NESSettings Settings = new NESSettings();
private NESSyncSettings SyncSettings = new NESSyncSettings();
public class NESSyncSettings
{
public Dictionary<string, string> BoardProperties = new Dictionary<string, string>();
public enum Region
{
Default,
NTSC,
PAL,
Dendy
};
public Region RegionOverride = Region.Default;
public NESControlSettings Controls = new NESControlSettings();
public NESSyncSettings Clone()
{
var ret = (NESSyncSettings)MemberwiseClone();
ret.BoardProperties = new Dictionary<string, string>(BoardProperties);
ret.Controls = Controls.Clone();
return ret;
}
public static bool NeedsReboot(NESSyncSettings x, NESSyncSettings y)
{
return !(Util.DictionaryEqual(x.BoardProperties, y.BoardProperties) &&
x.RegionOverride == y.RegionOverride &&
!NESControlSettings.NeedsReboot(x.Controls, y.Controls));
}
}
public class NESSettings
{
public bool AllowMoreThanEightSprites = false;
public bool ClipLeftAndRight = false;
public bool DispBackground = true;
public bool DispSprites = true;
public int BackgroundColor = 0;
public int NTSC_TopLine = 8;
public int NTSC_BottomLine = 231;
public int PAL_TopLine = 0;
public int PAL_BottomLine = 239;
public int[,] Palette;
public int Square1 = 376;
public int Square2 = 376;
public int Triangle = 426;
public int Noise = 247;
public int DMC = 167;
public NESSettings Clone()
{
var ret = (NESSettings)MemberwiseClone();
ret.Palette = (int[,])ret.Palette.Clone();
return ret;
}
public NESSettings()
{
Palette = (int[,])Palettes.QuickNESPalette.Clone();
}
[Newtonsoft.Json.JsonConstructor]
public NESSettings(int[,] Palette)
{
if (Palette == null)
// only needed for SVN purposes
this.Palette = (int[,])Palettes.QuickNESPalette.Clone();
else
this.Palette = Palette;
}
}
}
}

View File

@ -0,0 +1,92 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using BizHawk.Common;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Nintendo.NES
{
public partial class NES : IStatable
{
public bool BinarySaveStatesPreferred
{
get { return false; }
}
public void SaveStateText(TextWriter writer)
{
SyncState(Serializer.CreateTextWriter(writer));
}
public void LoadStateText(TextReader reader)
{
SyncState(Serializer.CreateTextReader(reader));
}
public void SaveStateBinary(BinaryWriter bw)
{
SyncState(Serializer.CreateBinaryWriter(bw));
}
public void LoadStateBinary(BinaryReader br)
{
SyncState(Serializer.CreateBinaryReader(br));
}
public byte[] SaveStateBinary()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
return ms.ToArray();
}
private void SyncState(Serializer ser)
{
int version = 4;
ser.BeginSection("NES");
ser.Sync("version", ref version);
ser.Sync("Frame", ref _frame);
ser.Sync("Lag", ref _lagcount);
ser.Sync("IsLag", ref islag);
cpu.SyncState(ser);
ser.Sync("ram", ref ram, false);
ser.Sync("CIRAM", ref CIRAM, false);
ser.Sync("cpu_accumulate", ref cpu_accumulate);
ser.Sync("_irq_apu", ref _irq_apu);
ser.Sync("sprdma_countdown", ref sprdma_countdown);
ser.Sync("cpu_step", ref cpu_step);
ser.Sync("cpu_stepcounter", ref cpu_stepcounter);
ser.Sync("cpu_deadcounter", ref cpu_deadcounter);
ser.BeginSection("Board");
board.SyncState(ser);
if (board is NESBoardBase && !((NESBoardBase)board).SyncStateFlag)
throw new InvalidOperationException("the current NES mapper didnt call base.SyncState");
ser.EndSection();
ppu.SyncState(ser);
apu.SyncState(ser);
if (version >= 2)
{
ser.Sync("DB", ref DB);
}
if (version >= 3)
{
ser.Sync("latched4016", ref latched4016);
ser.BeginSection("ControllerDeck");
ControllerDeck.SyncState(ser);
ser.EndSection();
}
if (version >= 4)
{
ser.Sync("resetSignal", ref resetSignal);
ser.Sync("hardResetSignal", ref hardResetSignal);
}
ser.EndSection();
}
}
}

View File

@ -76,9 +76,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
BootGodDB.Initialize();
}
public bool DriveLightEnabled { get; private set; }
public bool DriveLightOn { get; private set; }
public void WriteLogTimestamp()
{
if (ppu != null)
@ -329,9 +326,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
int _frame;
int _lagcount;
bool lagged = true;
bool islag = false;
public int Frame { get { return _frame; } set { _frame = value; } }
public void ResetCounters()
@ -342,111 +337,9 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
public long Timestamp { get; private set; }
public int LagCount { get { return _lagcount; } set { _lagcount = value; } }
public bool IsLagFrame { get { return islag; } }
private readonly InputCallbackSystem _inputCallbacks = new InputCallbackSystem();
public IInputCallbackSystem InputCallbacks { get { return _inputCallbacks; } }
public bool DeterministicEmulation { get { return true; } }
public byte[] CloneSaveRam()
{
if (board is FDS)
return (board as FDS).ReadSaveRam();
if (board == null || board.SaveRam == null)
return null;
return (byte[])board.SaveRam.Clone();
}
public void StoreSaveRam(byte[] data)
{
if (board is FDS)
{
(board as FDS).StoreSaveRam(data);
return;
}
if (board == null || board.SaveRam == null)
return;
Array.Copy(data, board.SaveRam, data.Length);
}
public bool SaveRamModified
{
get
{
if (board == null) return false;
if (board is FDS) return true;
if (board.SaveRam == null) return false;
return true;
}
}
private MemoryDomainList memoryDomains;
private void SetupMemoryDomains()
{
var domains = new List<MemoryDomain>();
var RAM = new MemoryDomain("RAM", 0x800, MemoryDomain.Endian.Little,
addr => ram[addr], (addr, value) => ram[addr] = value);
var SystemBus = new MemoryDomain("System Bus", 0x10000, MemoryDomain.Endian.Little,
addr => PeekMemory((ushort)addr), (addr, value) => ApplySystemBusPoke(addr, value));
var PPUBus = new MemoryDomain("PPU Bus", 0x4000, MemoryDomain.Endian.Little,
addr => ppu.ppubus_peek(addr), (addr, value) => ppu.ppubus_write(addr, value));
var CIRAMdomain = new MemoryDomain("CIRAM (nametables)", 0x800, MemoryDomain.Endian.Little,
addr => CIRAM[addr], (addr, value) => CIRAM[addr] = value);
var OAMdoman = new MemoryDomain("OAM", 64 * 4, MemoryDomain.Endian.Unknown,
addr => ppu.OAM[addr], (addr, value) => ppu.OAM[addr] = value);
domains.Add(RAM);
domains.Add(SystemBus);
domains.Add(PPUBus);
domains.Add(CIRAMdomain);
domains.Add(OAMdoman);
if (!(board is FDS) && board.SaveRam != null)
{
var BatteryRam = new MemoryDomain("Battery RAM", board.SaveRam.Length, MemoryDomain.Endian.Little,
addr => board.SaveRam[addr], (addr, value) => board.SaveRam[addr] = value);
domains.Add(BatteryRam);
}
var PRGROM = new MemoryDomain("PRG ROM", cart.prg_size * 1024, MemoryDomain.Endian.Little,
addr => board.ROM[addr], (addr, value) => board.ROM[addr] = value);
domains.Add(PRGROM);
if (board.VROM != null)
{
var CHRROM = new MemoryDomain("CHR VROM", cart.chr_size * 1024, MemoryDomain.Endian.Little,
addr => board.VROM[addr], (addr, value) => board.VROM[addr] = value);
domains.Add(CHRROM);
}
if (board.VRAM != null)
{
var VRAM = new MemoryDomain("VRAM", board.VRAM.Length, MemoryDomain.Endian.Little,
addr => board.VRAM[addr], (addr, value) => board.VRAM[addr] = value);
domains.Add(VRAM);
}
if (board.WRAM != null)
{
var WRAM = new MemoryDomain("WRAM", board.WRAM.Length, MemoryDomain.Endian.Little,
addr => board.WRAM[addr], (addr, value) => board.WRAM[addr] = value);
domains.Add(WRAM);
}
// if there were more boards with special ram sets, we'd want to do something more general
if (board is FDS)
domains.Add((board as FDS).GetDiskPeeker());
else if (board is ExROM)
domains.Add((board as ExROM).GetExRAM());
memoryDomains = new MemoryDomainList(domains);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(memoryDomains);
}
public string SystemId { get { return "NES"; } }
public string GameName { get { return game_name; } }
@ -842,235 +735,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.NES
}
}
void SyncState(Serializer ser)
{
int version = 4;
ser.BeginSection("NES");
ser.Sync("version", ref version);
ser.Sync("Frame", ref _frame);
ser.Sync("Lag", ref _lagcount);
ser.Sync("IsLag", ref islag);
cpu.SyncState(ser);
ser.Sync("ram", ref ram, false);
ser.Sync("CIRAM", ref CIRAM, false);
ser.Sync("cpu_accumulate", ref cpu_accumulate);
ser.Sync("_irq_apu", ref _irq_apu);
ser.Sync("sprdma_countdown", ref sprdma_countdown);
ser.Sync("cpu_step", ref cpu_step);
ser.Sync("cpu_stepcounter", ref cpu_stepcounter);
ser.Sync("cpu_deadcounter", ref cpu_deadcounter);
ser.BeginSection("Board");
board.SyncState(ser);
if (board is NESBoardBase && !((NESBoardBase)board).SyncStateFlag)
throw new InvalidOperationException("the current NES mapper didnt call base.SyncState");
ser.EndSection();
ppu.SyncState(ser);
apu.SyncState(ser);
if (version >= 2)
{
ser.Sync("DB", ref DB);
}
if (version >= 3)
{
ser.Sync("latched4016", ref latched4016);
ser.BeginSection("ControllerDeck");
ControllerDeck.SyncState(ser);
ser.EndSection();
}
if (version >= 4)
{
ser.Sync("resetSignal", ref resetSignal);
ser.Sync("hardResetSignal", ref hardResetSignal);
}
ser.EndSection();
}
public void SaveStateText(TextWriter writer) { SyncState(Serializer.CreateTextWriter(writer)); }
public void LoadStateText(TextReader reader) { SyncState(Serializer.CreateTextReader(reader)); }
public void SaveStateBinary(BinaryWriter bw) { SyncState(Serializer.CreateBinaryWriter(bw)); }
public void LoadStateBinary(BinaryReader br) { SyncState(Serializer.CreateBinaryReader(br)); }
public byte[] SaveStateBinary()
{
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
SaveStateBinary(bw);
bw.Flush();
return ms.ToArray();
}
public bool BinarySaveStatesPreferred { get { return false; } }
public IDictionary<string, RegisterValue> GetCpuFlagsAndRegisters()
{
return new Dictionary<string, RegisterValue>
{
{ "A", cpu.A },
{ "X", cpu.X },
{ "Y", cpu.Y },
{ "S", cpu.S },
{ "PC", cpu.PC },
{ "Flag C", cpu.FlagC },
{ "Flag Z", cpu.FlagZ },
{ "Flag I", cpu.FlagI },
{ "Flag D", cpu.FlagD },
{ "Flag B", cpu.FlagB },
{ "Flag V", cpu.FlagV },
{ "Flag N", cpu.FlagN },
{ "Flag T", cpu.FlagT }
};
}
public void SetCpuRegister(string register, int value)
{
switch (register)
{
default:
throw new InvalidOperationException();
case "A":
cpu.A = (byte)value;
break;
case "X":
cpu.X = (byte)value;
break;
case "Y":
cpu.Y = (byte)value;
break;
case "S":
cpu.S = (byte)value;
break;
case "PC":
cpu.PC = (ushort)value;
break;
case "Flag I":
cpu.FlagI = value > 0;
break;
}
}
public bool CanStep(StepType type) { return false; }
[FeatureNotImplemented]
public void Step(StepType type) { throw new NotImplementedException(); }
private ITraceable Tracer { get; set; }
public IMemoryCallbackSystem MemoryCallbacks { get; private set; }
NESSettings Settings = new NESSettings();
NESSyncSettings SyncSettings = new NESSyncSettings();
public NESSettings GetSettings() { return Settings.Clone(); }
public NESSyncSettings GetSyncSettings() { return SyncSettings.Clone(); }
public bool PutSettings(NESSettings o)
{
Settings = o;
if (Settings.ClipLeftAndRight)
{
videoProvider.left = 8;
videoProvider.right = 247;
}
else
{
videoProvider.left = 0;
videoProvider.right = 255;
}
CoreComm.ScreenLogicalOffsetX = videoProvider.left;
CoreComm.ScreenLogicalOffsetY = DisplayType == DisplayType.NTSC ? Settings.NTSC_TopLine : Settings.PAL_TopLine;
SetPalette(Settings.Palette);
apu.Square1V = Settings.Square1;
apu.Square2V = Settings.Square2;
apu.TriangleV = Settings.Triangle;
apu.NoiseV = Settings.Noise;
apu.DMCV = Settings.DMC;
return false;
}
public bool PutSyncSettings(NESSyncSettings o)
{
bool ret = NESSyncSettings.NeedsReboot(SyncSettings, o);
SyncSettings = o;
return ret;
}
public class NESSettings
{
public bool AllowMoreThanEightSprites = false;
public bool ClipLeftAndRight = false;
public bool DispBackground = true;
public bool DispSprites = true;
public int BackgroundColor = 0;
public int NTSC_TopLine = 8;
public int NTSC_BottomLine = 231;
public int PAL_TopLine = 0;
public int PAL_BottomLine = 239;
public int[,] Palette;
public int Square1 = 376;
public int Square2 = 376;
public int Triangle = 426;
public int Noise = 247;
public int DMC = 167;
public NESSettings Clone()
{
var ret = (NESSettings)MemberwiseClone();
ret.Palette = (int[,])ret.Palette.Clone();
return ret;
}
public NESSettings()
{
Palette = (int[,])Palettes.QuickNESPalette.Clone();
}
[Newtonsoft.Json.JsonConstructor]
public NESSettings(int[,] Palette)
{
if (Palette == null)
// only needed for SVN purposes
this.Palette = (int[,])Palettes.QuickNESPalette.Clone();
else
this.Palette = Palette;
}
}
public class NESSyncSettings
{
public Dictionary<string, string> BoardProperties = new Dictionary<string, string>();
public enum Region
{
Default,
NTSC,
PAL,
Dendy
};
public Region RegionOverride = Region.Default;
public NESControlSettings Controls = new NESControlSettings();
public NESSyncSettings Clone()
{
var ret = (NESSyncSettings)MemberwiseClone();
ret.BoardProperties = new Dictionary<string, string>(BoardProperties);
ret.Controls = Controls.Clone();
return ret;
}
public static bool NeedsReboot(NESSyncSettings x, NESSyncSettings y)
{
return !(Util.DictionaryEqual(x.BoardProperties, y.BoardProperties) &&
x.RegionOverride == y.RegionOverride &&
!NESControlSettings.NeedsReboot(x.Controls, y.Controls));
}
}
}
}