- Preparant la nova API

This commit is contained in:
2025-06-30 14:03:42 +02:00
parent becc33b88c
commit 28f4da9b26
16 changed files with 601 additions and 607 deletions

View File

@@ -25,7 +25,7 @@ namespace gamestate
menu::fondo = draw::loadSurface("menuprin.gif", true);
menu::cursor = draw::loadSurface("cursor.gif");
JA_LoadAndPlayMusic("mus3.ogg");
audio::loadAndPlayMusic("mus3.ogg");
font::selectFont(font::type::colored);
font::setColor(font::color::white);

View File

@@ -24,7 +24,7 @@ namespace gamestate
fondo = draw::loadSurface("mort.gif", true);
cursor = draw::loadSurface("cursor.gif");
JA_LoadAndPlayMusic("mus5.ogg");
audio::loadAndPlayMusic("mus5.ogg");
draw::fadein();

View File

@@ -72,7 +72,7 @@ namespace gamestate
// arounder_seleccionat = primerArounders
// Enxufa el arradio
JA_LoadAndPlayMusic((game::getConfig("fase")+1) % 5 == 0 ? "mus6.ogg" : "mus4.ogg");
audio::loadAndPlayMusic((game::getConfig("fase")+1) % 5 == 0 ? "mus6.ogg" : "mus4.ogg");
// Fiquem a contar el cronómetre de arounders
play::arounderCount = play::startTicks = game::getTicks();
@@ -224,11 +224,11 @@ namespace gamestate
if (mapa::arounders::arrivats >= mapa::arounders::necessaris) {
game::setConfig("fase", game::getConfig("fase")+1);
draw::fadeout();
JA_FadeOutMusic(250);
audio::fadeOutMusic();
play::exit = 1;
} else {
draw::fadeout();
JA_FadeOutMusic(250);
audio::fadeOutMusic();
play::exit = 2;
}
}
@@ -286,13 +286,13 @@ namespace gamestate
if (input::mouseY() >= 71 && input::mouseY() <= 76) {
free(play::original_palette);
draw::fadeout();
JA_FadeOutMusic(250);
audio::fadeOutMusic();
play::exit = 1;
}
if (input::mouseY() >= 82 && input::mouseY() <= 87) {
free(play::original_palette);
draw::fadeout();
JA_FadeOutMusic(250);
audio::fadeOutMusic();
play::exit = 2;
}
if (input::mouseY() >= 93 && input::mouseY() <= 98) {

View File

@@ -31,7 +31,7 @@ namespace gamestate
gamestate::sequence::init();
return;
} else {
JA_LoadAndPlayMusic("mus3.ogg");
audio::loadAndPlayMusic("mus3.ogg");
}
if (game::getConfig("fase") % 5 == 0) {

View File

@@ -99,14 +99,14 @@ namespace gamestate
} else if (command=="PLAYMUSIC") {
fscanf(sequence_file, " '%[^']'", text);
JA_LoadAndPlayMusic(text);
audio::loadAndPlayMusic(text);
} else if (command=="FADEOUT") {
draw::fadeout();
} else if (command=="FADEOUTMUSIC") {
draw::fadeout();
JA_FadeOutMusic(250);
audio::fadeOutMusic();
} else if (command=="END") {
fclose(sequence_file);
@@ -125,7 +125,7 @@ namespace gamestate
void drawPic(std::string filename)
{
draw::surface *pic = draw::loadSurface(filename, true);
draw::surface *pic = draw::loadSurface(filename.c_str(), true);
draw::draw(pic);
draw::freeSurface(pic);
}

View File

@@ -1,509 +0,0 @@
#ifndef JA_USESDLMIXER
#include "jail_audio.h"
#include "jfile.h"
#include "stb_vorbis.h"
#include <SDL3/SDL.h>
#include <stdio.h>
#define JA_MAX_SIMULTANEOUS_CHANNELS 5
struct JA_Sound_t
{
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
Uint32 length { 0 };
Uint8 *buffer { NULL };
};
struct JA_Channel_t
{
JA_Sound_t *sound { nullptr };
int pos { 0 };
int times { 0 };
SDL_AudioStream *stream { nullptr };
JA_Channel_state state { JA_CHANNEL_FREE };
};
struct JA_Music_t
{
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
Uint32 length { 0 };
Uint8 *buffer { nullptr };
char *filename { nullptr };
int pos { 0 };
int times { 0 };
SDL_AudioStream *stream { nullptr };
JA_Music_state state { JA_MUSIC_INVALID };
};
JA_Music_t *current_music { nullptr };
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
SDL_AudioSpec JA_audioSpec { SDL_AUDIO_S16, 2, 48000 };
float JA_musicVolume { 1.0f };
float JA_soundVolume { 0.5f };
bool JA_musicEnabled { true };
bool JA_soundEnabled { true };
SDL_AudioDeviceID sdlAudioDevice { 0 };
SDL_TimerID JA_timerID { 0 };
bool fading = false;
int fade_start_time;
int fade_duration;
int fade_initial_volume;
/*
void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, current_music->samples*2-current_music->pos);
SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_musicVolume);
current_music->pos += size/2;
if (size < len) {
if (current_music->times != 0) {
SDL_MixAudioFormat(stream+size, (Uint8*)current_music->output, AUDIO_S16, len-size, JA_musicVolume);
current_music->pos = (len-size)/2;
if (current_music->times > 0) current_music->times--;
} else {
current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED;
}
}
}
// Mixar els channels mi amol
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state == JA_CHANNEL_PLAYING) {
const int size = SDL_min(len, channels[i].sound->length - channels[i].pos);
SDL_MixAudioFormat(stream, channels[i].sound->buffer + channels[i].pos, AUDIO_S16, size, JA_soundVolume);
channels[i].pos += size;
if (size < len) {
if (channels[i].times != 0) {
SDL_MixAudioFormat(stream + size, channels[i].sound->buffer, AUDIO_S16, len-size, JA_soundVolume);
channels[i].pos = len-size;
if (channels[i].times > 0) channels[i].times--;
} else {
JA_StopChannel(i);
}
}
}
}
}
*/
Uint32 JA_UpdateCallback(void *userdata, SDL_TimerID timerID, Uint32 interval)
{
if (JA_musicEnabled && current_music && current_music->state == JA_MUSIC_PLAYING)
{
if (fading) {
int time = SDL_GetTicks();
if (time > (fade_start_time+fade_duration)) {
fading = false;
JA_StopMusic();
return 30;
} else {
const int time_passed = time - fade_start_time;
const float percent = (float)time_passed / (float)fade_duration;
SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume*(1.0 - percent));
}
}
if (current_music->times != 0)
{
if (SDL_GetAudioStreamAvailable(current_music->stream) < (current_music->length/2)) {
SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length);
}
if (current_music->times>0) current_music->times--;
}
else
{
if (SDL_GetAudioStreamAvailable(current_music->stream) == 0) JA_StopMusic();
}
}
if (JA_soundEnabled)
{
for (int i=0; i < JA_MAX_SIMULTANEOUS_CHANNELS; ++i)
if (channels[i].state == JA_CHANNEL_PLAYING)
{
if (channels[i].times != 0)
{
if (SDL_GetAudioStreamAvailable(channels[i].stream) < (channels[i].sound->length/2)) {
SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer, channels[i].sound->length);
if (channels[i].times>0) channels[i].times--;
}
}
else
{
if (SDL_GetAudioStreamAvailable(channels[i].stream) == 0) JA_StopChannel(i);
}
}
}
return 30;
}
void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels)
{
#ifdef DEBUG
SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
#endif
SDL_Log("Iniciant JailAudio...");
JA_audioSpec = {format, num_channels, freq };
if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &JA_audioSpec);
SDL_Log( (sdlAudioDevice==0) ? "Failed to initialize SDL audio!\n" : "OK!\n");
for (int i=0;i<JA_MAX_SIMULTANEOUS_CHANNELS;++i) channels[i].state = JA_CHANNEL_FREE;
//SDL_PauseAudioDevice(sdlAudioDevice);
JA_timerID = SDL_AddTimer(30, JA_UpdateCallback, nullptr);
}
void JA_Quit()
{
if (JA_timerID) SDL_RemoveTimer(JA_timerID);
if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = 0;
}
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
{
JA_Music_t *music = new JA_Music_t();
int chan, samplerate;
short *output;
music->length = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &output) * chan * 2;
music->spec.channels = chan;
music->spec.freq = samplerate;
music->spec.format = SDL_AUDIO_S16;
music->buffer = (Uint8*)SDL_malloc(music->length);
SDL_memcpy(music->buffer, output, music->length);
free(output);
music->pos = 0;
music->state = JA_MUSIC_STOPPED;
return music;
}
JA_Music_t *JA_LoadMusic(const char* filename)
{
int size;
char *buffer = file_getfilebuffer(filename, size);
JA_Music_t *music = JA_LoadMusic((Uint8*)buffer, size);
music->filename = (char*)malloc(strlen(filename)+1);
strcpy(music->filename, filename);
free(buffer);
return music;
}
void JA_PlayMusic(JA_Music_t *music, const int loop)
{
if (!JA_musicEnabled) return;
JA_StopMusic();
current_music = music;
current_music->pos = 0;
current_music->state = JA_MUSIC_PLAYING;
current_music->times = loop;
current_music->stream = SDL_CreateAudioStream(&current_music->spec, &JA_audioSpec);
if (!SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length)) printf("[ERROR] SDL_PutAudioStreamData failed!\n");
SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume);
if (!SDL_BindAudioStream(sdlAudioDevice, current_music->stream)) printf("[ERROR] SDL_BindAudioStream failed!\n");
//SDL_ResumeAudioStreamDevice(current_music->stream);
}
void JA_LoadAndPlayMusic(const char* filename, const bool force_reinit)
{
if ( (JA_GetMusicState() != JA_MUSIC_PLAYING) || (strcmp(JA_GetMusicFilename(), filename)!=0) || force_reinit ) {
JA_PlayMusic(JA_LoadMusic(filename));
}
}
char *JA_GetMusicFilename(JA_Music_t *music)
{
if (!music) music = current_music;
return music->filename;
}
void JA_PauseMusic()
{
if (!JA_musicEnabled) return;
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PAUSED;
//SDL_PauseAudioStreamDevice(current_music->stream);
SDL_UnbindAudioStream(current_music->stream);
}
void JA_ResumeMusic()
{
if (!JA_musicEnabled) return;
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PLAYING;
//SDL_ResumeAudioStreamDevice(current_music->stream);
SDL_BindAudioStream(sdlAudioDevice, current_music->stream);
}
void JA_StopMusic()
{
if (!JA_musicEnabled) return;
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED;
//SDL_PauseAudioStreamDevice(current_music->stream);
SDL_DestroyAudioStream(current_music->stream);
current_music->stream = nullptr;
free(current_music->filename);
current_music->filename = nullptr;
}
void JA_FadeOutMusic(const int milliseconds)
{
if (!JA_musicEnabled) return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
fading = true;
fade_start_time = SDL_GetTicks();
fade_duration = milliseconds;
fade_initial_volume = JA_musicVolume;
}
JA_Music_state JA_GetMusicState()
{
if (!JA_musicEnabled) return JA_MUSIC_DISABLED;
if (!current_music) return JA_MUSIC_INVALID;
return current_music->state;
}
void JA_DeleteMusic(JA_Music_t *music)
{
if (current_music == music) current_music = nullptr;
SDL_free(music->buffer);
if (music->stream) SDL_DestroyAudioStream(music->stream);
delete music;
}
float JA_SetMusicVolume(float volume)
{
JA_musicVolume = SDL_clamp( volume, 0.0f, 1.0f );
if (current_music) SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume);
return JA_musicVolume;
}
void JA_SetMusicPosition(float value)
{
if (!current_music) return;
current_music->pos = value * current_music->spec.freq;
}
float JA_GetMusicPosition()
{
if (!current_music) return 0;
return float(current_music->pos)/float(current_music->spec.freq);
}
void JA_EnableMusic(const bool value)
{
if ( !value && current_music && (current_music->state==JA_MUSIC_PLAYING) ) JA_StopMusic();
JA_musicEnabled = value;
}
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;
}
JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size)
{
JA_Sound_t *sound = new JA_Sound_t();
SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size),1, &sound->spec, &sound->buffer, &sound->length);
return sound;
}
JA_Sound_t *JA_LoadSound(const char* filename)
{
JA_Sound_t *sound = new JA_Sound_t();
SDL_LoadWAV(filename, &sound->spec, &sound->buffer, &sound->length);
return sound;
}
int JA_PlaySound(JA_Sound_t *sound, const int loop)
{
if (!JA_soundEnabled) return -1;
int channel = 0;
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
JA_StopChannel(channel);
channels[channel].sound = sound;
channels[channel].times = loop;
channels[channel].pos = 0;
channels[channel].state = JA_CHANNEL_PLAYING;
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec);
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume);
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
return channel;
}
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop)
{
if (!JA_soundEnabled) return -1;
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return -1;
JA_StopChannel(channel);
channels[channel].sound = sound;
channels[channel].times = loop;
channels[channel].pos = 0;
channels[channel].state = JA_CHANNEL_PLAYING;
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &JA_audioSpec);
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
SDL_SetAudioStreamGain(channels[channel].stream, JA_soundVolume);
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
return channel;
}
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);
delete sound;
}
void JA_PauseChannel(const int channel)
{
if (!JA_soundEnabled) return;
if (channel == -1)
{
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
if (channels[i].state == JA_CHANNEL_PLAYING)
{
channels[i].state = JA_CHANNEL_PAUSED;
//SDL_PauseAudioStreamDevice(channels[i].stream);
SDL_UnbindAudioStream(channels[i].stream);
}
}
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
if (channels[channel].state == JA_CHANNEL_PLAYING)
{
channels[channel].state = JA_CHANNEL_PAUSED;
//SDL_PauseAudioStreamDevice(channels[channel].stream);
SDL_UnbindAudioStream(channels[channel].stream);
}
}
}
void JA_ResumeChannel(const int channel)
{
if (!JA_soundEnabled) return;
if (channel == -1)
{
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
if (channels[i].state == JA_CHANNEL_PAUSED)
{
channels[i].state = JA_CHANNEL_PLAYING;
//SDL_ResumeAudioStreamDevice(channels[i].stream);
SDL_BindAudioStream(sdlAudioDevice, channels[i].stream);
}
}
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
if (channels[channel].state == JA_CHANNEL_PAUSED)
{
channels[channel].state = JA_CHANNEL_PLAYING;
//SDL_ResumeAudioStreamDevice(channels[channel].stream);
SDL_BindAudioStream(sdlAudioDevice, channels[channel].stream);
}
}
}
void JA_StopChannel(const int channel)
{
if (!JA_soundEnabled) return;
if (channel == -1)
{
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[i].stream);
channels[i].stream = nullptr;
channels[i].state = JA_CHANNEL_FREE;
channels[i].pos = 0;
channels[i].sound = NULL;
}
}
else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS)
{
if (channels[channel].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[channel].stream);
channels[channel].stream = nullptr;
channels[channel].state = JA_CHANNEL_FREE;
channels[channel].pos = 0;
channels[channel].sound = NULL;
}
}
JA_Channel_state JA_GetChannelState(const int channel)
{
if (!JA_soundEnabled) return JA_SOUND_DISABLED;
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state;
}
float JA_SetSoundVolume(float volume)
{
JA_soundVolume = SDL_clamp( volume, 0.0f, 1.0f );
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
if ( (channels[i].state == JA_CHANNEL_PLAYING) || (channels[i].state == JA_CHANNEL_PAUSED) )
SDL_SetAudioStreamGain(channels[i].stream, JA_soundVolume);
return JA_soundVolume;
}
void JA_EnableSound(const bool value)
{
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++)
{
if (channels[i].state == JA_CHANNEL_PLAYING) JA_StopChannel(i);
}
JA_soundEnabled = value;
}
float JA_SetVolume(float volume)
{
JA_SetSoundVolume(JA_SetMusicVolume(volume) / 2.0f);
return JA_musicVolume;
}
#endif

View File

@@ -1,42 +0,0 @@
#pragma once
#include <SDL3/SDL.h>
enum JA_Channel_state { JA_CHANNEL_INVALID, JA_CHANNEL_FREE, JA_CHANNEL_PLAYING, JA_CHANNEL_PAUSED, JA_SOUND_DISABLED };
enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED };
struct JA_Sound_t;
struct JA_Music_t;
void JA_Init(const int freq, const SDL_AudioFormat format, const int num_channels);
void JA_Quit();
JA_Music_t *JA_LoadMusic(const char* filename);
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length);
void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
void JA_LoadAndPlayMusic(const char* filename, const bool force_reinit=false);
char *JA_GetMusicFilename(JA_Music_t *music = nullptr);
void JA_PauseMusic();
void JA_ResumeMusic();
void JA_StopMusic();
void JA_FadeOutMusic(const int milliseconds);
JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music_t *music);
float JA_SetMusicVolume(float volume);
void JA_SetMusicPosition(float value);
float JA_GetMusicPosition();
void JA_EnableMusic(const bool value);
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound_t *sound, const int loop = 0);
int JA_PlaySoundOnChannel(JA_Sound_t *sound, const int channel, const int loop = 0);
void JA_PauseChannel(const int channel);
void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel);
JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound_t *sound);
float JA_SetSoundVolume(float volume);
void JA_EnableSound(const bool value);
float JA_SetVolume(float volume);

493
source/jaudio.cpp Normal file
View File

@@ -0,0 +1,493 @@
#include "jaudio.h"
#include "jfile.h"
#include "stb_vorbis.h"
#include <SDL3/SDL.h>
#include <stdio.h>
namespace audio {
#define MAX_CHANNELS 5
struct sound
{
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
Uint32 length { 0 };
Uint8 *buffer { NULL };
};
struct channel
{
audio::sound *sound { nullptr };
int pos { 0 };
int times { 0 };
SDL_AudioStream *stream { nullptr };
audio::state state { audio::state::available };
};
struct music
{
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
Uint32 length { 0 };
Uint8 *buffer { nullptr };
char *filename { nullptr };
int pos { 0 };
int times { 0 };
SDL_AudioStream *stream { nullptr };
audio::state state { audio::state::invalid };
};
audio::music *current_music { nullptr };
audio::channel channels[MAX_CHANNELS];
SDL_AudioSpec audio_spec { SDL_AUDIO_S16, 2, 48000 };
float music_volume { 1.0f };
float sound_volume { 0.5f };
bool music_enabled { true };
bool sound_enabled { true };
SDL_AudioDeviceID audio_device { 0 };
SDL_TimerID timer_id { 0 };
bool fading { false };
int fade_start_time;
int fade_duration;
int fade_initial_volume;
Uint32 updateCallback(void *userdata, SDL_TimerID timer_id, Uint32 interval)
{
if (music_enabled && current_music && current_music->state == audio::state::playing)
{
if (fading)
{
const int time = SDL_GetTicks();
if (time > (fade_start_time+fade_duration)) {
fading = false;
stopMusic();
return 30;
} else {
const int time_passed = time - fade_start_time;
const float percent = (float)time_passed / (float)fade_duration;
SDL_SetAudioStreamGain(current_music->stream, music_volume*(1.0 - percent));
}
}
if (current_music->times != 0)
{
if (SDL_GetAudioStreamAvailable(current_music->stream) < int(current_music->length/2))
{
SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length);
}
if (current_music->times>0) current_music->times--;
}
else
{
if (SDL_GetAudioStreamAvailable(current_music->stream) == 0) stopMusic();
}
}
if (sound_enabled)
{
for (int i=0; i < MAX_CHANNELS; ++i)
if (channels[i].state == audio::state::playing)
{
if (channels[i].times != 0)
{
if (SDL_GetAudioStreamAvailable(channels[i].stream) < int(channels[i].sound->length/2))
{
SDL_PutAudioStreamData(channels[i].stream, channels[i].sound->buffer, channels[i].sound->length);
if (channels[i].times>0) channels[i].times--;
}
}
else
{
if (SDL_GetAudioStreamAvailable(channels[i].stream) == 0) stopChannel(i);
}
}
}
return 30;
}
void init(const int freq, const SDL_AudioFormat format, const int num_channels)
{
#ifdef DEBUG
SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
#endif
SDL_Log("Iniciant JailAudio...");
audio_spec = {format, num_channels, freq };
if (!audio_device) SDL_CloseAudioDevice(audio_device);
audio_device = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &audio_spec);
SDL_Log( (audio_device==0) ? "Failed to initialize SDL audio!\n" : "OK!\n");
for (int i=0;i<MAX_CHANNELS;++i) channels[i].state = audio::state::available;
timer_id = SDL_AddTimer(30, updateCallback, nullptr);
}
void quit()
{
if (timer_id) SDL_RemoveTimer(timer_id);
if (!audio_device) SDL_CloseAudioDevice(audio_device);
audio_device = 0;
}
audio::music *loadMusic(Uint8* buffer, Uint32 length)
{
audio::music *music = new audio::music();
int chan, samplerate;
short *output;
music->length = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &output) * chan * 2;
music->spec.channels = chan;
music->spec.freq = samplerate;
music->spec.format = SDL_AUDIO_S16;
music->buffer = (Uint8*)SDL_malloc(music->length);
SDL_memcpy(music->buffer, output, music->length);
free(output);
music->pos = 0;
music->state = audio::state::stopped;
return music;
}
audio::music *loadMusic(const char* filename)
{
int size;
char *buffer = file_getfilebuffer(filename, size);
if (buffer == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR (audio::loadMusic): No s'ha trobat l'arxiu %s\n", filename);
exit(1);
}
audio::music *music = loadMusic((Uint8*)buffer, size);
music->filename = (char*)malloc(strlen(filename)+1);
strcpy(music->filename, filename);
free(buffer);
return music;
}
void playMusic(audio::music *music, const int loop)
{
if (!music_enabled) return;
stopMusic();
current_music = music;
current_music->pos = 0;
current_music->state = audio::state::playing;
current_music->times = loop;
current_music->stream = SDL_CreateAudioStream(&current_music->spec, &audio_spec);
if (!current_music->stream) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR (audio::playMusic): SDL_CreateAudioStream: %s\n", SDL_GetError());
exit(1);
}
if (!SDL_PutAudioStreamData(current_music->stream, current_music->buffer, current_music->length)) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR (audio::playMusic): SDL_PutAudioStreamData: %s\n", SDL_GetError());
exit(1);
}
SDL_SetAudioStreamGain(current_music->stream, music_volume);
if (!SDL_BindAudioStream(audio_device, current_music->stream)) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR (audio::playMusic): SDL_BindAudioStream: %s\n", SDL_GetError());
exit(1);
}
}
void loadAndPlayMusic(const char* filename, const bool force_reinit)
{
if ( (getMusicState() != audio::state::playing) || (strcmp(getMusicFilename(), filename)!=0) || force_reinit )
{
playMusic(loadMusic(filename));
}
}
char *getMusicFilename(audio::music *music)
{
if (!music) music = current_music;
return music->filename;
}
void pauseMusic()
{
if (!music_enabled) return;
if (!current_music || current_music->state == audio::state::invalid) return;
current_music->state = audio::state::paused;
SDL_UnbindAudioStream(current_music->stream);
}
void resumeMusic()
{
if (!music_enabled) return;
if (!current_music || current_music->state == audio::state::invalid) return;
current_music->state = audio::state::playing;
SDL_BindAudioStream(audio_device, current_music->stream);
}
void stopMusic()
{
if (!music_enabled) return;
if (!current_music || current_music->state == audio::state::invalid) return;
current_music->pos = 0;
current_music->state = audio::state::stopped;
SDL_DestroyAudioStream(current_music->stream);
current_music->stream = nullptr;
free(current_music->filename);
current_music->filename = nullptr;
}
void fadeOutMusic(const int milliseconds)
{
if (!music_enabled) return;
if (current_music == NULL || current_music->state == audio::state::invalid) return;
fading = true;
fade_start_time = SDL_GetTicks();
fade_duration = milliseconds;
fade_initial_volume = music_volume;
}
audio::state getMusicState()
{
if (!music_enabled) return audio::state::disabled;
if (!current_music) return audio::state::invalid;
return current_music->state;
}
void deleteMusic(audio::music *music)
{
if (current_music == music) current_music = nullptr;
SDL_free(music->buffer);
if (music->stream) SDL_DestroyAudioStream(music->stream);
delete music;
}
float setMusicVolume(float volume)
{
music_volume = SDL_clamp( volume, 0.0f, 1.0f );
if (current_music) SDL_SetAudioStreamGain(current_music->stream, music_volume);
return music_volume;
}
void setMusicPosition(float value)
{
if (!current_music) return;
current_music->pos = value * current_music->spec.freq;
}
float getMusicPosition()
{
if (!current_music) return 0;
return float(current_music->pos)/float(current_music->spec.freq);
}
void enableMusic(const bool value)
{
if ( !value && current_music && (current_music->state==audio::state::playing) ) stopMusic();
music_enabled = value;
}
audio::sound *newSound(Uint8* buffer, Uint32 length)
{
audio::sound *sound = new audio::sound();
sound->buffer = buffer;
sound->length = length;
return sound;
}
audio::sound *loadSound(uint8_t* buffer, uint32_t size)
{
audio::sound *sound = new audio::sound();
SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size),1, &sound->spec, &sound->buffer, &sound->length);
return sound;
}
audio::sound *loadSound(const char* filename)
{
int size;
uint8_t *buffer = (uint8_t *)file_getfilebuffer(filename, size);
if (buffer == nullptr) {
SDL_LogError(SDL_LOG_CATEGORY_ERROR, "ERROR (audio::loadSound): No s'ha trobat l'arxiu %s\n", filename);
exit(1);
}
audio::sound *sound = loadSound(buffer, size);
free(buffer);
return sound;
}
int playSound(audio::sound *sound, const int loop)
{
if (!sound_enabled) return -1;
int channel = 0;
while (channel < MAX_CHANNELS && channels[channel].state != audio::state::available) { channel++; }
if (channel == MAX_CHANNELS) channel = 0;
stopChannel(channel);
channels[channel].sound = sound;
channels[channel].times = loop;
channels[channel].pos = 0;
channels[channel].state = audio::state::playing;
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &audio_spec);
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
SDL_SetAudioStreamGain(channels[channel].stream, sound_volume);
SDL_BindAudioStream(audio_device, channels[channel].stream);
return channel;
}
int playSoundOnChannel(audio::sound *sound, const int channel, const int loop)
{
if (!sound_enabled) return -1;
if (channel < 0 || channel >= MAX_CHANNELS) return -1;
stopChannel(channel);
channels[channel].sound = sound;
channels[channel].times = loop;
channels[channel].pos = 0;
channels[channel].state = audio::state::playing;
channels[channel].stream = SDL_CreateAudioStream(&channels[channel].sound->spec, &audio_spec);
SDL_PutAudioStreamData(channels[channel].stream, channels[channel].sound->buffer, channels[channel].sound->length);
SDL_SetAudioStreamGain(channels[channel].stream, sound_volume);
SDL_BindAudioStream(audio_device, channels[channel].stream);
return channel;
}
void deleteSound(audio::sound *sound)
{
for (int i = 0; i < MAX_CHANNELS; i++) {
if (channels[i].sound == sound) stopChannel(i);
}
SDL_free(sound->buffer);
delete sound;
}
void pauseChannel(const int channel)
{
if (!sound_enabled) return;
if (channel == -1)
{
for (int i = 0; i < MAX_CHANNELS; i++)
if (channels[i].state == audio::state::playing)
{
channels[i].state = audio::state::paused;
SDL_UnbindAudioStream(channels[i].stream);
}
}
else if (channel >= 0 && channel < MAX_CHANNELS)
{
if (channels[channel].state == audio::state::playing)
{
channels[channel].state = audio::state::paused;
SDL_UnbindAudioStream(channels[channel].stream);
}
}
}
void resumeChannel(const int channel)
{
if (!sound_enabled) return;
if (channel == -1)
{
for (int i = 0; i < MAX_CHANNELS; i++)
if (channels[i].state == audio::state::paused)
{
channels[i].state = audio::state::playing;
SDL_BindAudioStream(audio_device, channels[i].stream);
}
}
else if (channel >= 0 && channel < MAX_CHANNELS)
{
if (channels[channel].state == audio::state::paused)
{
channels[channel].state = audio::state::playing;
SDL_BindAudioStream(audio_device, channels[channel].stream);
}
}
}
void stopChannel(const int channel)
{
if (!sound_enabled) return;
if (channel == -1)
{
for (int i = 0; i < MAX_CHANNELS; i++) {
if (channels[i].state != audio::state::available) SDL_DestroyAudioStream(channels[i].stream);
channels[i].stream = nullptr;
channels[i].state = audio::state::available;
channels[i].pos = 0;
channels[i].sound = NULL;
}
}
else if (channel >= 0 && channel < MAX_CHANNELS)
{
if (channels[channel].state != audio::state::available) SDL_DestroyAudioStream(channels[channel].stream);
channels[channel].stream = nullptr;
channels[channel].state = audio::state::available;
channels[channel].pos = 0;
channels[channel].sound = NULL;
}
}
audio::state getChannelState(const int channel)
{
if (!sound_enabled) return audio::state::disabled;
if (channel < 0 || channel >= MAX_CHANNELS) return audio::state::invalid;
return channels[channel].state;
}
float setSoundVolume(float volume)
{
sound_volume = SDL_clamp( volume, 0.0f, 1.0f );
for (int i = 0; i < MAX_CHANNELS; i++)
if ( (channels[i].state == audio::state::playing) || (channels[i].state == audio::state::paused) )
SDL_SetAudioStreamGain(channels[i].stream, sound_volume);
return sound_volume;
}
void enableSound(const bool value)
{
for (int i = 0; i < MAX_CHANNELS; i++)
{
if (channels[i].state == audio::state::playing) stopChannel(i);
}
sound_enabled = value;
}
float setVolume(float volume)
{
setSoundVolume(setMusicVolume(volume) / 2.0f);
return music_volume;
}
#undef MAX_CHANNELS
}

44
source/jaudio.h Normal file
View File

@@ -0,0 +1,44 @@
#pragma once
#include <SDL3/SDL.h>
namespace audio
{
enum state { invalid, available, playing, paused, stopped, disabled };
struct sound;
struct music;
void init(const int freq, const SDL_AudioFormat format, const int num_channels);
void quit();
audio::music *loadMusic(const char* filename);
audio::music *loadMusic(Uint8* buffer, Uint32 length);
void playMusic(audio::music *music, const int loop = -1);
void loadAndPlayMusic(const char* filename, const bool force_reinit=false);
char *getMusicFilename(audio::music *music = nullptr);
void pauseMusic();
void resumeMusic();
void stopMusic();
void fadeOutMusic(const int milliseconds=250);
audio::state getMusicState();
void deleteMusic(audio::music *music);
float setMusicVolume(float volume);
void setMusicPosition(float value);
float getMusicPosition();
void enableMusic(const bool value);
audio::sound *newSound(Uint8* buffer, Uint32 length);
audio::sound *loadSound(Uint8* buffer, Uint32 length);
audio::sound *loadSound(const char* filename);
int playSound(audio::sound *sound, const int loop = 0);
int playSoundOnChannel(audio::sound *sound, const int channel, const int loop = 0);
void pauseChannel(const int channel);
void resumeChannel(const int channel);
void stopChannel(const int channel);
audio::state getChannelState(const int channel);
void deleteSound(audio::sound *sound);
float setSoundVolume(float volume);
void enableSound(const bool value);
float setVolume(float volume);
}

View File

@@ -10,22 +10,22 @@ namespace draw
// Aleshores, en "render" el contingut de screen se volca a la textura SDL que crearem,
// i eixa textura se pintarà a pantalla com se sol fer amb SDL. Ho anirem veient en el codi.
SDL_Window *sdl_window = nullptr; // La finestra de SDL
SDL_Renderer *sdl_renderer = nullptr; // El renderer de SDL
SDL_Texture *sdl_texture = nullptr; // La textura de SDL a la que pintarem la nostra superficie "screen" i que despres volcarem a pantalla
SDL_Window *sdl_window {nullptr}; // La finestra de SDL
SDL_Renderer *sdl_renderer {nullptr}; // El renderer de SDL
SDL_Texture *sdl_texture {nullptr}; // La textura de SDL a la que pintarem la nostra superficie "screen" i que despres volcarem a pantalla
static int screen_zoom = 1;
surface *screen = nullptr; // La superficie screen, que representa la pantalla. Se crea i destrueix internament
surface *destination = nullptr; // Punter a la actual superficie de destí
surface *source = nullptr; // Punter a la actual superficie d'oritge
surface *pushedSource = nullptr; // Punter a la superficie d'oritge que s'ha pushat
surface *screen {nullptr}; // La superficie screen, que representa la pantalla. Se crea i destrueix internament
surface *destination {nullptr}; // Punter a la actual superficie de destí
surface *source {nullptr}; // Punter a la actual superficie d'oritge
surface *pushed_source {nullptr}; // Punter a la superficie d'oritge que s'ha pushat
uint32_t palette[256]; // La paleta de colors
uint32_t aux_palette[256]; // La paleta de colors
uint32_t aux_palette[256]; // La paleta de colors, para els fadein
uint8_t color_indices[256]; // Indices dels colors per defecte
uint8_t sel_color = 0; // Color seleccionat per defecte
uint8_t transparent = 0; // El color transparent
uint8_t sel_color {0}; // Color seleccionat per defecte
uint8_t transparent {0}; // El color transparent
//surface *textsurf = nullptr; // Surface on guardar el gif amb la font
@@ -35,23 +35,26 @@ namespace draw
bool fading_in = false;
// Inicialització de tot el que fa falta per a carregar gràfics i pintar en pantalla
void init(const std::string &titol, const uint16_t width, const uint16_t height, const int zoom)
void init(const char *titol, const uint16_t width, const uint16_t height, const int zoom)
{
screen_zoom = zoom;
// [TODO] Incloure gestió de pantalla completa
// Inicialització de les estructures de SDL
sdl_window = SDL_CreateWindow(titol.c_str(), width * zoom, height * zoom, 0);
if (!sdl_window) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR: Failed to initialize window!\n"); exit(1); }
sdl_window = SDL_CreateWindow(titol, width * zoom, height * zoom, 0);
if (!sdl_window) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR (draw::init): Failed to initialize window!\n"); exit(1);
}
sdl_renderer = SDL_CreateRenderer(sdl_window, NULL);
if (!sdl_renderer) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR: Failed to initialize renderer!\n"); exit(1); }
if (!sdl_renderer) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR (draw::init): Failed to initialize renderer!\n"); exit(1);
}
sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height);
SDL_SetTextureScaleMode(sdl_texture, SDL_SCALEMODE_NEAREST);
if (!sdl_texture) { SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR: Failed to initialize texture!\n"); exit(1); }
// Establim el tamany "logic", indepndent del tamany de finestra
//SDL_SetRenderLogicalPresentation(sdl_renderer, width, height,);
if (!sdl_texture) {
SDL_LogError(SDL_LOG_CATEGORY_VIDEO, "ERROR (draw::init): Failed to initialize texture!\n"); exit(1);
}
// Creem la superficie "screen" i la establim com a superficie destinació
screen = createSurface(width, height);
@@ -113,12 +116,12 @@ namespace draw
}
// Carrega un gràfic d'un arxiu (en format GIF) a una nova superficie, i torna un punter a ella
surface *loadSurface(const std::string &filename, const bool loadPalette)
surface *loadSurface(const char *filename, const bool loadPalette)
{
// Agafem un buffer de bytes de l'arxiu especificat
// getFileBuffer() simplement ens torna el arxiu sencer dins de un array de char
int size;
uint8_t *buffer = (uint8_t *)file_getfilebuffer(filename.c_str(), size);
uint8_t *buffer = (uint8_t *)file_getfilebuffer(filename, size);
// Si ens ha tornat nullptr, es que no l'ha trobat, tornem nosaltres també nullptr ja que no s'ha pogut crear la superficie
if (buffer == nullptr)
@@ -195,12 +198,12 @@ namespace draw
void pushSource()
{
pushedSource = source;
pushed_source = source;
}
void popSource()
{
source = pushedSource;
source = pushed_source;
}
void setViewport(const int x, const int y, const int w, const int h)
@@ -229,12 +232,12 @@ namespace draw
}
// Carrega la paleta d'un GIF i la torna en un array de uint32_t
uint32_t *loadPalette(const std::string &filename, int *paletteSize)
uint32_t *loadPalette(const char *filename, int *paletteSize)
{
// Agafem un buffer de bytes de l'arxiu especificat
// getFileBuffer() simplement ens torna el arxiu sencer dins de un array de char
int size;
uint8_t *buffer = (uint8_t *)file_getfilebuffer(filename.c_str(), size);
uint8_t *buffer = (uint8_t *)file_getfilebuffer(filename, size);
// Li passem el array del arxiu a LoadPalette. Ell ens torna un array de uint32_t amb la paleta
// Van a ser 256 entrades de 32 bits, cada entrada es un color, amb el format 0xAARRGGBB
@@ -325,7 +328,7 @@ namespace draw
}
// Pinta un troç de la superficie "source" en la superficie "destination".
void draw(const int dx, const int dy, const int w, const int h, const int sx, const int sy, const int flip)
void draw(const int dx, const int dy, const int w, const int h, const int sx, const int sy, const draw::flip flip)
{
// Si no hi ha superficie d'oritge especificada, no fem res, o petarà el mame
if (source == nullptr)
@@ -337,14 +340,14 @@ namespace draw
int sdx = 1, sdy = 1, ssx = sx, ssy = sy;
// Però si s'ha especificat que fem flip en horitzontal...
if (flip & DRAW_FLIP_HORIZONTAL)
if (flip & draw::flip::horizontal)
{
sdx = -1; // Avançarem 1 pixel en negatiu
ssx = sx + w - 1; // I començarem al final, o siga, sumarem a sx el ample
}
// De igual forma per al flip en vertical, per a la y
if (flip & DRAW_FLIP_VERTICAL)
if (flip & draw::flip::vertical)
{
sdy = -1;
ssy = sy + h - 1;

View File

@@ -1,15 +1,16 @@
#pragma once
#include <cstdint>
#include <string>
#define DRAW_FLIP_NONE 0
#define DRAW_FLIP_HORIZONTAL 1
#define DRAW_FLIP_VERTICAL 2
#define DRAW_FLIP_BOTH 3
//#define DRAW_FLIP_NONE 0
//#define DRAW_FLIP_HORIZONTAL 1
//#define DRAW_FLIP_VERTICAL 2
//#define DRAW_FLIP_BOTH 3
// Unitat per a la gestió dels recursos gràfics i dibuixat en pantalla
namespace draw
{
enum flip { none, horizontal, vertical, both };
// Estructura per a mantindre una superficie de pintat, la "pantalla virtual" de tota la vida
struct surface
{
@@ -24,7 +25,7 @@ namespace draw
/// @param width es el ample de la finestra "virtual"
/// @param height es el alt de la finestra "virtual"
/// @param zoom es com de grans son els pixels.
void init(const std::string &titol, const uint16_t width, const uint16_t height, const int zoom);
void init(const char *titol, const uint16_t width, const uint16_t height, const int zoom);
/// @brief Finalització del sistema (tancar coses de SDL, superficies fixes, etc...)
void quit();
@@ -41,7 +42,7 @@ namespace draw
/// @param filename nom de l'arxiu GIF d'on carregar la superficie
/// @param loadPalette si es true també se carrega la paleta del GIF
/// @return un punter a una nova superficie
surface *loadSurface(const std::string &filename, const bool loadPalette = false);
surface *loadSurface(const char* filename, const bool loadPalette = false);
/// @brief Allibera la memòria d'una superficie, els seus pixels inclosos
/// @param surf punter a la superficie a alliberar
@@ -67,7 +68,7 @@ namespace draw
/// @brief Carrega la paleta d'un GIF i la torna en un array de uint32_t
/// @param filename nom de l'arxiu GIF d'on carregar la paleta
/// @param paletteSize si no es NULL ens torna el tamany de la paleta carregada
uint32_t *loadPalette(const std::string &filename, int *paletteSize = nullptr);
uint32_t *loadPalette(const char *filename, int *paletteSize = nullptr);
/// @brief Estableix la paleta del sistema, o part de ella, des d'un array especificat
/// @param pal un array de uint32_t
@@ -104,7 +105,7 @@ namespace draw
/// @param sx coordenada x de l'oritge
/// @param sy coordenada y de l'oritge
/// @param flip si s'ha de fer flip en hortizontal o vertical (o ambdos)
void draw(const int dx, const int dy, const int w, const int h, const int sx, const int sy, const int flip = DRAW_FLIP_NONE);
void draw(const int dx, const int dy, const int w, const int h, const int sx, const int sy, const draw::flip flip = draw::flip::none);
/// @brief Pinta tota la superficie "source" en la superficie "destination", posició (x,y).
/// @param x coordenada x de la destinació

View File

@@ -69,7 +69,7 @@ bool file_getdictionary() {
fi.read((char*)&toc_offset, 4);
fi.seekg(toc_offset);
for (int i=0; i<num_files; ++i)
for (uint i=0; i<num_files; ++i)
{
uint32_t file_offset, file_size;
fi.read( (char*)&file_offset, 4 );
@@ -83,6 +83,7 @@ bool file_getdictionary() {
toc.push_back({filename, file_size, file_offset});
}
fi.close();
return true;
}
char *file_getfilenamewithfolder(const char* filename) {
@@ -129,10 +130,11 @@ FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool bi
return f;
}
char *file_getfilebuffer(const char *resourcename, int& filesize) {
char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zero_terminate) {
FILE *f = file_getfilepointer(resourcename, filesize, true);
char* buffer = (char*)malloc(filesize);
char* buffer = (char*)malloc(zero_terminate?filesize:filesize+1);
fread(buffer, filesize, 1, f);
if (zero_terminate) buffer[filesize]=0;
fclose(f);
return buffer;
}

View File

@@ -12,7 +12,7 @@ void file_setresourcefolder(const char *str);
void file_setsource(const int src);
FILE *file_getfilepointer(const char *resourcename, int& filesize, const bool binary=false);
char *file_getfilebuffer(const char *resourcename, int& filesize);
char *file_getfilebuffer(const char *resourcename, int& filesize, const bool zero_terminate=false);
const char* file_getconfigvalue(const char *key);
void file_setconfigvalue(const char* key, const char* value);

View File

@@ -3,6 +3,7 @@
#include "jinput.h"
#include <SDL3/SDL.h>
#include <map>
#include <string>
#ifdef MACOS_BUNDLE
#include <libgen.h>

View File

@@ -2,8 +2,9 @@
#include "jdraw.h"
#include "jinput.h"
#include "jail_audio.h"
#include "jaudio.h"
#include "jfile.h"
namespace game
{
extern bool windowHasFocus;

View File

@@ -8,7 +8,7 @@ void game::init()
draw::setTrans(0);
input::init(3);
JA_Init(48000, SDL_AUDIO_S16, 2);
audio::init(48000, SDL_AUDIO_S16, 2);
font::init();