diff --git a/assets/hit.wav b/assets/hit.wav index e64c544..83af3f4 100644 Binary files a/assets/hit.wav and b/assets/hit.wav differ diff --git a/gui.cpp b/gui.cpp index dabd33e..0f44784 100644 --- a/gui.cpp +++ b/gui.cpp @@ -62,9 +62,6 @@ GUI::GUI() : { $font.loadFromFile("./assets/text.otf"); resize_map(BASE_MAP_FONT_SIZE); - int res = $hit_buf.loadFromFile("./assets/hit.wav"); - dbc::check(res, "failed to load hit.wav"); - $hit_sound.setBuffer($hit_buf); $ui_text.setFont($font); $ui_text.setPosition(0,0); @@ -261,7 +258,6 @@ void GUI::draw_screen(bool clear, float map_off_x, float map_off_y) { } void GUI::shake() { - $hit_sound.play(); for(int i = 0; i < 10; ++i) { int x = Random::uniform(-10,10); int y = Random::uniform(-10,10); @@ -318,6 +314,10 @@ void GUI::render_scene() { } int GUI::main() { + SoundManager sounds("./assets"); + sounds.load("hit", "hit.wav"); + $world.set(sounds); + configure_world(); create_renderer(); run_systems(); diff --git a/gui.hpp b/gui.hpp index a5458ba..d2a6462 100644 --- a/gui.hpp +++ b/gui.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include @@ -13,6 +12,7 @@ #include #include "map.hpp" #include "dinkyecs.hpp" +#include "sound.hpp" using std::string; using ftxui::Canvas, ftxui::Component, ftxui::Screen; @@ -37,8 +37,6 @@ enum class Value { class GUI { Map $game_map; - sf::SoundBuffer $hit_buf; - sf::Sound $hit_sound; string $status_text = "NOT DEAD"; Component $document; Component $map_view; diff --git a/meson.build b/meson.build index e8f3673..757fda3 100644 --- a/meson.build +++ b/meson.build @@ -17,11 +17,13 @@ runtests = executable('runtests', [ 'dbc.cpp', 'map.cpp', 'rand.cpp', + 'sound.cpp', 'collider.cpp', 'tests/fsm.cpp', 'tests/dbc.cpp', 'tests/map.cpp', 'tests/collider.cpp', + 'tests/sound.cpp', ], dependencies: dependencies) @@ -31,6 +33,7 @@ roguish = executable('roguish', [ 'map.cpp', 'gui.cpp', 'rand.cpp', + 'sound.cpp', 'collider.cpp', 'combat.cpp', 'systems.cpp', diff --git a/scratchpad/testragel.cpp b/scratchpad/testragel.cpp index a8c2947..4bab31b 100644 --- a/scratchpad/testragel.cpp +++ b/scratchpad/testragel.cpp @@ -5,62 +5,68 @@ using namespace fmt; -#line 14 ".\\scratchpad\\testragel.rl" +#line 11 ".\\scratchpad\\testragel.rl" #line 8 ".\\scratchpad\\testragel.cpp" static const char _foo_actions[] = { - 0, 1, 0, 1, 1, 1, 2 + 0, 1, 0, 1, 1, 1, 2, 1, + 3, 1, 4, 1, 5 }; static const char _foo_key_offsets[] = { - 0, 0, 1, 2, 4, 7, 9, 12, - 13 + 0, 0, 1, 3, 5, 8, 10, 13, + 14, 16, 19, 21, 24, 25 }; static const char _foo_trans_keys[] = { - 27, 91, 48, 57, 59, 48, 57, 48, - 57, 109, 48, 57, 0, 0 + 27, 65, 91, 48, 57, 59, 48, 57, + 48, 57, 109, 48, 57, 0, 48, 57, + 59, 48, 57, 48, 57, 109, 48, 57, + 0, 0 }; static const char _foo_single_lengths[] = { - 0, 1, 1, 0, 1, 0, 1, 1, - 0 + 0, 1, 2, 0, 1, 0, 1, 1, + 0, 1, 0, 1, 1, 0 }; static const char _foo_range_lengths[] = { 0, 0, 0, 1, 1, 1, 1, 0, - 0 + 1, 1, 1, 1, 0, 0 }; static const char _foo_index_offsets[] = { - 0, 0, 2, 4, 6, 9, 11, 14, - 16 + 0, 0, 2, 5, 7, 10, 12, 15, + 17, 19, 22, 24, 27, 29 }; static const char _foo_indicies[] = { - 0, 1, 2, 1, 3, 1, 4, 3, - 1, 5, 1, 6, 5, 1, 7, 1, - 1, 0 + 0, 1, 2, 3, 1, 4, 1, 5, + 4, 1, 6, 1, 7, 6, 1, 8, + 1, 9, 1, 10, 9, 1, 11, 1, + 12, 11, 1, 13, 1, 1, 0 }; static const char _foo_trans_targs[] = { - 2, 0, 3, 4, 5, 6, 7, 8 + 2, 0, 3, 8, 4, 5, 6, 7, + 13, 9, 10, 11, 12, 13 }; static const char _foo_trans_actions[] = { - 0, 0, 0, 1, 0, 3, 0, 5 + 0, 0, 0, 0, 7, 0, 9, 0, + 11, 1, 0, 3, 0, 5 }; static const int foo_start = 1; -static const int foo_first_final = 8; +static const int foo_first_final = 13; static const int foo_error = 0; static const int foo_en_main = 1; -#line 17 ".\\scratchpad\\testragel.rl" +#line 14 ".\\scratchpad\\testragel.rl" int main() { int cs, res = 0; @@ -69,14 +75,14 @@ int main() { char *p = test; char *pe = p + strlen(p) + 1; -#line 64 ".\\scratchpad\\testragel.cpp" +#line 70 ".\\scratchpad\\testragel.cpp" { cs = foo_start; } -#line 25 ".\\scratchpad\\testragel.rl" +#line 22 ".\\scratchpad\\testragel.rl" -#line 67 ".\\scratchpad\\testragel.cpp" +#line 73 ".\\scratchpad\\testragel.cpp" { int _klen; unsigned int _trans; @@ -151,18 +157,30 @@ _match: switch ( *_acts++ ) { case 0: -#line 9 ".\\scratchpad\\testragel.rl" +#line 7 ".\\scratchpad\\testragel.rl" { println("NUM1"); } break; case 1: -#line 11 ".\\scratchpad\\testragel.rl" +#line 7 ".\\scratchpad\\testragel.rl" { println("NUM2"); } break; case 2: -#line 13 ".\\scratchpad\\testragel.rl" +#line 7 ".\\scratchpad\\testragel.rl" { res = 1; } break; -#line 149 ".\\scratchpad\\testragel.cpp" + case 3: +#line 8 ".\\scratchpad\\testragel.rl" + { println("NUM1"); } + break; + case 4: +#line 8 ".\\scratchpad\\testragel.rl" + { println("NUM2"); } + break; + case 5: +#line 8 ".\\scratchpad\\testragel.rl" + { res = 2; } + break; +#line 164 ".\\scratchpad\\testragel.cpp" } } @@ -175,7 +193,7 @@ _again: _out: {} } -#line 26 ".\\scratchpad\\testragel.rl" +#line 23 ".\\scratchpad\\testragel.rl" fmt::println("result = {}", res); return 0; diff --git a/scratchpad/testragel.rl b/scratchpad/testragel.rl index f9f535b..6eafa6a 100644 --- a/scratchpad/testragel.rl +++ b/scratchpad/testragel.rl @@ -4,13 +4,10 @@ using namespace fmt; %%{ machine foo; - main := - 0x1B "[" - [0-9]+ @{ println("NUM1"); } - ";" - [0-9]+ @{ println("NUM2"); } - "m" - 0 @{ res = 1; }; + test1 = 0x1B . "[" . [0-9]+ @{ println("NUM1"); } . ";" . [0-9]+ @{ println("NUM2"); } . "m" 0 @{ res = 1; }; + test2 = 0x1B "A" [0-9]+ @{ println("NUM1"); } ";" [0-9]+ @{ println("NUM2"); } "m" 0 @{ res = 2; }; + + main := (test1 | test2); }%% %% write data; diff --git a/sound.cpp b/sound.cpp new file mode 100644 index 0000000..cf4531a --- /dev/null +++ b/sound.cpp @@ -0,0 +1,42 @@ +#include "sound.hpp" +#include "dbc.hpp" +#include + +using namespace fmt; +namespace fs = std::filesystem; + +SoundManager::SoundManager(std::string base_path) : $base_path(base_path) { + dbc::check(fs::exists($base_path), "sound asset path is missing"); +} + +void SoundManager::load(const std::string name, const std::string sound_path) { + // get the sound file with base_path + fs::path full_path = $base_path / sound_path; + // confirm it's there + dbc::check(fs::exists(full_path), format("sound file {} does not exist", sound_path)); + + // create the buffer and keep in the buffer map + SoundPair *pair = new SoundPair(); + $sounds[name] = pair; + + bool good = pair->buffer.loadFromFile(full_path.string()); + dbc::check(good, format("failed to load sound {}", sound_path)); + + // set it on the sound and keep in the sound map + pair->sound.setBuffer(pair->buffer); + pair->sound.setRelativeToListener(true); +} + +void SoundManager::play(const std::string name) { + dbc::check($sounds.contains(name), format("sound {} is not loaded in map", name)); + // get the sound from the sound map + SoundPair *pair = $sounds.at(name); + // play it + pair->sound.play(); +} + +void SoundManager::playAt(const std::string name, float x, float y, float z) { + SoundPair *pair = $sounds.at(name); + pair->sound.setPosition(x, y, z); + pair->sound.play(); +} diff --git a/sound.hpp b/sound.hpp new file mode 100644 index 0000000..2eb5f4e --- /dev/null +++ b/sound.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +#include +#include +#include + +struct SoundPair { + sf::SoundBuffer buffer; + sf::Sound sound; +}; + +struct SoundManager { + std::filesystem::path $base_path; + std::unordered_map $sounds; + + SoundManager(std::string base_path); + + void load(const std::string name, const std::string path); + void play(const std::string name); + void playAt(const std::string name, float x, float y, float z); +}; diff --git a/status.txt b/status.txt index 4e03869..09f4767 100644 --- a/status.txt +++ b/status.txt @@ -14,5 +14,4 @@ TODO: * Simple loot system. * Actually render FTXUI ansi output instead of the gui.cpp hack. -* Remove entity from world, _or_ mark them dead, switch their icon, and make them an entity the player walks over? * Bring back sounds, check out SoLoud. diff --git a/systems.cpp b/systems.cpp index bcc7a54..303fe3d 100644 --- a/systems.cpp +++ b/systems.cpp @@ -4,6 +4,7 @@ #include #include "rand.hpp" #include "collider.hpp" +#include "sound.hpp" using std::string; using namespace fmt; @@ -90,6 +91,7 @@ void System::combat(DinkyECS::World &world, Player &player) { const auto& player_position = world.component(player.entity); auto& player_combat = world.component(player.entity); auto& log = world.get(); + auto& sounds = world.get(); // this is guaranteed to not return the given position auto [found, nearby] = collider.neighbors(player_position.location); @@ -101,6 +103,7 @@ void System::combat(DinkyECS::World &world, Player &player) { if(player_dmg > 0) { log.log(format("You HIT for {} damage, HP left {}.", player_dmg, enemy_combat.hp)); + sounds.play("hit"); } else { log.log("You missed! They're quick!"); } @@ -109,6 +112,7 @@ void System::combat(DinkyECS::World &world, Player &player) { int enemy_dmg = enemy_combat.fight(player_combat); if(enemy_dmg > 0) { + sounds.play("hit"); log.log(format("Enemy HIT YOU for {} damage.", enemy_dmg)); } else { log.log("Enemy MISSED, you dodged it."); diff --git a/tests/sound.cpp b/tests/sound.cpp new file mode 100644 index 0000000..a39e4de --- /dev/null +++ b/tests/sound.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include "sound.hpp" +#include "dinkyecs.hpp" + +using DinkyECS::Entity; +using namespace fmt; + +TEST_CASE("confirm basic functionality", "[sounds]") { + REQUIRE_THROWS([&](){SoundManager sounds("./BADassets");}()); + + SoundManager sounds("./assets"); + + REQUIRE_THROWS(sounds.load("hit", "badfileDOESNOTEXIST.wav")); + REQUIRE_THROWS(sounds.play("hit")); + + sounds.load("hit", "hit.wav"); + sounds.play("hit"); + sounds.playAt("hit", 1, 1, 1); +}