The m4nfo User manual and Technical Report

newGRF Initialisation

Initialising a newGRF file

Each newGRF file needs an initialisation function, mainly to provide a unique newGRF-ID, besides supplying additional information, such as the newGRF's name, a short description text, the palette type used, version information, and (probably) parameter information.

This initialisation function must be included once per newGRF (i.e., not per file, in case of distributed source files), and it has to be one of the very first functions to be used in a newGRF. It is however valid to have a limited type of other functions before it (especially error functions or functions for flow of control), except those that define new sprites or feature properties.

Format

grfinit(<grf-ID>,<block>)

<block> ::= {grfdescription(<language-ID>,<String>) | grfminversion(<Dword>) | grfblitter(BPP8 | BPP32) | grfname(<language-ID>,<String>) | grfpalette(DOS | WINDOWS | ANY) | grfparameter(<param-block>) | grfurl(<language-ID>,"{"<String>"}") | grfversion(<Dword>)}

<param-block> ::= {grfsetting(<set-block>)}

<set-block> ::= {setdescription({<language-ID>,<String>}) | setname({<language-ID>,<String>}) | settype(BOOL | ENUM, <grf-parameter>,<bit>,<num-bits>) | setlimits(<Dword>,<Dword>) | setdefault(<Dword>) | setvalues(<menuvalue-block>)}

<menuvalue-block> ::= {menuvalue({<Dword>,<language-ID>,<String>})}

ElementSizeDescription
<grf-ID>LabelThe identification of this newGRF file
<language-ID>StringThe language ID of this particular text string
<grf-parameter>ByteA grf parameter (i.e. usually set as option in the newgrf.cfg file)

Function Description
grfinit(<grf-ID>,<block>)newGRF initialisation
   grfblitter(BPP8 | BPP32)Preferred blitter
grfdescription({<language-ID>,<String>})Description of newGRF
grfminversion(<Dword>)newGRF minimal version
grfname({<language-ID>,<String>})Name of newGRF
grfpalette(DOS | WINDOWS | ANY)Palette to be used
grfurl(<language-ID>,"{"<String>"}")Including an URL in the newGRF description
grfversion(<Dword>)Setting the newGRF version
grfparameter(<param-block>)Setting parameters for this newGRF
   grfsetting(<set-block>)Defining a parameter "setting"
   setdescription({<language-ID>,<String>})Defining a description text for a setting
setname({<language-ID>,<String>})Defining a name for a setting
settype(BOOL | ENUM, <grf-parameter>,<bit>,<num-bits>)Defining type and parameter mapping for a setting
setlimits(<Dword>,<Dword>)Min and max allowed value for integer/enumeration settings
setdefault(<Dword>)Default value for a setting
setvalues(<menuvalue-block>)Defines a block of "menuvalue" settings, see below.
 menuvalue({<Dword>,<language-ID>,<String>})Define text(s) displayed instead of values

Description

grfinit(<grf-ID>,<block>)

First parameter of the initialisation function is a label representing the newGRF's ID. It can be either written as a string (e.g., "mb12") or in hexadecimal notations (6D 62 31 32). By convention, it uses the first two characters for the creator's initials. The last two characters should be numbers, typically the first number identifying which of the author's sets this is, and the second number being a version number.

In principle, you are free what to use for the newGRF-ID as long as you are sure it is unique, but generally it is best to follow the above guidelines.

Note that newGRF-IDs starting with hex number 0xFF (i.e. the first byte being "FF", such as in FF123456) are reserved for internal purposes and should not be used by regular newGRF files. A newGRF-ID of FFFFFFFF is a special case for a newGRF file that is used for feature-specific TTDPatch graphics such as electrified railways or pre-signals. These newGRF files are always active and cannot be deactivated, and are marked with a blue flag in the GRF Status Window.

The extra newGRF file, part of OpenTTD base sets, have to have a newGRF-ID starting with FF "OT". The fourth letter may not be "W" nor "D" which are reserved for the openttdd.grf file. OpenGFX defines 01 for its extra newgrf.

grfminversion(<Dword>)

This function specifies the minimal version of newGRFs with the same newGRF-ID this newGRF is still compatible with. The minimal version has to be set after the newGRF's current version, and the minimal version has to be smaller or equal than the current version of the newGRF.

When loading a game which used an older version of the current newGRF which is no longer installed, the newest installed version of the newGRF in question, which is still compatible to the version used before, will be loaded. Older newGRFs are never considered compatible to newGRFs with a newer version number, though.

If the minimal version number is not set, the newGRF is only considered compatible to newGRFs with the same version number. If the minimal version number is set to 0, the newGRF is also considered compatible to old newGRFs without any version information.

grfpalette(DOS | WINDOWS | ANY)

This function specifies the palette the graphics sprites in the GRF are meant for: DOS, WINDOWS, or ANY in case the newGRF does not contain any sprites.

grfparameter(<param-block>)

This function describes how to specify information about newGRF parameters, and what "settings" are stored in them. By default, a newGRF comes with 128 settings, i.e. a DWORD for every of the 128 newGRF parameters. The number of used parameters is independant from the number of allowed newGRF parameters, as multiple settings might go into the same newGRF parameter, e.g. when using bit masks.

Variable "__parcount" might be referenced to get the number of parameters used. This might be helpful when working with distributed source files, and additional parameters are needed for internal use, e.g. to allocate memory for recolour tables. In these cases, parameter numbers above __parcount have to (and may be) used by simply exporting __parcount from the file containing the initialisation procedure (i.e. grfparameter()), and importing it by those files needing to allocate (or work with already alllocated) further parameters:

Exporting file:
grfinit(GRF_DBXL,
	...
	grfparameter(
		...
	)
)

export({__parcount})
Importing file:
import()
...
def(0x50, ET87GREEN) getcolour(0xB6)
def(0x51, ET87BEIGE) getcolour(0xB7)
def(0x52, ET87RED) getcolour(0xB8)
...
def(3) yearbuilt(
	ref(ET87GREEN) if(< 1932)       // green
	ref(ET87BEIGE) if(1932 .. 1949) // beige/red
	ref(ET87RED) else		// DB red
)

grfversion(<Dword>)

This function specifies the newGRF's version. It is then used (by OpenTTD) to internally order newGRFs with the same newGRF-ID. That order will determine which newGRF is loaded as "compatible" newGRF and which newGRFs to show in the newGRF list. By default each newGRF has version 0 if no grfversion() given.

If all newGRFs (with the same newGRF-ID) have version 0, all will be shown in the newGRF list. If the highest version is shared by multiple newGRFs, one is randomly chosen as "compatible" newGRF. Therefore, it is important to prevent releasing multiple newGRFs with the same version number.

When setting a version number, also grfminversion() should be set. Else this number will default to the version number, which results in the newGRF only being considered compatible to itself (resp. same version).

grfsetting(<set-block>)

This function specifies a parameter setting, s. functions below.

setdescription({<language-ID>,<String>})

This function specifies the parameter description, which is displayed when this parameter is selected in the parameter selection window (see picture). It is used to explain in detail the meaning and impact this parameter will have.

setname({<language-ID>,<String>})

This function sets a short description text for the parameter in question, to be shown in the parameter selection window.

settype(BOOL | ENUM, <grf-parameter>,<bit>,<num-bits>)

This function defines the parameter type and size. Possible values are: - integer (unsigned) or enumeration, - or boolean (on/off). Further parameters of this function specify the newGRF parameter mapping to be used:

If no first bit and/or number of bits are specified, the grfsetting() uses the whole newGRF parameter by default. If no settype() has been specified at all, the grfsetting() will use the newGRF parameter with the same number as the (implicit) setting number.

By using function settype(), newGRF parameters have to be specified sequentially, i.e. starting with parameter 0 and counting upwards. Any random parameter specification will corrupt m4nfo's internal use of newGRF parameters (e.g. for allocating recolour maps).

setdefault(<Dword>)

This function sets the default value for the current setting. In this way, the behaviour of the "reset" functionality in the parameter window changes. Unlike unsetting all parameters on reset, the parameter of a default setting is set to the given value (or to 0 in case no default is provided).

A "reset" happens when adding a newGRF to a configuration, or when the user presses the reset button in the parameter window.

menuvalue({<Dword>,<language-ID>,<String>})

This function defines text(s) to be displayed instead of the integer/enumeration values set by functions settype() and setlimits(). It is possible to specify text(s) only for some of the valid values. E.g., if a setting allows values in the range 0 .. 8, you might show "none" instead of "0" only, but handle other values unchanged.

Example (specifying text to display instead of raw enum values):
grfsetting(
	settype(ENUM,0,0,8) # grf_parameter 0 bits 0 .. 8
	setlimits(0,2)
	setdefault(1)
	setvalues(
		menuvalue(0,ALL,"low")
		menuvalue(1,ALL,"normal")
		menuvalue(2,ALL,"high")
	)
	setname(
		...
	)
)


Examples

Example 1 (French NG rail set initialisation, no parameters):
grfinit(GRF_FSRAILS,
	grfname(ALL,"French Rails Set Protoype v0.101 27/1/2012")
	grfdescription(ALL, UTF8 CRLF T_LGRAY "Custom track for OTTD railtypes." 0D
	"© 2011-2012 by Jacopo Coletto. All rights reserved.")
	grfpalette(DOS)
	grfversion(1)
	grfminversion(1)
)

Example 2 (NewStations initialisation, one parameter using string templating):
grfinit(GRF_NEWSTATIONS,
	grfname(ALL, "NewStations v0.50 12.12.2012")
	grfdescription(ALL,CRLF T_LGRAY A9 "2004 - 2012 Michael Blunck. All rights reserved." CRLF
	"Visit www.ttdpatch.de")
	grfurl(ALL,"http://www.ttdpatch.de")
	grfpalette(DOS)
	grfversion(1)
	grfminversion(1)
	grfparameter(
		grfsetting(
			settype(BOOL,0,0,1) # grf-parameter 0 bit 0 one bit
			setname(STR_PARAMETER)
			setdescription(STR_DESCRIPTION)
		)
	)
)

Example 3 (DBXL initialisation, 3 parameters):
grfinit(GRF_DBXL,
	grfname(ALL,"DB Set V0.90 (XL) 11.11.11")
	grfdescription(ALL, UTF8 CRLF T_LGRAY " © 2003 - 2012 Michael Blunck. All rights reserved." CRLF
	"Visit www.ttdpatch.de")
	grfurl(ALL, {"http://www.ttdpatch.de"})
	grfpalette(DOS)
	grfversion(1)
	grfminversion(0)
	grfparameter(
		grfsetting(
			settype(BOOL,0,0,1) # grf-parameter 0 bit 0 one bit
			setname(
				ALL, "No gates",
				D, "Keine Bahnschranken",
				...
			)
			setdescription(
				ALL,T_LGRAY "By default, the original level crossings are replaced by gates.",
				D, UTF8 T_LGRAY "Standardmässig werden die originalen Bahnübergänge durch Schranken ersetzt.",
				...
			)
		)
		grfsetting(
			settype(BOOL,0,1,1) # grf-parameter 0 bit 1 one bit
			setname(
				ALL, "Random livery for tankers",
				D, UTF8 "Zufällige Farbgebungen für Kesselwagen",
				...
			)
			setdescription(
				ALL, T_LGRAY "By default, all tankers of a train will be randomly chosen of the same colour.",
				D, UTF8 T_LGRAY "Standardmässig werden die Kesselwagen eines Zuges gleichartig zufällig gewählt.",
				...
			)
		)
		...
		grfsetting(
			settype(BOOL,0,5,1) # grf-parameter 0 bit 5 one bit
			setname(
				ALL, "Without DBRails",
				D, "Ohne DBRails",
				..
			)
			setdescription(
				ALL, T_LGRAY "The 'DBRails' track set is being de-activated.",
				D, T_LGRAY "Das 'DBRails' Gleis-Set wird deaktiviert.",
				...
			)
		)
	)
)