diff --git a/.gitignore b/.gitignore index b48a69e..1473a90 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ build/ /Debug-sanitize/ /Debug-GL/ + +assets/test_music.ogg + diff --git a/CMakeLists.txt b/CMakeLists.txt index 78a933c..f6a131c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -39,6 +39,10 @@ add_library(APG-d ${APG_SOURCES}) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS_BASE} ${APG_RELEASE_FLAGS}") add_library(APG ${APG_SOURCES}) +if ( EXISTS "assets/test_music.ogg" ) + add_definitions(-DAPG_GL_TEST_AUDIO) +endif ( EXISTS "assets/test_music.ogg" ) + if ( (NOT EXCLUDE_SDL_TEST) OR (NOT EXCLUDE_GL_TEST) ) file(MAKE_DIRECTORY assets) file(COPY ${APG_TEST_ASSETS} DESTINATION assets) diff --git a/include/APG/Audio.hpp b/include/APG/Audio.hpp index f84913c..172df24 100644 --- a/include/APG/Audio.hpp +++ b/include/APG/Audio.hpp @@ -39,10 +39,6 @@ namespace APG { -class SoundClip { - -}; - /** * Handles everything audio related in the engine. Loaded music and sounds will persist until the manager is destroyed; * if you're running into memory issues, you can delete sooner however. @@ -54,8 +50,8 @@ class SoundClip { */ class AudioManager { public: - using music_handle = uint32_t; - using sound_handle = uint32_t; + using music_handle = int32_t; + using sound_handle = int32_t; static_assert(std::is_copy_constructible(), "Music handle type must be copy constructible."); static_assert(std::is_copy_constructible(), "Sound handle type must be copy constructible."); @@ -76,8 +72,10 @@ class AudioManager { virtual music_handle loadMusicFile(const std::string &filename) = 0; virtual sound_handle loadSoundFile(const std::string &filename) = 0; - virtual void freeMusic(const music_handle &handle) = 0; - virtual void freeSound(const sound_handle &handle) = 0; + virtual void freeMusic(music_handle &handle) = 0; + virtual void freeSound(sound_handle &handle) = 0; + + virtual void playMusic(const music_handle &handle) = 0; }; } diff --git a/include/APG/SDLAudioManager.hpp b/include/APG/SDLAudioManager.hpp index 5be84ff..b699574 100644 --- a/include/APG/SDLAudioManager.hpp +++ b/include/APG/SDLAudioManager.hpp @@ -28,13 +28,20 @@ #ifndef INCLUDE_APG_SDLAUDIOMANAGER_HPP_ #define INCLUDE_APG_SDLAUDIOMANAGER_HPP_ +#include + #include +#include "APG/SXXDL.hpp" #include "APG/Audio.hpp" namespace APG { class SDLAudioManager: public AudioManager { +private: + std::unordered_map loadedMusic; + std::unordered_map loadedSounds; + public: explicit SDLAudioManager(int frequency = MIX_DEFAULT_FREQUENCY, uint16_t format = MIX_DEFAULT_FORMAT); virtual ~SDLAudioManager(); @@ -42,8 +49,10 @@ class SDLAudioManager: public AudioManager { virtual music_handle loadMusicFile(const std::string &filename) override; virtual sound_handle loadSoundFile(const std::string &filename) override; - virtual void freeMusic(const music_handle &handle) override; - virtual void freeSound(const sound_handle &handle) override; + virtual void freeMusic(music_handle &handle) override; + virtual void freeSound(sound_handle &handle) override; + + virtual void playMusic(const music_handle &handle) override; }; } diff --git a/include/APG/SXXDL.hpp b/include/APG/SXXDL.hpp index 81103ef..ab37229 100644 --- a/include/APG/SXXDL.hpp +++ b/include/APG/SXXDL.hpp @@ -24,8 +24,8 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef SXXDL_HPP_ -#define SXXDL_HPP_ +#ifndef SXXDL_INCLUDE_HPP_ +#define SXXDL_INCLUDE_HPP_ #include @@ -46,11 +46,12 @@ renderer_ptr make_renderer_ptr(SDL_Renderer *renderer); namespace mixer { -using sound_ptr = std::unique_ptr; + using music_ptr = std::unique_ptr; +using sound_ptr = std::unique_ptr; -sound_ptr make_sound_ptr(Mix_Chunk *chunk); music_ptr make_music_ptr(Mix_Music *music); +sound_ptr make_sound_ptr(Mix_Chunk *chunk); } diff --git a/include/test/APGGLRenderTest.hpp b/include/test/APGGLRenderTest.hpp index d14d04c..dc99997 100644 --- a/include/test/APGGLRenderTest.hpp +++ b/include/test/APGGLRenderTest.hpp @@ -67,6 +67,10 @@ class APGGLRenderTest final : public APG::SDLGame { std::vector playerFrames; std::unique_ptr playerAnimation; +#ifdef APG_GL_TEST_AUDIO + AudioManager::music_handle testHandle = -1; +#endif + public: explicit APGGLRenderTest(const std::string &windowTitle, uint32_t windowWidth, uint32_t windowHeight, uint32_t glContextMajor = 3, uint32_t glContextMinor = 2, uint32_t windowX = SDL_WINDOWPOS_CENTERED, uint32_t windowY = SDL_WINDOWPOS_CENTERED) : diff --git a/src/Audio.cpp b/src/Audio.cpp index 8623475..ecc5e1c 100644 --- a/src/Audio.cpp +++ b/src/Audio.cpp @@ -48,15 +48,15 @@ APG::AudioManager::music_handle APG::AudioManager::getNextMusicHandle() { APG::AudioManager::sound_handle APG::AudioManager::getNextSoundHandle() { const auto retval = availableSoundHandles.front(); availableSoundHandles.pop_front(); - return retval;; + return retval; } void APG::AudioManager::fillDefaultQueues() { - for(music_handle i = 0u; i < 256u; ++i) { + for(music_handle i = 0; i < 256; ++i) { availableMusicHandles.push_back(i); } - for(sound_handle i = 0u; i < 256u; ++i) { + for(sound_handle i = 0; i < 256; ++i) { availableSoundHandles.push_back(i); } } diff --git a/src/SDLAudioManager.cpp b/src/SDLAudioManager.cpp index 2b18db7..a47da43 100644 --- a/src/SDLAudioManager.cpp +++ b/src/SDLAudioManager.cpp @@ -47,11 +47,21 @@ APG::AudioManager::music_handle APG::SDLAudioManager::loadMusicFile(const std::s const auto logger = el::Loggers::getLogger("default"); logger->info("Loading music file \"%v\".", filename); - const auto handle = getNextMusicHandle(); + auto sdlMusic = SXXDL::mixer::make_music_ptr(Mix_LoadMUS(filename.c_str())); - // LOAD + if (sdlMusic == nullptr) { + logger->fatal("Couldn't load \"%v\", error: %v.", filename, Mix_GetError()); + return -1; + } else { + const auto handle = getNextMusicHandle(); + logger->info("Loaded \"%v\" at handle %v.", filename, handle); - return handle; + loadedMusic.emplace(handle, std::move(sdlMusic)); + + logger->verbose(9, "Total loaded music files: %v", loadedMusic.size()); + + return handle; + } } APG::AudioManager::sound_handle APG::SDLAudioManager::loadSoundFile(const std::string &filename) { @@ -65,10 +75,16 @@ APG::AudioManager::sound_handle APG::SDLAudioManager::loadSoundFile(const std::s return handle; } -void APG::SDLAudioManager::freeMusic(const music_handle &handle) { - // FREE +void APG::SDLAudioManager::freeMusic(music_handle &handle) { + loadedMusic.erase(handle); + handle = -1; +} + +void APG::SDLAudioManager::freeSound(sound_handle &handle) { + handle = -1; } -void APG::SDLAudioManager::freeSound(const sound_handle &handle) { - // FREE +void APG::SDLAudioManager::playMusic(const music_handle &handle) { + const auto &song = loadedMusic.find(handle); + Mix_PlayMusic((*song).second.get(), 0); } diff --git a/src/SDLGame.cpp b/src/SDLGame.cpp index 46892de..77d9fb1 100644 --- a/src/SDLGame.cpp +++ b/src/SDLGame.cpp @@ -76,14 +76,8 @@ APG::SDLGame::SDLGame(const std::string &windowTitle, uint32_t windowWidth, uint inputManager = std::make_unique(); audioManager = std::make_unique(); - const auto sdlWindow = SDL_CreateWindow(windowTitle.c_str(), windowX, windowY, windowWidth, windowHeight, - SDL_WINDOW_FLAGS); - - if (sdlWindow == nullptr) { - logger->fatal("Couldn't create window: %v", SDL_GetError()); - } - - window = SXXDL::make_window_ptr(sdlWindow); + window = SXXDL::make_window_ptr( + SDL_CreateWindow(windowTitle.c_str(), windowX, windowY, windowWidth, windowHeight, SDL_WINDOW_FLAGS)); if (window == nullptr) { logger->fatal("Couldn't create SDL window: %v", SDL_GetError()); @@ -98,12 +92,13 @@ APG::SDLGame::SDLGame(const std::string &windowTitle, uint32_t windowWidth, uint glewExperimental = GL_TRUE; glewInit(); - logger->verbose(9, "OpenGL errors have been reset (probably as a workaround for any bugs with glew)"); // reset all errors because some are caused by glew even upon successful setup. auto error = glGetError(); while (error != GL_NO_ERROR) { error = glGetError(); } + + logger->verbose(9, "OpenGL errors have been reset (probably as a workaround for any bugs with glew)"); } APG::SDLGame::~SDLGame() { diff --git a/src/SXXDL.cpp b/src/SXXDL.cpp index 5ab3a2a..9225b3e 100644 --- a/src/SXXDL.cpp +++ b/src/SXXDL.cpp @@ -25,6 +25,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include +#include + +#include "easylogging++.h" + #include "APG/SXXDL.hpp" SXXDL::window_ptr SXXDL::make_window_ptr(SDL_Window *window) { @@ -48,6 +53,8 @@ SXXDL::mixer::sound_ptr SXXDL::mixer::make_sound_ptr(Mix_Chunk *chunk) { } SXXDL::mixer::music_ptr SXXDL::mixer::make_music_ptr(Mix_Music *music) { +// el::Loggers::getLogger("default")->info("Creating music_ptr!"); +// return music_ptr(music, +// [](Mix_Music *music) {el::Loggers::getLogger("default")->info("Freeing music_ptr!"); Mix_FreeMusic(music);}); return music_ptr(music, Mix_FreeMusic); } - diff --git a/test/APGGLRenderTest.cpp b/test/APGGLRenderTest.cpp index 4e36044..9f7509a 100644 --- a/test/APGGLRenderTest.cpp +++ b/test/APGGLRenderTest.cpp @@ -86,6 +86,10 @@ bool APG::APGGLRenderTest::init() { return false; } +#ifdef APG_GL_TEST_AUDIO + logger->info("Note: audio test enabled. Use P and SPACE to test."); +#endif + return true; } @@ -120,6 +124,20 @@ void APG::APGGLRenderTest::render(float deltaTime) { playerX += 32.0f; } +#ifdef APG_GL_TEST_AUDIO + if(inputManager->isKeyJustPressed(SDL_SCANCODE_P)) { + if(testHandle == -1) { + testHandle = audioManager->loadMusicFile("assets/test_music.ogg"); + } else { + audioManager->freeMusic(testHandle); + } + } + + if (inputManager->isKeyJustPressed(SDL_SCANCODE_SPACE) && testHandle != -1) { + audioManager->playMusic(testHandle); + } +#endif + spriteBatch->begin(); spriteBatch->draw(playerAnimation.get(), playerX, playerY); spriteBatch->end(); @@ -159,7 +177,7 @@ int main(int argc, char *argv[]) { const float fps = 1 / (sum / timesTaken.size()); - el::Loggers::getLogger("default")->info("FPS: ", fps); + el::Loggers::getLogger("default")->info("FPS: %v", fps); timesTaken.clear(); }