diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index 4391f5176e..da76db1807 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -52,6 +52,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate ushort snes_input_state_t(int port, int device, int index, int id); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate void snes_input_notify_t(int index); + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void snes_audio_sample_t(ushort left, ushort right); [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate void snes_scanlineStart_t(int line); @@ -63,6 +65,8 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES [DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void snes_set_input_state(snes_input_state_t input_state); [DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)] + public static extern void snes_set_input_notify(snes_input_notify_t input_notify); + [DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void snes_set_audio_sample(snes_audio_sample_t audio_sample); [DllImport("libsneshawk.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void snes_set_scanlineStart(snes_scanlineStart_t scanlineStart); @@ -296,6 +300,9 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES inputcb = new LibsnesDll.snes_input_state_t(snes_input_state); BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_state(inputcb); + notifycb = new LibsnesDll.snes_input_notify_t(snes_input_notify); + BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_input_notify(notifycb); + soundcb = new LibsnesDll.snes_audio_sample_t(snes_audio_sample); BizHawk.Emulation.Consoles.Nintendo.SNES.LibsnesDll.snes_set_audio_sample(soundcb); @@ -322,6 +329,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES LibsnesDll.snes_video_refresh_t vidcb; LibsnesDll.snes_input_poll_t pollcb; LibsnesDll.snes_input_state_t inputcb; + LibsnesDll.snes_input_notify_t notifycb; LibsnesDll.snes_audio_sample_t soundcb; LibsnesDll.snes_scanlineStart_t scanlineStart_cb; @@ -356,6 +364,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES } void snes_input_poll() + { + // libsnes.cpp calls this on every video refresh regardless of any underlying anything, so... + //IsLagFrame = false; + } + + void snes_input_notify(int index) { IsLagFrame = false; } diff --git a/BizHawk.MultiClient/output/libsneshawk.dll b/BizHawk.MultiClient/output/libsneshawk.dll index 90616f7e70..07a20ab094 100644 Binary files a/BizHawk.MultiClient/output/libsneshawk.dll and b/BizHawk.MultiClient/output/libsneshawk.dll differ diff --git a/libsnes/bsnes/snes/cpu/mmio/mmio.cpp b/libsnes/bsnes/snes/cpu/mmio/mmio.cpp index 8b6aaa6a52..f0af7df283 100644 --- a/libsnes/bsnes/snes/cpu/mmio/mmio.cpp +++ b/libsnes/bsnes/snes/cpu/mmio/mmio.cpp @@ -204,14 +204,14 @@ uint8 CPU::mmio_r4217() { return status.rdmpy >> 8; } -uint8 CPU::mmio_r4218() { return status.joy1 >> 0; } //JOY1L -uint8 CPU::mmio_r4219() { return status.joy1 >> 8; } //JOY1H -uint8 CPU::mmio_r421a() { return status.joy2 >> 0; } //JOY2L -uint8 CPU::mmio_r421b() { return status.joy2 >> 8; } //JOY2H -uint8 CPU::mmio_r421c() { return status.joy3 >> 0; } //JOY3L -uint8 CPU::mmio_r421d() { return status.joy3 >> 8; } //JOY3H -uint8 CPU::mmio_r421e() { return status.joy4 >> 0; } //JOY4L -uint8 CPU::mmio_r421f() { return status.joy4 >> 8; } //JOY4H +uint8 CPU::mmio_r4218() { interface->inputNotify(8); return status.joy1 >> 0; } //JOY1L +uint8 CPU::mmio_r4219() { interface->inputNotify(9); return status.joy1 >> 8; } //JOY1H +uint8 CPU::mmio_r421a() { interface->inputNotify(10); return status.joy2 >> 0; } //JOY2L +uint8 CPU::mmio_r421b() { interface->inputNotify(11); return status.joy2 >> 8; } //JOY2H +uint8 CPU::mmio_r421c() { interface->inputNotify(12); return status.joy3 >> 0; } //JOY3L +uint8 CPU::mmio_r421d() { interface->inputNotify(13); return status.joy3 >> 8; } //JOY3H +uint8 CPU::mmio_r421e() { interface->inputNotify(14); return status.joy4 >> 0; } //JOY4L +uint8 CPU::mmio_r421f() { interface->inputNotify(15); return status.joy4 >> 8; } //JOY4H //DMAPx uint8 CPU::mmio_r43x0(uint8 i) { diff --git a/libsnes/bsnes/snes/interface/interface.cpp b/libsnes/bsnes/snes/interface/interface.cpp index 9f86e58d81..dac9cd5db7 100644 --- a/libsnes/bsnes/snes/interface/interface.cpp +++ b/libsnes/bsnes/snes/interface/interface.cpp @@ -14,6 +14,9 @@ int16_t Interface::inputPoll(bool port, Input::Device device, unsigned index, un return 0; } +void Interface::inputNotify(int index) { +} + void Interface::message(const string &text) { print(text, "\n"); } diff --git a/libsnes/bsnes/snes/interface/interface.hpp b/libsnes/bsnes/snes/interface/interface.hpp index 4c96c3c56c..86afad702a 100644 --- a/libsnes/bsnes/snes/interface/interface.hpp +++ b/libsnes/bsnes/snes/interface/interface.hpp @@ -2,7 +2,9 @@ struct Interface { virtual void videoRefresh(const uint32_t *data, bool hires, bool interlace, bool overscan); virtual void audioSample(int16_t lsample, int16_t rsample); virtual int16_t inputPoll(bool port, Input::Device device, unsigned index, unsigned id); - + + virtual void inputNotify(int index); + virtual string path(Cartridge::Slot slot, const string &hint) = 0; virtual void message(const string &text); virtual time_t currentTime(); diff --git a/libsnes/bsnes/target-libsnes/libsnes.cpp b/libsnes/bsnes/target-libsnes/libsnes.cpp index 8ef4e9f721..53fe31d37e 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes.cpp @@ -10,6 +10,7 @@ struct Interface : public SNES::Interface { snes_audio_sample_t paudio_sample; snes_input_poll_t pinput_poll; snes_input_state_t pinput_state; + snes_input_notify_t pinput_notify; string basename; uint32_t *buffer; uint32_t *palette; @@ -52,6 +53,10 @@ struct Interface : public SNES::Interface { return 0; } + void inputNotify(int index) { + if (pinput_notify) pinput_notify(index); + } + void message(const string &text) { print(text, "\n"); } @@ -60,7 +65,7 @@ struct Interface : public SNES::Interface { return { basename, hint }; } - Interface() : pvideo_refresh(0), paudio_sample(0), pinput_poll(0), pinput_state(0) { + Interface() : pvideo_refresh(0), paudio_sample(0), pinput_poll(0), pinput_state(0), pinput_notify(0) { buffer = new uint32_t[512 * 480]; palette = new uint32_t[16 * 32768]; @@ -128,6 +133,10 @@ void snes_set_input_state(snes_input_state_t input_state) { interface.pinput_state = input_state; } +void snes_set_input_notify(snes_input_notify_t input_notify) { + interface.pinput_notify = input_notify; +} + void snes_set_controller_port_device(bool port, unsigned device) { SNES::input.connect(port, (SNES::Input::Device)device); } diff --git a/libsnes/bsnes/target-libsnes/libsnes.hpp b/libsnes/bsnes/target-libsnes/libsnes.hpp index 2e3b05d4aa..ba455b1744 100644 --- a/libsnes/bsnes/target-libsnes/libsnes.hpp +++ b/libsnes/bsnes/target-libsnes/libsnes.hpp @@ -71,6 +71,7 @@ typedef void (*snes_video_refresh_t)(const uint32_t *data, unsigned width, unsig typedef void (*snes_audio_sample_t)(uint16_t left, uint16_t right); typedef void (*snes_input_poll_t)(void); typedef int16_t (*snes_input_state_t)(unsigned port, unsigned device, unsigned index, unsigned id); +typedef void (*snes_input_notify_t)(int index); const char* snes_library_id(void); unsigned snes_library_revision_major(void); @@ -80,6 +81,7 @@ void snes_set_video_refresh(snes_video_refresh_t); void snes_set_audio_sample(snes_audio_sample_t); void snes_set_input_poll(snes_input_poll_t); void snes_set_input_state(snes_input_state_t); +void snes_set_input_notify(snes_input_notify_t); void snes_set_controller_port_device(bool port, unsigned device); void snes_set_cartridge_basename(const char *basename);