Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion include/reone/audio/mixer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class IAudioMixer {
virtual ~IAudioMixer() = default;

virtual void render() = 0;
virtual void stop(AudioType type) = 0;
virtual void stopAll() = 0;

virtual std::shared_ptr<AudioSource> play(
std::shared_ptr<AudioClip> clip,
Expand All @@ -48,6 +50,8 @@ class AudioMixer : public IAudioMixer, boost::noncopyable {
}

void render() override;
void stop(AudioType type) override;
void stopAll() override;

std::shared_ptr<AudioSource> play(
std::shared_ptr<AudioClip> clip,
Expand All @@ -57,9 +61,14 @@ class AudioMixer : public IAudioMixer, boost::noncopyable {
std::optional<glm::vec3> = std::nullopt) override;

private:
struct ActiveSource {
std::shared_ptr<AudioSource> source;
AudioType type {AudioType::Sound};
};

AudioOptions &_options;

std::vector<std::shared_ptr<AudioSource>> _sources;
std::vector<ActiveSource> _sources;

float gainByType(AudioType type, float gain) const;
};
Expand Down
6 changes: 6 additions & 0 deletions include/reone/game/game.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

#pragma once

#include <queue>

#include "reone/audio/source.h"
#include "reone/graphics/cursor.h"
#include "reone/input/event.h"
Expand Down Expand Up @@ -183,6 +185,7 @@ class Game : boost::noncopyable {
void loadModule(const std::string &name, std::string entry = "");

void scheduleModuleTransition(const std::string &moduleName, const std::string &entry);
void scheduleModuleTransitionWithMovies(const std::string &moduleName, const std::string &entry, std::vector<std::string> movies);

// END Module loading

Expand Down Expand Up @@ -321,6 +324,7 @@ class Game : boost::noncopyable {
Screen _screen {Screen::None};

std::shared_ptr<movie::IMovie> _movie;
std::queue<std::string> _moduleTransitionMovies;
resource::CursorType _cursorType {resource::CursorType::None};
std::shared_ptr<graphics::Cursor> _cursor;
float _gameSpeed {1.0f};
Expand Down Expand Up @@ -408,6 +412,8 @@ class Game : boost::noncopyable {

// Updates

bool startVideo(const std::string &name);
bool playNextModuleTransitionMovie();
void updateMovie(float dt);
void updateMusic();
void updateCamera(float dt);
Expand Down
23 changes: 21 additions & 2 deletions src/libs/audio/mixer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace audio {

void AudioMixer::render() {
for (auto it = _sources.begin(); it != _sources.end();) {
auto &source = *it;
auto &source = it->source;
source->render();
if (!source->isPlaying()) {
it = _sources.erase(it);
Expand All @@ -33,6 +33,25 @@ void AudioMixer::render() {
}
}

void AudioMixer::stop(AudioType type) {
for (auto it = _sources.begin(); it != _sources.end();) {
if (it->type != type) {
++it;
continue;
}

it->source->stop();
it = _sources.erase(it);
}
}

void AudioMixer::stopAll() {
for (auto &source : _sources) {
source.source->stop();
}
_sources.clear();
}

std::shared_ptr<AudioSource> AudioMixer::play(std::shared_ptr<AudioClip> clip,
AudioType type,
float gain,
Expand All @@ -45,7 +64,7 @@ std::shared_ptr<AudioSource> AudioMixer::play(std::shared_ptr<AudioClip> clip,
std::move(position));
source->init();
source->play();
_sources.push_back(source);
_sources.push_back(ActiveSource {source, type});
return source;
}

Expand Down
66 changes: 49 additions & 17 deletions src/libs/game/game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,15 +412,8 @@ void Game::setCursorType(CursorType type) {
}

void Game::playVideo(const std::string &name) {
_movie = _services.resource.movies.get(name);
if (!_movie) {
return;
}

if (_music) {
_music->stop();
_music.reset();
}
_moduleTransitionMovies = std::queue<std::string>();
startVideo(name);
}

void Game::playMusic(const std::string &resRef) {
Expand Down Expand Up @@ -526,14 +519,6 @@ void Game::renderGUI() {
}
}

void Game::updateMovie(float dt) {
_movie->update(dt);

if (_movie->isFinished()) {
_movie.reset();
}
}

void Game::updateMusic() {
if (_musicResRef.empty()) {
return;
Expand Down Expand Up @@ -563,6 +548,53 @@ void Game::stopMovement() {
void Game::scheduleModuleTransition(const std::string &moduleName, const std::string &entry) {
_nextModule = moduleName;
_nextEntry = entry;
_moduleTransitionMovies = std::queue<std::string>();
}

void Game::scheduleModuleTransitionWithMovies(const std::string &moduleName, const std::string &entry, std::vector<std::string> movies) {
_nextModule = moduleName;
_nextEntry = entry;
_moduleTransitionMovies = std::queue<std::string>();
for (auto &movie : movies) {
_moduleTransitionMovies.push(std::move(movie));
}

if (!_movie) {
playNextModuleTransitionMovie();
}
}

bool Game::startVideo(const std::string &name) {
_services.audio.mixer.stopAll();
_music.reset();

_movie = _services.resource.movies.get(name);
if (!_movie) {
return false;
}

return true;
}

bool Game::playNextModuleTransitionMovie() {
while (!_moduleTransitionMovies.empty()) {
auto name = std::move(_moduleTransitionMovies.front());
_moduleTransitionMovies.pop();

if (startVideo(name)) {
return true;
}
}
return false;
}

void Game::updateMovie(float dt) {
_movie->update(dt);

if (_movie->isFinished()) {
_movie.reset();
playNextModuleTransitionMovie();
}
}

void Game::updateCamera(float dt) {
Expand Down
18 changes: 17 additions & 1 deletion src/libs/game/script/routine/impl/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4389,9 +4389,25 @@ static Variable StartNewModule(const std::vector<Variable> &args, const RoutineC
// Transform
auto moduleName = boost::to_lower_copy(sModuleName);
auto waypoint = boost::to_lower_copy(sWayPoint);
std::vector<std::string> movies;
auto addMovie = [&movies](const std::string &movie) {
if (!movie.empty()) {
movies.push_back(boost::to_lower_copy(movie));
}
};
addMovie(sMovie1);
addMovie(sMovie2);
addMovie(sMovie3);
addMovie(sMovie4);
addMovie(sMovie5);
addMovie(sMovie6);

// Execute
ctx.game.scheduleModuleTransition(moduleName, waypoint);
if (movies.empty()) {
ctx.game.scheduleModuleTransition(moduleName, waypoint);
} else {
ctx.game.scheduleModuleTransitionWithMovies(moduleName, waypoint, std::move(movies));
}
return Variable::ofNull();
}

Expand Down
2 changes: 2 additions & 0 deletions test/fixtures/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class MockContext : public IContext, boost::noncopyable {
class MockAudioMixer : public IAudioMixer, boost::noncopyable {
public:
MOCK_METHOD(void, render, (), (override));
MOCK_METHOD(void, stop, (AudioType), (override));
MOCK_METHOD(void, stopAll, (), (override));
MOCK_METHOD(std::shared_ptr<AudioSource>, play, (std::shared_ptr<AudioClip>, AudioType, float, bool, std::optional<glm::vec3>), (override));
};

Expand Down
Loading