c# side changes for ST-V with Saturnus

This commit is contained in:
CasualPokePlayer 2024-11-14 17:35:04 -08:00
parent a51c7c07d0
commit 8708fc3e35
5 changed files with 79 additions and 19 deletions

View File

@ -34,7 +34,14 @@ namespace BizHawk.Emulation.Cores.Consoles.Sega.Saturn
: base(lp.Comm, VSystemID.Raw.SAT, "Saturn Controller", lp.Settings, lp.SyncSettings)
{
if (lp.Roms.Count > 0)
throw new InvalidOperationException("To load a Saturn game, please load the CUE file and not the BIN file.");
{
// roms might be valid (ST-V Arcade ROMs)
if (lp.Roms.Exists(rom => rom.FileData.Length > 0x3000000))
{
throw new InvalidOperationException("To load a Saturn game, please load the CUE file and not the BIN file.");
}
}
var firmwareIDMap = new Dictionary<string, FirmwareID>
{
{ "FIRMWARE:$J", new("SAT", "J") },

View File

@ -142,6 +142,13 @@ namespace BizHawk.Emulation.Cores.Waterbox
SECAM
}
public enum GameMediumTypes : int
{
GMT_NONE = 0,
GMT_ARCADE,
GMT_PLAYER
}
[StructLayout(LayoutKind.Sequential)]
public struct SystemInfo
{
@ -150,14 +157,15 @@ namespace BizHawk.Emulation.Cores.Waterbox
public int NominalWidth;
public int NominalHeight;
public VideoSystem VideoSystem;
public GameMediumTypes GameType;
public int FpsFixed;
public long MasterClock;
public int LcmWidth;
public int LcmHeight;
public int PointerScaleX;
public int PointerScaleY;
public int PointerOffsetX;
public int PointerOffsetY;
public int PointerScaleX;
public int PointerScaleY;
public int PointerOffsetX;
public int PointerOffsetY;
}
[BizImport(CC, Compatibility = true)]

View File

@ -76,6 +76,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
{
{ "Power", "System" },
{ "Reset", "System" },
{ "Insert Coin", "System" },
{ "Open Tray", "System" },
{ "Close Tray", "System" },
{ "Disk Index", "System" },
@ -325,6 +326,10 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
ret.BoolButtons.Add("Power");
ret.BoolButtons.Add("Reset");
if (systemInfo.GameType == GameMediumTypes.GMT_ARCADE)
{
ret.BoolButtons.Add("Insert Coin");
}
if (numCds > 0)
{
ret.BoolButtons.Add("Open Tray");

View File

@ -321,6 +321,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
private static readonly IReadOnlyDictionary<string, SettingOverride> ExtraOverrides = new Dictionary<string, SettingOverride>
{
{ "nyma.constantfb", new() { NonSync = true, NoRestart = true } },
// global setting... needs a value set if it gets used (only use case in practice is ST-V with Saturnus)
{ "filesys.untrusted_fip_check", new() { Hide = true, Default = "0" } },
};
private static readonly IReadOnlyCollection<SettingT> ExtraSettings = new List<SettingT>

View File

@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using BizHawk.BizInvoke;
using BizHawk.Common;
using BizHawk.Emulation.Common;
@ -45,6 +46,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
private LibNymaCore _nyma;
protected T DoInit<T>(
CoreLoadParameters<NymaSettings, NymaSyncSettings> lp,
string wbxFilename,
@ -53,8 +55,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
where T : LibNymaCore
{
return DoInit<T>(
lp.Game,
lp.Roms.FirstOrDefault()?.RomData,
lp.Roms.Select(r => (r.RomData,
Path.GetFileName(r.RomPath[(r.RomPath.LastIndexOf('|') + 1)..])!.ToLowerInvariant())).ToArray(),
lp.Discs.Select(d => d.DiscData).ToArray(),
wbxFilename,
lp.Roms.FirstOrDefault()?.Extension,
@ -62,8 +64,24 @@ namespace BizHawk.Emulation.Cores.Waterbox
firmwareIDMap
);
}
protected T DoInit<T>(GameInfo game, byte[] rom, Disc[] discs, string wbxFilename, string extension, bool deterministic,
IDictionary<string, FirmwareID> firmwareIDMap = null)
protected T DoInit<T>(
GameInfo game, byte[] rom, Disc[] discs, string wbxFilename,
string romExtension, bool deterministic, IDictionary<string, FirmwareID> firmwareIDMap = null)
where T : LibNymaCore
{
return DoInit<T>(
[ (Data: rom, Filename: game.FilesystemSafeName() + romExtension.ToLowerInvariant()) ],
discs,
wbxFilename,
romExtension,
deterministic,
firmwareIDMap
);
}
protected T DoInit<T>((byte[] Data, string Filename)[] roms, Disc[] discs, string wbxFilename,
string romExtension, bool deterministic, IDictionary<string, FirmwareID> firmwareIDMap = null)
where T : LibNymaCore
{
_settingsQueryDelegate = SettingsQuery;
@ -72,7 +90,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
var filesToRemove = new List<string>();
var firmwareDelegate = new LibNymaCore.FrontendFirmwareNotify((name) =>
var firmwareDelegate = new LibNymaCore.FrontendFirmwareNotify(name =>
{
if (firmwareIDMap != null && firmwareIDMap.TryGetValue(name, out var id))
{
@ -123,21 +141,25 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
else
{
var fn = game.FilesystemSafeName();
_exe.AddReadonlyFile(rom, fn);
foreach (var (data, filename) in roms)
{
_exe.AddReadonlyFile(data, filename);
}
var didInit = _nyma.InitRom(new LibNymaCore.InitData
{
// TODO: Set these as some cores need them
FileNameBase = "",
FileNameExt = extension.Trim('.').ToLowerInvariant(),
FileNameFull = fn
FileNameBase = Path.GetFileNameWithoutExtension(roms[0].Filename),
FileNameExt = romExtension.Trim('.').ToLowerInvariant(),
FileNameFull = roms[0].Filename
});
if (!didInit)
throw new InvalidOperationException("Core rejected the rom!");
_exe.RemoveReadonlyFile(fn);
foreach (var (_, filename) in roms)
{
_exe.RemoveReadonlyFile(filename);
}
}
foreach (var s in filesToRemove)
@ -171,6 +193,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
VsyncDenominator = 1 << 24;
ClockRate = info.MasterClock / (double)0x100000000;
_soundBuffer = new short[22050 * 2];
_isArcade = info.GameType == LibNymaCore.GameMediumTypes.GMT_ARCADE;
InitControls(portData, discs?.Length ?? 0, ref info);
PostInit();
@ -232,12 +255,18 @@ namespace BizHawk.Emulation.Cores.Waterbox
private IController _currentController;
private bool _isArcade;
protected override LibWaterboxCore.FrameInfo FrameAdvancePrep(IController controller, bool render, bool rendersound)
{
DriveLightOn = false;
_currentController = controller; // need to remember this for rumble
_controllerAdapter.SetBits(controller, _inputPortData);
_frameAdvanceInputLock = GCHandle.Alloc(_inputPortData, GCHandleType.Pinned);
if (!_frameAdvanceInputLock.IsAllocated)
{
_frameAdvanceInputLock = GCHandle.Alloc(_inputPortData, GCHandleType.Pinned);
}
LibNymaCore.BizhawkFlags flags = 0;
if (!render)
flags |= LibNymaCore.BizhawkFlags.SkipRendering;
@ -260,7 +289,9 @@ namespace BizHawk.Emulation.Cores.Waterbox
? LibNymaCore.CommandType.POWER
: controller.IsPressed("Reset")
? LibNymaCore.CommandType.RESET
: LibNymaCore.CommandType.NONE,
: _isArcade && controller.IsPressed("Insert Coin")
? LibNymaCore.CommandType.INSERT_COIN
: LibNymaCore.CommandType.NONE,
InputPortData = (byte*)_frameAdvanceInputLock.AddrOfPinnedObject(),
FrontendTime = GetRtcTime(SettingsQuery("nyma.rtcrealtime") != "0"),
DiskIndex = diskIndex,
@ -271,6 +302,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
return ret;
}
protected override void FrameAdvancePost()
{
_controllerAdapter.DoRumble(_currentController, _inputPortData);
@ -350,6 +382,12 @@ namespace BizHawk.Emulation.Cores.Waterbox
disk.Dispose();
}
}
if (_frameAdvanceInputLock.IsAllocated)
{
_frameAdvanceInputLock.Free();
}
base.Dispose();
}
}