Bstinfo Files and the Specifics of Booster Operation

If you're designing scenery destined for release on compact disc, you need to be aware of how booster processors work as well as their interaction with Bstinfo files and file grids. The front-end processor both starts and stops booster processors. The front-end processor also determines the booster processors that are available by examining the booster list, stored in the World.vis file. Each booster entry has the format shown in the following example.

BOOSTER struc
dbopcode;1 = booster
dbactive;1 = active
dwcache_size;max size of hard disk cache
dbcleanup_mod;0 = cleanup on exit
;1 = do not cleanup on exit
dbupdate_strategy;0 = manual - update cache on user
;request (spacebar press)
;1 = semiauto-update manually below
;750 ft AGL, automatically above
;2 = automatic
dbsource_path;directory path of CD-ROM source
dbcache_path;directory path of hard disk cache
BOOSTER ends

The front-end processor checks the active flag of each booster entry. If the booster is active, the front-end processor opens cache_path\Bstinfo and reads the north, south, east, and west (NSEW) bounds from the Bstinfo header. When the user's plane is within a booster's bounds, the front-end processor starts the specified booster. When the user's plane goes outside the booster's bounds, the front-end processor stops the booster.

The booster processor determines the scenery that it will load by interpreting a list of data structures in the Bstinfo file. The booster processor compares the bounds of each data structure with the current location (lat and lon) of the user's plane. If the booster determines that the data structure is in range, it copies one or more files specified in the data structure to the hard disk cache. If the booster determines that the data structure is out of range the booster deletes the indicated files from the cache, provided that the data structure is resident in the hard disk cache. The booster performs this data structure check once every 8 seconds; the timing of the check is specified by having the routine booster_sequencer placed on an 8-second execution chain. The Bstinfo file is structured as shown in the following example.

HEADER:
ddnorth;00 N bound 32 bit meter units
ddsouth;04 S bound
ddeast;08 E bound, 32-bit pseudo
ddwest;12 W bound
dwtitle1;16 ptr to title asciiz string
dwdescription;18 ptr to description asciiz string
dwgrids_and_files_list;20 ptr to grids_and_files_list
dwrec_cach_size;22 recommended cache size in K bytes

TITLE1labelbyte
db'Title of CD-ROM product',0

DESCRIPTIONlabelbyte
db'Descriptive'
db'text'
db'for'
db'product',0

GRIDS_AND_FILES_LIST label word

;------------------
;Database description
;------------------
;db 0;00 opcode=EOL (end of list)
;
;db 1;00 opcode for FILES
;dw 0;01 op size (all bytes including opcode)
;db 0,0,0;03 north bound (2M units, inclusive)
;db 0,0,0;06 south bound (2M units, inclusive)
;db 0,0,0;09 east bound (24-bit pseudo inclusive)
;db 0,0,0;12 west bound (24-bit pseudo inclusive)
;dw 0;15 scan radius (256m units inclusive)
;dw 0;17 scenery/texture and item directory # on CD
;;   xx00............ = scenery (.bgl in scenery directory)
;;   xx01............ = texture (.txr in texture directory)
;;   xx10............ = palette (.pal in texture directory)
;;   ....nnnnnnnnnnnn = Fnnn... =item directory #
;dw 0;19 FILE 0 number/status    = F...nnn =item file #
;;   xx0x............ = file in cache 0/1
;;   ...nnnnnnnnnnnnn = F...nnn =file number
;......;21 FILE 1 - N number/status
;db 2;00 opcode for GRID
;dw 0;01 op size (all bytes including opcode)
;db 0,0,0;03 north bound (2M inclusive)
;db 0,0,0;06 south bound (2M inclusive)
;db 0,0,0;09 east bound (24-bit pseudodeg inclusive)
;db 0,0,0;12 west bound (24-bit pseudodeg inclusive)
;dw 0;15 scan radius (256m units inclusive)
;dw 0;17 scenery/texture and item directory # on CD
;;   xx00............ = scenery (.bgl in scenery directory)
;;   xx01............ = texture (.txr in texture directory)
;;   xx10............ = palette (.pal in texture directory)
;;   ....nnnnnnnnnnnn = Gnnn... =item directory #
;dw 0;19 divisions X (lon) dimension
;dw 0;21 divisions Y (lat) dimension
;db 0;23 FILE 0&1 STATUS= .......0 = file0 exists
;;     ......0. = file0 in cache
;;     ....xx.. = file0 spares
;;     ...0.... = file1 exists
;;     ..0..... = file1 in cache
;;     xx...... = file1 spares
;db 0....;24 FILE 2 - N status
;
;
;db 3;00 opcode for ALTITUDE_RANGE
;dw 0;01 opcode size
;dw 0,0;03 low altitude range for all following items
;;(m units inclusive)
;dw 0,0;07 high altitude range for all following items
;;(m units inclusive, 7fffxxxx=infinity)
;db 4;00 opcode for DGRID
;dw 0;01 op size (all bytes including opcode)
;db 0,0,0;03 north bound (2M inclusive)
;db 0,0,0;06 south bound (2M inclusive)
;db 0,0,0;09 east bound (24-bit pseudodeg inclusive)
;db 0,0,0;12 west bound (24-bit pseudodeg inclusive)
;dw 0;15 scan radius (256m units inclusive)
;dw 0;17 scenery/texture and item directory # on CD
;;   xx00............ = scenery (.bgl in scenery directory)
;;        = texture (.txr in texture directory)
;;   ....nnnnnnnnnnnn = Gnnn... =item directory #
;dw 0;19 divisions X (lon) dimension
;dw 0;21 divisions Y (lat) dimension
;db 0;23 FILE 0&1 STATUS= .......0 = file0 exists
;;     ......0. = file0 in cache
;;     ....xx.. = file0 spares
;;     ...0.... = file1 exists
;;     ..0..... = file1 in cache
;;     xx...... = file1 spares
;db 0....;24 FILE 2 - N status
;
;db 5;00 opcode for DFILES
;dw 0;01 op size (all bytes including opcode)
;db 0,0,0;03 north bound (2M units, inclusive)
;db 0,0,0;06 south bound (2M units, inclusive)
;db 0,0,0;09 east bound (24-bit pseudo inclusive)
;db 0,0,0;12 west bound (24-bit pseudo inclusive)
;dw 0;15 scan radius (256m units inclusive)
;dw 0;17 scenery/texture and item directory # on CD
;;   xx00............ = scenery (.bgl in scenery directory)
;;                    = texture (.txr in texture directory)
;;   ....nnnnnnnnnnnn = Fnnn... =item directory #
;dw 0;19 FILE 0 number/status    = F...nnn =item file #
;;   xx0x............ = file in cache 0/1
;;   ...nnnnnnnnnnnnn = F...nnn =file number
;;21 FILE 1 - N number/status
;------------------
;MACRO declarations
;------------------
EOLmacro
db0;;opcode
endm

FILESmacroNhi,Nlo,Shi,Slo,Ehi,Elo,Whi,Wlo,rad,st,subdir,endfil
localopcode
opcode:db01;;opcode
dwendfil-opcode;;entity size
dwNlo;;N bound (2M units, inclusive)
dbNhi
dwSlo;;S bound (2M units, inclusive)
dbShi
dwElo;;E bound (24-bit pseudo, inclusive)
dbEhi
dwWlo;;W bound (24-bit pseudo, inclusive)
dbWhi
dwrad;;scan radius (256m units)
dwst+subdir;scenery/texture and directory #
endm

A_FILEmacrofilnum
dwfilnum;;file number
endm

FILES_END macroendfil
endfillabelbyte
endm

GRID macroNhi,Nlo,Shi,Slo,Ehi,Elo,Whi,Wlo,rad,st,subdir,dlon,dlat,endfil
localopcode
opcode:db02;;opcode
dwendfil-opcode;;entity size
dwNlo;;N bound (2M units, inclusive)
dbNhi
dwSlo;;S bound (2M units, inclusive)
dbShi
dwElo;;E bound (24-bit pseudo, inclusive)
dbEhi
dwWlo;;W bound (24-bit pseudo, inclusive)
dbWhi
dwrad;;scan radius (256m units)
dwst+subdir;;scenery/texture and directory #
dwdlon,dlat;;grid lon/lat dimensions
endm

GSTAT1macrostatus
g_temp=status
dbstatus
endm

GSTAT2macrostatus
org$-1
dbstatus*16+g_temp
endm

GRID_END macroendfil
endfillabelbyte
endm

ALTITUDE_RANGEmacrobasehi,baselo,topshi,topslo
localopcode,opend
opcode:db03;;opcode
dwopend-opcode;;entity size
dwbaselo;;base altitude 32-bit M
dwbasehi
dwtopslo;;tops altitude 32-bit M
dwtopshi
opend:
endm

DGRID macroNhi,Nlo,Shi,Slo,Ehi,Elo,Whi,Wlo,rad,st,subdir,dlon,dlat,endfil
localopcode
opcode:db04;;opcode
dwendfil-opcode;;entity size
dwNlo;;N bound (2M units, inclusive)
dbNhi
dwSlo;;S bound (2M units, inclusive)
dbShi
dwElo;;E bound (24-bit pseudo, inclusive)
dbEhi
dwWlo;;W bound (24-bit pseudo, inclusive)
dbWhi
dwrad;;scan radius (256m units)
dwst+subdir;;scenery/texture and directory #
dwdlon,dlat;;grid lon/lat dimensions
endm

DFILESmacroNhi,Nlo,Shi,Slo,Ehi,Elo,Whi,Wlo,rad,st,subdir,endfil
localopcode
opcode:db05;;opcode
dwendfil-opcode;;entity size
dwNlo;;N bound (2M units, inclusive)
dbNhi
dwSlo;;S bound (2M units, inclusive)
dbShi
dwElo;;E bound (24-bit pseudo, inclusive)
dbEhi
dwWlo;;W bound (24-bit pseudo, inclusive)
dbWhi
dwrad;;scan radius (256m units)
dwst+subdir;;scenery/texture and subdir #
endm

;-------------------------
;CONSTANT declarations
;-------------------------
TEXTURE=0000000000000000b
SCENERY=0001000000000000b
PALETTE=0010000000000000b
SCEN_AND_TXR=0000000000000000b
HOLE=00000000b
EXISTS=00000001b
;-----------------------
;Begin code
;-----------------------
FILES01fh,028a7h,01dh,0e3a7h,0afh,01a96h,0adh,0b05bh,160,TEXTURE,1,ft1end
A_FILE000
FILES_ENDft1end
FILES01fh,028a7h,01dh,0e3a7h,0afh,01a96h,0adh,0b05bh,160,PALETTE,1,fp1end
A_FILE000
FILES_ENDfp1end
GRID 01fh,028c0h,01eh,0f6c0h,0adh,0e45fh,0adh,0b033h,160,SCENERY,0,4,4,gs0end
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GSTAT1exists
GSTAT2exists
GRID_ENDgs0end
end

A FILE op loads the files listed in the data structure if the bounds of the FILE op are in range; a GRID op loads only the individual file corresponding to the appropriate subgrid. Each GRID contains dlat and dlon information that the booster uses to divide the width and height of the grid into equally sized subgrids.

Each GRID and FILE section contain only one type of file: scenery (.bgl), texture (.txr, .r8, and so on), or palette (.pal). The DGRID and DFILE ops enable linking between two file types in one opcode. Linking requires that, for each entry in the DGRID or DFILE, both files be copied or deleted as a unit. If only one file type can be copied, usually because of space limitations on the user's hard drive, the file that was copied is deleted.

Each opcode has a scan range (in 256-meter units) associated with it. For example, a scan range of 160 translates into a 40.96 km radius from the current plane's latitude/longitude. Any FILE/DFILE op or GRID/DGRID subgrid with an edge or corner within the scan radius is determined to be within range, and the associated files are loaded in the cache. The scan range is also referred to as the load range. To prevent overprocessing on the hard drive, there is an unload range that is 25 percent greater than the load range. Files aren't removed from the cache until their associated FILE/DFILE op or GRID/DGRID op subgrid is outside the unload range.

After determining the files that are in range, the booster builds an internal list of files sorted by range from the plane; closer files are at the beginning of the list and more distant files are further down on the list. If, during the process of copying files from the compact disc to the cache, a disk space shortage occurs, sorting ensures that the files that are closer to the plane are loaded.

Disk space shortage occurs for one of two reasons: 1) there is not enough space on the hard disk, or 2) the cache has reached the limit set by the user and stored in the booster entry in World.vis. The booster monitors the size of the cache and available hard disk space. If a space shortage occurs, the radius for both load and unload is gradually decreased. As a result, files that are further away are deleted, usually those that are behind the plane. This allows new files to be loaded, specifically, files that contain scenery that is in front of the plane.

Flight Simulator treats the hard disk cache as a scenery area. The front-end processor builds a list of the files resident in all of the active scenery areas; as a result, whenever the booster modifies the hard disk cache, the front-end processor must be cued to rebuild the file list. This isn't necessary in the case of new files; in fact, the booster waits for seven copy updates before sending a request that the front-end processor rebuild the file list. However, when files are deleted from the cache, the booster immediately sends a request to front-end to rebuild to file list; this prevents front-end processor from opening a file that is in the file list, but no longer exists in a scenery area.

The actual name of a file depends on what type of opcode it's referenced in, its position or number within the opcode, and the file type of the opcode. The following code sample is an example of the file naming convention.

FILES0h,01000h,0h,04000h,0ch,0h,0eh,160,SCENERY,1,f01end
A_FILE0
A_FILE1
A_FILE2
FILES_ENDf01end

The preceding example is a FILES op, so the file name begins with 'f'. It is FILES op # 1, as indicated by the tenth argument of the macro, so the next three characters of the file name are '001'. The first file in the FILES op is number 0, as indicated by the argument to the A_FILE macro, so the next three characters of the file name are '000'. The type of the FILES op is SCENERY, so the file name extension is .bgl. So, the first file in this op is named f001000.bgl.

The path to the file on the CD-ROM drive is determined by starting with the source_path string stored in the Bstinfo file. Next, because the type of the FILES op is SCENERY, the next directory in the path is Scenery directory. (In the case of texture and palette files, the next directory in the path would be the Texture directory.) The op is a FILES op, and it's number is 1; the next directory in the path is Files001. The full path is source_path\Scenery\Files001\f001000.bgl. The path to the file for a GRID op is determined similarly, except that the file number is based on its order sequence among the other files in that GRID op. But, it's starting letter is 'g' and the directory containing the file would be 'Gridxxx.'