World Wide Guide | Knowledge BankKukushkin's Notebook | Design Fundamentals


Notes for FSASM users

This document discusses the usage of low-level BGL instructions, which work independently from the scenery assembler. While SCASM was chosen to be the "main" language of this document, low-level BGL programming can also be done with FSASM or any other scenery compiler capable of translating low-level instructions. However, there are differences how FSASM translates these instructions into their binary representations. This sections describes these differences and also some caveats in FSASM programming.

FSASM Developer's Kit (FSADK) is required in order to be able to use low-level instructions in FSASM sceneries.

At the time this document is written, FSADK is still in its beta stage. This document refers to beta 0.2. Some instruction names(!) have changed from version 0.1, and also many new instructions have been added. Instruction and parameter names mentioned in this document are SCASM names. In FSASM, most instruction names are the same, but some are different. In this text, each time a SCASM instruction is mentioned for the first time, its FSASM equivalent is given in square brackets if its name differs from the SCASM version. There is also a section in APPENDIX.TXT that lists different names. Besides instructions names, the order of arguments is often different in FSASM. These differences are described in the FSADK documentation.

FSASM doesn't use delta coordinates

Unlike SCASM, FSASM hides delta- and other low-level coordinates from the programmer. Instead, it allows (and requires) specifying coordinates in real units, like meters, or even as absolute geographical locations, and converts them into delta or RefPoint coordinates. While this greatly simplifies the development of a "high-level" scenery, it can cause major problems when using low-level instructions, because FSASM basically does not allow to specify delta coordinates explicitly.

In order to convert real units into delta coordinates, FSASM uses the scale factor of the RefPoint LAST PROCESSED BY FSASM. FSASM processes instructions in the same order as they appear in the source file. Unlike that, the actual execution order is often affected by different Call/Jump instructions. For example, the sequence

.relative LatPos,LongPos
RefPtGL RP2:, 0,0,1 ; Set scale factor of 1
Call DrawFuelBox: ; Draw a fuel box
RP2:
RefPtGL End:, ...,...,100 ; Set scale factor of 100 ... ; Draw something bigger
Jump End: ; Finished drawing
DrawFuelBox: ; Called from many RefPoints
LineColor 0f014h
MoveTo 0,0,0 ; Draw a square of 10x10 meters... or not? LineTo 10,0,0
LineTo 10,10,0
LineTo 0,10,0
LineTo 0,0,0
... ; Draw the 'F'
Return

would not work as could be expected. The DrawFuelBox: routine would actually be called with the RefPoint scale factor of 1. However, FSASM would process the second RefPoint with the scale factor of 100 before processing the routine. While translating the routine, FSASM would assume a scale factor of 100. Because delta coordinates must be integer, FSASM would round them down to 0 (10/100=0.1) in all ...To instructions. Thus, nothing would be drawn.

In such cases, it is possible to tell FSASM to assume a specific scale factor. FSASM stores the "current" scale factor in the FSASM variable SCALE. FSASM assumes the value of SCALE is given in meters per delta unit. The scale factor can be redefined like this:

SCALE = 10 cm ; set scale factor to 0.10 meters per delta unit

If you only want to change the scale factor temporarily, after which you want to restore the original scale factor, use the .PushGlobals and .PopGlobals directives. The .PushGlobals directive saves the value of SCALE and several other built-in variables on an internal stack.

Then you can change the scale factor, do your calculations, then restore the original value of SCALE by using .PopGlobals. For example,

.PushGlobals ; save SCALE SCALE = 10 cm ; set new scale
<your code> ; do your calculations using the modified scale factor
.PopGlobals ; restore the original SCALE

Note that setting the SCALE variable does NOT change the scale factor used by FS5, but only affects the way FSASM converts coordinates.

Delta coordinates are described in "How to draw primitives".

FSASM often uses directives

FSASM can evaluate complex expressions, like I=I+1. However, it is important to understand that statements like this are directives for FSASM and not instructions for FS5. The difference between a directive and an instruction is that a directive is executed by the compiler (FSASM), and an instruction is only translated by the compiler and is executed by FS5. Directives are NOT executed by FS5! Of course, some directives cause the compiler to generate instructions, but with I=I+1 this is not the case. Similarly, the variable I is a variable in FSASM and is NOT available from FS5. When FSASM compiles the code, it simply substitutes all references to such variables with their values CURRENTLY KEPT BY FSASM. Such 'compiler' variables are called 'defines' or sometimes 'macros'.

For example, the sequence

C=0f000h ; Daytime color IfVarAnd SetColor: ... ; Nighttime?
C=0f00fh ; Yes -> Nighttime color SetColor:
SurfaceColor C ; Set the surface color

would not work as could be expected. FSASM would simply substitute the last value assigned to C (0F00Fh) into the SurfaceColor instruction, so the surface color would always be set to F00Fh. Similarly, the statement

RefPoint 50*sin(vTimer1*pi*/180), 50*cos(vTimer1*pi*/180), 8 nm

would simply cause FSASM to substitute the address of vTimer1 and calculate (constant) RefPoint coordinates. Nothing would rotate, of course.

Some other differences

Unlike SCASM, FSASM does not allow jumping to the end of a Group?R block simply by using ':' instead of a label reference. For such jumps, a label must be inserted before EndGroup and used in jump instructions.

Unlike SCASM, FSASM allows to embed exclusion information into the main BGL file using the AreaExclude instruction in section 19. However, doing so would leave the user no opportunity to remove this information or change it. For this reason, exclusion information must always be put into separate BGL files, even if FSASM allows doing it otherwise.


Last updated 11 October 1996 by Gene Kraybill.