diff --git a/output/dll/faust.wbx.gz b/output/dll/faust.wbx.gz
index 1cbfd5b46c..3253b74fe3 100644
Binary files a/output/dll/faust.wbx.gz and b/output/dll/faust.wbx.gz differ
diff --git a/output/dll/ngp.wbx.gz b/output/dll/ngp.wbx.gz
index e844a763a5..38dbebee8b 100644
Binary files a/output/dll/ngp.wbx.gz and b/output/dll/ngp.wbx.gz differ
diff --git a/output/dll/pce-fast.wbx.gz b/output/dll/pce-fast.wbx.gz
index 69de895163..bc8bf63579 100644
Binary files a/output/dll/pce-fast.wbx.gz and b/output/dll/pce-fast.wbx.gz differ
diff --git a/output/dll/pce.wbx.gz b/output/dll/pce.wbx.gz
index d74db38efa..ea92f6ba02 100644
Binary files a/output/dll/pce.wbx.gz and b/output/dll/pce.wbx.gz differ
diff --git a/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs b/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs
index ba14511cf2..ae51b12cf8 100644
--- a/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs
+++ b/src/BizHawk.Emulation.Cores/Waterbox/LibNymaCore.cs
@@ -43,7 +43,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
[BizImport(CC)]
public abstract bool InitCd(int numdisks);
- public enum CommandType : short
+ public enum CommandType : int
{
NONE = 0x00,
RESET = 0x01,
@@ -69,26 +69,30 @@ namespace BizHawk.Emulation.Cores.Waterbox
TOGGLE_DIP15,
}
+ [Flags]
+ public enum BizhawkFlags : int
+ {
+ // skip video output
+ SkipRendering = 1,
+ // skip sound output
+ SkipSoundening = 2,
+ // render at LCM * LCM instead of raw
+ RenderConstantSize = 4,
+ // switch to the previous disk, if possible
+ PreviousDisk = 8,
+ // switch to the next disk, if possible
+ NextDisk = 16
+ }
+
[StructLayout(LayoutKind.Sequential)]
public new class FrameInfo : LibWaterboxCore.FrameInfo
{
- ///
- /// true to skip video rendering
- ///
- public short SkipRendering;
- ///
- /// true to skip audion rendering
- ///
- public short SkipSoundening;
+ public BizhawkFlags Flags;
///
/// a single command to run at the start of this frame
///
public CommandType Command;
///
- /// True to render to a single framebuffer size (LCM * LCM)
- ///
- public short RenderConstantSize;
- ///
/// raw data for each input port, assumed to be MAX_PORTS * MAX_PORT_DATA long
///
public byte* InputPortData;
diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs
index c241fb5177..eb9fb5ae2c 100644
--- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs
+++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.Controller.cs
@@ -13,9 +13,9 @@ namespace BizHawk.Emulation.Cores.Waterbox
private readonly byte[] _inputPortData = new byte[16 * 16];
private readonly string _controllerDeckName;
- private void InitControls(List allPorts)
+ private void InitControls(List allPorts, bool hasCds)
{
- _controllerAdapter = new ControllerAdapter(allPorts, _syncSettingsActual.PortDevices, ButtonNameOverrides);
+ _controllerAdapter = new ControllerAdapter(allPorts, _syncSettingsActual.PortDevices, ButtonNameOverrides, hasCds);
_nyma.SetInputDevices(_controllerAdapter.Devices);
ControllerDefinition = _controllerAdapter.Definition;
}
@@ -37,7 +37,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
///
public string[] Devices { get; }
public ControllerDefinition Definition { get; }
- public ControllerAdapter(List allPorts, IDictionary config, IDictionary overrides)
+ public ControllerAdapter(List allPorts, IDictionary config, IDictionary overrides, bool hasCds)
{
var ret = new ControllerDefinition
{
@@ -46,6 +46,8 @@ namespace BizHawk.Emulation.Cores.Waterbox
{
{ "Power", "System" },
{ "Reset", "System" },
+ { "Previous Disk", "System" },
+ { "Next Disk", "System" },
}
};
@@ -210,6 +212,11 @@ namespace BizHawk.Emulation.Cores.Waterbox
}
ret.BoolButtons.Add("Power");
ret.BoolButtons.Add("Reset");
+ if (hasCds)
+ {
+ ret.BoolButtons.Add("Previous Disk");
+ ret.BoolButtons.Add("Next Disk");
+ }
Definition = ret;
finalDevices.Add(null);
Devices = finalDevices.ToArray();
diff --git a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs
index 1299e2bc0e..e37ac531f9 100644
--- a/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs
+++ b/src/BizHawk.Emulation.Cores/Waterbox/NymaCore.cs
@@ -119,7 +119,7 @@ namespace BizHawk.Emulation.Cores.Waterbox
VsyncDenominator = 1 << 24;
_soundBuffer = new short[22050 * 2];
- InitControls(portData);
+ InitControls(portData, discs?.Length > 0);
_nyma.SetFrontendSettingQuery(null);
if (_disks != null)
_nyma.SetCDCallbacks(null, null);
@@ -179,16 +179,26 @@ namespace BizHawk.Emulation.Cores.Waterbox
DriveLightOn = false;
_controllerAdapter.SetBits(controller, _inputPortData);
_frameAdvanceInputLock = GCHandle.Alloc(_inputPortData, GCHandleType.Pinned);
+ LibNymaCore.BizhawkFlags flags = 0;
+ if (!render)
+ flags |= LibNymaCore.BizhawkFlags.SkipRendering;
+ if (!rendersound)
+ flags |= LibNymaCore.BizhawkFlags.SkipSoundening;
+ if (SettingsQuery("nyma.constantfb") != "0")
+ flags |= LibNymaCore.BizhawkFlags.RenderConstantSize;
+ if (controller.IsPressed("Previous Disk"))
+ flags |= LibNymaCore.BizhawkFlags.PreviousDisk;
+ if (controller.IsPressed("Next Disk"))
+ flags |= LibNymaCore.BizhawkFlags.NextDisk;
+
var ret = new LibNymaCore.FrameInfo
{
- SkipRendering = (short)(render ? 0 : 1),
- SkipSoundening = (short)(rendersound ? 0 : 1),
+ Flags = flags,
Command = controller.IsPressed("Power")
? LibNymaCore.CommandType.POWER
: controller.IsPressed("Reset")
? LibNymaCore.CommandType.RESET
: LibNymaCore.CommandType.NONE,
- RenderConstantSize = (short)(SettingsQuery("nyma.constantfb") != "0" ? 1 : 0),
InputPortData = (byte*)_frameAdvanceInputLock.AddrOfPinnedObject(),
FrontendTime = GetRtcTime(SettingsQuery("nyma.rtcrealtime") != "0"),
};
diff --git a/waterbox/nyma/NymaCore.cpp b/waterbox/nyma/NymaCore.cpp
index 68377ebc62..6ed597dac1 100644
--- a/waterbox/nyma/NymaCore.cpp
+++ b/waterbox/nyma/NymaCore.cpp
@@ -82,8 +82,6 @@ ECL_EXPORT bool InitRom(const InitData& data)
return true;
}
-void StartGameWithCds(int numdisks);
-
ECL_EXPORT bool InitCd(int numdisks)
{
try
@@ -98,15 +96,25 @@ ECL_EXPORT bool InitCd(int numdisks)
return true;
}
+enum BizhawkFlags
+{
+ // skip video output
+ SkipRendering = 1,
+ // skip sound output
+ SkipSoundening = 2,
+ // render at LCM * LCM instead of raw
+ RenderConstantSize = 4,
+ // switch to the previous disk, if possible
+ PreviousDisk = 8,
+ // switch to the next disk, if possible
+ NextDisk = 16
+};
+
struct MyFrameInfo: public FrameInfo
{
- // true to skip video rendering
- int16_t SkipRendering;
- int16_t SkipSoundening;
+ int32_t BizhawkFlags;
// a single MDFN_MSC_* command to run at the start of this frame; 0 if none
- int16_t Command;
- // true to render LCM * LCM instead of raw
- int16_t RenderConstantSize;
+ int32_t Command;
// raw data for each input port, assumed to be MAX_PORTS * MAX_PORT_DATA long
uint8_t* InputPortData;
int64_t FrontendTime;
@@ -116,7 +124,14 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo& frame)
{
FrontendTime = frame.FrontendTime;
LagFlag = true;
- EES->skip = frame.SkipRendering;
+ EES->skip = !!(frame.BizhawkFlags & BizhawkFlags::SkipRendering);
+
+ {
+ auto prev = !!(frame.BizhawkFlags & BizhawkFlags::PreviousDisk);
+ auto next = !!(frame.BizhawkFlags & BizhawkFlags::NextDisk);
+ if (prev || next)
+ SwitchCds(prev, next);
+ }
if (frame.Command)
Game->DoSimpleCommand(frame.Command);
@@ -131,12 +146,12 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo& frame)
EES->SoundFormatChanged = false;
frame.Cycles = EES->MasterCycles;
frame.Lagged = LagFlag;
- if (!frame.SkipSoundening)
+ if (!(frame.BizhawkFlags & BizhawkFlags::SkipSoundening))
{
memcpy(frame.SoundBuffer, EES->SoundBuf, EES->SoundBufSize * 4);
frame.Samples = EES->SoundBufSize;
}
- if (!frame.SkipRendering)
+ if (!(frame.BizhawkFlags & BizhawkFlags::SkipRendering))
{
int h = EES->DisplayRect.h;
int lineStart = EES->DisplayRect.y;
@@ -147,7 +162,7 @@ ECL_EXPORT void FrameAdvance(MyFrameInfo& frame)
uint32_t* src = pixels + EES->DisplayRect.x + EES->DisplayRect.y * srcp;
uint32_t* dst = frame.VideoBuffer;
- if (!frame.RenderConstantSize || !multiWidth && Game->lcm_width == EES->DisplayRect.w && Game->lcm_height == h)
+ if (!(frame.BizhawkFlags & BizhawkFlags::RenderConstantSize) || !multiWidth && Game->lcm_width == EES->DisplayRect.w && Game->lcm_height == h)
{
// simple non-resizing blitter
// TODO: What does this do with true multiwidth? Probably not anything good
diff --git a/waterbox/nyma/cdrom.cpp b/waterbox/nyma/cdrom.cpp
index 4a1e525bd8..408c312228 100644
--- a/waterbox/nyma/cdrom.cpp
+++ b/waterbox/nyma/cdrom.cpp
@@ -110,7 +110,6 @@ void StartGameWithCds(int numdisks)
}
MDFNGameInfo->RMD = rmd;
- // TODO: Wire up a way for the user to change disks
Mednafen::MDFNGameInfo->SetMedia(
0, // drive: 0 unless there's more than one drive
2, // state: 0 = open, 1 = closed (media absent), 2 = closed (media present)
@@ -118,6 +117,39 @@ void StartGameWithCds(int numdisks)
0 // orientation: flip sides on NES FDS. not used elsewhere?
);
}
+static bool wasPrev;
+static bool wasNext;
+static int cd;
+void SwitchCds(bool prev, bool next)
+{
+ auto newCd = cd;
+ if (prev && !wasPrev)
+ {
+ newCd = std::max(newCd - 1, -1);
+ }
+ if (next && !wasNext)
+ {
+ newCd = std::min(newCd + 1, (int)(CDInterfaces->size() - 1));
+ }
+ if (newCd != cd)
+ {
+ Mednafen::MDFNGameInfo->SetMedia(
+ 0, // drive: 0 unless there's more than one drive
+ 0, // state: 0 = open, 1 = closed (media absent), 2 = closed (media present)
+ std::max(cd, 0), // media: index into the disk list
+ 0 // orientation: flip sides on NES FDS. not used elsewhere?
+ );
+ Mednafen::MDFNGameInfo->SetMedia(
+ 0, // drive: 0 unless there's more than one drive
+ newCd == -1 ? 0 : 2, // state: 0 = open, 1 = closed (media absent), 2 = closed (media present)
+ std::max(newCd, 0), // media: index into the disk list
+ 0 // orientation: flip sides on NES FDS. not used elsewhere?
+ );
+ }
+ cd = newCd;
+ wasPrev = prev;
+ wasNext = next;
+}
// CDInterface::Load pulls in a bunch of things that we do not want, stub them out here
namespace Mednafen
diff --git a/waterbox/nyma/cdrom_dummy.cpp b/waterbox/nyma/cdrom_dummy.cpp
index e3b36e150b..013d4b1b46 100644
--- a/waterbox/nyma/cdrom_dummy.cpp
+++ b/waterbox/nyma/cdrom_dummy.cpp
@@ -11,3 +11,7 @@ ECL_EXPORT void SetCDCallbacks()
{
abort();
}
+void SwitchCds(bool prev, bool next)
+{
+ abort();
+}
diff --git a/waterbox/nyma/common/nyma.h b/waterbox/nyma/common/nyma.h
index 89d0c08ddc..f1e9010c98 100644
--- a/waterbox/nyma/common/nyma.h
+++ b/waterbox/nyma/common/nyma.h
@@ -25,3 +25,6 @@ typedef void (*FrameCallback)();
// The callback may not call any C standard library functions, or otherwise trigger a syscall
// The callback must return before frame advance finishes
void RegisterFrameThreadProc(FrameCallback threadproc);
+
+void StartGameWithCds(int numdisks);
+void SwitchCds(bool prev, bool next);