All VOS-related data structures are in little-endian format.
Strings are encoded as:
struct string {
u8 len;
char val[len];
};
File structure:
(from beyer85.vos)
0x00: "\x03\x00\x00\x00"
0x04: Segment table:
struct seg {
u32 offset; /* Offset of the segment in the file */
char name[16]; /* "inf", "mid", "EOF" */
} segs[variable]; /* The last segment is "EOF" */
The "inf" segment:
Before the inf_header, there can be an optional "VOS1" header:
struct vos1_header {
char magic[4]; /* "VOS1" */
u16 version; /* Usually 1 */
char dummy[64]; /* Usually all zeros */
string str1;
};
struct inf_header {
string title; /* Song title */
string artist; /* Artist of the original song */
string comment; /* Unknown; in beyer** it is "Step xx" where xx is the difficulty level,
but it can also be empty */
string vos_author; /* Author of the VOS */
u8 song_type; /* Probably things like "Classical" or "NewAge" */
u8 extended_type;
u32 length; /* The unit is approx. 1/974 sec (1024us?) */
u8 level; /* The shown level minus 1 */
char dummy[1023]; /* Seems to be zeroed out */
};
After the "inf" header, there is a list of note_arrays. The last note array just collects
the user-played notes in the other note arrays.
struct note_array {
u32 type; /* Instrument? */
u32 nnote; /* Number of notes */
char dummy2[14]; /* Seems to be always zero */
note notes[nnote];
}
struct note {
u32 time;
u32 len; /* Length of the note */
char midi[3]; /* The MIDI key-down command */
u16 mode; /* Bit 0-3: color (?); 4-6: corresponding key (do,re,mi,fa,so,la,ti);
Bit 7: set for notes played by the user;
Bit 8: set for long notes. */
char unknown2[2]; /* what? The first byte can be 0x80 or 0xB0 or 0xD0, ... Is it the length? */
};
The "mid" segment:
An ordinary MIDI file, but seems to contain initialization stuff only (please investigate further).