Railway Simulation BAHN 3.86r3 8/2012

Specification of Data Formats for User-defined and Zoom Graphics Data

Last recent changes: 2012-Aug-27

Valid for versions:

(Info about older versions deleted, for more see German original file T13GR.TXT incl. formats from BAHN 3.40, e.g. 16 colors with[out] transparency)


There is no warranty for the contents of this file. Changes are reserved.


Contents:

Changes

There follow the changes in reverse order.

Changes in BAHN 3.86b2
Changes in BAHN 3.86b1
Changes in BAHN 3.85r3
Changes in BAHN 3.85
Changes in BAHN 3.84
Changes in BAHN 3.83
Changes in BAHN 3.81

(although extended, no new data format has been defined, i.e. these data can be loaded by 3.59..3.80 and may look a bit crazy then).

Changes in BAHN 3.75Beta/BAHN 3.80

(although extended, no new data format has been defined, i.e. these data can be loaded by 3.59..3.70 and may look a bit crazy then).

Changes in B359Beta9
Changes in B359Beta8

General Information

Filenames and Extensions
Filename / ExtensionContents
xxxxx.nfz User-defined vehicle data Zoom1
xxxxx.ufg Vehicle graphics Zoom1 (old format)
xxxxx.uzz Vehicle set data Zoom1 (old format)
bahn.fz2 Standard vehicle archive Zoom2
bahn.fz4 Standard vehicle archive Zoom4
xxxxx.fzz Vehicle data Zoom2 (single file) (until 3.85Beta)
xxxxx.fz2 Vehicle data Zoom2 (single file) (from 3.85r1)
xxxxx.fz4 Vehicle data Zoom4 (single file)
xxxxx.fz2/.fz4 Vehicle data Zoom2/Zoom4 (archive file) (from 3.86Beta2)
bahn.fx1 Standard scenery archive Zoom1
bahn.fx2 Standard scenery archive Zoom2
bahn.fx4 Standard scenery archive Zoom4
xxxxx.gz1 Scenery and Driving way Zoom1 (single file)
xxxxx.gz2 Scenery and Driving way Zoom2 (single file)
xxxxx.gz4 Scenery and Driving way Zoom4 (single file)
xxxxx.uzg User-defined scenery archive Zoom1 (old format)
xxxxx.uz1 User-defined scenery archive Zoom1
xxxxx.uz2 User-defined scenery archive Zoom2
xxxxx.uz4 User-defined scenery archive Zoom4
bahn.gzg Driving way masks Zoom1+Zoom2 (old format, until BAHN 3.85r3)
bahn.fm1 Driving way masks archive Zoom1 (since BAHN 3.86)
bahn.fm2 Driving way masks archive Zoom2 (since BAHN 3.86)
bahn.fm4 Driving way masks archive Zoom4 (since BAHN 3.86)
bahn.fw1 Driving way add-on archive Zoom1
bahn.fw2 Driving way add-on archive Zoom2
bahn.fw4 Driving way add-on archive Zoom4

"xxxxx" is a placeholder for any name of a user-defined file. Some files are connected via their names, e.g. the pairs of .ufg/.uzz must have the same name, for instance "My_Cars.ufg" and "My_Cars.uzz" belong together. The same is with Zoom2/4 archives to .nfz files, e.g. "My_locos.fz2" may store the Zoom2 graphics to the vehicles of "My_locos.nfz".

In case of single files, the name consists of the archive name and some more added info, typically numbers and sometimes letters, e.g. "My_locos-00-01.fz2". You find more details about it here and in the BAHN Help at "Filenames" and "Single files" topics. The scheme of filenames for single files for scenery and ways was changed with BAHN 3.86Beta2.

until BAHN 3.70

Per layout, 4 .uzg files and 1 .ufg+.uzz file are possible. Filenames are DOS names according to 8.3-convention and DOS/OEM-coded.

since BAHN 3.80

Per layout, 10 .uzg and 8 .ufg+.uzz files are possible. Filenames are Windows32-compatible, i.e. long names are allowed. Coding is ANSI/Windows, depending on loaded fonts and Windows installation.

Names of .uzz files are stored no more, but created from the name of the respective .ufg file. E.g. for "abcd.ufg" the name of .uzz file must be "abcd.uzz". Texts stored inside the files remain DOS/OEM-coded.

since BAHN 3.81

Per layout, 40 .uzg and 40 .ufg+.uzz files are possible.

since BAHN 3.83

Instead of .ufg/.uzz combination, new .nfz files may be used. Per layout, 100 .nfz/.ufg+.uzz files are possible. Texts stored in .nfz and .fzz are coded Windows/ANSI (8 bit). Vehicles can get more details by using extra Zoom2 graphics.

since BAHN 3.84

Per layout, up to 100 .uzg files are possible.

since BAHN 3.85

Per layout, up to 110 .uzg files are possible. These can be replaced by .gz1 single files or by .uz1 packages. All have their own graphics. i.e. they are not mirrored. The number of elements per set is extended from 72 to 90. Each element can exist in 1, 2 or 4 versions depending on the BAHN co-ordinates. Vehicles and scenery can get more details by using extra Zoom2/Zoom4 graphics.

from here for all versions

Filenames of .uzg/.uz1 and .nfz/.ufg are stored in the .nt3 layout file. Multiple layout files can use the same graphics files. No path data are stored, i.e. the user-defined graphics files must stand in the same directory as the layout file. Changing of vehicle file names is possible only if that time no user-defined vehicles from this file are in use (but some may be installed).

File Header Text

All files begin with a text of unlimited length, terminated with Ctrl+Z character (26). It should consist of printable ASCI characters only (incl. CRLF). Recommended to store an information here about program and version that created/edited the file. Using the DOS command "TYPE" or similar, the text can be displayed correctly.

Data types and symbols, used in this documentation
SymbolMeaning
BYTE8 bit unsigned
WORD1616 bit unsigned (in LOBYTE-HIBYTE-sequence, if not said otherwise)
INT1616 bit signed (in LOBYTE-HIBYTE-sequence, if not said otherwise)
WORD3232 bit unsigned (from 2 WORD16 as LOWORD-HIWORD)
INT3232 bit signed (from WORD16 and INT16 as LOWORD-HIWORD)
CHAR1616 bit signed character coded in Unicode
[]Array of variable length (with an extra given terminator sign or an extra given length measure)
[n]Array of constant length (normally without end sign), n = Number (count) of elements
0x..Hexadecimal number (eg 0xFF = 255)
|Bitwise OR (non-exclusive)
&Bitwise AND
>>nShift-right by n bit, left filled with 0
<<nShift-left by n bit, right filled with 0
bppBit per Pixel (color depth)
a == ba is equal b
a != ba is not equal b
UNICODE_NULL= 0x0000
UNICODE_TAB= 0x0009
UNICODE_CR= 0x000d
UNICODE_LF= 0x000a
UNICODE_SPACE= 0x0020
UNICODE_HILO= 0xFeFf
UNICODE_LOHI= 0xFfFe

When loading user-defined data, not all data are completely checked for correct values (this would be impossible for some reason). In result, wrong data can cause program aborts or other bad results. Since version 3.58, wrong, changed or deleted vehicles are replaced by substitute data. That makes it possible to continue without error in many situations. However, you have to replace the substitute data by correct vehicles manually later. Wrong Zoom graphics are ignored and the standard data (scale 1:1) are used instead.

All gfx data from BAHN 3.59 to 3.81 use the 256-color-scheme.

Since 3.83, the 24bpp-scheme is used more and more.

Colors (24bpp/32bpp)

This is the standard color scheme since BAHN 3.83. It was first used in Zoom2 graphics for vehicles since BAHN 3.83Beta2 8/2004 and -optionally- for Zoom1 vehicles since 3.83Beta3 9/2004. It is also used for all file formats that have been defined later, e.g. the .nfz vehicle files, .gz1 scenery files and the respective Zoom2/4 files.

For each pixel a value of 32 bit length is needed. In BAHN it is called COLORREFRGB to distinguish from some COLORREF that is defined reverse, i.e. BGR instead of RGB.

typedef WORD32 COLORREFRGB

Meaning:

Basic Colors

A normal (basic) color is defined by Bit24..31 = 0. Any values of Bit0..23 are possible. The values define the daylight view. At night the basic colors are displayed as dark gray values (if day-night-switching is turned on), see night colors for details.

Macro for setting a COLORREFRGB value from single r,g,b:

#define GETRGB(r, g ,b) ((WORD32) (((BYTE) (b) | ((WORD16) (g) << 8)) | (((WORD32) (BYTE) (r)) << 16)))

Special Colors

Additional information / Logical colors / Light effects is always coded in Bit24..31. There are "Logical colors" (without own RGB values), and colors with additional info (with own RGB).

Mask for any additional information:

#define FARBE_ZUSATZ 0xFf000000

Logical Colors (Colors without RGB)

Logical colors do not have an own RGB value. The bits 0..23 are interpreted in a different way, e.g. as transparency or for replacing by a color that is defined elsewhere (use of configurable colors like "As background").

#define FARBE_LOGISCH 0x80000000

Transparent Color

#define FARBE_TRANSPARENT (FARBE_LOGISCH | 0x00000001)

This "color" has no effect, i.e. the background remains unchanged.

If there are only pixels of this color from deepest level to surface, then the background color is used. In case a background picture is assigned, then the background pixels are taken from this picture instead of the background color.

Half Transparent Color ("Behind Glass")

#define FARBE_HINTERGLAS (FARBE_LOGISCH)

Always changing the background as behind a glass (more dark+blue). When multiple overlapping, then no addition of this effect (that's unrealistic, but compatible with previous versions and faster)

The resulting color of the pixel (red, green, blue) is calculated as:

red = max( (red - GLASDIFF_ROT, 0 );
green = max( (green - GLASDIFF_GRUEN, 0 );
blue = max( (blue - GLASDIFF_BLAU, 0 );
#define GLASDIFF_ROT 70
#define GLASDIFF_GRUEN 50
#define GLASDIFF_BLAU 35

Configurable Colors

These colors are defined by the user in BAHN via "Options"-"Color Assignment". In result, on any computer they may look different, although there are defined default values.

Some of them are also generated by BAHN self, like background of grassy lines.

When drawing graphics, you don't know the RGB values that a user or BAHN really have set for background, text, rails, sleepers etc. However, maybe your graphics should include such areas or elements. Then, do not use "hard-coded" RGB values but the configurable colors instead. On output, BAHN replaces these colors by the currently set ones, incl. day-night-switching if needed.

#define FARBE_WIE_MIN (FARBE_LOGISCH | 0x00000100)
#define FARBE_WIE_MAX (FARBE_LOGISCH | 0x00000116) // since B386b1, before =_MIN
#define FARBE_WIE_ANZAHL (FARBE_WIE_MAX - FARBE_WIE_MIN + 1) // count of configurable colors

From BAHN VersionNameValueRGB (Default, Daylight)Appearance / Used for
AllFARBE_WIE_HGR(FARBE_LOGISCH | 0x00000100) surface: 0, (28<<2), 0
levels below: 60, 60, 60
Variable Background Color, depending on level (surface or below)
3.86Beta1FARBE_WIE_SCHWELLEN0(FARBE_LOGISCH | 0x00000101) 188, 188, 188 as sleepers 0, default: gray (concrete)
3.86Beta1FARBE_WIE_SCHWELLEN1(FARBE_LOGISCH | 0x00000102) 84, 40, 0 as sleepers 1, default: dark brown (wooden)
3.86Beta1FARBE_WIE_SCHWELLEN3(FARBE_LOGISCH | 0x00000103) 84, 40, 0 as sleepers 3 (local line), default: dark brown (wooden)
3.86Beta1FARBE_WIE_GLSTR0(FARBE_LOGISCH | 0x00000104) 168, 168, 168 as rails on road 0, default: gray
3.86Beta1FARBE_WIE_GLSTR1(FARBE_LOGISCH | 0x00000105) 60, 60, 60 as rails on road 1, default: gray
3.86Beta1FARBE_WIE_GLSTR2(FARBE_LOGISCH | 0x00000106) 168, 168, 168 as rails on road 2, default: gray
3.86Beta1FARBE_WIE_GLSTR3(FARBE_LOGISCH | 0x00000107) 104, 104, 104 as rails on road 3, default: gray
3.86Beta1FARBE_WIE_GLBBK0(FARBE_LOGISCH | 0x00000108) 104, 104, 104 as rails on own trackbed 0, default: gray
3.86Beta1FARBE_WIE_GLBBK1(FARBE_LOGISCH | 0x00000109) 148, 148, 148 as rails on own trackbed 1, default: gray
3.86Beta1FARBE_WIE_GLBBK2(FARBE_LOGISCH | 0x0000010A) 148, 148, 148 as rails on own trackbed 2, default: gray
3.86Beta1FARBE_WIE_GLBBK3(FARBE_LOGISCH | 0x0000010B) 104, 104, 104 as rails on own trackbed 3, default: gray
3.86Beta1FARBE_WIE_MKBUS0(FARBE_LOGISCH | 0x0000010C) 252, 252, 252 marking points for bus on road 0, default: white
3.86Beta1FARBE_WIE_MKBUS1(FARBE_LOGISCH | 0x0000010D) 252, 252, 252 marking points for bus on road 1, default: white
3.86Beta1FARBE_WIE_MKBUS2(FARBE_LOGISCH | 0x0000010E) 252, 252, 252 marking points for bus on road 2, default: white
3.86Beta1FARBE_WIE_MKBUS3(FARBE_LOGISCH | 0x0000010F) 252, 252, 252 marking points for bus on road 3, default: white
3.86Beta1FARBE_WIE_MKH2O(FARBE_LOGISCH | 0x00000110) 84, 252, 252 marking points for ships on water, default: light turkey blue
3.86Beta1FARBE_WIE_SCHOTTER(FARBE_LOGISCH | 0x00000111) mixed (see BAHN Color Settings) as gravel stones, default: mix brown/gray
3.86Beta1FARBE_WIE_KIES(FARBE_LOGISCH | 0x00000112) mixed (generic) as small gravel stones / sand, default: mix brown/gray/yellow
3.86Beta1FARBE_WIE_GRASHALM(FARBE_LOGISCH | 0x00000113) mixed (generic) as grassy, default: mix green/gray/yellow
3.86Beta1FARBE_WIE_FELDWEG(FARBE_LOGISCH | 0x00000114) mixed (generic) as path, background, default: mix green/brown/gray/yellow
3.86Beta1FARBE_WIE_FELDWEG(FARBE_LOGISCH | 0x00000115) mixed (generic) as path, foreground (tracks), default: mix brown/yellow
3.86Beta1FARBE_WIE_TEXTVG(FARBE_LOGISCH | 0x00000116) 252, 252, 252 as text in the layout, foreground, default: white

The colors introduced with BAHN 3.86 are used in files:
vehicles: from format=ZOOMXFZGFORMAT385, subformat=ZOOMXFZGSUBFORMAT5
.gzn files: from format=ZOOMXGZGFORMAT384, subformat=ZOOMXGZGSUBFORMAT5

Before, there was only defined the background color and only for scenery graphics, i.e. not for vehicles. Even now, it seems not to make sense to use these colors for vehicles.

Special Colors with Own RGB Value

Mask for colors with any light effect:

#define FARBMASK_LICHTEFFEKT 0x70000000

Light Colors

#define FARBE_IMMERHELL 0x40000000

These colors are ignored by the day-night-switching. The RGB value is valid always, also at night. They are used e.g. for signal lamps, advertising, LED matrix tables.

Lamp Colors

#define FARBE_LAMPE 0x50000000
#define FARBE_LAMPE_MIN 0
#define FARBE_LAMPE_MAX 4 // since B386b0e, before =1
#define FARBE_LAMPE_ANZAHL (FARBE_LAMPE_MAX-FARBE_LAMPE_MIN+1) // count of lamp colors

Lamps have an own day-night-switching:
The RGB value is valid at daylight (as long lamp is turned off). At night, fixed values are used instead (see below). Used e.g. for front/rear lamps of vehicles, road lamps, signs.

From BAHN VersionNameValueRGB (Lighting)Appearance / Used for
AllFARBE_LAMPE_GELB(FARBE_LAMPE | 0x00000000) (63<<2),(63<<2),(42<<2) white-yellow (front lamp of vehicles)
AllFARBE_LAMPE_ROT(FARBE_LAMPE | 0x01000000) (63<<2),(12<<2),(5<<2) red (rear lamp of vehicles)
3.86Beta0eFARBE_LAMPE_KALTWEISS(FARBE_LAMPE | 0x02000000) 223, 241, 255 cold white with a bit blue (front lamp of vehicles, LED)
3.86Beta0eFARBE_LAMPE_GELBWEISS(FARBE_LAMPE | 0x03000000) 214, 170, 20 yellow, darker than _GELB (el. bulb with low voltage)
3.86Beta0eFARBE_LAMPE_GAS_GELB(FARBE_LAMPE | 0x04000000) 208, 192, 20 yellow with a bit green (gas light)

The colors introduced with BAHN 3.86 are used in files:
vehicles: from format=ZOOMXFZGFORMAT385, subformat=ZOOMXFZGSUBFORMAT5
.gzn files: from format=ZOOMXGZGFORMAT384, subformat=ZOOMXGZGSUBFORMAT5

Window Colors

These colors have a RGB value but a special day-night-switching:
RGB is valid as long windows do not shine (at daylight and sometimes at night). Used e.g. for windows in vehicles and buildings. If light is turned on, then fixed values are used.

The colors are combined of the mask FARBE_FENSTER, a mask defining the time and a mask defining the color.

Definition of time:

#define FARBE_FENSTER 0x60000000
#define FARBE_FENSTER_0 (FARBE_FENSTER | 0x00000000)
#define FARBE_FENSTER_1 (FARBE_FENSTER | 0x01000000)
#define FARBE_FENSTER_2 (FARBE_FENSTER | 0x02000000)
#define FARBMASK_FENSTER_ZEIT (FARBE_FENSTER | 0x03000000)

Definition of color:
Yellow:

#define FARBE_FENSTER_GELB (FARBE_FENSTER | 0x00000000)

"Neon" (blue):

#define FARBE_FENSTER_NEON (FARBE_FENSTER | 0x04000000)
#define FARBMASK_FENSTER_FARBE (FARBE_FENSTER | 0x0C000000)

Color values (RGB) for night color (shining) of windows:
Yellow version:

#define FFARBE_G_NACHTS_ROT (44<<2)
#define FFARBE_G_NACHTS_GRUEN (36<<2)
#define FFARBE_G_NACHTS_BLAU (0)

"Neon" version:

#define FFARBE_B_NACHTS_ROT (40<<2)
#define FFARBE_B_NACHTS_GRUEN (43<<2)
#define FFARBE_B_NACHTS_BLAU (39<<2)

Packing of Colors (24bpp/32bpp)

In files, the color data may be packed in a simple way, resulting in shorter and variable length of data.

The decompressing as given here shows how to interpret a value read from a file or buffer. You need to insert this into a loop, running for width * height or for size in pixels.

Unpacking of Colors BAHN 3.83-3.85

This algorithm is used for vehicles with
Format, Subformat < ZOOMXFZGFORMAT385, ZOOMXFZGSUBFORMAT5

and for scenery/way graphics with
Format, Subformat < ZOOMXGZGFORMAT384, ZOOMXGZGSUBFORMAT5

#define FARBE_KOMPRIMIERT (FARBE_LOGISCH | 0x40000000)
#define FARBMASK_KOMPR_TR 0x00010000
#define FARBE_KOMPR_TR (FARBE_KOMPRIMIERT | FARBMASK_KOMPR_TR)
#define FARBMASK_KOMPR_ZAHL 0x000000Ff
#define MAX_FARB_WDH 257

 INT32  count;
 WORD32 w32;  // i.e. COLORREFRGB
 COLORREFRGB color;

  (loop)
 
  w32 = ReadWord32(); /* read next value from file */
  if ( (w32 & FARBE_ZUSATZ) == FARBE_KOMPRIMIERT )
     /* packed, more than 1 pixel */
    {
     /* Bit7..0 contain number of loops minus 2, ie 0..255 for 2..257 */
     count = ( w32 & FARBMASK_KOMPR_ZAHL ) + 2;

     if ( w32 & FARBMASK_KOMPR_TR )
       {
        /* this color is needed more than any other... */
        color = FARBE_TRANSPARENT;
       }
     else /* color in next value from file */
       {
        color = ReadWord32();
       }
    }
  else /* not packed, single pixel */
    {
     count = 1;
     color = w32;
    }

This results in color and count, where count represents the number of pixels of the same color, following each other. At end of lines resp. columns, the packing may continue. At end of each view (when more than one, e.g. for vehicles), the packing is broken.

Unpacking of Colors since BAHN 3.86

This algorithm is used for vehicles with
Format, Subformat >= ZOOMXFZGFORMAT385, ZOOMXFZGSUBFORMAT5

and for scenery/way graphics with
Format, Subformat >= ZOOMXGZGFORMAT384, ZOOMXGZGSUBFORMAT5

There was added the possibility to repeat a short block of colors instead of a single color. Further, the view is started with an info about the total length of data. This may be used for test purposes, or to store all the data to a temporary memory block first.

#define FARBE_KOMPRIMIERT (FARBE_LOGISCH | 0x40000000)
#define FARBMASK_KOMPR_TR 0x00010000
#define FARBE_KOMPR_TR (FARBE_KOMPRIMIERT | FARBMASK_KOMPR_TR)
#define FARBMASK_KOMPR_SYS 0x00040000
#define FARBE_KOMPR_SYS (FARBE_KOMPRIMIERT | FARBMASK_KOMPR_SYS)
#define FARBMASK_KOMPR_SFB 0x0000ff00
#define FARBMASK_KOMPR_ZAHL 0x000000Ff
#define MAX_FARB_WDH 257 // max. count of repeats
#define FARBMASK_KOMPR_LEN 0x0000Ff00
#define MAX_FARBFOLGE_LEN 4 // max. length of a color repetition block (possible up to 256 but packing would become slower then)

 INT32  viewlen, count, wdhlen, i;
 WORD32 w32, f;  // i.e. COLORREFRGB
 COLORREFRGB color[MAX_FARBFOLGE_LEN];

  viewlen = ReadInt32(); // Length of packed data in COLORREFRGB, see remark above

  (loop)
  
  w32 = ReadWord32(); // read next value from file or from buffer
  if ( (w32 & FARBE_ZUSATZ) == FARBE_KOMPRIMIERT )
     // packed, more than 1 pixel
    {
     // Bit7..0 contain number of loops minus 2, ie 0..255 for 2..257
     count = ( w32 & FARBMASK_KOMPR_ZAHL ) + 2;

     if ( w32 & FARBMASK_KOMPR_TR )
       {
        // this "color" is needed more than any other...
        color[0]  = FARBE_TRANSPARENT;
        wdhlen = 1;
       }
     else
       {
        if ( w32 & FARBMASK_KOMPR_SYS )
          {
           // this color is not RGB but a configurable color
           color[0]  = (( w32 & FARBMASK_KOMPR_SFB ) >> 8 ) + FARBE_WIE_MIN;
           wdhlen = 1;
          }
        else
          {
           wdhlen = (( w32 & FARBMASK_KOMPR_LEN ) >> 8 ) + 1;
           wdhlen = min( wdhlen, MAX_FARBFOLGE_LEN ); // for security, but otherwise you should cancel here
           // there follows a number of RGB colors
           for ( i = 0; i < wdhlen; i++ )
             {
              f = ReadWord32();
              color[i] = f;
             }
          }          
       }
    }
  else /* not packed, single pixel */
    {
     count    = 1;    
     wdhlen   = 1;
     color[0] = w32;
    }

This results in count, wdhlen and color[wdhlen]. The color block color[wdhlen] stores the colors, and count represents the number of repetitions of the color block, following each other. At end of lines resp. columns, the packing may continue. At end of each view (when more than one, e.g. for vehicles), the packing is broken.

Night Colors

This section describes the handling of basic colors at night and while dawn and dusk. Some special colors remain unchanged and some have extra defined constant values at night (e.g. lamps and windows). For both see 24/32bpp-colors and 256-colors.

At Night

At night, the red, green and blue values are equal, resulting in a gray scale for all colors. The color is calculated from the daylight values as:

  {
   nw = ( red + green + blue ) / 8;

   RGBColor = GETRGB( nw, nw, nw );
  }
Dawn and Dusk
ZeitDiff = Length of dawn/dusk in minutes
ZeitLoc  = Current position inside ZeitDiff (0..ZeitDiff-1)

  {
   nw = see above (same value as at night)
   
   redloc = ( ZeitLoc * ( red - nw )) / ZeitDiff;
   greenloc = ( ZeitLoc * ( green - nw )) / ZeitDiff;
   blueloc = ( ZeitLoc * ( blue - nw )) / ZeitDiff;

   if ( Dawn )
     {
      red = max( nw + redloc, 0 );
      green = max( nw + greenloc, 0 );
      blue = max( nw + blueloc, 0 );
     }
   else /* Dusk */
     {
      red = max( red - redloc, 0 );
      green = max( green - greenloc, 0 );
      blue = max( blue - blueloc, 0 );
     }

   RGBColor = GETRGB( red, green, blue );
  }

Color Palette (256 colors)

This was the standard color system of BAHN 3.59 to BAHN 3.81. Some of the BAHN standard graphics data files still used this scheme partially until including BAHN 3.85. It is also used for some older user-defined data.

All values for color parts (red, green, blue) are calculated for a 16-bit-color controler (DAC). Valid values are 0..63 for each. For the red and blue values, the Bit0 is dont-care.

For calculating the corresponding values for 24bpp, multiply each with 4 (or shift left by 2). This is needed e.g. for palette data in PCX files, or in the 24bpp data format of newer BAHN versions. Doing so, causes minor errors, e.g. white = (63,63,63) results in (252,252,252) instead of (255,255,255).

The first 16 palette values are the same of the former 16-color-palette as used until BAHN 3.58 (VGA standard palette, but a few colors changed for BAHN).

You should use the colors only that are documented as follows. BAHN internally uses some more, but not as input data.

Special Colors

Code for transparent color (i.e. the background remains unchanged):

#define FARBE_TRANSPARENT 255

Code for "half"transparent color (since BAHN 3.75):

#define FARBE_GLAS 254

"halftransparent" means the background is changed as behind a glass. The resulting color of the pixel is calculated as:

#define GLASDIFF_ROT 70
#define GLASDIFF_GRUEN 50
#define GLASDIFF_BLAU 35
red = max( (red<<2) - GLASDIFF_ROT, 0 );
green = max( (green<<2) - GLASDIFF_GRUEN, 0 );
blue = max( (blue<<2) - GLASDIFF_BLAU, 0 );

Code for variable background color (available since BAHN 3.75Beta8e):
only defined for scenery graphics, do not use for vehicles

#define DATEIFARBE_HINTERGRUND 253

Basic Colors

These are the normal colors used for scenery, buildings, vehicles (with day-night-switching, inside of dialog windows always as daylight color).

The names and values do not apply to any standard, i.e. they are BAHN specific.

#define FARBE_MIN 0
#define FARBE_MAX 59 (until BAHN 3.70 incl.)
#define FARBE_MAX 61 (since BAHN 3.75)
#define FARBE_MAX 62 (since BAHN 3.81Beta1)

From BAHN VersionNameValueRGBAppearance / Used for
3.40FARBE_SCHWARZ00,0,0 black
3.40FARBE_DUNKELBLAU10,0,42 dark blue
3.40FARBE_DUNKELGRUEN20,42,0 dark green
3.40FARBE_TUERKIS30,42,42 turkey
3.40FARBE_DUNKELROT442,0,0 dark red
3.40FARBE_HELLBRAUN542,34,0 light brown (different from standard VGA)
3.40FARBE_BAHN_GRUEN60,28,0 former background color, looks same as standard background color (different from standard VGA)
3.40FARBE_HELLGRAU742,42,42 light gray
3.40FARBE_DUNKELGRAU821,21,21 dark gray
3.40FARBE_HELLBLAU921,21,63 light blue
3.40FARBE_HELLGRUEN1021,63,21 light green
3.40FARBE_HELLTUERKIS1121,63,63 light turkey
3.40FARBE_HELLROT1263,21,21 light red
3.40FARBE_ORANGE1363,40,0 orange (different from standard VGA)
3.40FARBE_GELB1463,63,21 yellow
3.40FARBE_WEISS1563,63,63 white
3.59FARBE_CREME1663,61,35 cream, German "elfenbein"
3.59FARBE_OCKER1755,47,12 "Yellow" (dark, more brown, e.g. Berlin S-Bahn, Ikarus buses)
3.59FARBE_DUNKELBRAUN1831,9,0 dark brown (more red, e.g. older freight cars DR)
3.59FARBE_SCHWARZGRAU1915,15,15 very dark gray
3.59FARBE_MITTELGRAU2031,31,31 middle gray
3.59FARBE_WEISSGRAU2147,47,47 white gray
3.59FARBE_SCHWARZGRUEN220,23,0 "black green", very dark green
3.59FARBE_MITTELROT2352,10,10 middle red
3.59FARBE_SCHWARZBRAUN2421,10,0 very dark brown, e.g. for wooden sleepers
3.59FARBE_CREMEWEISS2563,63,49 cream white (more light than FARBE_CREME)
3.59FARBE_LILA2642,0,42 violet (original EGA/VGA color #5)
3.59FARBE_MITTELBLAU2715,15,52 middle blue, e.g. DB coaches and locos 1970ies
3.59FARBE_DR_GRUEN285,32,5 green between dark green and black green, e.g. older DR coaches
3.59FARBE_FF_xxx29..32see below 29..32 are equivalent to window colors (see below).
They do not light at night.
3.59FARBE_FF_DUNKEL293,11,33 dark turkey blue (also available as window color)
3.59FARBE_FF_MITTEL3017,31,31 middle turkey blue (also available as window color)
3.59FARBE_FF_HELL3127,42,42 light turkey blue (also available as window color)
3.59FARBE_FF_BRAUN3222,15,5 dark brown (also available as window color)
3.59FARBE_MVB_GRUEN3315,33,25 green/gray (Magdeburg modernized Tatra trams, some locos)
3.59FARBE_MITTELGRUEN3410,52,10 middle green
3.59FARBE_GELBORANGE3561,53,0 dark yellow
3.59FARBE_GRAUROT3642,20,20 typical Chemnitz road material [granite stones]
3.59FARBE_ROSA3755,32,32 pig pink (old DB IC coaches stripe between red and white)
3.59FARBE_BETONGRAU3837,37,30 concrete road / sleepers
3.59FARBE_MITTELBRAUN3939,13,0 middle brown, newer freight cars DR and others
3.59FARBE_DUNKELWEISS4055,55,55 dark white
3.59FARBE_GRAUGRUEN4125,38,25 gray green, e.g. some ČSD/ČD/ŽSR/PKP/RŽD el.locos
3.59FARBE_GRUENSCHWARZ420,16,0 green black, e.g. some ČSD/ČD/ŽSR/PKP/RŽD el.locos
3.59FARBE_DUNKELORANGE4363,27,3 middle orange (e.g. some MÁV DMU+locos)
3.59FARBE_MITTELHELLROT4459,10,0 middle light red (e.g. DB "verkehrsrot"[="traffic red"])
3.59FARBE_HELLGRUENGRAU4533,52,44 light gray green (e.g. some PKP el. locos)
3.59FARBE_DUNKELBRAUNGRAU4626,24,18 dark gray brown
3.59FARBE_GRAUBLAU4727,36,42 gray/silver blue, e.g. some FS el. locos
3.59FARBE_MITTELTUERKIS4811,52,52 middle turkey
3.59FARBE_HELLLILA4960,20,60 light violet
3.59FARBE_MITTELHELLBLAU5025,38,63 middle light blue
3.59FARBE_DUNKELORANGE5151,25,0 dark orange
3.59FARBE_DUNKELLLILA5225,0,38 dark violet
3.59FARBE_HELLBRAUNGRAU5351,48,42 light brown gray
3.59FARBE_SCHWARZBRAUNGRAU5413,13,0 black brown gray
3.59FARBE_WEISSBLAU5550,51,59 white blue
3.59FARBE_DUNKELGRUENBLAU560,25,38 dark green blue
3.59FARBE_HELLGRUENBLAU570,38,51 light green blue
3.59FARBE_MITTELDUNKELGRAU5826,26,26 middle dark gray
3.59FARBE_MITTELGELB5962,58,11 middle yellow
3.75FARBE_KAKAOBRAUN6046,37,30 cacao brown
3.75FARBE_MITTELHELLGRAU6137,37,37 middle light gray
3.81FARBE_BASEL_GRUEN623,37,3 green, e.g. Basel trams

The RGB values given before are the values for daylight. For calculation of night values see Night colors and do not forget to multiply the Red, Green and Blue values by 4.

Light Colors

These colors are always lighting, without day-night-switching.

Use them for lamps that shine alltimes: Signals, lamps at metros, advertising and other light tables and signs.

From BAHN VersionNameValueRGBAppearance / Used for
3.59LFARBE_GRUEN6415,59,31 light green (a few blue)
3.59LFARBE_ROT6563,15,20 light red (a few blue)
3.59LFARBE_GELB6663,57,19 yellow (a few red)
3.59LFARBE_WEISS6763,63,59 white (a few yellow)
3.59LFARBE_BLAU6819,23,61 blue (a few green)
3.59LFARBE_ORANGE6963,45,5 orange
Lamp Colors

At night, these colors appear yellow-white resp. red, over the day gray/red. Inside of dialog windows they are set to a similar basic color.

Use them for the lamps as front/rear lights of vehicles.

From BAHN VersionNameValueRGBAppearance / Used for
3.59LNFARBE_GELB_DUNKELGRAU7518,18,18 dark gray (front lamp, at night yellow-white)
3.59LNFARBE_GELB_HELLGRAU7639,39,39 light gray (front lamp, at night yellow-white)
3.59LNFARBE_ROT_DUNKELROT7749,8,8 middle red (rear lamp, at night red)
3.59LNFARBE_ROT_DUNKELGRAU7823,18,18 dark gray (rear lamp, at night red)

Night values for the lamps (RGB parts for each):
Yellow-white:

#define LNFARBE_GELB_NACHTS_ROT 63
#define LNFARBE_GELB_NACHTS_GRUEN 63
#define LNFARBE_GELB_NACHTS_BLAU 42

Red:

#define LNFARBE_ROT_NACHTS_ROT 63
#define LNFARBE_ROT_NACHTS_GRUEN 12
#define LNFARBE_ROT_NACHTS_BLAU 5

Window Colors

These colors shine yellow or blue ("neon") at night (the whole night or some time).

Use them for windows of buildings and vehicles that shine because there may be a lamp behind the window.

These colors also are available as basic colors with day-night-switching for windows that never shine, for RGB see FARBE_FF_DUNKEL.
So you can mix windows that look exactly the same at daylight, but at night some of them shine while others are dark.

80ff: Window colors that shine yellow the whole night

#define FFARBE_G0_MIN 80
#define FFARBE_G0_MAX 83
#define FFARBE_G0_DUNKEL 80// dark
#define FFARBE_G0_MITTEL 81// middle
#define FFARBE_G0_HELL 82// light
#define FFARBE_G0_BRAUN 83// brown

85ff: Window colors that shine yellow at evening and before morning, suitable for buildings; also for railways coaches for single compartments (RGB values equivalent to FARBE_FF_DUNKEL.. and FFARBE_G0_DUNKEL...)

#define FFARBE_G1_MIN 85
#define FFARBE_G1_MAX 88
#define FFARBE_G1_DUNKEL 85
#define FFARBE_G1_MITTEL 86
#define FFARBE_G1_HELL 87
#define FFARBE_G1_BRAUN 88

90ff: Window colors that shine yellow at evening and before morning (but times differing from FFARBE_G1_xxx)
suitable for buildings; also for railways coaches for single compartments (RGB values equivalent to FARBE_FF_DUNKEL.. and FFARBE_G0_DUNKEL...)

#define FFARBE_G2_MIN 90
#define FFARBE_G2_MAX 93
#define FFARBE_G2_DUNKEL 90
#define FFARBE_G2_MITTEL 91
#define FFARBE_G2_HELL 92
#define FFARBE_G2_BRAUN 93

100ff: Window colors that shine blue ("neon") the whole night

#define FFARBE_B0_MIN 100
#define FFARBE_B0_MAX 103
#define FFARBE_B0_DUNKEL 100
#define FFARBE_B0_MITTEL 101
#define FFARBE_B0_HELL 102
#define FFARBE_B0_BRAUN 103

105ff: Window colors that shine blue ("neon") at evening and before morning, suitable for buildings; also for railways coaches for single compartments (RGB values equivalent to FARBE_FF_DUNKEL.. and FFARBE_G0_DUNKEL...)

#define FFARBE_B1_MIN 105
#define FFARBE_B1_MAX 108
#define FFARBE_B1_DUNKEL 105
#define FFARBE_B1_MITTEL 106
#define FFARBE_B1_HELL 107
#define FFARBE_B1_BRAUN 108

110ff: Window colors that shine blue ("neon") at evening and before morning (but times differing from FFARBE_G1_xxx) suitable for buildings; also for railways coaches for single compartments (RGB values equivalent to FARBE_FF_DUNKEL.. and FFARBE_G0_DUNKEL...)

#define FFARBE_B2_MIN 110
#define FFARBE_B2_MAX 113
#define FFARBE_B2_DUNKEL 110
#define FFARBE_B2_MITTEL 111
#define FFARBE_B2_HELL 112
#define FFARBE_B2_BRAUN 113

Color values (RGB) for night color (shining) of windows
Yellow version:

#define FFARBE_G_NACHTS_ROT 44
#define FFARBE_G_NACHTS_GRUEN 36
#define FFARBE_G_NACHTS_BLAU 0

"Neon" version:

#define FFARBE_B_NACHTS_ROT 40
#define FFARBE_B_NACHTS_GRUEN 43
#define FFARBE_B_NACHTS_BLAU 39

Scenery Elements, Driving Way Elements, Signals (.gz1)

This is available since BAHN 3.85Beta0 9/2008 for scenery elements and driving way add-ons. Later it was extended to user-defined signals and with BAHN 3.86 to user-defined driving ways.

General Data

This section is valid for both standard and user-defined scenery. Also, the scenic add-ons of driving way elements are included, i.e. the parts that are not rails, sleepers, gravel or marking points of configurable colors, but "normal" graphics like any signs, platforms or signals. Further, the user-defined signals are included (introduced with 3.85Beta3).

A ".gz1" file holds the graphics data for exactly one element. In case of an element that exists in multiple variants or phases (like signals or animations), it holds exactly one of them.

Some standard driving way elements are combined from multiple .gz1 files: One for the way self, one for the add-on graphics and one for the platform.
The way self contains road, rails, sleepers, gravel, marking points, water etc.
The add-on contains signs, platforms, signals etc.
User-defined signals are add-ons in this sense and are always combined with a way element.

The file format is made for multi-purpose. Depending on the usage of a certain element, some properties do not make sense and are ignored.

Co-Ordinates

#define SYMBREITE 32 // basic element width in pixels for scale 1:1
#define SYMHOEHE 16 // basic element height in pixels for scale 1:1
#define MAXSYMHOEHE (6*SYMHOEHE) // max. "height" to North (upwards)

One element is a static object that can be placed in the layout at any valid position (nx,ny,nz). In BAHN, such a position is represented by SYMBREITE * SYMHOEHE pixels in 1:1 scale, or more in scales 2:1 and higher.
However, the element can be larger: It can overlap its neighbours to South (SYMHOEHE pixels), West and East (SYMBREITE pixels each) and North (MAXSYMHOEHE pixels).
The BAHN world is only two-dimensional, so in result "North" means "upwards" for many objects. However, this "upwards" is not displayed to the next upper level of BAHN layout co-ordinates (nz+1).

"The element self" (or basic element) is limited by co-ordinates x from 0 to SYMBREITE-1 and y from 0 to SYMHOEHE, where the 0,0 position is the lower left corner. To the left (West) and down (South) we find negative co-ordinates.

Layers

Maximum count of layers per element:

#define GSYMTEIL_MAXZAHL 3 // until BAHN 3.86Beta0c
#define GSYMTEIL_MAXZAHL 4 // since BAHN 3.86Beta0d (from format=ZOOMXGZGFORMAT384, subformat=ZOOMXGZGSUBFORMAT5)

The graphics of an element can consist of up to GSYMTEIL_MAXZAHL layers. This defines a kind of z co-ordinate. In case of overlapping with other elements and trains, the layer defines the order of display. Each layer has assigned one of the GFX_Z_nn values (see below).

For one element there can exist multiple layers that have assigned the same GFX_Z_nn value. In this case, the order of the data causes the order of drawing each onto the other. The BAHN integrated editor assigns the layers in a less flexible way than the data format allows.

Layers in gz1 graphics (see BAHN Help for more details)
VersionNameValueMeaning
AllGFX_Z_HI1 to background (=flat, not "upwards", i.e. platforms)
AllGFX_Z_VG2 foreground (in front of driving way and train)
AllGFX_Z_HG3 background (also behind train on ny+1)
AllGFX_Z_OG4 front (covers anything here on ny), but is covered by Z_HI/Z_HG from ny+1
(used especially for bridges 45 degrees)
>=3.85Beta1GFX_Z_VGO5 foreground above (in front of driving way and train same as _Z_VG, but also overlapping anything that is coming upwards from ny+1
(use e.g. for overhead wires)
AllGFX_Z_MIN1 The minimum value
<3.85Beta1GFX_Z_MAX4 The maximum value
>=3.85Beta1GFX_Z_MAX5 The maximum value

For standard driving way elements, the layers are interpreted a bit different: GFX_Z_VG and GFX_Z_HG are used and are handled both as background. In result, it is possible to have a total number of more than GSYMTEIL_MAXZAHL layers in combination with a driving way add-on element. That was needed as long GSYMTEIL_MAXZAHL was limited to 3, but today it is more useful for optimizations.

Further, the addition of platforms is hard-coded for the most standard driving ways as copy from the simple "way + platform" elements. In result, changing the simple platform causes a change of all elements using the same platform, e.g. stopping points, turnouts or signals. On the other hand, we need less memory to store it, and the GSYMTEIL_MAXZAHL limit can be overidden.

Variants (Scenic elements only)

Any scenic element can exist in up to 4 variants. The idea is that one and the same object should be a bit different when used multiple.

Since many years, this is used in BAHN for some trees: If you set one tree into the layout and the same as the neighbour, then it may look different. The same can be used for a building with windows or advertising signs that shows different lights.

For each variant, there must exist an own ".gz1" file.

BAHN does not select the variants at random, but depending on the position in the layout:

  1. nx even, ny even: "a" position
  2. nx odd, ny even: "b" position
  3. nx even, ny odd: "c" position
  4. nx odd, ny odd: "d" position

When there exist 4 variants, then "a" to "d" are used. Otherwise "a" is used on "d", "b" on "c" and "a" on "b" when missing.

Variant positions
-nx evennx odd
ny evenab(a)
ny oddc(b)d(a)

#define KEINE_ALTERNATIVE 0 // = all variants when more exist
#define MIN_ALTERNATIVE 1
#define MAX_ALTERNATIVE 4
#define MAX_ALTERNATIVZAHL ( MAX_ALTERNATIVE - MIN_ALTERNATIVE + 1 )

Animations (Scenic elements only)

Any scenic element can get additional animation phases. Controled by an animation program file (".bnm" file), it can be animated by displaying the single phases in programmable order. For details of ".bnm" files see BAHN Help.

For each phase, there must exist an own ".gz1" file. However, the animation program can consist of more steps than animation phases exist, i.e. they can be used multiple when looking the same.

#define MIN_ANIPHASE 0
#define MAX_ANIPHASE 99 // maximum animation phase

When an animation consists of steam or smoke only, then an additional graphic is not needed. Simply set the steam/smoke data in the header info (see below) and create an animation program of only one step and one phase.

The clock animations as introduced in BAHN 3.85r3 need neither extra graphics nor animation program.

Combining Variants and Animations

Both can be combined. I.e. you can create up to four different animations of the -in principle- same element (see "lturm.*" example used in the "demo_0.nt3" layout where the same tower blinks with different frequency depending on its position in the layout).

Directories and Filenames of Single Files (.gz1)
Directories (Folders)

Data for BAHN standard scenery are stored in the "\zoom1g" subdirectory of BAHN's system directory (where the .exe file is stored, by default "c:\bahn385" etc.).

Data for BAHN standard driving way add-ons are stored in "\zoom1f" instead.

Data for BAHN standard driving ways are stored in "\zoom1m" instead.

Any user-defined data (scenery, ways and signals) are stored in the same directory that contains the layout file (.nt3) that should use them.

Filenames

The integrated editor of BAHN shows the filename in the window's title.

All numbers used for filenames are decimal.

Filenames of Standard Scenic Elements

The filename is constructed from decimal element number (6 digits) + "-" + animation phase (2 digits) + a small letter + extension ".gz1".

Example: 049154-00a.gz1

If existing, then additional animation phases are shown by a phase number from 01 upwards.
Before BAHN 3.86Beta2, the phase number 00 was omitted in the filename. That is always the element that is shown when animations are turned off.

Example:
050972-00a.gz1 = Phase #0
050972-01a.gz1 = Phase #1
050972-02a.gz1 = Phase #2

If there exist variants, then the letter defines the variant from "a" to "d".
In case there are no variants, then the letter is always "a". Before BAHN 3.86Beta2, it was omitted then.

Example: 051220-00a.gz1 and 051220-00b.gz1

Filenames of Standard Driving Way Add-On Elements

The filename consists of driving way letter + number (3 digits) + "-" + version (3 digits) + phase letter.

Example: b168-000a.gz1 and s464-016b.gz1

Driving way letters
LetterMeaning
broad / busway
hwater way
strack on road
ttrack on own trackbed

Versions (designs): Same function but different design, e.g. different colored stopping points or elements with/without a platform.

For many driving way elements, the graphics on different driving ways look the same, and also there are many versions that look equal except of a platform on one side. Then, the same graphics are used, and some elements are defined as "primary". It does not make sense to create own graphics for all the others ("secondary") because these would never be used and waste much main memory. For the most elements, the primary driving ways are track on road and the water ways.

For the most elements that own a platform, this platform is added by BAHN, i.e. it is not a part of the element's own graphics. BAHN copies the platform from the simple driving way with platform elements, i.e. if you alter them, then all the others are changed too.

Example:
s264-002a.gz1 Stopping point with yellow-green sign and platform
The version without platform would be s264-010a.gz1 but is not defined as primary. Also, there are no primary versions for own trackbed and bus line because they look the same.

Phase letter:
The phase letter is needed for signals only. Otherwise, it is always set to "a" and was omitted before BAHN 3.86Beta2.
Some signals are flashing or switching in two or three steps, using immediate phases. In result, different graphics are needed that are marked by the phase letters:

Signal phase letters
LetterMeaning
anormal phase, i.e. signal is in end position
bimmediate phase, while switching (e.g. yellow light at traffic lights)
cadditional immediate phase, displayed before "b"
dsecond picture of an alternating (flashing) signal

There is always an "a" letter but the others are optionally. If not existing, then BAHN shows always the normal phase.

After switching the signal there is displayed the "b" picture for about 2s of simulation time, and then the "a" picture. However, the function of the signal is not influenced, i.e. undependent on the design of the "b" picture, the train will interpret the signal as if it has switched ready to the new status.
When a "c" picture also exists, then the order of display is "c-b-a".

Examples:

s440-000a.gz1 is a simple stop signal in clear status (green light).
s448-000a.gz1 is the same signal in danger status (red light).
A "b" version does not exist for both.

s440-060a.gz1 is a stop signal (traffic lights) with 3 phases in clear status (green light).
s448-060a.gz1 is the same signal in danger status (red light). There are "b" versions:
s448-060b.gz1 shows yellow light and is displayed before the red light.
s440-060b.gz1 shows red and yellow light and is displayed before the green light.
Notice that "b" is shown before "a" and not after.

s464-008a.gz1 is a grade crossing, blinking with two red lights, when the left light is turned on and the right light is turned off.
s464-008d.gz1 is the same but the left light is turned off and the right is turned on.

Before BAHN 3.86Beta2, the flashing signals were hard-coded for some grade crossings, using the "b" phase instead of the "d".
Since BAHN 3.86Beta2, any signals, including user-defined ones, can use both flash and immediate phases.

Filenames of Standard Driving Way Elements

New added with BAHN 3.86. Before, the driving ways were "hard-coded" from a few graphics in old 256 colors format with many layers, stored in the "bahn.gzg" file.

The filename consists of the letter "m" + driving way number (2 digits) + "-" + element number (3 digits) + "-" + "000" (3 digits, currently not used) + "a" letter (currently no meaning) + ".gz1" extension.

Example: m01-002-000a.gz1

For the ways on road and water there exist two versions: without and with borders. However, not all elements of the two versions really differ. Mostly, a difference exists for elements in a 45 degrees direction.

Driving way numbers
Number (without borders)Number (with borders)Meaning
0001track on road, dark gray
0203track on road, light gray, paved
0405track on road, red, paved
0607track on road, concrete gray
08-track on own bed, concrete sleepers
09-track on own bed, wooden sleepers
10-track on own bed, grassy line
11-track on own bed, local line (on sand)
1415water way, dark blue
1617bus way on road, dark gray
1819bus way on road, light gray, paved
2021bus way on road, red, paved
2223bus way on road, concrete gray
24-bus way on path

The element numbers are found in the nt3 layout file documentation (Appendix A).

Some elements exist for a subset of driving ways only, like the special turnouts for combination of bus way and track on road. They would not make sense for water or track on own trackbed.

Examples:

m00-001-000a.gz1 is track on road, dark grey, North-South, without borders. The version with borders is m01-001-000a.gz1 but looks exactly the same.

m14-002-000a.gz1 is water way, Northwest-Southeast, without borders. The version with borders is m15-002-000a.gz1.

Filenames of User-defined Scenic Elements and Signals BAHN 3.86Beta2

With BAHN 3.86Beta2, the scheme was changed to make it more simple. Now, the scheme is Archive name + "-" + element number (2 digits) + "-" + animation phase + small letter + extension ".gz1".

Example: Trolleybus2-58-00a.gz1 is element #58 of archive "Trolleybus2".

The animation phase is the same as for standard elements.

The small letter at the end represents either the variant (for scenery) or the signal phase (for signals). Both work the same way as for standard elements. In most situation, it is not of importance and set to "a".

For signals: The element number defines both the direction of effect and the status of the signal. There is a table in the BAHN Help at "User-defined signals" or "Zoom graphics".

You find more details in BAHN Help at "Single Graphics Files" and "Filenames".

There are prepared two versions for each signal. BAHN assumes the first version to stand right and the second one left to the way. Often you need both, undependent whether your traffic runs right or left handed, e.g. for double track lines.
In the schematic view, BAHN displays them as assumed, and it mixes the platforms in a suitable way in normal view.
This behaviour cannot be changed. However, this is a recommendation only, and you may draw something different if you need it for special ideas.

About the archive files and their filenames see .uz1 files, especially the remark of Initial problem.

File Contents of .gz1

Each file contains some header information and at least 1 up to GSYMTEIL_MAXZAHL layers of the element.

Measures

In principle the same as for .nfz data.

However, there are many elements that differ from this. Many details are shown too large because otherwise it would be impossible to make them visible.
Using Zoom graphics for higher scales, you may use more exact measures.

Limits

Width (West-East): 3*SYMBREITE
Height (North-South): MAXSYMHOEHE+SYMHOEHE

Contents Details of .gz1

This header info is similar also for Zoom2 and Zoom4 data.

File format versions and subversions:

#define ZOOMXGZGFORMAT384 0x0384
#define ZOOMXGZGSUBFORMAT0 0x00 // BAHN 3.84, 3.85Beta,r1,r2,r3
#define ZOOMXGZGSUBFORMAT3 0x03 // BAHN 3.85r3 only if GSYMEIG_UHR is set
#define ZOOMXGZGSUBFORMAT5 0x05 // BAHN 3.86

Header
AvailableNameTypeValueMeaning / Contents
AlwaysVspBYTE[]Text (ANSI) Printable text see File Header, terminated by Ctrl+Z == 26
AlwaysIdGZGBYTE[3]'G','Z','G' Identification string
AlwaysZoomfaktorIDBYTE'1' Zoom factor as text
AlwaysversionBYTE[2]ZOOMXGZGFORMAT384 in the file stored in HIBYTE-LOBYTE-order, i.e. 0x03,0x84
AlwayssubversionBYTE[2]ZOOMXGZGSUBFORMAT0 in the file stored in HIBYTE-LOBYTE-order, i.e. 0x00,0x03
AlwaysGzg_EigINT32Mask of some bits

Properties, consisting of:

#define GSYMEIG_RAUCH 0x0001 // Smoke (industry), more dark gray
#define GSYMEIG_DAMPF 0x0002 // Steam (as smoke, but more light colors)
#define GSYMEIG_24BPP 0x0200 // Color format of BAHN 3.83 as for vehicles
#define GSYMEIG_UHR 0x0004 // Element owns a clock, since BAHN 3.85r3
#define GSYMEIG_KURINFO 0x0008 // Direction info for cursor available, since BAHN 3.86b0
#define GSYMEIG_FWINFO 0x0010 // Driving way info available, since BAHN 3.86b0
#define GSYMEIG_KFARBE 0x0020 // Color for map / schematic view available, since BAHN 3.86b0 (prepared, not supported)

Since BAHN 3.86b0: From format=ZOOMXGZGFORMAT384, subformat=ZOOMXGZGSUBFORMAT5

GSYMEIG_24BPP must be set in any case.
GSYMEIG_RAUCH and GSYMEIG_DAMPF are exclusive.
If BAHN finds clock data in driving way elements, then it may display the clock too, but it will not animate it.

GSYMEIG_KURINFO, GSYMEIG_FWINFO and GSYMEIG_KFARBE do not make sense if they are found in Zoom2 or Zoom4 data. Then, the bits and their additional data are loaded but ignored, and the info of the matching Zoom1 element is used.

if ( Gzg_Eig & ( GSYMEIG_DAMPF | GSYMEIG_RAUCH )) Gzg_DampfXINT32pixel x position where steam/smoke begins
if ( Gzg_Eig & ( GSYMEIG_DAMPF | GSYMEIG_RAUCH )) Gzg_DampfYINT32pixel y position where steam/smoke begins
if ( Gzg_Eig & ( GSYMEIG_DAMPF | GSYMEIG_RAUCH )) Gzg_DampfBrINT32pixel

width (length) of steam resp. smoke

Set steam data in a way that the steam/smoke cannot leave the limits.
Steam/Smoke is always going from left to right (West->East).

if ( Gzg_Eig & GSYMEIG_UHR) reservedINT321 for future use
if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrEigINT32Mask of some bits

Properties of the clock:

#define UHREIG_24H 0x0002 // display 24h (else: 12h)
#define UHREIG_MIN 0x0004 // minute pointer available
#define UHREIG_NW 0x0010 // clock rotated some degrees to Northwest
#define UHREIG_NO 0x0020 // clock rotated some degrees to Northeast

UHREIG_NW and UHREIG_NO are exclusive, i.e. don't use them both together.

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrXMINT32pixel

x position of center

All co-ordinates are in pixels for the Zoom mode of the element.

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrYMINT32pixel

y position of center

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrZMINT32pixel

z position of center (layer)

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrBrINT32pixel

Width of clock

Length of pointer: calculated as (width+1)/2
If there are two pointers, then the hours pointer is shortened to 2/3 of length of the minutes pointer.

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrHoINT32pixel

Height of clock

Height should be equal width.

Set borders in a way that the clock cannot leave the limits.
It is recommended that it also does not cross the borders between central element (Zoom1 co-ordinate x 0..31) and left or right overlapping sections.

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrFarbe1COLORREFRGBsee 24bpp colors

Color of hours pointer

Colors that light at night are possible.

if ( Gzg_Eig & GSYMEIG_UHR) Gzg_UhrFarbe2COLORREFRGBditto

Color of minutes pointer

if ( Gzg_Eig & GSYMEIG_UHR) reservedCOLORREFRGBditto

for future use, set it =Gzg_UhrFarbe1

if ( Gzg_Eig & GSYMEIG_KURINFO) KuRi_NormalINT32RICHTUNG_xxx

Normal cursor direction

#define RICHTUNG_N 0 // to North
#define RICHTUNG_S 1 // to South
#define RICHTUNG_W 2 // to West
#define RICHTUNG_O 3 // to East
#define RICHTUNG_SO 4 // to SE
#define RICHTUNG_NW 5 // to NW
#define RICHTUNG_SW 6 // to SW
#define RICHTUNG_NO 7// to NE

if ( Gzg_Eig & GSYMEIG_KURINFO) KuRi_InversINT32RICHTUNG_xxx

Cursor direction if "reverse direction" option is set
Mostly, this is the opposite direction of KuRi_Normal

Both cursor direction infos are used for Zoom1 scenery and user-defined elements only. Otherwise, the data are ignored, even when existing.

if ( Gzg_Eig & GSYMEIG_KFARBE) KFarbeCOLORREFRGBColor

Color for displaying the element in schematic and map mode

This is prepared in BAHN 3.86b1, but not implemented. The data are ignored.

if ( Gzg_Eig & GSYMEIG_KFARBE) reservedINT32 (resp. COLORREFRGB)0

not used

if ( Gzg_Eig & GSYMEIG_FWINFO) FwInfo_AnzahlINT321..GSYM_FWINFO_MAXZAHL

Count of following driving way information blocks
#define GSYM_FWINFO_MAXZAHL 8

The driving way information is used only for Zoom1 user-defined driving way elements. Otherwise, the data are ignored, even when existing.

if ( Gzg_Eig & GSYMEIG_FWINFO) FwInfoINT32[FwInfo_Anzahl]

for each:

HIBYTE(HIWORD):
FW_xxx

LOBYTE(HIWORD):
GSYM_FW_FKT_xxx

HIBYTE(LOWORD):
0

LOBYTE(LOWORD):
(RICHTUNG_xxx << 4) | RICHTUNG_xxx

Driving way information blocks, for each:

Driving way bits:
#define FW_SCHIENE 0x0001 // Rails
#define FW_WASSER 0x0002 // Water
#define FW_BUS 0x0004 // Road
Combination of rail and road is common, but water is normally exclusive.

Additional functions:
#define GSYM_FW_FKT_KEINE 0x00 // no additional function
#define GSYM_FW_FKT_KRZG 0x80 // keep crossings free
#define GSYM_FW_FKT_TUNNEIN 0x01 // tunnel entry (level -1)
#define GSYM_FW_FKT_TUNNAUS 0x02 // tunnel exit (level +1)
#define GSYM_FW_FKT_RAMPE 0x03 // ramp (level +1)
Functions are exclusive except GSYM_FW_FKT_KRZG.

LOBYTE(LOWORD) stores the directions:
Bit0..3 Arrival (incoming)
Bit4..7 Departure (leaving)
both as RICHTUNG_xxx see above at cursor directions

AlwaysanzebenenINT321..GSYMTEIL_MAXZAHL Number of layers (views)
AlwaysTextCHAR16[]Unicode Text info, at max. MAX_UGFXTEXTLINELEN characters
terminated by UNICODE_NULL

Then, the views of the single layers follow. The count is given in anzebenen before.

View

All co-ordinates and width/height values must not exceed the limits as defined above.

NameTypeValueMeaning / Contents
layerINT16GFX_Z_MIN..GFX_Z_MAX one of the GFX_Z_xxx values
x0INT16pixel lower left corner x co-ordinate in pixels
y0INT16pixel lower left corner y co-ordinate in pixels
widthINT16pixel width in pixels
heightINT16pixel height in pixels
dataCOLORREFRGB[]pixels

Rectangle, no separator, no terminator

The data run from y0 to y0 + height-1 in lines,
each from x0 to x0 + width - 1.

Color scheme 24 bpp colors with packing, depending on the version and subversion format info.

Zoom2 and Zoom4 Graphics for Scenery Elements and Signals (.gz2,.gz4)

This is available since BAHN 3.85Beta0 9/2008.

Zoom2/Zoom4 are optional add-ons, making available more detailed graphics for any element that is available in 1:1-scale (inclusive user-defined ones). The Zoom data are used in BAHN in view scale 2:1..8:1 instead of the original scale 1:1-data.

If not available (or if any error occurs), the original data are used in the same way as before. The error message #621 in BAHN gives a return code that specifies more details about the error, see "bahn.hlp"/"bahn.chm" at "Errors and messages, 621" for more.

Data structures and handling are quite similar to Zoom1 ".gz1" data The next section describes the differences.

Differences to .gz1

File name extension is ".gz2" resp. ".gz4".

Files for standard graphics are stored to subdirectories "zoom2f" and "zoom2g" resp. "zoom4f" and "zoom4g".

The header info contains a different ZoomFaktorID:
ZoomfaktorID = BYTE[1] = '2' or '4' for Zoom2 or Zoom4

Not all possible properties make sense for Zoom2+4. See remark at definition of GSYMEIG_xxx in .gz1 section.

The co-ordinates, measures and limits are multiplied by 2 resp. 4.

Archive Files for Scenery Elements and Signals (.uz1, .uz2, .uz4, .fwn/.fxn)

This is available since BAHN 3.85Beta0 9/2008.

Storing all the scenery and driving way add-on data in single files results in thousands small files that make your computer slow down and waste resources.

For that reason, the data can be combined to a few larger archive files:

"bahn.fw1" for BAHN standard driving way graphic add-ons
"bahn.fx1" for BAHN standard scenic graphics
"name.uz1" for a set of user-defined scenic graphics or signals

For Zoom2 and Zoom4 data, replace the "1" by "2" resp. "4".

The files with standard data are stored in the BAHN system directory, i.e. at the same place as "bahn.exe".

The user-defined must be stored at the same place where the layout file is found that uses them. Thus, the ".uz1" files can replace the old ".uzg" files, using the extended possibilities of BAHN 3.85 and storing up to 90 elements each instead of 2*36, including variants and animations.

For user-defined signals, the same ".uz1" data are used. Each file can hold the two versions of a signal, in all 8 directions, with all phases.

When there exist both a single .gz1 file and a file packed in an archive file for one and the same element, then BAHN always loads the single file.

The integrated BAHN editor always stores single files. In result, the archive files can be used as security copy when you like to make experiments with some elements.

If you like to extract a single file from a package, then simply edit it in BAHN and save it to disk.

For creating and extracting the archive files there is the same command line software "fzgc2.exe" as for vehicle Zoom archives. You should find it published somewhere at www.jbss.de. The source code file "fzgc2.c" includes documentation about handling (command file parameters) and a short description of the supported archive file format, both in English and German.

"Initial Problem" - Creating a new .uz1 File

When you like to create a new ".uz1" file then you have to create its single file components first. But to store them, BAHN needs a valid filename of the not-yet-existing ".uz1" file. You cannot explicitely enter a filename for a single file.

Run BAHN and enter the name in "File"-"Userdefined Graphics"-"Scenery", "Signals" or "Driving Ways", as if it would already exist, and confirm with "OK". BAHN may give you a message that the file could not be loaded because not found. However, it will store the name, and then it will save and load the single files using this filename. Another way it would be to copy any already existing ".uz1" or ".uzg" file to another name and to use and edit it.

Scenery Elements, Old Style (.uzg)

(with BAHN 3.85 replaced by .gz1/.uz1 format, but still supported)

An ".uzg" file contains 36 graphic symbols without function, that can be used for scenery. They can be accessed as "Userdefined graphic symbols" the same way as other scenery. Each of the blocks in the Status window contains 9 symbols, so it is the best to make groups of 9 symbols that belong together in any way. You should not paint symbols that look identically to original BAHN symbols, because this may confuse the users. Avoid this, especially with the empty symbol and with driving ways.

In BAHN 3.56-3.59 each symbol consists of 4 simple symbols (32x16 pixel) that are arranged one upon the other (32x64 pixel). It is not needed to use all the simple symbols (see table data).

Any simple symbol consists of 4 partial symbols ("horizontal MiniSprites", in the following called "MSP1"). Construction of a MSP1 (8 pixels width, 16 pixels height):

16 lines with 8 byte each, where each byte represents one pixel (colors see 256 colors)

The lines follow each other from top down. All 4 MSP1 of a simple symbol stand one after the other without separator.

The file is used for 36 symbols (=4*36 simple symbols). It must contain at least 4 and at maximum 4*4*36=576 MSP1. If symbols use MSP1 that are missing in the file, then BAHN displays them as black-white pattern. To any simple symbol there belong the MSP1 from symbol number * 4 to symbol number * 4 + 3, e.g.

In case of wrong values for the number, BAHN gives an error message and all symbols are replaced by standard data.

NameTypeContents / Values
Filemixed Header + Identificator + Msp1Zahl + MSP1[ Msp1Zahl ] + Msp2Zahl + Symbol-Table
HeaderBYTE[] printable text see File Header, terminator Ctrl+Z == 26
IdentificatorBYTE[2] = {0x35,0x09} for BAHN 3.59-files
Msp1ZahlWORD16 = number of MSP1, BAHN 3.56-59: 4 <= .. < 36*4*4 /* max. 36*4*4 MSP1 */
Msp2ZahlWORD16 = reserved = 0
MSP1Line[16] Following the MSP1 one after the other, without separator
LineBYTE[8] Byte = Pixel 256 colors

Additionally: Symbol table for arrangement of the simple symbols. The format is more flexible as needed.

NameTypeContents / Values
HeaderBYTE[4] = {'S','Y','M','T'}
SymbolsSymbol[36] for each Symbol
SymbolWORD16[6] symbol numbers in range 0 .. 4*36-1 for the symbols of this file
or = 0xFFFF for not used

Order per Symbol:

  1. Down part (visible at x,y+1, as background)
  2. Self1 (visible at x,y)
  3. Self2 (visible at x,y, covering Self1)
  4. Upper part1 (visible at x,y-1)
  5. Upper part2 (visible at x,y-2)
  6. Upper part3 (visible at x,y-3)

All simple symbols can be used multiple. However, it is not needed to support this, because there are 4 simple symbols available per symbol (eg B34EDI and WB35EDI use a fixed table without multi-use).

Conditions (checked while loading!):

In result:

File length = Header length + 2 + 2*2 + Msp1Zahl*16*8 + 4 + 36*6*2 = at least 955 Byte

Example:
All MSP1 may be used, all 36 symbols have height = 4 symbols without down part, each uses its own MSP1. In result, the most simple table is:

0xFFFF, 0xFFFF, 0, 1, 2, 3,
0xFFFF, 0xFFFF, 4, 5, 6, 7,
0xFFFF, 0xFFFF, 8, 9,10,11,
... ...
0xFFFF, 0xFFFF,140,141,142,143

Vehicle Data (.nfz)

(new since BAHN 3.83Beta3, replacing the combination of .ufg and .uzz data)

Data are organized in vehicle sets. Each file can store some sets, each set can contain some vehicles.

Maximum number of vehicle sets per file:

#define NUTZERFZGSATZ_PRODATEI 10

Maximum number of vehicles per set:

#define FZGF_MAXFZGZAHL 16

Max. Length of name of a vehicle set incl. terminator character:

#define ZUGGNAMESIZE 33

Number of text lines per vehicle:

#define MAX_FZGTEXTZAHL 5

Maximum length of a single text line of a vehicle incl. terminator (also used for the text line of Zoom2/4 vehicles and scenic graphics):
This is the number of characters, i.e. not the size in BYTE. The real size depends on the type of data (BYTE or CHAR16 Unicode characters). Terminator is '\0' (0x00) for BYTE-coded and UNICODE_NULL for CHAR16 text.

some old formats of CAREDI 1.x and 2.x:
#define MAX_UFZGTEXTLINELEN 61

until BAHN 3.86 Beta0d:
#define MAX_UGFXTEXTLINELEN_81 81

since BAHN 3.86 Beta0e
(vehicles: from format=ZOOMXFZGFORMAT385, subformat=ZOOMXFZGSUBFORMAT5)
(also used for .gzn files: from format=ZOOMXGZGFORMAT384, subformat=ZOOMXGZGSUBFORMAT5)
#define MAX_UGFXTEXTLINELEN 121

Maximum length (=count of characters) of all texts of a user-defined vehicle set:

#define MAX_UFZGTEXTLEN ( ZUGGNAMESIZE\ + MAX_FZGTEXTZAHL * FZGF_MAXFZGZAHL\ * MAX_UGFXTEXTLINELEN )

Minimum and maximum numbers of vehicle sets in the file:

#define NUTZERFZGSATZNRDATEI_MIN 4000
#define NUTZERFZGSATZNRDATEI_MAX (NUTZERFZGSATZNRDATEI_MIN + NUTZERFMSPSATZNR_PRODATEI - 1)

Measures

In BAHN, the recommended calculation of measures for scale 1:1 is:

original [mm] / 467 = pixel in BAHN.

(1 ft = 304.8mm)

However, I know that many available vehicles differ from this scale. It is a recommendation only. For displaying more details, the height and width of many vehicles are too large. Also, you cannot assume that a pixel is "quadratic" in any case, because this depends on the screen resolution. Originally, BAHN was designed for 640x480 (4:3 ratio), but also used with EGA adapters of 640x350, using the same graphics. Today, common resolutions are 800x600, 1024x768 and 1152x864 (4:3 each), but also 1280x1024 (5:4) and others. A different ratio results in a different length:height for each pixel.

Limits

Constants defined for 1:1 scale, in pixels: Vehicle length (horizontally):

#define MIN_FZGLEN 8
#define MAX_FZGLEN (32 * 8)

Vehicle height (horizontally and vertically):

#define MIN_FZGHO 2
#define MAX_FZGHO 14

Vehicle width (vertically):

#define MIN_FZGBR 4
#define MAX_FZGBR 16

maximum number of steam start points per vehicle type:

#define MAXDAMPFZAHL 3

limits of steam positions (pixel) (as undependent of vehicle length):

#define DAMPFX_MIN 0 (x minimum, counted in driving dir., begin = 0)
#define DAMPFY_MIN 4 (y minimum)
#define DAMPFY_MAX 13 (y maximum)

Contents Overview
  1. Header
  2. List of vehicle sets
  3. Vehicle sets, each consisting of up to FZGF_MAXFZGZAHL vehicles.
  4. Vehicle control data
  5. Views (at minimum 6, but also 8, 10, 12, 14 up to 16)
Contents Details
Header

This header is similar also for the bahn.fzg file.

NameTypeValues / Contents
VspBYTE[] Printable text, terminated by Ctrl+Z (26), see here
IDENT_CODEBYTE[3] = {'F', 'Z', 'G' |0x80 }
for identification / test purposes
format versionBYTE[2]

in the file stored in HIBYTE-LOBYTE-order, i.e. 0x38,0x30

0x3830: Standard BAHN 3.83 and 3.84

0x3840: Since BAHN 3.85 (identical, but ZGGEIG_SEITE2 may be used)

0x3850: BAHN 3.85, Text as Unicode-16

0x3853: identical, ZGGEIG_HSTR and _HSTL may be used

0x3855: single vehicles contain version info

There is no real difference between 0x3830 and 0x3840 versions. However, you may use the 0x3840 value to prevent loading the data into BAHN 3.83 or 3.84 because they may get confused when the ZGGEIG_SEITE2 bit is used in the file (supported since 3.85, see vehicle properties).

The 0x3850 format is identical except that it assumes all text data stored as Unicode (CHAR16 in LOBYTE-HIBYTE notation). Numbers of characters are the same, but data lengths of text given in BYTE must get doubled.

List of Vehicle Sets

The list consists of pairs of logical number and file offset. Terminated by logical number == 0, then no file offset follows. There are at max. NUTZERFZGSATZ_PRODATEI user-defined vehicle sets.

NameTypeContents / Values
logical numberWORD16 valid values: NUTZERFZGSATZNRDATEI_MIN..NUTZERFZGSATZNRDATEI_MAX
order from min to max, gaps are possible
file offsetWORD32 file offset for seek() from position behind the WORD32 for reaching the vehicle set

Example:

WORD16 log.number = NUTZERFZGSATZNRDATEI_MIN
WORD32 Offset = 2
WORD16 terminator = 0

Vehicle Set

After reading the file offset, set the current file pointer position relative to this offset to reach the vehicle set data.

File VersionNameTypeContents / Values
Alllogical numberWORD16 = the same as above (useful for testing correct position)
AllfzgzahlWORD16 = number of vehicles in the set
= 1..FZGF_MAXFZGZAHL
AllsgrnrWORD32 #define SGR_NUTZER 0x00008000

Mask for pre-selection = SGR_NUTZER (for user-defined vehicles do not use the other values that can be found in bahn.fzg section)

AlltxtlenINT32 = Summary length of all texts of the vehicle set (number of characters) at max. = MAX_UFZGTEXTLEN
<0x3850TexteBYTE[txtlen] = all the text data for all vehicles
  • coded Windows/ANSI
  • all lines terminated by '\0'
  • first line = set name, at max. BYTE[ZUGGNAMESIZE] incl. '\0'
  • next lines = vehicle texts, for each at max. BYTE[MAX_UFZGTEXTLINELEN] incl. '\0'
  • for each vehicle exactly lines[MAX_FZGTEXTZAHL]
  • empty lines consist of '\0' only
  • set name and first line of each vehicle should not be empty
  • in result, (fzgzahl*MAX_FZGTEXTZAHL+1) lines needed
>=0x3850TexteCHAR16[txtlen] = all the text data for all vehicles
  • coded Unicode CHAR16 LOBYTE-HIBYTE (as for X86 compatible CPU)
  • all lines terminated by UNICODE_NULL
  • first line = set name, at max. CHAR16[ZUGGNAMESIZE] incl. UNICODE_NULL
  • next lines = vehicle texts, for each at max. CHAR16[MAX_UFZGTEXTLINELEN] incl. UNICODE_NULL
  • for each vehicle exactly lines[MAX_FZGTEXTZAHL]
  • empty lines consist of UNICODE_NULL only
  • set name and first line of each vehicle should not be empty
  • in result, (fzgzahl*MAX_FZGTEXTZAHL+1) lines needed
Vehicle
NameTypeContents / Values
FzgLokNrBYTE = Local number of the vehicle in the set 0..FZGF_MAXFZGZAHL-1 The number must be unique inside the set. Order and gaps are dont-care.
(In former data formats, this number was defined by the order of the vehicles in the set. In result, when deleting one vehicle from the set, all the following vehicles had been renumbered.)
This number defines the last 2 digits in the .fz2/.fz4 Zoom2/4 files.
FzgLenWORD16 = Length MIN_FZGLEN..MAX_FZGLEN
FzgHoW1WORD16 = Height (horizontal view) MIN_FZGHO..MAX_FZGHO
FzgBr1WORD16 = Width (vertical view) MIN_FZGBR..MAX_FZGBR
FzgHoS1WORD16 = Height (vertical view) MIN_FZGHO..MAX_FZGHO

For details see also measures and limits

The length of the roof in vertical view is FzgLen/2. In result, it is recommended to use even values for length of vehicles that should be coupled to trains. Otherwise, in vertical view some rounding problem may cause a bit different display of the train depending on the current position.

For width, the use of even values is recommended. Otherwise, BAHN cannot place the vehicle exactly centered. This may be don't-care for pneu vehicles and ships, but not for something running on tracks.

File VersionNameTypeContents / Values
AllEigWORD32

Properties, OR-combined by bits defined in the next table

>=0x3855Version infoWORD16[2]

Info about graphics of the single vehicle, format and subformat

Possible values: The same as for Zoom2 vehicles.
The data define the packing algorithm for the views.

For File format <0x3855, assume format=ZOOMXFZGFORMAT385 and subformat=ZOOMXFZGSUBFORMAT3

AllSteam infomixed Info about steam, dampfzahl + Positions[dampfzahl], as follows
AlldampfzahlBYTE Number of steam/smoke positions, 0..MAXDAMPFZAHL
AllPositionsWORD16[3*dampfzahl] each is a triple of start point (x,y) and length as follows
AllDampfPosXWORD16 =DAMPFX_MIN..FzgLen-1 x-position (in driving direction)
AllDampfPosYWORD16 =DAMPFY_MIN..DAMPFY_MAX y-position (over rail, i.e. on rail = 0)
AllDampfLenWORD16 =1..FzgLen - DampfPosX length
Vehicle Property Bits (Eig value of previous table):
VersionNameValueMeaning
All ZGGEIG_24BPP0x0200 Using the 24 bpp color format (if not set then instead the 256-color format)
All ZGGEIG_ER0x0001 Single direction car (e.g. buses, many trams) but not used for asymmetric bidirectional cars (steam locos, cab cars etc.)
All ZGGEIG_TFZ0x8000 Motorized car that can run alone (unimportant)
Usually, in BAHN motorized cars that cannot run alone are not marked as motorized (e.g. trams with lowered pantograph)
All ZGGEIG_DRW0x0040 When running backwards then do not exchange graphics (left-right/front-rear) i.e. when turning, the vehicle is "rotated".
Use for symmetric bidirectional cars with arrangement of pantographs depending on travelling direction, e.g. trolley connector trams or el.locos with only one raised panto
further since BAHN 3.59 for front/head light changing: However it works only if front+rear and left+right look the same except the lights.
All ZGGEIG_LWX0x0080 Light change:
Front and rear view are shown undependent from "backwards" status. Use for vehicles with same-looking front and rear view to show the right headlights/backlights. Can be combined with ZGGEIG_DRW.
All ZGGEIG_FRONT20x0100

Light change by extra graphics:
Use for changing front/rear lights depending on travelling direction by exchanging front and rear view using extra graphics. Needed for vehicles with different front and rear view, e.g. most steam locos, typical US design diesel locos and cab cars.
Do not combine with ZGGEIG_LWX.
If set, than 2nd front and rear view must exist in the file.

Until BAHN 3.85r3:
If set in Zoom2 or Zoom4 data, but not used in the scale 1:1 original, then the data in Zoom2/4 are ignored.
If missing in Zoom2/Zoom4 but used in the 1:1 original, then BAHN copies front and rear view.

From BAHN 3.86:
The data are undependent on Zoom status: When existing in any Zoom, then they are used when this Zoom is used, undependent whether existing or missing in any other Zoom.

>=0x3850, i.e. BAHN 3.85 ZGGEIG_SEITE20x0400

Exchanging side views depending on driving direction by use of extra graphics for sides and roof.
The exchange is needed for changing the pantographs of electric locos and EMUs raised/lowered when travelling forwards/backwards. For many locos it is sufficient to exchange the both side and roof views for that (using the ZGGEIG_DRW option).
However, when both sides look different, then there must exist copies of both (e.g. for many Czech locos or locos with asymmetric advertising liveries).
If set, then 2nd side and roof views must exist in the file.

Until BAHN 3.85r3:
If set in Zoom2 or Zoom4 data, but not used in the scale 1:1 original, then the data in Zoom2/4 are ignored.
If missing in Zoom2/Zoom4 but used in the 1:1 original, then BAHN copies front and rear view.

From BAHN 3.86:
The data are undependent on Zoom status: When existing in any Zoom, then they are used when this Zoom is used, undependent whether existing or missing n any other Zoom.

Can be combined with ZGGEIG_HSTR/_HSTL and needs additional views then.

>=0x3850, but BAHN 3.85r3
(see remark on right side)
ZGGEIG_HSTR
ZGGEIG_HSTL
0x0800
0x1000

Using extra graphics for status "Halted" at stopping points and timing points to display open doors on the right resp. left side

Exchanging side views depending on status "Halt at stop"/"Halt at timing pt." by use of extra graphics:

_HSTR: For right side when the stop sign is on the right side or vice versa when travelling backwards and stop sign is on the left side. If set, then 2nd right side view must exist in the file.

_HSTL: Identical to ZGGEIG_HSTR but for the left side.

The data are undependent on Zoom status: When existing in any Zoom, then they are used when this Zoom is used, undependent whether existing or missing in any other Zoom. In other words, you can add this feature and data e.g. in Zoom2 graphics but you don't need to add it in Zoom1 where the small details would be nearly invisible.

Both can be set and used together, as typically for bidirectional vehicles with doors on both sides, like the most railway cars. But for unidirectional cars you may use only one of the bits, e.g. for buses and some trams, depending on whether they are made for right-handed or left-handed traffic.

Both can be combined with ZGGEIG_SEITE2 and need additional views then.

Remark: supported since BAHN 3.85r3, and marked by the new sub file version ZOOMXFZGSUBFORMAT3;
however since 08/2009 and 01/2010 there was not defined a new file subversion, i.e. there may exist some files using this feature and marked with version ZOOMXFZGFORMAT385+ZOOMXFZGSUBFORMAT0: BAHN 3.85r1+r2 ignore these bits and the data for Zoom2 and Zoom4 graphics, however they can get trouble when these bits are found in Zoom1 data

All
(see remark on right side)
ZGGEIG_V
ZGGEIG_H
0x0010
0x0020

use only as first in the train (no coupling device in front)
use only as last in the train (no coupling at rear side)

In principle supported since BAHN 3.40 up to now. However, the reason to define it was the limited length possibility of former BAHN versions (see ufg files for explanation, the same was true for standard vehicles that time).

Since BAHN 3.83, you can use a nearly exactly suitable length for cars, and it is no more needed to have a gap of transparent color on one side.
In BAHN 3.58 to BAHN 3.81 there were a few cars in the standard vehicle library using _V and _H (SJ snowploughs, Vienna ULF, some buses).

The only reason to know and support it until now is the support of old user-defined files.

Vehicle Views (Graphical Data)

There follow the single views, each as rectangle, no separator, no terminator. Set pixels not used to FARBE_TRANSPARENT. Each rectangle from top left to bottom right in lines, exceptions see below. The order of the views is as in the table. Some are available always, some depending on the properties defined in the sections above.

AvailableNameMeasuresContents
Always Right sideFzgLen * FzgHoW1running to East
Always Left sideFzgLen * FzgHoW1running to West
Always RoofFzgLen/2 * FzgBr1running to South
Always FrontFzgBr1 * FzgHoS1running to South
Always RoofFzgLen/2 * FzgBr1running to North
Always Rear viewFzgBr1 * FzgHoS1running to North
if ( Eig & ZGGEIG_FRONT2 ) FrontFzgBr1 * FzgHoS1running to North, i.e. backwards
if ( Eig & ZGGEIG_FRONT2 ) Rear viewFzgBr1 * FzgHoS1running to South, i.e. backwards
if ( Eig & ZGGEIG_SEITE2 ) Left sideFzgLen * FzgHoW1running to West, i.e. backwards
if ( Eig & ZGGEIG_SEITE2 ) Right sideFzgLen * FzgHoW1running to East, i.e. backwards
if ( Eig & ZGGEIG_SEITE2 ) RoofFzgLen/2 * FzgBr1running to North, i.e. backwards
if ( Eig & ZGGEIG_SEITE2 ) RoofFzgLen/2 * FzgBr1running to South, i.e. backwards
if ( Eig & ZGGEIG_HSTR ) Right sideFzgLen * FzgHoW1stopping to East
if (( Eig & ZGGEIG_HSTR ) && ( Eig & ZGGEIG_SEITE2 )) Right sideFzgLen * FzgHoW1stopping to West, i.e. backwards
if ( Eig & ZGGEIG_HSTL ) Left sideFzgLen * FzgHoW1stopping to West
if (( Eig & ZGGEIG_HSTL ) && ( Eig & ZGGEIG_SEITE2 )) Left sideFzgLen * FzgHoW1stopping to East, i.e. backwards

For each view:

If ( Eig & ZGGEIG_24BPP )

else

Zoom2 Vehicle Graphics (.fz2/.fzz)

This is available since BAHN 3.83Beta2 2004-Aug-29.

Zoom2 is an optional add-on, making available more detailed graphics for any vehicle that is available in 1:1-scale (inclusive user-defined ones). The Zoom2 data are used in BAHN in view scale 2:1..8:1 instead of the original scale 1:1-data. If not available (or if any error occurs), the original data are used in the same way as before. The error message #620 in BAHN gives a return code that specifies more details about the error, for more see also the Help file "bahn.hlp"/"bahn.chm" at "Errors and Messages, 620".

The data are stored in separate files for each vehicle type (i.e. not in vehicle sets). For standard vehicles, the single files can be combined to archive files. The most properties of the vehicle are taken from the 1:1 data.

Directories (Folders)

Zoom2 data for BAHN standard vehicles are stored in the "\zoom2" subdirectory of BAHN's system directory (where the .exe file is stored, by default "c:\bahn383" resp. "c:\bahn386" or similar). Data for user-defined vehicles are stored in the same directory that contains the scale 1:1 data (.nfz or .ufg/.uzz files).

Filenames

For BAHN standard vehicles, the name is constructed from vehicle set number (5 digits) + '-' + local vehicle number in the set (2 digits) + extension. All numbers decimal, counting starts with 0. Extension is ".fzz" for BAHN 3.83,3.84 and 3.85Beta, but since 3.85r1 it was changed to ".fz2". However, if 3.85 does not find ".fz2" then it also looks for a suitable ".fzz" file.

Example: "05220-00.fz2" is set #5220, car #0.

BAHN shows the set and vehicle number in the "Vehicle list" function of Train menu.

For user-defined vehicles the name is constructed from the .nfz/.ufg filename (without extension) + '-' + vehicle set number (2 digits) + '-' + local vehicle number in the set (2 digits) + ".fzz". All numbers decimal, counting starts with 0.

Example: "ship1-00-01.fz2" is from "ship1.nfz" or from "ship1.ufg", set #00, vehicle #01.

Contents Overview

Each file contains some header information and at least 6 up to 16 views of the vehicle. The views are the same as described in the NFZ section, but the measures are different.

Measures

See .nfz data for the general definition in scale 1:1.

Resulting in recommended calculation of measures for scale 2:1:

original [mm] / 233.5 = pixel in BAHN.

Limits

Length: 2*MIN_FZGLEN .. 2*MAX_FZGLEN

This must be exactly = 2*length of the scale 1:1 original. Otherwise BAHN does not load this file. The length of the roof in vertical view is Length/2.

Height: 2*MIN_FZGHO .. 2*MAX_FZGHO

Note that height of front and rear view of older BAHN data formats (before BAHN 3.83) is zero. This is true for any user-defined car stored in .ufg data. When making a Zoom2-view of such an original, than lengthen the roof and make fronts and rear views of suitable height. The BAHN internal graphics editor sets the height to 2*MIN_FZGHO when loading the data and fills the data with transparent color.

Width: 2*MIN_FZGBR .. 2*MAX_FZGBR

Recommended to use even values only.

Contents Details
Header
VersionNameTypeContents / Values
AllVspBYTE[] Printable text of unlimited length, terminated by Ctrl+Z (26), see here
AllIdFZG2BYTE[4] Identification string, ={'F', 'Z', 'G', '2'}
AllversionWORD16

File version, =ZOOM2FZGFORMAT383 or =ZOOMXFZGFORMAT385
(in the file stored in HIBYTE-LOBYTE-order, i.e. 0x03,0x83)

#define ZOOM2FZGFORMAT383 0x0383
#define ZOOM2FZGSUBFORMAT2 0x02
#define ZOOM2FZGSUBFORMAT3 0x03
#define ZOOMXFZGFORMAT385 0x0385
#define ZOOMXFZGSUBFORMAT0 0x00
#define ZOOMXFZGSUBFORMAT3 0x03
#define ZOOMXFZGSUBFORMAT5 0x05
ZOOM2FZGFORMAT383subversionBYTE = ZOOM2FZGSUBFORMAT2 (BAHN 3.83Beta2) or
= ZOOM2FZGSUBFORMAT3 (since BAHN 3.83Beta3)
ZOOMXFZGFORMAT385subversionWORD16 = ZOOMXFZGSUBFORMAT0 (since BAHN 3.85Beta0) or
= ZOOMXFZGSUBFORMAT3 (since BAHN 3.85r3, but only if ZGGEIG_HSTR or ZGGEIG_HSTL are set)
= ZOOMXFZGSUBFORMAT5 (since BAHN 3.86)
ZOOMXFZGFORMAT385EigINT32 Properties, see below
AllFzg2LenWORD16 Length in pixels for horizontal views (divide by 2 for length of roof vertically)
AllFzg2HoWWORD16 Height in pixels for horizontal views
AllFzg2BrWORD16 Width in pixels for vertical views
AllFzg2HoSWORD16 Height in pixels for vertical views
ZOOM2FZGFORMAT383EigWORD16 Properties, see below
(Remark: in the 385 format stored as INT32 and before the measures, see above)
ZOOM2FZGFORMAT383TxtBYTE[]

ANSI-coded text line with optional information
max.length (number of characters!) MAX_UFZGTEXTLINELEN incl. terminator '\0' (0x00)
No control characters (like CRLF or TAB)
While loading/storing transformed into and from Unicode, using the codepage information in BAHN-Options-Miscelleanous

Since BAHN 3.84 (3.84Beta7 4/2007): The text line may be coded Unicode-16bit instead of ANSI-8bit, see below.

ZOOMXFZGFORMAT385TxtCHAR16[] The same text line as before, but coded Unicode-16.
Terminator is UNICODE_NULL.
The line has to begin with UNICODE_LOHI or UNICODE_HILO, and the coding must be compatible with it.
This value is not stored with the text and is additional, i.e. not belonging to the size above.
When BAHN 3.84 saves a Zoom2 file, then it always uses the 8-bit-ANSI coding to make the file compatible with 3.83.
When BAHN 3.85 saves a Zoom2 file, then it always uses the ZOOMXFZGFORMAT385 format using Unicode.

The properties are the same as shown for nfz data. The next table mentions the differences only.

Vehicle Property Bits (Eig value of Zoom2/Zoom4):
VersionNameValueMeaning
All ZGGEIG_24BPP0x0200 Using the 24 bpp color format (if not set then instead the 256-color format, but this works only with 3.83Beta2, not with later versions)
All ZGGEIG_FRONT20x0100

Exchanging front/rear view depending on travelling direction by exchanging front and rear view by use of extra graphics.
If set, then 2nd front and rear view must exist in the file.

Until BAHN 3.85r3:
If set and available here, but not used in the scale 1:1 original, then the data are ignored.
If missing here but used in the 1:1 original, then BAHN copies front and rear view.

From BAHN 3.86:
This is independent to the 1:1 original data: When defined and existing here, then the graphics are displayed, even when Zoom1 does not have such graphics, and vice versa.

ZOOMXFZGFORMAT385, i.e. BAHN 3.85 ZGGEIG_SEITE20x0400

Exchanging side and roof views depending on driving direction by use of extra graphics.
If set, then 2nd side and roof views must exist in the file.

Until BAHN 3.85r3:
If set and available here, but not used in the scale 1:1 original, then the data are ignored.
If missing here but used in the 1:1 original, then BAHN copies front and rear view.

From BAHN 3.86:
This is independent to the 1:1 original data: When defined and existing here, then the graphics are displayed, even when Zoom1 does not have such graphics, and vice versa.

ZOOMXFZGFORMAT385, but not before BAHN 3.85r3 ZGGEIG_HSTR
ZGGEIG_HSTL
0x0800
0x1000

Using extra graphics for status "Halted" at stopping points and timing points to display open doors on the right resp. left side
If set, then resp. side views must exist in the file.

This is independent to the 1:1 original data: When defined and existing here, then the graphics are displayed, even when Zoom1 does not have such graphics, and vice versa.

Views

The order of the views is the same as found in the NFZ section. The measures and limits are found in Contents overview above. The number of views (i.e. if available for some of them) depends on the properties (see above).

Each view is a COLORREFRGB[], as rectangle, with no separator and no terminator. Pixels not used are set to FARBE_TRANSPARENT.

if (version == ZOOM2FZGFORMAT383) and (subformat == ZOOM2FZGSUBFORMAT2):
Each rectangle from top left to bottom right in lines.

if ((version == ZOOM2FZGFORMAT383) and (subformat == ZOOM2FZGSUBFORMAT3)) or (version == ZOOMXFZGFORMAT385):
The same rectangles but using packed data, resulting in variable length of data.
Further, the roof views are stored from left top to right bottom in columns for better packing. For unpacking see color packing.

Archive Files for Zoom2 Vehicle Graphics "bahn.fz2"/"name.fz2"

For standard vehicles, this is available since BAHN 3.84Beta6 2/2007.
For user-defined ones, this was added with BAHN 3.86Beta2 2/2011.

The reason is that handling of some thousand single files may make your computer slow down and may waste resources. However, details are depending on the OS and especially on the file system.

All the Zoom2 files for the standard vehicles are combined to a single file "bahn.fz2".
This file is stored in the BAHN system directory, i.e. at the same place as "bahn.exe".

All the Zoom2 files for vehicles of a .nfz file "name.nfz" can be combined to a single file "name.fz2".
This file is stored at the same place as the .nfz file.

When there exist data for the same vehicle both in a single file as described in Zoom2 Vehicles and in an archive file, then BAHN always loads the single file.

The integrated BAHN graphics editor always stores single files. In result, you can use the archives as security copies when you like to make experiments with standard Zoom2 vehicles. If you like to copy a Zoom2 file from "bahn.fz2", then simply edit it in BAHN and save it to disk.

For creating and extracting the ".fz2" archive files there is a simple command line software "fzgc2.exe".
You should find it published somewhere at www.jbss.de. The source code file "fzgc2.c" includes documentation about handling (command file parameters) and a short description of the "bahn.fz2" archive file format, both in English and German.
In result of some changes in the data structures, there may exist different versions of this software for different BAHN versions.

Zoom4 Vehicle Graphics (.fz4)

This is available since BAHN 3.85Beta0 9/2008.

Zoom4 is an optional add-on, making available more detailed graphics for any vehicle that is available in 1:1-scale (inclusive user-defined ones). The Zoom4 data are used in BAHN in view scale 4:1 and 8:1 instead of the original scale 1:1-data (from 3.85r2 also in 6:1 scale). If not available (or if any error occurs), then the original data are used in the same way as before, or existing Zoom2 data when found.

Handling and data are nearly the same as for Zoom2 vehicle data.

Directories (Folders)

Zoom4 data for BAHN standard vehicles are stored in the "\zoom4" subdirectory of BAHN's system directory (where the .exe file is stored, by default "c:\bahn385" or similar, depending on version). Data for user-defined vehicles are stored in the same directory that contains the scale 1:1 data (.nfz or .ufg/.uzz files).

Filenames

The same as for Zoom2 data, except the standard file extension is ".fz4" instead of ".fz2".

Example: "05220-00.fz4" is set #5220, car #0.

Contents overview

Identical to Zoom2.

Measures

In general see .nfz data.

Resulting in recommended calculation of measures for scale 4:1:

original [mm] / 116.75 = pixel in BAHN.

Limits

As for Zoom2, with doubled limits:

Length: 4*MIN_FZGLEN .. 4*MAX_FZGLEN
Height: 4*MIN_FZGHO .. 4*MAX_FZGHO
Width: 4*MIN_FZGBR .. 4*MAX_FZGBR

Contents Details
Header

The header info is nearly identical with Zoom2 vehicle data. There are minor differences only.

The value of identification string is {'F','Z','G','4'}.

Supported file version versions: ZOOMXFZGFORMAT385 with subformats ZOOMXFZGSUBFORMAT0 and ZOOMXFZGSUBFORMAT3 (i.e. the same as for newer Zoom2 vehicles).

Properties: The same as for Zoom2, see also general remarks about vehicle properties.

Measures: Fzg4Len, Fzg4HoW, Fzg4Br, Fzg4HoS instead of Fxx2Xxx.

Text line always Unicode-UTF16.

Views

Structure and order same as for Zoom2 vehicles, see there. Ofcourse, the measures of Zoom4 are used instead of Zoom2.

Archive Files for Zoom4 Vehicle Graphics "bahn.fz4"/"name.fz4"

This is available for standard vehicles since BAHN 3.85Beta0 9/2008.
For user-defined vehicles, it was added with BAHN 3.86Beta2 2/2011.

The handling is the same as for Zoom2 vehicles, see at bahn.fz2/name.fz2.

For creating and extracting the ".fz4" archive files there is the same simple command line software "fzgc2.exe" as for Zoom2.

Standard Vehicle Library File (bahn.fzg)

This file is stored in the BAHN system directory, i.e. at the same place as "bahn.exe".

It contains all the BAHN standard vehicles including their Zoom1 graphics and properties. It may be of interest to read it for making an Import function to copy a BAHN standard vehicle into any other software.

The data structures are similar to .nfz files. However it stores many more vehicle sets and vehicles. Further, the data are a mix of some older data formats.

The "bahn.fzg" is language-independent, i.e. it does not contain text data. Instead, there are numbers that reference lines in the "bahn.lnv" text data file or the respective ".lnv" file for other languages, as selected by the user.
The numbers are not direct line numbers, but logical numbers. For details look at a ".lnv" file: Any line of text has a unique number standing before.

If not stated otherwise, then and limits are the same as for .nfz data.

Contents Overview
  1. Header
  2. Seek list of vehicle sets
  3. "Compatibility Vehicle Sets"
  4. Vehicle sets, each consisting of up to FZGF_MAXFZGZAHL vehicles.
  5. For each car: Vehicle control data
  6. For each car: Views (at minimum 6, but also 8, 10, 12, 14 up to 16)
Contents Details
Header
NameTypeContents / Values
VspBYTE[] Printable text, terminated by Ctrl+Z (26), see here
Ident_CodeBYTE[3] = {'F', 'Z', 'G' |0x80 }
File format versionBYTE[2] = 0x38, 0x50 or 0x38, 0x53 or 0x38, 0x55
for 0x3850, 0x3853 and 0x3855, same as for .nfz files
Seek Table pairs of WORD16 = Set Number
and WORD32 = Position
see below

The seek table is a list of all vehicle sets in the file, for quicker search. If you find a vehicle set number in the table, then seek directly to the seek position to get the set.

The terminator is a set number == 0, not followed by a seek position.

"Compatibility Vehicle Sets"

Beginning with WORD16 Set number. This can be used to check whether you did seek correctly.

Set number is 1..4096.

This type is needed for opening older layouts (before BAHN 3.83). It doesn't contain vehicles, but information by what vehicles of 3.83 the old ones should be replaced. Not of interest here, so omitted here.

Normal Vehicle Sets

After reading the file offset, set the current file pointer position relative to this offset to reach the vehicle set data.

VersionNameTypeContents / Values
AllSet NumberWORD16 = the same as above (useful for testing correct position)
= 5000..65000
AllfzgzahlWORD16 = number of vehicles in the set
= 1..FZGF_MAXFZGZAHL
AllsgrnrWORD32

Mask for pre-selection (Category). This is a combination of the following bits:

#define SGR_STRAB_D 0x00000001 -- tram, DE
#define SGR_STRAB_T 0x00000002 -- tram, Tatra/Skoda (CZ)
#define SGR_STRAB_EURO 0x00000004 -- tram, EU
#define SGR_STRAB_WELT 0x00000008 -- tram, World
#define SGR_SBAHN 0x00000010 -- commuter service railway
#define SGR_UBAHN 0x00000020 -- subway/metro
#define SGR_EB_TW 0x00000040 -- railway MU
#define SGR_EB_DLOK 0x00000080 -- steam loco
#define SGR_EB_ELOK 0x00000100 -- el. loco
#define SGR_EB_VLOK 0x00000200 -- diesel loco
#define SGR_EB_PWG 0x00000400 -- passenger car/coach incl. baggage
#define SGR_EB_GWG 0x00000800 -- freight/goods car
#define SGR_BUS 0x00002000 -- bus
#define SGR_OBUS 0x00010000 -- trolley bus
#define SGR_SCHIFF 0x00004000 -- ship
#define SGR_BAUTECHNIK 0x00020000 -- service/maintenance

not (more) used here:

#define SGR_HILFDAT 0x00001000 -- special data (BAHN internal)
#define SGR_NUTZER 0x00008000 -- user-defined

At least one bit is set, in some case multiple bits are set.

Allset nameINT32 A text number for the .lnv file
(in formats <0x3850 WORD16 instead of INT32)

The vehicles of the set follow.

Vehicle
File VersionNameTypeContents / Values
AllFzgLokNrBYTE

= Local number of the vehicle in the set 0..FZGF_MAXFZGZAHL-1 The number must be unique inside the set. Order and gaps are dont-care.
(In former data formats, this number was defined by the order of the vehicles in the set. In result, when deleting one vehicle from the set, all the following vehicles had been renumbered.)
This number defines the last 2 digits in the .fz2/.fz4 Zoom2/4 vehicle filenames.

Note: There were versions of NFZ-Edit where the Import function ignored this value and used the simple order instead. That resulted in some wrong assignment of numbers, e.g. when creating a Zoom2 gfx file for a standard car. In that case, you need to rename the resulting file manually.

AllFzgLenWORD16 = Length in pixels horizontally scale 1:1, MIN_FZGLEN..MAX_FZGLEN
For details see also measures and limits
AllFzgHoW1WORD16 = Height (horizontal view) MIN_FZGHO..MAX_FZGHO
AllFzgBr1WORD16 = Width (vertical view) MIN_FZGBR..MAX_FZGBR
AllFzgHoS1WORD16 = Height (vertical view) MIN_FZGHO..MAX_FZGHO
AllEigWORD32 = Properties ZGGEIG_xxx, the same values as in .nfz vehicle properties
>=0x3855Graphics format WORD16[2]

Graphics format of the vehicle, as in .nfz files (Format + Subformat)

for older file versions: Set Format=ZOOMXFZGFORMAT385 and Subformat=ZOOMXFZGSUBFORMAT3

AllSteam infomixed = BYTE count + triples WORD16[3*count] as in .nfz vehicles
AllText dataINT32[MAXTEXTZAHL]

Text data for the vehicle, as numbers in .lnv file

#define MAXTEXTZAHL 5
#define TXTNR_UNDEF 0

All lines except the first one can be TXTNR_UNDEF to define an empty line.

The graphics data follow, depending on the properties ZGGEIG_xxx and on the measures read before.

When ZGGEIG_24BPP is set, then the same as in the .nfz files:
32 bit per pixel, packed, views as for (version == ZOOMXFZGFORMAT385)

When ZGGEIG_24BPP is not set, then the "old" style is used:
8 bpp, not packed, color palette and special colors as defined for old user-defined gfx (.ufg files).
However, the ZGGEIG_FRONT2 property of BAHN 3.83 is supported.

Vehicle Graphics, Old Style (.ufg)

With BAHN 3.83, this format was replaced by .nfz format, but it is still supported to load older user-defined vehicles.

An .ufg file holds graphics data of a vehicle set of up to 8 cars. The additional data like properties and texts are stored in an .uzz file of the same name. For correct loading, both files must exist and suitable.

Data blocks consist of "MiniSprites" MSP1 and MSP2:

An MSP1 consists of 14 lines of 8 Byte each. Each byte represents 1 pixel, colors see 256-colors scheme. The both bottom lines (14+15) do not exist here because there are tracks and sleepers. Since BAHN 3.80 the tracks moved up to the symbols center, but the principle did not change, because the output of vehicles was shifted up too.

Further here are "vertical MiniSprites", in the follwing called MSP2. Consisting of 4 lines with 8 byte each, similar to MSP1.

In both MSP, lines follow from top down.

Each vehicle consists of 4 views: Horizontally left and right sides, and vertically front+roof and rear+roof. There are no extra front + rear views, i.e. the vertical height = 0 compared with newer formats.

The views are made by assignment of MSP (MSP1 for horizontal, MSP2 for vertical). In result, vehicle length is possible only in steps of MSP1 (8,16,24 pixels etc.). The most vehicles have been drawn in a way that they fitted into this limit. But, there are exceptions where the gap is filled by transparent color. For these, you should prevent coupling on the gap side, by using suitable vehicle properties in the .uzz file

In principle, one MSP can be used multiple inside the same vehicle, and also by multiple vehicles inside the same vehicle set. That was common in older BAHN versions for standard vehicles to use less main memory. For instance, many bidirectional cars used the same MSP1 for their right and left view. However, AFAIK the editors for user-defined vehicles never supported to use this optimization because of the complicated handling, resulting in longer but more simple files.

Length (in MSP):

#define MAXFSYMLEN 32 (since BAHN 3.59 Beta7 1999-10-24)

Examples:

The MSP are counted from 0..63, separately for MSP1 and MSP2. In result, a vehicle set can contain at max. 64 MSP. As told above, the multiple use of MSP inside a vehicle or set was not supported by known editors. In result, the summary length of all the vehicles of a set is limited to 64 MSP. This is the reason why the number of vehicles per set may be limited to less than 8, when the cars are too long.

Numbers of user-defined vehicle sets:

#define NUTZERFMSPSATZNR_MIN (4000 << 4) // minimum set number)
#define NUTZERFMSPSATZNR_PRODATEI 10 // number of sets per file)

Since BAHN 3.75, use always the set numbers 4000 to 4009. Depending on the position of the file in the list of .ufg files, BAHN maps these numbers to correct values (e.g. file #2 set #4002 becomes 4022 in the layout file).
Until BAHN 3.70, the numbers 4000 to 4095 could be used freely. However, any known versions of FZGEDI/CAREDI/GE used 4000 to 4009 and created data that are compatible with the new definition.

File structure
Header and Seek Table
NameTypeValueMeaning / Remarks
HeaderBYTE[]Text, ANSI, terminated by Ctr+Z (26) see file header text
IDENT_CODEBYTE[5]{'F', 'Z', 'G' | 0x80, 0x35, 0x09} identification code (since BAHN 3.59Beta4)
Seek Tablemixedpairs of {Set Number, File Offset} Table for quick search with lseek(), see following lines
Set NumberWORD16 logical set number (set number in Bit 15..4, i.e. Bit 3..0 = 0000) 0 == end of table, no WORD32 follows
valid set numbers (NUTZERFMSPSATZNR_MIN>>4)..4009,
see remark above, numbers used for standard-data in bahn.fzg sets 1..3999
File OffsetWORD32 offset from here offset for lseek() for accessing the data set, from position behind the WORD32
Data Blocksmixed Vehicle graphics the vehicle sets as shown in the next table

Example most simple case of a seek table (1 vehicle set only):

WORD16 Set number = 4000<<4
WORD32 Offset = 2
WORD16 end sign = 0

Data Blocks
NameTypeValueMeaning / Remarks
Set NumberWORD164000<<4 .. 4009<<4 Logical set number (same as in the seek table before, can be used for test of correct seek)
MSP1 countWORD16(1..64) | 0x8000 Number of horizontal MSP1 in the set
As marker for 256 colors (since BAHN 3.59 always) set the Bit 15 additionally (| 0x8000)
Example: 0x8009 for 9 MSP1 in 256-color-scheme
MSP2 countWORD161..64 Number of vertical MSP2 in the set
Vehicle countWORD161..8 Number of vehicles in the set
Sym data lengthWORD16>=5 Length of symbol data in Byte:
Each car consists of 4 views of the same number of MSP each, see above.
Examples:
A car of length = 3 MSP consists of BYTE[1] = Length in MSP, and BYTE[4*3] for the views, in result 1+4*3 = 13.
A set of 2 cars with length = 2 MSP each: 1+4*2+1+4*2 = 18
TextBYTE[]ASCI, end = '\0' (dont-care text, is ignored, never really used)
Symbol dataBYTE[Sym data length]MSP numbers For all the vehicles of the set, details in next lines for each car
LengthBYTE1..MAXFSYMLEN Length of the car in MSP
Right side (to East)BYTE[Length]0..63 each Assigned MSP1 to this view, from left to right (i.e. reverse to travelling direction!)
Front side (to South)BYTE[Length]0..63 each Assigned MSP2 to this view, from top down (i.e. reverse to travelling direction!)
Left side (to West)BYTE[Length]0..63 each Assigned MSP1 to this view, from left to right (i.e. in direction of travel)
Rear side (to North)BYTE[Length]0..63 each Assigned MSP2 to this view, from top down (i.e. in direction of travel)

Further, the MSP numbers can get one of the both following bit masks:

#define FMSPDAMPF_ANFG 0x80 (Steam begin)
#define FMSPDAMPF_ENDE 0x40 (Steam end)

_ANFG creates steam in an angle area around a virtual chimney. _ENDE creates steam in a rectangle area and may be arranged multiple side by side. Normally, mark the MSP with the chimney as _ANFG, and the next one[s] with _ENDE, where _ENDE may be omitted in case of small locos. In the front view, the marking should be moved by 1 or 2 MSP to top, because the chimney is displayed more above.

Graphics Data

After all vehicle assignments, there follow the graphics data. First all MSP1, then all MSP2, one after the other, without separator or terminator.

They consist of BYTE[pixcount] where one byte represents one pixel as in 256-colors.

Calculation of picxount:

(Number of MSP1) * 14 * 8 + (Number of MSP2) * 4 * 8

Vehicle Set Data, Old Style (.uzz)

With BAHN 3.83, this format was replaced by .nfz format, but it is still supported to load older user-defined vehicles.

An .uzz file holds additional data of a vehicle set of up to 8 cars. The graphics data are stored in an .uzz file of the same name. For correct loading, both files must exist and suitable.

BAHN does no more allow to offer complete trains consisting of single vehicles (as in BAHN 3.20). In result, the 2 files and 2 sorts of "vehicle sets" are obsolete, however they are still in use for some compatibility reasons (with 3.83 replaced by new .nfz format).

Range for user-defined vehicle set numbers (per file at max NUTZERFZGSATZ_PRODATEI):

#define NUTZERFZGSATZ_PRODATEI 10
#define NUTZERFZGSATZ_MIN 50000

Max. Length of name of a vehicle set incl. '\0':

#define ZUGGNAMESIZE 22

There are at max. NUTZERFZGSATZ_PRODATEI user-defined vehicle sets.

File structure
Header and Seek Table
NameTypeValueMeaning / Remarks
HeaderBYTE[]Text, ANSI, terminated by Ctr+Z (26) see file header text
IDENT_CODEBYTE[3]{'Z', 'G' | 0x80, 'G'} identification code
Seek Tablemixedpairs of {Set Number, File Offset} Table for quick search with lseek(), see following lines
Logical NumberWORD16 NUTZERFZGSATZ_MIN..NUTZERFZGSATZ_MIN+NUTZERFZGSATZ_PRODATEI-1 0 == end of table, no WORD32 follows
There are at max. NUTZERFZGSATZ_PRODATEI user-defined vehicle sets.
File OffsetWORD32 offset from here offset for lseek() for accessing the data set, from position behind the WORD32
Data Blocksmixed Vehicle data the vehicle data as shown in the next table

Example most simple case of a seek table (1 vehicle set only):

WORD16 Log. number = NUTZERFZGSATZ_MIN
WORD32 Offset = 2
WORD16 end sign = 0

The BAHN-Standard-data use log. numbers of 1..NUTZERFZGSATZ_MIN-1.

Data Blocks

For each vehicle set, there is a data block. As terminator, the last data block consists of logical number 0 only.

NameTypeValueMeaning / Remarks
Log. NumberWORD16 NUTZERFZGSATZ_MIN..NUTZERFZGSATZ_MIN+NUTZERFZGSATZ_PRODATEI-1 Logical set number (same as in the seek table before, can be used for test of correct seek)
MaskWORD16 SGR_NUTZER mask for user-defined, do not use other values here
#define SGR_NUTZER 0x8000
Data lengthWORD16 variable Length of all cars of the set + Length of the texts of the set in BYTE
(without the remaining data block header, i.e. from Texte)
Number of vehiclesWORD16 variable Count of vehicles in the set
NameBYTE[ZUGGNAMESIZE] Text, ASCI (DOS/OEM-coded, inclusive '\0' at end)

Name of the set

or since BAHN3.56Beta5:
[0],[1] = 0 then [2][3] = WORD16 number of an RTX string (in LoHi-order, binary) and[4]..[ZUGGNAMESIZE-1] are ignored
resp.since BAHN3.75: the same, but LNG instead of RTX, only for LNG coding Windows/ANSI instead DOS/OEM
(However, it seems not to make sense to use it here)

gfx file countWORD16 usually = 1 Number of needed vehicle MSP files
Numbers of gfx filesWORD16[gfx file count] 4000<<4..4095<<4 see above File number[s] of needed MSP files (vehicle set numbers in .ufg)
TexteBYTE[] Text, ASCI (DOS/OEM-coded) Text lines (separated by '\0', after last one '\0\0')
  • are used by all vehicles of the set
  • length per line at max. 61 byte without '\0'
  • per vehicle up to 3 lines usable
  • multiple use of one line by more vehicles is possible

or since BAHN3.56Beta5 (for each line possible): [0] = '#' then [1][2] = WORD16 number of an RTX-string (in LoHi-order, binary)
resp. since BAHN3.75: the same but LNG instead RTX, coding Windows/ANSI instead DOS/OEM
[3] = end of line \0
(It seems it does not make sense to use it here, but in result a normal text line cannot start with '#')

After all text lines, the vehicles follow:

Vehicle
NameTypeValueMeaning / Remarks
Number of train partsWORD16 1 =number of vehicle symbols, this is = 1 since BAHN 3.3, because we have only single cars from that time
EigWORD16 some bits

Properties, OR-combined by some bits, see vehicle properties

This format knows only a subset:

  • ZGGEIG_ER (single direction car)
  • ZGGEIG_TFZ (motorized)
  • ZGGEIG_DRW (rotate on reversing, since BAHN3.4Beta 1995-07-25)
  • ZGGEIG_V (use only as first in the train, no coupling device in front)
  • ZGGEIG_H (use only as last in the train, no coupling at rear side)
reservedWORD16 0 not used
vehiclesWORD16[1] 4000<<4 .. 4095<<4 vehicles (formerly train parts) (= only one, see above)
Bit15-4 = MSP file number, see ufg files
Bit3 = 0
Bit2-0 = local number in the vehicle set (0, 1, 2, ... 7)
textsWORD16[] 0..max.count of texts Numbers of text lines of the set above, that should be displayed together with this vehicle
  • zero-based (first line == number 0)
  • at max 3 lines per vehicle
  • terminator == ZGARN_ETXTE == 0xFFFF
Example: 2,3,0xFFFF shows lines #2 and #3

Let the trains run...
Jan Bochmann