aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJP Cimalando <jpcima@users.noreply.github.com>2018-08-02 20:19:37 +0200
committerJP Cimalando <jpcima@users.noreply.github.com>2018-08-02 20:32:54 +0200
commitd8394a61e0bf71b41851b4fdf2094ac2614204e0 (patch)
tree17cff6aedb6297eb8664513ec520b350b1c89411 /src
parent9395426e07706546f31c7b0f4e79ca01be5b037d (diff)
downloadlibADLMIDI-d8394a61e0bf71b41851b4fdf2094ac2614204e0.tar.gz
libADLMIDI-d8394a61e0bf71b41851b4fdf2094ac2614204e0.tar.bz2
libADLMIDI-d8394a61e0bf71b41851b4fdf2094ac2614204e0.zip
add safety check for emulator switching
Diffstat (limited to 'src')
-rw-r--r--src/adlmidi.cpp2
-rw-r--r--src/adlmidi_midiplay.cpp2
-rw-r--r--src/adlmidi_opl3.cpp43
-rw-r--r--src/adlmidi_private.hpp3
4 files changed, 48 insertions, 2 deletions
diff --git a/src/adlmidi.cpp b/src/adlmidi.cpp
index ab0c0c4..c7c5cf3 100644
--- a/src/adlmidi.cpp
+++ b/src/adlmidi.cpp
@@ -613,7 +613,7 @@ ADLMIDI_EXPORT int adl_switchEmulator(struct ADL_MIDIPlayer *device, int emulato
assert(play);
if(!play)
return -1;
- if((emulator >= 0) && (emulator < ADLMIDI_EMU_end))
+ if(adl_isEmulatorAvailable(emulator))
{
play->m_setup.emulator = emulator;
play->partialReset();
diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp
index f1adddd..ded81b3 100644
--- a/src/adlmidi_midiplay.cpp
+++ b/src/adlmidi_midiplay.cpp
@@ -129,7 +129,7 @@ MIDIplay::MIDIplay(unsigned long sampleRate):
{
m_midiDevices.clear();
- m_setup.emulator = ADLMIDI_EMU_NUKED;
+ m_setup.emulator = adl_getLowestEmulator();
m_setup.runAtPcmRate = false;
m_setup.PCM_RATE = sampleRate;
diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp
index 9365e8c..bad9cf3 100644
--- a/src/adlmidi_opl3.cpp
+++ b/src/adlmidi_opl3.cpp
@@ -22,6 +22,8 @@
*/
#include "adlmidi_private.hpp"
+#include <stdlib.h>
+#include <cassert>
#ifdef ADLMIDI_HW_OPL
static const unsigned OPLBase = 0x388;
@@ -42,6 +44,45 @@ static const unsigned OPLBase = 0x388;
# endif
#endif
+static const unsigned adl_emulatorSupport = 0
+#ifndef ADLMIDI_HW_OPL
+#ifndef ADLMIDI_DISABLE_NUKED_EMULATOR
+ | (1u << ADLMIDI_EMU_NUKED) | (1u << ADLMIDI_EMU_NUKED_174)
+#endif
+#ifndef ADLMIDI_DISABLE_DOSBOX_EMULATOR
+ | (1u << ADLMIDI_EMU_DOSBOX)
+#endif
+#endif
+;
+
+//! Check emulator availability
+bool adl_isEmulatorAvailable(int emulator)
+{
+ return (adl_emulatorSupport & (1u << (unsigned)emulator)) != 0;
+}
+
+//! Find highest emulator
+int adl_getHighestEmulator()
+{
+ int emu = -1;
+ for(unsigned m = adl_emulatorSupport; m > 0; m >>= 1)
+ ++emu;
+ return emu;
+}
+
+//! Find lowest emulator
+int adl_getLowestEmulator()
+{
+ int emu = -1;
+ unsigned m = adl_emulatorSupport;
+ if(m > 0)
+ {
+ for(emu = 0; (m & 1) == 0; m >>= 1)
+ ++emu;
+ }
+ return emu;
+}
+
//! Per-channel and per-operator registers map
static const uint16_t g_operatorsMap[23 * 2] =
{
@@ -578,6 +619,8 @@ void OPL3::reset(int emulator, unsigned long PCM_RATE, void *audioTickHandler)
switch(emulator)
{
default:
+ assert(false);
+ abort();
#ifndef ADLMIDI_DISABLE_NUKED_EMULATOR
case ADLMIDI_EMU_NUKED: /* Latest Nuked OPL3 */
chip = new NukedOPL3;
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index 0a7a1bb..0219c67 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -1472,5 +1472,8 @@ extern void adl_audioTickHandler(void *instance, uint32_t chipId, uint32_t rate)
#endif
extern int adlRefreshNumCards(ADL_MIDIPlayer *device);
+extern bool adl_isEmulatorAvailable(int emulator);
+extern int adl_getHighestEmulator();
+extern int adl_getLowestEmulator();
#endif // ADLMIDI_PRIVATE_HPP