From 35c9fba323b940f9dd8fdb25b69cd948fca23262 Mon Sep 17 00:00:00 2001 From: "anthony@rabine.fr" Date: Sun, 19 Jan 2025 22:51:21 +0100 Subject: [PATCH] working import commercial stories --- story-editor/src/importers/ni_parser.c | 4 +- story-editor/src/importers/ni_parser.h | 4 +- story-editor/src/importers/pack_archive.cpp | 132 +++++++++++------- .../src/node_editor/media_node_widget.cpp | 23 ++- story-editor/src/web_server.cpp | 1 + 5 files changed, 111 insertions(+), 53 deletions(-) diff --git a/story-editor/src/importers/ni_parser.c b/story-editor/src/importers/ni_parser.c index db670e7..4958040 100644 --- a/story-editor/src/importers/ni_parser.c +++ b/story-editor/src/importers/ni_parser.c @@ -186,9 +186,9 @@ void ni_parse_nodes(ni_file_t *ni_file, const uint8_t *data) ptr += 4; n->sound_asset_index_in_si = leu32_get(ptr); ptr += 4; - n->ok_btn_node_idx_in_li = leu32_get(ptr); + n->ok_btn_base_idx = leu32_get(ptr); ptr += 4; - n->ok_btn_size_or_base_idx = leu32_get(ptr); + n->ok_btn_base_nb_elements = leu32_get(ptr); ptr += 4; n->ok_btn_offset_from_base = leu32_get(ptr); ptr += 4; diff --git a/story-editor/src/importers/ni_parser.h b/story-editor/src/importers/ni_parser.h index eaeedd2..22c53ce 100644 --- a/story-editor/src/importers/ni_parser.h +++ b/story-editor/src/importers/ni_parser.h @@ -14,8 +14,8 @@ extern "C" { typedef struct { uint32_t image_asset_index_in_ri; uint32_t sound_asset_index_in_si; - uint32_t ok_btn_node_idx_in_li; - uint32_t ok_btn_size_or_base_idx; + uint32_t ok_btn_base_idx; + uint32_t ok_btn_base_nb_elements; uint32_t ok_btn_offset_from_base; uint32_t home_transition_action_node_index_in_li; uint32_t home_transition_number_of_options; diff --git a/story-editor/src/importers/pack_archive.cpp b/story-editor/src/importers/pack_archive.cpp index 93cdd0c..8e7296e 100644 --- a/story-editor/src/importers/pack_archive.cpp +++ b/story-editor/src/importers/pack_archive.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "pack_archive.h" @@ -218,11 +219,19 @@ void PackArchive::ConvertCommercialFormat(StoryProject &proj, const std::filesys // value: list of node ids in desination std::map> referencedIndexes; + // Groups: + // Un groupe est un synoynme de ok_btn_base_idx, un offset dans la table des transitions + // Chaque groupe a un nombre de noeuds max + std::map groups; + + + std::unordered_set wheels; + // Direct nodes (no choices) // key: nodeID source, value: nodeID destination - std::map nodeLinks; + // std::map nodeLinks; - for (int i = 0; i < mNiFile.node_size; i++) + for (int i = 0; i < mNiFile.stage_nodes_count; i++) { ni_get_node_info(i, &node_info); @@ -231,6 +240,7 @@ void PackArchive::ConvertCommercialFormat(StoryProject &proj, const std::filesys if (node) { // On sauvegarde la relation entre l'index du noeud et son UUID + // On s'en servira plus tard pour effectuer les liens nodeIds[i] = node->GetId(); node->SetPosition(80 * i, 80 * i); @@ -243,49 +253,38 @@ void PackArchive::ConvertCommercialFormat(StoryProject &proj, const std::filesys std::cout << i << "\t==> Node\t" << img << "\t" << snd << std::endl; - std::cout << "\tOK node index in LI\t" << node_info.current->ok_btn_node_idx_in_li << std::endl; - std::cout << "\tOK number of options\t" << node_info.current->ok_btn_size_or_base_idx << std::endl; + std::cout << "\tOK node index in LI\t" << node_info.current->ok_btn_base_idx << std::endl; + std::cout << "\tOK number of options\t" << node_info.current->ok_btn_base_nb_elements << std::endl; std::cout << "\tOK selected option index\t" << node_info.current->ok_btn_offset_from_base << std::endl; node->SetInternalData(internalData); - std::vector jumpArray; - - - + referencedIndexes[node_info.current->ok_btn_base_idx + node_info.current->ok_btn_offset_from_base].push_back(i); + // On appartient à un système de roue de sélection + // On va donc sauvegarder l'id du goue if (node_info.current->wheel) { - /* - Exemple d'un noeud de choix (wheel == true) avec trois noeuds : - node number 13 17 21 - ok_btn_node_idx_in_li 36 36 36 - ok_btn_size_or_base_idx 18 18 18 - ok_btn_offset_from_base 0 2 4 - - Dans ce cas: - - le 18 est l'index de base où sont situés les 3 choix - - 36+0 est l'index où aller lors de l'appui sur OK pour le noeud 13 - - 36+2 est l'index où aller lors de l'appui sur OK pour le noeud 17 - - 36+4 est l'index où aller lors de l'appui sur OK pour le noeud 21 - - */ - - // On ajouter ce noeud à la liste des références - // dans ce cas, le champs ok_btn_size_or_base_idx est interprété en tant que index - referencedIndexes[node_info.current->ok_btn_size_or_base_idx].push_back(i); - - // On va créer le lien entre notre noeud et le noeud indiqué dans la table de transition - nodeLinks[i] = transitions[node_info.current->ok_btn_size_or_base_idx + node_info.current->ok_btn_offset_from_base]; - } - else - { - /* - ici, pas de wheel de sélection, donc c'est un son joué et un lien direct - */ - nodeLinks[i] = transitions[node_info.current->ok_btn_size_or_base_idx + node_info.current->ok_btn_offset_from_base]; + wheels.insert(i); // current ID is in a selection group } + groups[node_info.current->ok_btn_base_idx] = node_info.current->ok_btn_base_nb_elements; + + /* + Exemple d'un noeud de choix (wheel == true) avec trois noeuds : + node number 13 17 21 + ok_btn_base_idx 36 36 36 + ok_btn_base_nb_elements 18 18 18 + ok_btn_offset_from_base 0 2 4 + + Dans ce cas: + - le 18 est l'index de base où sont situés les 3 choix + - 36+0 est l'index où aller lors de l'appui sur OK pour le noeud 13 + - 36+2 est l'index où aller lors de l'appui sur OK pour le noeud 17 + - 36+4 est l'index où aller lors de l'appui sur OK pour le noeud 21 + + */ + } else { @@ -294,23 +293,60 @@ void PackArchive::ConvertCommercialFormat(StoryProject &proj, const std::filesys } } - // Create links, parse again the nodes - // for (int i = 0; i < mNiFile.node_size; i++) - //{ - // std::cout << "Node id " << nodeIds[i] << " has " << nodeTransitions[i].size() << " transistions" << std::endl; + auto addLink = [&](int src, int dst, int index = 0) { + std::cout << "Node " << src << " -> " << dst << std::endl; - for (auto &j : nodeLinks) + auto c = std::make_shared(); + + c->outNodeId = nodeIds[src]; // source + c->outPortIndex = index; + c->inNodeId = nodeIds[dst]; // destination + c->inPortIndex = 0; + + page->AddLink(c); + }; + + for (auto &ref : groups) + { + std::cout << "Group " << ref.first << " -> count: " << ref.second << std::endl; + + for (int n = 0; n < ref.second; n++) { - auto c = std::make_shared(); + // Get node referenced in the transition table + // It is the destination + auto offset = ref.first + n; + auto dst = transitions[offset]; - c->outNodeId = nodeIds[j.first]; // source - c->outPortIndex = 0; - c->inNodeId = nodeIds[j.second]; // destination - c->inPortIndex = 0; + if (wheels.contains(dst)) + { + // Ce noeud de destination est une sélection + // On recherche le noeud parent et on crée un lien + // (ce noeud parent est le groupe en cours) - page->AddLink(c); + auto srcList = referencedIndexes[ref.first]; + if (srcList.size() == 1) + { + addLink(srcList[0], dst, n); + } + else + { + std::cout << "Error: more than one source for a wheel" << std::endl; + } + } + else if (referencedIndexes.count(offset)) + { + auto srcList = referencedIndexes[offset]; + + for (auto &src : srcList) + { + addLink(src, dst); + } + } + else { + std::cout << "???" << std::endl; + } } - //} + } proj.Save(res); } diff --git a/story-editor/src/node_editor/media_node_widget.cpp b/story-editor/src/node_editor/media_node_widget.cpp index d881dd3..9252dec 100644 --- a/story-editor/src/node_editor/media_node_widget.cpp +++ b/story-editor/src/node_editor/media_node_widget.cpp @@ -25,10 +25,11 @@ void MediaNodeWidget::Draw() { BaseNodeWidget::FrameStart(); - +/* static ImGuiTableFlags flags = ImGuiTableFlags_Borders | ImGuiTableFlags_NoHostExtendX | ImGuiTableFlags_SizingFixedFit; + ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(10.0f, 10.0f)); if (ImGui::BeginTable("table1", 1, flags)) { @@ -41,7 +42,27 @@ void MediaNodeWidget::Draw() ImGui::EndTable(); } ImGui::PopStyleVar(); +*/ + const char * text = "Media node"; + // Obtenir la position courante du curseur + ImVec2 pos = ImGui::GetCursorScreenPos(); + // Définir les dimensions du texte + ImVec2 text_size = ImGui::CalcTextSize(text); + + // Ajouter un padding autour du texte + float padding = 5.0f; + ImVec2 rect_min = ImVec2(pos.x - padding, pos.y - padding); + ImVec2 rect_max = ImVec2(pos.x + text_size.x + padding, pos.y + text_size.y + padding); + + // Définir la couleur du rectangle (bleu avec transparence) + ImU32 bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 1.0f)); + + // Dessiner le rectangle de fond + ImGui::GetWindowDrawList()->AddRectFilled(rect_min, rect_max, bg_color); + + // Afficher le texte + ImGui::TextUnformatted(text); if (m_image.Valid()) { diff --git a/story-editor/src/web_server.cpp b/story-editor/src/web_server.cpp index 2fc0148..4e7ba8f 100644 --- a/story-editor/src/web_server.cpp +++ b/story-editor/src/web_server.cpp @@ -49,6 +49,7 @@ static const char *options[] = { "access_control_allow_origin", "*", "access_control_allow_methods", "GET, POST, PUT, DELETE, OPTIONS", "access_control_allow_headers", "Content-Type", + "enable_webdav", "yes", 0 };