From: <sv...@op...> - 2024-10-20 12:35:26
|
Author: sagamusix Date: Sun Oct 20 14:35:14 2024 New Revision: 21875 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=21875 Log: Merged revision(s) 21825, 21854 from trunk/OpenMPT: [Mod] SymMOD: Ignore unknown hunks, as that's what Symphonie does as well. Fixes reading of Natsh1.SymMOD, which has garbage at the end of the file. ........ [Imp] SymMOD: When running out of Zxx macros, try to find the closest macro to use instead. Fixes files like ocean view.symmod with tons of filter sweeps. ........ Modified: branches/OpenMPT-1.31/ (props changed) branches/OpenMPT-1.31/soundlib/Load_symmod.cpp Modified: branches/OpenMPT-1.31/soundlib/Load_symmod.cpp ============================================================================== --- branches/OpenMPT-1.31/soundlib/Load_symmod.cpp Sun Oct 20 14:33:28 2024 (r21874) +++ branches/OpenMPT-1.31/soundlib/Load_symmod.cpp Sun Oct 20 14:35:14 2024 (r21875) @@ -980,6 +980,30 @@ } +static uint8 MapToClosestMidiMacro(const SymEvent event, std::map<SymEvent, uint8> ¯oMap) +{ + if(event.command == SymEvent::DSPDelay) + return 0; + uint8 bestMatch = 0; + uint32 bestDistance = uint32_max; + for(const auto &m : macroMap) + { + const auto &mapEvent = m.first; + if(event.command != mapEvent.command || event.note != mapEvent.note) + continue; + const uint32 diff1 = static_cast<uint32>(event.param) - mapEvent.param, diff2 = static_cast<uint32>(event.inst) - mapEvent.inst; + const uint32 distance = diff1 * diff1 + diff2 * diff2; + if(distance >= bestDistance) + continue; + + bestMatch = m.second; + bestDistance = distance; + } + macroMap[event] = bestMatch; + return bestMatch; +} + + CSoundFile::ProbeResult CSoundFile::ProbeFileHeaderSymMOD(MemoryFileReader file, const uint64 *pfilesize) { MPT_UNREFERENCED_PARAMETER(pfilesize); @@ -1044,6 +1068,7 @@ uint16 sampleBoost = 2500; bool isSymphoniePro = false; bool externalSamples = false; + bool unknownHunks = false; std::vector<SymPosition> positions; std::vector<SymSequence> sequences; std::vector<SymEvent> patternData; @@ -1202,9 +1227,10 @@ file.Skip(file.ReadUint32BE()); break; - // Unrecognized chunk/value type + // Unrecognized chunk/value type (e.g. garbage at the end of Natsh1.SymMOD) default: - return false; + unknownHunks = true; + break; } } @@ -1212,6 +1238,8 @@ return false; if((loadFlags & loadPatternData) && (positions.empty() || patternData.empty() || sequences.empty())) return false; + if(unknownHunks) + AddToLog(LogWarning, U_("Unknown hunks were found and ignored.")); // Let's hope noone is going to use the 256th instrument ;) if(instruments.size() >= MAX_INSTRUMENTS) @@ -1641,10 +1669,9 @@ case SymEvent::DSPEcho: case SymEvent::DSPDelay: #endif - if(macroMap.count(event)) + if(auto it = macroMap.find(event); it != macroMap.end() && it->second != 0) { - m.command = CMD_MIDI; - m.param = macroMap[event]; + m.SetEffectCommand(CMD_MIDI, it->second); } else if(macroMap.size() < m_MidiCfg.Zxx.size()) { uint8 param = static_cast<uint8>(macroMap.size()); @@ -1656,6 +1683,9 @@ if(event.command == SymEvent::DSPEcho || event.command == SymEvent::DSPDelay) useDSP = true; } + } else if(uint8 param = MapToClosestMidiMacro(event, macroMap)) + { + m.SetEffectCommand(CMD_MIDI, param); } break; |