Intro
Ralf-J. Triebel and me, Andreas Klisch, we both regard some
knowledge of scasm maro programming as being essential for
making good 3D-objects.
Even if the macro was made with a good tool like FSDS, Nova, EOD
oder VOD.
With the help of a simple texteditor like notepad or wordpad one
can make amazing good objects by handcoding. MAT´s "scasmEditor" as well works like a texteditor, but is optimized for
working with scasm code. It provides important enhanced
functions like searching for terms, input of complete command
lines via menues and ready code-templates for many complex
topics. But to handle it perfectly, one will need some basic
knowledge in scasm-programming. But even a complex CAD-pogram
like FSDS can be handled better with knowledge about scasm and
3D-Fsim-rendering, to avoid problems and use all options. And if
one has macros written with an old tool like VOD, on has to
fiddle around with the code anyway to make it compatible to the
new Fsim-versions like FS2000/CFS2/(FS2002).
This thread is not an official tutorial for the scasm compiler.
Nor can it replace reading the scasm-documentation (scacmd~.doc,
coming with scasm).
But this paper shall provide an insight into the structure and
mechanism of 3D-objects. Especially for newbies, but not only
for those, the original scasm documentation is sometimes
cryptical to read and difficult to understand. We hope, this
will change after having read this document.
It contains several so called hyperlinks. By clicking on an
underlined word or text part you will be linked to the
concerning section which explains the topic in detail.
What is scasm doing at all?
Microsoft´s Flight Simulator was developed in a way that the
user can add scenery to the default. These sceneries are
contained in so called "bgl"- files, with extension ".bgl". They
contain binary coded hex-number rows, which are passing over the
commands for this scenery to Flightsim.
These commands are also called "opcodes", because every command
is only existing as a hex number with additional hex parameters.
This makes execution fast and the bgl file size small.
Scasm is a so called "compiler-program". It "translates" a
textcode which is readable for human beings into this binary hex
code, which can be read and executed fast by FSIM. The primary
text program code cannot by executed by FSIM.
But it is readable by us and, hopefully, logical. At least this
document should help.
This
assembler-like
textcode
was
developed
by
Manfred
Moldenhauer, the author of scasm.
It lists the original hex commands (opcodes) decrypted in form
of ASCII-text. A file with such text is called "sca-input-file"
with file extension ".sca".
Not to forget it, scasm is not the only existing compiler
program, but there are also "FSC" und "FSASM", and the Scenery
Developement Kit (SDK) compiler tool provided by Microsoft
themselves.
FSC is orientated to scasm and is mostly compatible with scasmcommand code. But FSASM is using an own textcode language,
somehow more modular orientated, using very often predefined
functions of its own FSASMLIB.dll.
Currently a new version of FSASM is under construction.
The Microsoft tool could not really introduce itself to the
designers. This is because most scenery design programs are
basing on the scasm compiler, but also because the documentation
in the MS-SDK is in many cases cryptical and incomplete.
Why does one need design programs?
Design programs do a lot of work for us. They e.g. produce
commands for placing scenery objects on a WYSIWYG-virtual
program surface and actually only do produce sca-input-textcode.
So a scenery designer must not know all scasm commands, but can
partially rely on these programs. The input sca-code provided by
the scenery program is then compiled by scasm.
There are design programs which generate runways, streets,
roads, rivers, and which can place the 3D-objects made by us
into the scenery: ASD, Airport, FS-SC, Architect, Groundmaker
are well-known.
And there are other programs which make 3D-objects. These
programs as well generate sca-code, but as macros, which are
placed and included by a scenery design program ( ASD,
Airport...) and included into the scenery-sca-code.
What is a scasm-macro?
A scasm-macro is a module which has been written in the same
scasm input code language as the sca-input textfile. But the
input-file is calling this macro and includes its text with the
correct parameters. So the scasm macro can contain all usable
scasm commands.
This document is referring to macro design for CFS1/2 and
FS2000.
Partially it is valid as well for FS98 and older, although it
deals with several commands and options which won´t run under
FS98 and older.
Macros with „api“-format ( with extension .api ) are common. As
well as the „scm“-format, the macro-Format of ASD (Abacus
Airport and Scenery Designer). The most important difference to
the api-format is the handling of the user- variables, see
below. I am always referring to the api-Format here because it
is the most popular.
And I recommend to get scasm in the version at least 2.46,
better 2.50, as delivered e.g. with Airport 2.60 or FS-SceneryCreator.
An api-Macro is actually a text file for scasm containing
commands of all the elements of a 3D-object to binary bgl-code.
Basic elements of a 3D-macro
If one has understood the meaning of these basic elements, one
is already familiar with 3D-design. We are starting with
something basical.
What is a loop, and what is a variable?
If one is experienced with Basic, VB, Pascal, C++ or so, one can
skip this section. But there is no need to be a programmer to be
able to write a scasm-macro. Only some knowledge about the
mechanism of these two elements of a program belongs to it, or
the whole stuff will be too difficult.
A loop is actually a part of a program causing the processor to
execute some commands repeatedly, until the condition for
aborting the loop is fulfilled.
One can illustrate this by the example of a train which is
driving on a circle all the time. The switch to leave the circle
is only set to "exit", if a counter has verified, that the train
has circled 50 times. The counter gives a message to the
processor: „variable n is now 50 !!!!!“ The processor,
administrating the value of this switch-variable, now provides a
command for the switch. The switch is set, and the train moves
over to the straight track.
Here we also have explained what a variable is. Variables
contain dynamic changeable values which determine the execution
of a program. Because these values are dynamic, they are no
fixed values in the program, but the program causes the
processor to keep these values into the memory, to read it or
change it under certain conditions. A changed variable content
can change execution of the program by determining execution of
the loop.
And the program itself can change the content of the variable
and determine its own execution.
A variable always consists of a variable name (=index) und the
variable-content. In our railway example the variablenname is
„n“. There may exist other variables, and they must be
identified properly. Variable-content is any number which the
counter passes over to the processor.
Variable-index und content are saved in the computer memory as
long as the program is working. The content of the variable is
accessable by the programm with read- and write- operations.
A "hanging-up" program which does not react to mouse and key
inputs is always caught in a loop. For some reason (programmbug
or any other error) the loop cannot be terminated, and the
programm is turning around itself like a hamster in its wheel.
Such can also happen with scasm-programming. Although the scasmcompiler tries to check the macro for severe bugs. One is
getting the typical "End without EndA" error-log messages then.
But the compiler cannot check all possible bugs, and then
Flightsim can "hang" or "crash". This can be annoying, but I
cannot imagine that any harm could be done to the computer or
the Flightsim installation, because the worst which can happen
is is that you may have to restart the computer and remove the
buggy bgl-files from your addon scenery folder. But more often
it will be the case that FS runs and that only the object won`t
show up at all or show up with visual bugs.
A bgl-file is actually a loop. Because the Flightsim program is
checking if the condition for the execution of the bgl is
fulfilled at all. If the aircraft is moving around the North
Pole, the "NewYork".bgl will be skipped and not rendered by the
3D-engine, because it contains a condition that it is only to be
executed if the distance from its scenery reference coordinates
is below e.g. 30 miles.
Within this bgl-loop there are contained additional loops. These
loops always start with the "Area(...)"-command and contain each
the commands for one scenery object.
The processor can leave this Area loop only if all its commands
are executed and terminated. Only then it can go over to process
the next scenery object.
It is important to know that each bgl file and, within it, each
scenery object is processed in a strict successive way. How fast
this will happen, meaning how often per second (=framerate) a
new processing circle can be started, depends on the computer
performance and on the complexity of the scenery.
This means that with e.g. a framerate of 10 fps all commands
contained within a bgl can be executed 10 times in a second.
Each scenery object contains an exit condition for its area
loop. This condition checks if the distance between object and
viewer is below a limit which was selected for this object. If
the viewing pilot is too far from the object, the loop is
terminated before executing any visual object commands. This
improves the framerate performance in complex sceneries. Even if
the scenery is loaded and active, not all its objects must be
executed necessarily all the time.
A macro is actually a module part to be included by the compiler
to the binary scenery data file as an object loop.
Important for getting into macro programming is also the term
"subroutine". A subroutine is a separated subordinated part of a
program. It contains command modules which have to be execuded
repeatedly during execution of the program. This makes the
program code shorter because it is no longer necessary to
include the same code parts a hundred times and more.
This subroutine can be called from another part of the main
program then.
Another reason for including a subroutine may be that some parts
of a program must be loaded to a separated array of the computer
memory.
User-variables
The user variable determines properties of the scenery object.
In a macro one can code visual commands, e.g. having Flightsim
showing up a red polygon area of 5X5 metres.
But such a macro should be valid to be included in many
sceneries. The compiler must know e.g. where on earth the object
should show up. It needs coordinates, latitude and longitude
Because the user does not want to handle such long number
collumns and rows all the time, the designprograms take over the
work for him and pass over the coordinate values to uservariables.
The latitude coordinate is then contained in the user variable
%1, the longitude in %2.
We can find these variables in the macro-code, in the area
definition and reference point:
Area( b %1 %2 %3 )
That´s the area definition...
RefPoint( 7 :h3 %4 %1 %2 v1= %10 %13 %14 )
that´s the reference point.
In our design program, we have shifted the object to the place
where it should be, using the mouse.
The design program calculates that here e.g. is latitude N 48
deg 30 min and longitude E 7 deg 50 min.
Now it stores these values to the user variables %1 and %2, and
includes the macro by passing over the values in the macro call
command, so that later on the scasm compiler can write the
appropriate fixed values to the bgl code.
User-variables are always identified with the „%“ (percent-)
sign.
Important to know:
These user-variables have nothing to do with Flightsim program
variables!
This always leads to misunderstandings. The variable indices
„%X“ are only referring to the program environment of the scasm
compiler. They contain values which only scasm can work with.
The scenery desing program is responsible to fill in the proper
values to the macro calling command as fixed parameters.
By the macro calling statement
Macro(
c:\games\design\macros\mynewmacro.api
N48:32:46.8137
E007:38:36.1377 20 1.0 50.0 0 0 0 0 10000 0.0 0 v2= 100 0 0 0 0
0 0 )
the correct user parameters are contained from %1 up to %15 as
fixed values here. So, whenever scasm finds a %x in the macro
code, it can fill in the correct value and compile the object
with this fixed value to bgl-code.
This macro call is done for each 3D-object after having placed
it with the design program.
It is possible to do some simple arithmetic operations with the
user variables. Very often the user variables determine a colour
of the object. We can write a macro which sets a red or any
other color, depending on the selection the user defines in the
menue when placing the object in the design program.
The design program can pass over the colour value e.g. to the
user var %6. If we want bright blue, we select "07" to the
parameter %6. The design program then passes over this "07"
within the macro calling command line.
Then scasm can read the command "SurfaceColor( %6 F0 )", but it
writes into the bgl: "SurfaceColor( 07 F0 )", because the
expression "%6" cannot be understood by Flightsim.
If a user-variable is used in a macro, but is not filled by the
designprogram, scasm passes the value with "0" (zero) to the
bgl-code.
A user variable can also content string values. It may be that
in a macro you don´t want to use a fixed texture but want it to
be selectable by the user via the selection menue in the design
program. Now we can replace the filename by "%6". If we write
"asphalt.r8" to the parameter %6, scasm fills this in when
working with the command, and it compiles
LoadBitmap( 0 5 ef 0 0 0 asphalt.r8 )
to the bgl file.
In the macro we wrote:
LoadBitmap( 0 5 ef 0 0 0 %6 )
But in all cases the content of the user presets must fit to the
concerning commands using the preset user variables. Scasm is
checking that, and errors are reported by the scasm error log
messages.
A common error appears if a floating point value is filled in to
a user variable where the concerning command perhaps can only
work with an integer value.
In this case we are getting an "integer parameters expected..."
error message.
One can avoid this by enhancing the expression e.g. %6 with the
term int[ %6 ].
Now on all cases scasm is rounding the value to an integer.
This is an example for a simple arithmetic calculation scasm can
perform with the user parameters.
One can do tricky calculations with the user parameters. This
should be used more often in macro design.
We can combine a user variable with a calculator expression,
e.g. "%7*2". For complex calculations we can include the
expression into square brackets. Within these square brackets we
can include additional square brackets. Note that scasm does not
respect any "* / before + -" rules, so you should include
additional brackets to separate expressions.
One example: int[ %6*[ sin%5 ] ] calculates the integer value
from %6 multiplied with the sinus of %5. See the scasmdocumentation.
One can also generate comparing operations with user variables.
These operations are often used to determine properties of the
macro.
It is e.g. possible to cause scasm to compile the next lines
only if the user variable content fits to the condition of this
comparing operation.
That is the meaning of the "MIF" command. Note that "MIF" cannot
generate a Flightsim executable loop, but only gives instruction
to scasm to compile the following lines to bgl if the condition
in the mif-bracket is true. This conditional compiling of lines
is valid until an "MIFEND" statement is found. Below this
command ending the comparing operation the normal macro code
compiling is continued.
Every MIF must have a MIFEND. The MIFELSE command is optional
and determines alternative following lines to be compiled if the
MIF condition is false.
Mif, Melse and Mifend will not appear as FSIM commands in bgl.
They only determine parts of the macro code to be included or
excluded. This is a common source of misunderstandings.
Partially the user-Variables are predefined and used by the
design-program. When inserting a scenery object, there are wellknown menues asking for visibility range, coordinates, altitude
and all that.
So, although there are 20 user variables accessable by scasm,
you cannot use all freely.
There are some variables usable for determining user-colours and
so on, if the macro had been programmed that way.
Such free user variables with the api-macro-format are:
%6, %7, %8, %9, %15, %16, %17, %18, %19, %20.
Airport as well as FSSC and Architect can store values which
were set by the macro user here. These variables are free
accessable to determine object properties.
These are the user variables which are already preoccupied by
the design program:
%1 latitude
%2 longitude
%3 area range
%4 scale
%5 rotation angle [deg]
%10 long-range-visibility V1
%11 object altitude
%12 lower scenery density limit for object display
%13 „V2= “ (for traditional reason...)
%14 radial visibility V2
Scasm-environmental variables
These variables contain values which the scasm-compiler can
process similar to the user-variables. By no means they give
access to Flightsim variables. Similar to the user-Variablen
they are only referring to the scasm program environment. But
they are not set by the design program, but by a direct
predefinition command in the macro.
Very often they are used to peform complicated operations with
the user variables and to store the result of this operation.
This scasm-variable can then by used to replace a parameter
setting in a scasm command.
The scasm variable always consists of the index with „$“as
identifier and the content which is set by the command
Uvar( $name expr )
The Uvar-command does not generate bgl-code, but works only in
scasm environment.
„$name“ can be any sign string, the var can e.g. be named
„$Mycolor1“.
„expr“ can be a number or a string. One can also fill in a
calculator expression containing user variables here.
For example:
Uvar( $xshift [ cos[ %5 ]*-200 ] )
The scasm variable is also interesting in connection with a Mifcommand. This way one can set default values for user
parameters, if the user has forgotten to fill in the values:
Mif( %6 )
compiles commands from the following lines only, if %6 is not = zero
Uvar( $col1 %6 )
sets parameter %6 into $col1
Melse
compiles commands from the following lines only if %6 is = zero (if
condition in Mif... is not true)
Uvar( $col1 04 )
if &6 was forgotten, set $col1 to 04( white color)
Mifend
ends the comparing operation and tells scasm that now the normal macro
code is continued
SurfaceColor( $col1 F0 )
the colour command, here containing the scasm variable $col1
The macrolines after the Mif-command are compiled by scasm only
if the condition which is contained in the MIF-brackets is true.
If it is not true, then the lines after the Melse command are
compiled.
Melse is optional and not always necessary.
But after every Mif scasm exspects a Mifend, because Mifend ends
the comparing operation.
After the Mifend, the macro is compiled in the normal way.
Global FS-variables
Flight Simulator saves the content of many global program
variables which are necessary for execution into the memory of
the computer.
Working with these variables in scenery is something for
advanced designers.
Some vars (by no means all!) can be read by scasm commands, and
some few can be overwritten. Which ones and what they mean can
very sparely be read in the Microsoft SDK and also in the scasm
documentation.
Such a global variable consists of an index und its content. The
index names the hex-offset of the variable in memory.
With global FS-variables the scasm-compiler or Flight Simulator
cannot perform calculations, at least not within the area object
loop.
There are only comparing operations possible, meaning that
within the object loop the content of global variables can be
read from memory and be compared with a predefined condition (
IfVarRange, IfVarAnd ).
The content of a global variable can also be overwritten from
the object area loop with the SetVar command. But one should
know what one is doing, because FS can likely crash by misused
SetVar commands. There are only some few globals which can be
overwritten without problems.
A calculation operation known from programming languages, e.g.
Set n=n+1
is unfortunately not possible in scenery commands.
The globals are referring to the whole FS-programm environment
and are not specific for the concerning 3D-object calling for
them.
Although reading and setting global vars can open up interesting
opions.
Somebody has programmed a panel gauge switch setting a global
FS-variable which can actually be read by scenery bgl IfVarRange
commands and influence visual effects.
A common application for reading a global variable is the timecode.
Here the FS-internal daytime-variable with index 028C is
queried. If its content is between 2 and 4, then it is
dusk/dawn/night, and the object loop can execute predefined
commands which are placed behind the line
IfVarRange( :skiplabel 028C 0002 0004 )
This is very often used as a "nightswitch", to enable night
lighting options. This command line means that following lines
are only executed if the condition is true (night). If not, a
jump to the label :skiplabel is executed, and the night commands
are skipped.
It is also common to read the preset FS-scenery density from the
variable 346.
An example for overwriting the variable content is setting the
„crashcode“. Here the FS-internal variable „ 284“ is overwritten
with the value „14“. Now FS shows the well-known "crashsequence" (boum...bang....splash....aaaargh....ouch):
SetVar( 284 14 )
„14“ means „crash with building“. Of course this requires a
precondition,e,g. a „Monitor3D“ area, otherwise one will always
"crash", if only the object becomes visible!
This MonitorTr will be described in the enhanced section of the
document.
Local FS-object-variables
A very special topic.
Many macro designers don´t know that such really exists. I
really mean variables which can be accessed and which are valid
only for the concerning scenery object!
The FS-global-vars 390 and others cannot perform that. Because
they are not keeping the content reliable and can easily be
overwritten by other sceneries or different objects from the
same scenery.
But in an object area it is possible to reserve an own memory
array and use it for local variables. This memory area is
administrated by Flightsim and can be accessed with read- and
write operations.
This opens up interesting options of macro programming. Because
now different scenery objects can influence each other, and
object parts can be moved by predefined switched animation
processes.
This special topic is worked out in the enhanced section of the
document.
The object area
Flightsim must know up to what distance range all the commands
which appear in the scenery object are to be loaded into the
computer memory.
One can say that Flightsim has a separate object"buffer" to
define which objects at all are existing in the bgl.
It may be that one has generated an extended wide bgl, e.g.
50X50 miles. Because now not all the scenery objects can be
visible, FS loads an object list to memory. This object list
primary only contains a remark that this object does exist at
all.
The actually visible commands of the objects are not loaded into
memory. This happens only if one is nearing to the object. The
simulator repeatedly checks the distance between viewer and
object, the object "area".
This range is determined within the "Area..." command. The area
command somehow rings the bells and tells Flightsim that the
object does exist.
Therefore such an Area command must be placed on top of every
macro.
example:
Area( 5 %1 %2 %3 )
That´s a common example. We can place such a line in the
beginning of every macro. „5“ is a cryptic number setting a
priority to the object buffer. "b" instead of "5" seems to cause
a higher visibility priority, the object is loaded into memory
earlier.
In FS2000 the visibility of 3D-objects seems to be limited to
around 20 miles maximum.
The "area" command also tells Flightsim that we have a visible
object.
It must not necessarily be a 3D-object, also commands for
runways are starting with this Area command. There are also
other types of area commands, but within this document they are
not so important, because we want to make 3D-objects.
%1 and %2 are user-variables for the coordinates, as described
above.
%3 is the user-variable for the kilometer-range for the
described object buffer.
If the viewer is outside of this object area, the object does
not reside in memory with all its visible commands, but only in
form of a hint that it does exist at all. After this, we are
telling Flightsim the lower limit for the scenery density preset
up to which the object should be visible:
IfVarRange( :no_display 346 %12 5 )
This command line must not necessarily be contained in a macro,
but it does make sense.
IfVarRange ... 346 queries the content of the global FS-variable
346 („szenery density“). The %12-user-variable had been set in
the design program, e.g. to "2" (=normal). Here it determines
the lower limit for the variable reading operation.
If the variable is outside 2-5, the whole object will not be
displayed, because FS will at once jump to the label
":no_display" which we should add in the end of our macro code,
immediately before the EndA command.
So the FS-user can determine himself if he wants our object
showing up, or if his computer is so slow in performance that
he´d better switch off this and other objects with the scenery
density preset of Flightsim, to enable flyable framerates.
The macro end
:no_display
EndA
These two lines are all we need to end a macro code.
The label „:no_display“ is the platform to land on if the range
test for the scenery density failed.
"EndA" tells the compiler that now our programmed code for this
scenery object ends. The EndA-command is not compiled into bglcode. Flightsim does not know such an opcode at all. But scasm
demands it as a certificate that the macro ends here.
Each macro must be terminated with the "EndA" command.
Again, we can see the modular property of our macro. There is no
real "end-of-file"- signal as there is in other programs, but
our macro will be included as a module to the scenery library.
The Jump( : )-command in the starting sequence of the macro
causes
the
program
to
jump
to
this
macroend,
if
all
macrocommands are executed. These macrocommands are contained
into an own subroutine.
The label
One can imagine a label as being like a hyperlink-object on a
website.
If one clicks on a marked object of a website, one is linked to
another site or section.
Like here in this document all the time.
Someting similar happens with program jump instructions. The
program execution jumps to another section of the program, or a
subroutine is loaded and executed.
With a jump-command ("Jump") or with a subroutine call ("Call")
the program is directed to the place (=label) where to jump or
where to load the part from.
In a macro, a label must always be identified with a ":" sign
and its name.
So it is introduced with
:labelname
where "labelname" can be any combination of numbers or strings,
but no special strings like $,%,/ and so on, and no blank spaces
usable. The "_" (underscore) is allowed.
A labelname must not be used more than once in a macro.
Which name the label has, does not really matter. One can call a
label e.g.:
:mygrandmadrivesonamotorbike_in_the_hencage_a_1000_Honda
that is of no interest for scasm. Anyway scasm renames the
labels into up-counting hex label numbers when compiling to bgl.
But for reason of readable macros the labels should be named in
a logical senseful way.
And once the label has a name, this name must be called and used
exactly this way when calling it or referring to it in other
scasm-commands. Respect high and low characters.
The reference to a label in other commands must always be done
with this ":" and the correct labelname.
Loop and jump commands
Jump( :labelname )
causes the program to jump to the marked „:labelname“ code section.
If the name of the label is not specified, but if only ":" is on
the bracket
Jump( : )
the program jumps to the end of the macro, i.e. to the EndAline.
This "Jump( : )" line can often be found after the
"PerspectiveCall" in macros. After the macro commands are
executed, the program jumps to the macroend, therefore here a
labelname is not needed.
Call( :labelname ) or
Call32( :labelname ) .... ->32-bit-command, better in long
macros
Loads the lines after
:labelname
as a subroutine ( subroutine ). This subroutine is ended at the
place where a
Return
command is found.
The Return command causes the program to jump back to the line
situated immediately after the "Call( :labelname )" calling
line.
Important:
Such a subroutine must not contain a new "Area".
The subroutine must be terminated with the Return-command.
„Return“ causes the program to jump back to the line immediately
after the subroutine calling line, like the "back" button at a
webbrowser.
And normal program execution is continued.
Note that the subroutines should be separated from the main
macro code structure, otherwise the subroutines will be executed
once more...! -In most cases, one will hide the subroutines
behind the "Return" command which ends the main macro structure,
placed
between
this
"Return"
and
the
":no_display"/EndA
instruction.
A simple example for subroutines:
Call32( :loadcolor )
Call32( :drawpoly1 )
Call32( :drawpoly2 )
;..and so on, other macro commands...
;blahblah...
Return
;Important! Macro execution ends here.
;now our subroutines, as parts separated from the main code:
:loadcolor
SurfaceColor( 0F F0 )
Return
:drawpoly1
Poly( a 1 2 3 4 )
Return
:drawpoly2
Poly( a 5 6 7 8 )
Return
< p>
:no_display
EndA
In a subroutine, it is allowed to call again a new subordinated
subroutine.
But do not „Jump“ from outside the subroutine into a label which
is contained within a subroutine!
The Return command always terminates a subroutine.
Additional
to
the
Call-/Call32-commands
there
are
the
TransfomCall and RotatedCall, and also PerspectiveCall and
ShadowCall, as explained below.
These
commands
also
refer
to
a
subroutine.
But
the
PerspectiveCall performs a perspective correction with the
commands included in the called label, and the RotatedCall
rotates a pointsystem included in the called label in all three
room axes. Additionally, the TransformCall can move (shift) the
pointsystem in all axes.
A forgotten „Return“ and misplaced "Jump"-instructions are
common bug-traps in macro programming which are often hard to
detect, especially for beginners, but which can cause mad
results up to Flightim-hangups or program crashs.
But also a "Return" too much can cost framerate-performance.
The Perspective Call
This is what a typical macro start code sequence looks like.
I have added comments with „;“ All behind the ";" is ignored by
scasm and not compiled. See the special scasm commands section.
Area( 5 %1 %2 %3 )
IfVarRange( :no_display 346 %12 5 )
;these two lines were explained above
PerspectiveCall( :h1 )
;this line is needed to enable 3D-rendering.
;The label :h1 is called as a subroutine and perspectivecorrection is enabled.
ShadowCall( :h1 )
;this line generates ground shadow. Leave it out, if not
wanted.
Jump( : )
;Jump instruction to leave the object area (jumps to the
EndA-line, after all commands are executed)
;a very important line, because FS will hangup if missing.
Loop without termination then!
;.............. hereafter the Reference point and visual commands will be
added.
We can see that this starting sequence is again a loop. The
other commands of the macro (Referencepoint a.s.o.) which are
described later are included in thesubroutine :h1. This
subroutine is called by the PerspectiveCall. PerspectiveCall and
ShadowCall are special forms of the Call-command. They are
always referring to a subroutine.
The reference-point
and visibility
with
coordinates,
altitude,
scale,
Hereafter, we must tell FS, where on earth the symmetric zero
center of the new to be created virtual 3D-pointsystem should
be. And at what altitude above sealevel it should be. And from
what distance-limit the object should be visible.
And its size. One can determine here, that e.g. it should appear
with its doubled size as it was planned in the pointsystem.
The definition of the visibility range defined here is once more
clearer as in the Area-command. It was explained above that the
Area-command tells Flightsim to load the object commands into
memory if the viewer is within the distance range. The
reference-point contains a second, sharper condition. If this
condition test fails ("false"), the object commands, although
loaded into memory, are skipped and not executed.
The reference-point must be a subroutine ( :h1 ) of the start
sequence, so that it is always called by the PerspectiveCall
from the startsequence.
:h1
;Perspective
;the "Perspective"-command is obsolete for FS200 and higher, according
to the MS-Scenery-SDK, and can be left out. I deactivated the command
by the";".
;this label
Shadow-Call.
mif( %11 )
:h1
is
called
by
the
PerspectiveCall
and
;this is a comparing operation with the user-variable %11.
;the compiler checks, if an altitude definition was done in the design
program, and - depending on this - determines several macro properties.
Mif( %11 ) checks, if %11 is equal or not equal to zero. The line after
"Mif( %11 )" is only compiled to bgl, if %11 is not equal to zero.
RefPoint( 2 :h3 %4 %1 %2 v1= %10 E= %11 %13 %14 )
;if an absolute altitude definition exists, if %11 is not zero, the
Refpoint-type 2 will be used. It is using the “E= %11“ parameter with
absolute altitude setting in metres ASL. Regardless to the terrain
altitude, the object will always be placed at this altitude. The other
parameters of the RefPoint are described in detail below.
melse
;melse tells what to do, if %11 ( altitude) = zero
RefPoint( 7 :h3 %4 %1 %2 v1= %10 %13 %14 )
;then the RefPoint Typ 7 is going to be used.
;this RefPoint7 will always place the object on top of the terrain.
;so it won´t need any altitude setting.
mifend
; end of the comparing instruction
RotatedCall( :h2 0 0 %5 )
; here the point system and the visual commands are called as an own
subroutine :h2. We are using the RotatedCall because we want to allow
the user to rotate the object around the vertical axis at the angle the
designprogram passed over with the %5 user-variable.
:h3
;important! Here our RefPoint subroutine is terminated if the object
fails to pass the range check contained in the RefPoint command. The
RefPoint contains a hidden Jump-instruction, causing a jump to the
label :h3, if the distance between viewer and object is larger than
defined in the V1 and V2 range definition in the RefPoint.
Return
;important! Here the RefPoint-subroutine ends. A jump to the line after
the PerspectiveCall will be performed and loop-execution will be
terminated with the Jump( : ) instruction.
The syntax for the three possible types of RefPoints is:
RefPoint( 7 :h3 %4 %1 %2 v1= %10 %13 %14 )
RefPoint( 2 :h3 %4 %1 %2 v1= %10 E= %11 %13 %14 )
RefPoint( 3 :h3 %1 %2 v1= %10 E= %11 %13 %14 )
By example of the RefPoint7-command we will now explain the
parameters of the RefPoint.
RefPoint( 7 :h3 %4 %1 %2 v1= %10 %13 %14 )
RefPoint( 7
Typ: 7 means relative altitude reference. The object will always be
placed on top of the mesh terrain. There is also the type 2 ( siehe
oben ), where an absolute altitude definition is contained. There the
object will be placed at the altitude defined in E= %11, regardless to
the terrain altitude; and type 3 , which also contains absolute
altitude setting, but no scale definition. This RefPoint( 3 ...) is
especially used for small complex objects. It fastens the 3D-engine of
Flightsim, if the scenery contains many high detailed 3D-objects. The
scale definition is performed serparately with the SetScaleX-command,
because this RefPoint type3 has scale-definition in its parameters.
RefPoint( 7 :h3
a hidden jump-instruction to subroutine (label) :h3, if the condition
for the distance viewer-object is not true. Then the RotatedCall which
calls the 3D-points and the visual object commands is skipped and the
macro is terminated, at least for this framed loop execution.
RefPoint( 7 :h3 %4
The scale definition. One can also type 1. Then the object will always
appear at the size given by the pointsystem. The 3D-pointystem is
basically a 3D-one-metre-grid. At scale 1, two neighboured 3D-points
are always 1 metre apart from each other. If one wants to allow
flexible handling of the object size, one should type %4 here. The
user-Variable %4 ( scale ) is set by the design program in the macro
placing menue. The scale changes the object size proportionally. The
user can also fill in floating point values, like 0.25 or 1.8476. With
very small and complex objects, one can use e.g. 0.1 here. Then the
detail accuracy of our object is 10 centimetres. That means that two
neighboured 3D-points are at least 10 cm apart from each other. This
detail-resolution is also called
"RefPoint-units per metre."
The smaller the scale, the higher the detail accuracy. Drawbacks of
small scales 0.1 and below:
-if in a scenery much complex objects are using scale 0.1 and
below,
the
framerate
performance
will
decrease,
Flightsim
"stutters" with graphic display.
-visibility of the object in FS2000 will only be up to a very
short range ( ~ 2-4 km max ), reagardless to the „visibility
range“-values entered in the design program! To avoid this all,
it is recommended to use the RefPoint type 3 for complex objects.
Refpoint( 7 :h3 %4 %1 %2
These are the user-variables %1 for latitude and %2 for longitude, as
set in the design programm. Flightsim is told where on earth the center
of the new 3D-point-coordinatesystem is. That is the referencepoint for
our object.
Refpoint( 7 :h3 %4 %1 %2 v1= %10
v1 is the „long range visibility“ of the object, the limit for the
visibility when viewed from distance.
If the range limit which the design program stores in the user-variable
%10 is exceeded, the RotatedCall is skipped and the macro terminated in
the label :h3. The object is not rendered and shown up then.
Syntax-hint: respect the blankspace (" ") between v1= and %10.
Refpoint( 7 :h3 %4 %1 %2 v1= %10 %13 %14 )
Instead of %13 %14 one can also type: v2= %14 (respect the blankspace!)
, the meaning is the same. For some reason of lazy tradition, not
having to write "v2=", one user variable was sacrificed and the
expression "v2= " was fixed in %13. This was kept for reason of
compatibility.
v2 means „radial visibility“. That is a bit difficult to explain: If
the viewing pilot passes the object, he will of course leave it behind
somewhen. Now v2 defines a radius in metres enabling the object showup
until it is really passed by. Normally this v2 value will somehow be
identical with the largest horizontal size extension of the object.
This information is needed in the RefPoint. If this limit is exceeded,
the RefPoint reacts according to v1-exceed: the RotatedCall is skipped,
and a jump to the label :h3 is performed and the loop execution
terminated.
The task of the v2-definition is to prevent Flightsim from having to
calculate and render objects the pilot is actually turning his back to.
The %14 user variable is calculated by the design-programs, in most
cases reliable.
According to the scasm-documentation v2 is an optional parameter in the
RefPoint.
But it is not recommended to leave out the v2-definition because the
framerates will decrease.
The 3D-room
For generating visual object parts virtual points are needed.
These
points
are
coordinate-system.
placed
in
a
virtual
threedimensional
The most important point of this coordinate-system is the
reference-point which we have defined above.
In most cases the reference-Point lies on top of the 3D-terrain,
otherwise the object will float in the air, or some parts will
be "buried" below the ground.
Therefore in most 3D-objects we will not find negative z-pointcoordinates.
In latitude and longitude direction, the reference-point should
describe somehow the symmetrical (as far as possible) center of
the object.
To this RefPoint our virtual coordinate-system is calibrated to
zero.
The grid size of this coordinate system is always 1 metre, if
the scale in the RefPoint was set to 1. With other scales, the
grid size changes proportionally.
This means, at scale=1 the smallest possible object size is
1x1x1 metre, because its points must all be at least 1 metre
apart from each other.
At
scale=0.1
the
smallest
possible
object
is
10x10x10
centimetres. Detail accuracy will be 10 centimetres.
This grid-size (size of a RefPoint-unit) determines the possible
detail level of the object and should be respected first before
planning the pointsystem. For large objects like buildings very
often a grid size of 1 metre is sufficient.
For small and detailed objects like vehicles 10 centimeters are
required, often even less.
The
x-axis
lies
in
west-east-direction.
west=negative,
east=positive values.
The
y-axis
lies
in
south-north-direction.
south=negative,
Nord=positive values.
The z-axis moves from downside to uside. downside=negative,
upside=positive values.
Some will detect that the conventions for z- and y- direction
differs from common cad-design programs and also from FSDS. I am
referring to the scasm- und Microsoft-convention to avoid
confusion.
As already said, the RotatedCall-command can turn the whole
coordinate-system around all the three axes. But that is only
important when placing the object into scenery and does not
affect 3D-design-planning. So we are looking at the point-system
always in its normal angulation.
The virtual point-system
In this imaginary virtual 3D-room we are defining 3D-points,
according to some rules. These points are required to enable
Flightsim to execute any visible command.
For all these commands there must exist 3D-points.
We need a „virtual point-system“. The points defined here will
not be visible in Flightsim but provide a reference coordinate
grid system. Between these grid points Flightsim can execute the
visible commands.
Any visible command like „paint a surface...“ ("Poly...") is
always working with these 3D-points. One cannot tell FSIM: „show
a 6 metres large red surface at 3 metres altitude, angulated 30
deg eastbound“. No. Every detail must be predetermined: „... you
have four points. The first at (x/z/y)-coordinate –3/3/-3. The
second at –3/3/3. The third 3/2/3. The fourth 3/2/-3. Now define
a surface color with RGB-color-value 255 0 0, that´s red.
Then show a surface between these points.“
The scasm commands would look like this:
Points( 1
; new pointlist! 1 means: point with index number 1 as the first
point
–3 3 -3
; point with index number 1 at x: –3 z: 3 y: -3
–3 3 3
; point with index number 2 at x: –3 z: 3 y: 3
3 2 3
; point with index number 3 at x: 3 z: 2 y: 3
3 2 -3
; point with index number 4 at x: 3 z: 2 y: -3
)
;end of pointlist. The points are defined.
RGBScolor( ef 255 0 0 )
;load a surface colour with this RBG-color- value for red-greenblue, each ranging 0->255. 255 = max. intensity for the
concerning colour channel.
;“ef“ in the bracket means „not transparent surface“ =opaque
Poly( a 1 2 3 4 )
;show a surface ( polygon ) with this colour between the points
No. 1,2,3 and 4
;the surface is 6X6 metres large: x-extension 6 m, y-extension 6
m
;we have defined the pointsystem this way, for this macro
Of course such a point-system can consist of more than these 4
points. Pointlists with 100 points and more can often be found.
A macro can have more than one pointlist. With complex macros,
we will likely have more.
A new pointlist can start with point index no. 1 again.
But the corresponding visual commands (polygons) must occur
immediately after this pointlist, without any new initialized
pointlist.
A new pointlist may also be started with another index no. than
1.
E.g. one can type: „Points( a 23 ..... ). Does not matter. If
only the polygon and other commands are referring to the correct
point indices.
The
actual
polygons
visible
object-elements:
points,lines,
Every 3D-object in Flightsim consists of only three types of
visual commands:
point ( dot ), coloured, at position of a virtual point
line, coloured thin straight line connecting two virtual points.
polygon ( poly ), a surface between at least three virtual
points, filled with a colour or a texture. There are several
subtypes.
In FS2000, the dot is a visible coloured point with a graphic
halo-like rendereffect around. It always appears with the same
brightness, regardless to the daytime. The colour must be
assigned with a line-colour-command (RGBLcolor, LineColor).
The line connects two points. Its colour command is the same as
for the dot.
The poly is a surface lying between given virtual 3D-points. A
polygon needs at least 3 3D-points. But it may have more, e.g.
12 points. But this does occur very seldom. In most cases, a
poly will have 4 or 3 points.
If the polygon has more than 3 points, one has to take care that
it is planar. That means, its surface must be plain, not concave
or convex. Of course the surface may be angulated in all three
axis, if it is only plain. One must respect this when planning
the object and the points. If it is not possible to create a
plain e.g. rectangle, then one should subdivide the poly into
two triangles.
The polygon must not necessarily be of regular geometric shape,
it can be an irregular trapezoid, pentagon, or of any shape with
a plain surface.
If one wants a rounded object surface, it is only possible by
adding multiple rectangular and triangular plain polygons,
similar to a facette insect eye. The more polygons, the more
perfect rounded will the surface appear in Flightsim.
We all know that the new FS-aircraft-models with 12-pointrounded fuselage are looking better than the old 8-point-tubes,
where the edges were significant. But together with the number
of points, the number of polyons will increase dramatically. And
this amount of polygons in an object will determine the
performance of Flightsim, because every polygon costs computer
performance.
One can foresee that a scenery consisting of 20 objects
containing more than 2000 polygons will run stuttering under
Flightsim, like a "slideshow".
One should always remember: good object-design in Flightsim is
not identical with 50,000 polygons. Because we are in a dynamic
simulation, we must search for the best compromise between
detail level and framerates.
One can very often find sceneries which are splendid in detail
level, but unusable for a flight simulation, even on a highperformance-computer.
How does one create complex object shapes? A sphere consisting
of 8X8 3D-points looks nice in FSIM. But having to handcode its
pointsystem will be some good work. One would have to calculate
the coordinates of every 3D-point with the geometrical circleformula. Oh, sing a song of joy... how was that with pi and r2
...? And all that 64 times.
It is not too difficult to handcode a cube object. 8 points, one
can imagine that. And 5 polygons, because the downside of the
cube will be identical to the terrain level und not visible
anyway. But a sphere? Or a castle with towers, arches, corners
all around? That could last months to handcode that.
For this purpose we need 3D-object design programs. The most
well-knowns are FSDS (FS-Design- Studio, Abacus), NOVA2000
(Rafael Garcia Sanchez) and EOD (Easy Object Designer, Matthias
Brueckner).
Sometimes these programs are also useful to create object parts,
whose code can easily be implemented into another main code.
The most common visual scenery element is the polygon.
The scasm-command for a poly just reads
Poly( a 1 2 3 4) .
„a“means that the viewing vector of the polygon points away from the
RefPoint. This means, the polygon is visible from outside the object. If the
polygon should be an inner wall, visible from inside, we must write: „ai“
(i=inverted).
This viewing vector gives a 3D-room-angle (polar-coordinates) orthogonal to
the surface of the polygon. This value is important for the exact rendering
in Flighsim. But scasm can calculate the values for us, if we use the "a" or
"ai" Form. One can say, with "a" or "ai" the presign of the vector is
changing.
„1 2 3 4“ refers to points which we must have described in the pointlist
above. The visual surface will ly between these virtual points.
There are several subtypes of polygons. Of course one can not
only generate a coloured surface, but also a surface filled with
an image (texture).
These commands are all explained in the enhanced second part of
the tutorial.
Additional commands: colours, transparency,image loading
a.s.o.
Every visible object command has always one or more additional
commands, required to be executed properly.
For example, a polygon needs the information, which colour it
shall show. Or which texture it should display. Or if it should
be partially transparent (glas-effect).
Again, these additional commands will be explained in detail in
the enhanced second document part.
Simple macro example – coloured cube
First, we only want to build a simple cube, to illustrate the
program structure of such a macro. We make a cube with a colour
selectable in the design-program.
Afterwards every single step is explained by hyperlinks - just
click on a marked code part.
The cube is added as "cube.api" in the document-subfolder
...\api.
;/////////////////////////cube.api///////////////////////////
Area( 5 %1 %2 %3 )
IfVarRange( :no_display 346 %12 5 )
;do not display object if scenery density very sparse or sparse
;Objekt nicht anzeigen bei vorgewählter Szeneriedichte sehr gering oder gering
PerspectiveCall( :h1 )
ShadowCall( :h1 )
Jump( : )
:h1
;"Perspective"-command was omitted, because obsolete for FS2000
;der "Perspective"-Befehl ist ab FS2000 überflüssig und wurde hier deaktiviert
mif( %11 )
RefPoint( 2 :h3 %4 %1 %2 v1= %10 E= %11 %13 %14 )
melse
RefPoint( 7 :h3 %4 %1 %2 v1= %10 %13 %14 )
mifend
RotatedCall( :h2 0 0 %5 )
:h3
Return
:h2
Points( 1
-25 0 -25
-25 0 25
25 0 25
25 0 -25;4
-25 50 -25
-25 50 25
25 50 25
25 50 -25;8
)
SurfaceColor( %6 F0 )
;the user selects the color in Airport/FSSC with %6
;e.g. "F0" for %6 gives a bright red color
;alternative for FS2K/CFS could be: RGBSColor( ef %6 )
; then the user should type e.g. 255 0 0 for %6 to have e.g. a red color
;Der Anwender kann die Farbe in Airport/FSSC mit %6 wählen
;z.B. "F0" in %6 ergibt rot
;Alternative für FS2K/CFS: RGBSColor( ef %6 )
Poly( a 1 5 8 4 )
Poly( a 2 6 5 1 )
Poly( a 3 7 6 2 )
Poly( a 4 8 7 3 )
Poly( a 5 6 7 8 )
Return
;end of object code, Ende des Objektcodes
:no_display
;byebye and good night
EndA
The basic structures of 3D-macros are all very similar. If the
mechanism is clear, one can use templates of the scasm-editor,
e.g. the "normal object template" for almost all cases. One
"only" has to add own points and polygon program code then.
Enhanced explainations of the macro:
RotatedCall
The RotatedCall calls the label :h2 and turns the virtual pointsystem around the vertical (z-)axis according to the presets
stored in the user-variable %5.
:h2
Here starts the subroutine with the points and visual
commands.
This label was called "h2", one can name it different. But
then the labelname in the RotatedCall must be renamed with
this new name.
Points( 1
Here a new pointlist starts, and the first used point is
the point with index No. 1.
-25 0 -25
That is the first point, No. 1, and its related
coordinates: x(-25), z(0), y(-25) If all three coordinates
for a point are defined, the compiler knows, that a new
point will come now; here = point No. 2 and so on. It is
recommended to start a new line for each point definition
for reason of readability.
)
Do not forget this bracket! It tells the compiler that our
actual pointlist ends here.
;4
Just a comment that this is point No.4. Not necessary, but one
can often find this. And it makes sense to mark the point
indices this way, from time to time, for reason of readability.
SurfaceColor( %6 F0 )
;The traditional colour command.
This is an old command and will cause compatibility
problems in one of the next new simulator versions. The MSSDK tells that they "try to fade this command out".
The first parameter in the bracket contains the actual
colour-code. This colour code refers to the old FS5-„direct
colors“ which are still compatible in FS2000/CFS2. They are
hex-coded, causing the strange values. 0F e.g. is bright
red. One can find out the colours in the macro placing
menues of the design programs. -Or look at that picture.
Note that these direct hardcoded FS-colours will no longer
be supported in next Flightsim versions. CFS2 still
supports them, but I do not know, if FS2002 will do so.
Here %6 is typed in as a user-variable to let the user
select the colour in the design program. E.g. „0E“ would be
blue. F0: The second value in the brackets defines the
properties of that color code. „F0“ means that we are
referring to the direct FS internal colours. An alternative
is „68“. Setting a kind of transparent glass-effect. But color coding is tricky then. We must type in the
hexagesimal value from the desired colour index of FS5.pal.
I would rather recommend to use the new RGBSColor command
for such cases.
RGBSColor( ef %6 )
The new CFS1/2/FS2000-command for colour coding. The
alternative to the SurfaceColor-command. Loads a colour for
polygons and applys transparency.
It is recommended to get familiar with this command, and
use it instead of the old "SurfaceColor" command.
With this command, we can define any wanted colour. The
colour will be additive-mixed from the three basic computer
monitor colours red, green, blue ( R G B ) with values each
between 0 and 255.
0 means 0-intensity for this colour, 255 means maximum
intensity. From these three basic colours all colours can
be generated by mixing their index values. E.g. yellow =
255 255 0,
bright blue = 100 100 255 , black = 0 0 0, white = 255 255
255, orange = 255 150 0 etc.
One only has to know the principle of additive colour
mixing. Here yellow is generated by a mixture of red and
green
with
equal
intensity.
That
differs
from
the
subtraktive colour mixing we know from e.g. aquarell paint
colours.
With the scasm-editor, FS-Scenery-creator, and FSDS one can
select these 8-bit-colours very easy by selection menues. I
can´t imagine why other design programs still have not
implemented this.
One is speaking of 8-bit-colours, because the three basic
colours with each 256 values have 8 bit information depth.
That´s what our computer monitors can show.
Example for a grey colour: RGBSColor( ef 80 80 80 )
ef means „total opaque“, i.e. the poly surface is dense
opaque; e0 would be total transparent. Then we would see no
colour at all, regardless which one was selected with R G
B. Best for transparent glass-effects is e.g. e2 or e3. The
strange
nomenclatura
is
due
to
hex-coding
of
the
transparency level.
Here "%6" is typed in as selection user variable. Then the
user must type e.g. „255 0 0“ (with blankspaces!) for red.
Poly( a 1 5 8 4 )
Here we draw a polygon between the points 1,5,8, and 4 . We
must have loaded the colours with RGBSColor or SurfaceColor
before, otherwise the poly will be black. „a“ means
automatic vectorcalculation by scasm. I.e., scasm compiles
to bgl-code the correct values for the viewing direction
angle of the polygon. This polygon will be seen from
outside in FSIM, we want this. If the polygon were an inner
wall in a house, visible through transparent windows, we
must type "ai", meaning "automatically inverted". One can
say, the presign of the vector changes then.
Rule for a/ai vectoring: A polygon, whose viewing direction
points away from the RefPoint, must have vector "a".
A polygon, whose viewing direction points in the direction
to the RefPoint, must have the vector „ai“ .
This is valid regardless to any presigns in 3D-pointcoordinates.
If we want to see both sides of the polygon, the command
line for that poly must be repeated with changed vector
parameter. Then one poly with "a" and one with "ai" vector
parameter must exist, for example:
Poly( a 1 5 8 4 )
Poly( ai 1 5 8 4 )
Additionally to automatic vector calculation by scasm it is
possible to insert direct vector values as numbers, instead
using the "a" form.
But then we must calculate the vector polar 16bitcoordinates ( -32767...32767 ) for each axis with correct
presign, and type in four values here: length, x,z,y.
FSDS and Nova/VOD are using this „m“-Form, because they are
better in vector-calculation, than we are.
This looks e.g. this way:
Poly( 0 32767 0 100.00 1 5 8 4 )
I am only mentioning this for reason of completion, you
won´t
need
manual
vector-calculation
when
handcoding
objects. The a/ai-options will be sufficient for all cases.
The points do not need to be mentioned in clockwise order.
And it does not matter, which point is mentioned first. But
the points must be called in a logical order following the
outer edges of the polygon. E.g. „Poly( a 1 8 4 5 )“ would
be wrong, in our case. „Poly( a 5 8
correct, as well as „Poly( a 1 4 8 5 )“.
4
1
)“
would
be
Return
Here the subroutine „:h2“ where our points and polygon
commands are situated ends. This subroutine was called by
the RotatedCall from the RefPoint- subroutine, which was a
subroutine of the PerspectiveCall. After terminating these
two loops the macro is ended in the „Jump( : )“ line. do
not forget this Return.
:no_display
The program jumps to this label from the start sequence if
the scenery density was set by the user to a value lower
than in %12. The macro will be terminated at once, because
neither
ReferencePoint
nor
visual
commands
will
be
processed. A fast skip-exit.
End_A
This command will not be translated to bgl-code. It does
not exist in FS. but the scasm-compiler demands it as a
certificate that the macro is terminated here.
special scasm evironmental commands
A very common command is the „;“ (Semicolon).
If within a macro line this semicolon is found, scasm ignores
the whole rest of this line. All what is hidden behind a
semicolon
will
not
be
compiled
to
bgl.
This is usable to append comments to have a better insight
through the macro code.
Additionally, there are som "secret options" connected with the
semicolon, which are not yet too common. Airport and FS-SC can process
certain pseudo-commands which are hidden behind the semicolon.
They are not intended as scasm or bgl-Fsim-commands, but they pass over
important informations about the macro to the scenery design program.
Informations which make handling of this macro easier.
E.g. the macro-programmer can place default presets for the userparameters, which can of course be overwritten by the user.
Read about this „macroheader“ in a special section here.
It is something to give the final finish to a macro, to make it
perfect.
All blank lines are ignored by the compiler. This is used to
make the code more readable.
There are some special commands which show the content of the
scasm environmental variables during compiling. Mainly used for
debugging. But this is too special here, see the scasm docs.
But more important are pseudo-commands enabling long macro code.
These are used if the area-memory and linebuffer of scasm is
exceeded, what may happen with long complex macros e.g. of
static
aircraft
models.
Set( Areamx 64 ) increases area-memory to 64 kB
Set( linbuf 64000 ) increases line-buffer 64 kB
These two commands can be set to the top of the macro code if
one gets scasm-errors telling that "linebuffer" or "area memory"
are exceeded.
Macroheader
This is the syntax of the new api-macro-header as processable by Airport 2.60 and FS-SceneryCreator.
Developed by Tom Hiscox and the beta testers of Airport.
;macrodesc [title]
sets a description of the macro-title (text)
exmp: ;macrodesk hangar with closed doors
;defaultscale [scale]
sets the default scale for the obj. exmp: ;defaultscale 0.5
;defaultparams [%6val],[%7val],[%8val],[%9val],[%15val],[%16val],...,[%20val]
sets default parameters instantly filled in to the 3D-menue not used parameters separated by ", ," exmp:
;defaultparams 04,0B, ,01,abc,0.32,27 note that this example sets defaults for %6,%7,%9,%15,%16,%17.
;paramdescr [%6text],[%7textl],[%8text],[%9text],[%15text],[%16text],...,[%20text]
sets help texts for a parameter description appearing in the 3D-macro-menue exmp:
;paramdescr door-color,roof-color,int. color
;defaultrange [range]
sets V1-range of visibility in meters prevents newbies from setting a range of 50 kilometers
exmp:
;defaultrange 8000
;defaultdensity [level]
sets default scenery level. [level]=very dense, dense, normal, sparse, very sparse. exmp: ;defaultdensity
very dense
;designshape [x1],[y1],[x2],[y2],[x3],[y3],[x4],[y4],...,[x12],[y12]
gives points for a design outline APT will draw as a shape representing the object on the drawing surface.
Enables showup of complex objects in APT. Max. 12 points allowed.
The old shape display is still supported, if such a line is not contained in the macro header.
Exmp: ;designshape -2,-8,-2,8,2,8,2,-8
this will define a 4X16-meter-rectangle for APT.
;textures [text1file],[text2file],[text3file],...,[textnfile]
lists up the textures needed for this object. List is read by APT's distribution list feature.
Makes sure that no texture-upload will be forgotten.
exmp: ;textures VOD28.pat,Airpt005.oav,mytex.bmp
general rules:
No space between the semicolon ";" and the identifier word (;paramdescr).
After identifier word, space or comma to first parameter.
E.g. ";defaultscale,0.5" is correct as well as ";defaultscale 0.5".
After each parameter must be a comma.
Spaces are ok but are included in the parameter, such as 'total height'.
No need to put in extra commas at the end.
Need to put in commas in the middle if leaving a parameter out, e.g. length,,total height, color The defaults are
initially filled in by APT, but can of course be overridden by the user.
Hexagesimale Zahlen
Mit Computern hat es schon etwas lästiges auf sich. Ein Computer
arbeitet nicht im Dezimal-, sondern im Hexagesimalsystem. Das
liegt daran, daß seine Speicheradresen in eben diesem System
kodiert sind, und die Lese- und Schreibzugriffe darauf aufbauen.
Daher
muß
sich
ein
Programmierer
mit
hex-Zahlen
auseinandersetzen.
Wenn man eine dezimale in eine hexagesimale Zahl übersetzen
will, kann man das am besten mit dem Windows-StandardTaschenrechner tun. Man öffnet ihn in der "wissenschaftlichen"
Ansicht, gibt z.B. eine normale dezimale Zahl ein, und klickt
dann auf "hex". Und sofort erscheint der Wert als hex-Zahl.
Beispiel für hex-Zahlen:
dezimal
hex
1
1
2
2
3
3
4
4
5
5
6
6
7
7
8
8
9
9
10
A
11
B
12
C
13
D
14
E
15
F
16
10
17
11
...
...
256
100
512
200
Appendix
Details for debugging
FS-crash or hangup
During compilation, the scasm compiler checks the macro for
severe bugs, e.g. forgotten „Return“ commands and others.
But scasm cannot exclude all possible errors, and so it may
really happen that Flightsim will crash or hang after the
installation of a new macro to scenery.
Then one should check:
Is it really the macro which is responsible? –Remove the macro
from the scenery design project and generate a new scenery bgl.
If now after an FS-restart FS works o.k., the macro was really
causing it.
Then check the RefPoint and PerspectiveCall for any rubbish or
misplaced code, e.g. for misplaced "Jump" or forgotten "Return"
lines.
E.g. a misplaced „Jump( : ?label )“-instruction can cause FShangups. Check if there is any Jump-Instruction which jumps
inside
to
a
subroutine
(
not
allowed
).
Another reason can be a misplaced "Jump" in the PerspectiveCall. It is possible, instead to write
(Jump : )
e.g. to type "Jump( :end )". But then such an :end –label must
really exist, immediately before the "EndA", and not somewhere
within the macro. This would be a "loop without end", causing a
hangup.
Also "IfVarRange"-tests can cause FS-hangups, if the IfVarRange
test defines a loop without a possible condition to leave the
loop.
I can only describe
possible
Just one example:
it
in
general,
there
are
hundreds of
bugs.
:Starttest
IfVarRange( :test1 30A 0 2000 )
Call( :example1 )
:test2
IfVarRange( :test3 30A 2000 3000 )
Call( :example2 )
:test3
IfVarRange( :Starttest 30A 3000 5000 )
Call( :example3 )
Return
Although the "Return" to end the Schleife is contained, this
loop can never be terminated because with values in the variable
30A (timer) lying between 5000 and 65534 the loop is connected
to its start all the time, to the label ":Starttest". Here the
loop is turning in itself, like a "Hamster in the wheel", and FS
will hang!
Do not forget to check if every subroutine is terminated with
the Return-command.
The object does not appear at all in FS
Unfortunately, there may be several reasons.
Check:
Was the macro really be placed correctly in the scenery design
program?
Altitude? Scale? Visibility-range? Coordinates?
Is the bgl installed correct and the entries in the scenery.cfg
correct?
Was
the
FS-presetting
for
the
scenery
density
set
to
"sparse/very sparse", so that the object does not appear because
it contains a density-check? There have been designers spending
whole evenings and halfnights over such a "self-cheat".
Then check the Area-Call and RefPoint if there is any junk or
rubbish code contained.
If PerspectiveCall and RefPoint are coded correctly, in a way as
described above, you should see at least anything, or I shall be
named "Meier". ;-)
A misplaced Jump-instruction may cause an early jump to the end
of the object code, before any visual command could be executed.
I cannot be more precise, because there are thousands of
possible ways to place bugs.
Another case may be that the object is using a RefPoint3, which
reqires absolute object altitude setting [m ASL]. Perhaps this
setting was forgotten when placing the macro, so that the object
is "buried" at zero sealevel below the terrain.
The object
transparent
is
visible,
but
it
appears
black
or
It is most likely that you failed to install one or more texture
files required for the object.
Or maybe the texture files are misnamed, differently from the
names in the texture loading commands.
The texture files must be in the „...\texture“-subfolder of your
addon-scenery or in the main "...\texture"-folder of Flightsim (
normally not recommended ).
For VOD/NOVA/Airport-objects,the concerning textures belonging
to the macros must have been installed. These could as well be
installed into the main FS\texture-folder, because then they
have to be installed only once and can be used by all sceneries
calling for them.
The object appears too small or too large
Was the scale-parameter for this macro set correctly in the
scenery design program?
If so, and if the size of the object in FS won`t change although
you tried it with different scales, then the reference-point of
the macro, as currently coded, does not allow any changing of
the scale-factor at all.
Then try to change the RefPoint-code. Instead e.g.
Refpoint( 7 :?label 1 ....... (as well as 1 here could
appear any fixed number, actually setting a fix scale!)
one can type
RefPoint( 7 :?label %4 ........
. Then one can change the scale via the macro placing menue of
the design program.
Do not forget to read the section about the reference-point.
The object disappears already at short viewing-distances
Mainly a special FS2000-problem.
In FS2000, the long-range-visibility (V1) is decreased badly if
in the RefPoint a scale of 0.1 and lower is used.
One can try to use higher %10 -values. But that will only
partially lead to success. In any case, the visibility will not
be better than ~3-4 miles.
The only way round is using RefPoint3 together with SetScaleXscaling.
Especially when working with FSDS-generated macros, read this
section.
The object dissappears too early if the viewpoint turns
or passes by
Please read the section about the radiale V2-visibility .
This problem should normally not occur because Airport/FS-SC
calculate V2 reliable and fill in the proper values to the uservariable %14 ( V2 ). But if in the RefPoint not „%13 %14“ or
„V2= %14“ does appear, but e.g. „%V2= 10“ or so, then v2 was set
too low. Type here: „%13 %14“ .
Some object parts appear to be distorted
If this is the case, check the pointlist in detail. One mistyped
coordinate is enough, and all polygons using this point are
distorted.
Perhaps a polygon-command is referring to one or more pointindex-numbers which do not fit to this polygon as intended.
Maybe the displayed texture seems to be distorted. Then the
pixeloffsets applied in the TexPoly- command does not match to
the
polygon
shape.
Try
to
redesign
the
pixel-offsets.
It is a drawback of VOD and NOVA that the real object can not be
viewed with any textured 3D-preview in the program. So sometimes
it is hard - if not sometimes impossible - to overlay a texture
without distortion.
bleedthrough
So-called „bleedthrough“-artifacts, if parts shine through each
other, can hardly be found in FS2000/CFS2.
Here we have a new 3D-engine, working with "z-buffering". Every
Point in a scenery will be sorted according to a perspective
buffer list depending to its actual position. This buffer list
determines which part shall hide which other one. This is
working
reliable.
But in FS98 and older and in CFS1 there is no z-buffering. Here
sorting of object parts is made by the so called "drawing
order". That means, object parts which have a high view priority
( which are hiding others) are placed in the code at latest
position, and vice versa with objects having low priority, which
are
hidden
by
others.
These
have
to
be
coded
first.
Parts lying near to the Referenzpunkt must be coded first, then
the more distanced parts. The whole stuff will be complex if we
have a building with transparent windows, where the inner walls
should
be
visible
from
outside.
Here the polygonsdrawing the inner walls (mostly with "ai"vector-parameter) must be coded first in the macro, then the
polygons
for
the
outer
walls.
There will always be cases when this drawing order rule is not
sufficient to design an object without any bleedthrough in FS98.
Where there is no logical solution for correct drawing order.
For example, a building with a double-T-shape. Regardless how
you place the code, you will always have bleedthrough somewhere.
There FS98 needs the VectorJump-command. It will be explained in
a separate section in the enhanced second part of the document.
Bleedthrough-fixing a complex object for CFS1/FS98 can be
Sysiphus´ work. One example is Ralf-J. Triebel´s "Kyffhaeuser"tunnel-bunker scenery for CFS1, where you can drive through a
hidden labyrinth of tunnels and floors. It was a good piece of
work to fix this in a way that no part shines through any other
one. One can only imagine if ever tried such. I am still amazed
that he finally got out of the tunnels somehow...;-)
With the new 3D-engine and z-buffering, scenery design has
become much simplier and more flexible.
Glass-objects in FS2000/CFS2:
An important exception of z-buffering appears when dealing with
transparent surfaces in FS2000/CFS2. There it seems to be
partially impossible to implement z-buffering in its full
extent.
It is recommended to install the official MS-patch for FS2000.
Give a hint in your readme.txt when uploading freeware-scenery.
Because with transparent polygons, there are significant
improvements
with
the
patched
simulator.
A basic rule:
Object parts with tranparent polygons must be treated according
to
the
good
old
drawing-order
rule
(see
above).
A building with inner walls visible through a glass window must
be
treated
as
if
designed
for
FS98/CFS1:
1.
code
the
floor
and
roof
inner
side.
2.
code
the
inner
side
walls
and
inner
glass
polys.
3.
code
the
outer
side
walls
and
outer
glass
polys.
4.
code
the
roof
outside.
This will fix all hide-and-seek problems with "invisible"
polygons
behind
glass
polys.
If
you
are
designing
with
FSDS:
Make a part consisting only of inner surfaces first ( perhaps
you have to flip all polygons ). Then copy (STRG+C) and paste
(STRG+V) the part as a new part, do not shift or rescale
anything
now.
Flip all polygons of the new part, so that they show to the
outside.
Select the two parts. Click "parts...join selected". That´s it.
It won´t work with a primary single part with doublesided
polygons.
Some object surfaces show a flicker-effect in FS200/CFS2
This flicker-effect occurs with coplanar surfaces, if two
polygon-surfaces have identical x/z/y-shifts and angulation, but
different
outlined
size,
with
different
points
used.
It is the only problem appearing with the z-buffer-engine. The
3D-engine cannot decide which of the polygon should hide the
other one, and tries to display both with a mixed flicker
effect.
This effect can often be seen at VOD-generated objects, when the
typical buildings with overlaid surface parts are drawn. By the
time when VOD was developed, there was no FS2000 and of course
the whole problem unknown. Of course, that´s fixed in NOVA.
The same effect is often visible with FS98-aircrafts seen in
FS2000, if you are looking at the cockpit windows and wheels and
other parts. How to fix it? - Sometimes, only a complete
redesign
is
necessary.
Partially one can use a semitransparent poly as an overlay of an
opaque poly, with equal poly shape and same points used. Here,
the old drawing order rule is valid again, meaning that the
hidden
poly
must
be
coded
first
in
the
macro.
Sometimes it makes sense to shift the points of the overlaying
poly in a way that a small gap appears between the two surfaces.
If the gap is e.g. 1 centimetre wide, it will be invisible in
FS, but the 3D-engine displays both with correct buffering order
now.
Of course, the drawback is that one will need a low scale factor
then, to enable the slight gap, scale 0.01 or 0.02, or even
SetScaleX( 0 0 10 ). But for a simple building, that would be
too much effort.
Many designers working for CFS2/FS2000 are making complete
redesigns, caring that only complete texture-filled polygon
sides are used, without overlaying second polygons over an
existing surface.
This
way
one
can
even
continue
working
with
VOD.
However, FSDS or NOVA or EOD or the scasm-editor are featuring
the new FS2000-options, and one should better try one ( or more
) of these programs.
z-bias:
A special option for advanced is z-bias. Here we are partially
overriding
the
z-buffer-engine.
With a command telling FS that the following 3D-points should
have a changed (higher) z-buffer- priority. This command
described in the SDK is implemented in scasm in version 2.50:
ZBias( 1 )
can be added before the part of a pointsystem ( or pointsystem
as a whole ) which should have this z-buffer-override.
Perhaps
place
the
whole
part
into
a
new
label.
Syntax is then:
:newlabel
ZBias( 1 ); try values 1-5
Points( 1
…..
…..)
Poly( a 1 2 3 4 )
Poly( …..
…etc.
ZBias( 0 )
Return
When z-bias ends, at the concerning place, behind the polycommands, should appear the command
ZBias( 0 )
to reset normal z-buffering.
Louis Sinclair, the author of FSDS, recommends to try values
between 1-5..
FSDS has implemented z-bias in the program, to be found in the
"part...properties".
Object parts which should be transparent appear opaque
black
This problem only occurs if the official patch II for MS-Flightsim 2000 was installed and if the concerning object was designed
using
a
VOD-type
start
macro
sequence.
If the user switches off the "ground shadow" display in the
FS2000 quality settings, the problem is gone. But that´s not
state of the art...
The problem is due to the old VOD-kind of PerspectiveCall-startloop in which the ShadowCall as an own label appears behind the
RefPoint. This had been o.k. with FS98, but now leads to these
problems with transparency.
All object parts with "BitmpapMode( 1 )"-generated transparency
are opaque black then.
Note: With CFS2, „BitmapMode( 1 )“ does not work anyway, as announced already
in the FS2000-SDK.
Simple workaround:
Open the macro-file with notepad. When finding the line starting
with „ShadowCall.....“, just delete this one line. Save the
macro and regenerate the bgl. That´s it.
Of course you will go without the ground shadow then, at least
for this object. But that won´t really matter, in most cases.
If really the shadow should be kept, there is no way around
retyping the whole PerspectiveCall- and RefPoint-loops as I
described it above. Respect the correct naming of the labels.
And see the appendix section about the VOD-start-loops with an
example.
Object parts which should
opaque at dusk and dawn
be
transparent
appear
dense
That´s a special FS2000-problem. Texture-parts treated for
transparency with BMP2000 appear dense opaque in the colour
index which should be transparent.
This only appears in connection with "_lm"-nighttextures and
LoadBitmap-command, and only at „dusk“ and „dawn“. Due is
probably a problem with mipmapping if the FS2000 option
„smoothing change dusk/dawn“ is activated in FS2K-settings.
This bug was obviously fixed in CFS2.
The workaround is tricky and nothing for newbies, especially if
the macro was written by another designer.
First you have to find the code line for the concerning problem
polygon.
This needs some scasm-knowledge and also insight into the
structure of that object.
If the concerning poly reads e.g.:
TexPoly( a 1 0 0 2 0 255 3 255 255 4 255 0 )
then add following lines before it :
RGBSColor( e0 0 0 0 )
Poly( a 1 2 3 4 )
What are we doing here? – We just place a polygon filled with
total transparent colour ( I call this a "dummy polygon") behind
the
problem
polygon,
using
the
same
point
indices.
This dummy polygon will not be visible in FS (because it´s
totally transparent), but it fixes the bug reliable. Note that
the dummy polygon must use the same point-indices as the
problem-poly.
I don´t know a different working fix. Note that this bugfix only
works if the problem texture index has total transparency with
value
0.
It
does
not
work
with
semitransparent
textures.
But you can select e.g. transparency "e3" and e.g. a green RGBcolor 0 180 80 if you want a glass effect behind the transparent
texture.
With FSDS, it can be done without having to fiddle around with
the macro code.
Keep this part-generating order:
Generate the part. Firstly without textures.
In „current item properties“, set the part colour to black and
total
transparent,
opacity
value
0.
Or select e.g. a green colour and transparency 8, if you want
glass windows.
Then copy this part with Strg+C and paste it as a new one with
Strg+V. Now don´t shift or rescale anything.
Lay the transparent textures over this new part, with part
textures
or
single
polygon
texturing.
Then
select
both
parts,
each
with
Shft+S.
Select „part... join selected“ and after that “part…snap to
scale”.
That´s
it!
Now you have "dummy-polygons".
Maybe you can delete any dummy-polygons from the dummy parts
which are actually not needed because overlaying a textured poly
which has no transparency.
The scenery design program won´t show the correct shape
of the object
With the newest versions of Airport or FS-SC this problem will
seldom occur.
Both have some different methods and few odds displaying object
shapes.
Airport checks the points in the main label ( z.B. in :h2 in my
cube.api ) and tries to show the object shape from there. In
most cases that succees, but not if
-the RefPoint does not allow scaling but the user has set a
different %4 setzt
-all points are "hidden" in sub-labels, as with complex
VOD/Nova-/FSDS-/mdltobgl-objects.
FSDS and mdltobgl, the well-known aircraft-api-compiler, are
placing "dummy-point" instructions for Airport, always starting
with „Mif( 0 )“, at the beginning of the macro. This dummycheat-code will not be compiled to bgl, but Airport can read the
points and show the correct shape.
FS-SC recognizes points even if they are in sublables and
according
to
correct
scaling.
And FS-SC reads the shape from an FSDS-objects by the macroheader "macrodesc..."line, e.g. ";macrodesc FSDS-object 10X20".
If FS-SC finds such an entry, it displays a 10X20 rectangle.
One can change or delete this header-entry so that FS-SC
calculates the shape from the point-lists.
Both programs can process ;designshape... header commands as
described in the section about the Macroheader.
During compilation there are scasm error messages
Scasm checks the whole scenery project for severe bugs. For
example it checks if any scenery object lies outside the bglscenery-range. All scenery-objects, 3D-macros and other objects,
are checked. And of course there are thousands of possible bugs
which simply cannot be checked all by scasm.
If the compiler finds a bug, an error message is generated. This
message can be viewed in the scenery design program and will be
stored to the file scaerror.log mostly to be found in the main
folder of the design program. These error messages are often
cryptical to newcomers. But if one gets into their logic, they
are really helpful for debugging.
First, one should check that the error is really due to our new
3D-design-object and not to any other object in that scenery
project.
If an error occurs in our macrofile „mymacro.api“, in most cases
the first line of the message reads:
Error in macro file C:\SPIELE\AIRPORT\MACROS\MYMACRO.API line 89
-> TaxPoly( a 1 2 3 4 )
-> unknown command
Scasm compilation status: error(s) 1
Here, in the first line of the message it can be seen that our
macro is responsible.
The second line quotes the actual problem line as it was coded.
Note that long code lines cannot be quoted as a whole here, but
a rest will be omitted.
The third line tries to give a hint which error occured. Here we
have an "unknown command", meaning that the compiler does not
know this command. It really cannot, of course the line should
read „TexPoly...“ and not „TaxPoly...“. In most cases we have
such simple syntax errors creating an "unknown command"-message.
missing „enda“ instruction
Error in line 459
-> -> missing "enda" instruction
Here the „EndA“-line
forgotten.
at
the
bottom
of
the
macro
code
was
integer parameter expected
-> Area( 5 48:13.81064 007:44.65781 1.2 )
-> integer parameter expected ... 1.2 ) ...
Here a floating point value was entered, although the concerning
command only allows an "integer" (=natural number) value.
The quote „1.2“ in the comment already indicates which number is
wrong. It´s the 1.2 for the kilometer-range in the Area-command.
Allowed would be „1“ or „2“, but not 1.2.
...
linebuffer exceeded...
in line...
Such a message only occurs if the macro is too long for scasm.
Scasm primary has only a limited memory rewerved for the
textbuffer and for the length of the object commands in the
concerning
area.
But one can increase these values. Read the concerning section
about the special scasm environmental commands.
VOD-startloops
Here an old startloop, as typically generated by VOD:
Area( 5 %1 %2 22 )
mif( %12 )
IfVarRange( : 0346 %12 4 )
mifend
PerspectiveCall( : project )
Jump( : )
: project
Perspective
mif( %11 )
RefPoint( 2 :SubEnd %4 %1 %2 v1= %10 E= %11 %13 %14 )
melse
RefPoint( 7 :SubEnd %4 %1 %2 v1= %10 %13 %14 )
mifend
mif( %5 )
RotatedCall( :B 0 0 %5 )
melse
Call( :B )
mifend
:SubEnd
Return
:B
ShadowCall( :B2 )
:B2
; Main project
;**********************beginning of points and rest of macro here...
Points( 0 ...........................
Here the new, adapted startloop, where no transparency problems
should occur:
Area( 5 %1 %2 %3 )
mif( %12 )
IfVarRange( : 0346 %12 5 )
mifend
PerspectiveCall( :B2 )
ShadowCall( :B2 )
Jump( : )
;Perspective;leave out this command for FS2000/CFS2! Obsolete
:B2
mif( %11 )
RefPoint( 2 :SubEnd %4 %1 %2 v1= %10 E= %11 %13 %14 )
melse
RefPoint( 7 :SubEnd %4 %1 %2 v1= %10 %13 %14 )
mifend
mif( %5 )
RotatedCall( :B 0 0 %5 )
melse
Call( :B )
mifend
:SubEnd
Return
:B
; now points and polygons
; - a.s.o.
RefPoint3
As already described in the section about the RefPoint, this
RefPoint-type-3
RefPoint( 3 :h3 %1 %2 v1= %10 E= %11 %13 %14 )
serves to improve the performance of flightsim (framerates) with
high-detailed objects in the scenery. This is because this
RefPoint does not use a linear scale-factor, but the "binary",
generated with the
SetScaleX
-command. This binary scale works basing on the computerfriendly term (2x)/65536. Therefore it can always be divided
through
16
bit
(65536).
This fastens the internal calculation work of the 3D-engine.
As small drawback of binscale is that it is not so flexible and
cannot represent all possible floating point-scales. But by
reasonable planning of the 3D-points one can respect this fact.
The scasm-command reads:
SetScaleX( :h3 0 0 x )
Here we set the x following values for x and get as real object
scale in Flightsim:
x
realer scale =ca.
6
0.000977
0.001
7
0.001953
0.002
8
0.003906
0.004
9
0.007813
0.008
10 0.015625
0.016
11 0.03125
0.032
12 0.0625
0.06
13 0.125
0.13
14 0.25
0.3
15 0.5
0.5
16 1
1
The SetScaleX-command works also together with the normal 2-u.7RefPoint-types, although a relevant advantage of performance can
only be achieved with RefPoint3.
Note that RefPoint3 requires absolute object altitude setting.
The macro-user must fill in the object altitude [m ASL] when
placing the macro in the scenery design program.
If he fails, then the object will be unvisible because "buried"
under the terrain at sealevel.
And respect that some beta-versions of Airport 2.60 (build 82
und some following, not sure) have a problem with exactly this
altitude setting and in some cases won´t pass over the
concerning user-variable to the sca-input. Then, although the
user filled in an altitude, the %11 variable is passed over with
"zero", and the object is unvisible because at sealevel. So, get
the
newest
Airport
build!
It
is
fixed.
With FS-Scenery-Creator no such problem occurs.
Here once more an example for correct coding with RefPoint3, as
e.g. to be generated quick and safely with MAT´s Scasm Editor:
; generated with MAT's Scasm Editor Version 1.0
; copyright 2001
Area( 5 %1 %2 %3 )
IfVarRange( : 346 %12 5 )
PerspectiveCall( :Persp )
Jump( : )
:Persp
;Perspective;I deactivate it with semicolon, because obsolete since FS2000
RefPoint( abs :h3 %4 %1 %2 E= %11 v1= %10 %13 %14 )
SetScaleX( :h2 0 0 10 )
; set binary scale factor to 10 -> real scale: 0.015625 ( ~0.016 )
RotatedCall( :h2 0 0 %5 )
; rotates object to user preset
:h3
Return
:h2
; !!! Insert all your point and polygon code here !!!
; !!! End of your inserted code !!!
Return
EndA
Our thanks to: MAT'S
tutorial
SHOF 12/22nd. 2003
Combatflight
for
making
this superb
available.
© Copyright 2025 Paperzz