refactor: JA_Sound_t RAII — buffer amb unique_ptr + SDLFreeDeleter, elimina JA_NewSound
This commit is contained in:
@@ -7,12 +7,22 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#define STB_VORBIS_HEADER_ONLY
|
||||
#include "external/stb_vorbis.h"
|
||||
|
||||
// Deleter stateless per a buffers reservats amb `SDL_malloc` / `SDL_LoadWAV*`.
|
||||
// Compatible amb `std::unique_ptr<Uint8[], SDLFreeDeleter>` — zero size
|
||||
// overhead gràcies a EBO, igual que un unique_ptr amb default_delete.
|
||||
struct SDLFreeDeleter {
|
||||
void operator()(Uint8* p) const noexcept {
|
||||
if (p) SDL_free(p);
|
||||
}
|
||||
};
|
||||
|
||||
// --- Public Enums ---
|
||||
enum JA_Channel_state {
|
||||
JA_CHANNEL_INVALID,
|
||||
@@ -36,7 +46,9 @@ enum JA_Music_state {
|
||||
struct JA_Sound_t {
|
||||
SDL_AudioSpec spec{SDL_AUDIO_S16, 2, 48000};
|
||||
Uint32 length{0};
|
||||
Uint8* buffer{nullptr};
|
||||
// Buffer descomprimit (PCM) propietat del sound. Reservat per SDL_LoadWAV
|
||||
// via SDL_malloc; el deleter `SDLFreeDeleter` allibera amb SDL_free.
|
||||
std::unique_ptr<Uint8[], SDLFreeDeleter> buffer;
|
||||
};
|
||||
|
||||
struct JA_Channel_t {
|
||||
@@ -172,7 +184,7 @@ inline void JA_Update() {
|
||||
if (channels[i].state == JA_CHANNEL_PLAYING) {
|
||||
if (channels[i].times != 0) {
|
||||
if ((Uint32)SDL_GetAudioStreamAvailable(channels[i].stream) < (channels[i].sound->length / 2)) {
|
||||
SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer, channels[i].sound->length);
|
||||
SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer.get(), channels[i].sound->length);
|
||||
if (channels[i].times > 0) channels[i].times--;
|
||||
}
|
||||
} else {
|
||||
@@ -355,31 +367,26 @@ inline void JA_EnableMusic(const bool value) {
|
||||
|
||||
// --- Sound Functions ---
|
||||
|
||||
inline JA_Sound_t* JA_NewSound(Uint8* buffer, Uint32 length) {
|
||||
JA_Sound_t* sound = new JA_Sound_t();
|
||||
sound->buffer = buffer;
|
||||
sound->length = length;
|
||||
return sound;
|
||||
}
|
||||
|
||||
inline JA_Sound_t* JA_LoadSound(uint8_t* buffer, uint32_t size) {
|
||||
JA_Sound_t* sound = new JA_Sound_t();
|
||||
if (!SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size), 1, &sound->spec, &sound->buffer, &sound->length)) {
|
||||
auto sound = std::make_unique<JA_Sound_t>();
|
||||
Uint8* raw = nullptr;
|
||||
if (!SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size), 1, &sound->spec, &raw, &sound->length)) {
|
||||
SDL_Log("Failed to load WAV from memory: %s", SDL_GetError());
|
||||
delete sound;
|
||||
return nullptr;
|
||||
}
|
||||
return sound;
|
||||
sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer
|
||||
return sound.release();
|
||||
}
|
||||
|
||||
inline JA_Sound_t* JA_LoadSound(const char* filename) {
|
||||
JA_Sound_t* sound = new JA_Sound_t();
|
||||
if (!SDL_LoadWAV(filename, &sound->spec, &sound->buffer, &sound->length)) {
|
||||
auto sound = std::make_unique<JA_Sound_t>();
|
||||
Uint8* raw = nullptr;
|
||||
if (!SDL_LoadWAV(filename, &sound->spec, &raw, &sound->length)) {
|
||||
SDL_Log("Failed to load WAV file: %s", SDL_GetError());
|
||||
delete sound;
|
||||
return nullptr;
|
||||
}
|
||||
return sound;
|
||||
sound->buffer.reset(raw); // adopta el SDL_malloc'd buffer
|
||||
return sound.release();
|
||||
}
|
||||
|
||||
inline int JA_PlaySound(JA_Sound_t* sound, const int loop = 0, const int group = 0) {
|
||||
@@ -411,7 +418,7 @@ inline int JA_PlaySoundOnChannel(JA_Sound_t* sound, const int channel, const int
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
|
||||
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer.get(), channels[channel].sound->length);
|
||||
SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume[group]);
|
||||
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
|
||||
|
||||
@@ -423,7 +430,7 @@ inline void JA_DeleteSound(JA_Sound_t* sound) {
|
||||
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
|
||||
if (channels[i].sound == sound) JA_StopChannel(i);
|
||||
}
|
||||
SDL_free(sound->buffer);
|
||||
// buffer es destrueix automàticament via RAII (SDLFreeDeleter).
|
||||
delete sound;
|
||||
}
|
||||
|
||||
|
||||
@@ -161,18 +161,31 @@ std::vector<char> file_readfile(const char* resourcename) {
|
||||
// Accepta rutes amb subdirectoris (ex: "jailgames/aee") i crea tota la jerarquia.
|
||||
void file_setconfigfolder(const char* foldername) {
|
||||
#ifdef _WIN32
|
||||
config_folder = std::string(getenv("APPDATA")) + "/" + foldername;
|
||||
const char* base = getenv("APPDATA");
|
||||
if (!base) base = "C:/";
|
||||
config_folder = std::string(base) + "/" + foldername;
|
||||
#elif __APPLE__
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
const char* homedir = pw->pw_dir;
|
||||
const char* homedir = (pw && pw->pw_dir) ? pw->pw_dir : nullptr;
|
||||
if (!homedir) homedir = getenv("HOME");
|
||||
if (!homedir) homedir = "/tmp";
|
||||
config_folder = std::string(homedir) + "/Library/Application Support/" + foldername;
|
||||
#elif __linux__
|
||||
// Nota emscripten: `__linux__` també està definit, però `getpwuid` no
|
||||
// troba cap /etc/passwd al MEMFS i retorna nullptr. Amb els fallbacks
|
||||
// HOME → /tmp evitem crashejar al primer arranque dins del navegador.
|
||||
// La config no persistirà entre recàrregues de la pàgina (MEMFS és
|
||||
// volàtil); caldria IDBFS si volguéssem persistència a web.
|
||||
struct passwd* pw = getpwuid(getuid());
|
||||
const char* homedir = pw->pw_dir;
|
||||
const char* homedir = (pw && pw->pw_dir) ? pw->pw_dir : nullptr;
|
||||
if (!homedir) homedir = getenv("HOME");
|
||||
if (!homedir) homedir = "/tmp";
|
||||
config_folder = std::string(homedir) + "/.config/" + foldername;
|
||||
#endif
|
||||
|
||||
std::filesystem::create_directories(config_folder);
|
||||
if (!config_folder.empty()) {
|
||||
std::filesystem::create_directories(config_folder);
|
||||
}
|
||||
}
|
||||
|
||||
const char* file_getconfigfolder() {
|
||||
|
||||
Reference in New Issue
Block a user