media loop ok, add jumpr assembly, remove old arts
BIN
art/hat-only-mini.png
Normal file
|
After Width: | Height: | Size: 7.6 KiB |
BIN
art/hat-only.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
52
art/hat-only.svg
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
art/header.xcf
|
Before Width: | Height: | Size: 197 KiB |
BIN
art/logo-color2.png
Normal file
|
After Width: | Height: | Size: 116 KiB |
78
art/logo-color2.svg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
art/logo.png
Normal file
|
After Width: | Height: | Size: 114 KiB |
88
art/logo.svg
Normal file
|
After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 18 KiB |
BIN
art/osb-logo.kra
BIN
art/osb-logo.png
|
Before Width: | Height: | Size: 1.6 KiB |
|
|
@ -55,7 +55,7 @@ static const uint32_t NbRegs = sizeof(AllRegs) / sizeof(AllRegs[0]);
|
||||||
// Keep same order than the opcodes list!!
|
// Keep same order than the opcodes list!!
|
||||||
static const std::string Mnemonics[] = {
|
static const std::string Mnemonics[] = {
|
||||||
"nop", "halt", "syscall", "lcons", "mov", "push", "pop", "store", "load", "add", "sub", "mul", "div",
|
"nop", "halt", "syscall", "lcons", "mov", "push", "pop", "store", "load", "add", "sub", "mul", "div",
|
||||||
"shiftl", "shiftr", "ishiftr", "and", "or", "xor", "not", "call", "ret", "jump", "skipz", "skipnz"
|
"shiftl", "shiftr", "ishiftr", "and", "or", "xor", "not", "call", "ret", "jump", "jumpr", "skipz", "skipnz"
|
||||||
};
|
};
|
||||||
|
|
||||||
static OpCode OpCodes[] = OPCODES_LIST;
|
static OpCode OpCodes[] = OPCODES_LIST;
|
||||||
|
|
@ -196,6 +196,7 @@ bool Assembler::CompileMnemonicArguments(Instr &instr)
|
||||||
case OP_SKIPZ:
|
case OP_SKIPZ:
|
||||||
case OP_SKIPNZ:
|
case OP_SKIPNZ:
|
||||||
case OP_CALL:
|
case OP_CALL:
|
||||||
|
case OP_JUMPR:
|
||||||
GET_REG(instr.args[0], ra);
|
GET_REG(instr.args[0], ra);
|
||||||
instr.compiledArgs.push_back(ra);
|
instr.compiledArgs.push_back(ra);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -354,6 +354,13 @@ chip32_result_t chip32_step(chip32_ctx_t *ctx)
|
||||||
ctx->registers[PC] = _NEXT_SHORT - 1;
|
ctx->registers[PC] = _NEXT_SHORT - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case OP_JUMPR:
|
||||||
|
{
|
||||||
|
const uint8_t reg = _NEXT_BYTE;
|
||||||
|
_CHECK_REGISTER_VALID(reg)
|
||||||
|
ctx->registers[PC] = ctx->registers[reg] - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OP_SKIPZ:
|
case OP_SKIPZ:
|
||||||
case OP_SKIPNZ:
|
case OP_SKIPNZ:
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -76,8 +76,9 @@ typedef enum
|
||||||
OP_CALL = 20, ///< set register RA to the next instruction and jump to subroutine, e.g.: call 0x10 0x00
|
OP_CALL = 20, ///< set register RA to the next instruction and jump to subroutine, e.g.: call 0x10 0x00
|
||||||
OP_RET = 21, ///< return to the address of last callee (RA), e.g.: ret
|
OP_RET = 21, ///< return to the address of last callee (RA), e.g.: ret
|
||||||
OP_JUMP = 22, ///< jump to address (can use label or address), e.g.: jump .my_label
|
OP_JUMP = 22, ///< jump to address (can use label or address), e.g.: jump .my_label
|
||||||
OP_SKIPZ = 23, ///< skip next instruction if zero, e.g.: skipz r0
|
OP_JUMPR = 23, ///< jump to address contained in a register, e.g.: jumpr t9
|
||||||
OP_SKIPNZ = 24, ///< skip next instruction if not zero, e.g.: skipnz r2
|
OP_SKIPZ = 24, ///< skip next instruction if zero, e.g.: skipz r0
|
||||||
|
OP_SKIPNZ = 25, ///< skip next instruction if not zero, e.g.: skipnz r2
|
||||||
|
|
||||||
INSTRUCTION_COUNT
|
INSTRUCTION_COUNT
|
||||||
} chip32_instruction_t;
|
} chip32_instruction_t;
|
||||||
|
|
@ -153,7 +154,7 @@ typedef struct {
|
||||||
{ OP_STORE, 3, 4 }, { OP_LOAD, 3, 4 }, { OP_ADD, 2, 2 }, { OP_SUB, 2, 2 }, { OP_MUL, 2, 2 }, \
|
{ OP_STORE, 3, 4 }, { OP_LOAD, 3, 4 }, { OP_ADD, 2, 2 }, { OP_SUB, 2, 2 }, { OP_MUL, 2, 2 }, \
|
||||||
{ OP_DIV, 2, 2 }, { OP_SHL, 2, 2 }, { OP_SHR, 2, 2 }, { OP_ISHR, 2, 2 }, { OP_AND, 2, 2 }, \
|
{ OP_DIV, 2, 2 }, { OP_SHL, 2, 2 }, { OP_SHR, 2, 2 }, { OP_ISHR, 2, 2 }, { OP_AND, 2, 2 }, \
|
||||||
{ OP_OR, 2, 2 }, { OP_XOR, 2, 2 }, { OP_NOT, 1, 1 }, { OP_CALL, 1, 1 }, { OP_RET, 0, 0 }, \
|
{ OP_OR, 2, 2 }, { OP_XOR, 2, 2 }, { OP_NOT, 1, 1 }, { OP_CALL, 1, 1 }, { OP_RET, 0, 0 }, \
|
||||||
{ OP_JUMP, 1, 2 }, { OP_SKIPZ, 1, 1 }, { OP_SKIPNZ, 1, 1 } }
|
{ OP_JUMP, 1, 2 }, { OP_JUMPR, 1, 1 }, { OP_SKIPZ, 1, 1 }, { OP_SKIPNZ, 1, 1 } }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Whole memory is 64KB
|
Whole memory is 64KB
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
; t1: increment 1
|
; t1: increment 1
|
||||||
; t2: increment 4
|
; t2: increment 4
|
||||||
; t3: current media address
|
; t3: current media address
|
||||||
|
; t4: where to jump when OK button is pressed
|
||||||
|
|
||||||
.media_loop_start:
|
.media_loop_start:
|
||||||
load t0, @r0, 4 ; Le premier élément est le nombre de choix possibles, t0 = 3 (exemple)
|
load t0, @r0, 4 ; Le premier élément est le nombre de choix possibles, t0 = 3 (exemple)
|
||||||
|
|
@ -18,12 +19,27 @@
|
||||||
add t3, t2 ; @++
|
add t3, t2 ; @++
|
||||||
|
|
||||||
|
|
||||||
; ------- On appelle un autre media node
|
; --------- We call a media transition node
|
||||||
push r0 ; save r0
|
push r0 ; save r0
|
||||||
load r0, @t3, 4 ; r0 = content in ram at address in T4
|
load r0, @t3, 4 ; r0 = content in ram at address in T4
|
||||||
call r0
|
call r0 ; call subroutine
|
||||||
|
|
||||||
|
; Return argument in R0: the address of the node to call whe OK is pressed
|
||||||
|
; save it in t4
|
||||||
|
mov t4, r0
|
||||||
pop r0
|
pop r0
|
||||||
; TODO: wait for event
|
|
||||||
|
; wait for event (OK or wheel)
|
||||||
|
syscall 2
|
||||||
|
; Event is stored in R0
|
||||||
|
|
||||||
|
; ----- Test if event is OK button
|
||||||
|
lcons r1, 1 ; mask for OK button
|
||||||
|
and r1, r0 ; r1 = r1 AND r0
|
||||||
|
skipz r1 ; not OK, skip jump
|
||||||
|
jumpr t4 ; we do not plan to return here, so a jump is enough
|
||||||
|
|
||||||
|
; all other events mean: next node
|
||||||
|
|
||||||
sub t0, t1 ; i--
|
sub t0, t1 ; i--
|
||||||
skipnz t0 ; if (r0) goto start_loop;
|
skipnz t0 ; if (r0) goto start_loop;
|
||||||
|
|
|
||||||
|
|
@ -243,6 +243,7 @@ MainWindow::MainWindow()
|
||||||
|
|
||||||
if ((m_dbg.run_result == VM_WAIT_EVENT) && (m_dbg.running))
|
if ((m_dbg.run_result == VM_WAIT_EVENT) && (m_dbg.running))
|
||||||
{
|
{
|
||||||
|
m_dbg.run_result = VM_OK;
|
||||||
// Continue execution of node
|
// Continue execution of node
|
||||||
m_runTimer->start(100);
|
m_runTimer->start(100);
|
||||||
}
|
}
|
||||||
|
|
@ -478,7 +479,8 @@ bool MainWindow::event(QEvent *event)
|
||||||
{
|
{
|
||||||
// Result event is in R1
|
// Result event is in R1
|
||||||
m_chip32_ctx.registers[R1] = 0x01;
|
m_chip32_ctx.registers[R1] = 0x01;
|
||||||
stepInstruction();
|
m_dbg.run_result = VM_OK;
|
||||||
|
m_runTimer->start(100);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -494,16 +496,27 @@ uint8_t MainWindow::Syscall(uint8_t code)
|
||||||
qDebug() << "SYSCALL: " << (int)code;
|
qDebug() << "SYSCALL: " << (int)code;
|
||||||
|
|
||||||
// Media
|
// Media
|
||||||
if (code == 1)
|
if (code == 1) // Execute media
|
||||||
|
{
|
||||||
|
if (m_chip32_ctx.registers[R0] != 0)
|
||||||
{
|
{
|
||||||
// image file name address is in R0
|
// image file name address is in R0
|
||||||
QString imageFile = m_model.BuildFullImagePath(GetFileNameFromMemory(m_chip32_ctx.registers[R0]));
|
QString imageFile = m_model.BuildFullImagePath(GetFileNameFromMemory(m_chip32_ctx.registers[R0]));
|
||||||
|
qDebug() << "Image: " << imageFile;
|
||||||
|
m_ostHmiDock->SetImage(imageFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_ostHmiDock->ClearImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_chip32_ctx.registers[R1] != 0)
|
||||||
|
{
|
||||||
// sound file name address is in R1
|
// sound file name address is in R1
|
||||||
QString soundFile = m_model.BuildFullSoundPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1]));
|
QString soundFile = m_model.BuildFullSoundPath(GetFileNameFromMemory(m_chip32_ctx.registers[R1]));
|
||||||
|
qDebug() << ", Sound: " << soundFile;
|
||||||
qDebug() << "Image: " << imageFile << ", Sound: " << soundFile;
|
|
||||||
m_ostHmiDock->SetImage(imageFile);
|
|
||||||
m_model.PlaySound(soundFile);
|
m_model.PlaySound(soundFile);
|
||||||
|
}
|
||||||
retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause
|
retCode = SYSCALL_RET_WAIT_EV; // set the VM in pause
|
||||||
}
|
}
|
||||||
// WAIT EVENT bits:
|
// WAIT EVENT bits:
|
||||||
|
|
@ -513,7 +526,7 @@ uint8_t MainWindow::Syscall(uint8_t code)
|
||||||
// 3: pause button
|
// 3: pause button
|
||||||
// 4: rotary left
|
// 4: rotary left
|
||||||
// 5: rotary right
|
// 5: rotary right
|
||||||
else if (code == 2)
|
else if (code == 2) // Wait for event
|
||||||
{
|
{
|
||||||
// Event mask is located in R0
|
// Event mask is located in R0
|
||||||
// optional timeout is located in R1
|
// optional timeout is located in R1
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,22 @@ MediaNodeModel::MediaNodeModel(StoryGraphModel &model)
|
||||||
};
|
};
|
||||||
|
|
||||||
m_mediaData.merge_patch(StoryNodeBase::ToJson());
|
m_mediaData.merge_patch(StoryNodeBase::ToJson());
|
||||||
|
|
||||||
|
QtNodes::NodeStyle _nodeStyle;
|
||||||
|
|
||||||
|
QColor bgColor = QColor(94, 94, 94);
|
||||||
|
_nodeStyle.GradientColor0 = bgColor;
|
||||||
|
_nodeStyle.GradientColor1 = bgColor;
|
||||||
|
_nodeStyle.GradientColor2 = bgColor;
|
||||||
|
_nodeStyle.GradientColor3 = bgColor;
|
||||||
|
_nodeStyle.NormalBoundaryColor = bgColor;
|
||||||
|
_nodeStyle.FontColor = QColor(206, 206, 206);
|
||||||
|
_nodeStyle.FontColorFaded = QColor(125, 125, 125);
|
||||||
|
_nodeStyle.ShadowColor = QColor(20, 20, 20);
|
||||||
|
_nodeStyle.ConnectionPointColor = QColor(125, 125, 125);
|
||||||
|
_nodeStyle.FilledConnectionPointColor = QColor(206, 206, 206);
|
||||||
|
|
||||||
|
setNodeStyle(_nodeStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString MediaNodeModel::caption() const
|
QString MediaNodeModel::caption() const
|
||||||
|
|
@ -131,29 +147,65 @@ std::string MediaNodeModel::GenerateConstants()
|
||||||
s += StoryProject::FileToConstant(sound);
|
s += StoryProject::FileToConstant(sound);
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Generate choice table if needed (out ports > 1)
|
int nb_out_conns = ComputeOutputConnections();
|
||||||
|
if (nb_out_conns > 1)
|
||||||
|
{
|
||||||
|
// Generate choice table if needed (out ports > 1)
|
||||||
|
std::stringstream ss;
|
||||||
|
std::string label = ChoiceLabel();
|
||||||
|
ss << "$" << label
|
||||||
|
<< " DC32, "
|
||||||
|
<< nb_out_conns << ", ";
|
||||||
|
|
||||||
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
||||||
|
int i = 0;
|
||||||
int nb_out_ports = 0;
|
|
||||||
|
|
||||||
for (auto & c : conns)
|
for (auto & c : conns)
|
||||||
{
|
{
|
||||||
if (c.outNodeId > 0)
|
std::stringstream ssChoice;
|
||||||
|
|
||||||
|
// On va chercher le label d'entrée du noeud connecté à l'autre bout
|
||||||
|
ss << m_model.GetNodeEntryLabel(c.inNodeId);
|
||||||
|
if (i < (nb_out_conns - 1))
|
||||||
{
|
{
|
||||||
nb_out_ports++;
|
ss << ", ";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ss << "\n";
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
s += ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MediaNodeModel::ChoiceLabel() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "mediaChoice" << std::setw(4) << std::setfill('0') << getNodeId();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
std::string MediaNodeModel::Build()
|
std::string MediaNodeModel::Build()
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
|
int nb_out_conns = ComputeOutputConnections();
|
||||||
|
|
||||||
ss << R"(; ---------------- )" << GetNodeTitle() << "\n";
|
ss << R"(; ---------------------------- )"
|
||||||
|
<< GetNodeTitle()
|
||||||
|
<< " Type: "
|
||||||
|
<< (nb_out_conns == 0 ? "End" : nb_out_conns == 1 ? "Transition" : "Choice")
|
||||||
|
<< "\n";
|
||||||
std::string image = StoryProject::RemoveFileExtension(m_mediaData["image"].get<std::string>());
|
std::string image = StoryProject::RemoveFileExtension(m_mediaData["image"].get<std::string>());
|
||||||
std::string sound = StoryProject::RemoveFileExtension(m_mediaData["sound"].get<std::string>());
|
std::string sound = StoryProject::RemoveFileExtension(m_mediaData["sound"].get<std::string>());
|
||||||
|
|
||||||
|
// 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
|
||||||
|
ss << EntryLabel() << ":\n";
|
||||||
|
|
||||||
if (image.size() > 0)
|
if (image.size() > 0)
|
||||||
{
|
{
|
||||||
ss << "lcons r0, $" << image << "\n";
|
ss << "lcons r0, $" << image << "\n";
|
||||||
|
|
@ -174,53 +226,54 @@ std::string MediaNodeModel::Build()
|
||||||
// Call the media executor (image, sound)
|
// Call the media executor (image, sound)
|
||||||
ss << "syscall 1\n";
|
ss << "syscall 1\n";
|
||||||
|
|
||||||
NodeId id = getNodeId();
|
// Check output connections number
|
||||||
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(id);
|
// == 0: end node : generate halt
|
||||||
|
// == 1: transition node : image + sound on demand, jump directly to the other node when OK
|
||||||
|
// > 1 : choice node : call the node choice manager
|
||||||
|
|
||||||
int nb_out_ports = 0;
|
if (nb_out_conns == 0) // End node
|
||||||
|
|
||||||
for (auto & c : conns)
|
|
||||||
{
|
|
||||||
if (c.inNodeId == id)
|
|
||||||
{
|
|
||||||
nb_out_ports++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nb_out_ports == 0)
|
|
||||||
{
|
{
|
||||||
ss << "halt\n";
|
ss << "halt\n";
|
||||||
}
|
}
|
||||||
else
|
else if (nb_out_conns == 1) // Transition node
|
||||||
{
|
{
|
||||||
|
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(getNodeId());
|
||||||
|
|
||||||
|
auto it = conns.begin();
|
||||||
|
++it;
|
||||||
|
// On place dans R0 le prochain noeud à exécuter en cas de OK
|
||||||
|
ss << "lcons r0, "
|
||||||
|
<< m_model.GetNodeEntryLabel(it->inNodeId) << "\n"
|
||||||
|
<< "ret\n";
|
||||||
|
}
|
||||||
|
else // Choice node
|
||||||
|
{
|
||||||
|
ss << "lcons r0, $" << ChoiceLabel() << "\n"
|
||||||
|
<< "jump .media ; no return possible, so a jump is enough";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check output connections number
|
|
||||||
// == 0: end, generate halt
|
|
||||||
// == 1: jump directly to the other node
|
|
||||||
// > 1 : call the node choice manager
|
|
||||||
|
|
||||||
// lcons r0, $ChoiceObject
|
|
||||||
// jump .media ; no return possible, so a jump is enough
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
syscall 1
|
|
||||||
lcons r0, $ChoiceObject
|
|
||||||
jump .media ; no return possible, so a jump is enough
|
|
||||||
*/
|
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MediaNodeModel::SetOutPortCount(int count) {
|
int MediaNodeModel::ComputeOutputConnections()
|
||||||
|
{
|
||||||
|
NodeId id = getNodeId();
|
||||||
|
std::unordered_set<ConnectionId> conns = m_model.allConnectionIds(id);
|
||||||
|
|
||||||
// m_ui.spinBox->blockSignals(true);
|
int nb_out_conns = 0;
|
||||||
|
|
||||||
|
for (auto & c : conns)
|
||||||
|
{
|
||||||
|
if (c.outNodeId == id)
|
||||||
|
{
|
||||||
|
nb_out_conns++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nb_out_conns;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaNodeModel::SetOutPortCount(int count)
|
||||||
|
{
|
||||||
m_ui.spinBox->setValue(count);
|
m_ui.spinBox->setValue(count);
|
||||||
// m_ui.spinBox->blockSignals(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int MediaNodeModel::nPorts(PortType portType) const
|
unsigned int MediaNodeModel::nPorts(PortType portType) const
|
||||||
|
|
@ -286,3 +339,10 @@ void MediaNodeModel::setInData(std::shared_ptr<NodeData> nodeData, PortIndex con
|
||||||
|
|
||||||
Q_EMIT dataUpdated(0);
|
Q_EMIT dataUpdated(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MediaNodeModel::EntryLabel() const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << ".mediaEntry" << std::setw(4) << std::setfill('0') << getNodeId();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ public:
|
||||||
|
|
||||||
bool resizable() const override { return true; }
|
bool resizable() const override { return true; }
|
||||||
|
|
||||||
|
virtual std::string EntryLabel() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
|
@ -80,4 +81,6 @@ private:
|
||||||
|
|
||||||
nlohmann::json m_mediaData;
|
nlohmann::json m_mediaData;
|
||||||
void setImage(const QString &fileName);
|
void setImage(const QString &fileName);
|
||||||
|
int ComputeOutputConnections();
|
||||||
|
std::string ChoiceLabel() const;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,3 +15,8 @@ void OstHmiDock::SetImage(const QString &fileName)
|
||||||
{
|
{
|
||||||
m_uiOstDisplay.display->setPixmap(QPixmap(fileName));
|
m_uiOstDisplay.display->setPixmap(QPixmap(fileName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OstHmiDock::ClearImage()
|
||||||
|
{
|
||||||
|
m_uiOstDisplay.display->clear();
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ public:
|
||||||
OstHmiDock();
|
OstHmiDock();
|
||||||
|
|
||||||
void SetImage(const QString &fileName);
|
void SetImage(const QString &fileName);
|
||||||
|
void ClearImage();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sigOkButton();
|
void sigOkButton();
|
||||||
|
|
|
||||||
|
|
@ -523,7 +523,7 @@ std::string StoryGraphModel::Build()
|
||||||
|
|
||||||
NodeId firstNode = FindFirstNode();
|
NodeId firstNode = FindFirstNode();
|
||||||
|
|
||||||
chip32 << "\tjump .entry\r\n";
|
chip32 << "\tjump " << GetNodeEntryLabel(firstNode) << "\r\n";
|
||||||
|
|
||||||
// First generate all constants
|
// First generate all constants
|
||||||
for (auto const nodeId : allNodeIds())
|
for (auto const nodeId : allNodeIds())
|
||||||
|
|
@ -535,27 +535,30 @@ std::string StoryGraphModel::Build()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
nlohmann::json nodesJsonArray;
|
nlohmann::json nodesJsonArray;
|
||||||
for (auto const nodeId : allNodeIds())
|
for (auto const nodeId : allNodeIds())
|
||||||
{
|
{
|
||||||
auto it = _models.find(nodeId);
|
auto it = _models.find(nodeId);
|
||||||
if (it == _models.end())
|
if (it != _models.end())
|
||||||
return "";
|
|
||||||
|
|
||||||
auto &model = it->second;
|
|
||||||
if (model->getNodeId() == firstNode)
|
|
||||||
{
|
{
|
||||||
chip32 << ".entry:\r\n";
|
chip32 << it->second->Build() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
chip32 << model->Build() << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return chip32.str();
|
return chip32.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string StoryGraphModel::GetNodeEntryLabel(NodeId nodeId) const
|
||||||
|
{
|
||||||
|
std::string label;
|
||||||
|
auto it = _models.find(nodeId);
|
||||||
|
if (it != _models.end())
|
||||||
|
{
|
||||||
|
label = it->second->EntryLabel();
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
void StoryGraphModel::addPort(NodeId nodeId, PortType portType, PortIndex portIndex)
|
void StoryGraphModel::addPort(NodeId nodeId, PortType portType, PortIndex portIndex)
|
||||||
{
|
{
|
||||||
// STAGE 1.
|
// STAGE 1.
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,8 @@ public:
|
||||||
|
|
||||||
std::string Build();
|
std::string Build();
|
||||||
|
|
||||||
|
///< Returns a node entry name
|
||||||
|
std::string GetNodeEntryLabel(NodeId nodeId) const;
|
||||||
|
|
||||||
// Centralized for wide usage
|
// Centralized for wide usage
|
||||||
void PlaySound(const QString &fileName);
|
void PlaySound(const QString &fileName);
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,8 @@ public:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string EntryLabel() const = 0;
|
||||||
|
|
||||||
NodeGeometryData &geometryData() { return m_geometryData; }
|
NodeGeometryData &geometryData() { return m_geometryData; }
|
||||||
|
|
||||||
std::string GetNodeTitle() const { return m_nodeTitle; }
|
std::string GetNodeTitle() const { return m_nodeTitle; }
|
||||||
|
|
|
||||||