2022-07-03 11:57:43 -04:00
|
|
|
#ifndef SI_H
|
|
|
|
#define SI_H
|
|
|
|
|
|
|
|
#include <fstream>
|
|
|
|
|
2022-07-18 14:25:00 -04:00
|
|
|
#include "file.h"
|
2022-07-03 11:57:43 -04:00
|
|
|
#include "types.h"
|
|
|
|
|
|
|
|
namespace si {
|
|
|
|
|
2022-07-18 03:27:00 -04:00
|
|
|
/**
|
|
|
|
* @brief RIFF chunk type
|
|
|
|
*
|
|
|
|
* Name | Size | Type | Description
|
|
|
|
* -------- | -------- | -------- | -----------
|
|
|
|
* Format | 4 | u32 | 4-byte ASCII identifier for what type of RIFF this is (usually 'OMNI' in the case of LEGO Island)
|
|
|
|
*/
|
|
|
|
class RIFF
|
2022-07-17 21:51:16 -04:00
|
|
|
{
|
|
|
|
public:
|
2022-07-18 03:27:00 -04:00
|
|
|
enum Type {
|
|
|
|
RIFF_ = 0x46464952,
|
2022-07-17 21:51:16 -04:00
|
|
|
LIST = 0x5453494c,
|
|
|
|
MxSt = 0x7453784d,
|
|
|
|
MxHd = 0x6448784d,
|
|
|
|
MxCh = 0x6843784d,
|
|
|
|
MxOf = 0x664f784d,
|
|
|
|
MxOb = 0x624f784d,
|
|
|
|
MxDa = 0x6144784d,
|
2022-07-18 03:27:00 -04:00
|
|
|
pad_ = 0x20646170,
|
|
|
|
OMNI = 0x494e4d4f,
|
|
|
|
WAVE = 0x45564157,
|
|
|
|
fmt_ = 0x20746D66,
|
|
|
|
data = 0x61746164
|
2022-07-17 21:51:16 -04:00
|
|
|
};
|
|
|
|
|
2022-07-18 03:27:00 -04:00
|
|
|
struct Chk
|
|
|
|
{
|
|
|
|
std::ios::pos_type size_position;
|
|
|
|
std::ios::pos_type data_start;
|
2022-07-11 17:18:56 -04:00
|
|
|
};
|
2022-07-18 03:27:00 -04:00
|
|
|
|
2022-07-18 14:25:00 -04:00
|
|
|
static Chk BeginChunk(FileBase *f, uint32_t type);
|
|
|
|
static void EndChunk(FileBase *f, const Chk &stat);
|
2022-07-18 03:27:00 -04:00
|
|
|
|
|
|
|
static inline std::string PrintU32AsString(uint32_t u)
|
|
|
|
{
|
|
|
|
return std::string((const char *) &u, sizeof(u));
|
|
|
|
}
|
|
|
|
|
2022-07-18 12:49:27 -04:00
|
|
|
LIBWEAVER_EXPORT static const char *GetTypeDescription(Type t);
|
2022-07-18 03:27:00 -04:00
|
|
|
|
2022-07-03 11:57:43 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief LIST chunk type
|
|
|
|
*
|
|
|
|
* Name | Size | Type | Description
|
|
|
|
* -------- | -------- | -------- | -----------
|
|
|
|
* Format | 4 | u32 | 4-byte ASCII identifier for what type of LIST this is.
|
|
|
|
* Count | 4 | u32 | (Optional) for 'MxCh' type LISTs, the number of elements in this list.
|
|
|
|
*/
|
|
|
|
class LIST : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief MxHd chunk type
|
|
|
|
*
|
|
|
|
* Name | Size | Type | Description
|
|
|
|
* ----------- | -------- | -------- | -----------
|
|
|
|
* Version | 4 | u32 | Version of this SI file stored as two packed 16-bit words, the high word being the major version and the low word being the minor version.
|
|
|
|
* BufferSize | 4 | u32 | The amount of data to read from disk at a time.
|
|
|
|
* BufferCount | 4 | u32 | FIXME: Currently not understood what this field does.
|
|
|
|
*/
|
|
|
|
class MxHd : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief MxSt chunk type
|
|
|
|
*
|
|
|
|
* MxSt is a container type only, it has none of its own members.
|
|
|
|
*/
|
|
|
|
class MxSt : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief MxCh chunk type
|
|
|
|
*
|
|
|
|
* Name | Size | Type | Description
|
|
|
|
* ---------- | -------- | --------- | -----------
|
|
|
|
* Flags | 2 | u16 | Flags determining the behavior of this chunk.
|
|
|
|
* Object | 4 | u32 | ID of the MxOb that this chunk belongs to.
|
|
|
|
* Time | 4 | u32 | Time in milliseconds that this chunk's data should be presented at.
|
|
|
|
* DataSize | 4 | u32 | Size of the data in this chunk.
|
|
|
|
* Data | DataSize | bytearray | Actual data in chunk.
|
|
|
|
*/
|
|
|
|
class MxCh : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
2022-07-11 17:18:56 -04:00
|
|
|
enum Flag {
|
2022-07-18 05:12:22 -04:00
|
|
|
FLAG_SPLIT = 0x10,
|
2022-07-11 17:18:56 -04:00
|
|
|
FLAG_END = 0x2
|
|
|
|
};
|
|
|
|
|
|
|
|
static const uint32_t HEADER_SIZE = 14;
|
2022-07-03 11:57:43 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief MxOf chunk type
|
|
|
|
*
|
|
|
|
* Name | Size | Type | Description
|
|
|
|
* ---------- | -------- | ---------------- | -----------
|
|
|
|
* Count | 4 | u32 | Number of objects in this list. Not necessarily the number of offsets, as one offset may point to an object with multiple sub-objects.
|
2022-07-03 23:45:32 -04:00
|
|
|
* Offsets | Variable | bytearray/u32[] | List of 4-byte file offsets where objects begin.
|
2022-07-03 11:57:43 -04:00
|
|
|
*/
|
|
|
|
class MxOf : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief pad_ chunk type
|
|
|
|
*
|
|
|
|
* Denotes padding to optimize disc reads. Contains no useful information,
|
|
|
|
* customarily filled with the byte 0xCD.
|
|
|
|
*/
|
|
|
|
class pad_ : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
2022-07-18 03:27:00 -04:00
|
|
|
static void WriteArbitraryPadding(std::ostream &os, uint32_t size);
|
2022-07-03 11:57:43 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief MxOb chunk type
|
|
|
|
*
|
|
|
|
* Name | Size | Type | Description
|
|
|
|
* ----------- | -------- | ---------------- | -----------
|
|
|
|
* Type | 2 | u16 | Type of object (member of MxOb::Type enum)
|
|
|
|
* Presenter | Variable | string | Null-terminated string identifying the presenter to use (if type is set to `Presenter`)
|
|
|
|
* 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)
|
2022-07-04 22:50:23 -04:00
|
|
|
* Flags | 4 | u32 | Flags of object (member of MxOb::Flags enum)
|
2022-07-04 13:59:47 -04:00
|
|
|
* Unknown4 | 4 | u32 | Similar to Duration, but only used for Lego3DWavePresenter
|
|
|
|
* Duration | 4 | u32 | Duration in milliseconds * Loops
|
|
|
|
* Loops | 4 | u32 |
|
2022-07-04 02:33:38 -04:00
|
|
|
* Position | 24 | Vector3 | Position
|
2022-07-04 13:59:47 -04:00
|
|
|
* Direction | 24 | Vector3 | Direction to look towards
|
|
|
|
* Up | 24 | Vector3 | Up vector
|
2022-07-03 11:57:43 -04:00
|
|
|
* ExtraLength | 2 | u16 |
|
|
|
|
* ExtraData | ExtraLength | bytearray |
|
|
|
|
* FileName | Variable | string | Original filename of the file represented by this object.
|
|
|
|
* Unknown26 | 4 | u32 |
|
|
|
|
* Unknown27 | 4 | u32 |
|
|
|
|
* Unknown28 | 4 | u32 |
|
|
|
|
* FileType | 4 | u32 | 4-byte ASCII ID for the file type
|
|
|
|
* Unknown29 | 4 | u32 |
|
|
|
|
* Unknown30 | 4 | u32 |
|
|
|
|
* Unknown31 | 4 | u32 | (Optional) only populated for WAV files
|
|
|
|
*/
|
|
|
|
class MxOb : public RIFF
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum Type
|
|
|
|
{
|
2022-07-11 17:18:56 -04:00
|
|
|
/// Not an MxOb type, this is our identifier for an object that is in the TOC but doesn't
|
|
|
|
/// actually exist
|
|
|
|
Null = -1,
|
|
|
|
|
2022-07-11 04:48:20 -04:00
|
|
|
/// Video
|
|
|
|
Video = 0x03,
|
2022-07-03 11:57:43 -04:00
|
|
|
|
2022-07-11 04:48:20 -04:00
|
|
|
/// Audio
|
|
|
|
Sound = 0x04,
|
2022-07-03 11:57:43 -04:00
|
|
|
|
|
|
|
/// World object for LegoWorldPresenter
|
|
|
|
World = 0x06,
|
|
|
|
|
|
|
|
/// Custom MxPresenter
|
|
|
|
Presenter = 0x07,
|
|
|
|
|
|
|
|
/// Event
|
|
|
|
Event = 0x08,
|
|
|
|
|
|
|
|
/// Animation
|
|
|
|
Animation = 0x09,
|
|
|
|
|
|
|
|
/// Bitmap image
|
2022-07-17 19:25:06 -04:00
|
|
|
Bitmap = 0x0A,
|
2022-07-03 11:57:43 -04:00
|
|
|
|
|
|
|
/// 3D Object
|
2022-07-17 19:25:06 -04:00
|
|
|
Object = 0x0B,
|
2022-07-03 11:57:43 -04:00
|
|
|
|
|
|
|
/// Total number of types (not a real type)
|
|
|
|
TYPE_COUNT
|
|
|
|
};
|
|
|
|
|
2022-07-04 13:59:47 -04:00
|
|
|
enum Flags
|
|
|
|
{
|
2022-07-04 22:50:23 -04:00
|
|
|
/// Object loops via cache (i.e. hard disk)
|
|
|
|
LoopCache = 0x01,
|
|
|
|
|
2022-07-04 13:59:47 -04:00
|
|
|
/// Object does not loop
|
2022-07-04 22:50:23 -04:00
|
|
|
NoLoop = 0x02,
|
2022-07-04 13:59:47 -04:00
|
|
|
|
|
|
|
/// Object loops via stream (i.e. CD-ROM)
|
2022-07-04 22:50:23 -04:00
|
|
|
LoopStream = 0x04,
|
|
|
|
|
|
|
|
/// Object is transparent
|
|
|
|
Transparent = 0x08,
|
2022-07-04 13:59:47 -04:00
|
|
|
|
|
|
|
/// Unknown flag, but set by every object thus far
|
2022-07-04 22:50:23 -04:00
|
|
|
Unknown = 0x20,
|
2022-07-04 13:59:47 -04:00
|
|
|
|
|
|
|
/// Total number of flags (not a real type)
|
2022-07-11 04:48:20 -04:00
|
|
|
FLAGS_COUNT,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum FileType
|
|
|
|
{
|
|
|
|
/// WAVE audio
|
|
|
|
WAV = 0x56415720,
|
|
|
|
|
|
|
|
/// Bitmap image
|
|
|
|
STL = 0x4C545320,
|
2022-07-11 17:18:56 -04:00
|
|
|
|
|
|
|
/// FLIC animation
|
|
|
|
FLC = 0x434c4620,
|
2022-07-17 19:25:06 -04:00
|
|
|
|
|
|
|
/// SMK video
|
|
|
|
SMK = 0x4b4d5320,
|
|
|
|
|
|
|
|
/// 3D Object
|
|
|
|
OBJ = 0x4a424f20,
|
2022-07-04 13:59:47 -04:00
|
|
|
};
|
|
|
|
|
2022-07-03 11:57:43 -04:00
|
|
|
// 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);
|
2022-07-04 13:59:47 -04:00
|
|
|
LIBWEAVER_EXPORT static std::vector<const char*> GetFlagsName(Flags flags);
|
2022-07-03 11:57:43 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // SI_H
|