diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua
index c76fa629..b281c0f3 100644
--- a/autogen/lua_definitions/functions.lua
+++ b/autogen/lua_definitions/functions.lua
@@ -8148,6 +8148,26 @@ function get_vertex_color(index)
-- ...
end
+--- @return number
+function get_volume_env()
+ -- ...
+end
+
+--- @return number
+function get_volume_level()
+ -- ...
+end
+
+--- @return number
+function get_volume_master()
+ -- ...
+end
+
+--- @return number
+function get_volume_sfx()
+ -- ...
+end
+
--- @param index integer
--- @return integer
function get_water_level(index)
@@ -8336,6 +8356,26 @@ function set_vertex_color(index, value)
-- ...
end
+--- @param volume number
+function set_volume_env(volume)
+ -- ...
+end
+
+--- @param volume number
+function set_volume_level(volume)
+ -- ...
+end
+
+--- @param volume number
+function set_volume_master(volume)
+ -- ...
+end
+
+--- @param volume number
+function set_volume_sfx(volume)
+ -- ...
+end
+
--- @param index integer
--- @param height integer
--- @param sync boolean
diff --git a/docs/lua/functions-5.md b/docs/lua/functions-5.md
index 33eecbd0..bcf9bf8f 100644
--- a/docs/lua/functions-5.md
+++ b/docs/lua/functions-5.md
@@ -2163,6 +2163,78 @@
+## [get_volume_env](#get_volume_env)
+
+### Lua Example
+`local numberValue = get_volume_env()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_env(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_level](#get_volume_level)
+
+### Lua Example
+`local numberValue = get_volume_level()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_level(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_master](#get_volume_master)
+
+### Lua Example
+`local numberValue = get_volume_master()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_master(void);`
+
+[:arrow_up_small:](#)
+
+
+
+## [get_volume_sfx](#get_volume_sfx)
+
+### Lua Example
+`local numberValue = get_volume_sfx()`
+
+### Parameters
+- None
+
+### Returns
+- `number`
+
+### C Prototype
+`f32 get_volume_sfx(void);`
+
+[:arrow_up_small:](#)
+
+
+
## [get_water_level](#get_water_level)
### Lua Example
@@ -2831,6 +2903,86 @@
+## [set_volume_env](#set_volume_env)
+
+### Lua Example
+`set_volume_env(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_env(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_level](#set_volume_level)
+
+### Lua Example
+`set_volume_level(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_level(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_master](#set_volume_master)
+
+### Lua Example
+`set_volume_master(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_master(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
+## [set_volume_sfx](#set_volume_sfx)
+
+### Lua Example
+`set_volume_sfx(volume)`
+
+### Parameters
+| Field | Type |
+| ----- | ---- |
+| volume | `number` |
+
+### Returns
+- None
+
+### C Prototype
+`void set_volume_sfx(f32 volume);`
+
+[:arrow_up_small:](#)
+
+
+
## [set_water_level](#set_water_level)
### Lua Example
diff --git a/docs/lua/functions.md b/docs/lua/functions.md
index 80abecba..94d68a08 100644
--- a/docs/lua/functions.md
+++ b/docs/lua/functions.md
@@ -1695,6 +1695,10 @@
- [get_time](functions-5.md#get_time)
- [get_ttc_speed_setting](functions-5.md#get_ttc_speed_setting)
- [get_vertex_color](functions-5.md#get_vertex_color)
+ - [get_volume_env](functions-5.md#get_volume_env)
+ - [get_volume_level](functions-5.md#get_volume_level)
+ - [get_volume_master](functions-5.md#get_volume_master)
+ - [get_volume_sfx](functions-5.md#get_volume_sfx)
- [get_water_level](functions-5.md#get_water_level)
- [hud_get_flash](functions-5.md#hud_get_flash)
- [hud_get_value](functions-5.md#hud_get_value)
@@ -1728,6 +1732,10 @@
- [set_save_file_modified](functions-5.md#set_save_file_modified)
- [set_ttc_speed_setting](functions-5.md#set_ttc_speed_setting)
- [set_vertex_color](functions-5.md#set_vertex_color)
+ - [set_volume_env](functions-5.md#set_volume_env)
+ - [set_volume_level](functions-5.md#set_volume_level)
+ - [set_volume_master](functions-5.md#set_volume_master)
+ - [set_volume_sfx](functions-5.md#set_volume_sfx)
- [set_water_level](functions-5.md#set_water_level)
- [set_window_title](functions-5.md#set_window_title)
diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c
index 961f695c..3b842e76 100644
--- a/src/pc/lua/smlua_functions_autogen.c
+++ b/src/pc/lua/smlua_functions_autogen.c
@@ -30040,6 +30040,66 @@ int smlua_func_get_vertex_color(lua_State* L) {
return 1;
}
+int smlua_func_get_volume_env(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_volume_env", 0, top);
+ return 0;
+ }
+
+
+ lua_pushnumber(L, get_volume_env());
+
+ return 1;
+}
+
+int smlua_func_get_volume_level(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_volume_level", 0, top);
+ return 0;
+ }
+
+
+ lua_pushnumber(L, get_volume_level());
+
+ return 1;
+}
+
+int smlua_func_get_volume_master(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_volume_master", 0, top);
+ return 0;
+ }
+
+
+ lua_pushnumber(L, get_volume_master());
+
+ return 1;
+}
+
+int smlua_func_get_volume_sfx(UNUSED lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 0) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_volume_sfx", 0, top);
+ return 0;
+ }
+
+
+ lua_pushnumber(L, get_volume_sfx());
+
+ return 1;
+}
+
int smlua_func_get_water_level(lua_State* L) {
if (L == NULL) { return 0; }
@@ -30633,6 +30693,74 @@ int smlua_func_set_vertex_color(lua_State* L) {
return 1;
}
+int smlua_func_set_volume_env(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "set_volume_env", 1, top);
+ return 0;
+ }
+
+ f32 volume = smlua_to_number(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_volume_env"); return 0; }
+
+ set_volume_env(volume);
+
+ return 1;
+}
+
+int smlua_func_set_volume_level(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "set_volume_level", 1, top);
+ return 0;
+ }
+
+ f32 volume = smlua_to_number(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_volume_level"); return 0; }
+
+ set_volume_level(volume);
+
+ return 1;
+}
+
+int smlua_func_set_volume_master(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "set_volume_master", 1, top);
+ return 0;
+ }
+
+ f32 volume = smlua_to_number(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_volume_master"); return 0; }
+
+ set_volume_master(volume);
+
+ return 1;
+}
+
+int smlua_func_set_volume_sfx(lua_State* L) {
+ if (L == NULL) { return 0; }
+
+ int top = lua_gettop(L);
+ if (top != 1) {
+ LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "set_volume_sfx", 1, top);
+ return 0;
+ }
+
+ f32 volume = smlua_to_number(L, 1);
+ if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "set_volume_sfx"); return 0; }
+
+ set_volume_sfx(volume);
+
+ return 1;
+}
+
int smlua_func_set_water_level(lua_State* L) {
if (L == NULL) { return 0; }
@@ -34113,6 +34241,10 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "get_time", smlua_func_get_time);
smlua_bind_function(L, "get_ttc_speed_setting", smlua_func_get_ttc_speed_setting);
smlua_bind_function(L, "get_vertex_color", smlua_func_get_vertex_color);
+ smlua_bind_function(L, "get_volume_env", smlua_func_get_volume_env);
+ smlua_bind_function(L, "get_volume_level", smlua_func_get_volume_level);
+ smlua_bind_function(L, "get_volume_master", smlua_func_get_volume_master);
+ smlua_bind_function(L, "get_volume_sfx", smlua_func_get_volume_sfx);
smlua_bind_function(L, "get_water_level", smlua_func_get_water_level);
smlua_bind_function(L, "hud_get_flash", smlua_func_hud_get_flash);
smlua_bind_function(L, "hud_get_value", smlua_func_hud_get_value);
@@ -34146,6 +34278,10 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "set_save_file_modified", smlua_func_set_save_file_modified);
smlua_bind_function(L, "set_ttc_speed_setting", smlua_func_set_ttc_speed_setting);
smlua_bind_function(L, "set_vertex_color", smlua_func_set_vertex_color);
+ smlua_bind_function(L, "set_volume_env", smlua_func_set_volume_env);
+ smlua_bind_function(L, "set_volume_level", smlua_func_set_volume_level);
+ smlua_bind_function(L, "set_volume_master", smlua_func_set_volume_master);
+ smlua_bind_function(L, "set_volume_sfx", smlua_func_set_volume_sfx);
smlua_bind_function(L, "set_water_level", smlua_func_set_water_level);
smlua_bind_function(L, "set_window_title", smlua_func_set_window_title);
diff --git a/src/pc/lua/utils/smlua_misc_utils.c b/src/pc/lua/utils/smlua_misc_utils.c
index 0ce353d7..470176cb 100644
--- a/src/pc/lua/utils/smlua_misc_utils.c
+++ b/src/pc/lua/utils/smlua_misc_utils.c
@@ -24,6 +24,7 @@
#include "include/course_table.h"
#include "game/level_geo.h"
#include "game/first_person_cam.h"
+#include "pc/lua/utils/smlua_math_utils.h"
#ifdef DISCORD_SDK
#include "pc/discord/discord.h"
@@ -655,6 +656,40 @@ const char* get_local_discord_id(void) {
///
+f32 get_volume_master(void) {
+ return gLuaVolumeMaster;
+}
+
+f32 get_volume_level(void) {
+ return gLuaVolumeLevel;
+}
+
+f32 get_volume_sfx(void) {
+ return gLuaVolumeSfx;
+}
+
+f32 get_volume_env(void) {
+ return gLuaVolumeEnv;
+}
+
+void set_volume_master(f32 volume) {
+ gLuaVolumeMaster = clampf(volume, 0.0f, 1.0f);
+}
+
+void set_volume_level(f32 volume) {
+ gLuaVolumeLevel = clampf(volume, 0.0f, 1.0f);
+}
+
+void set_volume_sfx(f32 volume) {
+ gLuaVolumeSfx = clampf(volume, 0.0f, 1.0f);
+}
+
+void set_volume_env(f32 volume) {
+ gLuaVolumeEnv = clampf(volume, 0.0f, 1.0f);
+}
+
+///
+
void set_window_title(const char* title) {
WAPI.set_window_title(title);
}
diff --git a/src/pc/lua/utils/smlua_misc_utils.h b/src/pc/lua/utils/smlua_misc_utils.h
index 5f037083..c490e9bf 100644
--- a/src/pc/lua/utils/smlua_misc_utils.h
+++ b/src/pc/lua/utils/smlua_misc_utils.h
@@ -169,6 +169,15 @@ bool djui_is_playerlist_open(void);
const char* get_local_discord_id(void);
+f32 get_volume_master(void);
+f32 get_volume_level(void);
+f32 get_volume_sfx(void);
+f32 get_volume_env(void);
+void set_volume_master(f32 volume);
+void set_volume_level(f32 volume);
+void set_volume_sfx(f32 volume);
+void set_volume_env(f32 volume);
+
void set_window_title(const char* title);
void reset_window_title(void);
diff --git a/src/pc/network/network.c b/src/pc/network/network.c
index 1b3f530b..bee2bc2e 100644
--- a/src/pc/network/network.c
+++ b/src/pc/network/network.c
@@ -20,8 +20,9 @@
#include "pc/mods/mods.h"
#include "pc/crash_handler.h"
#include "pc/debuglog.h"
-#include "game/camera.h"
+#include "pc/pc_main.h"
#include "pc/gfx/gfx_pc.h"
+#include "game/camera.h"
#include "game/skybox.h"
#include "game/object_list_processor.h"
#include "game/object_helpers.h"
@@ -699,6 +700,10 @@ void network_shutdown(bool sendLeaving, bool exiting, bool popup, bool reconnect
gOverrideDialogColor = 0;
gDialogMinWidth = 0;
gOverrideAllowToxicGasCamera = FALSE;
+ gLuaVolumeMaster = 1.0f;
+ gLuaVolumeLevel = 1.0f;
+ gLuaVolumeSfx = 1.0f;
+ gLuaVolumeEnv = 1.0f;
struct Controller* cnt = gPlayer1Controller;
cnt->rawStickX = 0;
diff --git a/src/pc/pc_main.c b/src/pc/pc_main.c
index 5f30aec2..464066ad 100644
--- a/src/pc/pc_main.c
+++ b/src/pc/pc_main.c
@@ -88,6 +88,11 @@ static f64 sFrameTimeStart;
bool gGameInited = false;
bool gGfxInited = false;
+f32 gLuaVolumeMaster = 1.0f;
+f32 gLuaVolumeLevel = 1.0f;
+f32 gLuaVolumeSfx = 1.0f;
+f32 gLuaVolumeEnv = 1.0f;
+
static struct AudioAPI *audio_api;
struct GfxWindowManagerAPI *wm_api = &WAPI;
@@ -217,10 +222,10 @@ void produce_interpolation_frames_and_delay(void) {
}
inline static void buffer_audio(void) {
- const f32 masterMod = (f32)configMasterVolume / 127.0f;
- set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * masterMod);
- set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * masterMod);
- set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * masterMod);
+ const f32 masterMod = (f32)configMasterVolume / 127.0f * gLuaVolumeMaster;
+ set_sequence_player_volume(SEQ_PLAYER_LEVEL, (f32)configMusicVolume / 127.0f * gLuaVolumeLevel * masterMod);
+ set_sequence_player_volume(SEQ_PLAYER_SFX, (f32)configSfxVolume / 127.0f * gLuaVolumeSfx * masterMod);
+ set_sequence_player_volume(SEQ_PLAYER_ENV, (f32)configEnvVolume / 127.0f * gLuaVolumeEnv * masterMod);
int samplesLeft = audio_api->buffered();
u32 numAudioSamples = samplesLeft < audio_api->get_desired_buffered() ? SAMPLES_HIGH : SAMPLES_LOW;
diff --git a/src/pc/pc_main.h b/src/pc/pc_main.h
index 041c0545..d04a2515 100644
--- a/src/pc/pc_main.h
+++ b/src/pc/pc_main.h
@@ -64,6 +64,11 @@ extern "C" {
extern bool gGameInited;
extern bool gGfxInited;
+extern f32 gLuaVolumeMaster;
+extern f32 gLuaVolumeLevel;
+extern f32 gLuaVolumeSfx;
+extern f32 gLuaVolumeEnv;
+
extern struct GfxWindowManagerAPI* wm_api;
void produce_one_dummy_frame(void (*callback)());
void game_deinit(void);