mirror of
https://github.com/isledecomp/SIEdit.git
synced 2024-12-02 11:57:35 -05:00
lib: implement write functions for RIFF classes
This commit is contained in:
parent
6f8d3d500c
commit
4d05dc8ac8
5 changed files with 97 additions and 9 deletions
|
@ -8,9 +8,10 @@
|
||||||
|
|
||||||
namespace si {
|
namespace si {
|
||||||
|
|
||||||
Chunk::Chunk()
|
Chunk::Chunk(uint32_t id) :
|
||||||
|
id_(id),
|
||||||
|
offset_(0)
|
||||||
{
|
{
|
||||||
id_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Chunk::~Chunk()
|
Chunk::~Chunk()
|
||||||
|
@ -89,6 +90,40 @@ bool Chunk::Read(std::ifstream &f, uint32_t &version, uint32_t &alignment)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Chunk::Write(std::ofstream &f, const uint32_t &version) const
|
||||||
|
{
|
||||||
|
// Write 4-byte ID
|
||||||
|
f.write((const char *) &id_, sizeof(id_));
|
||||||
|
|
||||||
|
// Write placeholder for size and store position so we can come back later
|
||||||
|
uint32_t chunk_size = 0;
|
||||||
|
std::ios::pos_type size_pos = f.tellp();
|
||||||
|
f.write((const char *) &chunk_size, sizeof(chunk_size));
|
||||||
|
|
||||||
|
if (RIFF *writer = GetReaderFromType(type())) {
|
||||||
|
writer->Write(f, data_, version);
|
||||||
|
delete writer;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Children::const_iterator it=GetChildren().begin(); it!=GetChildren().end(); it++) {
|
||||||
|
static_cast<Chunk*>(*it)->Write(f, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Backtrack and write chunk size
|
||||||
|
chunk_size = uint32_t(f.tellp()) - (uint32_t(size_pos) + sizeof(uint32_t));
|
||||||
|
f.seekp(size_pos);
|
||||||
|
f.write((const char *) &chunk_size, sizeof(chunk_size));
|
||||||
|
f.seekp(0, std::ios::end);
|
||||||
|
|
||||||
|
// Byte align to 2
|
||||||
|
if (chunk_size%2 == 1) {
|
||||||
|
const char nothing = 0;
|
||||||
|
f.write(¬hing, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
RIFF *Chunk::GetReaderFromType(Type type)
|
RIFF *Chunk::GetReaderFromType(Type type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -108,6 +143,8 @@ RIFF *Chunk::GetReaderFromType(Type type)
|
||||||
return new pad_();
|
return new pad_();
|
||||||
case TYPE_MxOb:
|
case TYPE_MxOb:
|
||||||
return new MxOb();
|
return new MxOb();
|
||||||
|
case TYPE_MxDa:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -122,6 +159,23 @@ void Chunk::Clear()
|
||||||
DeleteChildren();
|
DeleteChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Chunk::Write(const std::string &f)
|
||||||
|
{
|
||||||
|
return Write(f.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Chunk::Write(const char *f)
|
||||||
|
{
|
||||||
|
std::ofstream file(f, std::ios::out | std::ios::binary);
|
||||||
|
if (!file.is_open() || !file.good()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t version = 0;
|
||||||
|
|
||||||
|
return Write(file, version);
|
||||||
|
}
|
||||||
|
|
||||||
const char *Chunk::GetTypeDescription(Type type)
|
const char *Chunk::GetTypeDescription(Type type)
|
||||||
{
|
{
|
||||||
switch (type) {
|
switch (type) {
|
||||||
|
@ -141,6 +195,8 @@ const char *Chunk::GetTypeDescription(Type type)
|
||||||
return "Padding";
|
return "Padding";
|
||||||
case TYPE_MxOb:
|
case TYPE_MxOb:
|
||||||
return "Streamable Object";
|
return "Streamable Object";
|
||||||
|
case TYPE_MxDa:
|
||||||
|
return "Data";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
|
|
|
@ -24,16 +24,20 @@ public:
|
||||||
TYPE_MxCh = 0x6843784d,
|
TYPE_MxCh = 0x6843784d,
|
||||||
TYPE_MxOf = 0x664f784d,
|
TYPE_MxOf = 0x664f784d,
|
||||||
TYPE_MxOb = 0x624f784d,
|
TYPE_MxOb = 0x624f784d,
|
||||||
|
TYPE_MxDa = 0x6144784d,
|
||||||
TYPE_pad_ = 0x20646170
|
TYPE_pad_ = 0x20646170
|
||||||
};
|
};
|
||||||
|
|
||||||
LIBWEAVER_EXPORT Chunk();
|
LIBWEAVER_EXPORT Chunk(uint32_t id = 0);
|
||||||
virtual LIBWEAVER_EXPORT ~Chunk();
|
virtual LIBWEAVER_EXPORT ~Chunk();
|
||||||
|
|
||||||
LIBWEAVER_EXPORT bool Read(const std::string &f);
|
LIBWEAVER_EXPORT bool Read(const std::string &f);
|
||||||
LIBWEAVER_EXPORT bool Read(const char *f);
|
LIBWEAVER_EXPORT bool Read(const char *f);
|
||||||
LIBWEAVER_EXPORT void Clear();
|
LIBWEAVER_EXPORT void Clear();
|
||||||
|
|
||||||
|
LIBWEAVER_EXPORT bool Write(const std::string &f);
|
||||||
|
LIBWEAVER_EXPORT bool Write(const char *f);
|
||||||
|
|
||||||
LIBWEAVER_EXPORT Type type() const { return static_cast<Type>(id_); }
|
LIBWEAVER_EXPORT Type type() const { return static_cast<Type>(id_); }
|
||||||
LIBWEAVER_EXPORT const uint32_t &id() const { return id_; }
|
LIBWEAVER_EXPORT const uint32_t &id() const { return id_; }
|
||||||
LIBWEAVER_EXPORT const uint32_t &offset() const { return offset_; }
|
LIBWEAVER_EXPORT const uint32_t &offset() const { return offset_; }
|
||||||
|
@ -52,6 +56,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool Read(std::ifstream &f, uint32_t &version, uint32_t &alignment);
|
bool Read(std::ifstream &f, uint32_t &version, uint32_t &alignment);
|
||||||
|
bool Write(std::ofstream &f, const uint32_t &version) const;
|
||||||
|
|
||||||
static RIFF *GetReaderFromType(Type type);
|
static RIFF *GetReaderFromType(Type type);
|
||||||
|
|
||||||
|
|
|
@ -78,6 +78,7 @@ void WriteString(std::ofstream &os, const std::string &d)
|
||||||
const char *s = &d[0];
|
const char *s = &d[0];
|
||||||
while ((*s) != 0) {
|
while ((*s) != 0) {
|
||||||
os.write(s, 1);
|
os.write(s, 1);
|
||||||
|
s++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,15 +187,19 @@ void MxOf::Write(std::ofstream &os, const DataMap &data, uint32_t version)
|
||||||
|
|
||||||
void pad_::Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size)
|
void pad_::Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size)
|
||||||
{
|
{
|
||||||
|
data["Size"] = size;
|
||||||
is.seekg(size, std::ios::cur);
|
is.seekg(size, std::ios::cur);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pad_::WritePadding(std::ofstream &os, size_t size)
|
void pad_::Write(std::ofstream &os, const DataMap &data, uint32_t version)
|
||||||
{
|
{
|
||||||
|
uint32_t sz = data.at("Size").toU32();
|
||||||
|
if (sz > 0) {
|
||||||
bytearray b;
|
bytearray b;
|
||||||
b.resize(size);
|
b.resize(sz);
|
||||||
b.fill(0xCD);
|
b.fill(0xCD);
|
||||||
WriteBytes(os, b);
|
WriteBytes(os, b);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *MxOb::GetTypeName(Type type)
|
const char *MxOb::GetTypeName(Type type)
|
||||||
|
|
|
@ -18,6 +18,10 @@ namespace si {
|
||||||
class RIFF
|
class RIFF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum {
|
||||||
|
OMNI = 0x494e4d4f
|
||||||
|
};
|
||||||
|
|
||||||
virtual ~RIFF(){}
|
virtual ~RIFF(){}
|
||||||
|
|
||||||
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
||||||
|
@ -81,6 +85,13 @@ public:
|
||||||
class MxCh : public RIFF
|
class MxCh : public RIFF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum Flag {
|
||||||
|
FLAG_SPLIT = 0x16,
|
||||||
|
FLAG_END = 0x2
|
||||||
|
};
|
||||||
|
|
||||||
|
static const uint32_t HEADER_SIZE = 14;
|
||||||
|
|
||||||
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
||||||
virtual void Write(std::ofstream &os, const DataMap &data, uint32_t version);
|
virtual void Write(std::ofstream &os, const DataMap &data, uint32_t version);
|
||||||
};
|
};
|
||||||
|
@ -110,7 +121,7 @@ class pad_ : public RIFF
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
virtual void Read(std::ifstream &is, DataMap &data, uint32_t version, uint32_t size);
|
||||||
void WritePadding(std::ofstream &os, size_t size);
|
virtual void Write(std::ofstream &os, const DataMap &data, uint32_t version);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -146,6 +157,10 @@ class MxOb : public RIFF
|
||||||
public:
|
public:
|
||||||
enum Type
|
enum Type
|
||||||
{
|
{
|
||||||
|
/// Not an MxOb type, this is our identifier for an object that is in the TOC but doesn't
|
||||||
|
/// actually exist
|
||||||
|
Null = -1,
|
||||||
|
|
||||||
/// Video
|
/// Video
|
||||||
Video = 0x03,
|
Video = 0x03,
|
||||||
|
|
||||||
|
@ -202,6 +217,9 @@ public:
|
||||||
|
|
||||||
/// Bitmap image
|
/// Bitmap image
|
||||||
STL = 0x4C545320,
|
STL = 0x4C545320,
|
||||||
|
|
||||||
|
/// FLIC animation
|
||||||
|
FLC = 0x434c4620,
|
||||||
};
|
};
|
||||||
|
|
||||||
// FIXME: sitypes.h probably won't be part of the public API, so this should
|
// FIXME: sitypes.h probably won't be part of the public API, so this should
|
||||||
|
|
|
@ -26,6 +26,10 @@ class bytearray : public std::vector<char>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bytearray(){}
|
bytearray(){}
|
||||||
|
bytearray(size_t size)
|
||||||
|
{
|
||||||
|
resize(size);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *cast() { return reinterpret_cast<T*>(data()); }
|
T *cast() { return reinterpret_cast<T*>(data()); }
|
||||||
|
|
Loading…
Reference in a new issue