mirror of
https://github.com/arabine/open-story-teller.git
synced 2025-12-07 01:15:14 +01:00
201 lines
5.5 KiB
C++
201 lines
5.5 KiB
C++
// SPDX-License-Identifier: MIT
|
|
// SPDX-FileCopyrightText: 2023-2099 Anthony Rabine <anthony@rabine.fr>
|
|
|
|
#ifndef MAIN_WINDOW_H
|
|
#define MAIN_WINDOW_H
|
|
|
|
#include <QAction>
|
|
#include <QScreen>
|
|
#include <QtWidgets/QApplication>
|
|
#include <QBoxLayout>
|
|
#include <QGridLayout>
|
|
#include <QGroupBox>
|
|
#include <QLabel>
|
|
#include <QMainWindow>
|
|
#include <QDockWidget>
|
|
#include <QTimer>
|
|
|
|
#include <QtNodes/ConnectionStyle>
|
|
#include <QtNodes/GraphicsView>
|
|
#include <QtNodes/BasicGraphicsScene>
|
|
#include <QtNodes/StyleCollection>
|
|
#include <QtNodes/DataFlowGraphModel>
|
|
#include <QtNodes/DataFlowGraphicsScene>
|
|
#include <QtNodes/NodeData>
|
|
#include <QtNodes/NodeDelegateModelRegistry>
|
|
|
|
|
|
using QtNodes::DataFlowGraphicsScene;
|
|
using QtNodes::ConnectionStyle;
|
|
using QtNodes::BasicGraphicsScene;
|
|
using QtNodes::GraphicsView;
|
|
using QtNodes::NodeRole;
|
|
using QtNodes::StyleCollection;
|
|
using QtNodes::DataFlowGraphModel;
|
|
using QtNodes::NodeDelegateModelRegistry;
|
|
|
|
#include "ui_choose-file.h"
|
|
#include "story_project.h"
|
|
#include "story_graph_model.h"
|
|
#include "story_graph_scene.h"
|
|
#include "chip32_assembler.h"
|
|
#include "chip32_vm.h"
|
|
#include "vm_dock.h"
|
|
#include "resources_dock.h"
|
|
#include "script_editor_dock.h"
|
|
#include "memory_view_dock.h"
|
|
#include "osthmi_dock.h"
|
|
#include "log_dock.h"
|
|
#include "toolbar.h"
|
|
#include "new_project_dialog.h"
|
|
#include "resource_model.h"
|
|
|
|
struct DebugContext
|
|
{
|
|
uint32_t event_mask{0};
|
|
bool wait_event{0};
|
|
bool free_run{false};
|
|
int line{-1};
|
|
chip32_result_t run_result{VM_FINISHED};
|
|
|
|
std::set<int> m_breakpoints;
|
|
|
|
static void DumpCodeAssembler(Chip32::Assembler & assembler) {
|
|
|
|
for (std::vector<Chip32::Instr>::const_iterator iter = assembler.Begin();
|
|
iter != assembler.End(); ++iter)
|
|
{
|
|
if (iter->isRomCode() || iter->isRomData)
|
|
{
|
|
qDebug() << "-------------------";
|
|
qDebug() << "Instr: " << iter->mnemonic.c_str();
|
|
qDebug() << "Addr: " << Qt::hex << iter->addr;
|
|
qDebug() << "Line: " << iter->line;
|
|
qDebug() << "\t- Opcode: " << Qt::hex << iter->code.opcode
|
|
<< ", opcode args: " << iter->code.bytes;
|
|
|
|
int i = 1;
|
|
for (auto arg : iter->compiledArgs)
|
|
{
|
|
qDebug() << "\t- Arg " << i << " : " << Qt::hex << arg;
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
};
|
|
|
|
#include <functional>
|
|
|
|
template <typename T>
|
|
struct Callback;
|
|
|
|
template <typename Ret, typename... Params>
|
|
struct Callback<Ret(Params...)> {
|
|
template <typename... Args>
|
|
static Ret callback(Args... args) {
|
|
return func(args...);
|
|
}
|
|
static std::function<Ret(Params...)> func;
|
|
};
|
|
|
|
template <typename Ret, typename... Params>
|
|
std::function<Ret(Params...)> Callback<Ret(Params...)>::func;
|
|
|
|
|
|
class VmEvent : public QEvent {
|
|
public:
|
|
VmEvent(QEvent::Type type)
|
|
: QEvent(type)
|
|
{}
|
|
static const QEvent::Type evStep = static_cast<QEvent::Type>(QEvent::User + 1);
|
|
static const QEvent::Type evOkButton = static_cast<QEvent::Type>(QEvent::User + 2);
|
|
static const QEvent::Type evLeftButton = static_cast<QEvent::Type>(QEvent::User + 3);
|
|
static const QEvent::Type evRightButton = static_cast<QEvent::Type>(QEvent::User + 4);
|
|
static const QEvent::Type evAudioFinished = static_cast<QEvent::Type>(QEvent::User + 5);
|
|
|
|
uint8_t ev{0};
|
|
};
|
|
|
|
class MainWindow : public QMainWindow
|
|
{
|
|
Q_OBJECT
|
|
|
|
public:
|
|
MainWindow();
|
|
|
|
protected:
|
|
void BuildAndRun();
|
|
|
|
private slots:
|
|
void stepInstruction();
|
|
void closeEvent(QCloseEvent *event);
|
|
void slotDefaultDocksPosition();
|
|
void slotWelcome();
|
|
|
|
private:
|
|
StoryProject m_project;
|
|
ResourceModel m_resourceModel;
|
|
StoryGraphModel m_model;
|
|
StoryGraphScene m_scene;
|
|
GraphicsView *m_view{nullptr};
|
|
|
|
// Qt stuff
|
|
QTimer *m_runTimer{nullptr};
|
|
ToolBar *m_toolbar{nullptr};
|
|
OstHmiDock *m_ostHmiDock{nullptr};
|
|
ResourcesDock *m_resourcesDock{nullptr};
|
|
ScriptEditorDock *m_scriptEditorDock{nullptr};
|
|
VmDock *m_vmDock{nullptr};
|
|
MemoryViewDock *m_ramView{nullptr};
|
|
MemoryViewDock *m_romView{nullptr};
|
|
LogDock *m_logDock{nullptr};
|
|
QSettings m_settings;
|
|
QDialog *m_chooseFileDialog;
|
|
Ui::chooseFileDIalog m_chooseFileUi;
|
|
NewProjectDialog *m_newProjectDialog{nullptr};
|
|
QStringList m_recentProjects;
|
|
|
|
// VM
|
|
uint8_t m_rom_data[16*1024];
|
|
uint8_t m_ram_data[16*1024];
|
|
chip32_ctx_t m_chip32_ctx;
|
|
|
|
// Assembleur & Debugger
|
|
std::vector<uint8_t> m_program;
|
|
Chip32::Assembler m_assembler;
|
|
Chip32::Result m_result;
|
|
DebugContext m_dbg;
|
|
|
|
// Private functions
|
|
void createActions();
|
|
void createStatusBar();
|
|
void SaveProject();
|
|
void DisplayNode(StoryNode *m_tree, QtNodes::NodeId parentId);
|
|
void GenerateBinary();
|
|
void highlightNextLine();
|
|
void readSettings();
|
|
void updateAll();
|
|
uint8_t Syscall(chip32_ctx_t *ctx, uint8_t code);
|
|
QString GetFileNameFromMemory(uint32_t addr);
|
|
|
|
bool event(QEvent *event);
|
|
void MessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
|
|
void NewProject();
|
|
|
|
void RefreshProjectInformation();
|
|
void CloseProject();
|
|
void OpenProjectDialog();
|
|
void ExitProgram();
|
|
void EnableProject();
|
|
void OpenProject(const QString &filePath);
|
|
QString ReadResourceFile(const QString &fileName);
|
|
void EventFinished(uint32_t replyEvent);
|
|
bool CompileToAssembler();
|
|
void ConvertResources();
|
|
void BuildAll();
|
|
};
|
|
|
|
#endif // MAIN_WINDOW_H
|