Welcome to Protodata!
Protodata is a language that allows you to manually create binary data files without the use of a hex editor. It allows binary files to be prototyped very quickly, and it is especially useful in developing custom file formats.
Why is this useful? Have you ever been working on a project that required you to have custom data files, but didn't have the time or money to write an editor? Protodata works for that. Have you ever wanted to have a human-readable, annotated version of a data file? It does that, too. If you're an indie game developer, you've probably run into one of these two issues, and Protodata is here to help.
What's the catch? There isn't one! There's so little of a catch that there's practically an anti-catch. Protodata is licensed under the GNU LGPL, which in a nutshell means that you're free to use the Protodata executable as part of your toolchain, and it won't cost you a dime. Even better, you don't have to make your project open source just to use the software.
You should download the latest copy here.
Table of Contents
Usage
To compile a Protodata document from input.pd to output.bin, use the following command:
pd input.pd output.bin
To read a Protodata document from standard input, just omit the input file name:
pd output.bin
Documents
A Protodata document consists of a series of commands separated by newlines. A command consists of a type specifier followed by any number of whitespace-separated values of that type. Multiple commands can appear on the same line if separated by a semicolon.
uint32 5 5 float 0.0 1.1 2.2 3.3 int 0; char 5 6 7 8
Because the pd compiler accepts code from standard input, you can use a command such as the following to write a file from the command line:
echo "short 1 2; ulong 3" | pd ouput.bin
Shorthand equivalents of each type are provided to make typing this kind of command a little easier:
echo "h 1 2; L 3" | pd output.bin
If a type is not specified, the type of the previous command is implicitly used.
uint 10 20 30 40 50 60 70 80 90
Therefore, only the first command in the document need specify a type. The following types are currently supported:
Type | Shorthand Type | Description |
---|---|---|
char | c | A signed character. |
uchar | C | An unsigned character. |
short | h | A signed short int. |
ushort | H | An unsigned short int. |
int | i | A signed int. |
uint | I | An unsigned int. |
long | l | A signed long int. |
ulong | L | An unsigned long int. |
float | f | A single-precision floating-point number. |
double | F | A double-precision floating-point number. |
extended | x | An extended-precision floating-point number. |
int8 | i8 | A signed 8-bit integer. |
uint8 | I8 | An unsigned 8-bit integer. |
int16 | i16 | A signed 16-bit integer. |
uint16 | I16 | An unsigned 16-bit integer. |
int32 | i32 | A signed 32-bit integer. |
uint32 | I32 | An unsigned 32-bit integer. |
int64 | i64 | A signed 64-bit integer. |
uint64 | I64 | An unsigned 64-bit integer. |
Comments
One of the most useful features of Protodata is the ability to provide inline annotations of the data in the file. Protodata supports two styles of comment. C++-style comments begin with two forward slashes (//), and shell-style comments begin with a single hash mark (#). Both extend from the comment symbol until the end of the current line
float 123.45 // This is a comment. # This is also a comment.
C++-style comments are preferred. Shell-style comments are supported for the ability to make use of the shebang syntax on Unix-style systems to automatically invoke pd.
#!/usr/bin/pd output.bin
Qualifiers
In a command, the type (or implicit type) may be preceded by any number of qualifiers that alter the behaviour of the program. The following qualifiers are currently supported:
Qualifier | Shorthand | Description |
---|---|---|
native | @ | Specifies that values should be written in native byte order; this is the default. |
little | < | Specifies that values should be written in little-endian order. |
big | > | Specifies that values should be written in big-endian order. |
errors | Specifies that compilation should be aborted on the first error. | |
warnings | Specifies that a warning message should be written on each error, without aborting the program; this is the default. | |
silent | Supresses all error output and ignores all errors. This is not recommended and provided only for completeness. |
Qualifiers can be associated with implicit types, too:
little i32 -1 big -2
Note that endianness specifiers, like types, are implicit in all subsequent statements unless explicitly changed.
little i32 -1 -2 // Equivalent to "little i32 -2".
So if you find it more intuitive to think of endianness qualifiers as large, blanket options, you might put them alone on a line at the start of the document.
little i32 1 2 3 4 5 6
Quoted Values
If a double-quoted string is given as a value, each character in that series is written as a value of the current type.
uint8 "Unsigned 8-bit characters." 0 // Null-terminated.
To insert a literal double quote, escape it with a backslash. The following characters have special meaning when prefixed with a backslash; all others, including backslash itself, are simply output literally.
Escape | Result | Number |
---|---|---|
\a | Alarm (BEL) | 7 |
\b | Backspace (BS) | 8 |
\f | Formfeed (FF) | 12 |
\n | Newline (LF) | 10 |
\r | Carriage Return (CR) | 13 |
\t | Horizontal Tab (HT) | 9 |
\v | Vertical Tab | 11 |
\" | Quote | 34 |
\\ | Backslash | 92 |
char "Quotes (\"\") and a backslash (\\)!"
Example
3D Model
Following is an example Protodata file containing a representation of a 3D model of a cube, consisting of a vertex count, vertex data, and face data, with each face linked to a named texture, and each vertex of each face linked to a vertex colour and texture coordinate.
// Vertices. uint32 8 single +1.0 +1.0 -1.0 +1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 +1.0 -1.0 +1.0 +1.0 +1.0 -1.0 +1.0 +1.0 -1.0 -1.0 +1.0 +1.0 -1.0 +1.0 // Back face. uint32 4 char "texture" 0 uint16 0; single 1.0 0.0 0.0; 1.0 0.0 uint16 1; single 1.0 0.0 0.0; 1.0 1.0 uint16 2; single 1.0 0.0 0.0; 0.0 1.0 uint16 3; single 1.0 0.0 0.0; 0.0 0.0 // Front face. uint32 4 char "texture" 0 uint16 4; single 0.0 1.0 0.0; 0.0 0.0 uint16 5; single 0.0 1.0 0.0; 1.0 0.0 uint16 6; single 0.0 1.0 0.0; 1.0 1.0 uint16 7; single 0.0 1.0 0.0; 0.0 1.0 // Right face. uint32 4 char "texture" 0 uint16 0; single 0.0 0.0 1.0; 0.0 0.0 uint16 4; single 0.0 0.0 1.0; 1.0 0.0 uint16 7; single 0.0 0.0 1.0; 1.0 1.0 uint16 1; single 0.0 0.0 1.0; 0.0 1.0 // Bottom face. uint32 4 char "texture" 0 uint16 1; single 1.0 1.0 0.0; 1.0 0.0 uint16 7; single 1.0 1.0 0.0; 1.0 1.0 uint16 6; single 1.0 1.0 0.0; 0.0 1.0 uint16 2; single 1.0 1.0 0.0; 0.0 0.0 // Left face. uint32 4 char "texture" 0 uint16 2; single 0.0 1.0 1.0; 1.0 1.0 uint16 6; single 0.0 1.0 1.0; 0.0 1.0 uint16 5; single 0.0 1.0 1.0; 0.0 0.0 uint16 3; single 0.0 1.0 1.0; 1.0 0.0 // Top face. uint32 4 char "texture" 0 uint16 4; single 1.0 0.0 1.0; 0.0 1.0 uint16 0; single 1.0 0.0 1.0; 0.0 0.0 uint16 3; single 1.0 0.0 1.0; 1.0 0.0 uint16 5; single 1.0 0.0 1.0; 1.0 1.0
Protodata is hosted on Sourceforge.net.