From: <sag...@us...> - 2012-04-02 17:59:17
|
Revision: 1240 http://modplug.svn.sourceforge.net/modplug/?rev=1240&view=rev Author: saga-games Date: 2012-04-02 17:59:09 +0000 (Mon, 02 Apr 2012) Log Message: ----------- [Fix] IT/ST3 Compatibility: Delayed notes that are on a row that has a row delay effect should be retriggered. [Fix] Sample Editor: Propagating autovibrato changes in XM files didn't work for the last instrument. [Mod] VST: Changed JBridge handling a bit. [Mod] VST: If the plugin DLL is not found, OpenMPT tries to find it in the plugin directory instead of the settings directory. [Mod] Updated XM loading/saving test to check for unreferenced sample handling. Modified Paths: -------------- trunk/OpenMPT/mptrack/Childfrm.cpp trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/test/test.xm trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/MIDIMacros.cpp trunk/OpenMPT/soundlib/ModInstrument.h trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/XMTools.cpp trunk/OpenMPT/soundlib/plugins/JBridge.cpp trunk/OpenMPT/soundlib/plugins/JBridge.h trunk/OpenMPT/soundlib/plugins/PlugInterface.h Modified: trunk/OpenMPT/mptrack/Childfrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Childfrm.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -312,6 +312,10 @@ if ((!wParam) && (pSndFile->m_nInstruments > 0)) { nIns = pModDoc->FindSampleParent(nIns); + if(nIns == INSTRUMENTINDEX_INVALID) + { + nIns = 0; + } } ::SendMessage(m_hWndCtrl, WM_MOD_CTRLMSG, CTRLMSG_PAT_SETINSTRUMENT, nIns); } Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -1288,21 +1288,21 @@ //end rewbs.instroVSTi for(int nRes = 0; nRes<m_CbnResampling.GetCount(); nRes++) { - DWORD v = m_CbnResampling.GetItemData(nRes); - if (pIns->nResampling == v) + DWORD v = m_CbnResampling.GetItemData(nRes); + if (pIns->nResampling == v) { m_CbnResampling.SetCurSel(nRes); break; - } + } } for(int nFltMode = 0; nFltMode<m_CbnFilterMode.GetCount(); nFltMode++) { - DWORD v = m_CbnFilterMode.GetItemData(nFltMode); - if (pIns->nFilterMode == v) + DWORD v = m_CbnFilterMode.GetItemData(nFltMode); + if (pIns->nFilterMode == v) { m_CbnFilterMode.SetCurSel(nFltMode); break; - } + } } // NNA, DCT, DCA @@ -1313,7 +1313,7 @@ m_ComboPPC.SetCurSel(pIns->nPPC); SetDlgItemInt(IDC_EDIT15, pIns->nPPS); // Filter - if (m_pSndFile->m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) + if (m_pSndFile->GetType() & (MOD_TYPE_IT | MOD_TYPE_MPT)) { m_CheckCutOff.SetCheck((pIns->IsCutoffEnabled()) ? TRUE : FALSE); m_CheckResonance.SetCheck((pIns->IsResonanceEnabled()) ? TRUE : FALSE); @@ -2168,6 +2168,28 @@ m_pModDoc->SetModified(); } UpdatePluginList(); + + if(plugin.pMixPlugin != nullptr && plugin.pMixPlugin->isInstrument()) + { + // If we just added an instrument plugin, zap the sample assignments. + const std::set<SAMPLEINDEX> referencedSamples = pIns->GetSamples(); + bool hasSamples = false; + for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) + { + if(*sample > 0 && *sample <= m_pSndFile->GetNumSamples() && m_pSndFile->GetSample(*sample).pSample != nullptr) + { + hasSamples = true; + break; + } + } + + if(!hasSamples || Reporting::Confirm("Remove sample associations of this instrument?") == cnfYes) + { + pIns->AssignSample(0); + m_NoteMap.Invalidate(); + } + } + m_pModDoc->UpdateAllViews(NULL, HINT_MIXPLUGINS, NULL); } #endif // NO_VST Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -385,8 +385,11 @@ INSTRUMENTINDEX k = m_pParent->GetInstrumentChange(); if (!pModDoc->IsChildSample(k, lParam)) { - UINT nins = pModDoc->FindSampleParent(lParam); - if (nins) m_pParent->InstrumentChanged(nins); + INSTRUMENTINDEX nins = pModDoc->FindSampleParent(lParam); + if(nins != INSTRUMENTINDEX_INVALID) + { + m_pParent->InstrumentChanged(nins); + } } } else { @@ -920,8 +923,11 @@ UINT k = m_pParent->GetInstrumentChange(); if (!m_pModDoc->IsChildSample(k, m_nSample)) { - UINT nins = m_pModDoc->FindSampleParent(m_nSample); - if (nins) m_pParent->InstrumentChanged(nins); + INSTRUMENTINDEX nins = m_pModDoc->FindSampleParent(m_nSample); + if(nins != INSTRUMENTINDEX_INVALID) + { + m_pParent->InstrumentChanged(nins); + } } } else { @@ -970,9 +976,9 @@ } m_pModDoc->UpdateAllViews(NULL, (smp << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA | HINT_SMPNAMES); - if ((pSndFile->m_nInstruments) && (!m_pModDoc->FindSampleParent(smp))) + if(m_pModDoc->FindSampleParent(smp) == INSTRUMENTINDEX_INVALID) { - if (Reporting::Confirm("This sample is not used by any instrument. Do you want to create a new instrument using this sample?") == cnfYes) + if(Reporting::Confirm("This sample is not used by any instrument. Do you want to create a new instrument using this sample?") == cnfYes) { INSTRUMENTINDEX nins = m_pModDoc->InsertInstrument(smp); m_pModDoc->UpdateAllViews(NULL, (nins << HINT_SHIFT_INS) | HINT_INSTRUMENT | HINT_INSNAMES | HINT_ENVELOPE); @@ -3241,7 +3247,7 @@ return; } - for(INSTRUMENTINDEX i = 1; i < m_pSndFile->GetNumInstruments(); i++) + for(INSTRUMENTINDEX i = 1; i <= m_pSndFile->GetNumInstruments(); i++) { if(m_pSndFile->IsSampleReferencedByInstrument(m_nSample, i)) { Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -952,8 +952,9 @@ pChn->nMasterChn = 0; // remove NNA association pChn->nNewNote = static_cast<BYTE>(note); - if (nins) // Set instrument + if (nins) { + // Set instrument pChn->ResetEnvelopes(); m_SndFile.InstrumentChange(pChn, nins); pChn->nFadeOutVol = 0x10000; // Needed for XM files, as the nRowInstr check in NoteChange() will fail. @@ -1321,6 +1322,7 @@ return true; } + bool CModDoc::MuteInstrument(INSTRUMENTINDEX nInstr, bool bMute) //-------------------------------------------------------------- { @@ -1445,22 +1447,30 @@ } -UINT CModDoc::FindSampleParent(UINT nSmp) const -//--------------------------------------------- +// Find an instrument that references the given sample. +// If no such instrument is found, INSTRUMENTINDEX_INVALID is returned. +INSTRUMENTINDEX CModDoc::FindSampleParent(SAMPLEINDEX sample) const +//----------------------------------------------------------------- { - if ((!m_SndFile.m_nInstruments) || (!nSmp)) return 0; - for (UINT i=1; i<=m_SndFile.m_nInstruments; i++) + if(sample == 0) { - ModInstrument *pIns = m_SndFile.Instruments[i]; - if (pIns) + return INSTRUMENTINDEX_INVALID; + } + for(INSTRUMENTINDEX i = 1; i <= m_SndFile.GetNumInstruments(); i++) + { + const ModInstrument *pIns = m_SndFile.Instruments[i]; + if(pIns != nullptr) { - for (UINT j=0; j<NOTE_MAX; j++) + for(size_t j = 0; j < NOTE_MAX; j++) { - if (pIns->Keyboard[j] == nSmp) return i; + if(pIns->Keyboard[j] == sample) + { + return i; + } } } } - return 0; + return INSTRUMENTINDEX_INVALID; } Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Moddoc.h 2012-04-02 17:59:09 UTC (rev 1240) @@ -278,7 +278,7 @@ UINT GetPatternSize(PATTERNINDEX nPat) const; BOOL AdjustEndOfSample(UINT nSample); bool IsChildSample(INSTRUMENTINDEX nIns, SAMPLEINDEX nSmp) const; - UINT FindSampleParent(UINT nSmp) const; + INSTRUMENTINDEX FindSampleParent(SAMPLEINDEX sample) const; UINT FindInstrumentChild(UINT nIns) const; bool MoveOrder(ORDERINDEX nSourceNdx, ORDERINDEX nDestNdx, bool bUpdate = true, bool bCopy = false, SEQUENCEINDEX nSourceSeq = SEQUENCEINDEX_INVALID, SEQUENCEINDEX nDestSeq = SEQUENCEINDEX_INVALID); BOOL ExpandPattern(PATTERNINDEX nPattern); Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -158,16 +158,15 @@ if (ERROR_SUCCESS == RegQueryValueEx(hksub, nullptr, 0, &datatype, (LPBYTE)s, &datasize)) { VSTPluginLib *p = new VSTPluginLib(); - - p->pPrev = nullptr; p->pNext = m_pVstHead; p->dwPluginId1 = kDmoMagic; p->dwPluginId2 = clsid.Data1; - p->pPluginsList = nullptr; - p->isInstrument = false; lstrcpyn(p->szLibraryName, s, sizeof(p->szLibraryName)); + StringFixer::SetNullTerminator(p->szLibraryName); + StringFromGUID2(clsid, w, 100); WideCharToMultiByte(CP_ACP, 0, w, -1, p->szDllPath, sizeof(p->szDllPath), nullptr, nullptr); + StringFixer::SetNullTerminator(p->szDllPath); #ifdef DMO_LOG if (theApp.IsDebug()) Log("Found \"%s\" clsid=%s\n", p->szLibraryName, p->szDllPath); #endif @@ -194,15 +193,25 @@ { library = LoadLibrary(pluginPath); + if(library == nullptr) + { + DWORD error = GetLastError(); + #ifdef _DEBUG - DWORD dw = GetLastError(); - if(library == nullptr && dw != ERROR_MOD_NOT_FOUND) // "File not found errors" are annoying. - { - TCHAR szBuf[256]; - wsprintf(szBuf, "Warning: encountered problem when loading plugin dll. Error %d: %s", dw, (LPCTSTR)GetErrorMessage(dw)); - Reporting::Error(szBuf, "DEBUG: Error when loading plugin dll"); + if(error != ERROR_MOD_NOT_FOUND) // "File not found errors" are annoying. + { + TCHAR szBuf[256]; + wsprintf(szBuf, "Warning: encountered problem when loading plugin dll. Error %d: %s", error, (LPCTSTR)GetErrorMessage(error)); + Reporting::Error(szBuf, "DEBUG: Error when loading plugin dll"); + } +#endif //_DEBUG + + if(error == ERROR_MOD_NOT_FOUND) + { + // No point in trying with JBride, either... + return; + } } -#endif //_DEBUG } catch(...) { CVstPluginManager::ReportPlugException("Exception caught in LoadLibrary (%s)", pluginPath); @@ -226,9 +235,13 @@ Log("Entry point not found! (handle=%08X)\n", library); #endif // VST_LOG } - } else + } + + if(effect == nullptr) { // Try loading the plugin using JBridge instead. + FreeLibrary(library); + library = nullptr; effect = JBridge::LoadBridgedPlugin(MasterCallBack, pluginPath); } } @@ -238,8 +251,8 @@ // LibraryName = ID100000ID200000 // ID100000ID200000 = FullDllPath // ID100000ID200000.Flags = Plugin Flags (for now, just isInstrument). - -VSTPluginLib *CVstPluginManager::AddPlugin(LPCSTR pszDllPath, BOOL bCache, const bool checkFileExistence, CString* const errStr) + +VSTPluginLib *CVstPluginManager::AddPlugin(LPCSTR pszDllPath, BOOL bCache, const bool checkFileExistence, CString *const errStr) //------------------------------------------------------------------------------------------------------------------------------ { TCHAR szPath[_MAX_PATH]; @@ -281,18 +294,17 @@ VSTPluginLib *p; try { - p = new VSTPluginLib(); + p = new VSTPluginLib(pszDllPath); } catch(MPTMemoryException) { return nullptr; } - lstrcpyn(p->szDllPath, pszDllPath, sizeof(p->szDllPath)); _splitpath(pszDllPath, nullptr, nullptr, p->szLibraryName, nullptr); p->szLibraryName[63] = '\0'; p->pNext = m_pVstHead; - p->pPrev = nullptr; if (m_pVstHead) m_pVstHead->pPrev = p; m_pVstHead = p; + // Extract plugin Ids for (UINT i=0; i<16; i++) { @@ -340,17 +352,14 @@ VSTPluginLib *p = nullptr; try { - p = new VSTPluginLib(); + p = new VSTPluginLib(pszDllPath); } catch(MPTMemoryException) { return nullptr; } - p->pPluginsList = nullptr; - lstrcpyn(p->szDllPath, pszDllPath, CountOf(p->szDllPath)); _splitpath(pszDllPath, nullptr, nullptr, p->szLibraryName, nullptr); p->szLibraryName[63] = 0; p->pNext = m_pVstHead; - p->pPrev = nullptr; try { @@ -522,14 +531,23 @@ if ((!pFound) && strcmp(pMixPlugin->GetLibraryName(), "")) { - CHAR s[_MAX_PATH], dir[_MAX_PATH]; - _splitpath(theApp.GetConfigFileName(), s, dir, nullptr, nullptr); - strcat(s, dir); - int len = strlen(s); - if ((len > 0) && (s[len - 1] != '\\')) strcat(s, "\\"); - strncat(s, "plugins\\", _MAX_PATH - 1); - strncat(s, pMixPlugin->GetLibraryName(), _MAX_PATH - 1); - strncat(s, ".dll", _MAX_PATH-1); + // Try finding the plugin DLL in the plugin directory instead. + CHAR s[_MAX_PATH]; + strncpy(s, CMainFrame::GetSettings().GetDefaultDirectory(DIR_PLUGINS), CountOf(s)); + if(!strcmp(s, "")) + { + strncpy(s, theApp.GetAppDirPath(), CountOf(s)); + } + size_t len = strlen(s); + if((len > 0) && (s[len - 1] != '\\') && (s[len - 1] != '/')) + { + strcat(s, "\\"); + } + strncat(s, pMixPlugin->GetLibraryName(), CountOf(s)); + strncat(s, ".dll", CountOf(s)); + + StringFixer::SetNullTerminator(s); + pFound = AddPlugin(s); if (!pFound) { @@ -949,21 +967,23 @@ //"startStopProcess" //"sendVstMidiEventFlagIsRealtime" - if ((strcmp((char*)ptr,"sendVstEvents") == 0 || - strcmp((char*)ptr,"sendVstMidiEvent") == 0 || - strcmp((char*)ptr,"sendVstTimeInfo") == 0 || - strcmp((char*)ptr,"receiveVstEvents") == 0 || - strcmp((char*)ptr,"receiveVstMidiEvent") == 0 || - strcmp((char*)ptr,"supplyIdle") == 0 || - strcmp((char*)ptr,"sizeWindow") == 0 || - strcmp((char*)ptr,"openFileSelector") == 0 || - strcmp((char*)ptr,"closeFileSelector") == 0 || - strcmp((char*)ptr,"acceptIOChanges") == 0 || - strcmp((char*)ptr,"reportConnectionChanges") == 0 - )) + if(!strcmp((char*)ptr,"sendVstEvents") + || !strcmp((char*)ptr,"sendVstMidiEvent") + || !strcmp((char*)ptr,"sendVstTimeInfo") + || !strcmp((char*)ptr,"receiveVstEvents") + || !strcmp((char*)ptr,"receiveVstMidiEvent") + || !strcmp((char*)ptr,"supplyIdle") + || !strcmp((char*)ptr,"sizeWindow") + || !strcmp((char*)ptr,"openFileSelector") + || !strcmp((char*)ptr,"closeFileSelector") + || !strcmp((char*)ptr,"acceptIOChanges") + || !strcmp((char*)ptr,"reportConnectionChanges")) + { return HostCanDo; - else + } else + { return HostCanNotDo; + } case audioMasterGetLanguage: return kVstLangEnglish; @@ -1015,7 +1035,7 @@ // close a fileselector operation with VstFileSelect* in <ptr>: Must be always called after an open ! case audioMasterCloseFileSelector: - return VstFileSelector(opcode == audioMasterCloseFileSelector, (VstFileSelect *)ptr, effect); + return VstFileSelector(opcode == audioMasterCloseFileSelector, static_cast<VstFileSelect *>(ptr), effect); // open an editor for audio (defined by XML text in ptr) - DEPRECATED in VST 2.4 case audioMasterEditFile: @@ -1051,26 +1071,26 @@ // Helper function for file selection dialog stuff. -VstIntPtr CVstPluginManager::VstFileSelector(const bool destructor, VstFileSelect *pFileSel, const AEffect *effect) -//----------------------------------------------------------------------------------------------------------------- +VstIntPtr CVstPluginManager::VstFileSelector(bool destructor, VstFileSelect *fileSel, const AEffect *effect) +//---------------------------------------------------------------------------------------------------------- { - if(pFileSel == nullptr) + if(fileSel == nullptr) { return 0; } if(!destructor) { - pFileSel->nbReturnPath = 0; - pFileSel->reserved = 0; + fileSel->nbReturnPath = 0; + fileSel->reserved = 0; - if(pFileSel->command != kVstDirectorySelect) + if(fileSel->command != kVstDirectorySelect) { // Plugin wants to load or save a file. std::string extensions, workingDir; - for(VstInt32 i = 0; i < pFileSel->nbFileTypes; i++) + for(VstInt32 i = 0; i < fileSel->nbFileTypes; i++) { - VstFileType *pType = &(pFileSel->fileTypes[i]); + VstFileType *pType = &(fileSel->fileTypes[i]); extensions += pType->name; extensions += "|"; #if (defined(WIN32) || (defined(WINDOWS) && WINDOWS == 1)) @@ -1088,9 +1108,9 @@ extensions += "|"; } - if(pFileSel->initialPath != nullptr) + if(fileSel->initialPath != nullptr) { - workingDir = pFileSel->initialPath; + workingDir = fileSel->initialPath; } else { // Plugins are probably looking for presets...? @@ -1098,9 +1118,9 @@ } FileDlgResult files = CTrackApp::ShowOpenSaveFileDialog( - (pFileSel->command != kVstFileSave), + (fileSel->command != kVstFileSave), "", "", extensions, workingDir, - (pFileSel->command == kVstMultipleFilesLoad) + (fileSel->command == kVstMultipleFilesLoad) ); if(files.abort) @@ -1108,16 +1128,16 @@ return 0; } - if(pFileSel->command == kVstMultipleFilesLoad) + if(fileSel->command == kVstMultipleFilesLoad) { // Multiple paths - pFileSel->nbReturnPath = files.filenames.size(); - pFileSel->returnMultiplePaths = new char *[pFileSel->nbReturnPath]; + fileSel->nbReturnPath = files.filenames.size(); + fileSel->returnMultiplePaths = new char *[fileSel->nbReturnPath]; for(size_t i = 0; i < files.filenames.size(); i++) { char *fname = new char[files.filenames[i].length() + 1]; strcpy(fname, files.filenames[i].c_str()); - pFileSel->returnMultiplePaths[i] = fname; + fileSel->returnMultiplePaths[i] = fname; } return 1; } else @@ -1127,28 +1147,28 @@ // VOPM doesn't initialize required information properly (it doesn't memset the struct to 0)... if(CCONST('V', 'O', 'P', 'M') == effect->uniqueID) { - pFileSel->sizeReturnPath = _MAX_PATH; + fileSel->sizeReturnPath = _MAX_PATH; } - if(pFileSel->returnPath == nullptr || pFileSel->sizeReturnPath == 0) + if(fileSel->returnPath == nullptr || fileSel->sizeReturnPath == 0) { // Provide some memory for the return path. - pFileSel->sizeReturnPath = files.first_file.length() + 1; - pFileSel->returnPath = new char[pFileSel->sizeReturnPath]; - if(pFileSel->returnPath == nullptr) + fileSel->sizeReturnPath = files.first_file.length() + 1; + fileSel->returnPath = new char[fileSel->sizeReturnPath]; + if(fileSel->returnPath == nullptr) { return 0; } - pFileSel->returnPath[pFileSel->sizeReturnPath - 1] = '\0'; - pFileSel->reserved = 1; + fileSel->returnPath[fileSel->sizeReturnPath - 1] = '\0'; + fileSel->reserved = 1; } else { - pFileSel->reserved = 0; + fileSel->reserved = 0; } - strncpy(pFileSel->returnPath, files.first_file.c_str(), pFileSel->sizeReturnPath - 1); - pFileSel->nbReturnPath = 1; - pFileSel->returnMultiplePaths = nullptr; + strncpy(fileSel->returnPath, files.first_file.c_str(), fileSel->sizeReturnPath - 1); + fileSel->nbReturnPath = 1; + fileSel->returnMultiplePaths = nullptr; } return 1; @@ -1158,9 +1178,9 @@ char szInitPath[_MAX_PATH]; MemsetZero(szInitPath); - if(pFileSel->initialPath) + if(fileSel->initialPath) { - strncpy(szInitPath, pFileSel->initialPath, _MAX_PATH - 1); + strncpy(szInitPath, fileSel->initialPath, _MAX_PATH - 1); } char szBuffer[_MAX_PATH]; @@ -1169,37 +1189,37 @@ BROWSEINFO bi; MemsetZero(bi); bi.hwndOwner = CMainFrame::GetMainFrame()->m_hWnd; - bi.lpszTitle = pFileSel->title; + bi.lpszTitle = fileSel->title; bi.pszDisplayName = szInitPath; bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; LPITEMIDLIST pid = SHBrowseForFolder(&bi); if(pid != nullptr && SHGetPathFromIDList(pid, szBuffer)) { - if(CCONST('V', 'S', 'T', 'r') == effect->uniqueID && pFileSel->returnPath != nullptr && pFileSel->sizeReturnPath == 0) + if(CCONST('V', 'S', 'T', 'r') == effect->uniqueID && fileSel->returnPath != nullptr && fileSel->sizeReturnPath == 0) { // old versions of reViSiT (which still relied on the host's file selection code) seem to be dodgy. // They report a path size of 0, but when using an own buffer, they will crash. // So we'll just assume that reViSiT can handle long enough (_MAX_PATH) paths here. - pFileSel->sizeReturnPath = strlen(szBuffer) + 1; - pFileSel->returnPath[pFileSel->sizeReturnPath - 1] = '\0'; + fileSel->sizeReturnPath = strlen(szBuffer) + 1; + fileSel->returnPath[fileSel->sizeReturnPath - 1] = '\0'; } - if(pFileSel->returnPath == nullptr || pFileSel->sizeReturnPath == 0) + if(fileSel->returnPath == nullptr || fileSel->sizeReturnPath == 0) { // Provide some memory for the return path. - pFileSel->sizeReturnPath = strlen(szBuffer) + 1; - pFileSel->returnPath = new char[pFileSel->sizeReturnPath]; - if(pFileSel->returnPath == nullptr) + fileSel->sizeReturnPath = strlen(szBuffer) + 1; + fileSel->returnPath = new char[fileSel->sizeReturnPath]; + if(fileSel->returnPath == nullptr) { return 0; } - pFileSel->returnPath[pFileSel->sizeReturnPath - 1] = '\0'; - pFileSel->reserved = 1; + fileSel->returnPath[fileSel->sizeReturnPath - 1] = '\0'; + fileSel->reserved = 1; } else { - pFileSel->reserved = 0; + fileSel->reserved = 0; } - strncpy(pFileSel->returnPath, szBuffer, pFileSel->sizeReturnPath - 1); - pFileSel->nbReturnPath = 1; + strncpy(fileSel->returnPath, szBuffer, fileSel->sizeReturnPath - 1); + fileSel->nbReturnPath = 1; return 1; } else { @@ -1209,23 +1229,23 @@ } else { // Close file selector - delete allocated strings. - if(pFileSel->command == kVstMultipleFilesLoad && pFileSel->returnMultiplePaths != nullptr) + if(fileSel->command == kVstMultipleFilesLoad && fileSel->returnMultiplePaths != nullptr) { - for(VstInt32 i = 0; i < pFileSel->nbReturnPath; i++) + for(VstInt32 i = 0; i < fileSel->nbReturnPath; i++) { - if(pFileSel->returnMultiplePaths[i] != nullptr) + if(fileSel->returnMultiplePaths[i] != nullptr) { - delete[] pFileSel->returnMultiplePaths[i]; + delete[] fileSel->returnMultiplePaths[i]; } } - delete[] pFileSel->returnMultiplePaths; - pFileSel->returnMultiplePaths = nullptr; + delete[] fileSel->returnMultiplePaths; + fileSel->returnMultiplePaths = nullptr; } else { - if(pFileSel->reserved == 1 && pFileSel->returnPath != nullptr) + if(fileSel->reserved == 1 && fileSel->returnPath != nullptr) { - delete[] pFileSel->returnPath; - pFileSel->returnPath = nullptr; + delete[] fileSel->returnPath; + fileSel->returnPath = nullptr; } } return 1; Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/Vstplug.h 2012-04-02 17:59:09 UTC (rev 1240) @@ -44,6 +44,19 @@ CVstPlugin *pPluginsList; CHAR szLibraryName[_MAX_FNAME]; CHAR szDllPath[_MAX_PATH]; + + VSTPluginLib(const CHAR *dllPath = nullptr) + { + pPrev = pNext = nullptr; + dwPluginId1 = dwPluginId2 = 0; + isInstrument = false; + pPluginsList = nullptr; + if(dllPath != nullptr) + { + lstrcpyn(szDllPath, dllPath, CountOf(szDllPath)); + StringFixer::SetNullTerminator(szDllPath); + } + } }; @@ -281,7 +294,7 @@ protected: VstIntPtr VstCallback(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt); - VstIntPtr VstFileSelector(const bool destructor, VstFileSelect *pFileSel, const AEffect *effect); + VstIntPtr VstFileSelector(bool destructor, VstFileSelect *fileSel, const AEffect *effect); static VstIntPtr VSTCALLBACK MasterCallBack(AEffect *effect, VstInt32 opcode, VstInt32 index, VstIntPtr value, void *ptr, float opt); static BOOL __cdecl CreateMixPluginProc(SNDMIXPLUGIN *, CSoundFile *); VstTimeInfo timeInfo; //rewbs.VSTcompliance Modified: trunk/OpenMPT/mptrack/test/test.cpp =================================================================== --- trunk/OpenMPT/mptrack/test/test.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/mptrack/test/test.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -305,7 +305,13 @@ VERIFY_EQUAL_NONCONT(pSndFile->ChnSettings[1].nMixPlugin, 1); // Samples - VERIFY_EQUAL_NONCONT(pSndFile->GetNumSamples(), 2); + VERIFY_EQUAL_NONCONT(pSndFile->GetNumSamples(), 3); + VERIFY_EQUAL_NONCONT(strcmp(pSndFile->m_szNames[1], "Pulse Sample"), 0); + VERIFY_EQUAL_NONCONT(strcmp(pSndFile->m_szNames[2], "Empty Sample"), 0); + VERIFY_EQUAL_NONCONT(strcmp(pSndFile->m_szNames[3], "Unassigned Sample"), 0); + VERIFY_EQUAL_NONCONT(pModDoc->FindSampleParent(1), 1); + VERIFY_EQUAL_NONCONT(pModDoc->FindSampleParent(2), 1); + VERIFY_EQUAL_NONCONT(pModDoc->FindSampleParent(3), INSTRUMENTINDEX_INVALID); const ModSample &sample = pSndFile->GetSample(1); VERIFY_EQUAL_NONCONT(sample.GetBytesPerSample(), 1); VERIFY_EQUAL_NONCONT(sample.GetNumChannels(), 1); Modified: trunk/OpenMPT/mptrack/test/test.xm =================================================================== (Binary files differ) Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -806,21 +806,13 @@ } // Check which samples are referenced by which instruments (for assigning unreferenced samples to instruments) - vector<bool> sampleAssigned(GetNumSamples(), false); + vector<bool> sampleAssigned(GetNumSamples() + 1, false); for(INSTRUMENTINDEX ins = 1; ins <= GetNumInstruments(); ins++) { - if(Instruments[ins] == nullptr) + if(Instruments[ins] != nullptr) { - continue; + Instruments[ins]->GetSamples(sampleAssigned); } - const std::set<SAMPLEINDEX> referencedSamples = Instruments[ins]->GetSamples(); - for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) - { - if(*sample <= GetNumSamples()) - { - sampleAssigned[*sample - 1] = true; - } - } } // Writing instruments @@ -853,12 +845,12 @@ for(vector<SAMPLEINDEX>::const_iterator sample = samples.begin(); sample != samples.end(); sample++) { SAMPLEINDEX smp = *sample; - while(smp < GetNumSamples() - && !sampleAssigned[smp] // zero-based + while(++smp <= GetNumSamples() + && !sampleAssigned[smp] && insHeader.numSamples < (compatibilityExport ? 16 : 32)) { - sampleAssigned[smp++] = true; // Don't want to add this sample again. - additionalSamples.push_back(smp); // Not zero-based :) + sampleAssigned[smp] = true; // Don't want to add this sample again. + additionalSamples.push_back(smp); insHeader.numSamples++; } } Modified: trunk/OpenMPT/soundlib/MIDIMacros.cpp =================================================================== --- trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/MIDIMacros.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -180,7 +180,7 @@ #ifndef NO_VST if(plugin < MAX_MIXPLUGINS) { - CVstPlugin *pPlug = reinterpret_cast<CVstPlugin *>(sndFile.m_MixPlugins[plugin].pMixPlugin); + CVstPlugin *pPlug = dynamic_cast<CVstPlugin *>(sndFile.m_MixPlugins[plugin].pMixPlugin); if(pPlug) { paramName = pPlug->GetParamName(param); Modified: trunk/OpenMPT/soundlib/ModInstrument.h =================================================================== --- trunk/OpenMPT/soundlib/ModInstrument.h 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/ModInstrument.h 2012-04-02 17:59:09 UTC (rev 1240) @@ -165,6 +165,20 @@ return referencedSamples; } + // Write sample references into a bool vector. If a sample is referenced by this instrument, true is written. + // The caller has to initialize the vector. + void GetSamples(std::vector<bool> &referencedSamples) const + { + for(size_t i = 0; i < CountOf(Keyboard); i++) + { + // 0 isn't a sample. + if(Keyboard[i] != 0 && Keyboard[i] < referencedSamples.size()) + { + referencedSamples[Keyboard[i]] = true; + } + } + } + // Translate instrument properties between two given formats. void Convert(MODTYPE fromType, MODTYPE toType); Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -173,12 +173,7 @@ // Check if any of those samples are referenced by other instruments as well, in which case we want to keep them of course. for(INSTRUMENTINDEX nIns = 1; nIns <= GetNumInstruments(); nIns++) if (Instruments[nIns] != nullptr && nIns != nInstr) { - referencedSamples = Instruments[nIns]->GetSamples(); - for(std::set<SAMPLEINDEX>::const_iterator sample = referencedSamples.begin(); sample != referencedSamples.end(); sample++) - { - if((*sample) <= GetNumSamples()) - keepSamples[*sample] = true; - } + Instruments[nIns]->GetSamples(keepSamples); } // Now nuke the selected samples. Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -1620,8 +1620,16 @@ } } + bool triggerNote = (m_nTickCount == nStartTick); // Can be delayed by a note delay effect + // IT Compatibility: Delayed notes (using SDx) that are on the same row as a Row Delay effect are retriggered. Scream Tracker 3 does the same. + // Test case: PatternDelay-NoteDelay.it + if((GetType() & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)) && nStartTick > 0 && (m_nTickCount % (m_nMusicSpeed + m_nFrameDelay)) == nStartTick) + { + triggerNote = true; + } + // Handles note/instrument/volume changes - if (m_nTickCount == nStartTick) // can be delayed by a note delay effect + if(triggerNote) { UINT note = pChn->rowCommand.note; if (instr) pChn->nNewIns = instr; Modified: trunk/OpenMPT/soundlib/XMTools.cpp =================================================================== --- trunk/OpenMPT/soundlib/XMTools.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/XMTools.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -254,7 +254,7 @@ type = mptIns.nMidiProgram; // If FT2 writes crap here, we can do so, too! - numSamples = static_cast<uint16>(min(mptIns.GetSamples().size(), size_t(compatibilityExport ? 16 : 32))); + numSamples = static_cast<uint16>(Util::Min(mptIns.GetSamples().size(), size_t(compatibilityExport ? 16 : 32))); } @@ -305,7 +305,7 @@ version = LittleEndianW(0x102); - numSamples = static_cast<uint16>(LittleEndianW(min(mptIns.GetSamples().size(), size_t(compatibilityExport ? 16 : 32)))); + numSamples = static_cast<uint16>(LittleEndianW(Util::Min(mptIns.GetSamples().size(), size_t(compatibilityExport ? 16 : 32)))); } Modified: trunk/OpenMPT/soundlib/plugins/JBridge.cpp =================================================================== --- trunk/OpenMPT/soundlib/plugins/JBridge.cpp 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/plugins/JBridge.cpp 2012-04-02 17:59:09 UTC (rev 1240) @@ -11,17 +11,22 @@ #include "stdafx.h" #include <pluginterfaces/vst2.x/aeffectx.h> +#include "JBridge.h" namespace JBridge { +#ifdef ENABLE_JBRIDGE + // Name of the proxy DLL to load static const char *proxyRegKey = "Software\\JBridge"; #ifdef _M_X64 static const char *proxyRegVal = "Proxy64"; //use this for x64 builds +static_assert(sizeof(void *) == 8, "Wrong platform!"); #else static const char *proxyRegVal = "Proxy32"; //use this for x86 builds +static_assert(sizeof(void *) == 4, "Wrong platform!"); #endif // Typedef for BridgeMain proc @@ -101,4 +106,6 @@ return pfnBridgeMain(audioMaster, pluginPath); } +#endif // ENABLE_JBRIDGE + } Modified: trunk/OpenMPT/soundlib/plugins/JBridge.h =================================================================== --- trunk/OpenMPT/soundlib/plugins/JBridge.h 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/plugins/JBridge.h 2012-04-02 17:59:09 UTC (rev 1240) @@ -10,7 +10,15 @@ #pragma once +#if !defined(NO_VST) && (defined(WIN32) || (defined(WINDOWS) && WINDOWS == 1)) +#define ENABLE_JBRIDGE +#endif + namespace JBridge { +#ifdef ENABLE_JBRIDGE AEffect *LoadBridgedPlugin(audioMasterCallback audioMaster, const char *pluginPath); +#else + void *LoadBridgedPlugin(void *, const char *) { return nullptr; } +#endif // ENABLE_JBRIDGE } Modified: trunk/OpenMPT/soundlib/plugins/PlugInterface.h =================================================================== --- trunk/OpenMPT/soundlib/plugins/PlugInterface.h 2012-04-01 19:26:38 UTC (rev 1239) +++ trunk/OpenMPT/soundlib/plugins/PlugInterface.h 2012-04-02 17:59:09 UTC (rev 1240) @@ -105,11 +105,11 @@ irExpandMix = 0x08, // [0%,100%] -> [-200%,200%] }; - DWORD dwPluginId1; // Plugin type (kEffectMagic, kDmoMagic, kBuzzMagic) - DWORD dwPluginId2; // Plugin unique ID - DWORD dwInputRouting; // Bits 0 to 7 = RoutingFlags, bits 8 - 15 = mixing mode, bits 16-23 = gain - DWORD dwOutputRouting; // 0 = send to master 0x80 + x = send to plugin x - DWORD dwReserved[4]; // Reserved for routing info + VstInt32 dwPluginId1; // Plugin type (kEffectMagic, kDmoMagic, kBuzzMagic) + VstInt32 dwPluginId2; // Plugin unique ID + uint32 dwInputRouting; // Bits 0 to 7 = RoutingFlags, bits 8 - 15 = mixing mode, bits 16-23 = gain + uint32 dwOutputRouting; // 0 = send to master 0x80 + x = send to plugin x + uint32 dwReserved[4]; // Reserved for routing info CHAR szName[32]; // User-chosen plugin name CHAR szLibraryName[64]; // original DLL name This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |