mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
tr2/savegame: save and load current music
This allows the current music track and position to be saved and restored on load, similar to TR1X. Resolves #2579.
This commit is contained in:
parent
0e24b65ae6
commit
ec2a0452ff
16 changed files with 92 additions and 34 deletions
|
@ -11,6 +11,7 @@
|
|||
- added BSON savegame support, removing the limits imposed by the OG 8KB file size, so allowing for storing more data and offering improved feature support (legacy save files can still be read, similar to TR1) (#2662)
|
||||
- added NG+, Japanese, and Japanese NG+ game mode options to the New Game page in the passport (#2731)
|
||||
- added the ability for spike walls to be reset (antitriggered)
|
||||
- added the current music track and timestamp to the savegame so they now persist on load (#2579)
|
||||
- added waterfalls to the savegame so that they now persist on load (#2686)
|
||||
- changed savegame files to be stored in the `saves` directory (#2087)
|
||||
- changed the default fog distance to 22 tiles cutting off at 30 tiles to match TR1X (#1622)
|
||||
|
|
|
@ -303,6 +303,7 @@ as Notepad.
|
|||
|
||||
#### Audio
|
||||
- added an option to control how music is played while underwater rather than simply muting it
|
||||
- added the current music track and timestamp to the savegame so they now persist on load
|
||||
- fixed music not playing with certain game versions
|
||||
- fixed the audio not being in sync when Lara strikes the gong in Ice Palace
|
||||
- fixed sound settings resuming the music
|
||||
|
|
|
@ -60,5 +60,6 @@ CFG_INT32(g_Config, audio.sound_volume, 10)
|
|||
CFG_INT32(g_Config, audio.music_volume, 10)
|
||||
CFG_BOOL(g_Config, audio.enable_lara_mic, false)
|
||||
CFG_ENUM(g_Config, audio.underwater_music_mode, UMM_FULL, UNDERWATER_MUSIC_MODE)
|
||||
CFG_ENUM(g_Config, audio.music_load_condition, MUSIC_LOAD_NON_AMBIENT, MUSIC_LOAD_CONDITION)
|
||||
CFG_BOOL(g_Config, gameplay.enable_game_modes, true)
|
||||
CFG_BOOL(g_Config, profile.new_game_plus_unlock, false)
|
||||
|
|
|
@ -1,5 +1,11 @@
|
|||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
MUSIC_LOAD_NEVER,
|
||||
MUSIC_LOAD_NON_AMBIENT,
|
||||
MUSIC_LOAD_ALWAYS,
|
||||
} MUSIC_LOAD_CONDITION;
|
||||
|
||||
#if TR_VERSION == 1
|
||||
#include "./types_tr1.h"
|
||||
#elif TR_VERSION == 2
|
||||
|
|
|
@ -47,12 +47,6 @@ typedef enum {
|
|||
BC_PURPLE,
|
||||
} BAR_COLOR;
|
||||
|
||||
typedef enum {
|
||||
MUSIC_LOAD_NEVER,
|
||||
MUSIC_LOAD_NON_AMBIENT,
|
||||
MUSIC_LOAD_ALWAYS,
|
||||
} MUSIC_LOAD_CONDITION;
|
||||
|
||||
typedef enum {
|
||||
TLM_FULL,
|
||||
TLM_SEMI,
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef struct {
|
|||
int32_t music_volume;
|
||||
bool enable_lara_mic;
|
||||
UNDERWATER_MUSIC_MODE underwater_music_mode;
|
||||
MUSIC_LOAD_CONDITION music_load_condition;
|
||||
} audio;
|
||||
|
||||
struct {
|
||||
|
|
|
@ -51,6 +51,10 @@ ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_CREATURE_LOT, "Creature pathfinding")
|
|||
ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_SAMPLE_INFOS, "Sample information")
|
||||
ENUM_MAP_DEFINE(GAME_BUFFER, GBUF_SAMPLES, "Samples")
|
||||
|
||||
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_NEVER, "never")
|
||||
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_NON_AMBIENT, "non-ambient")
|
||||
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_ALWAYS, "always")
|
||||
|
||||
ENUM_MAP_DEFINE(UNDERWATER_MUSIC_MODE, UMM_FULL, "full")
|
||||
ENUM_MAP_DEFINE(UNDERWATER_MUSIC_MODE, UMM_QUIET, "quiet")
|
||||
ENUM_MAP_DEFINE(UNDERWATER_MUSIC_MODE, UMM_FULL_NO_AMBIENT, "full_no_ambient")
|
||||
|
|
|
@ -30,10 +30,6 @@ ENUM_MAP_DEFINE(TARGET_LOCK_MODE, TLM_FULL, "full-lock")
|
|||
ENUM_MAP_DEFINE(TARGET_LOCK_MODE, TLM_SEMI, "semi-lock")
|
||||
ENUM_MAP_DEFINE(TARGET_LOCK_MODE, TLM_NONE, "no-lock")
|
||||
|
||||
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_NEVER, "never")
|
||||
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_NON_AMBIENT, "non-ambient")
|
||||
ENUM_MAP_DEFINE(MUSIC_LOAD_CONDITION, MUSIC_LOAD_ALWAYS, "always")
|
||||
|
||||
ENUM_MAP_DEFINE(STAT_DETAIL_MODE, SDM_MINIMAL, "minimal")
|
||||
ENUM_MAP_DEFINE(STAT_DETAIL_MODE, SDM_DETAILED, "detailed")
|
||||
ENUM_MAP_DEFINE(STAT_DETAIL_MODE, SDM_FULL, "full")
|
||||
|
|
|
@ -2,11 +2,13 @@
|
|||
#include "game/game_flow.h"
|
||||
#include "game/inventory.h"
|
||||
#include "game/lara/control.h"
|
||||
#include "game/music.h"
|
||||
#include "game/objects/general/lift.h"
|
||||
#include "game/savegame.h"
|
||||
#include "global/vars.h"
|
||||
|
||||
#include <libtrx/bson.h>
|
||||
#include <libtrx/config.h>
|
||||
#include <libtrx/debug.h>
|
||||
#include <libtrx/game/camera.h>
|
||||
#include <libtrx/game/music.h>
|
||||
|
@ -303,6 +305,15 @@ static JSON_OBJECT *M_DumpMusic(void)
|
|||
JSON_ArrayAppendInt(track_arr, Music_GetTrackFlags(i));
|
||||
}
|
||||
JSON_ObjectAppendArray(music_obj, "flags", track_arr);
|
||||
|
||||
const MUSIC_TRACK_ID current_track = Music_GetCurrentPlayingTrack();
|
||||
const bool is_ambient = current_track == Music_GetCurrentLoopedTrack();
|
||||
JSON_OBJECT *const current_obj = JSON_ObjectNew();
|
||||
JSON_ObjectAppendInt(current_obj, "current_track", current_track);
|
||||
JSON_ObjectAppendDouble(current_obj, "timestamp", Music_GetTimestamp());
|
||||
JSON_ObjectAppendBool(current_obj, "is_ambient", is_ambient);
|
||||
JSON_ObjectAppendObject(music_obj, "current", current_obj);
|
||||
|
||||
return music_obj;
|
||||
}
|
||||
|
||||
|
@ -330,6 +341,35 @@ static bool M_LoadMusic(JSON_OBJECT *const music_obj)
|
|||
Music_SetTrackFlags(i, JSON_ArrayGetInt(track_arr, i, 0));
|
||||
}
|
||||
|
||||
const JSON_OBJECT *const current_obj =
|
||||
JSON_ObjectGetObject(music_obj, "current");
|
||||
if (current_obj == nullptr
|
||||
|| g_Config.audio.music_load_condition == MUSIC_LOAD_NEVER) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const int16_t current_track =
|
||||
JSON_ObjectGetInt(current_obj, "current_track", -1);
|
||||
double timestamp = JSON_ObjectGetDouble(current_obj, "timestamp", -1.0);
|
||||
if (current_track != MX_INACTIVE) {
|
||||
const bool is_ambient =
|
||||
JSON_ObjectGetBool(music_obj, "is_ambient", false);
|
||||
if (is_ambient) {
|
||||
if (g_Config.audio.music_load_condition == MUSIC_LOAD_NON_AMBIENT) {
|
||||
return true;
|
||||
}
|
||||
Music_Play(current_track, MPM_LOOPED);
|
||||
} else {
|
||||
Music_Play(current_track, MPM_ALWAYS);
|
||||
}
|
||||
|
||||
if (!Music_SeekTimestamp(timestamp)) {
|
||||
LOG_WARNING(
|
||||
"Could not load current track %d at timestamp %" PRId64 ".",
|
||||
current_track, timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,11 +54,6 @@
|
|||
"semi-lock": "Semi lock",
|
||||
"no-lock": "No lock"
|
||||
},
|
||||
"music_load_condition": {
|
||||
"never": "Never",
|
||||
"non-ambient": "Non-ambient",
|
||||
"always": "Always"
|
||||
},
|
||||
"stat_mode": {
|
||||
"minimal": "Minimal",
|
||||
"detailed": "Detailed",
|
||||
|
|
|
@ -58,18 +58,6 @@
|
|||
"semi-lock": "Parziale",
|
||||
"no-lock": "Nessuno"
|
||||
},
|
||||
"underwater_music": {
|
||||
"full": "Completa",
|
||||
"quiet": "Attenuata",
|
||||
"full_no_ambient": "Completa ma senza suoni ambientali",
|
||||
"quiet_no_ambient": "Attenuata ma senza suoni ambientali",
|
||||
"none": "Assente"
|
||||
},
|
||||
"music_load_condition": {
|
||||
"never": "Mai",
|
||||
"non-ambient": "Non ambientale",
|
||||
"always": "Sempre"
|
||||
},
|
||||
"stat_mode": {
|
||||
"minimal": "Minimo",
|
||||
"detailed": "Dettagliato",
|
||||
|
|
|
@ -114,6 +114,10 @@
|
|||
"Title": "Gun/explosion lighting",
|
||||
"Description": "Enables dynamic lighting to be generated for gunshots and explosions."
|
||||
},
|
||||
"music_load_condition": {
|
||||
"Title": "Load music track",
|
||||
"Description": "Loads the music track that was playing when the game was saved.\n- Never: do not restore music tracks on load.\n- Non-ambient: restore only non-ambient music tracks on load.\n- Always: restore any kind of music track on load."
|
||||
},
|
||||
"enable_lara_mic" : {
|
||||
"Title": "Microphone at Lara",
|
||||
"Description": "Set the microphone to be at Lara's position. If disabled, the microphone will be at the camera's position."
|
||||
|
|
|
@ -15,13 +15,6 @@
|
|||
"any": "Qualsiasi",
|
||||
"16:9": "16:9",
|
||||
"4:3": "4:3"
|
||||
},
|
||||
"underwater_music": {
|
||||
"full": "Completa",
|
||||
"quiet": "Attenuata",
|
||||
"full_no_ambient": "Completa ma senza suoni ambientali",
|
||||
"quiet_no_ambient": "Attenuata ma senza suoni ambientali",
|
||||
"none": "Assente"
|
||||
}
|
||||
},
|
||||
"Properties": {
|
||||
|
@ -121,6 +114,10 @@
|
|||
"Title": "Illuminazione spari/esplosioni",
|
||||
"Description": "Abilita l'illuminazione dinamica per spari ed esplosioni."
|
||||
},
|
||||
"music_load_condition": {
|
||||
"Title": "Carica la traccia musicale",
|
||||
"Description": "Carica la traccia musicale che era in riproduzione al momento del salvataggio della partita.\n- Mai: non ripristina le tracce musicali al caricamento.\n- Non ambientale: ripristina le tracce musicali ma non le tracce ambientali al caricamento.\n- Sempre: ripristina qualsiasi tipo di traccia musicale al caricamento."
|
||||
},
|
||||
"enable_lara_mic" : {
|
||||
"Title": "Microfono su Lara",
|
||||
"Description": "Imposta il microfono nella posizione in cui si trova Lara. Se disabilitato, il microfono sarà nella posizione della telecamera."
|
||||
|
|
|
@ -19,6 +19,11 @@
|
|||
"full_no_ambient",
|
||||
"quiet_no_ambient",
|
||||
"none"
|
||||
],
|
||||
"music_load_condition": [
|
||||
"never",
|
||||
"non-ambient",
|
||||
"always"
|
||||
]
|
||||
},
|
||||
"CategorisedProperties": [
|
||||
|
@ -189,6 +194,12 @@
|
|||
"DataType": "Bool",
|
||||
"DefaultValue": false
|
||||
},
|
||||
{
|
||||
"Field": "music_load_condition",
|
||||
"DataType": "Enum",
|
||||
"EnumKey": "music_load_condition",
|
||||
"DefaultValue": "non-ambient"
|
||||
},
|
||||
{
|
||||
"Field": "underwater_music_mode",
|
||||
"DataType": "Enum",
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
"jpg": "JPEG",
|
||||
"png": "PNG"
|
||||
},
|
||||
"music_load_condition": {
|
||||
"never": "Never",
|
||||
"non-ambient": "Non-ambient",
|
||||
"always": "Always"
|
||||
},
|
||||
"underwater_music": {
|
||||
"full": "Full",
|
||||
"quiet": "Quiet",
|
||||
|
|
|
@ -38,5 +38,19 @@
|
|||
"graphics": "Grafica",
|
||||
"sound": "Suono",
|
||||
"ui": "Interfaccia utente"
|
||||
},
|
||||
"Enums": {
|
||||
"underwater_music": {
|
||||
"full": "Completa",
|
||||
"quiet": "Attenuata",
|
||||
"full_no_ambient": "Completa ma senza suoni ambientali",
|
||||
"quiet_no_ambient": "Attenuata ma senza suoni ambientali",
|
||||
"none": "Assente"
|
||||
},
|
||||
"music_load_condition": {
|
||||
"never": "Mai",
|
||||
"non-ambient": "Non ambientale",
|
||||
"always": "Sempre"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue