diff --git a/meson.build b/meson.build index 20f455a6..01bb3857 100644 --- a/meson.build +++ b/meson.build @@ -77,6 +77,7 @@ vst3_plugin_sources = [ 'src/common/communication/common.cpp', 'src/common/logging/common.cpp', 'src/common/logging/vst3.cpp', + 'src/common/serialization/vst3/base.cpp', 'src/common/serialization/vst3/component.cpp', 'src/common/serialization/vst3/plugin-factory.cpp', 'src/common/configuration.cpp', @@ -110,6 +111,7 @@ host_sources = [ if with_vst3 host_sources += [ 'src/common/logging/vst3.cpp', + 'src/common/serialization/vst3/base.cpp', 'src/common/serialization/vst3/component.cpp', 'src/common/serialization/vst3/plugin-factory.cpp', 'src/wine-host/bridges/vst3.cpp', diff --git a/src/common/serialization/vst3/base.cpp b/src/common/serialization/vst3/base.cpp new file mode 100644 index 00000000..afbdceff --- /dev/null +++ b/src/common/serialization/vst3/base.cpp @@ -0,0 +1,91 @@ +// yabridge: a Wine VST bridge +// Copyright (C) 2020 Robbert van der Helm +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 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 General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +#include "base.h" + +UniversalTResult::UniversalTResult(tresult native_result) + : universal_result(to_universal_result(native_result)) { + // +} + +tresult UniversalTResult::native() const { + static_assert(Steinberg::kResultOk == Steinberg::kResultTrue); + switch (universal_result) { + case Value::kNoInterface: + return Steinberg::kNoInterface; + break; + case Value::kResultOk: + return Steinberg::kResultOk; + break; + case Value::kResultFalse: + return Steinberg::kResultFalse; + break; + case Value::kInvalidArgument: + return Steinberg::kInvalidArgument; + break; + case Value::kNotImplemented: + return Steinberg::kNotImplemented; + break; + case Value::kInternalError: + return Steinberg::kInternalError; + break; + case Value::kNotInitialized: + return Steinberg::kNotInitialized; + break; + case Value::kOutOfMemory: + return Steinberg::kOutOfMemory; + break; + default: + // Shouldn't be happening + return Steinberg::kInvalidArgument; + break; + } +} + +UniversalTResult::Value UniversalTResult::to_universal_result( + tresult native_result) { + static_assert(Steinberg::kResultOk == Steinberg::kResultTrue); + switch (native_result) { + case Steinberg::kNoInterface: + return Value::kNoInterface; + break; + case Steinberg::kResultOk: + return Value::kResultOk; + break; + case Steinberg::kResultFalse: + return Value::kResultFalse; + break; + case Steinberg::kInvalidArgument: + return Value::kInvalidArgument; + break; + case Steinberg::kNotImplemented: + return Value::kNotImplemented; + break; + case Steinberg::kInternalError: + return Value::kInternalError; + break; + case Steinberg::kNotInitialized: + return Value::kNotInitialized; + break; + case Steinberg::kOutOfMemory: + return Value::kOutOfMemory; + break; + default: + // Shouldn't be happening + return Value::kInvalidArgument; + break; + } +} diff --git a/src/common/serialization/vst3/base.h b/src/common/serialization/vst3/base.h index c9d8a591..2dd19f30 100644 --- a/src/common/serialization/vst3/base.h +++ b/src/common/serialization/vst3/base.h @@ -43,3 +43,46 @@ struct Ack { template void serialize(S&) {} }; + +/** + * A wrapper around `Steinberg::tresult` that we can safely share between the + * native plugin and the Wine process. Depending on the platform and on whether + * or not the VST3 SDK is compiled to be COM compatible, the result codes may + * have three different values for the same meaning. + */ +class UniversalTResult { + public: + UniversalTResult(tresult native_result); + + /** + * Get the native equivalent for the wrapped `tresult` value. + */ + tresult native() const; + + template + void serialize(S& s) { + s.value4b(universal_result); + } + + private: + /** + * These are the non-COM compatible values copied from + * ` The actual values h ere don't matter + * but hopefully the compiler can be a bit smarter about it this way. + */ + enum class Value { + kNoInterface = -1, + kResultOk, + kResultTrue = kResultOk, + kResultFalse, + kInvalidArgument, + kNotImplemented, + kInternalError, + kNotInitialized, + kOutOfMemory + }; + + static Value to_universal_result(tresult native_result); + + Value universal_result; +};