clang-format & cleanup

This commit is contained in:
Pieter-Jan Briers
2026-09-12 20:33:08 +02:00
parent 03390b807e
commit ab6db7d4e6
28 changed files with 324 additions and 393 deletions
+1 -5
View File
@@ -54,10 +54,6 @@ struct Z2AudioCamera {
/* 0x00 */ JGeometry::TPosition3f32 mViewMatrix;
/* 0x30 */ JGeometry::TVec3<f32> mVel;
/* 0x3C */ JGeometry::TVec3<f32> mPos;
/**
*
*/
/* 0x48 */ JGeometry::TVec3<f32> mLastPos;
/* 0x54 */ f32 mFovySin;
/* 0x58 */ f32 mVolCenterZ;
@@ -281,7 +277,7 @@ struct Z2Audience : public JAIAudience, public JASGlobalInstance<Z2Audience> {
}
Z2Audience3DSetting* getSetting() { return &mSetting; }
const Z2AudioCamera* getAudioCamera(int camID) const { return &mAudioCamera[camID]; }
const Z2AudioCamera* getAudioCamera(int camID) const { return &mAudioCamera[camID]; }
void setUsingOffMicVol(bool value) { mUsingOffMicVol = value; }
+3 -2
View File
@@ -8,11 +8,12 @@ namespace dusk::helpers {
* @param ptr Address to read from.
* @return The copied value.
*/
template <typename T> requires std::is_trivially_copyable_v<T>
template <typename T>
requires std::is_trivially_copyable_v<T>
[[nodiscard]] constexpr T read_unaligned(u8 const* ptr) {
T copy;
memcpy(&copy, ptr, sizeof(T));
return copy;
}
}
} // namespace dusk::helpers
+35 -35
View File
@@ -1,48 +1,48 @@
#pragma once
#include <limits>
#include <utility>
#include <span>
#include <utility>
/**
* Helper functions for performing casts.
*/
namespace dusk::helpers::cast {
/**
* Implementation details of dusk::helpers::cast.
*/
namespace _impl {
[[noreturn]] void overrun_high();
[[noreturn]] void overrun_low();
}
/**
* Implementation details of dusk::helpers::cast.
*/
namespace _impl {
[[noreturn]] void overrun_high();
[[noreturn]] void overrun_low();
} // namespace _impl
template <typename T>
concept IntCastable = std::is_integral_v<T> && std::is_trivially_copyable_v<T>;
template <typename T>
concept IntCastable = std::is_integral_v<T> && std::is_trivially_copyable_v<T>;
/**
* Helper type that allows easily casting between integer types,
* that safely aborts if an overflow were to occur.
* Usage:
* @code
* size_t foobar = 20;
* int real = bounded_cast(foobar);
* @endcode
*/
template <IntCastable Source>
struct bounded_cast {
Source src;
/**
* Helper type that allows easily casting between integer types,
* that safely aborts if an overflow were to occur.
* Usage:
* @code
* size_t foobar = 20;
* int real = bounded_cast(foobar);
* @endcode
*/
template <IntCastable Source>
struct bounded_cast {
Source src;
template <IntCastable Target>
[[nodiscard]] constexpr operator Target() const {
if (std::cmp_greater(src, std::numeric_limits<Target>::max())) [[unlikely]] {
_impl::overrun_high();
}
if (std::cmp_less(src, std::numeric_limits<Target>::min())) [[unlikely]] {
_impl::overrun_low();
}
return static_cast<Target>(src);
template <IntCastable Target>
[[nodiscard]] constexpr operator Target() const {
if (std::cmp_greater(src, std::numeric_limits<Target>::max())) [[unlikely]] {
_impl::overrun_high();
}
};
}
if (std::cmp_less(src, std::numeric_limits<Target>::min())) [[unlikely]] {
_impl::overrun_low();
}
return static_cast<Target>(src);
}
};
} // namespace dusk::helpers::cast
+5 -18
View File
@@ -12,28 +12,15 @@ MOD_EXPORT ModResult mod_initialize(ModError*) {
svc_log->info(mod_ctx, "template_mod initialized");
AudioWaveHandle handle;
svc_audio_res->replace_wave(
mod_ctx,
AUDIO_WAVE_BANK_SOUND_EFFECTS,
4238,
"res/go.opus",
nullptr,
&handle);
mod_ctx, AUDIO_WAVE_BANK_SOUND_EFFECTS, 4238, "res/go.opus", nullptr, &handle);
svc_audio_res->replace_wave(
mod_ctx,
AUDIO_WAVE_BANK_SOUND_EFFECTS,
4237,
"res/go.opus",
nullptr,
&handle);
mod_ctx, AUDIO_WAVE_BANK_SOUND_EFFECTS, 4237, "res/go.opus", nullptr, &handle);
constexpr AudioSoundTableEffectInfo effect(128, 1, 1.5);
svc_audio_res->replace_sound_table_effect(
mod_ctx,
SE_CATEGORY_CHARA_SE,
0, // MIDNA_APPEAR
&effect,
nullptr);
svc_audio_res->replace_sound_table_effect(mod_ctx, SE_CATEGORY_CHARA_SE,
0, // MIDNA_APPEAR
&effect, nullptr);
return MOD_OK;
}
+2 -4
View File
@@ -14,9 +14,7 @@ luabridge::Stack<const luau_runtime::Vm&>::get(lua_State* L, int) {
namespace luau_runtime {
BridgeScriptHandle::BridgeScriptHandle(uint64_t const handle) noexcept : handle(handle) {
}
BridgeScriptHandle::BridgeScriptHandle(uint64_t const handle) noexcept : handle(handle) {}
BridgeScriptHandle::~BridgeScriptHandle() = default;
@@ -37,4 +35,4 @@ void BridgeScriptHandle::unregister(lua_State* state, Vm& vm) {
handle = 0;
}
}
} // namespace luau_runtime
+25 -19
View File
@@ -1,25 +1,29 @@
#pragma once
// clang-format off
#include "lua.h"
#include "lualib.h"
#include "LuaBridge/LuaBridge.h"
// clang-format on
#include "runtime.hpp"
/**
* Defines (i.e. implements) a LuaBridge3 Stack<T> converter for an enum that is passed by string name.
* Defines (i.e. implements) a LuaBridge3 Stack<T> converter for an enum that is passed by string
* name.
*
* @param type The type name of the enum to convert.
* @param names The constant field containing the string name <-> enum value mapping.
* @see DECLARE_STRING_ENUM
*/
#define DEFINE_STRING_ENUM(type, names) \
Result Stack<type>::push(lua_State* L, type value) { \
return Stack<std::string_view>::push(L, ::luau_runtime::enum_value_to_str(L, value, names)); \
} \
\
TypeResult<type> Stack<type>::get(lua_State* L, int index) { \
const char* str = lua_tolstring(L, index, nullptr); \
return ::luau_runtime::enum_str_to_value(L, str, names); \
#define DEFINE_STRING_ENUM(type, names) \
Result Stack<type>::push(lua_State* L, type value) { \
return Stack<std::string_view>::push( \
L, ::luau_runtime::enum_value_to_str(L, value, names)); \
} \
\
TypeResult<type> Stack<type>::get(lua_State* L, int index) { \
const char* str = lua_tolstring(L, index, nullptr); \
return ::luau_runtime::enum_str_to_value(L, str, names); \
}
/**
@@ -28,11 +32,11 @@
* @param type The type name of the enum to convert.
* @see DEFINE_STRING_ENUM
*/
#define DECLARE_STRING_ENUM(type) \
template<> \
struct Stack<type> { \
[[nodiscard]] static Result push(lua_State* L, type value); \
[[nodiscard]] static TypeResult<type> get(lua_State* L, int index); \
#define DECLARE_STRING_ENUM(type) \
template <> \
struct Stack<type> { \
[[nodiscard]] static Result push(lua_State* L, type value); \
[[nodiscard]] static TypeResult<type> get(lua_State* L, int index); \
}
/**
@@ -41,16 +45,18 @@
*/
template <>
struct luabridge::Stack<luau_runtime::Vm&> {
[[nodiscard]] static TypeResult<std::reference_wrapper<luau_runtime::Vm>> get(lua_State* L, int);
[[nodiscard]] static TypeResult<std::reference_wrapper<luau_runtime::Vm>> get(
lua_State* L, int);
};
/**
* Template specialization to allow luau_runtime::Vm const& to be directly acquired
* from a LuaBridge3 function.
*/
template<>
template <>
struct luabridge::Stack<luau_runtime::Vm const&> {
[[nodiscard]] static TypeResult<std::reference_wrapper<luau_runtime::Vm const>> get(lua_State* L, int);
[[nodiscard]] static TypeResult<std::reference_wrapper<luau_runtime::Vm const>> get(
lua_State* L, int);
};
namespace luau_runtime {
@@ -72,7 +78,7 @@ public:
void unregister(lua_State* state, Vm& vm);
};
}
} // namespace luau_runtime
/**
* Convert a @ref luaBridge::LuaRef to an *optional* value.
@@ -100,7 +106,7 @@ std::optional<T> opt(TLuaRef const& value) {
* @param value Lua ref to convert to the desired type.
* @param default_value The default value if the lua item is nil.
*/
template<typename T, typename TLuaRef>
template <typename T, typename TLuaRef>
T opt_or(TLuaRef const& value, T const& default_value) {
return opt<T>(value).value_or(default_value);
}
+1 -1
View File
@@ -115,4 +115,4 @@ int ref_required_function(lua_State* state, int table, const char* field) {
return ref;
}
}
} // namespace luau_runtime
+5 -6
View File
@@ -31,7 +31,7 @@ uint32_t get_uint32(lua_State* state, int table, const char* field);
/**
* Concept that demands things be an enum. C++ is such a cool language.
*/
template<typename T>
template <typename T>
concept Enum = std::is_enum_v<T>;
/**
@@ -44,8 +44,7 @@ struct EnumName {
T value;
std::string_view name;
constexpr EnumName(T value, std::string_view name) : value(value), name(name) {
}
constexpr EnumName(T value, std::string_view name) : value(value), name(name) {}
};
/**
@@ -59,7 +58,7 @@ struct EnumName {
* @param options The predefined set of possible enum names.
*/
template <Enum T, size_t N>
T enum_str_to_value(lua_State* state, char const* str, EnumName<T> const(& options)[N]) {
T enum_str_to_value(lua_State* state, char const* str, EnumName<T> const (&options)[N]) {
std::string_view strv(str);
for (size_t i = 0; i < N; ++i) {
if (options[i].name == strv) {
@@ -81,7 +80,7 @@ T enum_str_to_value(lua_State* state, char const* str, EnumName<T> const(& optio
* @param options The predefined set of possible enum names.
*/
template <Enum T, size_t N>
std::string_view enum_value_to_str(lua_State* state, T value, EnumName<T> const(& options)[N]) {
std::string_view enum_value_to_str(lua_State* state, T value, EnumName<T> const (&options)[N]) {
for (auto [nameValue, name] : options) {
if (nameValue == value) {
return name;
@@ -91,4 +90,4 @@ std::string_view enum_value_to_str(lua_State* state, T value, EnumName<T> const(
luaL_errorL(state, "Attempted to return invalid enum to Lua!");
}
}
} // namespace luau_runtime
+1 -1
View File
@@ -327,7 +327,7 @@ ModResult runtime_activate(ModContext*, ModContext* subject, ModError* outError)
lua_pushlightuserdata(vm->state, vm.get());
lua_rawsetp(vm->state, LUA_REGISTRYINDEX, &vm_registry_index);
lua_callbacks(vm->state)->userdata = vm.get();
#if NDEBUG // Annoying for debuggers
#if NDEBUG // Annoying for debuggers
lua_callbacks(vm->state)->interrupt = [](lua_State* state, int gc) {
auto* current = static_cast<Vm*>(lua_callbacks(state)->userdata);
if (gc < 0 && current != nullptr && current->deadlineActive &&
@@ -5,8 +5,8 @@
#include "mods/svc/audio_res.h"
#include "wsys.hpp"
#include "bst.hpp"
#include "wsys.hpp"
namespace luau_runtime::services {
namespace {
@@ -31,7 +31,7 @@ int open_audio_res(lua_State* state) {
.addFunction("replace_wave", replace_wave)
.addFunction("add_wave", add_wave)
.beginClass<LuaAudioWaveHandle>("AudioWaveHandle")
.addFunction("unregister", &LuaAudioWaveHandle::unregister)
.addFunction("unregister", &LuaAudioWaveHandle::unregister)
.endClass()
// BST
.addFunction("default_effect_info", default_effect_info)
@@ -42,13 +42,11 @@ int open_audio_res(lua_State* state) {
.addFunction("replace_sound_table_stream", replace_sound_table_stream)
.addFunction("add_sound_table_stream", add_sound_table_stream)
.beginClass<LuaSoundTableHandle>("AudioSoundTableHandle")
.addFunction("unregister", &LuaSoundTableHandle::unregister)
.addFunction("unregister", &LuaSoundTableHandle::unregister)
.endClass();
lua_setreadonly(state, -1, true);
return 1;
}
}
} // namespace luau_runtime::services
@@ -2,7 +2,8 @@
namespace luau_runtime::services::audio_res {
LuaSoundTableHandle::LuaSoundTableHandle(AudioSoundTableHandle handle) : BridgeScriptHandle(handle) { }
LuaSoundTableHandle::LuaSoundTableHandle(AudioSoundTableHandle handle)
: BridgeScriptHandle(handle) {}
void LuaSoundTableHandle::unregister_impl(lua_State*, Vm& vm) {
svc_audio_res->remove_sound_table(vm.subject, handle);
@@ -21,19 +22,16 @@ LuaSoundTableHandle replace_sound_table_effect(SoundEffectCategory category_id,
AudioSoundTableHandle handle;
check_result(
state,
svc_audio_res->replace_sound_table_effect(vm.subject, category_id, effect_id, effect_info, &handle),
check_result(state,
svc_audio_res->replace_sound_table_effect(
vm.subject, category_id, effect_id, effect_info, &handle),
"audio_res.replace_sound_table_effect");
return LuaSoundTableHandle(handle);
}
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_effect(
SoundEffectCategory category_id,
std::optional<AudioSoundTableEffectInfo> info,
lua_State* state,
Vm& vm) {
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_effect(SoundEffectCategory category_id,
std::optional<AudioSoundTableEffectInfo> info, lua_State* state, Vm& vm) {
AudioSoundTableEffectInfo const* effect_info = nullptr;
if (info.has_value()) {
effect_info = &*info;
@@ -42,12 +40,12 @@ std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_effect(
uint16_t out_effect_id;
AudioSoundTableHandle handle;
check_result(
state,
svc_audio_res->add_sound_table_effect(vm.subject, category_id, effect_info, &handle, &out_effect_id),
check_result(state,
svc_audio_res->add_sound_table_effect(
vm.subject, category_id, effect_info, &handle, &out_effect_id),
"audio_res.add_sound_table_effect");
return { out_effect_id, LuaSoundTableHandle(handle) };
return {out_effect_id, LuaSoundTableHandle(handle)};
}
AudioSoundTableStreamInfo const& default_stream_info() {
@@ -63,19 +61,16 @@ LuaSoundTableHandle replace_sound_table_stream(uint16_t stream_id, char const* f
AudioSoundTableHandle handle;
check_result(
state,
svc_audio_res->replace_sound_table_stream(vm.subject, stream_id, file_path, stream_info, &handle),
check_result(state,
svc_audio_res->replace_sound_table_stream(
vm.subject, stream_id, file_path, stream_info, &handle),
"audio_res.replace_sound_table_stream");
return LuaSoundTableHandle(handle);
}
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_stream(
char const* file_path,
std::optional<AudioSoundTableStreamInfo> info,
lua_State* state,
Vm& vm) {
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_stream(char const* file_path,
std::optional<AudioSoundTableStreamInfo> info, lua_State* state, Vm& vm) {
AudioSoundTableStreamInfo const* stream_info = nullptr;
if (info.has_value()) {
stream_info = &*info;
@@ -84,15 +79,14 @@ std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_stream(
uint16_t out_stream_id;
AudioSoundTableHandle handle;
check_result(
state,
svc_audio_res->add_sound_table_stream(vm.subject, file_path, stream_info, &handle, &out_stream_id),
check_result(state,
svc_audio_res->add_sound_table_stream(
vm.subject, file_path, stream_info, &handle, &out_stream_id),
"audio_res.add_sound_table_stream");
return { out_stream_id, LuaSoundTableHandle(handle) };
return {out_stream_id, LuaSoundTableHandle(handle)};
}
} // namespace luau_runtime::services::audio_res
namespace luabridge {
@@ -130,10 +124,9 @@ DEFINE_STRING_ENUM(StreamPan, kStreamPanNames);
TypeResult<AudioSoundTableEffectInfo> Stack<AudioSoundTableEffectInfo>::get(
lua_State* L, int index) {
auto const ref = LuaRef::fromStack(L, index);
return AudioSoundTableEffectInfo {
return AudioSoundTableEffectInfo{
.priority = ref["priority"],
.volume = ref["volume"],
.pitch = ref["pitch"],
@@ -153,7 +146,6 @@ TypeResult<AudioSoundTableEffectInfo> Stack<AudioSoundTableEffectInfo>::get(
Result Stack<AudioSoundTableEffectInfo>::push(
lua_State* L, const AudioSoundTableEffectInfo& value) {
LuaRef const ref = newTable(L);
ref["priority"] = value.priority;
@@ -178,12 +170,12 @@ Result Stack<AudioSoundTableEffectInfo>::push(
TypeResult<AudioSoundTableStreamInfo> Stack<AudioSoundTableStreamInfo>::get(
lua_State* L, int index) {
auto const ref = LuaRef::fromStack(L, index);
std::array<std::optional<StreamPan>, STREAM_MAX_CHILDREN> const pan_parameters = ref["pan_parameters"];
std::array<std::optional<StreamPan>, STREAM_MAX_CHILDREN> const pan_parameters =
ref["pan_parameters"];
auto info = AudioSoundTableStreamInfo {
auto info = AudioSoundTableStreamInfo{
.priority = ref["priority"],
.volume = ref["volume"],
.stop_on_scene_change = ref["stop_on_scene_change"],
@@ -198,7 +190,6 @@ TypeResult<AudioSoundTableStreamInfo> Stack<AudioSoundTableStreamInfo>::get(
Result Stack<AudioSoundTableStreamInfo>::push(
lua_State* L, const AudioSoundTableStreamInfo& value) {
LuaRef const ref = newTable(L);
ref["priority"] = value.priority;
@@ -1,59 +1,46 @@
#pragma once
#include "mods/svc/audio_res.h"
#include "../../lua_helpers.hpp"
#include "../../lua_bridge_helpers.hpp"
#include "../../lua_helpers.hpp"
#include "mods/svc/audio_res.h"
namespace luau_runtime::services::audio_res {
class LuaSoundTableHandle final : public BridgeScriptHandle {
protected:
void unregister_impl(lua_State*, Vm& vm) override;
public:
explicit LuaSoundTableHandle(AudioSoundTableHandle handle);
};
AudioSoundTableEffectInfo const& default_effect_info();
LuaSoundTableHandle replace_sound_table_effect(
SoundEffectCategory category_id,
uint16_t effect_id,
std::optional<AudioSoundTableEffectInfo> info,
lua_State* state,
Vm& vm);
LuaSoundTableHandle replace_sound_table_effect(SoundEffectCategory category_id, uint16_t effect_id,
std::optional<AudioSoundTableEffectInfo> info, lua_State* state, Vm& vm);
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_effect(
SoundEffectCategory category_id,
std::optional<AudioSoundTableEffectInfo> info,
lua_State* state,
Vm& vm);
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_effect(SoundEffectCategory category_id,
std::optional<AudioSoundTableEffectInfo> info, lua_State* state, Vm& vm);
AudioSoundTableStreamInfo const& default_stream_info();
LuaSoundTableHandle replace_sound_table_stream(
uint16_t stream_id,
char const* file_path,
std::optional<AudioSoundTableStreamInfo> info,
lua_State* state,
Vm& vm);
LuaSoundTableHandle replace_sound_table_stream(uint16_t stream_id, char const* file_path,
std::optional<AudioSoundTableStreamInfo> info, lua_State* state, Vm& vm);
std::tuple<uint16_t, LuaSoundTableHandle> add_sound_table_stream(
char const* file_path,
std::optional<AudioSoundTableStreamInfo> info,
lua_State* state,
Vm& vm);
char const* file_path, std::optional<AudioSoundTableStreamInfo> info, lua_State* state, Vm& vm);
}
} // namespace luau_runtime::services::audio_res
namespace luabridge {
template<>
template <>
struct Stack<AudioSoundTableEffectInfo> {
[[nodiscard]] static Result push(lua_State* L, const AudioSoundTableEffectInfo& value);
[[nodiscard]] static TypeResult<AudioSoundTableEffectInfo> get(lua_State* L, int index);
};
template<>
template <>
struct Stack<AudioSoundTableStreamInfo> {
[[nodiscard]] static Result push(lua_State* L, const AudioSoundTableStreamInfo& value);
[[nodiscard]] static TypeResult<AudioSoundTableStreamInfo> get(lua_State* L, int index);
@@ -62,4 +49,4 @@ struct Stack<AudioSoundTableStreamInfo> {
DECLARE_STRING_ENUM(SoundEffectCategory);
DECLARE_STRING_ENUM(StreamPan);
}
} // namespace luabridge
@@ -2,7 +2,7 @@
namespace luau_runtime::services::audio_res {
LuaAudioWaveHandle::LuaAudioWaveHandle(AudioWaveHandle handle) : BridgeScriptHandle(handle) { }
LuaAudioWaveHandle::LuaAudioWaveHandle(AudioWaveHandle handle) : BridgeScriptHandle(handle) {}
void LuaAudioWaveHandle::unregister_impl(lua_State*, Vm& vm) {
svc_audio_res->remove_wave(vm.subject, handle);
@@ -12,7 +12,8 @@ AudioWaveInfo const& default_wave_info() {
return *svc_audio_res->default_wave_info;
}
LuaAudioWaveHandle replace_wave(AudioWaveBank bank, uint16_t wave_id, char const* file, std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm) {
LuaAudioWaveHandle replace_wave(AudioWaveBank bank, uint16_t wave_id, char const* file,
std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm) {
AudioWaveInfo const* wave_info = nullptr;
if (info.has_value()) {
wave_info = &info->info;
@@ -20,15 +21,15 @@ LuaAudioWaveHandle replace_wave(AudioWaveBank bank, uint16_t wave_id, char const
AudioWaveHandle handle;
check_result(
state,
check_result(state,
svc_audio_res->replace_wave(vm.subject, bank, wave_id, file, wave_info, &handle),
"audio_res.replace_wave");
return LuaAudioWaveHandle(handle);
}
std::tuple<uint16_t, LuaAudioWaveHandle> add_wave(AudioWaveBank bank, char const* file, std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm) {
std::tuple<uint16_t, LuaAudioWaveHandle> add_wave(AudioWaveBank bank, char const* file,
std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm) {
AudioWaveInfo const* wave_info = nullptr;
if (info.has_value()) {
wave_info = &info->info;
@@ -37,8 +38,7 @@ std::tuple<uint16_t, LuaAudioWaveHandle> add_wave(AudioWaveBank bank, char const
AudioWaveHandle handle;
uint16_t out_wave_id;
check_result(
state,
check_result(state,
svc_audio_res->add_wave(vm.subject, bank, file, wave_info, &handle, &out_wave_id),
"audio_res.replace_wave");
@@ -80,7 +80,7 @@ Result Stack<AudioRawWave>::push(lua_State* L, const AudioRawWave& value) {
TypeResult<AudioRawWave> Stack<AudioRawWave>::get(lua_State* L, int index) {
auto const ref = LuaRef::fromStack(L, index);
return AudioRawWave {
return AudioRawWave{
.format = ref["format"],
.sample_rate = ref["sample_rate"],
.sample_value_last = opt_or<int16_t>(ref["sample_value_last"], 0),
@@ -97,11 +97,12 @@ Result Stack<OwnedWaveInfo>::push(lua_State* L, const OwnedWaveInfo& value) {
TypeResult<OwnedWaveInfo> Stack<OwnedWaveInfo>::get(lua_State* L, int index) {
auto const ref = LuaRef::fromStack(L, index);
AudioWaveInfo info {
AudioWaveInfo info{
.base_key = opt_or<uint8_t>(ref["base_key"], AUDIO_RES_DEFAULT_KEY),
.loop = opt_or<bool>(ref["loop"], false),
.loop_start_sample = opt_or<uint32_t>(ref["loop_start_sample"], 0),
.loop_end_sample = opt_or<uint32_t>(ref["loop_end_sample"], std::numeric_limits<uint32_t>::max()),
.loop_end_sample =
opt_or<uint32_t>(ref["loop_end_sample"], std::numeric_limits<uint32_t>::max()),
};
std::unique_ptr<AudioRawWave> raw;
@@ -110,7 +111,7 @@ TypeResult<OwnedWaveInfo> Stack<OwnedWaveInfo>::get(lua_State* L, int index) {
info.raw_wave = raw.get();
}
return OwnedWaveInfo { info, std::move(raw) };
return OwnedWaveInfo{info, std::move(raw)};
}
namespace {
@@ -118,21 +119,20 @@ namespace {
using namespace std::string_view_literals;
constexpr luau_runtime::EnumName<AudioWaveFormat> kWaveFormatNames[] = {
{ AUDIO_WAVE_FORMAT_ADPCM4, "adpcm4"sv },
{ AUDIO_WAVE_FORMAT_ADPCM2, "adpcm2"sv },
{ AUDIO_WAVE_FORMAT_PCM8, "pcm8"sv },
{ AUDIO_WAVE_FORMAT_PCM16, "pcm16"sv },
{AUDIO_WAVE_FORMAT_ADPCM4, "adpcm4"sv},
{AUDIO_WAVE_FORMAT_ADPCM2, "adpcm2"sv},
{AUDIO_WAVE_FORMAT_PCM8, "pcm8"sv},
{AUDIO_WAVE_FORMAT_PCM16, "pcm16"sv},
};
constexpr luau_runtime::EnumName<AudioWaveBank> kWaveBankNames[] = {
{ AUDIO_WAVE_BANK_SOUND_EFFECTS, "sound_effects"sv } ,
{ AUDIO_WAVE_BANK_MUSIC_SAMPLES, "music_samples"sv } ,
{AUDIO_WAVE_BANK_SOUND_EFFECTS, "sound_effects"sv},
{AUDIO_WAVE_BANK_MUSIC_SAMPLES, "music_samples"sv},
};
}
} // namespace
DEFINE_STRING_ENUM(AudioWaveFormat, kWaveFormatNames);
DEFINE_STRING_ENUM(AudioWaveBank, kWaveBankNames);
} // namespace luabridge
@@ -1,11 +1,11 @@
#pragma once
#include "LuaBridge/LuaBridge.h"
#include "lua.h"
#include "lualib.h"
#include "LuaBridge/LuaBridge.h"
#include "../../runtime.hpp"
#include "../../lua_helpers.hpp"
#include "../../runtime.hpp"
#include "mods/svc/audio_res.h"
#include <memory>
@@ -20,36 +20,41 @@ struct OwnedWaveInfo {
class LuaAudioWaveHandle final : public BridgeScriptHandle {
protected:
void unregister_impl(lua_State*, Vm& vm) override;
public:
explicit LuaAudioWaveHandle(AudioWaveHandle handle);
};
AudioWaveInfo const& default_wave_info();
LuaAudioWaveHandle replace_wave(AudioWaveBank bank, uint16_t wave_id, char const* file, std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm);
std::tuple<uint16_t, LuaAudioWaveHandle> add_wave(AudioWaveBank bank, char const* file, std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm);
LuaAudioWaveHandle replace_wave(AudioWaveBank bank, uint16_t wave_id, char const* file,
std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm);
std::tuple<uint16_t, LuaAudioWaveHandle> add_wave(AudioWaveBank bank, char const* file,
std::optional<OwnedWaveInfo> info, lua_State* state, Vm& vm);
}
} // namespace luau_runtime::services::audio_res
namespace luabridge {
template<>
template <>
struct Stack<AudioWaveInfo> {
[[nodiscard]] static Result push(lua_State* L, const AudioWaveInfo& value);
};
template<>
template <>
struct Stack<AudioRawWave> {
[[nodiscard]] static Result push(lua_State* L, const AudioRawWave& value);
[[nodiscard]] static TypeResult<AudioRawWave> get(lua_State* L, int index);
};
template<>
template <>
struct Stack<luau_runtime::services::audio_res::OwnedWaveInfo> {
[[nodiscard]] static Result push(lua_State* L, const luau_runtime::services::audio_res::OwnedWaveInfo& value);
[[nodiscard]] static TypeResult<luau_runtime::services::audio_res::OwnedWaveInfo> get(lua_State* L, int index);
[[nodiscard]] static Result push(
lua_State* L, const luau_runtime::services::audio_res::OwnedWaveInfo& value);
[[nodiscard]] static TypeResult<luau_runtime::services::audio_res::OwnedWaveInfo> get(
lua_State* L, int index);
};
DECLARE_STRING_ENUM(AudioWaveFormat);
DECLARE_STRING_ENUM(AudioWaveBank);
}
} // namespace luabridge
+1 -1
View File
@@ -338,4 +338,4 @@ int open_texture(lua_State* state) {
return 1;
}
} // namespace luau_runtime
} // namespace luau_runtime::services
+1 -1
View File
@@ -243,4 +243,4 @@ int open_config(lua_State* state) {
return 1;
}
} // namespace luau_runtime
} // namespace luau_runtime::services
+11 -11
View File
@@ -7,20 +7,20 @@ namespace {
using namespace std::string_view_literals;
constexpr std::pair<std::string_view, lua_CFunction> kModules[] = {
{ "dusklight.log"sv, open_log },
{ "dusklight.host"sv, open_host },
{ "dusklight.resource"sv, open_resource },
{ "dusklight.overlay"sv, open_overlay },
{ "dusklight.texture"sv, open_texture },
{ "dusklight.config"sv, open_config },
{ "dusklight.ui"sv, open_ui },
{ "dusklight.audio_res"sv, open_audio_res },
{"dusklight.log"sv, open_log},
{"dusklight.host"sv, open_host},
{"dusklight.resource"sv, open_resource},
{"dusklight.overlay"sv, open_overlay},
{"dusklight.texture"sv, open_texture},
{"dusklight.config"sv, open_config},
{"dusklight.ui"sv, open_ui},
{"dusklight.audio_res"sv, open_audio_res},
};
}
} // namespace
ModuleOpenFn module_factory(std::string_view name) {
for (auto [ modName, ptr ] : kModules) {
for (auto [modName, ptr] : kModules) {
if (name == modName) {
return ptr;
}
@@ -29,4 +29,4 @@ ModuleOpenFn module_factory(std::string_view name) {
return nullptr;
}
}
} // namespace luau_runtime::services
+1 -1
View File
@@ -18,4 +18,4 @@ int open_ui(lua_State* state);
ModuleOpenFn module_factory(std::string_view name);
}
} // namespace luau_runtime::services
+15 -15
View File
@@ -292,14 +292,14 @@ std::vector<UiListItem> list_items(lua_State* state, int table, std::vector<std:
}
constexpr EnumName<UiControlKind> kControlKindNames[] = {
{ UI_CONTROL_BUTTON, "button"sv },
{ UI_CONTROL_TOGGLE, "toggle"sv },
{ UI_CONTROL_NUMBER, "number"sv },
{ UI_CONTROL_STRING, "string"sv },
{ UI_CONTROL_SELECT, "select"sv },
{ UI_CONTROL_COLOR, "color"sv },
{ UI_CONTROL_GROUP, "group"sv },
{ UI_CONTROL_FILE_PICKER, "file_picker"sv },
{UI_CONTROL_BUTTON, "button"sv},
{UI_CONTROL_TOGGLE, "toggle"sv},
{UI_CONTROL_NUMBER, "number"sv},
{UI_CONTROL_STRING, "string"sv},
{UI_CONTROL_SELECT, "select"sv},
{UI_CONTROL_COLOR, "color"sv},
{UI_CONTROL_GROUP, "group"sv},
{UI_CONTROL_FILE_PICKER, "file_picker"sv},
};
UiControlKind control_kind(lua_State* state, const std::string& kind) {
@@ -307,12 +307,12 @@ UiControlKind control_kind(lua_State* state, const std::string& kind) {
}
constexpr EnumName<UiStyleScope> kStyleScopeNames[] = {
{ UI_SCOPE_PRELAUNCH, "prelaunch"sv },
{ UI_SCOPE_WINDOW, "window"sv },
{ UI_SCOPE_MENU_BAR, "menu_bar"sv },
{ UI_SCOPE_OVERLAY, "overlay"sv },
{ UI_SCOPE_TOUCH_CONTROLS, "touch_controls"sv },
{ UI_SCOPE_GRAPHICS_TUNER, "graphics_tuner"sv },
{UI_SCOPE_PRELAUNCH, "prelaunch"sv},
{UI_SCOPE_WINDOW, "window"sv},
{UI_SCOPE_MENU_BAR, "menu_bar"sv},
{UI_SCOPE_OVERLAY, "overlay"sv},
{UI_SCOPE_TOUCH_CONTROLS, "touch_controls"sv},
{UI_SCOPE_GRAPHICS_TUNER, "graphics_tuner"sv},
};
UiStyleScope style_scope(lua_State* state, const std::string& scope) {
@@ -851,4 +851,4 @@ int open_ui(lua_State* state) {
return 1;
}
} // namespace luau_runtime
} // namespace luau_runtime::services
+4 -7
View File
@@ -42,18 +42,15 @@ void sync_audio_replacements() {
bst::sync_audio_replacements();
}
}
} // namespace
} // namespace audio_res
constinit const ServiceModule g_audioResModule{
.id = AUDIO_RES_SERVICE_ID,
constinit const ServiceModule g_audioResModule{.id = AUDIO_RES_SERVICE_ID,
.majorVersion = AUDIO_RES_SERVICE_MAJOR,
.minorVersion = AUDIO_RES_SERVICE_MINOR,
.service = &audio_res::s_audioResService,
.modDetached = audio_res::mod_detached,
.lifecycleApplied = audio_res::sync_audio_replacements,
.frameEnd = audio_res::frame_end
};
};
.frameEnd = audio_res::frame_end};
}; // namespace dusk::mods::svc
+15 -39
View File
@@ -15,25 +15,15 @@ void sync_audio_replacements();
extern AudioWaveInfo const default_wave_info;
ModResult insert_replace_wave(
ModContext* ctx,
AudioWaveBank bank,
u16 wave_id,
char const* file_name,
AudioWaveInfo const* wave_info,
AudioWaveHandle* out_handle);
ModResult insert_replace_wave(ModContext* ctx, AudioWaveBank bank, u16 wave_id,
char const* file_name, AudioWaveInfo const* wave_info, AudioWaveHandle* out_handle);
ModResult insert_add_wave(
ModContext* ctx,
AudioWaveBank bank,
char const* file_name,
AudioWaveInfo const* wave_info,
AudioWaveHandle* out_handle,
u16* out_wave_id);
ModResult insert_add_wave(ModContext* ctx, AudioWaveBank bank, char const* file_name,
AudioWaveInfo const* wave_info, AudioWaveHandle* out_handle, u16* out_wave_id);
ModResult remove_wave(ModContext* ctx, AudioWaveHandle handle);
}
} // namespace wsys
namespace bst {
@@ -43,38 +33,24 @@ void sync_audio_replacements();
extern AudioSoundTableEffectInfo const default_effect_info;
ModResult replace_sound_table_effect(
ModContext* ctx,
SoundEffectCategory category_id,
uint16_t effect_id,
AudioSoundTableEffectInfo const* info,
AudioSoundTableHandle* out_handle);
ModResult replace_sound_table_effect(ModContext* ctx, SoundEffectCategory category_id,
uint16_t effect_id, AudioSoundTableEffectInfo const* info, AudioSoundTableHandle* out_handle);
ModResult add_sound_table_effect(
ModContext* ctx,
SoundEffectCategory category_id,
AudioSoundTableEffectInfo const* info,
AudioSoundTableHandle* out_handle,
ModResult add_sound_table_effect(ModContext* ctx, SoundEffectCategory category_id,
AudioSoundTableEffectInfo const* info, AudioSoundTableHandle* out_handle,
uint16_t* out_effect_id);
extern AudioSoundTableStreamInfo const default_stream_info;
ModResult replace_sound_table_stream(
ModContext* ctx,
uint16_t stream_id,
char const* file_path,
AudioSoundTableStreamInfo const* info,
AudioSoundTableHandle* out_handle);
ModResult replace_sound_table_stream(ModContext* ctx, uint16_t stream_id, char const* file_path,
AudioSoundTableStreamInfo const* info, AudioSoundTableHandle* out_handle);
ModResult add_sound_table_stream(
ModContext* ctx,
char const* file_path,
AudioSoundTableStreamInfo const* info,
AudioSoundTableHandle* out_handle,
ModResult add_sound_table_stream(ModContext* ctx, char const* file_path,
AudioSoundTableStreamInfo const* info, AudioSoundTableHandle* out_handle,
uint16_t* out_stream_id);
ModResult remove_sound_table(ModContext* ctx, AudioSoundTableHandle handle);
}
} // namespace bst
}
} // namespace dusk::mods::svc::audio_res
+35 -40
View File
@@ -17,16 +17,16 @@ aurora::Module Log("dusk::mods::svc::audio_res");
SlotMap<std::shared_ptr<SoundTableReplacementSlot>> sound_replacements;
std::array sound_effect_id_allocator = {
PlainIdAllocator<u16>(0x1000), // SYSTEM_SE
PlainIdAllocator<u16>(0x1000), // PLAYER_VOICE
PlainIdAllocator<u16>(0x1000), // PLAYER_SE
PlainIdAllocator<u16>(0x1000), // FOOTNOTE_SE
PlainIdAllocator<u16>(0x1000), // COLLISION_SE
PlainIdAllocator<u16>(0x1000), // CHARA_VOICE
PlainIdAllocator<u16>(0x1000), // CHARA_SE
PlainIdAllocator<u16>(0x1000), // ENEMY_SE
PlainIdAllocator<u16>(0x1000), // OBJECT_SE
PlainIdAllocator<u16>(0x1000), // ENV_SE
PlainIdAllocator<u16>(0x1000), // SYSTEM_SE
PlainIdAllocator<u16>(0x1000), // PLAYER_VOICE
PlainIdAllocator<u16>(0x1000), // PLAYER_SE
PlainIdAllocator<u16>(0x1000), // FOOTNOTE_SE
PlainIdAllocator<u16>(0x1000), // COLLISION_SE
PlainIdAllocator<u16>(0x1000), // CHARA_VOICE
PlainIdAllocator<u16>(0x1000), // CHARA_SE
PlainIdAllocator<u16>(0x1000), // ENEMY_SE
PlainIdAllocator<u16>(0x1000), // OBJECT_SE
PlainIdAllocator<u16>(0x1000), // ENV_SE
};
PlainIdAllocator<u16> stream_id_allocator(0x1000);
@@ -40,7 +40,8 @@ uint8_t volume_to_item(float volume) {
return static_cast<uint8_t>(volume * 127);
}
absl::flat_hash_map<SoundEffectKey, std::shared_ptr<SoundEffectReplacementSlot>> active_se_replacements;
absl::flat_hash_map<SoundEffectKey, std::shared_ptr<SoundEffectReplacementSlot>>
active_se_replacements;
absl::flat_hash_map<u16, std::shared_ptr<StreamReplacementSlot>> active_stream_replacements;
std::mutex active_replacements_mutex;
@@ -74,9 +75,11 @@ SoundEffectReplacementSlot::SoundEffectReplacementSlot(
sw_bit |= (info.doppler_power << SOUND_SW_DOPPLER_POWER_OFFSET) & SOUND_SW_DOPPLER_POWER_MASK;
if (info.volume_dist_class < 8) {
sw_bit |= (info.volume_dist_class << SOUND_SW_VOL_DIST_BIT_OFFSET) & SOUND_SW_VOL_DIST_BIT_MASK;
sw_bit |=
(info.volume_dist_class << SOUND_SW_VOL_DIST_BIT_OFFSET) & SOUND_SW_VOL_DIST_BIT_MASK;
} else {
sw_bit |= ((info.volume_dist_class - 8) << SOUND_SW_VOL_DIST_BIT_2_OFFSET) & SOUND_SW_VOL_DIST_BIT_2_MASK;
sw_bit |= ((info.volume_dist_class - 8) << SOUND_SW_VOL_DIST_BIT_2_OFFSET) &
SOUND_SW_VOL_DIST_BIT_2_MASK;
}
if (info.clamp_min_volume)
@@ -140,8 +143,7 @@ std::shared_ptr<SoundEffectReplacementSlot> get_override_for_se(JAISoundID id) {
std::lock_guard lock(active_replacements_mutex);
SoundEffectKey const key(
static_cast<SoundEffectCategory>(id.id_.info.type.parts.groupID),
id.id_.info.waveID);
static_cast<SoundEffectCategory>(id.id_.info.type.parts.groupID), id.id_.info.waveID);
auto const entry = active_se_replacements.find(key);
if (entry == active_se_replacements.end()) {
@@ -181,13 +183,14 @@ void frame_end() {
void sync_audio_replacements() {
sound_replacements_dirty = false;
absl::flat_hash_map<SoundEffectKey, std::shared_ptr<SoundEffectReplacementSlot>> new_se_replacements;
absl::flat_hash_map<SoundEffectKey, std::shared_ptr<SoundEffectReplacementSlot>>
new_se_replacements;
absl::flat_hash_map<u16, std::shared_ptr<StreamReplacementSlot>> new_stream_replacements;
for (auto const& mod : ModLoader::instance().active_mods()) {
sound_replacements.for_each([&](auto, auto const& entry) {
if (entry.owner != &mod) {
return;
return;
}
std::shared_ptr<SoundTableReplacementSlot> const& value = entry.value;
@@ -212,7 +215,8 @@ void sync_audio_replacements() {
}
static ModResult insert_sound_table_effect_core(ModContext* ctx, SoundEffectCategory category_id,
uint16_t effect_id, bool mod_defined, AudioSoundTableEffectInfo const* info, AudioSoundTableHandle* out_handle) {
uint16_t effect_id, bool mod_defined, AudioSoundTableEffectInfo const* info,
AudioSoundTableHandle* out_handle) {
if (out_handle != nullptr) {
*out_handle = 0;
}
@@ -226,7 +230,8 @@ static ModResult insert_sound_table_effect_core(ModContext* ctx, SoundEffectCate
info = &default_effect_info;
}
auto slot = std::make_shared<SoundEffectReplacementSlot>(mod_defined, effect_id, category_id, *info);
auto slot =
std::make_shared<SoundEffectReplacementSlot>(mod_defined, effect_id, category_id, *info);
sound_replacements_dirty = true;
auto const handle = sound_replacements.emplace(*mod, std::move(slot));
@@ -247,7 +252,6 @@ AudioSoundTableEffectInfo const default_effect_info(128, 1, 1);
ModResult add_sound_table_effect(ModContext* ctx, SoundEffectCategory category_id,
AudioSoundTableEffectInfo const* info, AudioSoundTableHandle* out_handle,
uint16_t* out_effect_id) {
if (out_effect_id == nullptr || !validate_category(category_id)) {
return MOD_INVALID_ARGUMENT;
}
@@ -257,7 +261,8 @@ ModResult add_sound_table_effect(ModContext* ctx, SoundEffectCategory category_i
auto& allocator = sound_effect_id_allocator[category_id];
auto const effect_id = allocator.alloc();
auto const result = insert_sound_table_effect_core(ctx, category_id, effect_id, true, info, out_handle);
auto const result =
insert_sound_table_effect_core(ctx, category_id, effect_id, true, info, out_handle);
if (result != MOD_OK) {
allocator.free(effect_id);
}
@@ -267,12 +272,8 @@ ModResult add_sound_table_effect(ModContext* ctx, SoundEffectCategory category_i
return result;
}
static ModResult insert_sound_table_stream_core(
ModContext* ctx,
uint16_t stream_id,
bool mod_defined,
char const* file_path,
AudioSoundTableStreamInfo const* info,
static ModResult insert_sound_table_stream_core(ModContext* ctx, uint16_t stream_id,
bool mod_defined, char const* file_path, AudioSoundTableStreamInfo const* info,
AudioSoundTableHandle* out_handle) {
if (out_handle != nullptr) {
*out_handle = 0;
@@ -298,30 +299,24 @@ static ModResult insert_sound_table_stream_core(
return MOD_OK;
}
AudioSoundTableStreamInfo const default_stream_info(
128,
1,
{
STREAM_PAN_LEFT,
STREAM_PAN_RIGHT
});
AudioSoundTableStreamInfo const default_stream_info(128, 1, {STREAM_PAN_LEFT, STREAM_PAN_RIGHT});
ModResult replace_sound_table_stream(ModContext* ctx, uint16_t stream_id,
char const* file_path,
ModResult replace_sound_table_stream(ModContext* ctx, uint16_t stream_id, char const* file_path,
AudioSoundTableStreamInfo const* info, AudioSoundTableHandle* out_handle) {
return insert_sound_table_stream_core(ctx, stream_id, false, file_path, info, out_handle);
}
ModResult add_sound_table_stream(ModContext* ctx,
char const* file_path, AudioSoundTableStreamInfo const* info,
AudioSoundTableHandle* out_handle, uint16_t* out_stream_id) {
ModResult add_sound_table_stream(ModContext* ctx, char const* file_path,
AudioSoundTableStreamInfo const* info, AudioSoundTableHandle* out_handle,
uint16_t* out_stream_id) {
if (out_stream_id == nullptr) {
return MOD_INVALID_ARGUMENT;
}
auto const stream_id = stream_id_allocator.alloc();
auto const result = insert_sound_table_stream_core(ctx, stream_id, true, file_path, info, out_handle);
auto const result =
insert_sound_table_stream_core(ctx, stream_id, true, file_path, info, out_handle);
if (result != MOD_OK) {
stream_id_allocator.free(stream_id);
}
+3 -2
View File
@@ -35,7 +35,8 @@ struct StreamReplacementSlot final : SoundTableReplacementSlot {
std::string file_path;
bool stop_on_scene_change;
StreamReplacementSlot(bool mod_defined, u16 id, char const* file_path, const AudioSoundTableStreamInfo& info);
StreamReplacementSlot(
bool mod_defined, u16 id, char const* file_path, const AudioSoundTableStreamInfo& info);
~StreamReplacementSlot() override = default;
@@ -60,4 +61,4 @@ std::shared_ptr<SoundTableReplacementSlot> get_override_for(JAISoundID id);
std::shared_ptr<SoundEffectReplacementSlot> get_override_for_se(JAISoundID id);
std::shared_ptr<StreamReplacementSlot> get_override_for_stream(JAISoundID id);
}
} // namespace dusk::mods::svc::audio_res::bst
+20 -20
View File
@@ -1,10 +1,10 @@
#if DUSK_OPUS
#include "wsys.hpp"
#include "aurora/lib/logging.hpp"
#include "dusk/mod_loader.hpp"
#include "helpers/cast.hpp"
#include "opusfile.h"
#include "wsys.hpp"
namespace {
@@ -13,19 +13,16 @@ aurora::Module Log("dusk::mods::svc::audio_res::wsys::opus");
struct OpusHandle {
OggOpusFile* file;
~OpusHandle() {
op_free(file);
}
~OpusHandle() { op_free(file); }
operator OggOpusFile*() const {
return file;
}
operator OggOpusFile*() const { return file; }
};
}
} // namespace
namespace dusk::mods::svc::audio_res::wsys {
ModResult load_opus(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData) {
ModResult load_opus(
LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData) {
OpusHead head;
const int result = op_test(&head, fileData.data(), fileData.size());
if (result != 0) {
@@ -33,26 +30,30 @@ ModResult load_opus(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std:
}
if (head.channel_count != 1) {
Log.error("[{}] replace_wave: file '{}' must be mono but actually has {} channels", mod.metadata.id, slot.bundle_path, head.channel_count);
Log.error("[{}] replace_wave: file '{}' must be mono but actually has {} channels",
mod.metadata.id, slot.bundle_path, head.channel_count);
return MOD_INVALID_ARGUMENT;
}
if (head.stream_count != 1) {
Log.error("[{}] replace_wave: file '{}' has multiple Opus streams!", mod.metadata.id, slot.bundle_path);
Log.error("[{}] replace_wave: file '{}' has multiple Opus streams!", mod.metadata.id,
slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
int error;
auto const handle_raw = op_open_memory(fileData.data(), fileData.size(), &error);
if (error != 0) {
Log.error("[{}] replace_wave: file '{}': unable to open Opus file: {}", mod.metadata.id, slot.bundle_path, error);
Log.error("[{}] replace_wave: file '{}': unable to open Opus file: {}", mod.metadata.id,
slot.bundle_path, error);
return MOD_ERROR;
}
const OpusHandle handle(handle_raw);
auto const length = op_pcm_total(handle, -1);
if (length < 0) {
Log.error("[{}] replace_wave: file '{}': failed to check stream length?", mod.metadata.id, slot.bundle_path);
Log.error("[{}] replace_wave: file '{}': failed to check stream length?", mod.metadata.id,
slot.bundle_path);
return MOD_ERROR;
}
@@ -62,13 +63,12 @@ ModResult load_opus(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std:
std::span span_pcm(pcm_buffer.data);
while (!span_pcm.empty()) {
auto read_result = op_read(
handle,
span_pcm.data(), helpers::cast::bounded_cast(span_pcm.size()),
nullptr);
auto read_result =
op_read(handle, span_pcm.data(), helpers::cast::bounded_cast(span_pcm.size()), nullptr);
if (read_result <= 0) {
Log.error("[{}] replace_wave: file '{}': failed to read Opus: {}", mod.metadata.id, slot.bundle_path, read_result);
Log.error("[{}] replace_wave: file '{}': failed to read Opus: {}", mod.metadata.id,
slot.bundle_path, read_result);
return MOD_ERROR;
}
@@ -82,12 +82,12 @@ ModResult load_opus(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std:
pcm_buffer.be_swap();
slot.data = std::make_shared<SampleDataPcm16>(std::move(pcm_buffer));
slot.sample_rate = 48000; // Opus always decodes at 48 kHz.
slot.sample_rate = 48000; // Opus always decodes at 48 kHz.
slot.sample_count = length;
slot.format = AUDIO_WAVE_FORMAT_PCM16;
return MOD_OK;
}
}
} // namespace dusk::mods::svc::audio_res::wsys
#endif
+21 -13
View File
@@ -1,7 +1,7 @@
#include "wsys.hpp"
#include "aurora/lib/logging.hpp"
#include "dusk/mod_loader.hpp"
#include "helpers/alignment.hpp"
#include "wsys.hpp"
namespace {
@@ -13,8 +13,8 @@ struct ChunkHeader {
};
struct RiffChunk {
ChunkHeader header; // magic "RIFF"
char id[4]; // "WAVE"
ChunkHeader header; // magic "RIFF"
char id[4]; // "WAVE"
// Data after chunk.
};
@@ -35,11 +35,12 @@ bool check_four_cc(char const (&field)[4], char const (&expected)[5]) {
return memcmp(field, expected, 4) == 0;
}
}
} // namespace
namespace dusk::mods::svc::audio_res::wsys {
ModResult load_wav(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData) {
ModResult load_wav(
LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData) {
using namespace helpers;
if (fileData.size() < sizeof(RiffChunk)) {
@@ -55,7 +56,8 @@ ModResult load_wav(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::
return MOD_UNSUPPORTED;
}
if (sizeof(ChunkHeader) + riffChunk.header.size > fileData.size() || riffChunk.header.size < 4) {
if (sizeof(ChunkHeader) + riffChunk.header.size > fileData.size() || riffChunk.header.size < 4)
{
Log.error("[{}] wav file {}: invalid size!", mod.metadata.id, slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
@@ -69,29 +71,34 @@ ModResult load_wav(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::
if (check_four_cc(chunkHeader.magic, "fmt ")) {
if (has_read_fmt) {
Log.error("[{}] wav file {}: multiple fmt chunks!", mod.metadata.id, slot.bundle_path);
Log.error(
"[{}] wav file {}: multiple fmt chunks!", mod.metadata.id, slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
if (waveData.size() < sizeof(FmtPcmChunkData)) {
Log.error("[{}] wav file {}: fmt chunk too small!", mod.metadata.id, slot.bundle_path);
Log.error(
"[{}] wav file {}: fmt chunk too small!", mod.metadata.id, slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
auto const fmtChunk = read_unaligned<FmtPcmChunkData>(&waveData[0]);
if (fmtChunk.nChannels != 1) {
Log.error("[{}] wav file {}: only mono audio is supported", mod.metadata.id, slot.bundle_path);
Log.error("[{}] wav file {}: only mono audio is supported", mod.metadata.id,
slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
if (fmtChunk.wFormatTag != WAVE_FORMAT_PCM) {
Log.error("[{}] wav file {}: only 16-bit PCM is supported", mod.metadata.id, slot.bundle_path);
Log.error("[{}] wav file {}: only 16-bit PCM is supported", mod.metadata.id,
slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
if (fmtChunk.wBitsPerSample != 16) {
Log.error("[{}] wav file {}: only 16-bit PCM is supported", mod.metadata.id, slot.bundle_path);
Log.error("[{}] wav file {}: only 16-bit PCM is supported", mod.metadata.id,
slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
@@ -100,7 +107,8 @@ ModResult load_wav(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::
} else if (check_four_cc(chunkHeader.magic, "data")) {
if (sizeof(chunkHeader) + chunkHeader.size > fileData.size()) {
Log.error("[{}] wav file {}: unexpected EOF reading sample data", mod.metadata.id, slot.bundle_path);
Log.error("[{}] wav file {}: unexpected EOF reading sample data", mod.metadata.id,
slot.bundle_path);
return MOD_INVALID_ARGUMENT;
}
@@ -142,4 +150,4 @@ ModResult load_wav(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::
return MOD_OK;
}
}
} // namespace dusk::mods::svc::audio_res::wsys
+25 -40
View File
@@ -1,7 +1,7 @@
#include "audio_res.hpp"
#include "wsys.hpp"
#include "../internal.hpp"
#include "../id_allocator.hpp"
#include "../internal.hpp"
#include "audio_res.hpp"
#include "aurora/lib/logging.hpp"
#include "dusk/audio/DuskAudioSystem.h"
#include "dusk/mods/loader/loader.hpp"
@@ -30,10 +30,12 @@ PlainIdAllocator<u16> sound_effect_id_allocator(5'000);
PlainIdAllocator<u16> music_sample_id_allocator(1'000);
PlainIdAllocator<u16>& id_allocator_for_bank(AudioWaveBank const bank) {
return bank == AUDIO_WAVE_BANK_SOUND_EFFECTS ? sound_effect_id_allocator : music_sample_id_allocator;
return bank == AUDIO_WAVE_BANK_SOUND_EFFECTS ? sound_effect_id_allocator :
music_sample_id_allocator;
}
bool validate_raw_size(LoadedMod const& mod, std::string const& path, uintptr_t actual_size, AudioRawWave const& raw, u32& sample_count) {
bool validate_raw_size(LoadedMod const& mod, std::string const& path, uintptr_t actual_size,
AudioRawWave const& raw, u32& sample_count) {
u32 samples_per_block;
u32 bytes_per_block;
switch (raw.format) {
@@ -51,7 +53,8 @@ bool validate_raw_size(LoadedMod const& mod, std::string const& path, uintptr_t
}
if (actual_size % bytes_per_block != 0) {
Log.error("[{}] raw file is not divisible by format block size: '{}'", mod.metadata.id, path);
Log.error(
"[{}] raw file is not divisible by format block size: '{}'", mod.metadata.id, path);
return false;
}
@@ -116,7 +119,7 @@ JASWaveInfo wave_info_from_slot(RuntimeWaveReplacementSlot const& slot) {
info.mBaseKey = slot.base_key;
info.mLoopFlag = slot.loop ? 0xFF : 0;
info.mSampleRate = slot.sample_rate;
info.mOffsetStart = 0; // Unused but just init it ig.
info.mOffsetStart = 0; // Unused but just init it ig.
info.mOffsetLength = bounded_cast(slot.data->size());
info.mLoopStartSample = slot.loop_start_sample;
info.mLoopEndSample = bounded_cast(slot.loop_end_sample);
@@ -142,13 +145,8 @@ bool wave_remove(LoadedMod const& mod, AudioWaveHandle const handle) {
return true;
}
ModResult insert_replace_wave_core(
ModContext* ctx,
AudioWaveBank bank,
u16 wave_id,
bool mod_defined,
char const* file_name,
AudioWaveInfo const* wave_info,
ModResult insert_replace_wave_core(ModContext* ctx, AudioWaveBank bank, u16 wave_id,
bool mod_defined, char const* file_name, AudioWaveInfo const* wave_info,
AudioWaveHandle* out_handle) {
if (out_handle != nullptr) {
*out_handle = 0;
@@ -206,13 +204,13 @@ ModResult insert_replace_wave_core(
return MOD_OK;
}
}
} // namespace
absl::flat_hash_map<AudioWaveKey, AudioWaveReplacementValue> s_replacements;
std::mutex s_replacements_mutex;
AudioWaveInfo const default_wave_info(AUDIO_RES_DEFAULT_KEY, false, 0, std::numeric_limits<u32>::max(), nullptr);
AudioWaveInfo const default_wave_info(
AUDIO_RES_DEFAULT_KEY, false, 0, std::numeric_limits<u32>::max(), nullptr);
ModResult remove_wave(ModContext* ctx, AudioWaveHandle handle) {
auto* mod = mod_from_context(ctx);
@@ -226,25 +224,13 @@ ModResult remove_wave(ModContext* ctx, AudioWaveHandle handle) {
return MOD_OK;
}
ModResult insert_replace_wave(
ModContext* ctx,
AudioWaveBank bank,
u16 wave_id,
char const* file_name,
AudioWaveInfo const* wave_info,
AudioWaveHandle* out_handle) {
ModResult insert_replace_wave(ModContext* ctx, AudioWaveBank bank, u16 wave_id,
char const* file_name, AudioWaveInfo const* wave_info, AudioWaveHandle* out_handle) {
return insert_replace_wave_core(ctx, bank, wave_id, false, file_name, wave_info, out_handle);
}
ModResult insert_add_wave(
ModContext* ctx,
AudioWaveBank bank,
char const* file_name,
AudioWaveInfo const* wave_info,
AudioWaveHandle* out_handle,
u16* out_wave_id) {
ModResult insert_add_wave(ModContext* ctx, AudioWaveBank bank, char const* file_name,
AudioWaveInfo const* wave_info, AudioWaveHandle* out_handle, u16* out_wave_id) {
if (out_wave_id == nullptr) {
return MOD_INVALID_ARGUMENT;
}
@@ -258,7 +244,8 @@ ModResult insert_add_wave(
auto& allocator = id_allocator_for_bank(bank);
auto const new_wave_id = allocator.alloc();
auto const result = insert_replace_wave_core(ctx, bank, new_wave_id, true, file_name, wave_info, out_handle);
auto const result =
insert_replace_wave_core(ctx, bank, new_wave_id, true, file_name, wave_info, out_handle);
if (result != MOD_OK) {
allocator.free(new_wave_id);
}
@@ -280,13 +267,12 @@ void sync_audio_replacements() {
for (auto const& mod : ModLoader::instance().active_mods()) {
s_waveReplacements.for_each([&](auto, auto entry) {
if (entry.owner != &mod) {
return;
}
if (entry.owner != &mod) {
return;
}
auto const wave_info = wave_info_from_slot(entry.value);
new_map.emplace(
AudioWaveKey(entry.value.bank, entry.value.wave_id),
new_map.emplace(AudioWaveKey(entry.value.bank, entry.value.wave_id),
AudioWaveReplacementValue(wave_info, entry.value.data));
});
}
@@ -330,5 +316,4 @@ void SampleDataPcm16::be_swap() {
}
}
}
} // namespace dusk::mods::svc::audio_res::wsys
+11 -9
View File
@@ -15,9 +15,7 @@ namespace dusk::mods::svc::audio_res::wsys {
struct SampleDataBuf {
virtual ~SampleDataBuf() = default;
[[nodiscard]] virtual std::span<std::byte const> get_data() const = 0;
[[nodiscard]] size_t size() const {
return get_data().size();
}
[[nodiscard]] size_t size() const { return get_data().size(); }
};
// Making a separate type for this rather than just using a vector<u8>
@@ -60,12 +58,13 @@ struct AudioWaveKey {
}
[[nodiscard]] bool operator==(const AudioWaveKey& other) const {
return other.bank == bank && other.wave_id == wave_id;
return other.bank == bank && other.wave_id == wave_id;
}
};
struct AudioWaveReplacementValue : JASWaveHandle {
AudioWaveReplacementValue(const JASWaveInfo& wave_info, std::shared_ptr<SampleDataBuf> data) : wave_info(wave_info), data(std::move(data)) {};
AudioWaveReplacementValue(const JASWaveInfo& wave_info, std::shared_ptr<SampleDataBuf> data)
: wave_info(wave_info), data(std::move(data)) {};
~AudioWaveReplacementValue() override;
[[nodiscard]] const JASWaveInfo* getWaveInfo() const override;
[[nodiscard]] intptr_t getWavePtr() const override;
@@ -99,9 +98,12 @@ struct RuntimeWaveReplacementSlot {
std::shared_ptr<SampleDataBuf> data;
};
using ContainerLoadFunction = ModResult (*)(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData);
using ContainerLoadFunction = ModResult (*)(
LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData);
ModResult load_wav(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData);
ModResult load_opus(LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData);
ModResult load_wav(
LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData);
ModResult load_opus(
LoadedMod const& mod, RuntimeWaveReplacementSlot& slot, std::span<u8 const> fileData);
}
} // namespace dusk::mods::svc::audio_res::wsys
+6 -7
View File
@@ -1,23 +1,22 @@
#pragma once
#include <vector>
#include <limits>
#include <vector>
namespace dusk::mods::svc {
[[noreturn]] void id_allocator_exhausted();
template<typename T> requires std::is_integral_v<T>
template <typename T>
requires std::is_integral_v<T>
class PlainIdAllocator {
std::vector<T> reusable;
T alloc_next;
T alloc_max;
public:
constexpr explicit PlainIdAllocator(T first, T max=std::numeric_limits<T>::max())
: alloc_next(first), alloc_max(max) {
}
constexpr explicit PlainIdAllocator(T first, T max = std::numeric_limits<T>::max())
: alloc_next(first), alloc_max(max) {}
T alloc() {
if (reusable.empty()) {
@@ -40,4 +39,4 @@ public:
}
};
}
} // namespace dusk::mods::svc