Skip to content

Commit

Permalink
Automatic sound loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Matqyou committed Dec 6, 2024
1 parent 53f4d1e commit a68c093
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 93 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.idea
cmake-build-debug
cmake-build-release
40 changes: 39 additions & 1 deletion src/GameReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

#include "GameReference.h"
#include "client/Decals.h"
#include "game/entities/Crate.h"
#include "game/entities/item/weapons/EntityGuns.h"

GameReference::GameReference() {
m_Window = nullptr;
Expand Down Expand Up @@ -134,16 +136,52 @@ bool GameReference::Initialize() {

m_GLContext = SDL_GL_CreateContext(m_Window);

Decals::initialize(m_Renderer);
Decals::initialize(m_Renderer, m_InitializedAudio);

if (!m_Timer) m_Timer = new Clock(60);
if (!m_Random) m_Random = new Randomizer();
if (!m_Draw) m_Draw = new Drawing(this);
if (!m_AssetsHandler) m_AssetsHandler = new AssetsManager(m_Renderer, m_InitializedAudio);

m_GameWorld = new GameWorld(this, 50, 30);
m_Controllers = new GameControllers();

m_Draw->SetWorld(m_GameWorld);
Character::ms_BotNamePlate = new TextSurface(m_GameWorld->GameWindow()->Assets(),
m_GameWorld->GameWindow()->Assets()->TextHandler()->GetMainFont(),
"Bot User", { 255, 150, 150, 255 });
new Crate(m_GameWorld, Vec2d(200, 200), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(400, 200), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(600, 200), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(200, 400), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(400, 400), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(600, 400), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(200, 600), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(400, 600), DropType(rand() % 2));
new Crate(m_GameWorld, Vec2d(600, 600), DropType(rand() % 2));

new EntityGlock(m_GameWorld, nullptr, nullptr, Vec2d(800, 200));
new EntityShotgun(m_GameWorld, nullptr, nullptr, Vec2d(900, 200));
new EntityBurst(m_GameWorld, nullptr, nullptr, Vec2d(1000, 200));
new EntityMinigun(m_GameWorld, nullptr, nullptr, Vec2d(1100, 200));
new EntitySniper(m_GameWorld, nullptr, nullptr, Vec2d(1200, 200));


auto Player1 = new Player(m_GameWorld, "Keyboard");
auto Char1 = new Character(m_GameWorld,
Player1,
100.0,
Vec2d(32 * 17.5, 32 * 17.5),
Vec2d(10, 10));
Player1->GainXP(300);
// Char1->GiveWeapon(new WeaponGlock(nullptr));

return true;
}

void GameReference::Deinitialize(bool keep_sound) {
delete m_GameWorld;
delete m_Controllers;
Decals::deinitialize();
m_AssetsHandler->DeinitializeImages();
delete m_Draw;
Expand Down
7 changes: 7 additions & 0 deletions src/GameReference.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include "technical stuff/Drawing.h"
#include "technical stuff/Randomizer.h"
#include "technical stuff/AssetsManager.h"
#include "game/GameWorld.h"
#include "technical stuff/GameControllers.h"

class GameReference {
private:
Expand All @@ -23,6 +25,9 @@ class GameReference {
Randomizer* m_Random;
AssetsManager* m_AssetsHandler;

GameWorld* m_GameWorld;
GameControllers* m_Controllers;

int m_Width, m_Height;
double m_Width2, m_Height2;
bool m_InitializedSDL;
Expand Down Expand Up @@ -51,6 +56,8 @@ class GameReference {
[[nodiscard]] Randomizer* Random() const { return m_Random; }
[[nodiscard]] Drawing* Render() const { return m_Draw; }
[[nodiscard]] AssetsManager* Assets() const { return m_AssetsHandler; }
[[nodiscard]] GameWorld* World() const { return m_GameWorld; }
[[nodiscard]] GameControllers* Controllers() const { return m_Controllers; }
[[nodiscard]] int GetWidth() const { return m_Width; }
[[nodiscard]] int GetHeight() const { return m_Height; }
[[nodiscard]] double GetWidth2() const { return m_Width2; }
Expand Down
131 changes: 107 additions & 24 deletions src/client/Decals.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
Decals* Decals::Instance = nullptr;

Texture2::Texture2(std::string key, SDL_Texture* sdl_texture, std::string load_extension)
: m_Key(std::move(key)) {
: m_Key(std::move(key)),
m_LoadExtension(std::move(load_extension)) {
m_SDLTexture = sdl_texture;
m_LoadExtension = std::move(load_extension);

m_Information = {};
SDL_QueryTexture(m_SDLTexture,
Expand All @@ -43,16 +43,34 @@ void Texture2::SetAlphaMod(int alpha) {
SDL_SetTextureAlphaMod(m_SDLTexture, alpha);
}

Decals::Decals(SDL_Renderer* renderer): m_InvalidTexture(nullptr)
Sound2::Sound2(std::string key, Mix_Chunk* mix_chunk, std::string load_extension)
: m_Key(std::move(key)),
m_LoadExtension(std::move(load_extension)) {
m_MixChunk = mix_chunk;
}

Sound2::~Sound2() {
if (m_MixChunk)
Mix_FreeChunk(m_MixChunk);
}

void Sound2::SetVolume(int volume) {
Mix_VolumeChunk(m_MixChunk, volume);
}

void Sound2::PlaySound()
{
// Todo: Loading assets in realtime (adding/removing files?)
// Load assets (decals specifically)
const char* ASSETS_DIRECTORY = R"(.\assets\images\)";
std::unordered_set<std::string> supportedExtensions = {
".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tif", ".tiff", ".webp"
};
if (m_MixChunk == nullptr || !Decals::Get()->SoundsEnabled())
return;

for (const auto& entry : std::filesystem::recursive_directory_iterator(ASSETS_DIRECTORY)) {
Mix_PlayChannel(-1, m_MixChunk, 0);
}

std::vector<std::tuple<std::string, std::string, std::string>> GetResourceKeys(const char* directory,
const std::unordered_set<std::string>& supported_extensions) {
std::vector<std::tuple<std::string, std::string, std::string>> results;

for (const auto& entry : std::filesystem::recursive_directory_iterator(directory)) {
if (!entry.is_regular_file())
continue;

Expand All @@ -64,61 +82,117 @@ Decals::Decals(SDL_Renderer* renderer): m_InvalidTexture(nullptr)
std::transform(extension_lower.begin(), extension_lower.end(), extension_lower.begin(), ::tolower);

// Check if the extension is supported
if (supportedExtensions.find(extension) == supportedExtensions.end()) {
if (supported_extensions.find(extension) == supported_extensions.end()) {
std::cout << "Unsupported texture format: " << file_path.string() << std::endl;
continue;
}

// Process the path string for logging or other use
std::string identificator = file_path.string();
identificator = ErasePrefix(identificator, ASSETS_DIRECTORY);
identificator = ErasePrefix(identificator, directory);
identificator = EraseSuffix(identificator, extension);

// Convert to lowercase and replace slashes to periods
std::transform(identificator.begin(), identificator.end(), identificator.begin(), ::tolower);
std::replace(identificator.begin(), identificator.end(), '/', '.');
std::replace(identificator.begin(), identificator.end(), '\\', '.');

auto it = m_Textures.find(identificator);
// Add the key and path to the results
results.emplace_back(identificator, file_path.string(), extension);
}

return results;
}

Decals::Decals(SDL_Renderer* renderer, bool sounds_enabled)
: m_InvalidTexture(nullptr) {
m_SoundsEnabled = sounds_enabled;

// Todo: Loading assets in realtime (adding/removing files?)
// Load assets (decals specifically)
std::unordered_set<std::string> texture_extensions = {
".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tif", ".tiff", ".webp"
};
auto texture_keys = GetResourceKeys(R"(.\assets\images\)", texture_extensions);
for (auto entry : texture_keys) {
std::string& key = std::get<0>(entry);
std::string& file_path = std::get<1>(entry);
std::string& extension = std::get<2>(entry);

auto it = m_Textures.find(key);
if (it != m_Textures.end()) {
std::cout << FString("Attempted to load duplicate texture '%s' (%s)", identificator.c_str(), it->second->m_LoadExtension.c_str()) << std::endl;
std::cout << FString("Attempted to load duplicate texture '%s' (%s)", key.c_str(), it->second->m_LoadExtension.c_str()) << std::endl;
continue;
}

// Load the texture
SDL_Surface* TempSurface = IMG_Load(file_path.string().c_str());
SDL_Surface* TempSurface = IMG_Load(file_path.c_str());
if (!TempSurface) {
std::cout << FString("Failed to load texture '%s'", file_path.string().c_str()) << std::endl;
std::cout << FString("Failed to load texture '%s'", file_path.c_str()) << std::endl;
continue;
}

SDL_Texture* NewSDLTexture = SDL_CreateTextureFromSurface(renderer, TempSurface);
SDL_FreeSurface(TempSurface);

// Add it to all the textures
auto new_texture = new Texture2(identificator, NewSDLTexture, extension_lower);
m_Textures[identificator] = new_texture;
auto new_texture = new Texture2(key, NewSDLTexture, extension);
m_Textures[key] = new_texture;
}

std::cout << FString("Loaded %i textures", m_Textures.size()) << std::endl;
m_InvalidTexture = nullptr;
m_InvalidTexture = GetTexture("invalid");

std::unordered_set<std::string> sound_extensions = {
".wav", ".aiff", ".voc", ".mp3", ".ogg", ".flac",
".mod", ".s3m", ".it", ".xm", ".mid", ".midi", ".opus"
};
auto sound_keys = GetResourceKeys(R"(.\assets\sounds\)", sound_extensions);
for (auto entry : sound_keys) {
std::string& key = std::get<0>(entry);
std::string& file_path = std::get<1>(entry);
std::string& extension = std::get<2>(entry);

auto it = m_Sounds.find(key);
if (it != m_Sounds.end()) {
std::cout << FString("Attempted to load duplicate sound '%s' (%s)", key.c_str(), it->second->m_LoadExtension.c_str()) << std::endl;
continue;
}

// Load the sound
Mix_Chunk* NewMixChunk = Mix_LoadWAV(file_path.c_str());
if (!NewMixChunk) {
std::cout << FString("Failed to load sound '%s'", file_path.c_str()) << std::endl;
continue;
}

// Add it to all the textures
auto new_sound = new Sound2(key, NewMixChunk, extension);
m_Sounds[key] = new_sound;
}
std::cout << FString("Loaded %i sounds", m_Sounds.size()) << std::endl;
}

Decals::~Decals()
{
size_t num_destroyed = 0;
size_t destroyed_textures = 0;
size_t destroyed_sounds = 0;
for (const auto& entry : m_Textures) {
delete entry.second;
num_destroyed++;
destroyed_textures++;
}
for (const auto& entry : m_Sounds) {
delete entry.second;
destroyed_sounds++;
}
std::cout << FString("Unloaded %zu textures", num_destroyed) << std::endl;
std::cout << FString("Unloaded %zu textures", destroyed_textures) << std::endl;
std::cout << FString("Unloaded %zu sounds", destroyed_sounds) << std::endl;
}

void Decals::initialize(SDL_Renderer* renderer)
void Decals::initialize(SDL_Renderer* renderer, bool sounds_enabled)
{
if (Instance == nullptr)
Instance = new Decals(renderer);
Instance = new Decals(renderer, sounds_enabled);
}

void Decals::deinitialize()
Expand All @@ -143,3 +217,12 @@ Texture2* Decals::GetTexture(const std::string& texture_key) {
std::cout << FString("Texture '%s' not found", texture_key.c_str()) << std::endl;
return m_InvalidTexture;
}

Sound2* Decals::GetSound(const std::string& sound_key) {
auto it = m_Sounds.find(sound_key);
if (it != m_Sounds.end())
return it->second;

std::cout << FString("Sound '%s' not found", sound_key.c_str()) << std::endl;
return nullptr;
}
32 changes: 28 additions & 4 deletions src/client/Decals.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <vector>
#include <unordered_map>
#include "SDL_image.h"
#include "SDL_mixer.h"


struct TextureInfo2 {
Expand All @@ -27,7 +28,7 @@ class Texture2 {
std::string m_LoadExtension;

public:
explicit Texture2(std::string key = "NaN",SDL_Texture* sdl_texture = nullptr, std::string load_extension = "NaN");
explicit Texture2(std::string key = "NaN", SDL_Texture* sdl_texture = nullptr, std::string load_extension = "NaN");
~Texture2();

// Getting
Expand All @@ -43,14 +44,35 @@ class Texture2 {
void SetAlphaMod(int alpha);
};

class Sound2 {
private:
friend class Decals;
const std::string m_Key;
Mix_Chunk* m_MixChunk;
std::string m_LoadExtension;

public:
explicit Sound2(std::string key = "NaN", Mix_Chunk* mix_chunk = nullptr, std::string load_extension = "NaN");
~Sound2();

// Getting
[[nodiscard]] Mix_Chunk* MixChunk() const { return m_MixChunk; }

// Manipulating
void SetVolume(int volume);
void PlaySound();
};

class Decals {
static Decals* Instance;
bool m_SoundsEnabled;
std::unordered_map<std::string, Texture2*> m_Textures;
std::vector<Texture2> m_UsedTextures;
std::unordered_map<std::string, Sound2*> m_Sounds;
// std::vector<Texture2> m_UsedTextures;
Texture2* m_InvalidTexture;

public:
static void initialize(SDL_Renderer* renderer);
static void initialize(SDL_Renderer* renderer, bool sounds_enabled);
static void deinitialize();
static Decals* Get();

Expand All @@ -59,9 +81,11 @@ class Decals {

// Copying textures
Texture2* GetTexture(const std::string& texture_key);
Sound2* GetSound(const std::string& sound_key);
bool SoundsEnabled() const { return m_SoundsEnabled; }

private:
Decals(SDL_Renderer* renderer);
Decals(SDL_Renderer* renderer, bool sounds_enabled);
~Decals();

};
2 changes: 2 additions & 0 deletions src/game/interface/LevelUpMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ void LevelUpMenu::HandleEvent(const SDL_Event &event)
{
case SDL_QUIT:
m_GameWindow->Deinitialize(true);
while (Mix_Playing(-1)) {} // wait until last sound is done playing
delete m_GameWindow;
break;
case SDL_MOUSEBUTTONDOWN:
if (event.button.button == SDL_BUTTON_LEFT)
Expand Down
10 changes: 5 additions & 5 deletions src/game/interface/MainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ void MainMenu::HandleEvent(const SDL_Event &event, bool &running, bool &menuOpen
switch (event.type)
{
case SDL_QUIT:
menuOpen = false;
running = false;
m_GameWindow->Deinitialize(true);
m_GameWindow->Deinitialize(true); // close everything except sound
while (Mix_Playing(-1)) {} // wait until last sound is done playing
delete m_GameWindow;
break;
case SDL_MOUSEBUTTONDOWN:
SDL_SetCursor(SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_ARROW));
Expand All @@ -71,8 +71,8 @@ void MainMenu::HandleEvent(const SDL_Event &event, bool &running, bool &menuOpen
{
soundHandler->PlaySound(quitSound);
m_GameWindow->Deinitialize(true);
running = false;
menuOpen = false;
while (Mix_Playing(-1)) {} // wait until last sound is done playing
delete m_GameWindow;
}
}
break;
Expand Down
Loading

0 comments on commit a68c093

Please sign in to comment.