1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2026-01-05 18:43:06 +00:00
This commit is contained in:
Andrew Lanzone 2025-07-01 12:22:35 -10:00
commit e2e8a02a26
177 changed files with 1711 additions and 763 deletions

View file

@ -73,7 +73,7 @@ jobs:
- uses: actions/checkout@v4
- name: Install Building Dependencies
run: CI/before_install.osx.sh
run: CI/before_install.macos.sh
- name: Prime ccache
uses: hendrikmuhs/ccache-action@v1
@ -82,11 +82,9 @@ jobs:
max-size: 1000M
- name: Configure
run: CI/before_script.osx.sh
run: CI/before_script.macos.sh
- name: Build
run: |
cd build
make -j $(sysctl -n hw.logicalcpu) package
run: CI/macos/build.sh
Output-Envs:
name: Read .env file and expose it as output

View file

@ -507,14 +507,15 @@ Ubuntu_GCC_integration_tests_asan:
paths:
- ccache/
script:
- CI/before_install.osx.sh
- CI/before_install.macos.sh
- export CCACHE_BASEDIR="$(pwd)"
- export CCACHE_DIR="$(pwd)/ccache"
- mkdir -pv "${CCACHE_DIR}"
- ccache -z -M "${CCACHE_SIZE}"
- CI/before_script.osx.sh
- cd build; make -j $(sysctl -n hw.logicalcpu) package
- for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${CI_COMMIT_REF_NAME##*/}.dmg"; done
- CI/macos/ccache_prep.sh
- CI/before_script.macos.sh
- CI/macos/build.sh
- cd build
- for dmg in *.dmg; do mv "$dmg" "${dmg%.dmg}_${DMG_IDENTIFIER}_${CI_COMMIT_REF_NAME##*/}.dmg"; done
- |
if [[ -n "${AWS_ACCESS_KEY_ID}" ]]; then
echo "[default]" > ~/.s3cfg
@ -529,11 +530,23 @@ Ubuntu_GCC_integration_tests_asan:
s3cmd put "${dmg}" s3://openmw-artifacts/${artifactDirectory}
done
fi
- ccache -s
- ../CI/macos/ccache_save.sh
artifacts:
paths:
- build/OpenMW-*.dmg
macOS14_Xcode15_amd64:
extends: .MacOS
image: macos-14-xcode-15
tags:
- saas-macos-medium-m1
cache:
key: macOS14_Xcode15_amd64.v2
variables:
CCACHE_SIZE: 3G
DMG_IDENTIFIER: amd64
MACOS_AMD64: true
macOS14_Xcode15_arm64:
extends: .MacOS
image: macos-14-xcode-15
@ -542,6 +555,7 @@ macOS14_Xcode15_arm64:
cache:
key: macOS14_Xcode15_arm64.v1
variables:
DMG_IDENTIFIER: arm64
CCACHE_SIZE: 3G
.Compress_And_Upload_Symbols_Base:
@ -968,7 +982,7 @@ Windows_MSBuild_CacheInit:
- flatpak build-bundle ./repo openmw.flatpak org.openmw.OpenMW.devel
cache:
key: flatpak
paths:
paths:
- ".flatpak-builder"
artifacts:
untracked: false

View file

@ -1,3 +1,7 @@
0.50.0
------
0.49.0
------
@ -236,6 +240,8 @@
Bug #8465: Blue screen w/ antialiasing and post-processing on macOS
Bug #8503: Camera does not handle NaN gracefully
Bug #8541: Lua: util.color:asHex produces wrong output for some colors
Bug #8567: Token replacement does not work via CLI and relative paths passed via the command line are not relative to the CWD
Bug #8576: Crash on exit when unresolving containers with scripted items
Feature #1415: Infinite fall failsafe
Feature #2566: Handle NAM9 records for manual cell references
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking

11
CI/before_install.macos.sh Executable file
View file

@ -0,0 +1,11 @@
#!/bin/sh -ex
export HOMEBREW_NO_EMOJI=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_AUTOREMOVE=1
if [[ "${MACOS_AMD64}" ]]; then
./CI/macos/before_install.amd64.sh
else
./CI/macos/before_install.arm64.sh
fi

View file

@ -1,29 +0,0 @@
#!/bin/sh -ex
export HOMEBREW_NO_EMOJI=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
export HOMEBREW_AUTOREMOVE=1
brew tap --repair
brew update --quiet
brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd
command -v ccache >/dev/null 2>&1 || brew install ccache
command -v cmake >/dev/null 2>&1 || brew install cmake
command -v qmake >/dev/null 2>&1 || brew install qt@6
# Install deps
brew install openal-soft icu4c yaml-cpp sqlite
ccache --version
cmake --version
qmake --version
if [[ "${MACOS_AMD64}" ]]; then
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240802.zip -o ~/openmw-deps.zip
unzip -o ~/openmw-deps.zip -d /tmp > /dev/null
else
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240818-arm64.tar.xz -o ~/openmw-deps.tar.xz
tar xf ~/openmw-deps.tar.xz -C /tmp > /dev/null
fi

77
CI/before_script.macos.sh Executable file
View file

@ -0,0 +1,77 @@
#!/bin/sh -e
# Silence a git warning
git config --global advice.detachedHead false
rm -fr build
mkdir build
cd build
DEPENDENCIES_ROOT="/tmp/openmw-deps"
if [[ "${MACOS_AMD64}" ]]; then
QT_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix qt@6)
ICU_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix icu4c)
OPENAL_PATH=$(arch -x86_64 /usr/local/bin/brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(arch -x86_64 /usr/local/bin/brew --prefix ccache)/bin/ccache
else
QT_PATH=$(brew --prefix qt@6)
ICU_PATH=$(brew --prefix icu4c)
OPENAL_PATH=$(brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
fi
declare -a CMAKE_CONF_OPTS=(
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH"
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_FLAGS="-stdlib=libc++"
-D CMAKE_C_COMPILER="clang"
-D CMAKE_CXX_COMPILER="clang++"
-D CMAKE_OSX_DEPLOYMENT_TARGET="13.6"
-D OPENMW_USE_SYSTEM_RECASTNAVIGATION=TRUE
-D Boost_INCLUDE_DIR="$DEPENDENCIES_ROOT/include"
-D OSGPlugins_LIB_DIR="$DEPENDENCIES_ROOT/lib/osgPlugins-3.6.5"
-D ICU_ROOT="$ICU_PATH"
-D OPENMW_OSX_DEPLOYMENT=TRUE
)
declare -a BUILD_OPTS=(
-D BUILD_OPENMW=TRUE
-D BUILD_OPENCS=TRUE
-D BUILD_ESMTOOL=TRUE
-D BUILD_BSATOOL=TRUE
-D BUILD_ESSIMPORTER=TRUE
-D BUILD_NIFTEST=TRUE
-D BUILD_NAVMESHTOOL=TRUE
-D BUILD_BULLETOBJECTTOOL=TRUE
-G"Unix Makefiles"
)
if [[ "${MACOS_AMD64}" ]]; then
CMAKE_CONF_OPTS+=(
-D CMAKE_OSX_ARCHITECTURES="x86_64"
)
fi
if [[ "${CMAKE_BUILD_TYPE}" ]]; then
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
)
else
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=RelWithDebInfo
)
fi
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 cmake \
"${CMAKE_CONF_OPTS[@]}" \
"${BUILD_OPTS[@]}" \
..
else
cmake \
"${CMAKE_CONF_OPTS[@]}" \
"${BUILD_OPTS[@]}" \
..
fi

View file

@ -1,53 +0,0 @@
#!/bin/sh -e
# Silence a git warning
git config --global advice.detachedHead false
rm -fr build
mkdir build
cd build
DEPENDENCIES_ROOT="/tmp/openmw-deps"
QT_PATH=$(brew --prefix qt@6)
ICU_PATH=$(brew --prefix icu4c)
OPENAL_PATH=$(brew --prefix openal-soft)
CCACHE_EXECUTABLE=$(brew --prefix ccache)/bin/ccache
declare -a CMAKE_CONF_OPTS=(
-D CMAKE_PREFIX_PATH="$DEPENDENCIES_ROOT;$QT_PATH;$OPENAL_PATH"
-D CMAKE_C_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_COMPILER_LAUNCHER="$CCACHE_EXECUTABLE"
-D CMAKE_CXX_FLAGS="-stdlib=libc++"
-D CMAKE_C_COMPILER="clang"
-D CMAKE_CXX_COMPILER="clang++"
-D CMAKE_OSX_DEPLOYMENT_TARGET="13.6"
-D OPENMW_USE_SYSTEM_RECASTNAVIGATION=TRUE
-D Boost_INCLUDE_DIR="$DEPENDENCIES_ROOT/include"
-D OSGPlugins_LIB_DIR="$DEPENDENCIES_ROOT/lib/osgPlugins-3.6.5"
-D ICU_ROOT="$ICU_PATH"
-D OPENMW_OSX_DEPLOYMENT=TRUE
)
if [[ "${CMAKE_BUILD_TYPE}" ]]; then
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
)
else
CMAKE_CONF_OPTS+=(
-D CMAKE_BUILD_TYPE=RelWithDebInfo
)
fi
cmake \
"${CMAKE_CONF_OPTS[@]}" \
-D BUILD_OPENMW=TRUE \
-D BUILD_OPENCS=TRUE \
-D BUILD_ESMTOOL=TRUE \
-D BUILD_BSATOOL=TRUE \
-D BUILD_ESSIMPORTER=TRUE \
-D BUILD_NIFTEST=TRUE \
-D BUILD_NAVMESHTOOL=TRUE \
-D BUILD_BULLETOBJECTTOOL=TRUE \
-G"Unix Makefiles" \
..

View file

@ -1,7 +1,6 @@
#!/bin/bash -ex
git ls-files -- ':(exclude)extern/' '*.cpp' '*.hpp' '*.h' |
grep -vP '/[a-z0-9]+\.(cpp|hpp|h)$' |
grep -vFf CI/file_name_exceptions.txt &&
grep -vP '/[a-z0-9]+\.(cpp|hpp|h)$' &&
( echo 'File names do not follow the naming convention, see https://wiki.openmw.org/index.php?title=Naming_Conventions#Files'; exit -1 )
exit 0

View file

@ -1,48 +0,0 @@
apps/openmw/android_main.cpp
apps/openmw/mwsound/efx-presets.h
apps/openmw/mwsound/ffmpeg_decoder.cpp
apps/openmw/mwsound/ffmpeg_decoder.hpp
apps/openmw/mwsound/openal_output.cpp
apps/openmw/mwsound/openal_output.hpp
apps/openmw/mwsound/sound_buffer.cpp
apps/openmw/mwsound/sound_buffer.hpp
apps/openmw/mwsound/sound_decoder.hpp
apps/openmw/mwsound/sound_output.hpp
apps/components_tests/esm/test_fixed_string.cpp
apps/components_tests/files/conversion_tests.cpp
apps/components_tests/lua/test_async.cpp
apps/components_tests/lua/test_configuration.cpp
apps/components_tests/lua/test_l10n.cpp
apps/components_tests/lua/test_lua.cpp
apps/components_tests/lua/test_scriptscontainer.cpp
apps/components_tests/lua/test_serialization.cpp
apps/components_tests/lua/test_storage.cpp
apps/components_tests/lua/test_ui_content.cpp
apps/components_tests/lua/test_utilpackage.cpp
apps/components_tests/lua/test_inputactions.cpp
apps/components_tests/lua/test_yaml.cpp
apps/components_tests/misc/test_endianness.cpp
apps/components_tests/misc/test_resourcehelpers.cpp
apps/components_tests/misc/test_stringops.cpp
apps/openmw_tests/mwdialogue/test_keywordsearch.cpp
apps/openmw_tests/mwscript/test_scripts.cpp
apps/openmw_tests/mwscript/test_utils.hpp
apps/openmw_tests/mwworld/test_store.cpp
components/bsa/bsa_file.cpp
components/bsa/bsa_file.hpp
components/crashcatcher/windows_crashcatcher.cpp
components/crashcatcher/windows_crashcatcher.hpp
components/crashcatcher/windows_crashmonitor.cpp
components/crashcatcher/windows_crashmonitor.hpp
components/crashcatcher/windows_crashshm.hpp
components/fx/lexer_types.hpp
components/fx/parse_constants.hpp
components/platform/file.posix.cpp
components/platform/file.stdio.cpp
components/platform/file.win32.cpp
components/sdlutil/gl4es_init.cpp
components/sdlutil/gl4es_init.h
components/to_utf8/gen_iconv.cpp
components/to_utf8/tables_gen.hpp
components/to_utf8/to_utf8.cpp
components/to_utf8/to_utf8.hpp

View file

@ -0,0 +1,8 @@
#!/bin/sh -ex
arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
arch -x86_64 /usr/local/bin/brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd ccache cmake qt@6 openal-soft icu4c yaml-cpp sqlite
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240802.zip -o ~/openmw-deps.zip
unzip -o ~/openmw-deps.zip -d /tmp > /dev/null

View file

@ -0,0 +1,16 @@
#!/bin/sh -ex
brew tap --repair
brew update --quiet
brew install curl xquartz gd fontconfig freetype harfbuzz brotli s3cmd
command -v ccache >/dev/null 2>&1 || brew install ccache
command -v cmake >/dev/null 2>&1 || brew install cmake
command -v qmake >/dev/null 2>&1 || brew install qt@6
# Install deps
brew install openal-soft icu4c yaml-cpp sqlite
curl -fSL -R -J https://gitlab.com/OpenMW/openmw-deps/-/raw/main/macos/openmw-deps-20240818-arm64.tar.xz -o ~/openmw-deps.tar.xz
tar xf ~/openmw-deps.tar.xz -C /tmp > /dev/null

9
CI/macos/build.sh Executable file
View file

@ -0,0 +1,9 @@
#!/bin/sh -ex
cd build
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 make -j $(sysctl -n hw.logicalcpu) package
else
make -j $(sysctl -n hw.logicalcpu) package
fi

7
CI/macos/ccache_prep.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh -ex
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 ccache -z -M "${CCACHE_SIZE}"
else
ccache -z -M "${CCACHE_SIZE}"
fi

7
CI/macos/ccache_save.sh Executable file
View file

@ -0,0 +1,7 @@
#!/bin/sh -ex
if [[ "${MACOS_AMD64}" ]]; then
arch -x86_64 ccache -s
else
ccache -s
fi

View file

@ -80,7 +80,7 @@ endif()
message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 49)
set(OPENMW_VERSION_MINOR 50)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_LUA_API_REVISION 76)
set(OPENMW_POSTPROCESSING_API_REVISION 2)

View file

@ -5,7 +5,7 @@ OpenMW is an open-source open-world RPG game engine that supports playing Morrow
OpenMW also comes with OpenMW-CS, a replacement for Bethesda's Construction Set.
* Version: 0.49.0
* Version: 0.50.0
* License: GPLv3 (see [LICENSE](https://gitlab.com/OpenMW/openmw/-/raw/master/LICENSE) for more information)
* Website: https://www.openmw.org
* IRC: #openmw on irc.libera.chat

View file

@ -20,7 +20,7 @@
#include <components/resource/niffilemanager.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/settings/settings.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include <components/version/version.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp>
@ -125,6 +125,7 @@ namespace
}
Files::ConfigurationManager config;
config.processPaths(variables, std::filesystem::current_path());
config.readConfiguration(variables, desc);
Debug::setupLogging(config.getLogPath(), applicationName);

View file

@ -4,29 +4,28 @@ include_directories(SYSTEM ${GMOCK_INCLUDE_DIRS})
file(GLOB UNITTEST_SRC_FILES
main.cpp
esm/test_fixed_string.cpp
esm/variant.cpp
esm/testfixedstring.cpp
esm/testrefid.cpp
esm/variant.cpp
lua/test_lua.cpp
lua/test_scriptscontainer.cpp
lua/test_utilpackage.cpp
lua/test_serialization.cpp
lua/test_configuration.cpp
lua/test_l10n.cpp
lua/test_storage.cpp
lua/test_async.cpp
lua/test_inputactions.cpp
lua/test_yaml.cpp
lua/test_ui_content.cpp
lua/testasync.cpp
lua/testconfiguration.cpp
lua/testinputactions.cpp
lua/testl10n.cpp
lua/testlua.cpp
lua/testscriptscontainer.cpp
lua/testserialization.cpp
lua/teststorage.cpp
lua/testuicontent.cpp
lua/testutilpackage.cpp
lua/testyaml.cpp
misc/compression.cpp
misc/progressreporter.cpp
misc/test_endianness.cpp
misc/test_resourcehelpers.cpp
misc/test_stringops.cpp
misc/testendianness.cpp
misc/testmathutil.cpp
misc/testresourcehelpers.cpp
misc/teststringops.cpp
nifloader/testbulletnifloader.cpp
@ -64,8 +63,8 @@ file(GLOB UNITTEST_SRC_FILES
esmloader/esmdata.cpp
esmloader/record.cpp
files/conversiontests.cpp
files/hash.cpp
files/conversion_tests.cpp
toutf8/toutf8.cpp

View file

@ -10,7 +10,7 @@
#include <components/esmloader/load.hpp>
#include <components/files/collections.hpp>
#include <components/files/multidircollection.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include <gtest/gtest.h>

View file

@ -1,5 +1,5 @@
#include <components/misc/strings/conversion.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include <gtest/gtest.h>

View file

@ -15,7 +15,7 @@
#include <components/esm4/readerutils.hpp>
#include <components/esm4/records.hpp>
#include <components/esm4/typetraits.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
namespace EsmTool
{

View file

@ -25,7 +25,7 @@
#include <components/misc/constants.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "importercontext.hpp"

View file

@ -40,6 +40,7 @@ Allowed options)");
bpo::notify(variables);
Files::ConfigurationManager cfgManager(true);
cfgManager.processPaths(variables, std::filesystem::current_path());
cfgManager.readConfiguration(variables, desc);
const auto& essFile = variables["mwsave"].as<Files::MaybeQuotedPath>();

View file

@ -8,7 +8,7 @@
#include <string>
#include <vector>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
class MwIniImporter
{

View file

@ -25,7 +25,7 @@
#include <components/resource/niffilemanager.hpp>
#include <components/resource/scenemanager.hpp>
#include <components/settings/values.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include <components/version/version.hpp>
#include <components/vfs/manager.hpp>
#include <components/vfs/registerarchives.hpp>
@ -143,6 +143,7 @@ namespace NavMeshTool
}
Files::ConfigurationManager config;
config.processPaths(variables, std::filesystem::current_path());
config.readConfiguration(variables, desc);
Debug::setupLogging(config.getLogPath(), applicationName);

View file

@ -34,7 +34,7 @@
#include <components/misc/rng.hpp>
#include <components/nifosg/nifloader.hpp>
#include <components/settings/settings.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "view/doc/viewmanager.hpp"

View file

@ -12,7 +12,7 @@
#include <apps/opencs/model/world/universalid.hpp>
#include <components/files/multidircollection.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "../world/data.hpp"
#include "../world/idcompletionmanager.hpp"

View file

@ -9,7 +9,7 @@
#include <vector>
#include <components/files/multidircollection.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "loader.hpp"

View file

@ -2,11 +2,8 @@
#include <utility>
#if defined(Q_OS_MAC)
#include <QCoreApplication>
#include <QDir>
#endif
#include <QProcess>
#include <QString>
#include <QStringList>
@ -55,16 +52,17 @@ void CSMDoc::Runner::start(bool delayed)
QString path = "openmw";
#ifdef Q_OS_WIN
path.append(QString(".exe"));
#elif defined(Q_OS_MAC)
QDir dir(QCoreApplication::applicationDirPath());
dir.cdUp();
dir.cdUp();
dir.cdUp();
path = dir.absoluteFilePath(path.prepend("OpenMW.app/Contents/MacOS/"));
#else
path.prepend(QString("./"));
path.append(QLatin1String(".exe"));
#endif
QDir dir(QCoreApplication::applicationDirPath());
#ifdef Q_OS_MAC
// the CS and engine are in separate .app directories
dir.cdUp();
dir.cdUp();
dir.cdUp();
path.prepend("OpenMW.app/Contents/MacOS/");
#endif
path = dir.absoluteFilePath(path);
mStartup = new QTemporaryFile(this);
mStartup->open();

View file

@ -3,7 +3,7 @@
#include <QObject>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "operation.hpp"
#include "savingstate.hpp"

View file

@ -9,7 +9,7 @@
#include <components/esm3/esmwriter.hpp>
#include <components/misc/algorithm.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
namespace CSMDoc
{

View file

@ -78,7 +78,7 @@ namespace CSMPrefs
}
}
bool ShortcutManager::getModifier(const std::string& name, int& modifier) const
bool ShortcutManager::getModifier(std::string_view name, int& modifier) const
{
ModifierMap::const_iterator item = mModifiers.find(name);
if (item != mModifiers.end())
@ -175,14 +175,14 @@ namespace CSMPrefs
return concat;
}
void ShortcutManager::convertFromString(const std::string& data, QKeySequence& sequence) const
void ShortcutManager::convertFromString(std::string_view data, QKeySequence& sequence) const
{
const int MaxKeys = 4; // A limitation of QKeySequence
size_t end = data.find(';');
size_t size = std::min(end, data.size());
std::string value = data.substr(0, size);
std::string_view value = data.substr(0, size);
size_t start = 0;
int keyPos = 0;
@ -195,7 +195,7 @@ namespace CSMPrefs
end = data.find('+', start);
end = std::min(end, value.size());
std::string name = value.substr(start, end - start);
std::string_view name = value.substr(start, end - start);
if (name == "Ctrl")
{
@ -242,12 +242,12 @@ namespace CSMPrefs
sequence = QKeySequence(keys[0], keys[1], keys[2], keys[3]);
}
void ShortcutManager::convertFromString(const std::string& data, int& modifier) const
void ShortcutManager::convertFromString(std::string_view data, int& modifier) const
{
size_t start = data.find(';') + 1;
start = std::min(start, data.size());
std::string name = data.substr(start);
std::string_view name = data.substr(start);
KeyMap::const_iterator searchResult = mKeys.find(name);
if (searchResult != mKeys.end())
{
@ -259,7 +259,7 @@ namespace CSMPrefs
}
}
void ShortcutManager::convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const
void ShortcutManager::convertFromString(std::string_view data, QKeySequence& sequence, int& modifier) const
{
convertFromString(data, sequence);
convertFromString(data, modifier);

View file

@ -31,7 +31,7 @@ namespace CSMPrefs
bool getSequence(std::string_view name, QKeySequence& sequence) const;
void setSequence(std::string_view name, const QKeySequence& sequence);
bool getModifier(const std::string& name, int& modifier) const;
bool getModifier(std::string_view name, int& modifier) const;
void setModifier(std::string_view name, int modifier);
std::string convertToString(const QKeySequence& sequence) const;
@ -39,10 +39,10 @@ namespace CSMPrefs
std::string convertToString(const QKeySequence& sequence, int modifier) const;
void convertFromString(const std::string& data, QKeySequence& sequence) const;
void convertFromString(const std::string& data, int& modifier) const;
void convertFromString(std::string_view data, QKeySequence& sequence) const;
void convertFromString(std::string_view data, int& modifier) const;
void convertFromString(const std::string& data, QKeySequence& sequence, int& modifier) const;
void convertFromString(std::string_view data, QKeySequence& sequence, int& modifier) const;
/// Replaces "{sequence-name}" or "{modifier-name}" with the appropriate text
QString processToolTip(const QString& toolTip) const;
@ -53,7 +53,7 @@ namespace CSMPrefs
typedef std::map<std::string, QKeySequence, std::less<>> SequenceMap;
typedef std::map<std::string, int, std::less<>> ModifierMap;
typedef std::map<int, std::string> NameMap;
typedef std::map<std::string, int> KeyMap;
typedef std::map<std::string, int, std::less<>> KeyMap;
ShortcutMap mShortcuts;
SequenceMap mSequences;

View file

@ -498,7 +498,7 @@ CSMPrefs::ShortcutSetting& CSMPrefs::State::declareShortcut(
// Setup with actual data
QKeySequence sequence;
getShortcutManager().convertFromString(value, sequence);
getShortcutManager().convertFromString(value.get(), sequence);
getShortcutManager().setSequence(value.mName, sequence);
CSMPrefs::ShortcutSetting* setting

View file

@ -3,7 +3,7 @@
#include <memory>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "../doc/operation.hpp"

View file

@ -9,7 +9,7 @@
#include <apps/opencs/model/world/idcollection.hpp>
#include <apps/opencs/model/world/record.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "../doc/stage.hpp"

View file

@ -6,7 +6,7 @@
#include <apps/opencs/model/world/universalid.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include <QObject>

View file

@ -38,7 +38,7 @@
#include <components/esm3/selectiongroup.hpp>
#include <components/files/multidircollection.hpp>
#include <components/misc/algorithm.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "cell.hpp"
#include "idcollection.hpp"

View file

@ -171,16 +171,18 @@ osg::Vec3f CSVRender::InstanceMode::getProjectionSpaceCoords(const osg::Vec3f& p
osg::Vec3f CSVRender::InstanceMode::getMousePlaneCoords(const QPoint& point, const osg::Vec3d& dragStart)
{
osg::Matrix viewMatrix;
viewMatrix.invert(getWorldspaceWidget().getCamera()->getViewMatrix());
osg::Matrix projMatrix;
projMatrix.invert(getWorldspaceWidget().getCamera()->getProjectionMatrix());
osg::Matrix combined = projMatrix * viewMatrix;
const osg::Matrix viewMatrix = getWorldspaceWidget().getCamera()->getViewMatrix();
const osg::Matrix projMatrix = getWorldspaceWidget().getCamera()->getProjectionMatrix();
const osg::Matrix combined = osg::Matrix::inverse(viewMatrix * projMatrix);
/* calculate viewport normalized coordinates
note: is there a reason to use getCamera()->getViewport()->computeWindowMatrix() instead? */
float x = (point.x() * 2) / getWorldspaceWidget().getCamera()->getViewport()->width() - 1.0f;
float y = 1.0f - (point.y() * 2) / getWorldspaceWidget().getCamera()->getViewport()->height();
const float scale = getWorldspaceWidget().devicePixelRatioF();
const osg::Viewport* viewport = getWorldspaceWidget().getCamera()->getViewport();
float x = point.x() * scale / viewport->width();
float y = point.y() * scale / viewport->height();
x = x * 2.0f - 1.0f;
y = 1.0f - y * 2.0f;
osg::Vec3f mousePlanePoint = osg::Vec3f(x, y, dragStart.z()) * combined;

View file

@ -15,7 +15,7 @@ set(OPENMW_HEADERS
profile.hpp
)
source_group(apps/openmw FILES main.cpp android_main.cpp ${OPENMW_SOURCES} ${OPENMW_HEADERS} ${OPENMW_RESOURCES})
source_group(apps/openmw FILES main.cpp androidmain.cpp ${OPENMW_SOURCES} ${OPENMW_HEADERS} ${OPENMW_RESOURCES})
add_openmw_dir (mwrender
actors objects renderingmanager animation rotatecontroller sky skyutil npcanimation esm4npcanimation vismask
@ -71,8 +71,8 @@ add_openmw_dir (mwlua
)
add_openmw_dir (mwsound
soundmanagerimp openal_output ffmpeg_decoder sound sound_buffer sound_decoder sound_output
loudness movieaudiofactory alext efx efx-presets regionsoundselector watersoundupdater
soundmanagerimp openaloutput ffmpegdecoder sound soundbuffer sounddecoder soundoutput
loudness movieaudiofactory alext efx efxpresets regionsoundselector watersoundupdater
)
add_openmw_dir (mwworld
@ -127,7 +127,7 @@ if(BUILD_OPENMW)
if (ANDROID)
add_library(openmw SHARED
main.cpp
android_main.cpp
androidmain.cpp
)
else()
openmw_add_executable(openmw
@ -138,6 +138,12 @@ if(BUILD_OPENMW)
endif()
target_link_libraries(openmw openmw-lib)
# Workaround necessary to ensure osgAnimation::MatrixLinearSampler dynamic casts work under Clang
# NOTE: it's unclear whether the broken behavior is spec-compliant
if (CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set_target_properties(openmw PROPERTIES ENABLE_EXPORTS ON)
endif()
endif()
# Sound stuff - here so CMake doesn't stupidly recompile EVERYTHING

View file

@ -404,8 +404,8 @@ OMW::Engine::~Engine()
mMechanicsManager = nullptr;
mDialogueManager = nullptr;
mJournal = nullptr;
mScriptManager = nullptr;
mWindowManager = nullptr;
mScriptManager = nullptr;
mWorld = nullptr;
mStereoManager = nullptr;
mSoundManager = nullptr;

View file

@ -61,6 +61,8 @@ bool parseOptions(int argc, char** argv, OMW::Engine& engine, Files::Configurati
return false;
}
cfgMgr.processPaths(variables, std::filesystem::current_path());
cfgMgr.readConfiguration(variables, desc);
Debug::setupLogging(cfgMgr.getLogPath(), "OpenMW");

View file

@ -39,8 +39,8 @@ namespace MWSound
class Sound;
class Stream;
struct Sound_Decoder;
typedef std::shared_ptr<Sound_Decoder> DecoderPtr;
struct SoundDecoder;
typedef std::shared_ptr<SoundDecoder> DecoderPtr;
/* These must all fit together */
enum class PlayMode

View file

@ -265,10 +265,6 @@ bool MWDialogue::Filter::testFunctionLocal(const MWDialogue::SelectWrapper& sele
bool MWDialogue::Filter::testSelectStruct(const SelectWrapper& select) const
{
if (select.isNpcOnly() && (mActor.getType() != ESM::NPC::sRecordId))
// If the actor is a creature, we pass all conditions only applicable to NPCs.
return true;
if (select.getFunction() == ESM::DialogueCondition::Function_Choice && mChoice == -1)
// If not currently in a choice, we reject all conditions that test against choices.
return false;
@ -305,9 +301,13 @@ bool MWDialogue::Filter::testSelectStructNumeric(const SelectWrapper& select) co
switch (select.getFunction())
{
case ESM::DialogueCondition::Function_Global:
{
const auto& world = MWBase::Environment::get().getWorld();
if (world->getGlobalVariableType(select.getName()) == ' ')
return true; // ignore this filter if the global doesn't exist
// internally all globals are float :(
return select.selectCompare(MWBase::Environment::get().getWorld()->getGlobalFloat(select.getName()));
return select.selectCompare(world->getGlobalFloat(select.getName()));
}
case ESM::DialogueCondition::Function_Local:
{
@ -504,7 +504,8 @@ int MWDialogue::Filter::getSelectStructInteger(const SelectWrapper& select) cons
return MWBase::Environment::get().getWorld()->getCurrentWeather();
case ESM::DialogueCondition::Function_Reputation:
if (!mActor.getClass().isNpc())
return 0;
return mActor.getClass().getNpcStats(mActor).getReputation();
case ESM::DialogueCondition::Function_FactionRankDifference:
@ -586,11 +587,11 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con
case ESM::DialogueCondition::Function_NotClass:
return mActor.get<ESM::NPC>()->mBase->mClass != select.getId();
return !mActor.getClass().isNpc() || mActor.get<ESM::NPC>()->mBase->mClass != select.getId();
case ESM::DialogueCondition::Function_NotRace:
return mActor.get<ESM::NPC>()->mBase->mRace != select.getId();
return !mActor.getClass().isNpc() || mActor.get<ESM::NPC>()->mBase->mRace != select.getId();
case ESM::DialogueCondition::Function_NotCell:
{
@ -598,12 +599,14 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con
return !Misc::StringUtils::ciStartsWith(actorCell, select.getCellName());
}
case ESM::DialogueCondition::Function_SameSex:
if (!mActor.getClass().isNpc())
return false;
return (player.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female)
== (mActor.get<ESM::NPC>()->mBase->mFlags & ESM::NPC::Female);
case ESM::DialogueCondition::Function_SameRace:
if (!mActor.getClass().isNpc())
return false;
return mActor.get<ESM::NPC>()->mBase->mRace == player.get<ESM::NPC>()->mBase->mRace;
case ESM::DialogueCondition::Function_SameFaction:
@ -668,7 +671,7 @@ bool MWDialogue::Filter::getSelectStructBoolean(const SelectWrapper& select) con
case ESM::DialogueCondition::Function_Werewolf:
return mActor.getClass().getNpcStats(mActor).isWerewolf();
return mActor.getClass().isNpc() && mActor.getClass().getNpcStats(mActor).isWerewolf();
default:

View file

@ -247,29 +247,6 @@ MWDialogue::SelectWrapper::Type MWDialogue::SelectWrapper::getType() const
};
}
bool MWDialogue::SelectWrapper::isNpcOnly() const
{
switch (mSelect.mFunction)
{
case ESM::DialogueCondition::Function_NotFaction:
case ESM::DialogueCondition::Function_NotClass:
case ESM::DialogueCondition::Function_NotRace:
case ESM::DialogueCondition::Function_SameSex:
case ESM::DialogueCondition::Function_SameRace:
case ESM::DialogueCondition::Function_SameFaction:
case ESM::DialogueCondition::Function_RankRequirement:
case ESM::DialogueCondition::Function_Reputation:
case ESM::DialogueCondition::Function_FactionRankDifference:
case ESM::DialogueCondition::Function_Werewolf:
case ESM::DialogueCondition::Function_PcWerewolfKills:
case ESM::DialogueCondition::Function_FacReactionLowest:
case ESM::DialogueCondition::Function_FacReactionHighest:
return true;
default:
return false;
}
}
bool MWDialogue::SelectWrapper::selectCompare(int value) const
{
return selectCompareImp(mSelect, value);

View file

@ -28,9 +28,6 @@ namespace MWDialogue
Type getType() const;
bool isNpcOnly() const;
///< \attention Do not call any of the select functions for this select struct!
bool selectCompare(int value) const;
bool selectCompare(float value) const;

View file

@ -4,7 +4,7 @@
#include "bookpage.hpp"
#include "journalviewmodel.hpp"
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
namespace MWGui
{

View file

@ -3,7 +3,7 @@
#include "windowbase.hpp"
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include <memory>

View file

@ -83,7 +83,7 @@ namespace MWGui
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mActor, x, true);
std::string name{ iter->getClass().getName(*iter) };
name += " - " + MyGUI::utility::toString(price)
name += " - " + MyGUI::utility::toString(price)
+ MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>().find("sgp")->mValue.getString();
items.emplace_back(name, price, *iter);

View file

@ -101,8 +101,8 @@ namespace MWGui
{
MWBase::Environment::get().getMechanicsManager()->commitCrime(
player, mActor, MWBase::MechanicsManager::OT_Pickpocket, ESM::RefId(), 0, true);
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
mPickpocketDetected = true;
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
}
}
@ -129,8 +129,8 @@ namespace MWGui
{
MWBase::Environment::get().getMechanicsManager()->commitCrime(
player, mActor, MWBase::MechanicsManager::OT_Pickpocket, ESM::RefId(), 0, true);
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
mPickpocketDetected = true;
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Container);
return false;
}
else

View file

@ -434,6 +434,9 @@ namespace MWGui
}
store.setSelectedEnchantItem(it);
// to reset WindowManager::mSelectedSpell immediately
MWBase::Environment::get().getWindowManager()->setSelectedEnchantItem(*it);
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState::Spell);
}
}
@ -461,6 +464,9 @@ namespace MWGui
store.unequipSlot(MWWorld::InventoryStore::Slot_CarriedRight);
MWBase::Environment::get().getWorld()->getPlayer().setDrawState(MWMechanics::DrawState::Weapon);
}
// Updates the state of equipped/not equipped (skin) in spellwindow
MWBase::Environment::get().getWindowManager()->updateSpellWindow();
}
bool QuickKeysMenu::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)

View file

@ -45,6 +45,7 @@ namespace MWGui
{
getWidget(mScreenshot, "Screenshot");
getWidget(mCharacterSelection, "SelectCharacter");
getWidget(mCellName, "CellName");
getWidget(mInfoText, "InfoText");
getWidget(mOkButton, "OkButton");
getWidget(mCancelButton, "CancelButton");
@ -230,7 +231,8 @@ namespace MWGui
title << " (#{OMWEngine:Level} " << signature.mPlayerLevel << " "
<< MyGUI::TextIterator::toTagsString(MyGUI::UString(className)) << ")";
mCharacterSelection->addItem(MyGUI::LanguageManager::getInstance().replaceTags(title.str()));
const MyGUI::UString playerDesc = MyGUI::LanguageManager::getInstance().replaceTags(title.str());
mCharacterSelection->addItem(playerDesc, signature.mPlayerName);
if (mCurrentCharacter == &*it
|| (!mCurrentCharacter && !mSaving
@ -424,6 +426,7 @@ namespace MWGui
if (pos == MyGUI::ITEM_NONE || !mCurrentCharacter)
{
mCurrentSlot = nullptr;
mCellName->setCaption({});
mInfoText->setCaption({});
mScreenshot->setImageTexture({});
return;
@ -445,15 +448,21 @@ namespace MWGui
std::stringstream text;
text << Misc::fileTimeToString(mCurrentSlot->mTimeStamp, "%Y.%m.%d %T") << "\n";
const size_t profileIndex = mCharacterSelection->getIndexSelected();
const std::string& slotPlayerName = mCurrentSlot->mProfile.mPlayerName;
const std::string& profilePlayerName = *mCharacterSelection->getItemDataAt<std::string>(profileIndex);
if (slotPlayerName != profilePlayerName)
text << slotPlayerName << "\n";
text << "#{OMWEngine:Level} " << mCurrentSlot->mProfile.mPlayerLevel << "\n";
if (mCurrentSlot->mProfile.mCurrentDay > 0)
text << "#{Calendar:day} " << mCurrentSlot->mProfile.mCurrentDay << "\n";
if (mCurrentSlot->mProfile.mMaximumHealth > 0)
text << "#{OMWEngine:Health} " << static_cast<int>(mCurrentSlot->mProfile.mCurrentHealth) << "/"
<< static_cast<int>(mCurrentSlot->mProfile.mMaximumHealth) << "\n";
text << "#{OMWEngine:Level} " << mCurrentSlot->mProfile.mPlayerLevel << "\n";
text << "#{sCell=" << mCurrentSlot->mProfile.mPlayerCellName << "}\n";
int hour = int(mCurrentSlot->mProfile.mInGameTime.mGameHour);
bool pm = hour >= 12;
if (hour >= 13)
@ -461,20 +470,19 @@ namespace MWGui
if (hour == 0)
hour = 12;
if (mCurrentSlot->mProfile.mCurrentDay > 0)
text << "#{Calendar:day} " << mCurrentSlot->mProfile.mCurrentDay << "\n";
text << mCurrentSlot->mProfile.mInGameTime.mDay << " "
<< MWBase::Environment::get().getWorld()->getTimeManager()->getMonthName(
mCurrentSlot->mProfile.mInGameTime.mMonth)
<< " " << hour << " " << (pm ? "#{Calendar:pm}" : "#{Calendar:am}");
<< " " << hour << " " << (pm ? "#{Calendar:pm}" : "#{Calendar:am}") << "\n";
if (mCurrentSlot->mProfile.mTimePlayed > 0)
{
text << "\n"
<< "#{OMWEngine:TimePlayed}: " << formatTimeplayed(mCurrentSlot->mProfile.mTimePlayed);
text << "#{OMWEngine:TimePlayed}: " << formatTimeplayed(mCurrentSlot->mProfile.mTimePlayed) << "\n";
}
text << Misc::fileTimeToString(mCurrentSlot->mTimeStamp, "%Y.%m.%d %T") << "\n";
mCellName->setCaptionWithReplacing("#{sCell=" + mCurrentSlot->mProfile.mPlayerCellName + "}");
mInfoText->setCaptionWithReplacing(text.str());
// Reset the image for the case we're unable to recover a screenshot

View file

@ -59,6 +59,7 @@ namespace MWGui
bool mSaving;
MyGUI::ComboBox* mCharacterSelection;
MyGUI::EditBox* mCellName;
MyGUI::EditBox* mInfoText;
MyGUI::Button* mOkButton;
MyGUI::Button* mCancelButton;

View file

@ -20,6 +20,7 @@
#include "../mwmechanics/actorutil.hpp"
#include "../mwmechanics/creaturestats.hpp"
#include "../mwmechanics/spells.hpp"
#include "../mwmechanics/spellutil.hpp"
namespace MWGui
{
@ -52,8 +53,8 @@ namespace MWGui
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
int price = std::max(1,
static_cast<int>(
spell.mData.mCost * store.get<ESM::GameSetting>().find("fSpellValueMult")->mValue.getFloat()));
static_cast<int>(MWMechanics::calcSpellCost(spell)
* store.get<ESM::GameSetting>().find("fSpellValueMult")->mValue.getFloat()));
price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(mPtr, price, true);
MWWorld::Ptr player = MWMechanics::getPlayer();
@ -71,7 +72,7 @@ namespace MWGui
mCurrentY += lineHeight;
toAdd->setUserData(price);
toAdd->setCaptionWithReplacing(spell.mName + " - " + MyGUI::utility::toString(price) + "#{sgp}");
toAdd->setCaptionWithReplacing(spell.mName + " - " + MyGUI::utility::toString(price) + "#{sgp}");
toAdd->setSize(mSpellsView->getWidth(), lineHeight);
toAdd->eventMouseWheel += MyGUI::newDelegate(this, &SpellBuyingWindow::onMouseWheel);
toAdd->setUserString("ToolTipType", "Spell");

View file

@ -252,22 +252,51 @@ namespace MWGui
return;
mSpellView->setModel(new SpellModel(MWMechanics::getPlayer()));
SpellModel::ModelIndex selected = mSpellView->getModel()->getSelectedIndex();
if (selected < 0)
selected = 0;
selected += next ? 1 : -1;
int itemcount = mSpellView->getModel()->getItemCount();
if (itemcount == 0)
int itemCount = mSpellView->getModel()->getItemCount();
if (itemCount == 0)
return;
selected = (selected + itemcount) % itemcount;
const Spell& spell = mSpellView->getModel()->getItem(selected);
if (spell.mType == Spell::Type_EnchantedItem)
onEnchantedItemSelected(spell.mItem, spell.mActive);
SpellModel::ModelIndex nextIndex;
SpellModel::ModelIndex currentIndex = mSpellView->getModel()->getSelectedIndex();
// If we have a selected index, search for a valid selection in the target direction
if (currentIndex >= 0)
{
MWWorld::ContainerStore store;
const Spell& currentSpell = mSpellView->getModel()->getItem(currentIndex);
nextIndex = currentIndex;
for (int i = 0; i < itemCount; i++)
{
nextIndex += next ? 1 : -1;
nextIndex = (nextIndex + itemCount) % itemCount;
// We can keep this selection if:
// * we're not switching off of an enchanted item
// * we're not switching to an enchanted item
// * the next item wouldn't stack with the current item
if (currentSpell.mType != Spell::Type_EnchantedItem)
break;
const Spell& nextSpell = mSpellView->getModel()->getItem(nextIndex);
if (nextSpell.mType != Spell::Type_EnchantedItem || !store.stacks(currentSpell.mItem, nextSpell.mItem))
break;
}
}
// Otherwise, the first selection is always index 0
else
onSpellSelected(spell.mId);
nextIndex = 0;
// Only trigger the selection event if the selection is actually changing.
// The itemCount check earlier ensures we have at least one spell to select.
if (nextIndex != currentIndex)
{
const Spell& selectedSpell = mSpellView->getModel()->getItem(nextIndex);
if (selectedSpell.mType == Spell::Type_EnchantedItem)
onEnchantedItemSelected(selectedSpell.mItem, selectedSpell.mActive);
else
onSpellSelected(selectedSpell.mId);
}
}
bool SpellWindow::onControllerButtonEvent(const SDL_ControllerButtonEvent& arg)

View file

@ -33,16 +33,10 @@ namespace MWGui
{
getWidget(mCancelButton, "CancelButton");
getWidget(mPlayerGold, "PlayerGold");
getWidget(mSelect, "Select");
getWidget(mDestinations, "Travel");
getWidget(mDestinationsView, "DestinationsView");
mCancelButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TravelWindow::onCancelButtonClicked);
mDestinations->setCoord(450 / 2 - mDestinations->getTextSize().width / 2, mDestinations->getTop(),
mDestinations->getTextSize().width, mDestinations->getHeight());
mSelect->setCoord(8, mSelect->getTop(), mSelect->getTextSize().width, mSelect->getHeight());
if (Settings::gui().mControllerMenus)
{
mDisableGamepadCursor = true;
@ -100,8 +94,7 @@ namespace MWGui
const std::string& nameString = name.getRefIdString();
toAdd->setUserString("price", std::to_string(price));
toAdd->setCaptionWithReplacing(
"#{sCell=" + nameString + "} - " + MyGUI::utility::toString(price) + "#{sgp}");
toAdd->setCaptionWithReplacing("#{sCell=" + nameString + "} - " + MyGUI::utility::toString(price) + "#{sgp}");
toAdd->setSize(mDestinationsView->getWidth(), lineHeight);
toAdd->eventMouseWheel += MyGUI::newDelegate(this, &TravelWindow::onMouseWheel);
toAdd->setUserString("Destination", nameString);

View file

@ -24,8 +24,7 @@ namespace MWGui
protected:
MyGUI::Button* mCancelButton;
MyGUI::TextBox* mPlayerGold;
MyGUI::TextBox* mDestinations;
MyGUI::TextBox* mSelect;
std::vector<MyGUI::Button*> mDestinationButtons;
MyGUI::ScrollView* mDestinationsView;

View file

@ -22,7 +22,7 @@
#include <components/sdlutil/sdlcursormanager.hpp>
#include <components/sdlutil/sdlvideowrapper.hpp>
#include <components/settings/settings.hpp>
#include <components/to_utf8/to_utf8.hpp>
#include <components/toutf8/toutf8.hpp>
#include "charactercreation.hpp"
#include "controllerbuttonsoverlay.hpp"

View file

@ -267,7 +267,7 @@ namespace MWMechanics
if (spell->mData.mType != ESM::Spell::ST_Spell && spell->mData.mType != ESM::Spell::ST_Power
&& !isSpellActive(spell->mId))
{
mSpells.emplace_back(ActiveSpellParams{ spell, ptr });
mSpells.emplace_back(ActiveSpellParams{ spell, ptr, true });
mSpells.back().setActiveSpellId(MWBase::Environment::get().getESMStore()->generateId());
}
}
@ -506,9 +506,9 @@ namespace MWMechanics
mQueue.emplace_back(params);
}
void ActiveSpells::addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor)
void ActiveSpells::addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, bool ignoreResistances)
{
mQueue.emplace_back(ActiveSpellParams{ spell, actor, true });
mQueue.emplace_back(ActiveSpellParams{ spell, actor, ignoreResistances });
}
void ActiveSpells::purge(ParamsPredicate predicate, const MWWorld::Ptr& ptr)

View file

@ -137,8 +137,8 @@ namespace MWMechanics
///
void addSpell(const ActiveSpellParams& params);
/// Bypasses resistances
void addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor);
/// Force resistances
void addSpell(const ESM::Spell* spell, const MWWorld::Ptr& actor, bool ignoreResistances = true);
/// Removes the active effects from this spell/potion/.. with \a id
void removeEffectsBySourceSpellId(const MWWorld::Ptr& ptr, const ESM::RefId& id);

View file

@ -119,6 +119,7 @@ namespace MWMechanics
/// Reset pathfinding state
void reset();
virtual void resetInitialPosition() {}
/// Return if actor's rotation speed is sufficient to rotate to the destination pathpoint on the run. Otherwise
/// actor should rotate while standing.

View file

@ -400,7 +400,7 @@ namespace MWMechanics
const auto newTypeId = package.getTypeId();
if (currentTypeId <= MWMechanics::AiPackageTypeId::Wander
&& !hasPackage(MWMechanics::AiPackageTypeId::InternalTravel)
&& (newTypeId <= MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue
&& (newTypeId == MWMechanics::AiPackageTypeId::Combat || newTypeId == MWMechanics::AiPackageTypeId::Pursue
|| newTypeId == MWMechanics::AiPackageTypeId::Cast))
{
osg::Vec3f dest;
@ -444,8 +444,15 @@ namespace MWMechanics
if ((*it)->getPriority() <= package.getPriority())
{
if (cancelOther && isActualAiPackage((*it)->getTypeId()))
mAiState.reset();
onPackageAdded(package);
mPackages.insert(it, package.clone());
it = mPackages.insert(it, package.clone());
if (newTypeId == MWMechanics::AiPackageTypeId::Follow)
{
for (++it; it != mPackages.end(); ++it)
(*it)->resetInitialPosition();
}
return;
}
}
@ -455,11 +462,7 @@ namespace MWMechanics
// Make sure that temporary storage is empty
if (cancelOther)
{
mAiState.moveIn(std::make_unique<AiCombatStorage>());
mAiState.moveIn(std::make_unique<AiFollowStorage>());
mAiState.moveIn(std::make_unique<AiWanderStorage>());
}
mAiState.reset();
}
bool MWMechanics::AiSequence::isEmpty() const

View file

@ -59,12 +59,7 @@ namespace MWMechanics
mStorage = std::make_unique<Derived>(payload);
}
/// \brief takes ownership of the passed object
template <class Derived>
void moveIn(std::unique_ptr<Derived>&& storage)
{
mStorage = std::move(storage);
}
void reset() { mStorage.reset(); }
};
}

View file

@ -676,6 +676,13 @@ namespace MWMechanics
stopMovement(actor);
}
void AiWander::resetInitialPosition()
{
mStoredInitialActorPosition = false;
mPathFinder.clearPath();
mHasDestination = false;
}
bool AiWander::playIdle(const MWWorld::Ptr& actor, unsigned short idleSelect)
{
if ((GroupIndex_MinIdle <= idleSelect) && (idleSelect <= GroupIndex_MaxIdle))
@ -804,7 +811,7 @@ namespace MWMechanics
converter.toWorld(dest);
state.moveIn(std::make_unique<AiWanderStorage>());
state.reset();
osg::Vec3f pos(static_cast<float>(dest.mX), static_cast<float>(dest.mY), static_cast<float>(dest.mZ));
MWBase::Environment::get().getWorld()->moveObject(actor, pos);

View file

@ -122,6 +122,8 @@ namespace MWMechanics
static std::string_view getIdleGroupName(size_t index) { return sIdleSelectToGroupName[index]; }
void resetInitialPosition() override;
private:
void stopWalking(const MWWorld::Ptr& actor);

View file

@ -66,7 +66,9 @@ namespace MWMechanics
if (Misc::Rng::rollDice(10000, prng) < x)
{
// Contracted disease!
actor.getClass().getCreatureStats(actor).getSpells().add(spell);
MWMechanics::CreatureStats& creatureStats = actor.getClass().getCreatureStats(actor);
creatureStats.getSpells().add(spell);
creatureStats.getActiveSpells().addSpell(spell, actor, false);
MWBase::Environment::get().getWorld()->applyLoopingParticles(actor);
std::string msg = MWBase::Environment::get()

View file

@ -185,18 +185,18 @@ namespace MWMechanics
*
* Formula on UESPWiki is not entirely correct.
*/
float Enchanting::getEnchantPoints(bool precise) const
std::vector<float> Enchanting::getEffectCosts() const
{
std::vector<float> costs;
if (mEffectList.mList.empty())
// No effects added, cost = 0
return 0;
return costs;
costs.reserve(mEffectList.mList.size());
const MWWorld::ESMStore& store = *MWBase::Environment::get().getESMStore();
const float fEffectCostMult = store.get<ESM::GameSetting>().find("fEffectCostMult")->mValue.getFloat();
const float fEnchantmentConstantDurationMult
= store.get<ESM::GameSetting>().find("fEnchantmentConstantDurationMult")->mValue.getFloat();
float enchantmentCost = 0.f;
float cost = 0.f;
for (const ESM::IndexedENAMstruct& effect : mEffectList.mList)
{
@ -215,9 +215,18 @@ namespace MWMechanics
if (effect.mData.mRange == ESM::RT_Target)
cost *= 1.5f;
enchantmentCost += precise ? cost : std::floor(cost);
costs.push_back(cost);
}
return costs;
}
float Enchanting::getEnchantPoints(bool precise) const
{
float enchantmentCost = 0.f;
for (float cost : getEffectCosts())
enchantmentCost += precise ? cost : std::floor(cost);
return enchantmentCost;
}
@ -278,13 +287,19 @@ namespace MWMechanics
if (mEnchanter.isEmpty())
return 0;
// Use the final effect's accumulated cost
float finalEffectCost = 0.f;
std::vector<float> effectCosts = getEffectCosts();
if (!effectCosts.empty())
finalEffectCost = effectCosts.back();
float priceMultipler = MWBase::Environment::get()
.getESMStore()
->get<ESM::GameSetting>()
.find("fEnchantmentValueMult")
->mValue.getFloat();
int price = MWBase::Environment::get().getMechanicsManager()->getBarterOffer(
mEnchanter, static_cast<int>(getEnchantPoints() * priceMultipler), true);
mEnchanter, static_cast<int>(finalEffectCost * priceMultipler), true);
price *= count * getTypeMultiplier();
return std::max(1, price);
}

View file

@ -2,6 +2,7 @@
#define GAME_MWMECHANICS_ENCHANTING_H
#include <string>
#include <vector>
#include <components/esm3/effectlist.hpp>
#include <components/esm3/loadench.hpp>
@ -32,6 +33,7 @@ namespace MWMechanics
float getTypeMultiplier() const;
void payForEnchantment(int count) const;
int getEnchantPrice(int count) const;
std::vector<float> getEffectCosts() const;
public:
Enchanting();

View file

@ -1232,33 +1232,39 @@ namespace MWMechanics
victim.getClass().getCreatureStats(victim).notifyMurder();
// Bounty and disposition penalty for each type of crime
float disp = 0.f, dispVictim = 0.f;
int bounty;
float disp, dispVictim;
if (type == OT_Trespassing || type == OT_SleepingInOwnedBed)
{
arg = store.find("iCrimeTresspass")->mValue.getInteger();
bounty = store.find("iCrimeTresspass")->mValue.getInteger();
disp = dispVictim = store.find("iDispTresspass")->mValue.getFloat();
}
else if (type == OT_Pickpocket)
{
arg = store.find("iCrimePickPocket")->mValue.getInteger();
bounty = store.find("iCrimePickPocket")->mValue.getInteger();
disp = dispVictim = store.find("fDispPickPocketMod")->mValue.getFloat();
}
else if (type == OT_Assault)
{
arg = store.find("iCrimeAttack")->mValue.getInteger();
bounty = store.find("iCrimeAttack")->mValue.getInteger();
disp = store.find("iDispAttackMod")->mValue.getFloat();
dispVictim = store.find("fDispAttacking")->mValue.getFloat();
}
else if (type == OT_Murder)
{
arg = store.find("iCrimeKilling")->mValue.getInteger();
bounty = store.find("iCrimeKilling")->mValue.getInteger();
disp = dispVictim = store.find("iDispKilling")->mValue.getFloat();
}
else if (type == OT_Theft)
{
bounty = static_cast<int>(arg * store.find("fCrimeStealing")->mValue.getFloat());
bounty = std::max(1, bounty); // Minimum bounty of 1, in case items with zero value are stolen
disp = dispVictim = store.find("fDispStealing")->mValue.getFloat() * arg;
arg = static_cast<int>(arg * store.find("fCrimeStealing")->mValue.getFloat());
arg = std::max(1, arg); // Minimum bounty of 1, in case items with zero value are stolen
}
else
{
bounty = arg;
disp = dispVictim = 0.f;
}
// Make surrounding actors within alarm distance respond to the crime
@ -1296,7 +1302,7 @@ namespace MWMechanics
else if (type == OT_Murder)
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("iFightKilling")->mValue.getInteger();
else if (type == OT_Theft)
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("fFightStealing")->mValue.getInteger();
fight = fightVictim = esmStore.get<ESM::GameSetting>().find("fFightStealing")->mValue.getInteger() * arg;
bool reported = false;
@ -1457,7 +1463,7 @@ namespace MWMechanics
if (reported)
{
player.getClass().getNpcStats(player).setBounty(
std::max(0, player.getClass().getNpcStats(player).getBounty() + arg));
std::max(0, player.getClass().getNpcStats(player).getBounty() + bounty));
// If committing a crime against a faction member, expell from the faction
if (!victim.isEmpty() && victim.getClass().isNpc())

View file

@ -115,6 +115,11 @@ namespace MWScript
std::string_view cell = runtime.getStringLiteral(runtime[0].mInteger);
runtime.pop();
// In Morrowind, using an empty string either errors out (e.g. console) or kills the game
// so it should be reasonable to interrupt the script
if (cell.empty())
throw std::runtime_error("ShowMap substring must not be empty");
// "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's
// House as well." http://www.uesp.net/wiki/Tes3Mod:ShowMap

View file

@ -884,8 +884,8 @@ namespace MWScript
return;
}
const MWMechanics::CreatureStats& stats = ptr.getClass().getCreatureStats(ptr);
runtime.push(stats.getActiveSpells().isSpellActive(id));
const auto& activeSpells = ptr.getClass().getCreatureStats(ptr).getActiveSpells();
runtime.push(activeSpells.isSpellActive(id) || activeSpells.isEnchantmentActive(id));
}
};

View file

@ -1,7 +1,7 @@
/* Reverb presets for EFX */
#ifndef EFX_PRESETS_H
#define EFX_PRESETS_H
#ifndef GAME_SOUND_EFXPRESETS_H
#define GAME_SOUND_EFXPRESETS_H
#ifndef EFXEAXREVERBPROPERTIES_DEFINED
#define EFXEAXREVERBPROPERTIES_DEFINED
@ -852,4 +852,4 @@ typedef struct
0.1900f, 0.9920f, 5000.0000f, 250.0000f, 0.0000f, 0x0 \
}
#endif /* EFX_PRESETS_H */
#endif

View file

@ -1,4 +1,4 @@
#include "ffmpeg_decoder.hpp"
#include "ffmpegdecoder.hpp"
#include <algorithm>
#include <memory>
@ -44,11 +44,11 @@ namespace MWSound
av_frame_free(&ptr);
}
int FFmpeg_Decoder::readPacket(void* user_data, uint8_t* buf, int buf_size)
int FFmpegDecoder::readPacket(void* user_data, uint8_t* buf, int buf_size)
{
try
{
std::istream& stream = *static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
std::istream& stream = *static_cast<FFmpegDecoder*>(user_data)->mDataStream;
stream.clear();
stream.read((char*)buf, buf_size);
std::streamsize count = stream.gcount();
@ -65,18 +65,18 @@ namespace MWSound
}
#if OPENMW_FFMPEG_CONST_WRITEPACKET
int FFmpeg_Decoder::writePacket(void*, const uint8_t*, int)
int FFmpegDecoder::writePacket(void*, const uint8_t*, int)
#else
int FFmpeg_Decoder::writePacket(void*, uint8_t*, int)
int FFmpegDecoder::writePacket(void*, uint8_t*, int)
#endif
{
Log(Debug::Error) << "can't write to read-only stream";
return -1;
}
int64_t FFmpeg_Decoder::seek(void* user_data, int64_t offset, int whence)
int64_t FFmpegDecoder::seek(void* user_data, int64_t offset, int whence)
{
std::istream& stream = *static_cast<FFmpeg_Decoder*>(user_data)->mDataStream;
std::istream& stream = *static_cast<FFmpegDecoder*>(user_data)->mDataStream;
whence &= ~AVSEEK_FORCE;
@ -106,7 +106,7 @@ namespace MWSound
/* Used by getAV*Data to search for more compressed data, and buffer it in the
* correct stream. It won't buffer data for streams that the app doesn't have a
* handle for. */
bool FFmpeg_Decoder::getNextPacket()
bool FFmpegDecoder::getNextPacket()
{
if (!mStream)
return false;
@ -129,7 +129,7 @@ namespace MWSound
return false;
}
bool FFmpeg_Decoder::getAVAudioData()
bool FFmpegDecoder::getAVAudioData()
{
bool got_frame = false;
@ -192,7 +192,7 @@ namespace MWSound
return true;
}
size_t FFmpeg_Decoder::readAVAudioData(void* data, size_t length)
size_t FFmpegDecoder::readAVAudioData(void* data, size_t length)
{
size_t dec = 0;
@ -227,7 +227,7 @@ namespace MWSound
return dec;
}
void FFmpeg_Decoder::open(VFS::Path::NormalizedView fname)
void FFmpegDecoder::open(VFS::Path::NormalizedView fname)
{
close();
mDataStream = mResourceMgr->get(fname);
@ -317,7 +317,7 @@ namespace MWSound
mStream = stream;
}
void FFmpeg_Decoder::close()
void FFmpegDecoder::close()
{
mStream = nullptr;
mCodecCtx.reset();
@ -332,7 +332,7 @@ namespace MWSound
mDataStream.reset();
}
std::string FFmpeg_Decoder::getName()
std::string FFmpegDecoder::getName()
{
// In the FFMpeg 4.0 a "filename" field was replaced by "url"
#if LIBAVCODEC_VERSION_INT < 3805796
@ -342,7 +342,7 @@ namespace MWSound
#endif
}
void FFmpeg_Decoder::getInfo(int* samplerate, ChannelConfig* chans, SampleType* type)
void FFmpegDecoder::getInfo(int* samplerate, ChannelConfig* chans, SampleType* type)
{
if (!mStream)
throw std::runtime_error("No audio stream info");
@ -459,7 +459,7 @@ namespace MWSound
}
}
size_t FFmpeg_Decoder::read(char* buffer, size_t bytes)
size_t FFmpegDecoder::read(char* buffer, size_t bytes)
{
if (!mStream)
{
@ -469,7 +469,7 @@ namespace MWSound
return readAVAudioData(buffer, bytes);
}
void FFmpeg_Decoder::readAll(std::vector<char>& output)
void FFmpegDecoder::readAll(std::vector<char>& output)
{
if (!mStream)
{
@ -490,7 +490,7 @@ namespace MWSound
}
}
size_t FFmpeg_Decoder::getSampleOffset()
size_t FFmpegDecoder::getSampleOffset()
{
#if OPENMW_FFMPEG_5_OR_GREATER
std::size_t delay = (mFrameSize - mFramePos) / mOutputChannelLayout.nb_channels
@ -501,8 +501,8 @@ namespace MWSound
return static_cast<std::size_t>(mNextPts * mCodecCtx->sample_rate) - delay;
}
FFmpeg_Decoder::FFmpeg_Decoder(const VFS::Manager* vfs)
: Sound_Decoder(vfs)
FFmpegDecoder::FFmpegDecoder(const VFS::Manager* vfs)
: SoundDecoder(vfs)
, mStream(nullptr)
, mFrameSize(0)
, mFramePos(0)
@ -534,7 +534,7 @@ namespace MWSound
}
}
FFmpeg_Decoder::~FFmpeg_Decoder()
FFmpegDecoder::~FFmpegDecoder()
{
close();
}

View file

@ -1,5 +1,5 @@
#ifndef GAME_SOUND_FFMPEG_DECODER_H
#define GAME_SOUND_FFMPEG_DECODER_H
#ifndef GAME_SOUND_FFMPEGDECODER_H
#define GAME_SOUND_FFMPEGDECODER_H
#include <cstdint>
@ -31,7 +31,7 @@ extern "C"
#include <string>
#include "sound_decoder.hpp"
#include "sounddecoder.hpp"
namespace MWSound
{
@ -63,7 +63,7 @@ namespace MWSound
using AVFramePtr = std::unique_ptr<AVFrame, AVFrameDeleter>;
class FFmpeg_Decoder final : public Sound_Decoder
class FFmpegDecoder final : public SoundDecoder
{
AVIOContextPtr mIoCtx;
AVFormatContextPtr mFormatCtx;
@ -114,13 +114,13 @@ namespace MWSound
void readAll(std::vector<char>& output) override;
size_t getSampleOffset() override;
FFmpeg_Decoder& operator=(const FFmpeg_Decoder& rhs);
FFmpeg_Decoder(const FFmpeg_Decoder& rhs);
FFmpegDecoder& operator=(const FFmpegDecoder& rhs);
FFmpegDecoder(const FFmpegDecoder& rhs);
public:
explicit FFmpeg_Decoder(const VFS::Manager* vfs);
explicit FFmpegDecoder(const VFS::Manager* vfs);
virtual ~FFmpeg_Decoder();
virtual ~FFmpegDecoder();
friend class SoundManager;
};

View file

@ -4,7 +4,7 @@
#include <deque>
#include <vector>
#include "sound_decoder.hpp"
#include "sounddecoder.hpp"
namespace MWSound
{

View file

@ -7,17 +7,17 @@
#include "../mwbase/environment.hpp"
#include "../mwbase/soundmanager.hpp"
#include "sound_decoder.hpp"
#include "sounddecoder.hpp"
namespace MWSound
{
class MovieAudioDecoder;
class MWSoundDecoderBridge final : public Sound_Decoder
class MWSoundDecoderBridge final : public SoundDecoder
{
public:
MWSoundDecoderBridge(MWSound::MovieAudioDecoder* decoder)
: Sound_Decoder(nullptr)
: SoundDecoder(nullptr)
, mDecoder(decoder)
{
}

View file

@ -17,14 +17,13 @@
#include <components/misc/thread.hpp>
#include <components/vfs/manager.hpp>
#include "efxpresets.h"
#include "loudness.hpp"
#include "openal_output.hpp"
#include "openaloutput.hpp"
#include "sound.hpp"
#include "sound_decoder.hpp"
#include "sounddecoder.hpp"
#include "soundmanagerimp.hpp"
#include "efx-presets.h"
#ifndef ALC_ALL_DEVICES_SPECIFIER
#define ALC_ALL_DEVICES_SPECIFIER 0x1013
#endif
@ -301,7 +300,7 @@ namespace MWSound
OpenAL_SoundStream(const OpenAL_SoundStream& rhs);
OpenAL_SoundStream& operator=(const OpenAL_SoundStream& rhs);
friend class OpenAL_Output;
friend class OpenALOutput;
public:
OpenAL_SoundStream(ALuint src, DecoderPtr decoder);
@ -323,7 +322,7 @@ namespace MWSound
//
// A background streaming thread (keeps active streams processed)
//
struct OpenAL_Output::StreamThread
struct OpenALOutput::StreamThread
{
std::vector<OpenAL_SoundStream*> mStreams;
@ -393,13 +392,13 @@ namespace MWSound
StreamThread& operator=(const StreamThread& rhs) = delete;
};
class OpenAL_Output::DefaultDeviceThread
class OpenALOutput::DefaultDeviceThread
{
public:
std::basic_string<ALCchar> mCurrentName;
private:
OpenAL_Output& mOutput;
OpenALOutput& mOutput;
std::atomic<bool> mQuitNow;
std::mutex mMutex;
@ -433,7 +432,7 @@ namespace MWSound
}
public:
DefaultDeviceThread(OpenAL_Output& output, std::basic_string_view<ALCchar> name = {})
DefaultDeviceThread(OpenALOutput& output, std::basic_string_view<ALCchar> name = {})
: mCurrentName(name)
, mOutput(output)
, mQuitNow(false)
@ -655,7 +654,7 @@ namespace MWSound
//
// An OpenAL output device
//
std::vector<std::string> OpenAL_Output::enumerate()
std::vector<std::string> OpenALOutput::enumerate()
{
std::vector<std::string> devlist;
const ALCchar* devnames;
@ -672,14 +671,14 @@ namespace MWSound
return devlist;
}
void OpenAL_Output::eventCallback(
void OpenALOutput::eventCallback(
ALenum eventType, ALuint object, ALuint param, ALsizei length, const ALchar* message, void* userParam)
{
if (eventType == AL_EVENT_TYPE_DISCONNECTED_SOFT)
static_cast<OpenAL_Output*>(userParam)->onDisconnect();
static_cast<OpenALOutput*>(userParam)->onDisconnect();
}
void OpenAL_Output::onDisconnect()
void OpenALOutput::onDisconnect()
{
if (!mInitialized || !alcReopenDeviceSOFT)
return;
@ -702,7 +701,7 @@ namespace MWSound
}
}
bool OpenAL_Output::init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode)
bool OpenALOutput::init(const std::string& devname, const std::string& hrtfname, HrtfMode hrtfmode)
{
deinit();
std::lock_guard<std::mutex> lock(mReopenMutex);
@ -802,7 +801,7 @@ namespace MWSound
{
static const std::array<ALenum, 1> events{ { AL_EVENT_TYPE_DISCONNECTED_SOFT } };
alEventControlSOFT(events.size(), events.data(), AL_TRUE);
alEventCallbackSOFT(&OpenAL_Output::eventCallback, this);
alEventCallbackSOFT(&OpenALOutput::eventCallback, this);
}
else
Log(Debug::Warning) << "Cannot detect audio device changes";
@ -970,7 +969,7 @@ namespace MWSound
return true;
}
void OpenAL_Output::deinit()
void OpenALOutput::deinit()
{
mStreamThread->removeAll();
mDefaultDeviceThread.reset();
@ -1006,7 +1005,7 @@ namespace MWSound
mInitialized = false;
}
std::vector<std::string> OpenAL_Output::enumerateHrtf()
std::vector<std::string> OpenALOutput::enumerateHrtf()
{
std::vector<std::string> ret;
@ -1028,7 +1027,7 @@ namespace MWSound
return ret;
}
std::pair<Sound_Handle, size_t> OpenAL_Output::loadSound(VFS::Path::NormalizedView fname)
std::pair<Sound_Handle, size_t> OpenALOutput::loadSound(VFS::Path::NormalizedView fname)
{
getALError();
@ -1076,7 +1075,7 @@ namespace MWSound
return std::make_pair(MAKE_PTRID(buf), size);
}
size_t OpenAL_Output::unloadSound(Sound_Handle data)
size_t OpenALOutput::unloadSound(Sound_Handle data)
{
ALuint buffer = GET_PTRID(data);
if (!buffer)
@ -1105,7 +1104,7 @@ namespace MWSound
return size;
}
void OpenAL_Output::initCommon2D(
void OpenALOutput::initCommon2D(
ALuint source, const osg::Vec3f& pos, ALfloat gain, ALfloat pitch, bool loop, bool useenv)
{
alSourcef(source, AL_REFERENCE_DISTANCE, 1.0f);
@ -1143,7 +1142,7 @@ namespace MWSound
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
}
void OpenAL_Output::initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist,
void OpenALOutput::initCommon3D(ALuint source, const osg::Vec3f& pos, ALfloat mindist, ALfloat maxdist,
ALfloat gain, ALfloat pitch, bool loop, bool useenv)
{
alSourcef(source, AL_REFERENCE_DISTANCE, mindist);
@ -1183,7 +1182,7 @@ namespace MWSound
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
}
void OpenAL_Output::updateCommon(
void OpenALOutput::updateCommon(
ALuint source, const osg::Vec3f& pos, ALfloat maxdist, ALfloat gain, ALfloat pitch, bool useenv)
{
if (useenv && mListenerEnv == Env_Underwater && !mWaterFilter)
@ -1199,7 +1198,7 @@ namespace MWSound
alSource3f(source, AL_VELOCITY, 0.0f, 0.0f, 0.0f);
}
bool OpenAL_Output::playSound(Sound* sound, Sound_Handle data, float offset)
bool OpenALOutput::playSound(Sound* sound, Sound_Handle data, float offset)
{
ALuint source;
@ -1238,7 +1237,7 @@ namespace MWSound
return true;
}
bool OpenAL_Output::playSound3D(Sound* sound, Sound_Handle data, float offset)
bool OpenALOutput::playSound3D(Sound* sound, Sound_Handle data, float offset)
{
ALuint source;
@ -1277,7 +1276,7 @@ namespace MWSound
return true;
}
void OpenAL_Output::finishSound(Sound* sound)
void OpenALOutput::finishSound(Sound* sound)
{
if (!sound->mHandle)
return;
@ -1294,7 +1293,7 @@ namespace MWSound
mActiveSounds.erase(std::find(mActiveSounds.begin(), mActiveSounds.end(), sound));
}
bool OpenAL_Output::isSoundPlaying(Sound* sound)
bool OpenALOutput::isSoundPlaying(Sound* sound)
{
if (!sound->mHandle)
return false;
@ -1307,7 +1306,7 @@ namespace MWSound
return state == AL_PLAYING || state == AL_PAUSED;
}
void OpenAL_Output::updateSound(Sound* sound)
void OpenALOutput::updateSound(Sound* sound)
{
if (!sound->mHandle)
return;
@ -1318,7 +1317,7 @@ namespace MWSound
getALError();
}
bool OpenAL_Output::streamSound(DecoderPtr decoder, Stream* sound, bool getLoudnessData)
bool OpenALOutput::streamSound(DecoderPtr decoder, Stream* sound, bool getLoudnessData)
{
if (mFreeSources.empty())
{
@ -1349,7 +1348,7 @@ namespace MWSound
return true;
}
bool OpenAL_Output::streamSound3D(DecoderPtr decoder, Stream* sound, bool getLoudnessData)
bool OpenALOutput::streamSound3D(DecoderPtr decoder, Stream* sound, bool getLoudnessData)
{
if (mFreeSources.empty())
{
@ -1380,7 +1379,7 @@ namespace MWSound
return true;
}
void OpenAL_Output::finishStream(Stream* sound)
void OpenALOutput::finishStream(Stream* sound)
{
if (!sound->mHandle)
return;
@ -1402,7 +1401,7 @@ namespace MWSound
delete stream;
}
double OpenAL_Output::getStreamDelay(Stream* sound)
double OpenALOutput::getStreamDelay(Stream* sound)
{
if (!sound->mHandle)
return 0.0;
@ -1410,7 +1409,7 @@ namespace MWSound
return stream->getStreamDelay();
}
double OpenAL_Output::getStreamOffset(Stream* sound)
double OpenALOutput::getStreamOffset(Stream* sound)
{
if (!sound->mHandle)
return 0.0;
@ -1419,7 +1418,7 @@ namespace MWSound
return stream->getStreamOffset();
}
float OpenAL_Output::getStreamLoudness(Stream* sound)
float OpenALOutput::getStreamLoudness(Stream* sound)
{
if (!sound->mHandle)
return 0.0;
@ -1428,7 +1427,7 @@ namespace MWSound
return stream->getCurrentLoudness();
}
bool OpenAL_Output::isStreamPlaying(Stream* sound)
bool OpenALOutput::isStreamPlaying(Stream* sound)
{
if (!sound->mHandle)
return false;
@ -1437,7 +1436,7 @@ namespace MWSound
return stream->isPlaying();
}
void OpenAL_Output::updateStream(Stream* sound)
void OpenALOutput::updateStream(Stream* sound)
{
if (!sound->mHandle)
return;
@ -1449,17 +1448,17 @@ namespace MWSound
getALError();
}
void OpenAL_Output::startUpdate()
void OpenALOutput::startUpdate()
{
alcSuspendContext(alcGetCurrentContext());
}
void OpenAL_Output::finishUpdate()
void OpenALOutput::finishUpdate()
{
alcProcessContext(alcGetCurrentContext());
}
void OpenAL_Output::updateListener(
void OpenALOutput::updateListener(
const osg::Vec3f& pos, const osg::Vec3f& atdir, const osg::Vec3f& updir, Environment env)
{
if (mContext)
@ -1501,7 +1500,7 @@ namespace MWSound
mListenerEnv = env;
}
void OpenAL_Output::pauseSounds(int types)
void OpenALOutput::pauseSounds(int types)
{
std::vector<ALuint> sources;
for (Sound* sound : mActiveSounds)
@ -1524,7 +1523,7 @@ namespace MWSound
}
}
void OpenAL_Output::pauseActiveDevice()
void OpenALOutput::pauseActiveDevice()
{
if (mDevice == nullptr)
return;
@ -1540,7 +1539,7 @@ namespace MWSound
alListenerf(AL_GAIN, 0.0f);
}
void OpenAL_Output::resumeActiveDevice()
void OpenALOutput::resumeActiveDevice()
{
if (mDevice == nullptr)
return;
@ -1556,7 +1555,7 @@ namespace MWSound
alListenerf(AL_GAIN, 1.0f);
}
void OpenAL_Output::resumeSounds(int types)
void OpenALOutput::resumeSounds(int types)
{
std::vector<ALuint> sources;
for (Sound* sound : mActiveSounds)
@ -1579,8 +1578,8 @@ namespace MWSound
}
}
OpenAL_Output::OpenAL_Output(SoundManager& mgr)
: Sound_Output(mgr)
OpenALOutput::OpenALOutput(SoundManager& mgr)
: SoundOutput(mgr)
, mDevice(nullptr)
, mContext(nullptr)
, mListenerPos(0.0f, 0.0f, 0.0f)
@ -1593,12 +1592,12 @@ namespace MWSound
{
}
OpenAL_Output::~OpenAL_Output()
OpenALOutput::~OpenALOutput()
{
OpenAL_Output::deinit();
OpenALOutput::deinit();
}
float OpenAL_Output::getTimeScaledPitch(SoundBase* sound)
float OpenALOutput::getTimeScaledPitch(SoundBase* sound)
{
const bool shouldScale = !(sound->mParams.mFlags & PlayMode::NoScaling);
return shouldScale ? sound->getPitch() * mManager.getSimulationTimeScale() : sound->getPitch();

View file

@ -1,5 +1,5 @@
#ifndef GAME_SOUND_OPENAL_OUTPUT_H
#define GAME_SOUND_OPENAL_OUTPUT_H
#ifndef GAME_SOUND_OPENALOUTPUT_H
#define GAME_SOUND_OPENALOUTPUT_H
#include <deque>
#include <map>
@ -13,7 +13,7 @@
#include "alc.h"
#include "alext.h"
#include "sound_output.hpp"
#include "soundoutput.hpp"
namespace MWSound
{
@ -22,7 +22,7 @@ namespace MWSound
class Sound;
class Stream;
class OpenAL_Output : public Sound_Output
class OpenALOutput : public SoundOutput
{
ALCdevice* mDevice;
ALCcontext* mContext;
@ -72,8 +72,8 @@ namespace MWSound
float getTimeScaledPitch(SoundBase* sound);
OpenAL_Output& operator=(const OpenAL_Output& rhs);
OpenAL_Output(const OpenAL_Output& rhs);
OpenALOutput& operator=(const OpenALOutput& rhs);
OpenALOutput(const OpenALOutput& rhs);
static void eventCallback(
ALenum eventType, ALuint object, ALuint param, ALsizei length, const ALchar* message, void* userParam);
@ -117,8 +117,8 @@ namespace MWSound
void pauseActiveDevice() override;
void resumeActiveDevice() override;
OpenAL_Output(SoundManager& mgr);
virtual ~OpenAL_Output();
OpenALOutput(SoundManager& mgr);
virtual ~OpenALOutput();
};
}

View file

@ -3,7 +3,7 @@
#include <algorithm>
#include "sound_output.hpp"
#include "soundoutput.hpp"
namespace MWSound
{
@ -53,7 +53,7 @@ namespace MWSound
protected:
Sound_Instance mHandle = nullptr;
friend class OpenAL_Output;
friend class OpenALOutput;
public:
void setPosition(const osg::Vec3f& pos) { mParams.mPos = pos; }

View file

@ -1,4 +1,4 @@
#include "sound_buffer.hpp"
#include "soundbuffer.hpp"
#include "../mwbase/environment.hpp"
#include "../mwworld/esmstore.hpp"
@ -35,7 +35,7 @@ namespace MWSound
}
}
SoundBufferPool::SoundBufferPool(Sound_Output& output)
SoundBufferPool::SoundBufferPool(SoundOutput& output)
: mOutput(&output)
, mBufferCacheMax(Settings::sound().mBufferCacheMax * 1024 * 1024)
, mBufferCacheMin(
@ -48,31 +48,31 @@ namespace MWSound
clear();
}
Sound_Buffer* SoundBufferPool::lookup(const ESM::RefId& soundId) const
SoundBuffer* SoundBufferPool::lookup(const ESM::RefId& soundId) const
{
const auto it = mBufferNameMap.find(soundId);
if (it != mBufferNameMap.end())
{
Sound_Buffer* sfx = it->second;
SoundBuffer* sfx = it->second;
if (sfx->getHandle() != nullptr)
return sfx;
}
return nullptr;
}
Sound_Buffer* SoundBufferPool::lookup(std::string_view fileName) const
SoundBuffer* SoundBufferPool::lookup(std::string_view fileName) const
{
const auto it = mBufferFileNameMap.find(std::string(fileName));
if (it != mBufferFileNameMap.end())
{
Sound_Buffer* sfx = it->second;
SoundBuffer* sfx = it->second;
if (sfx->getHandle() != nullptr)
return sfx;
}
return nullptr;
}
Sound_Buffer* SoundBufferPool::loadSfx(Sound_Buffer* sfx)
SoundBuffer* SoundBufferPool::loadSfx(SoundBuffer* sfx)
{
if (sfx->getHandle() != nullptr)
return sfx;
@ -95,7 +95,7 @@ namespace MWSound
return sfx;
}
Sound_Buffer* SoundBufferPool::load(const ESM::RefId& soundId)
SoundBuffer* SoundBufferPool::load(const ESM::RefId& soundId)
{
if (mBufferNameMap.empty())
{
@ -103,7 +103,7 @@ namespace MWSound
insertSound(sound.mId, sound);
}
Sound_Buffer* sfx;
SoundBuffer* sfx;
const auto it = mBufferNameMap.find(soundId);
if (it != mBufferNameMap.end())
sfx = it->second;
@ -118,9 +118,9 @@ namespace MWSound
return loadSfx(sfx);
}
Sound_Buffer* SoundBufferPool::load(std::string_view fileName)
SoundBuffer* SoundBufferPool::load(std::string_view fileName)
{
Sound_Buffer* sfx;
SoundBuffer* sfx;
const auto it = mBufferFileNameMap.find(std::string(fileName));
if (it != mBufferFileNameMap.end())
sfx = it->second;
@ -146,7 +146,7 @@ namespace MWSound
mUnusedBuffers.clear();
}
Sound_Buffer* SoundBufferPool::insertSound(std::string_view fileName)
SoundBuffer* SoundBufferPool::insertSound(std::string_view fileName)
{
static const AudioParams audioParams
= makeAudioParams(MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>());
@ -158,13 +158,13 @@ namespace MWSound
min = std::max(min, 1.0f);
max = std::max(min, max);
Sound_Buffer& sfx = mSoundBuffers.emplace_back(fileName, volume, min, max);
SoundBuffer& sfx = mSoundBuffers.emplace_back(fileName, volume, min, max);
mBufferFileNameMap.emplace(fileName, &sfx);
return &sfx;
}
Sound_Buffer* SoundBufferPool::insertSound(const ESM::RefId& soundId, const ESM::Sound& sound)
SoundBuffer* SoundBufferPool::insertSound(const ESM::RefId& soundId, const ESM::Sound& sound)
{
static const AudioParams audioParams
= makeAudioParams(MWBase::Environment::get().getESMStore()->get<ESM::GameSetting>());
@ -183,7 +183,7 @@ namespace MWSound
min = std::max(min, 1.0f);
max = std::max(min, max);
Sound_Buffer& sfx = mSoundBuffers.emplace_back(
SoundBuffer& sfx = mSoundBuffers.emplace_back(
Misc::ResourceHelpers::correctSoundPath(VFS::Path::Normalized(sound.mSound)), volume, min, max);
mBufferNameMap.emplace(soundId, &sfx);
@ -194,7 +194,7 @@ namespace MWSound
{
while (!mUnusedBuffers.empty() && mBufferCacheSize > mBufferCacheMin)
{
Sound_Buffer* const unused = mUnusedBuffers.back();
SoundBuffer* const unused = mUnusedBuffers.back();
mBufferCacheSize -= mOutput->unloadSound(unused->getHandle());
unused->mHandle = nullptr;

View file

@ -1,14 +1,15 @@
#ifndef GAME_SOUND_SOUND_BUFFER_H
#define GAME_SOUND_SOUND_BUFFER_H
#ifndef GAME_SOUND_SOUNDBUFFER_H
#define GAME_SOUND_SOUNDBUFFER_H
#include <algorithm>
#include <deque>
#include <string>
#include <unordered_map>
#include "sound_output.hpp"
#include <components/esm/refid.hpp>
#include "soundoutput.hpp"
namespace ESM
{
struct Sound;
@ -23,11 +24,11 @@ namespace MWSound
{
class SoundBufferPool;
class Sound_Buffer
class SoundBuffer
{
public:
template <class T>
Sound_Buffer(T&& resname, float volume, float mindist, float maxdist)
SoundBuffer(T&& resname, float volume, float mindist, float maxdist)
: mResourceName(std::forward<T>(resname))
, mVolume(volume)
, mMinDist(mindist)
@ -59,7 +60,7 @@ namespace MWSound
class SoundBufferPool
{
public:
SoundBufferPool(Sound_Output& output);
SoundBufferPool(SoundOutput& output);
SoundBufferPool(const SoundBufferPool&) = delete;
@ -67,20 +68,20 @@ namespace MWSound
/// Lookup a soundId for its sound data (resource name, local volume,
/// minRange, and maxRange)
Sound_Buffer* lookup(const ESM::RefId& soundId) const;
SoundBuffer* lookup(const ESM::RefId& soundId) const;
/// Lookup a sound by file name for its sound data (resource name, local volume,
/// minRange, and maxRange)
Sound_Buffer* lookup(std::string_view fileName) const;
SoundBuffer* lookup(std::string_view fileName) const;
/// Lookup a soundId for its sound data (resource name, local volume,
/// minRange, and maxRange), and ensure it's ready for use.
Sound_Buffer* load(const ESM::RefId& soundId);
SoundBuffer* load(const ESM::RefId& soundId);
// Lookup for a sound by file name, and ensure it's ready for use.
Sound_Buffer* load(std::string_view fileName);
SoundBuffer* load(std::string_view fileName);
void use(Sound_Buffer& sfx)
void use(SoundBuffer& sfx)
{
if (sfx.mUses++ == 0)
{
@ -90,7 +91,7 @@ namespace MWSound
}
}
void release(Sound_Buffer& sfx)
void release(SoundBuffer& sfx)
{
if (--sfx.mUses == 0)
mUnusedBuffers.push_front(&sfx);
@ -99,23 +100,23 @@ namespace MWSound
void clear();
private:
Sound_Buffer* loadSfx(Sound_Buffer* sfx);
SoundBuffer* loadSfx(SoundBuffer* sfx);
Sound_Output* mOutput;
std::deque<Sound_Buffer> mSoundBuffers;
std::unordered_map<ESM::RefId, Sound_Buffer*> mBufferNameMap;
std::unordered_map<std::string, Sound_Buffer*> mBufferFileNameMap;
SoundOutput* mOutput;
std::deque<SoundBuffer> mSoundBuffers;
std::unordered_map<ESM::RefId, SoundBuffer*> mBufferNameMap;
std::unordered_map<std::string, SoundBuffer*> mBufferFileNameMap;
std::size_t mBufferCacheMax;
std::size_t mBufferCacheMin;
std::size_t mBufferCacheSize = 0;
// NOTE: unused buffers are stored in front-newest order.
std::deque<Sound_Buffer*> mUnusedBuffers;
std::deque<SoundBuffer*> mUnusedBuffers;
inline Sound_Buffer* insertSound(const ESM::RefId& soundId, const ESM::Sound& sound);
inline Sound_Buffer* insertSound(std::string_view fileName);
inline SoundBuffer* insertSound(const ESM::RefId& soundId, const ESM::Sound& sound);
inline SoundBuffer* insertSound(std::string_view fileName);
inline void unloadUnused();
};
}
#endif /* GAME_SOUND_SOUND_BUFFER_H */
#endif /* GAME_SOUND_SOUNDBUFFER_H */

View file

@ -1,5 +1,5 @@
#ifndef GAME_SOUND_SOUND_DECODER_H
#define GAME_SOUND_SOUND_DECODER_H
#ifndef GAME_SOUND_SOUNDDECODER_H
#define GAME_SOUND_SOUNDDECODER_H
#include <components/vfs/pathutil.hpp>
@ -34,7 +34,7 @@ namespace MWSound
size_t framesToBytes(size_t frames, ChannelConfig config, SampleType type);
size_t bytesToFrames(size_t bytes, ChannelConfig config, SampleType type);
struct Sound_Decoder
struct SoundDecoder
{
const VFS::Manager* mResourceMgr;
@ -48,15 +48,15 @@ namespace MWSound
virtual void readAll(std::vector<char>& output);
virtual size_t getSampleOffset() = 0;
Sound_Decoder(const VFS::Manager* resourceMgr)
SoundDecoder(const VFS::Manager* resourceMgr)
: mResourceMgr(resourceMgr)
{
}
virtual ~Sound_Decoder() {}
virtual ~SoundDecoder() {}
private:
Sound_Decoder(const Sound_Decoder& rhs);
Sound_Decoder& operator=(const Sound_Decoder& rhs);
SoundDecoder(const SoundDecoder& rhs);
SoundDecoder& operator=(const SoundDecoder& rhs);
};
}

View file

@ -26,12 +26,12 @@
#include "../mwmechanics/actorutil.hpp"
#include "constants.hpp"
#include "ffmpeg_decoder.hpp"
#include "openal_output.hpp"
#include "ffmpegdecoder.hpp"
#include "openaloutput.hpp"
#include "sound.hpp"
#include "sound_buffer.hpp"
#include "sound_decoder.hpp"
#include "sound_output.hpp"
#include "soundbuffer.hpp"
#include "sounddecoder.hpp"
#include "soundoutput.hpp"
namespace MWSound
{
@ -57,7 +57,7 @@ namespace MWSound
return settings;
}
float initialFadeVolume(float squaredDist, Sound_Buffer* sfx, Type type, PlayMode mode)
float initialFadeVolume(float squaredDist, SoundBuffer* sfx, Type type, PlayMode mode)
{
// If a sound is farther away than its maximum distance, start playing it with a zero fade volume.
// It can still become audible once the player moves closer.
@ -111,7 +111,7 @@ namespace MWSound
SoundManager::SoundManager(const VFS::Manager* vfs, bool useSound)
: mVFS(vfs)
, mOutput(std::make_unique<OpenAL_Output>(*this))
, mOutput(std::make_unique<OpenALOutput>(*this))
, mWaterSoundUpdater(makeWaterSoundUpdaterSettings())
, mSoundBuffers(*mOutput)
, mMusicType(MWSound::MusicType::Normal)
@ -169,7 +169,7 @@ namespace MWSound
// Return a new decoder instance, used as needed by the output implementations
DecoderPtr SoundManager::getDecoder()
{
return std::make_shared<FFmpeg_Decoder>(mVFS);
return std::make_shared<FFmpegDecoder>(mVFS);
}
DecoderPtr SoundManager::loadVoice(VFS::Path::NormalizedView voicefile)
@ -459,7 +459,7 @@ namespace MWSound
return false;
}
Sound* SoundManager::playSound(Sound_Buffer* sfx, float volume, float pitch, Type type, PlayMode mode, float offset)
Sound* SoundManager::playSound(SoundBuffer* sfx, float volume, float pitch, Type type, PlayMode mode, float offset)
{
if (!mOutput->isInitialized())
return nullptr;
@ -495,7 +495,7 @@ namespace MWSound
if (!mVFS->exists(normalizedName))
return nullptr;
Sound_Buffer* sfx = mSoundBuffers.load(normalizedName);
SoundBuffer* sfx = mSoundBuffers.load(normalizedName);
if (!sfx)
return nullptr;
@ -508,14 +508,14 @@ namespace MWSound
if (!mOutput->isInitialized())
return nullptr;
Sound_Buffer* sfx = mSoundBuffers.load(soundId);
SoundBuffer* sfx = mSoundBuffers.load(soundId);
if (!sfx)
return nullptr;
return playSound(sfx, volume, pitch, type, mode, offset);
}
Sound* SoundManager::playSound3D(const MWWorld::ConstPtr& ptr, Sound_Buffer* sfx, float volume, float pitch,
Sound* SoundManager::playSound3D(const MWWorld::ConstPtr& ptr, SoundBuffer* sfx, float volume, float pitch,
Type type, PlayMode mode, float offset)
{
if (!mOutput->isInitialized())
@ -576,7 +576,7 @@ namespace MWSound
return nullptr;
// Look up the sound in the ESM data
Sound_Buffer* sfx = mSoundBuffers.load(soundId);
SoundBuffer* sfx = mSoundBuffers.load(soundId);
if (!sfx)
return nullptr;
@ -594,7 +594,7 @@ namespace MWSound
if (!mVFS->exists(normalizedName))
return nullptr;
Sound_Buffer* sfx = mSoundBuffers.load(normalizedName);
SoundBuffer* sfx = mSoundBuffers.load(normalizedName);
if (!sfx)
return nullptr;
@ -608,7 +608,7 @@ namespace MWSound
return nullptr;
// Look up the sound in the ESM data
Sound_Buffer* sfx = mSoundBuffers.load(soundId);
SoundBuffer* sfx = mSoundBuffers.load(soundId);
if (!sfx)
return nullptr;
@ -642,7 +642,7 @@ namespace MWSound
mOutput->finishSound(sound);
}
void SoundManager::stopSound(Sound_Buffer* sfx, const MWWorld::ConstPtr& ptr)
void SoundManager::stopSound(SoundBuffer* sfx, const MWWorld::ConstPtr& ptr)
{
SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef);
if (snditer != mActiveSounds.end())
@ -660,7 +660,7 @@ namespace MWSound
if (!mOutput->isInitialized())
return;
Sound_Buffer* sfx = mSoundBuffers.lookup(soundId);
SoundBuffer* sfx = mSoundBuffers.lookup(soundId);
if (!sfx)
return;
@ -673,7 +673,7 @@ namespace MWSound
return;
std::string normalizedName = VFS::Path::normalizeFilename(fileName);
Sound_Buffer* sfx = mSoundBuffers.lookup(normalizedName);
SoundBuffer* sfx = mSoundBuffers.lookup(normalizedName);
if (!sfx)
return;
@ -725,7 +725,7 @@ namespace MWSound
SoundMap::iterator snditer = mActiveSounds.find(ptr.mRef);
if (snditer != mActiveSounds.end())
{
Sound_Buffer* sfx = mSoundBuffers.lookup(soundId);
SoundBuffer* sfx = mSoundBuffers.lookup(soundId);
if (sfx == nullptr)
return;
for (SoundBufferRefPair& sndbuf : snditer->second.mList)
@ -743,7 +743,7 @@ namespace MWSound
SoundMap::const_iterator snditer = mActiveSounds.find(ptr.mRef);
if (snditer != mActiveSounds.end())
{
Sound_Buffer* sfx = mSoundBuffers.lookup(normalizedName);
SoundBuffer* sfx = mSoundBuffers.lookup(normalizedName);
if (!sfx)
return false;
@ -761,7 +761,7 @@ namespace MWSound
SoundMap::const_iterator snditer = mActiveSounds.find(ptr.mRef);
if (snditer != mActiveSounds.end())
{
Sound_Buffer* sfx = mSoundBuffers.lookup(soundId);
SoundBuffer* sfx = mSoundBuffers.lookup(soundId);
if (!sfx)
return false;
@ -846,7 +846,7 @@ namespace MWSound
const auto update = mWaterSoundUpdater.update(player, *world);
WaterSoundAction action;
Sound_Buffer* sfx;
SoundBuffer* sfx;
std::tie(action, sfx) = getWaterSoundAction(update, curcell);
switch (action)
@ -870,7 +870,7 @@ namespace MWSound
mLastCell = curcell;
}
std::pair<SoundManager::WaterSoundAction, Sound_Buffer*> SoundManager::getWaterSoundAction(
std::pair<SoundManager::WaterSoundAction, SoundBuffer*> SoundManager::getWaterSoundAction(
const WaterSoundUpdate& update, const MWWorld::Cell* cell) const
{
if (mNearWaterSound)
@ -880,7 +880,7 @@ namespace MWSound
bool soundIdChanged = false;
Sound_Buffer* sfx = mSoundBuffers.lookup(update.mId);
SoundBuffer* sfx = mSoundBuffers.lookup(update.mId);
if (mLastCell != cell)
{
const auto snditer = mActiveSounds.find(nullptr);
@ -1168,7 +1168,7 @@ namespace MWSound
// Default readAll implementation, for decoders that can't do anything
// better
void Sound_Decoder::readAll(std::vector<char>& output)
void SoundDecoder::readAll(std::vector<char>& output)
{
size_t total = output.size();
size_t got;

Some files were not shown because too many files have changed in this diff Show more