VERSIÓ 1.2

- [NEW] Convertit a SDL3
This commit is contained in:
2025-06-18 12:47:24 +02:00
parent 16be589a72
commit 0cb1296ad3
8 changed files with 310 additions and 171 deletions

View File

@@ -3,25 +3,25 @@ source = *.cpp ./lua/*.c
windows: windows:
@echo off @echo off
g++ $(source) icon.res -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -lmingw32 -lSDL2main -lSDL2 -mwindows -o "$(executable).exe" g++ $(source) icon.res -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -lmingw32 -lSDL3 -mwindows -o "$(executable).exe"
strip -s -R .comment -R .gnu.version --strip-unneeded "$(executable).exe" strip -s -R .comment -R .gnu.version --strip-unneeded "$(executable).exe"
windows_debug: windows_debug:
@echo off @echo off
g++ $(source) -D DEBUG -g -Wall -Os -lmingw32 -lSDL2main -lSDL2 -o "$(executable)_debug.exe" g++ $(source) -D DEBUG -g -Wall -Os -lmingw32 -lSDL3 -o "$(executable)_debug.exe"
macos: macos:
clang++ $(source) -Wall -Os -std=c++11 -ffunction-sections -fdata-sections -lSDL2 -o "$(executable)" clang++ $(source) -Wall -Os -std=c++11 -ffunction-sections -fdata-sections -lSDL3 -o "$(executable)"
macos_debug: macos_debug:
clang++ $(source) -D DEBUG -g -Wall -Os -std=c++11 -ffunction-sections -fdata-sections -lSDL2 -o "$(executable)_debug" clang++ $(source) -D DEBUG -g -Wall -Os -std=c++11 -ffunction-sections -fdata-sections -lSDL3 -o "$(executable)_debug"
macos_bundle: macos_bundle:
clang++ $(source) -D MACOS_BUNDLE -Wall -Os -std=c++11 -framework SDL2 -F /Library/Frameworks -ffunction-sections -fdata-sections -o mini_bundle -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12 clang++ $(source) -D MACOS_BUNDLE -Wall -Os -std=c++11 -framework SDL3 -F /Library/Frameworks -ffunction-sections -fdata-sections -o mini_bundle -rpath @executable_path/../Frameworks/ -target x86_64-apple-macos10.12
linux: linux:
g++ $(source) -D LUA_USE_LINUX -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -lSDL2 -o "$(executable)" g++ $(source) -D LUA_USE_LINUX -Wall -Os -ffunction-sections -fdata-sections -Wl,--gc-sections -lSDL3 -o "$(executable)"
strip -s -R .comment -R .gnu.version --strip-unneeded "$(executable)" strip -s -R .comment -R .gnu.version --strip-unneeded "$(executable)"
linux_debug: linux_debug:
g++ $(source) -D LUA_USE_LINUX -D DEBUG -g -Wall -lSDL2 -o "$(executable)_debug" g++ $(source) -D LUA_USE_LINUX -D DEBUG -g -Wall -lSDL3 -o "$(executable)_debug"

View File

@@ -13,4 +13,6 @@ end
function mini.update() function mini.update()
surf.cls(1) surf.cls(1)
draw.surf(0, 0, 64, 64, 10, 10) draw.surf(0, 0, 64, 64, 10, 10)
if key.down(key.ESCAPE) then sys.quit() end
draw.text(sys.fps(), 0, 0, 4)
end end

View File

@@ -1,47 +1,60 @@
#ifndef JA_USESDLMIXER #ifndef JA_USESDLMIXER
#include "jail_audio.h" #include "jail_audio.h"
#include "stb_vorbis.h" #include "stb_vorbis.h"
#include <SDL2/SDL.h> #include <SDL3/SDL.h>
#include <stdio.h> #include <stdio.h>
#define JA_MAX_SIMULTANEOUS_CHANNELS 5 #define JA_MAX_SIMULTANEOUS_CHANNELS 5
struct JA_Sound_t { struct JA_Sound_t
{
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
Uint32 length { 0 }; Uint32 length { 0 };
Uint8 *buffer { NULL }; Uint8 *buffer { NULL };
}; };
struct JA_Channel_t { struct JA_Channel_t
JA_Sound_t *sound; {
JA_Sound_t *sound { nullptr };
int pos { 0 }; int pos { 0 };
int times { 0 }; int times { 0 };
SDL_AudioStream *stream { nullptr };
JA_Channel_state state { JA_CHANNEL_FREE }; JA_Channel_state state { JA_CHANNEL_FREE };
}; };
struct JA_Music_t { struct JA_Music_t
int samples {0}; {
SDL_AudioSpec spec { SDL_AUDIO_S16, 2, 48000 };
Uint32 length { 0 };
Uint8 *buffer { nullptr };
int pos { 0 }; int pos { 0 };
int times { 0 }; int times { 0 };
short* output {NULL}; SDL_AudioStream *stream { nullptr };
JA_Music_state state { JA_MUSIC_INVALID }; JA_Music_state state { JA_MUSIC_INVALID };
}; };
JA_Music_t *current_music{NULL}; JA_Music_t *current_music { nullptr };
JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS]; JA_Channel_t channels[JA_MAX_SIMULTANEOUS_CHANNELS];
int JA_freq {48000}; SDL_AudioSpec JA_audioSpec { SDL_AUDIO_S16, 2, 48000 };
SDL_AudioFormat JA_format {AUDIO_S16}; float JA_musicVolume { 1.0f };
Uint8 JA_channels {2}; float JA_soundVolume { 0.5f };
int JA_musicVolume = 128; bool JA_musicEnabled { true };
int JA_soundVolume = 64; bool JA_soundEnabled { true };
bool JA_musicEnabled = true; SDL_AudioDeviceID sdlAudioDevice { 0 };
bool JA_soundEnabled = true; SDL_TimerID JA_timerID { 0 };
SDL_AudioDeviceID sdlAudioDevice = 0;
bool fading = false;
int fade_start_time;
int fade_duration;
int fade_initial_volume;
/*
void audioCallback(void * userdata, uint8_t * stream, int len) { void audioCallback(void * userdata, uint8_t * stream, int len) {
SDL_memset(stream, 0, len); SDL_memset(stream, 0, len);
if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) { if (current_music != NULL && current_music->state == JA_MUSIC_PLAYING) {
const int size = SDL_min(len, (current_music->samples-current_music->pos)*2); 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); SDL_MixAudioFormat(stream, (Uint8*)(current_music->output+current_music->pos), AUDIO_S16, size, JA_musicVolume);
current_music->pos += size/2; current_music->pos += size/2;
if (size < len) { if (size < len) {
@@ -73,56 +86,101 @@ void audioCallback(void * userdata, uint8_t * stream, int len) {
} }
} }
} }
*/
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, 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) 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) < 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) JA_StopChannel(i);
}
}
return 30;
}
void JA_Init(const int freq, const SDL_AudioFormat format, const int channels) void JA_Init(const int freq, const SDL_AudioFormat format, const int channels)
{ {
#ifdef DEBUG #ifdef DEBUG
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG); SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
#endif #endif
SDL_Log("Iniciant JailAudio..."); SDL_Log("Iniciant JailAudio...");
JA_freq = freq; JA_audioSpec = {format, channels, freq };
JA_format = format; if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
JA_channels = channels; sdlAudioDevice = SDL_OpenAudioDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &JA_audioSpec);
SDL_AudioSpec audioSpec{JA_freq, JA_format, JA_channels, 0, 1024, 0, 0, audioCallback, NULL}; if (!sdlAudioDevice) {
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); SDL_Log("Failed to initialize SDL audio: %s\n", SDL_GetError());
sdlAudioDevice = SDL_OpenAudioDevice(NULL, 0, &audioSpec, NULL, 0);
if (sdlAudioDevice==0)
{
SDL_Log("FAILED!\n");
SDL_Log("Failed to initialize SDL audio!\n");
} else { } else {
SDL_Log("OK!\n"); SDL_Log( "JailAudio OK!\n");
} }
SDL_PauseAudioDevice(sdlAudioDevice, 0); //SDL_PauseAudioDevice(sdlAudioDevice);
JA_timerID = SDL_AddTimer(30, JA_UpdateCallback, nullptr);
} }
void JA_Quit() { void JA_Quit()
SDL_PauseAudioDevice(sdlAudioDevice, 1); {
if (sdlAudioDevice != 0) SDL_CloseAudioDevice(sdlAudioDevice); if (JA_timerID) SDL_RemoveTimer(JA_timerID);
if (!sdlAudioDevice) SDL_CloseAudioDevice(sdlAudioDevice);
sdlAudioDevice = 0; sdlAudioDevice = 0;
} }
JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length) JA_Music_t *JA_LoadMusic(Uint8* buffer, Uint32 length)
{ {
int chan, samplerate;
JA_Music_t *music = new JA_Music_t(); JA_Music_t *music = new JA_Music_t();
music->samples = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &music->output); int chan, samplerate;
// [RZC 28/08/22] Abans el descomprimiem mentre el teniem obert short *output;
// music->samples = stb_vorbis_decode_filename(filename, &chan, &samplerate, &music->output); music->length = stb_vorbis_decode_memory(buffer, length, &chan, &samplerate, &output) * chan * 2;
SDL_AudioCVT cvt; music->spec.channels = chan;
SDL_BuildAudioCVT(&cvt, AUDIO_S16, chan, samplerate, JA_format, JA_channels, JA_freq); music->spec.freq = samplerate;
SDL_Log("Music length: %f\n", float(music->samples)/float(JA_freq)); music->spec.format = SDL_AUDIO_S16;
if (cvt.needed) { music->buffer = (Uint8*)SDL_malloc(music->length);
cvt.len = music->samples * chan * 2; SDL_memcpy(music->buffer, output, music->length);
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult); free(output);
SDL_memcpy(cvt.buf, music->output, cvt.len);
SDL_ConvertAudio(&cvt);
free(music->output);
music->output = (short*)cvt.buf;
}
music->pos = 0; music->pos = 0;
music->state = JA_MUSIC_STOPPED; music->state = JA_MUSIC_STOPPED;
@@ -151,75 +209,101 @@ void JA_PlayMusic(JA_Music_t *music, const int loop)
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled) return;
if (current_music != NULL) { JA_StopMusic();
current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED;
}
current_music = music; current_music = music;
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_PLAYING; current_music->state = JA_MUSIC_PLAYING;
current_music->times = loop; 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_PauseMusic() void JA_PauseMusic()
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled) return;
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PAUSED; current_music->state = JA_MUSIC_PAUSED;
//SDL_PauseAudioStreamDevice(current_music->stream);
SDL_UnbindAudioStream(current_music->stream);
} }
void JA_ResumeMusic() void JA_ResumeMusic()
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled) return;
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->state = JA_MUSIC_PLAYING; current_music->state = JA_MUSIC_PLAYING;
//SDL_ResumeAudioStreamDevice(current_music->stream);
SDL_BindAudioStream(sdlAudioDevice, current_music->stream);
} }
void JA_StopMusic() void JA_StopMusic()
{ {
if (!JA_musicEnabled) return; if (!JA_musicEnabled) return;
if (!current_music || current_music->state == JA_MUSIC_INVALID) return;
if (current_music == NULL || current_music->state == JA_MUSIC_INVALID) return;
current_music->pos = 0; current_music->pos = 0;
current_music->state = JA_MUSIC_STOPPED; current_music->state = JA_MUSIC_STOPPED;
//SDL_PauseAudioStreamDevice(current_music->stream);
SDL_DestroyAudioStream(current_music->stream);
current_music->stream = nullptr;
} }
JA_Music_state JA_GetMusicState() { void JA_FadeOutMusic(const int milliseconds)
if (!JA_musicEnabled) return JA_MUSIC_DISABLED; {
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;
if (current_music == NULL) return JA_MUSIC_INVALID;
return current_music->state; return current_music->state;
} }
void JA_DeleteMusic(JA_Music_t *music) { void JA_DeleteMusic(JA_Music_t *music)
if (current_music == music) current_music = NULL; {
free(music->output); if (current_music == music) current_music = nullptr;
SDL_free(music->buffer);
if (music->stream) SDL_DestroyAudioStream(music->stream);
delete music; delete music;
} }
int JA_SetMusicVolume(int volume) float JA_SetMusicVolume(float volume)
{ {
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_musicVolume = SDL_clamp( volume, 0.0f, 1.0f );
if (current_music) SDL_SetAudioStreamGain(current_music->stream, JA_musicVolume);
return JA_musicVolume; return JA_musicVolume;
} }
void JA_SetMusicPosition(float value) void JA_SetMusicPosition(float value)
{ {
if (!current_music) return; if (!current_music) return;
current_music->pos = value * JA_freq; current_music->pos = value * current_music->spec.freq;
} }
float JA_GetMusicPosition() float JA_GetMusicPosition()
{ {
if (!current_music) return 0; if (!current_music) return 0;
return float(current_music->pos)/float(JA_freq); return float(current_music->pos)/float(current_music->spec.freq);
} }
void JA_EnableMusic(const bool value) void JA_EnableMusic(const bool value)
{ {
if (!value && current_music != NULL && current_music->state==JA_MUSIC_PLAYING) JA_StopMusic(); if ( !value && current_music && (current_music->state==JA_MUSIC_PLAYING) ) JA_StopMusic();
JA_musicEnabled = value; JA_musicEnabled = value;
} }
@@ -228,45 +312,26 @@ void JA_EnableMusic(const bool value)
JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length) { JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length)
{
JA_Sound_t *sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
sound->buffer = buffer; sound->buffer = buffer;
sound->length = length; sound->length = length;
return sound; return sound;
} }
JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size) { JA_Sound_t *JA_LoadSound(uint8_t* buffer, uint32_t size)
{
JA_Sound_t *sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; SDL_LoadWAV_IO(SDL_IOFromMem(buffer, size),1, &sound->spec, &sound->buffer, &sound->length);
SDL_LoadWAV_RW(SDL_RWFromMem(buffer, size),1, &wavSpec, &sound->buffer, &sound->length);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
cvt.len = sound->length;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
SDL_ConvertAudio(&cvt);
SDL_FreeWAV(sound->buffer);
sound->buffer = cvt.buf;
sound->length = cvt.len_cvt;
return sound; return sound;
} }
JA_Sound_t *JA_LoadSound(const char* filename) { JA_Sound_t *JA_LoadSound(const char* filename)
{
JA_Sound_t *sound = new JA_Sound_t(); JA_Sound_t *sound = new JA_Sound_t();
SDL_AudioSpec wavSpec; SDL_LoadWAV(filename, &sound->spec, &sound->buffer, &sound->length);
SDL_LoadWAV(filename, &wavSpec, &sound->buffer, &sound->length);
SDL_AudioCVT cvt;
SDL_BuildAudioCVT(&cvt, wavSpec.format, wavSpec.channels, wavSpec.freq, JA_format, JA_channels, JA_freq);
cvt.len = sound->length;
cvt.buf = (Uint8 *) SDL_malloc(cvt.len * cvt.len_mult);
SDL_memcpy(cvt.buf, sound->buffer, sound->length);
SDL_ConvertAudio(&cvt);
SDL_FreeWAV(sound->buffer);
sound->buffer = cvt.buf;
sound->length = cvt.len_cvt;
return sound; return sound;
} }
@@ -278,11 +343,36 @@ int JA_PlaySound(JA_Sound_t *sound, const int loop)
int channel = 0; int channel = 0;
while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; } while (channel < JA_MAX_SIMULTANEOUS_CHANNELS && channels[channel].state != JA_CHANNEL_FREE) { channel++; }
if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0; if (channel == JA_MAX_SIMULTANEOUS_CHANNELS) channel = 0;
JA_StopChannel(channel);
channels[channel].sound = sound; channels[channel].sound = sound;
channels[channel].times = loop; channels[channel].times = loop;
channels[channel].pos = 0; channels[channel].pos = 0;
channels[channel].state = JA_CHANNEL_PLAYING; 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; return channel;
} }
@@ -299,12 +389,24 @@ void JA_PauseChannel(const int channel)
{ {
if (!JA_soundEnabled) return; if (!JA_soundEnabled) return;
if (channel == -1) { 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; 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);
} }
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
if (channels[channel].state == JA_CHANNEL_PLAYING) channels[channel].state = JA_CHANNEL_PAUSED;
} }
} }
@@ -312,12 +414,24 @@ void JA_ResumeChannel(const int channel)
{ {
if (!JA_soundEnabled) return; if (!JA_soundEnabled) return;
if (channel == -1) { 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; 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);
} }
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) {
if (channels[channel].state == JA_CHANNEL_PAUSED) channels[channel].state = JA_CHANNEL_PLAYING;
} }
} }
@@ -325,13 +439,20 @@ void JA_StopChannel(const int channel)
{ {
if (!JA_soundEnabled) return; if (!JA_soundEnabled) return;
if (channel == -1) { if (channel == -1)
{
for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) { for (int i = 0; i < JA_MAX_SIMULTANEOUS_CHANNELS; i++) {
if (channels[i].state != JA_CHANNEL_FREE) SDL_DestroyAudioStream(channels[i].stream);
channels[channel].stream = nullptr;
channels[i].state = JA_CHANNEL_FREE; channels[i].state = JA_CHANNEL_FREE;
channels[i].pos = 0; channels[i].pos = 0;
channels[i].sound = NULL; channels[i].sound = NULL;
} }
} else if (channel >= 0 && channel < JA_MAX_SIMULTANEOUS_CHANNELS) { }
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].state = JA_CHANNEL_FREE;
channels[channel].pos = 0; channels[channel].pos = 0;
channels[channel].sound = NULL; channels[channel].sound = NULL;
@@ -343,12 +464,18 @@ JA_Channel_state JA_GetChannelState(const int channel)
if (!JA_soundEnabled) return JA_SOUND_DISABLED; if (!JA_soundEnabled) return JA_SOUND_DISABLED;
if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID; if (channel < 0 || channel >= JA_MAX_SIMULTANEOUS_CHANNELS) return JA_CHANNEL_INVALID;
return channels[channel].state; return channels[channel].state;
} }
int JA_SetSoundVolume(int volume) float JA_SetSoundVolume(float volume)
{ {
JA_soundVolume = volume > 128 ? 128 : volume < 0 ? 0 : 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; return JA_soundVolume;
} }
@@ -361,10 +488,10 @@ void JA_EnableSound(const bool value)
JA_soundEnabled = value; JA_soundEnabled = value;
} }
int JA_SetVolume(int volume) float JA_SetVolume(float volume)
{ {
JA_musicVolume = volume > 128 ? 128 : volume < 0 ? 0 : volume; JA_SetSoundVolume(JA_SetMusicVolume(volume) / 2.0f);
JA_soundVolume = JA_musicVolume/2;
return JA_musicVolume; return JA_musicVolume;
} }

View File

@@ -1,5 +1,5 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #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_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 }; enum JA_Music_state { JA_MUSIC_INVALID, JA_MUSIC_PLAYING, JA_MUSIC_PAUSED, JA_MUSIC_STOPPED, JA_MUSIC_DISABLED };
@@ -16,9 +16,10 @@ void JA_PlayMusic(JA_Music_t *music, const int loop = -1);
void JA_PauseMusic(); void JA_PauseMusic();
void JA_ResumeMusic(); void JA_ResumeMusic();
void JA_StopMusic(); void JA_StopMusic();
void JA_FadeOutMusic(const int milliseconds);
JA_Music_state JA_GetMusicState(); JA_Music_state JA_GetMusicState();
void JA_DeleteMusic(JA_Music_t *music); void JA_DeleteMusic(JA_Music_t *music);
int JA_SetMusicVolume(int volume); float JA_SetMusicVolume(float volume);
void JA_SetMusicPosition(float value); void JA_SetMusicPosition(float value);
float JA_GetMusicPosition(); float JA_GetMusicPosition();
void JA_EnableMusic(const bool value); void JA_EnableMusic(const bool value);
@@ -27,12 +28,13 @@ JA_Sound_t *JA_NewSound(Uint8* buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length); JA_Sound_t *JA_LoadSound(Uint8* buffer, Uint32 length);
JA_Sound_t *JA_LoadSound(const char* filename); JA_Sound_t *JA_LoadSound(const char* filename);
int JA_PlaySound(JA_Sound_t *sound, const int loop = 0); 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_PauseChannel(const int channel);
void JA_ResumeChannel(const int channel); void JA_ResumeChannel(const int channel);
void JA_StopChannel(const int channel); void JA_StopChannel(const int channel);
JA_Channel_state JA_GetChannelState(const int channel); JA_Channel_state JA_GetChannelState(const int channel);
void JA_DeleteSound(JA_Sound_t *sound); void JA_DeleteSound(JA_Sound_t *sound);
int JA_SetSoundVolume(int volume); float JA_SetSoundVolume(float volume);
void JA_EnableSound(const bool value); void JA_EnableSound(const bool value);
int JA_SetVolume(int volume); float JA_SetVolume(float volume);

View File

@@ -1,4 +1,4 @@
libs = -lSDL2 libs = -lSDL3
cppflags = -D LUA_USE_LINUX -D DEBUG -g -Wall cppflags = -D LUA_USE_LINUX -D DEBUG -g -Wall
executable = mini_debug executable = mini_debug
sourcepath = . lua sourcepath = . lua

View File

@@ -95,15 +95,15 @@ char base64glyphs[193] = "/h/AqV/hhhh/GMYYMGz/t/eS33H477wsjjswY4IOPHEFFVVVAVAVAV
"AMShAAAQsjAAAwsjAAAeSzAAAcU3AAAEqRAAABVaiAAMezhAAAAAMAADH4wAASb2SAAMAttAQYcefACGOe+AAAVVAAAAbbAA"; "AMShAAAQsjAAAwsjAAAeSzAAAcU3AAAEqRAAABVaiAAMezhAAAAAMAADH4wAASb2SAAMAttAQYcefACGOe+AAAVVAAAAbbAA";
//Uint8 keymapping[6] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_Z, SDL_SCANCODE_X }; //Uint8 keymapping[6] = { SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_Z, SDL_SCANCODE_X };
const Uint8 *keys; const bool *keys;
Uint8 key_just_pressed = 0; Uint8 key_just_pressed = 0;
int mouse_x, mouse_y, mouse_wheel; int mouse_x, mouse_y, mouse_wheel;
Uint32 mouse_buttons; Uint32 mouse_buttons;
uint8_t mouse_just_pressed = 0; uint8_t mouse_just_pressed = 0;
SDL_GameController *gamepad = NULL; SDL_Gamepad *gamepad = NULL;
int8_t pad_just_pressed = SDL_CONTROLLER_BUTTON_INVALID; int8_t pad_just_pressed = SDL_GAMEPAD_BUTTON_INVALID;
#define MAX_SOUNDS 50 #define MAX_SOUNDS 50
JA_Music_t *music = NULL; JA_Music_t *music = NULL;
@@ -182,7 +182,7 @@ void reinit() {
} }
void initaudio() { void initaudio() {
JA_Init(48000, AUDIO_S16, 1); JA_Init(48000, SDL_AUDIO_S16, 1);
for (int i=0;i<MAX_SOUNDS;++i) sounds[i] = NULL; for (int i=0;i<MAX_SOUNDS;++i) sounds[i] = NULL;
} }
@@ -300,13 +300,20 @@ void createDisplay() {
if (screen_zoom <= 0) screen_zoom = 1; if (screen_zoom <= 0) screen_zoom = 1;
while (screen_width*screen_zoom > desktop_width || screen_height*screen_zoom > desktop_height) screen_zoom--; while (screen_width*screen_zoom > desktop_width || screen_height*screen_zoom > desktop_height) screen_zoom--;
mini_win = SDL_CreateWindow(window_title, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, screen_width*screen_zoom, screen_height*screen_zoom, screen_fullscreen?SDL_WINDOW_FULLSCREEN_DESKTOP:SDL_WINDOW_RESIZABLE); mini_win = SDL_CreateWindow(window_title, screen_width*screen_zoom, screen_height*screen_zoom, screen_fullscreen?SDL_WINDOW_FULLSCREEN:SDL_WINDOW_RESIZABLE);
windowID = SDL_GetWindowID(mini_win); windowID = SDL_GetWindowID(mini_win);
mini_ren = SDL_CreateRenderer(mini_win, -1, 0); mini_ren = SDL_CreateRenderer(mini_win, NULL);
//SDL_CreateWindowAndRenderer(512,512,0,&mini_win,&mini_ren); //SDL_CreateWindowAndRenderer(512,512,0,&mini_win,&mini_ren);
SDL_RenderSetLogicalSize(mini_ren, screen_width, screen_height); //SDL_SetRenderLogicalPresentation(mini_ren, screen_width, screen_height);
SDL_ShowCursor(screen_cursor?SDL_ENABLE:SDL_DISABLE); if (screen_cursor) SDL_ShowCursor(); else SDL_HideCursor();
mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen_width, screen_height); mini_bak = SDL_CreateTexture(mini_ren, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, screen_width, screen_height);
SDL_SetTextureScaleMode(mini_bak, SDL_SCALEMODE_NEAREST);
SDL_PropertiesID props = SDL_GetTextureProperties(mini_bak);
int real_pixelformat = SDL_GetNumberProperty(props, SDL_PROP_TEXTURE_FORMAT_NUMBER, -1);
if (real_pixelformat != SDL_PIXELFORMAT_ARGB8888) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Pixelformat incorrecte: %i\n", real_pixelformat);
exit(1);
}
//SDL_GetWindowPosition(mini_win, &windowpos_x, &windowpos_y); //SDL_GetWindowPosition(mini_win, &windowpos_x, &windowpos_y);
} }
@@ -317,13 +324,14 @@ void destroyDisplay() {
} }
void initGamePad() { void initGamePad() {
const int num_joysticks = SDL_NumJoysticks(); int num_joysticks;
if (num_joysticks>=1) { SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks);
if (joysticks) {
for (int i=0; i<num_joysticks; ++i) { for (int i=0; i<num_joysticks; ++i) {
if (SDL_IsGameController(i)) { if (SDL_IsGamepad(joysticks[i])) {
gamepad = SDL_GameControllerOpen(i); gamepad = SDL_OpenGamepad(joysticks[i]);
if (SDL_GameControllerGetAttached(gamepad) == SDL_TRUE) { if (SDL_GamepadConnected(gamepad)) {
SDL_GameControllerEventState(SDL_ENABLE); SDL_SetGamepadEventsEnabled(true);
return; return;
} }
} }
@@ -334,7 +342,7 @@ void initGamePad() {
int main(int argc,char*argv[]){ int main(int argc,char*argv[]){
#ifdef DEBUG #ifdef DEBUG
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG); SDL_SetLogPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_DEBUG);
#endif #endif
if (argc>1) if (argc>1)
@@ -383,16 +391,16 @@ int main(int argc,char*argv[]){
setdest(newsurf(screen_width, screen_height)); setdest(newsurf(screen_width, screen_height));
SDL_Init(SDL_INIT_EVERYTHING); SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD);
SDL_DisplayMode dm; const SDL_DisplayMode *dm = SDL_GetDesktopDisplayMode(SDL_GetPrimaryDisplay());
if (SDL_GetDesktopDisplayMode(0, &dm) != 0) if (!dm)
{ {
SDL_Log("SDL_GetDesktopDisplayMode failed: %s", SDL_GetError()); SDL_Log("SDL_GetDesktopDisplayMode failed: %s", SDL_GetError());
return 1; return 1;
} }
desktop_width = dm.w; desktop_width = dm->w;
desktop_height = dm.h; desktop_height = dm->h;
createDisplay(); createDisplay();
@@ -412,15 +420,15 @@ int main(int argc,char*argv[]){
Uint32 dt=SDL_GetTicks(); Uint32 dt=SDL_GetTicks();
key_just_pressed = 0; key_just_pressed = 0;
pad_just_pressed = SDL_CONTROLLER_BUTTON_INVALID; pad_just_pressed = SDL_GAMEPAD_BUTTON_INVALID;
mouse_just_pressed = 0; mouse_just_pressed = 0;
while(!should_exit) { while(!should_exit) {
mouse_wheel = 0; mouse_wheel = 0;
if (update_mode==UPDATE_WAIT) SDL_WaitEvent(NULL); if (update_mode==UPDATE_WAIT) SDL_WaitEvent(NULL);
else if (update_mode==UPDATE_TIMEOUT) SDL_WaitEventTimeout(NULL, timeout); else if (update_mode==UPDATE_TIMEOUT) SDL_WaitEventTimeout(NULL, timeout);
while(SDL_PollEvent(&mini_eve)) { while(SDL_PollEvent(&mini_eve)) {
if (mini_eve.type == SDL_QUIT) { should_exit=true; should_quit=true; break; } if (mini_eve.type == SDL_EVENT_QUIT) { should_exit=true; should_quit=true; break; }
if (mini_eve.type == SDL_KEYDOWN) { if (mini_eve.type == SDL_EVENT_KEY_DOWN) {
/* /*
if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F2) { if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F2) {
screen_zoom+=2; if (screen_zoom>=10) screen_zoom=2; screen_zoom+=2; if (screen_zoom>=10) screen_zoom=2;
@@ -436,7 +444,7 @@ int main(int argc,char*argv[]){
} }
*/ */
#ifdef DEBUG #ifdef DEBUG
if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F12) { if (mini_eve.key.scancode == SDL_SCANCODE_F12) {
if (lua_is_playing()) { if (lua_is_playing()) {
lua_quit(); lua_quit();
quitaudio(); quitaudio();
@@ -444,23 +452,23 @@ int main(int argc,char*argv[]){
} else { } else {
should_exit=true; should_exit=true;
} }
} else if (mini_eve.key.keysym.scancode == SDL_SCANCODE_F5) { } else if (mini_eve.key.scancode == SDL_SCANCODE_F5) {
should_exit=true; should_exit=true;
} else { } else {
key_just_pressed = mini_eve.key.keysym.scancode; key_just_pressed = mini_eve.key.scancode;
} }
#else #else
key_just_pressed = mini_eve.key.keysym.scancode; key_just_pressed = mini_eve.key.scancode;
#endif #endif
} }
if (mini_eve.type == SDL_MOUSEBUTTONUP) { if (mini_eve.type == SDL_EVENT_MOUSE_BUTTON_UP) {
mouse_just_pressed = mini_eve.button.button; mouse_just_pressed = mini_eve.button.button;
} }
if (mini_eve.type == SDL_MOUSEWHEEL) { if (mini_eve.type == SDL_EVENT_MOUSE_WHEEL) {
mouse_wheel = mini_eve.wheel.y; mouse_wheel = mini_eve.wheel.y;
} }
if (mini_eve.type == SDL_CONTROLLERBUTTONDOWN) { if (mini_eve.type == SDL_EVENT_GAMEPAD_BUTTON_DOWN) {
pad_just_pressed = mini_eve.cbutton.button; pad_just_pressed = mini_eve.gbutton.button;
} }
/*if ( (mini_eve.type == SDL_WINDOWEVENT) && /*if ( (mini_eve.type == SDL_WINDOWEVENT) &&
(mini_eve.window.windowID == windowID) && (mini_eve.window.windowID == windowID) &&
@@ -471,10 +479,10 @@ int main(int argc,char*argv[]){
}*/ }*/
} }
keys = SDL_GetKeyboardState(NULL); keys = SDL_GetKeyboardState(NULL);
int real_mouse_x, real_mouse_y; float real_mouse_x, real_mouse_y;
mouse_buttons = SDL_GetMouseState(&real_mouse_x, &real_mouse_y); mouse_buttons = SDL_GetMouseState(&real_mouse_x, &real_mouse_y);
float mx, my; float mx, my;
SDL_RenderWindowToLogical(mini_ren, real_mouse_x, real_mouse_y, &mx, &my); SDL_RenderCoordinatesFromWindow(mini_ren, real_mouse_x, real_mouse_y, &mx, &my);
mouse_x = int(mx); mouse_x = int(mx);
mouse_y = int(my); mouse_y = int(my);
//mouse_x /= screen_zoom; mouse_y /= screen_zoom; //mouse_x /= screen_zoom; mouse_y /= screen_zoom;
@@ -490,14 +498,14 @@ int main(int argc,char*argv[]){
if (beats>0)beats--; if (beats>0)beats--;
key_just_pressed = 0; key_just_pressed = 0;
mouse_just_pressed = 0; mouse_just_pressed = 0;
pad_just_pressed = SDL_CONTROLLER_BUTTON_INVALID; pad_just_pressed = SDL_GAMEPAD_BUTTON_INVALID;
} }
SDL_SetRenderDrawColor(mini_ren, 0, 0, 0, 255); SDL_SetRenderDrawColor(mini_ren, 0, 0, 0, 255);
SDL_RenderClear(mini_ren); SDL_RenderClear(mini_ren);
SDL_LockTexture(mini_bak, NULL, (void**)&pixels, &pitch); SDL_LockTexture(mini_bak, NULL, (void**)&pixels, &pitch);
for (uint32_t i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]]; for (uint32_t i=0;i<screen_surface->size;++i) pixels[i] = palette[screen_surface->p[i]];
SDL_UnlockTexture(mini_bak); SDL_UnlockTexture(mini_bak);
SDL_RenderCopy(mini_ren, mini_bak, NULL, NULL); SDL_RenderTexture(mini_ren, mini_bak, NULL, NULL);
SDL_RenderPresent(mini_ren); SDL_RenderPresent(mini_ren);
fps_counter++; fps_counter++;
if (SDL_GetTicks()>=(fps_timer+1000)) { if (SDL_GetTicks()>=(fps_timer+1000)) {
@@ -1123,7 +1131,7 @@ bool anykey() {
bool pad(int8_t i) { bool pad(int8_t i) {
if (!gamepad) return false; if (!gamepad) return false;
return SDL_GameControllerGetButton(gamepad, SDL_GameControllerButton(i)) == 1; return SDL_GetGamepadButton(gamepad, SDL_GamepadButton(i)) == 1;
} }
bool padp(int8_t i) { bool padp(int8_t i) {
@@ -1152,7 +1160,7 @@ int mwheel() {
} }
bool mbtn(uint8_t i) { bool mbtn(uint8_t i) {
return mouse_buttons & SDL_BUTTON(i); return mouse_buttons & SDL_BUTTON_MASK(i);
} }
bool mbtnp(uint8_t i) { bool mbtnp(uint8_t i) {
@@ -1273,7 +1281,7 @@ bool getcursor() {
void setcursor(const bool value) { void setcursor(const bool value) {
screen_cursor=value; screen_cursor=value;
SDL_ShowCursor(screen_cursor?SDL_ENABLE:SDL_DISABLE); if (screen_cursor) SDL_ShowCursor(); else SDL_HideCursor();
} }
const char* getconfig(const char* key) { const char* getconfig(const char* key) {

2
mini.h
View File

@@ -1,6 +1,6 @@
#pragma once #pragma once
#include <SDL2/SDL.h> #include <SDL3/SDL.h>
#include "version.h" #include "version.h"

View File

@@ -1,3 +1,3 @@
#pragma once #pragma once
#define MINI_VERSION "1.1" #define MINI_VERSION "1.2"