Skip to content

Commit

Permalink
camera: add underwater music behavior options
Browse files Browse the repository at this point in the history
Resolves #528.
  • Loading branch information
walkawayy authored and rr- committed Aug 13, 2024
1 parent 871259d commit f2092cd
Show file tree
Hide file tree
Showing 16 changed files with 161 additions and 14 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- added skybox support, with a default option provided for Lost Valley, Colosseum and Obelisk of Khamoon (#94)
- added an option for Lara to use her underwater swimming physics from TR2+ (#1003)
- added weapons to Lara's empty holsters on pickup (#1291)
- added options to quiet or mute music while underwater (#528)
- changed the turbo cheat to no longer affect the gameplay time (#1420)
- fixed adjacent Midas Touch objects potentially allowing gold bar duplication in custom levels (#1415)
- fixed the excessive pitch and playback speed correction for music files with sampling rate other than 44100 Hz (#1417, regression from 2.0)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ Not all options are turned on by default. Refer to `TR1X_ConfigTool.exe` for det
- added an option to restore the mummy in City of Khamoon room 25, similar to the PS version
- added a flag indicating if new game plus is unlocked to the player config which allows the player to select new game plus or not when making a new game
- added weapons to Lara's empty holsters on pickup
- added options to quiet or mute music while underwater
- fixed keys and items not working when drawing guns immediately after using them
- fixed counting the secret in The Great Pyramid
- fixed running out of ammo forcing Lara to equip pistols even if she doesn't carry them
Expand Down
1 change: 1 addition & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ typedef struct {
bool enable_enhanced_saves;
bool enable_pitched_sounds;
bool enable_ps_uzi_sfx;
UNDERWATER_MUSIC_MODE underwater_music_mode;
bool enable_jump_twists;
bool enabled_inverted_look;
int32_t camera_speed;
Expand Down
1 change: 1 addition & 0 deletions src/config_map.def
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ CFG_BOOL(enable_loading_screens, false)
CFG_BOOL(enable_cine, true)
CFG_BOOL(enable_music_in_menu, true)
CFG_BOOL(enable_music_in_inventory, true)
CFG_ENUM(underwater_music_mode, UMM_FULL, UNDERWATER_MUSIC_MODE)
CFG_BOOL(enable_round_shadow, true)
CFG_BOOL(enable_3d_pickups, true)
CFG_FLOAT(rendering.anisotropy_filter, 16.0f)
Expand Down
45 changes: 42 additions & 3 deletions src/game/camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include "game/input.h"
#include "game/items.h"
#include "game/los.h"
#include "game/music.h"
#include "game/random.h"
#include "game/room.h"
#include "game/sound.h"
Expand Down Expand Up @@ -42,6 +43,7 @@ static void Camera_Move(GAME_VECTOR *ideal, int32_t speed);
static void Camera_LoadCutsceneFrame(void);
static void Camera_OffsetAdditionalAngle(int16_t delta);
static void Camera_OffsetAdditionalElevation(int16_t delta);
static void Camera_AdjustMusicVolume(bool underwater);
static void Camera_EnsureEnvironment(void);

static bool Camera_BadPosition(
Expand Down Expand Up @@ -408,6 +410,39 @@ static void Camera_OffsetAdditionalElevation(int16_t delta)
}
}

static void Camera_AdjustMusicVolume(const bool underwater)
{
const bool is_ambient =
Music_GetCurrentPlayingTrack() == Music_GetCurrentLoopedTrack();

double multiplier = 1.0;

if (underwater) {
switch (g_Config.underwater_music_mode) {
case UMM_FULL:
multiplier = 1.0;
break;
case UMM_QUIET:
multiplier = 0.5;
break;
case UMM_NONE:
multiplier = 0.0;
break;
case UMM_FULL_NO_AMBIENT:
multiplier = is_ambient ? 0.0 : 1.0;
break;
case UMM_QUIET_NO_AMBIENT:
multiplier = is_ambient ? 0.0 : 0.5;
break;
default:
multiplier = 1.0;
break;
}
}

Music_SetVolume(g_Config.music_volume * multiplier);
}

void Camera_Reset(void)
{
g_Camera.pos.room_number = NO_ROOM;
Expand Down Expand Up @@ -749,11 +784,15 @@ static void Camera_EnsureEnvironment(void)
}

if (g_RoomInfo[g_Camera.pos.room_number].flags & RF_UNDERWATER) {
Camera_AdjustMusicVolume(true);
Sound_Effect(SFX_UNDERWATER, NULL, SPM_ALWAYS);
g_Camera.underwater = true;
} else if (g_Camera.underwater) {
Sound_StopEffect(SFX_UNDERWATER, NULL);
g_Camera.underwater = false;
} else {
Camera_AdjustMusicVolume(false);
if (g_Camera.underwater) {
Sound_StopEffect(SFX_UNDERWATER, NULL);
g_Camera.underwater = false;
}
}
}

Expand Down
37 changes: 30 additions & 7 deletions src/game/music.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,28 @@

static const char *m_Extensions[] = { ".flac", ".ogg", ".mp3", ".wav", NULL };

static float m_MusicVolume = 0.0f;
static bool m_Muted = false;
static int16_t m_Volume = 0;
static int m_AudioStreamID = -1;
static MUSIC_TRACK_ID m_TrackCurrent = MX_INACTIVE;
static MUSIC_TRACK_ID m_TrackLastPlayed = MX_INACTIVE;
static MUSIC_TRACK_ID m_TrackLooped = MX_INACTIVE;

static void Music_SyncVolume(const int32_t audio_stream_id);
static bool Music_IsBrokenTrack(MUSIC_TRACK_ID track);
static void Music_StopActiveStream(void);
static void Music_StreamFinished(int stream_id, void *user_data);
static char *Music_GetTrackFileName(MUSIC_TRACK_ID track);

static void Music_SyncVolume(const int32_t audio_stream_id)
{
if (audio_stream_id < 0) {
return;
}
const float multiplier = m_Volume ? (25 * m_Volume + 5) / 255.0f : 0.0f;
Audio_Stream_SetVolume(audio_stream_id, m_Muted ? 0 : multiplier);
}

static bool Music_IsBrokenTrack(MUSIC_TRACK_ID track)
{
return track == MX_UNUSED_0 || track == MX_UNUSED_1 || track == MX_UNUSED_2;
Expand Down Expand Up @@ -107,7 +118,7 @@ bool Music_Play(MUSIC_TRACK_ID track)
m_TrackLastPlayed = track;
}

Audio_Stream_SetVolume(m_AudioStreamID, m_MusicVolume);
Music_SyncVolume(m_AudioStreamID);
Audio_Stream_SetFinishCallback(m_AudioStreamID, Music_StreamFinished, NULL);

return true;
Expand Down Expand Up @@ -136,7 +147,7 @@ bool Music_PlayLooped(MUSIC_TRACK_ID track)
return false;
}

Audio_Stream_SetVolume(m_AudioStreamID, m_MusicVolume);
Music_SyncVolume(m_AudioStreamID);
Audio_Stream_SetFinishCallback(m_AudioStreamID, Music_StreamFinished, NULL);
Audio_Stream_SetIsLooped(m_AudioStreamID, true);

Expand Down Expand Up @@ -167,16 +178,28 @@ void Music_StopTrack(MUSIC_TRACK_ID track)
}
}

void Music_Mute(void)
{
m_Muted = true;
Music_SyncVolume(m_AudioStreamID);
}

void Music_Unmute(void)
{
m_Muted = false;
Music_SyncVolume(m_AudioStreamID);
}

int16_t Music_GetVolume(void)
{
return m_MusicVolume * Music_GetMaxVolume();
return m_Volume;
}

void Music_SetVolume(int16_t volume)
{
m_MusicVolume = volume ? (25 * volume + 5) / 255.0f : 0.0f;
if (m_AudioStreamID >= 0) {
Audio_Stream_SetVolume(m_AudioStreamID, m_MusicVolume);
if (volume != m_Volume) {
m_Volume = volume;
Music_SyncVolume(m_AudioStreamID);
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/game/music.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ void Music_Stop(void);
// Stops the provided single track and restarts the looped track if applicable.
void Music_StopTrack(MUSIC_TRACK_ID track);

// Mutes the game music. Doesn't change the music volume.
void Music_Mute(void);

// Unmutes the game music. Doesn't change the music volume.
void Music_Unmute(void);

// Gets the game volume.
int16_t Music_GetVolume(void);

Expand Down
9 changes: 9 additions & 0 deletions src/global/enum_str.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,12 @@ const ENUM_STRING_MAP g_EnumStr_SCREENSHOT_FORMAT[] = {
{ "png", SCREENSHOT_FORMAT_PNG },
{ NULL, -1 },
};

const ENUM_STRING_MAP g_EnumStr_UNDERWATER_MUSIC_MODE[] = {
{ "full", UMM_FULL },
{ "quiet", UMM_QUIET },
{ "full_no_ambient", UMM_FULL_NO_AMBIENT },
{ "quiet_no_ambient", UMM_QUIET_NO_AMBIENT },
{ "none", UMM_NONE },
{ NULL, -1 },
};
1 change: 1 addition & 0 deletions src/global/enum_str.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,6 @@ extern const ENUM_STRING_MAP g_EnumStr_BAR_LOCATION[];
extern const ENUM_STRING_MAP g_EnumStr_BAR_COLOR[];
extern const ENUM_STRING_MAP g_EnumStr_TARGET_LOCK_MODE[];
extern const ENUM_STRING_MAP g_EnumStr_SCREENSHOT_FORMAT[];
extern const ENUM_STRING_MAP g_EnumStr_UNDERWATER_MUSIC_MODE[];

#define ENUM_STR_MAP(type) g_EnumStr_##type
8 changes: 8 additions & 0 deletions src/global/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,14 @@ typedef enum SOUND_PLAY_MODE {
SPM_ALWAYS = 2,
} SOUND_PLAY_MODE;

typedef enum UNDERWATER_MUSIC_MODE {
UMM_FULL,
UMM_QUIET,
UMM_FULL_NO_AMBIENT,
UMM_QUIET_NO_AMBIENT,
UMM_NONE,
} UNDERWATER_MUSIC_MODE;

typedef enum GAME_BONUS_FLAG {
GBF_NGPLUS = 1 << 0,
GBF_JAPANESE = 1 << 1,
Expand Down
4 changes: 2 additions & 2 deletions src/specific/s_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,12 @@ void S_Shell_SpinMessageLoop(void)
case SDL_WINDOWEVENT:
switch (event.window.event) {
case SDL_WINDOWEVENT_FOCUS_GAINED:
Music_SetVolume(g_Config.music_volume);
Music_Unmute();
Sound_SetMasterVolume(g_Config.sound_volume);
break;

case SDL_WINDOWEVENT_FOCUS_LOST:
Music_SetVolume(0);
Music_Mute();
Sound_SetMasterVolume(0);
break;

Expand Down
11 changes: 11 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@
"full-lock": "Full lock",
"semi-lock": "Semi lock",
"no-lock": "No lock"
},
"underwater_music": {
"full": "Full",
"quiet": "Quiet",
"full_no_ambient": "Full but no ambient",
"quiet_no_ambient": "Quiet but no ambient",
"none": "None"
}
},
"Categories": {
Expand Down Expand Up @@ -381,6 +388,10 @@
"Title": "Enable PS Uzi SFX",
"Description": "Changes the Uzi sound effects to match the PlayStation version."
},
"underwater_music_mode": {
"Title": "Underwater music behavior",
"Description": "Changes how the music is played underwater.\n- Full: music plays normally while underwater (OG TR1).\n- Quiet: music plays at half volume while underwater.\n- Full but no ambient: music plays normally while underwater except ambient music is muted.\n- Quiet but no ambient: music plays at half volume while underwater except ambient music is muted.\n- None: no music plays while underwater."
},
"menu_style": {
"Title": "Menu style",
"Description": "Changes how menus are displayed.\n - PC: UI style matches the PC version.\n - PS1: UI style matches the PS1 version."
Expand Down
13 changes: 12 additions & 1 deletion tools/config/TR1X_ConfigTool/Resources/Lang/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,14 @@
"full-lock": "Bloqueo total",
"semi-lock": "Semibloqueo",
"no-lock": "Sin bloqueo"
}
},
"underwater_music": {
"full": "Completo",
"quiet": "Tranquilo",
"full_no_ambient": "Completo pero sin ambiente",
"quiet_no_ambient": "Tranquilo pero sin ambientet",
"none": "Ninguno"
}
},
"Properties": {
"airbar_color": {
Expand Down Expand Up @@ -277,6 +284,10 @@
"Title": "Habilitar efectos de sonido de PS Uzi",
"Description": "Cambia los efectos de sonido de las Uzis para que coincidan con la versión de PlayStation."
},
"underwater_music_mode": {
"Title": "Comportamiento de la música bajo el agua",
"Description": "Cambia cómo se reproduce la música bajo el agua.\n- Completo: la música se reproduce normalmente mientras estás bajo el agua (TR1 original).\n- Tranquilo: la música se reproduce a la mitad del volumen mientras estás bajo el agua.\n- Completo pero sin ambiente: la música suena normalmente mientras estás bajo el agua, excepto la música ambiental, que está silenciada.\n- Tranquilo pero sin ambiente: la música suena a la mitad del volumen mientras estás bajo el agua, excepto la música ambiental, que está silenciada.\n- Ninguno: no se reproduce música mientras estás bajo el agua."
},
"enable_round_shadow": {
"Title": "Sombras redondeadas",
"Description": "Habilita sombras redondas en lugar de las octogonales predeterminadas."
Expand Down
11 changes: 11 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/Lang/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,13 @@
"full-lock": "Full lock",
"semi-lock": "Semi lock",
"no-lock": "No lock"
},
"underwater_music": {
"full": "Complète",
"quiet": "Calme",
"full_no_ambient": "Plein mais sans ambiance",
"quiet_no_ambient": "Calme mais sans ambiance",
"none": "Aucune"
}
},
"Categories": {
Expand Down Expand Up @@ -381,6 +388,10 @@
"Title": "Activer les SFX PlayStation des uzis",
"Description": "Change les effets sonores des uzis pour correspondre à ceux de la version PlayStation."
},
"underwater_music_mode": {
"Title": "Comportement de la musique sous l'eau",
"Description": "Modifie la façon dont la musique est jouée sous l'eau.\n- Complète: la musique joue normalement sous l'eau (Comportement original de TR1).\n- Calme: music plays at half volume while underwater.\n- Plein mais sans ambiance: la musique joue normalement sous l'eau, sauf la musique d'ambiance qui est coupée.\n- Calme mais sans ambiance: la musique joue à moitié volume sous l'eau, sauf la musique d'ambiance qui est coupée.\n- Aucune: aucune musique ne joue sous l'eau."
},
"menu_style": {
"Title": "Style des menus",
"Description": "Changer le rendu des menus.\n - PC: Style d'interface de la version PC.\n - PS1: Style d'interface de la version PlayStation."
Expand Down
13 changes: 12 additions & 1 deletion tools/config/TR1X_ConfigTool/Resources/Lang/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,14 @@
"full-lock": "Completo",
"semi-lock": "Parziale",
"no-lock": "Nessuno"
}
},
"underwater_music": {
"full": "Completa",
"quiet": "Tranquilla",
"full_no_ambient": "Completo ma senza ambiente",
"quiet_no_ambient": "Tranquilla ma senza ambiente",
"none": "Nessuna"
}
},
"Categories": {
"controls": "Controlli",
Expand Down Expand Up @@ -381,6 +388,10 @@
"Title": "Abilita gli effetti sonori PS per le Uzi",
"Description": "Modifica gli effetti sonori delle Uzi per adattarli a quelli della versione PlayStation."
},
"underwater_music_mode": {
"Title": "Underwater music behavior",
"Description": "Cambia il modo in cui la musica viene riprodotta sott'acqua.\n- Completa: la musica viene riprodotta normalmente sott'acqua (TR1).\n- Tranquilla: la musica viene riprodotta a metà volume sott'acqua.\n- Completo ma senza ambiente: la musica suona normalmente mentre sei sott'acqua, eccetto la musica ambientale che è silenziata.\n- Tranquilla ma senza ambiente: la musica suona a metà volume mentre sei sott'acqua, eccetto la musica ambientale che è silenziata.\n- Nessuna: nessuna musica viene riprodotta sott'acqua."
},
"menu_style": {
"Title": "Stile del menù",
"Description": "Modifica la modalità di visualizzazione dei menu.\n - PC: Lo stile dell'interfaccia utente corrisponde alla versione PC.\n - PS1: Lo stile dell'interfaccia utente corrisponde alla versione PS1."
Expand Down
13 changes: 13 additions & 0 deletions tools/config/TR1X_ConfigTool/Resources/specification.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@
"full-lock",
"semi-lock",
"no-lock"
],
"underwater_music": [
"full",
"quiet",
"full_no_ambient",
"quiet_no_ambient",
"none"
]
},
"CategorisedProperties": [
Expand Down Expand Up @@ -460,6 +467,12 @@
"Field": "enable_ps_uzi_sfx",
"DataType": "Bool",
"DefaultValue": false
},
{
"Field": "underwater_music_mode",
"DataType": "Enum",
"EnumKey": "underwater_music",
"DefaultValue": "full"
}
]
},
Expand Down

0 comments on commit f2092cd

Please sign in to comment.