From 193ac787fed2beb43c89312e5f45e231d50c544d Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Fri, 18 Sep 2020 11:00:05 +0300 Subject: ADLMIDI2: Fixed an MSVC build However, it may work glitchy! --- utils/adlmidi-2/midiplay.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc index 8a39f2f..b8f9551 100644 --- a/utils/adlmidi-2/midiplay.cc +++ b/utils/adlmidi-2/midiplay.cc @@ -1154,7 +1154,7 @@ static void SendStereoAudio(unsigned long count, short* samples) //static unsigned counter = 0; if(++counter < 8000) return; -#if defined(__WIN32__) && 0 +#if defined(_WIN32) && 0 // Cheat on dosbox recording: easier on the cpu load. {count*=2; std::vector AudioBuffer(count); @@ -1185,7 +1185,7 @@ static void SendStereoAudio(unsigned long count, short* samples) reverb_data.chan[w].Process(count); // Convert to signed 16-bit int format and put to playback queue -#ifdef __WIN32__ +#ifdef _WIN32 std::vector AudioBuffer(count*2); const size_t pos = 0; #else @@ -1299,7 +1299,7 @@ static void SendStereoAudio(unsigned long count, short* samples) } } #endif -#ifndef __WIN32__ +#ifndef _WIN32 AudioBuffer_lock.Unlock(); #else if(!WritePCMfile) @@ -1491,7 +1491,7 @@ bool AdlInstrumentTester::HandleInputChar(char ch) DoNoteOff(); break; case 3: -#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)) +#if !((!defined(_WIN32) || defined(__CYGWIN__)) && !defined(__DJGPP__)) case 27: #endif return false; -- cgit v1.2.3 From 9b51dd7d667e97338a92711543fc3e942faae52f Mon Sep 17 00:00:00 2001 From: Vitaly Novichkov Date: Mon, 21 Sep 2020 00:43:58 +0300 Subject: Added WinMM driver for windows (#236) * ADLMIDI2: Fixed an MSVC build However, it may work glitchy! * Experimental WinMM MIDI driver TODO: Make a control panel to configure the driver * WinMM-DRV: A workaround for older MinGW * WinMM-DRV: WIP control panel appled / tool * WinMM-DRV: Better test a driver's work * WinMM-DRV: More progress on a control panel * WinMM-DRV: And more progress on this control panel It's almost completed, I need to make the working setup through a registry. * WinMM-DRV: Driver is almost ready However, control panel can't ping a driver to reload settings yet * WinMM-DRV: Fix the missing volume model setup * WinMM-DRV: Setup reload on the fly now work! * WinMM-DRV: Stabilize the thing * WinMM-DRV: Stabilizing * WinMM-DRV: Avoid all "setup" in names to avoid a stupid PCA thing: https://stackoverflow.com/questions/17660404/how-to-programmatically-disable-program-compatibility-assistant-in-windows-7-and * A small warning fix at the WOPL module * WinMM-DRV: Fixed some warnings * WinMM-DRV: Avoid PCA dialog on the installer * WiNMM-DRV: Make the linking of pthread being optional Required to use MinGW-w64 toolchain with the "win32" threading mode * WinMM-DRV: Receive the MODM_RESET to reset the MIDI state * WinMM-DRV: Attempt to fix a sound distorsion on song song * WinMM-Drv: Fixed a build on some older MinGW toolchains * WinMM-Drv: Fixed default settings not being loaded --- .gitattributes | 3 + CMakeLists.txt | 8 + src/adlmidi_midiplay.cpp | 2 +- src/wopl/wopl_file.c | 5 +- utils/adlmidi-2/midiplay.cc | 8 +- utils/vlc_codec/libadlmidi.c | 2 + utils/winmm_drv/CMakeLists.txt | 126 +++++ utils/winmm_drv/config/regconfig.c | 297 ++++++++++ utils/winmm_drv/config/regconfig.h | 61 ++ utils/winmm_drv/cpl/adlconfig-tool.c | 20 + utils/winmm_drv/cpl/adlconfig-tool.exe.manifest | 36 ++ utils/winmm_drv/cpl/adlconfig.c | 101 ++++ utils/winmm_drv/cpl/adlconfig.cpl.manifest | 36 ++ utils/winmm_drv/cpl/adlconfig.def | 5 + utils/winmm_drv/cpl/adlconfig.rc | 142 +++++ utils/winmm_drv/cpl/config_dialog.c | 383 +++++++++++++ utils/winmm_drv/cpl/config_dialog.h | 12 + utils/winmm_drv/cpl/opl3icon.ico | Bin 0 -> 22486 bytes utils/winmm_drv/cpl/resource.h | 50 ++ utils/winmm_drv/cpl/targetver.h | 24 + utils/winmm_drv/installer/drvinst.c | 276 +++++++++ utils/winmm_drv/installer/drvinst.exe.manifest | 25 + utils/winmm_drv/installer/drvinst.rc | 6 + utils/winmm_drv/src/MidiSynth.cpp | 720 ++++++++++++++++++++++++ utils/winmm_drv/src/MidiSynth.h | 90 +++ utils/winmm_drv/src/stdafx.h | 83 +++ utils/winmm_drv/src/targetver.h | 24 + utils/winmm_drv/src/winmm_drv.cpp | 386 +++++++++++++ utils/winmm_drv/src/winmm_drv.def | 6 + utils/winmm_drv/test/test.c | 105 ++++ 30 files changed, 3035 insertions(+), 7 deletions(-) create mode 100644 .gitattributes create mode 100644 utils/winmm_drv/CMakeLists.txt create mode 100644 utils/winmm_drv/config/regconfig.c create mode 100644 utils/winmm_drv/config/regconfig.h create mode 100644 utils/winmm_drv/cpl/adlconfig-tool.c create mode 100644 utils/winmm_drv/cpl/adlconfig-tool.exe.manifest create mode 100644 utils/winmm_drv/cpl/adlconfig.c create mode 100644 utils/winmm_drv/cpl/adlconfig.cpl.manifest create mode 100644 utils/winmm_drv/cpl/adlconfig.def create mode 100644 utils/winmm_drv/cpl/adlconfig.rc create mode 100644 utils/winmm_drv/cpl/config_dialog.c create mode 100644 utils/winmm_drv/cpl/config_dialog.h create mode 100644 utils/winmm_drv/cpl/opl3icon.ico create mode 100644 utils/winmm_drv/cpl/resource.h create mode 100644 utils/winmm_drv/cpl/targetver.h create mode 100644 utils/winmm_drv/installer/drvinst.c create mode 100644 utils/winmm_drv/installer/drvinst.exe.manifest create mode 100644 utils/winmm_drv/installer/drvinst.rc create mode 100644 utils/winmm_drv/src/MidiSynth.cpp create mode 100644 utils/winmm_drv/src/MidiSynth.h create mode 100644 utils/winmm_drv/src/stdafx.h create mode 100644 utils/winmm_drv/src/targetver.h create mode 100644 utils/winmm_drv/src/winmm_drv.cpp create mode 100644 utils/winmm_drv/src/winmm_drv.def create mode 100644 utils/winmm_drv/test/test.c diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..7885016 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.rc text eol=crlf +*.manifest text eol=crlf +*.def text eol=crlf diff --git a/CMakeLists.txt b/CMakeLists.txt index 855a3d1..b241b54 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,6 +136,10 @@ option(WITH_MUS2MID "Build a MUS to MIDI converter" OFF) option(WITH_XMI2MID "Build a XMI to MIDI converter" OFF) option(EXAMPLE_SDL2_AUDIO "Build also a simple SDL2 demo MIDI player" OFF) +if(WIN32) + option(WITH_WINMMDRV "Build a WinMM MIDI driver" OFF) +endif() + function(handle_options targetLib) if(WITH_MIDI_SEQUENCER) target_sources(${targetLib} PRIVATE ${libADLMIDI_SOURCE_DIR}/src/adlmidi_sequencer.cpp) @@ -345,6 +349,10 @@ if(WITH_VLC_PLUGIN AND NOT ADLMIDI_DOS) add_subdirectory(utils/vlc_codec) endif() +if(WIN32 AND WITH_WINMMDRV) + add_subdirectory(utils/winmm_drv) +endif() + set(libADLMIDI_INSTALLS ) foreach(lib ADLMIDI_static ADLMIDI_shared) if(TARGET ${lib}) diff --git a/src/adlmidi_midiplay.cpp b/src/adlmidi_midiplay.cpp index 8d92933..56283f3 100644 --- a/src/adlmidi_midiplay.cpp +++ b/src/adlmidi_midiplay.cpp @@ -1841,7 +1841,7 @@ void MIDIplay::describeChannels(char *str, char *attr, size_t size) AdlChannel::const_users_iterator locnext(loc); if(!loc.is_end()) ++locnext; - if(loc.is_end()) // off + if(loc.is_end()) // off { str[index] = '-'; } diff --git a/src/wopl/wopl_file.c b/src/wopl/wopl_file.c index b712020..5c96e41 100644 --- a/src/wopl/wopl_file.c +++ b/src/wopl/wopl_file.c @@ -173,7 +173,8 @@ static void WOPL_parseInstrument(WOPLInstrument *ins, uint8_t *cursor, uint16_t static void WOPL_writeInstrument(WOPLInstrument *ins, uint8_t *cursor, uint16_t version, uint8_t has_sounding_delays) { int l; - strncpy((char*)cursor, ins->inst_name, 32); + memcpy((char*)cursor, ins->inst_name, 32); + cursor[32] = '\0'; fromSint16BE(ins->note_offset1, cursor + 32); fromSint16BE(ins->note_offset2, cursor + 34); cursor[36] = (uint8_t)ins->midi_velocity_offset; @@ -278,7 +279,7 @@ WOPLFile *WOPL_LoadBankFromMem(void *mem, size_t length, int *error) outFile->version = version; outFile->opl_flags = head[4]; outFile->volume_model = head[5]; - } + } bankslots_sizes[0] = count_melodic_banks; bankslots[0] = outFile->banks_melodic; diff --git a/utils/adlmidi-2/midiplay.cc b/utils/adlmidi-2/midiplay.cc index 8a39f2f..b8f9551 100644 --- a/utils/adlmidi-2/midiplay.cc +++ b/utils/adlmidi-2/midiplay.cc @@ -1154,7 +1154,7 @@ static void SendStereoAudio(unsigned long count, short* samples) //static unsigned counter = 0; if(++counter < 8000) return; -#if defined(__WIN32__) && 0 +#if defined(_WIN32) && 0 // Cheat on dosbox recording: easier on the cpu load. {count*=2; std::vector AudioBuffer(count); @@ -1185,7 +1185,7 @@ static void SendStereoAudio(unsigned long count, short* samples) reverb_data.chan[w].Process(count); // Convert to signed 16-bit int format and put to playback queue -#ifdef __WIN32__ +#ifdef _WIN32 std::vector AudioBuffer(count*2); const size_t pos = 0; #else @@ -1299,7 +1299,7 @@ static void SendStereoAudio(unsigned long count, short* samples) } } #endif -#ifndef __WIN32__ +#ifndef _WIN32 AudioBuffer_lock.Unlock(); #else if(!WritePCMfile) @@ -1491,7 +1491,7 @@ bool AdlInstrumentTester::HandleInputChar(char ch) DoNoteOff(); break; case 3: -#if !((!defined(__WIN32__) || defined(__CYGWIN__)) && !defined(__DJGPP__)) +#if !((!defined(_WIN32) || defined(__CYGWIN__)) && !defined(__DJGPP__)) case 27: #endif return false; diff --git a/utils/vlc_codec/libadlmidi.c b/utils/vlc_codec/libadlmidi.c index d247d30..0d04b6a 100644 --- a/utils/vlc_codec/libadlmidi.c +++ b/utils/vlc_codec/libadlmidi.c @@ -109,6 +109,8 @@ static const char * const emulator_type_descriptions[] = N_("Nuked OPL3 1.8"), N_("Nuked OPL3 1.7.4 (Optimized)"), N_("DOSBox"), + N_("Opal"), + N_("Java OPL3"), NULL }; diff --git a/utils/winmm_drv/CMakeLists.txt b/utils/winmm_drv/CMakeLists.txt new file mode 100644 index 0000000..e65f281 --- /dev/null +++ b/utils/winmm_drv/CMakeLists.txt @@ -0,0 +1,126 @@ + +if(NOT WIN32) + message(FATAL_ERROR "WinDriver: This component is for Windows Platform only") +endif() + +option(WITH_WINMMDRV_PTHREADS "Link libwinpthreads statically (when using pthread-based builds)" ON) + +#==================================== +# Driver module +#==================================== + +set(ADLMIDI_DRIVER_SRC + src/winmm_drv.def + src/winmm_drv.cpp + src/MidiSynth.cpp + config/regconfig.c +) + +add_library(adlmididrv MODULE ${ADLMIDI_DRIVER_SRC}) +set_target_properties(adlmididrv PROPERTIES PREFIX "") +target_link_libraries(adlmididrv PRIVATE winmm ADLMIDI_static) +target_include_directories(adlmididrv PRIVATE config) +target_compile_definitions(adlmididrv PRIVATE + -D_USRDLL + -D_WINDLL + -DMM_WIN32DRV_EXPORTS + -DENABLE_REG_SERVER +) + +if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) + set_property(TARGET adlmididrv APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc -static-libstdc++ -Wl,--enable-stdcall-fixup") + if(WITH_WINMMDRV_PTHREADS) + set_property(TARGET adlmididrv APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lpthread -Wl,-Bdynamic,--no-whole-archive") + endif() +endif() + +if(NOT MSVC) + target_compile_options(adlmididrv PRIVATE "-Wno-cast-function-type") +endif() + + + +#==================================== +# Install utility +#==================================== + +set(ADLMIDI_INSTALLER_SRC + installer/drvinst.c +) + +if(NOT MSVC) + list(APPEND ADLMIDI_INSTALLER_SRC + installer/drvinst.rc + ) +endif() + +add_executable(drvsetup ${ADLMIDI_INSTALLER_SRC}) + +target_compile_definitions(drvsetup PRIVATE + -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 + -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1 + -D_CRT_SECURE_NO_WARNINGS +) + +if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) + set_property(TARGET drvsetup APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc") +endif() + + +#==================================== +# A unit test to verify the driver +#==================================== + +add_executable(drvtest test/test.c) +target_link_libraries(drvtest PRIVATE winmm) +target_compile_options(drvtest PRIVATE "-Wno-cast-function-type") + + +#==================================== +# Control panel applet +#==================================== + +set(ADLMIDI_DRIVER_SRC + cpl/adlconfig.def + cpl/adlconfig.rc + cpl/config_dialog.c + config/regconfig.c +) + +add_library(adlmidiconfig MODULE ${ADLMIDI_DRIVER_SRC} cpl/adlconfig.c) +set_target_properties(adlmidiconfig PROPERTIES PREFIX "" OUTPUT_NAME "libadlconfig" SUFFIX ".cpl") +target_include_directories(adlmidiconfig PRIVATE config) +target_compile_definitions(adlmidiconfig PRIVATE + -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 + -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1 + -D_CRT_SECURE_NO_WARNINGS + -D_UNICODE + -DUNICODE + -DADL_IS_CPL_APPLET +) + +target_link_libraries(adlmidiconfig PRIVATE comctl32 gdi32 user32) + +add_executable(adlmidiconfigtool ${ADLMIDI_DRIVER_SRC} cpl/adlconfig-tool.c) +set_target_properties(adlmidiconfigtool PROPERTIES WIN32_EXECUTABLE ON) +target_include_directories(adlmidiconfigtool PRIVATE config) +target_compile_definitions(adlmidiconfigtool PRIVATE + -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1 + -D_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1 + -D_CRT_SECURE_NO_WARNINGS + -D_UNICODE + -DUNICODE +) + +target_link_libraries(adlmidiconfigtool PRIVATE comctl32 gdi32 user32) + +if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) + target_compile_options(adlmidiconfig PRIVATE "-Wno-cast-function-type") + target_compile_options(adlmidiconfigtool PRIVATE "-Wno-cast-function-type") + set_property(TARGET adlmidiconfig APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc -Wl,--enable-stdcall-fixup") + set_property(TARGET adlmidiconfigtool APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc -Wl,--enable-stdcall-fixup") +endif() + + +#install(TARGETS adlmididrv +# RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") diff --git a/utils/winmm_drv/config/regconfig.c b/utils/winmm_drv/config/regconfig.c new file mode 100644 index 0000000..517bab8 --- /dev/null +++ b/utils/winmm_drv/config/regconfig.c @@ -0,0 +1,297 @@ +#include +#include + +#include +#include +#include + +#include "regconfig.h" + + +#define TOTAL_BYTES_READ 1024 +#define OFFSET_BYTES 1024 + +static BOOL createRegistryKey(HKEY hKeyParent, const PWCHAR subkey) +{ + DWORD dwDisposition; //It verify new key is created or open existing key + HKEY hKey; + DWORD ret; + + ret = RegCreateKeyExW(hKeyParent, subkey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); + if(ret != ERROR_SUCCESS) + { + return FALSE; + } + + RegCloseKey(hKey); //close the key + return TRUE; +} + +static BOOL writeStringToRegistry(HKEY hKeyParent, const PWCHAR subkey, const PWCHAR valueName, PWCHAR strData) +{ + DWORD ret; + HKEY hKey; + + //Check if the registry exists + ret = RegOpenKeyExW(hKeyParent, subkey, 0, KEY_WRITE, &hKey); + if(ret == ERROR_SUCCESS) + { + ret = RegSetValueExW(hKey, valueName, 0, REG_SZ, (LPBYTE)(strData), wcslen(strData) * sizeof(wchar_t)); + if(ret != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return FALSE; + } + + RegCloseKey(hKey); + return TRUE; + } + return FALSE; +} + +static BOOL readStringFromRegistry(HKEY hKeyParent, const PWCHAR subkey, const PWCHAR valueName, PWCHAR *readData) +{ + HKEY hKey; + DWORD len = TOTAL_BYTES_READ; + DWORD readDataLen = len; + PWCHAR readBuffer = (PWCHAR )malloc(sizeof(PWCHAR)* len); + + if (readBuffer == NULL) + return FALSE; + + //Check if the registry exists + DWORD ret = RegOpenKeyExW(hKeyParent, subkey, 0, KEY_READ, &hKey); + + if(ret == ERROR_SUCCESS) + { + ret = RegQueryValueExW(hKey, valueName, NULL, NULL, (BYTE*)readBuffer, &readDataLen); + + while(ret == ERROR_MORE_DATA) + { + // Get a buffer that is big enough. + len += OFFSET_BYTES; + readBuffer = (PWCHAR)realloc(readBuffer, len); + readDataLen = len; + ret = RegQueryValueExW(hKey, valueName, NULL, NULL, (BYTE*)readBuffer, &readDataLen); + } + if (ret != ERROR_SUCCESS) + { + RegCloseKey(hKey); + return FALSE; + } + + *readData = readBuffer; + RegCloseKey(hKey); + return TRUE; + } + else + { + return FALSE; + } +} + +static BOOL readIntFromRegistry(HKEY hKeyParent, const PWCHAR subkey, const PWCHAR valueName, int *readData) +{ + WCHAR *buf; + BOOL ret; + ret = readStringFromRegistry(hKeyParent, subkey, valueName, &buf); + if(ret && readData) + { + *readData = _wtoi(buf); + } + if(buf) + free(buf); + return ret; +} + +static BOOL writeIntToRegistry(HKEY hKeyParent, const PWCHAR subkey, const PWCHAR valueName, int intData) +{ + WCHAR buf[20]; + BOOL ret; + + ZeroMemory(buf, 20); + _snwprintf(buf, 20, L"%d", intData); + + ret = writeStringToRegistry(hKeyParent, subkey, valueName, buf); + return ret; +} + + + + +void setupDefault(DriverSettings *setup) +{ + setup->useExternalBank = 0; + setup->bankId = 68; + ZeroMemory(setup->bankPath, sizeof(setup->bankPath)); + setup->emulatorId = 0; + + setup->flagDeepTremolo = BST_INDETERMINATE; + setup->flagDeepVibrato = BST_INDETERMINATE; + + setup->flagSoftPanning = BST_CHECKED; + setup->flagScaleModulators = BST_UNCHECKED; + setup->flagFullBrightness = BST_UNCHECKED; + + setup->volumeModel = 0; + setup->numChips = 4; + setup->num4ops = -1; +} + + + +static const PWCHAR s_regPath = L"SOFTWARE\\Wohlstand\\libADLMIDI"; + +void loadSetup(DriverSettings *setup) +{ + int iVal; + WCHAR *sVal = NULL; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"useExternalBank", &iVal)) + setup->useExternalBank = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"bankId", &iVal)) + setup->bankId = iVal; + + if(readStringFromRegistry(HKEY_CURRENT_USER, s_regPath, L"bankPath", &sVal)) + wcsncpy(setup->bankPath, sVal, MAX_PATH); + if(sVal) + free(sVal); + sVal = NULL; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"emulatorId", &iVal)) + setup->emulatorId = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"flagDeepTremolo", &iVal)) + setup->flagDeepTremolo = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"flagDeepVibrato", &iVal)) + setup->flagDeepVibrato = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"flagSoftPanning", &iVal)) + setup->flagSoftPanning = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"flagScaleModulators", &iVal)) + setup->flagScaleModulators = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"flagFullBrightness", &iVal)) + setup->flagFullBrightness = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"volumeModel", &iVal)) + setup->volumeModel = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"numChips", &iVal)) + setup->numChips = iVal; + + if(readIntFromRegistry(HKEY_CURRENT_USER, s_regPath, L"num4ops", &iVal)) + setup->num4ops = iVal; +} + +void saveSetup(DriverSettings *setup) +{ + createRegistryKey(HKEY_CURRENT_USER, s_regPath); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"useExternalBank", setup->useExternalBank); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"bankId", setup->bankId); + writeStringToRegistry(HKEY_CURRENT_USER, s_regPath, L"bankPath", setup->bankPath); + + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"emulatorId", setup->emulatorId); + + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"flagDeepTremolo", setup->flagDeepTremolo); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"flagDeepVibrato", setup->flagDeepVibrato); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"flagSoftPanning", setup->flagSoftPanning); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"flagScaleModulators", setup->flagScaleModulators); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"flagFullBrightness", setup->flagFullBrightness); + + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"volumeModel", setup->volumeModel); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"numChips", setup->numChips); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"num4ops", setup->num4ops); +} + + +static const PWCHAR s_regPathNotify = L"SOFTWARE\\Wohlstand\\libADLMIDI\\notify"; + +void sendSignal(int sig) +{ + writeIntToRegistry(HKEY_CURRENT_USER, s_regPathNotify, L"command", sig); +} + + +#ifdef ENABLE_REG_SERVER + +static HKEY hKey = 0; +static HANDLE hEvent = 0; + +void openSignalListener() +{ + LONG errorcode; + DWORD dwFilter = REG_NOTIFY_CHANGE_NAME | + REG_NOTIFY_CHANGE_ATTRIBUTES | + REG_NOTIFY_CHANGE_LAST_SET | + REG_NOTIFY_CHANGE_SECURITY; + + createRegistryKey(HKEY_CURRENT_USER, s_regPathNotify); + writeIntToRegistry(HKEY_CURRENT_USER, s_regPathNotify, L"command", 0); + + errorcode = RegOpenKeyExW(HKEY_CURRENT_USER, s_regPathNotify, 0, KEY_NOTIFY, &hKey); + if(errorcode != ERROR_SUCCESS) + return; + + hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + if(hEvent == NULL) + { + RegCloseKey(hKey); + hKey = 0; + return; + } + + errorcode = RegNotifyChangeKeyValue(hKey, + FALSE, + dwFilter, + hEvent, + TRUE); + if(errorcode != ERROR_SUCCESS) + { + CloseHandle(hEvent); + hEvent = 0; + RegCloseKey(hKey); + hKey = 0; + return; + } +} + +int hasReloadSetupSignal() +{ + DWORD ret; + int cmd; + + if(hEvent == 0) + return 0; + + ret = WaitForSingleObject(hEvent, 0); + + if(ret == WAIT_OBJECT_0) + { + readIntFromRegistry(HKEY_CURRENT_USER, s_regPathNotify, L"command", &cmd); + return cmd; + } + + return 0; +} + +void resetSignal() +{ + writeIntToRegistry(HKEY_CURRENT_USER, s_regPathNotify, L"command", 0); +} + +void closeSignalListener() +{ + if(hKey) + RegCloseKey(hKey); + hKey = 0; + + if(hEvent) + CloseHandle(hEvent); + hEvent = 0; +} + +#endif diff --git a/utils/winmm_drv/config/regconfig.h b/utils/winmm_drv/config/regconfig.h new file mode 100644 index 0000000..f854d1b --- /dev/null +++ b/utils/winmm_drv/config/regconfig.h @@ -0,0 +1,61 @@ +#pragma once +#ifndef REG_SETUP_HHHH +#define REG_SETUP_HHHH + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef struct DriverSettings_t +{ + BOOL useExternalBank; + int bankId; + WCHAR bankPath[MAX_PATH]; + int emulatorId; + + BOOL flagDeepTremolo; + BOOL flagDeepVibrato; + + BOOL flagSoftPanning; + BOOL flagScaleModulators; + BOOL flagFullBrightness; + + int volumeModel; + int numChips; + int num4ops; +} DriverSettings; + +extern const WCHAR g_adlSignalMemory[]; + +extern void setupDefault(DriverSettings *setup); +extern void loadSetup(DriverSettings *setup); +extern void saveSetup(DriverSettings *setup); + + +#define DRV_SIGNAL_RELOAD_SETUP 1 +#define DRV_SIGNAL_RESET_SYNTH 2 + +// Client +/** + * @brief Ping the running driver to immediately reload the settings + */ +extern void sendSignal(int sig); + +#ifdef ENABLE_REG_SERVER +// Server +extern void openSignalListener(); +extern int hasReloadSetupSignal(); +extern void resetSignal(); +extern void closeSignalListener(); +#endif + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/utils/winmm_drv/cpl/adlconfig-tool.c b/utils/winmm_drv/cpl/adlconfig-tool.c new file mode 100644 index 0000000..513f5eb --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig-tool.c @@ -0,0 +1,20 @@ +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "resource.h" + +#include "config_dialog.h" + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pCmdLine, int nCmdShow) +{ + initAdlSetupBox(hInstance, NULL); + runAdlSetupBox(hInstance, NULL); + return 0; + + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(pCmdLine); + UNREFERENCED_PARAMETER(nCmdShow); +} diff --git a/utils/winmm_drv/cpl/adlconfig-tool.exe.manifest b/utils/winmm_drv/cpl/adlconfig-tool.exe.manifest new file mode 100644 index 0000000..1016f98 --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig-tool.exe.manifest @@ -0,0 +1,36 @@ + + + + libADLMIDI synth Driver settings tool + + + + + + + + + + + + + + + + + + + + diff --git a/utils/winmm_drv/cpl/adlconfig.c b/utils/winmm_drv/cpl/adlconfig.c new file mode 100644 index 0000000..744fc14 --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig.c @@ -0,0 +1,101 @@ +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "resource.h" + +#include "config_dialog.h" + +static HANDLE hModule = NULL; + +BOOL WINAPI DllMain( + PVOID hmod, + ULONG ulReason, + PCONTEXT pctx OPTIONAL +) +{ + if(ulReason != DLL_PROCESS_ATTACH) + { + return TRUE; + } + else + { + hModule = hmod; + } + + return TRUE; + + UNREFERENCED_PARAMETER(pctx); +} + +LONG APIENTRY CPlApplet( + HWND hwndCPL, // handle of Control Panel window + UINT uMsg, // message + LONG_PTR lParam1, // first message parameter + LONG_PTR lParam2 // second message parameter +) +{ + LPCPLINFO lpCPlInfo; + LPNEWCPLINFO lpNewCPlInfo; + LONG retCode = 0; + + switch (uMsg) + { + // first message, sent once + case CPL_INIT: + initAdlSetupBox(hModule, hwndCPL); + return TRUE; + + // second message, sent once + case CPL_GETCOUNT: + return 1L; + + // third message, sent once per app + case CPL_INQUIRE: + lpCPlInfo = (LPCPLINFO)lParam2; + lpCPlInfo->idIcon = IDI_ICON1; + lpCPlInfo->idName = IDC_DRIVERNAME; + lpCPlInfo->idInfo = IDC_DRIVERDESC; + lpCPlInfo->lData = 0L; + break; + + // third message, sent once per app + case CPL_NEWINQUIRE: + lpNewCPlInfo = (LPNEWCPLINFO)lParam2; + lpNewCPlInfo->dwSize = (DWORD) sizeof(NEWCPLINFO); + lpNewCPlInfo->dwFlags = 0; + lpNewCPlInfo->dwHelpContext = 0; + lpNewCPlInfo->lData = 0; + lpNewCPlInfo->hIcon = LoadIconW(hModule, (LPCTSTR)MAKEINTRESOURCEW(IDI_ICON1)); + lpNewCPlInfo->szHelpFile[0] = '\0'; + + LoadStringW(hModule, IDC_DRIVERNAME, lpNewCPlInfo->szName, 32); + LoadStringW(hModule, IDC_DRIVERDESC, lpNewCPlInfo->szInfo, 64); + break; + + // application icon selected + case CPL_SELECT: + break; + + // application icon double-clicked + case CPL_DBLCLK: + runAdlSetupBox(hModule, hwndCPL); + break; + + case CPL_STOP: + break; + + case CPL_EXIT: + cleanUpAdlSetupBox(hModule, hwndCPL); + break; + + default: + break; + } + + return retCode; + + UNREFERENCED_PARAMETER(lParam1); +} diff --git a/utils/winmm_drv/cpl/adlconfig.cpl.manifest b/utils/winmm_drv/cpl/adlconfig.cpl.manifest new file mode 100644 index 0000000..1016f98 --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig.cpl.manifest @@ -0,0 +1,36 @@ + + + + libADLMIDI synth Driver settings tool + + + + + + + + + + + + + + + + + + + + diff --git a/utils/winmm_drv/cpl/adlconfig.def b/utils/winmm_drv/cpl/adlconfig.def new file mode 100644 index 0000000..97ed971 --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig.def @@ -0,0 +1,5 @@ +LIBRARY "libADLMIDIConfig" + +EXPORTS + CPlApplet + ToolDlgProc diff --git a/utils/winmm_drv/cpl/adlconfig.rc b/utils/winmm_drv/cpl/adlconfig.rc new file mode 100644 index 0000000..75551fd --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig.rc @@ -0,0 +1,142 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +///////////////////////////////////////////////////////////////////////////// +// Russian (Russia) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) +LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT +#pragma code_page(1251) + +///////////////////////////////////////////////////////////////////////////// +// +// RT_MANIFEST +// + +#ifdef ADL_IS_CPL_APPLET +MANIFSEST_RES_CPL RT_MANIFEST "adlconfig.cpl.manifest" +#else +MANIFSEST_RES RT_MANIFEST "adlconfig-tool.exe.manifest" +#endif + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ICON1 ICON "opl3icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_CONFIG_BOX DIALOGEX 0, 0, 243, 242 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "libADLMIDI settings" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,81,210,50,14 + PUSHBUTTON "Cancel",IDCANCEL,135,210,50,14 + PUSHBUTTON "Apply",IDC_APPLYBUTTON,191,210,50,14 + COMBOBOX IDC_VOLUMEMODEL,79,95,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Volume model:",IDC_VM_LABEL,5,97,66,8 + COMBOBOX IDC_BANK_ID,79,15,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Instruments bank",IDC_INS_BANK,4,2,234,51 + CONTROL "Internal bank",IDC_BANK_INTERNAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,9,16,63,10 + CONTROL "External bank",IDC_BANK_EXTERNAL,"Button",BS_AUTORADIOBUTTON,9,33,67,10 + EDITTEXT IDC_BANK_PATH,79,31,107,14,ES_AUTOHSCROLL | WS_DISABLED + PUSHBUTTON "Browse...",IDC_BROWSE_BANK,187,31,48,14 + PUSHBUTTON "Restore defaults",IDC_RESTORE_DEFAULTS,153,193,88,14 + CONTROL "Deep tremolo (Auto/Enable/Disable)",IDC_FLAG_TREMOLO, + "Button",BS_AUTO3STATE | WS_TABSTOP,5,124,227,10 + CONTROL "Deep virbrato (Auto/Enable/Disable)",IDC_FLAG_VIBRATO, + "Button",BS_AUTO3STATE | WS_TABSTOP,5,141,227,10 + CONTROL "Full-panning stereo",IDC_FLAG_SOFTPAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,108,227,10 + COMBOBOX IDC_EMULATOR,79,56,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Chip emulator type:",IDC_CHIPEMU_LABEL,5,58,67,8 + LTEXT "Number of chips",IDC_CHIPNUM_LABEL,5,75,69,8 + COMBOBOX IDC_NUM_CHIPS,79,74,33,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + COMBOBOX IDC_NUM_4OPVO,193,74,41,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Number of 4OP voices",IDC_4OPSNUM_LABEL,115,76,72,8 + CONTROL "Scalable modulation",IDC_FLAG_SCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,157,228,10 + CONTROL "Full-range brightness (CC74)",IDC_FLAG_FULLBRIGHT, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,173,228,10 + PUSHBUTTON "About...",IDC_ABOUT,5,210,50,14 + PUSHBUTTON "Reset synth now",IDC_RESET_SYNTH,69,193,80,14 + RTEXT "Settings will be applied immediately",IDC_BOTTOMNOTE_LABEL,0,227,241,8 +END + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_SETUP_BOX, DIALOG + BEGIN + RIGHTMARGIN, 241 + BOTTOMMARGIN, 241 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDC_DRIVERNAME "libADLMIDI settings" + IDC_DRIVERDESC "Settings for libADLMIDI synthesizer" +END + +#endif // Russian (Russia) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/utils/winmm_drv/cpl/config_dialog.c b/utils/winmm_drv/cpl/config_dialog.c new file mode 100644 index 0000000..8489273 --- /dev/null +++ b/utils/winmm_drv/cpl/config_dialog.c @@ -0,0 +1,383 @@ +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include +#include + +#include "config_dialog.h" +#include "resource.h" + +#include "regconfig.h" + +#ifndef CBM_FIRST +#define CBM_FIRST 0x1700 +#endif +#ifndef CB_SETMINVISIBLE +#define CB_SETMINVISIBLE (CBM_FIRST+1) +#endif + +typedef int (*BankNamesCount)(void); +typedef const char *const *(*BankNamesList)(void); + +static const char *const volume_models_descriptions[] = +{ + "Auto (defined by bank)", + "Generic", + "OPL3 Native", + "DMX", + "Apogee Sound System", + "Win9x SB16 driver", + "DMX (Fixed AM)", + "Apogee Sound System (Fixed AM)", + "Audio Interfaces Library (AIL)", + "Win9x Generic FM driver", + "HMI Sound Operating System", + "HMI Sound Operating System (Old)", + NULL +}; + +static const char * const emulator_type_descriptions[] = +{ + "Nuked OPL3 1.8", + "Nuked OPL3 1.7.4 (Optimized)", + "DOSBox", + "Opal", + "Java OPL3", + NULL +}; + +static DriverSettings g_setup; +static HINSTANCE s_hModule; + +static void syncBankType(HWND hwnd, int type); +static void sync4ops(HWND hwnd); +static void syncWidget(HWND hwnd); +static void buildLists(HWND hwnd); +static void syncBankType(HWND hwnd, int type); +static void openCustomBank(HWND hwnd); +static void updateBankName(HWND hwnd, const WCHAR *filePath); + +static void sync4ops(HWND hwnd) +{ + char buff[10]; + int i; + + SendDlgItemMessageW(hwnd, IDC_NUM_4OPVO, CB_RESETCONTENT, 0, 0); + SendDlgItemMessageA(hwnd, IDC_NUM_4OPVO, CB_ADDSTRING, (LPARAM)-1, (LPARAM)"AUTO"); + for(i = 0; i <= g_setup.numChips * 6; i++) + { + ZeroMemory(buff, 10); + snprintf(buff, 10, "%d", i); + SendDlgItemMessageA(hwnd, IDC_NUM_4OPVO, CB_ADDSTRING, (LPARAM)0, (LPARAM)buff); + } + SendDlgItemMessageA(hwnd, IDC_NUM_4OPVO, CB_SETCURSEL, (WPARAM)g_setup.num4ops + 1, (LPARAM)0); +} + +static void syncWidget(HWND hwnd) +{ + char buff[10]; + int i; + + SendDlgItemMessage(hwnd, IDC_BANK_EXTERNAL, BM_SETCHECK, 0, 0); + SendDlgItemMessage(hwnd, IDC_BANK_INTERNAL, BM_SETCHECK, 0, 0); + + if(g_setup.useExternalBank == 1) + SendDlgItemMessage(hwnd, IDC_BANK_EXTERNAL, BM_SETCHECK, 1, 0); + else + SendDlgItemMessage(hwnd, IDC_BANK_INTERNAL, BM_SETCHECK, 1, 0); + + syncBankType(hwnd, g_setup.useExternalBank); + + SendDlgItemMessage(hwnd, IDC_FLAG_TREMOLO, BM_SETCHECK, g_setup.flagDeepTremolo, 0); + SendDlgItemMessage(hwnd, IDC_FLAG_VIBRATO, BM_SETCHECK, g_setup.flagDeepVibrato, 0); + SendDlgItemMessage(hwnd, IDC_FLAG_SOFTPAN, BM_SETCHECK, g_setup.flagSoftPanning, 0); + SendDlgItemMessage(hwnd, IDC_FLAG_SCALE, BM_SETCHECK, g_setup.flagScaleModulators, 0); + SendDlgItemMessage(hwnd, IDC_FLAG_FULLBRIGHT, BM_SETCHECK, g_setup.flagFullBrightness, 0); + + SendDlgItemMessageW(hwnd, IDC_NUM_CHIPS, CB_RESETCONTENT, 0, 0); + for(i = 1; i <= 100; i++) + { + ZeroMemory(buff, 10); + snprintf(buff, 10, "%d", i); + SendDlgItemMessageA(hwnd, IDC_NUM_CHIPS, CB_ADDSTRING, (LPARAM)0, (LPARAM)buff); + } + + SendDlgItemMessageA(hwnd, IDC_NUM_CHIPS, CB_SETCURSEL, (WPARAM)g_setup.numChips - 1, (LPARAM)0); + SendDlgItemMessageA(hwnd, IDC_BANK_ID, CB_SETCURSEL, (WPARAM)g_setup.bankId, (LPARAM)0); + updateBankName(hwnd, g_setup.bankPath); + SendDlgItemMessageA(hwnd, IDC_EMULATOR, CB_SETCURSEL, (WPARAM)g_setup.emulatorId, (LPARAM)0); + SendDlgItemMessageA(hwnd, IDC_VOLUMEMODEL, CB_SETCURSEL, (WPARAM)g_setup.volumeModel, (LPARAM)0); + + sync4ops(hwnd); +} + +static void buildLists(HWND hwnd) +{ + int i, bMax; + HMODULE lib; + const char *const* list; + BankNamesCount adl_getBanksCount; + BankNamesList adl_getBankNames; + + lib = LoadLibraryW(L"adlmididrv.dll"); + if(lib) + { + adl_getBanksCount = (BankNamesCount)GetProcAddress(lib, "adl_getBanksCount"); + adl_getBankNames = (BankNamesList)GetProcAddress(lib, "adl_getBankNames"); + if(adl_getBanksCount && adl_getBankNames) + { + bMax = adl_getBanksCount(); + list = adl_getBankNames(); + for(i = 0; i < bMax; i++) + { + SendDlgItemMessageA(hwnd, IDC_BANK_ID, CB_ADDSTRING, (LPARAM)0, (LPARAM)list[i]); + } + } + else + { + SendDlgItemMessageA(hwnd, IDC_BANK_ID, CB_ADDSTRING, (LPARAM)0, (LPARAM)""); + } + FreeLibrary(lib); + } + else + { + SendDlgItemMessageA(hwnd, IDC_BANK_ID, CB_ADDSTRING, (LPARAM)0, (LPARAM)""); + } + + // Volume models + for(i = 0; volume_models_descriptions[i] != NULL; ++i) + { + SendDlgItemMessageA(hwnd, IDC_VOLUMEMODEL, CB_ADDSTRING, (LPARAM)0, (LPARAM)volume_models_descriptions[i]); + } + + // Emulators list + for(i = 0; emulator_type_descriptions[i] != NULL; ++i) + { + SendDlgItemMessageA(hwnd, IDC_EMULATOR, CB_ADDSTRING, (LPARAM)0, (LPARAM)emulator_type_descriptions[i]); + } +} + +static void syncBankType(HWND hwnd, int type) +{ + EnableWindow(GetDlgItem(hwnd, IDC_BANK_ID), !type); + EnableWindow(GetDlgItem(hwnd, IDC_BROWSE_BANK), type); +} + +static void updateBankName(HWND hwnd, const WCHAR *filePath) +{ + int i, len = wcslen(filePath); + const WCHAR *p = NULL; + + for(i = 0; i < len; i++) + { + if(filePath[i] == L'\\' || filePath[i] == L'/') + p = filePath + i + 1; + } + + if(p == NULL) + SendDlgItemMessage(hwnd, IDC_BANK_PATH, WM_SETTEXT, (WPARAM)NULL, (LPARAM)L""); + else + SendDlgItemMessage(hwnd, IDC_BANK_PATH, WM_SETTEXT, (WPARAM)NULL, (LPARAM)p); +} + +static void openCustomBank(HWND hwnd) +{ + OPENFILENAMEW ofn; + WCHAR szFile[MAX_PATH]; + + ZeroMemory(&ofn, sizeof(ofn)); + ZeroMemory(szFile, sizeof(szFile)); + + wcsncpy(szFile, g_setup.bankPath, MAX_PATH); + + ofn.lStructSize = sizeof(ofn); + ofn.hInstance = s_hModule; + ofn.hwndOwner = hwnd; + ofn.lpstrFilter = L"WOPL bank file (*.wopl)\0*.WOPL\0All files (*.*)\0*.*\0"; + ofn.lpstrFile = szFile; + ofn.nMaxFile = sizeof(szFile); + ofn.lpstrTitle = L"Open external bank file"; + ofn.Flags = OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_READONLY | OFN_HIDEREADONLY | OFN_EXPLORER; + + if(GetOpenFileNameW(&ofn) == TRUE) + { + ZeroMemory(g_setup.bankPath, sizeof(g_setup.bankPath)); + wcsncpy(g_setup.bankPath, szFile, MAX_PATH); + updateBankName(hwnd, g_setup.bankPath); + } +} + +INT_PTR CALLBACK ToolDlgProc(HWND hwnd, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch(Message) + { + case WM_INITDIALOG: + buildLists(hwnd); + syncWidget(hwnd); + return TRUE; + + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDC_ABOUT: + MessageBoxW(hwnd, + L"libADLMIDI - a software MIDI synthesizer with OPL3 FM synth,\n" + L"Made by Vitaly Novichkov \"Wohlstand\".\n\n" + L"Source code is here: https://github.com/Wohlstand/libADLMIDI", + L"About this driver", + MB_OK); + break; + + case IDC_NUM_CHIPS: + if(HIWORD(wParam) == CBN_SELCHANGE) + { + g_setup.numChips = 1 + SendMessageW((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0); + g_setup.num4ops = -1; + sync4ops(hwnd); + } + break; + + case IDC_NUM_4OPVO: + if(HIWORD(wParam) == CBN_SELCHANGE) + { + g_setup.num4ops = SendMessageW((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0) - 1; + } + break; + + case IDC_EMULATOR: + if(HIWORD(wParam) == CBN_SELCHANGE) + { + g_setup.emulatorId = SendMessageW((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0); + } + break; + + case IDC_VOLUMEMODEL: + if(HIWORD(wParam) == CBN_SELCHANGE) + { + g_setup.volumeModel = SendMessageW((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0); + } + break; + + case IDC_BANK_INTERNAL: + g_setup.useExternalBank = 0; + syncBankType(hwnd, FALSE); + break; + + case IDC_BANK_EXTERNAL: + g_setup.useExternalBank = 1; + syncBankType(hwnd, TRUE); + break; + + case IDC_BANK_ID: + if(HIWORD(wParam) == CBN_SELCHANGE) + { + g_setup.bankId = SendMessageW((HWND)lParam, (UINT)CB_GETCURSEL, (WPARAM)0, (LPARAM)0); + } + break; + + case IDC_BROWSE_BANK: + openCustomBank(hwnd); + break; + + case IDC_FLAG_TREMOLO: + if(HIWORD(wParam) == BN_CLICKED) + { + g_setup.flagDeepTremolo = SendDlgItemMessage(hwnd, IDC_FLAG_TREMOLO, (UINT)BM_GETCHECK, 0, 0); + } + break; + + case IDC_FLAG_VIBRATO: + if(HIWORD(wParam) == BN_CLICKED) + { + g_setup.flagDeepVibrato = SendDlgItemMessage(hwnd, IDC_FLAG_VIBRATO, (UINT)BM_GETCHECK, 0, 0); + } + break; + + case IDC_FLAG_SOFTPAN: + if(HIWORD(wParam) == BN_CLICKED) + { + g_setup.flagSoftPanning = SendDlgItemMessage(hwnd, IDC_FLAG_SOFTPAN, (UINT)BM_GETCHECK, 0, 0); + } + break; + + case IDC_FLAG_SCALE: + if(HIWORD(wParam) == BN_CLICKED) + { + g_setup.flagScaleModulators = SendDlgItemMessage(hwnd, IDC_FLAG_SCALE, (UINT)BM_GETCHECK, 0, 0); + } + break; + + case IDC_FLAG_FULLBRIGHT: + if(HIWORD(wParam) == BN_CLICKED) + { + g_setup.flagFullBrightness = SendDlgItemMessage(hwnd, IDC_FLAG_FULLBRIGHT, (UINT)BM_GETCHECK, 0, 0); + } + break; + + + case IDC_RESTORE_DEFAULTS: + setupDefault(&g_setup); + syncWidget(hwnd); + break; + + case IDC_RESET_SYNTH: + sendSignal(DRV_SIGNAL_RESET_SYNTH); + break; + + case IDC_APPLYBUTTON: + saveSetup(&g_setup); + sendSignal(DRV_SIGNAL_RELOAD_SETUP); + break; + + case IDOK: + saveSetup(&g_setup); + sendSignal(DRV_SIGNAL_RELOAD_SETUP); + EndDialog(hwnd, IDOK); + break; + + case IDCANCEL: + EndDialog(hwnd, IDCANCEL); + break; + } + break; + + default: + return FALSE; + } + + return TRUE; + + UNREFERENCED_PARAMETER(lParam); +} + + +BOOL runAdlSetupBox(HINSTANCE hModule, HWND hwnd) +{ + s_hModule = hModule; + + loadSetup(&g_setup); + + DialogBoxW(hModule, MAKEINTRESOURCEW(IDD_CONFIG_BOX), hwnd, ToolDlgProc); + + s_hModule = NULL; + + return TRUE; +} + +WINBOOL initAdlSetupBox(HINSTANCE hModule, HWND hwnd) +{ + InitCommonControls(); + setupDefault(&g_setup); + UNREFERENCED_PARAMETER(hModule); + UNREFERENCED_PARAMETER(hwnd); + return TRUE; +} + +WINBOOL cleanUpAdlSetupBox(HINSTANCE hModule, HWND hwnd) +{ + UNREFERENCED_PARAMETER(hModule); + UNREFERENCED_PARAMETER(hwnd); + return TRUE; +} diff --git a/utils/winmm_drv/cpl/config_dialog.h b/utils/winmm_drv/cpl/config_dialog.h new file mode 100644 index 0000000..1cb45d6 --- /dev/null +++ b/utils/winmm_drv/cpl/config_dialog.h @@ -0,0 +1,12 @@ +#pragma once + +#ifndef SETUP_DIALOG_HHHH +#define SETUP_DIALOG_HHHH + +#include + +extern BOOL initAdlSetupBox(HINSTANCE hModule, HWND hwnd); +extern BOOL runAdlSetupBox(HINSTANCE hModule, HWND hwnd); +extern BOOL cleanUpAdlSetupBox(HINSTANCE hModule, HWND hwnd); + +#endif diff --git a/utils/winmm_drv/cpl/opl3icon.ico b/utils/winmm_drv/cpl/opl3icon.ico new file mode 100644 index 0000000..16c3d9a Binary files /dev/null and b/utils/winmm_drv/cpl/opl3icon.ico differ diff --git a/utils/winmm_drv/cpl/resource.h b/utils/winmm_drv/cpl/resource.h new file mode 100644 index 0000000..bd6b662 --- /dev/null +++ b/utils/winmm_drv/cpl/resource.h @@ -0,0 +1,50 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by adlsetup.rc +// +#include + +#define MANIFSEST_RES 1 +#define MANIFSEST_RES_CPL 123 +#define IDD_CONFIG_BOX 101 +#define IDI_ICON1 102 +#define IDC_DRIVERNAME 103 +#define IDC_DRIVERDESC 104 + +#define IDC_APPLYBUTTON 1000 +#define IDC_VOLUMEMODEL 1001 +#define IDC_VM_LABEL 1002 +#define IDC_BANK_ID 1003 +#define IDC_INS_BANK 1004 +#define IDC_BANK_INTERNAL 1005 +#define IDC_BANK_EXTERNAL 1006 +#define IDC_BANK_PATH 1007 +#define IDC_BROWSE_BANK 1008 +#define IDC_RESTORE_DEFAULTS 1010 +#define IDC_FLAG_TREMOLO 1011 +#define IDC_FLAG_VIBRATO 1012 +#define IDC_FLAG_SOFTPAN 1013 +#define IDC_EMULATOR 1014 +#define IDC_NUM_CHIPS 1018 +#define IDC_NUM_4OPVO 1019 +#define IDC_FLAG_SCALE 1020 +#define IDC_FLAG_FULLBRIGHT 1021 +#define IDC_ABOUT 1022 +#define IDC_CHIPEMU_LABEL 1023 +#define IDC_CHIPNUM_LABEL 1024 +#define IDC_4OPSNUM_LABEL 1025 +#define IDC_RESET_SYNTH 1026 +#define IDC_BOTTOMNOTE_LABEL 1027 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 105 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1028 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/utils/winmm_drv/cpl/targetver.h b/utils/winmm_drv/cpl/targetver.h new file mode 100644 index 0000000..203dfbc --- /dev/null +++ b/utils/winmm_drv/cpl/targetver.h @@ -0,0 +1,24 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Specifies that the minimum required platform is Windows Vista. +#define WINVER 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista. +#define _WIN32_WINNT 0x0600 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 7.0. +#define _WIN32_IE 0x0700 // Change this to the appropriate value to target other versions of IE. +#endif diff --git a/utils/winmm_drv/installer/drvinst.c b/utils/winmm_drv/installer/drvinst.c new file mode 100644 index 0000000..e354691 --- /dev/null +++ b/utils/winmm_drv/installer/drvinst.c @@ -0,0 +1,276 @@ +/* Copyright (C) 2011, 2012 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#define WIN32_LEAN_AND_MEAN +#include +#include +#include +#include +#include + +const char OPL3EMU_DRIVER_NAME[] = "adlmididrv.dll"; +const char OPL3EMU_CPLAPPLET_NAME[] = "libadlconfig.cpl"; +const char OPL3EMU_SETUPTOOL_NAME[] = "adlmidiconfigtool.exe"; + +const char WDM_DRIVER_NAME[] = "wdmaud.drv"; +const char SYSTEM_DIR_NAME[] = "SYSTEM32"; +const char SYSTEM_ROOT_ENV_NAME[] = "SYSTEMROOT"; +const char INSTALL_COMMAND[] = "install"; +const char UNINSTALL_COMMAND[] = "uninstall"; +const char DRIVERS_REGISTRY_KEY[] = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32"; +const char PATH_SEPARATOR[] = "\\"; + +const char SUCCESSFULLY_INSTALLED_MSG[] = "libADLMIDI synth MIDI Driver successfully installed"; +const char SUCCESSFULLY_UPDATED_MSG[] = "libADLMIDI synth MIDI Driver successfully updated"; +const char SUCCESSFULLY_UNINSTALLED_MSG[] = "libADLMIDI synth MIDI Driver successfully uninstalled"; +const char USAGE_MSG[] = "Usage:\n drvsetup install - install driver\n drvsetup uninstall - uninstall driver"; + +const char CANNOT_OPEN_REGISTRY_ERR[] = "Cannot open registry key"; +const char CANNOT_INSTALL_NO_PORTS_ERR[] = "Cannot install libADLMIDI synth MIDI driver:\n There is no MIDI ports available"; +const char CANNOT_REGISTER_ERR[] = "Cannot register driver"; +const char CANNOT_UNINSTALL_ERR[] = "Cannot uninstall libADLMIDI synth MIDI driver"; +const char CANNOT_UNINSTALL_NOT_FOUND_ERR[] = "Cannot uninstall libADLMIDI synth MIDI driver:\n There is no driver registry entry found"; +const char CANNOT_INSTALL_PATH_TOO_LONG_ERR[] = "libADLMIDI synth MIDI Driver cannot be installed:\n Installation path is too long"; +const char CANNOT_INSTALL_FILE_COPY_ERR[] = "libADLMIDI synth MIDI Driver failed to install:\n File copying error"; + +const char INFORMATION_TITLE[] = "Information"; +const char ERROR_TITLE[] = "Error"; +const char REGISTRY_ERROR_TITLE[] = "Registry error"; +const char FILE_ERROR_TITLE[] = "File error"; + +BOOL registerDriver(BOOL *installMode) +{ + char str[255]; + char drvName[] = "midi0"; + DWORD len, res; + BOOL wdmEntryFound = FALSE; + int freeEntry = -1; + HKEY hReg; + int i; + + if(RegOpenKeyA(HKEY_LOCAL_MACHINE, DRIVERS_REGISTRY_KEY, &hReg)) + { + MessageBoxA(NULL, CANNOT_OPEN_REGISTRY_ERR, REGISTRY_ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + return FALSE; + } + + for(i = 0; i < 10; i++) + { + len = 255; + if(i) + drvName[4] = '0' + i; + else + drvName[4] = 0; + res = RegQueryValueExA(hReg, drvName, NULL, NULL, (LPBYTE)str, &len); + if(res != ERROR_SUCCESS) + { + if((freeEntry == -1) && (res == ERROR_FILE_NOT_FOUND)) + freeEntry = i; + continue; + } + if(!_stricmp(str, OPL3EMU_DRIVER_NAME)) + { + RegCloseKey(hReg); + *installMode = FALSE; + return TRUE; + } + if(freeEntry != -1) continue; + if(strlen(str) == 0) + freeEntry = i; + else if(!_stricmp(str, WDM_DRIVER_NAME)) + { + // Considering multiple WDM entries are just garbage, though one entry shouldn't be modified + if(wdmEntryFound) + freeEntry = i; + else + wdmEntryFound = TRUE; + } + } + + if(freeEntry == -1) + { + MessageBoxA(NULL, CANNOT_INSTALL_NO_PORTS_ERR, ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + RegCloseKey(hReg); + return FALSE; + } + + if(freeEntry) + drvName[4] = '0' + freeEntry; + else + drvName[4] = 0; + + res = RegSetValueExA(hReg, drvName, 0, REG_SZ, (LPBYTE)OPL3EMU_DRIVER_NAME, sizeof(OPL3EMU_DRIVER_NAME)); + if(res != ERROR_SUCCESS) + { + MessageBoxA(NULL, CANNOT_REGISTER_ERR, REGISTRY_ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + RegCloseKey(hReg); + return FALSE; + } + + RegCloseKey(hReg); + + return TRUE; +} + +void unregisterDriver() +{ + char str[255]; + char drvName[] = "midi0"; + DWORD len, res; + HKEY hReg; + int i; + + if(RegOpenKeyA(HKEY_LOCAL_MACHINE, DRIVERS_REGISTRY_KEY, &hReg)) + { + MessageBoxA(NULL, CANNOT_OPEN_REGISTRY_ERR, REGISTRY_ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + return; + } + + for(i = 0; i < 10; i++) + { + len = 255; + if(i) + drvName[4] = '0' + i; + else + drvName[4] = 0; + res = RegQueryValueExA(hReg, drvName, NULL, NULL, (LPBYTE)str, &len); + if(res != ERROR_SUCCESS) + continue; + if(!_stricmp(str, OPL3EMU_DRIVER_NAME)) + { + res = RegDeleteValueA(hReg, drvName); + if(res != ERROR_SUCCESS) + { + MessageBoxA(NULL, CANNOT_UNINSTALL_ERR, REGISTRY_ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + RegCloseKey(hReg); + return; + } + MessageBoxA(NULL, SUCCESSFULLY_UNINSTALLED_MSG, INFORMATION_TITLE, MB_OK | MB_ICONINFORMATION); + RegCloseKey(hReg); + return; + } + } + + MessageBoxA(NULL, CANNOT_UNINSTALL_NOT_FOUND_ERR, ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + RegCloseKey(hReg); +} + +void constructSystemDirName(char *pathName) +{ + char sysRoot[MAX_PATH + 1]; + GetEnvironmentVariableA(SYSTEM_ROOT_ENV_NAME, sysRoot, MAX_PATH); + strncpy(pathName, sysRoot, MAX_PATH + 1); + strncat(pathName, PATH_SEPARATOR, MAX_PATH - strlen(pathName)); + strncat(pathName, SYSTEM_DIR_NAME, MAX_PATH - strlen(pathName)); + strncat(pathName, PATH_SEPARATOR, MAX_PATH - strlen(pathName)); +} + +void constructDriverPathName(char *pathName, const char*fileName) +{ + constructSystemDirName(pathName); + strncat(pathName, fileName, MAX_PATH - strlen(pathName)); +} + +void deleteFileReliably(char *pathName, const char *fileName) +{ + const size_t nameSize = strlen(fileName) + 1; + char tmpFilePrefix[nameSize + 1]; + char tmpDirName[MAX_PATH + 1]; + char tmpPathName[MAX_PATH + 1]; + + if(DeleteFileA(pathName)) + return; + // File doesn't exist, nothing to do + if(ERROR_FILE_NOT_FOUND == GetLastError()) + return; + + // File can't be deleted, rename it and register pending deletion + strncpy(tmpFilePrefix, fileName, nameSize); + strncat(tmpFilePrefix, ".", nameSize); + constructSystemDirName(tmpDirName); + GetTempFileNameA(tmpDirName, tmpFilePrefix, 0, tmpPathName); + DeleteFileA(tmpPathName); + MoveFileA(pathName, tmpPathName); + MoveFileExA(tmpPathName, NULL, MOVEFILE_DELAY_UNTIL_REBOOT); +} + +BOOL copyFileIntoSystem(const char *fileName, char **argv) +{ + char driverPathName[MAX_PATH + 1]; + char setupPathName[MAX_PATH + 1]; + int setupPathLen; + + setupPathLen = strrchr(argv[0], '\\') - argv[0]; + if(setupPathLen > (int)(MAX_PATH - strlen(fileName) + 1 - 2)) + { + MessageBoxA(NULL, CANNOT_INSTALL_PATH_TOO_LONG_ERR, ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + return 2; + } + + constructDriverPathName(driverPathName, fileName); + deleteFileReliably(driverPathName, fileName); + + strncpy(setupPathName, argv[0], setupPathLen); + setupPathName[setupPathLen] = 0; + strncat(setupPathName, PATH_SEPARATOR, MAX_PATH - strlen(setupPathName)); + strncat(setupPathName, fileName, MAX_PATH - strlen(setupPathName)); + + if(!CopyFileA(setupPathName, driverPathName, FALSE)) + { + MessageBoxA(NULL, CANNOT_INSTALL_FILE_COPY_ERR, FILE_ERROR_TITLE, MB_OK | MB_ICONEXCLAMATION); + return FALSE; + } + return TRUE; +} + +int main(int argc, char *argv[]) +{ + char pathName[MAX_PATH + 1]; + BOOL installMode; + + if(argc != 2 || (_stricmp(INSTALL_COMMAND, argv[1]) != 0 && _stricmp(UNINSTALL_COMMAND, argv[1]) != 0)) + { + MessageBoxA(NULL, USAGE_MSG, INFORMATION_TITLE, MB_OK | MB_ICONINFORMATION); + return 1; + } + + if(_stricmp(UNINSTALL_COMMAND, argv[1]) == 0) + { + constructDriverPathName(pathName, OPL3EMU_DRIVER_NAME); + deleteFileReliably(pathName, OPL3EMU_DRIVER_NAME); + constructDriverPathName(pathName, OPL3EMU_CPLAPPLET_NAME); + deleteFileReliably(pathName, OPL3EMU_CPLAPPLET_NAME); + constructDriverPathName(pathName, OPL3EMU_SETUPTOOL_NAME); + deleteFileReliably(pathName, OPL3EMU_SETUPTOOL_NAME); + + unregisterDriver(); + return 0; + } + + installMode = TRUE; + if(!registerDriver(&installMode)) + return 3; + + if(!copyFileIntoSystem(OPL3EMU_DRIVER_NAME, argv)) + return 4; + if(!copyFileIntoSystem(OPL3EMU_CPLAPPLET_NAME, argv)) + return 4; + if(!copyFileIntoSystem(OPL3EMU_SETUPTOOL_NAME, argv)) + return 4; + + MessageBoxA(NULL, installMode ? SUCCESSFULLY_INSTALLED_MSG : SUCCESSFULLY_UPDATED_MSG, INFORMATION_TITLE, MB_OK | MB_ICONINFORMATION); + return 0; +} diff --git a/utils/winmm_drv/installer/drvinst.exe.manifest b/utils/winmm_drv/installer/drvinst.exe.manifest new file mode 100644 index 0000000..5aba825 --- /dev/null +++ b/utils/winmm_drv/installer/drvinst.exe.manifest @@ -0,0 +1,25 @@ + + + libADLMIDI synth Driver Installer + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/utils/winmm_drv/installer/drvinst.rc b/utils/winmm_drv/installer/drvinst.rc new file mode 100644 index 0000000..ae8ce72 --- /dev/null +++ b/utils/winmm_drv/installer/drvinst.rc @@ -0,0 +1,6 @@ +#include "winuser.h" + +#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 +#define RT_MANIFEST 24 + +CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "drvinst.exe.manifest" diff --git a/utils/winmm_drv/src/MidiSynth.cpp b/utils/winmm_drv/src/MidiSynth.cpp new file mode 100644 index 0000000..29cbb78 --- /dev/null +++ b/utils/winmm_drv/src/MidiSynth.cpp @@ -0,0 +1,720 @@ +/* Copyright (C) 2011, 2012 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "stdafx.h" + +namespace OPL3Emu +{ + +#define DRIVER_MODE + +static MidiSynth &midiSynth = MidiSynth::getInstance(); + +static class MidiStream +{ +private: + static const unsigned int maxPos = 1024; + unsigned int startpos; + unsigned int endpos; + DWORD stream[maxPos][2]; + +public: + MidiStream() + { + startpos = 0; + endpos = 0; + } + + DWORD PutMessage(DWORD msg, DWORD timestamp) + { + unsigned int newEndpos = endpos; + + newEndpos++; + if(newEndpos == maxPos) // check for buffer rolloff + newEndpos = 0; + if(startpos == newEndpos) // check for buffer full + return -1; + stream[endpos][0] = msg; // ok to put data and update endpos + stream[endpos][1] = timestamp; + endpos = newEndpos; + return 0; + } + + DWORD GetMidiMessage() + { + if(startpos == endpos) // check for buffer empty + return -1; + DWORD msg = stream[startpos][0]; + startpos++; + if(startpos == maxPos) // check for buffer rolloff + startpos = 0; + return msg; + } + + DWORD PeekMessageTime() + { + if(startpos == endpos) // check for buffer empty + return (DWORD) -1; + return stream[startpos][1]; + } + + DWORD PeekMessageTimeAt(unsigned int pos) + { + if(startpos == endpos) // check for buffer empty + return -1; + unsigned int peekPos = (startpos + pos) % maxPos; + return stream[peekPos][1]; + } + + void Clean() + { + startpos = 0; + endpos = 0; + memset(stream, 0, sizeof(stream)); + } + +} midiStream; + +static class SynthEventWin32 +{ +private: + HANDLE hEvent; + +public: + int Init() + { + hEvent = CreateEvent(NULL, false, true, NULL); + if(hEvent == NULL) + { + MessageBoxW(NULL, L"Can't create sync object", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 1; + } + return 0; + } + + void Close() + { + CloseHandle(hEvent); + } + + void Wait() + { + WaitForSingleObject(hEvent, INFINITE); + } + + void Release() + { + SetEvent(hEvent); + } +} synthEvent; + +static class WaveOutWin32 +{ +private: + HWAVEOUT hWaveOut; + WAVEHDR *WaveHdr; + HANDLE hEvent; + DWORD chunks; + DWORD prevPlayPos; + DWORD getPosWraps; + bool stopProcessing; + +public: + int Init(Bit16s *buffer, unsigned int bufferSize, unsigned int chunkSize, bool useRingBuffer, unsigned int sampleRate) + { + DWORD callbackType = CALLBACK_NULL; + DWORD_PTR callback = (DWORD_PTR)NULL; + hEvent = NULL; + if(!useRingBuffer) + { + hEvent = CreateEvent(NULL, false, true, NULL); + callback = (DWORD_PTR)hEvent; + callbackType = CALLBACK_EVENT; + } + + PCMWAVEFORMAT wFormat = {WAVE_FORMAT_PCM, 2, sampleRate, sampleRate * 4, 4, 16}; + + // Open waveout device + int wResult = waveOutOpen(&hWaveOut, WAVE_MAPPER, (LPWAVEFORMATEX)&wFormat, callback, (DWORD_PTR)&midiSynth, callbackType); + if(wResult != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to open waveform output device", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 2; + } + + // Prepare headers + chunks = useRingBuffer ? 1 : bufferSize / chunkSize; + WaveHdr = new WAVEHDR[chunks]; + LPSTR chunkStart = (LPSTR)buffer; + DWORD chunkBytes = 4 * chunkSize; + for(UINT i = 0; i < chunks; i++) + { + if(useRingBuffer) + { + WaveHdr[i].dwBufferLength = 4 * bufferSize; + WaveHdr[i].lpData = chunkStart; + WaveHdr[i].dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; + WaveHdr[i].dwLoops = -1L; + } + else + { + WaveHdr[i].dwBufferLength = chunkBytes; + WaveHdr[i].lpData = chunkStart; + WaveHdr[i].dwFlags = 0L; + WaveHdr[i].dwLoops = 0L; + chunkStart += chunkBytes; + } + wResult = waveOutPrepareHeader(hWaveOut, &WaveHdr[i], sizeof(WAVEHDR)); + if(wResult != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to Prepare Header", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 3; + } + } + stopProcessing = false; + return 0; + } + + int Close() + { + stopProcessing = true; + SetEvent(hEvent); + int wResult = waveOutReset(hWaveOut); + if(wResult != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to Reset WaveOut", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 8; + } + + for(UINT i = 0; i < chunks; i++) + { + wResult = waveOutUnprepareHeader(hWaveOut, &WaveHdr[i], sizeof(WAVEHDR)); + if(wResult != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to Unprepare Wave Header", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 8; + } + } + delete[] WaveHdr; + WaveHdr = NULL; + + wResult = waveOutClose(hWaveOut); + if(wResult != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to Close WaveOut", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 8; + } + if(hEvent != NULL) + { + CloseHandle(hEvent); + hEvent = NULL; + } + return 0; + } + + int Start() + { + getPosWraps = 0; + prevPlayPos = 0; + for(UINT i = 0; i < chunks; i++) + { + if(waveOutWrite(hWaveOut, &WaveHdr[i], sizeof(WAVEHDR)) != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to write block to device", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 4; + } + } + _beginthread(RenderingThread, 16384, this); + return 0; + } + + int Pause() + { + if(waveOutPause(hWaveOut) != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to Pause wave playback", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 9; + } + return 0; + } + + int Resume() + { + if(waveOutRestart(hWaveOut) != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to Resume wave playback", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 9; + } + return 0; + } + + UINT64 GetPos() + { + MMTIME mmTime; + mmTime.wType = TIME_SAMPLES; + + if(waveOutGetPosition(hWaveOut, &mmTime, sizeof(MMTIME)) != MMSYSERR_NOERROR) + { + MessageBoxW(NULL, L"Failed to get current playback position", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 10; + } + + if(mmTime.wType != TIME_SAMPLES) + { + MessageBoxW(NULL, L"Failed to get # of samples played", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 10; + } + + // Deal with waveOutGetPosition() wraparound. For 16-bit stereo output, it equals 2^27, + // presumably caused by the internal 32-bit counter of bits played. + // The output of that nasty waveOutGetPosition() isn't monotonically increasing + // even during 2^27 samples playback, so we have to ensure the difference is big enough... + int delta = mmTime.u.sample - prevPlayPos; + if(delta < -(1 << 26)) + { + std::cout << "OPL3: GetPos() wrap: " << delta << "\n"; + ++getPosWraps; + } + prevPlayPos = mmTime.u.sample; + return mmTime.u.sample + getPosWraps * (1 << 27); + } + + static void RenderingThread(void *); +} s_waveOut; + +void WaveOutWin32::RenderingThread(void *) +{ + if(s_waveOut.chunks == 1) + { + // Rendering using single looped ring buffer + while(!s_waveOut.stopProcessing) + midiSynth.RenderAvailableSpace(); + } + else + { + while(!s_waveOut.stopProcessing) + { + bool allBuffersRendered = true; + for(UINT i = 0; i < s_waveOut.chunks; i++) + { + if(s_waveOut.WaveHdr[i].dwFlags & WHDR_DONE) + { + allBuffersRendered = false; + midiSynth.Render((Bit16s *)s_waveOut.WaveHdr[i].lpData, s_waveOut.WaveHdr[i].dwBufferLength / 4); + if(waveOutWrite(s_waveOut.hWaveOut, &s_waveOut.WaveHdr[i], sizeof(WAVEHDR)) != MMSYSERR_NOERROR) + MessageBoxW(NULL, L"Failed to write block to device", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + midiSynth.CheckForSignals(); + } + } + if(allBuffersRendered) + WaitForSingleObject(s_waveOut.hEvent, INFINITE); + } + } +} + + +MidiSynth::MidiSynth() : + synth(NULL) +{ + m_setupInit = false; + setupDefault(&m_setup); + loadSetup(); + ::openSignalListener(); +} + +MidiSynth::~MidiSynth() +{ + if(synth) + adl_close(synth); + synth = NULL; + ::closeSignalListener(); +} + +MidiSynth &MidiSynth::getInstance() +{ + static MidiSynth *instance = new MidiSynth; + return *instance; +} + +// Renders all the available space in the single looped ring buffer +void MidiSynth::RenderAvailableSpace() +{ + DWORD playPos = s_waveOut.GetPos() % bufferSize; + DWORD framesToRender; + + if(playPos < framesRendered) + { + // Buffer wrap, render 'till the end of the buffer + framesToRender = bufferSize - framesRendered; + } + else + { + framesToRender = playPos - framesRendered; + if(framesToRender < chunkSize) + { + Sleep(1 + (chunkSize - framesToRender) * 1000 / sampleRate); + return; + } + } + midiSynth.Render(buffer + 2 * framesRendered, framesToRender); +} + +// Renders totalFrames frames starting from bufpos +// The number of frames rendered is added to the global counter framesRendered +void MidiSynth::Render(Bit16s *bufpos, DWORD totalFrames) +{ + while(totalFrames > 0) + { + DWORD timeStamp; + // Incoming MIDI messages timestamped with the current audio playback position + midiLatency + while((timeStamp = midiStream.PeekMessageTime()) == framesRendered) + { + DWORD msg = midiStream.GetMidiMessage(); + + synthEvent.Wait(); + + Bit8u event = msg & 0xFF; + Bit8u channel = msg & 0x0F; + Bit8u p1 = (msg >> 8) & 0x7f; + Bit8u p2 = (msg >> 16) & 0x7f; + + event &= 0xF0; + + if(event == 0xF0) + { + switch (channel) + { + case 0xF: + adl_reset(synth); + break; + } + } + + switch(event & 0xF0) + { + case 0x80: + adl_rt_noteOff(synth, channel, p1); + break; + case 0x90: + adl_rt_noteOn(synth, channel, p1, p2); + break; + case 0xA0: + adl_rt_noteAfterTouch(synth, channel, p1, p2); + break; + case 0xB0: + adl_rt_controllerChange(synth, channel, p1, p2); + break; + case 0xC0: + adl_rt_patchChange(synth, channel, p1); + break; + case 0xD0: + adl_rt_channelAfterTouch(synth, channel, p1); + break; + case 0xE0: + adl_rt_pitchBendML(synth, channel, p2, p1); + break; + } + + synthEvent.Release(); + } + + // Find out how many frames to render. The value of timeStamp == -1 indicates the MIDI buffer is empty + DWORD framesToRender = timeStamp - framesRendered; + if(framesToRender > totalFrames) + { + // MIDI message is too far - render the rest of frames + framesToRender = totalFrames; + } + + synthEvent.Wait(); + adl_generate(synth, framesToRender * 2, bufpos); + synthEvent.Release(); + framesRendered += framesToRender; + bufpos += 2 * framesToRender; // each frame consists of two samples for both the Left and Right channels + totalFrames -= framesToRender; + } + + // Wrap framesRendered counter + if(framesRendered >= bufferSize) + framesRendered -= bufferSize; +} + +void MidiSynth::CheckForSignals() +{ + int cmd = ::hasReloadSetupSignal(); + + if(cmd == 0) + return; + + switch(cmd) + { + case 1: // Reload settings on the fly + this->loadSetup(); + LoadSynthSetup(); + break; + + case 2: + adl_reset(synth); + break; + + default: + break; + } + + if(cmd > 0) + ::resetSignal(); +} + +unsigned int MidiSynth::MillisToFrames(unsigned int millis) +{ + return UINT(sampleRate * millis / 1000.f); +} + +void MidiSynth::LoadSettings() +{ + sampleRate = 49716; + bufferSize = MillisToFrames(100); + chunkSize = MillisToFrames(10); + midiLatency = MillisToFrames(0); + useRingBuffer = false; + if(!useRingBuffer) + { + // Number of chunks should be ceil(bufferSize / chunkSize) + DWORD chunks = (bufferSize + chunkSize - 1) / chunkSize; + // Refine bufferSize as chunkSize * number of chunks, no less then the specified value + bufferSize = chunks * chunkSize; + } +} + +int MidiSynth::Init() +{ + LoadSettings(); + buffer = new Bit16s[2 * bufferSize]; // each frame consists of two samples for both the Left and Right channels + + // Init synth + if(synthEvent.Init()) + return 1; + + synth = adl_init(49716); + if(!synth) + { + MessageBoxW(NULL, L"Can't open Synth", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 1; + } + + m_setupInit = false; + LoadSynthSetup(); + + UINT wResult = s_waveOut.Init(buffer, bufferSize, chunkSize, useRingBuffer, sampleRate); + if(wResult) return wResult; + + // Start playing stream + adl_generate(synth, bufferSize * 2, buffer); + framesRendered = 0; + + wResult = s_waveOut.Start(); + return wResult; +} + +int MidiSynth::Reset() +{ +#ifdef DRIVER_MODE + return 0; +#endif + + UINT wResult = s_waveOut.Pause(); + if(wResult) return wResult; + + synthEvent.Wait(); + + if(synth) + adl_close(synth); + + synth = adl_init(49716); + if(!synth) + { + MessageBoxW(NULL, L"Can't open Synth", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + return 1; + } + + m_setupInit = false; + LoadSynthSetup(); + + synthEvent.Release(); + + wResult = s_waveOut.Resume(); + return wResult; +} + +void MidiSynth::ResetSynth() +{ + synthEvent.Wait(); + adl_reset(synth); + midiStream.Clean(); + synthEvent.Release(); +} + +void MidiSynth::PanicSynth() +{ + synthEvent.Wait(); + adl_panic(synth); + synthEvent.Release(); +} + +void MidiSynth::PushMIDI(DWORD msg) +{ + midiStream.PutMessage(msg, (s_waveOut.GetPos() + midiLatency) % bufferSize); +} + +void MidiSynth::PlaySysex(Bit8u *bufpos, DWORD len) +{ + synthEvent.Wait(); + adl_rt_systemExclusive(synth, bufpos, len); + synthEvent.Release(); +} + +void MidiSynth::loadSetup() +{ + ::loadSetup(&m_setup); +} + +void MidiSynth::LoadSynthSetup() +{ + if(!m_setupInit || m_setupCurrent.emulatorId != m_setup.emulatorId) + { + adl_switchEmulator(synth, m_setup.emulatorId); + m_setupCurrent.emulatorId = m_setup.emulatorId; + } + + if(!m_setupInit || m_setupCurrent.numChips != m_setup.numChips) + { + adl_setNumChips(synth, m_setup.numChips); + m_setupCurrent.numChips = m_setup.numChips; + } + + if(!m_setupInit || m_setupCurrent.flagDeepTremolo != m_setup.flagDeepTremolo) + { + switch(m_setup.flagDeepTremolo) + { + case BST_INDETERMINATE: + adl_setHTremolo(synth, -1); + break; + case BST_CHECKED: + adl_setHTremolo(synth, 1); + break; + case BST_UNCHECKED: + adl_setHTremolo(synth, 0); + break; + } + m_setupCurrent.flagDeepTremolo = m_setup.flagDeepTremolo; + } + + if(!m_setupInit || m_setupCurrent.flagDeepVibrato != m_setup.flagDeepVibrato) + { + switch(m_setup.flagDeepVibrato) + { + case BST_INDETERMINATE: + adl_setHVibrato(synth, -1); + break; + case BST_CHECKED: + adl_setHVibrato(synth, 1); + break; + case BST_UNCHECKED: + adl_setHVibrato(synth, 0); + break; + } + m_setupCurrent.flagDeepVibrato = m_setup.flagDeepVibrato; + } + + if(!m_setupInit || m_setupCurrent.flagSoftPanning != m_setup.flagSoftPanning) + { + adl_setSoftPanEnabled(synth, m_setup.flagSoftPanning); + m_setupCurrent.flagSoftPanning = m_setup.flagSoftPanning; + } + + + if(!m_setupInit || m_setupCurrent.flagScaleModulators != m_setup.flagScaleModulators) + { + adl_setScaleModulators(synth, m_setup.flagScaleModulators); + m_setupCurrent.flagScaleModulators = m_setup.flagScaleModulators; + } + + if(!m_setupInit || m_setupCurrent.flagFullBrightness != m_setup.flagFullBrightness) + { + adl_setFullRangeBrightness(synth, m_setup.flagFullBrightness); + m_setupCurrent.flagFullBrightness = m_setup.flagFullBrightness; + } + + if(!m_setupInit || m_setupCurrent.volumeModel != m_setup.volumeModel) + { + adl_setVolumeRangeModel(synth, m_setup.volumeModel); + m_setupCurrent.volumeModel = m_setup.volumeModel; + } + + if(!m_setupInit || m_setupCurrent.numChips != m_setup.numChips) + { + adl_setNumChips(synth, m_setup.numChips); + m_setupCurrent.numChips = m_setup.numChips; + } + + if(!m_setupInit || m_setupCurrent.num4ops != m_setup.num4ops) + { + adl_setNumFourOpsChn(synth, m_setup.num4ops); + m_setupCurrent.num4ops = m_setup.num4ops; + } + + if(!m_setupInit || + m_setupCurrent.useExternalBank != m_setup.useExternalBank || + m_setupCurrent.bankId != m_setup.bankId || + wcscmp(m_setupCurrent.bankPath, m_setup.bankPath) != 0 + ) + { + if(m_setup.useExternalBank) + { + char pathUtf8[MAX_PATH * 4]; + ZeroMemory(pathUtf8, MAX_PATH * 4); + int len = WideCharToMultiByte(CP_UTF8, 0, m_setup.bankPath, wcslen(m_setup.bankPath), pathUtf8, MAX_PATH * 4, 0, 0); + pathUtf8[len] = '\0'; + adl_openBankFile(synth, pathUtf8); + } + else + adl_setBank(synth, m_setup.bankId); + + m_setupCurrent.useExternalBank = m_setup.useExternalBank; + m_setupCurrent.bankId = m_setup.bankId; + wcscpy(m_setupCurrent.bankPath, m_setup.bankPath); + } + + m_setupInit = true; +} + +void MidiSynth::Close() +{ + s_waveOut.Pause(); + s_waveOut.Close(); + synthEvent.Wait(); + //synth->close(); + + // Cleanup memory + if(synth) + adl_close(synth); + synth = NULL; + delete buffer; + + synthEvent.Close(); +} + +} diff --git a/utils/winmm_drv/src/MidiSynth.h b/utils/winmm_drv/src/MidiSynth.h new file mode 100644 index 0000000..bf2da02 --- /dev/null +++ b/utils/winmm_drv/src/MidiSynth.h @@ -0,0 +1,90 @@ +/* Copyright (C) 2011, 2012 Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include "stdafx.h" +#include "regconfig.h" + +#ifndef OPL3EMU_MIDISYNTH_H +#define OPL3EMU_MIDISYNTH_H + +typedef unsigned char Bit8u; +typedef signed char Bit8s; +typedef unsigned short Bit16u; +typedef signed short Bit16s; +typedef unsigned long Bit32u; +typedef signed long Bit32s; +typedef unsigned __int64 Bit64u; +typedef signed __int64 Bit64s; +typedef unsigned int Bitu; +typedef signed int Bits; + +namespace OPL3Emu +{ + +class MidiSynth +{ +private: + unsigned int sampleRate; + unsigned int midiLatency; + unsigned int bufferSize; + unsigned int chunkSize; + bool useRingBuffer; + bool resetEnabled; + float outputGain; + float reverbOutputGain; + bool reverbEnabled; + bool reverbOverridden; + Bit8u reverbMode; + Bit8u reverbTime; + Bit8u reverbLevel; + + Bit16s *buffer; + DWORD framesRendered; + + ADL_MIDIPlayer *synth; + + bool m_setupInit; + DriverSettings m_setup; + DriverSettings m_setupCurrent; + + unsigned int MillisToFrames(unsigned int millis); + void LoadSettings(); + + MidiSynth(); + ~MidiSynth(); + +public: + static MidiSynth &getInstance(); + int Init(); + void Close(); + int Reset(); + void ResetSynth(); + void PanicSynth(); + void RenderAvailableSpace(); + void Render(Bit16s *bufpos, DWORD totalFrames); + void CheckForSignals(); + void PushMIDI(DWORD msg); + void PlaySysex(Bit8u *bufpos, DWORD len); + + void loadSetup(); + + void LoadSynthSetup(); +}; + +} +#endif diff --git a/utils/winmm_drv/src/stdafx.h b/utils/winmm_drv/src/stdafx.h new file mode 100644 index 0000000..dd8b15c --- /dev/null +++ b/utils/winmm_drv/src/stdafx.h @@ -0,0 +1,83 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#include +#ifndef __MINGW32__ +#include +#endif +#include +#include +#include +#include +#include "MidiSynth.h" + +#ifdef __MINGW32__ +// Define missing in MinGW macros here + +#ifndef EXTERN_C +#ifdef __cplusplus + #define EXTERN_C extern "C" + #define EXTERN_C_START extern "C" { + #define EXTERN_C_END } +#else + #define EXTERN_C extern + #define EXTERN_C_START + #define EXTERN_C_END +#endif +#endif + +#ifndef STDAPICALLTYPE +#define STDAPICALLTYPE __stdcall +#endif + +#ifndef STDAPI_ +#define STDAPI_(type) EXTERN_C type STDAPICALLTYPE +#endif + +#define DRV_PNPINSTALL (DRV_RESERVED + 11) + +#ifndef MMNOMIDI + +typedef struct midiopenstrmid_tag +{ + DWORD dwStreamID; + UINT uDeviceID; +} MIDIOPENSTRMID; + +typedef struct midiopendesc_tag { + HMIDI hMidi; + DWORD_PTR dwCallback; + DWORD_PTR dwInstance; + DWORD_PTR dnDevNode; + DWORD cIds; + MIDIOPENSTRMID rgIds[1]; +} MIDIOPENDESC; + +typedef MIDIOPENDESC FAR *LPMIDIOPENDESC; + +#endif // MMNOMIDI + +#define MODM_GETNUMDEVS 1 +#define MODM_GETDEVCAPS 2 +#define MODM_OPEN 3 +#define MODM_CLOSE 4 +#define MODM_PREPARE 5 +#define MODM_UNPREPARE 6 +#define MODM_DATA 7 +#define MODM_LONGDATA 8 +#define MODM_RESET 9 +#define MODM_GETVOLUME 10 +#define MODM_SETVOLUME 11 +#define MODM_CACHEPATCHES 12 +#define MODM_CACHEDRUMPATCHES 13 + +#endif // __MINGW32__ diff --git a/utils/winmm_drv/src/targetver.h b/utils/winmm_drv/src/targetver.h new file mode 100644 index 0000000..658f76f --- /dev/null +++ b/utils/winmm_drv/src/targetver.h @@ -0,0 +1,24 @@ +#pragma once + +// The following macros define the minimum required platform. The minimum required platform +// is the earliest version of Windows, Internet Explorer etc. that has the necessary features to run +// your application. The macros work by enabling all features available on platform versions up to and +// including the version specified. + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Specifies that the minimum required platform is Windows NT4. +#define WINVER 0x0510 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows 2000. +#define _WIN32_WINNT 0x0510 // Change this to the appropriate value to target other versions of Windows. +#endif + +#ifndef _WIN32_WINDOWS // Specifies that the minimum required platform is Windows 98. +#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Specifies that the minimum required platform is Internet Explorer 5.0. +#define _WIN32_IE 0x0500 // Change this to the appropriate value to target other versions of IE. +#endif diff --git a/utils/winmm_drv/src/winmm_drv.cpp b/utils/winmm_drv/src/winmm_drv.cpp new file mode 100644 index 0000000..73a7d34 --- /dev/null +++ b/utils/winmm_drv/src/winmm_drv.cpp @@ -0,0 +1,386 @@ +/* Copyright (C) 2003, 2004, 2005 Dean Beeler, Jerome Fisher + * Copyright (C) 2011, 2012 Dean Beeler, Jerome Fisher, Sergey V. Mikayev + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 2.1 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +#include "stdafx.h" + +#define MAX_DRIVERS 8 +#define MAX_CLIENTS 8 // Per driver + +#ifdef __MINGW32__ + +#if !defined(MM_MPU401_MIDIOUT) && !defined(MM_MPU401_MIDIOUT) +typedef struct tagMIDIOUTCAPS2A { + WORD wMid; + WORD wPid; + MMVERSION vDriverVersion; + CHAR szPname[MAXPNAMELEN]; + WORD wTechnology; + WORD wVoices; + WORD wNotes; + WORD wChannelMask; + DWORD dwSupport; + GUID ManufacturerGuid; + GUID ProductGuid; + GUID NameGuid; +} MIDIOUTCAPS2A,*PMIDIOUTCAPS2A,*NPMIDIOUTCAPS2A,*LPMIDIOUTCAPS2A; + +typedef struct tagMIDIOUTCAPS2W { + WORD wMid; + WORD wPid; + MMVERSION vDriverVersion; + WCHAR szPname[MAXPNAMELEN]; + WORD wTechnology; + WORD wVoices; + WORD wNotes; + WORD wChannelMask; + DWORD dwSupport; + GUID ManufacturerGuid; + GUID ProductGuid; + GUID NameGuid; +} MIDIOUTCAPS2W,*PMIDIOUTCAPS2W,*NPMIDIOUTCAPS2W,*LPMIDIOUTCAPS2W; +#endif + +#ifndef MM_UNMAPPED +#define MM_UNMAPPED 0xffff +#endif +#ifndef MM_MPU401_MIDIOUT +#define MM_MPU401_MIDIOUT 10 +#endif + +//BOOL APIENTRY DriverCallback(DWORD_PTR dwCallback, +// DWORD dwFlags, +// HDRVR hDevice, +// DWORD dwMsg, +// DWORD_PTR dwUser, +// DWORD_PTR dwParam1, +// DWORD_PTR dwParam2); + +typedef BOOL (APIENTRY *DriverCallbackPtr)(DWORD_PTR dwCallback, + DWORD dwFlags, + HDRVR hDevice, + DWORD dwMsg, + DWORD_PTR dwUser, + DWORD_PTR dwParam1, + DWORD_PTR dwParam2); + +static HMODULE s_winmm_dll = NULL; +static DriverCallbackPtr s_DriverCallback = NULL; + +#define DriverCallback s_DriverCallback + +static void initWorkarounds() +{ + s_winmm_dll = LoadLibraryW(L"winmm.dll"); + if(s_winmm_dll) + { + s_DriverCallback = (DriverCallbackPtr)GetProcAddress(s_winmm_dll, "DriverCallback"); + if(!s_DriverCallback) + MessageBoxW(NULL, L"Failed to get a workaround for DriverCallback", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + } + else + { + MessageBoxW(NULL, L"Failed to open a library for a workaround for DriverCallback", L"libADLMIDI", MB_OK | MB_ICONEXCLAMATION); + } +} + +static void freeWorkarounds() +{ + if(s_winmm_dll) + FreeLibrary(s_winmm_dll); + s_winmm_dll = NULL; + s_DriverCallback = NULL; +} +#endif + +static OPL3Emu::MidiSynth &midiSynth = OPL3Emu::MidiSynth::getInstance(); +static bool synthOpened = false; +//static HWND hwnd = NULL; +static int driverCount; + +struct Driver +{ + bool open; + int clientCount; + HDRVR hdrvr; + struct Client + { + bool allocated; + DWORD_PTR instance; + DWORD flags; + DWORD_PTR callback; + DWORD synth_instance; + } clients[MAX_CLIENTS]; +} drivers[MAX_DRIVERS]; + +EXTERN_C LONG __declspec(dllexport) __stdcall DriverProc(DWORD dwDriverID, HDRVR hdrvr, UINT wMessage, LONG dwParam1, LONG dwParam2) +{ + (void)dwDriverID; (void)dwParam1; (void)dwParam2; + + switch(wMessage) + { + case DRV_LOAD: +#ifdef __MINGW32__ + initWorkarounds(); +#endif + memset(drivers, 0, sizeof(drivers)); + driverCount = 0; + return DRV_OK; + case DRV_ENABLE: + return DRV_OK; + case DRV_OPEN: + int driverNum; + if(driverCount == MAX_DRIVERS) + return 0; + else + { + for(driverNum = 0; driverNum < MAX_DRIVERS; driverNum++) + { + if(!drivers[driverNum].open) + break; + if(driverNum == MAX_DRIVERS) + return 0; + } + } + drivers[driverNum].open = true; + drivers[driverNum].clientCount = 0; + drivers[driverNum].hdrvr = hdrvr; + driverCount++; + return DRV_OK; + case DRV_INSTALL: + case DRV_PNPINSTALL: + return DRV_OK; + case DRV_QUERYCONFIGURE: + return 0; + case DRV_CONFIGURE: + return DRVCNF_OK; + case DRV_CLOSE: + for(int i = 0; i < MAX_DRIVERS; i++) + { + if(drivers[i].open && drivers[i].hdrvr == hdrvr) + { + drivers[i].open = false; + --driverCount; + return DRV_OK; + } + } + return DRV_CANCEL; + case DRV_DISABLE: + return DRV_OK; + case DRV_FREE: +#ifdef __MINGW32__ + freeWorkarounds(); +#endif + return DRV_OK; + case DRV_REMOVE: + return DRV_OK; + } + return DRV_OK; +} + + +EXTERN_C HRESULT modGetCaps(PVOID capsPtr, DWORD capsSize) +{ + MIDIOUTCAPSA *myCapsA; + MIDIOUTCAPSW *myCapsW; + MIDIOUTCAPS2A *myCaps2A; + MIDIOUTCAPS2W *myCaps2W; + + CHAR synthName[] = "libADLMIDI synth\0"; + WCHAR synthNameW[] = L"libADLMIDI synth\0"; + + switch(capsSize) + { + case(sizeof(MIDIOUTCAPSA)): + myCapsA = (MIDIOUTCAPSA *)capsPtr; + myCapsA->wMid = MM_UNMAPPED; + myCapsA->wPid = MM_MPU401_MIDIOUT; + memcpy(myCapsA->szPname, synthName, sizeof(synthName)); + myCapsA->wTechnology = MOD_MIDIPORT; + myCapsA->vDriverVersion = 0x0090; + myCapsA->wVoices = 0; + myCapsA->wNotes = 0; + myCapsA->wChannelMask = 0xffff; + myCapsA->dwSupport = 0; + return MMSYSERR_NOERROR; + + case(sizeof(MIDIOUTCAPSW)): + myCapsW = (MIDIOUTCAPSW *)capsPtr; + myCapsW->wMid = MM_UNMAPPED; + myCapsW->wPid = MM_MPU401_MIDIOUT; + memcpy(myCapsW->szPname, synthNameW, sizeof(synthNameW)); + myCapsW->wTechnology = MOD_MIDIPORT; + myCapsW->vDriverVersion = 0x0090; + myCapsW->wVoices = 0; + myCapsW->wNotes = 0; + myCapsW->wChannelMask = 0xffff; + myCapsW->dwSupport = 0; + return MMSYSERR_NOERROR; + + case(sizeof(MIDIOUTCAPS2A)): + myCaps2A = (MIDIOUTCAPS2A *)capsPtr; + myCaps2A->wMid = MM_UNMAPPED; + myCaps2A->wPid = MM_MPU401_MIDIOUT; + memcpy(myCaps2A->szPname, synthName, sizeof(synthName)); + myCaps2A->wTechnology = MOD_MIDIPORT; + myCaps2A->vDriverVersion = 0x0090; + myCaps2A->wVoices = 0; + myCaps2A->wNotes = 0; + myCaps2A->wChannelMask = 0xffff; + myCaps2A->dwSupport = 0; + return MMSYSERR_NOERROR; + + case(sizeof(MIDIOUTCAPS2W)): + myCaps2W = (MIDIOUTCAPS2W *)capsPtr; + myCaps2W->wMid = MM_UNMAPPED; + myCaps2W->wPid = MM_MPU401_MIDIOUT; + memcpy(myCaps2W->szPname, synthNameW, sizeof(synthNameW)); + myCaps2W->wTechnology = MOD_MIDIPORT; + myCaps2W->vDriverVersion = 0x0090; + myCaps2W->wVoices = 0; + myCaps2W->wNotes = 0; + myCaps2W->wChannelMask = 0xffff; + myCaps2W->dwSupport = 0; + return MMSYSERR_NOERROR; + + default: + return MMSYSERR_ERROR; + } +} + +void DoCallback(int driverNum, DWORD_PTR clientNum, DWORD msg, DWORD_PTR param1, DWORD_PTR param2) +{ + Driver::Client *client = &drivers[driverNum].clients[clientNum]; +#ifdef __MINGW32__ + if(s_DriverCallback) + initWorkarounds(); +#endif + DriverCallback(client->callback, client->flags, drivers[driverNum].hdrvr, msg, client->instance, param1, param2); +} + +LONG OpenDriver(Driver *driver, UINT uDeviceID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2) +{ + (void)uMsg; + + int clientNum; + if(driver->clientCount == 0) + clientNum = 0; + else if(driver->clientCount == MAX_CLIENTS) + return MMSYSERR_ALLOCATED; + else + { + int i; + for(i = 0; i < MAX_CLIENTS; i++) + { + if(!driver->clients[i].allocated) + break; + } + if(i == MAX_CLIENTS) + return MMSYSERR_ALLOCATED; + clientNum = i; + } + + MIDIOPENDESC *desc = (MIDIOPENDESC *)dwParam1; + driver->clients[clientNum].allocated = true; + driver->clients[clientNum].flags = HIWORD(dwParam2); + driver->clients[clientNum].callback = desc->dwCallback; + driver->clients[clientNum].instance = desc->dwInstance; + *(LONG *)dwUser = clientNum; + driver->clientCount++; + DoCallback(uDeviceID, clientNum, MOM_OPEN, (DWORD_PTR)NULL, (DWORD_PTR)NULL); + return MMSYSERR_NOERROR; +} + +LONG CloseDriver(Driver *driver, UINT uDeviceID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2) +{ + (void)uMsg; (void)dwParam1; (void)dwParam2; + + if(!driver->clients[dwUser].allocated) + return MMSYSERR_INVALPARAM; + driver->clients[dwUser].allocated = false; + driver->clientCount--; + DoCallback(uDeviceID, dwUser, MOM_CLOSE, (DWORD_PTR)NULL, (DWORD_PTR)NULL); + return MMSYSERR_NOERROR; +} + +EXTERN_C DWORD __declspec(dllexport) __stdcall modMessage(DWORD uDeviceID, DWORD uMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1, DWORD_PTR dwParam2) +{ + MIDIHDR *midiHdr; + Driver *driver = &drivers[uDeviceID]; + DWORD instance; + switch(uMsg) + { + case MODM_OPEN: + if(!synthOpened) + { + if(midiSynth.Init() != 0) return MMSYSERR_ERROR; + synthOpened = true; + } + instance = (DWORD)NULL; + DWORD res; + res = OpenDriver(driver, uDeviceID, uMsg, dwUser, dwParam1, dwParam2); + driver->clients[*(LONG *)dwUser].synth_instance = instance; + return res; + + case MODM_CLOSE: + if(driver->clients[dwUser].allocated == false) + return MMSYSERR_ERROR; + if(synthOpened) + { + midiSynth.Reset(); + midiSynth.ResetSynth(); + } + return CloseDriver(driver, uDeviceID, uMsg, dwUser, dwParam1, dwParam2); + + case MODM_PREPARE: + return MMSYSERR_NOTSUPPORTED; + + case MODM_UNPREPARE: + return MMSYSERR_NOTSUPPORTED; + + case MODM_RESET: + midiSynth.PanicSynth(); + return MMSYSERR_NOERROR; + + case MODM_GETDEVCAPS: + return modGetCaps((PVOID)dwParam1, (DWORD)dwParam2); + + case MODM_DATA: + if(driver->clients[dwUser].allocated == false) + return MMSYSERR_ERROR; + midiSynth.PushMIDI((DWORD)dwParam1); + return MMSYSERR_NOERROR; + + case MODM_LONGDATA: + if(driver->clients[dwUser].allocated == false) + return MMSYSERR_ERROR; + midiHdr = (MIDIHDR *)dwParam1; + if((midiHdr->dwFlags & MHDR_PREPARED) == 0) + return MIDIERR_UNPREPARED; + midiSynth.PlaySysex((unsigned char *)midiHdr->lpData, midiHdr->dwBufferLength); + midiHdr->dwFlags |= MHDR_DONE; + midiHdr->dwFlags &= ~MHDR_INQUEUE; + DoCallback(uDeviceID, dwUser, MOM_DONE, dwParam1, (DWORD_PTR)NULL); + return MMSYSERR_NOERROR; + + case MODM_GETNUMDEVS: + return 0x1; + + default: + return MMSYSERR_NOERROR; + break; + } +} diff --git a/utils/winmm_drv/src/winmm_drv.def b/utils/winmm_drv/src/winmm_drv.def new file mode 100644 index 0000000..8d105bc --- /dev/null +++ b/utils/winmm_drv/src/winmm_drv.def @@ -0,0 +1,6 @@ +LIBRARY adlmidisynth +EXPORTS + DriverProc + modMessage + adl_getBankNames + adl_getBanksCount diff --git a/utils/winmm_drv/test/test.c b/utils/winmm_drv/test/test.c new file mode 100644 index 0000000..f6fd2e9 --- /dev/null +++ b/utils/winmm_drv/test/test.c @@ -0,0 +1,105 @@ +#include +#include +#include + +typedef DWORD (WINAPI * MessagePtr)(UINT, UINT, DWORD, DWORD, DWORD); + +#ifndef MODM_GETDEVCAPS +#define MODM_GETDEVCAPS 2 +#endif + +LONG testDriver() +{ + HDRVR hdrvr; + DRVCONFIGINFO dci; + LONG lRes; + HMODULE lib; + DWORD modRet; + MIDIOUTCAPSA myCapsA; + MessagePtr modMessagePtr; + + printf("Open...\n"); + // Open the driver (no additional parameters needed this time). + if((hdrvr = OpenDriver(L"adlmididrv.dll", 0, 0)) == 0) + { + printf("!!! Can't open the driver\n"); + return -1; + } + + printf("Send DRV_QUERYCONFIGURE...\n"); + // Make sure driver has a configuration dialog box. + if(SendDriverMessage(hdrvr, DRV_QUERYCONFIGURE, 0, 0) != 0) + { + // Set the DRVCONFIGINFO structure and send the message + dci.dwDCISize = sizeof (dci); + dci.lpszDCISectionName = (LPWSTR)0; + dci.lpszDCIAliasName = (LPWSTR)0; + printf("Send DRV_CONFIGURE...\n"); + lRes = SendDriverMessage(hdrvr, DRV_CONFIGURE, 0, (LPARAM)&dci); + printf("<-- Got answer: %ld)\n", lRes); + } + else + { + printf("<-- No configure\n"); + lRes = DRVCNF_OK; + } + + + printf("Getting library pointer\n"); + if((lib = GetDriverModuleHandle(hdrvr))) + { + printf("Getting modMessage call\n"); + modMessagePtr = (MessagePtr)GetProcAddress(lib, "modMessage"); + if(!modMessagePtr) + { + CloseDriver(hdrvr, 0, 0); + printf("!!! modMessage not found!\n"); + return -1; + } + + printf("Getting capabilities...\n"); + modRet = modMessagePtr(0, MODM_GETDEVCAPS, (DWORD_PTR)NULL, (DWORD_PTR)&myCapsA, sizeof(myCapsA)); + if(modRet != MMSYSERR_NOERROR) + { + CloseDriver(hdrvr, 0, 0); + printf("!!! modMessage returned an error!\n"); + return -1; + } + + printf("<-- %s\n", myCapsA.szPname); + } + else + { + CloseDriver(hdrvr, 0, 0); + printf("!!! Error when getting module handler!\n"); + return -1; + } + + printf("Close...\n"); + // Close the driver (no additional parameters needed this time). + if(FAILED(CloseDriver(hdrvr, 0, 0))) + { + printf("!!! Error when closing\n"); + return -1; + } + + printf("Return...\n"); + + return 0; +} + +int main() +{ + LONG d = testDriver(); + + if(d == 0) + { + printf("TEST = OK\n"); + return 0; + } + else + { + printf("TEST = FAILED\n"); + return 1; + } +} -- cgit v1.2.3 From 88f4e811242e1abd2a1577dcc8486bba73edfc4f Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 00:44:48 +0300 Subject: WinMM-DRV: Don't write a blank path line into registry --- utils/winmm_drv/config/regconfig.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/winmm_drv/config/regconfig.c b/utils/winmm_drv/config/regconfig.c index 517bab8..275b930 100644 --- a/utils/winmm_drv/config/regconfig.c +++ b/utils/winmm_drv/config/regconfig.c @@ -123,7 +123,7 @@ void setupDefault(DriverSettings *setup) { setup->useExternalBank = 0; setup->bankId = 68; - ZeroMemory(setup->bankPath, sizeof(setup->bankPath)); + ZeroMemory(setup->bankPath, MAX_PATH * sizeof(WCHAR)); setup->emulatorId = 0; setup->flagDeepTremolo = BST_INDETERMINATE; @@ -192,8 +192,8 @@ void saveSetup(DriverSettings *setup) createRegistryKey(HKEY_CURRENT_USER, s_regPath); writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"useExternalBank", setup->useExternalBank); writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"bankId", setup->bankId); - writeStringToRegistry(HKEY_CURRENT_USER, s_regPath, L"bankPath", setup->bankPath); - + if(setup->bankPath[0] != L'\0') + writeStringToRegistry(HKEY_CURRENT_USER, s_regPath, L"bankPath", setup->bankPath); writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"emulatorId", setup->emulatorId); writeIntToRegistry(HKEY_CURRENT_USER, s_regPath, L"flagDeepTremolo", setup->flagDeepTremolo); -- cgit v1.2.3 From b5375a3917a6ce1863e70971a405ec449f8eb879 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 00:50:14 +0300 Subject: WinMM-DRV: Fixed a small typo in a "vibrato" word Thanks to @jpcima for a hint --- utils/winmm_drv/cpl/adlconfig.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/winmm_drv/cpl/adlconfig.rc b/utils/winmm_drv/cpl/adlconfig.rc index 75551fd..91d0cb7 100644 --- a/utils/winmm_drv/cpl/adlconfig.rc +++ b/utils/winmm_drv/cpl/adlconfig.rc @@ -54,7 +54,7 @@ BEGIN PUSHBUTTON "Restore defaults",IDC_RESTORE_DEFAULTS,153,193,88,14 CONTROL "Deep tremolo (Auto/Enable/Disable)",IDC_FLAG_TREMOLO, "Button",BS_AUTO3STATE | WS_TABSTOP,5,124,227,10 - CONTROL "Deep virbrato (Auto/Enable/Disable)",IDC_FLAG_VIBRATO, + CONTROL "Deep vibrato (Auto/Enable/Disable)",IDC_FLAG_VIBRATO, "Button",BS_AUTO3STATE | WS_TABSTOP,5,141,227,10 CONTROL "Full-panning stereo",IDC_FLAG_SOFTPAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,108,227,10 COMBOBOX IDC_EMULATOR,79,56,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP -- cgit v1.2.3 From 687cea0e53d4b5dcf2326b5c2a4483f5265251ff Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 01:36:34 +0300 Subject: WinMM-DRV: Organize resources and use ResEdit instead of VS --- utils/winmm_drv/CMakeLists.txt | 4 +- utils/winmm_drv/cpl/adlconfig-tool.exe.manifest | 36 ------ utils/winmm_drv/cpl/adlconfig.cpl.manifest | 36 ------ utils/winmm_drv/cpl/adlconfig.manifest | 36 ++++++ utils/winmm_drv/cpl/adlconfig.rc | 164 +++++++----------------- utils/winmm_drv/cpl/res-cpl.rc | 3 + utils/winmm_drv/cpl/res-tool.rc | 3 + utils/winmm_drv/cpl/resource.h | 80 +++++------- 8 files changed, 120 insertions(+), 242 deletions(-) delete mode 100644 utils/winmm_drv/cpl/adlconfig-tool.exe.manifest delete mode 100644 utils/winmm_drv/cpl/adlconfig.cpl.manifest create mode 100644 utils/winmm_drv/cpl/adlconfig.manifest create mode 100644 utils/winmm_drv/cpl/res-cpl.rc create mode 100644 utils/winmm_drv/cpl/res-tool.rc diff --git a/utils/winmm_drv/CMakeLists.txt b/utils/winmm_drv/CMakeLists.txt index e65f281..ad35aaa 100644 --- a/utils/winmm_drv/CMakeLists.txt +++ b/utils/winmm_drv/CMakeLists.txt @@ -87,7 +87,7 @@ set(ADLMIDI_DRIVER_SRC config/regconfig.c ) -add_library(adlmidiconfig MODULE ${ADLMIDI_DRIVER_SRC} cpl/adlconfig.c) +add_library(adlmidiconfig MODULE ${ADLMIDI_DRIVER_SRC} cpl/adlconfig.c cpl/res-cpl.rc) set_target_properties(adlmidiconfig PROPERTIES PREFIX "" OUTPUT_NAME "libadlconfig" SUFFIX ".cpl") target_include_directories(adlmidiconfig PRIVATE config) target_compile_definitions(adlmidiconfig PRIVATE @@ -101,7 +101,7 @@ target_compile_definitions(adlmidiconfig PRIVATE target_link_libraries(adlmidiconfig PRIVATE comctl32 gdi32 user32) -add_executable(adlmidiconfigtool ${ADLMIDI_DRIVER_SRC} cpl/adlconfig-tool.c) +add_executable(adlmidiconfigtool ${ADLMIDI_DRIVER_SRC} cpl/adlconfig-tool.c cpl/res-tool.rc) set_target_properties(adlmidiconfigtool PROPERTIES WIN32_EXECUTABLE ON) target_include_directories(adlmidiconfigtool PRIVATE config) target_compile_definitions(adlmidiconfigtool PRIVATE diff --git a/utils/winmm_drv/cpl/adlconfig-tool.exe.manifest b/utils/winmm_drv/cpl/adlconfig-tool.exe.manifest deleted file mode 100644 index 1016f98..0000000 --- a/utils/winmm_drv/cpl/adlconfig-tool.exe.manifest +++ /dev/null @@ -1,36 +0,0 @@ - - - - libADLMIDI synth Driver settings tool - - - - - - - - - - - - - - - - - - - - diff --git a/utils/winmm_drv/cpl/adlconfig.cpl.manifest b/utils/winmm_drv/cpl/adlconfig.cpl.manifest deleted file mode 100644 index 1016f98..0000000 --- a/utils/winmm_drv/cpl/adlconfig.cpl.manifest +++ /dev/null @@ -1,36 +0,0 @@ - - - - libADLMIDI synth Driver settings tool - - - - - - - - - - - - - - - - - - - - diff --git a/utils/winmm_drv/cpl/adlconfig.manifest b/utils/winmm_drv/cpl/adlconfig.manifest new file mode 100644 index 0000000..1016f98 --- /dev/null +++ b/utils/winmm_drv/cpl/adlconfig.manifest @@ -0,0 +1,36 @@ + + + + libADLMIDI synth Driver settings tool + + + + + + + + + + + + + + + + + + + + diff --git a/utils/winmm_drv/cpl/adlconfig.rc b/utils/winmm_drv/cpl/adlconfig.rc index 91d0cb7..584276e 100644 --- a/utils/winmm_drv/cpl/adlconfig.rc +++ b/utils/winmm_drv/cpl/adlconfig.rc @@ -1,142 +1,68 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" -///////////////////////////////////////////////////////////////////////////// -// Russian (Russia) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_RUS) -LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT -#pragma code_page(1251) - -///////////////////////////////////////////////////////////////////////////// -// -// RT_MANIFEST -// - -#ifdef ADL_IS_CPL_APPLET -MANIFSEST_RES_CPL RT_MANIFEST "adlconfig.cpl.manifest" -#else -MANIFSEST_RES RT_MANIFEST "adlconfig-tool.exe.manifest" -#endif +// Generated by ResEdit 1.6.6 +// Copyright (C) 2006-2015 +// http://www.resedit.net +#include +#include +#include +#include "resource.h" -///////////////////////////////////////////////////////////////////////////// -// -// Icon -// -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -IDI_ICON1 ICON "opl3icon.ico" -///////////////////////////////////////////////////////////////////////////// // -// Dialog +// Dialog resources // - -IDD_CONFIG_BOX DIALOGEX 0, 0, 243, 242 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +IDD_CONFIG_BOX DIALOGEX 0, 0, 251, 244 +STYLE DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_POPUP | WS_SYSMENU CAPTION "libADLMIDI settings" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,81,210,50,14 - PUSHBUTTON "Cancel",IDCANCEL,135,210,50,14 - PUSHBUTTON "Apply",IDC_APPLYBUTTON,191,210,50,14 - COMBOBOX IDC_VOLUMEMODEL,79,95,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Volume model:",IDC_VM_LABEL,5,97,66,8 - COMBOBOX IDC_BANK_ID,79,15,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Instruments bank",IDC_INS_BANK,4,2,234,51 - CONTROL "Internal bank",IDC_BANK_INTERNAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,9,16,63,10 - CONTROL "External bank",IDC_BANK_EXTERNAL,"Button",BS_AUTORADIOBUTTON,9,33,67,10 - EDITTEXT IDC_BANK_PATH,79,31,107,14,ES_AUTOHSCROLL | WS_DISABLED - PUSHBUTTON "Browse...",IDC_BROWSE_BANK,187,31,48,14 - PUSHBUTTON "Restore defaults",IDC_RESTORE_DEFAULTS,153,193,88,14 - CONTROL "Deep tremolo (Auto/Enable/Disable)",IDC_FLAG_TREMOLO, - "Button",BS_AUTO3STATE | WS_TABSTOP,5,124,227,10 - CONTROL "Deep vibrato (Auto/Enable/Disable)",IDC_FLAG_VIBRATO, - "Button",BS_AUTO3STATE | WS_TABSTOP,5,141,227,10 - CONTROL "Full-panning stereo",IDC_FLAG_SOFTPAN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,108,227,10 - COMBOBOX IDC_EMULATOR,79,56,155,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Chip emulator type:",IDC_CHIPEMU_LABEL,5,58,67,8 - LTEXT "Number of chips",IDC_CHIPNUM_LABEL,5,75,69,8 - COMBOBOX IDC_NUM_CHIPS,79,74,33,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_NUM_4OPVO,193,74,41,200,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Number of 4OP voices",IDC_4OPSNUM_LABEL,115,76,72,8 - CONTROL "Scalable modulation",IDC_FLAG_SCALE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,157,228,10 - CONTROL "Full-range brightness (CC74)",IDC_FLAG_FULLBRIGHT, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,5,173,228,10 - PUSHBUTTON "About...",IDC_ABOUT,5,210,50,14 - PUSHBUTTON "Reset synth now",IDC_RESET_SYNTH,69,193,80,14 - RTEXT "Settings will be applied immediately",IDC_BOTTOMNOTE_LABEL,0,227,241,8 -END - - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE +FONT 8, "MS Shell Dlg", 400, 0, 1 BEGIN - "resource.h\0" + GROUPBOX "Instruments bank", IDC_INS_BANK, 9, 4, 233, 51, 0, WS_EX_LEFT + AUTORADIOBUTTON "Internal bank", IDC_BANK_INTERNAL, 15, 17, 63, 8, WS_GROUP | WS_TABSTOP, WS_EX_LEFT + COMBOBOX IDC_BANK_ID, 83, 14, 155, 14, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + AUTORADIOBUTTON "External bank", IDC_BANK_EXTERNAL, 15, 33, 63, 8, WS_TABSTOP, WS_EX_LEFT + EDITTEXT IDC_BANK_PATH, 83, 31, 107, 14, WS_DISABLED | ES_AUTOHSCROLL, WS_EX_LEFT + PUSHBUTTON "Browse...", IDC_BROWSE_BANK, 194, 30, 45, 14, 0, WS_EX_LEFT + LTEXT "Chip emulator type:", IDC_CHIPEMU_LABEL, 11, 60, 67, 10, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_EMULATOR, 83, 58, 159, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + LTEXT "Number of chips", IDC_CHIPNUM_LABEL, 11, 78, 67, 8, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_NUM_CHIPS, 83, 76, 34, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + LTEXT "Number of 4OP voices", IDC_4OPSNUM_LABEL, 131, 78, 72, 8, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_NUM_4OPVO, 209, 76, 33, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + LTEXT "Volume model:", IDC_VM_LABEL, 11, 95, 67, 13, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_VOLUMEMODEL, 83, 95, 159, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + AUTOCHECKBOX "Full-panning stereo", IDC_FLAG_SOFTPAN, 11, 115, 227, 10, 0, WS_EX_LEFT + AUTO3STATE "Deep tremolo (Auto/Enable/Disable)", IDC_FLAG_TREMOLO, 11, 130, 227, 10, NOT WS_TABSTOP, WS_EX_LEFT + AUTO3STATE "Deep vibrato (Auto/Enable/Disable)", IDC_FLAG_VIBRATO, 11, 145, 227, 10, NOT WS_TABSTOP, WS_EX_LEFT + AUTOCHECKBOX "Scalable modulation", IDC_FLAG_SCALE, 11, 160, 227, 10, 0, WS_EX_LEFT + AUTOCHECKBOX "Full-range brightness (CC74)", IDC_FLAG_FULLBRIGHT, 11, 175, 227, 10, 0, WS_EX_LEFT + PUSHBUTTON "Reset synth now", IDC_RESET_SYNTH, 73, 195, 80, 14, 0, WS_EX_LEFT + PUSHBUTTON "Restore defaults", IDC_RESTORE_DEFAULTS, 155, 195, 88, 14, 0, WS_EX_LEFT + PUSHBUTTON "About...", IDC_ABOUT, 10, 212, 50, 14, 0, WS_EX_LEFT + DEFPUSHBUTTON "OK", IDOK, 88, 212, 50, 14, 0, WS_EX_LEFT + PUSHBUTTON "Cancel", IDCANCEL, 141, 212, 50, 14, 0, WS_EX_LEFT + PUSHBUTTON "Apply", IDC_APPLYBUTTON, 194, 212, 50, 14, 0, WS_EX_LEFT + RTEXT "Settings will be applied immediately", IDC_BOTTOMNOTE_LABEL, 7, 227, 235, 8, SS_RIGHT, WS_EX_LEFT END -2 TEXTINCLUDE -BEGIN - "\0" -END - -3 TEXTINCLUDE -BEGIN - "\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_SETUP_BOX, DIALOG - BEGIN - RIGHTMARGIN, 241 - BOTTOMMARGIN, 241 - END -END -#endif // APSTUDIO_INVOKED - -///////////////////////////////////////////////////////////////////////////// // -// String Table +// String Table resources // - +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US STRINGTABLE BEGIN - IDC_DRIVERNAME "libADLMIDI settings" - IDC_DRIVERDESC "Settings for libADLMIDI synthesizer" + IDC_DRIVERNAME "libADLMIDI settings" + IDC_DRIVERDESC "Settings for libADLMIDI synthesizer" END -#endif // Russian (Russia) resources -///////////////////////////////////////////////////////////////////////////// - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// // -// Generated from the TEXTINCLUDE 3 resource. +// Icon resources // - - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - +LANGUAGE LANG_NEUTRAL, SUBLANG_SYS_DEFAULT +IDI_ICON1 ICON "opl3icon.ico" diff --git a/utils/winmm_drv/cpl/res-cpl.rc b/utils/winmm_drv/cpl/res-cpl.rc new file mode 100644 index 0000000..c23b501 --- /dev/null +++ b/utils/winmm_drv/cpl/res-cpl.rc @@ -0,0 +1,3 @@ +#include + +123 RT_MANIFEST "adlconfig.manifest" diff --git a/utils/winmm_drv/cpl/res-tool.rc b/utils/winmm_drv/cpl/res-tool.rc new file mode 100644 index 0000000..22e6bfa --- /dev/null +++ b/utils/winmm_drv/cpl/res-tool.rc @@ -0,0 +1,3 @@ +#include + +1 RT_MANIFEST "adlconfig.manifest" diff --git a/utils/winmm_drv/cpl/resource.h b/utils/winmm_drv/cpl/resource.h index bd6b662..4d41e9f 100644 --- a/utils/winmm_drv/cpl/resource.h +++ b/utils/winmm_drv/cpl/resource.h @@ -1,50 +1,32 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by adlsetup.rc -// -#include - -#define MANIFSEST_RES 1 -#define MANIFSEST_RES_CPL 123 -#define IDD_CONFIG_BOX 101 -#define IDI_ICON1 102 -#define IDC_DRIVERNAME 103 -#define IDC_DRIVERDESC 104 - -#define IDC_APPLYBUTTON 1000 -#define IDC_VOLUMEMODEL 1001 -#define IDC_VM_LABEL 1002 -#define IDC_BANK_ID 1003 -#define IDC_INS_BANK 1004 -#define IDC_BANK_INTERNAL 1005 -#define IDC_BANK_EXTERNAL 1006 -#define IDC_BANK_PATH 1007 -#define IDC_BROWSE_BANK 1008 -#define IDC_RESTORE_DEFAULTS 1010 -#define IDC_FLAG_TREMOLO 1011 -#define IDC_FLAG_VIBRATO 1012 -#define IDC_FLAG_SOFTPAN 1013 -#define IDC_EMULATOR 1014 -#define IDC_NUM_CHIPS 1018 -#define IDC_NUM_4OPVO 1019 -#define IDC_FLAG_SCALE 1020 -#define IDC_FLAG_FULLBRIGHT 1021 -#define IDC_ABOUT 1022 -#define IDC_CHIPEMU_LABEL 1023 -#define IDC_CHIPNUM_LABEL 1024 -#define IDC_4OPSNUM_LABEL 1025 -#define IDC_RESET_SYNTH 1026 -#define IDC_BOTTOMNOTE_LABEL 1027 - - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NO_MFC 1 -#define _APS_NEXT_RESOURCE_VALUE 105 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1028 -#define _APS_NEXT_SYMED_VALUE 101 -#endif +#ifndef IDC_STATIC +#define IDC_STATIC (-1) #endif + +#define IDI_ICON1 104 +#define IDD_CONFIG_BOX 106 +#define IDC_APPLYBUTTON 1000 +#define IDC_VOLUMEMODEL 1001 +#define IDC_VM_LABEL 1002 +#define IDC_BANK_ID 1003 +#define IDC_INS_BANK 1004 +#define IDC_BANK_INTERNAL 1005 +#define IDC_BANK_EXTERNAL 1006 +#define IDC_BANK_PATH 1007 +#define IDC_BROWSE_BANK 1008 +#define IDC_RESTORE_DEFAULTS 1010 +#define IDC_FLAG_TREMOLO 1011 +#define IDC_FLAG_VIBRATO 1012 +#define IDC_FLAG_SOFTPAN 1013 +#define IDC_EMULATOR 1014 +#define IDC_NUM_CHIPS 1018 +#define IDC_NUM_4OPVO 1019 +#define IDC_FLAG_SCALE 1020 +#define IDC_FLAG_FULLBRIGHT 1021 +#define IDC_ABOUT 1022 +#define IDC_CHIPEMU_LABEL 1023 +#define IDC_CHIPNUM_LABEL 1024 +#define IDC_4OPSNUM_LABEL 1025 +#define IDC_RESET_SYNTH 1026 +#define IDC_BOTTOMNOTE_LABEL 1027 +#define IDC_DRIVERNAME 40000 +#define IDC_DRIVERDESC 40001 -- cgit v1.2.3 From f786bd7dff71f425d2a2c5be99f516f21e144d93 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 01:41:36 +0300 Subject: WinMM-DRV: Slightly change the wigth of 4ops combobox --- utils/winmm_drv/cpl/adlconfig.rc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/utils/winmm_drv/cpl/adlconfig.rc b/utils/winmm_drv/cpl/adlconfig.rc index 584276e..6cddd77 100644 --- a/utils/winmm_drv/cpl/adlconfig.rc +++ b/utils/winmm_drv/cpl/adlconfig.rc @@ -29,8 +29,8 @@ BEGIN COMBOBOX IDC_EMULATOR, 83, 58, 159, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT LTEXT "Number of chips", IDC_CHIPNUM_LABEL, 11, 78, 67, 8, SS_LEFT, WS_EX_LEFT COMBOBOX IDC_NUM_CHIPS, 83, 76, 34, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT - LTEXT "Number of 4OP voices", IDC_4OPSNUM_LABEL, 131, 78, 72, 8, SS_LEFT, WS_EX_LEFT - COMBOBOX IDC_NUM_4OPVO, 209, 76, 33, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + LTEXT "Number of 4OP voices", IDC_4OPSNUM_LABEL, 128, 78, 72, 8, SS_LEFT, WS_EX_LEFT + COMBOBOX IDC_NUM_4OPVO, 202, 76, 40, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT LTEXT "Volume model:", IDC_VM_LABEL, 11, 95, 67, 13, SS_LEFT, WS_EX_LEFT COMBOBOX IDC_VOLUMEMODEL, 83, 95, 159, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT AUTOCHECKBOX "Full-panning stereo", IDC_FLAG_SOFTPAN, 11, 115, 227, 10, 0, WS_EX_LEFT -- cgit v1.2.3 From 31f32ac688336e179ebad0ba24ee991804ac17d0 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 03:32:49 +0300 Subject: WinMM-Drv: A small fix of a menu height --- utils/winmm_drv/cpl/adlconfig.rc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/winmm_drv/cpl/adlconfig.rc b/utils/winmm_drv/cpl/adlconfig.rc index 6cddd77..455c906 100644 --- a/utils/winmm_drv/cpl/adlconfig.rc +++ b/utils/winmm_drv/cpl/adlconfig.rc @@ -21,7 +21,7 @@ FONT 8, "MS Shell Dlg", 400, 0, 1 BEGIN GROUPBOX "Instruments bank", IDC_INS_BANK, 9, 4, 233, 51, 0, WS_EX_LEFT AUTORADIOBUTTON "Internal bank", IDC_BANK_INTERNAL, 15, 17, 63, 8, WS_GROUP | WS_TABSTOP, WS_EX_LEFT - COMBOBOX IDC_BANK_ID, 83, 14, 155, 14, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT + COMBOBOX IDC_BANK_ID, 83, 14, 155, 200, WS_TABSTOP | WS_VSCROLL | CBS_DROPDOWNLIST, WS_EX_LEFT AUTORADIOBUTTON "External bank", IDC_BANK_EXTERNAL, 15, 33, 63, 8, WS_TABSTOP, WS_EX_LEFT EDITTEXT IDC_BANK_PATH, 83, 31, 107, 14, WS_DISABLED | ES_AUTOHSCROLL, WS_EX_LEFT PUSHBUTTON "Browse...", IDC_BROWSE_BANK, 194, 30, 45, 14, 0, WS_EX_LEFT -- cgit v1.2.3 From 08773b7ed7181e03392a766a7c1a8335d4ac44e6 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 03:33:23 +0300 Subject: WinMM-Drv: Better compatibility with older Windows Do link of a mingwex statically --- utils/winmm_drv/CMakeLists.txt | 22 +++++++++++++++++++++- utils/winmm_drv/installer/install.bat | 1 + utils/winmm_drv/installer/uninstall.bat | 1 + 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 utils/winmm_drv/installer/install.bat create mode 100644 utils/winmm_drv/installer/uninstall.bat diff --git a/utils/winmm_drv/CMakeLists.txt b/utils/winmm_drv/CMakeLists.txt index ad35aaa..ae76a0c 100644 --- a/utils/winmm_drv/CMakeLists.txt +++ b/utils/winmm_drv/CMakeLists.txt @@ -3,7 +3,10 @@ if(NOT WIN32) message(FATAL_ERROR "WinDriver: This component is for Windows Platform only") endif() -option(WITH_WINMMDRV_PTHREADS "Link libwinpthreads statically (when using pthread-based builds)" ON) +if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) + option(WITH_WINMMDRV_PTHREADS "Link libwinpthreads statically (when using pthread-based builds)" ON) + option(WITH_WINMMDRV_MINGWEX "Link libmingwex statically (when using vanilla MinGW builds)" OFF) +endif() #==================================== # Driver module @@ -32,6 +35,9 @@ if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) if(WITH_WINMMDRV_PTHREADS) set_property(TARGET adlmididrv APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lpthread -Wl,-Bdynamic,--no-whole-archive") endif() + if(WITH_WINMMDRV_MINGWEX) + set_property(TARGET adlmididrv APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lmingwex -Wl,-Bdynamic,--no-whole-archive") + endif() endif() if(NOT MSVC) @@ -64,8 +70,14 @@ target_compile_definitions(drvsetup PRIVATE if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) set_property(TARGET drvsetup APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc") + if(WITH_WINMMDRV_MINGWEX) + set_property(TARGET drvsetup APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lmingwex -Wl,-Bdynamic,--no-whole-archive") + endif() endif() +configure_file(installer/install.bat ${CMAKE_BINARY_DIR}/install.bat COPYONLY) +configure_file(installer/uninstall.bat ${CMAKE_BINARY_DIR}/uninstall.bat COPYONLY) + #==================================== # A unit test to verify the driver @@ -74,6 +86,9 @@ endif() add_executable(drvtest test/test.c) target_link_libraries(drvtest PRIVATE winmm) target_compile_options(drvtest PRIVATE "-Wno-cast-function-type") +if(WITH_WINMMDRV_MINGWEX) + set_property(TARGET drvtest APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lmingwex -Wl,-Bdynamic,--no-whole-archive") +endif() #==================================== @@ -101,6 +116,7 @@ target_compile_definitions(adlmidiconfig PRIVATE target_link_libraries(adlmidiconfig PRIVATE comctl32 gdi32 user32) + add_executable(adlmidiconfigtool ${ADLMIDI_DRIVER_SRC} cpl/adlconfig-tool.c cpl/res-tool.rc) set_target_properties(adlmidiconfigtool PROPERTIES WIN32_EXECUTABLE ON) target_include_directories(adlmidiconfigtool PRIVATE config) @@ -119,6 +135,10 @@ if(WIN32 AND CMAKE_COMPILER_IS_GNUCXX) target_compile_options(adlmidiconfigtool PRIVATE "-Wno-cast-function-type") set_property(TARGET adlmidiconfig APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc -Wl,--enable-stdcall-fixup") set_property(TARGET adlmidiconfigtool APPEND_STRING PROPERTY LINK_FLAGS " -static-libgcc -Wl,--enable-stdcall-fixup") + if(WITH_WINMMDRV_MINGWEX) + set_property(TARGET adlmidiconfig APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lmingwex -Wl,-Bdynamic,--no-whole-archive") + set_property(TARGET adlmidiconfigtool APPEND_STRING PROPERTY LINK_FLAGS " -Wl,-Bstatic,--whole-archive -lmingwex -Wl,-Bdynamic,--no-whole-archive") + endif() endif() diff --git a/utils/winmm_drv/installer/install.bat b/utils/winmm_drv/installer/install.bat new file mode 100644 index 0000000..3daf94d --- /dev/null +++ b/utils/winmm_drv/installer/install.bat @@ -0,0 +1 @@ +.\drvsetup install \ No newline at end of file diff --git a/utils/winmm_drv/installer/uninstall.bat b/utils/winmm_drv/installer/uninstall.bat new file mode 100644 index 0000000..537a8e8 --- /dev/null +++ b/utils/winmm_drv/installer/uninstall.bat @@ -0,0 +1 @@ +.\drvsetup uninstall \ No newline at end of file -- cgit v1.2.3 From 9dbd3f193d1b88a46fb86778506c45c29c4331bb Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 03:50:53 +0300 Subject: WinMM-Drv: Minor fix of the build for MSVC --- utils/winmm_drv/cpl/config_dialog.c | 4 ++-- utils/winmm_drv/installer/drvinst.c | 9 +++------ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/utils/winmm_drv/cpl/config_dialog.c b/utils/winmm_drv/cpl/config_dialog.c index 8489273..195524d 100644 --- a/utils/winmm_drv/cpl/config_dialog.c +++ b/utils/winmm_drv/cpl/config_dialog.c @@ -366,7 +366,7 @@ BOOL runAdlSetupBox(HINSTANCE hModule, HWND hwnd) return TRUE; } -WINBOOL initAdlSetupBox(HINSTANCE hModule, HWND hwnd) +BOOL initAdlSetupBox(HINSTANCE hModule, HWND hwnd) { InitCommonControls(); setupDefault(&g_setup); @@ -375,7 +375,7 @@ WINBOOL initAdlSetupBox(HINSTANCE hModule, HWND hwnd) return TRUE; } -WINBOOL cleanUpAdlSetupBox(HINSTANCE hModule, HWND hwnd) +BOOL cleanUpAdlSetupBox(HINSTANCE hModule, HWND hwnd) { UNREFERENCED_PARAMETER(hModule); UNREFERENCED_PARAMETER(hwnd); diff --git a/utils/winmm_drv/installer/drvinst.c b/utils/winmm_drv/installer/drvinst.c index e354691..cbba8f6 100644 --- a/utils/winmm_drv/installer/drvinst.c +++ b/utils/winmm_drv/installer/drvinst.c @@ -15,11 +15,8 @@ */ #define WIN32_LEAN_AND_MEAN -#include -#include -#include -#include -#include +#include + const char OPL3EMU_DRIVER_NAME[] = "adlmididrv.dll"; const char OPL3EMU_CPLAPPLET_NAME[] = "libadlconfig.cpl"; @@ -187,7 +184,7 @@ void constructDriverPathName(char *pathName, const char*fileName) void deleteFileReliably(char *pathName, const char *fileName) { const size_t nameSize = strlen(fileName) + 1; - char tmpFilePrefix[nameSize + 1]; + char tmpFilePrefix[MAX_PATH + 1]; char tmpDirName[MAX_PATH + 1]; char tmpPathName[MAX_PATH + 1]; -- cgit v1.2.3 From a0c5019dfeadc217181218d1c071e7924dbd136a Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 04:31:24 +0300 Subject: WinMM-Drv: A minor fix Don't call panic when synthesizer is not active --- utils/winmm_drv/src/winmm_drv.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/utils/winmm_drv/src/winmm_drv.cpp b/utils/winmm_drv/src/winmm_drv.cpp index 73a7d34..7f65dda 100644 --- a/utils/winmm_drv/src/winmm_drv.cpp +++ b/utils/winmm_drv/src/winmm_drv.cpp @@ -352,7 +352,8 @@ EXTERN_C DWORD __declspec(dllexport) __stdcall modMessage(DWORD uDeviceID, DWORD return MMSYSERR_NOTSUPPORTED; case MODM_RESET: - midiSynth.PanicSynth(); + if(synthOpened) + midiSynth.PanicSynth(); return MMSYSERR_NOERROR; case MODM_GETDEVCAPS: -- cgit v1.2.3 From 5236032cf266aa77ba63c1851f889e25376a864e Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 13:58:05 +0300 Subject: AppVeyor: Split build script by handy CMD files --- .appveyor.yml | 55 +++++++----- cmake/mingw-dlls.cmake | 40 +++++++++ cmake/win-ci/lib-sdk.cmd | 41 +++++++++ cmake/win-ci/vlc-plugin.cmd | 52 +++++++++++ cmake/win-ci/winmm-drivers.cmd | 195 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 362 insertions(+), 21 deletions(-) create mode 100644 cmake/mingw-dlls.cmake create mode 100644 cmake/win-ci/lib-sdk.cmd create mode 100644 cmake/win-ci/vlc-plugin.cmd create mode 100644 cmake/win-ci/winmm-drivers.cmd diff --git a/.appveyor.yml b/.appveyor.yml index 9eff4ba..cdaa0f5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -1,10 +1,12 @@ -version: 1.3.{build} +version: 1.4.{build} environment: global: PLATFORMTOOLSET: "v140" CMAKEPREFIXPATH: "." VLC_PLUGIN: OFF + WINMM_DRIVER: OFF + PACKAGE_TYPE: SDK BUILD_SHARED: ON BUILD_STATIC: ON BUILD_MIDIPLAY: ON @@ -14,6 +16,12 @@ environment: WGET_BIN: "C:\\msys64\\usr\\bin\\wget.exe" VLC_DIR: "vlc-3.0.4" matrix: + - BUILD_TYPE: MinSizeRel + COMPILER: MinGW + PACKAGE_TYPE: WINMMDRIVERS + COMPILER_FAMILY: MinGW + GENERATOR: "Ninja" + PLATFORM: WinAll - BUILD_TYPE: Release COMPILER: MinGW-w32 COMPILER_FAMILY: MinGW @@ -22,6 +30,7 @@ environment: CMAKEPREFIXPATH: "C:/mingw-w64/i686-6.3.0-posix-dwarf-rt_v5-rev1/mingw32" TOOLCHAIN_BIN: "C:\\mingw-w64\\i686-6.3.0-posix-dwarf-rt_v5-rev1\\mingw32\\bin" VLC_PLUGIN: ON + PACKAGE_TYPE: VLCPLUGIN BUILD_SHARED: OFF BUILD_MIDIPLAY: OFF VLC_TARBALL: ${VLC_TARBALL_x32} @@ -33,6 +42,7 @@ environment: CMAKEPREFIXPATH: "C:/mingw-w64/x86_64-6.3.0-posix-seh-rt_v5-rev1/mingw64" TOOLCHAIN_BIN: "C:\\mingw-w64\\x86_64-6.3.0-posix-seh-rt_v5-rev1\\mingw64\\bin" VLC_PLUGIN: ON + PACKAGE_TYPE: VLCPLUGIN BUILD_SHARED: OFF BUILD_MIDIPLAY: OFF VLC_TARBALL: ${VLC_TARBALL_x64} @@ -136,27 +146,30 @@ environment: PLATFORMTOOLSET: "v141_xp" build_script: - - if [%VLC_PLUGIN%]==[ON] md C:\vlc-temp - - if [%VLC_PLUGIN%]==[ON] "%WGET_BIN%" --quiet %VLC_TARBALL% -O C:\vlc-temp\vlcsdk.7z - - if [%VLC_PLUGIN%]==[ON] "%SEVENZIP%" x C:\vlc-temp\vlcsdk.7z -oC:\vlc-temp - - if [%VLC_PLUGIN%]==[ON] xcopy /S /E /Y "C:\vlc-temp\%VLC_DIR%\sdk\*" "%TOOLCHAIN_BIN%\.." - - md build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% - - cd build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% - - if NOT [%TOOLCHAIN_BIN%]==[] set PATH=%TOOLCHAIN_BIN%;%PATH:C:\Program Files\Git\usr\bin;=% - - cmake -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH% -DCMAKE_INSTALL_PREFIX=libADLMIDI -DWITH_OLD_UTILS=ON -DWITH_GENADLDATA=OFF -DlibADLMIDI_STATIC=%BUILD_STATIC% -DlibADLMIDI_SHARED=%BUILD_SHARED% -DWITH_MIDIPLAY=%BUILD_MIDIPLAY% -DWITH_VLC_PLUGIN=%VLC_PLUGIN% -DVLC_PLUGIN_NOINSTALL=ON .. - - if [%COMPILER_FAMILY%]==[MinGW] cmake --build . --config %BUILD_TYPE% -- -j 2 - - if [%COMPILER_FAMILY%]==[MinGW] mingw32-make install - - if [%COMPILER_FAMILY%]==[MSVC] cmake --build . --config %BUILD_TYPE% --target install - - if [%VLC_PLUGIN%]==[OFF] 7z a -t7z -mx9 "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" "libADLMIDI" - - if [%VLC_PLUGIN%]==[OFF] appveyor PushArtifact "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" -# - if [%VLC_PLUGIN%]==[OFF] move "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" .. - - if [%VLC_PLUGIN%]==[ON] 7z a -t7z -mx9 "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" "libadlmidi_plugin.dll" - - if [%VLC_PLUGIN%]==[ON] appveyor PushArtifact "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" -# - if [%VLC_PLUGIN%]==[ON] move "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" .. + - if [%PACKAGE_TYPE%]==[VLCPLUGIN] cmake\win-ci\vlc-plugin.cmd + - if [%PACKAGE_TYPE%]==[SDK] cmake\win-ci\lib-sdk.cmd + - if [%PACKAGE_TYPE%]==[WINMMDRIVERS] cmake\win-ci\winmm-drivers.cmd +# - if [%VLC_PLUGIN%]==[ON] md C:\vlc-temp +# - if [%VLC_PLUGIN%]==[ON] "%WGET_BIN%" --quiet %VLC_TARBALL% -O C:\vlc-temp\vlcsdk.7z +# - if [%VLC_PLUGIN%]==[ON] "%SEVENZIP%" x C:\vlc-temp\vlcsdk.7z -oC:\vlc-temp +# - if [%VLC_PLUGIN%]==[ON] xcopy /S /E /Y "C:\vlc-temp\%VLC_DIR%\sdk\*" "%TOOLCHAIN_BIN%\.." +# - md build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% +# - cd build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% +# - if NOT [%TOOLCHAIN_BIN%]==[] set PATH=%TOOLCHAIN_BIN%;%PATH:C:\Program Files\Git\usr\bin;=% +# - cmake -G "%GENERATOR%" -DCMAKE_BUILD_TYPE=%BUILD_TYPE% -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH% -DCMAKE_INSTALL_PREFIX=libADLMIDI -DWITH_OLD_UTILS=ON -DWITH_GENADLDATA=OFF -DlibADLMIDI_STATIC=%BUILD_STATIC% -DlibADLMIDI_SHARED=%BUILD_SHARED% -DWITH_MIDIPLAY=%BUILD_MIDIPLAY% -DWITH_VLC_PLUGIN=%VLC_PLUGIN% -DVLC_PLUGIN_NOINSTALL=ON .. +# - if [%COMPILER_FAMILY%]==[MinGW] cmake --build . --config %BUILD_TYPE% -- -j 2 +# - if [%COMPILER_FAMILY%]==[MinGW] mingw32-make install +# - if [%COMPILER_FAMILY%]==[MSVC] cmake --build . --config %BUILD_TYPE% --target install +# - if [%VLC_PLUGIN%]==[OFF] 7z a -t7z -mx9 "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" "libADLMIDI" +# - if [%VLC_PLUGIN%]==[OFF] appveyor PushArtifact "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" +## - if [%VLC_PLUGIN%]==[OFF] move "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" .. +# - if [%VLC_PLUGIN%]==[ON] 7z a -t7z -mx9 "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" "libadlmidi_plugin.dll" +# - if [%VLC_PLUGIN%]==[ON] appveyor PushArtifact "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" +## - if [%VLC_PLUGIN%]==[ON] move "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" .. -#artifacts: -# - path: 'libADLMIDI-$(COMPILER)-$(BUILD_TYPE)-$(PLATFORM).7z' -# - path: 'libADLMIDI-$(VLC_DIR)-codec-$(PLATFORM).7z' +##artifacts: +## - path: 'libADLMIDI-$(COMPILER)-$(BUILD_TYPE)-$(PLATFORM).7z' +## - path: 'libADLMIDI-$(VLC_DIR)-codec-$(PLATFORM).7z' deploy: - provider: Environment diff --git a/cmake/mingw-dlls.cmake b/cmake/mingw-dlls.cmake new file mode 100644 index 0000000..a720b33 --- /dev/null +++ b/cmake/mingw-dlls.cmake @@ -0,0 +1,40 @@ +function(find_mingw_dll _FieldName _FileName _DestList _SearchPaths) + find_file(MINGWDLL_${_FieldName} ${_FileName} PATHS "${_SearchPaths}") + if(MINGWDLL_${_FieldName}) + list(APPEND ${_DestList} "${MINGWDLL_${_FieldName}}") + set(${_DestList} ${${_DestList}} PARENT_SCOPE) + endif() +endfunction() + +set(MINGW_BIN_PATH $ENV{MinGW}) + +if(NOT MINGW_BIN_PATH) + set(MINGW_BIN_PATH "${QT_BINLIB_DIR}") +else() + string(REPLACE "\\" "/" MINGW_BIN_PATH $ENV{MinGW}) +endif() + +set(MINGW_DLLS) +find_mingw_dll(LIBGCCDW "libgcc_s_dw2-1.dll" MINGW_DLLS "${MINGW_BIN_PATH}") +find_mingw_dll(LIBGCCSJLJ "libgcc_s_sjlj-1.dll" MINGW_DLLS "${MINGW_BIN_PATH}") +find_mingw_dll(LIBGCCSEC "libgcc_s_seh-1.dll" MINGW_DLLS "${MINGW_BIN_PATH}") +find_mingw_dll(MINGWEX "libmingwex-0.dll" MINGW_DLLS "${MINGW_BIN_PATH}") +find_mingw_dll(WINPTHREAD "libwinpthread-1.dll" MINGW_DLLS "${MINGW_BIN_PATH}") +find_mingw_dll(WINPTHREADGC3 "pthreadGC-3.dll" MINGW_DLLS "${MINGW_BIN_PATH}") +find_mingw_dll(STDCPP "libstdc++-6.dll" MINGW_DLLS "${MINGW_BIN_PATH}") + +message("MinGW DLLs: [${MINGW_DLLS}]") + +install(FILES + ${MINGW_DLLS} + DESTINATION "${PGE_INSTALL_DIRECTORY}/" +) + +add_custom_target(copy_mingw_dlls DEPENDS pge_windeploy) +foreach(MingwRuntimeDll ${MINGW_DLLS}) + add_custom_command(TARGET copy_mingw_dlls POST_BUILD + COMMAND ${CMAKE_COMMAND} -E + copy ${MingwRuntimeDll} "${CMAKE_INSTALL_PREFIX_ORIG}/${PGE_INSTALL_DIRECTORY}" + ) +endforeach() + diff --git a/cmake/win-ci/lib-sdk.cmd b/cmake/win-ci/lib-sdk.cmd new file mode 100644 index 0000000..50e4da9 --- /dev/null +++ b/cmake/win-ci/lib-sdk.cmd @@ -0,0 +1,41 @@ +rem =============== BUILDING THE LIBRARY SDK AND THE DEMO =============== + +md build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% +cd build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% + +if NOT [%TOOLCHAIN_BIN%]==[] set PATH=%TOOLCHAIN_BIN%;%PATH:C:\Program Files\Git\usr\bin;=% + +cmake -G "%GENERATOR%"^ + -DCMAKE_BUILD_TYPE=%BUILD_TYPE%^ + -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH%^ + -DCMAKE_INSTALL_PREFIX=libADLMIDI^ + -DWITH_OLD_UTILS=ON ^ + -DWITH_GENADLDATA=OFF ^ + -DlibADLMIDI_STATIC=%BUILD_STATIC% ^ + -DlibADLMIDI_SHARED=%BUILD_SHARED% ^ + -DWITH_MIDIPLAY=%BUILD_MIDIPLAY% ^ + -DWITH_VLC_PLUGIN=%VLC_PLUGIN% ^ + -DVLC_PLUGIN_NOINSTALL=ON .. +if %errorlevel% neq 0 exit /b %errorlevel% + +if [%COMPILER_FAMILY%]==[MinGW] ( + cmake --build . --config %BUILD_TYPE% -- -j 2 + if %errorlevel% neq 0 exit /b %errorlevel% +) + +if [%COMPILER_FAMILY%]==[MinGW] ( + mingw32-make install + if %errorlevel% neq 0 exit /b %errorlevel% +) + +if [%COMPILER_FAMILY%]==[MSVC] ( + cmake --build . --config %BUILD_TYPE% --target install + if %errorlevel% neq 0 exit /b %errorlevel% +) + +7z a -t7z -mx9 "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" "libADLMIDI" +if %errorlevel% neq 0 exit /b %errorlevel% + +appveyor PushArtifact "libADLMIDI-%COMPILER%-%BUILD_TYPE%-%PLATFORM%.7z" +if %errorlevel% neq 0 exit /b %errorlevel% + diff --git a/cmake/win-ci/vlc-plugin.cmd b/cmake/win-ci/vlc-plugin.cmd new file mode 100644 index 0000000..7117980 --- /dev/null +++ b/cmake/win-ci/vlc-plugin.cmd @@ -0,0 +1,52 @@ +rem =============== BUILDING A VLC PLUGIN =============== + +md C:\vlc-temp + +"%WGET_BIN%" --quiet %VLC_TARBALL% -O C:\vlc-temp\vlcsdk.7z +if %errorlevel% neq 0 exit /b %errorlevel% + +"%SEVENZIP%" x C:\vlc-temp\vlcsdk.7z -oC:\vlc-temp +if %errorlevel% neq 0 exit /b %errorlevel% + +xcopy /S /E /Y "C:\vlc-temp\%VLC_DIR%\sdk\*" "%TOOLCHAIN_BIN%\.." +if %errorlevel% neq 0 exit /b %errorlevel% + +md build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% +cd build-%COMPILER%-%BUILD_TYPE%-%PLATFORM% + +if NOT [%TOOLCHAIN_BIN%]==[] set PATH=%TOOLCHAIN_BIN%;%PATH:C:\Program Files\Git\usr\bin;=% + +cmake -G "%GENERATOR%"^ + -DCMAKE_BUILD_TYPE=%BUILD_TYPE%^ + -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH%^ + -DCMAKE_INSTALL_PREFIX=libADLMIDI^ + -DWITH_OLD_UTILS=ON ^ + -DWITH_GENADLDATA=OFF ^ + -DlibADLMIDI_STATIC=%BUILD_STATIC% ^ + -DlibADLMIDI_SHARED=%BUILD_SHARED% ^ + -DWITH_MIDIPLAY=%BUILD_MIDIPLAY% ^ + -DWITH_VLC_PLUGIN=%VLC_PLUGIN% ^ + -DVLC_PLUGIN_NOINSTALL=ON .. +if %errorlevel% neq 0 exit /b %errorlevel% + +if [%COMPILER_FAMILY%]==[MinGW] ( + cmake --build . --config %BUILD_TYPE% -- -j 2 + if %errorlevel% neq 0 exit /b %errorlevel% +) + +if [%COMPILER_FAMILY%]==[MinGW] ( + mingw32-make install + if %errorlevel% neq 0 exit /b %errorlevel% +) + +if [%COMPILER_FAMILY%]==[MSVC] ( + cmake --build . --config %BUILD_TYPE% --target install + if %errorlevel% neq 0 exit /b %errorlevel% +) + +7z a -t7z -mx9 "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" "libadlmidi_plugin.dll" +if %errorlevel% neq 0 exit /b %errorlevel% + +appveyor PushArtifact "libADLMIDI-%VLC_DIR%-codec-%PLATFORM%.7z" +if %errorlevel% neq 0 exit /b %errorlevel% + diff --git a/cmake/win-ci/winmm-drivers.cmd b/cmake/win-ci/winmm-drivers.cmd new file mode 100644 index 0000000..c44f46c --- /dev/null +++ b/cmake/win-ci/winmm-drivers.cmd @@ -0,0 +1,195 @@ +rem =============== BUILDING THE WINMM DRIVERS, USING DIFFERENT MINGW TOOLCHAINS =============== + +set MINGW_VANILLA_URL=http://wohlsoft.ru/docs/Software/MinGW/MinGW-6-3-x86-dw2.zip +set MINGW_W64_32_URL=http://wohlsoft.ru/docs/Software/MinGW/i686-8.1.0-release-posix-dwarf-rt_v6-rev0.7z +set MINGW_W64_64_URL=http://wohlsoft.ru/docs/Software/MinGW/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z +set NINJA_URL=http://wohlsoft.ru/docs/Software/Ninja-Build/ninja-win.zip + +md C:\mingw-temp +md C:\mingw-temp\bin + +"%WGET_BIN%" --quiet %NINJA_URL% -O C:\mingw-temp\ninja.zip +if %errorlevel% neq 0 exit /b %errorlevel% +"%SEVENZIP%" x C:\mingw-temp\ninja.zip -oC:\mingw-temp\bin +if %errorlevel% neq 0 exit /b %errorlevel% + +md C:\mingw-temp\MinGW32 +md C:\mingw-temp\MinGW-w64 + +"%WGET_BIN%" --quiet %MINGW_VANILLA_URL% -O C:\mingw-temp\mingw-vanilla.zip +if %errorlevel% neq 0 exit /b %errorlevel% +"%SEVENZIP%" x C:\mingw-temp\mingw-vanilla.zip -oC:\mingw-temp\MinGW32 +if %errorlevel% neq 0 exit /b %errorlevel% + + +"%WGET_BIN%" --quiet %MINGW_W64_32_URL% -O C:\mingw-temp\mingw-w64-32.7z +if %errorlevel% neq 0 exit /b %errorlevel% +"%SEVENZIP%" x C:\mingw-temp\mingw-w64-32.7z -oC:\mingw-temp\MinGW-w64 +if %errorlevel% neq 0 exit /b %errorlevel% + +"%WGET_BIN%" --quiet %MINGW_W64_64_URL% -O C:\mingw-temp\mingw-w64-64.7z +if %errorlevel% neq 0 exit /b %errorlevel% +"%SEVENZIP%" x C:\mingw-temp\mingw-w64-64.7z -oC:\mingw-temp\MinGW-w64 +if %errorlevel% neq 0 exit /b %errorlevel% + +set PUREPATH=C:\mingw-temp\bin;%PATH:C:\Program Files\Git\usr\bin;=% + +set FILES_LIST=^ +"adlmidiconfigtool.exe" "adlmididrv.dll" "libadlconfig.cpl" ^ +"drvsetup.exe" "drvtest.exe" ^ +"install.bat" "uninstall.bat" + +rem ============= BUILD pre-WinXP 32-bit driver ============= + +md build-drv-prexp +cd build-drv-prexp + +set CMAKEPREFIXPATH=C:/mingw-temp/MinGW32 +set TOOLCHAIN_BIN=C:\mingw-temp\MinGW32\bin +set PATH=%TOOLCHAIN_BIN%;%PUREPATH% + +cmake -G "%GENERATOR%"^ + -DCMAKE_BUILD_TYPE=%BUILD_TYPE%^ + -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH%^ + -DCMAKE_INSTALL_PREFIX=libADLMIDI^ + -DWITH_OLD_UTILS=OFF ^ + -DWITH_GENADLDATA=OFF ^ + -DlibADLMIDI_STATIC=ON ^ + -DlibADLMIDI_SHARED=OFF ^ + -DWITH_MIDIPLAY=OFF ^ + -DWITH_VLC_PLUGIN=OFF ^ + -DWITH_WINMMDRV=ON ^ + -DWITH_WINMMDRV_PTHREADS=ON ^ + -DWITH_WINMMDRV_MINGWEX=ON ^ + .. +if %errorlevel% neq 0 exit /b %errorlevel% + +cmake --build . --config %BUILD_TYPE% -- -j 2 +if %errorlevel% neq 0 exit /b %errorlevel% + +cd .. + + +rem ============= BUILD WinXP+ 32-bit driver ============= + +md build-drv-32 +cd build-drv-32 + +set CMAKEPREFIXPATH=C:/mingw-temp/MinGW-w64/mingw32 +set TOOLCHAIN_BIN=C:\mingw-temp\MinGW-w64\mingw32\bin +set PATH=%TOOLCHAIN_BIN%;%PUREPATH% + +cmake -G "%GENERATOR%"^ + -DCMAKE_BUILD_TYPE=%BUILD_TYPE%^ + -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH%^ + -DCMAKE_INSTALL_PREFIX=libADLMIDI^ + -DWITH_OLD_UTILS=OFF ^ + -DWITH_GENADLDATA=OFF ^ + -DlibADLMIDI_STATIC=ON ^ + -DlibADLMIDI_SHARED=OFF ^ + -DWITH_MIDIPLAY=OFF ^ + -DWITH_VLC_PLUGIN=OFF ^ + -DWITH_WINMMDRV=ON ^ + -DWITH_WINMMDRV_PTHREADS=ON ^ + -DWITH_WINMMDRV_MINGWEX=OFF ^ + .. +if %errorlevel% neq 0 exit /b %errorlevel% + +cmake --build . --config %BUILD_TYPE% -- -j 2 +if %errorlevel% neq 0 exit /b %errorlevel% + +cd .. + + +rem ============= BUILD WinXP+ 64-bit driver ============= + +md build-drv-64 +cd build-drv-64 + +set CMAKEPREFIXPATH=C:/mingw-temp/MinGW-w64/mingw64 +set TOOLCHAIN_BIN=C:\mingw-temp\MinGW-w64\mingw64\bin +set PATH=%TOOLCHAIN_BIN%;%PUREPATH% + +cmake -G "%GENERATOR%"^ + -DCMAKE_BUILD_TYPE=%BUILD_TYPE%^ + -DCMAKE_PREFIX_PATH=%CMAKEPREFIXPATH%^ + -DCMAKE_INSTALL_PREFIX=libADLMIDI^ + -DWITH_OLD_UTILS=OFF ^ + -DWITH_GENADLDATA=OFF ^ + -DlibADLMIDI_STATIC=ON ^ + -DlibADLMIDI_SHARED=OFF ^ + -DWITH_MIDIPLAY=OFF ^ + -DWITH_VLC_PLUGIN=OFF ^ + -DWITH_WINMMDRV=ON ^ + -DWITH_WINMMDRV_PTHREADS=ON ^ + -DWITH_WINMMDRV_MINGWEX=OFF ^ + .. +if %errorlevel% neq 0 exit /b %errorlevel% + +cmake --build . --config %BUILD_TYPE% -- -j 2 +if %errorlevel% neq 0 exit /b %errorlevel% + +cd .. + + +rem ============= Deploy archives ============= + +cd build-drv-prexp +7z a -t7z -mx9 "libADLMIDI-winmm-driver-prexp.7z" %FILES_LIST% +if %errorlevel% neq 0 exit /b %errorlevel% +appveyor PushArtifact "libADLMIDI-winmm-driver-prexp.7z" +if %errorlevel% neq 0 exit /b %errorlevel% +cd .. + +md x86 +md x64 + +cd build-drv-32 +7z a -t7z -mx9 "libADLMIDI-winmm-driver-x86.7z" %FILES_LIST% +if %errorlevel% neq 0 exit /b %errorlevel% +appveyor PushArtifact "libADLMIDI-winmm-driver-x86.7z" +if %errorlevel% neq 0 exit /b %errorlevel% +for %%f in (%FILES_LIST%) DO copy %%f ..\x86 +cd .. + +cd build-drv-64 +7z a -t7z -mx9 "libADLMIDI-winmm-driver-x64.7z" %FILES_LIST% +if %errorlevel% neq 0 exit /b %errorlevel% +appveyor PushArtifact "libADLMIDI-winmm-driver-x64.7z" +if %errorlevel% neq 0 exit /b %errorlevel% +for %%f in (%FILES_LIST%) DO copy %%f ..\x64 +cd .. + +echo @echo off > install-x64.bat +echo cd x86 >> install-x64.bat +echo drvsetup install >> install-x64.bat +echo cd ..\x64 >> install-x64.bat +echo drvsetup install >> install-x64.bat +echo cd .. >> install-x64.bat +echo. >> install-x64.bat + +echo @echo off > install-x86.bat +echo cd x86 >> install-x86.bat +echo drvsetup install >> install-x86.bat +echo cd .. >> install-x86.bat +echo. >> install-x86.bat + +echo @echo off > uninstall-x64.bat +echo cd x86 >> uninstall-x64.bat +echo drvsetup uninstall >> uninstall-x64.bat +echo cd ..\x64 >> uninstall-x64.bat +echo drvsetup uninstall >> uninstall-x64.bat +echo cd .. >> uninstall-x64.bat +echo. >> install-x64.bat + +echo @echo off > uninstall-x86.bat +echo cd x86 >> uninstall-x86.bat +echo drvsetup uninstall >> uninstall-x86.bat +echo cd .. >> uninstall-x86.bat +echo. >> uninstall-x86.bat + +7z a -t7z -mx9 "libADLMIDI-winmm-driver-all.7z" *install*.bat x86 x64 +if %errorlevel% neq 0 exit /b %errorlevel% +appveyor PushArtifact "libADLMIDI-winmm-driver-all.7z" +if %errorlevel% neq 0 exit /b %errorlevel% + -- cgit v1.2.3 From 62a31bf919ab4928632ab75fa78d2189a8409e63 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 14:05:08 +0300 Subject: WinMM-DRV: A small fix for the vanilla MinGW toolchain --- utils/winmm_drv/config/regconfig.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/utils/winmm_drv/config/regconfig.c b/utils/winmm_drv/config/regconfig.c index 275b930..5afcd81 100644 --- a/utils/winmm_drv/config/regconfig.c +++ b/utils/winmm_drv/config/regconfig.c @@ -1,9 +1,8 @@ #include #include -#include -#include -#include +#define WIN32_LEAN_AND_MEAN +#include #include "regconfig.h" -- cgit v1.2.3 From 14d7c7c710b4a7847624473bb66f148cd5cf4dc9 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Mon, 21 Sep 2020 14:10:33 +0300 Subject: AppVeyor: Attempt to fix the build --- cmake/win-ci/winmm-drivers.cmd | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/cmake/win-ci/winmm-drivers.cmd b/cmake/win-ci/winmm-drivers.cmd index c44f46c..5cf1ffe 100644 --- a/cmake/win-ci/winmm-drivers.cmd +++ b/cmake/win-ci/winmm-drivers.cmd @@ -8,6 +8,7 @@ set NINJA_URL=http://wohlsoft.ru/docs/Software/Ninja-Build/ninja-win.zip md C:\mingw-temp md C:\mingw-temp\bin +echo Downloading %NINJA_URL%... "%WGET_BIN%" --quiet %NINJA_URL% -O C:\mingw-temp\ninja.zip if %errorlevel% neq 0 exit /b %errorlevel% "%SEVENZIP%" x C:\mingw-temp\ninja.zip -oC:\mingw-temp\bin @@ -16,17 +17,19 @@ if %errorlevel% neq 0 exit /b %errorlevel% md C:\mingw-temp\MinGW32 md C:\mingw-temp\MinGW-w64 +echo Downloading %MINGW_VANILLA_URL%... "%WGET_BIN%" --quiet %MINGW_VANILLA_URL% -O C:\mingw-temp\mingw-vanilla.zip if %errorlevel% neq 0 exit /b %errorlevel% "%SEVENZIP%" x C:\mingw-temp\mingw-vanilla.zip -oC:\mingw-temp\MinGW32 if %errorlevel% neq 0 exit /b %errorlevel% - +echo Downloading %MINGW_W64_32_URL%... "%WGET_BIN%" --quiet %MINGW_W64_32_URL% -O C:\mingw-temp\mingw-w64-32.7z if %errorlevel% neq 0 exit /b %errorlevel% "%SEVENZIP%" x C:\mingw-temp\mingw-w64-32.7z -oC:\mingw-temp\MinGW-w64 if %errorlevel% neq 0 exit /b %errorlevel% +echo Downloading %MINGW_W64_64_URL%... "%WGET_BIN%" --quiet %MINGW_W64_64_URL% -O C:\mingw-temp\mingw-w64-64.7z if %errorlevel% neq 0 exit /b %errorlevel% "%SEVENZIP%" x C:\mingw-temp\mingw-w64-64.7z -oC:\mingw-temp\MinGW-w64 @@ -34,10 +37,7 @@ if %errorlevel% neq 0 exit /b %errorlevel% set PUREPATH=C:\mingw-temp\bin;%PATH:C:\Program Files\Git\usr\bin;=% -set FILES_LIST=^ -"adlmidiconfigtool.exe" "adlmididrv.dll" "libadlconfig.cpl" ^ -"drvsetup.exe" "drvtest.exe" ^ -"install.bat" "uninstall.bat" +set FILES_LIST=adlmidiconfigtool.exe adlmididrv.dll libadlconfig.cpl drvsetup.exe drvtest.exe install.bat uninstall.bat rem ============= BUILD pre-WinXP 32-bit driver ============= -- cgit v1.2.3 From 1b5f0707d2b08ac9b24b1fe0f6bae8ffb03dc441 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Tue, 22 Sep 2020 18:28:49 +0300 Subject: WinMM-Drv: fixed a minor crash --- utils/winmm_drv/config/regconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/winmm_drv/config/regconfig.c b/utils/winmm_drv/config/regconfig.c index 275b930..70874ab 100644 --- a/utils/winmm_drv/config/regconfig.c +++ b/utils/winmm_drv/config/regconfig.c @@ -92,7 +92,7 @@ static BOOL readStringFromRegistry(HKEY hKeyParent, const PWCHAR subkey, const P static BOOL readIntFromRegistry(HKEY hKeyParent, const PWCHAR subkey, const PWCHAR valueName, int *readData) { - WCHAR *buf; + WCHAR *buf = NULL; BOOL ret; ret = readStringFromRegistry(hKeyParent, subkey, valueName, &buf); if(ret && readData) -- cgit v1.2.3 From baefee8dbe094a05ae89b0f9b909d19982711dc7 Mon Sep 17 00:00:00 2001 From: Wohlstand Date: Tue, 22 Sep 2020 18:55:08 +0300 Subject: Update readme --- CMakeLists.txt | 3 +++ README.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index b241b54..a22fadf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -430,3 +430,6 @@ message("WITH_OLD_UTILS = ${WITH_OLD_UTILS}") message("WITH_MUS2MID = ${WITH_MUS2MID}") message("WITH_XMI2MID = ${WITH_XMI2MID}") message("EXAMPLE_SDL2_AUDIO = ${EXAMPLE_SDL2_AUDIO}") +if(WIN32) + message("WITH_WINMMDRV = ${WITH_WINMMDRV}") +endif() diff --git a/README.md b/README.md index 17f62c8..d6d7723 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,9 @@ The library is licensed under in it's parts LGPL 2.1+, GPL v2+, GPL v3+, and MIT * **MIDIPLAY_WAVE_ONLY** - (ON/OFF, default OFF) Build Demo MIDI player without support of real time playing. It will output into WAV only. * **WITH_ADLMIDI2** - (ON/OFF, default OFF) Build Classic ADLMIDI MIDI player (Requires SDL2 on Linux and macOS, requires pthread on Windows with MinGW, SDL doesn't required on Windows). * **WITH_VLC_PLUGIN** - (ON/OFF, default OFF) Compile VLC plugin. For now, works on Linux and VLC. Support for other platforms comming soon! +* **WITH_WINMMDRV** - (ON/OFF, default OFF) (Windows platform only) Compile the WinMM MIDI driver to use libOPNMIDI as a system MIDI device. + * **WITH_WINMMDRV_PTHREADS** - (ON/OFF, default ON) Link libwinpthreads statically (when using pthread-based builds). + * **WITH_WINMMDRV_MINGWEX** - (ON/OFF, default OFF) Link libmingwex statically (when using vanilla MinGW builds). Useful for targetting to pre-XP Windows versions. * **WITH_OLD_UTILS** - (ON/OFF, default OFF) Build old utilities to dump some bank formats, made by original creator of ADLMIDI * **EXAMPLE_SDL2_AUDIO** - (ON/OFF, default OFF) Build also a simple SDL2 demo MIDI player -- cgit v1.2.3