From 7919f7f69b0abd54a6df92f34e1392b84dae3669 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Mon, 30 Sep 2019 15:13:37 -0400 Subject: created base audiosystem --- src/audio.cpp | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/audio.hpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 src/audio.cpp create mode 100644 src/audio.hpp (limited to 'src') diff --git a/src/audio.cpp b/src/audio.cpp new file mode 100644 index 0000000..7dec4c3 --- /dev/null +++ b/src/audio.cpp @@ -0,0 +1,51 @@ +/** + * @file audio.cpp + * Handles audio loading and playback + * + * Copyright (C) 2019 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "audio.hpp" + +AudioSystem::AudioSystem(void) : + device(nullptr, [](ALCdevice *d) { alcCloseDevice(d); }), + context(nullptr, [](ALCcontext *c) { alcDestroyContext(c); }) {} + +AudioSystem::~AudioSystem(void) +{ + // Delete context before device + context.get_deleter()(context.get()); +} + +void AudioSystem::configure([[maybe_unused]] entityx::EntityManager& entities, + [[maybe_unused]] entityx::EventManager& events) +{ + // Access device + device.reset(alcOpenDevice(nullptr)); + if (!device) + return; // TODO Uh oh + + // Create context + context.reset(alcCreateContext(device.get(), nullptr)); + if (!alcMakeContextCurrent(context.get())) + return; // TODO Another uh oh +} + +void AudioSystem::update([[maybe_unused]] entityx::EntityManager& entities, + [[maybe_unused]] entityx::EventManager& events, + [[maybe_unused]] entityx::TimeDelta dt) +{} + diff --git a/src/audio.hpp b/src/audio.hpp new file mode 100644 index 0000000..4d617c7 --- /dev/null +++ b/src/audio.hpp @@ -0,0 +1,52 @@ +/** + * @file audio.hpp + * Handles audio loading and playback + * + * Copyright (C) 2019 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef SYSTEM_AUDIO_HPP_ +#define SYSTEM_AUDIO_HPP_ + +#include <AL/alut.h> + +#include <entityx/entityx.h> + +class AudioSystem : public entityx::System<AudioSystem> +{ +private: + std::unique_ptr<ALCdevice, void (*)(ALCdevice *)> device; + std::unique_ptr<ALCcontext, void (*)(ALCcontext *)> context; + +public: + AudioSystem(void); + ~AudioSystem(void); + + /** + * Prepares the system for running. + */ + void configure(entityx::EntityManager& entities, + entityx::EventManager& events) final; + + /** + * Updates the render system. + */ + void update(entityx::EntityManager& entities, + entityx::EventManager& events, + entityx::TimeDelta dt) final; +}; + +#endif // SYSTEM_AUDIO_HPP_ + -- cgit v1.2.3 From bebc6e955114a0907c43df9a9c00f22b1f743446 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Mon, 30 Sep 2019 15:29:49 -0400 Subject: created Audio component --- src/audio.cpp | 18 ++++++++++++++++-- src/audio.hpp | 9 +++++++-- src/components/Audio.hpp | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 4 deletions(-) create mode 100644 src/components/Audio.hpp (limited to 'src') diff --git a/src/audio.cpp b/src/audio.cpp index 7dec4c3..975cfce 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -27,12 +27,16 @@ AudioSystem::AudioSystem(void) : AudioSystem::~AudioSystem(void) { // Delete context before device - context.get_deleter()(context.get()); + context.reset(); + device.reset(); } void AudioSystem::configure([[maybe_unused]] entityx::EntityManager& entities, - [[maybe_unused]] entityx::EventManager& events) + entityx::EventManager& events) { + events.subscribe<entityx::ComponentAddedEvent<Audio>>(*this); + events.subscribe<entityx::ComponentRemovedEvent<Audio>>(*this); + // Access device device.reset(alcOpenDevice(nullptr)); if (!device) @@ -49,3 +53,13 @@ void AudioSystem::update([[maybe_unused]] entityx::EntityManager& entities, [[maybe_unused]] entityx::TimeDelta dt) {} +void AudioSystem::receive(const entityx::ComponentAddedEvent<Audio>& cae) +{ + alGenSources(1, const_cast<ALuint*>(&cae.component->source)); +} + +void AudioSystem::receive(const entityx::ComponentRemovedEvent<Audio>& cae) +{ + alDeleteSources(1, &cae.component->source); +} + diff --git a/src/audio.hpp b/src/audio.hpp index 4d617c7..97fff99 100644 --- a/src/audio.hpp +++ b/src/audio.hpp @@ -21,10 +21,12 @@ #define SYSTEM_AUDIO_HPP_ #include <AL/alut.h> - #include <entityx/entityx.h> -class AudioSystem : public entityx::System<AudioSystem> +#include <components/Audio.hpp> + +class AudioSystem : public entityx::System<AudioSystem>, + public entityx::Receiver<AudioSystem> { private: std::unique_ptr<ALCdevice, void (*)(ALCdevice *)> device; @@ -46,6 +48,9 @@ public: void update(entityx::EntityManager& entities, entityx::EventManager& events, entityx::TimeDelta dt) final; + + void receive(const entityx::ComponentAddedEvent<Audio>& cae); + void receive(const entityx::ComponentRemovedEvent<Audio>& cae); }; #endif // SYSTEM_AUDIO_HPP_ diff --git a/src/components/Audio.hpp b/src/components/Audio.hpp new file mode 100644 index 0000000..3f7296d --- /dev/null +++ b/src/components/Audio.hpp @@ -0,0 +1,47 @@ +/** + * Copyright (C) 2019 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#ifndef COMPONENT_AUDIO_HPP_ +#define COMPONENT_AUDIO_HPP_ + +#include <AL/al.h> + +#include "Component.hpp" + +struct Audio : Component<Audio> +{ +public: + ALuint source; + + Audio(ALuint _source = 0) : + source(_source) {} + + Audio FromLua([[maybe_unused]] sol::object ref) + { + // TODO load from file name? + return *this; + } + + void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} + void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} + + std::string serializeName(void) const final { + return "Audio"; + } +}; + +#endif // COMPONENT_AUDIO_HPP_ + -- cgit v1.2.3 From af39f2e08b0503db723ae707a5c7278d8c85f812 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Tue, 1 Oct 2019 20:50:28 -0400 Subject: Audio component loading, getting ready to play --- Assets/jump.wav | Bin 0 -> 303194 bytes Scripts/init.lua | 3 +++ src/audio.cpp | 25 +++++++++++++++++++++++++ src/audio.hpp | 3 +++ src/components/Audio.hpp | 17 +++++++++++++---- src/engine.cpp | 2 ++ src/script.cpp | 10 ++++++++++ 7 files changed, 56 insertions(+), 4 deletions(-) create mode 100644 Assets/jump.wav (limited to 'src') diff --git a/Assets/jump.wav b/Assets/jump.wav new file mode 100644 index 0000000..1cd1681 Binary files /dev/null and b/Assets/jump.wav differ diff --git a/Scripts/init.lua b/Scripts/init.lua index ec9e350..ea5a833 100644 --- a/Scripts/init.lua +++ b/Scripts/init.lua @@ -37,6 +37,9 @@ player = { }, Physics = 0, Name = "bord", + Audio = { + file = "Assets/jump.wav" + }, hellotrue = true, hellofalse = false, Render = { diff --git a/src/audio.cpp b/src/audio.cpp index 975cfce..8bb1413 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -20,13 +20,19 @@ #include "audio.hpp" +#include <AL/alut.h> +#include <iostream> + AudioSystem::AudioSystem(void) : device(nullptr, [](ALCdevice *d) { alcCloseDevice(d); }), context(nullptr, [](ALCcontext *c) { alcDestroyContext(c); }) {} AudioSystem::~AudioSystem(void) { + alutExit(); + // Delete context before device + alcMakeContextCurrent(nullptr); context.reset(); device.reset(); } @@ -46,6 +52,9 @@ void AudioSystem::configure([[maybe_unused]] entityx::EntityManager& entities, context.reset(alcCreateContext(device.get(), nullptr)); if (!alcMakeContextCurrent(context.get())) return; // TODO Another uh oh + + if (alutInitWithoutContext(nullptr, nullptr) != AL_TRUE) + return; // TODO Third uh oh } void AudioSystem::update([[maybe_unused]] entityx::EntityManager& entities, @@ -56,10 +65,26 @@ void AudioSystem::update([[maybe_unused]] entityx::EntityManager& entities, void AudioSystem::receive(const entityx::ComponentAddedEvent<Audio>& cae) { alGenSources(1, const_cast<ALuint*>(&cae.component->source)); + //alGenBuffers(1, const_cast<ALuint*>(&cae.component->buffer)); + + if (auto buf = alutCreateBufferFromFile(cae.component->fileName.c_str()); + buf != AL_NONE) { + const_cast<Audio*>(cae.component.get())->buffer = buf; + alSourcei(cae.component->source, AL_BUFFER, buf); + + std::cout << "Loaded audio: " << cae.component->fileName << std::endl; + } } void AudioSystem::receive(const entityx::ComponentRemovedEvent<Audio>& cae) { + alDeleteBuffers(1, &cae.component->buffer); alDeleteSources(1, &cae.component->source); } +void AudioSystem::playSound(const Position& pos, const Audio& audio) +{ + alSource3f(audio.source, AL_POSITION, pos.x, pos.y, 0); + alSourcePlay(audio.source); +} + diff --git a/src/audio.hpp b/src/audio.hpp index 97fff99..7a2076a 100644 --- a/src/audio.hpp +++ b/src/audio.hpp @@ -24,6 +24,7 @@ #include <entityx/entityx.h> #include <components/Audio.hpp> +#include <components/Position.hpp> class AudioSystem : public entityx::System<AudioSystem>, public entityx::Receiver<AudioSystem> @@ -51,6 +52,8 @@ public: void receive(const entityx::ComponentAddedEvent<Audio>& cae); void receive(const entityx::ComponentRemovedEvent<Audio>& cae); + + void playSound(const Position& pos, const Audio& audio); }; #endif // SYSTEM_AUDIO_HPP_ diff --git a/src/components/Audio.hpp b/src/components/Audio.hpp index 3f7296d..a97b235 100644 --- a/src/components/Audio.hpp +++ b/src/components/Audio.hpp @@ -24,14 +24,23 @@ struct Audio : Component<Audio> { public: + std::string fileName; ALuint source; + ALuint buffer; - Audio(ALuint _source = 0) : - source(_source) {} + Audio(std::string _fileName = "") : + fileName(_fileName), source(0), buffer(0) {} - Audio FromLua([[maybe_unused]] sol::object ref) + Audio FromLua(sol::object ref) { - // TODO load from file name? + if (ref.get_type() == sol::type::table) { + sol::table tab = ref; + if (tab["file"] != nullptr) + this->fileName = tab["file"]; + } else { + throw std::string("Audio table not formatted properly"); + } + return *this; } diff --git a/src/engine.cpp b/src/engine.cpp index b1d9a56..3fc4fdd 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -19,6 +19,7 @@ * along with this program. If not, see <https://www.gnu.org/licenses/>. */ +#include "audio.hpp" #include "config.hpp" #include "engine.hpp" #include "gamestate.hpp" @@ -54,6 +55,7 @@ int Engine::init(void) systems.add<ScriptSystem>(entities, *(systems.system<WorldSystem>().get())); systems.add<PhysicsSystem>(); systems.add<TextSystem>(); + systems.add<AudioSystem>(); systems.configure(); // Load game script and entity data diff --git a/src/script.cpp b/src/script.cpp index 6cda627..20011b4 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -75,6 +75,7 @@ void ScriptSystem::doFile(void) /******************** * SCRIPT PARSING * ********************/ +#include <components/Audio.hpp> #include <components/EventListener.hpp> #include <components/Position.hpp> #include <components/Player.hpp> @@ -127,6 +128,10 @@ void ScriptSystem::scriptExport(void) sol::constructors<Physics(void), Physics()>(), "standing", &Physics::standing); + lua.new_usertype<Audio>("Audio", + sol::constructors<Audio(std::string)>(), + "file", &Audio::fileName); + lua.new_usertype<World>("World", sol::constructors<World(sol::object), World(void)>(), "Generate", &World::generate, @@ -173,6 +178,11 @@ sol::table ScriptSystem::spawn(sol::object param) e.assign<Name>(Name().FromLua(tab["Name"])).get(); } + if (tab["Audio"] != nullptr) { + (*toRet)["Audio"] = + e.assign<Audio>(Audio().FromLua(tab["Audio"])).get(); + } + if (tab["Render"] != nullptr) { if (!e.has_component<Position>()) // Position must exist for render (*toRet)["Position"] = e.assign<Position>().get(); -- cgit v1.2.3 From 9d79ba461a399ce5c211dc7ca2fc49b8934c1cd7 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Tue, 1 Oct 2019 20:57:25 -0400 Subject: sound on jump --- Scripts/init.lua | 1 + src/engine.cpp | 3 +++ 2 files changed, 4 insertions(+) (limited to 'src') diff --git a/Scripts/init.lua b/Scripts/init.lua index ea5a833..d09fb14 100644 --- a/Scripts/init.lua +++ b/Scripts/init.lua @@ -21,6 +21,7 @@ player = { end, JumpKeyPressed = function(self) if self.Physics.standing == true then + game.play(self.Position, self.Audio) self.Velocity.y = self.Velocity.y + 9 end end, diff --git a/src/engine.cpp b/src/engine.cpp index ed5ba07..c6bec27 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -66,6 +66,9 @@ int Engine::init(void) script->addToGameNamespace("puts", bindInstance(&TextSystem::put, systems.system<TextSystem>().get())); + script->addToGameNamespace("play", + bindInstance(&AudioSystem::playSound, + systems.system<AudioSystem>().get())); script->init(); -- cgit v1.2.3 From eed19ec73698c8180a51c33fa56c7cfe7c0e60f0 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Thu, 3 Oct 2019 10:24:01 -0400 Subject: positional audio working --- Assets/boing.wav | Bin 605018 -> 302628 bytes Assets/jump.wav | Bin 303194 -> 151716 bytes src/audio.cpp | 18 ++++++++++++++++-- src/engine.cpp | 1 + 4 files changed, 17 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/Assets/boing.wav b/Assets/boing.wav index a142197..088963d 100644 Binary files a/Assets/boing.wav and b/Assets/boing.wav differ diff --git a/Assets/jump.wav b/Assets/jump.wav index 1cd1681..b9849ab 100644 Binary files a/Assets/jump.wav and b/Assets/jump.wav differ diff --git a/src/audio.cpp b/src/audio.cpp index 8bb1413..2f14c97 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -19,6 +19,7 @@ */ #include "audio.hpp" +#include "components/Player.hpp" #include <AL/alut.h> #include <iostream> @@ -55,12 +56,25 @@ void AudioSystem::configure([[maybe_unused]] entityx::EntityManager& entities, if (alutInitWithoutContext(nullptr, nullptr) != AL_TRUE) return; // TODO Third uh oh + + ALfloat listenerOri[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }; + alListener3f(AL_POSITION, 0, 0, 0.0f); + alListener3f(AL_VELOCITY, 0, 0, 0); + alListenerfv(AL_ORIENTATION, listenerOri); } -void AudioSystem::update([[maybe_unused]] entityx::EntityManager& entities, +void AudioSystem::update(entityx::EntityManager& entities, [[maybe_unused]] entityx::EventManager& events, [[maybe_unused]] entityx::TimeDelta dt) -{} +{ + entities.each<Player, Position>( + []([[maybe_unused]] entityx::Entity e, + [[maybe_unused]] Player& p, + Position &pos) + { + alListener3f(AL_POSITION, pos.x, pos.y, 0.0f); + }); +} void AudioSystem::receive(const entityx::ComponentAddedEvent<Audio>& cae) { diff --git a/src/engine.cpp b/src/engine.cpp index c6bec27..dc0c481 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -120,6 +120,7 @@ void Engine::logicLoop(void) }); } + systems.update<AudioSystem>(dt); std::this_thread::yield(); } } -- cgit v1.2.3 From 52cfc041425a80ffd7ec63b3aaa94289ec61a977 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Thu, 3 Oct 2019 12:47:40 -0400 Subject: controlled sound fading --- src/audio.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/audio.cpp b/src/audio.cpp index 2f14c97..7a5934f 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -57,10 +57,13 @@ void AudioSystem::configure([[maybe_unused]] entityx::EntityManager& entities, if (alutInitWithoutContext(nullptr, nullptr) != AL_TRUE) return; // TODO Third uh oh + // Set up listener ALfloat listenerOri[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f }; alListener3f(AL_POSITION, 0, 0, 0.0f); alListener3f(AL_VELOCITY, 0, 0, 0); alListenerfv(AL_ORIENTATION, listenerOri); + + alDistanceModel(AL_LINEAR_DISTANCE); } void AudioSystem::update(entityx::EntityManager& entities, @@ -85,6 +88,9 @@ void AudioSystem::receive(const entityx::ComponentAddedEvent<Audio>& cae) buf != AL_NONE) { const_cast<Audio*>(cae.component.get())->buffer = buf; alSourcei(cae.component->source, AL_BUFFER, buf); + // TODO Do these values need to be scaled to the world or window? + alSourcef(cae.component->source, AL_MAX_DISTANCE, 25); + alSourcef(cae.component->source, AL_REFERENCE_DISTANCE, 2); std::cout << "Loaded audio: " << cae.component->fileName << std::endl; } -- cgit v1.2.3 From da0913771538fd9b1ca538615fd9aa0388608466 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Sat, 9 May 2020 09:42:18 -0400 Subject: Merge audio; handle mouse events --- Scripts/init.lua | 5 +++ src/components/EventListener.hpp | 5 ++- src/input.cpp | 83 ++++++++++++++++++++++++++++++++++++++++ src/input.hpp | 33 ++++++---------- src/player.cpp | 42 +++++++++----------- 5 files changed, 120 insertions(+), 48 deletions(-) create mode 100644 src/input.cpp (limited to 'src') diff --git a/Scripts/init.lua b/Scripts/init.lua index 572f722..66fbcb1 100644 --- a/Scripts/init.lua +++ b/Scripts/init.lua @@ -111,6 +111,11 @@ npc = { b = 1.0, strength = 0.5 }, + EventListeners = { + MousePressed = function(self, x, y, button) + self.Velocity.y = 3.0; + end + }, Idle = function(self) if (self.visibleTick == 0) then self.visibleTick = math.random(40, 60) diff --git a/src/components/EventListener.hpp b/src/components/EventListener.hpp index 77a004e..c39b6ad 100644 --- a/src/components/EventListener.hpp +++ b/src/components/EventListener.hpp @@ -42,10 +42,11 @@ public: return *this; } - void tryListener(const std::string& name, sol::table& self) + template<typename... Args> + void tryListener(const std::string& name, sol::table& self, Args... args) { if (listeners[name] == sol::type::function) - listeners[name](self); + listeners[name](self, args...); } void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} diff --git a/src/input.cpp b/src/input.cpp new file mode 100644 index 0000000..21959c1 --- /dev/null +++ b/src/input.cpp @@ -0,0 +1,83 @@ +/** + * @file input.cpp + * Handles user input received from SDL. + * + * Copyright (C) 2020 Clyne Sullivan + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. + */ + +#include "input.hpp" + +#include "components/EventListener.hpp" +#include "components/Script.hpp" + +InputSystem::InputSystem() : + isMouseDown(false) {} + +/** + * Prepares the system for running. + */ +void InputSystem::configure([[maybe_unused]] entityx::EntityManager& entities, + [[maybe_unused]] entityx::EventManager& events) {} + +/** + * Updates the system by checking for SDL events. + */ +void InputSystem::update(entityx::EntityManager& entities, + entityx::EventManager& events, + [[maybe_unused]] entityx::TimeDelta dt) +{ + for (SDL_Event event; SDL_PollEvent(&event);) { + switch (event.type) { + case SDL_KEYUP: + if (auto key = event.key; key.repeat == 0) + events.emit<KeyUpEvent>(key.keysym); + break; + case SDL_KEYDOWN: + if (auto key = event.key; key.repeat == 0) + events.emit<KeyDownEvent>(key.keysym); + break; + case SDL_MOUSEBUTTONDOWN: + if (!isMouseDown) { + isMouseDown = true; + entities.each<EventListener>( + [&event](entityx::Entity e, EventListener& el) { + el.tryListener("MousePressed", + e.component<Scripted>()->caller, + event.button.x, + event.button.y, + event.button.button); + }); + } + break; + case SDL_MOUSEBUTTONUP: + if (isMouseDown) { + isMouseDown = false; + entities.each<EventListener>( + [&event](entityx::Entity e, EventListener& el) { + el.tryListener("MouseReleased", + e.component<Scripted>()->caller, + event.button.x, + event.button.y, + event.button.button); + }); + } + break; + default: + break; + } + } +} + diff --git a/src/input.hpp b/src/input.hpp index fa92c39..6180388 100644 --- a/src/input.hpp +++ b/src/input.hpp @@ -1,5 +1,5 @@ /** - * @file window.hpp + * @file input.hpp * Handles user input received from SDL. * * Copyright (C) 2019 Clyne Sullivan @@ -56,34 +56,23 @@ struct KeyDownEvent { class InputSystem : public entityx::System<InputSystem> { public: + InputSystem(); + /** * Prepares the system for running. */ - void configure([[maybe_unused]] entityx::EntityManager& entities, - [[maybe_unused]] entityx::EventManager& events) final {} + void configure(entityx::EntityManager& entities, + entityx::EventManager& events) final; /** * Updates the system by checking for SDL events. */ - void update([[maybe_unused]] entityx::EntityManager& entities, - [[maybe_unused]] entityx::EventManager& events, - [[maybe_unused]] entityx::TimeDelta dt) final - { - for (SDL_Event event; SDL_PollEvent(&event);) { - switch (event.type) { - case SDL_KEYUP: - if (auto key = event.key; key.repeat == 0) - events.emit<KeyUpEvent>(key.keysym); - break; - case SDL_KEYDOWN: - if (auto key = event.key; key.repeat == 0) - events.emit<KeyDownEvent>(key.keysym); - break; - default: - break; - } - } - } + void update(entityx::EntityManager& entities, + entityx::EventManager& events, + entityx::TimeDelta dt) final; + +private: + bool isMouseDown; }; #endif // SYSTEM_INPUT_HPP_ diff --git a/src/player.cpp b/src/player.cpp index b914672..f40a1d1 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -54,26 +54,23 @@ void PlayerSystem::receive(const KeyDownEvent& kue) { if (player.valid()) { if (kue.sym == SDLK_a) { - entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, - EventListener& el) - { + entities.each<EventListener>( + [](entityx::Entity e, EventListener& el) { el.tryListener("MoveLeftPressed", e.component<Scripted>()->caller); - }); + }); } else if (kue.sym == SDLK_d) { - entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, - EventListener& el) - { + entities.each<EventListener>( + [](entityx::Entity e, EventListener& el) { el.tryListener("MoveRightPressed", e.component<Scripted>()->caller); - }); + }); } else if (kue.sym == SDLK_SPACE) { - entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, - EventListener& el) - { + entities.each<EventListener>( + [](entityx::Entity e, EventListener& el) { el.tryListener("JumpKeyPressed", e.component<Scripted>()->caller); - }); + }); } } } @@ -82,26 +79,23 @@ void PlayerSystem::receive(const KeyUpEvent& kue) { if (player.valid()) { if (kue.sym == SDLK_a) { - entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, - EventListener& el) - { + entities.each<EventListener>( + [](entityx::Entity e, EventListener& el) { el.tryListener("MoveLeftReleased", e.component<Scripted>()->caller); - }); + }); } else if (kue.sym == SDLK_d) { - entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, - EventListener& el) - { + entities.each<EventListener>( + [](entityx::Entity e, EventListener& el) { el.tryListener("MoveRightReleased", e.component<Scripted>()->caller); - }); + }); } else if (kue.sym == SDLK_SPACE) { - entities.each<EventListener>([&]([[maybe_unused]] entityx::Entity e, - EventListener& el) - { + entities.each<EventListener>( + [](entityx::Entity e, EventListener& el) { el.tryListener("JumpKeyReleased", e.component<Scripted>()->caller); - }); + }); } } } -- cgit v1.2.3 From bdc0e843a4762a1abddebc53d12a351debe8d457 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Fri, 19 Aug 2022 20:52:59 -0400 Subject: add cereal and entityx submodules; fix compile errors --- .gitmodules | 7 +++++++ Makefile | 15 ++++++++++----- lib/cereal | 1 + lib/entityx | 1 + lib/libentityx.a | Bin 414808 -> 945228 bytes src/components/Audio.hpp | 2 +- src/components/Component.hpp | 2 +- src/components/EventListener.hpp | 2 +- src/components/Light.hpp | 2 +- src/components/Name.hpp | 2 +- src/components/Physics.hpp | 2 +- src/components/Player.hpp | 2 +- src/components/Position.hpp | 2 +- src/components/Render.hpp | 2 +- src/components/Script.hpp | 2 +- src/components/Velocity.hpp | 2 +- src/gamestate.hpp | 26 +++++++++++++++++++++++++- 17 files changed, 55 insertions(+), 17 deletions(-) create mode 160000 lib/cereal create mode 160000 lib/entityx (limited to 'src') diff --git a/.gitmodules b/.gitmodules index 340f9cd..e2f5cf7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,10 @@ [submodule "lib/sol2"] path = lib/sol2 url = https://github.com/ThePhD/sol2 +[submodule "lib/entityx"] + path = lib/entityx + url = https://github.com/tcsullivan/entityx + branch = remove-std-iterator +[submodule "lib/cereal"] + path = lib/cereal + url = https://github.com/USCiLab/cereal diff --git a/Makefile b/Makefile index 357d7ff..23f522e 100644 --- a/Makefile +++ b/Makefile @@ -40,11 +40,16 @@ LIBS = -L$(LIBDIR) -lSDL2 -lpthread -lentityx -lluajit -ldl -lGLEW -lGL \ -lSDL2_image -lSOIL -lfreetype -lopenal -lalut CXXFLAGS = -ggdb -std=c++17 -Wall -Wextra -Werror -pedantic \ - -Wno-class-memaccess -Wno-implicit-fallthrough -m64 - -CXXINCS = -Isrc -I$(LIBDIR)/LuaJIT/src -I$(LIBDIR)/entityx \ - -I$(LIBDIR)/LuaBridge/Source -I$(LIBDIR)/sol2/include \ - -I$(LIBDIR)/soil -I$(LIBDIR)/cereal/include -I$(LIBDIR)/freetype + -Wno-class-memaccess -Wno-implicit-fallthrough -Wno-unused-parameter + +CXXINCS = -I$(SRCDIR) \ + -I$(LIBDIR)/entityx \ + -I$(LIBDIR)/LuaJIT/src \ + -I$(LIBDIR)/LuaBridge/Source \ + -I$(LIBDIR)/sol2/include \ + -I$(LIBDIR)/soil \ + -I$(LIBDIR)/cereal/include \ + -I$(LIBDIR)/freetype CXXSRC := $(shell find $(SRCDIR) -type f -name *.$(SRCEXT)) CXXOBJ := $(patsubst $(SRCDIR)/%,$(OUTDIR)/%,$(CXXSRC:.$(SRCEXT)=.$(OBJEXT))) diff --git a/lib/cereal b/lib/cereal new file mode 160000 index 0000000..ddd4672 --- /dev/null +++ b/lib/cereal @@ -0,0 +1 @@ +Subproject commit ddd467244713ea4fe63733628992efcdd6a9187d diff --git a/lib/entityx b/lib/entityx new file mode 160000 index 0000000..39e0709 --- /dev/null +++ b/lib/entityx @@ -0,0 +1 @@ +Subproject commit 39e07099da7227d7d7baec072411ddc0abfd8be4 diff --git a/lib/libentityx.a b/lib/libentityx.a index c1b2a0d..b0042eb 100644 Binary files a/lib/libentityx.a and b/lib/libentityx.a differ diff --git a/src/components/Audio.hpp b/src/components/Audio.hpp index a97b235..2bb63eb 100644 --- a/src/components/Audio.hpp +++ b/src/components/Audio.hpp @@ -47,7 +47,7 @@ public: void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Audio"; } }; diff --git a/src/components/Component.hpp b/src/components/Component.hpp index 2928366..576a059 100644 --- a/src/components/Component.hpp +++ b/src/components/Component.hpp @@ -33,7 +33,7 @@ public: virtual void serialize(cereal::JSONOutputArchive& ar) = 0; virtual void serialize(cereal::JSONInputArchive& ar) = 0; - void internal_serialize(bool save, void *ar) final { + virtual void internal_serialize(bool save, void *ar) final { if (save) serialize(*reinterpret_cast<cereal::JSONOutputArchive*>(ar)); else diff --git a/src/components/EventListener.hpp b/src/components/EventListener.hpp index c39b6ad..fb55d95 100644 --- a/src/components/EventListener.hpp +++ b/src/components/EventListener.hpp @@ -52,7 +52,7 @@ public: void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "EventListener"; } }; diff --git a/src/components/Light.hpp b/src/components/Light.hpp index 6849d7c..c63b6cc 100644 --- a/src/components/Light.hpp +++ b/src/components/Light.hpp @@ -58,7 +58,7 @@ public: ar(CEREAL_NVP(r), CEREAL_NVP(g), CEREAL_NVP(b), CEREAL_NVP(strength)); } - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Light"; } }; diff --git a/src/components/Name.hpp b/src/components/Name.hpp index a6a6d8a..6390d5e 100644 --- a/src/components/Name.hpp +++ b/src/components/Name.hpp @@ -47,7 +47,7 @@ public: ar(CEREAL_NVP(name)); } - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Name"; } }; diff --git a/src/components/Physics.hpp b/src/components/Physics.hpp index 378e87f..edf5ac5 100644 --- a/src/components/Physics.hpp +++ b/src/components/Physics.hpp @@ -33,7 +33,7 @@ public: void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Physics"; } }; diff --git a/src/components/Player.hpp b/src/components/Player.hpp index a550c4f..43d083e 100644 --- a/src/components/Player.hpp +++ b/src/components/Player.hpp @@ -36,7 +36,7 @@ public: void serialize([[maybe_unused]] cereal::JSONOutputArchive& ar) final {} void serialize([[maybe_unused]] cereal::JSONInputArchive& ar) final {} - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Player"; } }; diff --git a/src/components/Position.hpp b/src/components/Position.hpp index 56e8707..fcd62f8 100644 --- a/src/components/Position.hpp +++ b/src/components/Position.hpp @@ -51,7 +51,7 @@ public: ar(CEREAL_NVP(x), CEREAL_NVP(y)); } - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Position"; } }; diff --git a/src/components/Render.hpp b/src/components/Render.hpp index 81ca591..93be5d8 100644 --- a/src/components/Render.hpp +++ b/src/components/Render.hpp @@ -62,7 +62,7 @@ public: ar(CEREAL_NVP(visible), CEREAL_NVP(flipX)); } - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Render"; } }; diff --git a/src/components/Script.hpp b/src/components/Script.hpp index 3f96be5..d7bc147 100644 --- a/src/components/Script.hpp +++ b/src/components/Script.hpp @@ -119,7 +119,7 @@ public: } - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Scripted"; } }; diff --git a/src/components/Velocity.hpp b/src/components/Velocity.hpp index 776c1dd..f48a9f3 100644 --- a/src/components/Velocity.hpp +++ b/src/components/Velocity.hpp @@ -52,7 +52,7 @@ public: ar(CEREAL_NVP(x), CEREAL_NVP(y)); } - std::string serializeName(void) const final { + virtual std::string serializeName(void) const final { return "Velocity"; } }; diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 55f4e47..86a4198 100644 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -27,6 +27,30 @@ #include <fstream> +struct EntitySerializer +{ + template<class Archive> + static void serialize(entityx::EntityManager& entities, entityx::Entity entity, bool save, Archive& ar) + { + // TODO try and reimplement without modifying entityx? + // Or, make a new branch... + + //const auto mask = entity.component_mask(); + + //for (size_t i = 0; i < entities.component_helpers_.size(); i++) { + // auto helper = entities.component_helpers_[i]; + // if (helper && mask.test(i)) { + // auto* c = helper->get_component(entity); + // ar.setNextName(c->serializeName().c_str()); + // ar.startNode(); + // c->internal_serialize(save, static_cast<void*>(&ar)); + // ar.finishNode(); + // } + //} + } +}; + + /** * @class GameState * Manages save files that contain entity data. @@ -98,7 +122,7 @@ private: for (auto entity : entities.entities_for_debugging()) { archive.setNextName((name + std::to_string(i++)).c_str()); archive.startNode(); - entities.entity_serialize(entity, save, archive); + EntitySerializer::serialize(entities, entity, save, archive); archive.finishNode(); } } -- cgit v1.2.3 From 2364287a961fa9c860e1146bbcc3391ec5b1fd54 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Fri, 19 Aug 2022 20:53:21 -0400 Subject: add entityx config.h --- src/entityx/config.h | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/entityx/config.h (limited to 'src') diff --git a/src/entityx/config.h b/src/entityx/config.h new file mode 100644 index 0000000..630f8a8 --- /dev/null +++ b/src/entityx/config.h @@ -0,0 +1,11 @@ +#pragma once + +#include <cstdint> +#include <cstddef> + +namespace entityx { + +static const size_t MAX_COMPONENTS = 64; +typedef double TimeDelta; + +} // namespace entityx -- cgit v1.2.3 From ea719de76706140ce87f16fd9bde61c0e665d089 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan <clyne@bitgloo.com> Date: Sat, 20 Aug 2022 11:15:45 -0400 Subject: fix serialization support --- .gitmodules | 2 +- Makefile | 8 +++++--- lib/entityx | 2 +- lib/soil/Makefile | 4 ++++ src/components/Script.hpp | 2 +- src/gamestate.hpp | 32 +++++++------------------------- 6 files changed, 19 insertions(+), 31 deletions(-) create mode 100644 lib/soil/Makefile (limited to 'src') diff --git a/.gitmodules b/.gitmodules index 911085e..812302f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,7 +4,7 @@ [submodule "lib/entityx"] path = lib/entityx url = https://github.com/tcsullivan/entityx - branch = remove-std-iterator + branch = serialize [submodule "lib/cereal"] path = lib/cereal url = https://github.com/USCiLab/cereal diff --git a/Makefile b/Makefile index db7c130..cc46888 100644 --- a/Makefile +++ b/Makefile @@ -68,6 +68,8 @@ directories: clean: @echo " CLEAN" @$(RM) -rf $(OUTDIR) + +cleanall: clean @$(RM) -f lib/libentityx.a lib/libluajit.a lib/libsoil.a cleaner: clean @@ -96,8 +98,8 @@ lib/libluajit.a: @cp lib/luajit/src/libluajit.a lib/libluajit.a lib/libsoil.a: - @gcc -c lib/soil/soil/*.c - @ar rcs lib/libsoil.a lib/soil/soil/*.o + @make -Clib/soil -j4 + @cp lib/soil/libsoil.a lib/libsoil.a -.PHONY: all remake clean cleaner resources +.PHONY: all remake clean cleaner cleanall resources diff --git a/lib/entityx b/lib/entityx index 39e0709..e04b856 160000 --- a/lib/entityx +++ b/lib/entityx @@ -1 +1 @@ -Subproject commit 39e07099da7227d7d7baec072411ddc0abfd8be4 +Subproject commit e04b856006cfe6b7e8ba5d6c1434331351cc791a diff --git a/lib/soil/Makefile b/lib/soil/Makefile new file mode 100644 index 0000000..0b67b7c --- /dev/null +++ b/lib/soil/Makefile @@ -0,0 +1,4 @@ +all: + @gcc -c soil/*.c + @ar rcs libsoil.a *.o + diff --git a/src/components/Script.hpp b/src/components/Script.hpp index d7bc147..93997a9 100644 --- a/src/components/Script.hpp +++ b/src/components/Script.hpp @@ -74,7 +74,7 @@ public: else if (value.get_type() == sol::type::number) table_components.push_back(std::make_tuple( key.as<std::string>(), - std::string("return " + value.as<std::string>()) + std::string("return ") + std::to_string(value.as<double>()) )); else if (value.get_type() == sol::type::boolean) { table_components.push_back(std::make_tuple( diff --git a/src/gamestate.hpp b/src/gamestate.hpp index 86a4198..3ef641f 100644 --- a/src/gamestate.hpp +++ b/src/gamestate.hpp @@ -27,30 +27,6 @@ #include <fstream> -struct EntitySerializer -{ - template<class Archive> - static void serialize(entityx::EntityManager& entities, entityx::Entity entity, bool save, Archive& ar) - { - // TODO try and reimplement without modifying entityx? - // Or, make a new branch... - - //const auto mask = entity.component_mask(); - - //for (size_t i = 0; i < entities.component_helpers_.size(); i++) { - // auto helper = entities.component_helpers_[i]; - // if (helper && mask.test(i)) { - // auto* c = helper->get_component(entity); - // ar.setNextName(c->serializeName().c_str()); - // ar.startNode(); - // c->internal_serialize(save, static_cast<void*>(&ar)); - // ar.finishNode(); - // } - //} - } -}; - - /** * @class GameState * Manages save files that contain entity data. @@ -122,7 +98,13 @@ private: for (auto entity : entities.entities_for_debugging()) { archive.setNextName((name + std::to_string(i++)).c_str()); archive.startNode(); - EntitySerializer::serialize(entities, entity, save, archive); + entities.serialize(entity, + [&archive, &save](auto c) { + archive.setNextName(c->serializeName().c_str()); + archive.startNode(); + c->internal_serialize(save, static_cast<void*>(&archive)); + archive.finishNode(); + }); archive.finishNode(); } } -- cgit v1.2.3