mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 17:09:06 +01:00
add logger, fix mem leak, pack copy to device finished.
This commit is contained in:
parent
73aefa7100
commit
3490cf0050
17 changed files with 503 additions and 411 deletions
10
shared/i_logger.h
Normal file
10
shared/i_logger.h
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class ILogger
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual void Log(const std::string &txt, bool critical = false) = 0;
|
||||||
|
};
|
||||||
|
|
@ -8,7 +8,19 @@
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
|
|
||||||
|
|
||||||
LibraryManager::LibraryManager() {}
|
LibraryManager::LibraryManager(ILogger &log)
|
||||||
|
: m_log(log)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LibraryManager::~LibraryManager()
|
||||||
|
{
|
||||||
|
if (m_copyWorker.joinable())
|
||||||
|
{
|
||||||
|
m_copyWorker.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LibraryManager::Initialize(const std::string &library_path)
|
void LibraryManager::Initialize(const std::string &library_path)
|
||||||
{
|
{
|
||||||
|
|
@ -43,7 +55,7 @@ void LibraryManager::Scan()
|
||||||
if (std::filesystem::exists(p))
|
if (std::filesystem::exists(p))
|
||||||
{
|
{
|
||||||
// okay, open it
|
// okay, open it
|
||||||
auto proj = std::make_shared<StoryProject>();
|
auto proj = std::make_shared<StoryProject>(m_log);
|
||||||
try {
|
try {
|
||||||
std::ifstream f(p);
|
std::ifstream f(p);
|
||||||
nlohmann::json j = nlohmann::json::parse(f);
|
nlohmann::json j = nlohmann::json::parse(f);
|
||||||
|
|
@ -55,7 +67,7 @@ void LibraryManager::Scan()
|
||||||
m_projectsList.push_back(proj);
|
m_projectsList.push_back(proj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(nlohmann::json::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
@ -68,7 +80,7 @@ void LibraryManager::Scan()
|
||||||
|
|
||||||
std::shared_ptr<StoryProject> LibraryManager::NewProject()
|
std::shared_ptr<StoryProject> LibraryManager::NewProject()
|
||||||
{
|
{
|
||||||
auto story = std::make_shared<StoryProject>();
|
auto story = std::make_shared<StoryProject>(m_log);
|
||||||
std::string uuid = Uuid().String();
|
std::string uuid = Uuid().String();
|
||||||
|
|
||||||
story->New(uuid, m_library_path);
|
story->New(uuid, m_library_path);
|
||||||
|
|
@ -92,10 +104,15 @@ std::shared_ptr<StoryProject> LibraryManager::GetStory(const std::string &uuid)
|
||||||
return current;
|
return current;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibraryManager::Save()
|
std::string LibraryManager::IndexFileName() const
|
||||||
{
|
{
|
||||||
auto p = std::filesystem::path(m_library_path) / "index.ost";
|
auto p = std::filesystem::path(m_library_path) / "index.ost";
|
||||||
Tlv tlv(p.string());
|
return p.string();
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibraryManager::Save()
|
||||||
|
{
|
||||||
|
Tlv tlv;
|
||||||
|
|
||||||
tlv.add_object(1);
|
tlv.add_object(1);
|
||||||
tlv.add_string(GetVersion());
|
tlv.add_string(GetVersion());
|
||||||
|
|
@ -115,6 +132,8 @@ void LibraryManager::Save()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tlv.Save(IndexFileName());
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -130,16 +149,37 @@ void LibraryManager::Save()
|
||||||
|
|
||||||
void LibraryManager::CopyToDevice(const std::string &outputDir)
|
void LibraryManager::CopyToDevice(const std::string &outputDir)
|
||||||
{
|
{
|
||||||
std::thread myThread([&]() {
|
try
|
||||||
myThread.detach();
|
{
|
||||||
|
// Generate TLV file (index of all stories)
|
||||||
|
Save();
|
||||||
|
// Copy TLV to the directory root
|
||||||
|
std::filesystem::copy(IndexFileName(), outputDir, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
|
if (m_copyWorker.joinable())
|
||||||
|
{
|
||||||
|
m_copyWorker.join();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_copyWorker = std::thread([&, outputDir]() {
|
||||||
|
// myThread.detach();
|
||||||
|
|
||||||
std::cout << "Starting to copy elements" << std::endl;
|
std::cout << "Starting to copy elements" << std::endl;
|
||||||
|
|
||||||
for (auto p : *this)
|
for (auto p : *this)
|
||||||
{
|
{
|
||||||
|
if (p->IsSelected())
|
||||||
|
{
|
||||||
|
p->CopyToDevice(outputDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
} catch (const std::filesystem::filesystem_error& e) {
|
||||||
|
std::cerr << "Filesystem error: " << e.what() << std::endl;
|
||||||
|
} catch(const std::exception& e)
|
||||||
|
{
|
||||||
|
std::cerr << e.what() << '\n';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LibraryManager::IsInitialized() const
|
bool LibraryManager::IsInitialized() const
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,15 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include "story_project.h"
|
#include <thread>
|
||||||
|
|
||||||
|
#include "story_project.h"
|
||||||
|
#include "i_logger.h"
|
||||||
class LibraryManager
|
class LibraryManager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LibraryManager();
|
LibraryManager(ILogger &log);
|
||||||
|
~LibraryManager();
|
||||||
|
|
||||||
void Initialize(const std::string &library_path);
|
void Initialize(const std::string &library_path);
|
||||||
bool IsInitialized() const;
|
bool IsInitialized() const;
|
||||||
|
|
@ -34,13 +37,17 @@ public:
|
||||||
|
|
||||||
std::shared_ptr<StoryProject> GetStory(const std::string &uuid);
|
std::shared_ptr<StoryProject> GetStory(const std::string &uuid);
|
||||||
|
|
||||||
|
std::string IndexFileName() const;
|
||||||
|
|
||||||
void SetStoreUrl(const std::string &store_url) { m_storeUrl = store_url; }
|
void SetStoreUrl(const std::string &store_url) { m_storeUrl = store_url; }
|
||||||
std::string GetStoreUrl() const { return m_storeUrl; }
|
std::string GetStoreUrl() const { return m_storeUrl; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ILogger &m_log;
|
||||||
std::string m_library_path;
|
std::string m_library_path;
|
||||||
std::vector<std::shared_ptr<StoryProject>> m_projectsList;
|
std::vector<std::shared_ptr<StoryProject>> m_projectsList;
|
||||||
std::string m_storeUrl;
|
std::string m_storeUrl;
|
||||||
|
std::thread m_copyWorker;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIBRARYMANAGER_H
|
#endif // LIBRARYMANAGER_H
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
#include "resource_manager.h"
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
|
||||||
|
#include "resource_manager.h"
|
||||||
|
#include "media_converter.h"
|
||||||
|
#include "sys_lib.h"
|
||||||
struct Media {
|
struct Media {
|
||||||
std::string type;
|
std::string type;
|
||||||
std::string format;
|
std::string format;
|
||||||
|
|
@ -32,3 +36,59 @@ std::string ResourceManager::ExtentionInfo(std::string extension, int info_type)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ResourceManager::ConvertResources(const std::filesystem::path &assetsPath, const std::string &destAssetsPath)
|
||||||
|
{
|
||||||
|
auto [b, e] = Items();
|
||||||
|
for (auto it = b; it != e; ++it)
|
||||||
|
{
|
||||||
|
std::filesystem::path inputfile = std::filesystem::path(assetsPath / (*it)->file);
|
||||||
|
std::filesystem::path outputfile = std::filesystem::path(assetsPath / SysLib::RemoveFileExtension((*it)->file));
|
||||||
|
|
||||||
|
int retCode = 0;
|
||||||
|
if (!std::filesystem::exists(outputfile))
|
||||||
|
{
|
||||||
|
if ((*it)->format == "PNG")
|
||||||
|
{
|
||||||
|
outputfile += ".qoi"; // FIXME: prendre la config en cours désirée
|
||||||
|
retCode = MediaConverter::ImageToQoi(inputfile.generic_string(), outputfile.generic_string());
|
||||||
|
}
|
||||||
|
else if ((*it)->format == "MP3")
|
||||||
|
{
|
||||||
|
outputfile += ".wav"; // FIXME: prendre la config en cours désirée
|
||||||
|
retCode = MediaConverter::Mp3ToWav(inputfile.generic_string(), outputfile.generic_string());
|
||||||
|
}
|
||||||
|
else if ((*it)->format == "OGG")
|
||||||
|
{
|
||||||
|
outputfile += ".wav"; // FIXME: prendre la config en cours désirée
|
||||||
|
retCode = MediaConverter::OggToWav(inputfile.generic_string(), outputfile.generic_string());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Log("Skipped: " + inputfile + ", unknown format" + outputfile, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retCode < 0)
|
||||||
|
{
|
||||||
|
//m_log.Log("Failed to convert media file " + inputfile + ", error code: " + std::to_string(retCode) + " to: " + outputfile, true);
|
||||||
|
}
|
||||||
|
else if (retCode == 0)
|
||||||
|
{
|
||||||
|
// Log("Convertered file: " + inputfile);
|
||||||
|
|
||||||
|
// Conversion success, now copy to output directory if necessary (ie: to an external device)
|
||||||
|
if ((destAssetsPath != assetsPath.generic_string()) && (std::filesystem::exists(destAssetsPath)))
|
||||||
|
{
|
||||||
|
// destination filename
|
||||||
|
auto destFile = destAssetsPath / outputfile.filename();
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(destFile))
|
||||||
|
{
|
||||||
|
std::filesystem::copy(outputfile, destAssetsPath, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <ranges>
|
#include <ranges>
|
||||||
|
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
#include "i_logger.h"
|
||||||
|
|
||||||
class ResourceManager
|
class ResourceManager
|
||||||
{
|
{
|
||||||
|
|
@ -24,6 +25,8 @@ public:
|
||||||
|
|
||||||
static std::string ExtentionInfo(std::string extension, int info_type);
|
static std::string ExtentionInfo(std::string extension, int info_type);
|
||||||
|
|
||||||
|
void ConvertResources(const std::filesystem::path &assetsPath, const std::string &destAssetsPath);
|
||||||
|
|
||||||
~ResourceManager() {
|
~ResourceManager() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,17 @@
|
||||||
#include "story_project.h"
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
#include "story_project.h"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "media_node.h"
|
#include "media_node.h"
|
||||||
|
#include "sys_lib.h"
|
||||||
|
|
||||||
StoryProject::StoryProject()
|
StoryProject::StoryProject(ILogger &log)
|
||||||
|
: m_log(log)
|
||||||
{
|
{
|
||||||
registerNode<MediaNode>("media-node");
|
registerNode<MediaNode>("media-node");
|
||||||
}
|
}
|
||||||
|
|
@ -34,6 +37,23 @@ void StoryProject::CopyToDevice(const std::string &outputDir)
|
||||||
|
|
||||||
Load(manager);
|
Load(manager);
|
||||||
|
|
||||||
|
// Output dir is the root. Build an assets directory to the device location
|
||||||
|
std::filesystem::path destRootDir = std::filesystem::path(outputDir) / m_uuid;
|
||||||
|
std::filesystem::path destAssetsDir = destRootDir / "assets";
|
||||||
|
std::filesystem::create_directories(destAssetsDir);
|
||||||
|
|
||||||
|
// Generate and copy binary
|
||||||
|
std::string code;
|
||||||
|
GenerateScript(code);
|
||||||
|
|
||||||
|
Chip32::Assembler::Error err;
|
||||||
|
if (GenerateBinary(code, err))
|
||||||
|
{
|
||||||
|
std::filesystem::copy(BinaryFileName(), destRootDir, std::filesystem::copy_options::overwrite_existing);
|
||||||
|
|
||||||
|
// Convert resources (if necessary) and copy them to destination assets
|
||||||
|
manager.ConvertResources(AssetsPath(), destAssetsDir);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoryProject::New(const std::string &uuid, const std::string &library_path)
|
void StoryProject::New(const std::string &uuid, const std::string &library_path)
|
||||||
|
|
@ -51,10 +71,15 @@ void StoryProject::New(const std::string &uuid, const std::string &library_path)
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::filesystem::path StoryProject::BinaryFileName() const
|
||||||
void StoryProject::SaveBinary(const std::vector<uint8_t> &m_program)
|
|
||||||
{
|
{
|
||||||
std::ofstream o(m_working_dir / "story.c32", std::ios::out | std::ios::binary);
|
return m_working_dir / "story.c32";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void StoryProject::SaveBinary()
|
||||||
|
{
|
||||||
|
std::ofstream o(BinaryFileName() , std::ios::out | std::ios::binary);
|
||||||
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
|
o.write(reinterpret_cast<const char*>(m_program.data()), m_program.size());
|
||||||
o.close();
|
o.close();
|
||||||
}
|
}
|
||||||
|
|
@ -192,13 +217,47 @@ bool StoryProject::ModelFromJson(const nlohmann::json &model)
|
||||||
}
|
}
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(nlohmann::json::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << "(NodeEditorWindow::Load) " << e.what() << std::endl;
|
std::cout << "(NodeEditorWindow::Load) " << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StoryProject::CopyProgramTo(uint8_t *memory, uint32_t size)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
// Update ROM memory
|
||||||
|
if (m_program.size() < size)
|
||||||
|
{
|
||||||
|
std::copy(m_program.begin(), m_program.end(), memory);
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoryProject::GetAssemblyLine(uint32_t pointer_counter, uint32_t &line)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
// On recherche quelle est la ligne qui possède une instruction à cette adresse
|
||||||
|
std::vector<Chip32::Instr>::const_iterator ptr = m_assembler.Begin();
|
||||||
|
for (; ptr != m_assembler.End(); ++ptr)
|
||||||
|
{
|
||||||
|
if ((ptr->addr == pointer_counter) && ptr->isRomCode())
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr != m_assembler.End())
|
||||||
|
{
|
||||||
|
line = ptr->line;
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
int StoryProject::OutputsCount(const std::string &nodeId)
|
int StoryProject::OutputsCount(const std::string &nodeId)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
@ -258,7 +317,7 @@ std::string StoryProject::FindFirstNode() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool StoryProject::Build(std::string &codeStr)
|
bool StoryProject::GenerateScript(std::string &codeStr)
|
||||||
{
|
{
|
||||||
std::stringstream code;
|
std::stringstream code;
|
||||||
std::stringstream chip32;
|
std::stringstream chip32;
|
||||||
|
|
@ -267,7 +326,7 @@ bool StoryProject::Build(std::string &codeStr)
|
||||||
|
|
||||||
if (firstNode == "")
|
if (firstNode == "")
|
||||||
{
|
{
|
||||||
std::cout << "First node not found, there must be only one node with a free input." << std::endl;
|
m_log.Log("First node not found, there must be only one node with a free input.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -285,9 +344,51 @@ bool StoryProject::Build(std::string &codeStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
codeStr = code.str();
|
codeStr = code.str();
|
||||||
|
|
||||||
|
// Add our utility functions
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
std::ifstream f("scripts/media.asm");
|
||||||
|
f.seekg(0, std::ios::end);
|
||||||
|
buffer.resize(f.tellg());
|
||||||
|
f.seekg(0);
|
||||||
|
f.read(buffer.data(), buffer.size());
|
||||||
|
codeStr += buffer;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool StoryProject::GenerateBinary(const std::string &code, Chip32::Assembler::Error &err)
|
||||||
|
{
|
||||||
|
Chip32::Result result;
|
||||||
|
bool success = false;
|
||||||
|
|
||||||
|
if (m_assembler.Parse(code) == true)
|
||||||
|
{
|
||||||
|
if (m_assembler.BuildBinary(m_program, result) == true)
|
||||||
|
{
|
||||||
|
result.Print();
|
||||||
|
|
||||||
|
m_log.Log("Binary successfully generated.");
|
||||||
|
SaveBinary();
|
||||||
|
success = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = m_assembler.GetLastError();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
err = m_assembler.GetLastError();
|
||||||
|
m_log.Log(err.ToString(), true);
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool StoryProject::Load(ResourceManager &manager)
|
bool StoryProject::Load(ResourceManager &manager)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
@ -320,69 +421,8 @@ bool StoryProject::Load(ResourceManager &manager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
if (j.contains("nodes"))
|
|
||||||
{
|
|
||||||
for (auto& element : j["nodes"])
|
|
||||||
{
|
|
||||||
StoryNode n;
|
|
||||||
|
|
||||||
n.auto_jump = element["auto_jump"];
|
|
||||||
|
|
||||||
for (auto& jump : element["jumps"])
|
|
||||||
{
|
|
||||||
n.jumps.push_back(jump.get<int>());
|
|
||||||
}
|
}
|
||||||
|
catch(nlohmann::json::exception &e)
|
||||||
n.id = element["id"];
|
|
||||||
n.image = element["image"];
|
|
||||||
n.sound = element["sound"];
|
|
||||||
|
|
||||||
m_nodes.push_back(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_images.clear();
|
|
||||||
if (j.contains("images"))
|
|
||||||
{
|
|
||||||
for (auto& element : j["images"])
|
|
||||||
{
|
|
||||||
Resource r;
|
|
||||||
|
|
||||||
r.file = element["file"];
|
|
||||||
r.description = element["description"];
|
|
||||||
r.format = element["format"];
|
|
||||||
|
|
||||||
m_images.push_back(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_sounds.clear();
|
|
||||||
if (j.contains("sounds"))
|
|
||||||
{
|
|
||||||
for (auto& element : j["sounds"])
|
|
||||||
{
|
|
||||||
Resource r;
|
|
||||||
|
|
||||||
r.file = element["file"];
|
|
||||||
r.description = element["description"];
|
|
||||||
r.format = element["format"];
|
|
||||||
|
|
||||||
m_sounds.push_back(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_type = j["type"];
|
|
||||||
m_code = j["code"];
|
|
||||||
m_name = j["name"];
|
|
||||||
|
|
||||||
success = true;
|
|
||||||
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
catch(std::exception &e)
|
|
||||||
{
|
{
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
@ -463,74 +503,7 @@ void StoryProject::Clear()
|
||||||
m_links.clear();
|
m_links.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoryProject::EraseString(std::string &theString, const std::string &toErase)
|
|
||||||
{
|
|
||||||
std::size_t found;
|
|
||||||
found = theString.find(toErase);
|
|
||||||
if (found != std::string::npos)
|
|
||||||
{
|
|
||||||
theString.erase(found, toErase.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StoryProject::ToUpper(const std::string &input)
|
|
||||||
{
|
|
||||||
std::string str = input;
|
|
||||||
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StoryProject::GetFileName(const std::string &path)
|
|
||||||
{
|
|
||||||
auto found = path.find_last_of("/\\");
|
|
||||||
return path.substr(found+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void StoryProject::ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace)
|
|
||||||
{
|
|
||||||
std::size_t found;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
found = theString.find(toFind);
|
|
||||||
if (found != std::string::npos)
|
|
||||||
{
|
|
||||||
theString.replace(found, 1, toReplace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (found != std::string::npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StoryProject::RemoveFileExtension(const std::string &FileName)
|
|
||||||
{
|
|
||||||
std::string f = GetFileName(FileName);
|
|
||||||
std::string ext = GetFileExtension(f);
|
|
||||||
EraseString(f, "." + ext);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StoryProject::FileToConstant(const std::string &FileName, const std::string &extension)
|
|
||||||
{
|
|
||||||
std::string f = RemoveFileExtension(FileName);
|
|
||||||
return "$" + f + " DC8 \"" + f + extension + "\", 8\r\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string StoryProject::Normalize(const std::string &input)
|
|
||||||
{
|
|
||||||
std::string valid_file = input;
|
|
||||||
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '\\', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '/', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), ':', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '?', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '\"', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '<', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '>', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), '|', '_');
|
|
||||||
std::replace(valid_file.begin(), valid_file.end(), ' ', '_');
|
|
||||||
|
|
||||||
return valid_file;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoryProject::SetTitleImage(const std::string &titleImage)
|
void StoryProject::SetTitleImage(const std::string &titleImage)
|
||||||
{
|
{
|
||||||
|
|
@ -542,12 +515,7 @@ void StoryProject::SetTitleSound(const std::string &titleSound)
|
||||||
m_titleSound = titleSound;
|
m_titleSound = titleSound;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StoryProject::GetFileExtension(const std::string &fileName)
|
|
||||||
{
|
|
||||||
if(fileName.find_last_of(".") != std::string::npos)
|
|
||||||
return fileName.substr(fileName.find_last_of(".")+1);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void StoryProject::SetImageFormat(ImageFormat format)
|
void StoryProject::SetImageFormat(ImageFormat format)
|
||||||
{
|
{
|
||||||
|
|
@ -580,5 +548,11 @@ std::string StoryProject::BuildFullAssetsPath(const std::string &fileName) const
|
||||||
return (AssetsPath() / fileName).generic_string();
|
return (AssetsPath() / fileName).generic_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "base_node.h"
|
#include "base_node.h"
|
||||||
#include "i_story_project.h"
|
#include "i_story_project.h"
|
||||||
|
#include "chip32_assembler.h"
|
||||||
|
|
||||||
// FIXME : Structure très Lunii style, à utiliser pour la conversion peut-être ...
|
// FIXME : Structure très Lunii style, à utiliser pour la conversion peut-être ...
|
||||||
struct StoryNode
|
struct StoryNode
|
||||||
|
|
@ -51,7 +52,7 @@ public:
|
||||||
enum ImageFormat { IMG_FORMAT_BMP_4BITS, IMG_FORMAT_QOIF, IMG_FORMAT_COUNT };
|
enum ImageFormat { IMG_FORMAT_BMP_4BITS, IMG_FORMAT_QOIF, IMG_FORMAT_COUNT };
|
||||||
enum SoundFormat { SND_FORMAT_WAV, SND_FORMAT_QOAF, SND_FORMAT_COUNT };
|
enum SoundFormat { SND_FORMAT_WAV, SND_FORMAT_QOAF, SND_FORMAT_COUNT };
|
||||||
|
|
||||||
StoryProject();
|
StoryProject(ILogger &log);
|
||||||
~StoryProject();
|
~StoryProject();
|
||||||
|
|
||||||
bool *Selected() {
|
bool *Selected() {
|
||||||
|
|
@ -66,20 +67,26 @@ public:
|
||||||
StoryNode *m_tree;
|
StoryNode *m_tree;
|
||||||
*/
|
*/
|
||||||
void New(const std::string &uuid, const std::string &library_path);
|
void New(const std::string &uuid, const std::string &library_path);
|
||||||
bool Build(std::string &codeStr);
|
std::filesystem::path BinaryFileName() const;
|
||||||
|
bool GenerateScript(std::string &codeStr);
|
||||||
|
bool GenerateBinary(const std::string &code, Chip32::Assembler::Error &err);
|
||||||
bool Load(ResourceManager &manager);
|
bool Load(ResourceManager &manager);
|
||||||
void Save(ResourceManager &manager);
|
void Save(ResourceManager &manager);
|
||||||
void SaveBinary(const std::vector<uint8_t> &m_program);
|
void SaveBinary();
|
||||||
void SetPaths(const std::string &uuid, const std::string &library_path);
|
void SetPaths(const std::string &uuid, const std::string &library_path);
|
||||||
void CopyToDevice(const std::string &outputDir);
|
void CopyToDevice(const std::string &outputDir);
|
||||||
|
|
||||||
void ModelToJson(nlohmann::json &model);
|
void ModelToJson(nlohmann::json &model);
|
||||||
bool ModelFromJson(const nlohmann::json &model);
|
bool ModelFromJson(const nlohmann::json &model);
|
||||||
|
|
||||||
|
bool CopyProgramTo(uint8_t *memory, uint32_t size);
|
||||||
|
|
||||||
|
// returns >= 0 on success
|
||||||
|
bool GetAssemblyLine(uint32_t pointer_counter, uint32_t &line);
|
||||||
|
|
||||||
void CreateTree();
|
void CreateTree();
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
|
|
||||||
std::pair<std::list<std::shared_ptr<BaseNode>>::iterator, std::list<std::shared_ptr<BaseNode>>::iterator> Nodes() {
|
std::pair<std::list<std::shared_ptr<BaseNode>>::iterator, std::list<std::shared_ptr<BaseNode>>::iterator> Nodes() {
|
||||||
return std::make_pair(m_nodes.begin(), m_nodes.end());
|
return std::make_pair(m_nodes.begin(), m_nodes.end());
|
||||||
}
|
}
|
||||||
|
|
@ -102,18 +109,13 @@ public:
|
||||||
std::string GetName() const { return m_name; }
|
std::string GetName() const { return m_name; }
|
||||||
std::string GetUuid() const { return m_uuid; }
|
std::string GetUuid() const { return m_uuid; }
|
||||||
std::string GetDescription() const { return m_description; }
|
std::string GetDescription() const { return m_description; }
|
||||||
int GetVersion() const { return m_version; }
|
uint32_t GetVersion() const { return m_version; }
|
||||||
|
|
||||||
std::string BuildFullAssetsPath(const std::string &fileName) const;
|
std::string BuildFullAssetsPath(const std::string &fileName) const;
|
||||||
|
|
||||||
std::filesystem::path AssetsPath() const { return m_assetsPath; }
|
|
||||||
|
|
||||||
static std::string GetFileExtension(const std::string &FileName);
|
|
||||||
static std::string GetFileName(const std::string &path);
|
|
||||||
static std::string RemoveFileExtension(const std::string &FileName);
|
|
||||||
static void ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace);
|
|
||||||
static std::string FileToConstant(const std::string &FileName, const std::string &extension);
|
static std::string FileToConstant(const std::string &FileName, const std::string &extension);
|
||||||
static std::string Normalize(const std::string &input);
|
|
||||||
|
std::filesystem::path AssetsPath() const { return m_assetsPath; }
|
||||||
|
|
||||||
void SetTitleImage(const std::string &titleImage);
|
void SetTitleImage(const std::string &titleImage);
|
||||||
void SetTitleSound(const std::string &titleSound);
|
void SetTitleSound(const std::string &titleSound);
|
||||||
|
|
@ -124,9 +126,6 @@ public:
|
||||||
// Initialize with an existing project
|
// Initialize with an existing project
|
||||||
const bool IsInitialized() const { return m_initialized; }
|
const bool IsInitialized() const { return m_initialized; }
|
||||||
|
|
||||||
static void EraseString(std::string &theString, const std::string &toErase);
|
|
||||||
static std::string ToUpper(const std::string &input);
|
|
||||||
|
|
||||||
bool ParseStoryInformation(nlohmann::json &j);
|
bool ParseStoryInformation(nlohmann::json &j);
|
||||||
|
|
||||||
// From IStoryProject
|
// From IStoryProject
|
||||||
|
|
@ -140,17 +139,22 @@ public:
|
||||||
void DeleteLink(std::shared_ptr<Connection> c);
|
void DeleteLink(std::shared_ptr<Connection> c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ILogger &m_log;
|
||||||
|
|
||||||
// Project properties and location
|
// Project properties and location
|
||||||
std::string m_name; /// human readable name
|
std::string m_name; /// human readable name
|
||||||
std::string m_uuid;
|
std::string m_uuid;
|
||||||
std::string m_titleImage;
|
std::string m_titleImage;
|
||||||
std::string m_titleSound;
|
std::string m_titleSound;
|
||||||
std::string m_description;
|
std::string m_description;
|
||||||
int m_version;
|
uint32_t m_version;
|
||||||
bool m_selected{false};
|
bool m_selected{false};
|
||||||
|
|
||||||
std::filesystem::path m_assetsPath;
|
std::filesystem::path m_assetsPath;
|
||||||
|
|
||||||
|
Chip32::Assembler m_assembler;
|
||||||
|
std::vector<uint8_t> m_program;
|
||||||
|
|
||||||
// Model in memory
|
// Model in memory
|
||||||
std::list<std::shared_ptr<Connection>> m_links;
|
std::list<std::shared_ptr<Connection>> m_links;
|
||||||
std::list<std::shared_ptr<BaseNode>> m_nodes;
|
std::list<std::shared_ptr<BaseNode>> m_nodes;
|
||||||
|
|
|
||||||
99
shared/sys_lib.cpp
Normal file
99
shared/sys_lib.cpp
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
|
||||||
|
#include "sys_lib.h"
|
||||||
|
#include <algorithm>
|
||||||
|
#include <regex>
|
||||||
|
|
||||||
|
void SysLib::EraseString(std::string &theString, const std::string &toErase)
|
||||||
|
{
|
||||||
|
std::size_t found;
|
||||||
|
found = theString.find(toErase);
|
||||||
|
if (found != std::string::npos)
|
||||||
|
{
|
||||||
|
theString.erase(found, toErase.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SysLib::ToUpper(const std::string &input)
|
||||||
|
{
|
||||||
|
std::string str = input;
|
||||||
|
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::string SysLib::GetFileExtension(const std::string &fileName)
|
||||||
|
{
|
||||||
|
auto idx = fileName.find_last_of(".");
|
||||||
|
if(idx != std::string::npos)
|
||||||
|
{
|
||||||
|
return fileName.substr(idx + 1);
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SysLib::GetFileName(const std::string &path)
|
||||||
|
{
|
||||||
|
if (path.size() > 0)
|
||||||
|
{
|
||||||
|
auto found = path.find_last_of("/\\");
|
||||||
|
|
||||||
|
if (found != std::string::npos)
|
||||||
|
{
|
||||||
|
return path.substr(found+1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SysLib::ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace)
|
||||||
|
{
|
||||||
|
std::size_t found;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
found = theString.find(toFind);
|
||||||
|
if (found != std::string::npos)
|
||||||
|
{
|
||||||
|
theString.replace(found, 1, toReplace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (found != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SysLib::RemoveFileExtension(const std::string &filename)
|
||||||
|
{
|
||||||
|
// Trouver la dernière occurrence du point
|
||||||
|
std::size_t dotPos = filename.rfind('.');
|
||||||
|
if (dotPos == std::string::npos) {
|
||||||
|
// Pas d'extension trouvée, retourner le nom tel quel
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
// Retourner la sous-chaîne avant le point
|
||||||
|
return filename.substr(0, dotPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string SysLib::Normalize(const std::string &input)
|
||||||
|
{
|
||||||
|
std::string valid_file = input;
|
||||||
|
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '\\', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '/', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), ':', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '?', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '\"', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '<', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '>', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), '|', '_');
|
||||||
|
std::replace(valid_file.begin(), valid_file.end(), ' ', '_');
|
||||||
|
|
||||||
|
return valid_file;
|
||||||
|
}
|
||||||
17
shared/sys_lib.h
Normal file
17
shared/sys_lib.h
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class SysLib
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
|
||||||
|
static std::string GetFileExtension(const std::string &FileName);
|
||||||
|
static std::string GetFileName(const std::string &path);
|
||||||
|
static std::string RemoveFileExtension(const std::string &FileName);
|
||||||
|
static void ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace);
|
||||||
|
static std::string Normalize(const std::string &input);
|
||||||
|
static void EraseString(std::string &theString, const std::string &toErase);
|
||||||
|
static std::string ToUpper(const std::string &input);
|
||||||
|
};
|
||||||
35
shared/tlv.h
35
shared/tlv.h
|
|
@ -15,34 +15,41 @@
|
||||||
class Tlv
|
class Tlv
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit Tlv(const std::string &filename)
|
explicit Tlv()
|
||||||
{
|
{
|
||||||
m_file = std::ofstream(filename, std::ios::out | std::ios::binary);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~Tlv() {
|
~Tlv() {
|
||||||
m_file.close();
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Save(const std::string &filename)
|
||||||
|
{
|
||||||
|
auto f = std::ofstream(filename, std::ios::out | std::ios::binary);
|
||||||
|
f << m_mem;
|
||||||
|
std::flush(f);
|
||||||
|
f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_array(uint16_t size)
|
void add_array(uint16_t size)
|
||||||
{
|
{
|
||||||
m_file.write(reinterpret_cast<const char*>(&m_objectType), sizeof(m_objectType));
|
m_mem.append(reinterpret_cast<const char*>(&m_arrayType), sizeof(m_arrayType));
|
||||||
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
m_mem.append(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_string(const char *s, uint16_t size)
|
void add_string(const char *s, uint16_t size)
|
||||||
{
|
{
|
||||||
m_file.write(reinterpret_cast<const char*>(&m_stringType), sizeof(m_stringType));
|
m_mem.append(reinterpret_cast<const char*>(&m_stringType), sizeof(m_stringType));
|
||||||
|
m_mem.append(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||||
m_file.write(s, size);
|
m_mem.append(s, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_integer(uint32_t value)
|
void add_integer(uint32_t value)
|
||||||
{
|
{
|
||||||
static const uint16_t size = 4;
|
static const uint16_t size = 4;
|
||||||
m_file.write(reinterpret_cast<const char*>(&m_integerType), sizeof(m_integerType));
|
m_mem.append(reinterpret_cast<const char*>(&m_integerType), sizeof(m_integerType));
|
||||||
m_file.write(reinterpret_cast<const char*>(&size), sizeof(size));
|
m_mem.append(reinterpret_cast<const char*>(&size), sizeof(size));
|
||||||
m_file.write(reinterpret_cast<const char*>(&value), sizeof(value));
|
m_mem.append(reinterpret_cast<const char*>(&value), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_string(const std::string &s)
|
void add_string(const std::string &s)
|
||||||
|
|
@ -52,12 +59,12 @@ public:
|
||||||
|
|
||||||
void add_object(uint16_t entries)
|
void add_object(uint16_t entries)
|
||||||
{
|
{
|
||||||
m_file.write(reinterpret_cast<const char*>(&m_arrayType), sizeof(m_arrayType));
|
m_mem.append(reinterpret_cast<const char*>(&m_objectType), sizeof(m_objectType));
|
||||||
m_file.write(reinterpret_cast<const char*>(&entries), sizeof(entries));
|
m_mem.append(reinterpret_cast<const char*>(&entries), sizeof(entries));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::ofstream m_file;
|
std::string m_mem;
|
||||||
|
|
||||||
uint8_t m_arrayType = TLV_ARRAY_TYPE;
|
uint8_t m_arrayType = TLV_ARRAY_TYPE;
|
||||||
uint8_t m_objectType = TLV_OBJECT_TYPE;
|
uint8_t m_objectType = TLV_OBJECT_TYPE;
|
||||||
|
|
|
||||||
|
|
@ -239,6 +239,8 @@ set(SRCS
|
||||||
../shared/thread_safe_queue.h
|
../shared/thread_safe_queue.h
|
||||||
../shared/library_manager.h
|
../shared/library_manager.h
|
||||||
../shared/library_manager.cpp
|
../shared/library_manager.cpp
|
||||||
|
../shared/sys_lib.cpp
|
||||||
|
../shared/sys_lib.h
|
||||||
)
|
)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,10 @@
|
||||||
#include "story_project.h"
|
#include "story_project.h"
|
||||||
#include "resource_manager.h"
|
#include "resource_manager.h"
|
||||||
#include "uuid.h"
|
#include "uuid.h"
|
||||||
|
#include "sys_lib.h"
|
||||||
|
|
||||||
PackArchive::PackArchive()
|
PackArchive::PackArchive(ILogger &log)
|
||||||
|
: m_log(log)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -34,50 +36,6 @@ std::vector<std::string> PackArchive::GetImages()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string PackArchive::GetFileName(const std::string &path)
|
|
||||||
{
|
|
||||||
auto found = path.find_last_of("/\\");
|
|
||||||
return path.substr(found+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PackArchive::GetFileExtension(const std::string &FileName)
|
|
||||||
{
|
|
||||||
if(FileName.find_last_of(".") != std::string::npos)
|
|
||||||
return FileName.substr(FileName.find_last_of(".")+1);
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackArchive::ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace)
|
|
||||||
{
|
|
||||||
std::size_t found;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
found = theString.find(toFind);
|
|
||||||
if (found != std::string::npos)
|
|
||||||
{
|
|
||||||
theString.replace(found, 1, toReplace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (found != std::string::npos);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackArchive::EraseString(std::string &theString, const std::string &toErase)
|
|
||||||
{
|
|
||||||
std::size_t found;
|
|
||||||
found = theString.find(toErase);
|
|
||||||
if (found != std::string::npos)
|
|
||||||
{
|
|
||||||
theString.erase(found, toErase.size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string PackArchive::ToUpper(const std::string &input)
|
|
||||||
{
|
|
||||||
std::string str = input;
|
|
||||||
std::transform(str.begin(), str.end(), str.begin(), ::toupper);
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PackArchive::Unzip(const std::string &filePath, const std::string &parent_dest_dir)
|
void PackArchive::Unzip(const std::string &filePath, const std::string &parent_dest_dir)
|
||||||
{
|
{
|
||||||
// std::string fileName = GetFileName(filePath);
|
// std::string fileName = GetFileName(filePath);
|
||||||
|
|
@ -189,7 +147,7 @@ std::vector<std::string> PackArchive::FilesToJson(const std::string &type, const
|
||||||
res_file[12] = '\0';
|
res_file[12] = '\0';
|
||||||
|
|
||||||
std::string res_file_string(res_file);
|
std::string res_file_string(res_file);
|
||||||
ReplaceCharacter(res_file_string, "\\", "/");
|
SysLib::ReplaceCharacter(res_file_string, "\\", "/");
|
||||||
|
|
||||||
resList.push_back(res_file_string);
|
resList.push_back(res_file_string);
|
||||||
|
|
||||||
|
|
@ -381,10 +339,10 @@ bool PackArchive::Load(const std::string &filePath)
|
||||||
mZip.Close();
|
mZip.Close();
|
||||||
mCurrentNodeId = 0;
|
mCurrentNodeId = 0;
|
||||||
|
|
||||||
std::string fileName = GetFileName(filePath);
|
std::string fileName = SysLib::GetFileName(filePath);
|
||||||
std::string ext = GetFileExtension(fileName);
|
std::string ext = SysLib::GetFileExtension(fileName);
|
||||||
EraseString(fileName, "." + ext); // on retire l'extension du pack
|
SysLib::EraseString(fileName, "." + ext); // on retire l'extension du pack
|
||||||
mPackName = ToUpper(fileName);
|
mPackName = SysLib::ToUpper(fileName);
|
||||||
|
|
||||||
std::cout << "Pack name: " << mPackName << std::endl;
|
std::cout << "Pack name: " << mPackName << std::endl;
|
||||||
|
|
||||||
|
|
@ -427,7 +385,7 @@ bool PackArchive::ImportStudioFormat(const std::string &fileName, const std::str
|
||||||
// STUDIO format
|
// STUDIO format
|
||||||
std::ifstream f(basePath + "/story.json");
|
std::ifstream f(basePath + "/story.json");
|
||||||
nlohmann::json j = nlohmann::json::parse(f);
|
nlohmann::json j = nlohmann::json::parse(f);
|
||||||
StoryProject proj;
|
StoryProject proj(m_log);
|
||||||
ResourceManager res;
|
ResourceManager res;
|
||||||
|
|
||||||
if (j.contains("title"))
|
if (j.contains("title"))
|
||||||
|
|
@ -517,7 +475,7 @@ bool PackArchive::ImportStudioFormat(const std::string &fileName, const std::str
|
||||||
}
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << e.what() << std::endl;
|
m_log.Log(std::string("Import failure: ") + e.what());
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -527,7 +485,7 @@ std::string PackArchive::GetImage(const std::string &fileName)
|
||||||
{
|
{
|
||||||
//"C8B39950DE174EAA8E852A07FC468267/rf/000/05FB5530"
|
//"C8B39950DE174EAA8E852A07FC468267/rf/000/05FB5530"
|
||||||
std::string imagePath = mPackName + "/rf/" + fileName;
|
std::string imagePath = mPackName + "/rf/" + fileName;
|
||||||
ReplaceCharacter(imagePath, "\\", "/");
|
SysLib::ReplaceCharacter(imagePath, "\\", "/");
|
||||||
|
|
||||||
std::cout << "Loading " + imagePath << std::endl;
|
std::cout << "Loading " + imagePath << std::endl;
|
||||||
return OpenImage(imagePath);
|
return OpenImage(imagePath);
|
||||||
|
|
@ -542,7 +500,7 @@ std::string PackArchive::CurrentSound()
|
||||||
{
|
{
|
||||||
//"C8B39950DE174EAA8E852A07FC468267/sf/000/05FB5530"
|
//"C8B39950DE174EAA8E852A07FC468267/sf/000/05FB5530"
|
||||||
std::string soundPath = mPackName + "/sf/" + std::string(mCurrentNode.si_file);
|
std::string soundPath = mPackName + "/sf/" + std::string(mCurrentNode.si_file);
|
||||||
ReplaceCharacter(soundPath, "\\", "/");
|
SysLib::ReplaceCharacter(soundPath, "\\", "/");
|
||||||
|
|
||||||
std::cout << "Loading " + soundPath << std::endl;
|
std::cout << "Loading " + soundPath << std::endl;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,12 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "ni_parser.h"
|
#include "ni_parser.h"
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
|
#include "i_logger.h"
|
||||||
|
|
||||||
class PackArchive
|
class PackArchive
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PackArchive();
|
PackArchive(ILogger &log);
|
||||||
|
|
||||||
bool Load(const std::string &filePath);
|
bool Load(const std::string &filePath);
|
||||||
std::string OpenImage(const std::string &fileName);
|
std::string OpenImage(const std::string &fileName);
|
||||||
|
|
@ -34,6 +35,7 @@ public:
|
||||||
|
|
||||||
std::string HexDump(const char *desc, const void *addr, int len);
|
std::string HexDump(const char *desc, const void *addr, int len);
|
||||||
private:
|
private:
|
||||||
|
ILogger &m_log;
|
||||||
Zip mZip;
|
Zip mZip;
|
||||||
std::string mPackName;
|
std::string mPackName;
|
||||||
uint32_t mCurrentNodeId = 0;
|
uint32_t mCurrentNodeId = 0;
|
||||||
|
|
@ -47,11 +49,7 @@ private:
|
||||||
std::map<std::string, std::string> m_resources;
|
std::map<std::string, std::string> m_resources;
|
||||||
|
|
||||||
bool ParseNIFile(const std::string &root);
|
bool ParseNIFile(const std::string &root);
|
||||||
std::string GetFileName(const std::string &path);
|
|
||||||
std::string GetFileExtension(const std::string &FileName);
|
|
||||||
void ReplaceCharacter(std::string &theString, const std::string &toFind, const std::string &toReplace);
|
|
||||||
void EraseString(std::string &theString, const std::string &toErase);
|
|
||||||
std::string ToUpper(const std::string &input);
|
|
||||||
|
|
||||||
void DecipherFileOnDisk(const std::string &fileName);
|
void DecipherFileOnDisk(const std::string &fileName);
|
||||||
void DecipherFiles(const std::string &directory, const std::string &suffix);
|
void DecipherFiles(const std::string &directory, const std::string &suffix);
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,13 @@
|
||||||
|
#include <filesystem>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
#include "IconsMaterialDesignIcons.h"
|
||||||
|
#include "i_story_manager.h"
|
||||||
|
#include "base64.hpp"
|
||||||
|
#include "sys_lib.h"
|
||||||
#include "library_window.h"
|
#include "library_window.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "ImGuiFileDialog.h"
|
#include "ImGuiFileDialog.h"
|
||||||
#include <filesystem>
|
|
||||||
#include "IconsMaterialDesignIcons.h"
|
|
||||||
#include "i_story_manager.h"
|
|
||||||
#include <functional>
|
|
||||||
#include "base64.hpp"
|
|
||||||
|
|
||||||
typedef int (*xfer_callback_t)(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
typedef int (*xfer_callback_t)(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
|
||||||
curl_off_t ultotal, curl_off_t ulnow);
|
curl_off_t ultotal, curl_off_t ulnow);
|
||||||
|
|
@ -237,19 +239,21 @@ void LibraryWindow::SharePointJsonDownloadedCallback(bool success, const std::st
|
||||||
std::ifstream f(filename);
|
std::ifstream f(filename);
|
||||||
nlohmann::json j = nlohmann::json::parse(f);
|
nlohmann::json j = nlohmann::json::parse(f);
|
||||||
|
|
||||||
|
|
||||||
std::string archive = j["@content.downloadUrl"].get<std::string>();
|
std::string archive = j["@content.downloadUrl"].get<std::string>();
|
||||||
std::string name = j["name"].get<std::string>();
|
std::string name = j["name"].get<std::string>();
|
||||||
|
|
||||||
|
|
||||||
m_downloadQueue.push({
|
m_downloadQueue.push({
|
||||||
"dl",
|
"dl",
|
||||||
archive,
|
archive,
|
||||||
ToLocalStoreFile(StoryProject::Normalize(name)),
|
ToLocalStoreFile(SysLib::Normalize(name)),
|
||||||
std::bind(&LibraryWindow::StoryFileDownloadedCallback, this, std::placeholders::_1, std::placeholders::_2)
|
std::bind(&LibraryWindow::StoryFileDownloadedCallback, this, std::placeholders::_1, std::placeholders::_2)
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
catch(nlohmann::json::exception &e)
|
||||||
|
{
|
||||||
|
std::cout << "Json parse error: " << e.what() << std::endl;
|
||||||
|
}
|
||||||
catch(std::exception &e)
|
catch(std::exception &e)
|
||||||
{
|
{
|
||||||
std::cout << e.what() << std::endl;
|
std::cout << e.what() << std::endl;
|
||||||
|
|
@ -261,7 +265,7 @@ void LibraryWindow::StoryFileDownloadedCallback(bool success, const std::string
|
||||||
std::cout << "Finished to download: " << filename << std::endl;
|
std::cout << "Finished to download: " << filename << std::endl;
|
||||||
|
|
||||||
|
|
||||||
std::string ext = StoryProject::GetFileExtension(filename);
|
std::string ext = SysLib::GetFileExtension(filename);
|
||||||
|
|
||||||
if (ext == "zip")
|
if (ext == "zip")
|
||||||
{
|
{
|
||||||
|
|
@ -354,7 +358,7 @@ inline void InfosPane(const char *vFilter, IGFDUserDatas vUserDatas, bool *vCant
|
||||||
|
|
||||||
std::string LibraryWindow::ToLocalStoreFile(const std::string &url)
|
std::string LibraryWindow::ToLocalStoreFile(const std::string &url)
|
||||||
{
|
{
|
||||||
auto filename = StoryProject::GetFileName(url);
|
auto filename = SysLib::GetFileName(url);
|
||||||
|
|
||||||
filename = m_libraryManager.LibraryPath() + "/store/" + filename;
|
filename = m_libraryManager.LibraryPath() + "/store/" + filename;
|
||||||
std::cout << "Store file: " << filename << std::endl;
|
std::cout << "Store file: " << filename << std::endl;
|
||||||
|
|
@ -576,7 +580,7 @@ void LibraryWindow::Draw()
|
||||||
m_downloadQueue.push({
|
m_downloadQueue.push({
|
||||||
"dl",
|
"dl",
|
||||||
obj.download,
|
obj.download,
|
||||||
ToLocalStoreFile(StoryProject::Normalize(obj.title)),
|
ToLocalStoreFile(SysLib::Normalize(obj.title)),
|
||||||
std::bind(&LibraryWindow::StoryFileDownloadedCallback, this, std::placeholders::_1, std::placeholders::_2)
|
std::bind(&LibraryWindow::StoryFileDownloadedCallback, this, std::placeholders::_1, std::placeholders::_2)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -647,9 +651,6 @@ void LibraryWindow::Draw()
|
||||||
|
|
||||||
if (std::filesystem::is_directory(outputDir))
|
if (std::filesystem::is_directory(outputDir))
|
||||||
{
|
{
|
||||||
// Generate TLV file (index of all stories)
|
|
||||||
m_libraryManager.Save();
|
|
||||||
|
|
||||||
// Copy all files to device
|
// Copy all files to device
|
||||||
m_libraryManager.CopyToDevice(outputDir);
|
m_libraryManager.CopyToDevice(outputDir);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@
|
||||||
#include "ImGuiFileDialog.h"
|
#include "ImGuiFileDialog.h"
|
||||||
|
|
||||||
MainWindow::MainWindow()
|
MainWindow::MainWindow()
|
||||||
: m_emulatorWindow(*this)
|
: m_libraryManager(*this)
|
||||||
|
, m_emulatorWindow(*this)
|
||||||
, m_resourcesWindow(*this)
|
, m_resourcesWindow(*this)
|
||||||
, m_nodeEditorWindow(*this)
|
, m_nodeEditorWindow(*this)
|
||||||
, m_libraryWindow(*this, m_libraryManager)
|
, m_libraryWindow(*this, m_libraryManager)
|
||||||
|
|
@ -658,7 +659,7 @@ void MainWindow::OpenProject(const std::string &uuid)
|
||||||
|
|
||||||
void MainWindow::ImportProject(const std::string &fileName, int format)
|
void MainWindow::ImportProject(const std::string &fileName, int format)
|
||||||
{
|
{
|
||||||
PackArchive archive;
|
PackArchive archive(*this);
|
||||||
|
|
||||||
archive.ImportStudioFormat(fileName, m_libraryManager.LibraryPath());
|
archive.ImportStudioFormat(fileName, m_libraryManager.LibraryPath());
|
||||||
|
|
||||||
|
|
@ -710,7 +711,7 @@ void MainWindow::Loop()
|
||||||
|
|
||||||
while (!done)
|
while (!done)
|
||||||
{
|
{
|
||||||
auto time = SDL_GetTicks();
|
Uint64 frameStart = SDL_GetTicks();
|
||||||
bool aboutToClose = m_gui.PollEvent();
|
bool aboutToClose = m_gui.PollEvent();
|
||||||
|
|
||||||
m_gui.StartFrame();
|
m_gui.StartFrame();
|
||||||
|
|
@ -755,8 +756,10 @@ void MainWindow::Loop()
|
||||||
|
|
||||||
|
|
||||||
// Rendering and event handling
|
// Rendering and event handling
|
||||||
if ((SDL_GetTicks() - time) < 10) {
|
Uint64 frameTime = SDL_GetTicks() - frameStart; // Temps écoulé pour la frame
|
||||||
SDL_Delay(10);
|
|
||||||
|
if (frameTime < 16) { // Limite de 60 FPS
|
||||||
|
SDL_Delay(16 - frameTime); // Attendez pour compléter la frame
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -819,19 +822,46 @@ std::shared_ptr<BaseNode> MainWindow::CreateNode(const std::string &type)
|
||||||
|
|
||||||
void MainWindow::Build(bool compileonly)
|
void MainWindow::Build(bool compileonly)
|
||||||
{
|
{
|
||||||
// 1. First compile nodes to assembly
|
if (m_story->GenerateScript(m_currentCode))
|
||||||
if (CompileToAssembler())
|
|
||||||
{
|
{
|
||||||
|
m_editorWindow.SetScript(m_currentCode);
|
||||||
// 2. Compile the assembly to machine binary
|
m_dbg.run_result = VM_FINISHED;
|
||||||
GenerateBinary();
|
m_dbg.free_run = false;
|
||||||
|
|
||||||
if (!compileonly)
|
if (!compileonly)
|
||||||
{
|
{
|
||||||
// 3. Convert all media to desired type format
|
// 3. Convert all media to desired type format
|
||||||
ConvertResources();
|
m_resources.ConvertResources(m_story->AssetsPath(), ""); // pas de répertoire de destination
|
||||||
|
}
|
||||||
|
|
||||||
|
Chip32::Assembler::Error err;
|
||||||
|
if (m_story->GenerateBinary(m_currentCode, err))
|
||||||
|
{
|
||||||
|
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));
|
||||||
|
// m_romView->SetMemory(m_rom_data, m_program.size());
|
||||||
|
m_story->SaveBinary();
|
||||||
|
chip32_initialize(&m_chip32_ctx);
|
||||||
|
m_dbg.run_result = VM_READY;
|
||||||
|
UpdateVmView();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log("Program too big. Expand ROM memory.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(err.ToString(), true);
|
||||||
|
m_editorWindow.AddError(err.line, err.message); // show also the error in the code editor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::DeleteNode(const std::string &id)
|
void MainWindow::DeleteNode(const std::string &id)
|
||||||
|
|
@ -849,94 +879,18 @@ std::list<std::shared_ptr<Connection>> MainWindow::GetNodeConnections(const std:
|
||||||
return m_story->GetNodeConnections(nodeId);
|
return m_story->GetNodeConnections(nodeId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MainWindow::CompileToAssembler()
|
|
||||||
{
|
|
||||||
// 1. Check if the model can be compiled, check for errors and report
|
|
||||||
// FIXME
|
|
||||||
|
|
||||||
// 2. Generate the assembly code from the model
|
|
||||||
bool ret = m_story->Build(m_currentCode);
|
|
||||||
|
|
||||||
// Add global functions
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
std::string buffer;
|
|
||||||
|
|
||||||
std::ifstream f("scripts/media.asm");
|
|
||||||
f.seekg(0, std::ios::end);
|
|
||||||
buffer.resize(f.tellg());
|
|
||||||
f.seekg(0);
|
|
||||||
f.read(buffer.data(), buffer.size());
|
|
||||||
m_currentCode += buffer;
|
|
||||||
|
|
||||||
m_editorWindow.SetScript(m_currentCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::GenerateBinary()
|
|
||||||
{
|
|
||||||
m_dbg.run_result = VM_FINISHED;
|
|
||||||
m_dbg.free_run = false;
|
|
||||||
|
|
||||||
if (m_assembler.Parse(m_currentCode) == true )
|
|
||||||
{
|
|
||||||
if (m_assembler.BuildBinary(m_program, m_result) == true)
|
|
||||||
{
|
|
||||||
m_result.Print();
|
|
||||||
|
|
||||||
Log("Binary successfully generated.");
|
|
||||||
|
|
||||||
// Update ROM memory
|
|
||||||
std::copy(m_program.begin(), m_program.end(), m_rom_data);
|
|
||||||
|
|
||||||
// FIXME
|
|
||||||
// m_ramView->SetMemory(m_ram_data, sizeof(m_ram_data));
|
|
||||||
// m_romView->SetMemory(m_rom_data, m_program.size());
|
|
||||||
m_story->SaveBinary(m_program);
|
|
||||||
chip32_initialize(&m_chip32_ctx);
|
|
||||||
m_dbg.run_result = VM_READY;
|
|
||||||
UpdateVmView();
|
|
||||||
// DebugContext::DumpCodeAssembler(m_assembler);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Chip32::Assembler::Error err = m_assembler.GetLastError();
|
|
||||||
Log(err.ToString(), true);
|
|
||||||
m_editorWindow.AddError(err.line, err.message); // show also the error in the code editor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Chip32::Assembler::Error err = m_assembler.GetLastError();
|
|
||||||
Log(err.ToString(), true);
|
|
||||||
m_editorWindow.AddError(err.line, err.message); // show also the error in the code editor
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::UpdateVmView()
|
void MainWindow::UpdateVmView()
|
||||||
{
|
{
|
||||||
// FIXME
|
// FIXME
|
||||||
// m_vmDock->updateRegistersView(m_chip32_ctx);
|
// m_vmDock->updateRegistersView(m_chip32_ctx);
|
||||||
|
|
||||||
|
|
||||||
// Highlight next line in the test editor
|
// Highlight next line in the test editor
|
||||||
uint32_t pcVal = m_chip32_ctx.registers[PC];
|
uint32_t pcVal = m_chip32_ctx.registers[PC];
|
||||||
|
|
||||||
// On recherche quelle est la ligne qui possède une instruction à cette adresse
|
uint32_t line = 1;
|
||||||
std::vector<Chip32::Instr>::const_iterator ptr = m_assembler.Begin();
|
if (m_story->GetAssemblyLine(pcVal, line))
|
||||||
for (; ptr != m_assembler.End(); ++ptr)
|
|
||||||
{
|
{
|
||||||
if ((ptr->addr == pcVal) && ptr->isRomCode())
|
m_dbg.line = (line - 1);
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ptr != m_assembler.End())
|
|
||||||
{
|
|
||||||
m_dbg.line = (ptr->line - 1);
|
|
||||||
m_editorWindow.HighlightLine(m_dbg.line);
|
m_editorWindow.HighlightLine(m_dbg.line);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -944,51 +898,10 @@ void MainWindow::UpdateVmView()
|
||||||
// Not found
|
// Not found
|
||||||
Log("Reached end or instruction not found line: " + std::to_string(m_dbg.line));
|
Log("Reached end or instruction not found line: " + std::to_string(m_dbg.line));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Refresh RAM content
|
// Refresh RAM content
|
||||||
// m_ramView->SetMemory(m_ram_data, m_chip32_ctx.ram.size);
|
// m_ramView->SetMemory(m_ram_data, m_chip32_ctx.ram.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::ConvertResources()
|
|
||||||
{
|
|
||||||
auto [b, e] = m_resources.Items();
|
|
||||||
for (auto it = b; it != e; ++it)
|
|
||||||
{
|
|
||||||
std::string inputfile = m_story->BuildFullAssetsPath((*it)->file.c_str());
|
|
||||||
std::string outputfile = std::filesystem::path(m_story->AssetsPath() / StoryProject::RemoveFileExtension((*it)->file)).string();
|
|
||||||
|
|
||||||
int retCode = 0;
|
|
||||||
if ((*it)->format == "PNG")
|
|
||||||
{
|
|
||||||
outputfile += ".qoi"; // FIXME: prendre la config en cours désirée
|
|
||||||
retCode = MediaConverter::ImageToQoi(inputfile, outputfile);
|
|
||||||
}
|
|
||||||
else if ((*it)->format == "MP3")
|
|
||||||
{
|
|
||||||
outputfile += ".wav"; // FIXME: prendre la config en cours désirée
|
|
||||||
retCode = MediaConverter::Mp3ToWav(inputfile, outputfile);
|
|
||||||
}
|
|
||||||
else if ((*it)->format == "OGG")
|
|
||||||
{
|
|
||||||
outputfile += ".wav"; // FIXME: prendre la config en cours désirée
|
|
||||||
retCode = MediaConverter::OggToWav(inputfile, outputfile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log("Skipped: " + inputfile + ", unknown format" + outputfile, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (retCode < 0)
|
|
||||||
{
|
|
||||||
Log("Failed to convert media file " + inputfile + ", error code: " + std::to_string(retCode) + " to: " + outputfile, true);
|
|
||||||
}
|
|
||||||
else if (retCode == 0)
|
|
||||||
{
|
|
||||||
Log("Convertered file: " + inputfile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MainWindow::SaveParams()
|
void MainWindow::SaveParams()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -63,7 +63,7 @@ struct DebugContext
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class MainWindow : public IStoryManager, public IAudioEvent
|
class MainWindow : public IStoryManager, public IAudioEvent, public ILogger
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MainWindow();
|
MainWindow();
|
||||||
|
|
@ -82,9 +82,7 @@ private:
|
||||||
uint8_t m_ram_data[16*1024];
|
uint8_t m_ram_data[16*1024];
|
||||||
chip32_ctx_t m_chip32_ctx;
|
chip32_ctx_t m_chip32_ctx;
|
||||||
|
|
||||||
// Assembleur & Debugger
|
|
||||||
std::vector<uint8_t> m_program;
|
|
||||||
Chip32::Assembler m_assembler;
|
|
||||||
Chip32::Result m_result;
|
Chip32::Result m_result;
|
||||||
DebugContext m_dbg;
|
DebugContext m_dbg;
|
||||||
std::string m_currentCode;
|
std::string m_currentCode;
|
||||||
|
|
@ -124,7 +122,6 @@ private:
|
||||||
// From IStoryManager (proxy to StoryProject class)
|
// From IStoryManager (proxy to StoryProject class)
|
||||||
virtual void OpenProject(const std::string &uuid) override;
|
virtual void OpenProject(const std::string &uuid) override;
|
||||||
virtual void ImportProject(const std::string &fileName, int format);
|
virtual void ImportProject(const std::string &fileName, int format);
|
||||||
virtual void Log(const std::string &txt, bool critical = false) override;
|
|
||||||
virtual void PlaySoundFile(const std::string &fileName) override;;
|
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 &fileName) const override;
|
||||||
virtual std::pair<FilterIterator, FilterIterator> Images() override;
|
virtual std::pair<FilterIterator, FilterIterator> Images() override;
|
||||||
|
|
@ -148,6 +145,10 @@ private:
|
||||||
virtual void Next() override;
|
virtual void Next() override;
|
||||||
virtual void Previous() override;
|
virtual void Previous() override;
|
||||||
|
|
||||||
|
|
||||||
|
// From ILogger
|
||||||
|
virtual void Log(const std::string &txt, bool critical = false) override;
|
||||||
|
|
||||||
// From IAudioEvent
|
// From IAudioEvent
|
||||||
virtual void EndOfAudio() override;
|
virtual void EndOfAudio() override;
|
||||||
|
|
||||||
|
|
@ -162,9 +163,6 @@ private:
|
||||||
void CloseProject();
|
void CloseProject();
|
||||||
void DrawStatusBar();
|
void DrawStatusBar();
|
||||||
|
|
||||||
bool CompileToAssembler();
|
|
||||||
void ConvertResources();
|
|
||||||
void GenerateBinary();
|
|
||||||
void UpdateVmView();
|
void UpdateVmView();
|
||||||
uint8_t Syscall(chip32_ctx_t *ctx, uint8_t code);
|
uint8_t Syscall(chip32_ctx_t *ctx, uint8_t code);
|
||||||
std::string GetFileNameFromMemory(uint32_t addr);
|
std::string GetFileNameFromMemory(uint32_t addr);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#include "media_node.h"
|
#include "media_node.h"
|
||||||
#include "story_project.h"
|
#include "story_project.h"
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
|
#include "sys_lib.h"
|
||||||
|
|
||||||
static std::string ChoiceLabel(const std::string &id)
|
static std::string ChoiceLabel(const std::string &id)
|
||||||
{
|
{
|
||||||
|
|
@ -74,25 +74,26 @@ std::string MediaNode::Build(IStoryProject &story, int nb_out_conns)
|
||||||
<< " Type: "
|
<< " Type: "
|
||||||
<< (nb_out_conns == 0 ? "End" : nb_out_conns == 1 ? "Transition" : "Choice")
|
<< (nb_out_conns == 0 ? "End" : nb_out_conns == 1 ? "Transition" : "Choice")
|
||||||
<< "\n";
|
<< "\n";
|
||||||
std::string image = StoryProject::RemoveFileExtension(image);
|
|
||||||
std::string sound = StoryProject::RemoveFileExtension(sound);
|
std::string img = SysLib::RemoveFileExtension(image);
|
||||||
|
std::string snd = SysLib::RemoveFileExtension(sound);
|
||||||
|
|
||||||
// Le label de ce noeud est généré de la façon suivante :
|
// 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
|
// "media" + Node ID + id du noeud parent. Si pas de noeud parent, alors rien
|
||||||
ss << BaseNode::GetEntryLabel(GetId()) << ":\n";
|
ss << BaseNode::GetEntryLabel(GetId()) << ":\n";
|
||||||
|
|
||||||
if (image.size() > 0)
|
if (img.size() > 0)
|
||||||
{
|
{
|
||||||
ss << "lcons r0, $" << image << "\n";
|
ss << "lcons r0, $" << img << "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ss << "lcons r0, 0\n";
|
ss << "lcons r0, 0\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sound.size() > 0)
|
if (snd.size() > 0)
|
||||||
{
|
{
|
||||||
ss << "lcons r1, $" << sound << "\n";
|
ss << "lcons r1, $" << snd << "\n";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue