diff --git a/BizHawk.Client.EmuHawk/MainForm.cs b/BizHawk.Client.EmuHawk/MainForm.cs index 611c693e20..13f72ae46f 100644 --- a/BizHawk.Client.EmuHawk/MainForm.cs +++ b/BizHawk.Client.EmuHawk/MainForm.cs @@ -1690,10 +1690,7 @@ namespace BizHawk.Client.EmuHawk switch (system) { case "GEN": - if (!(Emulator is PicoDrive)) // Currently PicoDrive doesn't support anything in this menu - { - GenesisSubMenu.Visible = true; - } + GenesisSubMenu.Visible = true; break; case "TI83": TI83SubMenu.Visible = true; @@ -3355,7 +3352,7 @@ namespace BizHawk.Client.EmuHawk AbortAv(); } - HANDLE_AUTODUMP: + HANDLE_AUTODUMP: if (argParse._autoDumpLength > 0) { argParse._autoDumpLength--; @@ -3544,7 +3541,7 @@ namespace BizHawk.Client.EmuHawk if (result) { - + string loaderName = "*" + OpenAdvancedSerializer.Serialize(ioa); Emulator = loader.LoadedEmulator; Global.Game = loader.Game; diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs index 820ce63e14..425e99eb76 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/LibPicoDrive.cs @@ -20,6 +20,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive [UnmanagedFunctionPointer(CC)] public delegate void CDReadCallback(int lba, IntPtr dest, bool audio); + public enum Region : int + { + Auto = 0, + JapanNTSC = 1, + JapanPAL = 2, + US = 4, + Europe = 8 + } + /// /// /// @@ -28,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive /// 32X games will still run, but will not have memory domains /// [BizImport(CC)] - public abstract bool Init(bool cd, bool _32xPreinit); + public abstract bool Init(bool cd, bool _32xPreinit, Region regionAutoOrder, Region regionOverride); [BizImport(CC)] public abstract void SetCDReadCallback(CDReadCallback callback); diff --git a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs index ddca184c04..826e3b1298 100644 --- a/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs +++ b/BizHawk.Emulation.Cores/Consoles/Sega/PicoDrive/PicoDrive.cs @@ -8,12 +8,14 @@ using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.IO; +using BizHawk.Common; +using System.ComponentModel; namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive { [Core("PicoDrive", "notaz", true, true, "0e352905c7aa80b166933970abbcecfce96ad64e", "https://github.com/notaz/picodrive", false)] - public class PicoDrive : WaterboxCore, IDriveLight, IRegionable + public class PicoDrive : WaterboxCore, IDriveLight, IRegionable, ISettable { private LibPicoDrive _core; private LibPicoDrive.CDReadCallback _cdcallback; @@ -22,15 +24,15 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive private bool _isPal; [CoreConstructor("GEN")] - public PicoDrive(CoreComm comm, GameInfo game, byte[] rom, bool deterministic) - :this(comm, game, rom, null, deterministic) + public PicoDrive(CoreComm comm, GameInfo game, byte[] rom, bool deterministic, SyncSettings syncSettings) + : this(comm, game, rom, null, deterministic, syncSettings) { } - public PicoDrive(CoreComm comm, GameInfo game, Disc cd, bool deterministic) - :this(comm, game, null, cd, deterministic) + public PicoDrive(CoreComm comm, GameInfo game, Disc cd, bool deterministic, SyncSettings syncSettings) + : this(comm, game, null, cd, deterministic, syncSettings) { } - private PicoDrive(CoreComm comm, GameInfo game, byte[] rom, Disc cd, bool deterministic) + private PicoDrive(CoreComm comm, GameInfo game, byte[] rom, Disc cd, bool deterministic, SyncSettings syncSettings) : base(comm, new Configuration { MaxSamples = 2048, @@ -49,6 +51,8 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive throw new InvalidOperationException("32X BIOS files are required for deterministic mode"); deterministic |= has32xBios; + _syncSettings = syncSettings ?? new SyncSettings(); + _core = PreInit(new PeRunnerOptions { Filename = "picodrive.wbx", @@ -83,7 +87,12 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive _exe.AddReadonlyFile(rom, "romfile.md"); } - if (!_core.Init(cd != null, game["32X"])) + var regionAutoOrder = (LibPicoDrive.Region)( + (int)_syncSettings.FirstChoice | + (int)_syncSettings.SecondChoice << 4 | + (int)_syncSettings.ThirdChoice << 8); + + if (!_core.Init(cd != null, game["32X"], regionAutoOrder, _syncSettings.RegionOverride)) throw new InvalidOperationException("Core rejected the file!"); if (cd != null) @@ -174,6 +183,68 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.PicoDrive _core.SetCDReadCallback(_cdcallback); } + #region ISettable + + public class SyncSettings + { + [DefaultValue(LibPicoDrive.Region.Auto)] + [Description("If set, force the console to this region")] + public LibPicoDrive.Region RegionOverride { get; set; } + + [DefaultValue(LibPicoDrive.Region.Auto)] + [Description("When region is set to automatic, highest priority region to use if the game supports multiple regions")] + public LibPicoDrive.Region FirstChoice { get; set; } + + [DefaultValue(LibPicoDrive.Region.Auto)] + [Description("When region is set to automatic, second highest priority region to use if the game supports multiple regions")] + public LibPicoDrive.Region SecondChoice { get; set; } + + [DefaultValue(LibPicoDrive.Region.Auto)] + [Description("When region is set to automatic, lowest priority region to use if the game supports multiple regions")] + public LibPicoDrive.Region ThirdChoice { get; set; } + + public SyncSettings Clone() + { + return (SyncSettings)MemberwiseClone(); + } + + public static bool NeedsReboot(SyncSettings x, SyncSettings y) + { + return !DeepEquality.DeepEquals(x, y); + } + + public SyncSettings() + { + SettingsUtil.SetDefaultValues(this); + } + } + + private SyncSettings _syncSettings; + + public object GetSettings() + { + return new object(); + } + + public SyncSettings GetSyncSettings() + { + return _syncSettings.Clone(); + } + + public bool PutSettings(object o) + { + return false; + } + + public bool PutSyncSettings(SyncSettings o) + { + var ret = SyncSettings.NeedsReboot(_syncSettings, o); + _syncSettings = o; + return ret; + } + + #endregion + #region IDriveLight public bool DriveLightEnabled { get; private set; } diff --git a/output/dll/picodrive.wbx.gz b/output/dll/picodrive.wbx.gz index d6e2dbd967..d1426e85ab 100644 Binary files a/output/dll/picodrive.wbx.gz and b/output/dll/picodrive.wbx.gz differ diff --git a/waterbox/picodrive/bizhawk.c b/waterbox/picodrive/bizhawk.c index 187723f14f..35e52d3059 100644 --- a/waterbox/picodrive/bizhawk.c +++ b/waterbox/picodrive/bizhawk.c @@ -138,8 +138,11 @@ static const uint8_t *TryLoadBios(const char *name) return ret; } -ECL_EXPORT int Init(int cd, int _32xPreinit) +ECL_EXPORT int Init(int cd, int _32xPreinit, int regionAutoOrder, int regionOverride) { + PicoAutoRgnOrder = regionAutoOrder; + PicoRegionOverride = regionOverride; + p32x_bios_g = TryLoadBios("32x.g"); p32x_bios_m = TryLoadBios("32x.m"); p32x_bios_s = TryLoadBios("32x.s");