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:

TypeShorthand TypeDescription
charc A signed character.
ucharC An unsigned character.
shorth A signed short int.
ushortH An unsigned short int.
inti A signed int.
uintI An unsigned int.
longl A signed long int.
ulongL An unsigned long int.
floatf A single-precision floating-point number.
doubleF A double-precision floating-point number.
extendedx An extended-precision floating-point number.
int8i8 A signed 8-bit integer.
uint8I8 An unsigned 8-bit integer.
int16i16 A signed 16-bit integer.
uint16I16 An unsigned 16-bit integer.
int32i32 A signed 32-bit integer.
uint32I32 An unsigned 32-bit integer.
int64i64 A signed 64-bit integer.
uint64I64 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:

QualifierShorthandDescription
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.

EscapeResultNumber
\aAlarm (BEL)7
\bBackspace (BS)8
\fFormfeed (FF)12
\nNewline (LF)10
\rCarriage Return (CR)13
\tHorizontal Tab (HT)9
\vVertical Tab11
\"Quote34
\\Backslash92
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.

Protodata Project at SourceForge.net