mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-08 09:43:32 +01:00
Make editor full use of Machine class
This commit is contained in:
parent
da1cb31ac2
commit
2b6d9946df
10 changed files with 138 additions and 240 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -111,7 +111,8 @@
|
||||||
"*.m": "cpp",
|
"*.m": "cpp",
|
||||||
"*.inc": "cpp",
|
"*.inc": "cpp",
|
||||||
"chip32_binary_format.h": "c",
|
"chip32_binary_format.h": "c",
|
||||||
"hash_map": "c"
|
"hash_map": "c",
|
||||||
|
"csignal": "cpp"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
#include "chip32_assembler.h"
|
#include "chip32_assembler.h"
|
||||||
#include "chip32_binary_format.h"
|
#include "chip32_binary_format.h"
|
||||||
|
|
@ -33,7 +36,7 @@ public:
|
||||||
std::vector<uint8_t> program;
|
std::vector<uint8_t> program;
|
||||||
Chip32::Assembler assembler;
|
Chip32::Assembler assembler;
|
||||||
chip32_binary_header_t header;
|
chip32_binary_header_t header;
|
||||||
|
chip32_binary_error_t error;
|
||||||
|
|
||||||
Machine() {
|
Machine() {
|
||||||
// Bind syscall handler to this instance
|
// Bind syscall handler to this instance
|
||||||
|
|
@ -159,10 +162,50 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ========================================================================
|
bool GetAssemblyLine(uint32_t pointer_counter, uint32_t &line)
|
||||||
// Méthode principale : Parse, Build, Execute
|
{
|
||||||
// ========================================================================
|
bool success = false;
|
||||||
void QuickExecute(const std::string &assemblyCode)
|
|
||||||
|
// On recherche quelle est la ligne qui possède une instruction à cette adresse
|
||||||
|
for (auto instr : assembler)
|
||||||
|
{
|
||||||
|
if ((instr->addr == pointer_counter) && instr->isRomCode())
|
||||||
|
{
|
||||||
|
line = instr->line;
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadBinary(const std::string &filename)
|
||||||
|
{
|
||||||
|
bool success = false;
|
||||||
|
std::ifstream file(filename, std::ios::binary);
|
||||||
|
|
||||||
|
if (file)
|
||||||
|
{
|
||||||
|
// Méthode 1 : La plus simple avec les itérateurs
|
||||||
|
program = std::vector<uint8_t>(
|
||||||
|
std::istreambuf_iterator<char>(file),
|
||||||
|
std::istreambuf_iterator<char>()
|
||||||
|
);
|
||||||
|
success = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SaveBinary(const std::string &filename)
|
||||||
|
{
|
||||||
|
std::ofstream o(filename , std::ios::out | std::ios::binary);
|
||||||
|
o.write(reinterpret_cast<const char*>(program.data()), program.size());
|
||||||
|
o.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Build(const std::string &assemblyCode)
|
||||||
{
|
{
|
||||||
chip32_binary_stats_t stats;
|
chip32_binary_stats_t stats;
|
||||||
|
|
||||||
|
|
@ -171,7 +214,7 @@ public:
|
||||||
|
|
||||||
if (!parseResult) {
|
if (!parseResult) {
|
||||||
std::cout << "Parse error: " << assembler.GetLastError().ToString() << std::endl;
|
std::cout << "Parse error: " << assembler.GetLastError().ToString() << std::endl;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build binary with new format
|
// Build binary with new format
|
||||||
|
|
@ -180,11 +223,29 @@ public:
|
||||||
|
|
||||||
if (!buildResult) {
|
if (!buildResult) {
|
||||||
std::cout << "Build error: " << assembler.GetLastError().ToString() << std::endl;
|
std::cout << "Build error: " << assembler.GetLastError().ToString() << std::endl;
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load binary using executable format
|
if (!LoadCurrentProgram()) {
|
||||||
chip32_binary_error_t error = chip32_binary_load(
|
std::cout << "Binary load error: " << chip32_binary_error_string(error) << std::endl;
|
||||||
|
buildResult = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
chip32_binary_build_stats(&header, &stats);
|
||||||
|
chip32_binary_print_stats(&stats);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetEvent(uint32_t ev) {
|
||||||
|
ctx.registers[R0] = ev;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadCurrentProgram()
|
||||||
|
{
|
||||||
|
// Load binary using executable format
|
||||||
|
error = chip32_binary_load(
|
||||||
&ctx,
|
&ctx,
|
||||||
program.data(),
|
program.data(),
|
||||||
static_cast<uint32_t>(program.size()),
|
static_cast<uint32_t>(program.size()),
|
||||||
|
|
@ -193,15 +254,16 @@ public:
|
||||||
&header
|
&header
|
||||||
);
|
);
|
||||||
|
|
||||||
if (error != CHIP32_BIN_OK) {
|
return error == CHIP32_BIN_OK;
|
||||||
std::cout << "Binary load error: " << chip32_binary_error_string(error) << std::endl;
|
}
|
||||||
buildResult = false;
|
|
||||||
return;
|
// ========================================================================
|
||||||
}
|
// Méthode principale : Parse, Build, Execute
|
||||||
|
// ========================================================================
|
||||||
|
void QuickExecute(const std::string &assemblyCode)
|
||||||
|
{
|
||||||
|
Build(assemblyCode);
|
||||||
|
|
||||||
chip32_binary_build_stats(&header, &stats);
|
|
||||||
chip32_binary_print_stats(&stats);
|
|
||||||
|
|
||||||
// Set syscall handler using wrapper
|
// Set syscall handler using wrapper
|
||||||
ctx.syscall = SyscallWrapper;
|
ctx.syscall = SyscallWrapper;
|
||||||
ctx.user_data = this;
|
ctx.user_data = this;
|
||||||
|
|
@ -544,4 +606,4 @@ private:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Chip32
|
} // namespace Chip32
|
||||||
|
|
|
||||||
|
|
@ -54,14 +54,16 @@ void StoryProject::CopyToDevice(const std::string &outputDir, NodesFactory &fact
|
||||||
|
|
||||||
std::cout << code << std::endl;
|
std::cout << code << std::endl;
|
||||||
|
|
||||||
Chip32::Assembler::Error err;
|
// FIXME génération
|
||||||
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
|
// Chip32::Assembler::Error err;
|
||||||
manager.ConvertResources(AssetsPath(), destAssetsDir, m_storyOptions.image_format, m_storyOptions.sound_format);
|
// 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, m_storyOptions.image_format, m_storyOptions.sound_format);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
void StoryProject::New(const std::string &uuid, const std::string &library_path)
|
void StoryProject::New(const std::string &uuid, const std::string &library_path)
|
||||||
|
|
@ -86,14 +88,6 @@ std::filesystem::path StoryProject::BinaryFileName() const
|
||||||
return m_working_dir / "story.c32";
|
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.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StoryProject::ParseStoryInformation(nlohmann::json &j)
|
bool StoryProject::ParseStoryInformation(nlohmann::json &j)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
@ -321,17 +315,6 @@ bool StoryProject::ModelFromJson(const nlohmann::json &model, NodesFactory &fact
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<IStoryProject::FunctionInfo> StoryProject::GetFunctionsList() const
|
std::vector<IStoryProject::FunctionInfo> StoryProject::GetFunctionsList() const
|
||||||
{
|
{
|
||||||
|
|
@ -357,27 +340,6 @@ std::vector<IStoryProject::FunctionInfo> StoryProject::GetFunctionsList() const
|
||||||
return functions;
|
return functions;
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<std::shared_ptr<Connection>> StoryProject::GetNodeConnections(const std::string &nodeId)
|
std::list<std::shared_ptr<Connection>> StoryProject::GetNodeConnections(const std::string &nodeId)
|
||||||
{
|
{
|
||||||
|
|
@ -542,37 +504,6 @@ bool StoryProject::GenerateCompleteProgram(std::string &assembly)
|
||||||
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, NodesFactory &factory)
|
bool StoryProject::Load(ResourceManager &manager, NodesFactory &factory)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -31,44 +31,22 @@ public:
|
||||||
return &m_selected;
|
return &m_selected;
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::shared_ptr<StoryProject> shared_from_this() {
|
|
||||||
// return shared_from_this();
|
|
||||||
// }
|
|
||||||
|
|
||||||
std::string MainUuid() const {
|
std::string MainUuid() const {
|
||||||
return "490745ab-df4d-476d-ae27-027e94b8ee0a";
|
return "490745ab-df4d-476d-ae27-027e94b8ee0a";
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FindMain(Chip32::Instr &mainLine) {
|
|
||||||
|
|
||||||
std::shared_ptr<Chip32::Instr> m;
|
|
||||||
bool success = m_assembler.GetMain(m);
|
|
||||||
if (success)
|
|
||||||
{
|
|
||||||
mainLine = *m;
|
|
||||||
}
|
|
||||||
return success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GenerateCompleteProgram(std::string &assembly);
|
bool GenerateCompleteProgram(std::string &assembly);
|
||||||
|
|
||||||
void New(const std::string &uuid, const std::string &library_path);
|
void New(const std::string &uuid, const std::string &library_path);
|
||||||
std::filesystem::path BinaryFileName() const;
|
std::filesystem::path BinaryFileName() const;
|
||||||
bool GenerateBinary(const std::string &code, Chip32::Assembler::Error &err);
|
|
||||||
bool Load(ResourceManager &manager, NodesFactory &factory);
|
bool Load(ResourceManager &manager, NodesFactory &factory);
|
||||||
void Save(ResourceManager &manager);
|
void Save(ResourceManager &manager);
|
||||||
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, NodesFactory &factory);
|
void CopyToDevice(const std::string &outputDir, NodesFactory &factory);
|
||||||
|
|
||||||
void ModelToJson(nlohmann::json &model);
|
void ModelToJson(nlohmann::json &model);
|
||||||
bool ModelFromJson(const nlohmann::json &model, NodesFactory &factory);
|
bool ModelFromJson(const nlohmann::json &model, NodesFactory &factory);
|
||||||
|
|
||||||
bool CopyProgramTo(uint8_t *memory, uint32_t size);
|
|
||||||
|
|
||||||
// returns >= 0 on success
|
|
||||||
bool GetAssemblyLine(uint32_t pointer_counter, uint32_t &line);
|
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
void Select(bool selected) { m_selected = selected; }
|
void Select(bool selected) { m_selected = selected; }
|
||||||
|
|
@ -148,10 +126,6 @@ private:
|
||||||
std::unordered_set<std::string> m_usedLabels; // permet de ne pas générer un label qui existe déjà
|
std::unordered_set<std::string> m_usedLabels; // permet de ne pas générer un label qui existe déjà
|
||||||
|
|
||||||
std::filesystem::path m_assetsPath;
|
std::filesystem::path m_assetsPath;
|
||||||
|
|
||||||
Chip32::Assembler m_assembler;
|
|
||||||
std::vector<uint8_t> m_program;
|
|
||||||
|
|
||||||
std::list<std::shared_ptr<StoryPage>> m_pages;
|
std::list<std::shared_ptr<StoryPage>> m_pages;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Variable>> m_variables;
|
std::vector<std::shared_ptr<Variable>> m_variables;
|
||||||
|
|
|
||||||
|
|
@ -27,23 +27,9 @@ AppController::AppController(ILogger& logger, EventBus& eventBus)
|
||||||
, m_player(*this) // m_player a besoin d'un IAudioEvent
|
, m_player(*this) // m_player a besoin d'un IAudioEvent
|
||||||
, m_webServer(m_libraryManager)
|
, m_webServer(m_libraryManager)
|
||||||
{
|
{
|
||||||
// VM Initialize - Déplacé du constructeur de MainWindow
|
|
||||||
m_chip32_ctx.stack_size = 512;
|
|
||||||
|
|
||||||
m_chip32_ctx.rom.mem = m_rom_data;
|
|
||||||
m_chip32_ctx.rom.addr = 0;
|
|
||||||
m_chip32_ctx.rom.size = sizeof(m_rom_data);
|
|
||||||
|
|
||||||
m_chip32_ctx.ram.mem = m_ram_data;
|
|
||||||
m_chip32_ctx.ram.addr = sizeof(m_rom_data);
|
|
||||||
m_chip32_ctx.ram.size = sizeof(m_ram_data);
|
|
||||||
|
|
||||||
// Initialise le trampoline de syscall avec cette instance
|
|
||||||
// SyscallTrampoline::s_instance = this;
|
|
||||||
// m_chip32_ctx.syscall = SyscallTrampoline::Callback;
|
|
||||||
|
|
||||||
Callback<uint8_t(chip32_ctx_t *, uint8_t)>::func = std::bind(&AppController::Syscall, this, std::placeholders::_1, std::placeholders::_2);
|
Callback<uint8_t(chip32_ctx_t *, uint8_t)>::func = std::bind(&AppController::Syscall, this, std::placeholders::_1, std::placeholders::_2);
|
||||||
m_chip32_ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(chip32_ctx_t *, uint8_t)>::callback);
|
m_machine.ctx.syscall = static_cast<syscall_t>(Callback<uint8_t(chip32_ctx_t *, uint8_t)>::callback);
|
||||||
|
|
||||||
// Assurez-vous que ces fonctions existent ou sont implémentées ailleurs
|
// Assurez-vous que ces fonctions existent ou sont implémentées ailleurs
|
||||||
// CloseProject() et CloseModule() étaient dans MainWindow
|
// CloseProject() et CloseModule() étaient dans MainWindow
|
||||||
|
|
@ -247,38 +233,20 @@ void AppController::Build(bool compileonly)
|
||||||
m_resources.ConvertResources(m_story->AssetsPath(), "", options.image_format, options.sound_format);
|
m_resources.ConvertResources(m_story->AssetsPath(), "", options.image_format, options.sound_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
Chip32::Assembler::Error err;
|
|
||||||
// La GUI (DebuggerWindow) doit être notifiée pour effacer les erreurs. FIXME
|
if (m_machine.Build(m_storyAssembly))
|
||||||
// m_debuggerWindow.ClearErrors();
|
|
||||||
|
|
||||||
if (m_story->GenerateBinary(m_storyAssembly, err))
|
|
||||||
{
|
{
|
||||||
m_result.Print(); // Imprime le résultat de l'assemblage (Debug uniquement)
|
m_machine.SaveBinary(m_story->BinaryFileName());
|
||||||
|
m_dbg.run_result = VM_READY;
|
||||||
|
UpdateVmView(); // Notifie la GUI de mettre à jour la vue VM
|
||||||
|
m_logger.Log("Build successful. VM ready.");
|
||||||
|
|
||||||
if (m_story->CopyProgramTo(m_rom_data, sizeof (m_rom_data)))
|
m_eventBus.Emit(std::make_shared<GenericResultEvent>(false, "Build success"));
|
||||||
{
|
|
||||||
m_story->SaveBinary();
|
|
||||||
chip32_initialize(&m_chip32_ctx);
|
|
||||||
|
|
||||||
Chip32::Instr mainLine;
|
|
||||||
if (m_story->FindMain(mainLine)) {
|
|
||||||
m_chip32_ctx.registers[PC] = mainLine.addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dbg.run_result = VM_READY;
|
|
||||||
UpdateVmView(); // Notifie la GUI de mettre à jour la vue VM
|
|
||||||
m_logger.Log("Build successful. VM ready.");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_logger.Log("Program too big. Expand ROM memory.", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_logger.Log(err.ToString(), true);
|
auto err = m_machine.assembler.GetLastError(); // FIXME: l'erreur ne vient pas uniquement de l'assembleur, enfouir cela et remonter d'autres erreurs liées à la machine
|
||||||
// La GUI (DebuggerWindow) doit être notifiée pour ajouter l'erreur. FIXME
|
m_eventBus.Emit(std::make_shared<GenericResultEvent>(false, "Build error: " + err.ToString()));
|
||||||
// m_debuggerWindow.AddError(err.line, err.message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,44 +265,22 @@ void AppController::BuildModule(bool compileonly)
|
||||||
m_logger.Log(m_moduleAssembly);
|
m_logger.Log(m_moduleAssembly);
|
||||||
m_logger.Log("============================");
|
m_logger.Log("============================");
|
||||||
|
|
||||||
// Try to compile the module code directly
|
if (m_machine.Build(m_moduleAssembly))
|
||||||
Chip32::Assembler::Error err;
|
|
||||||
|
|
||||||
if (m_module->GenerateBinary(m_moduleAssembly, err))
|
|
||||||
{
|
{
|
||||||
m_logger.Log("Module compiled successfully!");
|
m_logger.Log("Module compiled successfully!");
|
||||||
|
|
||||||
// Save the binary to disk
|
// Save the binary to disk
|
||||||
m_module->SaveBinary();
|
m_machine.SaveBinary(m_module->BinaryFileName());
|
||||||
|
m_dbg.run_result = VM_READY;
|
||||||
// Load into VM for testing
|
UpdateVmView(); // Notifie la GUI de mettre à jour la vue VM
|
||||||
if (m_module->CopyProgramTo(m_rom_data, sizeof(m_rom_data)))
|
m_eventBus.Emit(std::make_shared<ModuleEvent>(ModuleEvent::Type::BuildSuccess, m_module->GetUuid()));
|
||||||
{
|
|
||||||
chip32_initialize(&m_chip32_ctx);
|
|
||||||
|
|
||||||
Chip32::Instr mainLine;
|
|
||||||
if (m_module->FindMain(mainLine)) {
|
|
||||||
m_chip32_ctx.registers[PC] = mainLine.addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dbg.run_result = VM_READY;
|
|
||||||
UpdateVmView();
|
|
||||||
|
|
||||||
m_logger.Log("Module binary ready for testing.");
|
|
||||||
m_eventBus.Emit(std::make_shared<ModuleEvent>(ModuleEvent::Type::BuildSuccess, m_module->GetUuid()));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto errObj = std::make_shared<ModuleEvent>(ModuleEvent::Type::BuildFailure, m_module->GetUuid());
|
|
||||||
errObj->SetFailure("Module program too big. Expand ROM memory.", -1);
|
|
||||||
m_eventBus.Emit(errObj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Compilation failed - show error
|
// Compilation failed - show error
|
||||||
|
auto err = m_machine.assembler.GetLastError(); // FIXME: l'erreur ne vient pas uniquement de l'assembleur, enfouir cela et remonter d'autres erreurs liées à la machine
|
||||||
|
|
||||||
std::string errorMsg = err.ToString();
|
std::string errorMsg = err.ToString();
|
||||||
|
|
||||||
auto errObj = std::make_shared<ModuleEvent>(ModuleEvent::Type::BuildFailure, m_module->GetUuid());
|
auto errObj = std::make_shared<ModuleEvent>(ModuleEvent::Type::BuildFailure, m_module->GetUuid());
|
||||||
errObj->SetFailure(errorMsg, err.line);
|
errObj->SetFailure(errorMsg, err.line);
|
||||||
m_eventBus.Emit(errObj);
|
m_eventBus.Emit(errObj);
|
||||||
|
|
@ -372,32 +318,15 @@ void AppController::SetExternalSourceFile(const std::string &filename)
|
||||||
|
|
||||||
void AppController::LoadBinaryStory(const std::string &filename)
|
void AppController::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)
|
if (m_machine.LoadBinary(filename))
|
||||||
{
|
{
|
||||||
size_t sizeRead = fread(m_chip32_ctx.rom.mem, 1, sz, fp); // Corrected fread args
|
m_dbg.run_result = VM_READY;
|
||||||
if (sizeRead == (size_t)sz) // Cast sz to size_t for comparison
|
m_logger.Log("Loaded binary file: " + filename);
|
||||||
{
|
UpdateVmView();
|
||||||
m_dbg.run_result = VM_READY;
|
}
|
||||||
chip32_initialize(&m_chip32_ctx);
|
else
|
||||||
m_logger.Log("Loaded binary file: " + filename);
|
{
|
||||||
UpdateVmView();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_logger.Log("Failed to load binary file completely. Read " + std::to_string(sizeRead) + " of " + std::to_string(sz) + " bytes.", true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
m_logger.Log("Binary file is too large for ROM: " + std::to_string(sz) + " bytes, max " + std::to_string(m_chip32_ctx.rom.size) + " bytes.", true);
|
|
||||||
}
|
|
||||||
fclose(fp);
|
|
||||||
} else {
|
|
||||||
m_logger.Log("Failed to open binary file: " + filename, true);
|
m_logger.Log("Failed to open binary file: " + filename, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -422,7 +351,7 @@ uint32_t AppController::GetRegister(int reg)
|
||||||
uint32_t regVal = 0;
|
uint32_t regVal = 0;
|
||||||
if (reg >= 0 && reg < REGISTER_COUNT) // Assurez-vous que REGISTER_COUNT est défini
|
if (reg >= 0 && reg < REGISTER_COUNT) // Assurez-vous que REGISTER_COUNT est défini
|
||||||
{
|
{
|
||||||
regVal = m_chip32_ctx.registers[reg];
|
regVal = m_machine.ctx.registers[reg];
|
||||||
}
|
}
|
||||||
return regVal;
|
return regVal;
|
||||||
}
|
}
|
||||||
|
|
@ -620,7 +549,7 @@ void AppController::ProcessStory()
|
||||||
{
|
{
|
||||||
if (m_dbg.IsValidEvent(EV_MASK_OK_BUTTON))
|
if (m_dbg.IsValidEvent(EV_MASK_OK_BUTTON))
|
||||||
{
|
{
|
||||||
m_chip32_ctx.registers[R0] = EV_MASK_OK_BUTTON;
|
m_machine.SetEvent(EV_MASK_OK_BUTTON);
|
||||||
m_dbg.run_result = VM_OK;
|
m_dbg.run_result = VM_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -628,7 +557,7 @@ void AppController::ProcessStory()
|
||||||
{
|
{
|
||||||
if (m_dbg.IsValidEvent(EV_MASK_PREVIOUS_BUTTON))
|
if (m_dbg.IsValidEvent(EV_MASK_PREVIOUS_BUTTON))
|
||||||
{
|
{
|
||||||
m_chip32_ctx.registers[R0] = EV_MASK_PREVIOUS_BUTTON;
|
m_machine.SetEvent(EV_MASK_PREVIOUS_BUTTON);
|
||||||
m_dbg.run_result = VM_OK;
|
m_dbg.run_result = VM_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -636,7 +565,7 @@ void AppController::ProcessStory()
|
||||||
{
|
{
|
||||||
if (m_dbg.IsValidEvent(EV_MASK_NEXT_BUTTON))
|
if (m_dbg.IsValidEvent(EV_MASK_NEXT_BUTTON))
|
||||||
{
|
{
|
||||||
m_chip32_ctx.registers[R0] = EV_MASK_NEXT_BUTTON;
|
m_machine.SetEvent(EV_MASK_NEXT_BUTTON);
|
||||||
m_dbg.run_result = VM_OK;
|
m_dbg.run_result = VM_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -644,7 +573,7 @@ void AppController::ProcessStory()
|
||||||
{
|
{
|
||||||
if (m_dbg.IsValidEvent(EV_MASK_END_OF_AUDIO))
|
if (m_dbg.IsValidEvent(EV_MASK_END_OF_AUDIO))
|
||||||
{
|
{
|
||||||
m_chip32_ctx.registers[R0] = EV_MASK_END_OF_AUDIO;
|
m_machine.SetEvent(EV_MASK_END_OF_AUDIO);
|
||||||
m_dbg.run_result = VM_OK;
|
m_dbg.run_result = VM_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -652,7 +581,7 @@ void AppController::ProcessStory()
|
||||||
{
|
{
|
||||||
if (m_dbg.IsValidEvent(EV_MASK_HOME_BUTTON))
|
if (m_dbg.IsValidEvent(EV_MASK_HOME_BUTTON))
|
||||||
{
|
{
|
||||||
m_chip32_ctx.registers[R0] = EV_MASK_HOME_BUTTON;
|
m_machine.SetEvent(EV_MASK_HOME_BUTTON);
|
||||||
m_dbg.run_result = VM_OK;
|
m_dbg.run_result = VM_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -705,7 +634,7 @@ void AppController::ProcessStory()
|
||||||
|
|
||||||
void AppController::StepInstruction()
|
void AppController::StepInstruction()
|
||||||
{
|
{
|
||||||
m_dbg.run_result = chip32_step(&m_chip32_ctx);
|
m_dbg.run_result = chip32_step(&m_machine.ctx);
|
||||||
UpdateVmView();
|
UpdateVmView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -788,11 +717,11 @@ void AppController::UpdateVmView()
|
||||||
// C'est une fonction de notification pour la GUI.
|
// C'est une fonction de notification pour la GUI.
|
||||||
// AppController ne devrait pas directement manipuler les vues GUI.
|
// AppController ne devrait pas directement manipuler les vues GUI.
|
||||||
// Au lieu de cela, il émettrait un signal ou appellerait un observer.
|
// Au lieu de cela, il émettrait un signal ou appellerait un observer.
|
||||||
uint32_t pcVal = m_chip32_ctx.registers[PC];
|
uint32_t pcVal = m_machine.ctx.registers[PC];
|
||||||
|
|
||||||
if (m_story)
|
if (m_story)
|
||||||
{
|
{
|
||||||
if (m_story->GetAssemblyLine(pcVal, m_dbg.line))
|
if (m_machine.GetAssemblyLine(pcVal, m_dbg.line))
|
||||||
{
|
{
|
||||||
m_logger.Log("Executing line: " + std::to_string(m_dbg.line + 1));
|
m_logger.Log("Executing line: " + std::to_string(m_dbg.line + 1));
|
||||||
// m_debuggerWindow.HighlightLine(m_dbg.line); // Dépendance GUI
|
// m_debuggerWindow.HighlightLine(m_dbg.line); // Dépendance GUI
|
||||||
|
|
@ -835,7 +764,6 @@ void AppController::CloseProject()
|
||||||
m_dbg.run_result = VM_FINISHED;
|
m_dbg.run_result = VM_FINISHED;
|
||||||
m_dbg.free_run = false;
|
m_dbg.free_run = false;
|
||||||
m_dbg.m_breakpoints.clear();
|
m_dbg.m_breakpoints.clear();
|
||||||
chip32_initialize(&m_chip32_ctx); // Reset VM context
|
|
||||||
|
|
||||||
m_resources.Clear(); // Clear loaded resources
|
m_resources.Clear(); // Clear loaded resources
|
||||||
m_eventQueue.clear(); // Clear any pending VM events
|
m_eventQueue.clear(); // Clear any pending VM events
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
#include "variable.h" // Pour Variable (si géré par AppController)
|
#include "variable.h" // Pour Variable (si géré par AppController)
|
||||||
#include "debug_context.h" // Pour DebugContext
|
#include "debug_context.h" // Pour DebugContext
|
||||||
#include "event_bus.h"
|
#include "event_bus.h"
|
||||||
|
#include "chip32_machine.h"
|
||||||
|
|
||||||
// Forward declaration pour éviter les dépendances circulaires si le logger est une GUI
|
// Forward declaration pour éviter les dépendances circulaires si le logger est une GUI
|
||||||
class ILogger; // Peut être implémenté par la console_window par exemple
|
class ILogger; // Peut être implémenté par la console_window par exemple
|
||||||
|
|
@ -98,7 +99,7 @@ public:
|
||||||
void LoadParams();
|
void LoadParams();
|
||||||
|
|
||||||
// Méthodes pour interagir avec la VM et le débogueur
|
// Méthodes pour interagir avec la VM et le débogueur
|
||||||
chip32_ctx_t* GetChip32Context() { return &m_chip32_ctx; }
|
chip32_ctx_t* GetChip32Context() { return &m_machine.ctx; }
|
||||||
DebugContext* GetDebugContext() { return &m_dbg; }
|
DebugContext* GetDebugContext() { return &m_dbg; }
|
||||||
|
|
||||||
void ProcessStory();
|
void ProcessStory();
|
||||||
|
|
@ -130,15 +131,13 @@ private:
|
||||||
|
|
||||||
std::shared_ptr<StoryProject> m_story;
|
std::shared_ptr<StoryProject> m_story;
|
||||||
std::shared_ptr<StoryProject> m_module;
|
std::shared_ptr<StoryProject> m_module;
|
||||||
uint8_t m_rom_data[16*1024];
|
Chip32::Machine m_machine;
|
||||||
uint8_t m_ram_data[16*1024];
|
|
||||||
chip32_ctx_t m_chip32_ctx;
|
|
||||||
Chip32::Result m_result;
|
|
||||||
DebugContext m_dbg; // Contexte de débogage
|
DebugContext m_dbg; // Contexte de débogage
|
||||||
std::string m_storyAssembly;
|
std::string m_storyAssembly;
|
||||||
std::string m_moduleAssembly;
|
std::string m_moduleAssembly;
|
||||||
std::string m_externalSourceFileName;
|
|
||||||
std::vector<std::string> m_recentProjects;
|
std::vector<std::string> m_recentProjects;
|
||||||
|
std::string m_externalSourceFileName;
|
||||||
|
|
||||||
NodesFactory m_nodesFactory;
|
NodesFactory m_nodesFactory;
|
||||||
ResourceManager m_resources; // Gère les ressources (images, sons)
|
ResourceManager m_resources; // Gère les ressources (images, sons)
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@ struct DebugContext
|
||||||
return (event_mask & event) != 0;
|
return (event_mask & event) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void DumpCodeAssembler(Chip32::Assembler & assembler) {
|
static void DumpCodeAssembler(Chip32::Assembler & assembler)
|
||||||
|
{
|
||||||
|
|
||||||
for (std::vector<Chip32::Instr>::const_iterator iter = assembler.Begin();
|
for (auto iter : assembler)
|
||||||
iter != assembler.End(); ++iter)
|
|
||||||
{
|
{
|
||||||
if (iter->isRomCode() || iter->isRomData)
|
if (iter->isRomCode() || iter->isRomData)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -568,8 +568,6 @@ bool MainWindow::Loop()
|
||||||
|
|
||||||
if (m_appController.IsLibraryManagerInitialized())
|
if (m_appController.IsLibraryManagerInitialized())
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
bool nodeEditorFocused = m_nodeEditorWindow.IsFocused();
|
bool nodeEditorFocused = m_nodeEditorWindow.IsFocused();
|
||||||
bool moduleEditorFocused = m_moduleEditorWindow.IsFocused();
|
bool moduleEditorFocused = m_moduleEditorWindow.IsFocused();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "node_widget_factory.h"
|
#include "node_widget_factory.h"
|
||||||
#include "Localization.h"
|
#include "Localization.h"
|
||||||
#include "LanguageSelector.h"
|
#include "LanguageSelector.h"
|
||||||
|
#include "chip32_machine.h"
|
||||||
|
|
||||||
class MainWindow : public std::enable_shared_from_this<MainWindow>, public ILogSubject
|
class MainWindow : public std::enable_shared_from_this<MainWindow>, public ILogSubject
|
||||||
{
|
{
|
||||||
|
|
|
||||||
4
story-editor/story-editor.kdev4
Normal file
4
story-editor/story-editor.kdev4
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
[Project]
|
||||||
|
CreatedFrom=CMakeLists.txt
|
||||||
|
Manager=KDevCMakeManager
|
||||||
|
Name=story-editor
|
||||||
Loading…
Reference in a new issue