How to generate and use object libraries
Important! Please read this document carefully because there are some significant changes in the instruction format from version 2.22 to 2.32. There is a table of the changes at the end of this document.
There are also some changes in the handling of the object ID number in SCASM 2.36.
About BGL libraries
Library objects are defined in the Object Library Section of BGL files. This section is traditionally called section 10 by 3rd party scenery developers. Library objects are very memory efficient if you need to display a number of equal objects at the same time in your scenery. The disadvantage is that it is not easy to modify them.
BGL libraries appeared first in FS98 for the dynamic objects. Later we found lib objects also in CFS. CFS uses library objects also for often used aircraft parts such as propellers and bombs. Unfortunately the binary format of the FS98 and CFS/FS2K libs are not compatible.
If you have found out some interesting facts which are not mentioned in this document, please don't hesitate to send a small message to me (plain ASCII text).
Please note that SCLINK cannot handle object library data. If needed I will create an LibManager for this job. If you want to see a list of the names in an CFS/FS2K lib please use my CatGen program. (Most FS2K libs needs to be uncompressed by BGLZIP from MS)
If you do not only want to use objects from one of FS/CFS standard libraries, you have to create your own lib. It is recommended not to mix library object definitions with other BGL sections (use different source files for lib objects and your scenery). You also should not mix FS98 style objects and CFS/FS2K objects in the same library.
The new commands are as follows:
|FS98 - FS2002|
ObjID( id0 id1 id2 id3 )|
LibID( id0 id1 id2 id3 ) - obsolete
||object ID least significant value (hex)|
||object ID most significant value (hex)|
This command defines an 128 bit object ID, split up into four 32 bit hex numbers. In FS every library object is identifyed by his ID. You can chose any value you want for the ID numbers but you have to be sure that no other library object in any library BGL file uses the same value. This command is used to define the ID for the next (following) LibObj() command. You do not need to, but you can, repeat ObjID() for every object in your library since SCASM automatically increments the id0 value. This means that SCASM automatically generates consecutive ID numbers by default. Older SCASM versions increments the id3 value to generate a new ID. If you want this feature back (for FS98 compatibility reasons only!) add the following line at the beginning of your library source file:
Set( OBJID 0 )
|2.43 | (FS98) CFS FS2000 - FS2002|
LibObj( <list of named parameters> )|
- This command defines the beginning of an CFS / FS2K library object code and the library entry. Library objects are called as subroutines. So do not forget the Return command, besides the EndObj, at the end of your object definition.
The parameters are identified by name. You can omit unused parameters. For every used parameter enter its name and its value separated by spaces. SCASM recognises this new LibObj parameter format by the parameter name. If the first character in the parameter list is a number the old format is asumed.
Every library object is identified by an unique ID number. You first have to set this number with the ObjID() command.
||integer number 0 to 255, normally 0 or 100|
||the size/radius of this object in meters (int)|
||scalefactor of this object. Found values are 1.0, 0.5, 0.1, 0.001|
||Object type, purpose unknown. Typical values are:|
0x101, 0x102, 0x201, 0x203, 0x204 0x301, 0x401, 0x501
||property value, purpose unknown. According to new FS98 SDK currently unused|
Up to 45 characters to name this object. Use " if string includes spaces. This parameter is mandatory and must always be the last one in the parameter list.
- For FS2K dynamic objects use
PWR 100, SCALE 1024, TYPE 2
For FS2K vehicles use
PWR 0, SCALE 0.1 TYPE 0x400
|LibObj( pwr x1 x2 x3 x4 x5 x6 x7 x8 "Name of this Object" ) - obsolete|
Obsolete, continued for compatibility. This is the command for defining an object for a CFS object library (extended version).
Library objects are called as subroutines. So do not forget the Return command, besides the EndObj, at the end of your object definition.
- Note: SCASM will generate an error message if you try to mix LibObj() and LibObj1() in one source code, but it should always generate the correct object type. It is not tested if any version of FS can handle "mixed object format files" and their related library call commands.
||number 0 to 255, normally 0 or 100|
||16 bit hex values, purpose unknown format and amount may be changed tue to hopefully better knowledge in the future.|
||up to 32 characters to name this object. Use " if string includes spaces.|
- Found values for x parameters in CFS libraries:
||0, many values around 20 .. 30, one 1388 it seems this is the object diameter|
||0, many A, few 1, 2, two 3E8 (related to MDL objects)|
||101, 102, 201, 202, 203, 204, 301, 401, 401, 501|
- For FS2K dynamic objects use pwr = 100, x3 = 40, x5 = 2 (others 0).
FS2K vehicles: x1 = object radius?, x4 = A or 1, x5 = 400
|LibObj1( a b c d pwr )|
|a, b, c, d
||ID values (32 bit hex), purpose unknown, not tested, use numbers "1 2 3 4" for this.|
||This value is named power in the SDK. Maybe this value has somthing to do with the range of the object visibility. Allowed range is 1 to 255 (mostly found 100)|
- This instruction defines the beginning of an FS98 library object (similar to the Area() command in the visual object section). Normal BGL instructions are used to define this object. Since this object is called as a BGL subroutine the exit from this routine must be via a Return command.
- This command indicates to SCASM that an lib object ends here so some final checks, such as size checking, can be done. An FS98 library object cannot exceed 64 KB because of the FS internal header format.An FS2K/CFS library object code can be larger than 64kB (LibObj()).
- This command also increments the internal object ID counter so the following LibObj() is created automatically with the next available object ID. If you don't want to use this ID you are free to set a new one by a new ObjID() command.
|SCASM 2.32 +|
LibCat( "catalogue_file_name" )|
- Pseudocommand (this command does not generate BGL data)
Since it is not easy for humans to identify the lib objects by their 128 bit ID number SCASM now offers to use their description text. This is _exactly_ the same text as used in the LibObj(...) command. SCASM uses a catalogue file to convert the description to the ID sring.
To use this option you first have to build the catalogue (-> see my CatGen program for details) and then tell SCASM by this command to load it. This command only works with CFS/FS2K style libraries because the FS98 ones do not have a text description.
|CFS/FS2K - FS2002|
CallLibObj( x id0 id1 id2 id3 )|
CallLibObj( x "library object description" ) alternate format
This is the new library object call for CFS/FS2K. Only use this command for CFS/FS2K sceneries. It is not compatible with the FS98 version! (both use opcode 0x63 but have different length). The alternate format can only be used if you have loaded a library catalogue with the LibCat() instruction (see above). To activate an dynamic object from the dynamic scenery section please use the CallDLibObj( ) which replaces the old D_35() command.
||reserved, set it to 0 !|
||ID numbers of the wanted object (32 bit hex)|
CallLibObj1( id0 id1 id2 id3 )|
- This instruction is used in the visual section to display an object from the library.
||ID numbers of the wanted object (32 bit hex)|
- How to use an FS98 lib object from a scenery file:
This calling sequence is for an shadowed object.
PerspectiveCall( :house1 )
LayerCall( :shadow 60 )
Jump( :End )
ShadowCall( :house2 )
RefPoint( rel :house_end 0.125 LAT LON ... )
RotatedCall( :the_house 0 0 -90 )
CallLibObj1( 74736554 62694C20 1 0 )
; this calls the first lib object with index 0.
; If your lib has more objects you can increment
; the ID3 value accordingly.
- How to use an CFS /(FS2K) library object:
a typical calling sequence for an 3D object is:
Area( A 48:21:59 10:52:05 100 )
CrashIndirect( :OBJ :SHD :ROT 0 0 )
ShadowCall( :SHD )
PerspectiveCall( :PERSP )
Jump( : )
RefPoint( rel :END1 0.5 48:21 10:52 V2= 10 )
RotatedCall( :OBJ 0.00 0.00 64.00 )
CallLibObj(0 9797FC57 8A930060 11D14AC5 A028DC02)
; these 'cryptic' numbers identify the library
; and the wanted object in it
This is a typical calling sequence for an
CFS flat object:
Area( A 52:07:35 05:53:52 100 )
LayerCall( :Obj1 24 )
Jump( :End )
RefPoint( rel :End1 1 52:07 05:53 V2= 1200 )
RotatedCall( :The_Obj 0.00 0.00 -167.02 )
CallLibObj(0 9797FC57 8A930060 11D14AC5 A028DC9A)
A normal CFS 3D Object should start with the
CrashStart( :all_ok 50 )
( :no_crash 0 20 0 40 40 40 0 0 0 )
SetCrashCode( 14 )
Points( 0 ...
; the normal object code follows here...
- How to define an FS2K dynamic library object?
This is an often found startup sequence:
Header( 1 80 -80 -179 180 )
ObjId( 00C2CDA9 A9E100AA 596711D0 B1A18305 )
LibObj( PWR 100 SCALE 1024 TYPE 2
"FS2K dynamic aircraft" )
ShadowPosInd( 0 )
SuperScale( :L014 2048 15000 6 )
ShadowCallVI( :L038 18 )
RefPoint( nsi :L036 0 )
SuperScale( :L036 2048 15000 6 )
PBHCall( :L038 18 )
SetVar( 2C 25 )
IfHSize( :L288 64 2 )
Points( 0 ... )
LoadSurfaceColor( 32 )
Poly( ... )
Note: The local variables in dynamic objects seem to be the same in FS98 and FS2K. Variable 18 points to a data set containing pitch, bank and heading. Variables 30 to 28 are containing color codes. The scale factor in the object header looks very weired compared to others. Maybe it is interpreted in a different way by FS.
- How to use an FS2000 dynamic library object:
Header( 1 45:00:00 37:44:32 -85:00:00 -91:24:23 )
LatRange( 40:59:58 42:59:56 )
Area15( 42:59:56 40:59:58 -87:00:03 -89:00:01
44:22:52 38:14:06 -85:37:39 -90:22:25 )
LatRef( 41:55:00 )
Pattern( :L21B FFFFFE0 3 0 )
CallDLibObj( :L933 3 0
00C2CDA9 A9E100AA 596711D0 B1A18305 )
- Dynamic object parameter block.
There is one object parameter block for every dynamic object. The entries in this parameter block are "visible" from an dynamic library object as a local variable with the following values. It may usefull to know these values if you create your own dynamic objects.
||object position, Lat Lon Alt|
||objects pitch, bank and heading data|
||object flags, see below|
||mirror of beacon counter often masked with hex values of 0x404 or 0x808|
||slow moving prop position, 16 bit pseudodegrees (rotating angle)|
||fast prop position|
||object radius in meters|
||textured aircraft flag|
||object color 0|
||object color 1|
||object color 2|
||object color 3|
||object color 4|
||object color 5|
||object color 6|
||object color 7|
||anti collision stopping disabled|
||dawn / dusk|
||mask for density bits (0...4 valid)|
||object is considered "other traffic"|
||object is considered "service traffic"|
||object is considered "ground aircraft traffic"|
||object is considered "airborne aircraft traffic"|
- Changes from version 2.22 to 2.32 and later:
||2.32 and later
||renamed & 1 new parameter|
||new name added|
||© Manfred Moldenhauer