diff --git a/src/driver.cpp b/src/driver.cpp index 4daa3ce1e1..70e2071524 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -8,6 +8,7 @@ /** @file driver.cpp Base for all driver handling. */ #include "stdafx.h" +#include "core/string_consumer.hpp" #include "debug.h" #include "error.h" #include "error_func.h" @@ -43,18 +44,18 @@ static const std::string HWACCELERATION_TEST_FILE = "hwaccel.dat"; ///< Filename * @param name The parameter name we're looking for. * @return The parameter value. */ -const char *GetDriverParam(const StringList &parm, const char *name) +std::optional GetDriverParam(const StringList &parm, std::string_view name) { - if (parm.empty()) return nullptr; + if (parm.empty()) return std::nullopt; - size_t len = strlen(name); for (auto &p : parm) { - if (p.compare(0, len, name) == 0) { - if (p.length() == len) return ""; - if (p[len] == '=') return p.c_str() + len + 1; + StringConsumer consumer{p}; + if (consumer.ReadIf(name)) { + if (!consumer.AnyBytesLeft()) return ""; + if (consumer.ReadIf("=")) return consumer.GetLeftData(); } } - return nullptr; + return std::nullopt; } /** @@ -63,9 +64,9 @@ const char *GetDriverParam(const StringList &parm, const char *name) * @param name The parameter name we're looking for. * @return The parameter value. */ -bool GetDriverParamBool(const StringList &parm, const char *name) +bool GetDriverParamBool(const StringList &parm, std::string_view name) { - return GetDriverParam(parm, name) != nullptr; + return GetDriverParam(parm, name).has_value(); } /** @@ -75,13 +76,13 @@ bool GetDriverParamBool(const StringList &parm, const char *name) * @param def The default value if the parameter doesn't exist. * @return The parameter value. */ -int GetDriverParamInt(const StringList &parm, const char *name, int def) +int GetDriverParamInt(const StringList &parm, std::string_view name, int def) { - const char *p = GetDriverParam(parm, name); - if (p == nullptr) return def; - auto value = ParseInteger(p); + auto p = GetDriverParam(parm, name); + if (!p.has_value()) return def; + auto value = ParseInteger(*p); if (value.has_value()) return *value; - UserError("Invalid value for driver parameter {}: {}", name, p); + UserError("Invalid value for driver parameter {}: {}", name, *p); } /** @@ -241,7 +242,7 @@ void DriverFactoryBase::GetDriversInfo(std::back_insert_iterator &o * @param name The name of the driver. * @param description A long-ish description of the driver. */ -DriverFactoryBase::DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description) : +DriverFactoryBase::DriverFactoryBase(Driver::Type type, int priority, std::string_view name, std::string_view description) : type(type), priority(priority), name(name), description(description) { /* Prefix the name with driver type to make it unique */ diff --git a/src/driver.h b/src/driver.h index e827a61898..2850a34ce3 100644 --- a/src/driver.h +++ b/src/driver.h @@ -13,9 +13,9 @@ #include "core/enum_type.hpp" #include "string_type.h" -const char *GetDriverParam(const StringList &parm, const char *name); -bool GetDriverParamBool(const StringList &parm, const char *name); -int GetDriverParamInt(const StringList &parm, const char *name, int def); +std::optional GetDriverParam(const StringList &parm, std::string_view name); +bool GetDriverParamBool(const StringList &parm, std::string_view name); +int GetDriverParamInt(const StringList &parm, std::string_view name, int def); /** A driver for communicating with the user. */ class Driver { @@ -103,7 +103,7 @@ private: static void MarkVideoDriverOperational(); protected: - DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description); + DriverFactoryBase(Driver::Type type, int priority, std::string_view name, std::string_view description); virtual ~DriverFactoryBase(); diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp index 5ddc36bb03..0b099d3708 100644 --- a/src/music/dmusic.cpp +++ b/src/music/dmusic.cpp @@ -78,7 +78,7 @@ struct DLSFile { std::vector waves; /** Try loading a DLS file into memory. */ - bool LoadFile(const std::string &file); + bool LoadFile(std::string_view file); private: /** Load an articulation structure from a DLS file. */ @@ -422,7 +422,7 @@ bool DLSFile::ReadDLSWaveList(FileHandle &f, DWORD list_length) return true; } -bool DLSFile::LoadFile(const std::string &file) +bool DLSFile::LoadFile(std::string_view file) { Debug(driver, 2, "DMusic: Try to load DLS file {}", file); @@ -843,7 +843,7 @@ static void * DownloadArticulationData(int base_offset, void *data, const std::v return (CONNECTION *)(con_list + 1) + artic.size(); } -static const char *LoadDefaultDLSFile(const char *user_dls) +static std::optional LoadDefaultDLSFile(std::optional user_dls) { DMUS_PORTCAPS caps; MemSetT(&caps, 0); @@ -854,7 +854,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) if ((caps.dwFlags & (DMUS_PC_DLS | DMUS_PC_DLS2)) != 0 && (caps.dwFlags & DMUS_PC_GMINHARDWARE) == 0) { DLSFile dls_file; - if (user_dls == nullptr) { + if (!user_dls.has_value()) { /* Try loading the default GM DLS file stored in the registry. */ HKEY hkDM; if (SUCCEEDED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Microsoft\\DirectMusic", 0, KEY_READ, &hkDM))) { @@ -877,7 +877,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) if (!dls_file.LoadFile(FS2OTTD(path))) return "Can't load GM DLS collection"; } } else { - if (!dls_file.LoadFile(user_dls)) return "Can't load GM DLS collection"; + if (!dls_file.LoadFile(*user_dls)) return "Can't load GM DLS collection"; } /* Get download port and allocate download IDs. */ @@ -1060,7 +1060,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) download_port->Release(); } - return nullptr; + return std::nullopt; } @@ -1136,8 +1136,8 @@ std::optional MusicDriver_DMusic::Start(const StringList &parm if (FAILED(_music->CreateMusicBuffer(&desc, &_buffer, nullptr))) return "Failed to create music buffer"; /* On soft-synths (e.g. the default DirectMusic one), we might need to load a wavetable set to get music. */ - const char *dls = LoadDefaultDLSFile(GetDriverParam(parm, "dls")); - if (dls != nullptr) return dls; + auto dls = LoadDefaultDLSFile(GetDriverParam(parm, "dls")); + if (dls.has_value()) return dls; /* Create playback thread and synchronization primitives. */ _thread_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index 4ec5b72670..04143149e3 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -43,22 +43,21 @@ std::optional MusicDriver_ExtMidi::Start(const StringList &par return "the extmidi driver does not work when Allegro is loaded."; } - const char *command = GetDriverParam(parm, "cmd"); + auto command = GetDriverParam(parm, "cmd"); #ifndef MIDI_ARG - if (StrEmpty(command)) command = EXTERNAL_PLAYER; + if (!command.has_value() || command->empty()) command = EXTERNAL_PLAYER; #else - if (StrEmpty(command)) command = EXTERNAL_PLAYER " " MIDI_ARG; + if (!command.has_value() || command->empty()) command = EXTERNAL_PLAYER " " MIDI_ARG; #endif this->command_tokens.clear(); - std::string_view view = command; for (;;) { - auto pos = view.find(' '); - this->command_tokens.emplace_back(view.substr(0, pos)); + auto pos = command->find(' '); + this->command_tokens.emplace_back(command->substr(0, pos)); if (pos == std::string_view::npos) break; - view.remove_prefix(pos + 1); + command->remove_prefix(pos + 1); } this->song.clear(); diff --git a/src/music/fluidsynth.cpp b/src/music/fluidsynth.cpp index 3093a8d5b5..5d1a0bf01b 100644 --- a/src/music/fluidsynth.cpp +++ b/src/music/fluidsynth.cpp @@ -63,10 +63,10 @@ std::optional MusicDriver_FluidSynth::Start(const StringList & { std::lock_guard lock{ _midi.synth_mutex }; - const char *sfont_name = GetDriverParam(param, "soundfont"); + auto sfont_name = GetDriverParam(param, "soundfont"); int sfont_id; - Debug(driver, 1, "Fluidsynth: sf {}", sfont_name != nullptr ? sfont_name : "(null)"); + Debug(driver, 1, "Fluidsynth: sf {}", sfont_name.has_value() ? *sfont_name : "(null)"); /* Create the settings. */ _midi.settings = new_fluid_settings(); @@ -85,7 +85,7 @@ std::optional MusicDriver_FluidSynth::Start(const StringList & /* Load a SoundFont and reset presets (so that new instruments * get used from the SoundFont) */ - if (sfont_name == nullptr) { + if (!sfont_name.has_value()) { sfont_id = FLUID_FAILED; /* Try loading the default soundfont registered with FluidSynth. */ @@ -105,7 +105,8 @@ std::optional MusicDriver_FluidSynth::Start(const StringList & } if (sfont_id == FLUID_FAILED) return "Could not open any sound font"; } else { - sfont_id = fluid_synth_sfload(_midi.synth, sfont_name, 1); + std::string name{sfont_name}; + sfont_id = fluid_synth_sfload(_midi.synth, name.c_str(), 1); if (sfont_id == FLUID_FAILED) return "Could not open sound font"; } diff --git a/src/music/win32_m.cpp b/src/music/win32_m.cpp index 638a4210fd..00900f8161 100644 --- a/src/music/win32_m.cpp +++ b/src/music/win32_m.cpp @@ -372,10 +372,10 @@ std::optional MusicDriver_Win32::Start(const StringList &parm) int resolution = GetDriverParamInt(parm, "resolution", 5); uint port = (uint)GetDriverParamInt(parm, "port", UINT_MAX); - const char *portname = GetDriverParam(parm, "portname"); + auto portname = GetDriverParam(parm, "portname"); /* Enumerate ports either for selecting port by name, or for debug output */ - if (portname != nullptr || _debug_driver_level > 0) { + if (portname.has_value() || _debug_driver_level > 0) { uint numports = midiOutGetNumDevs(); Debug(driver, 1, "Win32-MIDI: Found {} output devices:", numports); for (uint tryport = 0; tryport < numports; tryport++) { @@ -386,7 +386,7 @@ std::optional MusicDriver_Win32::Start(const StringList &parm) /* Compare requested and detected port name. * If multiple ports have the same name, this will select the last matching port, and the debug output will be confusing. */ - if (portname != nullptr && strncmp(tryportname, portname, lengthof(tryportname)) == 0) port = tryport; + if (portname.has_value() && *portname == tryportname) port = tryport; Debug(driver, 1, "MIDI port {:2d}: {}{}", tryport, tryportname, (tryport == port) ? " [selected]" : ""); } diff --git a/src/sound/win32_s.cpp b/src/sound/win32_s.cpp index 1bfc4e06ec..e94358d594 100644 --- a/src/sound/win32_s.cpp +++ b/src/sound/win32_s.cpp @@ -39,7 +39,7 @@ static void PrepareHeader(HeaderDataPair &hdr) hdr.first.dwBufferLength = _bufsize * 4; hdr.first.dwFlags = 0; hdr.first.lpData = hdr.second.get(); - if (waveOutPrepareHeader(_waveout, &hdr.first, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) throw "waveOutPrepareHeader failed"; + if (waveOutPrepareHeader(_waveout, &hdr.first, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) throw "waveOutPrepareHeader failed"sv; } static DWORD WINAPI SoundThread(LPVOID) @@ -76,16 +76,16 @@ std::optional SoundDriver_Win32::Start(const StringList &parm) _bufsize = std::min(_bufsize, UINT16_MAX); try { - if (nullptr == (_event = CreateEvent(nullptr, FALSE, FALSE, nullptr))) throw "Failed to create event"; + if (nullptr == (_event = CreateEvent(nullptr, FALSE, FALSE, nullptr))) throw "Failed to create event"sv; - if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)_event, 0, CALLBACK_EVENT) != MMSYSERR_NOERROR) throw "waveOutOpen failed"; + if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)_event, 0, CALLBACK_EVENT) != MMSYSERR_NOERROR) throw "waveOutOpen failed"sv; MxInitialize(wfex.nSamplesPerSec); for (auto &hdr : _wave_hdr) PrepareHeader(hdr); - if (nullptr == (_thread = CreateThread(nullptr, 8192, SoundThread, 0, 0, &_threadId))) throw "Failed to create thread"; - } catch (const char *error) { + if (nullptr == (_thread = CreateThread(nullptr, 8192, SoundThread, 0, 0, &_threadId))) throw "Failed to create thread"sv; + } catch (std::string_view error) { this->Stop(); return error; }