171 lines
4.4 KiB
C#
171 lines
4.4 KiB
C#
using System;
|
|
using System.ComponentModel;
|
|
using System.Runtime.InteropServices;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
using BizHawk.Common;
|
|
using BizHawk.Emulation.Common;
|
|
|
|
namespace BizHawk.Emulation.Cores.Consoles.Nintendo.QuickNES
|
|
{
|
|
public partial class QuickNES : ISettable<QuickNES.QuickNESSettings, QuickNES.QuickNESSyncSettings>
|
|
{
|
|
public QuickNESSettings GetSettings()
|
|
{
|
|
return _settings.Clone();
|
|
}
|
|
|
|
public QuickNESSyncSettings GetSyncSettings()
|
|
{
|
|
return _syncSettingsNext.Clone();
|
|
}
|
|
|
|
public bool PutSettings(QuickNESSettings o)
|
|
{
|
|
_settings = o;
|
|
LibQuickNES.qn_set_sprite_limit(Context, _settings.NumSprites);
|
|
RecalculateCrops();
|
|
CalculatePalette();
|
|
return false;
|
|
}
|
|
|
|
public bool PutSyncSettings(QuickNESSyncSettings o)
|
|
{
|
|
bool ret = QuickNESSyncSettings.NeedsReboot(_syncSettings, o);
|
|
_syncSettingsNext = o;
|
|
return ret;
|
|
}
|
|
|
|
private QuickNESSettings _settings;
|
|
|
|
/// <summary>
|
|
/// the syncsettings that this run of emulation is using (was passed to ctor)
|
|
/// </summary>
|
|
private QuickNESSyncSettings _syncSettings;
|
|
|
|
/// <summary>
|
|
/// the syncsettings that were requested but won't be used yet
|
|
/// </summary>
|
|
private QuickNESSyncSettings _syncSettingsNext;
|
|
|
|
public class QuickNESSettings
|
|
{
|
|
[DefaultValue(8)]
|
|
[Description("Set the number of sprites visible per line. 0 hides all sprites, 8 behaves like a normal NES, and 64 is maximum.")]
|
|
[DisplayName("Visible Sprites")]
|
|
public int NumSprites
|
|
{
|
|
get { return _NumSprites; }
|
|
set { _NumSprites = Math.Min(64, Math.Max(0, value)); }
|
|
}
|
|
|
|
[JsonIgnore]
|
|
private int _NumSprites;
|
|
|
|
[DefaultValue(false)]
|
|
[Description("Clip the left and right 8 pixels of the display, which sometimes contain nametable garbage.")]
|
|
[DisplayName("Clip Left and Right")]
|
|
public bool ClipLeftAndRight { get; set; }
|
|
|
|
[DefaultValue(true)]
|
|
[Description("Clip the top and bottom 8 pixels of the display, which sometimes contain nametable garbage.")]
|
|
[DisplayName("Clip Top and Bottom")]
|
|
public bool ClipTopAndBottom { get; set; }
|
|
|
|
[Browsable(false)]
|
|
public byte[] Palette
|
|
{
|
|
get { return _Palette; }
|
|
set
|
|
{
|
|
if (value == null)
|
|
throw new ArgumentNullException();
|
|
else if (value.Length == 64 * 8 * 3)
|
|
_Palette = value;
|
|
else
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
}
|
|
|
|
[JsonIgnore]
|
|
private byte[] _Palette;
|
|
|
|
public QuickNESSettings Clone()
|
|
{
|
|
var ret = (QuickNESSettings)MemberwiseClone();
|
|
ret._Palette = (byte[])_Palette.Clone();
|
|
return ret;
|
|
}
|
|
|
|
public QuickNESSettings()
|
|
{
|
|
SettingsUtil.SetDefaultValues(this);
|
|
SetDefaultColors();
|
|
}
|
|
|
|
public void SetNesHawkPalette(int[,] pal)
|
|
{
|
|
if (pal.GetLength(0) != 64 || pal.GetLength(1) != 3)
|
|
{
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
|
|
for (int c = 0; c < 512; c++)
|
|
{
|
|
int a = c & 63;
|
|
byte[] inp = { (byte)pal[a, 0], (byte)pal[a, 1], (byte)pal[a, 2] };
|
|
byte[] outp = new byte[3];
|
|
Nes_NTSC_Colors.Emphasis(inp, outp, c);
|
|
_Palette[c * 3] = outp[0];
|
|
_Palette[c * 3 + 1] = outp[1];
|
|
_Palette[c * 3 + 2] = outp[2];
|
|
}
|
|
}
|
|
|
|
private static byte[] GetDefaultColors()
|
|
{
|
|
IntPtr src = LibQuickNES.qn_get_default_colors();
|
|
byte[] ret = new byte[1536];
|
|
Marshal.Copy(src, ret, 0, 1536);
|
|
return ret;
|
|
}
|
|
|
|
public void SetDefaultColors()
|
|
{
|
|
_Palette = GetDefaultColors();
|
|
}
|
|
}
|
|
|
|
public class QuickNESSyncSettings
|
|
{
|
|
[DefaultValue(true)]
|
|
[DisplayName("Left Port Connected")]
|
|
[Description("Specifies whether or not the Left (Player 1) Controller is connected")]
|
|
public bool LeftPortConnected { get; set; }
|
|
|
|
[DefaultValue(false)]
|
|
[DisplayName("Right Port Connected")]
|
|
[Description("Specifies whether or not the Right (Player 2) Controller is connected")]
|
|
public bool RightPortConnected { get; set; }
|
|
|
|
public QuickNESSyncSettings()
|
|
{
|
|
SettingsUtil.SetDefaultValues(this);
|
|
}
|
|
|
|
public QuickNESSyncSettings Clone()
|
|
{
|
|
return (QuickNESSyncSettings)MemberwiseClone();
|
|
}
|
|
|
|
public static bool NeedsReboot(QuickNESSyncSettings x, QuickNESSyncSettings y)
|
|
{
|
|
// the core can handle dynamic plugging and unplugging, but that changes
|
|
// the controllerdefinition, and we're not ready for that
|
|
return !DeepEquality.DeepEquals(x, y);
|
|
}
|
|
}
|
|
}
|
|
}
|