Skip to content

Commit

Permalink
Audio for splitscreen, cheats
Browse files Browse the repository at this point in the history
  • Loading branch information
deathkiller committed Jul 16, 2024
1 parent 7a69bdd commit 336cf52
Show file tree
Hide file tree
Showing 11 changed files with 137 additions and 55 deletions.
119 changes: 105 additions & 14 deletions Sources/Jazz2/LevelHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,56 @@ namespace Jazz2

using namespace Jazz2::Resources;

#if defined(WITH_AUDIO)
class AudioBufferPlayerForSplitscreen : public AudioBufferPlayer
{
DEATH_RUNTIME_OBJECT(AudioBufferPlayer);

public:
explicit AudioBufferPlayerForSplitscreen(AudioBuffer* audioBuffer);

void setPosition(const Vector3f& position) override;

void updatePosition(ArrayView<std::unique_ptr<PlayerViewport>> viewports);
};

AudioBufferPlayerForSplitscreen::AudioBufferPlayerForSplitscreen(AudioBuffer* audioBuffer)
: AudioBufferPlayer(audioBuffer)
{
}

void AudioBufferPlayerForSplitscreen::setPosition(const Vector3f& position)
{
position_ = position;
if (state_ == PlayerState::Playing && (GetFlags(PlayerFlags::SourceRelative) || GetFlags(PlayerFlags::As2D))) {
IAudioDevice& device = theServiceLocator().GetAudioDevice();
setPositionInternal(getAdjustedPosition(device, position_, GetFlags(PlayerFlags::SourceRelative), GetFlags(PlayerFlags::As2D)));
}
}

void AudioBufferPlayerForSplitscreen::updatePosition(ArrayView<std::unique_ptr<PlayerViewport>> viewports)
{
if (state_ != PlayerState::Playing || GetFlags(PlayerFlags::SourceRelative) || GetFlags(PlayerFlags::As2D)) {
return;
}

std::size_t minIndex = 0;
float minDistance = FLT_MAX;

for (std::size_t i = 0; i < viewports.size(); i++) {
float distance = (position_.ToVector2() - viewports[i]->_cameraPos).SqrLength();
if (minDistance > distance) {
minDistance = distance;
minIndex = i;
}
}

IAudioDevice& device = theServiceLocator().GetAudioDevice();
Vector3f relativePos = (position_ - Vector3f(viewports[minIndex]->_cameraPos, 0.0f));
setPositionInternal(getAdjustedPosition(device, relativePos, false, false));
}
#endif

LevelHandler::LevelHandler(IRootController* root)
: _root(root), _eventSpawner(this), _difficulty(GameDifficulty::Default), _isReforged(false), _cheatsUsed(false), _checkpointCreated(false),
_cheatsBufferLength(0), _nextLevelType(ExitType::None), _nextLevelTime(0.0f), _elapsedFrames(0.0f), _checkpointFrames(0.0f),
Expand Down Expand Up @@ -413,6 +463,25 @@ namespace Jazz2
viewport->UpdateCamera(timeMult);
}

#if defined(WITH_AUDIO)
if (!_assignedViewports.empty()) {
// Update audio listener position
IAudioDevice& audioDevice = theServiceLocator().GetAudioDevice();
if (_assignedViewports.size() == 1) {
audioDevice.updateListener(Vector3f(_assignedViewports[0]->_cameraPos, 0.0f),
Vector3f(_assignedViewports[0]->_targetPlayer->GetSpeed(), 0.0f));
} else {
audioDevice.updateListener(Vector3f::Zero, Vector3f::Zero);

for (auto& player : _playingSounds) {
if (auto* splitscreenPlayer = runtime_cast<AudioBufferPlayerForSplitscreen*>(player)) {
splitscreenPlayer->updatePosition(_assignedViewports);
}
}
}
}
#endif

_elapsedFrames += timeMult;
}

Expand Down Expand Up @@ -588,14 +657,18 @@ namespace Jazz2
if (_cheatsBuffer[2] == (char)KeySym::K) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
_players[0]->TakeDamage(INT32_MAX);
for (auto* player : _players) {
player->TakeDamage(INT32_MAX);
}
}
break;
case 5:
if (_cheatsBuffer[2] == (char)KeySym::G && _cheatsBuffer[3] == (char)KeySym::O && _cheatsBuffer[4] == (char)KeySym::D) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
_players[0]->SetInvulnerability(36000.0f, true);
for (auto* player : _players) {
player->SetInvulnerability(36000.0f, true);
}
}
break;
case 6:
Expand All @@ -607,42 +680,55 @@ namespace Jazz2
(_cheatsBuffer[2] == (char)KeySym::A && _cheatsBuffer[3] == (char)KeySym::M && _cheatsBuffer[4] == (char)KeySym::M && _cheatsBuffer[5] == (char)KeySym::O)) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
for (int32_t i = 0; i < (int32_t)WeaponType::Count; i++) {
_players[0]->AddAmmo((WeaponType)i, 99);
for (auto* player : _players) {
for (std::int32_t i = 0; i < (std::int32_t)WeaponType::Count; i++) {
player->AddAmmo((WeaponType)i, 99);
}
}
} else if (_cheatsBuffer[2] == (char)KeySym::R && _cheatsBuffer[3] == (char)KeySym::U && _cheatsBuffer[4] == (char)KeySym::S && _cheatsBuffer[5] == (char)KeySym::H) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
_players[0]->ActivateSugarRush(1300.0f);
for (auto* player : _players) {
player->ActivateSugarRush(1300.0f);
}
} else if (_cheatsBuffer[2] == (char)KeySym::G && _cheatsBuffer[3] == (char)KeySym::E && _cheatsBuffer[4] == (char)KeySym::M && _cheatsBuffer[5] == (char)KeySym::S) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
_players[0]->AddGems(5);
for (auto* player : _players) {
player->AddGems(5);
}
} else if (_cheatsBuffer[2] == (char)KeySym::B && _cheatsBuffer[3] == (char)KeySym::I && _cheatsBuffer[4] == (char)KeySym::R && _cheatsBuffer[5] == (char)KeySym::D) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
_players[0]->SpawnBird(0, _players[0]->GetPos());
for (auto* player : _players) {
player->SpawnBird(0, player->GetPos());
}
}
break;
case 7:
if (_cheatsBuffer[2] == (char)KeySym::P && _cheatsBuffer[3] == (char)KeySym::O && _cheatsBuffer[4] == (char)KeySym::W && _cheatsBuffer[5] == (char)KeySym::E && _cheatsBuffer[6] == (char)KeySym::R) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
for (std::int32_t i = 0; i < (std::int32_t)WeaponType::Count; i++) {
_players[0]->AddWeaponUpgrade((WeaponType)i, 0x01);
for (auto* player : _players) {
for (std::int32_t i = 0; i < (std::int32_t)WeaponType::Count; i++) {
player->AddWeaponUpgrade((WeaponType)i, 0x01);
}
}
} else if (_cheatsBuffer[2] == (char)KeySym::C && _cheatsBuffer[3] == (char)KeySym::O && _cheatsBuffer[4] == (char)KeySym::I && _cheatsBuffer[5] == (char)KeySym::N && _cheatsBuffer[6] == (char)KeySym::S) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
// Coins are synchronized automatically
_players[0]->AddCoins(5);
}
break;
case 8:
if (_cheatsBuffer[2] == (char)KeySym::S && _cheatsBuffer[3] == (char)KeySym::H && _cheatsBuffer[4] == (char)KeySym::I && _cheatsBuffer[5] == (char)KeySym::E && _cheatsBuffer[6] == (char)KeySym::L && _cheatsBuffer[7] == (char)KeySym::D) {
_cheatsBufferLength = 0;
_cheatsUsed = true;
ShieldType shieldType = (ShieldType)(((std::int32_t)_players[0]->GetActiveShield() + 1) % (std::int32_t)ShieldType::Count);
_players[0]->SetShield(shieldType, 600.0f * FrameTimer::FramesPerSecond);
for (auto* player : _players) {
ShieldType shieldType = (ShieldType)(((std::int32_t)player->GetActiveShield() + 1) % (std::int32_t)ShieldType::Count);
player->SetShield(shieldType, 600.0f * FrameTimer::FramesPerSecond);
}
}
break;
}
Expand Down Expand Up @@ -681,7 +767,9 @@ namespace Jazz2
std::shared_ptr<AudioBufferPlayer> LevelHandler::PlaySfx(Actors::ActorBase* self, const StringView identifier, AudioBuffer* buffer, const Vector3f& pos, bool sourceRelative, float gain, float pitch)
{
#if defined(WITH_AUDIO)
auto& player = _playingSounds.emplace_back(std::make_shared<AudioBufferPlayer>(buffer));
auto& player = _playingSounds.emplace_back(_assignedViewports.size() > 1
? std::make_shared<AudioBufferPlayerForSplitscreen>(buffer)
: std::make_shared<AudioBufferPlayer>(buffer));
player->setPosition(Vector3f(pos.X, pos.Y, 100.0f));
player->setGain(gain * PreferencesCache::MasterVolume * PreferencesCache::SfxVolume);
player->setSourceRelative(sourceRelative);
Expand All @@ -708,12 +796,15 @@ namespace Jazz2
return nullptr;
}
std::int32_t idx = (it->second.Buffers.size() > 1 ? Random().Next(0, (std::int32_t)it->second.Buffers.size()) : 0);
auto& player = _playingSounds.emplace_back(std::make_shared<AudioBufferPlayer>(&it->second.Buffers[idx]->Buffer));
auto* buffer = &it->second.Buffers[idx]->Buffer;
auto& player = _playingSounds.emplace_back(_assignedViewports.size() > 1
? std::make_shared<AudioBufferPlayerForSplitscreen>(buffer)
: std::make_shared<AudioBufferPlayer>(buffer));
player->setPosition(Vector3f(pos.X, pos.Y, 100.0f));
player->setGain(gain * PreferencesCache::MasterVolume * PreferencesCache::SfxVolume);

if (pos.Y >= _waterLevel) {
player->setLowPass(/*0.2f*/0.05f);
player->setLowPass(0.05f);
player->setPitch(pitch * 0.7f);
} else {
player->setPitch(pitch);
Expand Down
7 changes: 0 additions & 7 deletions Sources/Jazz2/PlayerViewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,13 +345,6 @@ namespace Jazz2
}

_camera->setView(_cameraPos - halfView.As<float>(), 0.0f, 1.0f);

// TODO: Viewports - Audio listener
if (_targetPlayer->GetPlayerIndex() == 0) {
// Update audio listener position
IAudioDevice& device = theServiceLocator().GetAudioDevice();
device.updateListener(Vector3f(_cameraPos, 0.0f), Vector3f(focusSpeed, 0.0f));
}
}

void PlayerViewport::ShakeCameraView(float duration)
Expand Down
2 changes: 1 addition & 1 deletion Sources/Shared/Containers/StringView.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ namespace Death { namespace Containers {
It's also explicitly disallowing T[] arguments (which are implicitly convertible to an ArrayView), because those should be picking the T*
overload and rely on strlen(), consistently with how C string literals work; and disallowing construction from a StringView
because it'd get preferred over the implicit copy constructor. */
template<class U, class = typename std::enable_if<!std::is_array<typename std::remove_reference<U&&>::type>::value && !std::is_same<typename std::decay<U&&>::type, BasicStringView<T>>::value && !std::is_same<typename std::decay<U&&>::type, std::nullptr_t>::value, decltype(ArrayView<T>{std::declval<U&&>()})>::type> constexpr /*implicit*/ BasicStringView(U&& data, StringViewFlags flags = {}) noexcept: BasicStringView{flags, ArrayView<T>(data)} {}
template<class U, class = typename std::enable_if<!std::is_array<typename std::remove_reference<U&&>::type>::value && !std::is_same<typename std::decay<U&&>::type, BasicStringView<T>>::value && !std::is_same<typename std::decay<U&&>::type, std::nullptr_t>::value, decltype(ArrayView<T>{std::declval<U&&>()})>::type> constexpr /*implicit*/ BasicStringView(U&& data, StringViewFlags flags = {}) noexcept : BasicStringView{flags, ArrayView<T>(data)} {}

/** @brief Construct a @ref StringView from a @ref MutableStringView */
template<class U, class = typename std::enable_if<std::is_same<const U, T>::value>::type> constexpr /*implicit*/ BasicStringView(BasicStringView<U> mutable_) noexcept : _data{mutable_._data}, _sizePlusFlags{mutable_._sizePlusFlags} {}
Expand Down
3 changes: 1 addition & 2 deletions Sources/nCine/Audio/AudioBufferPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,11 @@ namespace nCine

bool isSourceRelative = GetFlags(PlayerFlags::SourceRelative);
bool isAs2D = GetFlags(PlayerFlags::As2D);
Vector3f adjustedPos = getAdjustedPosition(device, position_, isSourceRelative, isAs2D);

alSourcei(sourceId_, AL_SOURCE_RELATIVE, isSourceRelative || isAs2D ? AL_TRUE : AL_FALSE);
alSource3f(sourceId_, AL_POSITION, adjustedPos.X, adjustedPos.Y, adjustedPos.Z);
alSourcef(sourceId_, AL_REFERENCE_DISTANCE, IAudioDevice::ReferenceDistance);
alSourcef(sourceId_, AL_MAX_DISTANCE, IAudioDevice::MaxDistance);
setPositionInternal(getAdjustedPosition(device, position_, isSourceRelative, isAs2D));

alSourcePlay(sourceId_);
state_ = PlayerState::Playing;
Expand Down
2 changes: 2 additions & 0 deletions Sources/nCine/Audio/AudioBufferPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace nCine
/// Audio buffer player class
class AudioBufferPlayer : public IAudioPlayer
{
DEATH_RUNTIME_OBJECT(IAudioPlayer);

public:
/// Default constructor
AudioBufferPlayer();
Expand Down
17 changes: 1 addition & 16 deletions Sources/nCine/Audio/AudioStreamPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ namespace nCine
{
}

/*AudioStreamPlayer::AudioStreamPlayer(const unsigned char* bufferPtr, unsigned long int bufferSize)
: IAudioPlayer(ObjectType::AudioStreamPlayer), audioStream_(bufferPtr, bufferSize)
{
}*/

AudioStreamPlayer::AudioStreamPlayer(const StringView& filename)
: IAudioPlayer(ObjectType::AudioStreamPlayer), audioStream_(filename)
{
Expand All @@ -26,15 +21,6 @@ namespace nCine
stop();
}

/*bool AudioStreamPlayer::loadFromMemory(const unsigned char* bufferPtr, unsigned long int bufferSize)
{
if (state_ != PlayerState::Stopped) {
audioStream_.stop(sourceId_);
}
return audioStream_.loadFromMemory(bufferPtr, bufferSize);
}*/

bool AudioStreamPlayer::loadFromFile(const char* filename)
{
if (state_ != PlayerState::Stopped) {
Expand Down Expand Up @@ -70,12 +56,11 @@ namespace nCine

bool isSourceRelative = GetFlags(PlayerFlags::SourceRelative);
bool isAs2D = GetFlags(PlayerFlags::As2D);
Vector3f adjustedPos = getAdjustedPosition(device, position_, isSourceRelative, isAs2D);

alSourcei(sourceId_, AL_SOURCE_RELATIVE, isSourceRelative || isAs2D ? AL_TRUE : AL_FALSE);
alSource3f(sourceId_, AL_POSITION, adjustedPos.X, adjustedPos.Y, adjustedPos.Z);
alSourcef(sourceId_, AL_REFERENCE_DISTANCE, IAudioDevice::ReferenceDistance);
alSourcef(sourceId_, AL_MAX_DISTANCE, IAudioDevice::MaxDistance);
setPositionInternal(getAdjustedPosition(device, position_, isSourceRelative, isAs2D));

alSourcePlay(sourceId_);
state_ = PlayerState::Playing;
Expand Down
4 changes: 2 additions & 2 deletions Sources/nCine/Audio/AudioStreamPlayer.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ namespace nCine
/// Audio stream player class
class AudioStreamPlayer : public IAudioPlayer
{
DEATH_RUNTIME_OBJECT(IAudioPlayer);

public:
/// Default constructor
AudioStreamPlayer();
/// A constructor creating a player from a named memory buffer
//AudioStreamPlayer(const unsigned char* bufferPtr, unsigned long int bufferSize);
/// A constructor creating a player from a file
explicit AudioStreamPlayer(const StringView& filename);
~AudioStreamPlayer() override;
Expand Down
8 changes: 6 additions & 2 deletions Sources/nCine/Audio/IAudioPlayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,7 @@ namespace nCine
position_ = position;
if (state_ == PlayerState::Playing) {
IAudioDevice& device = theServiceLocator().GetAudioDevice();
Vector3f adjustedPos = getAdjustedPosition(device, position_, GetFlags(PlayerFlags::SourceRelative), GetFlags(PlayerFlags::As2D));
alSource3f(sourceId_, AL_POSITION, adjustedPos.X, adjustedPos.Y, adjustedPos.Z);
setPositionInternal(getAdjustedPosition(device, position_, GetFlags(PlayerFlags::SourceRelative), GetFlags(PlayerFlags::As2D)));
}
}

Expand All @@ -109,6 +108,11 @@ namespace nCine
#endif
}

void IAudioPlayer::setPositionInternal(const Vector3f& position)
{
alSource3f(sourceId_, AL_POSITION, position.X, position.Y, position.Z);
}

Vector3f IAudioPlayer::getAdjustedPosition(IAudioDevice& device, const Vector3f& pos, bool isSourceRelative, bool isAs2D)
{
if (isAs2D) {
Expand Down
Loading

0 comments on commit 336cf52

Please sign in to comment.