-Subproject commit 2e992fd6861d4c45c5938bd519600aeb8b8be386
+Subproject commit 03a7d614b7e7e7c57c87b022b9bf76b09c5242fb
void LoadBlockTypes(
const std::string &set_name,
BlockTypeRegistry &,
- ResourceIndex &,
+ ResourceIndex &snd,
+ ResourceIndex &tex,
const ShapeRegistry &) const;
CubeMap LoadCubeMap(const std::string &name) const;
Font LoadFont(const std::string &name, int size) const;
void AssetLoader::LoadBlockTypes(
const string &set_name,
BlockTypeRegistry ®,
+ ResourceIndex &snd_index,
ResourceIndex &tex_index,
const ShapeRegistry &shapes
) const {
in.ReadVec(type.outline_color);
} else if (name == "label") {
in.ReadString(type.label);
+ } else if (name == "place_sound") {
+ in.ReadString(tex_name);
+ type.place_sound = snd_index.GetID(tex_name);
+ } else if (name == "remove_sound") {
+ in.ReadString(tex_name);
+ type.remove_sound = snd_index.GetID(tex_name);
} else if (name == "luminosity") {
type.luminosity = in.GetInt();
} else if (name == "block_light") {
--- /dev/null
+#ifndef BLANK_AUDIO_SOUNDBANK_HPP_
+#define BLANK_AUDIO_SOUNDBANK_HPP_
+
+#include "Sound.hpp"
+
+#include <vector>
+
+
+namespace blank {
+
+class AssetLoader;
+class Audio;
+class ResourceIndex;
+
+class SoundBank {
+
+public:
+ SoundBank();
+
+ void Load(const AssetLoader &, const ResourceIndex &);
+
+ const Sound &operator [](std::size_t i) const noexcept { return sounds[i]; }
+
+private:
+ std::vector<Sound> sounds;
+
+};
+
+}
+
+#endif
#include "ALError.hpp"
#include "Audio.hpp"
#include "Sound.hpp"
+#include "SoundBank.hpp"
+
+#include "../app/Assets.hpp"
+#include "../shared/ResourceIndex.hpp"
#include <algorithm>
#include <alut.h>
Sound::Sound()
: handle(AL_NONE)
, duration(0) {
- alGenBuffers(1, &handle);
- ALenum err = alGetError();
- if (err != AL_NO_ERROR) {
- throw ALError(err, "alGenBuffers");
- }
+
}
Sound::Sound(const char *file)
ALenum err = alGetError();
if (err != AL_NO_ERROR) {
std::cerr << "warning: alDeleteBuffers failed with " << al_error_string(err) << std::endl;
- //throw ALError(err, "alDeleteBuffers");
}
}
}
Sound::Sound(Sound &&other)
-: handle(other.handle) {
+: handle(other.handle)
+, duration(other.duration) {
other.handle = AL_NONE;
}
Sound &Sound::operator =(Sound &&other) {
std::swap(handle, other.handle);
+ std::swap(duration, other.duration);
return *this;
}
alSourcei(src, AL_BUFFER, handle);
}
+
+SoundBank::SoundBank()
+: sounds() {
+
+}
+
+void SoundBank::Load(const AssetLoader &loader, const ResourceIndex &index) {
+ sounds.clear();
+ sounds.resize(index.Size());
+ for (const auto &entry : index.Entries()) {
+ sounds[entry.second] = loader.LoadSound(entry.first);
+ }
+}
+
}
#include "ChunkReceiver.hpp"
#include "NetworkedInput.hpp"
#include "../app/IntervalTimer.hpp"
+#include "../audio/SoundBank.hpp"
#include "../graphics/SkyBox.hpp"
#include "../io/WorldSave.hpp"
#include "../net/Packet.hpp"
private:
MasterState &master;
WorldResources res;
+ SoundBank sounds;
WorldSave save;
World world;
Player &player;
InteractiveState::InteractiveState(MasterState &master, uint32_t player_id)
: master(master)
, res()
+, sounds()
, save(master.GetEnv().config.GetWorldPath(master.GetWorldConf().name, master.GetConfig().net.host))
, world(res.block_types, master.GetWorldConf())
, player(*world.AddPlayer(master.GetConfig().player.name))
, hud(master.GetEnv(), master.GetConfig(), player)
-, manip(master.GetEnv(), player.GetEntity())
+, manip(master.GetEnv().audio, sounds, player.GetEntity())
, input(world, player, master.GetClient())
, interface(master.GetConfig(), master.GetEnv().keymap, input, *this)
, chunk_receiver(world.Chunks(), save)
save.Write(master.GetWorldConf());
}
res.Load(master.GetEnv().loader, "default");
+ sounds.Load(master.GetEnv().loader, res.snd_index);
interface.SetInventorySlots(res.block_types.size() - 1);
chunk_renderer.LoadTextures(master.GetEnv().loader, res.tex_index);
chunk_renderer.FogDensity(master.GetWorldConf().fog_density);
BlockTypeRegistry block_types;
ModelRegistry models;
+ ResourceIndex snd_index;
ResourceIndex tex_index;
: shapes()
, block_types()
, models()
+, snd_index()
, tex_index() {
}
void WorldResources::Load(const AssetLoader &loader, const std::string &set) {
loader.LoadShapes("default", shapes);
- loader.LoadBlockTypes("default", block_types, tex_index, shapes);
+ loader.LoadBlockTypes("default", block_types, snd_index, tex_index, shapes);
loader.LoadModels("default", models, tex_index, shapes);
}
: config(config)
, env(env)
, res()
+, sounds()
, save(save)
, world(res.block_types, wc)
, spawn_index(world.Chunks().MakeIndex(wc.spawn, 3))
, player(*world.AddPlayer(config.player.name))
, spawn_player(false)
, hud(env, config, player)
-, manip(env, player.GetEntity())
+, manip(env.audio, sounds, player.GetEntity())
, input(world, player, manip)
, interface(config, env.keymap, input, *this)
, generator(gc)
if (res.models.size() < 2) {
throw std::runtime_error("need at least two models to run");
}
+ sounds.Load(env.loader, res.snd_index);
spawner.LimitModels(0, res.models.size());
interface.SetInventorySlots(res.block_types.size() - 1);
generator.LoadTypes(res.block_types);
#include "PreloadState.hpp"
#include "UnloadState.hpp"
#include "../ai/Spawner.hpp"
+#include "../audio/SoundBank.hpp"
#include "../graphics/SkyBox.hpp"
#include "../shared/WorldResources.hpp"
#include "../ui/DirectInput.hpp"
Config &config;
Environment &env;
WorldResources res;
+ SoundBank sounds;
const WorldSave &save;
World world;
ChunkIndex &spawn_index;
class Audio;
class Entity;
-class Environment;
+class SoundBank;
class InteractiveManipulator
: public WorldManipulator {
public:
- explicit InteractiveManipulator(Environment &, Entity &);
+ explicit InteractiveManipulator(Audio &, const SoundBank &, Entity &);
void SetBlock(Chunk &, int, const Block &) override;
private:
Entity &player;
Audio &audio;
- Sound place_sound;
- Sound remove_sound;
+ const SoundBank &sounds;
};
#include "../app/FrameCounter.hpp"
#include "../app/init.hpp"
#include "../audio/Audio.hpp"
+#include "../audio/SoundBank.hpp"
#include "../graphics/Font.hpp"
#include "../graphics/Viewport.hpp"
#include "../io/TokenStreamReader.hpp"
}
-InteractiveManipulator::InteractiveManipulator(Environment &env, Entity &player)
+InteractiveManipulator::InteractiveManipulator(Audio &audio, const SoundBank &sounds, Entity &player)
: player(player)
-, audio(env.audio)
-, place_sound(env.loader.LoadSound("thump"))
-, remove_sound(env.loader.LoadSound("plop")) {
+, audio(audio)
+, sounds(sounds) {
}
void InteractiveManipulator::SetBlock(Chunk &chunk, int index, const Block &block) {
+ const BlockType &old_type = chunk.Type(index);
chunk.SetBlock(index, block);
+ const BlockType &new_type = chunk.Type(index);
glm::vec3 coords = chunk.ToSceneCoords(player.ChunkCoords(), Chunk::ToCoords(index));
- // TODO: get sound effect from block type
- if (block.type == 0) {
- audio.Play(remove_sound, coords);
+ if (new_type.id == 0) {
+ if (old_type.remove_sound >= 0) {
+ audio.Play(sounds[old_type.remove_sound], coords);
+ }
} else {
- audio.Play(place_sound, coords);
+ if (new_type.place_sound >= 0) {
+ audio.Play(sounds[new_type.place_sound], coords);
+ }
}
}
/// a string to display to the user
std::string label;
+ int place_sound;
+ int remove_sound;
+
Block::Type id;
/// light level that blocks of this type emit
, rgb_mod(1.0f, 1.0f, 1.0f)
, outline_color(-1, -1, -1)
, label("some block")
+, place_sound(-1)
+, remove_sound(-1)
, id(0)
, luminosity(0)
, visible(true)