mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
switched audio from miniaudio to SDL_mixer
This commit is contained in:
parent
9accbbeea7
commit
be16a68e85
10 changed files with 231 additions and 324 deletions
|
|
@ -1,294 +1,29 @@
|
|||
/*
|
||||
Demonstrates how to load a sound file and play it back using the low-level API.
|
||||
|
||||
The low-level API uses a callback to deliver audio between the application and miniaudio for playback or recording. When
|
||||
in playback mode, as in this example, the application sends raw audio data to miniaudio which is then played back through
|
||||
the default playback device as defined by the operating system.
|
||||
|
||||
This example uses the `ma_decoder` API to load a sound and play it back. The decoder is entirely decoupled from the
|
||||
device and can be used independently of it. This example only plays back a single sound file, but it's possible to play
|
||||
back multiple files by simple loading multiple decoders and mixing them (do not create multiple devices to do this). See
|
||||
the simple_mixing example for how best to do this.
|
||||
*/
|
||||
|
||||
#define STB_VORBIS_HEADER_ONLY
|
||||
#include "stb_vorbis.c"
|
||||
|
||||
|
||||
#define MINIAUDIO_IMPLEMENTATION
|
||||
#include "miniaudio.h"
|
||||
|
||||
#include <functional>
|
||||
#include <stdio.h>
|
||||
#include "audio_player.h"
|
||||
|
||||
// #define MA_NO_LIBOPUS
|
||||
// #include "miniaudio_libvorbis.h"
|
||||
// #include "miniaudio_libopus.h"
|
||||
|
||||
#include <SDL3_mixer/SDL_mixer.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#if 0
|
||||
|
||||
static ma_result ma_decoding_backend_init__libvorbis(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend)
|
||||
{
|
||||
ma_result result;
|
||||
ma_libvorbis* pVorbis;
|
||||
static int audio_open = 0;
|
||||
static Mix_Music *music = NULL;
|
||||
static int next_track = 0;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks);
|
||||
if (pVorbis == NULL) {
|
||||
return MA_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = ma_libvorbis_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pVorbis);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_free(pVorbis, pAllocationCallbacks);
|
||||
return result;
|
||||
}
|
||||
|
||||
*ppBackend = pVorbis;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
static ma_result ma_decoding_backend_init_file__libvorbis(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend)
|
||||
{
|
||||
ma_result result;
|
||||
ma_libvorbis* pVorbis;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
pVorbis = (ma_libvorbis*)ma_malloc(sizeof(*pVorbis), pAllocationCallbacks);
|
||||
if (pVorbis == NULL) {
|
||||
return MA_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = ma_libvorbis_init_file(pFilePath, pConfig, pAllocationCallbacks, pVorbis);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_free(pVorbis, pAllocationCallbacks);
|
||||
return result;
|
||||
}
|
||||
|
||||
*ppBackend = pVorbis;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
static void ma_decoding_backend_uninit__libvorbis(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks)
|
||||
{
|
||||
ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
ma_libvorbis_uninit(pVorbis, pAllocationCallbacks);
|
||||
ma_free(pVorbis, pAllocationCallbacks);
|
||||
}
|
||||
|
||||
static ma_result ma_decoding_backend_get_channel_map__libvorbis(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap)
|
||||
{
|
||||
ma_libvorbis* pVorbis = (ma_libvorbis*)pBackend;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
return ma_libvorbis_get_data_format(pVorbis, NULL, NULL, NULL, pChannelMap, channelMapCap);
|
||||
}
|
||||
|
||||
static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libvorbis =
|
||||
{
|
||||
ma_decoding_backend_init__libvorbis,
|
||||
ma_decoding_backend_init_file__libvorbis,
|
||||
NULL, /* onInitFileW() */
|
||||
NULL, /* onInitMemory() */
|
||||
ma_decoding_backend_uninit__libvorbis
|
||||
};
|
||||
|
||||
|
||||
|
||||
static ma_result ma_decoding_backend_init__libopus(void* pUserData, ma_read_proc onRead, ma_seek_proc onSeek, ma_tell_proc onTell, void* pReadSeekTellUserData, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend)
|
||||
{
|
||||
ma_result result;
|
||||
ma_libopus* pOpus;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
pOpus = (ma_libopus*)ma_malloc(sizeof(*pOpus), pAllocationCallbacks);
|
||||
if (pOpus == NULL) {
|
||||
return MA_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = ma_libopus_init(onRead, onSeek, onTell, pReadSeekTellUserData, pConfig, pAllocationCallbacks, pOpus);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_free(pOpus, pAllocationCallbacks);
|
||||
return result;
|
||||
}
|
||||
|
||||
*ppBackend = pOpus;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
static ma_result ma_decoding_backend_init_file__libopus(void* pUserData, const char* pFilePath, const ma_decoding_backend_config* pConfig, const ma_allocation_callbacks* pAllocationCallbacks, ma_data_source** ppBackend)
|
||||
{
|
||||
ma_result result;
|
||||
ma_libopus* pOpus;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
pOpus = (ma_libopus*)ma_malloc(sizeof(*pOpus), pAllocationCallbacks);
|
||||
if (pOpus == NULL) {
|
||||
return MA_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = ma_libopus_init_file(pFilePath, pConfig, pAllocationCallbacks, pOpus);
|
||||
if (result != MA_SUCCESS) {
|
||||
ma_free(pOpus, pAllocationCallbacks);
|
||||
return result;
|
||||
}
|
||||
|
||||
*ppBackend = pOpus;
|
||||
|
||||
return MA_SUCCESS;
|
||||
}
|
||||
|
||||
static void ma_decoding_backend_uninit__libopus(void* pUserData, ma_data_source* pBackend, const ma_allocation_callbacks* pAllocationCallbacks)
|
||||
{
|
||||
ma_libopus* pOpus = (ma_libopus*)pBackend;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
ma_libopus_uninit(pOpus, pAllocationCallbacks);
|
||||
ma_free(pOpus, pAllocationCallbacks);
|
||||
}
|
||||
|
||||
static ma_result ma_decoding_backend_get_channel_map__libopus(void* pUserData, ma_data_source* pBackend, ma_channel* pChannelMap, size_t channelMapCap)
|
||||
{
|
||||
ma_libopus* pOpus = (ma_libopus*)pBackend;
|
||||
|
||||
(void)pUserData;
|
||||
|
||||
return ma_libopus_get_data_format(pOpus, NULL, NULL, NULL, pChannelMap, channelMapCap);
|
||||
}
|
||||
|
||||
static ma_decoding_backend_vtable g_ma_decoding_backend_vtable_libopus =
|
||||
{
|
||||
ma_decoding_backend_init__libopus,
|
||||
ma_decoding_backend_init_file__libopus,
|
||||
NULL, /* onInitFileW() */
|
||||
NULL, /* onInitMemory() */
|
||||
ma_decoding_backend_uninit__libopus
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
// {
|
||||
// ma_data_source* pDataSource = (ma_data_source*)pDevice->pUserData;
|
||||
// if (pDataSource == NULL) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ma_data_source_read_pcm_frames(pDataSource, pOutput, frameCount, NULL);
|
||||
|
||||
// (void)pInput;
|
||||
// }
|
||||
SDL_AudioSpec spec;
|
||||
|
||||
|
||||
static ThreadSafeQueue<AudioCommand> g_audioQueue;
|
||||
static ma_decoder decoder;
|
||||
static ma_device device;
|
||||
|
||||
void data_callback(ma_device* pDevice, void* pOutput, const void* pInput, ma_uint32 frameCount)
|
||||
|
||||
void music_finished()
|
||||
{
|
||||
ma_decoder* pDecoder = (ma_decoder*)pDevice->pUserData;
|
||||
if (pDecoder == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ma_uint64 framesRead;
|
||||
ma_result result = ma_decoder_read_pcm_frames(pDecoder, pOutput, frameCount, &framesRead);
|
||||
|
||||
|
||||
if (result == MA_AT_END) {
|
||||
Mix_FreeMusic(music);
|
||||
music = NULL;
|
||||
g_audioQueue.push({"end", ""});
|
||||
}
|
||||
// if (framesRead < frameCount) {
|
||||
// // Reached the end.
|
||||
// ma_event_signal(&g_stopEvent);
|
||||
// }
|
||||
|
||||
(void)pInput;
|
||||
}
|
||||
|
||||
|
||||
static int miniaudio_play(const char* filename)
|
||||
{
|
||||
ma_result result;
|
||||
ma_device_config deviceConfig;
|
||||
short *output = NULL;
|
||||
|
||||
result = ma_decoder_init_file(filename, NULL, &decoder);
|
||||
if (result != MA_SUCCESS)
|
||||
{
|
||||
printf("Could not load file: %s\n", filename);
|
||||
|
||||
// Try OGG (FIXME: plus tard, utiliser l'extension pour choisir le décodeur)
|
||||
int channels = 0, sample_rate = 0;
|
||||
|
||||
int sample_count = stb_vorbis_decode_filename("chemin/vers/fichier.ogg", &channels, &sample_rate, &output);
|
||||
if (sample_count == -1)
|
||||
{
|
||||
printf("Erreur de décodage du fichier Vorbis\n");
|
||||
return -2;
|
||||
}
|
||||
|
||||
ma_device_config deviceConfig = ma_device_config_init(ma_device_type_playback);
|
||||
deviceConfig.playback.format = ma_format_s16;
|
||||
deviceConfig.playback.channels = channels;
|
||||
deviceConfig.sampleRate = sample_rate;
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
deviceConfig.pUserData = &decoder;
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceConfig = ma_device_config_init(ma_device_type_playback);
|
||||
deviceConfig.playback.format = decoder.outputFormat;
|
||||
deviceConfig.playback.channels = decoder.outputChannels;
|
||||
deviceConfig.sampleRate = decoder.outputSampleRate;
|
||||
deviceConfig.dataCallback = data_callback;
|
||||
deviceConfig.pUserData = &decoder;
|
||||
}
|
||||
|
||||
if (ma_device_init(NULL, &deviceConfig, &device) != MA_SUCCESS) {
|
||||
printf("Failed to open playback device.\n");
|
||||
ma_decoder_uninit(&decoder);
|
||||
if (output != NULL)
|
||||
{
|
||||
free(output);
|
||||
}
|
||||
return -3;
|
||||
}
|
||||
|
||||
if (ma_device_start(&device) != MA_SUCCESS) {
|
||||
printf("Failed to start playback device.\n");
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
if (output != NULL)
|
||||
{
|
||||
free(output);
|
||||
}
|
||||
return -4;
|
||||
}
|
||||
|
||||
if (output != NULL)
|
||||
{
|
||||
free(output);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AudioPlayer::AudioPlayer(IAudioEvent &event)
|
||||
: m_event(event)
|
||||
|
|
@ -296,6 +31,33 @@ AudioPlayer::AudioPlayer(IAudioEvent &event)
|
|||
m_audioThread = std::thread( std::bind(&AudioPlayer::AudioThread, this) );
|
||||
}
|
||||
|
||||
void AudioPlayer::Initialize()
|
||||
{
|
||||
/* Initialize variables */
|
||||
spec.freq = MIX_DEFAULT_FREQUENCY;
|
||||
spec.format = MIX_DEFAULT_FORMAT;
|
||||
spec.channels = MIX_DEFAULT_CHANNELS;
|
||||
|
||||
if (Mix_Init(MIX_INIT_FLAC | MIX_INIT_MP3 | MIX_INIT_OGG) < 0) {
|
||||
return ;
|
||||
}
|
||||
|
||||
if (Mix_OpenAudio(0, &spec) < 0) {
|
||||
SDL_Log("Couldn't open audio: %s\n", SDL_GetError());
|
||||
return;
|
||||
} else {
|
||||
Mix_QuerySpec(&spec.freq, &spec.format, &spec.channels);
|
||||
SDL_Log("Opened audio at %d Hz %d bit%s %s audio buffer\n", spec.freq,
|
||||
(spec.format&0xFF),
|
||||
(SDL_AUDIO_ISFLOAT(spec.format) ? " (float)" : ""),
|
||||
(spec.channels > 2) ? "surround" : (spec.channels > 1) ? "stereo" : "mono");
|
||||
}
|
||||
audio_open = 1;
|
||||
|
||||
Mix_HookMusicFinished(music_finished);
|
||||
|
||||
}
|
||||
|
||||
void AudioPlayer::Play(const std::string &filename)
|
||||
{
|
||||
g_audioQueue.push({"play", filename});
|
||||
|
|
@ -304,6 +66,7 @@ void AudioPlayer::Play(const std::string &filename)
|
|||
AudioPlayer::~AudioPlayer()
|
||||
{
|
||||
// Quit audio thread
|
||||
g_audioQueue.clear();
|
||||
g_audioQueue.push({"quit", ""});
|
||||
if (m_audioThread.joinable())
|
||||
{
|
||||
|
|
@ -311,12 +74,13 @@ AudioPlayer::~AudioPlayer()
|
|||
}
|
||||
}
|
||||
|
||||
void AudioPlayer::CloseAudio()
|
||||
void AudioPlayer::Stop()
|
||||
{
|
||||
ma_device_uninit(&device);
|
||||
ma_decoder_uninit(&decoder);
|
||||
g_audioQueue.clear();
|
||||
g_audioQueue.push({"end", ""});
|
||||
}
|
||||
|
||||
|
||||
#define AUDIO_STATE_WAIT_PLAY 1
|
||||
#define AUDIO_STATE_WAIT_END 2
|
||||
|
||||
|
|
@ -328,7 +92,8 @@ void AudioPlayer::AudioThread()
|
|||
auto cmd = g_audioQueue.front();
|
||||
g_audioQueue.pop();
|
||||
|
||||
if (cmd.order == "quit") {
|
||||
if (cmd.order == "quit")
|
||||
{
|
||||
return;
|
||||
}
|
||||
else if (cmd.order == "play")
|
||||
|
|
@ -336,7 +101,12 @@ void AudioPlayer::AudioThread()
|
|||
if (state == AUDIO_STATE_WAIT_PLAY)
|
||||
{
|
||||
state = AUDIO_STATE_WAIT_END;
|
||||
miniaudio_play(cmd.filename.c_str());
|
||||
music = Mix_LoadMUS(cmd.filename.c_str());
|
||||
|
||||
if (music)
|
||||
{
|
||||
Mix_PlayMusic(music, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (cmd.order == "end")
|
||||
|
|
@ -344,7 +114,8 @@ void AudioPlayer::AudioThread()
|
|||
if (state == AUDIO_STATE_WAIT_END)
|
||||
{
|
||||
state = AUDIO_STATE_WAIT_PLAY;
|
||||
CloseAudio();
|
||||
Mix_HaltMusic();
|
||||
Mix_FreeMusic(music);
|
||||
m_event.EndOfAudio();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#ifndef AUDIO_PLAYER_H
|
||||
#define AUDIO_PLAYER_H
|
||||
|
||||
#include "miniaudio.h"
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
|
|
@ -34,6 +33,8 @@ public:
|
|||
~AudioPlayer();
|
||||
|
||||
void Play(const std::string &filename);
|
||||
void Stop();
|
||||
void Initialize();
|
||||
|
||||
private:
|
||||
IAudioEvent &m_event;
|
||||
|
|
@ -41,7 +42,7 @@ private:
|
|||
std::thread m_audioThread;
|
||||
|
||||
void AudioThread();
|
||||
void CloseAudio();
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@ public:
|
|||
queue.pop();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
std::lock_guard lock(mutex);
|
||||
while(!queue.empty()) {
|
||||
queue.pop();
|
||||
}
|
||||
}
|
||||
|
||||
bool try_pop(T& popped_item) {
|
||||
std::unique_lock lock(mutex);
|
||||
|
||||
|
|
|
|||
|
|
@ -126,6 +126,25 @@ FetchContent_MakeAvailable(sdl3)
|
|||
include_directories(${sdl3_SOURCE_DIR}/include)
|
||||
# add_subdirectory(${sdl3_SOURCE_DIR})
|
||||
|
||||
# =========================================================================================================================
|
||||
# SDL3 MIXER
|
||||
# =========================================================================================================================
|
||||
FetchContent_Declare(
|
||||
sdl3_mixer
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git
|
||||
GIT_TAG ace2d37796d2541123cdcbc06dce0b716a0416ad
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
GIT_SUBMODULES ""
|
||||
)
|
||||
|
||||
set(BUILD_SHARED_LIBS TRUE)
|
||||
set(SDL_PULSEAUDIO_SHARED TRUE)
|
||||
set(SDL_PIPEWIRE_SHARED TRUE)
|
||||
FetchContent_MakeAvailable(sdl3_mixer)
|
||||
include_directories(${sdl3_mixer_SOURCE_DIR}/include)
|
||||
|
||||
|
||||
# =========================================================================================================================
|
||||
# SDL3-Image
|
||||
# =========================================================================================================================
|
||||
|
|
@ -326,6 +345,7 @@ if(UNIX)
|
|||
dl
|
||||
SDL3::SDL3
|
||||
SDL3_image::SDL3_image
|
||||
SDL3_mixer::SDL3_mixer
|
||||
libcurl_static
|
||||
# OpenSSL::SSL OpenSSL::Crypto
|
||||
)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,18 @@ Gui::Gui()
|
|||
std::cout << "PATH: " << m_executablePath << std::endl;
|
||||
}
|
||||
|
||||
static ImFont* normalFont;
|
||||
// static ImFont* bigFont;
|
||||
|
||||
void Gui::PushBigFont()
|
||||
{
|
||||
// ImGui::PushFont(bigFont);
|
||||
}
|
||||
|
||||
void Gui::PopBigFont()
|
||||
{
|
||||
// ImGui::PopFont();
|
||||
}
|
||||
|
||||
bool Gui::Initialize()
|
||||
{
|
||||
|
|
@ -112,11 +124,29 @@ bool Gui::Initialize()
|
|||
// if (SDL_Init(SDL_INIT_EVERYTHING) != 0)
|
||||
|
||||
// Setup SDL3
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_GAMEPAD) != 0)
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||
{
|
||||
printf("Error: SDL_Init(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
/*
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) != 0)
|
||||
{
|
||||
int i, num_devices;
|
||||
SDL_AudioDeviceID *devices = SDL_GetAudioOutputDevices(&num_devices);
|
||||
if (devices) {
|
||||
for (i = 0; i < num_devices; ++i) {
|
||||
SDL_AudioDeviceID instance_id = devices[i];
|
||||
char *name = SDL_GetAudioDeviceName(instance_id);
|
||||
SDL_Log("AudioDevice %" SDL_PRIu32 ": %s\n", instance_id, name);
|
||||
SDL_free(name);
|
||||
}
|
||||
SDL_free(devices);
|
||||
}
|
||||
|
||||
printf("Error: SDL_InitSubSystem(): %s\n", SDL_GetError());
|
||||
return false;
|
||||
}*/
|
||||
|
||||
// Enable native IME.
|
||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
||||
|
|
@ -133,13 +163,13 @@ bool Gui::Initialize()
|
|||
if (window == nullptr)
|
||||
{
|
||||
printf("Error: SDL_CreateWindow(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
renderer = SDL_CreateRenderer(window, nullptr, SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_ACCELERATED);
|
||||
if (renderer == nullptr)
|
||||
{
|
||||
SDL_Log("Error: SDL_CreateRenderer(): %s\n", SDL_GetError());
|
||||
return -1;
|
||||
return false;
|
||||
}
|
||||
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
|
||||
SDL_ShowWindow(window);
|
||||
|
|
@ -155,7 +185,9 @@ bool Gui::Initialize()
|
|||
io.ConfigFlags |= ImGuiConfigFlags_ViewportsEnable;
|
||||
|
||||
|
||||
io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 20);
|
||||
// bigFont = io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 40);
|
||||
// io.Fonts->Build();
|
||||
normalFont = io.Fonts->AddFontFromFileTTF( std::string(m_executablePath + "/fonts/roboto.ttf").c_str(), 20);
|
||||
|
||||
{
|
||||
ImFontConfig config;
|
||||
|
|
|
|||
|
|
@ -47,8 +47,12 @@ public:
|
|||
static bool LoadRawImage(const std::string &filename, Image &image);
|
||||
static Size GetWindowSize();
|
||||
|
||||
static void PushBigFont();
|
||||
static void PopBigFont();
|
||||
|
||||
private:
|
||||
std::string m_executablePath;
|
||||
|
||||
};
|
||||
|
||||
// namespace ImGui {
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ int main(int, char**)
|
|||
{
|
||||
|
||||
MainWindow w;
|
||||
w.Initialize();
|
||||
|
||||
if (w.Initialize())
|
||||
{
|
||||
w.Loop();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -256,13 +256,15 @@ void MainWindow::DrawStatusBar()
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
void MainWindow::DrawMainMenuBar()
|
||||
float MainWindow::DrawMainMenuBar()
|
||||
{
|
||||
bool showAboutPopup = false;
|
||||
bool showParameters = false;
|
||||
bool showNewProject = false;
|
||||
bool showOpenProject = false;
|
||||
|
||||
float height = 60;
|
||||
|
||||
if (ImGui::BeginMainMenuBar())
|
||||
{
|
||||
if (ImGui::BeginMenu("File"))
|
||||
|
|
@ -333,6 +335,8 @@ void MainWindow::DrawMainMenuBar()
|
|||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
|
||||
height = ImGui::GetFrameHeight();
|
||||
ImGui::EndMainMenuBar();
|
||||
}
|
||||
|
||||
|
|
@ -380,14 +384,19 @@ void MainWindow::DrawMainMenuBar()
|
|||
}
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void MainWindow::Initialize()
|
||||
bool MainWindow::Initialize()
|
||||
{
|
||||
bool success = false;
|
||||
LoadParams();
|
||||
|
||||
// GUI Init
|
||||
m_gui.Initialize();
|
||||
if (m_gui.Initialize())
|
||||
{
|
||||
m_player.Initialize(); // Initialize audio after GUI (uses SDL)
|
||||
// gui.ApplyTheme();
|
||||
|
||||
m_editorWindow.Initialize();
|
||||
|
|
@ -395,6 +404,11 @@ void MainWindow::Initialize()
|
|||
m_nodeEditorWindow.Initialize();
|
||||
m_PropertiesWindow.Initialize();
|
||||
m_libraryWindow.Initialize();
|
||||
|
||||
success = true;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -591,20 +605,20 @@ void MainWindow::ProjectPropertiesPopup()
|
|||
}
|
||||
|
||||
|
||||
auto GetImageFormat = [](int idx) -> StoryProject::ImageFormat
|
||||
auto GetImageFormat = [](int idx) -> Resource::ImageFormat
|
||||
{
|
||||
StoryProject::ImageFormat img{StoryProject::IMG_SAME_FORMAT};
|
||||
if (idx < StoryProject::IMG_FORMAT_COUNT) {
|
||||
img = static_cast<StoryProject::ImageFormat>(idx);
|
||||
Resource::ImageFormat img{Resource::IMG_SAME_FORMAT};
|
||||
if (idx < Resource::IMG_FORMAT_COUNT) {
|
||||
img = static_cast<Resource::ImageFormat>(idx);
|
||||
}
|
||||
return img;
|
||||
};
|
||||
|
||||
auto GetSoundFormat = [](int idx) -> StoryProject::SoundFormat {
|
||||
auto GetSoundFormat = [](int idx) -> Resource::SoundFormat {
|
||||
|
||||
StoryProject::SoundFormat img{StoryProject::SND_FORMAT_WAV};
|
||||
if (idx < StoryProject::IMG_FORMAT_COUNT) {
|
||||
img = static_cast<StoryProject::SoundFormat>(idx);
|
||||
Resource::SoundFormat img{Resource::SND_FORMAT_WAV};
|
||||
if (idx < Resource::IMG_FORMAT_COUNT) {
|
||||
img = static_cast<Resource::SoundFormat>(idx);
|
||||
}
|
||||
|
||||
return img;
|
||||
|
|
@ -652,6 +666,11 @@ void MainWindow::OpenProject(const std::string &uuid)
|
|||
CloseProject();
|
||||
m_story = m_libraryManager.GetStory(uuid);
|
||||
|
||||
// DEBUG CODE !!!!!!!!!!!!! Permet si décommenter de forcer l'import, permet de tester plus facilement l'algo en ouvrant le projet
|
||||
// PackArchive arch(*this);
|
||||
// std::string basePath = m_libraryManager.LibraryPath() + "/" + uuid;
|
||||
// arch.ConvertJsonStudioToOst(basePath, uuid, m_libraryManager.LibraryPath());
|
||||
|
||||
if (!m_story)
|
||||
{
|
||||
Log("Cannot find story: " + uuid);
|
||||
|
|
@ -712,11 +731,11 @@ void MainWindow::RefreshProjectInformation()
|
|||
|
||||
void MainWindow::CloseProject()
|
||||
{
|
||||
if (m_story)
|
||||
{
|
||||
m_story->Clear();
|
||||
m_story.reset();
|
||||
}
|
||||
// if (m_story)
|
||||
// {
|
||||
// m_story->Clear();
|
||||
// m_story.reset();
|
||||
// }
|
||||
|
||||
m_resources.Clear();
|
||||
|
||||
|
|
@ -736,7 +755,43 @@ void MainWindow::CloseProject()
|
|||
}
|
||||
|
||||
|
||||
void MainWindow::DrawToolBar(float topPadding)
|
||||
{
|
||||
ImGuiWindowFlags window_flags = ImGuiWindowFlags_NoDecoration |
|
||||
ImGuiWindowFlags_NoMove |
|
||||
ImGuiWindowFlags_NoScrollbar |
|
||||
ImGuiWindowFlags_NoScrollWithMouse |
|
||||
ImGuiWindowFlags_NoDocking;
|
||||
|
||||
// Définit la taille et la position de la barre d'outils
|
||||
ImVec2 size = ImVec2(60, ImGui::GetIO().DisplaySize.y - topPadding); // Largeur de 60 pixels et hauteur égale à celle de l'écran
|
||||
ImGui::SetNextWindowSize(size);
|
||||
ImGui::SetNextWindowPos(ImVec2(0, topPadding)); // Positionné à gauche et en haut
|
||||
|
||||
// Création de la fenêtre pour la barre d'outils
|
||||
ImGui::Begin("ToolBar", nullptr, window_flags);
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.0f, 0.0f, 1.0f)); // rouge
|
||||
float old_size = ImGui::GetFont()->Scale;
|
||||
ImGui::GetFont()->Scale *= 2.5;
|
||||
|
||||
ImGui::PushFont(ImGui::GetFont());
|
||||
|
||||
// Ajouter des boutons à la barre d'outils
|
||||
if (ImGui::Button(ICON_MDI_SPEAKER_STOP "##stop_sound", ImVec2(-1, 50))) { // Le bouton prend toute la largeur de la fenêtre et a une hauteur de 50 pixels
|
||||
m_player.Stop();
|
||||
}
|
||||
|
||||
ImGui::GetFont()->Scale = old_size;
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
|
||||
// Fermeture de la fenêtre ImGui
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
#include "imgui_internal.h"
|
||||
void MainWindow::Loop()
|
||||
{
|
||||
// Main loop
|
||||
|
|
@ -749,14 +804,21 @@ void MainWindow::Loop()
|
|||
|
||||
m_gui.StartFrame();
|
||||
|
||||
ImGui::DockSpaceOverViewport(ImGui::GetMainViewport());
|
||||
DrawMainMenuBar();
|
||||
auto vp = ImGui::GetMainViewport();
|
||||
|
||||
auto pos = vp->WorkPos;
|
||||
auto size = vp->WorkSize;
|
||||
pos.x += 60;
|
||||
size.x -= 60;
|
||||
vp->WorkPos = pos;
|
||||
vp->WorkSize = size;
|
||||
ImGui::DockSpaceOverViewport(vp);
|
||||
float height = DrawMainMenuBar();
|
||||
|
||||
// DrawStatusBar();
|
||||
|
||||
|
||||
ProcessStory();
|
||||
|
||||
|
||||
// ------------ Draw all windows
|
||||
m_libraryWindow.Draw();
|
||||
|
||||
|
|
@ -771,6 +833,12 @@ void MainWindow::Loop()
|
|||
|
||||
m_PropertiesWindow.SetSelectedNode(m_nodeEditorWindow.GetSelectedNode());
|
||||
m_PropertiesWindow.Draw();
|
||||
|
||||
|
||||
// static ImGuiAxis toolbar2_axis = ImGuiAxis_Y;
|
||||
// DockingToolbar("Toolbar2", &toolbar2_axis);
|
||||
|
||||
DrawToolBar(height);
|
||||
}
|
||||
|
||||
ProjectPropertiesPopup();
|
||||
|
|
@ -863,7 +931,7 @@ void MainWindow::Build(bool compileonly)
|
|||
if (!compileonly)
|
||||
{
|
||||
// 3. Convert all media to desired type format
|
||||
m_resources.ConvertResources(m_story->AssetsPath(), ""); // pas de répertoire de destination
|
||||
m_resources.ConvertResources(m_story->AssetsPath(), "", m_story->GetImageFormat(), m_story->GetSoundFormat()); // pas de répertoire de destination
|
||||
}
|
||||
|
||||
Chip32::Assembler::Error err;
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ public:
|
|||
MainWindow();
|
||||
~MainWindow();
|
||||
|
||||
void Initialize();
|
||||
bool Initialize();
|
||||
void Loop();
|
||||
|
||||
private:
|
||||
|
|
@ -155,8 +155,9 @@ private:
|
|||
void SaveParams();
|
||||
void LoadParams();
|
||||
|
||||
void DrawMainMenuBar();
|
||||
float DrawMainMenuBar();
|
||||
bool ShowQuitConfirm();
|
||||
void DrawToolBar(float topPadding);
|
||||
|
||||
void SaveProject();
|
||||
void CloseProject();
|
||||
|
|
|
|||
|
|
@ -37,7 +37,9 @@ NodeEditorWindow::~NodeEditorWindow()
|
|||
void NodeEditorWindow::Initialize()
|
||||
{
|
||||
ed::Config config;
|
||||
config.SettingsFile = "Widgets.json";
|
||||
config.SettingsFile = nullptr;
|
||||
config.SaveSettings = nullptr;
|
||||
config.LoadSettings = nullptr;
|
||||
m_context = ed::CreateEditor(&config);
|
||||
|
||||
ed::SetCurrentEditor(m_context);
|
||||
|
|
|
|||
Loading…
Reference in a new issue