bool csShaderGLCGCommon::WriteToCache (iHierarchicalCache* cache, const ProfileLimits& limits, const ProfileLimitsPair& limitsPair, const char* tag) { csString objectCode; if (program != 0) objectCode = cgGetProgramString (program, CG_COMPILED_PROGRAM); ProgramObject programObj (objectCode, programPositionInvariant ? ProgramObject::flagPositionInvariant : 0, unusedParams); const char* preprocSource (cgGetProgramString (program, CG_PROGRAM_SOURCE)); csString failReason; ProgramObjectID progId; if (!shaderPlug->progCache.WriteObject (preprocSource, limits, programObj, progId, failReason)) { if (shaderPlug->doVerbose) { csReport (objectReg, CS_REPORTER_SEVERITY_WARNING, "crystalspace.graphics3d.shader.glcg", "Error writing %s program for %s to compile cache: %s", GetProgramType(), tag, failReason.GetData()); } return false; } programObj.SetID (progId); return WriteToCache (cache, limits, limitsPair, tag, programObj); }
// Create an instance of a plugin. bool CVstPluginManager::CreateMixPlugin(SNDMIXPLUGIN &mixPlugin, CSoundFile &sndFile) //----------------------------------------------------------------------------------- { VSTPluginLib *pFound = nullptr; // Find plugin in library int match = 0; for(const_iterator p = begin(); p != end(); p++) { VSTPluginLib *plug = *p; const bool matchID = (plug->pluginId1 == mixPlugin.Info.dwPluginId1) && (plug->pluginId2 == mixPlugin.Info.dwPluginId2); const bool matchName = !mpt::PathString::CompareNoCase(plug->libraryName, mpt::PathString::FromUTF8(mixPlugin.GetLibraryName())); if(matchID && matchName) { pFound = plug; break; } else if(matchID && match < 2) { match = 2; pFound = plug; } else if(matchName && match < 1) { match = 1; pFound = plug; } } if(mixPlugin.Info.dwPluginId1 == kDmoMagic) { if (!pFound) return false; AEffect *pEffect = DmoToVst(*pFound); if(pEffect && pEffect->magic == kDmoMagic) { CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(nullptr, *pFound, mixPlugin, *pEffect, sndFile); return pVstPlug != nullptr; } } if(!pFound && strcmp(mixPlugin.GetLibraryName(), "")) { // Try finding the plugin DLL in the plugin directory or plugin cache instead. mpt::PathString fullPath = TrackerDirectories::Instance().GetDefaultDirectory(DIR_PLUGINS); if(fullPath.empty()) { fullPath = theApp.GetAppDirPath() + MPT_PATHSTRING("Plugins\\"); } fullPath += mpt::PathString::FromUTF8(mixPlugin.GetLibraryName()) + MPT_PATHSTRING(".dll"); pFound = AddPlugin(fullPath); if(!pFound) { // Try plugin cache (search for library name) SettingsContainer &cacheFile = theApp.GetPluginCache(); std::string IDs = cacheFile.Read<std::string>(cacheSectionW, mpt::ToWide(mpt::CharsetUTF8, mixPlugin.GetLibraryName()), ""); if(IDs.length() >= 16) { fullPath = cacheFile.Read<mpt::PathString>(cacheSection, IDs, MPT_PATHSTRING("")); if(!fullPath.empty()) { fullPath = theApp.RelativePathToAbsolute(fullPath); if(PathFileExistsW(fullPath.AsNative().c_str())) { pFound = AddPlugin(fullPath); } } } } } if(pFound) { AEffect *pEffect = nullptr; HINSTANCE hLibrary = nullptr; bool validPlugin = false; try { pEffect = LoadPlugin(pFound->dllPath, hLibrary); if(pEffect != nullptr && pEffect->dispatcher != nullptr && pEffect->magic == kEffectMagic) { validPlugin = true; const bool oldIsInstrument = pFound->isInstrument; const VSTPluginLib::PluginCategory oldCategory = pFound->category; GetPluginInformation(pEffect, *pFound); if(oldIsInstrument != pFound->isInstrument || oldCategory != pFound->category) { // Update cached information WriteToCache(*pFound); } CVstPlugin *pVstPlug = new (std::nothrow) CVstPlugin(hLibrary, *pFound, mixPlugin, *pEffect, sndFile); if(pVstPlug == nullptr) { validPlugin = false; } } if(!validPlugin) { FreeLibrary(hLibrary); } } catch(...) { CVstPluginManager::ReportPlugException(mpt::String::PrintW(L"Exception while trying to create plugin \"%1\"!\n", pFound->libraryName)); } return validPlugin; } else { // "plug not found" notification code MOVED to CSoundFile::Create #ifdef VST_LOG Log("Unknown plugin\n"); #endif } return false; }
// Add a plugin to the list of known plugins. VSTPluginLib *CVstPluginManager::AddPlugin(const mpt::PathString &dllPath, bool fromCache, const bool checkFileExistence, std::wstring *const errStr) //--------------------------------------------------------------------------------------------------------------------------------------------------- { const mpt::PathString fileName = dllPath.GetFileName(); if(checkFileExistence && (PathFileExistsW(dllPath.AsNative().c_str()) == FALSE)) { if(errStr) { *errStr += L"\nUnable to find "; *errStr += dllPath.ToWide(); } } // Check if this is already a known plugin. for(const_iterator dupePlug = begin(); dupePlug != end(); dupePlug++) { if(!dllPath.CompareNoCase(dllPath, (**dupePlug).dllPath)) return *dupePlug; } // Look if the plugin info is stored in the PluginCache if(fromCache) { SettingsContainer & cacheFile = theApp.GetPluginCache(); const std::string IDs = cacheFile.Read<std::string>(cacheSectionW, fileName.ToWide(), ""); if(IDs.length() >= 16) { // Get path from cache file mpt::PathString realPath = cacheFile.Read<mpt::PathString>(cacheSection, IDs, MPT_PATHSTRING("")); realPath = theApp.RelativePathToAbsolute(realPath); if(!realPath.empty() && !dllPath.CompareNoCase(realPath, dllPath)) { VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(dllPath, fileName); if(plug == nullptr) { return nullptr; } pluginList.push_back(plug); // Extract plugin IDs for (int i = 0; i < 16; i++) { VstInt32 n = IDs[i] - '0'; if (n > 9) n = IDs[i] + 10 - 'A'; n &= 0x0f; if (i < 8) { plug->pluginId1 = (plug->pluginId1 << 4) | n; } else { plug->pluginId2 = (plug->pluginId2 << 4) | n; } } const std::string flagKey = IDs + ".Flags"; plug->DecodeCacheFlags(cacheFile.Read<int32>(cacheSection, flagKey, 0)); #ifdef VST_LOG Log("Plugin \"%s\" found in PluginCache\n", plug->libraryName.ToLocale().c_str()); #endif // VST_LOG return plug; } else { #ifdef VST_LOG Log("Plugin \"%s\" mismatch in PluginCache: \"%s\" [%s]=\"%s\"\n", s, dllPath, (LPCTSTR)IDs, (LPCTSTR)strFullPath); #endif // VST_LOG } } } // If this key contains a file name on program launch, a plugin previously crashed OpenMPT. theApp.GetSettings().Write<mpt::PathString>("VST Plugins", "FailedPlugin", dllPath); AEffect *pEffect; HINSTANCE hLib; bool validPlug = false; VSTPluginLib *plug = new (std::nothrow) VSTPluginLib(dllPath, fileName); if(plug == nullptr) { return nullptr; } try { pEffect = LoadPlugin(dllPath, hLib); if(pEffect != nullptr && pEffect->magic == kEffectMagic && pEffect->dispatcher != nullptr) { pEffect->dispatcher(pEffect, effOpen, 0, 0, 0, 0); plug->pluginId1 = pEffect->magic; plug->pluginId2 = pEffect->uniqueID; GetPluginInformation(pEffect, *plug); #ifdef VST_LOG int nver = pEffect->dispatcher(pEffect, effGetVstVersion, 0,0, nullptr, 0); if (!nver) nver = pEffect->version; Log("%-20s: v%d.0, %d in, %d out, %2d programs, %2d params, flags=0x%04X realQ=%d offQ=%d\n", plug->libraryName.ToLocale().c_str(), nver, pEffect->numInputs, pEffect->numOutputs, pEffect->numPrograms, pEffect->numParams, pEffect->flags, pEffect->realQualities, pEffect->offQualities); #endif // VST_LOG pEffect->dispatcher(pEffect, effClose, 0, 0, 0, 0); validPlug = true; } FreeLibrary(hLib); } catch(...) { CVstPluginManager::ReportPlugException(mpt::String::PrintW(L"Exception while trying to load plugin \"%1\"!\n", plug->libraryName)); } // Now it should be safe to assume that this plugin loaded properly. :) theApp.GetSettings().Remove("VST Plugins", "FailedPlugin"); // If OK, write the information in PluginCache if(validPlug) { pluginList.push_back(plug); WriteToCache(*plug); } else { delete plug; } return (validPlug ? plug : nullptr); }