diff --git a/shared/story_project.cpp b/shared/story_project.cpp index 16e9e83..bee7212 100644 --- a/shared/story_project.cpp +++ b/shared/story_project.cpp @@ -46,6 +46,8 @@ void StoryProject::CopyToDevice(const std::string &outputDir) std::string code; GenerateScript(code); + std::cout << code << std::endl; + Chip32::Assembler::Error err; if (GenerateBinary(code, err)) { @@ -192,6 +194,7 @@ bool StoryProject::ModelFromJson(const nlohmann::json &model) if (n) { n->FromJson(element); + n->Initialize(); } else { @@ -533,7 +536,6 @@ void StoryProject::Clear() } - void StoryProject::SetTitleImage(const std::string &titleImage) { m_titleImage = titleImage; @@ -544,8 +546,6 @@ void StoryProject::SetTitleSound(const std::string &titleSound) m_titleSound = titleSound; } - - void StoryProject::SetImageFormat(Resource::ImageFormat format) { m_imageFormat = format; @@ -572,7 +572,7 @@ std::string StoryProject::GetWorkingDir() const return m_working_dir.string(); } -std::string StoryProject::BuildFullAssetsPath(const std::string &fileName) const +std::string StoryProject::BuildFullAssetsPath(const std::string_view fileName) const { return (AssetsPath() / fileName).generic_string(); } diff --git a/shared/story_project.h b/shared/story_project.h index cc6c0a8..5f514bf 100644 --- a/shared/story_project.h +++ b/shared/story_project.h @@ -114,7 +114,7 @@ public: std::string GetDescription() const { return m_description; } uint32_t GetVersion() const { return m_version; } - std::string BuildFullAssetsPath(const std::string &fileName) const; + std::string BuildFullAssetsPath(const std::string_view fileName) const; static std::string FileToConstant(const std::string &FileName, const std::string &extension); diff --git a/story-editor/CMakeLists.txt b/story-editor/CMakeLists.txt index 1139640..1fc4748 100644 --- a/story-editor/CMakeLists.txt +++ b/story-editor/CMakeLists.txt @@ -132,7 +132,7 @@ include_directories(${sdl3_SOURCE_DIR}/include) FetchContent_Declare( sdl3_mixer GIT_REPOSITORY https://github.com/libsdl-org/SDL_mixer.git - GIT_TAG ace2d37796d2541123cdcbc06dce0b716a0416ad + GIT_TAG origin/main GIT_SHALLOW TRUE GIT_PROGRESS TRUE GIT_SUBMODULES "" diff --git a/story-editor/src/emulator_window.cpp b/story-editor/src/emulator_window.cpp index 6a9dba7..726fad6 100644 --- a/story-editor/src/emulator_window.cpp +++ b/story-editor/src/emulator_window.cpp @@ -1,5 +1,6 @@ #include "emulator_window.h" #include "gui.h" +#include "ImGuiFileDialog.h" #include "IconsMaterialDesignIcons.h" EmulatorWindow::EmulatorWindow(IStoryManager &proj) @@ -101,6 +102,37 @@ void EmulatorWindow::Draw() ImGui::Text("VM state: %s", m_story.VmState().c_str()); + + if (ImGui::Button("Load binary story (.c32)")) + { + IGFD::FileDialogConfig config; + config.path = "."; + config.countSelectionMax = 1; + config.flags = ImGuiFileDialogFlags_Modal; + ImGuiFileDialog::Instance()->OpenDialog("LoadBinarySoryDlgKey", + "Choose a binary story", + ".c32", + config + ); + } + + // ---------------- Load Binary story + if (ImGuiFileDialog::Instance()->Display("LoadBinarySoryDlgKey")) + { + if (ImGuiFileDialog::Instance()->IsOk()) + { + std::string filePathName = ImGuiFileDialog::Instance()->GetFilePathName(); + std::string filePath = ImGuiFileDialog::Instance()->GetCurrentPath(); + std::string filter = ImGuiFileDialog::Instance()->GetCurrentFilter(); + + m_story.LoadBinaryStory(filePathName); + } + // close + ImGuiFileDialog::Instance()->Close(); + } + + + WindowBase::EndDraw(); } diff --git a/story-editor/src/i_story_manager.h b/story-editor/src/i_story_manager.h index 5105f63..d1ddd77 100644 --- a/story-editor/src/i_story_manager.h +++ b/story-editor/src/i_story_manager.h @@ -35,7 +35,7 @@ public: virtual void ImportProject(const std::string &fileName, int format) = 0; virtual void Log(const std::string &txt, bool critical = false) = 0; virtual void PlaySoundFile(const std::string &fileName) = 0; - virtual std::string BuildFullAssetsPath(const std::string &fileName) const = 0; + virtual std::string BuildFullAssetsPath(const std::string_view fileName) const = 0; // Resources management virtual std::pair Images() = 0; @@ -51,6 +51,7 @@ public: virtual void DeleteNode(const std::string &id) = 0; virtual void DeleteLink(std::shared_ptr c) = 0; virtual std::list> GetNodeConnections(const std::string &nodeId) = 0; + virtual void LoadBinaryStory(const std::string &filename) = 0; virtual void Play() = 0; virtual void Ok() = 0; diff --git a/story-editor/src/main_window.cpp b/story-editor/src/main_window.cpp index 2e23ae5..e15157f 100644 --- a/story-editor/src/main_window.cpp +++ b/story-editor/src/main_window.cpp @@ -235,7 +235,7 @@ uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code) { // sound file name address is in R1 std::string soundFile = m_story->BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1])); - Log(", Sound: " + soundFile); + Log("Sound: " + soundFile); m_player.Play(soundFile); } retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause @@ -909,7 +909,7 @@ void MainWindow::PlaySoundFile(const std::string &fileName) m_player.Play(fileName); } -std::string MainWindow::BuildFullAssetsPath(const std::string &fileName) const +std::string MainWindow::BuildFullAssetsPath(const std::string_view fileName) const { return m_story->BuildFullAssetsPath(fileName); } @@ -949,6 +949,27 @@ std::shared_ptr MainWindow::CreateNode(const std::string &type) return m_story->CreateNode(type); } +void MainWindow::LoadBinaryStory(const std::string &filename) +{ + FILE *fp = fopen(filename.c_str(), "rb"); + if (fp != NULL) + { + fseek(fp, 0L, SEEK_END); + long int sz = ftell(fp); + fseek(fp, 0L, SEEK_SET); + + if (sz <= m_chip32_ctx.rom.size) + { + fread(m_chip32_ctx.rom.mem, sz, 1, fp); + m_dbg.run_result = VM_READY; + chip32_initialize(&m_chip32_ctx); + Log("Loaded binary file: " + filename); + } + fclose(fp); + } +} + + void MainWindow::Build(bool compileonly) { if (m_story->GenerateScript(m_currentCode)) @@ -968,8 +989,6 @@ void MainWindow::Build(bool compileonly) { m_result.Print(); - Log("Binary successfully generated."); - if (m_story->CopyProgramTo(m_rom_data, sizeof (m_rom_data))) { // m_ramView->SetMemory(m_ram_data, sizeof(m_ram_data)); diff --git a/story-editor/src/main_window.h b/story-editor/src/main_window.h index 1697a9d..62022b7 100644 --- a/story-editor/src/main_window.h +++ b/story-editor/src/main_window.h @@ -123,7 +123,7 @@ private: virtual void OpenProject(const std::string &uuid) override; virtual void ImportProject(const std::string &fileName, int format); virtual void PlaySoundFile(const std::string &fileName) override;; - virtual std::string BuildFullAssetsPath(const std::string &fileName) const override; + virtual std::string BuildFullAssetsPath(const std::string_view fileName) const override; virtual std::pair Images() override; virtual std::pair Sounds() override; @@ -137,6 +137,7 @@ private: virtual void DeleteNode(const std::string &id) override; virtual void DeleteLink(std::shared_ptr c) override; virtual std::list> GetNodeConnections(const std::string &nodeId) override; + virtual void LoadBinaryStory(const std::string &filename) override; virtual void Play() override; virtual void Ok() override; diff --git a/story-editor/src/node_editor/media_node_widget.cpp b/story-editor/src/node_editor/media_node_widget.cpp index 4e73feb..c76df37 100644 --- a/story-editor/src/node_editor/media_node_widget.cpp +++ b/story-editor/src/node_editor/media_node_widget.cpp @@ -101,19 +101,8 @@ void MediaNodeWidget::Draw() void MediaNodeWidget::Initialize() { BaseNodeWidget::Initialize(); - nlohmann::json j = m_mediaNode->GetInternalData(); - SetImage(j["image"].get()); - SetSound(j["sound"].get()); -} - - -void MediaNodeWidget::StoreInternalData() -{ - nlohmann::json j; - j["image"] = m_mediaNode->image; - j["sound"] = m_mediaNode->sound; - - m_mediaNode->SetInternalData(j); + m_image.Load(m_manager.BuildFullAssetsPath(m_mediaNode->GetImage())); + m_soundPath = m_manager.BuildFullAssetsPath(m_mediaNode->GetSound()); } void MediaNodeWidget::DrawProperties() @@ -122,7 +111,7 @@ void MediaNodeWidget::DrawProperties() ImGui::Text("Image"); ImGui::SameLine(); - ImGui::Text("%s", m_mediaNode->image.c_str()); + ImGui::Text("%s", m_mediaNode->GetImage().data()); ImGui::SameLine(); @@ -133,14 +122,15 @@ void MediaNodeWidget::DrawProperties() } ImGui::SameLine(); if (ImGui::Button(ICON_MDI_CLOSE_BOX_OUTLINE "##delimage")) { - SetImage(""); + m_mediaNode->SetImage(""); + Initialize(); } ImGui::AlignTextToFramePadding(); ImGui::Text("Sound"); ImGui::SameLine(); - ImGui::Text("%s", m_mediaNode->sound.c_str()); + ImGui::Text("%s", m_mediaNode->GetSound().data()); ImGui::SameLine(); @@ -158,7 +148,8 @@ void MediaNodeWidget::DrawProperties() ImGui::SameLine(); if (ImGui::Button(ICON_MDI_CLOSE_BOX_OUTLINE "##delsound")) { - SetSound(""); + m_mediaNode->SetSound(""); + Initialize(); } // This is the actual popup Gui drawing section. @@ -173,12 +164,13 @@ void MediaNodeWidget::DrawProperties() { if (isImage) { - SetImage((*it)->file); + m_mediaNode->SetImage((*it)->file); } else { - SetSound((*it)->file); + m_mediaNode->SetSound((*it)->file); } + Initialize(); } } @@ -187,18 +179,4 @@ void MediaNodeWidget::DrawProperties() } -void MediaNodeWidget::SetImage(const std::string &f) -{ - m_mediaNode->image = f; - m_image.Load(m_manager.BuildFullAssetsPath(f)); - StoreInternalData(); -} - -void MediaNodeWidget::SetSound(const std::string &f) -{ - m_mediaNode->sound = f; - m_soundPath = m_manager.BuildFullAssetsPath(m_mediaNode->sound); - StoreInternalData(); -} - diff --git a/story-editor/src/node_editor/media_node_widget.h b/story-editor/src/node_editor/media_node_widget.h index f942a23..e00da7a 100644 --- a/story-editor/src/node_editor/media_node_widget.h +++ b/story-editor/src/node_editor/media_node_widget.h @@ -29,11 +29,5 @@ private: std::string m_soundPath; std::string m_buttonUniqueName; - - - void SetImage(const std::string &f); - void SetSound(const std::string &f); - - void StoreInternalData(); - + }; diff --git a/story-editor/src/node_engine/base_node.h b/story-editor/src/node_engine/base_node.h index 56bdff5..6cdba04 100644 --- a/story-editor/src/node_engine/base_node.h +++ b/story-editor/src/node_engine/base_node.h @@ -22,6 +22,7 @@ public: static std::string GetEntryLabel(const std::string &id); + virtual void Initialize() = 0; virtual std::string Build(IStoryProject &story, int nb_out_conns) = 0; virtual std::string GenerateConstants(IStoryProject &story, int nb_out_conns) = 0; diff --git a/story-editor/src/node_engine/media_node.cpp b/story-editor/src/node_engine/media_node.cpp index a661434..e5154f3 100644 --- a/story-editor/src/node_engine/media_node.cpp +++ b/story-editor/src/node_engine/media_node.cpp @@ -17,18 +17,33 @@ MediaNode::MediaNode(const std::string &type) SetInternalData(j); } +void MediaNode::StoreInternalData() +{ + nlohmann::json j; + j["image"] = m_image; + j["sound"] = m_sound; + + SetInternalData(j); +} + +void MediaNode::Initialize() +{ + nlohmann::json j = GetInternalData(); + m_image = j["image"].get(); + m_sound = j["sound"].get(); +} std::string MediaNode::GenerateConstants(IStoryProject &story, int nb_out_conns) { std::string s; - if (image.size() > 0) + if (m_image.size() > 0) { - s = StoryProject::FileToConstant(image, story.ImageExtension(image)); + s = StoryProject::FileToConstant(m_image, story.ImageExtension(m_image)); } - if (sound.size() > 0) + if (m_sound.size() > 0) { - s += StoryProject::FileToConstant(sound, story.SoundExtension(sound)); // FIXME: Generate the extension setup in user option of output format + s += StoryProject::FileToConstant(m_sound, story.SoundExtension(m_sound)); // FIXME: Generate the extension setup in user option of output format } @@ -65,6 +80,27 @@ std::string MediaNode::GenerateConstants(IStoryProject &story, int nb_out_conns) return s; } +void MediaNode::SetImage(const std::string &image) +{ + m_image = image; + StoreInternalData(); +} + +std::string_view MediaNode::GetImage() const +{ + return m_image; +} + +void MediaNode::SetSound(const std::string &sound) +{ + m_sound = sound; + StoreInternalData(); +} + +std::string_view MediaNode::GetSound() const +{ + return m_sound; +} std::string MediaNode::Build(IStoryProject &story, int nb_out_conns) { @@ -76,8 +112,8 @@ std::string MediaNode::Build(IStoryProject &story, int nb_out_conns) << (nb_out_conns == 0 ? "End" : nb_out_conns == 1 ? "Transition" : "Choice") << "\n"; - std::string img = SysLib::RemoveFileExtension(image); - std::string snd = SysLib::RemoveFileExtension(sound); + std::string img = SysLib::RemoveFileExtension(m_image); + std::string snd = SysLib::RemoveFileExtension(m_sound); // Le label de ce noeud est généré de la façon suivante : // "media" + Node ID + id du noeud parent. Si pas de noeud parent, alors rien diff --git a/story-editor/src/node_engine/media_node.h b/story-editor/src/node_engine/media_node.h index 1bc99c2..5743939 100644 --- a/story-editor/src/node_engine/media_node.h +++ b/story-editor/src/node_engine/media_node.h @@ -6,15 +6,23 @@ #include "i_script_node.h" #include "i_story_project.h" -struct MediaNode : public BaseNode +class MediaNode : public BaseNode { - +public: MediaNode(const std::string &type); + virtual void Initialize() override; virtual std::string Build(IStoryProject &story, int nb_out_conns) override; virtual std::string GenerateConstants(IStoryProject &story, int nb_out_conns) override; - std::string image; - std::string sound; + void SetImage(const std::string &image); + std::string_view GetImage() const; + void SetSound(const std::string &sound); + std::string_view GetSound() const; + void StoreInternalData(); + +private: + std::string m_image; + std::string m_sound; }; diff --git a/story-player/.gitignore b/story-player/.gitignore index 24476c5..761717e 100644 --- a/story-player/.gitignore +++ b/story-player/.gitignore @@ -42,3 +42,4 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release +/android/app/.cxx \ No newline at end of file