Need the hit.wav to be mono, but now we have a sound we can move around, just not sure how to place it based on the visuals.

main
Zed A. Shaw 3 weeks ago
parent 9102bdc8ad
commit 4ed06b10b1
  1. BIN
      assets/hit.wav
  2. 8
      gui.cpp
  3. 4
      gui.hpp
  4. 3
      meson.build
  5. 70
      scratchpad/testragel.cpp
  6. 11
      scratchpad/testragel.rl
  7. 42
      sound.cpp
  8. 21
      sound.hpp
  9. 1
      status.txt
  10. 4
      systems.cpp
  11. 21
      tests/sound.cpp

Binary file not shown.

@ -62,9 +62,6 @@ GUI::GUI() :
{ {
$font.loadFromFile("./assets/text.otf"); $font.loadFromFile("./assets/text.otf");
resize_map(BASE_MAP_FONT_SIZE); 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.setFont($font);
$ui_text.setPosition(0,0); $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() { void GUI::shake() {
$hit_sound.play();
for(int i = 0; i < 10; ++i) { for(int i = 0; i < 10; ++i) {
int x = Random::uniform<int>(-10,10); int x = Random::uniform<int>(-10,10);
int y = Random::uniform<int>(-10,10); int y = Random::uniform<int>(-10,10);
@ -318,6 +314,10 @@ void GUI::render_scene() {
} }
int GUI::main() { int GUI::main() {
SoundManager sounds("./assets");
sounds.load("hit", "hit.wav");
$world.set<SoundManager>(sounds);
configure_world(); configure_world();
create_renderer(); create_renderer();
run_systems(); run_systems();

@ -1,5 +1,4 @@
#pragma once #pragma once
#include <SFML/Audio.hpp>
#include <SFML/Graphics/Color.hpp> #include <SFML/Graphics/Color.hpp>
#include <SFML/Graphics/Font.hpp> #include <SFML/Graphics/Font.hpp>
#include <SFML/Graphics/RenderWindow.hpp> #include <SFML/Graphics/RenderWindow.hpp>
@ -13,6 +12,7 @@
#include <string> #include <string>
#include "map.hpp" #include "map.hpp"
#include "dinkyecs.hpp" #include "dinkyecs.hpp"
#include "sound.hpp"
using std::string; using std::string;
using ftxui::Canvas, ftxui::Component, ftxui::Screen; using ftxui::Canvas, ftxui::Component, ftxui::Screen;
@ -37,8 +37,6 @@ enum class Value {
class GUI { class GUI {
Map $game_map; Map $game_map;
sf::SoundBuffer $hit_buf;
sf::Sound $hit_sound;
string $status_text = "NOT DEAD"; string $status_text = "NOT DEAD";
Component $document; Component $document;
Component $map_view; Component $map_view;

@ -17,11 +17,13 @@ runtests = executable('runtests', [
'dbc.cpp', 'dbc.cpp',
'map.cpp', 'map.cpp',
'rand.cpp', 'rand.cpp',
'sound.cpp',
'collider.cpp', 'collider.cpp',
'tests/fsm.cpp', 'tests/fsm.cpp',
'tests/dbc.cpp', 'tests/dbc.cpp',
'tests/map.cpp', 'tests/map.cpp',
'tests/collider.cpp', 'tests/collider.cpp',
'tests/sound.cpp',
], ],
dependencies: dependencies) dependencies: dependencies)
@ -31,6 +33,7 @@ roguish = executable('roguish', [
'map.cpp', 'map.cpp',
'gui.cpp', 'gui.cpp',
'rand.cpp', 'rand.cpp',
'sound.cpp',
'collider.cpp', 'collider.cpp',
'combat.cpp', 'combat.cpp',
'systems.cpp', 'systems.cpp',

@ -5,62 +5,68 @@
using namespace fmt; using namespace fmt;
#line 14 ".\\scratchpad\\testragel.rl" #line 11 ".\\scratchpad\\testragel.rl"
#line 8 ".\\scratchpad\\testragel.cpp" #line 8 ".\\scratchpad\\testragel.cpp"
static const char _foo_actions[] = { 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[] = { static const char _foo_key_offsets[] = {
0, 0, 1, 2, 4, 7, 9, 12, 0, 0, 1, 3, 5, 8, 10, 13,
13 14, 16, 19, 21, 24, 25
}; };
static const char _foo_trans_keys[] = { static const char _foo_trans_keys[] = {
27, 91, 48, 57, 59, 48, 57, 48, 27, 65, 91, 48, 57, 59, 48, 57,
57, 109, 48, 57, 0, 0 48, 57, 109, 48, 57, 0, 48, 57,
59, 48, 57, 48, 57, 109, 48, 57,
0, 0
}; };
static const char _foo_single_lengths[] = { static const char _foo_single_lengths[] = {
0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 2, 0, 1, 0, 1, 1,
0 0, 1, 0, 1, 1, 0
}; };
static const char _foo_range_lengths[] = { static const char _foo_range_lengths[] = {
0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0,
0 1, 1, 1, 1, 0, 0
}; };
static const char _foo_index_offsets[] = { static const char _foo_index_offsets[] = {
0, 0, 2, 4, 6, 9, 11, 14, 0, 0, 2, 5, 7, 10, 12, 15,
16 17, 19, 22, 24, 27, 29
}; };
static const char _foo_indicies[] = { static const char _foo_indicies[] = {
0, 1, 2, 1, 3, 1, 4, 3, 0, 1, 2, 3, 1, 4, 1, 5,
1, 5, 1, 6, 5, 1, 7, 1, 4, 1, 6, 1, 7, 6, 1, 8,
1, 0 1, 9, 1, 10, 9, 1, 11, 1,
12, 11, 1, 13, 1, 1, 0
}; };
static const char _foo_trans_targs[] = { 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[] = { 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_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_error = 0;
static const int foo_en_main = 1; static const int foo_en_main = 1;
#line 17 ".\\scratchpad\\testragel.rl" #line 14 ".\\scratchpad\\testragel.rl"
int main() { int main() {
int cs, res = 0; int cs, res = 0;
@ -69,14 +75,14 @@ int main() {
char *p = test; char *p = test;
char *pe = p + strlen(p) + 1; char *pe = p + strlen(p) + 1;
#line 64 ".\\scratchpad\\testragel.cpp" #line 70 ".\\scratchpad\\testragel.cpp"
{ {
cs = foo_start; 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; int _klen;
unsigned int _trans; unsigned int _trans;
@ -151,18 +157,30 @@ _match:
switch ( *_acts++ ) switch ( *_acts++ )
{ {
case 0: case 0:
#line 9 ".\\scratchpad\\testragel.rl" #line 7 ".\\scratchpad\\testragel.rl"
{ println("NUM1"); } { println("NUM1"); }
break; break;
case 1: case 1:
#line 11 ".\\scratchpad\\testragel.rl" #line 7 ".\\scratchpad\\testragel.rl"
{ println("NUM2"); } { println("NUM2"); }
break; break;
case 2: case 2:
#line 13 ".\\scratchpad\\testragel.rl" #line 7 ".\\scratchpad\\testragel.rl"
{ res = 1; } { res = 1; }
break; 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: {} _out: {}
} }
#line 26 ".\\scratchpad\\testragel.rl" #line 23 ".\\scratchpad\\testragel.rl"
fmt::println("result = {}", res); fmt::println("result = {}", res);
return 0; return 0;

@ -4,13 +4,10 @@ using namespace fmt;
%%{ %%{
machine foo; machine foo;
main := test1 = 0x1B . "[" . [0-9]+ @{ println("NUM1"); } . ";" . [0-9]+ @{ println("NUM2"); } . "m" 0 @{ res = 1; };
0x1B "[" test2 = 0x1B "A" [0-9]+ @{ println("NUM1"); } ";" [0-9]+ @{ println("NUM2"); } "m" 0 @{ res = 2; };
[0-9]+ @{ println("NUM1"); }
";" main := (test1 | test2);
[0-9]+ @{ println("NUM2"); }
"m"
0 @{ res = 1; };
}%% }%%
%% write data; %% write data;

@ -0,0 +1,42 @@
#include "sound.hpp"
#include "dbc.hpp"
#include <fmt/core.h>
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();
}

@ -0,0 +1,21 @@
#pragma once
#include <string>
#include <filesystem>
#include <unordered_map>
#include <SFML/Audio.hpp>
struct SoundPair {
sf::SoundBuffer buffer;
sf::Sound sound;
};
struct SoundManager {
std::filesystem::path $base_path;
std::unordered_map<std::string, SoundPair*> $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);
};

@ -14,5 +14,4 @@ TODO:
* Simple loot system. * Simple loot system.
* Actually render FTXUI ansi output instead of the gui.cpp hack. * 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. * Bring back sounds, check out SoLoud.

@ -4,6 +4,7 @@
#include <cmath> #include <cmath>
#include "rand.hpp" #include "rand.hpp"
#include "collider.hpp" #include "collider.hpp"
#include "sound.hpp"
using std::string; using std::string;
using namespace fmt; using namespace fmt;
@ -90,6 +91,7 @@ void System::combat(DinkyECS::World &world, Player &player) {
const auto& player_position = world.component<Position>(player.entity); const auto& player_position = world.component<Position>(player.entity);
auto& player_combat = world.component<Combat>(player.entity); auto& player_combat = world.component<Combat>(player.entity);
auto& log = world.get<ActionLog>(); auto& log = world.get<ActionLog>();
auto& sounds = world.get<SoundManager>();
// this is guaranteed to not return the given position // this is guaranteed to not return the given position
auto [found, nearby] = collider.neighbors(player_position.location); auto [found, nearby] = collider.neighbors(player_position.location);
@ -101,6 +103,7 @@ void System::combat(DinkyECS::World &world, Player &player) {
if(player_dmg > 0) { if(player_dmg > 0) {
log.log(format("You HIT for {} damage, HP left {}.", player_dmg, enemy_combat.hp)); log.log(format("You HIT for {} damage, HP left {}.", player_dmg, enemy_combat.hp));
sounds.play("hit");
} else { } else {
log.log("You missed! They're quick!"); 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); int enemy_dmg = enemy_combat.fight(player_combat);
if(enemy_dmg > 0) { if(enemy_dmg > 0) {
sounds.play("hit");
log.log(format("Enemy HIT YOU for {} damage.", enemy_dmg)); log.log(format("Enemy HIT YOU for {} damage.", enemy_dmg));
} else { } else {
log.log("Enemy MISSED, you dodged it."); log.log("Enemy MISSED, you dodged it.");

@ -0,0 +1,21 @@
#include <catch2/catch_test_macros.hpp>
#include <fmt/core.h>
#include <string>
#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);
}
Loading…
Cancel
Save