Skip to content

Commit

Permalink
add database, add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
drdaxxy committed Apr 8, 2018
1 parent 2bd43d1 commit 41ef912
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 28 deletions.
2 changes: 1 addition & 1 deletion sc3ntist.pro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
include(common.pri)

QT += core gui widgets
QT += core gui widgets sql

TARGET = sc3ntist
TEMPLATE = app
Expand Down
4 changes: 3 additions & 1 deletion src/SCXParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ int main() {
std::vector<std::pair<uint8_t *, std::streamsize>> files;

std::string path = "G:\\Games\\SGTL\\CCEnVitaPatch101\\script_dis";

int fileId = 0;
for (auto &p : std::experimental::filesystem::directory_iterator(path)) {
if (p.path().extension().string() != ".scx") continue;

Expand All @@ -105,7 +107,7 @@ int main() {
file.close();

std::string outPath = p.path().string() + ".txt";
SCXFile scx(buf, size, p.path().filename().string());
SCXFile scx(buf, size, p.path().filename().string(), fileId++);
CCDisassembler dis(scx);
dis.DisassembleFile();

Expand Down
128 changes: 116 additions & 12 deletions src/gui/disassemblymodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@
#include <sstream>
#include "textdump.h"
#include <algorithm>
#include "debuggerapplication.h"
#include "project.h"

DisassemblyModel::DisassemblyModel(const SCXFile *script, QObject *parent)
: QAbstractItemModel(parent), _script(script) {
reload();

connect(dApp->project(), &Project::commentChanged, this,
&DisassemblyModel::onCommentChanged);
}

void DisassemblyModel::reload() {
_labelRows.clear();

int labelCount = _script->disassembly().size();
_labelRows.reserve(labelCount);
for (int i = 0; i < labelCount; i++) {
Expand All @@ -27,6 +38,18 @@ DisassemblyModel::DisassemblyModel(const SCXFile *script, QObject *parent)
instRow.address = label->instructions()[j]->position();
instRow.parent = movedLabelRow;
movedLabelRow->children.push_back(std::move(instRow));
DisassemblyRow *movedInstRow = &movedLabelRow->children.data()[j];

QString comment =
dApp->project()->getComment(_script->getId(), movedInstRow->address);
if (!comment.isEmpty()) {
DisassemblyRow commentRow;
commentRow.type = RowType::Comment;
commentRow.id = 0;
commentRow.address = movedInstRow->address;
commentRow.parent = movedInstRow;
movedInstRow->children.push_back(std::move(commentRow));
}
}
}
}
Expand Down Expand Up @@ -58,11 +81,12 @@ const SC3CodeBlock *DisassemblyModel::labelForIndex(
if (!index.isValid()) return nullptr;
const DisassemblyRow *row =
static_cast<DisassemblyRow *>(index.internalPointer());
if (row == nullptr) return nullptr;
if (indexIsLabel(index)) {
return _script->disassembly()[row->id].get();
while (row != nullptr) {
if (row->type == RowType::Label)
return _script->disassembly()[row->id].get();
row = row->parent;
}
return _script->disassembly()[row->parent->id].get();
return nullptr;
}

QModelIndex DisassemblyModel::indexForLabel(SCXOffset labelId) const {
Expand All @@ -72,13 +96,24 @@ QModelIndex DisassemblyModel::indexForLabel(SCXOffset labelId) const {

// TODO use DisassemblyRows for this?
QModelIndex DisassemblyModel::firstIndexForAddress(SCXOffset address) const {
const auto &disasm = _script->disassembly();
int labelId = firstLabelForAddress(address);
if (labelId < 0) return QModelIndex();
if (_labelRows[labelId].address == address) return indexForLabel(labelId);
int instId = firstInstructionForAddress(labelId, address);
if (instId < 0) return indexForLabel(labelId);
return createIndex(instId, 0,
(void *)&_labelRows[labelId].children.data()[instId]);
}

int DisassemblyModel::firstLabelForAddress(SCXOffset address) const {
const auto &disasm = _script->disassembly();
const auto labelCount = disasm.size();
if (labelCount == 0) return QModelIndex();
if (labelCount == 0) return -1;
int labelId = 0;
for (int i = 0; i < labelCount; i++) {
if (disasm[i]->address() == address) {
return indexForLabel(i);
return i;
}
if (disasm[i]->address() < address) {
labelId = i;
Expand All @@ -87,14 +122,23 @@ QModelIndex DisassemblyModel::firstIndexForAddress(SCXOffset address) const {
break;
}
}
const auto &insts = disasm[labelId]->instructions();
return labelId;
}

int DisassemblyModel::firstInstructionForAddress(SCXOffset address) const {
return firstInstructionForAddress(firstLabelForAddress(address), address);
}

int DisassemblyModel::firstInstructionForAddress(int labelId,
SCXOffset address) const {
if (labelId < 0 || labelId > _script->disassembly().size()) return -1;
const auto &insts = _script->disassembly()[labelId]->instructions();
const auto instCount = insts.size();
if (instCount == 0) return indexForLabel(labelId);
if (instCount == 0) return -1;
int instId = 0;
for (int i = 0; i < instCount; i++) {
if (insts[i]->position() == address) {
instId = i;
break;
return i;
}
if (insts[i]->position() < address) {
instId = i;
Expand All @@ -103,8 +147,16 @@ QModelIndex DisassemblyModel::firstIndexForAddress(SCXOffset address) const {
break;
}
}
return createIndex(instId, 0,
(void *)&_labelRows[labelId].children.data()[instId]);
return instId;
}

SCXOffset DisassemblyModel::addressForIndex(const QModelIndex &index) const {
if (!index.isValid()) return -1;
const DisassemblyRow *row =
static_cast<DisassemblyRow *>(index.internalPointer());
if (row == nullptr) return -1;

return row->address;
}

QModelIndex DisassemblyModel::index(int row, int column,
Expand Down Expand Up @@ -159,6 +211,10 @@ QVariant DisassemblyModel::data(const QModelIndex &index, int role) const {
return QVariant(
QString::fromStdString(" " + DumpSC3InstructionToText(inst)));
}
case RowType::Comment: {
return QVariant(" ; " + dApp->project()->getComment(
_script->getId(), row->address));
}
default: { return QVariant(); }
}
}
Expand All @@ -174,4 +230,52 @@ Qt::ItemFlags DisassemblyModel::flags(const QModelIndex &index) const {
if (row == nullptr) return 0;
if (row->children.size() == 0) result |= Qt::ItemFlag::ItemNeverHasChildren;
return result;
}

void DisassemblyModel::onCommentChanged(int fileId, SCXOffset address,
const QString &comment) {
if (fileId != _script->getId()) return;

int labelId = firstLabelForAddress(address);
if (labelId < 0) return;
int instId = firstInstructionForAddress(labelId, address);
if (instId < 0) return;

DisassemblyRow *instructionRow = &_labelRows[labelId].children.data()[instId];

// TODO multiline

if (comment.isEmpty()) {
for (auto it = instructionRow->children.begin();
it != instructionRow->children.end(); it++) {
if (it->type == RowType::Comment) {
beginRemoveRows(createIndex(instId, 0, instructionRow),
it - instructionRow->children.begin(),
it - instructionRow->children.begin());
instructionRow->children.erase(it);
endRemoveRows();
return;
}
}
} else {
for (int i = 0; i < instructionRow->children.size(); i++) {
if (instructionRow->children[i].type == RowType::Comment) {
auto index =
createIndex(i, (int)ColumnType::Code, (void *)instructionRow);
emit dataChanged(index, index);
return;
}
}

// no existing comment
beginInsertRows(createIndex(instId, 0, instructionRow), 0, 0);
DisassemblyRow commentRow;
commentRow.id = instructionRow->children.size();
commentRow.address = instructionRow->address;
commentRow.type = RowType::Comment;
commentRow.parent = instructionRow;
instructionRow->children.insert(instructionRow->children.begin(),
std::move(commentRow));
endInsertRows();
}
}
30 changes: 21 additions & 9 deletions src/gui/disassemblymodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

class SCXFile;
class SC3CodeBlock;
struct DisassemblyRow;

class DisassemblyModel : public QAbstractItemModel {
Q_OBJECT
Expand All @@ -18,6 +19,8 @@ class DisassemblyModel : public QAbstractItemModel {
explicit DisassemblyModel(const SCXFile* script, QObject* parent = 0);
~DisassemblyModel() {}

const SCXFile* script() const { return _script; }

QVariant data(const QModelIndex& index, int role) const override;
Qt::ItemFlags flags(const QModelIndex& index) const override;
QVariant headerData(int section, Qt::Orientation orientation,
Expand All @@ -29,20 +32,29 @@ class DisassemblyModel : public QAbstractItemModel {
int columnCount(const QModelIndex& parent = QModelIndex()) const override;

QModelIndex firstIndexForAddress(SCXOffset address) const;
int firstLabelForAddress(SCXOffset address) const;
int firstInstructionForAddress(SCXOffset address) const;
int firstInstructionForAddress(int labelId, SCXOffset address) const;
SCXOffset addressForIndex(const QModelIndex& index) const;

private:
struct DisassemblyRow {
RowType type;
int id;
SCXOffset address;
std::vector<DisassemblyRow> children;
DisassemblyRow* parent;
};
private slots:
void onCommentChanged(int fileId, SCXOffset address, const QString& text);

private:
const SCXFile* _script;
std::vector<DisassemblyRow> _labelRows;

bool indexIsLabel(const QModelIndex& index) const;
const SC3CodeBlock* labelForIndex(const QModelIndex& index) const;
QModelIndex indexForLabel(SCXOffset labelId) const;
};

void reload();
};

struct DisassemblyRow {
DisassemblyModel::RowType type;
int id;
SCXOffset address;
std::vector<DisassemblyRow> children;
DisassemblyRow* parent;
};
33 changes: 33 additions & 0 deletions src/gui/disassemblyview.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include "disassemblyitemdelegate.h"
#include "project.h"
#include "debuggerapplication.h"
#include <QAction>
#include <QInputDialog>

DisassemblyView::DisassemblyView(QWidget* parent) : QTreeView(parent) {
connect(dApp, &DebuggerApplication::projectOpened, this,
Expand All @@ -27,11 +29,25 @@ DisassemblyView::DisassemblyView(QWidget* parent) : QTreeView(parent) {

void DisassemblyView::setModel(QAbstractItemModel* model) {
QTreeView::setModel(model);
connect(model, &QAbstractItemModel::modelReset, this,
&DisassemblyView::onModelReset);
connect(model, &QAbstractItemModel::rowsInserted, this,
&DisassemblyView::onModelReset);

expandAll();
scrollToTop();
}

void DisassemblyView::onModelReset() {
setUniformRowHeights(true);
setItemsExpandable(false);
setWordWrap(false);
setIndentation(0);
setRootIsDecorated(false);

expandAll();
}

void DisassemblyView::goToAddress(SCXOffset address) {
const DisassemblyModel* disModel = qobject_cast<DisassemblyModel*>(model());
if (disModel == nullptr) return;
Expand Down Expand Up @@ -67,4 +83,21 @@ void DisassemblyView::onFileSwitched(int previousId) {
QAbstractItemModel* oldModel = model();
setModel(new DisassemblyModel(dApp->project()->currentFile()));
if (oldModel != nullptr) delete oldModel;
}

void DisassemblyView::onCommentKeyPress() {
const DisassemblyModel* disModel = qobject_cast<DisassemblyModel*>(model());
if (disModel == nullptr) return;

SCXOffset address = disModel->addressForIndex(currentIndex());
if (address < 0) return;

QString oldComment =
dApp->project()->getComment(disModel->script()->getId(), address);

bool ok;
QString newComment = QInputDialog::getMultiLineText(
this, "Edit comment", "Comment:", oldComment, &ok);
if (!ok) return;
dApp->project()->setComment(disModel->script()->getId(), address, newComment);
}
4 changes: 4 additions & 0 deletions src/gui/disassemblyview.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ class DisassemblyView : public QTreeView {

void goToAddress(SCXOffset address);

public slots:
void onCommentKeyPress();

private slots:
void onModelReset();
void adjustHeader(int oldCount, int newCount);

void onProjectOpened();
Expand Down
5 changes: 5 additions & 0 deletions src/gui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "disassemblyview.h"
#include <QDockWidget>
#include <QInputDialog>
#include <QShortcut>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent), ui(new Ui::MainWindow) {
Expand Down Expand Up @@ -45,6 +46,10 @@ MainWindow::MainWindow(QWidget *parent)
&MainWindow::onProjectOpened);
connect(dApp, &DebuggerApplication::projectClosed, this,
&MainWindow::onProjectClosed);

QShortcut *commentShortcut = new QShortcut(Qt::Key_C, this);
connect(commentShortcut, &QShortcut::activated, _disasmView,
&DisassemblyView::onCommentKeyPress);
}

MainWindow::~MainWindow() { delete ui; }
Expand Down
Loading

0 comments on commit 41ef912

Please sign in to comment.