mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 11:52:40 +01:00
Merge pull request #586 from ShFil119/sfx_script
Sfx - ScriptObject, metadata, opcodes, listener position
This commit is contained in:
commit
ae0192333f
@ -6,9 +6,9 @@
|
||||
|
||||
#include "rw/debug.hpp"
|
||||
|
||||
bool LoaderSDT::load(const rwfs::path& path) {
|
||||
const auto sdtName = path.string() + ".SDT";
|
||||
const auto rawName = path.string() + ".RAW";
|
||||
bool LoaderSDT::load(const rwfs::path& sdtPath, const rwfs::path& rawPath) {
|
||||
const auto sdtName = sdtPath.string();
|
||||
const auto rawName = rawPath.string();
|
||||
|
||||
FILE* fp = fopen(sdtName.c_str(), "rb");
|
||||
if (fp) {
|
||||
@ -29,7 +29,7 @@ bool LoaderSDT::load(const rwfs::path& path) {
|
||||
m_archive = rawName;
|
||||
return true;
|
||||
} else {
|
||||
RW_ERROR("Error cannot find " << path);
|
||||
RW_ERROR("Error cannot open " << sdtName);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -62,8 +62,7 @@ public:
|
||||
~LoaderSDT() = default;
|
||||
|
||||
/// Load the structure of the archive
|
||||
/// Omit the extension in filename
|
||||
bool load(const rwfs::path& path);
|
||||
bool load(const rwfs::path& sdtPath, const rwfs::path& rawPath);
|
||||
|
||||
/// Load a file from the archive to memory and pass a pointer to it
|
||||
/// Warning: Returns nullptr if by any reason it can't load the file
|
||||
|
@ -18,6 +18,8 @@ set(RWENGINE_SOURCES
|
||||
|
||||
src/audio/alCheck.cpp
|
||||
src/audio/alCheck.hpp
|
||||
src/audio/SfxParameters.cpp
|
||||
src/audio/SfxParameters.hpp
|
||||
src/audio/Sound.hpp
|
||||
src/audio/SoundBuffer.cpp
|
||||
src/audio/SoundBuffer.hpp
|
||||
|
160
rwengine/src/audio/SfxParameters.cpp
Normal file
160
rwengine/src/audio/SfxParameters.cpp
Normal file
@ -0,0 +1,160 @@
|
||||
#include "audio/SfxParameters.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <iterator>
|
||||
|
||||
namespace {
|
||||
/// Hardcoded array for translating script index into sfx index
|
||||
/// Valid for gta3.
|
||||
/// (In origin it also had been hardcoded)
|
||||
/// (-1 means unlimited)
|
||||
/// @todo some of them should return
|
||||
/// random(?) number in range
|
||||
/// see comment in second column
|
||||
/// @todo: preparing data for VC and SA
|
||||
constexpr SoundInstanceData sfxData[] = {
|
||||
/// for opcode 018c
|
||||
{78, 2857 /*-2871*/, -1}, /// male pain soft
|
||||
{79, 2857 /*-2871*/, -1}, /// male pain loud
|
||||
{80, 2290 /*-2300*/, -1}, /// female pain soft
|
||||
{81, 2290 /*-2300*/, -1}, /// female pain loud
|
||||
{82, 161 /*-162*/, -1}, /// item pickup
|
||||
{83, 161 /*-162*/, -1}, /// item pickup
|
||||
{92, 147, 40}, /// gate start
|
||||
{93, 147, 40}, /// gate stop
|
||||
{94, 337, -1}, /// checkpoint
|
||||
{97, 336, -1}, /// countdown timer 3
|
||||
{98, 336, -1}, /// countdown timer 2
|
||||
{99, 336, -1}, /// countdown timer 1
|
||||
{100, 337, -1}, /// countdown finish
|
||||
{106, 176, 50}, /// bullet hit ground
|
||||
{107, 177, 50},
|
||||
{108, 178, 50},
|
||||
{110, 389, 80}, /// silent
|
||||
{111, 389, 80},
|
||||
{112, 283, 80}, /// payphone
|
||||
{114, 151, 60}, /// glass break
|
||||
{115, 151, 60}, /// glass break
|
||||
{116, 150, 60}, /// glass damage
|
||||
{117, 152 /*-155*/, 55}, /// glass shards
|
||||
{118, 327, 60}, /// boxes destroyed
|
||||
{119, 328, 60}, /// boxes destroyed
|
||||
{120, 140 /*-144*/, 60}, /// car collision
|
||||
{121, 29, 60}, /// tire collision
|
||||
{122, 167 /*-168*/, 20}, /// gun shell drop,
|
||||
/// dependent on collision
|
||||
/// the player is currently
|
||||
/// standing on
|
||||
{123, 168, 20}, /// gun shell drop soft
|
||||
/// for opcode 018d
|
||||
{4, 390, 30},
|
||||
{5, 390, 80}, /// Hepburn Heights
|
||||
/// southwest tower
|
||||
{6, 391, 30},
|
||||
{7, 391, 80}, /// Hepburn Heights
|
||||
/// north tower
|
||||
{8, 392, 30},
|
||||
{9, 392, 80},
|
||||
{10, 393, 30},
|
||||
{11, 393, 80},
|
||||
{12, 394, 30},
|
||||
{13, 394, 80},
|
||||
{14, 395, 30},
|
||||
{15, 395, 80},
|
||||
{16, 396, 30},
|
||||
{17, 396, 80},
|
||||
{18, 397, 30},
|
||||
{19, 397, 80},
|
||||
{20, 398, 30},
|
||||
{21, 398, 80},
|
||||
{22, 399, 30},
|
||||
{23, 399, 80},
|
||||
{24, 390, 30},
|
||||
{25, 390, 80},
|
||||
{26, 391, 30},
|
||||
{27, 391, 80},
|
||||
{28, 392, 30},
|
||||
{29, 392, 80},
|
||||
{30, 403, 30}, /// Meeouch Sex Kitten Club
|
||||
{31, 403, 80},
|
||||
{32, 404, 30}, /// Sex Club Seven
|
||||
{33, 404, 80},
|
||||
{34, 405, 30},
|
||||
{35, 405, 30},
|
||||
{36, 407 /*-408*/, 30}, /// 407 plays continuously
|
||||
/// while 408 plays intermittently
|
||||
{37, 407 /*-408*/, 30}, /// Liberty City
|
||||
/// Sawmills/Bitch'N' Dog Food
|
||||
{38, 409, 30},
|
||||
{39, 409, 80},
|
||||
{40, 410 /*-411*/, 30}, /// Both plays continuously
|
||||
{41, 410 /*-411*/, 30}, /// Mr. Wong's Laundrette
|
||||
{42, 412, 30}, /// Roast Peking Duck
|
||||
{43, 412, 80},
|
||||
{44, 413, 30}, /// Cipriani's Ristorante
|
||||
{45, 413, 80},
|
||||
{46, 414, 30},
|
||||
{47, 414, 30},
|
||||
{48, 415, 30}, /// Marco's Bistro (no sound)
|
||||
{49, 415, 80},
|
||||
{50, 416 /*-419*/, 30}, /// Plays separately and intermittently
|
||||
{51, 416 /*-419*/, 80}, /// Francis International Terminal B
|
||||
{52, 420 /*-422*/, 30},
|
||||
{53, 420 /*-422*/, 30}, /// Chinatown (no sound)
|
||||
{54, 423 /*-425*/, 30}, /// Plays separately and intermittently
|
||||
{55, 423 /*-425*/, 80},
|
||||
{56, 426, 30},
|
||||
{57, 426, 80}, /// Portland Docks (no sound)
|
||||
{58, 427 /*-431*/, 30}, /// Plays separately and intermittently
|
||||
{59, 427 /*-431*/, 80}, /// Left side of Misty's apartment
|
||||
{60, 406, 30}, /// Salvatore's place
|
||||
{61, 406, 80},
|
||||
{62, 432 /*-434*/, 20}, /// South of Sex Club Seven
|
||||
/// 432 plays continuously
|
||||
/// while 433-434
|
||||
/// plays separately
|
||||
/// and intermittently
|
||||
{63, 432 /*-434*/, 80},
|
||||
{64, 435 /*-437*/, 20}, /// East of Portland
|
||||
/// Pay 'N' Spray 435 plays
|
||||
/// continuously while
|
||||
/// 436-437 plays separately
|
||||
/// and intermittently
|
||||
{65, 435 /*-437*/, 80},
|
||||
{66, 438 /*-440*/, 20}, /// Executive Relief 438
|
||||
/// plays continuously while
|
||||
/// 439-440 plays separately
|
||||
/// and intermittently
|
||||
{67, 438 /*-440*/, 80},
|
||||
{68, 442, 30},
|
||||
{69, 442, 80}, /// Bank of Liberty/Staunton
|
||||
/// police HQ alarm
|
||||
{70, 441, 30},
|
||||
{71, 441, 80}, /// Old school hall
|
||||
{72, 443, 30},
|
||||
{73, 443, 80}, /// Warehouse rave
|
||||
{76, 179 /*-184*/, 30}, /// Plays separately and intermittently
|
||||
{77, 179 /*-184*/, 80}, /// Staunton police HQ
|
||||
{84, 444, 30},
|
||||
{85, 444, 80},
|
||||
{86, 444, 30},
|
||||
{87, 444, 80},
|
||||
{88, 445, 30},
|
||||
{89, 445, 80},
|
||||
{90, 433 /*-434*/, 20}, /// Plays separately and intermittently
|
||||
{91, 433 /*-434*/, 80}, /// Right side of Misty's apartment
|
||||
{102, 157, 50} /// Callahan Bridge fire
|
||||
};
|
||||
} // namespace
|
||||
|
||||
const SoundInstanceData* getSoundInstanceData(int scriptId) {
|
||||
const auto found = std::find_if(std::begin(sfxData), std::end(sfxData),
|
||||
[&scriptId](const SoundInstanceData data) {
|
||||
return data.id == scriptId;
|
||||
});
|
||||
if (found != std::end(sfxData)) {
|
||||
return found;
|
||||
}
|
||||
return std::begin(sfxData);
|
||||
}
|
19
rwengine/src/audio/SfxParameters.hpp
Normal file
19
rwengine/src/audio/SfxParameters.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef _RWENGINE_SFX_PARAMETERS_HPP_
|
||||
#define _RWENGINE_SFX_PARAMETERS_HPP_
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
/// Script is using different numeration of sounds
|
||||
/// than postion index in sfx file.
|
||||
/// Also it is needed to store range of sound.
|
||||
/// Struct is used by opcodes 018c, 018d.
|
||||
struct SoundInstanceData {
|
||||
int id;
|
||||
int sfx;
|
||||
int range;
|
||||
};
|
||||
|
||||
/// Get metadata for selected script index
|
||||
const SoundInstanceData* getSoundInstanceData(int scriptId);
|
||||
|
||||
#endif
|
@ -8,6 +8,9 @@ extern "C" {
|
||||
}
|
||||
|
||||
#include "audio/alCheck.hpp"
|
||||
#include "engine/GameData.hpp"
|
||||
#include "engine/GameWorld.hpp"
|
||||
#include "render/ViewCamera.hpp"
|
||||
|
||||
#include <rw/types.hpp>
|
||||
|
||||
@ -25,7 +28,11 @@ Sound& SoundManager::getSoundRef(const std::string& name) {
|
||||
return sounds[name]; // @todo reloading, how to check is it wav/mp3?
|
||||
}
|
||||
|
||||
SoundManager::SoundManager() {
|
||||
SoundManager::SoundManager(GameWorld* engine) : _engine(engine) {
|
||||
auto sdtPath = _engine->data->index.findFilePath("audio/sfx.SDT");
|
||||
auto rawPath = _engine->data->index.findFilePath("audio/sfx.RAW");
|
||||
sdt.load(sdtPath, rawPath);
|
||||
|
||||
initializeOpenAL();
|
||||
initializeAVCodec();
|
||||
}
|
||||
@ -71,6 +78,12 @@ bool SoundManager::initializeAVCodec() {
|
||||
av_log_set_level(AV_LOG_ERROR);
|
||||
#endif
|
||||
|
||||
// Some older versions of FFmpeg require it
|
||||
// before calling avformat_alloc_context()
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
|
||||
av_register_all();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -97,7 +110,7 @@ bool SoundManager::loadSound(const std::string& name,
|
||||
return sound->isLoaded;
|
||||
}
|
||||
|
||||
void SoundManager::loadSfxSound(const rwfs::path& path, size_t index) {
|
||||
void SoundManager::loadSound(size_t index) {
|
||||
Sound* sound = nullptr;
|
||||
|
||||
auto emplaced =
|
||||
@ -106,13 +119,19 @@ void SoundManager::loadSfxSound(const rwfs::path& path, size_t index) {
|
||||
sound = &emplaced.first->second;
|
||||
|
||||
sound->source = std::make_shared<SoundSource>();
|
||||
sound->source->loadSfx(path, sdt, index);
|
||||
sound->source->loadSfx(sdt, index);
|
||||
}
|
||||
|
||||
size_t SoundManager::createSfxInstance(size_t index) {
|
||||
Sound* sound = nullptr;
|
||||
auto soundRef = sfx.find(index);
|
||||
|
||||
if(soundRef == sfx.end()) {
|
||||
// Sound source is not loaded yet
|
||||
loadSound(index);
|
||||
soundRef = sfx.find(index);
|
||||
}
|
||||
|
||||
// Try to reuse first available buffer
|
||||
// (aka with stopped state)
|
||||
for (auto& sound : buffers) {
|
||||
@ -264,17 +283,21 @@ void SoundManager::pause(bool p) {
|
||||
}
|
||||
}
|
||||
|
||||
void SoundManager::setListenerPosition(const glm::vec3& position) {
|
||||
alListener3f(AL_POSITION, position.x, position.y, position.z);
|
||||
}
|
||||
void SoundManager::updateListenerTransform(const ViewCamera& cam) {
|
||||
// Orientation
|
||||
auto up = cam.rotation * glm::vec3(0.f, 0.f, 1.f);
|
||||
auto at = cam.rotation * glm::vec3(1.f, 0.f, 0.f);
|
||||
float orientation[6] = {at.x, at.y, at.z, up.x, up.y, up.z};
|
||||
alListenerfv(AL_ORIENTATION, orientation);
|
||||
|
||||
void SoundManager::setListenerVelocity(const glm::vec3& vel) {
|
||||
alListener3f(AL_VELOCITY, vel.x, vel.y, vel.z);
|
||||
}
|
||||
// Position
|
||||
float position[3] = {cam.position.x, cam.position.y, cam.position.z};
|
||||
alListenerfv(AL_POSITION, position);
|
||||
|
||||
void SoundManager::setListenerOrientation(const glm::vec3& at) {
|
||||
float v[6] = {0, at.y, 0, 0, 0, at.z};
|
||||
alListenerfv(AL_ORIENTATION, v);
|
||||
// @todo ShFil119 it should be implemented
|
||||
// Velocity
|
||||
// float velocity[3] = ...
|
||||
// alListenerfv(AL_VELOCITY, velocity);
|
||||
}
|
||||
|
||||
void SoundManager::setSoundPosition(const std::string& name,
|
||||
|
@ -18,6 +18,9 @@
|
||||
#include <rw/filesystem.hpp>
|
||||
#include <loaders/LoaderSDT.hpp>
|
||||
|
||||
class GameWorld;
|
||||
class ViewCamera;
|
||||
|
||||
/// Game's sound manager.
|
||||
/// It handles all stuff connected with sounds.
|
||||
/// Worth noted: there are three types of sounds,
|
||||
@ -26,14 +29,14 @@
|
||||
/// instances simultaneously without duplicating raw source).
|
||||
class SoundManager {
|
||||
public:
|
||||
SoundManager();
|
||||
SoundManager(GameWorld* engine);
|
||||
~SoundManager();
|
||||
|
||||
/// Load sound from file and store it with selected name
|
||||
bool loadSound(const std::string& name, const std::string& fileName);
|
||||
|
||||
/// Load all sfx sounds
|
||||
void loadSfxSound(const rwfs::path& path, size_t index);
|
||||
/// Load selected sfx sound
|
||||
void loadSound(size_t index);
|
||||
|
||||
Sound& getSoundRef(size_t name);
|
||||
Sound& getSoundRef(const std::string& name);
|
||||
@ -73,15 +76,8 @@ public:
|
||||
void playMusic(const std::string& name);
|
||||
void stopMusic(const std::string& name);
|
||||
|
||||
/// Setting position of listener for openAL.
|
||||
void setListenerPosition(const glm::vec3& position);
|
||||
|
||||
/// Setting velocity of velocity for openAL.
|
||||
void setListenerVelocity(const glm::vec3& vel);
|
||||
|
||||
/// Setting orientation of listener for openAL.
|
||||
/// Worth noted v = { at.x, at.y, at.z, up.x, up.y, up.z}
|
||||
void setListenerOrientation(const glm::vec3& at);
|
||||
/// Updating listener tranform, called by main loop of game.
|
||||
void updateListenerTransform(const ViewCamera& cam);
|
||||
|
||||
/// Setting position of sound source in buffer.
|
||||
void setSoundPosition(const std::string& name, const glm::vec3& position);
|
||||
@ -105,6 +101,7 @@ private:
|
||||
/// Nr of already created buffers
|
||||
size_t bufferNr = 0;
|
||||
|
||||
GameWorld* _engine;
|
||||
LoaderSDT sdt{};
|
||||
};
|
||||
|
||||
|
@ -254,7 +254,7 @@ static int read_packet(void* opaque, uint8_t* buf, int buf_size) {
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
void SoundSource::loadSfx(const rwfs::path& path, LoaderSDT& sdt, size_t index, bool asWave) {
|
||||
void SoundSource::loadSfx(LoaderSDT& sdt, size_t index, bool asWave) {
|
||||
// Allocate audio frame
|
||||
AVFrame* frame = av_frame_alloc();
|
||||
if (!frame) {
|
||||
@ -262,9 +262,6 @@ void SoundSource::loadSfx(const rwfs::path& path, LoaderSDT& sdt, size_t index,
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
sdt.load(path / "audio/sfx");
|
||||
|
||||
/// Now we need to prepare "custom" format context
|
||||
/// We need sdt loader for that purpose
|
||||
std::unique_ptr<char[]> raw_sound = sdt.loadToMemory(index, asWave);
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
void loadFromFile(const rwfs::path& filePath);
|
||||
|
||||
/// Load sound from sdt file
|
||||
void loadSfx(const rwfs::path& path, LoaderSDT& sdt, size_t index, bool asWave = true);
|
||||
void loadSfx(LoaderSDT& sdt, size_t index, bool asWave = true);
|
||||
|
||||
private:
|
||||
/// Raw data
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
};
|
||||
|
||||
GameWorld::GameWorld(Logger* log, GameData* dat)
|
||||
: logger(log), data(dat) {
|
||||
: logger(log), data(dat), sound(this) {
|
||||
data->engine = this;
|
||||
|
||||
collisionConfig = std::make_unique<btDefaultCollisionConfiguration>();
|
||||
|
@ -239,6 +239,15 @@ ScriptObjectType<Payphone> ScriptArguments::getScriptObject(
|
||||
}
|
||||
return {param.handleValue(), payphone};
|
||||
}
|
||||
|
||||
template <>
|
||||
ScriptObjectType<Sound> ScriptArguments::getScriptObject(
|
||||
unsigned int arg) const {
|
||||
auto& param = (*this)[arg];
|
||||
RW_CHECK(param.isLvalue(), "Non lvalue passed as object");
|
||||
return {param.handleValue(), &getWorld()->sound.getSoundRef(arg)};
|
||||
}
|
||||
|
||||
template <>
|
||||
ScriptObjectType<BlipData> ScriptArguments::getScriptObject(
|
||||
unsigned int arg) const {
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <rw/debug.hpp>
|
||||
|
||||
#include "audio/Sound.hpp"
|
||||
#include "engine/Garage.hpp"
|
||||
|
||||
class CharacterObject;
|
||||
@ -109,9 +110,9 @@ struct BlipData;
|
||||
using ScriptVehicleGenerator = ScriptObjectType<VehicleGenerator>;
|
||||
using ScriptBlip = ScriptObjectType<BlipData>;
|
||||
using ScriptPayphone = ScriptObjectType<Payphone>;
|
||||
using ScriptSound = ScriptObjectType<Sound>;
|
||||
|
||||
/// @todo replace these with real types for sounds etc.
|
||||
using ScriptSound = ScriptObjectType<int>;
|
||||
/// @todo replace these with real types
|
||||
using ScriptFire = ScriptObjectType<int>;
|
||||
using ScriptSphere = ScriptObjectType<int>;
|
||||
|
||||
@ -349,6 +350,9 @@ ScriptObjectType<VehicleGenerator> ScriptArguments::getScriptObject(
|
||||
template <>
|
||||
ScriptObjectType<Garage> ScriptArguments::getScriptObject(
|
||||
unsigned int arg) const;
|
||||
template <>
|
||||
ScriptObjectType<Sound> ScriptArguments::getScriptObject(
|
||||
unsigned int arg) const;
|
||||
|
||||
typedef std::function<void(const ScriptArguments&)> ScriptFunction;
|
||||
typedef std::function<bool(const ScriptArguments&)> ScriptFunctionBoolean;
|
||||
|
@ -1,20 +1,21 @@
|
||||
#include <script/ScriptTypes.hpp>
|
||||
#include <script/ScriptMachine.hpp>
|
||||
#include <script/SCMFile.hpp>
|
||||
#include <script/ScriptFunctions.hpp>
|
||||
#include <engine/GameWorld.hpp>
|
||||
#include <engine/GameState.hpp>
|
||||
#include <engine/GameData.hpp>
|
||||
#include <engine/Animator.hpp>
|
||||
#include <ai/PlayerController.hpp>
|
||||
#include <audio/SfxParameters.hpp>
|
||||
#include <core/Logger.hpp>
|
||||
#include <objects/CutsceneObject.hpp>
|
||||
#include <data/CutsceneData.hpp>
|
||||
#include <engine/Animator.hpp>
|
||||
#include <engine/GameData.hpp>
|
||||
#include <engine/GameState.hpp>
|
||||
#include <engine/GameWorld.hpp>
|
||||
#include <objects/CharacterObject.hpp>
|
||||
#include <objects/CutsceneObject.hpp>
|
||||
#include <objects/InstanceObject.hpp>
|
||||
#include <objects/ObjectTypes.hpp>
|
||||
#include <objects/PickupObject.hpp>
|
||||
#include <objects/VehicleObject.hpp>
|
||||
#include <ai/PlayerController.hpp>
|
||||
#include <data/CutsceneData.hpp>
|
||||
#include <script/SCMFile.hpp>
|
||||
#include <script/ScriptFunctions.hpp>
|
||||
#include <script/ScriptMachine.hpp>
|
||||
#include <script/ScriptTypes.hpp>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
|
||||
@ -4280,10 +4281,10 @@ void opcode_018b(const ScriptArguments& args, const ScriptBlip blip, const Scrip
|
||||
@arg sound
|
||||
*/
|
||||
void opcode_018c(const ScriptArguments& args, ScriptVec3 coord, const ScriptSoundType sound) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x018c);
|
||||
RW_UNUSED(coord);
|
||||
RW_UNUSED(sound);
|
||||
RW_UNUSED(args);
|
||||
auto world = args.getWorld();
|
||||
auto metaData = getSoundInstanceData(sound);
|
||||
auto name = world->sound.createSfxInstance(metaData->sfx);
|
||||
world->sound.playSfx(name, coord, false, metaData->range);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4295,11 +4296,11 @@ void opcode_018c(const ScriptArguments& args, ScriptVec3 coord, const ScriptSoun
|
||||
@arg sound1
|
||||
*/
|
||||
void opcode_018d(const ScriptArguments& args, ScriptVec3 coord, const ScriptSoundType sound0, ScriptSound& sound1) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x018d);
|
||||
RW_UNUSED(coord);
|
||||
RW_UNUSED(sound0);
|
||||
RW_UNUSED(sound1);
|
||||
RW_UNUSED(args);
|
||||
auto world = args.getWorld();
|
||||
auto metaData = getSoundInstanceData(sound0);
|
||||
auto bufferName = world->sound.createSfxInstance(metaData->sfx);
|
||||
world->sound.playSfx(bufferName, coord, true, metaData->range);
|
||||
sound1 = &world->sound.getSoundRef(bufferName);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -4309,9 +4310,8 @@ void opcode_018d(const ScriptArguments& args, ScriptVec3 coord, const ScriptSoun
|
||||
@arg sound
|
||||
*/
|
||||
void opcode_018e(const ScriptArguments& args, const ScriptSound sound) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x018e);
|
||||
RW_UNUSED(sound);
|
||||
RW_UNUSED(args);
|
||||
sound->stop();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -11329,9 +11329,9 @@ void opcode_03d6(const ScriptArguments& args, const ScriptString gxtEntry) {
|
||||
@arg coord Coordinates
|
||||
*/
|
||||
void opcode_03d7(const ScriptArguments& args, ScriptVec3 coord) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x03d7);
|
||||
RW_UNUSED(coord);
|
||||
RW_UNUSED(args);
|
||||
auto world = args.getWorld();
|
||||
auto& wav = world->sound.getSoundRef(world->missionAudio);
|
||||
wav.setPosition(coord);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -604,6 +604,8 @@ void RWGame::render(float alpha, float time) {
|
||||
viewCam.frustum.fov *= viewCam.frustum.aspectRatio;
|
||||
}
|
||||
|
||||
world->sound.updateListenerTransform(viewCam);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user