1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 02:12:45 +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()) {
auto vol = getCalculatedVolumeOfMusic();
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
void playSound(const std::string& name);
/// Erase sound with selected name
void eraseSound(const std::string& name);
/// Effect same as playSound with one parametr,
/// but this function works for sfx and
/// allows also for setting position,

View File

@ -522,14 +522,18 @@ bool GameData::loadModel(ModelID model) {
return true;
}
void GameData::loadIFP(const std::string& name) {
void GameData::loadIFP(const std::string& name, bool cutsceneAnimation) {
auto f = index.openFile(name);
if (f.data) {
LoaderIFP loader;
if (loader.loadFromMemory(f.data.get())) {
animations.insert(loader.animations.begin(),
loader.animations.end());
if (LoaderIFP loader{}; loader.loadFromMemory(f.data.get())) {
if (cutsceneAnimation) {
animationsCutscene.insert(loader.animations.begin(),
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
*/
void loadIFP(const std::string& name);
void loadIFP(const std::string& name, bool cutsceneAnimation = false);
/**
* Loads data from an object definition dat.
@ -289,10 +289,15 @@ public:
std::vector<TextureAtlas*> atlases;
/**
* Loaded Animations
* Loaded Animations (doesn't contain animations of cutscene)
*/
AnimationSet animations;
/**
* Loaded Animations (only) for cutscene
*/
AnimationSet animationsCutscene;
/**
* Pedestrian Animation Groups
*/

View File

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

View File

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

View File

@ -358,6 +358,10 @@ public:
void clearCutscene();
bool isCutsceneDone();
void eraseCutsceneObjects();
void eraseCutsceneSound();
void eraseCutsceneAnimations();
std::string cutsceneAudio;
bool cutsceneAudioLoaded;
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) {
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 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(arg2);
/// @todo make animation data-driven rather than oop
auto cutscene = args.getObject<CutsceneObject>(0);
std::string animName = arg2;
std::transform(animName.begin(), animName.end(), animName.begin(), ::tolower);
auto anim = args.getWorld()->data->animations[animName];
if( anim ) {
cutscene->animator->playAnimation(AnimIndexMovement, anim, 1.f, false);
}
else {
args.getWorld()->logger->error("SCM", "Failed to load cutscene anim: " + animName);
std::transform(animName.begin(), animName.end(), animName.begin(),
::tolower);
auto anim = args.getWorld()->data->animationsCutscene.at(animName);
if (anim) {
cutscene->animator->playAnimation(AnimIndexMovement, anim, 1.f, false);
} else {
args.getWorld()->logger->error(
"SCM", "Failed to load cutscene anim: " + animName);
}
}
@ -7915,9 +7917,9 @@ void opcode_02e7(const ScriptArguments& args) {
@arg arg1
*/
void opcode_02e8(const ScriptArguments& args, ScriptInt& arg1) {
auto cutscene = args.getState()->currentCutscene;
auto& cutscene = args.getState()->currentCutscene;
if (args.getState()->skipCutscene) {
arg1 = cutscene ? cutscene->tracks.duration * 1000 : 0.f;
arg1 = cutscene ? cutscene->tracks.duration * 1000 : 0.f;
}
else {
arg1 = (args.getWorld()->getGameTime() - args.getState()->cutsceneStartTime) * 1000;
@ -7935,7 +7937,7 @@ bool opcode_02e9(const ScriptArguments& args) {
return true;
}
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;
}

View File

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