Building fgrun - June 2006 - MSVC8

index

2008-12-06: See update at fgfs-048.htm ...

fgrun is a 'FlightGear Launch Control' program that provides a graphical front-end for running FlightGear flight simulator, http://www.flightgear.org/ . One of its coolest features is that it gives you a rotating view of the aircraft you choose - example -

Screen shot of the FlightGear Wizard, aircraft selection page

This alone makes it worth having ;=)) but it has a LOT of other features that make choosing the hundreds of command line options of FlightGear a BREEZE ...

top


It has a number of pre-requisites, before getting to fgrun itself. Since it is assumed you have already compiled FlightGear, so you have some already ;=))

A. The Folder Structure
B. Building the Components
    1. fltk - Fast Light Toolkit - http://www.fltk.org/
    2. zlib - A Massively Spiffy Yet Delicately Unobtrusive Compression Library - http://www.zlib.net/
    3. plib - STEVE'S PORTABLE GAME LIBRARY - http://plib.sourceforge.net/
    4. simgear - Simulator Construction Tools - http://www.simgear.org/
    5. pthreads - Open Source POSIX Threads for Win32 - http://sourceware.org/pthreads-win32/
    6. OpenGL - The Industry's Foundation for High Performance Graphics - http://www.opengl.org/
    7. fgrun - FlightGear Launch Control - http://sourceforge.net/projects/fgrun
C. Running fgrun
D. Additions - a command log, and crude flight log.
E. Download Binary - this is my runtime (Release) executable in a zip file.

top


A. The Folder Structure

You can use just about any folder structure, and drive arrangement to build fgrun. Unless you specifically use exactly that of the author of the MSVC solution file, you will have to make changes to the fgrun Property Page -> Configuration Properties -> C/C++ -> General -> Additional Include Directories.

For example, at the time of this build, the solution author used an i: drive for most of the components. Since I used the following structure, I had to 'fix' this to suit my structure ...

C:\FG0910-3\fgrun
           \fltk
           \zlib
           \plib
           \simgear
           \pthreads

Note I have removed the version information from the folder. For example, the svn fltk check out used the folder fltk-1.2; zlib unpacked into zlib-1.2.3, etc ... I do this by using xcopy to make a copy of the download into the folder I desire. Also I sometimes shorten the depth of the folders, like simgear, which downloads into simgear\source, but in making the xcopy I remove the 'source'; fgrun was in fgrun\fgrun, so I dropped one of these ...

This is a difficult topic, since everyone has their own 'favourite' structure, so I is good to get used to adjusting the 'Additional Include Directories' for the compile step, and the Linker -> General -> Additional Library Directories. Just remember, the path in here is relative the vcproj file containing that particular source ...

top


B. The Builds

1. fltk - Fast Light Toolkit - http://www.fltk.org/

This can be downloaded, either as a tar ball, or using svn ... the source includes a MSVC8 solution file, with about 70 projects in it ... for fgrun you only need the static libraries fltk.lib and fltkgl.lib ... Except for converting every project to use a runtime library of Multithreaded (/MT), I had little trouble compiling this source. Some of the EXE samples included failed to link, with a whole swath of 'unresolved external', but since I only wanted the static libraries, I ignored this ...

top


2. zlib - A Massively Spiffy Yet Delicately Unobtrusive Compression Library - http://www.zlib.net/

Since you have to also build this to be able to build and link FlightGear, I have already covered this recently in fgfs-023.htm#zlib and I note the zlib site still sports the latest version as zlib-1.2.3, so it is not covered here.

top


3. plib - STEVE'S PORTABLE GAME LIBRARY - http://plib.sourceforge.net/

Likewise, since you have to also build this to be able to build and link FlightGear, I have already covered this recently in fgfs-023.htm#plib, so it is not covered here.

top


4. simgear - Simulator Construction Tools - http://www.simgear.org/

Like wise, SimGear is also required for FlightGear, thus I already had this compiled with MSVC8 - see here fgfs-023.htm#simgear, so it is not covered here.

top


5. pthreads - Open Source POSIX Threads for Win32 - http://sourceware.org/pthreads-win32/

Also, my last FlightGear included pthreads - see here fgfs-023.htm#simgear. FlightGear can be built without using pthreads ... you have to also exclude it from simgear at the same time ... but I have not tried to remove pthreads from fgrun ...

top


6. OpenGL - The Industry's Foundation for High Performance Graphics - http://www.opengl.org/

This is usually already install in Windows XP. It comes from your video card manufacturer, but it is usually a good idea to check if there are any later driver from the your video card manufacturer site ... there are no direct downloads available from the OpenGL site.

The main header file is gl.h, and it is most often included as <Gl\gl.h>, which means it has to be in a GL folder. Searching my drives, I find many copies of gl.h, but the ones of interest are going to be in a PATH that my MSVC8 knows and uses. I found it in -

03/03/2006  11:23 PM 69,083 GL.h C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\gl\
26/07/2004  06:34 AM 69,083 GL.h C:\Program Files\Microsoft Platform SDK for Windows XP SP2\Include\gl\
23/04/1998  04:00 PM 69,083 GL.H C:\Program Files\Microsoft Visual Studio\VC98\Include\GL\
04/06/2002  08:12 AM 69,083 GL.h C:\Program Files\Microsoft Visual Studio .NET 2003\Vc7\PlatformSDK\Include\GL\

Note, while the date and time is different in each case, they are all exactly the same size, which suggests they are the same ... And checking in MSVC8, under Option ... -> Projects and Solutions -> VC++ Directories -> Show directories for: -> Include files, I note that the 'C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include' is listed first. This came from a recent download of this SDK from -

http://www.microsoft.com/downloads/details.aspx?FamilyId=0BAF2B35-C656-4969-ACE8-E4C0C0716ADB&displaylang=en

using their PSDK-x86.exe (1.2 MB), which actually does the big download and install ... it takes some time ...

For many months I was very disappointed with the frame rate - iterations per second - that I was getting when running FlightGear ... Eventually I downloaded some software from my video card manufacturer - since this machine has an ATI RADEON 9600PRO SAPPIRE card I went to the site http://www.ati.com/products/radeon9600/radeon9600pro/ - I downloaded the 34.4 MB Catalyst Control Center from -

https://support.ati.com/ics/support/default.asp?deptID=894&task=knowledge&folderID=293

After installation, my frame rate jump some 30-50 TIMES ;=)) So it is well worth checking out what your video manufacturer has done recently ...

top


7. fgrun - FlightGear Launch Control - http://sourceforge.net/projects/fgrun

As mentioned above, I had to considerably adjust the 'Additional Include Directories' and 'Additional Library Directories' to suit my structure, and, in some cases change the actual library name ... like zlib was listed as zlibd.lib, while in my case it is just zlib.lib, and I separate the debug from the release by having them in different folders; the pthreads DLL library was listed as pthreadVC2d.lib, but since this is a DLL library only, thus the debug code, if present, is only in the DLL, I changed this to just pthreadVC2.lib, etc ...

I also changed the RunTimeLibrary to /MTd and /MT respectively, my preferred run time ... The build was quick, after I had adjusted the properties, but I was surprised by some 'unresolved externals' like -
Linking...
AirportBrowser.obj : error LNK2019: unresolved external symbol _gzclose referenced in function "private: void __thiscall AirportBrowser::runways_idle_proc(void)" (?runways_idle_proc@AirportBrowser@@AAEXXZ)

I know gzclose() is in zlib, and I had include zlib.lib - what can be wrong here? Using the MS tool, DUMPBIN, like -

> DUMBIN /ALL zlibstat.lib

I find that gzclose is listed as -
    61F72 _gzclose@4

Is this something to do with a C convention versus the so called fastcall convention? But I do not have a problem including zlib in simgear, or flightgear - why a problem in fgrun?

I note in the zlibstat project of zlibvc, that ZLIB_WINAPI is defined, although the documentation suggests that it should not be??? I decide to recompile a new zlib, without this definition ... the project uses a zlibvc.def file to EXPORT these functions ... I have to remember to turn off the manifest creation, BUT FGRUN LINK WITHOUT PROBLEM TO THIS NEW STATIC LIBRARY ???

Now I am only left with the puzzle as to why this did not come up when linking SimGear/FlightGear, but I will leave that to another time ...

I now have a Debug version of fgrun ... swing over to the Release ... many things can be directly copied from the Debug configuration, but usually with minor changes ... I note for instance that the solution author has used non-standard PLIB extensions, like ssg-nd.lib, ul-nd.lib, etc, assuming the 'nd' is for 'no debug'. This is certainly another way to separate Debug and Release version of libraries, or DLL for that matter ... Eventually I get the Release configuration built also ...

top


C. Running fgrun

For this first try I just navigated into the Release folder, where the fgrun.exe exists, and enter fgrun at the command line ... and up it comes ... YOW! I am on my way ...

I have to first select the [ Defaults ] button, to tell it where my FlightGear.exe is, and where my scenery data, root, is ... then I select an aircraft ... but the first one I choose gives an error dialog ... ok .. I just select another ... change a few more parameters, then eventually click [ Run ] ... FlightGear starts to load, but almost immediately exits, but because the console window created to run FlightGear closes, I have no information why it aborted ...

I go back into the [ Defaults ] to check I had selected the correct runtime binary, but fgrun does not seem to 'remember' what I had selected before, so I do it again ... and try a different aircraft again ... leave most parameters as their default, AND FLIGHTGEAR LOADS, BUT THERE IS NO SCENERY? I can take the aircraft off, but these is no SF scenery to look at ... what is happening?

I look inside main.cxx and note that I can add parameters, like -

Options are:\n --silent\n --fg-exe=<PATH>\n --fg-root=<DIR>\n --fg-scenery=<DIR>\n -f, --fullscreen\n%s", Fl::help );

so this solves how I can set the exe, root and scenery path ... so I do not have to use the [ Default ] button ...

I find that it has written a fgrun.pref file in -

C:\Documents and Settings\username.machine\Application Data\flightgear.org

and looking in here, I guess that the problem of the scenery is that I only repeated the root path, but should perhaps add 'scenery' to the end ...

I decide to take the Harrier for a spin, so head into [ Advanced ] to change the FDM to Yasim ... hit [ Run ], and this time I HAVE SCENERY ;=)) As is usual, by the time the scene graph is shown the Harrier is already rolling as a rate of knots - there seems a residual value in the throttle slider, when the joystick is initialised - and I have to jump of the brakes, and wow, how the nose bounces ;=))

The first attempt at take-off end almost instantly in a CRASH ... I suppose I need to learn more about how to fly and control this aircraft ;=)) Through the aircraft specific help I learn m/M alter the thrust vectors ... with the thrust level back about 90% (repeated M key), and applying full throttle, with the parking brakes still on (B), I am able to get into the air almost vertically ... YEH, THIS IS GREAT STUFF ...

But I was unable to get it down smoothly using the throttle and thrust vectoring, but it should be remembered this is MY first time in the aircraft type ;=))

There is no doubt, fgrun really helps in choosing parameter ... lots of thanks to FredB, and others, for this excellent aid - indeed a great 'FlightGear Launch Control' ... so that I can keep a 'history' of what I have tried, I decide to add a file output just as fgrun passes the command string to the system to run FlightGear ... the source of this module is attached at the end ... it includes a very rudimentary flight log as well ...

top


D. Additions to fgrun

In run_win32.cxx, I added the following ... Near the top -

#include "fgfslog.h"

This is a small file, with the following contents -

fgfslog.h
//
// fgfslog.h -- fgrun log cmd and flight, to
// (a) keep a text file of commands run, and
// (b) a very rudimentary flight log
//
// Written by Geoff McLane, started June 2006.
// Copyright (c) 2006  Geoff McLane - geoffair at hotmail
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// file : fgfslog.h
#ifndef _fgfslog_h_
#define _fgfslog_h_

extern void out_fgfs_run_cmd( char * cmd );
extern void add_fgfs_end( void );
extern void out_fgfs_flight(string s);

#endif // _fgfslog_h_
// eof - fgfslog.h

And in the creation of the process to run FlightGear, added the functions :-

    else
    {
+        out_fgfs_flight( line );
+        out_fgfs_run_cmd( cmd );
         WaitForSingleObject( pi.hProcess, INFINITE );
         DWORD exitCode;
         GetExitCodeProcess( pi.hProcess, &exitCode );
         // Close process and thread handles.
         CloseHandle( pi.hProcess );
         CloseHandle( pi.hThread );
+        add_fgfs_end();
    }

And the file fgfslog.cxx, with some simple functions -

fgfslog.cxx
//
// fgfslog.cxx -- fgrun log cmd and flight, to
// (a) keep a text file of commands run, and
// (b) a very rudimentary flight log
//
// Written by Geoff McLane, started June 2006.
// Copyright (c) 2006  Geoff McLane - geoffair at hotmail
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//

// module: fgfslog.cxx
#include <string>
#include <iostream>
#include <stdio.h>
#include <time.h>

using namespace std;

// ========================================================
// functions to create and append to -
// (a) a command file, and
// (b) a flight log file
// version: 0.0.2 - 2006.06.28 - added CSV output,
//                               and time difference - geoff
// version: 0.0.1 - 2006.06.24 - initial file - geoff
// ========================================================
// output file names
static char * logfile = "tempfgfs.log";
static char * cmdfile = "tempcmds.txt";

#define WRT_AS_CSV  // else as a flat database file
#define air_min_len     25  // used to space items, if NOT CSV
#undef  DBG_TIMES   // just to provide some random debug values

#ifdef _MSC_VER
#define LOG_EOL     "\r\n"
#define add_end_of_line(a)      fwrite( LOG_EOL, 1, 2, fh )
#else // !#ifdef _MSC_VER
#define LOG_EOL     "\n"
#define add_end_of_line(a)      fwrite( LOG_EOL, 1, 1, fh )
#endif // #ifdef _MSC_VER

#ifdef  WRT_AS_CSV
#define LOG_SEP_CHAR    ","
#else // !#ifdef  WRT_AS_CSV
#define LOG_SEP_CHAR    " "
#endif // #ifdef  WRT_AS_CSV y/n

static time_t log_curr_time, log_start_time;

static void wrt_log_time( FILE * fh )
{
    log_curr_time = time(NULL);
    string s = ctime(&log_curr_time);
    size_t pos1 = s.find("\n"); // find,
    if( pos1 == string::npos ) { // if NOT FOUND
        pos1 = s.length();
    }
    fwrite( s.c_str(), 1, pos1, fh );
}

static string get_cmd_component( string & s, string & f, char * def )
{
    size_t pos1, pos2, sz;
    string are = " --"; // to next, if any
    string fnd = def;
    pos1 = s.find(f); // find,
    if( pos1 != string::npos ) { // if FOUND
        sz = pos1 + f.size(); // get the arg size
        pos2 = s.find( are, sz ); // find next arg beginning
        if( pos2 == string::npos ) { // if NOT FOUND
           pos2 = s.size();
        }
        pos1 += f.length(); // get to just the aircraft
        fnd = s.substr( pos1, pos2 - pos1 ); 
    }
    return fnd;
}

void out_fgfs_flight(string s)
{
    string air = "--aircraft=";
    string fdm = "--fdm=";
    FILE * fh;
    int add_hdr_line = 0;
    air = get_cmd_component( s, air, "c172" );
    // got an aircraft, or default ... find fdm command
    fdm = get_cmd_component( s, fdm, "jsb" );
    // got fdm, or default ... combine the two
    air += " (";
    air += fdm;
    air += ")"LOG_SEP_CHAR;
#ifndef  WRT_AS_CSV
    // up the length to the minimum
    while( air.length() < air_min_len )
        air += LOG_SEP_CHAR;
#endif // #ifdef  WRT_AS_CSV y/n
    // got aricraft and FDM strings
    fh = fopen( logfile, "r" ); // check if file exists ...
    if(fh) { // yup
        fclose(fh);
    } else { // no, add header line
        add_hdr_line = 1;
    }
    fh = fopen( logfile, "ab" ); // create or append
    if( fh ) {
        if(add_hdr_line) {
#ifdef  WRT_AS_CSV
            string hdr = "Aircraft (fdm)"LOG_SEP_CHAR
                "Start"LOG_SEP_CHAR
                "End"LOG_SEP_CHAR
                "Time"LOG_EOL;
#else // !#ifdef  WRT_AS_CSV
            string hdr = "Aircraft (fdm)";
            while(hdr.length() < air_min_len)
                hdr += " ";
            hdr += "Start";
            while(hdr.length() < air_min_len * 2)
                hdr += " ";
            hdr += "End";
            while(hdr.length() < air_min_len * 3)
                hdr += " ";
            hdr += "Time (HH:MM)"LOG_EOL;
#endif // #ifdef  WRT_AS_CSV y/n
            fwrite( hdr.c_str(), 1, hdr.length(), fh );
        }
        fwrite( air.c_str(), 1, air.length(), fh );
        wrt_log_time( fh );
        log_start_time = log_curr_time;

        fwrite( LOG_SEP_CHAR, 1, 1, fh );
        fclose(fh);
    } // fail gracefully
}

static void wrt_dif_time( FILE * fh, time_t diff )
{
    char tbuf[256];
    int mins = (int)(diff / 60);
    int hrs  = (int)(mins / 60);
    mins = mins - (hrs * 60);
    size_t len = sprintf(tbuf, LOG_SEP_CHAR"%02u:%02u", hrs, mins);
    fwrite( tbuf, 1, len, fh );
}

#ifdef  DBG_TIMES
time_t get_dbg_time( time_t diff )
{
    static int do_seed = 1;
    int RANGE_MIN = 0;
    int RANGE_MAX = 60;
    if( do_seed ) {
        unsigned int seed = (unsigned int)time(NULL);
        srand( seed );
        do_seed = 0;
    }
    int ih = (int)(((double) rand() / 
                 (double) RAND_MAX) * RANGE_MAX + RANGE_MIN);
    int im = (int)(((double) rand() / 
                 (double) RAND_MAX) * RANGE_MAX + RANGE_MIN);
    diff += ((ih * 60 * 60) + (im * 60));
    return diff;
}
#endif // #ifdef  DBG_TIMES


void add_fgfs_end( void )
{
    FILE * fh = fopen( logfile, "ab" ); // append
    if(fh) {
        wrt_log_time( fh ); // get and add current time
        time_t diff = log_curr_time - log_start_time; // difference
#ifdef  DBG_TIMES
        diff = get_dbg_time(diff); // just for DEBUG
#endif // #ifdef  DBG_TIMES
        wrt_dif_time( fh, diff ); // write difference as HH:MM
        add_end_of_line( fh );
        fclose(fh);
    } // fail gracefully
}

// just a DEBUG type list of the command lines
// passed to the system ...
void out_fgfs_run_cmd( char * cmd )
{
    size_t len = strlen(cmd);
    if(len) {
        FILE * fh = fopen( cmdfile, "ab" ); // append
        if( fh ) {
            fwrite( cmd, 1, len, fh );
            add_end_of_line( fh );
            fclose(fh);
        } // fail gracefully
    }
}
// ========================================================

// eof - fgfslog.cxx

This appends the commands to 'tempcmds.txt', and the aircraft (fdm) start, end times to 'tempfgfs.log' file ... then you have a trace of (a) what commands you have passed to FlightGear ... this is more diagnostic than anything else ... and a rather crude flight log of aircraft, and the start and end time for that aircraft ...

Enjoy ...

top


E: Download Binary Runtime Executable

This is a zipped copy of my runtime executable. Since it is built with MSVC8 there is no guarantee that it will run in your system. You must have the MSVC8 runtime DLL installed, and installed correctly. The following are the digests of this zip file, fgrun-01.zip, containing fgrun.exe -

 MD5 (fgrun-01.zip) = 6f4220fb652626525cda3f161310f3be
SHA1 (fgrun-01.zip) = 1AE9E2757D69738B5598F3B14B938D96BD9EF6B0

Download via HTTP or FTP - and remember the usual WARNING about downloading and running executables from the web.

top


index

EOF - fgfs-027.htm

checked by tidy  Valid HTML 4.01 Transitional