1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 10:22:52 +01:00

Clean animation and audio after cutscene

This commit is contained in:
Filip Gawin 2018-09-25 22:06:36 +02:00
parent df0bda35e1
commit 056864e1d7
9 changed files with 80 additions and 42 deletions

View File

@ -212,7 +212,16 @@ void SoundManager::playSound(const std::string& name) {
if (sound != sounds.end()) { if (sound != sounds.end()) {
auto vol = getCalculatedVolumeOfMusic(); auto vol = getCalculatedVolumeOfMusic();
sound->second.setGain(vol); sound->second.setGain(vol);
return sound->second.play(); sound->second.play();
}
}
void SoundManager::eraseSound(const std::string& name) {
auto sound = sounds.find(name);
if (sound != sounds.end()) {
sounds.erase(sound);
} else {
RW_MESSAGE("Tried to erase no existing sound " << name);
} }
} }

View File

@ -59,6 +59,9 @@ public:
/// Play sound with selected name /// Play sound with selected name
void playSound(const std::string& name); void playSound(const std::string& name);
/// Erase sound with selected name
void eraseSound(const std::string& name);
/// Effect same as playSound with one parametr, /// Effect same as playSound with one parametr,
/// but this function works for sfx and /// but this function works for sfx and
/// allows also for setting position, /// allows also for setting position,

View File

@ -522,14 +522,18 @@ bool GameData::loadModel(ModelID model) {
return true; return true;
} }
void GameData::loadIFP(const std::string& name) { void GameData::loadIFP(const std::string& name, bool cutsceneAnimation) {
auto f = index.openFile(name); auto f = index.openFile(name);
if (f.data) { if (f.data) {
LoaderIFP loader; if (LoaderIFP loader{}; loader.loadFromMemory(f.data.get())) {
if (loader.loadFromMemory(f.data.get())) { if (cutsceneAnimation) {
animations.insert(loader.animations.begin(), animationsCutscene.insert(loader.animations.begin(),
loader.animations.end()); loader.animations.end());
} else {
animations.insert(loader.animations.begin(),
loader.animations.end());
}
} }
} }
} }

View File

@ -160,7 +160,7 @@ public:
/** /**
* Loads an IFP file containing animations * Loads an IFP file containing animations
*/ */
void loadIFP(const std::string& name); void loadIFP(const std::string& name, bool cutsceneAnimation = false);
/** /**
* Loads data from an object definition dat. * Loads data from an object definition dat.
@ -289,10 +289,15 @@ public:
std::vector<TextureAtlas*> atlases; std::vector<TextureAtlas*> atlases;
/** /**
* Loaded Animations * Loaded Animations (doesn't contain animations of cutscene)
*/ */
AnimationSet animations; AnimationSet animations;
/**
* Loaded Animations (only) for cutscene
*/
AnimationSet animationsCutscene;
/** /**
* Pedestrian Animation Groups * Pedestrian Animation Groups
*/ */

View File

@ -3,25 +3,26 @@
#include <bitset> #include <bitset>
#include <cstdint> #include <cstdint>
#include <map> #include <map>
#include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
#include <data/VehicleGenerator.hpp>
#include <engine/GameData.hpp>
#include <engine/GameInputState.hpp>
#include <engine/GameWorld.hpp>
#include <engine/ScreenText.hpp>
#include <fonts/GameTexts.hpp> #include <fonts/GameTexts.hpp>
#include <objects/ObjectTypes.hpp> #include "data/CutsceneData.hpp"
#include <script/ScriptTypes.hpp> #include "data/VehicleGenerator.hpp"
#include "engine/GameData.hpp"
#include "engine/GameInputState.hpp"
#include "engine/GameWorld.hpp"
#include "engine/ScreenText.hpp"
#include "objects/ObjectTypes.hpp"
#include "script/ScriptTypes.hpp"
class GameWorld; class GameWorld;
class GameObject; class GameObject;
class ScriptMachine; class ScriptMachine;
struct CutsceneData;
struct SystemTime { struct SystemTime {
uint16_t year; uint16_t year;
@ -316,7 +317,9 @@ public:
bool skipCutscene = false; bool skipCutscene = false;
bool isIntroPlaying = false; bool isIntroPlaying = false;
CutsceneData* currentCutscene = nullptr;
std::optional<CutsceneData> currentCutscene;
float cutsceneStartTime{-1.f}; float cutsceneStartTime{-1.f};
/** Flag for rendering cutscene letterbox */ /** Flag for rendering cutscene letterbox */
bool isCinematic = false; bool isCinematic = false;

View File

@ -28,6 +28,7 @@
#include "data/WeaponData.hpp" #include "data/WeaponData.hpp"
#include "loaders/LoaderCutsceneDAT.hpp" #include "loaders/LoaderCutsceneDAT.hpp"
#include "loaders/LoaderIFP.hpp"
#include "loaders/LoaderIPL.hpp" #include "loaders/LoaderIPL.hpp"
#include "objects/CharacterObject.hpp" #include "objects/CharacterObject.hpp"
@ -750,15 +751,14 @@ void GameWorld::PhysicsTickCallback(btDynamicsWorld* physWorld,
void GameWorld::loadCutscene(const std::string& name) { void GameWorld::loadCutscene(const std::string& name) {
auto datfile = data->index.openFile(name + ".dat"); auto datfile = data->index.openFile(name + ".dat");
CutsceneData* cutscene = new CutsceneData; state->currentCutscene = CutsceneData();
if (datfile.data) { if (datfile.data) {
LoaderCutsceneDAT loaderdat; LoaderCutsceneDAT loaderdat;
loaderdat.load(cutscene->tracks, datfile); loaderdat.load(state->currentCutscene->tracks, datfile);
} }
data->loadIFP(name + ".ifp"); data->loadIFP(name + ".ifp", true);
cutsceneAudioLoaded = data->loadAudioStream(name + ".mp3"); cutsceneAudioLoaded = data->loadAudioStream(name + ".mp3");
if (!cutsceneAudioLoaded) { if (!cutsceneAudioLoaded) {
@ -769,10 +769,6 @@ void GameWorld::loadCutscene(const std::string& name) {
logger->warning("Data", "Failed to load cutscene audio: " + name); logger->warning("Data", "Failed to load cutscene audio: " + name);
} }
if (state->currentCutscene) {
delete state->currentCutscene;
}
state->currentCutscene = cutscene;
state->currentCutscene->meta.name = name; state->currentCutscene->meta.name = name;
logger->info("World", "Loaded cutscene: " + name); logger->info("World", "Loaded cutscene: " + name);
} }
@ -788,20 +784,32 @@ void GameWorld::startCutscene() {
} }
void GameWorld::clearCutscene() { void GameWorld::clearCutscene() {
eraseCutsceneObjects();
eraseCutsceneSound();
eraseCutsceneAnimations();
state->currentCutscene = std::nullopt;
state->isCinematic = false;
state->cutsceneStartTime = -1.f;
}
void GameWorld::eraseCutsceneObjects() {
for (auto& p : cutscenePool.objects) { for (auto& p : cutscenePool.objects) {
destroyObjectQueued(p.second.get()); destroyObjectQueued(p.second.get());
} }
}
void GameWorld::eraseCutsceneSound() {
if (cutsceneAudio.length() > 0) { if (cutsceneAudio.length() > 0) {
sound.stopMusic(cutsceneAudio); sound.stopMusic(cutsceneAudio);
sound.eraseSound(cutsceneAudio);
cutsceneAudio = ""; cutsceneAudio = "";
sound.resumeAllSounds(); sound.resumeAllSounds();
} }
}
delete state->currentCutscene; void GameWorld::eraseCutsceneAnimations() {
state->currentCutscene = nullptr; data->animationsCutscene.clear();
state->isCinematic = false;
state->cutsceneStartTime = -1.f;
} }
bool GameWorld::isCutsceneDone() { bool GameWorld::isCutsceneDone() {

View File

@ -358,6 +358,10 @@ public:
void clearCutscene(); void clearCutscene();
bool isCutsceneDone(); bool isCutsceneDone();
void eraseCutsceneObjects();
void eraseCutsceneSound();
void eraseCutsceneAnimations();
std::string cutsceneAudio; std::string cutsceneAudio;
bool cutsceneAudioLoaded; bool cutsceneAudioLoaded;
std::string missionAudio; std::string missionAudio;

View File

@ -6564,7 +6564,7 @@ void opcode_0243(const ScriptArguments& args, const ScriptCharacter character, c
*/ */
void opcode_0244(const ScriptArguments& args, ScriptVec3 coord) { void opcode_0244(const ScriptArguments& args, ScriptVec3 coord) {
if (args.getState()->currentCutscene) { if (args.getState()->currentCutscene) {
args.getState()->currentCutscene->meta.sceneOffset = coord; args.getState()->currentCutscene->meta.sceneOffset = coord;
} }
} }
@ -7883,19 +7883,21 @@ void opcode_02e5(const ScriptArguments& args, const ScriptModelID model, ScriptO
@arg object Player @arg object Player
@arg arg2 @arg arg2
*/ */
void opcode_02e6(const ScriptArguments& args, const ScriptObject object, const ScriptString arg2) { void opcode_02e6(const ScriptArguments& args, const ScriptObject object,
const ScriptString arg2) {
RW_UNUSED(object); RW_UNUSED(object);
RW_UNUSED(arg2); RW_UNUSED(arg2);
/// @todo make animation data-driven rather than oop /// @todo make animation data-driven rather than oop
auto cutscene = args.getObject<CutsceneObject>(0); auto cutscene = args.getObject<CutsceneObject>(0);
std::string animName = arg2; std::string animName = arg2;
std::transform(animName.begin(), animName.end(), animName.begin(), ::tolower); std::transform(animName.begin(), animName.end(), animName.begin(),
auto anim = args.getWorld()->data->animations[animName]; ::tolower);
if( anim ) { auto anim = args.getWorld()->data->animationsCutscene.at(animName);
cutscene->animator->playAnimation(AnimIndexMovement, anim, 1.f, false); if (anim) {
} cutscene->animator->playAnimation(AnimIndexMovement, anim, 1.f, false);
else { } else {
args.getWorld()->logger->error("SCM", "Failed to load cutscene anim: " + animName); args.getWorld()->logger->error(
"SCM", "Failed to load cutscene anim: " + animName);
} }
} }
@ -7915,9 +7917,9 @@ void opcode_02e7(const ScriptArguments& args) {
@arg arg1 @arg arg1
*/ */
void opcode_02e8(const ScriptArguments& args, ScriptInt& arg1) { void opcode_02e8(const ScriptArguments& args, ScriptInt& arg1) {
auto cutscene = args.getState()->currentCutscene; auto& cutscene = args.getState()->currentCutscene;
if (args.getState()->skipCutscene) { if (args.getState()->skipCutscene) {
arg1 = cutscene ? cutscene->tracks.duration * 1000 : 0.f; arg1 = cutscene ? cutscene->tracks.duration * 1000 : 0.f;
} }
else { else {
arg1 = (args.getWorld()->getGameTime() - args.getState()->cutsceneStartTime) * 1000; arg1 = (args.getWorld()->getGameTime() - args.getState()->cutsceneStartTime) * 1000;
@ -7935,7 +7937,7 @@ bool opcode_02e9(const ScriptArguments& args) {
return true; return true;
} }
auto time = (args.getWorld()->getGameTime() - args.getWorld()->state->cutsceneStartTime); auto time = (args.getWorld()->getGameTime() - args.getWorld()->state->cutsceneStartTime);
return time >= args.getState()->currentCutscene->tracks.duration; return time >= args.getState()->currentCutscene->tracks.duration;
} }
return true; return true;
} }

View File

@ -380,7 +380,7 @@ const ViewCamera& IngameState::getCamera(float alpha) {
auto world = getWorld(); auto world = getWorld();
if (state->currentCutscene && state->cutsceneStartTime >= 0.f) { if (state->currentCutscene && state->cutsceneStartTime >= 0.f) {
auto cutscene = state->currentCutscene; auto& cutscene = state->currentCutscene;
float cutsceneTime = float cutsceneTime =
std::min(world->getGameTime() - state->cutsceneStartTime, std::min(world->getGameTime() - state->cutsceneStartTime,
cutscene->tracks.duration); cutscene->tracks.duration);