mirror of
https://github.com/isledecomp/SIEdit.git
synced 2025-02-17 00:40:42 -05:00
Merge pull request #2 from MasonLeeBack/master
Document more of the MxOb structure
This commit is contained in:
commit
57930816f6
4 changed files with 188 additions and 9 deletions
|
@ -51,6 +51,83 @@ MxObPanel::MxObPanel(QWidget *parent) :
|
|||
|
||||
row++;
|
||||
|
||||
auto flag_group = new QGroupBox(tr("Flags"));
|
||||
layout()->addWidget(flag_group, row, 0, 1, 2);
|
||||
|
||||
row++;
|
||||
|
||||
{
|
||||
auto flag_layout = new QGridLayout(flag_group);
|
||||
|
||||
int flag_row = 0;
|
||||
|
||||
flag_layout->addWidget(new QLabel(tr("Value")), flag_row, 0);
|
||||
|
||||
flag_edit_ = new QLineEdit();
|
||||
flag_layout->addWidget(flag_edit_, flag_row, 1);
|
||||
|
||||
flag_row++;
|
||||
|
||||
auto loop_cache = new QCheckBox(tr("Loop from Cache"));
|
||||
loop_cache->setProperty("flag", 0x01);
|
||||
connect(loop_cache, &QCheckBox::clicked, this, &MxObPanel::FlagCheckBoxClicked);
|
||||
flag_checkboxes_.append(loop_cache);
|
||||
flag_layout->addWidget(loop_cache, flag_row, 0, 1, 2);
|
||||
|
||||
flag_row++;
|
||||
|
||||
auto no_loop = new QCheckBox(tr("No Loop"));
|
||||
no_loop->setProperty("flag", 0x02);
|
||||
connect(no_loop, &QCheckBox::clicked, this, &MxObPanel::FlagCheckBoxClicked);
|
||||
flag_checkboxes_.append(no_loop);
|
||||
flag_layout->addWidget(no_loop, flag_row, 0, 1, 2);
|
||||
|
||||
flag_row++;
|
||||
|
||||
auto loop_stream = new QCheckBox(tr("Loop from Stream"));
|
||||
loop_stream->setProperty("flag", 0x04);
|
||||
connect(loop_stream, &QCheckBox::clicked, this, &MxObPanel::FlagCheckBoxClicked);
|
||||
flag_checkboxes_.append(loop_stream);
|
||||
flag_layout->addWidget(loop_stream, flag_row, 0, 1, 2);
|
||||
|
||||
flag_row++;
|
||||
|
||||
auto transparent = new QCheckBox(tr("Transparent"));
|
||||
transparent->setProperty("flag", 0x08);
|
||||
connect(transparent, &QCheckBox::clicked, this, &MxObPanel::FlagCheckBoxClicked);
|
||||
flag_checkboxes_.append(transparent);
|
||||
flag_layout->addWidget(transparent, flag_row, 0, 1, 2);
|
||||
|
||||
flag_row++;
|
||||
|
||||
auto unknown = new QCheckBox(tr("Unknown"));
|
||||
unknown->setProperty("flag", 0x20);
|
||||
connect(unknown, &QCheckBox::clicked, this, &MxObPanel::FlagCheckBoxClicked);
|
||||
flag_checkboxes_.append(unknown);
|
||||
flag_layout->addWidget(unknown, flag_row, 0, 1, 2);
|
||||
|
||||
flag_row++;
|
||||
|
||||
}
|
||||
|
||||
layout()->addWidget(new QLabel(tr("Duration")), row, 0);
|
||||
|
||||
duration_edit_ = new QSpinBox();
|
||||
duration_edit_->setMinimum(0);
|
||||
duration_edit_->setMaximum(INT_MAX);
|
||||
layout()->addWidget(duration_edit_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
layout()->addWidget(new QLabel(tr("Loops")), row, 0);
|
||||
|
||||
loops_edit_ = new QSpinBox();
|
||||
loops_edit_->setMinimum(0);
|
||||
loops_edit_->setMaximum(INT_MAX);
|
||||
layout()->addWidget(loops_edit_, row, 1);
|
||||
|
||||
row++;
|
||||
|
||||
auto pos_grp = new QGroupBox(tr("Position"));
|
||||
auto pos_lyt = new QVBoxLayout(pos_grp);
|
||||
pos_lyt->setMargin(0);
|
||||
|
@ -87,6 +164,15 @@ void MxObPanel::OnOpeningData(si::Chunk *chunk)
|
|||
presenter_edit_->setText(QString(chunk->data("Presenter")));
|
||||
obj_id_edit_->setValue(chunk->data("ID"));
|
||||
|
||||
flag_edit_->setText(QString::number(chunk->data("Flags"), 16));
|
||||
|
||||
for (QCheckBox* cb : qAsConst(flag_checkboxes_)) {
|
||||
cb->setChecked(cb->property("flag").toUInt() & chunk->data("Flags"));
|
||||
}
|
||||
|
||||
duration_edit_->setValue(chunk->data("Duration"));
|
||||
loops_edit_->setValue(chunk->data("Loops"));
|
||||
|
||||
pos_edit_->SetValue(chunk->data("Position"));
|
||||
dir_edit_->SetValue(chunk->data("Direction"));
|
||||
up_edit_->SetValue(chunk->data("Up"));
|
||||
|
@ -96,7 +182,33 @@ void MxObPanel::OnClosingData(si::Chunk *chunk)
|
|||
{
|
||||
chunk->data("Type") = type_combo_->currentIndex();
|
||||
|
||||
bool ok;
|
||||
u32 flags = flag_edit_->text().toUInt(&ok, 16);
|
||||
if (ok) {
|
||||
chunk->data("Flags") = flags;
|
||||
}
|
||||
|
||||
chunk->data("Duration") = duration_edit_->value();
|
||||
chunk->data("Loops") = loops_edit_->value();
|
||||
|
||||
chunk->data("Position") = pos_edit_->GetValue();
|
||||
chunk->data("Direction") = dir_edit_->GetValue();
|
||||
chunk->data("Up") = up_edit_->GetValue();
|
||||
}
|
||||
|
||||
void MxObPanel::FlagCheckBoxClicked(bool e)
|
||||
{
|
||||
u32 flag = sender()->property("flag").toUInt();
|
||||
bool ok;
|
||||
u32 current = flag_edit_->text().toUInt(&ok, 16);
|
||||
if (ok) {
|
||||
if (e) {
|
||||
current |= flag;
|
||||
}
|
||||
else {
|
||||
current &= ~flag;
|
||||
}
|
||||
|
||||
flag_edit_->setText(QString::number(current, 16));
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef MXOBPANEL_H
|
||||
#define MXOBPANEL_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
|
@ -25,10 +26,20 @@ private:
|
|||
QLineEdit *filename_edit_;
|
||||
QSpinBox *obj_id_edit_;
|
||||
|
||||
QLineEdit* flag_edit_;
|
||||
|
||||
QSpinBox *duration_edit_;
|
||||
QSpinBox *loops_edit_;
|
||||
|
||||
Vector3Edit *pos_edit_;
|
||||
Vector3Edit *dir_edit_;
|
||||
Vector3Edit *up_edit_;
|
||||
|
||||
QVector<QCheckBox*> flag_checkboxes_;
|
||||
|
||||
private slots:
|
||||
void FlagCheckBoxClicked(bool e);
|
||||
|
||||
};
|
||||
|
||||
#endif // MXOBPANEL_H
|
||||
|
|
|
@ -18,6 +18,13 @@ Data ReadU16(std::ifstream &is)
|
|||
return u;
|
||||
}
|
||||
|
||||
Data ReadU8(std::ifstream &is)
|
||||
{
|
||||
u8 u;
|
||||
is.read((char *) &u, sizeof(u));
|
||||
return u;
|
||||
}
|
||||
|
||||
Data ReadVector3(std::ifstream &is)
|
||||
{
|
||||
Vector3 u;
|
||||
|
@ -127,6 +134,33 @@ const char *MxOb::GetTypeName(Type type)
|
|||
return "Unknown";
|
||||
}
|
||||
|
||||
std::vector<const char*> MxOb::GetFlagsName(Flags flags)
|
||||
{
|
||||
std::vector<const char*> names;
|
||||
|
||||
if (flags == FLAGS_COUNT) {
|
||||
return names;
|
||||
}
|
||||
|
||||
if (flags & Transparent) {
|
||||
names.push_back("Transparent");
|
||||
}
|
||||
if (flags & NoLoop) {
|
||||
names.push_back("NoLoop");
|
||||
}
|
||||
if (flags & LoopCache) {
|
||||
names.push_back("LoopCache");
|
||||
}
|
||||
if (flags & LoopStream) {
|
||||
names.push_back("LoopStream");
|
||||
}
|
||||
if (flags & Unknown) {
|
||||
names.push_back("Unknown");
|
||||
}
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
void MxOb::Read(std::ifstream &is, DataMap &data, u32 version, u32 size)
|
||||
{
|
||||
Data obj_type = ReadU16(is);
|
||||
|
@ -135,10 +169,10 @@ void MxOb::Read(std::ifstream &is, DataMap &data, u32 version, u32 size)
|
|||
data["Unknown1"] = ReadU32(is);
|
||||
data["Name"] = ReadString(is);
|
||||
data["ID"] = ReadU32(is);
|
||||
data["Unknown3"] = ReadU32(is);
|
||||
data["Flags"] = ReadU32(is);
|
||||
data["Unknown4"] = ReadU32(is);
|
||||
data["Unknown5"] = ReadU32(is);
|
||||
data["Unknown6"] = ReadU32(is);
|
||||
data["Duration"] = ReadU32(is);
|
||||
data["Loops"] = ReadU32(is);
|
||||
data["Position"] = ReadVector3(is);
|
||||
data["Direction"] = ReadVector3(is);
|
||||
data["Up"] = ReadVector3(is);
|
||||
|
|
|
@ -116,13 +116,13 @@ public:
|
|||
* Unknown1 | 4 | u32 |
|
||||
* Name | Variable | string | Null-terminated string identifying object's name
|
||||
* ID | 4 | u32 | Unique object identifier within file (used to differentiate interleaved MxChs)
|
||||
* Unknown3 | 4 | u32 |
|
||||
* Unknown4 | 4 | u32 |
|
||||
* Unknown5 | 4 | u32 |
|
||||
* Unknown6 | 4 | u32 |
|
||||
* Flags | 4 | u32 | Flags of object (member of MxOb::Flags enum)
|
||||
* Unknown4 | 4 | u32 | Similar to Duration, but only used for Lego3DWavePresenter
|
||||
* Duration | 4 | u32 | Duration in milliseconds * Loops
|
||||
* Loops | 4 | u32 |
|
||||
* Position | 24 | Vector3 | Position
|
||||
* Direction | 24 | Vector3 | Position
|
||||
* Up | 24 | Vector3 | Position
|
||||
* Direction | 24 | Vector3 | Direction to look towards
|
||||
* Up | 24 | Vector3 | Up vector
|
||||
* ExtraLength | 2 | u16 |
|
||||
* ExtraData | ExtraLength | bytearray |
|
||||
* FileName | Variable | string | Original filename of the file represented by this object.
|
||||
|
@ -167,9 +167,31 @@ public:
|
|||
TYPE_COUNT
|
||||
};
|
||||
|
||||
enum Flags
|
||||
{
|
||||
/// Object loops via cache (i.e. hard disk)
|
||||
LoopCache = 0x01,
|
||||
|
||||
/// Object does not loop
|
||||
NoLoop = 0x02,
|
||||
|
||||
/// Object loops via stream (i.e. CD-ROM)
|
||||
LoopStream = 0x04,
|
||||
|
||||
/// Object is transparent
|
||||
Transparent = 0x08,
|
||||
|
||||
/// Unknown flag, but set by every object thus far
|
||||
Unknown = 0x20,
|
||||
|
||||
/// Total number of flags (not a real type)
|
||||
FLAGS_COUNT
|
||||
};
|
||||
|
||||
// FIXME: sitypes.h probably won't be part of the public API, so this should
|
||||
// probably be moved
|
||||
LIBWEAVER_EXPORT static const char *GetTypeName(Type type);
|
||||
LIBWEAVER_EXPORT static std::vector<const char*> GetFlagsName(Flags flags);
|
||||
|
||||
virtual void Read(std::ifstream &is, DataMap &data, u32 version, u32 size);
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue