About Formal Specs
The Formal Specs are a method of describing the structure of any given lump. It describes the data using a sort of "map".
The map is a table which describes the format. It is 2 by x or 3 by x, where x can be any number. The optional first column is the "Offset", where the offset is from the start of the record or start of the file as appropriate, and is in INTs, not bytes. The next column is the "Data" column, which describes the type of data at any given point in the lump. The last column is the "Meaning" column, which is a short description of the data.
Data Types[edit]
For the purposes of the Formal Specs, the following data types will be used:
- BYTE: A single byte, combined to make other datatypes (0 to 255)
- INT: Two bytes, 16 bit signed integer (-32,768 - 32,767)
- LONG: Four bytes, 32 bit signed integer (-2,147,483,648 - 2,147,483,647)
- FLOAT: A 32 bit single precision number. Stored across two INTs
- ZSTR: A series of bytes terminated with a byte of value 0. No fixed length.
- VSTR: A composite type, consists of a value with the length of the string, and a series of bytes equal in length to the value. No fixed length. Datatype of values is specified by either (b) or (i) -- see below.
- FVSTR: A fixed length composite where the first value contains the length of the string, and the lowest byte of each value thereafter contains a character. It is padded with un-initialized bytes so that the whole field is a certain length, indicated by (hU+cU = lU) in the "Data" column (Note: size indicated includes the length value). Read with readbinstring$() if unit is b, or readbadbinstring$ if unit is 'i'.
- VLI: This is a Variable-Length Integer. Used in cases where a number is typically small, but can become large in certain cases. See below for more details.
- Records Start: Most lumps consist of 0 or more headers, plus a variable number of records after. This indicates the begining of the records.
The datatype of each element in a string is specified by a suffix. This suffix can be b (BYTE, 8bits) or i (INT, 16bits).
Example of the Formal Specs[edit]
[[About Formal Specs]] {| border="1" cellpadding="1" style="font-family:Courier New" ! Offset || Data || Meaning |- | colspan="3" | Records start (40 bytes) |- |0 || INT|| ID of plotscript |- |1 || VSTR (1i+b..)||Name of plotscript |}
About Formal Specs
Offset | Data | Meaning |
---|---|---|
Records start (40 bytes) | ||
0 | INT | ID of plotscript |
1 | VSTR (1i+b..) | Name of plotscript |
Variable Length Integer encoding[edit]
The format of a VLI is fairly simple, but you have to do some bit-twiddling.
Here is pseudo-code for reading a VLI:
negative := false ubyte := 0 ret := 0 read ubyte from file if ubyte & 64 != 0 then negative := true end if ret := ubyte & 63 if ubyte & 128 != 0 then ret := ret * 64 end if do while ubyte & 128 != 0 read ubyte from file ret := ret + ubyte & 127 if ubyte & 128 != 0 then ret := ret * 128 end if loop if negative then ret := ret * -1 end if return ret
And, writing it:
ubyte := 0 negative := false if number < 0 then negative := true number = number * -1 end if ubyte := number & 63 number := number / 64 if negative then ubyte := ubyte | &b1000000 end if if number > 0 then ubyte := ubyte | &b10000000 end if write ubyte to file do while number > 0 ubyte := number and 127 number := number / 128 if number > 0 then ubyte := ubyte | &b10000000 end if write ubyte to file loop