mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-06 08:59:35 +01:00
Multiple runtime fixes, first build+execution with graphical nodes
This commit is contained in:
parent
d6df8b65ab
commit
47552d4719
7 changed files with 148 additions and 44 deletions
|
|
@ -118,12 +118,18 @@ private:
|
|||
auto* varNode = inputNode->GetAs<VariableNode>();
|
||||
if (varNode) {
|
||||
auto var = varNode->GetVariable();
|
||||
// Generate code to load the variable value
|
||||
// FIXME: hardcoded 4 bytes, replace by actual real variable size
|
||||
m_assembly << " load r" << reg << ", $" << var->GetLabel() << ", 4" << "; Load variable " << var->GetVariableName() << "\n";
|
||||
m_assembly << " push r" << reg << "\n";
|
||||
// Assuming we have a function to load the variable value
|
||||
// m_assembly << " load r0, " << varNode->GetVariableName() << "\n";
|
||||
|
||||
if (var)
|
||||
{
|
||||
// Generate code to load the variable value
|
||||
// FIXME: hardcoded 4 bytes, replace by actual real variable size
|
||||
m_assembly << " load r" << reg << ", $" << var->GetLabel() << ", 4" << "; Load variable " << var->GetVariableName() << "\n";
|
||||
m_assembly << " push r" << reg << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("ERROR! Variable not set in node: " + inputNode->node->GetId());
|
||||
}
|
||||
}
|
||||
reg++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ PrintNode::PrintNode(const std::string &type)
|
|||
// Create empty variable in memory
|
||||
auto v = std::make_shared<Variable>(m_label);
|
||||
v->SetTextValue("");
|
||||
v->SetConstant(true);
|
||||
m_label = v->GetLabel();
|
||||
m_variables[m_label] = v;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ StoryProject::StoryProject(ILogger &log)
|
|||
: m_log(log)
|
||||
{
|
||||
// registerNode<MediaNode>("media-node");
|
||||
registerNode<FunctionNode>("operator-node");
|
||||
registerNode<OperatorNode>("operator-node");
|
||||
registerNode<FunctionNode>("function-node");
|
||||
registerNode<VariableNode>("variable-node");
|
||||
registerNode<PrintNode>("print-node");
|
||||
|
|
@ -384,6 +384,7 @@ bool StoryProject::UseResource(const std::string &label)
|
|||
|
||||
bool StoryProject::GenerateScript(std::string &codeStr)
|
||||
{
|
||||
bool retCode = true;
|
||||
std::stringstream code;
|
||||
|
||||
// Empty resources usage
|
||||
|
|
@ -403,43 +404,40 @@ bool StoryProject::GenerateScript(std::string &codeStr)
|
|||
// Create generator
|
||||
AssemblyGeneratorChip32 generator(context);
|
||||
|
||||
|
||||
generator.Reset();
|
||||
|
||||
// Generate header comments
|
||||
generator.GenerateHeader();
|
||||
|
||||
// Generate data section
|
||||
generator.StartSection(AssemblyGenerator::Section::DATA);
|
||||
for (const auto & p : m_pages)
|
||||
try
|
||||
{
|
||||
p->BuildNodesVariables(generator);
|
||||
generator.Reset();
|
||||
|
||||
// Generate header comments
|
||||
generator.GenerateHeader();
|
||||
|
||||
// Generate text section
|
||||
generator.StartSection(AssemblyGenerator::Section::TEXT);
|
||||
for (const auto & p : m_pages)
|
||||
{
|
||||
p->BuildNodes(generator);
|
||||
}
|
||||
|
||||
// Generate data section
|
||||
generator.StartSection(AssemblyGenerator::Section::DATA);
|
||||
for (const auto & p : m_pages)
|
||||
{
|
||||
p->BuildNodesVariables(generator);
|
||||
}
|
||||
generator.GenerateGlobalVariables(m_variables);
|
||||
|
||||
generator.GenerateExit();
|
||||
|
||||
}
|
||||
generator.GenerateGlobalVariables(m_variables);
|
||||
|
||||
// Generate text section
|
||||
generator.StartSection(AssemblyGenerator::Section::TEXT);
|
||||
|
||||
for (const auto & p : m_pages)
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
p->BuildNodes(generator);
|
||||
m_log.Log(e.what(), true);
|
||||
retCode = false;
|
||||
}
|
||||
|
||||
generator.GenerateExit();
|
||||
|
||||
codeStr = generator.GetAssembly();
|
||||
|
||||
// Add our utility functions
|
||||
// std::string buffer;
|
||||
|
||||
// std::ifstream f("scripts/media.chip32");
|
||||
// f.seekg(0, std::ios::end);
|
||||
// buffer.resize(f.tellg());
|
||||
// f.seekg(0);
|
||||
// f.read(buffer.data(), buffer.size());
|
||||
// codeStr += buffer;
|
||||
|
||||
return true;
|
||||
return retCode;
|
||||
}
|
||||
|
||||
bool StoryProject::GenerateBinary(const std::string &code, Chip32::Assembler::Error &err)
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ uint8_t vm_syscall(chip32_ctx_t *ctx, uint8_t code)
|
|||
if (m_chip32_ctx.registers[R0] != 0)
|
||||
{
|
||||
// image file name address is in R0
|
||||
// QString imageFile = m_model.BuildFullImagePath(GetFileNameFromMemory(m_chip32_ctx.registers[R0]));
|
||||
// QString imageFile = m_model.BuildFullImagePath(GetStringFromMemory(m_chip32_ctx.registers[R0]));
|
||||
// m_ostHmiDock->SetImage(imageFile);
|
||||
get_file_from_memory(ImageFile, m_chip32_ctx.registers[R0]);
|
||||
fs_task_image_start(ImageFile);
|
||||
|
|
@ -96,7 +96,7 @@ uint8_t vm_syscall(chip32_ctx_t *ctx, uint8_t code)
|
|||
if (m_chip32_ctx.registers[R1] != 0)
|
||||
{
|
||||
// sound file name address is in R1
|
||||
// QString soundFile = m_model.BuildFullSoundPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1]));
|
||||
// QString soundFile = m_model.BuildFullSoundPath(GetStringFromMemory(m_chip32_ctx.registers[R1]));
|
||||
// qDebug() << ", Sound: " << soundFile;
|
||||
// m_model.PlaySoundFile(soundFile);
|
||||
get_file_from_memory(SoundFile, m_chip32_ctx.registers[R1]);
|
||||
|
|
|
|||
|
|
@ -116,6 +116,30 @@ void BaseNodeWidget::FrameStart()
|
|||
}
|
||||
}
|
||||
m_firstFrame = false;
|
||||
|
||||
|
||||
// Title
|
||||
|
||||
const char * text = m_base->GetTypeName().c_str();
|
||||
// Obtenir la position courante du curseur
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
|
||||
// Définir les dimensions du texte
|
||||
ImVec2 text_size = ImGui::CalcTextSize(text);
|
||||
|
||||
// Ajouter un padding autour du texte
|
||||
float padding = 5.0f;
|
||||
ImVec2 rect_min = ImVec2(pos.x - padding, pos.y - padding);
|
||||
ImVec2 rect_max = ImVec2(pos.x + text_size.x + padding, pos.y + text_size.y + padding);
|
||||
|
||||
// Définir la couleur du rectangle (bleu avec transparence)
|
||||
ImU32 bg_color = ImGui::GetColorU32(ImVec4(0.3f, 0.3f, 0.7f, 1.0f));
|
||||
|
||||
// Dessiner le rectangle de fond
|
||||
ImGui::GetWindowDrawList()->AddRectFilled(rect_min, rect_max, bg_color);
|
||||
|
||||
// Afficher le texte
|
||||
ImGui::TextUnformatted(text);
|
||||
}
|
||||
|
||||
void BaseNodeWidget::FrameEnd()
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ MainWindow::~MainWindow()
|
|||
}
|
||||
|
||||
|
||||
std::string MainWindow::GetFileNameFromMemory(uint32_t addr)
|
||||
std::string MainWindow::GetStringFromMemory(uint32_t addr)
|
||||
{
|
||||
char strBuf[100];
|
||||
bool isRam = addr & 0x80000000;
|
||||
|
|
@ -77,6 +77,7 @@ std::string MainWindow::GetFileNameFromMemory(uint32_t addr)
|
|||
return strBuf;
|
||||
}
|
||||
|
||||
|
||||
void MainWindow::Play()
|
||||
{
|
||||
|
||||
|
|
@ -268,7 +269,36 @@ void MainWindow::ProcessStory()
|
|||
}
|
||||
else if (m_dbg.run_result > VM_OK)
|
||||
{
|
||||
Log("VM critical error", true);
|
||||
std::string error = "VM Error: ";
|
||||
switch (m_dbg.run_result)
|
||||
{
|
||||
case VM_ERR_STACK_OVERFLOW:
|
||||
error += "Stack overflow";
|
||||
break;
|
||||
case VM_ERR_STACK_UNDERFLOW:
|
||||
error += "Stack underflow";
|
||||
break;
|
||||
case VM_ERR_INVALID_ADDRESS:
|
||||
error += "Invalid address";
|
||||
break;
|
||||
case VM_ERR_UNSUPPORTED_OPCODE:
|
||||
error += "Invalid address";
|
||||
break;
|
||||
case VM_ERR_UNKNOWN_OPCODE:
|
||||
error += "Unknown opcode";
|
||||
break;
|
||||
case VM_ERR_UNHANDLED_INTERRUPT:
|
||||
error += "Unhandled interrupt";
|
||||
break;
|
||||
case VM_ERR_INVALID_REGISTER:
|
||||
error += "Invalid register";
|
||||
break;
|
||||
default:
|
||||
error += "Unknown error";
|
||||
break;
|
||||
}
|
||||
error += " (line: " + std::to_string(m_dbg.line) + ")";
|
||||
Log(error, true);
|
||||
}
|
||||
|
||||
// In this case, we wait for single step debugger
|
||||
|
|
@ -289,7 +319,7 @@ uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code)
|
|||
if (m_chip32_ctx.registers[R0] != 0)
|
||||
{
|
||||
// image file name address is in R0
|
||||
std::string imageFile = m_story->BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R0]));
|
||||
std::string imageFile = m_story->BuildFullAssetsPath(GetStringFromMemory(m_chip32_ctx.registers[R0]));
|
||||
Log("Image: " + imageFile);
|
||||
m_emulatorWindow.SetImage(imageFile);
|
||||
}
|
||||
|
|
@ -301,7 +331,7 @@ uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code)
|
|||
if (m_chip32_ctx.registers[R1] != 0)
|
||||
{
|
||||
// sound file name address is in R1
|
||||
std::string soundFile = m_story->BuildFullAssetsPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1]));
|
||||
std::string soundFile = m_story->BuildFullAssetsPath(GetStringFromMemory(m_chip32_ctx.registers[R1]));
|
||||
Log("Sound: " + soundFile);
|
||||
m_player.Play(soundFile);
|
||||
}
|
||||
|
|
@ -325,7 +355,52 @@ uint8_t MainWindow::Syscall(chip32_ctx_t *ctx, uint8_t code)
|
|||
// if timeout is set to zero, wait for infinite and beyond
|
||||
retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause
|
||||
}
|
||||
else if (code == 3)
|
||||
{
|
||||
// FIXME
|
||||
}
|
||||
else // Printf
|
||||
if (code == 4)
|
||||
{
|
||||
// In R0: string with escaped characters
|
||||
// R1: Number of arguments
|
||||
// R2, R3 ... arguments
|
||||
|
||||
// Integers: stored in registers by values
|
||||
// Strings: first character address in register
|
||||
|
||||
std::string text = GetStringFromMemory(ctx->registers[R0]);
|
||||
|
||||
int arg_count = ctx->registers[R1];
|
||||
char working_buf[200] = {0};
|
||||
|
||||
switch(arg_count){
|
||||
case 0:
|
||||
Log(text);
|
||||
break;
|
||||
case 1:
|
||||
snprintf(working_buf, sizeof(working_buf), text.c_str(), ctx->registers[R2]);
|
||||
Log(working_buf);
|
||||
break;
|
||||
case 2:
|
||||
snprintf(working_buf, sizeof(working_buf), text.c_str(), ctx->registers[R2], ctx->registers[R3]);
|
||||
Log(working_buf);
|
||||
break;
|
||||
case 3:
|
||||
snprintf(working_buf, sizeof(working_buf), text.c_str(), ctx->registers[R2], ctx->registers[R3], ctx->registers[R4]);
|
||||
Log(working_buf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
// WAIT (sleep)
|
||||
else if (code == 5)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(ctx->registers[R0]));
|
||||
}
|
||||
|
||||
|
||||
return retCode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ private:
|
|||
|
||||
void UpdateVmView();
|
||||
uint8_t Syscall(chip32_ctx_t *ctx, uint8_t code);
|
||||
std::string GetFileNameFromMemory(uint32_t addr);
|
||||
std::string GetStringFromMemory(uint32_t addr);
|
||||
void ProcessStory();
|
||||
void StepInstruction();
|
||||
void RefreshProjectInformation();
|
||||
|
|
|
|||
Loading…
Reference in a new issue