1
0
Fork 0

Merge branch 'next' of git://gitorious.org/fg/flightgear into next

This commit is contained in:
Erik Hofman 2011-11-20 10:29:23 +01:00
commit 269595a366
101 changed files with 3643 additions and 3269 deletions

View file

@ -41,7 +41,7 @@ set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/CMakeModules;${CMAKE_MODULE_PATH}")
if (FG_DATA_DIR)
message(STATUS "Using explicit data-dir: ${FG_DATA_DIR}")
else()
set(FG_DATA_DIR "${CMAKE_INSTALL_PREFIX}/lib/FlightGear")
set(FG_DATA_DIR "${CMAKE_INSTALL_PREFIX}/lib/FlightGear" CACHE PATH "Default location where data files are located")
message(STATUS "Using default data-dir: ${FG_DATA_DIR}")
endif()
@ -94,7 +94,7 @@ option(EVENT_INPUT "Set to ON to build FlightGear with event-based Input support
option(ENABLE_LIBSVN "Set to ON to build FlightGear/terrasync with libsvnclient support" ON)
option(ENABLE_RTI "Set to ON to build SimGear with RTI support" OFF)
option(WITH_FGPANEL "Set to ON to build the fgpanel application" ON)
option(JPEG_FACTORY "Enable JPEG-factory support" OFF)
if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_SOURCE_DIR} PATH)
@ -191,6 +191,26 @@ endif(ENABLE_LIBSVN)
find_package(PLIB REQUIRED puaux pu js fnt)
find_package(SimGear 2.5.0 REQUIRED)
if (JPEG_FACTORY)
# check simgear was built with JPEG-factory support
find_package(JPEG REQUIRED)
include_directories(${JPEG_INCLUDE_DIR})
set(CMAKE_REQUIRED_INCLUDES
${SIMGEAR_INCLUDE_DIR}
${JPEG_INCLUDE_DIR}
${OPENSCENEGRAPH_INCLUDE_DIRS})
check_cxx_source_compiles(
"#include <simgear/screen/jpgfactory.hxx>
int main() { return 0; } "
FG_JPEG_SERVER)
if (NOT FG_JPEG_SERVER)
message(STATUS "JPEG server support requested, but SimGear was built without JPEG support")
endif()
endif()
check_include_file(unistd.h HAVE_UNISTD_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
check_include_file(windows.h HAVE_WINDOWS_H)

View file

@ -3,11 +3,7 @@
You *must* have OpenSceneGraph (OSG) installed to build this version of
FlightGear.
Notice that from FlightGear version 1.9.0, OSG version 2.7.8 or later
is required. Using earlier versions of OSG will yield serious
rendering bugs. If you are using an 'older' distribution, this may mean
a suitable version of OSG may not be availble through the usual package
repositories.
Notice that FlightGear 2.6.0 requires at least version 3.0.0.
You can get the latest version of OSG from:

View file

@ -1,5 +1,7 @@
Getting started with CMake
[Windows instructions at the end of this document]
(These instructions apply to Unix-like systems, including Cygwin and Mac. To
build using Visual Studio or some other IDE supported by CMake, most of the
information below still applies)
@ -8,7 +10,7 @@ Always compile in a separate directory to the code. For example, if the
code (eg, from Git) is at /home/curt/projects/flightgear, you might create
/home/curt/projects/fgbuild. Change into the new directory, and run
cmake ../flightger
cmake ../flightgear
To generate standard Unix Makefiles in fgbuild.
@ -153,3 +155,71 @@ If you add an additional line
Then running 'make test' will run your executable as a unit test. The
executable should return either a success or failure result code.
SPECIAL INSTRUCTIONS TO BUILD UNDER WINDOWS WITH VISUAL STUDIO
==============================================================
On Windows, assumptions on the directory structure are made to automate the discovery of dependencies.
This recommended directory structure is described below:
${MSVC_3RDPARTY_ROOT} /
3rdParty / ( includes plib, fltk, zlib, libpng, libjpeg, libtiff, freetype, libsvn, gdal, ...
bin /
include /
lib /
3rdParty.x64 / ( 64 bit version )
...
boost_1_44_0 /
boost /
install /
msvc100 / ( for VS2010 32 bits, or msvc90, msvc90-64 or msvc100-64 for VS2008 32, VS2008 64 and VS2010 64 )
OpenSceneGraph / ( OSG CMake install
bin /
include /
lib /
SimGear /
include /
lib /
If you do not use the recommended structure you will need to enter paths by hand. Source and build directories can be located anywhere.
The suggested inputs to cmake are :
MSVC_3RDPARTY_ROOT : location of the above directory structure
CMAKE_INSTALL_PREFIX : ${MSVC_3RDPARTY_ROOT}/install/msvc100/FlightGear (or any variation for the compiler version described above )
1. Set up a work directory as described above.
2. Open the Cmake gui.
3. Set "Where is the source code" to wherever you put the FlightGear sources (from the released tarball or the git repository).
4. Set "Where to build the binaries" to an empty directory.
5. Press the "Configure" button. The first time that the project is configured, Cmake will bring up a window asking which compiler you wish to use. Normally just accept Cmakes suggestion, and press Finish. Cmake will now do a check on your system and will produce a preliminary build configuration.
6. Cmake adds new configuration variables in red. Some have a value ending with -NOTFOUND. These variables should receive your attention. Some errors will prevent FlightGear to build and others will simply invalidate some options without provoking build errors. First check the MSVC_3RDPARTY_ROOT variable. If it is not set, chances are that there will be a lot of -NOTFOUND errors. Instead of trying to fix every error individually, set that variable and press the "Configure" button again.
7. Also check the lines with a checkbox. These are build options and may impact the feature set of the built program.
8. Change the CMAKE_INSTALL_PREFIX to ${MSVC_3RDPARTY_ROOT}/install/msvc100/FlightGear because C:\Program Files is likely unwritable to ordinary Windows users and will integrate better with the above directory structure (this is mandatory for SimGear if you don't want to solve errors by hand).
10. Repeat the process until the "Generate" button is enabled.
11. Press the "Generate" button.
12. Start Visual Studio 2010 and load the FlightGear solution (FlightGear.sln) located in "Where to build the binaries" (point 4.)
13. Choose the "Release" build in the VS2010 "Generation" toolbar
14. Generate the solution.
15. If there are build errors, return to Cmake, clear remaining errors, "Configure" and "Generate"
16. When Visual Studio is able to build everything without errors, build the INSTALL project to put the product files in ${CMAKE_INSTALL_PREFIX}
17. Enjoy!
PS: When updating the source from git, it is usually unnecessary to restart Cmake as the solution is able to reconfigure itself when Cmake files are changed. Simply rebuild the solution from Visual Studio and accept the reload of updated projects. It also possible to edit CMakeList.txt files directly in Visual Studio as they also appear in the solution, and projects will be reconfigured on the next generation. To change build options or directory path, it is mandatory to use the Cmake Gui. In case of problems, locate the CMakeCache.txt in "Where to build the binaries directory and delete it to reconfigure from scratch or use the menu item File->Delete Cache.

View file

@ -89,7 +89,7 @@ Section "" ;No components page, name is not important
; VC runtime redistributables
File "$%VCINSTALLDIR%\redist\x86\Microsoft.VC100.CRT\*.dll"
File /r ${FGRunDir}\share
File /r ${FGRunDir}\share\locale
SetOutPath $INSTDIR\osgPlugins-${OSGVersion}
File ${OSGPluginsDir}\osgdb_ac.dll
@ -102,6 +102,7 @@ Section "" ;No components page, name is not important
File ${OSGPluginsDir}\osgdb_png.dll
File ${OSGPluginsDir}\osgdb_dds.dll
File ${OSGPluginsDir}\osgdb_txf.dll
File ${OSGPluginsDir}\osgdb_freetype.dll
File ${OSGPluginsDir}\osgdb_serializers_osg.dll
File ${OSGPluginsDir}\osgdb_serializers_osganimation.dll
File ${OSGPluginsDir}\osgdb_serializers_osgfx.dll

View file

@ -0,0 +1,91 @@
#!/bin/sh
echo $1 $2
if [ "x$1" != "x" ]; then
BASE="$1"
else
BASE="/home/curt/Projects/FlightGear/"
fi
if [ "x$2" != "x" ]; then
VERSION="$2"
else
VERSION="2.5"
fi
echo base dir = $BASE, version = $VERSION
cd $BASE
tar \
--exclude=CVS \
--exclude='*~' \
--exclude='*.bak' \
--exclude='*.tex' \
--exclude='*.xcf' \
--exclude='*/c172/Instruments.high' \
--exclude='*/Textures/Unused' \
--exclude='*/Textures/*.orig' \
--exclude='*/Textures.high/*.new' \
--exclude='*/Textures.high/*.orig' \
--exclude='*/Textures.high/*.save' \
--exclude='*/data/Data' \
--exclude='*/Docs/source' \
--exclude='*/Models/MNUAV' \
--exclude='*/Models/Airspace' \
-cjvf FlightGear-data-${VERSION}.tar.bz2 \
data/AI \
data/Aircraft/Generic \
data/Aircraft/Instruments \
data/Aircraft/Instruments-3d \
data/Aircraft/UIUC \
data/Aircraft/777-200 \
data/Aircraft/A6M2 \
data/Aircraft/ASK13 \
data/Aircraft/b1900d \
data/Aircraft/bo105 \
data/Aircraft/c172p \
data/Aircraft/CitationX \
data/Aircraft/Dragonfly \
data/Aircraft/dhc2 \
data/Aircraft/f-14b \
data/Aircraft/Cub \
data/Aircraft/SenecaII \
data/Aircraft/sopwithCamel \
data/Aircraft/ufo \
data/Aircraft/ZLT-NT \
data/Airports \
data/Astro \
data/ATC \
data/AUTHORS \
data/ChangeLog \
data/COPYING \
data/D* \
data/Effects \
data/Environment \
data/Fonts \
data/gui \
data/HLA \
data/Huds \
data/Input \
data/joysticks.xml \
data/keyboard.xml \
data/Lighting \
data/materials.dtd \
data/materials.xml \
data/mice.xml \
data/Models \
data/MP \
data/N* \
data/options.xml \
data/preferences.xml \
data/Protocol \
data/README \
data/Scenery/Airports \
data/Scenery/Objects \
data/Scenery/Terrain \
data/Shaders \
data/Sounds \
data/T* \
data/version

View file

@ -385,14 +385,6 @@
RelativePath="..\..\..\src\Aircraft\controls.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Aircraft\replay.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Aircraft\replay.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Aircraft\flightrecorder.cxx"
>
@ -401,6 +393,14 @@
RelativePath="..\..\..\src\Aircraft\flightrecorder.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Aircraft\replay.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Aircraft\replay.hxx"
>
</File>
</Filter>
<Filter
Name="Lib_Airports"
@ -2525,6 +2525,38 @@
RelativePath="..\..\..\src\GUI\dialog.hxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGColor.cxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGColor.hxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGFontCache.cxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGFontCache.hxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGPUIDialog.cxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGPUIDialog.hxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGPUIMenuBar.cxx"
>
</File>
<File
RelativePath="..\..\..\src\GUI\FGPUIMenuBar.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Gui\fonts.cxx"
>
@ -3753,6 +3785,14 @@
RelativePath="..\..\..\src\Instrumentation\mrg.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Instrumentation\NavDisplay.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Instrumentation\NavDisplay.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Instrumentation\navradio.cxx"
>
@ -3777,14 +3817,6 @@
RelativePath="..\..\..\src\Instrumentation\od_gauge.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Instrumentation\NavDisplay.cxx"
>
</File>
<File
RelativePath="..\..\..\src\Instrumentation\NavDisplay.hxx"
>
</File>
<File
RelativePath="..\..\..\src\Instrumentation\rad_alt.cxx"
>

View file

@ -820,10 +820,10 @@ bool FGAIAircraft::leadPointReached(FGAIWaypoint* curr) {
}
if (trafficRef) {
//cerr << "Tracking callsign : \"" << fgGetString("/ai/track-callsign") << "\"" << endl;
/* if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
cerr << trafficRef->getCallSign() << " " << tgt_altitude_ft << " " << _getSpeed() << " "
<< _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->name << " " << vs << " " << tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl;
}*/
//if (trafficRef->getCallSign() == fgGetString("/ai/track-callsign")) {
//cerr << trafficRef->getCallSign() << " " << tgt_altitude_ft << " " << _getSpeed() << " "
// << _getAltitude() << " "<< _getLatitude() << " " << _getLongitude() << " " << dist_to_go << " " << lead_dist << " " << curr->getName() << " " << vs << " " << //tgt_vs << " " << bearing << " " << minBearing << " " << speedFraction << endl;
//}
}
if ((dist_to_go < lead_dist) ||
((dist_to_go > prev_dist_to_go) && (bearing > (minBearing * 1.1))) ) {
@ -1275,9 +1275,9 @@ void FGAIAircraft::updateActualState() {
updatePosition();
if (onGround())
speed = _performance->actualSpeed(this, groundTargetSpeed, dt);
speed = _performance->actualSpeed(this, groundTargetSpeed, dt, holdPos);
else
speed = _performance->actualSpeed(this, (tgt_speed *speedFraction), dt);
speed = _performance->actualSpeed(this, (tgt_speed *speedFraction), dt, false);
//assertSpeed(speed);
updateHeading();
roll = _performance->actualBankAngle(this, tgt_roll, dt);

View file

@ -267,7 +267,7 @@ bool FGAIBase::init(bool search_in_AI_path) {
else
_installed = true;
osg::Node * mdl = SGModelLib::loadPagedModel(f, props, new FGNasalModelData(props));
osg::Node * mdl = SGModelLib::loadDeferredModel(f, props, new FGNasalModelData(props));
if (_model.valid())
{

View file

@ -357,7 +357,7 @@ void FGAIFlightPlan::createDefaultLandingTaxi(FGAIAircraft * ac,
double heading, lat, lon;
aAirport->getDynamics()->getParking(gateId, &lat, &lon, &heading);
wpt =
createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), airportElev,
createOnGround(ac, "ENDtaxi", SGGeod::fromDeg(lon, lat), airportElev,
ac->getPerformance()->vTaxi());
pushBackWaypoint(wpt);
}
@ -1039,7 +1039,7 @@ bool FGAIFlightPlan::createParking(FGAIAircraft * ac, FGAirport * apt,
pushBackWaypoint(wpt);
wpt =
createOnGround(ac, "END", SGGeod::fromDeg(lon, lat), aptElev,
createOnGround(ac, "END-Parking", SGGeod::fromDeg(lon, lat), aptElev,
vTaxiReduced);
pushBackWaypoint(wpt);
return true;

View file

@ -38,13 +38,13 @@
// TODO: Use James Turner's createOnGround functions.
bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius,
const string& fltType,
const string& aircraftType,
const string& airline)
bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius,
const string& fltType,
const string& aircraftType,
const string& airline)
{
double lat, lon, heading;
double vTaxi = ac->getPerformance()->vTaxi();
@ -56,132 +56,132 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
activeRunway.clear();
if (!(dep->getDynamics()->getGroundNetwork()->exists())) {
//cerr << "Push Back fallback" << endl;
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
//cerr << "Push Back fallback" << endl;
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
} else {
if (firstFlight) {
if (firstFlight) {
if (!(dep->getDynamics()->getAvailableParking(&lat, &lon,
&heading, &gateId,
radius, fltType,
aircraftType, airline))) {
SG_LOG(SG_INPUT, SG_WARN, "Warning: Could not find parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
return false;
char buffer[10];
snprintf (buffer, 10, "%d", gateId);
SGGeod coord = coord.fromDeg(lon, lat);
//FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
wpt->setRouteIndex(-1);
pushBackWaypoint(wpt);
}
//cerr << "Success : GateId = " << gateId << endl;
SG_LOG(SG_INPUT, SG_WARN, "Warning: Succesfully found a parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
} else {
//cerr << "Push Back follow-up Flight" << endl;
dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
}
if (gateId < 0) {
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
return true;
if (!(dep->getDynamics()->getAvailableParking(&lat, &lon,
&heading, &gateId,
radius, fltType,
aircraftType, airline))) {
SG_LOG(SG_INPUT, SG_WARN, "Warning: Could not find parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
return false;
char buffer[10];
snprintf (buffer, 10, "%d", gateId);
SGGeod coord = coord.fromDeg(lon, lat);
//FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
wpt->setRouteIndex(-1);
pushBackWaypoint(wpt);
}
//cerr << "Success : GateId = " << gateId << endl;
SG_LOG(SG_INPUT, SG_WARN, "Warning: Succesfully found a parking for a " <<
aircraftType <<
" of flight type " << fltType <<
" of airline " << airline <<
" at airport " << dep->getId());
} else {
//cerr << "Push Back follow-up Flight" << endl;
dep->getDynamics()->getParking(gateId, &lat, &lon, &heading);
}
if (gateId < 0) {
createPushBackFallBack(ac, firstFlight, dep, latitude, longitude,
radius, fltType, aircraftType, airline);
return true;
}
//cerr << "getting parking " << gateId;
//cerr << " for a " <<
// aircraftType <<
// " of flight type " << fltType <<
// " of airline " << airline <<
// " at airport " << dep->getId() << endl;
FGParking *parking = dep->getDynamics()->getParking(gateId);
int pushBackNode = parking->getPushBackPoint();
}
//cerr << "getting parking " << gateId;
//cerr << " for a " <<
// aircraftType <<
// " of flight type " << fltType <<
// " of airline " << airline <<
// " at airport " << dep->getId() << endl;
FGParking *parking = dep->getDynamics()->getParking(gateId);
int pushBackNode = parking->getPushBackPoint();
pushBackRoute = parking->getPushBackRoute();
if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
int node, rte;
FGTaxiRoute route;
//cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
parking->setPushBackRoute(new FGTaxiRoute(route));
pushBackRoute = parking->getPushBackRoute();
if ((pushBackNode > 0) && (pushBackRoute == 0)) { // Load the already established route for this gate
int node, rte;
FGTaxiRoute route;
//cerr << "Creating push-back for " << gateId << " (" << parking->getName() << ") using push-back point " << pushBackNode << endl;
route = dep->getDynamics()->getGroundNetwork()->findShortestRoute(gateId, pushBackNode, false);
parking->setPushBackRoute(new FGTaxiRoute(route));
pushBackRoute = parking->getPushBackRoute();
int size = pushBackRoute->size();
if (size < 2) {
SG_LOG(SG_GENERAL, SG_WARN, "Push back route from gate " << gateId << " has only " << size << " nodes.");
SG_LOG(SG_GENERAL, SG_WARN, "Using " << pushBackNode);
}
pushBackRoute->first();
while(pushBackRoute->next(&node, &rte))
{
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
char buffer[10];
snprintf (buffer, 10, "%d", node);
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
//ids.pop_back();
//wpt = new waypoint;
SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
pushBackRoute = parking->getPushBackRoute();
int size = pushBackRoute->size();
if (size < 2) {
SG_LOG(SG_GENERAL, SG_WARN, "Push back route from gate " << gateId << " has only " << size << " nodes.");
SG_LOG(SG_GENERAL, SG_WARN, "Using " << pushBackNode);
}
pushBackRoute->first();
while (pushBackRoute->next(&node, &rte))
{
//FGTaxiNode *tn = apt->getDynamics()->getGroundNetwork()->findSegment(node)->getEnd();
char buffer[10];
snprintf (buffer, 10, "%d", node);
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(node);
//ids.pop_back();
//wpt = new waypoint;
SGGeod coord = coord.fromDeg(tn->getLongitude(), tn->getLatitude());
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiBackward);
wpt->setRouteIndex(rte);
pushBackWaypoint(wpt);
}
// some special considerations for the last point:
waypoints.back()->setName(string("PushBackPoint"));
waypoints.back()->setSpeed(vTaxi);
ac->setTaxiClearanceRequest(true);
} else { // In case of a push forward departure...
ac->setTaxiClearanceRequest(false);
double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
wpt->setRouteIndex(rte);
pushBackWaypoint(wpt);
}
// some special considerations for the last point:
waypoints.back()->setName(string("PushBackPoint"));
waypoints.back()->setSpeed(vTaxi);
ac->setTaxiClearanceRequest(true);
} else { // In case of a push forward departure...
ac->setTaxiClearanceRequest(false);
double lat2 = 0.0, lon2 = 0.0, az2 = 0.0;
//cerr << "Creating final push forward point for gate " << gateId << endl;
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
FGTaxiSegmentVectorIterator te = tn->getEndRoute();
// if the starting node equals the ending node, then there aren't any routes for this parking.
// in cases like these we should flag the gate as being inoperative and return false
if (ts == te) {
SG_LOG(SG_GENERAL, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
parking->setAvailable(false);
return false;
}
tn = (*ts)->getEnd();
lastNodeVisited = tn->getIndex();
if (tn == NULL) {
SG_LOG(SG_GENERAL, SG_ALERT, "No valid taxinode found");
exit(1);
}
double distance = (*ts)->getLength();
//cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
lat2 = tn->getLatitude();
lon2 = tn->getLongitude();
//cerr << "Creating final push forward point for gate " << gateId << endl;
FGTaxiNode *tn = dep->getDynamics()->getGroundNetwork()->findNode(gateId);
FGTaxiSegmentVectorIterator ts = tn->getBeginRoute();
FGTaxiSegmentVectorIterator te = tn->getEndRoute();
// if the starting node equals the ending node, then there aren't any routes for this parking.
// in cases like these we should flag the gate as being inoperative and return false
if (ts == te) {
SG_LOG(SG_GENERAL, SG_ALERT, "Gate " << gateId << "doesn't seem to have routes associated with it.");
parking->setAvailable(false);
return false;
}
tn = (*ts)->getEnd();
lastNodeVisited = tn->getIndex();
if (tn == NULL) {
SG_LOG(SG_GENERAL, SG_ALERT, "No valid taxinode found");
exit(1);
}
double distance = (*ts)->getLength();
//cerr << "Length of push forward route = " << distance << " and heading is " << heading << endl;
lat2 = tn->getLatitude();
lon2 = tn->getLongitude();
for (int i = 1; i < 10; i++) {
geo_direct_wgs_84 ( 0, lat, lon, heading,
((i / 10.0) * distance), &lat2, &lon2, &az2 );
char buffer[16];
snprintf(buffer, 16, "pushback-%02d", i);
SGGeod coord = coord.fromDeg(lon2, lat2);
//cerr << i << endl;
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
for (int i = 1; i < 10; i++) {
geo_direct_wgs_84 ( 0, lat, lon, heading,
((i / 10.0) * distance), &lat2, &lon2, &az2 );
char buffer[16];
snprintf(buffer, 16, "pushback-%02d", i);
SGGeod coord = coord.fromDeg(lon2, lat2);
//cerr << i << endl;
FGAIWaypoint *wpt = createOnGround(ac, string(buffer), coord, dep->getElevation(), vTaxiReduced);
wpt->setRouteIndex((*ts)->getIndex());
pushBackWaypoint(wpt);
}
// cerr << "Done " << endl;
waypoints.back()->setName(string("PushBackPoint"));
// cerr << "Done assinging new name" << endl;
}
wpt->setRouteIndex((*ts)->getIndex());
pushBackWaypoint(wpt);
}
// cerr << "Done " << endl;
waypoints.back()->setName(string("PushBackPoint"));
// cerr << "Done assinging new name" << endl;
}
}
return true;
}
@ -191,50 +191,50 @@ bool FGAIFlightPlan::createPushBack(FGAIAircraft *ac,
* network yet.
******************************************************************/
void FGAIFlightPlan::createPushBackFallBack(FGAIAircraft *ac, bool firstFlight, FGAirport *dep,
double latitude,
double longitude,
double radius,
const string& fltType,
const string& aircraftType,
const string& airline)
double latitude,
double longitude,
double radius,
const string& fltType,
const string& aircraftType,
const string& airline)
{
double heading;
double lat;
double lon;
double lat2 = 0.0;
double lon2 = 0.0;
double az2 = 0.0;
double heading;
double lat;
double lon;
double lat2 = 0.0;
double lon2 = 0.0;
double az2 = 0.0;
double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiBackward = vTaxi * (-2.0/3.0);
double vTaxiReduced = vTaxi * (2.0/3.0);
double vTaxi = ac->getPerformance()->vTaxi();
double vTaxiBackward = vTaxi * (-2.0/3.0);
double vTaxiReduced = vTaxi * (2.0/3.0);
dep->getDynamics()->getParking(-1, &lat, &lon, &heading);
dep->getDynamics()->getParking(-1, &lat, &lon, &heading);
heading += 180.0;
if (heading > 360)
heading -= 360;
heading += 180.0;
if (heading > 360)
heading -= 360;
SGGeod coord = coord.fromDeg(lon, lat);
FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
SGGeod coord = coord.fromDeg(lon, lat);
FGAIWaypoint *wpt = createOnGround(ac, string("park"), coord, dep->getElevation(), vTaxiBackward);
pushBackWaypoint(wpt);
pushBackWaypoint(wpt);
geo_direct_wgs_84 ( 0, lat, lon, heading,
10,
&lat2, &lon2, &az2 );
coord = coord.fromDeg(lon2, lat2);
wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
geo_direct_wgs_84 ( 0, lat, lon, heading,
10,
&lat2, &lon2, &az2 );
coord = coord.fromDeg(lon2, lat2);
wpt = createOnGround(ac, string("park2"), coord, dep->getElevation(), vTaxiBackward);
pushBackWaypoint(wpt);
pushBackWaypoint(wpt);
geo_direct_wgs_84 ( 0, lat, lon, heading,
2.2*radius,
&lat2, &lon2, &az2 );
coord = coord.fromDeg(lon2, lat2);
wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
pushBackWaypoint(wpt);
geo_direct_wgs_84 ( 0, lat, lon, heading,
2.2*radius,
&lat2, &lon2, &az2 );
coord = coord.fromDeg(lon2, lat2);
wpt = createOnGround(ac, string("taxiStart"), coord, dep->getElevation(), vTaxiReduced);
pushBackWaypoint(wpt);
}

View file

@ -146,7 +146,7 @@ FGAIManager::update(double dt) {
if (!enabled)
return;
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("Traffic Manager");
FGTrafficManager *tmgr = (FGTrafficManager*) globals->get_subsystem("traffic-manager");
_dt = dt;
ai_list_iterator ai_list_itr = ai_list.begin();

View file

@ -49,7 +49,7 @@ PerformanceData::PerformanceData( const std::string& filename)
PerformanceData::~PerformanceData()
{}
double PerformanceData::actualSpeed(FGAIAircraft* ac, double tgt_speed, double dt) {
double PerformanceData::actualSpeed(FGAIAircraft* ac, double tgt_speed, double dt, bool maxBrakes) {
// if (tgt_speed > _vTaxi & ac->onGround()) // maximum taxi speed on ground
// tgt_speed = _vTaxi;
// bad idea for a take off roll :-)
@ -66,7 +66,13 @@ double PerformanceData::actualSpeed(FGAIAircraft* ac, double tgt_speed, double d
} else if (speed_diff < 0.0) { // decelerate
if (ac->onGround()) {
// deceleration performance is better due to wheel brakes.
speed -= BRAKE_SETTING * _deceleration * dt;
double brakePower = 0;
if (maxBrakes) {
brakePower = 3;
} else {
brakePower = BRAKE_SETTING;
}
speed -= brakePower * _deceleration * dt;
} else {
speed -= _deceleration * dt;
}

View file

@ -29,7 +29,7 @@ public:
PerformanceData(const std::string& filename);
~PerformanceData();
double actualSpeed(FGAIAircraft* ac, double tgt_speed, double dt);
double actualSpeed(FGAIAircraft* ac, double tgt_speed, double dt, bool needMaxBrake);
double actualBankAngle(FGAIAircraft* ac, double tgt_roll, double dt);
double actualPitch(FGAIAircraft* ac, double tgt_pitch, double dt);
double actualHeading(FGAIAircraft* ac, double tgt_heading, double dt);

View file

@ -45,7 +45,7 @@ FGSubmodelMgr::~FGSubmodelMgr()
FGAIManager* FGSubmodelMgr::aiManager()
{
return (FGAIManager*)globals->get_subsystem("ai_model");
return (FGAIManager*)globals->get_subsystem("ai-model");
}
void FGSubmodelMgr::init()

View file

@ -100,7 +100,7 @@ void FGATCManager::init() {
FGAirport *apt = FGAirport::findByIdent(airport);
if (apt && onGround) {
if (apt && onGround && !runway.empty()) {
FGAirportDynamics* dcs = apt->getDynamics();
int park_index = dcs->getNrOfParkings() - 1;
//cerr << "found information: " << runway << " " << airport << ": parking = " << parking << endl;

View file

@ -18,8 +18,13 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Main/fg_commands.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include <simgear/constants.h>
#include <simgear/structure/commands.hxx>

View file

@ -30,6 +30,7 @@
#include <Main/globals.hxx>
#include <GUI/gui.h> // mkDialog
#include <GUI/new_gui.hxx>
#include <Main/fg_props.hxx>
#include "ATCDialogOld.hxx"
#include "ATC.hxx"
@ -205,7 +206,13 @@ void FGATCDialog::PopupDialog() {
button_group->removeChildren("button", false);
string label;
FGATC* atcptr = globals->get_ATC_mgr()->GetComm1ATCPointer(); // Hardwired to comm1 at the moment
FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
if (!pAtcMgr)
{
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
return;
}
FGATC* atcptr = pAtcMgr->GetComm1ATCPointer(); // Hardwired to comm1 at the moment
if (!atcptr) {
label = "Not currently tuned to any ATC service";
@ -260,7 +267,13 @@ void FGATCDialog::PopupDialog() {
}
void FGATCDialog::PopupCallback(int num) {
FGATC* atcptr = globals->get_ATC_mgr()->GetComm1ATCPointer(); // FIXME - Hardwired to comm1 at the moment
FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
if (!pAtcMgr)
{
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
return;
}
FGATC* atcptr = pAtcMgr->GetComm1ATCPointer(); // FIXME - Hardwired to comm1 at the moment
if (!atcptr)
return;

View file

@ -48,9 +48,11 @@ FGATCMgr::FGATCMgr() :
voice(false),
#endif
{
globals->set_ATC_mgr(this);
}
FGATCMgr::~FGATCMgr() {
globals->set_ATC_mgr(NULL);
delete v1;
}

View file

@ -76,7 +76,14 @@ FGATIS::FGATIS() :
_prev_display(0),
refname("atis")
{
_vPtr = globals->get_ATC_mgr()->GetVoicePointer(ATIS);
FGATCMgr* pAtcMgr = globals->get_ATC_mgr();
if (!pAtcMgr)
{
SG_LOG(SG_ATC, SG_ALERT, "ERROR! No ATC manager! Oops...");
_vPtr = NULL;
}
else
_vPtr = pAtcMgr->GetVoicePointer(ATIS);
_voiceOK = (_vPtr == NULL ? false : true);
if (!(_type != ATIS || _type == AWOS)) {
SG_LOG(SG_ATC, SG_ALERT, "ERROR - _type not ATIS or AWOS in atis.cxx");

View file

@ -20,6 +20,10 @@
//
///////////////////////////////////////////////////////////////////////////////
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdio.h>
#include <string.h>
#include <assert.h>

View file

@ -102,6 +102,7 @@ bool FGAirportDynamics::getAvailableParking(double *lat, double *lon,
//cerr << "Could not find parking spot at " << _ap->getId() << endl;
*lat = _ap->getLatitude();
*lon = _ap->getLongitude();
* gateId = -1;
*heading = 0;
found = true;
} else {

View file

@ -26,6 +26,7 @@
#include <math.h>
#include <algorithm>
#include <fstream>
#include <osg/Geode>

View file

@ -13,6 +13,10 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/misc/sg_path.hxx>
#include <simgear/xml/easyxml.hxx>
#include <simgear/misc/strutils.hxx>

View file

@ -57,7 +57,7 @@
#include <Main/fg_props.hxx>
#include <Main/viewmgr.hxx>
#include <Time/light.hxx>
#include <GUI/new_gui.hxx> // FGFontCache
#include <GUI/FGFontCache.hxx>
#include <Main/viewer.hxx>
#include <Instrumentation/dclgps.hxx>

View file

@ -31,6 +31,7 @@
#include <simgear/structure/event_mgr.hxx>
#include <Main/main.hxx>
#include <Main/renderer.hxx>
#include <Main/fg_props.hxx>
#include <FDM/flight.hxx>
@ -45,9 +46,6 @@
#include "Airports/simple.hxx"
#include "gravity.hxx"
class SGSky;
extern SGSky *thesky;
class FG3DCloudsListener : public SGPropertyChangeListener {
public:
FG3DCloudsListener( FGClouds * fgClouds );
@ -91,7 +89,8 @@ FGEnvironmentMgr::FGEnvironmentMgr () :
_altitude_n(fgGetNode("/position/altitude-ft", true)),
_longitude_n(fgGetNode( "/position/longitude-deg", true )),
_latitude_n( fgGetNode( "/position/latitude-deg", true )),
_3dCloudsEnableListener(new FG3DCloudsListener(fgClouds) )
_3dCloudsEnableListener(new FG3DCloudsListener(fgClouds) ),
_sky(globals->get_renderer()->getSky())
{
set_subsystem("controller", Environment::LayerInterpolateController::createInstance( fgGetNode("/environment/config", true ) ));
set_subsystem("realwx", Environment::RealWxController::createInstance( fgGetNode("/environment/realwx", true ) ), 1.0 );
@ -171,7 +170,7 @@ FGEnvironmentMgr::bind ()
_tiedProperties.setRoot( fgGetNode( "/environment", true ) );
_tiedProperties.Tie( "effective-visibility-m", thesky,
_tiedProperties.Tie( "effective-visibility-m", _sky,
&SGSky::get_visibility );
_tiedProperties.Tie("rebuild-layers", fgClouds,
@ -220,15 +219,15 @@ FGEnvironmentMgr::bind ()
_tiedProperties.setRoot( fgGetNode("/sim/rendering", true ) );
_tiedProperties.Tie( "clouds3d-density", thesky,
_tiedProperties.Tie( "clouds3d-density", _sky,
&SGSky::get_3dCloudDensity,
&SGSky::set_3dCloudDensity);
_tiedProperties.Tie("clouds3d-vis-range", thesky,
_tiedProperties.Tie("clouds3d-vis-range", _sky,
&SGSky::get_3dCloudVisRange,
&SGSky::set_3dCloudVisRange);
_tiedProperties.Tie("clouds3d-wrap", thesky,
_tiedProperties.Tie("clouds3d-wrap", _sky,
&SGSky::get_3dCloudWrap,
&SGSky::set_3dCloudWrap);
@ -325,19 +324,19 @@ FGEnvironmentMgr::getEnvironment(const SGGeod& aPos) const
double
FGEnvironmentMgr::get_cloud_layer_span_m (int index) const
{
return thesky->get_cloud_layer(index)->getSpan_m();
return _sky->get_cloud_layer(index)->getSpan_m();
}
void
FGEnvironmentMgr::set_cloud_layer_span_m (int index, double span_m)
{
thesky->get_cloud_layer(index)->setSpan_m(span_m);
_sky->get_cloud_layer(index)->setSpan_m(span_m);
}
double
FGEnvironmentMgr::get_cloud_layer_elevation_ft (int index) const
{
return thesky->get_cloud_layer(index)->getElevation_m() * SG_METER_TO_FEET;
return _sky->get_cloud_layer(index)->getElevation_m() * SG_METER_TO_FEET;
}
void
@ -346,88 +345,88 @@ FGEnvironmentMgr::set_cloud_layer_elevation_ft (int index, double elevation_ft)
FGEnvironment env = *_environment;
env.set_elevation_ft(elevation_ft);
thesky->get_cloud_layer(index)
_sky->get_cloud_layer(index)
->setElevation_m(elevation_ft * SG_FEET_TO_METER);
thesky->get_cloud_layer(index)
_sky->get_cloud_layer(index)
->setSpeed(env.get_wind_speed_kt() * 0.5151); // 1 kt = 0.5151 m/s
thesky->get_cloud_layer(index)
_sky->get_cloud_layer(index)
->setDirection(env.get_wind_from_heading_deg());
}
double
FGEnvironmentMgr::get_cloud_layer_thickness_ft (int index) const
{
return thesky->get_cloud_layer(index)->getThickness_m() * SG_METER_TO_FEET;
return _sky->get_cloud_layer(index)->getThickness_m() * SG_METER_TO_FEET;
}
void
FGEnvironmentMgr::set_cloud_layer_thickness_ft (int index, double thickness_ft)
{
thesky->get_cloud_layer(index)
_sky->get_cloud_layer(index)
->setThickness_m(thickness_ft * SG_FEET_TO_METER);
}
double
FGEnvironmentMgr::get_cloud_layer_transition_ft (int index) const
{
return thesky->get_cloud_layer(index)->getTransition_m() * SG_METER_TO_FEET;
return _sky->get_cloud_layer(index)->getTransition_m() * SG_METER_TO_FEET;
}
void
FGEnvironmentMgr::set_cloud_layer_transition_ft (int index,
double transition_ft)
{
thesky->get_cloud_layer(index)
_sky->get_cloud_layer(index)
->setTransition_m(transition_ft * SG_FEET_TO_METER);
}
const char *
FGEnvironmentMgr::get_cloud_layer_coverage (int index) const
{
return thesky->get_cloud_layer(index)->getCoverageString().c_str();
return _sky->get_cloud_layer(index)->getCoverageString().c_str();
}
void
FGEnvironmentMgr::set_cloud_layer_coverage (int index,
const char * coverage_name)
{
if( thesky->get_cloud_layer(index)->getCoverageString() == coverage_name )
if( _sky->get_cloud_layer(index)->getCoverageString() == coverage_name )
return;
thesky->get_cloud_layer(index)->setCoverageString(coverage_name);
_sky->get_cloud_layer(index)->setCoverageString(coverage_name);
_cloudLayersDirty = true;
}
int
FGEnvironmentMgr::get_cloud_layer_coverage_type (int index) const
{
return thesky->get_cloud_layer(index)->getCoverage();
return _sky->get_cloud_layer(index)->getCoverage();
}
double
FGEnvironmentMgr::get_cloud_layer_visibility_m (int index) const
{
return thesky->get_cloud_layer(index)->getVisibility_m();
return _sky->get_cloud_layer(index)->getVisibility_m();
}
void
FGEnvironmentMgr::set_cloud_layer_visibility_m (int index, double visibility_m)
{
thesky->get_cloud_layer(index)->setVisibility_m(visibility_m);
_sky->get_cloud_layer(index)->setVisibility_m(visibility_m);
}
double
FGEnvironmentMgr::get_cloud_layer_maxalpha (int index ) const
{
return thesky->get_cloud_layer(index)->getMaxAlpha();
return _sky->get_cloud_layer(index)->getMaxAlpha();
}
void
FGEnvironmentMgr::set_cloud_layer_maxalpha (int index, double maxalpha)
{
thesky->get_cloud_layer(index)->setMaxAlpha(maxalpha);
_sky->get_cloud_layer(index)->setMaxAlpha(maxalpha);
}
void
@ -438,10 +437,10 @@ FGEnvironmentMgr::set_cloud_layer_coverage_type (int index, int type )
return;
}
if( static_cast<SGCloudLayer::Coverage>(type) == thesky->get_cloud_layer(index)->getCoverage() )
if( static_cast<SGCloudLayer::Coverage>(type) == _sky->get_cloud_layer(index)->getCoverage() )
return;
thesky->get_cloud_layer(index)->setCoverage(static_cast<SGCloudLayer::Coverage>(type));
_sky->get_cloud_layer(index)->setCoverage(static_cast<SGCloudLayer::Coverage>(type));
_cloudLayersDirty = true;
}

View file

@ -38,6 +38,7 @@ class FGMetarCtrl;
class FGMetarFetcher;
class FGClouds;
class FGPrecipitationMgr;
class SGSky;
/**
* Manage environment information.
@ -102,6 +103,8 @@ private:
SGPropertyNode_ptr _latitude_n;
simgear::TiedPropertyList _tiedProperties;
SGPropertyChangeListener * _3dCloudsEnableListener;
SGSky* _sky;
};
#endif // _ENVIRONMENT_MGR_HXX

View file

@ -32,6 +32,10 @@ Ephemeris::Ephemeris() :
_impl(NULL),
_latProp(NULL)
{
SGPath ephem_data_path(globals->get_fg_root());
ephem_data_path.append("Astro");
_impl = new SGEphemeris(ephem_data_path.c_str());
globals->set_ephem(_impl);
}
Ephemeris::~Ephemeris()
@ -41,15 +45,6 @@ Ephemeris::~Ephemeris()
void Ephemeris::init()
{
if (_impl) {
return;
}
SGPath ephem_data_path(globals->get_fg_root());
ephem_data_path.append("Astro");
_impl = new SGEphemeris(ephem_data_path.c_str());
globals->set_ephem(_impl);
_latProp = fgGetNode("/position/latitude-deg", true);
update(0.0);
}

View file

@ -38,13 +38,12 @@
#include <simgear/props/props_io.hxx>
#include <Main/globals.hxx>
#include <Main/renderer.hxx>
#include <Airports/simple.hxx>
#include <Main/util.hxx>
#include "fgclouds.hxx"
extern SGSky *thesky;
static bool do_delete_3Dcloud (const SGPropertyNode *arg);
static bool do_move_3Dcloud (const SGPropertyNode *arg);
static bool do_add_3Dcloud (const SGPropertyNode *arg);
@ -182,6 +181,8 @@ void FGClouds::buildLayer(int iLayer, const string& name, double coverage) {
int CloudVarietyCount = 0;
double totalCount = 0.0;
SGSky* thesky = globals->get_renderer()->getSky();
SGPropertyNode *cloud_def_root = fgGetNode("/environment/cloudlayers/clouds", false);
SGPropertyNode *box_def_root = fgGetNode("/environment/cloudlayers/boxes", false);
SGPropertyNode *layer_def_root = fgGetNode("/environment/cloudlayers/layers", false);
@ -274,6 +275,7 @@ void FGClouds::buildCloudLayers(void) {
double cumulus_base = 122.0 * (temperature_degc - dewpoint_degc);
double stratus_base = 100.0 * (100.0 - rel_humidity) * SG_FEET_TO_METER;
SGSky* thesky = globals->get_renderer()->getSky();
for(int iLayer = 0 ; iLayer < thesky->get_cloud_layer_count(); iLayer++) {
SGPropertyNode *cloud_root = fgGetNode("/environment/clouds/layer", iLayer, true);
@ -366,7 +368,7 @@ bool FGClouds::get_3dClouds() const
float x = arg->getFloatValue("x-offset-m", 0.0f);
float y = arg->getFloatValue("y-offset-m", 0.0f);
SGSky* thesky = globals->get_renderer()->getSky();
SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D();
SGNewCloud cld = SGNewCloud(texture_root, arg);
bool success = layer->addCloud(lon, lat, alt, x, y, index, cld.genCloud());
@ -392,6 +394,7 @@ bool FGClouds::get_3dClouds() const
int l = arg->getIntValue("layer", 0);
int i = arg->getIntValue("index", 0);
SGSky* thesky = globals->get_renderer()->getSky();
SGCloudField *layer = thesky->get_cloud_layer(l)->get_layer3D();
return layer->deleteCloud(i);
}
@ -410,6 +413,7 @@ bool FGClouds::get_3dClouds() const
{
int l = arg->getIntValue("layer", 0);
int i = arg->getIntValue("index", 0);
SGSky* thesky = globals->get_renderer()->getSky();
float lon = arg->getFloatValue("lon-deg", 0.0f);
float lat = arg->getFloatValue("lat-deg", 0.0f);

View file

@ -39,13 +39,11 @@
#include <Main/fg_props.hxx>
#include <Main/globals.hxx>
#include <Main/renderer.hxx>
#include <Scenery/scenery.hxx>
#include "precipitation_mgr.hxx"
extern SGSky *thesky;
/**
* @brief FGPrecipitation Manager constructor
*
@ -141,6 +139,8 @@ float FGPrecipitationMgr::getPrecipitationAtAltitudeMax(void)
max = SGCloudLayer::SG_MAX_CLOUD_COVERAGES;
result = 0;
SGSky* thesky = globals->get_renderer()->getSky();
// To avoid messing up
if (thesky == NULL)
return result;

View file

@ -1,3 +1,8 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "Math.hpp"
#include "BodyEnvironment.hpp"
#include "RigidBody.hpp"

View file

@ -1,3 +1,8 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/debug/logstream.hxx>
#include "Math.hpp"

View file

@ -139,7 +139,14 @@ void YASim::init()
SGPath f(fgGetString("/sim/aircraft-dir"));
f.append(fgGetString("/sim/aero"));
f.concat(".xml");
readXML(f.str(), *_fdm);
try {
readXML(f.str(), *_fdm);
} catch (const sg_exception &e) {
SG_LOG(SG_GENERAL, SG_ALERT,
"Error reading YASim FDM: '" << f.str() << "'" << std::endl
<< e.getFormattedMessage());
throw e;
}
// Compile it into a real airplane, and tell the user what they got
a->compile();

View file

@ -5,7 +5,7 @@
#include <simgear/compiler.h>
#include <plib/puAux.h>
#include "dialog.hxx"
#include "FGPUIDialog.hxx"
class FGAirportList;

View file

@ -6,14 +6,18 @@ set(SOURCES
SafeTexFont.cxx
WaypointList.cxx
dialog.cxx
FGPUIDialog.cxx
fonts.cxx
gui.cxx
gui_funcs.cxx
layout-props.cxx
layout.cxx
menubar.cxx
FGPUIMenuBar.cxx
new_gui.cxx
property_list.cxx
FGFontCache.cxx
FGColor.cxx
)
set(HEADERS
@ -22,11 +26,15 @@ set(HEADERS
SafeTexFont.hxx
WaypointList.hxx
dialog.hxx
FGPUIDialog.hxx
gui.h
layout.hxx
menubar.hxx
FGPUIMenuBar.hxx
new_gui.hxx
property_list.hxx
FGFontCache.hxx
FGColor.hxx
)
flightgear_component(GUI "${SOURCES}" "${HEADERS}")

55
src/GUI/FGColor.cxx Normal file
View file

@ -0,0 +1,55 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "FGColor.hxx"
#include <iostream>
#include <simgear/props/props.hxx>
#include <simgear/math/SGMath.hxx>
////////////////////////////////////////////////////////////////////////
// FGColor class.
////////////////////////////////////////////////////////////////////////
void
FGColor::print() const {
std::cerr << "red=" << _red << ", green=" << _green
<< ", blue=" << _blue << ", alpha=" << _alpha << std::endl;
}
bool
FGColor::merge(const SGPropertyNode *node)
{
if (!node)
return false;
bool dirty = false;
const SGPropertyNode * n;
if ((n = node->getNode("red")))
_red = n->getFloatValue(), dirty = true;
if ((n = node->getNode("green")))
_green = n->getFloatValue(), dirty = true;
if ((n = node->getNode("blue")))
_blue = n->getFloatValue(), dirty = true;
if ((n = node->getNode("alpha")))
_alpha = n->getFloatValue(), dirty = true;
return dirty;
}
bool
FGColor::merge(const FGColor *color)
{
bool dirty = false;
if (color && color->_red >= 0.0)
_red = color->_red, dirty = true;
if (color && color->_green >= 0.0)
_green = color->_green, dirty = true;
if (color && color->_blue >= 0.0)
_blue = color->_blue, dirty = true;
if (color && color->_alpha >= 0.0)
_alpha = color->_alpha, dirty = true;
return dirty;
}

49
src/GUI/FGColor.hxx Normal file
View file

@ -0,0 +1,49 @@
#ifndef FG_GUI_COLOR_HXX
#define FG_GUI_COLOR_HXX
// forward decls
class SGPropertyNode;
class FGColor {
public:
FGColor() { clear(); }
FGColor(float r, float g, float b, float a = 1.0f) { set(r, g, b, a); }
FGColor(const SGPropertyNode *prop) { set(prop); }
FGColor(FGColor *c) {
if (c) set(c->_red, c->_green, c->_blue, c->_alpha);
}
inline void clear() { _red = _green = _blue = _alpha = -1.0f; }
// merges in non-negative components from property with children <red> etc.
bool merge(const SGPropertyNode *prop);
bool merge(const FGColor *color);
bool set(const SGPropertyNode *prop) { clear(); return merge(prop); };
bool set(const FGColor *color) { clear(); return merge(color); }
bool set(float r, float g, float b, float a = 1.0f) {
_red = r, _green = g, _blue = b, _alpha = a;
return true;
}
bool isValid() const {
return _red >= 0.0 && _green >= 0.0 && _blue >= 0.0;
}
void print() const;
inline void setRed(float red) { _red = red; }
inline void setGreen(float green) { _green = green; }
inline void setBlue(float blue) { _blue = blue; }
inline void setAlpha(float alpha) { _alpha = alpha; }
inline float red() const { return clamp(_red); }
inline float green() const { return clamp(_green); }
inline float blue() const { return clamp(_blue); }
inline float alpha() const { return _alpha < 0.0 ? 1.0 : clamp(_alpha); }
protected:
float _red, _green, _blue, _alpha;
private:
float clamp(float f) const { return f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; }
};
#endif

223
src/GUI/FGFontCache.cxx Normal file
View file

@ -0,0 +1,223 @@
//
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
#include <windows.h>
#endif
#include "FGFontCache.hxx"
#include <plib/fnt.h>
#include <plib/pu.h>
#include <simgear/props/props.hxx>
#include <Main/globals.hxx>
////////////////////////////////////////////////////////////////////////
// FGFontCache class.
////////////////////////////////////////////////////////////////////////
extern puFont FONT_HELVETICA_14;
extern puFont FONT_SANS_12B;
namespace
{
struct GuiFont
{
const char *name;
puFont *font;
struct Predicate
: public std::unary_function<const GuiFont, bool>
{
Predicate(const char* name_) : name(name_) {}
bool operator() (const GuiFont& f1) const
{
return ::strcmp(f1.name, name) == 0;
}
const char* name;
};
};
const GuiFont guifonts[] = {
{ "default", &PUFONT_HELVETICA_12 },
{ "FIXED_8x13", &PUFONT_8_BY_13 },
{ "FIXED_9x15", &PUFONT_9_BY_15 },
{ "TIMES_10", &PUFONT_TIMES_ROMAN_10 },
{ "TIMES_24", &PUFONT_TIMES_ROMAN_24 },
{ "HELVETICA_10", &PUFONT_HELVETICA_10 },
{ "HELVETICA_12", &PUFONT_HELVETICA_12 },
{ "HELVETICA_14", &FONT_HELVETICA_14 },
{ "HELVETICA_18", &PUFONT_HELVETICA_18 },
{ "SANS_12B", &FONT_SANS_12B }
};
const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
}
FGFontCache::FGFontCache() :
_initialized(false)
{
}
FGFontCache::~FGFontCache()
{
PuFontMap::iterator it, end = _puFonts.end();
for (it = _puFonts.begin(); it != end; ++it)
delete it->second;
}
inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
const FntParams& f2) const
{
int comp = f1.name.compare(f2.name);
if (comp < 0)
return true;
else if (comp > 0)
return false;
if (f1.size < f2.size)
return true;
else if (f1.size > f2.size)
return false;
return f1.slant < f2.slant;
}
struct FGFontCache::fnt *
FGFontCache::getfnt(const char *name, float size, float slant)
{
std::string fontName(name);
FntParams fntParams(fontName, size, slant);
PuFontMap::iterator i = _puFonts.find(fntParams);
if (i != _puFonts.end())
return i->second;
// fntTexFont s are all preloaded into the _texFonts map
TexFontMap::iterator texi = _texFonts.find(fontName);
fntTexFont* texfont = 0;
puFont* pufont = 0;
if (texi != _texFonts.end()) {
texfont = texi->second;
} else {
const GuiFont* guifont = std::find_if(&guifonts[0], guifontsEnd,
GuiFont::Predicate(name));
if (guifont != guifontsEnd) {
pufont = guifont->font;
}
}
fnt* f = new fnt;
if (pufont) {
f->pufont = pufont;
} else if (texfont) {
f->texfont = texfont;
f->pufont = new puFont;
f->pufont->initialize(static_cast<fntFont *>(f->texfont), size, slant);
} else {
f->pufont = guifonts[0].font;
}
_puFonts[fntParams] = f;
return f;
}
puFont *
FGFontCache::get(const char *name, float size, float slant)
{
return getfnt(name, size, slant)->pufont;
}
fntTexFont *
FGFontCache::getTexFont(const char *name, float size, float slant)
{
init();
return getfnt(name, size, slant)->texfont;
}
puFont *
FGFontCache::get(SGPropertyNode *node)
{
if (!node)
return get("Helvetica.txf", 15.0, 0.0);
const char *name = node->getStringValue("name", "Helvetica.txf");
float size = node->getFloatValue("size", 15.0);
float slant = node->getFloatValue("slant", 0.0);
return get(name, size, slant);
}
void FGFontCache::init()
{
if (!_initialized) {
char *envp = ::getenv("FG_FONTS");
if (envp != NULL) {
_path.set(envp);
} else {
_path.set(globals->get_fg_root());
_path.append("Fonts");
}
_initialized = true;
}
}
SGPath
FGFontCache::getfntpath(const char *name)
{
init();
SGPath path(_path);
if (name && std::string(name) != "") {
path.append(name);
if (path.exists())
return path;
}
path = SGPath(_path);
path.append("Helvetica.txf");
return path;
}
bool FGFontCache::initializeFonts()
{
static std::string fontext("txf");
init();
ulDir* fontdir = ulOpenDir(_path.c_str());
if (!fontdir)
return false;
const ulDirEnt *dirEntry;
while ((dirEntry = ulReadDir(fontdir)) != 0) {
SGPath path(_path);
path.append(dirEntry->d_name);
if (path.extension() == fontext) {
fntTexFont* f = new fntTexFont;
if (f->load((char *)path.c_str()))
_texFonts[std::string(dirEntry->d_name)] = f;
else
delete f;
}
}
ulCloseDir(fontdir);
return true;
}
FGFontCache::fnt::~fnt()
{
if (texfont) {
delete pufont;
delete texfont;
}
}

96
src/GUI/FGFontCache.hxx Normal file
View file

@ -0,0 +1,96 @@
// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef __FGFONTCACHE_HXX
#define __FGFONTCACHE_HXX
#include <simgear/math/SGMath.hxx>
#include <simgear/misc/sg_path.hxx>
#include <map>
#include <algorithm>
// forward decls
class SGPropertyNode;
class puFont;
class fntTexFont;
/**
* A class to keep all fonts available for future use.
* This also assures a font isn't resident more than once.
*/
class FGFontCache {
private:
// The parameters of a request to the cache.
struct FntParams
{
const std::string name;
const float size;
const float slant;
FntParams() : size(0.0f), slant(0.0f) {}
FntParams(const FntParams& rhs)
: name(rhs.name), size(rhs.size), slant(rhs.slant)
{
}
FntParams(const std::string& name_, float size_, float slant_)
: name(name_), size(size_), slant(slant_)
{
}
};
struct FntParamsLess
: public std::binary_function<const FntParams, const FntParams, bool>
{
bool operator() (const FntParams& f1, const FntParams& f2) const;
};
struct fnt {
fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
~fnt();
// Font used by plib GUI code
puFont *pufont;
// TXF font
fntTexFont *texfont;
};
// Path to the font directory
SGPath _path;
typedef std::map<const std::string, fntTexFont*> TexFontMap;
typedef std::map<const FntParams, fnt*, FntParamsLess> PuFontMap;
TexFontMap _texFonts;
PuFontMap _puFonts;
bool _initialized;
struct fnt *getfnt(const char *name, float size, float slant);
void init();
public:
FGFontCache();
~FGFontCache();
puFont *get(const char *name, float size=15.0, float slant=0.0);
puFont *get(SGPropertyNode *node);
fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
SGPath getfntpath(const char *name);
/**
* Preload all the fonts in the FlightGear font directory. It is
* important to load the font textures early, with the proper
* graphics context current, so that no plib (or our own) code
* tries to load a font from disk when there's no current graphics
* context.
*/
bool initializeFonts();
};
#endif

1418
src/GUI/FGPUIDialog.cxx Normal file

File diff suppressed because it is too large Load diff

277
src/GUI/FGPUIDialog.hxx Normal file
View file

@ -0,0 +1,277 @@
// FGPUIDialog.hxx - XML-configured dialog box.
#ifndef FG_PUI_DIALOG_HXX
#define FG_PUI_DIALOG_HXX 1
#include "dialog.hxx"
#include <plib/puAux.h>
#include <simgear/props/props.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/condition.hxx>
#include <vector>
// ugly temporary workaround for plib's lack of user defined class ids FIXME
#define FGCLASS_LIST 0x00000001
#define FGCLASS_AIRPORTLIST 0x00000002
#define FGCLASS_PROPERTYLIST 0x00000004
#define FGCLASS_WAYPOINTLIST 0x00000008
class GUI_ID { public: GUI_ID(int id) : id(id) {} virtual ~GUI_ID() {} int id; };
class NewGUI;
class FGColor;
class puObject;
class puFont;
/**
* An XML-configured dialog box.
*
* The GUI manager stores only the property tree for the dialog
* boxes. This class creates a PUI dialog box on demand from
* the properties in that tree. The manager recreates the dialog
* every time it needs to show it.
*/
class FGPUIDialog : public FGDialog
{
public:
/**
* Construct a new GUI widget configured by a property tree.
*
* The configuration properties are not part of the main
* FlightGear property tree; the GUI manager reads them
* from individual configuration files.
*
* @param props A property tree describing the dialog.
*/
FGPUIDialog (SGPropertyNode * props);
/**
* Destructor.
*/
virtual ~FGPUIDialog ();
/**
* Update the values of all GUI objects with a specific name,
* or all if name is 0 (default).
*
* This method copies values from the FlightGear property tree to
* the GUI object(s).
*
* @param objectName The name of the GUI object(s) to update.
* Use the empty name for all unnamed objects.
*/
virtual void updateValues (const char * objectName = 0);
/**
* Apply the values of all GUI objects with a specific name,
* or all if name is 0 (default)
*
* This method copies values from the GUI object(s) to the
* FlightGear property tree.
*
* @param objectName The name of the GUI object(s) to update.
* Use the empty name for all unnamed objects.
*/
virtual void applyValues (const char * objectName = 0);
/**
* Update state. Called on active dialogs before rendering.
*/
virtual void update ();
/**
* Recompute the dialog's layout
*/
void relayout();
void setNeedsLayout() {
_needsRelayout = true;
}
private:
enum {
BACKGROUND = 0x01,
FOREGROUND = 0x02,
HIGHLIGHT = 0x04,
LABEL = 0x08,
LEGEND = 0x10,
MISC = 0x20,
EDITFIELD = 0x40
};
// Show the dialog.
void display (SGPropertyNode * props);
// Build the dialog or a subobject of it.
puObject * makeObject (SGPropertyNode * props,
int parentWidth, int parentHeight);
// Common configuration for all GUI objects.
void setupObject (puObject * object, SGPropertyNode * props);
// Common configuration for all GUI group objects.
void setupGroup (puGroup * group, SGPropertyNode * props,
int width, int height, bool makeFrame = false);
// Set object colors: the "which" argument defines which color qualities
// (PUCOL_LABEL, etc.) should pick up the <color> property.
void setColor(puObject * object, SGPropertyNode * props, int which = 0);
// return key code number for keystring
int getKeyCode(const char *keystring);
/**
* Apply layout sizes to a tree of puObjects
*/
void applySize(puObject *object);
// The top-level PUI object.
puObject * _object;
// The GUI subsystem.
NewGUI * _gui;
// The dialog font. Defaults to the global gui font, but can get
// overridden by a top level font definition.
puFont * _font;
// The source xml tree, so that we can pass data back, such as the
// last position.
SGPropertyNode_ptr _props;
bool _needsRelayout;
// Nasal module.
std::string _module;
SGPropertyNode_ptr _nasal_close;
// PUI provides no way for userdata to be deleted automatically
// with a GUI object, so we have to keep track of all the special
// data we allocated and then free it manually when the dialog
// closes.
std::vector<void *> _info;
struct PropertyObject {
PropertyObject (const char * name,
puObject * object,
SGPropertyNode_ptr node);
std::string name;
puObject * object;
SGPropertyNode_ptr node;
};
std::vector<PropertyObject *> _propertyObjects;
std::vector<PropertyObject *> _liveObjects;
class ConditionalObject : public SGConditional
{
public:
ConditionalObject(const std::string& aName, puObject* aPu) :
_name(aName),
_pu(aPu)
{ ; }
void update(FGPUIDialog* aDlg);
private:
const std::string _name;
puObject* _pu;
};
typedef SGSharedPtr<ConditionalObject> ConditionalObjectRef;
std::vector<ConditionalObjectRef> _conditionalObjects;
};
//
// Custom subclass of puPopup to implement "draggable" windows in the
// interface. Note that this is a subclass of puPopup, not
// puDialogBox. Sadly, PUI (mis)uses subclassing to implement a
// boolean property: modality. That means that we can't implement
// dragging of both puPopup windows and puDialogBoxes with the same
// code. Rather than duplicate code, I've chosen to implement only
// "non-modal dragability" here. Modal dialog boxes (like the exit
// confirmation) are not draggable.
//
class fgPopup : public puPopup {
public:
fgPopup(int x, int y, bool r = true, bool d = true) :
puPopup(x, y), _draggable(d), _resizable(r), _dragging(false)
{}
int checkHit(int b, int up, int x, int y);
int checkKey(int key, int updown);
int getHitObjects(puObject *, int x, int y);
puObject *getKeyObject(puObject *, int key);
puObject *getActiveInputField(puObject *);
void applySize(puObject *);
private:
enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
bool _draggable;
bool _resizable;
bool _dragging;
int _resizing;
int _start_cursor;
int _cursor;
int _dlgX, _dlgY, _dlgW, _dlgH;
int _startX, _startY;
};
class fgValueList {
public:
fgValueList(SGPropertyNode *p);
virtual ~fgValueList();
virtual void update();
protected:
char **_list;
private:
void make_list();
void destroy_list();
SGPropertyNode_ptr _props;
};
class fgList : public fgValueList, public puaList, public GUI_ID {
public:
fgList(int x1, int y1, int x2, int y2, SGPropertyNode *p, int sw) :
fgValueList(p), puaList(x1, y1, x2, y2, _list, sw), GUI_ID(FGCLASS_LIST) {}
void update();
};
class fgComboBox : public fgValueList, public puaComboBox {
public:
fgComboBox(int x1, int y1, int x2, int y2, SGPropertyNode *p, bool editable) :
fgValueList(p),
puaComboBox(x1, y1, x2, y2, _list, editable),
_inHit(false)
{}
void update();
virtual void setSize(int w, int h);
virtual int checkHit(int b, int up, int x, int y);
virtual void recalc_bbox();
private:
bool _inHit;
};
class fgSelectBox : public fgValueList, public puaSelectBox {
public:
fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) :
fgValueList(p), puaSelectBox(x1, y1, x2, y2, _list) {}
};
#endif // __DIALOG_HXX

376
src/GUI/FGPUIMenuBar.cxx Normal file
View file

@ -0,0 +1,376 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <string.h>
#include <iostream>
#include <plib/pu.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/SGBinding.hxx>
#include <simgear/props/props_io.hxx>
#include <Main/globals.hxx>
#include <Main/fg_props.hxx>
#include "new_gui.hxx"
#include "FGPUIMenuBar.hxx"
using std::vector;
using std::string;
using std::map;
////////////////////////////////////////////////////////////////////////
// FIXME!!
//
// Deprecated wrappers for old menu commands.
//
// DO NOT ADD TO THESE. THEY WILL BE DELETED SOON!
//
// These are defined in gui_funcs.cxx. They should be replaced with
// user-configured dialogs and new commands where necessary.
////////////////////////////////////////////////////////////////////////
#if defined(TR_HIRES_SNAP)
extern void dumpHiResSnapShot ();
static bool
do_hires_snapshot_dialog (const SGPropertyNode * arg)
{
dumpHiResSnapShot();
return true;
}
#endif // TR_HIRES_SNAP
static struct {
const char * name;
SGCommandMgr::command_t command;
} deprecated_dialogs [] = {
#if defined(TR_HIRES_SNAP)
{ "old-hires-snapshot-dialog", do_hires_snapshot_dialog },
#endif
{ 0, 0 }
};
static void
add_deprecated_dialogs ()
{
SG_LOG(SG_GENERAL, SG_INFO, "Initializing old dialog commands:");
for (int i = 0; deprecated_dialogs[i].name != 0; i++) {
SG_LOG(SG_GENERAL, SG_INFO, " " << deprecated_dialogs[i].name);
globals->get_commands()->addCommand(deprecated_dialogs[i].name,
deprecated_dialogs[i].command);
}
}
////////////////////////////////////////////////////////////////////////
// Static functions.
////////////////////////////////////////////////////////////////////////
static void
menu_callback (puObject * object)
{
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
FGPUIMenuBar* mb = static_cast<FGPUIMenuBar*>(gui->getMenuBar());
mb->fireItem(object);
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGPUIMenuBar.
////////////////////////////////////////////////////////////////////////
FGPUIMenuBar::FGPUIMenuBar ()
: _visible(false),
_menuBar(0)
{
}
FGPUIMenuBar::~FGPUIMenuBar ()
{
destroy_menubar();
}
void
FGPUIMenuBar::init ()
{
delete _menuBar; // FIXME: check if PUI owns the pointer
make_menubar();
// FIXME: temporary commands to get at
// old, hard-coded dialogs.
add_deprecated_dialogs();
}
void
FGPUIMenuBar::show ()
{
if (_menuBar != 0)
_menuBar->reveal();
_visible = true;
}
void
FGPUIMenuBar::hide ()
{
if (_menuBar != 0)
_menuBar->hide();
_visible = false;
}
bool
FGPUIMenuBar::isVisible () const
{
return _visible;
}
void
FGPUIMenuBar::fireItem (puObject * item)
{
const char * name = item->getLegend();
vector<SGBinding *> &bindings = _bindings[name];
int nBindings = bindings.size();
for (int i = 0; i < nBindings; i++)
bindings[i]->fire();
}
void
FGPUIMenuBar::make_menu (SGPropertyNode * node)
{
const char * name = strdup(node->getStringValue("label"));
vector<SGPropertyNode_ptr> item_nodes = node->getChildren("item");
int array_size = item_nodes.size();
char ** items = make_char_array(array_size);
puCallback * callbacks = make_callback_array(array_size);
for (unsigned int i = 0, j = item_nodes.size() - 1;
i < item_nodes.size();
i++, j--) {
// Set up the PUI entries for this item
items[j] = strdup((char *)item_nodes[i]->getStringValue("label"));
callbacks[j] = menu_callback;
// Load all the bindings for this item
vector<SGPropertyNode_ptr> bindings = item_nodes[i]->getChildren("binding");
SGPropertyNode * dest = fgGetNode("/sim/bindings/menu", true);
for (unsigned int k = 0; k < bindings.size(); k++) {
unsigned int m = 0;
SGPropertyNode_ptr binding;
while (dest->getChild("binding", m))
m++;
binding = dest->getChild("binding", m, true);
copyProperties(bindings[k], binding);
_bindings[items[j]].push_back(new SGBinding(binding, globals->get_props()));
}
}
_menuBar->add_submenu(name, items, callbacks);
}
void
FGPUIMenuBar::make_menubar ()
{
SGPropertyNode *targetpath;
targetpath = fgGetNode("/sim/menubar/default",true);
// fgLoadProps("gui/menubar.xml", targetpath);
/* NOTE: there is no check to see whether there's any usable data at all
*
* This would also have the advantage of being able to create some kind of
* 'fallback' menu - just in case that either menubar.xml is empty OR that
* its XML data is not valid, that way we would avoid displaying an
* unusable menubar without any functionality - if we decided to add another
* char * element to the commands structure in
* $FG_SRC/src/Main/fgcommands.cxx
* we could additionally save each function's (short) description and use
* this as label for the fallback PUI menubar item labels - as a workaround
* one might simply use the internal fgcommands and put them into the
* fallback menu, so that the user is at least able to re-init the menu
* loading - just in case there was some malformed XML in it
* (it happend to me ...)
*/
make_menubar(targetpath);
}
/* WARNING: We aren't yet doing any validation of what's found - but since
* this isn't done with menubar.xml either, it should not really matter
* right now. Although one should later on consider to validate the
* contents, whether they are representing a 'legal' menubar structure.
*/
void
FGPUIMenuBar::make_menubar(SGPropertyNode * props)
{
// Just in case.
destroy_menubar();
_menuBar = new puMenuBar;
vector<SGPropertyNode_ptr> menu_nodes = props->getChildren("menu");
for (unsigned int i = 0; i < menu_nodes.size(); i++)
make_menu(menu_nodes[i]);
_menuBar->close();
make_object_map(props);
if (_visible)
_menuBar->reveal();
else
_menuBar->hide();
}
void
FGPUIMenuBar::destroy_menubar ()
{
if ( _menuBar == 0 )
return;
hide();
puDeleteObject(_menuBar);
unsigned int i;
// Delete all the character arrays
// we were forced to keep around for
// plib.
SG_LOG(SG_GENERAL, SG_BULK, "Deleting char arrays");
for (i = 0; i < _char_arrays.size(); i++) {
for (int j = 0; _char_arrays[i][j] != 0; j++)
free(_char_arrays[i][j]); // added with strdup
delete[] _char_arrays[i];
}
// Delete all the callback arrays
// we were forced to keep around for
// plib.
SG_LOG(SG_GENERAL, SG_BULK, "Deleting callback arrays");
for (i = 0; i < _callback_arrays.size(); i++)
delete[] _callback_arrays[i];
// Delete all those bindings
SG_LOG(SG_GENERAL, SG_BULK, "Deleting bindings");
map<string,vector<SGBinding *> >::iterator it;
for (it = _bindings.begin(); it != _bindings.end(); it++) {
SG_LOG(SG_GENERAL, SG_BULK, "Deleting bindings for " << it->first);
for ( i = 0; i < it->second.size(); i++ )
delete it->second[i];
}
SG_LOG(SG_GENERAL, SG_BULK, "Done.");
}
void
FGPUIMenuBar::make_object_map(SGPropertyNode * node)
{
unsigned int menu_index = 0;
vector<SGPropertyNode_ptr> menus = node->getChildren("menu");
for (puObject *obj = ((puGroup *)_menuBar)->getFirstChild();
obj; obj = obj->getNextObject()) {
// skip puPopupMenus. They are also children of _menuBar,
// but we access them via getUserData() (see below)
if (!(obj->getType() & PUCLASS_ONESHOT))
continue;
if (menu_index >= menus.size()) {
SG_LOG(SG_GENERAL, SG_WARN, "'menu' object without node: "
<< node->getPath() << "/menu[" << menu_index << ']');
return;
}
SGPropertyNode *menu = menus.at(menu_index);
_objects[menu->getPath()] = obj;
add_enabled_listener(menu);
puGroup *popup = (puGroup *)obj->getUserData();
if (!popup)
continue;
// the entries are for some reason reversed (last first), and we
// don't know yet how many there will be; so we collect first
vector<puObject *> e;
for (puObject *me = popup->getFirstChild(); me; me = me->getNextObject())
e.push_back(me);
vector<SGPropertyNode_ptr> items = menu->getChildren("item");
for (unsigned int i = 0; i < e.size(); i++) {
if (i >= items.size()) {
SG_LOG(SG_GENERAL, SG_WARN, "'item' object without node: "
<< menu->getPath() << "/item[" << i << ']');
break;
}
SGPropertyNode *item = items.at(e.size() - i - 1);
_objects[item->getPath()] = e[i];
add_enabled_listener(item);
}
menu_index++;
}
}
struct EnabledListener : SGPropertyChangeListener {
void valueChanged(SGPropertyNode *node) {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
if (!gui)
return;
FGPUIMenuBar* menubar = static_cast<FGPUIMenuBar*>(gui->getMenuBar());
if (menubar)
menubar->enable_item(node->getParent(), node->getBoolValue());
}
};
void
FGPUIMenuBar::add_enabled_listener(SGPropertyNode * node)
{
if (!node->hasValue("enabled"))
node->setBoolValue("enabled", true);
enable_item(node, node->getBoolValue("enabled"));
node->getNode("enabled")->addChangeListener(new EnabledListener());
}
bool
FGPUIMenuBar::enable_item(const SGPropertyNode * node, bool state)
{
string path = node->getPath();
if (_objects.find(path) == _objects.end()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Trying to enable/disable "
"non-existent menu item for node `" << path << '\'');
return false;
}
puObject *object = _objects[path];
if (state)
object->activate();
else
object->greyOut();
return true;
}
char **
FGPUIMenuBar::make_char_array (int size)
{
char ** list = new char*[size+1];
for (int i = 0; i <= size; i++)
list[i] = 0;
_char_arrays.push_back(list);
return list;
}
puCallback *
FGPUIMenuBar::make_callback_array (int size)
{
puCallback * list = new puCallback[size+1];
for (int i = 0; i <= size; i++)
list[i] = 0;
_callback_arrays.push_back(list);
return list;
}
// end of menubar.cxx

138
src/GUI/FGPUIMenuBar.hxx Normal file
View file

@ -0,0 +1,138 @@
// menubar.hxx - XML-configured menu bar.
#ifndef FG_PUI_MENUBAR_HXX
#define FG_PUI_MENUBAR_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <GUI/menubar.hxx>
#include <map>
#include <vector>
// forward decls, avoid pulling in PLIB headers here
class puMenuBar;
class puObject;
class SGPropertyNode;
class SGBinding;
typedef void (*puCallback)(class puObject *) ;
/**
* XML-configured PUI menu bar.
*
* This class creates a menu bar from a tree of XML properties. These
* properties are not part of the main FlightGear property tree, but
* are read from a separate file ($FG_ROOT/gui/menubar.xml).
*
* WARNING: because PUI provides no easy way to attach user data to a
* menu item, all menu item strings must be unique; otherwise, this
* class will always use the first binding with any given name.
*/
class FGPUIMenuBar : public FGMenuBar
{
public:
/**
* Constructor.
*/
FGPUIMenuBar ();
/**
* Destructor.
*/
virtual ~FGPUIMenuBar ();
/**
* Initialize the menu bar from $FG_ROOT/gui/menubar.xml
*/
virtual void init ();
/**
* Make the menu bar visible.
*/
virtual void show ();
/**
* Make the menu bar invisible.
*/
virtual void hide ();
/**
* Test whether the menu bar is visible.
*/
virtual bool isVisible () const;
/**
* IGNORE THIS METHOD!!!
*
* This is necessary only because plib does not provide any easy
* way to attach user data to a menu item. FlightGear should not
* have to know about PUI internals, but this method allows the
* callback to pass the menu item one-shot on to the current menu.
*/
virtual void fireItem (puObject * item);
/**
* create a menubar based on a PropertyList within the PropertyTree
*/
void make_menubar (SGPropertyNode * props);
/**
* destroy a menubar based on a PropertyList within the PropertyTree
*/
void destroy_menubar ();
/**
* Disable/enable menu titles and entries
*/
bool enable_item (const SGPropertyNode * item, bool state);
private:
// Make a single menu.
void make_menu (SGPropertyNode * node);
// Make the top-level menubar.
void make_menubar ();
// Create a property-path -> puObject map for menu node
void make_object_map(SGPropertyNode * node);
// Add <enabled> listener that enables/disables menu entries.
void add_enabled_listener(SGPropertyNode * node);
// Is the menu visible?
bool _visible;
// The top-level menubar itself.
puMenuBar * _menuBar;
// A map of bindings for the menubar.
std::map<std::string,std::vector<SGBinding *> > _bindings;
// These are hoops that we have to jump through because PUI doesn't
// do memory management for lists. We have to allocate the arrays,
// hang onto pointers, and then delete them when the menubar is
// freed.
char ** make_char_array (int size);
puCallback * make_callback_array (int size);
std::vector<char **> _char_arrays;
std::vector<puCallback *> _callback_arrays;
// A map for {menu node path}->puObject translation.
std::map<std::string, puObject *> _objects;
};
#endif // __MENUBAR_HXX

View file

@ -374,7 +374,7 @@ int MapData::_fontDescender = 0;
///////////////////////////////////////////////////////////////////////////
const int MAX_ZOOM = 16;
const int MAX_ZOOM = 12;
const int SHOW_DETAIL_ZOOM = 8;
const int CURSOR_PAN_STEP = 32;
@ -403,11 +403,13 @@ MapWidget::~MapWidget()
void MapWidget::setProperty(SGPropertyNode_ptr prop)
{
_root = prop;
int zoom = _root->getBoolValue("zoom", -1);
int zoom = _root->getIntValue("zoom", -1);
if (zoom < 0) {
_root->setIntValue("zoom", 6); // default zoom
}
// expose MAX_ZOOM to the UI
_root->setIntValue("max-zoom", MAX_ZOOM);
_root->setBoolValue("centre-on-aircraft", true);
_root->setBoolValue("draw-data", false);
_root->setBoolValue("magnetic-headings", true);
@ -515,15 +517,6 @@ int MapWidget::zoom() const
}
void MapWidget::zoomIn()
{
if (zoom() <= 0) {
return;
}
_root->setIntValue("zoom", zoom() - 1);
}
void MapWidget::zoomOut()
{
if (zoom() >= MAX_ZOOM) {
return;
@ -532,6 +525,15 @@ void MapWidget::zoomOut()
_root->setIntValue("zoom", zoom() + 1);
}
void MapWidget::zoomOut()
{
if (zoom() <= 0) {
return;
}
_root->setIntValue("zoom", zoom() - 1);
}
void MapWidget::draw(int dx, int dy)
{
_aircraft = SGGeod::fromDeg(fgGetDouble("/position/longitude-deg"),
@ -561,7 +563,7 @@ void MapWidget::draw(int dx, int dy)
_upHeading = 0.0;
}
_cachedZoom = zoom();
_cachedZoom = MAX_ZOOM - zoom();
SGGeod topLeft = unproject(SGVec2d(_width/2, _height/2));
// compute draw range, including a fudge factor for ILSs and other 'long'
// symbols

View file

@ -10,7 +10,7 @@
#include <plib/pu.h>
#include "dialog.hxx" // for GUI_ID
#include "FGPUIDialog.hxx" // for GUI_ID
// forward decls
class puaScrollBar;

File diff suppressed because it is too large Load diff

View file

@ -7,31 +7,8 @@
# error This library requires C++
#endif
#include <plib/puAux.h>
#include <simgear/compiler.h> // for SG_USING_STD
#include <simgear/props/props.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/condition.hxx>
#include <vector>
using std::vector;
// ugly temporary workaround for plib's lack of user defined class ids FIXME
#define FGCLASS_LIST 0x00000001
#define FGCLASS_AIRPORTLIST 0x00000002
#define FGCLASS_PROPERTYLIST 0x00000004
#define FGCLASS_WAYPOINTLIST 0x00000008
class GUI_ID { public: GUI_ID(int id) : id(id) {} virtual ~GUI_ID() {} int id; };
class FGDialog;
class NewGUI;
class FGColor;
// forward decls
class SGPropertyNode;
/**
* An XML-configured dialog box.
@ -45,16 +22,6 @@ class FGDialog
{
public:
/**
* Construct a new GUI widget configured by a property tree.
*
* The configuration properties are not part of the main
* FlightGear property tree; the GUI manager reads them
* from individual configuration files.
*
* @param props A property tree describing the dialog.
*/
FGDialog (SGPropertyNode * props);
/**
@ -73,7 +40,7 @@ public:
* @param objectName The name of the GUI object(s) to update.
* Use the empty name for all unnamed objects.
*/
virtual void updateValues (const char * objectName = 0);
virtual void updateValues (const char * objectName = 0) = 0;
/**
@ -86,199 +53,28 @@ public:
* @param objectName The name of the GUI object(s) to update.
* Use the empty name for all unnamed objects.
*/
virtual void applyValues (const char * objectName = 0);
virtual void applyValues (const char * objectName = 0) = 0;
/**
* Update state. Called on active dialogs before rendering.
*/
virtual void update ();
/**
* Recompute the dialog's layout
*/
void relayout();
void setNeedsLayout() {
_needsRelayout = true;
}
private:
enum {
BACKGROUND = 0x01,
FOREGROUND = 0x02,
HIGHLIGHT = 0x04,
LABEL = 0x08,
LEGEND = 0x10,
MISC = 0x20,
EDITFIELD = 0x40
};
// Private copy constructor to avoid unpleasant surprises.
FGDialog (const FGDialog &);
// Show the dialog.
void display (SGPropertyNode * props);
// Build the dialog or a subobject of it.
puObject * makeObject (SGPropertyNode * props,
int parentWidth, int parentHeight);
// Common configuration for all GUI objects.
void setupObject (puObject * object, SGPropertyNode * props);
// Common configuration for all GUI group objects.
void setupGroup (puGroup * group, SGPropertyNode * props,
int width, int height, bool makeFrame = false);
// Set object colors: the "which" argument defines which color qualities
// (PUCOL_LABEL, etc.) should pick up the <color> property.
void setColor(puObject * object, SGPropertyNode * props, int which = 0);
// return key code number for keystring
int getKeyCode(const char *keystring);
/**
* Apply layout sizes to a tree of puObjects
*/
void applySize(puObject *object);
// The top-level PUI object.
puObject * _object;
// The GUI subsystem.
NewGUI * _gui;
// The dialog font. Defaults to the global gui font, but can get
// overridden by a top level font definition.
puFont * _font;
// The source xml tree, so that we can pass data back, such as the
// last position.
SGPropertyNode_ptr _props;
bool _needsRelayout;
// Nasal module.
std::string _module;
SGPropertyNode_ptr _nasal_close;
// PUI provides no way for userdata to be deleted automatically
// with a GUI object, so we have to keep track of all the special
// data we allocated and then free it manually when the dialog
// closes.
vector<void *> _info;
struct PropertyObject {
PropertyObject (const char * name,
puObject * object,
SGPropertyNode_ptr node);
std::string name;
puObject * object;
SGPropertyNode_ptr node;
};
vector<PropertyObject *> _propertyObjects;
vector<PropertyObject *> _liveObjects;
class ConditionalObject : public SGConditional
{
public:
ConditionalObject(const std::string& aName, puObject* aPu) :
_name(aName),
_pu(aPu)
{ ; }
void update(FGDialog* aDlg);
private:
const std::string _name;
puObject* _pu;
};
typedef SGSharedPtr<ConditionalObject> ConditionalObjectRef;
vector<ConditionalObjectRef> _conditionalObjects;
};
//
// Custom subclass of puPopup to implement "draggable" windows in the
// interface. Note that this is a subclass of puPopup, not
// puDialogBox. Sadly, PUI (mis)uses subclassing to implement a
// boolean property: modality. That means that we can't implement
// dragging of both puPopup windows and puDialogBoxes with the same
// code. Rather than duplicate code, I've chosen to implement only
// "non-modal dragability" here. Modal dialog boxes (like the exit
// confirmation) are not draggable.
//
class fgPopup : public puPopup {
public:
fgPopup(int x, int y, bool r = true, bool d = true) :
puPopup(x, y), _draggable(d), _resizable(r), _dragging(false)
{}
int checkHit(int b, int up, int x, int y);
int checkKey(int key, int updown);
int getHitObjects(puObject *, int x, int y);
puObject *getKeyObject(puObject *, int key);
puObject *getActiveInputField(puObject *);
void applySize(puObject *);
private:
enum { LEFT = 1, RIGHT = 2, TOP = 4, BOTTOM = 8 };
bool _draggable;
bool _resizable;
bool _dragging;
int _resizing;
int _start_cursor;
int _cursor;
int _dlgX, _dlgY, _dlgW, _dlgH;
int _startX, _startY;
};
class fgValueList {
public:
fgValueList(SGPropertyNode *p);
virtual ~fgValueList();
virtual void update();
virtual void update () = 0;
protected:
char **_list;
/**
* Construct a new GUI widget configured by a property tree.
*
* The configuration properties are not part of the main
* FlightGear property tree; the GUI manager reads them
* from individual configuration files.
*
* @param props A property tree describing the dialog.
*/
FGDialog (SGPropertyNode * props);
private:
void make_list();
void destroy_list();
SGPropertyNode_ptr _props;
};
class fgList : public fgValueList, public puaList, public GUI_ID {
public:
fgList(int x1, int y1, int x2, int y2, SGPropertyNode *p, int sw) :
fgValueList(p), puaList(x1, y1, x2, y2, _list, sw), GUI_ID(FGCLASS_LIST) {}
void update();
};
class fgComboBox : public fgValueList, public puaComboBox {
public:
fgComboBox(int x1, int y1, int x2, int y2, SGPropertyNode *p, bool editable) :
fgValueList(p),
puaComboBox(x1, y1, x2, y2, _list, editable),
_inHit(false)
{}
void update();
virtual void setSize(int w, int h);
virtual int checkHit(int b, int up, int x, int y);
virtual void recalc_bbox();
private:
bool _inHit;
};
class fgSelectBox : public fgValueList, public puaSelectBox {
public:
fgSelectBox(int x1, int y1, int x2, int y2, SGPropertyNode *p) :
fgValueList(p), puaSelectBox(x1, y1, x2, y2, _list) {}
};
#endif // __DIALOG_HXX

View file

@ -44,6 +44,7 @@
#include <Main/fg_props.hxx>
#include <Main/WindowSystemAdapter.hxx>
#include <GUI/new_gui.hxx>
#include <GUI/FGFontCache.hxx>
#include "gui.h"
#include "layout.hxx"

View file

@ -2,373 +2,11 @@
# include <config.h>
#endif
#include <string.h>
#include <iostream>
#include <plib/pu.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/SGBinding.hxx>
#include <simgear/props/props_io.hxx>
#include <Main/globals.hxx>
#include "new_gui.hxx"
#include "menubar.hxx"
using std::vector;
using std::string;
using std::map;
////////////////////////////////////////////////////////////////////////
// FIXME!!
//
// Deprecated wrappers for old menu commands.
//
// DO NOT ADD TO THESE. THEY WILL BE DELETED SOON!
//
// These are defined in gui_funcs.cxx. They should be replaced with
// user-configured dialogs and new commands where necessary.
////////////////////////////////////////////////////////////////////////
#if defined(TR_HIRES_SNAP)
extern void dumpHiResSnapShot ();
static bool
do_hires_snapshot_dialog (const SGPropertyNode * arg)
{
dumpHiResSnapShot();
return true;
}
#endif // TR_HIRES_SNAP
static struct {
const char * name;
SGCommandMgr::command_t command;
} deprecated_dialogs [] = {
#if defined(TR_HIRES_SNAP)
{ "old-hires-snapshot-dialog", do_hires_snapshot_dialog },
#endif
{ 0, 0 }
};
static void
add_deprecated_dialogs ()
{
SG_LOG(SG_GENERAL, SG_INFO, "Initializing old dialog commands:");
for (int i = 0; deprecated_dialogs[i].name != 0; i++) {
SG_LOG(SG_GENERAL, SG_INFO, " " << deprecated_dialogs[i].name);
globals->get_commands()->addCommand(deprecated_dialogs[i].name,
deprecated_dialogs[i].command);
}
}
////////////////////////////////////////////////////////////////////////
// Static functions.
////////////////////////////////////////////////////////////////////////
static void
menu_callback (puObject * object)
{
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
gui->getMenuBar()->fireItem(object);
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGMenuBar.
////////////////////////////////////////////////////////////////////////
FGMenuBar::FGMenuBar ()
: _visible(false),
_menuBar(0)
{
}
FGMenuBar::~FGMenuBar ()
{
destroy_menubar();
}
void
FGMenuBar::init ()
{
delete _menuBar; // FIXME: check if PUI owns the pointer
make_menubar();
// FIXME: temporary commands to get at
// old, hard-coded dialogs.
add_deprecated_dialogs();
}
void
FGMenuBar::show ()
{
if (_menuBar != 0)
_menuBar->reveal();
_visible = true;
}
void
FGMenuBar::hide ()
{
if (_menuBar != 0)
_menuBar->hide();
_visible = false;
}
bool
FGMenuBar::isVisible () const
{
return _visible;
}
void
FGMenuBar::fireItem (puObject * item)
{
const char * name = item->getLegend();
vector<SGBinding *> &bindings = _bindings[name];
int nBindings = bindings.size();
for (int i = 0; i < nBindings; i++)
bindings[i]->fire();
}
void
FGMenuBar::make_menu (SGPropertyNode * node)
{
const char * name = strdup(node->getStringValue("label"));
vector<SGPropertyNode_ptr> item_nodes = node->getChildren("item");
int array_size = item_nodes.size();
char ** items = make_char_array(array_size);
puCallback * callbacks = make_callback_array(array_size);
for (unsigned int i = 0, j = item_nodes.size() - 1;
i < item_nodes.size();
i++, j--) {
// Set up the PUI entries for this item
items[j] = strdup((char *)item_nodes[i]->getStringValue("label"));
callbacks[j] = menu_callback;
// Load all the bindings for this item
vector<SGPropertyNode_ptr> bindings = item_nodes[i]->getChildren("binding");
SGPropertyNode * dest = fgGetNode("/sim/bindings/menu", true);
for (unsigned int k = 0; k < bindings.size(); k++) {
unsigned int m = 0;
SGPropertyNode_ptr binding;
while (dest->getChild("binding", m))
m++;
binding = dest->getChild("binding", m, true);
copyProperties(bindings[k], binding);
_bindings[items[j]].push_back(new SGBinding(binding, globals->get_props()));
}
}
_menuBar->add_submenu(name, items, callbacks);
}
void
FGMenuBar::make_menubar ()
{
SGPropertyNode *targetpath;
targetpath = fgGetNode("/sim/menubar/default",true);
// fgLoadProps("gui/menubar.xml", targetpath);
/* NOTE: there is no check to see whether there's any usable data at all
*
* This would also have the advantage of being able to create some kind of
* 'fallback' menu - just in case that either menubar.xml is empty OR that
* its XML data is not valid, that way we would avoid displaying an
* unusable menubar without any functionality - if we decided to add another
* char * element to the commands structure in
* $FG_SRC/src/Main/fgcommands.cxx
* we could additionally save each function's (short) description and use
* this as label for the fallback PUI menubar item labels - as a workaround
* one might simply use the internal fgcommands and put them into the
* fallback menu, so that the user is at least able to re-init the menu
* loading - just in case there was some malformed XML in it
* (it happend to me ...)
*/
make_menubar(targetpath);
}
/* WARNING: We aren't yet doing any validation of what's found - but since
* this isn't done with menubar.xml either, it should not really matter
* right now. Although one should later on consider to validate the
* contents, whether they are representing a 'legal' menubar structure.
*/
void
FGMenuBar::make_menubar(SGPropertyNode * props)
{
// Just in case.
destroy_menubar();
_menuBar = new puMenuBar;
vector<SGPropertyNode_ptr> menu_nodes = props->getChildren("menu");
for (unsigned int i = 0; i < menu_nodes.size(); i++)
make_menu(menu_nodes[i]);
_menuBar->close();
make_object_map(props);
if (_visible)
_menuBar->reveal();
else
_menuBar->hide();
}
void
FGMenuBar::destroy_menubar ()
{
if ( _menuBar == 0 )
return;
hide();
puDeleteObject(_menuBar);
unsigned int i;
// Delete all the character arrays
// we were forced to keep around for
// plib.
SG_LOG(SG_GENERAL, SG_BULK, "Deleting char arrays");
for (i = 0; i < _char_arrays.size(); i++) {
for (int j = 0; _char_arrays[i][j] != 0; j++)
free(_char_arrays[i][j]); // added with strdup
delete[] _char_arrays[i];
}
// Delete all the callback arrays
// we were forced to keep around for
// plib.
SG_LOG(SG_GENERAL, SG_BULK, "Deleting callback arrays");
for (i = 0; i < _callback_arrays.size(); i++)
delete[] _callback_arrays[i];
// Delete all those bindings
SG_LOG(SG_GENERAL, SG_BULK, "Deleting bindings");
map<string,vector<SGBinding *> >::iterator it;
for (it = _bindings.begin(); it != _bindings.end(); it++) {
SG_LOG(SG_GENERAL, SG_BULK, "Deleting bindings for " << it->first);
for ( i = 0; i < it->second.size(); i++ )
delete it->second[i];
}
SG_LOG(SG_GENERAL, SG_BULK, "Done.");
}
void
FGMenuBar::make_object_map(SGPropertyNode * node)
{
unsigned int menu_index = 0;
vector<SGPropertyNode_ptr> menus = node->getChildren("menu");
for (puObject *obj = ((puGroup *)_menuBar)->getFirstChild();
obj; obj = obj->getNextObject()) {
// skip puPopupMenus. They are also children of _menuBar,
// but we access them via getUserData() (see below)
if (!(obj->getType() & PUCLASS_ONESHOT))
continue;
if (menu_index >= menus.size()) {
SG_LOG(SG_GENERAL, SG_WARN, "'menu' object without node: "
<< node->getPath() << "/menu[" << menu_index << ']');
return;
}
SGPropertyNode *menu = menus.at(menu_index);
_objects[menu->getPath()] = obj;
add_enabled_listener(menu);
puGroup *popup = (puGroup *)obj->getUserData();
if (!popup)
continue;
// the entries are for some reason reversed (last first), and we
// don't know yet how many there will be; so we collect first
vector<puObject *> e;
for (puObject *me = popup->getFirstChild(); me; me = me->getNextObject())
e.push_back(me);
vector<SGPropertyNode_ptr> items = menu->getChildren("item");
for (unsigned int i = 0; i < e.size(); i++) {
if (i >= items.size()) {
SG_LOG(SG_GENERAL, SG_WARN, "'item' object without node: "
<< menu->getPath() << "/item[" << i << ']');
break;
}
SGPropertyNode *item = items.at(e.size() - i - 1);
_objects[item->getPath()] = e[i];
add_enabled_listener(item);
}
menu_index++;
}
}
struct EnabledListener : SGPropertyChangeListener {
void valueChanged(SGPropertyNode *node) {
NewGUI * gui = (NewGUI *)globals->get_subsystem("gui");
if (!gui)
return;
FGMenuBar *menubar = gui->getMenuBar();
if (menubar)
menubar->enable_item(node->getParent(), node->getBoolValue());
}
};
void
FGMenuBar::add_enabled_listener(SGPropertyNode * node)
{
if (!node->hasValue("enabled"))
node->setBoolValue("enabled", true);
enable_item(node, node->getBoolValue("enabled"));
node->getNode("enabled")->addChangeListener(new EnabledListener());
}
bool
FGMenuBar::enable_item(const SGPropertyNode * node, bool state)
{
string path = node->getPath();
if (_objects.find(path) == _objects.end()) {
SG_LOG(SG_GENERAL, SG_ALERT, "Trying to enable/disable "
"non-existent menu item for node `" << path << '\'');
return false;
}
puObject *object = _objects[path];
if (state)
object->activate();
else
object->greyOut();
return true;
}
char **
FGMenuBar::make_char_array (int size)
{
char ** list = new char*[size+1];
for (int i = 0; i <= size; i++)
list[i] = 0;
_char_arrays.push_back(list);
return list;
}
puCallback *
FGMenuBar::make_callback_array (int size)
{
puCallback * list = new puCallback[size+1];
for (int i = 0; i <= size; i++)
list[i] = 0;
_callback_arrays.push_back(list);
return list;
}
// end of menubar.cxx

View file

@ -3,42 +3,19 @@
#ifndef __MENUBAR_HXX
#define __MENUBAR_HXX 1
#ifndef __cplusplus
# error This library requires C++
#endif
#include <Main/fg_props.hxx>
#include <plib/pu.h>
#include <map>
#include <vector>
class puMenuBar;
class puObject;
class SGBinding;
/**
* XML-configured PUI menu bar.
* XML-configured menu bar interface
*
* This class creates a menu bar from a tree of XML properties. These
* properties are not part of the main FlightGear property tree, but
* are read from a separate file ($FG_ROOT/gui/menubar.xml).
*
* WARNING: because PUI provides no easy way to attach user data to a
* menu item, all menu item strings must be unique; otherwise, this
* class will always use the first binding with any given name.
*/
class FGMenuBar
{
public:
/**
* Constructor.
*/
FGMenuBar ();
/**
* Destructor.
@ -49,89 +26,25 @@ public:
/**
* Initialize the menu bar from $FG_ROOT/gui/menubar.xml
*/
virtual void init ();
virtual void init () = 0;
/**
* Make the menu bar visible.
*/
virtual void show ();
virtual void show () = 0;
/**
* Make the menu bar invisible.
*/
virtual void hide ();
virtual void hide () = 0;
/**
* Test whether the menu bar is visible.
*/
virtual bool isVisible () const;
virtual bool isVisible () const = 0;
/**
* IGNORE THIS METHOD!!!
*
* This is necessary only because plib does not provide any easy
* way to attach user data to a menu item. FlightGear should not
* have to know about PUI internals, but this method allows the
* callback to pass the menu item one-shot on to the current menu.
*/
virtual void fireItem (puObject * item);
/**
* create a menubar based on a PropertyList within the PropertyTree
*/
void make_menubar (SGPropertyNode * props);
/**
* destroy a menubar based on a PropertyList within the PropertyTree
*/
void destroy_menubar ();
/**
* Disable/enable menu titles and entries
*/
bool enable_item (const SGPropertyNode * item, bool state);
private:
// Make a single menu.
void make_menu (SGPropertyNode * node);
// Make the top-level menubar.
void make_menubar ();
// Create a property-path -> puObject map for menu node
void make_object_map(SGPropertyNode * node);
// Add <enabled> listener that enables/disables menu entries.
void add_enabled_listener(SGPropertyNode * node);
// Is the menu visible?
bool _visible;
// The top-level menubar itself.
puMenuBar * _menuBar;
// A map of bindings for the menubar.
std::map<std::string,std::vector<SGBinding *> > _bindings;
// These are hoops that we have to jump through because PUI doesn't
// do memory management for lists. We have to allocate the arrays,
// hang onto pointers, and then delete them when the menubar is
// freed.
char ** make_char_array (int size);
puCallback * make_callback_array (int size);
std::vector<char **> _char_arrays;
std::vector<puCallback *> _callback_arrays;
// A map for {menu node path}->puObject translation.
std::map<std::string, puObject *> _objects;
};
#endif // __MENUBAR_HXX

View file

@ -26,11 +26,10 @@
#include "GL/glx.h"
#endif
#include "menubar.hxx"
#include "dialog.hxx"
extern puFont FONT_HELVETICA_14;
extern puFont FONT_SANS_12B;
#include "FGPUIMenuBar.hxx"
#include "FGPUIDialog.hxx"
#include "FGFontCache.hxx"
#include "FGColor.hxx"
using std::map;
using std::string;
@ -42,14 +41,13 @@ using std::string;
NewGUI::NewGUI ()
: _menubar(new FGMenuBar),
: _menubar(new FGPUIMenuBar),
_active_dialog(0)
{
}
NewGUI::~NewGUI ()
{
delete _menubar;
_dialog_props.clear();
for (_itt_t it = _colors.begin(); it != _colors.end(); ++it)
delete it->second;
@ -81,7 +79,7 @@ void
NewGUI::reset (bool reload)
{
map<string,FGDialog *>::iterator iter;
vector<string> dlg;
std::vector<string> dlg;
// close all open dialogs and remember them ...
for (iter = _active_dialogs.begin(); iter != _active_dialogs.end(); ++iter)
dlg.push_back(iter->first);
@ -93,8 +91,7 @@ NewGUI::reset (bool reload)
setStyle();
unbind();
delete _menubar;
_menubar = new FGMenuBar;
_menubar.reset(new FGPUIMenuBar);
if (reload) {
_dialog_props.clear();
@ -139,7 +136,7 @@ NewGUI::showDialog (const string &name)
return false;
} else {
if(!_active_dialogs[name])
_active_dialogs[name] = new FGDialog(_dialog_props[name]);
_active_dialogs[name] = new FGPUIDialog(_dialog_props[name]);
return true;
}
}
@ -215,7 +212,7 @@ NewGUI::getActiveDialog ()
FGMenuBar *
NewGUI::getMenuBar ()
{
return _menubar;
return _menubar.get();
}
bool
@ -326,247 +323,4 @@ NewGUI::setupFont (SGPropertyNode *node)
return;
}
////////////////////////////////////////////////////////////////////////
// FGColor class.
////////////////////////////////////////////////////////////////////////
void
FGColor::print() const {
std::cerr << "red=" << _red << ", green=" << _green
<< ", blue=" << _blue << ", alpha=" << _alpha << std::endl;
}
bool
FGColor::merge(const SGPropertyNode *node)
{
if (!node)
return false;
bool dirty = false;
const SGPropertyNode * n;
if ((n = node->getNode("red")))
_red = n->getFloatValue(), dirty = true;
if ((n = node->getNode("green")))
_green = n->getFloatValue(), dirty = true;
if ((n = node->getNode("blue")))
_blue = n->getFloatValue(), dirty = true;
if ((n = node->getNode("alpha")))
_alpha = n->getFloatValue(), dirty = true;
return dirty;
}
bool
FGColor::merge(const FGColor *color)
{
bool dirty = false;
if (color && color->_red >= 0.0)
_red = color->_red, dirty = true;
if (color && color->_green >= 0.0)
_green = color->_green, dirty = true;
if (color && color->_blue >= 0.0)
_blue = color->_blue, dirty = true;
if (color && color->_alpha >= 0.0)
_alpha = color->_alpha, dirty = true;
return dirty;
}
////////////////////////////////////////////////////////////////////////
// FGFontCache class.
////////////////////////////////////////////////////////////////////////
namespace
{
struct GuiFont
{
const char *name;
puFont *font;
struct Predicate
: public std::unary_function<const GuiFont, bool>
{
Predicate(const char* name_) : name(name_) {}
bool operator() (const GuiFont& f1) const
{
return std::strcmp(f1.name, name) == 0;
}
const char* name;
};
};
const GuiFont guifonts[] = {
{ "default", &FONT_HELVETICA_14 },
{ "FIXED_8x13", &PUFONT_8_BY_13 },
{ "FIXED_9x15", &PUFONT_9_BY_15 },
{ "TIMES_10", &PUFONT_TIMES_ROMAN_10 },
{ "TIMES_24", &PUFONT_TIMES_ROMAN_24 },
{ "HELVETICA_10", &PUFONT_HELVETICA_10 },
{ "HELVETICA_12", &PUFONT_HELVETICA_12 },
{ "HELVETICA_14", &FONT_HELVETICA_14 },
{ "HELVETICA_18", &PUFONT_HELVETICA_18 },
{ "SANS_12B", &FONT_SANS_12B }
};
const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
}
FGFontCache::FGFontCache() :
_initialized(false)
{
}
FGFontCache::~FGFontCache()
{
#if defined(SG_UNIX) && !defined(SG_MAC)
// Ugly workaround for a crash on exit with multiple screens configured
if (!glXGetCurrentContext())
return;
#endif
PuFontMap::iterator it, end = _puFonts.end();
for (it = _puFonts.begin(); it != end; ++it)
delete it->second;
}
inline bool FGFontCache::FntParamsLess::operator()(const FntParams& f1,
const FntParams& f2) const
{
int comp = f1.name.compare(f2.name);
if (comp < 0)
return true;
else if (comp > 0)
return false;
if (f1.size < f2.size)
return true;
else if (f1.size > f2.size)
return false;
return f1.slant < f2.slant;
}
struct FGFontCache::fnt *
FGFontCache::getfnt(const char *name, float size, float slant)
{
string fontName = boost::to_lower_copy(string(name));
FntParams fntParams(fontName, size, slant);
PuFontMap::iterator i = _puFonts.find(fntParams);
if (i != _puFonts.end()) {
// found in the puFonts map, all done
return i->second;
}
// fntTexFont s are all preloaded into the _texFonts map
TexFontMap::iterator texi = _texFonts.find(fontName);
fntTexFont* texfont = NULL;
puFont* pufont = NULL;
if (texi != _texFonts.end()) {
texfont = texi->second;
} else {
// check the built-in PUI fonts (in guifonts array)
const GuiFont* guifont = std::find_if(&guifonts[0], guifontsEnd,
GuiFont::Predicate(name));
if (guifont != guifontsEnd) {
pufont = guifont->font;
}
}
fnt* f = new fnt;
if (pufont) {
f->pufont = pufont;
} else if (texfont) {
f->texfont = texfont;
f->pufont = new puFont;
f->pufont->initialize(static_cast<fntFont *>(f->texfont), size, slant);
} else {
f->pufont = guifonts[0].font;
}
_puFonts[fntParams] = f;
return f;
}
puFont *
FGFontCache::get(const char *name, float size, float slant)
{
return getfnt(name, size, slant)->pufont;
}
fntTexFont *
FGFontCache::getTexFont(const char *name, float size, float slant)
{
return getfnt(name, size, slant)->texfont;
}
puFont *
FGFontCache::get(SGPropertyNode *node)
{
if (!node)
return get("Helvetica.txf", 15.0, 0.0);
const char *name = node->getStringValue("name", "Helvetica.txf");
float size = node->getFloatValue("size", 15.0);
float slant = node->getFloatValue("slant", 0.0);
return get(name, size, slant);
}
void FGFontCache::init()
{
if (_initialized) {
return;
}
char *envp = ::getenv("FG_FONTS");
if (envp != NULL) {
_path.set(envp);
} else {
_path.set(globals->get_fg_root());
_path.append("Fonts");
}
_initialized = true;
}
SGPath
FGFontCache::getfntpath(const char *name)
{
init();
SGPath path(_path);
if (name && std::string(name) != "") {
path.append(name);
if (path.exists())
return path;
}
path = SGPath(_path);
path.append("Helvetica.txf");
SG_LOG(SG_GENERAL, SG_WARN, "Unknown font name '" << name << "', defaulting to Helvetica");
return path;
}
bool FGFontCache::initializeFonts()
{
static string fontext("txf");
init();
ulDir* fontdir = ulOpenDir(_path.c_str());
if (!fontdir)
return false;
const ulDirEnt *dirEntry;
while ((dirEntry = ulReadDir(fontdir)) != 0) {
SGPath path(_path);
path.append(dirEntry->d_name);
if (path.extension() == fontext) {
fntTexFont* f = new fntTexFont;
if (f->load((char *)path.c_str())) {
// convert font names in the map to lowercase for matching
string fontName = boost::to_lower_copy(string(dirEntry->d_name));
_texFonts[fontName] = f;
} else
delete f;
}
}
ulCloseDir(fontdir);
return true;
}
// end of new_gui.cxx

View file

@ -3,17 +3,15 @@
#ifndef __NEW_GUI_HXX
#define __NEW_GUI_HXX 1
#include <plib/pu.h>
#include <simgear/props/props.hxx>
#include <simgear/structure/subsystem_mgr.hxx>
#include <simgear/misc/sg_path.hxx>
#include <string.h>
#include <functional>
#include <vector>
#include <map>
#include <Main/fg_props.hxx>
#include <memory> // for auto_ptr on some systems
class SGBinding;
@ -21,7 +19,7 @@ class FGMenuBar;
class FGDialog;
class FGColor;
class FGFontCache;
class puFont;
/**
* XML-configured GUI subsystem.
@ -222,7 +220,7 @@ private:
// Read all the configuration files in a directory.
void readDir (const SGPath& path);
FGMenuBar * _menubar;
std::auto_ptr<FGMenuBar> _menubar;
FGDialog * _active_dialog;
std::map<std::string,FGDialog *> _active_dialogs;
std::map<std::string,SGPropertyNode_ptr> _dialog_props;
@ -230,117 +228,5 @@ private:
};
class FGColor {
public:
FGColor() { clear(); }
FGColor(float r, float g, float b, float a = 1.0f) { set(r, g, b, a); }
FGColor(const SGPropertyNode *prop) { set(prop); }
FGColor(FGColor *c) {
if (c) set(c->_red, c->_green, c->_blue, c->_alpha);
}
inline void clear() { _red = _green = _blue = _alpha = -1.0f; }
// merges in non-negative components from property with children <red> etc.
bool merge(const SGPropertyNode *prop);
bool merge(const FGColor *color);
bool set(const SGPropertyNode *prop) { clear(); return merge(prop); };
bool set(const FGColor *color) { clear(); return merge(color); }
bool set(float r, float g, float b, float a = 1.0f) {
_red = r, _green = g, _blue = b, _alpha = a;
return true;
}
bool isValid() const {
return _red >= 0.0 && _green >= 0.0 && _blue >= 0.0;
}
void print() const;
inline void setRed(float red) { _red = red; }
inline void setGreen(float green) { _green = green; }
inline void setBlue(float blue) { _blue = blue; }
inline void setAlpha(float alpha) { _alpha = alpha; }
inline float red() const { return clamp(_red); }
inline float green() const { return clamp(_green); }
inline float blue() const { return clamp(_blue); }
inline float alpha() const { return _alpha < 0.0 ? 1.0 : clamp(_alpha); }
protected:
float _red, _green, _blue, _alpha;
private:
float clamp(float f) const { return f < 0.0 ? 0.0 : f > 1.0 ? 1.0 : f; }
};
/**
* A class to keep all fonts available for future use.
* This also assures a font isn't resident more than once.
*/
class FGFontCache {
private:
// The parameters of a request to the cache.
struct FntParams
{
const std::string name;
const float size;
const float slant;
FntParams() : size(0.0f), slant(0.0f) {}
FntParams(const FntParams& rhs)
: name(rhs.name), size(rhs.size), slant(rhs.slant)
{
}
FntParams(const std::string& name_, float size_, float slant_)
: name(name_), size(size_), slant(slant_)
{
}
};
struct FntParamsLess
: public std::binary_function<const FntParams, const FntParams, bool>
{
bool operator() (const FntParams& f1, const FntParams& f2) const;
};
struct fnt {
fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
~fnt() { if (texfont) { delete pufont; delete texfont; } }
// Font used by plib GUI code
puFont *pufont;
// TXF font
fntTexFont *texfont;
};
// Path to the font directory
SGPath _path;
typedef std::map<const std::string, fntTexFont*> TexFontMap;
typedef std::map<const FntParams, fnt*, FntParamsLess> PuFontMap;
TexFontMap _texFonts;
PuFontMap _puFonts;
bool _initialized;
struct fnt *getfnt(const char *name, float size, float slant);
void init();
public:
FGFontCache();
~FGFontCache();
puFont *get(const char *name, float size=15.0, float slant=0.0);
puFont *get(SGPropertyNode *node);
fntTexFont *getTexFont(const char *name, float size=15.0, float slant=0.0);
SGPath getfntpath(const char *name);
/**
* Preload all the fonts in the FlightGear font directory. It is
* important to load the font textures early, with the proper
* graphics context current, so that no plib (or our own) code
* tries to load a font from disk when there's no current graphics
* context.
*/
bool initializeFonts();
};
#endif // __NEW_GUI_HXX

View file

@ -27,7 +27,7 @@
#include <plib/puAux.h>
#include <simgear/props/props.hxx>
#include "dialog.hxx"
#include "FGPUIDialog.hxx"
class PropertyList : public puaList, public SGPropertyChangeListener, public GUI_ID {

View file

@ -36,3 +36,4 @@
#define PKGLIBDIR "@FG_DATA_DIR@"
#cmakedefine FG_HAVE_HLA
#cmakedefine FG_JPEG_SERVER

View file

@ -1,148 +0,0 @@
/**************************************************************************
* fg_callback.hxx -- Wrapper classes to treat function and method pointers
* as objects.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $Id$
**************************************************************************/
#ifndef _FG_CALLBACK_HXX
#define _FG_CALLBACK_HXX
/**
* Abstract base class for all FlightGear callbacks.
*/
class fgCallback
{
public:
/**
*
*/
virtual ~fgCallback() {}
/**
*
*/
virtual fgCallback* clone() const = 0;
/**
* Execute the callback function.
*/
virtual void operator()() = 0;
protected:
/**
*
*/
fgCallback() {}
private:
// Not implemented.
void operator=( const fgCallback& );
};
/**
* Callback for invoking a file scope function.
*/
template< typename Fun >
class fgFunctionCallback : public fgCallback
{
public:
/**
*
*/
fgFunctionCallback( const Fun& fun )
: fgCallback(), f_(fun) {}
fgCallback* clone() const
{
return new fgFunctionCallback( *this );
}
void operator()() { f_(); }
private:
// Not defined.
fgFunctionCallback();
private:
Fun f_;
};
/**
* Callback for invoking a member function.
*/
template< class ObjPtr, typename MemFn >
class fgMethodCallback : public fgCallback
{
public:
/**
*
*/
fgMethodCallback( const ObjPtr& pObj, MemFn pMemFn )
: fgCallback(),
pObj_(pObj),
pMemFn_(pMemFn)
{
}
/**
*
*/
fgCallback* clone() const
{
return new fgMethodCallback( *this );
}
/**
*
*/
void operator()()
{
((*pObj_).*pMemFn_)();
}
private:
// Not defined.
fgMethodCallback();
private:
ObjPtr pObj_;
MemFn pMemFn_;
};
/**
* Helper template functions.
*/
template< typename Fun >
fgCallback*
make_callback( const Fun& fun )
{
return new fgFunctionCallback<Fun>(fun);
}
template< class ObjPtr, typename MemFn >
fgCallback*
make_callback( const ObjPtr& pObj, MemFn pMemFn )
{
return new fgMethodCallback<ObjPtr,MemFn>(pObj, pMemFn );
}
#endif // _FG_CALLBACK_HXX

View file

@ -1,101 +0,0 @@
/*
// Alterations: Copyright C. Hotchkiss 1996
//
// $Log$
// Revision 1.2 2010/01/23 22:26:52 fredb
// MINGW patch from Benoît Laniel
//
// Revision 1.1.1.1 2002-09-10 01:14:04 curt
// Initial revision of FlightGear-0.9.0
//
// Revision 1.2 2001/05/16 21:27:59 curt
// Added David Megginson's patch for reconfigurable keyboard bindings.
//
// Revision 1.1.1.1 1999/06/17 18:07:30 curt
// Start of 0.7.x branch
//
// Revision 1.2 1999/04/22 18:45:42 curt
// Borland tweaks.
//
// Revision 1.1.1.1 1999/04/05 21:32:40 curt
// Start of 0.6.x branch.
//
// Revision 1.2 1998/05/13 18:23:46 curt
// fg_typedefs.h: updated version by Charlie Hotchkiss
// general.h: moved fg_root info to fgOPTIONS structure.
//
// Revision 1.1 1998/05/11 18:26:12 curt
// Initial revision.
//
// Rev 1.4 11 Nov 1997 15:34:28 CHOTCHKISS
// Expanded definitions.
//
// Rev 1.3 20 Jan 1997 9:21:26 CHOTCHKISS
// Minor additions.
//
// Rev 1.2 12 Nov 1996 15:06:52 CHOTCHKISS
// Dropped PC Write print format control lines.
//
// Rev 1.1 20 Nov 1995 15:59:02 CHOTCHKISS
// Additions and improvements. Memcheck compatibilities.
//
// Rev 1.0 06 Apr 1995 14:00:32 CHOTCHKISS
// Initial revision.

*/
/*
// TYPEDEFS.H - General purpose definition file
// Copyright (C) 1992 Paradigm Systems. All rights reserved.
//
// Function
// ========
// This file contains the general purpose definitions common to the
// all Paradigm applications. By defining synonyms for the physical
// data types to be manipulated, portability between memory models
// and machines is maximized.
//
// Note that this file follows the system include files and before
// any application include files.
*/
#ifndef _FG_TYPEDEFS
#define _FG_TYPEDEFS
//
// Define the types to be used to manipulate 8-, 16-, and 32-bit
// data.
//
typedef unsigned int BIT ; // Use for defining Borland bit fields
typedef char CHAR ; // 8-bit signed data
typedef const char COCHAR;
typedef unsigned char UCHAR ; // 8-bit unsigned data
typedef unsigned char BYTE;
typedef int INT ; // 16-bit signed data
typedef unsigned int UINT ; // 16-bit unsigned data
typedef const int COINT; // 16=bit constant int
typedef const UINT COUINT;
typedef long LONG ; // 32-bit signed data
typedef unsigned long ULONG ; // 32-bit unsigned data
typedef unsigned short UWORD; // Unsigned 16 bit quantity (WIN=SHORT)
#ifndef _WIN32
typedef signed short WORD; // Signed 16 bit quantity
#endif
typedef BYTE UBYTE; // Used in some 3rd party code
#ifndef _WIN32
typedef int BOOLEAN; //
#endif
typedef float FLOAT ; // 32-bit floating point data
typedef double DOUBLE ; // 64-bit floating point data
typedef long double LDOUBLE ; // 80-bit floating point data
typedef void(*VFNPTR) ( void );
typedef void(*VFNINTPTR)( int );
typedef int (*FNPTR) ( void );
typedef int (*FNINTPTR) ( int );
typedef int (*FNUIPTR) ( UINT );
typedef double( *DBLFNPTR)( void );
typedef float( *FLTFNPTR)( void );
#endif // _FG_TYPEDEFS

View file

@ -22,6 +22,10 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "FGJoystickInput.hxx"
#include <simgear/props/props_io.hxx>

View file

@ -22,6 +22,10 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "FGKeyboardInput.hxx"
#include <Main/fg_props.hxx>
#include <Scripting/NasalSys.hxx>

View file

@ -225,7 +225,7 @@ static struct enbet {
};
class EventNameByEventType : public map<unsigned,const char*> {
class EventNameByEventType : public std::map<unsigned,const char*> {
public:
EventNameByEventType() {
for( unsigned i = 0; i < sizeof(EVENT_NAMES_BY_EVENT_TYPE)/sizeof(EVENT_NAMES_BY_EVENT_TYPE[0]); i++ )
@ -234,7 +234,7 @@ public:
};
static EventNameByEventType EVENT_NAME_BY_EVENT_TYPE;
class EventNameByType : public map<TypeCode,const char*> {
class EventNameByType : public std::map<TypeCode,const char*> {
public:
EventNameByType() {
for( unsigned i = 0; i < sizeof(EVENT_TYPES)/sizeof(EVENT_TYPES[0]); i++ )
@ -246,11 +246,11 @@ static EventNameByType EVENT_NAME_BY_TYPE;
struct ltstr {
bool operator()(const char * s1, const char * s2 ) const {
return string(s1).compare( s2 ) < 0;
return std::string(s1).compare( s2 ) < 0;
}
};
class EventTypeByName : public map<const char *,TypeCode,ltstr> {
class EventTypeByName : public std::map<const char *,TypeCode,ltstr> {
public:
EventTypeByName() {
for( unsigned i = 0; i < sizeof(EVENT_TYPES)/sizeof(EVENT_TYPES[0]); i++ )
@ -260,7 +260,7 @@ public:
static EventTypeByName EVENT_TYPE_BY_NAME;
FGLinuxInputDevice::FGLinuxInputDevice( string aName, string aDevname ) :
FGLinuxInputDevice::FGLinuxInputDevice( std::string aName, std::string aDevname ) :
FGInputDevice(aName),
devname( aDevname ),
fd(-1)
@ -290,7 +290,7 @@ void FGLinuxInputDevice::Open()
{
if( fd != -1 ) return;
if( (fd = ::open( devname.c_str(), O_RDWR )) == -1 ) {
throw exception();
throw std::exception();
}
if( GetGrab() && ioctl( fd, EVIOCGRAB, 2 ) == -1 ) {
@ -440,7 +440,7 @@ const char * FGLinuxInputDevice::TranslateEventName( FGEventData & eventData )
return EVENT_NAME_BY_TYPE[typeCode];
}
void FGLinuxInputDevice::SetDevname( string name )
void FGLinuxInputDevice::SetDevname( std::string name )
{
this->devname = name;
}
@ -540,8 +540,8 @@ void FGLinuxEventInput::update( double dt )
// index the input devices by the associated fd and prepare
// the pollfd array by filling in the file descriptor
struct pollfd fds[input_devices.size()];
map<int,FGLinuxInputDevice*> devicesByFd;
map<int,FGInputDevice*>::const_iterator it;
std::map<int,FGLinuxInputDevice*> devicesByFd;
std::map<int,FGInputDevice*>::const_iterator it;
int i;
for( i=0, it = input_devices.begin(); it != input_devices.end(); ++it, i++ ) {
FGInputDevice* p = (*it).second;

View file

@ -43,7 +43,7 @@ struct FGLinuxEventData : public FGEventData {
class FGLinuxInputDevice : public FGInputDevice {
public:
FGLinuxInputDevice();
FGLinuxInputDevice( string name, string devname );
FGLinuxInputDevice( std::string name, std::string devname );
virtual ~FGLinuxInputDevice();
virtual void Open();
@ -51,17 +51,17 @@ public:
virtual void Send( const char * eventName, double value );
virtual const char * TranslateEventName( FGEventData & eventData );
void SetDevname( const string name );
string GetDevname() const { return devname; }
void SetDevname( const std::string name );
std::string GetDevname() const { return devname; }
int GetFd() { return fd; }
double Normalize( struct input_event & event );
private:
string devname;
std::string devname;
int fd;
map<unsigned int,input_absinfo> absinfo;
std::map<unsigned int,input_absinfo> absinfo;
};
class FGLinuxEventInput : public FGEventInput {

View file

@ -22,6 +22,10 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "FGMouseInput.hxx"
#include "Main/globals.hxx"

View file

@ -34,9 +34,12 @@
#include <simgear/props/props_io.hxx>
#include <osg/GLU>
#include <plib/fnt.h>
#include <Main/globals.hxx>
#include <Main/viewmgr.hxx>
#include <Main/viewer.hxx>
#include <GUI/FGFontCache.hxx>
#include "HUD.hxx"

View file

@ -45,7 +45,6 @@ using std::vector;
#include <Airports/runways.hxx> // FGRunway
#include <GUI/gui.h> // fntRenderer ? guiErrorMessage()
#include <GUI/new_gui.hxx> // FGFontCache, FGColor
#include <Include/fg_typedefs.h>
#include <Main/fg_props.hxx>

View file

@ -145,6 +145,22 @@ static osg::Vec2 mult(const osg::Vec2& v, const osg::Matrixf& m)
return osg::Vec2(r.x(), r.y());
}
class NavDisplay::CacheListener : public SGPropertyChangeListener
{
public:
CacheListener(NavDisplay *nd) :
_nd(nd)
{}
virtual void valueChanged (SGPropertyNode * prop)
{
_nd->invalidatePositionedCache();
SG_LOG(SG_INSTR, SG_INFO, "invalidating NavDisplay cache");
}
private:
NavDisplay* _nd;
};
///////////////////////////////////////////////////////////////////
class SymbolDef
@ -381,7 +397,13 @@ NavDisplay::~NavDisplay()
void
NavDisplay::init ()
{
_cachedItemsValid = false;
_cacheListener.reset(new CacheListener(this));
_serviceable_node = _Instrument->getNode("serviceable", true);
_rangeNode = _Instrument->getNode("range", true);
_rangeNode->setDoubleValue(40.0);
_rangeNode->addChangeListener(_cacheListener.get());
// texture name to use in 2D and 3D instruments
_texture_path = _Instrument->getStringValue("radar-texture-path",
@ -402,11 +424,6 @@ NavDisplay::init ()
_odg = (FGODGauge *)imgr->get_subsystem("od_gauge");
_odg->setSize(_Instrument->getIntValue("texture-size", 512));
_user_lat_node = fgGetNode("/position/latitude-deg", true);
_user_lon_node = fgGetNode("/position/longitude-deg", true);
_user_alt_node = fgGetNode("/position/altitude-ft", true);
_route = static_cast<FGRouteMgr*>(globals->get_subsystem("route-manager"));
_navRadio1Node = fgGetNode("/instrumentation/nav[0]", true);
@ -508,7 +525,7 @@ NavDisplay::update (double delta_time_sec)
}
_time -= _updateInterval;
_rangeNm = _Instrument->getFloatValue("range", 40.0);
_rangeNm = _rangeNode->getFloatValue();
if (_Instrument->getBoolValue("aircraft-heading-up", true)) {
_view_heading = fgGetDouble("/orientation/heading-deg");
} else {
@ -527,9 +544,17 @@ NavDisplay::update (double delta_time_sec)
_projectMat = osg::Matrixf::scale(_scale, _scale, 1.0) *
degRotation(-_view_heading) * _centerTrans;
_pos = SGGeod::fromDegFt(_user_lon_node->getDoubleValue(),
_user_lat_node->getDoubleValue(),
_user_alt_node->getDoubleValue());
_pos = globals->get_aircraft_position();
// invalidate the cache of positioned items, if we travelled more than 1nm
if (_cachedItemsValid) {
SGVec3d cartNow(SGVec3d::fromGeod(_pos));
double movedNm = dist(_cachedPos, cartNow) * SG_METER_TO_NM;
_cachedItemsValid = (movedNm < 1.0);
if (!_cachedItemsValid) {
SG_LOG(SG_INSTR, SG_INFO, "invalidating NavDisplay cache due to moving: " << movedNm);
}
}
_vertices->clear();
_lineVertices->clear();
@ -538,6 +563,11 @@ NavDisplay::update (double delta_time_sec)
_texCoords->clear();
_textGeode->removeDrawables(0, _textGeode->getNumDrawables());
BOOST_FOREACH(SymbolInstance* si, _symbols) {
delete si;
}
_symbols.clear();
BOOST_FOREACH(SymbolDef* def, _rules) {
if (def->enable) {
def->enabled = def->enable->test();
@ -787,15 +817,17 @@ public:
void NavDisplay::findItems()
{
Filter filt;
filt.minRunwayLengthFt = 2000;
if (!_cachedItemsValid) {
SG_LOG(SG_INSTR, SG_INFO, "re-validating NavDisplay cache");
Filter filt;
filt.minRunwayLengthFt = 2000;
_itemsInRange = FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
_cachedItemsValid = true;
_cachedPos = SGVec3d::fromGeod(_pos);
}
FGPositioned::List items =
FGPositioned::findWithinRange(_pos, _rangeNm, &filt);
FGPositioned::List::const_iterator it;
for (it = items.begin(); it != items.end(); ++it) {
foundPositionedItem(*it);
BOOST_FOREACH(FGPositioned* pos, _itemsInRange) {
foundPositionedItem(pos);
}
}
@ -1118,11 +1150,26 @@ void NavDisplay::computeAIStates(const SGPropertyNode* ai, string_set& states)
}
}
void NavDisplay::addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars)
bool NavDisplay::addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars)
{
if (isProjectedClipped(proj)) {
return false;
}
SymbolInstance* sym = new SymbolInstance(proj, heading, def, vars);
_symbols.push_back(sym);
return true;
}
bool NavDisplay::isProjectedClipped(const osg::Vec2& projected) const
{
double size = _odg->size();
return (projected.x() < 0.0) ||
(projected.y() < 0.0) ||
(projected.x() >= size) ||
(projected.y() >= size);
}

View file

@ -34,11 +34,13 @@
#include <vector>
#include <string>
#include <memory>
#include <Navaids/positioned.hxx>
class FGODGauge;
class FGRouteMgr;
class FGNavRecord;
class FGPositioned;
class SymbolInstance;
class SymbolDef;
@ -61,6 +63,10 @@ public:
virtual void init();
virtual void update(double dt);
void invalidatePositionedCache()
{
_cachedItemsValid = false;
}
protected:
std::string _name;
int _num;
@ -70,11 +76,7 @@ protected:
SGPropertyNode_ptr _serviceable_node;
SGPropertyNode_ptr _Instrument;
SGPropertyNode_ptr _radar_mode_control_node;
SGPropertyNode_ptr _user_lat_node;
SGPropertyNode_ptr _user_lon_node;
SGPropertyNode_ptr _user_heading_node;
SGPropertyNode_ptr _user_alt_node;
FGODGauge *_odg;
@ -103,11 +105,11 @@ private:
bool anyRuleMatches(const std::string& type, const string_set& states) const;
void findRules(const std::string& type, const string_set& states, SymbolDefVector& rules);
void addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars);
bool addSymbolInstance(const osg::Vec2& proj, double heading, SymbolDef* def, SGPropertyNode* vars);
void addLine(osg::Vec2 a, osg::Vec2 b, const osg::Vec4& color);
osg::Vec2 projectBearingRange(double bearingDeg, double rangeNm) const;
osg::Vec2 projectGeod(const SGGeod& geod) const;
bool isProjectedClipped(const osg::Vec2& projected) const;
void updateFont();
std::string _texture_path;
@ -154,13 +156,21 @@ private:
FGRouteMgr* _route;
SGGeod _pos;
double _rangeNm;
SGPropertyNode_ptr _rangeNode;
SymbolDefVector _rules;
FGNavRecord* _nav1Station;
FGNavRecord* _nav2Station;
std::vector<SymbolInstance*> _symbols;
std::set<FGPositioned*> _routeSources;
bool _cachedItemsValid;
SGVec3d _cachedPos;
FGPositioned::List _itemsInRange;
SGPropertyNode_ptr _excessDataNode;
class CacheListener;
std::auto_ptr<CacheListener> _cacheListener;
};
#endif // _INST_ND_HXX

View file

@ -3,6 +3,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <math.h>
#include <simgear/math/interpolater.hxx>

View file

@ -6,6 +6,10 @@
// TODO:
// - better spin-up
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/compiler.h>
#include <iostream>

View file

@ -3,6 +3,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/compiler.h>
#include <simgear/sg_inlines.h>
#include <iostream>

View file

@ -5,6 +5,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/compiler.h>
#include <iostream>
#include <string>

View file

@ -20,6 +20,10 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <limits>
#include <simgear/math/interpolater.hxx>

View file

@ -440,6 +440,7 @@ void FGNavRadio::updateReceiver(double dt)
_gsNeedleDeflectionNorm = 0.0;
heading_node->setDoubleValue(0.0);
inrange_node->setBoolValue(false);
signal_quality_norm_node->setDoubleValue(0.0);
return;
}

View file

@ -3,6 +3,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "slip_skid_ball.hxx"
#include <Main/fg_props.hxx>
#include <Main/util.hxx>

View file

@ -3,6 +3,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/compiler.h>
#include <iostream>
#include <string>

View file

@ -3,6 +3,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <simgear/math/interpolater.hxx>
#include "vertical_speed_indicator.hxx"

View file

@ -77,6 +77,7 @@ target_link_libraries(fgfs
${OPENAL_LIBRARY}
${OPENGL_LIBRARIES}
${PLIB_LIBRARIES}
${JPEG_LIBRARY}
${LIBSVN_LIBRARIES}
${HLA_LIBRARIES}
${SIMGEAR_CORE_LIBRARY_DEPENDENCIES}

View file

@ -56,6 +56,7 @@
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/structure/event_mgr.hxx>
#include <simgear/structure/SGPerfMon.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/misc/sgstream.hxx>
@ -106,7 +107,7 @@
#include <Traffic/TrafficMgr.hxx>
#include <MultiPlayer/multiplaymgr.hxx>
#include <FDM/fdm_shell.hxx>
#include <Environment/ephemeris.hxx>
#include <Environment/environment_mgr.hxx>
#include "fg_init.hxx"
@ -1176,12 +1177,6 @@ bool fgInitGeneral() {
// gear, its initialization call should located in this routine.
// Returns non-zero if a problem encountered.
bool fgInitSubsystems() {
// static const SGPropertyNode *longitude
// = fgGetNode("/sim/presets/longitude-deg");
// static const SGPropertyNode *latitude
// = fgGetNode("/sim/presets/latitude-deg");
// static const SGPropertyNode *altitude
// = fgGetNode("/sim/presets/altitude-ft");
SG_LOG( SG_GENERAL, SG_INFO, "Initialize Subsystems");
SG_LOG( SG_GENERAL, SG_INFO, "========== ==========");
@ -1205,6 +1200,14 @@ bool fgInitSubsystems() {
////////////////////////////////////////////////////////////////////
globals->add_subsystem("properties", new FGProperties);
////////////////////////////////////////////////////////////////////
// Add the performance monitoring system.
////////////////////////////////////////////////////////////////////
globals->add_subsystem("performance-mon",
new SGPerformanceMonitor(globals->get_subsystem_mgr(),
fgGetNode("/sim/performance-monitor", true)));
////////////////////////////////////////////////////////////////////
// Initialize the material property subsystem.
////////////////////////////////////////////////////////////////////
@ -1239,6 +1242,7 @@ bool fgInitSubsystems() {
// Initialize the weather modeling subsystem
globals->add_subsystem("environment", new FGEnvironmentMgr);
globals->add_subsystem("ephemeris", new Ephemeris);
////////////////////////////////////////////////////////////////////
// Initialize the aircraft systems and instrumentation (before the
@ -1287,9 +1291,7 @@ bool fgInitSubsystems() {
// sub system infrastructure.
////////////////////////////////////////////////////////////////////
SG_LOG(SG_GENERAL, SG_INFO, " ATC Manager");
globals->set_ATC_mgr(new FGATCMgr);
globals->get_ATC_mgr()->init();
globals->add_subsystem("ATC-old", new FGATCMgr, SGSubsystemMgr::INIT);
////////////////////////////////////////////////////////////////////
// Initialize the ATC subsystem
@ -1311,14 +1313,14 @@ bool fgInitSubsystems() {
// Initialise the AI Model Manager
////////////////////////////////////////////////////////////////////
SG_LOG(SG_GENERAL, SG_INFO, " AI Model Manager");
globals->add_subsystem("ai_model", new FGAIManager, SGSubsystemMgr::POST_FDM);
globals->add_subsystem("submodel_mgr", new FGSubmodelMgr, SGSubsystemMgr::POST_FDM);
globals->add_subsystem("ai-model", new FGAIManager, SGSubsystemMgr::POST_FDM);
globals->add_subsystem("submodel-mgr", new FGSubmodelMgr, SGSubsystemMgr::POST_FDM);
// It's probably a good idea to initialize the top level traffic manager
// After the AI and ATC systems have been initialized properly.
// AI Traffic manager
globals->add_subsystem("Traffic Manager", new FGTrafficManager, SGSubsystemMgr::POST_FDM);
globals->add_subsystem("traffic-manager", new FGTrafficManager, SGSubsystemMgr::POST_FDM);
////////////////////////////////////////////////////////////////////
// Add a new 2D panel.
@ -1453,7 +1455,7 @@ void fgReInitSubsystems()
// Force reupdating the positions of the ai 3d models. They are used for
// initializing ground level for the FDM.
globals->get_subsystem("ai_model")->reinit();
globals->get_subsystem("ai-model")->reinit();
// Initialize the FDM
globals->get_subsystem("flight")->reinit();

View file

@ -25,7 +25,7 @@
#include <simgear/misc/sg_path.hxx>
#include <simgear/scene/material/EffectCullVisitor.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/scene/tgdb/userdata.hxx>
#include <simgear/scene/tgdb/TileEntry.hxx>
#include <simgear/scene/model/ModelRegistry.hxx>
@ -223,15 +223,14 @@ fgviewerMain(int argc, char** argv)
// The file path list must be set in the registry.
osgDB::Registry::instance()->getDataFilePathList() = filePathList;
SGReaderWriterBTGOptions* btgOptions = new SGReaderWriterBTGOptions;
btgOptions->getDatabasePathList() = filePathList;
btgOptions->setMatlib(globals->get_matlib());
btgOptions->setUseRandomObjects(fgGetBool("/sim/rendering/random-objects", false));
btgOptions->setUseRandomVegetation(fgGetBool("/sim/rendering/random-vegetation", false));
simgear::SGReaderWriterOptions* options = new simgear::SGReaderWriterOptions;
options->getDatabasePathList() = filePathList;
options->setMaterialLib(globals->get_matlib());
options->setPropertyNode(globals->get_props());
// read the scene from the list of file specified command line args.
osg::ref_ptr<osg::Node> loadedModel;
loadedModel = osgDB::readNodeFiles(dataFiles, btgOptions);
loadedModel = osgDB::readNodeFiles(dataFiles, options);
// if no model has been successfully loaded report failure.
if (!loadedModel.valid()) {

View file

@ -47,7 +47,7 @@
#include <ATCDCL/ATCmgr.hxx>
#include <Autopilot/route_mgr.hxx>
#include <Cockpit/panel.hxx>
#include <GUI/new_gui.hxx>
#include <GUI/FGFontCache.hxx>
#include <Model/acmodel.hxx>
#include <Model/modelmgr.hxx>
#include <MultiPlayer/multiplaymgr.hxx>
@ -161,16 +161,13 @@ FGGlobals::FGGlobals() :
// Destructor
FGGlobals::~FGGlobals()
{
delete renderer;
renderer = NULL;
// The AIModels manager performs a number of actions upon
// Shutdown that implicitly assume that other subsystems
// are still operational (Due to the dynamic allocation and
// deallocation of AIModel objects. To ensure we can safely
// shut down all subsystems, make sure we take down the
// AIModels system first.
SGSubsystem* ai = subsystem_mgr->remove("ai_model");
SGSubsystem* ai = subsystem_mgr->remove("ai-model");
if (ai) {
ai->unbind();
delete ai;
@ -180,6 +177,9 @@ FGGlobals::~FGGlobals()
subsystem_mgr->unbind();
delete subsystem_mgr;
delete renderer;
renderer = NULL;
delete time_params;
delete mag;
delete matlib;
@ -220,7 +220,7 @@ void FGGlobals::set_fg_root (const string &root) {
SGPath tmp( fg_root );
tmp.append( "data" );
tmp.append( "version" );
if ( ulFileExists( tmp.c_str() ) ) {
if ( tmp.exists() ) {
fgGetNode("BAD_FG_ROOT", true)->setStringValue(fg_root);
fg_root += "/data";
fgGetNode("GOOD_FG_ROOT", true)->setStringValue(fg_root);

View file

@ -67,7 +67,6 @@
#include <ATCDCL/ATCmgr.hxx>
#include <Time/TimeManager.hxx>
#include <Environment/environment_mgr.hxx>
#include <Environment/ephemeris.hxx>
#include <GUI/gui.h>
#include <GUI/new_gui.hxx>
#include <MultiPlayer/multiplaymgr.hxx>
@ -83,7 +82,7 @@
#include "fg_os.hxx"
#include "WindowSystemAdapter.hxx"
#include <Main/viewer.hxx>
#include <Main/fg_props.hxx>
using namespace flightgear;
@ -104,33 +103,11 @@ extern int _bootstrap_OSInit;
// What should we do when we have nothing else to do? Let's get ready
// for the next move and update the display?
static void fgMainLoop( void ) {
static SGConstPropertyNode_ptr longitude
= fgGetNode("/position/longitude-deg");
static SGConstPropertyNode_ptr latitude
= fgGetNode("/position/latitude-deg");
static SGConstPropertyNode_ptr altitude
= fgGetNode("/position/altitude-ft");
static SGConstPropertyNode_ptr vn_fps
= fgGetNode("/velocities/speed-north-fps");
static SGConstPropertyNode_ptr ve_fps
= fgGetNode("/velocities/speed-east-fps");
static SGConstPropertyNode_ptr vd_fps
= fgGetNode("/velocities/speed-down-fps");
static void fgMainLoop( void )
{
static SGPropertyNode_ptr frame_signal
= fgGetNode("/sim/signals/frame", true);
static SGPropertyNode_ptr _statisticsFlag
= fgGetNode("/sim/timing-statistics/enabled", true);
static SGPropertyNode_ptr _statisticsInterval
= fgGetNode("/sim/timing-statistics/interval-s", true);
static SGPropertyNode_ptr _statiticsMinJitter
= fgGetNode("/sim/timing-statistics/min-jitter-ms", true);
static SGPropertyNode_ptr _statiticsMinTime
= fgGetNode("/sim/timing-statistics/min-time-ms", true);
frame_signal->fireValueChanged();
SG_LOG( SG_GENERAL, SG_DEBUG, "Running Main Loop");
@ -145,16 +122,9 @@ static void fgMainLoop( void ) {
timeMgr->computeTimeDeltas(sim_dt, real_dt);
// update magvar model
globals->get_mag()->update( longitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
latitude->getDoubleValue()
* SGD_DEGREES_TO_RADIANS,
altitude->getDoubleValue() * SG_FEET_TO_METER,
globals->get_mag()->update( globals->get_aircraft_position(),
globals->get_time_params()->getJD() );
// Run ATC subsystem
globals->get_ATC_mgr()->update(sim_dt);
globals->get_subsystem_mgr()->update(sim_dt);
// Update the sound manager last so it can use the CPU while the GPU
@ -218,27 +188,6 @@ static void fgMainLoop( void ) {
}
}
// print timing statistics
static bool _lastStatisticsFlag = false;
if (_lastStatisticsFlag != _statisticsFlag->getBoolValue())
{
// flag has changed, update subsystem manager
_lastStatisticsFlag = _statisticsFlag->getBoolValue();
globals->get_subsystem_mgr()->collectDebugTiming(_lastStatisticsFlag);
}
if (_lastStatisticsFlag)
{
static double elapsed = 0;
elapsed += real_dt;
if (elapsed >= _statisticsInterval->getDoubleValue())
{
// print and reset timing statistics
globals->get_subsystem_mgr()->printTimingStatistics(_statiticsMinTime->getDoubleValue(),
_statiticsMinJitter->getDoubleValue());
elapsed = 0;
}
}
simgear::AtomicChangeListener::fireChangeListeners();
SG_LOG( SG_GENERAL, SG_DEBUG, "" );
@ -410,63 +359,27 @@ static void fgIdleFunction ( void ) {
} else if ( idle_state == 6 ) {
idle_state++;
// Initialize the sky
Ephemeris* eph = new Ephemeris;
globals->add_subsystem("ephemeris", eph);
eph->init(); // FIXME - remove this once SGSky code below is also a subsystem
eph->bind();
// TODO: move to environment mgr
thesky = new SGSky;
SGPath texture_path(globals->get_fg_root());
texture_path.append("Textures");
texture_path.append("Sky");
for (int i = 0; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) {
SGCloudLayer * layer = new SGCloudLayer(texture_path.str());
thesky->add_cloud_layer(layer);
}
SGPath sky_tex_path( globals->get_fg_root() );
sky_tex_path.append( "Textures" );
sky_tex_path.append( "Sky" );
thesky->texture_path( sky_tex_path.str() );
// The sun and moon diameters are scaled down numbers of the
// actual diameters. This was needed to fit both the sun and the
// moon within the distance to the far clip plane.
// Moon diameter: 3,476 kilometers
// Sun diameter: 1,390,000 kilometers
thesky->build( 80000.0, 80000.0,
463.3, 361.8,
*globals->get_ephem(),
fgGetNode("/environment", true));
// Initialize MagVar model
SGMagVar *magvar = new SGMagVar();
globals->set_mag( magvar );
// kludge to initialize mag compass
// (should only be done for in-flight
// startup)
// kludge to initialize mag compass
// (should only be done for in-flight
// startup)
// update magvar model
globals->get_mag()->update( fgGetDouble("/position/longitude-deg")
* SGD_DEGREES_TO_RADIANS,
fgGetDouble("/position/latitude-deg")
* SGD_DEGREES_TO_RADIANS,
fgGetDouble("/position/altitude-ft")
* SG_FEET_TO_METER,
globals->get_time_params()->getJD() );
* SGD_DEGREES_TO_RADIANS,
fgGetDouble("/position/latitude-deg")
* SGD_DEGREES_TO_RADIANS,
fgGetDouble("/position/altitude-ft")
* SG_FEET_TO_METER,
globals->get_time_params()->getJD() );
double var = globals->get_mag()->get_magvar() * SGD_RADIANS_TO_DEGREES;
fgSetDouble("/instrumentation/heading-indicator/offset-deg", -var);
fgSetDouble("/instrumentation/heading-indicator-fg/offset-deg", -var);
// airport = new ssgBranch;
// airport->setName( "Airport Lighting" );
// lighting->addKid( airport );
fgSplashProgress("initializing subsystems");
} else if ( idle_state == 7 ) {

View file

@ -80,6 +80,7 @@ using std::cout;
using std::cerr;
using std::endl;
using std::vector;
using std::cin;
#define NEW_DEFAULT_MODEL_HZ 120
@ -1560,6 +1561,10 @@ public:
{
OptionValueVec::const_iterator it = values.begin();
for (; it != values.end(); ++it) {
if (!it->desc) {
continue; // ignore markers
}
if (it->desc->option == key) {
return it;
}
@ -1580,6 +1585,10 @@ public:
int processOption(OptionDesc* desc, const string& arg_value)
{
if (!desc) {
return FG_OPTIONS_OK; // tolerate marker options
}
switch ( desc->type & 0xffff ) {
case OPTION_BOOL:
fgSetBool( desc->property, desc->b_param );
@ -1648,9 +1657,35 @@ public:
return FG_OPTIONS_OK;
}
/**
* insert a marker value into the values vector. This is necessary
* when processing options, to ensure the correct ordering, where we scan
* for marker values in reverse, and then forwards within each group.
*/
void insertGroupMarker()
{
values.push_back(OptionValue(NULL, "-"));
}
/**
* given a current iterator into the values, find the preceeding group marker,
* or return the beginning of the value vector.
*/
OptionValueVec::const_iterator rfindGroup(OptionValueVec::const_iterator pos) const
{
while (--pos != values.begin()) {
if (pos->desc == NULL) {
return pos; // found a marker, we're done
}
}
return pos;
}
bool showHelp,
verbose,
showAircraft;
OptionDescDict options;
OptionValueVec values;
simgear::PathList propertyFiles;
@ -1710,6 +1745,7 @@ void Options::init(int argc, char **argv, const SGPath& appDataPath)
p->propertyFiles.push_back(f);
}
} // of arguments iteration
p->insertGroupMarker(); // command line is one group
// then config files
SGPath config;
@ -1850,6 +1886,7 @@ void Options::readConfig(const SGPath& path)
in >> skipcomment;
}
p->insertGroupMarker(); // each config file is a group
}
int Options::parseOption(const string& s)
@ -1898,6 +1935,7 @@ int Options::addOption(const string &key, const string &value)
{
OptionDesc* desc = p->findOption(key);
if (!desc) {
SG_LOG(SG_GENERAL, SG_ALERT, "unknown option:" << key);
return FG_OPTIONS_ERROR;
}
@ -1934,6 +1972,10 @@ string_list Options::valuesForOption(const std::string& key) const
string_list result;
OptionValueVec::const_iterator it = p->values.begin();
for (; it != p->values.end(); ++it) {
if (!it->desc) {
continue; // ignore marker values
}
if (it->desc->option == key) {
result.push_back(it->value);
}
@ -1951,15 +1993,26 @@ void Options::processOptions()
exit(0);
}
// proces options in LIFO order, so earlier (first in) options are processed
// after, and hence override, later specified options.
OptionValueVec::const_reverse_iterator it = p->values.rbegin();
for (; it != p->values.rend(); ++it) {
int result = p->processOption(it->desc, it->value);
if (result == FG_OPTIONS_ERROR) {
showUsage();
exit(-1);
// processing order is complicated. We must process groups LIFO, but the
// values *within* each group in FIFO order, to retain consistency with
// older versions of FG, and existing user configs.
// in practice this means system.fgfsrc must be *processed* before
// .fgfsrc, which must be processed before the command line args, and so on.
OptionValueVec::const_iterator groupEnd = p->values.end();
while (groupEnd != p->values.begin()) {
OptionValueVec::const_iterator groupBegin = p->rfindGroup(groupEnd);
// run over the group in FIFO order
OptionValueVec::const_iterator it;
for (it = groupBegin; it != groupEnd; ++it) {
int result = p->processOption(it->desc, it->value);
if (result == FG_OPTIONS_ERROR) {
showUsage();
exit(-1);
}
}
groupEnd = groupBegin;
}
BOOST_FOREACH(const SGPath& file, p->propertyFiles) {
@ -2137,8 +2190,8 @@ void Options::showUsage() const
cout << "For a complete list of options use --help --verbose" << endl;
}
#ifdef _MSC_VER
cout << "Hit a key to continue..." << endl;
cin.get();
std::cout << "Hit a key to continue..." << std::endl;
std::cin.get();
#endif
}

View file

@ -93,6 +93,7 @@
#include <GUI/new_gui.hxx>
#include <Instrumentation/HUD/HUD.hxx>
#include <Environment/precipitation_mgr.hxx>
#include <Environment/environment_mgr.hxx>
#include "splash.hxx"
#include "renderer.hxx"
@ -374,9 +375,6 @@ public:
bool FGScenerySwitchCallback::scenery_enabled = false;
// Sky structures
SGSky *thesky;
static osg::ref_ptr<osg::FrameStamp> mFrameStamp = new osg::FrameStamp;
static osg::ref_ptr<SGUpdateVisitor> mUpdateVisitor= new SGUpdateVisitor;
@ -391,7 +389,8 @@ static void updateRenderer()
}
#endif
FGRenderer::FGRenderer()
FGRenderer::FGRenderer() :
_sky(NULL)
{
#ifdef FG_JPEG_SERVER
jpgRenderFrame = updateRenderer;
@ -404,6 +403,7 @@ FGRenderer::~FGRenderer()
#ifdef FG_JPEG_SERVER
jpgRenderFrame = NULL;
#endif
delete _sky;
}
// Initialize various GL/view parameters
@ -411,7 +411,7 @@ FGRenderer::~FGRenderer()
// critical parts of the scene graph in addition to the splash screen.
void
FGRenderer::splashinit( void ) {
osgViewer::Viewer* viewer = globals->get_renderer()->getViewer();
osgViewer::Viewer* viewer = getViewer();
mRealRoot = dynamic_cast<osg::Group*>(viewer->getSceneData());
mRealRoot->addChild(fgCreateSplashNode());
mFrameStamp = viewer->getFrameStamp();
@ -454,6 +454,20 @@ FGRenderer::init( void )
SGConfigureDirectionalLights( use_point_sprites, enhanced_lighting,
distance_attenuation );
// create sky, but can't build until setupView, since we depend
// on other subsystems to be inited, eg Ephemeris
_sky = new SGSky;
SGPath texture_path(globals->get_fg_root());
texture_path.append("Textures");
texture_path.append("Sky");
for (int i = 0; i < FGEnvironmentMgr::MAX_CLOUD_LAYERS; i++) {
SGCloudLayer * layer = new SGCloudLayer(texture_path.str());
_sky->add_cloud_layer(layer);
}
_sky->texture_path( texture_path.str() );
}
void
@ -472,6 +486,17 @@ FGRenderer::setupView( void )
if ( fgGetBool("/sim/startup/fullscreen") )
fgOSFullScreen();
// build the sky
// The sun and moon diameters are scaled down numbers of the
// actual diameters. This was needed to fit both the sun and the
// moon within the distance to the far clip plane.
// Moon diameter: 3,476 kilometers
// Sun diameter: 1,390,000 kilometers
_sky->build( 80000.0, 80000.0,
463.3, 361.8,
*globals->get_ephem(),
fgGetNode("/environment", true));
viewer->getCamera()
->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
@ -547,15 +572,17 @@ FGRenderer::setupView( void )
sunLight->setUpdateCallback(new FGLightSourceUpdateCallback(true));
sunLight->setReferenceFrame(osg::LightSource::RELATIVE_RF);
sunLight->setLocalStateSetModes(osg::StateAttribute::ON);
// Hang a StateSet above the sky subgraph in order to turn off
// light 0
Group* skyGroup = new Group;
StateSet* skySS = skyGroup->getOrCreateStateSet();
skySS->setMode(GL_LIGHT0, StateAttribute::OFF);
skyGroup->addChild(thesky->getPreRoot());
skyGroup->addChild(_sky->getPreRoot());
sunLight->addChild(skyGroup);
mRoot->addChild(sceneGroup);
mRoot->addChild(sunLight);
// Clouds are added to the scene graph later
stateSet = globals->get_scenery()->get_scene_graph()->getOrCreateStateSet();
stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
@ -594,7 +621,7 @@ FGRenderer::setupView( void )
// The clouds are attached directly to the scene graph root
// because, in theory, they don't want the same default state set
// as the rest of the scene. This may not be true in practice.
mRealRoot->addChild(thesky->getCloudRoot());
mRealRoot->addChild(_sky->getCloudRoot());
mRealRoot->addChild(FGCreateRedoutNode());
// Attach empty program to the scene root so that shader programs
// don't leak into state sets (effects) that shouldn't have one.
@ -644,7 +671,7 @@ FGRenderer::update( ) {
// update fog params
double actual_visibility;
if (_cloud_status->getBoolValue()) {
actual_visibility = thesky->get_visibility();
actual_visibility = _sky->get_visibility();
} else {
actual_visibility = _visibility_m->getDoubleValue();
}
@ -673,10 +700,10 @@ FGRenderer::update( ) {
// update fog params if visibility has changed
double visibility_meters = _visibility_m->getDoubleValue();
thesky->set_visibility(visibility_meters);
_sky->set_visibility(visibility_meters);
double altitude_m = _altitude_ft->getDoubleValue() * SG_FEET_TO_METER;
thesky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
_sky->modify_vis( altitude_m, 0.0 /* time factor, now unused */);
// update the sky dome
if ( skyblend ) {
@ -720,8 +747,8 @@ FGRenderer::update( ) {
scolor.moon_angle = l->get_moon_angle();
double delta_time_sec = _sim_delta_sec->getDoubleValue();
thesky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
thesky->repaint( scolor, *globals->get_ephem() );
_sky->reposition( sstate, *globals->get_ephem(), delta_time_sec );
_sky->repaint( scolor, *globals->get_ephem() );
//OSGFIXME
// shadows->setupShadows(

View file

@ -35,7 +35,6 @@ class FGEventHandler;
}
class SGSky;
extern SGSky *thesky;
class FGRenderer {
@ -73,6 +72,8 @@ public:
*/
void addCamera(osg::Camera* camera, bool useSceneData);
SGSky* getSky() const { return _sky; }
protected:
osg::ref_ptr<osgViewer::Viewer> viewer;
osg::ref_ptr<flightgear::FGEventHandler> eventHandler;
@ -85,6 +86,7 @@ protected:
SGPropertyNode_ptr _panel_hotspots, _sim_delta_sec, _horizon_effect, _altitude_ft;
SGPropertyNode_ptr _virtual_cockpit;
SGTimeStamp _splash_time;
SGSky* _sky;
};
bool fgDumpSceneGraphToFile(const char* filename);

View file

@ -46,7 +46,10 @@
#include <simgear/math/sg_random.h>
#include <simgear/misc/sg_path.hxx>
#include <GUI/new_gui.hxx>
#include <plib/fnt.h>
#include "GUI/FGFontCache.hxx"
#include "GUI/FGColor.hxx"
#include "globals.hxx"
#include "fg_props.hxx"

View file

@ -75,7 +75,7 @@ FGModelMgr::add_model (SGPropertyNode * node)
osg::Node *object;
try {
object = SGModelLib::loadPagedModel(path, globals->get_props());
object = SGModelLib::loadDeferredModel(path, globals->get_props());
} catch (const sg_throwable& t) {
SG_LOG(SG_GENERAL, SG_ALERT, "Error loading " << path << ":\n "
<< t.getFormattedMessage() << t.getOrigin());

View file

@ -1309,7 +1309,7 @@ FGMultiplayMgr::addMultiplayer(const std::string& callsign,
mp->setCallSign(callsign);
mMultiPlayerMap[callsign] = mp;
FGAIManager *aiMgr = (FGAIManager*)globals->get_subsystem("ai_model");
FGAIManager *aiMgr = (FGAIManager*)globals->get_subsystem("ai-model");
if (aiMgr) {
aiMgr->attach(mp);

View file

@ -1,3 +1,8 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Navaids/routePath.hxx>
#include <simgear/structure/exception.hxx>

View file

@ -701,7 +701,7 @@ public:
if (modelPath.empty())
return;
FGAIManager *aiMgr;
aiMgr = static_cast<FGAIManager*>(globals->get_subsystem("ai_model"));
aiMgr = static_cast<FGAIManager*>(globals->get_subsystem("ai-model"));
if (!aiMgr)
return;

View file

@ -20,7 +20,6 @@
# include <config.h>
#endif
#include <simgear/scene/model/SGPagedLOD.hxx>
#include <simgear/math/SGMath.hxx>
#include "SceneryPager.hxx"
#include <algorithm>
@ -44,25 +43,6 @@ SceneryPager::~SceneryPager()
{
}
#if SG_PAGEDLOD_HAS_OPTIONS
#else
void SceneryPager::requestNodeFile(const std::string& fileName, Group* group,
float priority, const FrameStamp* framestamp,
ref_ptr<Referenced>& databaseRequest,
osgDB::ReaderWriter::Options* options)
{
simgear::SGPagedLOD *sgplod = dynamic_cast<simgear::SGPagedLOD*>(group);
if(sgplod)
DatabasePager::requestNodeFile(fileName, group, priority, framestamp,
databaseRequest,
sgplod->getReaderWriterOptions());
else
DatabasePager::requestNodeFile(fileName, group, priority, framestamp,
databaseRequest,
options);
}
#endif
void SceneryPager::queueRequest(const std::string& fileName, Group* group,
float priority, FrameStamp* frameStamp,
ref_ptr<Referenced>& databaseRequest,

View file

@ -28,7 +28,6 @@
#include <osgDB/DatabasePager>
#include <simgear/structure/OSGVersion.hxx>
#include <simgear/scene/model/SGPagedLOD.hxx>
namespace flightgear
{
@ -39,15 +38,6 @@ public:
SceneryPager(const SceneryPager& rhs);
// Unhide DatabasePager::requestNodeFile
using osgDB::DatabasePager::requestNodeFile;
// reimplement to add readerWriterOptions from SGPagedLOD
#if SG_PAGEDLOD_HAS_OPTIONS
#else
virtual void requestNodeFile(const std::string& fileName, osg::Group* group,
float priority,
const osg::FrameStamp* framestamp,
osg::ref_ptr<osg::Referenced>& databaseRequest,
osgDB::ReaderWriter::Options* options);
#endif
void queueRequest(const std::string& fileName, osg::Group* node,
float priority, osg::FrameStamp* frameStamp,
osg::ref_ptr<osg::Referenced>& databaseRequest,

View file

@ -29,12 +29,13 @@
#include <functional>
#include <osgViewer/Viewer>
#include <osgDB/Registry>
#include <simgear/constants.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
#include <simgear/scene/model/modellib.hxx>
#include <simgear/scene/tgdb/SGReaderWriterBTGOptions.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/scene/tsync/terrasync.hxx>
#include <Main/globals.hxx>
@ -54,33 +55,11 @@ using simgear::TileEntry;
using simgear::TileCache;
// helper: listen to property changes affecting tile loading
class LoaderPropertyWatcher : public SGPropertyChangeListener
{
public:
LoaderPropertyWatcher(FGTileMgr* pTileMgr) :
_pTileMgr(pTileMgr)
{
}
virtual void valueChanged(SGPropertyNode*)
{
_pTileMgr->configChanged();
}
private:
FGTileMgr* _pTileMgr;
};
FGTileMgr::FGTileMgr():
state( Start ),
vis( 16000 ),
_terra_sync(NULL),
_propListener(new LoaderPropertyWatcher(this))
_terra_sync(NULL)
{
_randomObjects = fgGetNode("/sim/rendering/random-objects", true);
_randomVegetation = fgGetNode("/sim/rendering/random-vegetation", true);
_maxTileRangeM = fgGetNode("/sim/rendering/static-lod/bare", true);
}
@ -90,8 +69,6 @@ FGTileMgr::~FGTileMgr()
// remove all nodes we might have left behind
osg::Group* group = globals->get_scenery()->get_terrain_branch();
group->removeChildren(0, group->getNumChildren());
delete _propListener;
_propListener = NULL;
// clear OSG cache
osgDB::Registry::instance()->clearObjectCache();
}
@ -101,12 +78,9 @@ FGTileMgr::~FGTileMgr()
void FGTileMgr::init() {
SG_LOG( SG_TERRAIN, SG_INFO, "Initializing Tile Manager subsystem." );
_options = new SGReaderWriterBTGOptions;
_options->setMatlib(globals->get_matlib());
_randomObjects.get()->addChangeListener(_propListener, false);
_randomVegetation.get()->addChangeListener(_propListener, false);
configChanged();
_options = new simgear::SGReaderWriterOptions;
_options->setMaterialLib(globals->get_matlib());
_options->setPropertyNode(globals->get_props());
osgDB::FilePathList &fp = _options->getDatabasePathList();
const string_list &sc = globals->get_fg_scenery();
@ -120,6 +94,10 @@ void FGTileMgr::init() {
reinit();
}
void FGTileMgr::refresh_tile(void* tileMgr, long tileIndex)
{
((FGTileMgr*) tileMgr)->tile_cache.refresh_tile(tileIndex);
}
void FGTileMgr::reinit()
{
@ -142,18 +120,12 @@ void FGTileMgr::reinit()
_terra_sync = (simgear::SGTerraSync*) globals->get_subsystem("terrasync");
if (_terra_sync)
_terra_sync->setTileCache(&tile_cache);
_terra_sync->setTileRefreshCb(&refresh_tile, this);
// force an update now
update(0.0);
}
void FGTileMgr::configChanged()
{
_options->setUseRandomObjects(_randomObjects.get()->getBoolValue());
_options->setUseRandomVegetation(_randomVegetation.get()->getBoolValue());
}
/* schedule a tile for loading, keep request for given amount of time.
* Returns true if tile is already loaded. */
bool FGTileMgr::sched_tile( const SGBucket& b, double priority, bool current_view, double duration)
@ -275,8 +247,8 @@ FGTileMgr::loadTileModel(const string& modelPath, bool cacheModel)
new FGNasalModelData);
else
result=
SGModelLib::loadPagedModel(fullPath.str(), globals->get_props(),
new FGNasalModelData);
SGModelLib::loadDeferredModel(fullPath.str(), globals->get_props(),
new FGNasalModelData);
} catch (const sg_io_exception& exc) {
string m(exc.getMessage());
m += " ";

View file

@ -31,8 +31,6 @@
#include <simgear/scene/tgdb/TileEntry.hxx>
#include <simgear/scene/tgdb/TileCache.hxx>
class SGReaderWriterBTGOptions;
namespace osg
{
class Node;
@ -41,6 +39,7 @@ class Node;
namespace simgear
{
class SGTerraSync;
class SGReaderWriterOptions;
}
class FGTileMgr : public SGSubsystem, public simgear::ModelLoadHelper {
@ -65,7 +64,7 @@ private:
SGBucket previous_bucket;
SGBucket current_bucket;
SGBucket pending;
osg::ref_ptr<SGReaderWriterBTGOptions> _options;
osg::ref_ptr<simgear::SGReaderWriterOptions> _options;
// x and y distance of tiles to load/draw
float vis;
@ -86,10 +85,9 @@ private:
// internal function, do not call directly.)
void update_queues();
static void refresh_tile(void* tileMgr, long tileIndex);
SGPropertyNode* _visibilityMeters;
SGPropertyChangeListener* _propListener;
SGPropertyNode_ptr _randomObjects;
SGPropertyNode_ptr _randomVegetation;
SGPropertyNode_ptr _maxTileRangeM;
public:
@ -103,9 +101,6 @@ public:
virtual void update(double dt);
// update loader configuration options
void configChanged();
int schedule_tiles_at(const SGGeod& location, double rangeM);

View file

@ -20,6 +20,10 @@
//
// $Id$
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <Main/globals.hxx>
#include <sstream>
#include <simgear/compiler.h>

View file

@ -3,6 +3,10 @@
//
// This file is in the Public Domain and comes with no warranty.
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "static.hxx"
#include <string>

View file

@ -102,6 +102,7 @@ void TimeManager::init()
// frame-rate / worst-case latency / update-rate counters
_frameRate = fgGetNode("/sim/frame-rate", true);
_frameLatency = fgGetNode("/sim/frame-latency-max-ms", true);
_frameRateWorst = fgGetNode("/sim/frame-rate-worst", true);
_lastFrameTime = 0;
_frameLatencyMax = 0.0;
_frameCount = 0;
@ -267,6 +268,8 @@ void TimeManager::computeFrameRate()
if ((_impl->get_cur_time() != _lastFrameTime)) {
_frameRate->setIntValue(_frameCount);
_frameLatency->setDoubleValue(_frameLatencyMax*1000);
if (_frameLatencyMax>0)
_frameRateWorst->setIntValue(1/_frameLatencyMax);
_frameCount = 0;
_frameLatencyMax = 0.0;
}
@ -331,7 +334,7 @@ void TimeManager::setTimeOffset(const std::string& offset_type, long int offset)
} else if ( offset_type == "noon" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time, lon, lat, 0.0, true );
} else if ( offset_type == "afternoon" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time, lon, lat, 60.0, false );
warp = fgTimeSecondsUntilSunAngle( cur_time, lon, lat, 75.0, false );
} else if ( offset_type == "dusk" ) {
warp = fgTimeSecondsUntilSunAngle( cur_time, lon, lat, 90.0, false );
} else if ( offset_type == "evening" ) {

View file

@ -82,6 +82,7 @@ private:
// frame-rate / worst-case latency / update-rate counters
SGPropertyNode_ptr _frameRate;
SGPropertyNode_ptr _frameRateWorst;
SGPropertyNode_ptr _frameLatency;
time_t _lastFrameTime;
double _frameLatencyMax;

View file

@ -149,6 +149,7 @@ void FGLight::bind () {
prop->tie("/rendering/scene/overcast",SGRawValuePointer<float>(&_overcast));
_sunAngleRad = prop->getNode("/sim/time/sun-angle-rad", true);
_sunAngleRad->setDoubleValue(_sun_angle);
// Read Only
prop->tie("/rendering/scene/ambient/red",SGRawValuePointer<float>(&_scene_ambient[0]));
@ -290,6 +291,8 @@ void FGLight::update_sky_color () {
_scene_ambient[3] = 1.0;
gamma_correct_rgb( _scene_ambient.data() );
SGSky* thesky = globals->get_renderer()->getSky();
SGVec4f color = thesky->get_scene_color();
_scene_diffuse[0] = color[0] * diffuse;
_scene_diffuse[1] = color[1] * diffuse;
@ -361,6 +364,7 @@ void FGLight::update_adj_fog_color () {
// revert to unmodified values before using them.
//
SGSky* thesky = globals->get_renderer()->getSky();
SGVec4f color = thesky->get_scene_color();
gamma_restore_rgb( _fog_color.data(), gamma );

View file

@ -228,7 +228,7 @@ bool FGAISchedule::update(time_t now, const SGVec3d& userCart)
if (AIManagerRef) {
// Check if this aircraft has been released.
FGTrafficManager *tmgr = (FGTrafficManager *) globals->get_subsystem("Traffic Manager");
FGTrafficManager *tmgr = (FGTrafficManager *) globals->get_subsystem("traffic-manager");
if (tmgr->isReleased(AIManagerRef)) {
AIManagerRef = 0;
} else {
@ -347,7 +347,7 @@ bool FGAISchedule::createAIAircraft(FGScheduledFlight* flight, double speedKnots
airline);
if (fp->isValidPlan()) {
aircraft->SetFlightPlan(fp);
FGAIManager* aimgr = (FGAIManager *) globals-> get_subsystem("ai_model");
FGAIManager* aimgr = (FGAIManager *) globals-> get_subsystem("ai-model");
aimgr->attach(aircraft);
AIManagerRef = aircraft->getID();
return true;
@ -465,7 +465,7 @@ FGScheduledFlight* FGAISchedule::findAvailableFlight (const string &currentDesti
{
time_t now = time(NULL) + fgGetLong("/sim/time/warp");
FGTrafficManager *tmgr = (FGTrafficManager *) globals->get_subsystem("Traffic Manager");
FGTrafficManager *tmgr = (FGTrafficManager *) globals->get_subsystem("traffic-manager");
FGScheduledFlightVecIterator fltBegin, fltEnd;
fltBegin = tmgr->getFirstFlight(req);
fltEnd = tmgr->getLastFlight(req);

View file

@ -22,11 +22,16 @@
#include <windows.h>
#endif
#include <map>
#include <algorithm>
#include <plib/fnt.h>
#include <plib/pu.h>
#include "ApplicationProperties.hxx"
#include "FGFontCache.hxx"
////////////////////////////////////////////////////////////////////////
// FGFontCache class.
////////////////////////////////////////////////////////////////////////
@ -68,6 +73,14 @@ const GuiFont guifonts[] = {
const GuiFont* guifontsEnd = &guifonts[sizeof(guifonts)/ sizeof(guifonts[0])];
}
FGFontCache::fnt::~fnt()
{
if (texfont) {
delete pufont;
delete texfont;
}
}
FGFontCache::FGFontCache() :
_initialized(false)
{

View file

@ -14,10 +14,16 @@
//
#ifndef __FGFONTCACHE_HXX
#define __FGFONTCACHE_HXX
#include <simgear/math/SGMath.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include <plib/pu.h>
// forward declare only!
class puFont;
class fntTexFont;
/**
* A class to keep all fonts available for future use.
* This also assures a font isn't resident more than once.
@ -47,7 +53,7 @@ private:
};
struct fnt {
fnt(puFont *pu = 0) : pufont(pu), texfont(0) {}
~fnt() { if (texfont) { delete pufont; delete texfont; } }
~fnt();
// Font used by plib GUI code
puFont *pufont;
// TXF font

View file

@ -32,6 +32,8 @@
#include <simgear/io/sg_socket.hxx>
#include <simgear/misc/strutils.hxx>
using namespace std;
class PropertySetter {
public:
PropertySetter( SGPropertyNode_ptr node ) : _node(node) {}
@ -123,15 +125,25 @@ FGPanelProtocol::~FGPanelProtocol()
void FGPanelProtocol::update( double dt )
{
char buf[8192];
char buf[2][8192];
if( io == NULL )
return;
int length = io->readline( buf, sizeof(buf)-1 );
buf[sizeof(buf)-1] = 0;
if ( length > 0 ) {
vector<string> tokens = simgear::strutils::split( buf, "," );
// read all available lines, keep last one
int Page = 0;
bool HaveData = false;
while ( io->readline( buf[Page], sizeof(buf[Page])-1 ) > 0 )
{
HaveData = true;
Page ^= 1;
}
if ( HaveData ) {
// process most recent line of data
Page ^= 1;
buf[Page][sizeof(buf[Page])-1] = 0;
vector<string> tokens = simgear::strutils::split( buf[Page], "," );
for( vector<string>::size_type i = 0; i < tokens.size(); i++ ) {
if( i < propertySetterVector.size() )
propertySetterVector[i]->setValue( tokens[i].c_str() );

View file

@ -41,7 +41,7 @@
#include "FGTextureLoaderInterface.hxx"
class FGPanelInstrument;
using namespace std;
////////////////////////////////////////////////////////////////////////
// Texture management.

Some files were not shown because too many files have changed in this diff Show more