mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
Fix media output format, fix link creation
This commit is contained in:
parent
be16a68e85
commit
016282064e
15 changed files with 197 additions and 150 deletions
|
|
@ -10,6 +10,8 @@ public:
|
|||
virtual ~IStoryProject() {};
|
||||
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(const std::string &nodeId) = 0;
|
||||
virtual int OutputsCount(const std::string &nodeId) = 0;
|
||||
virtual std::string ImageExtension(const std::string &filename) const = 0;
|
||||
virtual std::string SoundExtension(const std::string &filename) const = 0;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -27,3 +27,4 @@ std::string Resource::SoundFormatToString(SoundFormat format)
|
|||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -119,7 +119,6 @@ void StoryProject::ModelToJson(nlohmann::json &model)
|
|||
{
|
||||
nlohmann::json c(*cnx);
|
||||
connections.push_back(c);
|
||||
// Connection cnx = LinkToModel(linkInfo->ed_link->InputId, linkInfo->ed_link->OutputId);
|
||||
}
|
||||
|
||||
model["connections"] = connections;
|
||||
|
|
@ -275,6 +274,32 @@ int StoryProject::OutputsCount(const std::string &nodeId)
|
|||
return count;
|
||||
}
|
||||
|
||||
std::string StoryProject::ImageExtension(const std::string &filename) const
|
||||
{
|
||||
std::string ext = SysLib::GetFileExtension(filename);
|
||||
if (m_imageFormat == Resource::ImageFormat::IMG_FORMAT_QOIF)
|
||||
{
|
||||
return "qoi";
|
||||
}
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
std::string StoryProject::SoundExtension(const std::string &filename) const
|
||||
{
|
||||
std::string ext = SysLib::GetFileExtension(filename);
|
||||
if (m_soundFormat == Resource::SoundFormat::SND_FORMAT_QOAF)
|
||||
{
|
||||
return "qoa";
|
||||
}
|
||||
else if (m_soundFormat == Resource::SoundFormat::SND_FORMAT_WAV)
|
||||
{
|
||||
return "wav";
|
||||
}
|
||||
|
||||
return ext;
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<Connection>> StoryProject::GetNodeConnections(const std::string &nodeId)
|
||||
{
|
||||
std::list<std::shared_ptr<Connection>> c;
|
||||
|
|
@ -555,7 +580,7 @@ std::string StoryProject::BuildFullAssetsPath(const std::string &fileName) const
|
|||
std::string StoryProject::FileToConstant(const std::string &FileName, const std::string &extension)
|
||||
{
|
||||
std::string f = SysLib::RemoveFileExtension(FileName);
|
||||
return "$" + f + " DC8 \"" + f + extension + "\", 8\r\n";
|
||||
return "$" + f + " DC8 \"" + f + "." + extension + "\", 8\r\n";
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -135,6 +135,8 @@ public:
|
|||
virtual std::list<std::shared_ptr<Connection>> GetNodeConnections(const std::string &nodeId) override;
|
||||
std::string FindFirstNode() const;
|
||||
virtual int OutputsCount(const std::string &nodeId) override;
|
||||
virtual std::string ImageExtension(const std::string &filename) const override;
|
||||
virtual std::string SoundExtension(const std::string &filename) const override;
|
||||
|
||||
std::shared_ptr<BaseNode> CreateNode(const std::string& type);
|
||||
void AddConnection(std::shared_ptr<Connection> c);
|
||||
|
|
|
|||
|
|
@ -148,23 +148,23 @@ include_directories(${sdl3_mixer_SOURCE_DIR}/include)
|
|||
# =========================================================================================================================
|
||||
# SDL3-Image
|
||||
# =========================================================================================================================
|
||||
# FetchContent_Declare(
|
||||
# SDL2_image
|
||||
# GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
||||
# GIT_TAG origin/main
|
||||
# GIT_SHALLOW TRUE
|
||||
# GIT_PROGRESS TRUE
|
||||
# )
|
||||
FetchContent_Declare(
|
||||
sdl_image
|
||||
GIT_REPOSITORY https://github.com/libsdl-org/SDL_image.git
|
||||
GIT_TAG origin/main
|
||||
GIT_SHALLOW TRUE
|
||||
GIT_PROGRESS TRUE
|
||||
)
|
||||
|
||||
# # START ADDITION
|
||||
# set(SDL2IMAGE_INSTALL OFF)
|
||||
# set(BUILD_SHARED_LIBS FALSE)
|
||||
# # END ADDITION
|
||||
|
||||
add_subdirectory(libs/SDL_image)
|
||||
include_directories(libs/SDL_image/include)
|
||||
set(SDL3IMAGE_INSTALL OFF)
|
||||
set(BUILD_SHARED_LIBS FALSE)
|
||||
FetchContent_MakeAvailable(sdl_image)
|
||||
include_directories(${sdl_image_SOURCE_DIR}/include)
|
||||
|
||||
# FetchContent_MakeAvailable(SDL2_image)
|
||||
# =========================================================================================================================
|
||||
# Project sources
|
||||
# =========================================================================================================================
|
||||
set(SRCS
|
||||
|
||||
src/main.cpp
|
||||
|
|
@ -332,11 +332,12 @@ target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC cimg_display=0)
|
|||
|
||||
target_compile_definitions(${STORY_EDITOR_PROJECT} PUBLIC "$<$<CONFIG:DEBUG>:DEBUG>")
|
||||
|
||||
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl3_BINARY_DIR} ${curl_BINARY_DIR} ${CMAKE_BINARY_DIR}/libs/SDL_image)
|
||||
target_link_directories(${STORY_EDITOR_PROJECT} PUBLIC ${sdl3_BINARY_DIR} ${curl_BINARY_DIR})
|
||||
|
||||
# On est obligé de passer par une variable pour injecter
|
||||
# certaines informations à CPACK
|
||||
set(SDL_BIN_DIR ${sdl3_BINARY_DIR})
|
||||
set(SDL_IMAGE_BIN_DIR ${sdl_image_BINARY_DIR})
|
||||
|
||||
if(UNIX)
|
||||
target_link_libraries(${STORY_EDITOR_PROJECT}
|
||||
|
|
@ -389,6 +390,12 @@ if(WIN32)
|
|||
set(CPACK_NSIS_MUI_ICON "${CMAKE_SOURCE_DIR}/story-editor-logo.ico")
|
||||
endif()
|
||||
|
||||
if(LINUX)
|
||||
install_files("." FILES "${SDL_BIN_DIR}/SDL3.so")
|
||||
install_files("." FILES "${SDL_IMAGE_BIN_DIR}/SDL3_image.so")
|
||||
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
set(CPACK_GENERATOR "DragNDrop")
|
||||
set(MACOSX_BUNDLE_INFO_PLIST ${PROJECT_SOURCE_DIR}/bundle.plist.in)
|
||||
|
|
|
|||
|
|
@ -99,6 +99,8 @@ void EmulatorWindow::Draw()
|
|||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::Text("VM state: %s", m_story.VmState().c_str());
|
||||
|
||||
WindowBase::EndDraw();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ your use of the corresponding standard functions.
|
|||
|
||||
#include "IconsMaterialDesignIcons.h"
|
||||
#include "IconsFontAwesome5_c.h"
|
||||
#include "qoi.h"
|
||||
|
||||
|
||||
static void glfw_error_callback(int error, const char* description)
|
||||
|
|
@ -50,13 +49,6 @@ static SDL_Renderer* renderer{nullptr};
|
|||
|
||||
#include "stb_image.h"
|
||||
|
||||
static std::string GetFileExtension(const std::string &fileName)
|
||||
{
|
||||
if(fileName.find_last_of(".") != std::string::npos)
|
||||
return fileName.substr(fileName.find_last_of(".")+1);
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
// Simple helper function to load an image into a OpenGL texture with common settings
|
||||
bool LoadTextureFromFile(const char* filename, Gui::Image &img)
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ public:
|
|||
virtual void Pause() = 0;
|
||||
virtual void Next() = 0;
|
||||
virtual void Previous() = 0;
|
||||
virtual std::string VmState() const = 0;
|
||||
};
|
||||
|
||||
#endif // I_STORY_MANAGER_H
|
||||
|
|
|
|||
|
|
@ -93,16 +93,44 @@ void MainWindow::Pause()
|
|||
|
||||
void MainWindow::Next()
|
||||
{
|
||||
Log("End of audio track");
|
||||
Log("Next button");
|
||||
m_eventQueue.push({VmEventType::EvNextButton});
|
||||
}
|
||||
|
||||
void MainWindow::Previous()
|
||||
{
|
||||
Log("End of audio track");
|
||||
Log("Previous button");
|
||||
m_eventQueue.push({VmEventType::EvPreviousButton});
|
||||
}
|
||||
|
||||
std::string MainWindow::VmState() const
|
||||
{
|
||||
std::string state = "Unknown";
|
||||
|
||||
switch (m_dbg.run_result)
|
||||
{
|
||||
case VM_READY:
|
||||
state = "VM Ready";
|
||||
break;
|
||||
case VM_FINISHED:
|
||||
state = "VM Finished";
|
||||
break;
|
||||
case VM_SKIPED:
|
||||
state = "VM Skiped";
|
||||
break;
|
||||
case VM_WAIT_EVENT:
|
||||
state = "VM Wait Event";
|
||||
break;
|
||||
case VM_OK:
|
||||
state = "VM Ok";
|
||||
break;
|
||||
default:
|
||||
state = "VM Error";
|
||||
break;
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
||||
void MainWindow::EndOfAudio()
|
||||
{
|
||||
Log("End of audio track");
|
||||
|
|
@ -659,6 +687,7 @@ void MainWindow::SaveProject()
|
|||
{
|
||||
nlohmann::json model;
|
||||
m_story->Save(m_resources);
|
||||
Log("Project saved");
|
||||
}
|
||||
|
||||
void MainWindow::OpenProject(const std::string &uuid)
|
||||
|
|
@ -858,8 +887,8 @@ void MainWindow::Loop()
|
|||
// Rendering and event handling
|
||||
Uint64 frameTime = SDL_GetTicks() - frameStart; // Temps écoulé pour la frame
|
||||
|
||||
if (frameTime < 16) { // Limite de 60 FPS
|
||||
SDL_Delay(16 - frameTime); // Attendez pour compléter la frame
|
||||
if (frameTime < 32) { // 16 ms = 60 FPS
|
||||
SDL_Delay(32 - frameTime); // Attendez pour compléter la frame
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ private:
|
|||
virtual void Pause() override;
|
||||
virtual void Next() override;
|
||||
virtual void Previous() override;
|
||||
virtual std::string VmState() const override;
|
||||
|
||||
|
||||
// From ILogger
|
||||
|
|
|
|||
|
|
@ -14,19 +14,39 @@
|
|||
#define STBI_NO_LINEAR
|
||||
#include "stb_image.h"
|
||||
|
||||
#define QOI_IMPLEMENTATION
|
||||
#undef QOI_NO_STDIO
|
||||
#include "qoi.h"
|
||||
|
||||
#define DR_MP3_IMPLEMENTATION
|
||||
#include "dr_mp3.h"
|
||||
|
||||
#include "qoi.h"
|
||||
|
||||
|
||||
static int qoi_encode_and_write(const char *filename, const void *data, const qoi_desc *desc) {
|
||||
FILE *f = fopen(filename, "wb");
|
||||
int size;
|
||||
void *encoded;
|
||||
|
||||
if (!f) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
encoded = qoi_encode(data, desc, &size);
|
||||
if (!encoded) {
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fwrite(encoded, 1, size, f);
|
||||
fclose(f);
|
||||
|
||||
free(encoded);
|
||||
return size;
|
||||
}
|
||||
|
||||
MediaConverter::MediaConverter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
int MediaConverter::ImageToQoi(const std::string &inputFileName, const std::string &outputFileName)
|
||||
{
|
||||
void *pixels = NULL;
|
||||
|
|
@ -54,7 +74,8 @@ int MediaConverter::ImageToQoi(const std::string &inputFileName, const std::stri
|
|||
desc.width = w;
|
||||
desc.height = h;
|
||||
|
||||
int encoded = qoi_write(outputFileName.c_str(), pixels, &desc);
|
||||
|
||||
int encoded = qoi_encode_and_write(outputFileName.c_str(), pixels, &desc);
|
||||
free(pixels);
|
||||
|
||||
if (!encoded)
|
||||
|
|
@ -241,101 +262,3 @@ int MediaConverter::OggToWav(const std::string &inputFileName, const std::string
|
|||
|
||||
return cSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
OGG TO WAV
|
||||
|
||||
#define STB_VORBIS_HEADER_ONLY
|
||||
#include "stb_vorbis.c"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Function to read the entire contents of a file into memory
|
||||
unsigned char* read_entire_file(const char* filename, int* length) {
|
||||
FILE* f = fopen(filename, "rb");
|
||||
if (!f) return NULL;
|
||||
fseek(f, 0, SEEK_END);
|
||||
long size = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
unsigned char* buffer = (unsigned char*)malloc(size);
|
||||
if (!buffer) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
fread(buffer, 1, size, f);
|
||||
fclose(f);
|
||||
if (length) *length = (int)size;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc != 3) {
|
||||
printf("Usage: %s input.ogg output.wav\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char* input_filename = argv[1];
|
||||
const char* output_filename = argv[2];
|
||||
|
||||
int ogg_length;
|
||||
unsigned char* ogg_data = read_entire_file(input_filename, &ogg_length);
|
||||
if (!ogg_data) {
|
||||
printf("Failed to read input file %s\n", input_filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int channels, sample_rate;
|
||||
short* samples = stb_vorbis_decode_memory(ogg_data, ogg_length, &channels, &sample_rate);
|
||||
if (!samples) {
|
||||
printf("Failed to decode OGG file %s\n", input_filename);
|
||||
free(ogg_data);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Write WAV file header
|
||||
FILE* wav_file = fopen(output_filename, "wb");
|
||||
if (!wav_file) {
|
||||
printf("Failed to create output file %s\n", output_filename);
|
||||
free(ogg_data);
|
||||
free(samples);
|
||||
return 1;
|
||||
}
|
||||
fwrite("RIFF", 1, 4, wav_file);
|
||||
int total_size = 36 + channels * (sample_rate * sizeof(short));
|
||||
fwrite(&total_size, 4, 1, wav_file);
|
||||
fwrite("WAVEfmt ", 1, 8, wav_file);
|
||||
int format_size = 16;
|
||||
fwrite(&format_size, 4, 1, wav_file);
|
||||
short format_type = 1; // PCM
|
||||
fwrite(&format_type, 2, 1, wav_file);
|
||||
fwrite(&channels, 2, 1, wav_file);
|
||||
fwrite(&sample_rate, 4, 1, wav_file);
|
||||
int byte_rate = sample_rate * channels * sizeof(short);
|
||||
fwrite(&byte_rate, 4, 1, wav_file);
|
||||
short block_align = channels * sizeof(short);
|
||||
fwrite(&block_align, 2, 1, wav_file);
|
||||
short bits_per_sample = 16;
|
||||
fwrite(&bits_per_sample, 2, 1, wav_file);
|
||||
fwrite("data", 1, 4, wav_file);
|
||||
int data_size = channels * (sample_rate * sizeof(short));
|
||||
fwrite(&data_size, 4, 1, wav_file);
|
||||
|
||||
// Write sample data
|
||||
fwrite(samples, sizeof(short), sample_rate * channels, wav_file);
|
||||
|
||||
fclose(wav_file);
|
||||
|
||||
free(ogg_data);
|
||||
free(samples);
|
||||
|
||||
printf("Conversion complete. WAV file saved as %s\n", output_filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ public:
|
|||
atIndex = 0;
|
||||
for (auto &i : m_node->Outputs)
|
||||
{
|
||||
// std::cout << "Output Pin id: " << (int)i.ID.Get() << std::endl;
|
||||
|
||||
if (i.ID == pinId)
|
||||
{
|
||||
found = true;
|
||||
|
|
|
|||
|
|
@ -167,29 +167,79 @@ void NodeEditorWindow::CreateLink(std::shared_ptr<Connection> model, ed::PinId i
|
|||
m_links.push_back(conn);
|
||||
}
|
||||
|
||||
// retourne 1 si c'est une sortie, 2 une entrée, 0 pas trouvé
|
||||
int NodeEditorWindow::FindNodeAndPin(ed::PinId pinId, int &foundIndex, std::string &foundNodeId)
|
||||
{
|
||||
int success = 0;
|
||||
for (const auto & n : m_nodes)
|
||||
{
|
||||
// std::cout << "---> Node: " << n->Base()->GetId() << std::endl;
|
||||
|
||||
if (n->HasOnputPinId(pinId, foundIndex))
|
||||
{
|
||||
foundNodeId = n->Base()->GetId();
|
||||
success = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (n->HasInputPinId(pinId, foundIndex))
|
||||
{
|
||||
foundNodeId = n->Base()->GetId();
|
||||
success = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool NodeEditorWindow::FillConnection(std::shared_ptr<Connection> c, ed::PinId pinId)
|
||||
{
|
||||
bool success = false;
|
||||
std::string nodeId;
|
||||
int nodeIndex;
|
||||
int ret = FindNodeAndPin(pinId, nodeIndex, nodeId);
|
||||
if (ret > 0)
|
||||
{
|
||||
if (ret == 1)
|
||||
{
|
||||
c->outNodeId = nodeId;
|
||||
c->outPortIndex = nodeIndex;
|
||||
}
|
||||
else
|
||||
{
|
||||
c->inNodeId = nodeId;
|
||||
c->inPortIndex = nodeIndex;
|
||||
}
|
||||
success = true;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
std::shared_ptr<Connection> NodeEditorWindow::LinkToModel(ed::PinId InputId, ed::PinId OutputId)
|
||||
{
|
||||
auto c = std::make_shared<Connection>();
|
||||
int index;
|
||||
int foundIndex = -1;
|
||||
for (const auto & n : m_nodes)
|
||||
{
|
||||
if (n->HasOnputPinId(OutputId, index))
|
||||
// std::cout << "---> Node: " << n->Base()->GetId() << std::endl;
|
||||
|
||||
if (n->HasOnputPinId(OutputId, foundIndex))
|
||||
{
|
||||
c->outNodeId = n->Base()->GetId();
|
||||
c->outPortIndex = index;
|
||||
c->outPortIndex = foundIndex;
|
||||
}
|
||||
|
||||
if (n->HasInputPinId(InputId, index))
|
||||
if (n->HasInputPinId(InputId, foundIndex))
|
||||
{
|
||||
c->inNodeId = n->Base()->GetId();
|
||||
c->inPortIndex = index;
|
||||
c->inPortIndex = foundIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
std::shared_ptr<BaseNodeWidget> NodeEditorWindow::GetSelectedNode()
|
||||
|
|
@ -243,8 +293,8 @@ void NodeEditorWindow::Draw()
|
|||
// Handle creation action, returns true if editor want to create new object (node or link)
|
||||
if (ed::BeginCreate())
|
||||
{
|
||||
ed::PinId inputPinId, outputPinId;
|
||||
if (ed::QueryNewLink(&inputPinId, &outputPinId))
|
||||
ed::PinId startId, endId;
|
||||
if (ed::QueryNewLink(&startId, &endId))
|
||||
{
|
||||
// QueryNewLink returns true if editor want to create new link between pins.
|
||||
//
|
||||
|
|
@ -258,18 +308,26 @@ void NodeEditorWindow::Draw()
|
|||
// * input invalid, output valid - user started to drag new ling from output pin
|
||||
// * input valid, output valid - user dragged link over other pin, can be validated
|
||||
|
||||
if (inputPinId && outputPinId) // both are valid, let's accept link
|
||||
if (startId && endId) // both are valid, let's accept link
|
||||
{
|
||||
// ed::AcceptNewItem() return true when user release mouse button.
|
||||
if (ed::AcceptNewItem())
|
||||
{
|
||||
auto c = LinkToModel(inputPinId, outputPinId);
|
||||
m_story->AddConnection(c);
|
||||
auto c = std::make_shared<Connection>();
|
||||
|
||||
CreateLink(c, inputPinId, outputPinId);
|
||||
// On cherche à quel noeud appartien les pin (selon si le lien a été créé à partir d'une entrée ou d'une sortie)
|
||||
if (FillConnection(c, startId))
|
||||
{
|
||||
if (FillConnection(c, endId))
|
||||
{
|
||||
m_story->AddConnection(c);
|
||||
|
||||
// Draw new link.
|
||||
ed::Link(m_links.back()->ed_link->Id, inputPinId, outputPinId);
|
||||
CreateLink(c, startId, endId);
|
||||
|
||||
// Draw new link.
|
||||
ed::Link(m_links.back()->ed_link->Id, startId, endId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// You may choose to reject connection between these nodes
|
||||
|
|
|
|||
|
|
@ -116,6 +116,8 @@ private:
|
|||
ed::PinId GetInputPin(const std::string &modelNodeId, int pinIndex);
|
||||
ed::PinId GetOutputPin(const std::string &modelNodeId, int pinIndex);
|
||||
void CreateLink(std::shared_ptr<Connection> model, ed::PinId inId, ed::PinId outId);
|
||||
std::shared_ptr<Connection> LinkToModel(ed::PinId InputId, ed::PinId OutputId);
|
||||
// std::shared_ptr<Connection> LinkToModel(ed::PinId InputId, ed::PinId OutputId);
|
||||
int FindNodeAndPin(ed::PinId pinId, int &foundIndex, std::string &foundNodeId);
|
||||
bool FillConnection(std::shared_ptr<Connection> c, ed::PinId pinId);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -24,11 +24,11 @@ std::string MediaNode::GenerateConstants(IStoryProject &story, int nb_out_conns)
|
|||
|
||||
if (image.size() > 0)
|
||||
{
|
||||
s = StoryProject::FileToConstant(image, ".qoi"); // FIXME: Generate the extension setup in user option of output format
|
||||
s = StoryProject::FileToConstant(image, story.ImageExtension(image));
|
||||
}
|
||||
if (sound.size() > 0)
|
||||
{
|
||||
s += StoryProject::FileToConstant(sound, ".wav"); // FIXME: Generate the extension setup in user option of output format
|
||||
s += StoryProject::FileToConstant(sound, story.SoundExtension(sound)); // FIXME: Generate the extension setup in user option of output format
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue