Compare commits

...

220 Commits

Author SHA1 Message Date
durk
c044d711ef Documentation update regarding OpenAL and OSG. 2008-12-20 09:10:43 +00:00
curt
f2132f6a7d Attempt to sort out the version number mess in preparation for a 1.9.0 release. 2008-12-19 20:39:59 +00:00
fredb
69871b15ff Stuart Buchanan :
Attached is yet another 3D clouds patch, to fix the following:
1) The 3D clouds were not modified by the cloud coverage, due to some problems with osg::Switch
2) METAR changes to cloud coverage were not obeyed.
3) Making changes via the Cloud dialog had no effect unless 3D clouds were toggled.
4) Cloud cover was too sparse.
5) 3D Stratus clouds caused performance issues on some hardware (fixed by removing 3D stratus from cloudlayers.xml - it will now be a 2D layer).
2008-12-19 07:39:09 +00:00
mfranz
f4ec02a592 James TURNER: make the index of the current waypoint available 2008-12-18 22:51:58 +00:00
fredb
53f7743678 Stuart :
the 3D clouds now respect changes to the environment caused by updated METAR etc.

It also increases the AlphaFunc as suggested by Tim.
2008-12-14 18:47:30 +00:00
fredb
15893bc558 Csaba/Jester : fix a problem with tex transform animation 2008-12-12 20:02:44 +00:00
fredb
73b974f1b5 Csaba/Jester : fix a problem with material animation 2008-12-12 19:57:25 +00:00
fredb
0e7bdc208b Print the name of the file generating an OpenAL error 2008-12-12 07:41:44 +00:00
fredb
e0a07b7a92 Stuart :
- Removes the cloud type re-use code - I think they aren't worth the graphical artefacts that they cause in light of Tim's improvements
- Changes the transparency of the clouds. Previously, the clouds were transparent at 0m distance, opaque at 200m, then gradually more transparent to the fog limits. This meant they were generally quite transparent. Now, they are opaque from 200m to 15km, then become transparent at 20km. A side effect of this is that the current textures could probably benefit from being made slightly transparent to improve the blending of the sprites against each other.
2008-12-11 08:24:35 +00:00
fredb
4da58e8846 Update MSVC 7.1 projects. Add Boost 2008-12-11 08:23:37 +00:00
timoore
966b9e5c2b Use a singleton Fog attribute for all 3D clouds.
Don't update this Fog with any kind of update callback; instead, update from
the sky repaint method.
2008-12-10 22:39:48 +00:00
timoore
1625192c81 Use StateAttributeFactory for CullFace and ShadeModel attributes 2008-12-10 22:39:23 +00:00
timoore
c5e8c6603c Use Boost singleton template for our singletons 2008-12-10 22:39:02 +00:00
timoore
37e541d326 Render cloud layers with face culling
Also, allow definition of colors for the cloud layer corners for debugging.
2008-12-10 22:38:34 +00:00
timoore
862a827fe6 Add cullFaceFront as a state attribute to the StateAttributeFactory 2008-12-10 22:38:14 +00:00
timoore
b96c5c9e4b Render sky with depth test off.
Also, don't set BACKGROUND_BIT for cloud layers.
2008-12-10 22:37:52 +00:00
durk
f7e91f1f08 Finalizing the preparation of SimGear-1.99.5-rc2. 2008-12-10 18:20:36 +00:00
fredb
2d77178ba3 Stuart Buchanan :
- Replaces simple shader attributes with vectors (this was missed out of the last patch by mistake)
- Includes Yon's Fog update code (Thanks!)
- Fixes a bug since 1.0 where --enable-real-weather-fetch stopped the other weather scenarios from working.
2008-12-06 23:02:42 +00:00
fredb
b38e6d8bf3 Ugly hack to fix a memory corruption problem 2008-12-06 23:01:24 +00:00
fredb
b601cdb6a5 Stuart Buchanan :
This provides the following enhancements & bug fixes
- Fix the chequer-board bug.
- Add proper cloud coverage function - so scattered clouds are now truly scattered.
- Add real-time control for visibility range.
- Use a limited set of clouds rather than generating a completely new Geode for each cloud. This saves sorting and display time.
- Add controls to Rendering dialog to allow fine-tuning of the number of sprites, cloud visibility and the number of different types of cloud.
- Add some variance to the sort back-off to avoid all clouds being sorted at the same time.
- Pack attributes into vectors for performance
- Re-order the cloud type determination code so that if a cloud layer could either be stratus or cumulus, cumulus is used.
- Lowered the cloud level in the standard cloud configuration slightly so a cumulus layer is generated rather than stratus.

These last two mean that you should see some 3D cumuli if disabling real weather fetch.

My thanks to Yon Uriarte for his help with performance work.
2008-12-04 20:56:03 +00:00
fredb
2803154213 Stuart:
Attached is another clouds patch. This does the following:
1) Puts the 3D clouds in a cloud rendering bin, to reduce the transparent edge problem. Viewing 3d clouds against a 2D layer _above_ it now blends correctly. There is still a problem when viewing a layer below the 3d clouds, and I'm not sure if/how I'll manage to solve that. Thanks to Tim for pointing me at the correct code (again).
2) Performance improvement by calculating the Bounding box when the cloud is generated rather than ever time it is requested.
2008-11-30 23:06:18 +00:00
timoore
ae5297e6d7 logstream improvements from Yon Uriarte
Avoid descending into iostream when a message won't be logged.
2008-11-29 00:17:29 +00:00
fredb
fa7490fb38 Stuart:
> Something has changed in the environment manager which means that clouds
> generateion is now inconsistent. I'm still tracking it down, as my recent
> changes shouldn't have affected this.

Well, the cause was a bug in my code, but it didn't expose itself until we moved
to multiple cameras. The attached patch fixes the problem.

I've also put in a new heuristic to improve the frame-rate. Clouds that are already sorted
are likely to still be sorted in subsequent frames. Therefore I've put in a back-off
mechanism for the bubble-sort pass. This should mean that if you stay completely
stationary, once the clouds become sorted they will eventually only perform a
bubble sort pass every 128 frames.
2008-11-26 07:28:10 +00:00
timoore
bad80521a8 Track time in TileCache; assign new tiles the current time 2008-11-24 22:08:31 +00:00
fredb
8303e30033 Stuart :
> Warning: detected OpenGL error 'valeur non valide' after RenderBin::draw(,)

Fixed in the patch below. For some reason the shader didn't like index 16 being used...

The patch also fixes the chequer-board effect that was causing very sparse cloud cover.
2008-11-24 20:26:12 +00:00
fredb
27de1e271e Stuart Buchanan :
Attached is a small patch for 3D clouds.
It provide the following:
1) Proper spherical distribution of sprites (previously they were distributed cylindrically - whoops)
2) Better shading, so the bottom of the cloud is darker than the top.
3) Fixed a couple of texture sizing bugs.
2008-11-23 12:14:56 +00:00
timoore
98cecfe940 Templates for interacting with OSG objects 2008-11-21 14:48:15 +00:00
timoore
2e65538fb5 Template functions and overloaded functions for accessing property values.
These are useful for writing templates that manipulate properties.
2008-11-18 22:16:58 +00:00
curt
e6371cbf9c Manuel Massing:
Attached is a small fix for the sorting in CloudShaderGeometry.cxx.
I think the sorting problem stems from the osg idiosyncracy
to store transposed matrices...so the intuitive

       osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f);

needs to be replaced with...

       osg::Vec4f p = vm.preMult(osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f);

The patch also optimizes the distance calculation - it evaluates the distances
in model space instead of eye space, which reduces computation to a dot-
product instead of a matrix multiplication.
2008-11-09 15:39:54 +00:00
fredb
0b8b6ac56a Stuart Buchanan :
It fixes the following issues (to a greater or lesser extent):
1) Performance. Quad trees used to improve culling, and the sprites are placed on the surface of a sphere rather than
randomly throughout the cloud, requiring fewer textures. This saves about 5-10fps on my machine.
2) Disabled 3D clouds have no performance impact. Previously they were still in the scenegraph. Now they are removed.
3) Clouds are now loaded on start-up, and don't require the scenario to be changed, they also work with METAR.
4) The cloud field is shifted as you travel. There's a small bug in that the clouds "jump" as you reach the edge of the field.
5) Iterative sorting of sprites. This doesn't appear to solve the alpha blending problem completely, but may help a bit.
2008-11-06 21:58:07 +00:00
timoore
cc17cc4af7 Respect precipitation-enable property
From Csaba Halász
2008-10-31 09:46:23 +00:00
timoore
6afd7e1a38 enable world coordinate particle fix 2008-10-30 23:51:41 +00:00
curt
91e22c1fb3 Tidy up for a source code "snapshot" release. 2008-10-30 17:51:00 +00:00
fredb
ad6129816d 3D clouds from Stuart Buchanan. Need a recent driver update, --enable-clouds3d option and a Weather Scenario to show up 2008-10-26 09:37:13 +00:00
curt
409db9d7ef Fix a few spelling errors. 2008-10-23 18:46:55 +00:00
mfranz
2ccd58e917 fix regression: sgLoad3DModel_internal should not make assumptions
about the type of SGModelData. This *can* have to do with Nasal,
but doesn't have to. That's entirely that class instance's business.
2008-10-18 18:44:36 +00:00
mfranz
7585ad430a add global switch for particle systems 2008-10-17 21:15:58 +00:00
mfranz
c105c5a449 allow to modify the XML animation config of a loaded submodel by
defining an <overlay> branch, which is copied over the submodel's
properties before the animations are evaluated
2008-10-14 13:01:01 +00:00
mfranz
54065b59a1 Move omit-node part from startElement to endElement to allow nodes
of this type to have children. We have to save the omit state on the
stack for that.
2008-10-14 11:03:39 +00:00
durk
f9250ae522 Syd Adams: Replace rgb with png. 2008-10-14 05:04:43 +00:00
mfranz
2f8621ed3d s/multiplayer/multiplay/, as this seems to be the slightly more
official version (--multiplay option, /sim/multiplay/ properties etc.)
2008-10-10 09:48:03 +00:00
mfranz
98a3e7cffa if a model XML file contains a <multiplayer> block, copy its contents
to the model's property root (/ai/models/multiplayer[*])
2008-10-09 22:20:33 +00:00
andy
d7f2966216 Yeah, I really shouldn't be in the lexer 2008-09-30 21:52:44 +00:00
andy
8687b214e7 Another lexer fix 2008-09-30 20:19:01 +00:00
andy
f5f1f0da8e Fix broken lex.c checkin 2008-09-30 19:06:34 +00:00
andy
818359bfd0 Fixes for bugs shaken out in the recent push: die properly for nil
indexes in slices.  Fix string conversion issue with bare "+" and "-".
Fix lexing of exponent expressions such that "1e" is not a number.
2008-09-30 16:48:36 +00:00
fredb
8174005ac8 MINGW patch by Csaba Halasz 2008-09-28 08:11:10 +00:00
andy
0180cae8c3 Fix parsing for degenerate cases like a[,] a[:] and {:}. The slicing syntax exposed the low-level generators to some new cases. 2008-09-26 19:18:19 +00:00
andy
dd1ea541ec Sync with Nasal upstream (Melchior already had a chance to test this,
so hopefully not too much breaks).  New syntax features:

1. Call-by-name function arguments.  You can specify a hash literal in
place of ordered function arguments, and it will become the local
variable namespace for the called function, making functions with many
arguments more readable.  Ex:

   view_manager.lookat(heading:180, pitch:20, roll:0, x:X0, y:Y0, z:Z0,
                       time:now, fov:55);

Declared arguments are checked and defaulted as would be expected:
it's an error if you fail to pass a value for an undefaulted argument,
missing default arguments get assigned, and any rest parameter
(e.g. "func(a,b=2,rest...){}") will be assigned with an empty vector.

2. Vector slicing.  Vectors (lists) can now be created from others
using an ordered list of indexes and ranges.  For example:

   var v1 = ["a","b","c","d","e"]

   var v2 = v1[3,2];   # == ["d","c"];
   var v3 = v1[1:3];   # i.e. range from 1 to 3: ["b","c","d"];
   var v4 = v1[1:];    # no value means "to the end": ["b","c","d","e"]
   var i = 2;
   var v5 = v1[i];     # runtime expressions are fine: ["c"]
   var v6 = v1[-2,-1]; # negative indexes are relative to end: ["d","e"]

The range values can be computed at runtime (e.g. i=1; v5=v1[i:]).
Negative indices work the same way the do with the vector functions
(-1 is the last element, -2 is 2nd to last, etc...).

3. Multi-assignment expressions.  You can assign more than one
variable (or lvalue) at a time by putting them in a parenthesized
list:

   (var a, var b) = (1, 2);
   var (a, b) = (1, 2);               # Shorthand for (var a, var b)
   (var a, v[0], obj.field) = (1,2,3) # Any assignable lvalue works

   var color = [1, 1, 0.5];
   var (r, g, b) = color;  # works with runtime vectors too
2008-09-26 18:22:12 +00:00
timoore
19aac5b14c Keep non-local particles in a Z-up frame that is periodically moved.
This eliminates jitter and other rendering problems.
For the moment this is dependent on an osg fix.

Also, don't read wind properties from FlightGear; provide a mechanism
for fg to set the wind.
2008-09-11 10:19:05 +00:00
ehofman
f3f8a211cd Make sure the compiler is aware that SGModelData a child of osg::Referenced, now gcc-3.3 will compile. 2008-09-04 08:52:47 +00:00
fredb
3edcbc3b99 Use a more relevant library name 2008-08-31 18:39:49 +00:00
fredb
5a1cc8745e Update version 2008-08-31 18:35:02 +00:00
timoore
12495547c4 Don't use osgDB::SharedStateManager::share in SGLoadTexture2D
It is not safe to call this function from the database pager thread;
in any event, state sets and textures created in the database pager
will get passed through the SharedStateManager anyway.
2008-08-29 07:39:05 +00:00
curt
ff654ab094 - Update SimGear.dsp
- Assign an arbitrary prerelease version number
- Fix a "make dist" problem.
2008-08-28 17:52:43 +00:00
andy
e55f55cd3e Fix typing error with fgetc in readln(). On most boxes, this would
cause a spurious EOF when there was a 0xff in the stream.  But on PPC,
char is unsigned (for reasons known only to IBM) and it would loop
forever.
2008-08-25 16:53:34 +00:00
timoore
29aad066f0 pointers in Particles object should be ref_ptr 2008-08-11 08:32:13 +00:00
timoore
74d3bdc68c Return eof after a number of reptetitions of file input. 2008-08-07 22:24:01 +00:00
fredb
7f9b3a8666 Update MSVC 7.1 projects - Adapt to OSG 2.6.0-rc1 : location of header files should now be searched in the install directory, here ..\..\..\install\msvc71\OpenSceneGraph\include 2008-08-02 11:31:47 +00:00
ehofman
426f6de16f final fixes for SG_USING_STD removal 2008-07-29 08:25:17 +00:00
timoore
cf19b81dd4 forward declare osg::DrawElementsUShort for real 2008-07-29 02:54:48 +00:00
ehofman
d4c7e95092 Replace SG_USE_STD() by using std:: 2008-07-28 07:52:13 +00:00
fredb
aa07b5bdd8 GL/wgl.h never existed, and a glx equivalent is not needed 2008-07-27 18:04:13 +00:00
ehofman
c7cbb22667 - remove the SG_GLxxxx_H #defines, since OSG provides its own versions
- this exposed a bizarre issue on Mac where dragging in <AGL/agl.h> in
   extensions.hxx was pulling in all of Carbon to the global namespace
   - very scary. As a result, I now need to explicitly include CoreFoundation
   in fg_init.cxx.
 - change SG_USING_STD(x) to using std::x

Issues:

 - the logic for X11 and Win32 in RenderTexture and extensions is tortured,
   please see if you agree I got all the ifdefs correct.
2008-07-27 16:10:36 +00:00
fredb
ff72b68731 Remove unneeded inclusions of windows.h, GL.h and GLU.H 2008-07-27 15:15:33 +00:00
fredb
433be0e46b Maybe a more portable way to do it 2008-07-25 21:33:54 +00:00
fredb
900607034e Compile again with MSVC 2008-07-25 21:27:46 +00:00
ehofman
733e6fa14f Reduce compiler.h to almost nothing (but it's worth keeping around I think, for
the MSVC and MipsPro warning stuff).

As a result of this patch, simgear/sg_traits.h can be deleted. So can SGCMath.h,
but I'll do that separately.

There is one more 'mechanical' change to come - getting rid of SG_USING_STD(X),
but I want to keep that separate from everything else. (There's another mechnica
l change, replacing <math.h> with <cmath> and so on *everywhere*, but one step a
t a time)
2008-07-25 18:35:40 +00:00
ehofman
cd72eb20c6 Attached patches remove BORLANDC, and hence SG_MATH_EXCEPTION_CLASH and SG_INCOM
PLETE_FUNCTIONAL from SimGear and FlightGear.

As a result, SG_HAVE_STD_INCLUDES is now *always* set, so I will get the boring
fixes for that done, but separately. I'm still auditing the other things in comp
ilers.h - there's a lot that can die now BORLAND is gone.
2008-07-25 10:39:20 +00:00
ehofman
d754e616a5 remove a workaround for the C++ / stdlibary bug which existed aeons ago on Mac. 2008-07-25 08:34:15 +00:00
ehofman
d613e0a488 Patch to remove macintosh and MWERKS from Simgear. 2008-07-24 19:16:50 +00:00
timoore
942fa53ed9 Add repeat option to SGFile.
This supports auto-looping over a playback file, for demos and such.
2008-07-19 16:01:20 +00:00
timoore
1729841083 Eliminate empty default constructor for SGReaderWriterBTGOptions 2008-07-19 16:00:58 +00:00
mfranz
315d83bc88 s/getChild/getNode/ (otherwise "start/size" wouldn't work) 2008-07-12 15:31:29 +00:00
mfranz
223aa0ccd5 - XML interface changes:
* condition at top level
  * <start|end>/<color|size> hierarchy
  * wind/gravity -> bool
  * rename some properties (rotspeed -> rotation-speed, etc.)
  * unit suffixes
- remove redundant code
- warnings--
2008-07-12 14:06:11 +00:00
mfranz
38494a48d8 fix SGPropertyNode::LAST_USED_ATTRIBUTE 2008-07-10 10:33:32 +00:00
mfranz
38456bddb5 write-protection warning: use simplified path 2008-07-09 17:31:55 +00:00
mfranz
b8a12b0e5b let readProperties() refuse to overwrite write-proteced properties 2008-07-09 16:17:52 +00:00
mfranz
2d37c0aa42 remove redundant #defines (they are already in compiler.h) 2008-06-22 18:07:50 +00:00
timoore
c8c693db53 From Benoit Laniel: replace SG threading constructs with those from OpenThreads
Also, move any static local mutexes up to global level.
2008-06-12 08:14:40 +00:00
fredb
cdff0fceea Update MSVC 7.1 projects 2008-06-08 16:45:13 +00:00
mfranz
3b6f47aea1 warnings-- 2008-06-07 14:45:22 +00:00
timoore
7bc37651c3 add OSGVersion.hxx to VC7.1 project file 2008-06-02 20:26:07 +00:00
timoore
4fe43c3e50 OSG DatabasePager interface change in 2.5.1
Move OSG version macro from FlightGear to simgear
2008-06-02 20:22:16 +00:00
timoore
0826b7c3ca Replace header files istream and ostream with iosfwd 2008-06-02 20:21:50 +00:00
timoore
d219c5c4c6 Don't include <iostream> and "using" declarations in header files
<iostream> sucks in expensive initialization of the standard streams
and isn't appropriate in a header file. Use <istream> and <ostream>
instead.

using declarations should never appear at global scope in a header
file; source files get to decide what they want to use in their
namespace.
2008-06-02 20:21:27 +00:00
fredb
1a498348ee Fix non threadsafe code 2008-06-01 17:25:05 +00:00
fredb
c6b03555f7 Report abnormal condition 2008-05-31 12:08:17 +00:00
fredb
bb1a270532 Update MSVC 7.1 projects 2008-05-31 12:06:30 +00:00
fredb
69ea4b846a Fix a problem in loading models with paged LOD in some circunstances ( debug with MSVC for instance ) 2008-05-31 12:05:11 +00:00
fredb
373a0e4a7d Use bool instead of int to represent boolean values 2008-05-31 10:02:43 +00:00
mfranz
f4f5ab2392 xmlsound: warning-- 2008-05-21 14:51:39 +00:00
mfranz
b20b3229bf add <delay-sec> parameter that defines how many seconds after triggering
the sound should be played (default: 0)
2008-05-21 14:47:06 +00:00
mfranz
77fb93bb61 update library version requirements 2008-05-19 15:17:55 +00:00
fredb
ec72b46dcb Win32 fix 2008-05-15 06:19:15 +00:00
timoore
367f1813de sg: move most scenery-related code to simgear
From Till Busch
2008-05-14 22:07:50 +00:00
mfranz
74116057a7 Till BUSCH: enable HOT intersection tests on random buildings 2008-05-01 12:21:52 +00:00
mfranz
9deb40216e Nicolas: let SGPath::create_dir() return success/failure (for screenshot) 2008-04-26 15:25:29 +00:00
mfranz
daef76ec0b Till BUSCH:
"tim recently noticed the database pager was repeatedly loading and unloading
the same objects. he also tracked down the problem to missing bounding sphere
information in osgDB::PagedLOD. this is a simplicistic approach to fix this:
SGPagedLOD will now remember whatever value it sees for getBound() after
loading a child. this patch will make database pager run much calmer."
2008-04-25 08:41:29 +00:00
timoore
569a29fbbc Fix new livery code
It turns out that the database pager causes the texture image to be
unloaded after it is applied, so the image and its file name may not
be available for doing the livery substitution. Ask a work around we
set the name of the texture to its file name.
2008-04-24 22:06:06 +00:00
fredb
0c06bfd3d9 Update MSVC 7.1 projects 2008-04-23 22:09:23 +00:00
timoore
8f46f2cac8 Rewrite livery texture replacement to copy StateSet objects
Also, add a NodeAndDrawableVisitor that descends into osg::Drawable.

That motivation for this is that it's a bad idea to modify state sets
that the osgDB::SharedStateManager might be keeping.
2008-04-23 18:13:50 +00:00
mfranz
8f48515b80 Till BUSCH:
this is a small (-1/+3) patch to fix pick animations on scenery objects.
since picking apparently doesn't care for polygon offsets, the objects
got into the picklist in the wrong way. now, no matter if the "highlight
group" or the "normal group" gets hit first, the callback will fire.
2008-04-23 12:28:45 +00:00
timoore
c7dab4abea rewrite of sky dome code
Add more points to the dome, giving it a dome shape rather than a
dunce cap shape.

Represent as OpenGL DrawElements instead of as triangle strips.

Only calculate have the sky colors and reflect those across the dome.
2008-04-14 21:44:21 +00:00
fredb
5e4c4725bc Update MSVC 7.1 projects 2008-04-14 06:27:26 +00:00
timoore
9861d74221 Fixes for compiling with gcc 4.3
Include standard header files and qualify with std:: where needed.

Add "const" to various char parameters and variables.
2008-04-13 21:11:44 +00:00
fredb
bb3b606820 Allows to load submodels with path relative to current model path.
Submodel path must be prefixed by ./ otherwise path is relative to fg_root ( current behavior )
2008-04-02 22:25:12 +00:00
timoore
09fb51189e Change the tile light group node mask to traverse VASI lights too.
The change to set the light group node mask to LIGHTS_BITS caused
VASI/PAPI lights to not be displayed during the day. This patch fixes
that and optimizes VASI creation a bit.
2008-03-24 21:41:30 +00:00
fredb
bd19899bbc Update MSVC 7.1 projects 2008-03-22 11:39:01 +00:00
fredb
b69753fb76 Win32 fix 2008-03-22 11:38:50 +00:00
timoore
9dc1b5f6f5 model paging patch from Till Busch
Comments from Till:
I started the project at the end of february with a simple idea: move all
3d-model loading to the DatabasePager-thread. my first attempts looked
promising, though they were a little too optimistic (or naive?). the patch
has evolved a lot since.

currently it does the following things:
1. revive SGModelLib, move functions for xml-model-loading there

2. replace all calls to sgLoad3dModel with calls to either
SGModelLib::loadModel() or SGModelLib::loadPagedModel()
almost all models will be loaded by the DatabasePager. the few exceptions are:
your own plane, shared models in scenery, random objects, AIBallistic models.

3. simplify mode-loading functions (avoid passing around fg_root)

4. avoid supurious MatrixTransform nodes in loaded models

5. fix some memory leaks
2008-03-22 09:30:26 +00:00
mfranz
55c1ac36e3 - warnings--
- make one-shot sounds subject to volume and pitch control (To get
  constant volume/pitch during the whole lifetime, just *configure*
  the sound that way.)
2008-03-20 17:20:54 +00:00
timoore
c12e6cdc09 rationalize node masks a bit 2008-03-17 08:46:23 +00:00
curt
85562e8b95 argh, missed 1.8.4 in one spot. 2008-03-15 16:33:49 +00:00
curt
fd34cc0b87 Simgear also enforces plib-1.8.5 in order to build. 2008-03-15 16:32:36 +00:00
timoore
6322393782 From Till Busch: use install -p if possible 2008-03-11 13:44:43 +00:00
fredb
1f9e954610 Update MSVC 7.1 projects 2008-03-09 22:09:52 +00:00
mfranz
6491746809 use new arrow shortcuts for compatibility reasons (will be removed later) 2008-03-04 11:48:51 +00:00
timoore
6d2f1ff81e cleanup of precipitation contribution
Reindent everything to Stroustrup style and make member variable style
consistent.

Remove unused header files.

SGPrecipitation is now a subclass of osg::Referenced.

Initialize snow and ice intensity to 0 directly. The methods that set
the intensities change the value slowly and so don't work when the
initial value is garbage.
2008-03-04 08:58:33 +00:00
timoore
c724e5fb20 precipitation effects from Nicolas Vivien 2008-03-04 08:54:00 +00:00
timoore
600726976c Add methods to SGGeod to return OSG Matrix objects for local frames.
Methods have been added for Z down (simulation) and Z up frames.
2008-03-04 08:53:27 +00:00
fredb
49b5c2058d Initialize variables before using them 2008-03-02 16:49:07 +00:00
durk
21df21b144 Olaf Flebbe: Micro update to the MSVC8 Project files. 2008-03-02 16:09:57 +00:00
fredb
620e71e800 Update MSVC 7.1 projects 2008-02-28 21:25:44 +00:00
mfranz
db2216848d don't reset visibility modifier in the M5SM case 2008-02-20 23:36:27 +00:00
mfranz
cfffe91ed5 Syd ADAMS: remove season suffix, this is now done via <condition>s 2008-02-16 22:09:40 +00:00
mfranz
a95aed1047 remove getRootNode(), as this resets the model root 2008-02-16 17:01:01 +00:00
mfranz
2883a36c76 Csaba HALASZ: implement conditional (e.g. seasonal) texture loading at startup 2008-02-15 17:54:01 +00:00
timoore
ac4245013f Cleanup of particles contribution
Put particles classes inside simgear namespace

Refactored some redundant code

Reworked local frame math to use OSG math classes as much as possible
2008-02-15 06:44:24 +00:00
timoore
b09e484492 particles from Tiago_G 2008-02-15 06:44:05 +00:00
timoore
dc63ddb010 Small cleanup of tree shader 2008-02-07 23:01:32 +00:00
timoore
09778a8eab Minor cleanup of Stuart Buchanan's tree patch.
Separate random objects and random trees for real.
2008-02-07 23:01:16 +00:00
timoore
8cbe9f1bd0 Second trees patch from Stuart Buchanan
Adds random variation of tree texture maps
2008-02-07 23:00:23 +00:00
timoore
be61689458 Cleanup and performance tuning of the random trees code.
The QuadTreeBuilder class was completely revamped as a templated class
to support flexible creation of scene graph quad trees, and a major
bug was fixed as well. Now it actually generates quadtrees instead of
some weird striped thing.

One StateSet is shared among all the "forests." The trees are drawn
after normal terrain objects to minimize some of the transparency
related artifacts.

Lighting was implemented in the ShaderGeometry shader (for both
polygon sides). Ambient-diffuse values for trees are hard-coded in
TreeBin.cxx.

DotOsg wrappers were added for ShaderGeometry so it can be output in
the scene graph dump.
2008-02-02 23:01:27 +00:00
timoore
4b63bc051e Random trees from Stuart Buchanan
Stuart's new file SGTreeBin.hxx has been split into 4 files:
TreeBin.[ch]xx and ShaderGeometry.[ch]xx.
2008-02-02 23:01:05 +00:00
timoore
a098ba5e79 Memory leak fixes from Till Busch 2008-01-24 23:05:18 +00:00
fredb
edee4b3fe5 Update MSVC 7.1 projects 2008-01-17 21:41:48 +00:00
timoore
0c9013e60e fix memory leaks in random object code
Don't allocate mt structures (for the random number generator) on the heap.
2008-01-17 08:28:15 +00:00
fredb
701c4bcf27 Avoid spitting gazillion 'Cannot find image file "" ' message on the console while loading random objects 2008-01-12 08:50:21 +00:00
frohlich
22f2fac56b Modified Files:
simgear/scene/model/animation.cxx:
	Change factor/offset order for texture animations.
	Fixes remaining bug with texture animations.
2008-01-07 22:05:48 +00:00
timoore
605125c0e7 Random object support from Stuart Buchanan
In addition to Stuart's changes, there's an independent quad tree
builder class for constructing loose quad trees from scene graph nodes.

Stuart also implemented changes to the random number generator suggested by
Andy Ross.
2008-01-06 15:04:43 +00:00
fredb
65d0ee126a Update MSVC 7.1 projects 2008-01-04 21:45:41 +00:00
fredb
4db6435090 Remove warnings 2008-01-04 21:45:14 +00:00
timoore
4383fd3c45 Give the sky a BACKGROUND_BIT nodemask
Add a MODEL_BIT and tag clouds with that.

Remove vestigial post_root from sky code.
2008-01-04 07:33:42 +00:00
timoore
b6be76b0ab background node mask 2008-01-04 07:33:23 +00:00
frohlich
92d8fa1193 Modified Files:
simgear/scene/model/SGClipGroup.cxx
	simgear/scene/model/SGClipGroup.hxx Update the clip group.
2007-12-31 15:49:01 +00:00
frohlich
9c51bf3edf Modified Files:
simgear/scene/model/animation.cxx: Create animation inputs if not
	already there. Fixes broken texture animations from past checkin.
2007-12-31 15:48:02 +00:00
frohlich
cf0e4e6f8c Modified Files:
Makefile.am SGPickCallback.hxx: add proirities for pick callbacks.
2007-12-26 19:19:51 +00:00
frohlich
c3719f35e3 Modified Files:
animation.cxx animation.hxx: Make use of the expression stuff.
	Factors out common code with other animations stuff in flightgear.
2007-12-26 19:12:04 +00:00
frohlich
0b1f074bcf Modified Files:
Makefile.am
Added Files:
	SGExpression.cxx SGExpression.hxx: Add not yet complete but already
	usable expression tree. Will be used with the panel code.
2007-12-26 19:10:40 +00:00
frohlich
7fe8514434 Modified Files:
scene/model/SGClipGroup.cxx: Oops, add missing simgear_config.h
2007-12-26 19:08:45 +00:00
frohlich
37c4dcf8ba Modified Files:
Makefile.am
Added Files:
	SGClipGroup.cxx SGClipGroup.hxx: Add helper group node for reuse
	of clipping planes. Will be used for the panel code.
2007-12-26 19:05:06 +00:00
frohlich
e33dd3c499 Modified Files:
simgear/props/props.hxx: Add a bunch of convinience functions.
2007-12-26 19:03:21 +00:00
timoore
94be52886e Pass ReaderWriter options to SGMaterialAnimation
It needs to grab the path list from options in order to support the texture
change animation.
2007-12-23 23:33:04 +00:00
timoore
6646aa5644 Fix tiny bugs in sun constructor and repaint code 2007-12-22 23:01:36 +00:00
timoore
d556eba296 Add StateAttributeFactory files to VS project file 2007-12-21 06:29:36 +00:00
timoore
a5b573b2d3 optimize groups from .AC file optimizer run 2007-12-21 06:25:40 +00:00
timoore
18d30ea8fa Repaint 2D cloud layers using texture combiner
Don't change the color in the cloud layer geometry
2007-12-21 06:25:13 +00:00
timoore
4324ffccf4 Fix cloud layer - point lights visibility issue
Move point lights to render bin 8, clouds to render bin 9. Turn on
AlphaFunc for cloud layers.

Create a StateAttributeFactory object to create and share common state
objects.
2007-12-21 06:24:53 +00:00
fredb
182ee9d7e4 Update MSVC 7.1 projects 2007-12-18 22:25:24 +00:00
timoore
68c1cfed46 Use node masks and shared state sets to manage ground lights
Do away with the switch in each terrain tile for the ground lights. They are
turned on by node masks now.

Share state sets among all the light nodes and manage the fog values through a
"GroundLightManager" instead of having separate state sets and callback
functions for each group in each tile.
2007-12-13 23:30:24 +00:00
timoore
1159784538 minor fix to ModelRegistry and syntax changes for Windows
Create the local path in the right order in OptionsPusher. When
OptionsPusher is used, put it inside a new code block so the order of
destruction with respect to the mutex on reader functions id clear.

Add #include <algorithm> to top of ModelRegistry.cxx.

Change include syntax in PathOptions.cxx
2007-12-11 11:07:21 +00:00
timoore
e683b5fdec Check for null options before changing path in registry 2007-12-10 08:30:43 +00:00
timoore
3c409c5070 Work around osg Registry path list problems
The OSG reader plugins overwrite the path list passed in options with the local
directory of the file being read, forcing you to set the path list in
the Registry. I think this a bug, but in the meantime here's a workaround.
2007-12-09 22:38:10 +00:00
timoore
4b7361dfe7 Add operator!= to SGBucket 2007-12-07 23:35:04 +00:00
timoore
037d5c11a5 Add option to SGLoadTexture2D to load dynamic textures 2007-12-07 09:13:34 +00:00
mfranz
95d857e091 - comparison: don't crash if second element is missing
- better messages ("panel"?!)
2007-12-06 17:57:41 +00:00
timoore
4efa087cd1 Don't modify OSG Registry with file path
To set a path when loading model files, use an osg ReaderWriter::Options object.

Put locks in ModelRegistry::readNode and ModelRegistry::readImage to avoid
conflicts when files are loaded from both the pager and the main thread.
2007-12-04 22:38:40 +00:00
fredb
60f0003436 Update MSVC 7.1 projects 2007-12-02 12:28:30 +00:00
timoore
fdb265cd6e Change the main ModelRegistry callback function to stash the substituted file in the cache. 2007-11-29 23:56:49 +00:00
timoore
34704a17f2 Avoid copying drawables and dirtying display lists.
For the alpha-test animation, use an OVERRIDE attribute on the state
set of the top level node instead of copying drawables and state sets
throughout the model.

As a temporary hack in the blend animation, don't use display lists in
the cloned drawables.

These changes are aimed at cutting down the number of display lists
that the pager needs to compile.
2007-11-29 23:56:31 +00:00
timoore
4a959ec2fd rewrite ModelRegistry callbacks as a template with pluggable policy classes
In a big effort to improve use of the object cache, provide a
ModelRegistryCallback template class with different policies for
substitution,  caching, optimization, etc.

Change SGTexDataVarianceVistor to make StateSets static too.
2007-11-29 23:56:09 +00:00
timoore
f182886fce Start of cleanup of scene graph node masks 2007-11-29 23:55:35 +00:00
timoore
2fbaddbecf Move SGReadFileCallback from model.cxx to public class ModelRegistry
Move SGReadFileCallback and all its help classes into a new
ModelRegistry class that also provides an interface to add custom
callbacks for specific file extensions. SGReaderWriterBTG uses that to
keep any further processing from being done on .btg files. Various
namespace-releated cleanup was done on this code too.
2007-11-29 23:55:01 +00:00
timoore
cafcecf03d StateSet optimizations
Use only one shared StateSet to control GL_NORMALIZE. This removes
thousands of state sets from the scene graph.

Fix a typo that was causing two copies of groundLights0 to be added to
each tile.
2007-11-18 23:31:03 +00:00
timoore
49473845cf Some scene graph optimizations
When loading terrain, use DrawElementsUShort where possible.

Don't chunk unconnected triangles in the terrain into seperate
Geometry sets; make the sets as big as possible.
2007-11-18 23:30:34 +00:00
durk
d4d4ed22a0 Minor documentation updates. 2007-11-18 14:21:41 +00:00
durk
240ed6f0b1 Refined debug timing control:
- Added a SampleStatistic class (from the old deprecated libg++) library.
 - Make time statistics and printing conditionable
 - Added an interface function to switch time stamp collection and printing
   on and off from the application (defaults to off).
2007-11-17 09:16:58 +00:00
frohlich
084a24e958 Improove texture sharing. 2007-11-09 05:55:50 +00:00
frohlich
cd9e3648e9 Update node masks 2007-11-09 05:52:58 +00:00
curt
7ed51be4e6 In the original flightgear native/binary scenery terrain data format, we
used short's extensively to represent counts of objects (number of points,
number of texture coordinates, number of traingle strips, etc.) and we used
shorts to index into larger structures.  But this capped many of our structure
sizes to a maximum of 32768.

By switching to unsigned shorts in the future, we can double the maximum
object/index counts without losing anything.  This was a pretty major
oversight in our original specification.

I have bumped up the native object file version from 6 to 7 and added code
in the reader to maintain full backwards compatibilty with version 6
scenery files (i.e. the current 0.9.10 scenery release.)

Curt.
2007-11-05 21:42:29 +00:00
durk
0c8358ae67 - A few fixes to ensure SimGear compiles again on cygwin.
* on cygwin, isnan is declared in ieeepf.h
  * CYGWIN is a special case in that it is windows based, but sometimes
    folows unix conventions. SGAtomic compilation failed on an illegal
    volatile type cast without the additional __CYGWIN__ define check.
2007-10-15 18:49:50 +00:00
durk
25cefd9129 * Fixed memory leak in RenderTexture.cpp (tiny, but still...)
* Added Timestamping debugging code to SGSubsystems (ported from plib
  branch).
2007-10-14 13:46:13 +00:00
timoore
af75c0ca0c Add ability to override existing model files with .osg files.
This enables off-line optimization of models and other special effects.
2007-10-12 22:46:35 +00:00
timoore
a91b2629d3 Manage OSG object cache explicitly
Don't have Registry::ReadNodeImplementation store its results in the
object cache; instead store the optimized model in the cache.
2007-10-12 22:46:13 +00:00
mfranz
de9070dba1 better standard compliance: allow empty top level tags (<PropertyList>) 2007-10-10 12:45:53 +00:00
timoore
813b518b6f Don't reset the random texture base when rebuilding a cloud layer
This fix removes obnoxious visuals (texture jumping) when a cloud
layer is moved due to a metar update or, more significantly, when
switching from metar to a scenario. Also, I switched to using a TexMat
to displace the cloud texture in order to avoid writing the texture
array every frame.
2007-10-04 20:53:22 +00:00
timoore
c47e800f60 Order the cloud layers properly using OSG RenderBin 2007-10-02 21:43:52 +00:00
timoore
8398f45d43 ocean state set in osg::Geometry
Put the ocean tile state set in osg::Geometry, not the osg::Geode, so that
is readily available during intersection testing and can be used to find the
corresponding SGMaterial.

Problem reported by grtux (gh.robin@laposte.net)
2007-09-30 19:51:49 +00:00
timoore
aeaaa50f6c Fix material animations with only a <texture-prop>
On 8/31/07, K. Hoercher <wbhoer@gmail.com> wrote:
> > Some notes:
> > - I found that in order to make the example from model-howto.html work
> > ( starting at "To make a texture replaceable at runtime") one has to
> > specify a valid (i.e. loadable) <texture>  in the material animation.

The cause seems to be the condition in SGMaterialAnimation.cxx l.277
ignoring any texture update by the UpdateCallback (only there
<texture-prop> is looked at)  without an already existing stateSet.
That in turn will not be created with a <texture-prop> alone l. 379ff.

Unless I overlooked some compelling reason contradicting, I'd like to
suggest allowing for a stateSet to be created for those situations
too. I think that would match the behaviour of animation.cxx
(PRE_OSG_PLIB_20061029) and is imho the more expected and also
documented one.
2007-09-05 22:12:00 +00:00
durk
f33ce846b8 Change "FlightGear" to "SimGear" of course. 2007-09-01 12:57:53 +00:00
durk
4718b9dc07 Added a check for OpenSceneGraph and created some basic documentation. 2007-09-01 12:55:46 +00:00
durk
fba00f7c5a Add separate check for openal and ALUT, as these are now separate. 2007-09-01 10:04:36 +00:00
durk
3360383fd7 Documentation fixes: Updated the contents of README.plib and README.OpenAL
Also make sure that these files are included in the release. This is
required, since ./configure refers to these files.
2007-09-01 09:45:21 +00:00
timoore
6c30f62693 Add curvature to ocean tiles.
An apron around the tile hides cracks with coastal tiles.

The VectorArrayAdapter, which lives in the simgear namespace, is a useful
utility class for treating vectors as 2D arrays.
2007-08-12 21:03:43 +00:00
timoore
ab5b0382da Ocean tile detail work in progress 2007-08-12 21:02:54 +00:00
fredb
671f3f5890 Update MSVC 7.1 projects 2007-08-12 13:40:16 +00:00
fredb
9bae445624 Fix a typo 2007-08-12 13:32:42 +00:00
frohlich
30529ccdf5 Modified Files:
projects/VC7.1/SimGear.vcproj projects/VC8/SimGear.vcproj
	simgear/math/Makefile.am simgear/math/SGGeoc.hxx
	simgear/math/SGGeodesy.cxx simgear/math/SGGeodesy.hxx
	simgear/math/polar3d.hxx simgear/math/sg_geodesy.hxx
	simgear/math/sg_types.hxx
Removed Files:
	simgear/math/polar3d.cxx simgear/math/sg_geodesy.cxx
	simgear/math/sg_memory.h:
	Remove sg_memory.h It is unused anyway and should not be required
	in a c++ world. Move distance course functions to the SG* type
	system. Move the implementation into SGGeodesy.cxx. Remove some of
	the old Point3D Based sg* functions that are already unused.
2007-08-07 05:26:21 +00:00
frohlich
a8a02d3a2e Modified Files:
projects/VC8/SimGear.vcproj:
	MSVC8 Build system updates from Olaf Flebbe.
2007-08-07 04:59:09 +00:00
andy
5da33ca244 Melchior discovered that call(call) would crash due to a longstanding bug with argument parsing 2007-08-01 22:46:12 +00:00
andy
04c1e95f08 Fix crash in code generator for some bad lvalue expressions 2007-08-01 22:33:01 +00:00
andy
2186fc1fc7 Add ppc64 to the list of supported platforms based on testing by Tom Callaway at Red Hat 2007-07-31 20:57:21 +00:00
timoore
fb49a9192e Fix ocean texture scaling problem. 2007-07-31 06:39:26 +00:00
curt
ccbc5abec6 Remove an extern SGSky *thesky reference that isn't used in the code anyway.
The original code forced a dependency in SimGear back to something that is
defined globaly in FlightGear, not a great strategy for a library with some
"general purpose" intentions.
2007-07-31 01:21:21 +00:00
timoore
7aa6fd479d OSG Reader and Writer for BTG files
This is part of a somewhat long road towards terrain database paging using
OSG's database pager thread.
2007-07-29 22:32:58 +00:00
frohlich
3fcc16c1a0 Modified Files:
simgear/math/SGGeoc.hxx: Fix unit conversion problem
2007-07-27 19:27:24 +00:00
timoore
b3e0298189 SimGear: Typo in Thanks file
Fix typo

Author: Hans Ulrich Niedermann <hun@n-dimensional.de>
Committer: Tim Moore <moore@redhat.com>
2007-07-23 22:00:31 +00:00
timoore
7e1fe7d852 SimGear: Properly print compilers in configure.ac
Print $CC and $CXX using the proper configure.ac mechanism

Author: Hans Ulrich Niedermann <hun@n-dimensional.de>
Signed-off-by: Tim Moore <timoore@redhat.com>
2007-07-23 21:45:11 +00:00
timoore
5d7d77d4b6 Allow parallel make ("make -j2") by giving make the opportunity to
determine dependencies.

As in subdirectory foo/bar, $(top_builddir)/foo/bar is defined to be the
current directory, this does not cause any regressions.

From Hans Ulrich Niedermann (hun@n-dimensional.de)
2007-07-22 22:37:26 +00:00
timoore
418856769b Support for reading and writing nodes in .osg files, plus some new accessors. 2007-07-22 20:06:20 +00:00
mfranz
46a32dd3ee coding style fixes 2007-07-22 13:58:26 +00:00
mfranz
ecb4dc57b4 Maik JUSTUS: workaround for broken Doppler effect in OpenAL
mf: this patch is meant to be removed as soon as OpenAL got fixed. (The
    OpenAL developers acknowleged the bug and announced that it'll get
    fixed.) For removal try
    $ cd simgear/sound
    $ cvs diff -rAFTER_OPENAL_DOPPLER_WORKAROUND -rBEFORE_OPENAL_DOPPLER_WORKAROUND|patch
2007-07-22 13:50:24 +00:00
mfranz
89d426470b Maik JUSTUS: Doppler fixes (add option to turn off Doppler for sounds that
shouldn't be affected -- marker beep, ATIS messages, etc.)

mf: this is the first part of the original patch. It is supposed to contain
    fixes that are not caused by OpenAL bugs, and thus aren't meant to be
    reverted later. The second part will contain a temprary workaround for
    OpenAL bugs. Unfortunately, I had to do the split myself as the contributor
    refused to do it.
2007-07-22 13:33:23 +00:00
mfranz
23c7a1b5b7 - close loophole through which one could sneak in illegal property names
containing slashes, colons and all sorts of evil characters. In Nasal
  this could be done via props.globals.getChild("1!@#$//[]{}", 0, 1).setValue(0);
  The cause is that getChild() hands the given name directly over to an
  alternative SGPropertyNode ("convenience") constructor which sets the
  name without any checks.
- unify exception messages: first character is lower case
2007-07-17 14:52:51 +00:00
frohlich
3b21e9434f Modified Files:
simgear/route/route.hxx: Remove unused include.
2007-07-08 08:43:40 +00:00
frohlich
d4a4428e64 Modified Files:
simgear/route/waypoint.hxx simgear/route/waypoint.cxx: Use const
	refs where possible.
2007-07-08 08:43:15 +00:00
mfranz
2dfc057135 replace exit() by throw sg_exception(). Of course, we have to be aware
that interdependencies between sg libs are generally unwelcome, but
sg_exception is a rather basic part, and it's already used by xml, props,
scene, sound and, of course, structure. Since props and xml are core
libs, we can assume that sg_exceptions are available.  (OK'ed by Curt)
2007-07-02 15:42:19 +00:00
mfranz
a25eebef9b add SG_ORIGIN macro that expands to a string __FILE__":"__LINE__
Note that __LINE__ is a number and can't be directly used in string
context, which makes the macro worthwhile. (IMHO :-)
2007-07-02 12:55:10 +00:00
mfranz
741c4ca15a back out last changes (radar patch) 2007-06-29 22:45:37 +00:00
276 changed files with 15403 additions and 7111 deletions

View File

@@ -22,7 +22,7 @@ PROJECT_NAME = SimGear
# This could be handy for archiving the generated documentation or
# if some version control system is used.
PROJECT_NUMBER = 0.3.10
PROJECT_NUMBER = 1.9.0
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
# base path where the generated documentation will be put.

View File

@@ -4,6 +4,9 @@ EXTRA_DIST = \
DoxygenMain.cxx \
README.MSVC \
README.zlib \
README.plib \
README.OpenAL \
README.OSG \
projects \
SimGear.dsp \
SimGear.dsw

12
NEWS
View File

@@ -1,3 +1,15 @@
Version 1.9.0
* Thu Dec 18 15:12:15 CST 2008
Version 1.8.6
* Mon Dec 1 14:02:47 CST 2008
Version 1.8.5
* October 30, 2008 (source code snapshot release)
New in 0.3.10
* April 5, 2006

27
README.OSG Normal file
View File

@@ -0,0 +1,27 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have OpenSceneGraph (OSG) installed to build this version of
FlightGear.
Notice that FlightGear 1.9.0 requires at least version 2.7.8. Using earlier
versions of OSG will yield serious rendering bugs.
You can get the latest version of OSG from:
http://www.openscenegraph.org/
Build notes:
Unzip the file OpenSceneGraph-x.x.zip and install using the following
commands:
unzip OpenSceneGraph-x.x
cd OpenSceneGraph
ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
make
sudo make install

View File

@@ -3,10 +3,27 @@
You *must* have the development components of OpenAL installed on your system
to build FlightGear!" You can get a copy here:
http://www.openal.org
http://connect.creativelabs.com/openal/default.aspx
Build notes:
The OpenAL developers do not make "versioned" releases so we recommend that
you pull the latest version via anonymous CVS (follow the instructions at
the OpenAL web site) and build/install that.
You can download a versioned release of the openal library from
http://www.openal.org/downloads.html. Download the openal source,
release 0.0.8 (dated February 11, 2006) and run:
tar xjvf openal-soft-1.5.304.tar.bz2
cd openal-soft-1.5.304/
ccmake .
[ While running ccmake: press 'c' to configure, press 'c' once more, and
then press 'g' to generate and exit ]
The alut library is also required, but comes separately in the package
freelut-1.1.0.tar.gz. This package can be downloaded from the same page
(http://connect.creativelabs.com/openal/default.aspx). Download and run:
tar xzvf freelut-1.1.0.tar.gz
cd freealut-1.1.0
./configure
make
sudo make install

View File

@@ -1,6 +1,6 @@
[This file is mirrored in both the FlightGear and SimGear packages.]
You *must* have plib version 1.6.0 or later installed on your system
You *must* have plib version 1.8.5 or later installed on your system
to build FlightGear!" Flight Gear is no longer compatible with the
earlier versions of the library.
@@ -14,3 +14,19 @@ You should be able to just run "./configure" to configure the package
and use all of plib's defaults. Then run "make" followed by "make
install". By default, plib installs itself into /usr so if you don't
like this, be sure to specify an alternate prefix such as --prefix=/usr/local
As of this writing (2007-11-18), many linux distributions are shipped with a
working version of plib, so chances are that this library is already
installed. It should be noted, that currently plib version no longer compiles
using recent versions of gcc (confirmed on version gcc 4.1.2, as shipped with
SuSe 10.2). As a workaround, it is possible to either use plib SVN. Run the
following commands:
svn co https://plib.svn.sourceforge.net/svnroot/plib/trunk plib
cd plib
./autogen.sh
./configure
make
make install

View File

@@ -496,36 +496,6 @@ SOURCE=.\simgear\math\leastsqs.cxx
# End Source File
# Begin Source File
SOURCE=.\simgear\math\polar3d.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmath"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmath"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\math\sg_geodesy.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmath"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmath"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\math\sg_random.c
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -556,6 +526,21 @@ SOURCE=.\simgear\math\vector.cxx
# End Source File
# Begin Source File
SOURCE=.\simgear\math\SGGeod.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmath"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmath"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\math\SGGeodesy.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -602,6 +587,21 @@ SOURCE=.\simgear\environment\visual_enviro.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\environment\precipitation.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgenvironment"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgenvironment"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgmisc"
@@ -711,6 +711,21 @@ SOURCE=.\simgear\misc\interpolator.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\misc\PathOptions.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmisc"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmisc"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgnasal"
@@ -718,6 +733,21 @@ SOURCE=.\simgear\misc\interpolator.cxx
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\simgear\nasal\bitslib.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\code.c
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -808,6 +838,36 @@ SOURCE=.\simgear\nasal\hash.c
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\iolib.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\iolib.h
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\lex.c
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -853,51 +913,6 @@ SOURCE=.\simgear\nasal\mathlib.c
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\iolib.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\iolib.h
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\bitslib.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\misc.c
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -913,6 +928,21 @@ SOURCE=.\simgear\nasal\misc.c
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\naref.h
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\nasal.h
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -973,21 +1003,6 @@ SOURCE=.\simgear\nasal\string.c
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\vector.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\thread-posix.c
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -1015,6 +1030,51 @@ SOURCE=.\simgear\nasal\thread-win32.c
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\threadlib.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\utf8lib.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\nasal\vector.c
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgnasal"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgnasal"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgprops"
@@ -1169,6 +1229,21 @@ SOURCE=.\simgear\scene\model\animation.cxx
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\particles.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\location.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -1214,6 +1289,21 @@ SOURCE=.\simgear\scene\model\modellib.cxx
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\ModelRegistry.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\persparam.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -1274,6 +1364,36 @@ SOURCE=.\simgear\scene\model\shadanim.cxx
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\CheckSceneryVisitor.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGClipGroup.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGMaterialAnimation.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -1286,6 +1406,96 @@ SOURCE=.\simgear\scene\model\SGMaterialAnimation.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGOffsetTransform.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGPagedLOD.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGReaderWriterXML.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGRotateTransform.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGScaleTransform.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\model\SGTranslateTransform.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgmodel"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgmodel"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgsky"
@@ -1440,6 +1650,21 @@ SOURCE=.\simgear\scene\sky\newcloud.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\sky\CloudShaderGeometry.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgsky"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgsky"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgtgdb"
@@ -1462,21 +1687,6 @@ SOURCE=.\simgear\scene\tgdb\apt_signs.cxx
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\leaf.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\obj.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -1519,6 +1729,186 @@ SOURCE=.\simgear\scene\tgdb\userdata.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\ReaderWriterSTG.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\SGOceanTile.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\SGReaderWriterBTG.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\SGReaderWriterBTG.hxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\SGVasiDrawable.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\GroundLightManager.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\SGModelBin.hxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\ShaderGeometry.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\TileCache.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\TileEntry.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\TreeBin.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\tgdb\TreeBin.hxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgtgdb"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgtgdb"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgutil"
@@ -1526,6 +1916,51 @@ SOURCE=.\simgear\scene\tgdb\userdata.cxx
# PROP Default_Filter ""
# Begin Source File
SOURCE=.\simgear\scene\util\SGEnlargeBoundingBox.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgutil"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgutil"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\util\SGSceneFeatures.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgutil"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgutil"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\util\SGSceneUserData.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgutil"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgutil"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\util\SGStateAttributeVisitor.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
@@ -1553,6 +1988,51 @@ SOURCE=.\simgear\scene\util\SGTextureStateAttributeVisitor.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\util\NodeAndDrawableVisitor.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgutil"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgutil"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\util\StateAttributeFactory.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgutil"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgutil"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\scene\util\QuadTreeBuilder.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgutil"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgutil"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgscreen"
@@ -1839,6 +2319,51 @@ SOURCE=.\simgear\structure\SGBinding.cxx
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\structure\SGExpression.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgstructure"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\structure\SGSmplhist.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgstructure"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
!ENDIF
# End Source File
# Begin Source File
SOURCE=.\simgear\structure\SGSmplstat.cxx
!IF "$(CFG)" == "SimGear - Win32 Release"
# PROP Intermediate_Dir "Release\Lib_sgstructure"
!ELSEIF "$(CFG)" == "SimGear - Win32 Debug"
# PROP Intermediate_Dir "Debug\Lib_sgstructure"
!ENDIF
# End Source File
# End Group
# Begin Group "Lib_sgtiming"

2
Thanks
View File

@@ -120,7 +120,7 @@ Petter Reinholdtsen <pere@games.no>
Incorporated the Gnu automake/autoconf system (with libtool).
This should streamline and standardize the build process for all
Unix-like platforms. It should have little effect on IDE type
environments since the don't use the Unix make system.
environments since these don't use the Unix make system.
Paul Schlyter <pausch@saaf.se>

View File

@@ -413,3 +413,274 @@ AC_DEFUN([AC_SG_SET_COMPILER],
## CFLAGS=
;;
esac])
pushdef([AC_PROG_INSTALL],
[
dnl our own version, testing for a -p flag
popdef([AC_PROG_INSTALL])
dnl as AC_PROG_INSTALL works as it works we first have
dnl to save if the user didn't specify INSTALL, as the
dnl autoconf one overwrites INSTALL and we have no chance to find
dnl out afterwards
AC_PROG_INSTALL
# OK, user hasn't given any INSTALL, autoconf found one for us
# now we test, if it supports the -p flag
AC_MSG_CHECKING(for -p flag to install)
rm -f confinst.$$.* > /dev/null 2>&1
echo "Testtest" > confinst.$$.orig
ac_res=no
if ${INSTALL} -p confinst.$$.orig confinst.$$.new > /dev/null 2>&1 ; then
if test -f confinst.$$.new ; then
# OK, -p seems to do no harm to install
INSTALL="${INSTALL} -p"
ac_res=yes
fi
fi
rm -f confinst.$$.*
AC_MSG_RESULT($ac_res)
dnl the following tries to resolve some signs and wonders coming up
dnl with different autoconf/automake versions
dnl e.g.:
dnl *automake 1.4 install-strip sets A_M_INSTALL_PROGRAM_FLAGS to -s
dnl and has INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(A_M_INSTALL_PROGRAM_FLAGS)
dnl it header-vars.am, so there the actual INSTALL_PROGRAM gets the -s
dnl *automake 1.4a (and above) use INSTALL_STRIP_FLAG and only has
dnl INSTALL_PROGRAM = @INSTALL_PROGRAM@ there, but changes the
dnl install-@DIR@PROGRAMS targets to explicitly use that flag
dnl *autoconf 2.13 is dumb, and thinks it can use INSTALL_PROGRAM as
dnl INSTALL_SCRIPT, which breaks with automake <= 1.4
dnl *autoconf >2.13 (since 10.Apr 1999) has not that failure
dnl to clean up that mess we:
dnl +set INSTALL_PROGRAM to use INSTALL_STRIP_FLAG
dnl which cleans KDE's program with automake > 1.4;
dnl +set INSTALL_SCRIPT to only use INSTALL, to clean up autoconf's problems
dnl with automake<=1.4
dnl note that dues to this sometimes two '-s' flags are used
INSTALL_PROGRAM='${INSTALL} $(INSTALL_STRIP_FLAG)'
INSTALL_SCRIPT='${INSTALL}'
])dnl
# ===========================================================================
# http://autoconf-archive.cryp.to/ax_boost_base.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_BASE([MINIMUM-VERSION])
#
# DESCRIPTION
#
# Test for the Boost C++ libraries of a particular version (or newer)
#
# If no path to the installed boost library is given the macro searchs
# under /usr, /usr/local, /opt and /opt/local and evaluates the
# $BOOST_ROOT environment variable. Further documentation is available at
# <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
#
# And sets:
#
# HAVE_BOOST
#
# LAST MODIFICATION
#
# 2008-04-12
#
# COPYLEFT
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved.
AC_DEFUN([AX_BOOST_BASE],
[
AC_ARG_WITH([boost],
AS_HELP_STRING([--with-boost@<:@=DIR@:>@], [use boost (default is yes) - it is possible to specify the root directory for boost (optional)]),
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ac_boost_path=""
else
want_boost="yes"
ac_boost_path="$withval"
fi
],
[want_boost="yes"])
AC_ARG_WITH([boost-libdir],
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
[Force given directory for boost libraries. Note that this will overwrite library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
[
if test -d $withval
then
ac_boost_lib_path="$withval"
else
AC_MSG_ERROR(--with-boost-libdir expected directory name)
fi
],
[ac_boost_lib_path=""]
)
if test "x$want_boost" = "xyes"; then
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
boost_lib_version_req_sub_minor="0"
fi
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
succeeded=no
dnl first we check the system location for boost libraries
dnl this location ist chosen if boost libraries are installed with the --layout=system option
dnl or if you install boost with RPM
if test "$ac_boost_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_path/lib"
BOOST_CPPFLAGS="-I$ac_boost_path/include"
else
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
BOOST_LDFLAGS="-L$ac_boost_path_tmp/lib"
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
break;
fi
done
fi
dnl overwrite ld flags if we have required special directory with
dnl --with-boost-libdir parameter
if test "$ac_boost_lib_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_lib_path"
fi
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
dnl if we found no boost with system layout we search for boost libraries
dnl built and installed without the --layout=system option or for a staged(not installed) version
if test "x$succeeded" != "xyes"; then
_version=0
if test "$ac_boost_path" != ""; then
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
fi
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
done
fi
else
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
best_path=$ac_boost_path
fi
done
fi
done
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
if test "$ac_boost_lib_path" = ""
then
BOOST_LDFLAGS="-L$best_path/lib"
fi
if test "x$BOOST_ROOT" != "x"; then
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/lib" && test -r "$BOOST_ROOT/stage/lib"; then
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
V_CHECK=`expr $stage_version_shorten \>\= $_version`
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
BOOST_CPPFLAGS="-I$BOOST_ROOT"
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/lib"
fi
fi
fi
fi
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
fi
if test "$succeeded" != "yes" ; then
if test "$_version" = "0" ; then
AC_MSG_ERROR([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
else
AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
fi
else
AC_SUBST(BOOST_CPPFLAGS)
AC_SUBST(BOOST_LDFLAGS)
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

View File

@@ -8,7 +8,7 @@ dnl Require at least automake 2.52
AC_PREREQ(2.52)
dnl Initialize the automake stuff
AM_INIT_AUTOMAKE(SimGear, 0.3.10)
AM_INIT_AUTOMAKE(SimGear, 1.9.0)
dnl Specify KAI C++ compiler and flags.
dnl Borrowed with slight modification from blitz distribution.
@@ -24,8 +24,10 @@ AC_ARG_WITH(cxx,
esac
])
echo CXX = $CXX
echo CC = $CC
AC_MSG_CHECKING([CXX])
AC_MSG_RESULT([$CXX])
AC_MSG_CHECKING([CC])
AC_MSG_RESULT([$CC])
dnl Checks for programs.
AC_PROG_MAKE_SET
@@ -35,6 +37,11 @@ AC_PROG_CXX
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_PROG_LN_S
AX_BOOST_BASE([1.34.0])
if test "x$BOOST_CPPFLAGS" != "x-I/usr/include" ; then
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
fi
dnl set the $host variable based on local machine/os
AC_CANONICAL_HOST
@@ -266,6 +273,7 @@ LIBS="$base_LIBS"
dnl check for OpenAL libraries
OPENAL_OK="no"
ALUT_OK="no"
case "${host}" in
*-*-cygwin* | *-*-mingw32*)
dnl CygWin under Windoze.
@@ -276,6 +284,7 @@ case "${host}" in
LIBS="$LIBS -lwinmm -ldsound -ldxguid -lole32"
openal_LIBS="$LIBS"
OPENAL_OK="$ac_cv_search_alGenBuffers"
ALUT_OK="$ac_cv_search_alutInit"
;;
*-apple-darwin*)
@@ -285,6 +294,7 @@ case "${host}" in
openal_LIBS="$LIBS"
# not sure how to test if OpenAL exists on MacOS (does it come by default?)
OPENAL_OK="yes"
ALUT_OK="yes"
;;
*)
@@ -295,6 +305,7 @@ case "${host}" in
AC_SEARCH_LIBS(alGenBuffers, openal)
AC_SEARCH_LIBS(alutInit, [ alut openal ] )
OPENAL_OK="$ac_cv_search_alGenBuffers"
ALUT_OK="$ac_cv_search_alutInit"
openal_LIBS="$LIBS"
LIBS=$save_LIBS
;;
@@ -312,6 +323,19 @@ if test "$OPENAL_OK" == "no"; then
exit
fi
if test "$ALUT_OK" == "no"; then
echo
echo "You *must* have the alut library installed on your system to build"
echo "SimGear!"
echo
echo "Please see README.OpenAL for more details."
echo
echo "configure aborted."
exit
fi
LIBS="$base_LIBS"
AC_SUBST(base_LIBS)
@@ -342,11 +366,11 @@ if test "x$ac_cv_header_plib_ul_h" != "xyes"; then
exit
fi
AC_MSG_CHECKING([for plib 1.8.4 or newer])
AC_MSG_CHECKING([for plib 1.8.5 or newer])
AC_TRY_RUN([
#include <plib/ul.h>
#define MIN_PLIB_VERSION 184
#define MIN_PLIB_VERSION 185
int main() {
int major, minor, micro;
@@ -361,12 +385,34 @@ int main() {
],
AC_MSG_RESULT(yes),
[AC_MSG_RESULT(wrong version);
AC_MSG_ERROR([Install plib 1.8.4 or later first...])],
AC_MSG_ERROR([Install plib 1.8.5 or later first...])],
AC_MSG_RESULT(yes)
)
LIBS="$saved_LIBS"
AC_CHECK_HEADER(osg/Version)
if test "x$ac_cv_header_osg_Version" != "xyes"; then
echo
echo "You *must* have the OpenSceneGraph support library installed on your system"
echo "to build this version of SimGear!"
echo
echo "Please see README.OSG for more details."
echo
echo "configure aborted."
exit
fi
AC_CHECK_HEADER(boost/version.hpp)
if test "x$ac_cv_header_boost_version_hpp" != "xyes"; then
echo
echo "You *must* have the Boost library installed on your system"
echo "to build this version of SimGear!"
echo
echo "configure aborted."
exit
fi
AC_LANG_POP
dnl Check for system installed zlib

View File

@@ -23,7 +23,7 @@
<Tool
Name="VCCLCompilerTool"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..;..\..\..\OpenSceneGraph\include;..\..\..\OpenThreads\include;..\..\..\3rdparty\include;&quot;..\..\..\pthreads-w32-2-7-0-release&quot;"
AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..;..\..\..\install\msvc71\OpenSceneGraph\include;..\..\..\3rdparty\include;&quot;..\..\..\pthreads-w32-2-7-0-release&quot;;..\..\..\boost_1_36_0"
PreprocessorDefinitions="HAVE_CONFIG_H,NDEBUG,WIN32;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
StringPooling="TRUE"
RuntimeLibrary="2"
@@ -35,6 +35,7 @@
ProgramDataBaseFileName=".\Release/"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
@@ -74,7 +75,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..;..\..\..\OpenSceneGraph\include;..\..\..\OpenThreads\include;..\..\..\3rdparty\include;&quot;..\..\..\pthreads-w32-2-7-0-release&quot;"
AdditionalIncludeDirectories="..\..;..\..\simgear;..\..\..;..\..\..\install\msvc71\OpenSceneGraph\include;..\..\..\3rdparty\include;&quot;..\..\..\pthreads-w32-2-7-0-release&quot;;..\..\..\boost_1_36_0"
PreprocessorDefinitions="HAVE_CONFIG_H,_DEBUG,WIN32;_USE_MATH_DEFINES;_CRT_SECURE_NO_WARNINGS;_CRT_NONSTDC_NO_WARNINGS"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
@@ -132,6 +133,9 @@
<Filter
Name="Lib_sgdebug"
Filter="">
<File
RelativePath="..\..\simgear\debug\debug_types.h">
</File>
<File
RelativePath="..\..\simgear\debug\logstream.cxx">
</File>
@@ -307,21 +311,12 @@
<File
RelativePath="..\..\simgear\math\point3d.hxx">
</File>
<File
RelativePath="..\..\simgear\math\polar3d.cxx">
</File>
<File
RelativePath="..\..\simgear\math\polar3d.hxx">
</File>
<File
RelativePath="..\..\simgear\math\sg_geodesy.cxx">
</File>
<File
RelativePath="..\..\simgear\math\sg_geodesy.hxx">
</File>
<File
RelativePath="..\..\simgear\math\sg_memory.h">
</File>
<File
RelativePath="..\..\simgear\math\sg_random.c">
</File>
@@ -331,6 +326,9 @@
<File
RelativePath="..\..\simgear\math\sg_types.hxx">
</File>
<File
RelativePath="..\..\simgear\math\SGGeod.cxx">
</File>
<File
RelativePath="..\..\simgear\math\SGGeodesy.cxx">
</File>
@@ -356,6 +354,12 @@
<File
RelativePath="..\..\simgear\misc\interpolator.hxx">
</File>
<File
RelativePath="..\..\simgear\misc\PathOptions.cxx">
</File>
<File
RelativePath="..\..\simgear\misc\PathOptions.hxx">
</File>
<File
RelativePath="..\..\simgear\misc\sg_path.cxx">
</File>
@@ -504,6 +508,12 @@
<File
RelativePath="..\..\simgear\scene\sky\cloudfield.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\sky\CloudShaderGeometry.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\sky\CloudShaderGeometry.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\sky\dome.cxx">
</File>
@@ -667,6 +677,12 @@
<File
RelativePath="..\..\simgear\scene\model\animation.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\CheckSceneryVisitor.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\CheckSceneryVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\location.cxx">
</File>
@@ -685,6 +701,18 @@
<File
RelativePath="..\..\simgear\scene\model\modellib.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\ModelRegistry.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\ModelRegistry.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\particles.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\particles.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\persparam.cxx">
</File>
@@ -703,6 +731,12 @@
<File
RelativePath="..\..\simgear\scene\model\placementtrans.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGClipGroup.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGClipGroup.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGMaterialAnimation.cxx">
</File>
@@ -715,6 +749,21 @@
<File
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGPagedLOD.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGPagedLOD.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGReaderWriterXML.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGReaderWriterXMLOptions.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\model\SGRotateTransform.cxx">
</File>
@@ -790,6 +839,12 @@
<File
RelativePath="..\..\simgear\scene\tgdb\apt_signs.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\obj.cxx">
</File>
@@ -802,18 +857,57 @@
<File
RelativePath="..\..\simgear\scene\tgdb\pt_lights.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\ReaderWriterSTG.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGModelBin.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGOceanTile.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGOceanTile.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTGOptions.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\ShaderGeometry.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\ShaderGeometry.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\TileCache.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\TileCache.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\TileEntry.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\TileEntry.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\TreeBin.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\TreeBin.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\userdata.cxx">
</File>
@@ -885,12 +979,21 @@
<File
RelativePath="..\..\simgear\structure\exception.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\OSGVersion.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGBinding.cxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGBinding.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGExpression.cxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGExpression.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGReferenced.hxx">
</File>
@@ -898,7 +1001,16 @@
RelativePath="..\..\simgear\structure\SGSharedPtr.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\ssgSharedPtr.hxx">
RelativePath="..\..\simgear\structure\SGSmplhist.cxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGSmplhist.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGSmplstat.cxx">
</File>
<File
RelativePath="..\..\simgear\structure\SGSmplstat.hxx">
</File>
<File
RelativePath="..\..\simgear\structure\subsystem_mgr.cxx">
@@ -1002,6 +1114,12 @@
<File
RelativePath="..\..\simgear\environment\metar.hxx">
</File>
<File
RelativePath="..\..\simgear\environment\precipitation.cxx">
</File>
<File
RelativePath="..\..\simgear\environment\precipitation.hxx">
</File>
<File
RelativePath="..\..\simgear\environment\visual_enviro.cxx">
</File>
@@ -1012,6 +1130,21 @@
<Filter
Name="Lib_sgutil"
Filter="">
<File
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\NodeAndDrawableVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\RenderConstants.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\SGDebugDrawCallback.hxx">
</File>
@@ -1051,6 +1184,12 @@
<File
RelativePath="..\..\simgear\scene\util\SGUpdateVisitor.hxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\StateAttributeFactory.cxx">
</File>
<File
RelativePath="..\..\simgear\scene\util\StateAttributeFactory.hxx">
</File>
</Filter>
<File
RelativePath="..\..\simgear\simgear_config.h-msvc71">

View File

@@ -103,7 +103,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories="../..;../../..;$(ProgramFiles)/OpenThreads/include;$(ProgramFiles)/OpenSceneGraph/include;../../Simgear;../../../3rdparty/include"
AdditionalIncludeDirectories="../..;../../..;&quot;$(ProgramFiles)/OpenThreads/include&quot;;&quot;$(ProgramFiles)/OpenSceneGraph/include&quot;;../../Simgear;../../../3rdparty/include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;HAVE_CONFIG_H;ENABLE_THREADS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_CONST_CORRECT_OVERLOADS;NOMINMAX;_USE_MATH_DEFINES"
StringPooling="true"
MinimalRebuild="true"
@@ -467,10 +467,6 @@
RelativePath="..\..\simgear\sg_inlines.h"
>
</File>
<File
RelativePath="..\..\simgear\math\sg_memory.h"
>
</File>
<File
RelativePath="..\..\simgear\misc\sg_path.hxx"
>
@@ -583,6 +579,14 @@
RelativePath="..\..\simgear\threads\SGQueue.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTGOptions.hxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGReferenced.hxx"
>
@@ -887,6 +891,14 @@
RelativePath="..\..\simgear\screen\GLBitmaps.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\GroundLightManager.hxx"
>
</File>
<File
RelativePath="..\..\simgear\nasal\hash.c"
>
@@ -987,6 +999,14 @@
RelativePath="..\..\simgear\scene\model\modellib.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\ModelRegistry.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\ModelRegistry.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\sky\moon.cxx"
>
@@ -1019,10 +1039,18 @@
RelativePath="..\..\simgear\nasal\parse.c"
>
</File>
<File
RelativePath="..\..\simgear\misc\PathOptions.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\persparam.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\persparam.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\placement.cxx"
>
@@ -1031,10 +1059,6 @@
RelativePath="..\..\simgear\scene\model\placementtrans.cxx"
>
</File>
<File
RelativePath="..\..\simgear\math\polar3d.cxx"
>
</File>
<File
RelativePath="..\..\simgear\props\props.cxx"
>
@@ -1047,6 +1071,10 @@
RelativePath="..\..\simgear\scene\tgdb\pt_lights.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\QuadTreeBuilder.cxx"
>
</File>
<File
RelativePath="..\..\simgear\screen\RenderTexture.cpp"
>
@@ -1079,10 +1107,6 @@
RelativePath="..\..\simgear\io\sg_file.cxx"
>
</File>
<File
RelativePath="..\..\simgear\math\sg_geodesy.cxx"
>
</File>
<File
RelativePath="..\..\simgear\misc\sg_path.cxx"
>
@@ -1111,6 +1135,18 @@
RelativePath="..\..\simgear\structure\SGBinding.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGClipGroup.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGClipGroup.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGDirectionalLightBin.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\SGEnlargeBoundingBox.cxx"
>
@@ -1119,10 +1155,18 @@
RelativePath="..\..\simgear\math\SGGeodesy.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGLightBin.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGMaterialAnimation.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGModelBin.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGOceanTile.cxx"
>
@@ -1131,6 +1175,10 @@
RelativePath="..\..\simgear\scene\model\SGOffsetTransform.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGReaderWriterBTG.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\SGRotateTransform.cxx"
>
@@ -1147,6 +1195,14 @@
RelativePath="..\..\simgear\scene\util\SGSceneUserData.cxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGSmplhist.cxx"
>
</File>
<File
RelativePath="..\..\simgear\structure\SGSmplstat.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\SGStateAttributeVisitor.cxx"
>
@@ -1155,6 +1211,10 @@
RelativePath="..\..\simgear\misc\sgstream.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGTexturedTriangleBin.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\SGTextureStateAttributeVisitor.cxx"
>
@@ -1167,10 +1227,18 @@
RelativePath="..\..\simgear\scene\model\SGTranslateTransform.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGTriangleBin.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGVasiDrawable.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\tgdb\SGVertexArrayBin.hxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\model\shadanim.cxx"
>
@@ -1203,6 +1271,10 @@
RelativePath="..\..\simgear\scene\sky\stars.cxx"
>
</File>
<File
RelativePath="..\..\simgear\scene\util\StateAttributeFactory.cxx"
>
</File>
<File
RelativePath="..\..\simgear\nasal\string.c"
>

View File

@@ -10,7 +10,7 @@ METAR_DIRS = environment
EXTRA_DIST = simgear_config.h.vc5 simgear_config.h-msvc71 version.h.in
include_HEADERS = \
compiler.h constants.h sg_inlines.h sg_traits.hxx version.h
compiler.h constants.h sg_inlines.h version.h
SUBDIRS = \
$(compatibility_DIR) \

View File

@@ -11,7 +11,7 @@ libsgbucket_a_SOURCES = newbucket.cxx
# testbucket_SOURCES = testbucket.cxx
# testbucket_LDADD = \
# $(top_builddir)/bucket/libsgbucket.a \
# libsgbucket.a \
# $(top_builddir)/misc/libsgmisc.a
INCLUDES = -I$(top_srcdir)

View File

@@ -33,29 +33,10 @@
#include <simgear/constants.h>
#include <simgear/math/SGMath.hxx>
#ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
# include <cstdio> // sprintf()
#else
# include <math.h>
# include <stdio.h> // sprintf()
#endif
#include STL_IOSTREAM
// I don't understand ... <math.h> or <cmath> should be included
// already depending on how you defined SG_HAVE_STD_INCLUDES, but I
// can go ahead and add this -- CLO
#ifdef __MWERKS__
SG_USING_STD(sprintf);
SG_USING_STD(fabs);
#endif
#include STL_STRING
SG_USING_STD(string);
SG_USING_STD(ostream);
#include <cmath>
#include <cstdio> // sprintf()
#include <ostream>
#include <string>
/**
* standard size of a bucket in degrees (1/8 of a degree)
@@ -210,18 +191,19 @@ public:
* string form.
* @return tile index in string form
*/
inline string gen_index_str() const {
inline std::string gen_index_str() const {
char tmp[20];
sprintf(tmp, "%ld",
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
return (string)tmp;
std::sprintf(tmp, "%ld",
(((long)lon + 180) << 14) + ((lat + 90) << 6)
+ (y << 3) + x);
return (std::string)tmp;
}
/**
* Build the base path name for this bucket.
* @return base path in string form
*/
string gen_base_path() const;
std::string gen_base_path() const;
/**
* @return the center lon of a tile.
@@ -306,10 +288,15 @@ public:
// friends
friend ostream& operator<< ( ostream&, const SGBucket& );
friend std::ostream& operator<< ( std::ostream&, const SGBucket& );
friend bool operator== ( const SGBucket&, const SGBucket& );
};
inline bool operator!= (const SGBucket& lhs, const SGBucket& rhs)
{
return !(lhs == rhs);
}
/**
* \relates SGBucket
@@ -340,8 +327,8 @@ void sgBucketDiff( const SGBucket& b1, const SGBucket& b2, int *dx, int *dy );
* @param out output stream
* @param b bucket
*/
inline ostream&
operator<< ( ostream& out, const SGBucket& b )
inline std::ostream&
operator<< ( std::ostream& out, const SGBucket& b )
{
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
}

View File

@@ -23,48 +23,9 @@
* A set of defines to encapsulate compiler and platform differences.
* Please refer to the source code for full documentation on this file.
*
* Here is a summary of what this file does.
* This file is useful to set compiler-specific options in every file - for
* example, disabling warnings.
*
* (1) Defines macros for some STL includes which may be affected
* by file name length limitations.
*
* (2) Defines macros for some features not supported by all C++ compilers.
*
* (3) Defines 'explicit' as a null macro if the compiler doesn't support
* the explicit keyword.
*
* (4) Defines 'typename' as a null macro if the compiler doesn't support
* the typename keyword.
*
* (5) Defines bool, true and false if the compiler doesn't do so.
*
* (6) Defines SG_EXPLICIT_FUNCTION_TMPL_ARGS if the compiler
* supports calling a function template by providing its template
* arguments explicitly.
*
* (7) Defines SG_NEED_AUTO_PTR if STL doesn't provide auto_ptr<>.
*
* (8) Defines SG_NO_ARROW_OPERATOR if the compiler is unable
* to support operator->() for iterators.
*
* (9) Defines SG_USE_EXCEPTIONS if the compiler supports exceptions.
* Note: no FlightGear code uses exceptions.
*
* (10) Define SG_NAMESPACES if the compiler supports namespaces.
*
* (11) SG_MATH_FN_IN_NAMESPACE_STD -- not used??
*
* (12) Define SG_HAVE_STD if std namespace is supported.
*
* (13) Defines SG_CLASS_PARTIAL_SPECIALIZATION if the compiler
* supports partial specialization of class templates.
*
* (14) Defines SG_HAVE_STD_INCLUDES to use ISO C++ Standard headers.
*
* (15) Defines SG_HAVE_STREAMBUF if <streambuf> of <streambuf.h> are present.
*
* (16) Define SG_MATH_EXCEPTION_CLASH if math.h defines an exception class
* that clashes with the one defined in <stdexcept>.
*/
#ifndef _SG_COMPILER_H
@@ -79,155 +40,27 @@
#define SG_DO_STRINGIZE(X) #X
#ifdef __GNUC__
# if __GNUC__ == 2
# if __GNUC_MINOR__ < 8
// g++-2.7.x
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip.h>
# define STL_IOSTREAM <iostream.h>
# define STL_ITERATOR <iterator.h>
# define STL_FSTREAM <fstream.h>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream.h>
# define SG_NEED_AUTO_PTR
# define SG_NO_DEFAULT_TEMPLATE_ARGS
# define SG_INCOMPLETE_FUNCTIONAL
# define SG_NO_ARROW_OPERATOR
# elif __GNUC_MINOR__ >= 8
// g++-2.8.x and egcs-1.x
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
# define SG_NEED_AUTO_PTR
# define SG_MEMBER_TEMPLATES
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STREAMBUF
# define SG_CLASS_PARTIAL_SPECIALIZATION
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# endif
# elif __GNUC__ >= 3
// g++-3.0.x
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
# define SG_NEED_AUTO_PTR
# define SG_MEMBER_TEMPLATES
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STREAMBUF
# define SG_CLASS_PARTIAL_SPECIALIZATION
# define SG_HAVE_STD_INCLUDES
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# else
# error Time to upgrade. GNU compilers < 2.7 not supported
# if __GNUC__ < 3
# error Time to upgrade. GNU compilers < 3.0 not supported
# elif (__GNUC__ == 3) && (__GNUC_MINOR__ < 4)
# warning GCC compilers prior to 3.4 are suspect
# endif
# define SG_COMPILER_STR "GNU C++ version " SG_STRINGIZE(__GNUC__) "." SG_STRINGIZE(__GNUC_MINOR__)
#endif // __GNUC__
/* KAI C++ */
#if defined(__KCC)
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STREAMBUF
# define SG_HAVE_TRAITS
# define SG_HAVE_STD_INCLUDES
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# define SG_COMPILER_STR "Kai C++ version " SG_STRINGIZE(__KCC_VERSION)
#endif // __KCC
//
// Metrowerks
//
#if defined(__MWERKS__)
/*
CodeWarrior compiler from Metrowerks, Inc.
*/
# define SG_HAVE_TRAITS
# define SG_HAVE_STD_INCLUDES
# define SG_HAVE_STD
# define SG_NAMESPACES
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
// Temp:
# define bcopy(from, to, n) memcpy(to, from, n)
// -rp- please use FG_MEM_COPY everywhere !
// #define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
// -dw- currently used glut has no game mode stuff
# define GLUT_WRONG_VERSION
# define SG_COMPILER_STR "Metrowerks CodeWarrior C++ version " SG_STRINGIZE(__MWERKS__)
#endif // __MWERKS__
//
// Microsoft compilers.
//
#ifdef _MSC_VER
# define bcopy(from, to, n) memcpy(to, from, n)
# define FG_MEM_COPY(to,from,n) memcpy(to, from, n)
# if _MSC_VER >= 1200 // msvc++ 6.0 or greater
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STD_INCLUDES
# define SG_HAVE_STREAMBUF
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# define isnan _isnan
# define snprintf _snprintf
# define copysign _copysign
@@ -244,79 +77,23 @@
#endif // _MSC_VER
#ifdef __BORLANDC__
# if defined(HAVE_SGI_STL_PORT)
// Use quotes around long file names to get around Borland's include hackery
# define STL_ALGORITHM "algorithm"
# define STL_FUNCTIONAL "functional"
# define SG_MATH_EXCEPTION_CLASH
# else
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRSTREAM <strstream>
# define SG_INCOMPLETE_FUNCTIONAL
# endif // HAVE_SGI_STL_PORT
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STRING <string>
# define SG_NO_DEFAULT_TEMPLATE_ARGS
# define SG_NAMESPACES
// # define SG_HAVE_STD
# define SG_COMPILER_STR "Borland C++ version " SG_STRINGIZE(__BORLANDC__)
#endif // __BORLANDC__
//
// Native SGI compilers
//
#if defined ( sgi ) && !defined( __GNUC__ )
# define SG_HAVE_NATIVE_SGI_COMPILERS
# if (_COMPILER_VERSION < 740)
# error Need MipsPro 7.4.0 or higher now
# endif
# define SG_EXPLICIT_FUNCTION_TMPL_ARGS
# define SG_CLASS_PARTIAL_SPECIALIZATION
# define SG_NEED_AUTO_PTR
# define SG_MEMBER_TEMPLATES
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STREAMBUF
# define SG_HAVE_TRAITS
# define SG_HAVE_STD_INCLUDES
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
#if (_COMPILER_VERSION < 740)
# define STL_STRING <irix_string>
#else
# define STL_STRING <string>
#endif
# define STL_STRSTREAM <strstream>
#define SG_HAVE_NATIVE_SGI_COMPILERS
#pragma set woff 1001,1012,1014,1116,1155,1172,1174
#pragma set woff 1401,1460,1551,1552,1681
#ifdef __cplusplus
#pragma set woff 1682,3303
#if (_COMPILER_VERSION >= 740)
# pragma set woff 3624
#endif
# pragma set woff 1682,3303
# pragma set woff 3624
#endif
# define SG_COMPILER_STR "SGI MipsPro compiler version " SG_STRINGIZE(_COMPILER_VERSION)
@@ -346,24 +123,7 @@
// Intel C++ Compiler
//
#if defined(__ICC) || defined (__ECC)
# define SG_NAMESPACES
# define SG_HAVE_STD
# define SG_HAVE_STREAMBUF
# define SG_HAVE_TRAITS
# define SG_HAVE_STD_INCLUDES
# define STL_ALGORITHM <algorithm>
# define STL_FUNCTIONAL <functional>
# define STL_IOMANIP <iomanip>
# define STL_IOSTREAM <iostream>
# define STL_ITERATOR <iterator>
# define STL_FSTREAM <fstream>
# define STL_STDEXCEPT <stdexcept>
# define STL_STRING <string>
# define STL_STRSTREAM <strstream>
# define SG_COMPILER_STR "Intel C++ version " SG_STRINGIZE(__ICC)
#endif // __ICC
//
@@ -371,19 +131,9 @@
//
#ifdef __APPLE__
# define SG_GL_H <OpenGL/gl.h>
# define SG_GLX_H <AGL/agl.h>
# define SG_GLU_H <OpenGL/glu.h>
# define SG_GLEXT_H <OpenGL/glext.h>
# define SG_GLUT_H <GLUT/glut.h>
inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
#else
# define SG_GL_H <GL/gl.h>
# define SG_GLX_H <GL/glx.h>
# define SG_GLU_H <GL/glu.h>
# define SG_GLEXT_H <GL/glext.h>
# define SG_GLUT_H <GL/glut.h>
#endif
@@ -391,81 +141,5 @@ inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
// No user modifiable definitions beyond here.
//
#ifdef SG_NEED_EXPLICIT
# define explicit
#endif
#ifdef SG_NEED_TYPENAME
# define typename
#endif
#ifdef SG_NEED_MUTABLE
# define mutable
#endif
#ifdef SG_NEED_BOOL
typedef int bool;
# define true 1
# define false 0
#endif
#ifdef SG_EXPLICIT_FUNCTION_TMPL_ARGS
# define SG_NULL_TMPL_ARGS <>
#else
# define SG_NULL_TMPL_ARGS
#endif
#ifdef SG_CLASS_PARTIAL_SPECIALIZATION
# define SG_TEMPLATE_NULL template<>
#else
# define SG_TEMPLATE_NULL
#endif
// SG_NO_NAMESPACES is a hook so that users can disable namespaces
// without having to edit library headers.
#if defined(SG_NAMESPACES) && !defined(SG_NO_NAMESPACES)
# define SG_NAMESPACE(X) namespace X {
# define SG_NAMESPACE_END }
# define SG_USING_NAMESPACE(X) using namespace X
# else
# define SG_NAMESPACE(X)
# define SG_NAMESPACE_END
# define SG_USING_NAMESPACE(X)
#endif
/** \def SG_USING_STD(x)
* Expands to using std::x if SG_HAVE_STD is defined
*/
# ifdef SG_HAVE_STD
# define SG_USING_STD(X) using std::X
# define STD std
# else
# define SG_USING_STD(X)
# define STD
# endif
// Additional <functional> implementation from SGI STL 3.11
// Adapter function objects: pointers to member functions
#ifdef SG_INCOMPLETE_FUNCTIONAL
template <class _Ret, class _Tp>
class const_mem_fun_ref_t
#ifndef __BORLANDC__
: public unary_function<_Tp,_Ret>
#endif // __BORLANDC__
{
public:
explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) {}
_Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); }
private:
_Ret (_Tp::*_M_f)() const;
};
template <class _Ret, class _Tp>
inline const_mem_fun_ref_t<_Ret,_Tp> mem_fun_ref(_Ret (_Tp::*__f)() const)
{ return const_mem_fun_ref_t<_Ret,_Tp>(__f); }
#endif // SG_INCOMPLETE_FUNCTIONAL
#endif // _SG_COMPILER_H

View File

@@ -31,14 +31,8 @@
#include <simgear/compiler.h>
#ifdef SG_HAVE_STD_INCLUDES
# include <cmath>
#else
# ifdef SG_MATH_EXCEPTION_CLASH
# define exception C_exception
# endif
# include <math.h>
#endif
#include <cmath>
#include <plib/sg.h>
@@ -75,6 +69,8 @@
* 6378.165 but this is probably close enough */
#define SG_EARTH_RAD 6378.155
// Maximum terrain elevation from sea level
#define SG_MAX_ELEVATION_M 9000.0
// Earth parameters for WGS 84, taken from LaRCsim/ls_constants.h

View File

@@ -20,9 +20,11 @@
//
// $Id$
#include <iostream>
#include "logstream.hxx"
logstream *global_logstream = NULL;
logstream *logstream::global_logstream = 0;
bool logbuf::logging_enabled = true;
#ifdef _MSC_VER
@@ -32,6 +34,17 @@ sgDebugClass logbuf::logClass = SG_NONE;
sgDebugPriority logbuf::logPriority = SG_INFO;
streambuf* logbuf::sbuf = NULL;
namespace {
struct ignore_me
{
ignore_me()
{
logstream::initGlobalLogstream();
}
};
static ignore_me im;
}
logbuf::logbuf()
{
// if ( sbuf == NULL )
@@ -90,3 +103,12 @@ logstream::setLogLevels( sgDebugClass c, sgDebugPriority p )
logbuf::set_log_level( c, p );
}
logstream *
logstream::initGlobalLogstream()
{
// Force initialization of cerr.
static std::ios_base::Init initializer;
if( !global_logstream )
global_logstream = new logstream(std::cerr);
return global_logstream;
}

View File

@@ -31,25 +31,13 @@
# include <windows.h>
#endif
#ifdef SG_HAVE_STD_INCLUDES
# include <streambuf>
# include <iostream>
#else
# include <iostream.h>
# include <simgear/sg_traits.hxx>
#endif
#include <streambuf>
#include <ostream>
#include <simgear/debug/debug_types.h>
SG_USING_STD(streambuf);
SG_USING_STD(ostream);
SG_USING_STD(cout);
SG_USING_STD(cerr);
SG_USING_STD(endl);
#ifdef __MWERKS__
SG_USING_STD(iostream);
#endif
using std::streambuf;
using std::ostream;
//
// TODO:
@@ -67,17 +55,10 @@ SG_USING_STD(iostream);
#ifdef SG_NEED_STREAMBUF_HACK
class logbuf : public __streambuf
#else
class logbuf : public streambuf
class logbuf : public std::streambuf
#endif
{
public:
#ifndef SG_HAVE_STD_INCLUDES
typedef char_traits<char> traits_type;
typedef char_traits<char>::int_type int_type;
// typedef char_traits<char>::pos_type pos_type;
// typedef char_traits<char>::off_type off_type;
#endif
// logbuf( streambuf* sb ) : sbuf(sb) {}
/** Constructor */
logbuf();
@@ -97,6 +78,8 @@ public:
*/
void set_log_state( sgDebugClass c, sgDebugPriority p );
bool would_log( sgDebugClass c, sgDebugPriority p ) const;
/**
* Set the global logging level.
* @param c debug class
@@ -137,7 +120,7 @@ public:
* Set the stream buffer
* @param sb stream buffer
*/
void set_sb( streambuf* sb );
void set_sb( std::streambuf* sb );
#ifdef _MSC_VER
static void has_no_console() { has_console = false; }
@@ -155,7 +138,7 @@ protected:
private:
// The streambuf used for actual output. Defaults to cerr.rdbuf().
static streambuf* sbuf;
static std::streambuf* sbuf;
static bool logging_enabled;
#ifdef _MSC_VER
@@ -174,11 +157,7 @@ private:
inline int
logbuf::sync()
{
#ifdef SG_HAVE_STD_INCLUDES
return sbuf->pubsync();
#else
return sbuf->sync();
#endif
}
inline void
@@ -187,6 +166,12 @@ logbuf::set_log_state( sgDebugClass c, sgDebugPriority p )
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
}
inline bool
logbuf::would_log( sgDebugClass c, sgDebugPriority p ) const
{
return ((c & logClass) != 0 && p >= logPriority);
}
inline logbuf::int_type
logbuf::overflow( int c )
{
@@ -238,23 +223,23 @@ struct logstream_base
/**
* Class to manage the debug logging stream.
*/
class logstream : private logstream_base, public ostream
class logstream : private logstream_base, public std::ostream
{
public:
/**
* The default is to send messages to cerr.
* @param out output stream
*/
logstream( ostream& out )
logstream( std::ostream& out )
// : logstream_base(out.rdbuf()),
: logstream_base(),
ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
std::ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
/**
* Set the output stream
* @param out output stream
*/
void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
void set_output( std::ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
/**
* Set the global log class and priority level.
@@ -263,22 +248,29 @@ public:
*/
void setLogLevels( sgDebugClass c, sgDebugPriority p );
bool would_log( sgDebugClass c, sgDebugPriority p ) const
{
return lbuf.would_log( c, p );
};
/**
* Output operator to capture the debug level and priority of a message.
* @param l log level
*/
inline ostream& operator<< ( const loglevel& l );
inline std::ostream& operator<< ( const loglevel& l );
friend logstream& sglog();
static logstream *initGlobalLogstream();
protected:
static logstream *global_logstream;
};
inline ostream&
inline std::ostream&
logstream::operator<< ( const loglevel& l )
{
lbuf.set_log_state( l.logClass, l.logPriority );
return *this;
}
extern logstream *global_logstream;
/**
* \relates logstream
* Return the one and only logstream instance.
@@ -289,22 +281,7 @@ extern logstream *global_logstream;
inline logstream&
sglog()
{
if (global_logstream == NULL) {
#ifdef __APPLE__
/**
* There appears to be a bug in the C++ runtime in Mac OS X that
* will crash if certain funtions are called (in this case
* cerr.rdbuf()) during static initialization of a class. This
* print statement is hack to kick the library in the pants so it
* won't crash when cerr.rdbuf() is first called -DW
**/
cout << "Using Mac OS X hack for initializing C++ stdio..." << endl;
#endif
global_logstream = new logstream (cerr);
}
return *global_logstream;
return *logstream::initGlobalLogstream();
}
@@ -316,12 +293,15 @@ sglog()
*/
#ifdef FG_NDEBUG
# define SG_LOG(C,P,M)
#elif defined( __MWERKS__ )
# define SG_LOG(C,P,M) ::sglog() << ::loglevel(C,P) << M << std::endl
#else
# define SG_LOG(C,P,M) sglog() << loglevel(C,P) << M << endl
# define SG_LOG(C,P,M) do { \
logstream& __tmplogstreamref(sglog()); \
if(__tmplogstreamref.would_log(C,P)) { \
__tmplogstreamref << loglevel(C,P) << M << std::endl; } \
} while(0)
#endif
#define SG_ORIGIN __FILE__ ":" SG_STRINGIZE(__LINE__)
#endif // _LOGSTREAM_H

View File

@@ -2,8 +2,8 @@ includedir = @includedir@/environment
lib_LIBRARIES = libsgenvironment.a
include_HEADERS = metar.hxx visual_enviro.hxx
include_HEADERS = metar.hxx visual_enviro.hxx precipitation.hxx
libsgenvironment_a_SOURCES = metar.cxx visual_enviro.cxx
libsgenvironment_a_SOURCES = metar.cxx visual_enviro.cxx precipitation.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -493,7 +493,6 @@ bool SGMetar::scanVisibility()
distance = i;
} else {
// M?(\d{1,2}|\d{1,2}/\d{1,2}|\d{1,2} \d{1,2}/\d{1,2})(SM|KM)
modifier = 0;
if (*m == 'M')
m++, modifier = SGMetarVisibility::LESS_THAN;
@@ -1182,7 +1181,7 @@ const struct Token *SGMetar::scanToken(char **str, const struct Token *list)
{
const struct Token *longest = 0;
int maxlen = 0, len;
char *s;
const char *s;
for (int i = 0; (s = list[i].id); i++) {
len = strlen(s);
if (!strncmp(s, *str, len) && len > maxlen) {

View File

@@ -29,16 +29,16 @@
#include <simgear/constants.h>
SG_USING_STD(vector);
SG_USING_STD(map);
SG_USING_STD(string);
using std::vector;
using std::map;
using std::string;
const double SGMetarNaN = -1E20;
#define NaN SGMetarNaN
struct Token {
char *id;
char *text;
const char *id;
const char *text;
};
@@ -130,25 +130,21 @@ protected:
class SGMetarCloud {
friend class SGMetar;
public:
SGMetarCloud() :
_coverage(-1),
_altitude(NaN),
_type(0),
_type_long(0) {}
SGMetarCloud() : _coverage(-1), _altitude(NaN), _type(0), _type_long(0) {}
void set(double alt, int cov = -1);
inline int getCoverage() const { return _coverage; }
inline double getAltitude_m() const { return _altitude; }
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
inline char *getTypeString() const { return _type; }
inline char *getTypeLongString() const { return _type_long; }
inline int getCoverage() const { return _coverage; }
inline double getAltitude_m() const { return _altitude; }
inline double getAltitude_ft() const { return _altitude == NaN ? NaN : _altitude * SG_METER_TO_FEET; }
inline const char *getTypeString() const { return _type; }
inline const char *getTypeLongString() const { return _type_long; }
protected:
int _coverage; // quarters: 0 -> clear ... 4 -> overcast
double _altitude; // 1000 m
char *_type; // CU
char *_type_long; // cumulus
int _coverage; // quarters: 0 -> clear ... 4 -> overcast
double _altitude; // 1000 m
const char *_type; // CU
const char *_type_long; // cumulus
};

View File

@@ -0,0 +1,181 @@
/**
* @file precipitation.cxx
* @author Nicolas VIVIEN
* @date 2008-02-10
*
* @note Copyright (C) 2008 Nicolas VIVIEN
*
* @brief Precipitation effects to draw rain and snow.
*
* @par Licences
* 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.
*
*/
#include "precipitation.hxx"
#include "visual_enviro.hxx"
#include <simgear/constants.h>
/**
* @brief SGPrecipitation constructor
*
* Build a new OSG object from osgParticle.
*/
SGPrecipitation::SGPrecipitation() :
_freeze(false), _snow_intensity(0.0), _rain_intensity(0.0)
{
_precipitationEffect = new osgParticle::PrecipitationEffect;
}
/**
* @brief Build and add the object "precipitationEffect"
*
* This function permits you to create an object precipitationEffect and initialize it.
* I define by default the color of water (for raining)
*/
osg::Group* SGPrecipitation::build(void)
{
osg::Group* group = new osg::Group;
_precipitationEffect->snow(0);
_precipitationEffect->rain(0);
group->addChild(_precipitationEffect.get());
return group;
}
/**
* @brief Define the snow intensity
*
* This function permits you to define and change the snow intensity
* The param 'intensity' is normed (0 to 1).
*/
void SGPrecipitation::setSnowIntensity(float intensity)
{
if (this->_snow_intensity < intensity-0.001)
this->_snow_intensity += 0.001;
else if (this->_snow_intensity > intensity+0.001)
this->_snow_intensity -= 0.001;
else
this->_snow_intensity = intensity;
}
/**
* @brief Define the rain intensity
*
* This function permits you to define and change the rain intensity
* The param 'intensity' is normed (0 to 1).
*/
void SGPrecipitation::setRainIntensity(float intensity)
{
if (this->_rain_intensity < intensity-0.001)
this->_rain_intensity += 0.001;
else if (this->_rain_intensity > intensity+0.001)
this->_rain_intensity -= 0.001;
else
this->_rain_intensity = intensity;
}
/**
* @brief Freeze the rain to snow
*
* @param freeze Boolean
*
* This function permits you to turn off the rain to snow.
*/
void SGPrecipitation::setFreezing(bool freeze)
{
this->_freeze = freeze;
}
/**
* @brief Define the wind direction and speed
*
* This function permits you to define and change the wind direction
*
* After apply the MatrixTransform to the osg::Precipitation object,
* x points full south... From wind heading and speed, we can calculate
* the wind vector.
*/
void SGPrecipitation::setWindProperty(double heading, double speed)
{
double x, y, z;
heading = (heading + 180) * SGD_DEGREES_TO_RADIANS;
speed = speed * SG_FEET_TO_METER;
x = -cos(heading) * speed;
y = sin(heading) * speed;
z = 0;
this->_wind_vec = osg::Vec3(x, y, z);
}
/**
* @brief Update the precipitation effects
*
* This function permits you to update the precipitation effects.
* Be careful, if snow and rain intensity are greater than '0', snow effect
* will be first.
*
* The settings come from the osgParticule/PrecipitationEffect.cpp exemple.
*/
bool SGPrecipitation::update(void)
{
if (this->_freeze) {
if (this->_rain_intensity > 0)
this->_snow_intensity = this->_rain_intensity;
}
bool enabled = sgEnviro.get_precipitation_enable_state();
if (enabled && this->_snow_intensity > 0) {
_precipitationEffect->setWind(_wind_vec);
_precipitationEffect->setParticleSpeed( -0.75f - 0.25f*_snow_intensity);
_precipitationEffect->setParticleSize(0.02f + 0.03f*_snow_intensity);
_precipitationEffect->setMaximumParticleDensity(_snow_intensity * 7.2f);
_precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_snow_intensity), 5.0f / (0.25f+_snow_intensity), 5.0f));
_precipitationEffect->setNearTransition(25.f);
_precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_snow_intensity));
_precipitationEffect->setParticleColor(osg::Vec4(0.85, 0.85, 0.85, 1.0) - osg::Vec4(0.1, 0.1, 0.1, 1.0) * _snow_intensity);
} else if (enabled && this->_rain_intensity > 0) {
_precipitationEffect->setWind(_wind_vec);
_precipitationEffect->setParticleSpeed( -2.0f + -5.0f*_rain_intensity);
_precipitationEffect->setParticleSize(0.01 + 0.02*_rain_intensity);
_precipitationEffect->setMaximumParticleDensity(_rain_intensity * 7.5f);
_precipitationEffect->setCellSize(osg::Vec3(5.0f / (0.25f+_rain_intensity), 5.0f / (0.25f+_rain_intensity), 5.0f));
_precipitationEffect->setNearTransition(25.f);
_precipitationEffect->setFarTransition(100.0f - 60.0f*sqrtf(_rain_intensity));
_precipitationEffect->setParticleColor( osg::Vec4(0x7A, 0xCE, 0xFF, 0x80));
} else {
_precipitationEffect->snow(0);
_precipitationEffect->rain(0);
}
return true;
}

View File

@@ -0,0 +1,60 @@
/**
* @file precipitation.hxx
* @author Nicolas VIVIEN
* @date 2008-02-10
*
* @note Copyright (C) 2008 Nicolas VIVIEN
*
* @brief Precipitation effects to draw rain and snow.
*
* @par Licences
* 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 _PRECIPITATION_HXX
#define _PRECIPITATION_HXX
#include <osg/Group>
#include <osg/Referenced>
#include <osgParticle/PrecipitationEffect>
class SGPrecipitation : public osg::Referenced
{
private:
bool _freeze;
float _snow_intensity;
float _rain_intensity;
int _wind_dir;
osg::Vec3 _wind_vec;
osg::ref_ptr<osgParticle::PrecipitationEffect> _precipitationEffect;
public:
SGPrecipitation();
virtual ~SGPrecipitation() {}
osg::Group* build(void);
bool update(void);
void setWindProperty(double, double);
void setFreezing(bool);
void setRainIntensity(float);
void setSnowIntensity(float);
};
#endif

View File

@@ -1,9 +1,6 @@
// Visual environment helper class
//
// Written by Harald JOHNSEN, started April 2005.
// Minor changes/additions by Vivian Meazza Apr- May 2007
//
// Ported to OSG by Tim Moore Jun 2007
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
@@ -41,7 +38,7 @@
#include <vector>
SG_USING_STD(vector);
using std::vector;
typedef struct {
@@ -206,8 +203,6 @@ void SGEnviro::startOfFrame( sgVec3 p, sgVec3 up, double lon, double lat, double
return;
view_in_cloud = false;
// ask the impostor cache to do some cleanup
if(SGNewCloud::cldCache)
SGNewCloud::cldCache->startNewFrame();
last_cloud_turbulence = cloud_turbulence;
cloud_turbulence = 0.0;
elapsed_time += delta_time;
@@ -258,43 +253,10 @@ void SGEnviro::set_view_in_cloud(bool incloud) {
view_in_cloud = incloud;
}
int SGEnviro::get_CacheResolution(void) const {
return SGCloudField::get_CacheResolution();
}
int SGEnviro::get_clouds_CacheSize(void) const {
return SGCloudField::get_CacheSize();
}
float SGEnviro::get_clouds_visibility(void) const {
return SGCloudField::get_CloudVis();
}
float SGEnviro::get_clouds_density(void) const {
return SGCloudField::get_density();
}
bool SGEnviro::get_clouds_enable_state(void) const {
return SGCloudField::get_enable3dClouds();
}
bool SGEnviro::get_turbulence_enable_state(void) const {
return turbulence_enable_state;
}
void SGEnviro::set_CacheResolution(int resolutionPixels) {
SGCloudField::set_CacheResolution(resolutionPixels);
}
void SGEnviro::set_clouds_CacheSize(int sizeKb) {
SGCloudField::set_CacheSize(sizeKb);
}
void SGEnviro::set_clouds_visibility(float distance) {
SGCloudField::set_CloudVis(distance);
}
void SGEnviro::set_clouds_density(float density) {
SGCloudField::set_density(density);
}
void SGEnviro::set_clouds_enable_state(bool enable) {
SGCloudField::set_enable3dClouds(enable);
}
void SGEnviro::set_turbulence_enable_state(bool enable) {
turbulence_enable_state = enable;
}
@@ -333,8 +295,8 @@ void SGEnviro::setLight(sgVec4 adj_fog_color) {
// ssgGetLight( 0 ) -> setColour( GL_DIFFUSE, l->scene_diffuse() );
}
}
void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family, float dist, int cloudId) {
#if 0
void SGEnviro::callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId) {
// send data to wx radar
// compute turbulence
// draw precipitation
@@ -409,7 +371,7 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
// add to the list for the wxRadar instrument
if( LWC > 0.0 )
radarEcho.push_back( SGWxRadarEcho ( bearing, alt, radius, dist, 0.0 , LWC, false, cloudId, false ) );
radarEcho.push_back( SGWxRadarEcho ( heading, alt, radius, dist, LWC, false, cloudId ) );
// NB:data valid only from cockpit view
@@ -422,7 +384,7 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
orig.setlon(last_lon * SG_DEGREES_TO_RADIANS );
orig.setelev(0.0);
dist = sgSqrt(dist);
dest = calc_gc_lon_lat(orig, bearing, dist);
dest = calc_gc_lon_lat(orig, heading, dist);
lon = dest.lon() * SG_RADIANS_TO_DEGREES;
lat = dest.lat() * SG_RADIANS_TO_DEGREES;
addLightning( lon, lat, alt );
@@ -444,6 +406,8 @@ void SGEnviro::callback_cloud(float bearing, float alt, float radius, int family
}
}
#endif
list_of_SGWxRadarEcho *SGEnviro::get_radar_echo(void) {
return &radarEcho;
}
@@ -714,7 +678,7 @@ void SGLightning::lt_Render(void) {
glTranslatef( ax, ay, -sgEnviro.last_alt );
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, 0.0, age, true, 0, false ) );
sgEnviro.radarEcho.push_back( SGWxRadarEcho ( course, 0.0, 0.0, dist, age, true, 0 ) );
for( int n = 0 ; n < nb_tree ; n++ ) {
if( lt_tree[n].prev < 0 )

View File

@@ -1,9 +1,6 @@
// Visual environment helper class
//
// Written by Harald JOHNSEN, started April 2005.
// Minor changes/additions by Vivian Meazza Apr- May 2007
//
// Ported to OSG by Tim Moore Jun 2007
//
// Copyright (C) 2005 Harald JOHNSEN - hjohnsen@evc.net
//
@@ -28,11 +25,11 @@
#include <plib/sg.h>
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <vector>
SG_USING_STD(vector);
SG_USING_STD(string);
using std::vector;
using std::string;
class SGLightning;
class SGSoundMgr;
@@ -43,32 +40,24 @@ class SGSoundMgr;
*/
class SGWxRadarEcho {
public:
SGWxRadarEcho(float _bearing, float _alt, float _radius, float _dist, float _heading,
double _LWC, bool _lightning, int _cloudId, bool _aircraft) :
bearing (_bearing),
SGWxRadarEcho(float _heading, float _alt, float _radius, float _dist,
double _LWC, bool _lightning, int _cloudId ) :
heading( _heading ),
alt ( _alt ),
radius ( _radius ),
dist ( _dist ),
LWC ( _LWC ),
lightning ( _lightning ),
aircraft ( _aircraft ),
cloudId ( _cloudId )
{}
/** the heading and bearing in radian are versus north */
float bearing, heading;
/** the heading in radian is versus north */
float heading;
float alt, radius, dist;
/** reflectivity converted to liquid water content. */
double LWC;
/** if true then this data is for a lightning else it is for water echo. */
bool lightning;
/** if true then this data is for an aircraft */
bool aircraft;
bool lightning;
/** Unique identifier of cloud */
int cloudId;
};
@@ -136,6 +125,7 @@ public:
void endOfFrame(void);
#if 0
/**
* Whenever a cloud is drawn we check his 'impact' on the environment.
* @param heading direction of cloud in radians
@@ -145,7 +135,7 @@ public:
* @param dist squared dist to cloud in meters
*/
void callback_cloud(float heading, float alt, float radius, int family, float dist, int cloudId);
#endif
void drawRain(double pitch, double roll, double heading, double hspeed, double rain_norm);
/**
* Draw rain or snow precipitation around the viewer.

View File

@@ -24,9 +24,6 @@
#include <simgear/debug/logstream.hxx>
#ifdef SG_MATH_EXCEPTION_CLASH
# define exception c_exception
#endif
#include <math.h>
#include "celestialBody.hxx"

View File

@@ -22,10 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include "jupiter.hxx"

View File

@@ -22,9 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include "mars.hxx"

View File

@@ -22,9 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include "mercury.hxx"

View File

@@ -27,9 +27,6 @@
#include <simgear/debug/logstream.hxx>
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
// #include <FDM/flight.hxx>

View File

@@ -22,9 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include "saturn.hxx"

View File

@@ -22,10 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include <simgear/debug/logstream.hxx>

View File

@@ -31,7 +31,7 @@
#include "stardata.hxx"
#if defined (_MSC_VER)
SG_USING_STD(getline);
using std::getline;
#endif
// Constructor

View File

@@ -22,9 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include "uranus.hxx"

View File

@@ -22,9 +22,6 @@
* $Id$
**************************************************************************/
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#include "venus.hxx"

View File

@@ -27,7 +27,7 @@ noinst_PROGRAMS = decode_binobj socktest lowtest tcp_server tcp_client
tcp_server_SOURCES = tcp_server.cxx
tcp_server_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
@@ -38,7 +38,7 @@ tcp_server_LDADD = \
tcp_client_SOURCES = tcp_client.cxx
tcp_client_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
@@ -49,7 +49,7 @@ tcp_client_LDADD = \
socktest_SOURCES = socktest.cxx
socktest_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
@@ -60,7 +60,7 @@ socktest_LDADD = \
lowtest_SOURCES = lowtest.cxx
lowtest_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
@@ -69,7 +69,7 @@ lowtest_LDADD = \
decode_binobj_SOURCES = decode_binobj.cxx
decode_binobj_LDADD = \
$(top_builddir)/simgear/io/libsgio.a \
libsgio.a \
$(top_builddir)/simgear/debug/libsgdebug.a \
$(top_builddir)/simgear/bucket/libsgbucket.a \
$(top_builddir)/simgear/misc/libsgmisc.a \

View File

@@ -5,12 +5,12 @@
#include <simgear/compiler.h>
#include <unistd.h>
#include STL_IOSTREAM
#include <iostream>
#include "sg_binobj.hxx"
SG_USING_STD(cout);
SG_USING_STD(endl);
using std::cout;
using std::endl;
int main( int argc, char **argv ) {

View File

@@ -32,11 +32,11 @@
// #include "protocol.hxx"
#include STL_STRING
#include <string>
#include <vector>
SG_USING_STD(vector);
SG_USING_STD(string);
using std::vector;
using std::string;
#define SG_IO_MAX_MSG_SIZE 16384

View File

@@ -1,6 +1,6 @@
#include <simgear/compiler.h>
#include STL_IOSTREAM
#include <iostream>
#include "lowlevel.hxx"
@@ -8,8 +8,8 @@ static const int sgEndianTest = 1;
#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
SG_USING_STD(cout);
SG_USING_STD(endl);
using std::cout;
using std::endl;
int main() {

View File

@@ -33,7 +33,8 @@
#include <time.h>
#include <vector>
#include STL_STRING
#include <string>
#include <iostream>
#include <simgear/bucket/newbucket.hxx>
#include <simgear/misc/sg_path.hxx>
@@ -42,9 +43,10 @@
#include "sg_binobj.hxx"
SG_USING_STD( string );
SG_USING_STD( vector );
using std::string;
using std::vector;
using std::cout;
using std::endl;
enum sgObjectTypes {
SG_BOUNDING_SPHERE = 0,
@@ -364,18 +366,32 @@ bool SGBinObject::read_bin( const string& file ) {
#endif
// read number of top level objects
short nobjects;
sgReadShort( fp, &nobjects );
unsigned short nobjects;
if ( version >= 7 ) {
sgReadUShort( fp, &nobjects );
} else {
short tmp;
sgReadShort( fp, &tmp );
nobjects = tmp;
}
// cout << "Total objects to read = " << nobjects << endl;
// read in objects
for ( i = 0; i < nobjects; ++i ) {
// read object header
char obj_type;
short nproperties, nelements;
unsigned short nproperties, nelements;
sgReadChar( fp, &obj_type );
sgReadShort( fp, &nproperties );
sgReadShort( fp, &nelements );
if ( version >= 7 ) {
sgReadUShort( fp, &nproperties );
sgReadUShort( fp, &nelements );
} else {
short tmp;
sgReadShort( fp, &tmp );
nproperties = tmp;
sgReadShort( fp, &tmp );
nelements = tmp;
}
// cout << "object " << i << " = " << (int)obj_type << " props = "
// << nproperties << " elements = " << nelements << endl;
@@ -649,7 +665,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
string material;
int start;
int end;
short nobjects = 0;
unsigned short nobjects = 0;
nobjects++; // for gbs
nobjects++; // for vertices
nobjects++; // for colors
@@ -657,7 +673,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects++; // for texcoords
// points
short npts = 0;
unsigned short npts = 0;
start = 0; end = 1;
while ( start < (int)pt_materials.size() ) {
material = pt_materials[start];
@@ -671,7 +687,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += npts;
// tris
short ntris = 0;
unsigned short ntris = 0;
start = 0; end = 1;
while ( start < (int)tri_materials.size() ) {
material = tri_materials[start];
@@ -685,7 +701,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += ntris;
// strips
short nstrips = 0;
unsigned short nstrips = 0;
start = 0; end = 1;
while ( start < (int)strip_materials.size() ) {
material = strip_materials[start];
@@ -699,7 +715,7 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += nstrips;
// fans
short nfans = 0;
unsigned short nfans = 0;
start = 0; end = 1;
while ( start < (int)fan_materials.size() ) {
material = fan_materials[start];
@@ -713,12 +729,12 @@ bool SGBinObject::write_bin( const string& base, const string& name,
nobjects += nfans;
cout << "total top level objects = " << nobjects << endl;
sgWriteShort( fp, nobjects );
sgWriteUShort( fp, nobjects );
// write bounding sphere
sgWriteChar( fp, (char)SG_BOUNDING_SPHERE ); // type
sgWriteShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUShort( fp, 0 ); // nproperties
sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, sizeof(double) * 3 + sizeof(float) ); // nbytes
sgdVec3 center;
@@ -728,8 +744,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump vertex list
sgWriteChar( fp, (char)SG_VERTEX_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUShort( fp, 0 ); // nproperties
sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, wgs84_nodes.size() * sizeof(float) * 3 ); // nbytes
for ( i = 0; i < (int)wgs84_nodes.size(); ++i ) {
SGVec3f p = toVec3f(wgs84_nodes[i] - gbs_center);
@@ -738,8 +754,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump vertex color list
sgWriteChar( fp, (char)SG_COLOR_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUShort( fp, 0 ); // nproperties
sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, colors.size() * sizeof(float) * 4 ); // nbytes
for ( i = 0; i < (int)colors.size(); ++i ) {
sgWriteVec4( fp, colors[i].data() );
@@ -747,8 +763,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump vertex normal list
sgWriteChar( fp, (char)SG_NORMAL_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUShort( fp, 0 ); // nproperties
sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, normals.size() * 3 ); // nbytes
char normal[3];
for ( i = 0; i < (int)normals.size(); ++i ) {
@@ -761,8 +777,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// dump texture coordinates
sgWriteChar( fp, (char)SG_TEXCOORD_LIST ); // type
sgWriteShort( fp, 0 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUShort( fp, 0 ); // nproperties
sgWriteUShort( fp, 1 ); // nelements
sgWriteUInt( fp, texcoords.size() * sizeof(float) * 2 ); // nbytes
for ( i = 0; i < (int)texcoords.size(); ++i ) {
sgWriteVec2( fp, texcoords[i].data() );
@@ -786,8 +802,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_POINTS ); // type
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements
sgWriteUShort( fp, 2 ); // nproperties
sgWriteUShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
@@ -806,19 +822,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write strips
for ( i = start; i < end; ++i ) {
// nbytes
sgWriteUInt( fp, pts_v[i].size() * idx_size * sizeof(short) );
sgWriteUInt( fp, pts_v[i].size() * idx_size
* sizeof(unsigned short) );
for ( j = 0; j < (int)pts_v[i].size(); ++j ) {
if ( pts_v.size() ) {
sgWriteShort( fp, (short)pts_v[i][j] );
sgWriteUShort( fp, (unsigned short)pts_v[i][j] );
}
if ( pts_n.size() ) {
sgWriteShort( fp, (short)pts_n[i][j] );
sgWriteUShort( fp, (unsigned short)pts_n[i][j] );
}
if ( pts_c.size() ) {
sgWriteShort( fp, (short)pts_c[i][j] );
sgWriteUShort( fp, (unsigned short)pts_c[i][j] );
}
if ( pts_tc.size() ) {
sgWriteShort( fp, (short)pts_tc[i][j] );
sgWriteUShort( fp, (unsigned short)pts_tc[i][j] );
}
}
}
@@ -847,8 +864,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_FACES ); // type
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, 1 ); // nelements
sgWriteUShort( fp, 2 ); // nproperties
sgWriteUShort( fp, 1 ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
@@ -865,22 +882,23 @@ bool SGBinObject::write_bin( const string& base, const string& name,
sgWriteChar( fp, idx_mask );
// nbytes
sgWriteUInt( fp, (end - start) * 3 * idx_size * sizeof(short) );
sgWriteUInt( fp, (end - start) * 3 * idx_size
* sizeof(unsigned short) );
// write group
for ( i = start; i < end; ++i ) {
for ( j = 0; j < 3; ++j ) {
if ( tris_v.size() ) {
sgWriteShort( fp, (short)tris_v[i][j] );
sgWriteUShort( fp, (unsigned short)tris_v[i][j] );
}
if ( tris_n.size() ) {
sgWriteShort( fp, (short)tris_n[i][j] );
sgWriteUShort( fp, (unsigned short)tris_n[i][j] );
}
if ( tris_c.size() ) {
sgWriteShort( fp, (short)tris_c[i][j] );
sgWriteUShort( fp, (unsigned short)tris_c[i][j] );
}
if ( tris_tc.size() ) {
sgWriteShort( fp, (short)tris_tc[i][j] );
sgWriteUShort( fp, (unsigned short)tris_tc[i][j] );
}
}
}
@@ -908,8 +926,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_STRIPS ); // type
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements
sgWriteUShort( fp, 2 ); // nproperties
sgWriteUShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
@@ -928,19 +946,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write strips
for ( i = start; i < end; ++i ) {
// nbytes
sgWriteUInt( fp, strips_v[i].size() * idx_size * sizeof(short));
sgWriteUInt( fp, strips_v[i].size() * idx_size
* sizeof(unsigned short));
for ( j = 0; j < (int)strips_v[i].size(); ++j ) {
if ( strips_v.size() ) {
sgWriteShort( fp, (short)strips_v[i][j] );
sgWriteUShort( fp, (unsigned short)strips_v[i][j] );
}
if ( strips_n.size() ) {
sgWriteShort( fp, (short)strips_n[i][j] );
sgWriteUShort( fp, (unsigned short)strips_n[i][j] );
}
if ( strips_c.size() ) {
sgWriteShort( fp, (short)strips_c[i][j] );
sgWriteUShort( fp, (unsigned short)strips_c[i][j] );
}
if ( strips_tc.size() ) {
sgWriteShort( fp, (short)strips_tc[i][j] );
sgWriteUShort( fp, (unsigned short)strips_tc[i][j] );
}
}
}
@@ -968,8 +987,8 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write group headers
sgWriteChar( fp, (char)SG_TRIANGLE_FANS ); // type
sgWriteShort( fp, 2 ); // nproperties
sgWriteShort( fp, end - start ); // nelements
sgWriteUShort( fp, 2 ); // nproperties
sgWriteUShort( fp, end - start ); // nelements
sgWriteChar( fp, (char)SG_MATERIAL ); // property
sgWriteUInt( fp, material.length() ); // nbytes
@@ -988,19 +1007,20 @@ bool SGBinObject::write_bin( const string& base, const string& name,
// write fans
for ( i = start; i < end; ++i ) {
// nbytes
sgWriteUInt( fp, fans_v[i].size() * idx_size * sizeof(short) );
sgWriteUInt( fp, fans_v[i].size() * idx_size
* sizeof(unsigned short) );
for ( j = 0; j < (int)fans_v[i].size(); ++j ) {
if ( fans_v.size() ) {
sgWriteShort( fp, (short)fans_v[i][j] );
sgWriteUShort( fp, (unsigned short)fans_v[i][j] );
}
if ( fans_n.size() ) {
sgWriteShort( fp, (short)fans_n[i][j] );
sgWriteUShort( fp, (unsigned short)fans_n[i][j] );
}
if ( fans_c.size() ) {
sgWriteShort( fp, (short)fans_c[i][j] );
sgWriteUShort( fp, (unsigned short)fans_c[i][j] );
}
if ( fans_tc.size() ) {
sgWriteShort( fp, (short)fans_tc[i][j] );
sgWriteUShort( fp, (unsigned short)fans_tc[i][j] );
}
}
}

View File

@@ -39,7 +39,7 @@
#include <time.h>
#include <list>
#include STL_STRING
#include <string>
@@ -74,9 +74,9 @@ typedef group_list::const_iterator const_group_list_iterator;
*
* - prop_typecode: material_name | ???
*
* - nelements: SHORT (Gives us 65536 which ought to be enough, right?)
* - nelements: USHORT (Gives us 65536 which ought to be enough, right?)
*
* - nproperties: SHORT
* - nproperties: USHORT
*
* - *_typecode: CHAR
*

View File

@@ -23,24 +23,26 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#if defined(_MSC_VER) || defined(__MINGW32__)
# include <io.h>
#endif
#include <cstring>
#include <simgear/misc/stdint.hxx>
#include <simgear/debug/logstream.hxx>
#include "sg_file.hxx"
SG_USING_STD(string);
using std::string;
SGFile::SGFile( const string &file) {
SGFile::SGFile(const string &file, int repeat_)
: file_name(file), fp(-1), eof_flag(true), repeat(repeat_), iteration(0)
{
set_type( sgFileType );
file_name = file;
eof_flag = true;
}
@@ -82,7 +84,20 @@ int SGFile::read( char *buf, int length ) {
// read a chunk
ssize_t result = ::read( fp, buf, length );
if ( length > 0 && result == 0 ) {
eof_flag = true;
if (repeat < 0 || iteration < repeat - 1) {
iteration++;
// loop reading the file, unless it is empty
off_t fileLen = ::lseek(fp, 0, SEEK_CUR);
if (fileLen == 0) {
eof_flag = true;
return 0;
} else {
::lseek(fp, 0, SEEK_SET);
return ::read(fp, buf, length);
}
} else {
eof_flag = true;
}
}
return result;
}
@@ -96,7 +111,13 @@ int SGFile::readline( char *buf, int length ) {
// read a chunk
ssize_t result = ::read( fp, buf, length );
if ( length > 0 && result == 0 ) {
eof_flag = true;
if ((repeat < 0 || iteration < repeat - 1) && pos != 0) {
iteration++;
pos = ::lseek(fp, 0, SEEK_SET);
result = ::read(fp, buf, length);
} else {
eof_flag = true;
}
}
// find the end of line and reset position
@@ -129,7 +150,7 @@ int SGFile::write( const char *buf, const int length ) {
// write null terminated string to a file
int SGFile::writestring( const char *str ) {
int length = strlen( str );
int length = std::strlen( str );
return write( str, length );
}

View File

@@ -44,7 +44,7 @@
#include "iochannel.hxx"
SG_USING_STD(string);
using std::string;
/**
@@ -55,6 +55,10 @@ class SGFile : public SGIOChannel {
string file_name;
int fp;
bool eof_flag;
// Number of repetitions to play. -1 means loop infinitely.
const int repeat;
int iteration; // number of current repetition,
// starting at 0
public:
@@ -64,8 +68,9 @@ public:
* name. This file is not opened immediately, but instead will be
* opened when the open() method is called.
* @param file name of file to open
* @param repeat On eof restart at the beginning of the file
*/
SGFile( const string& file );
SGFile( const string& file, int repeat_ = 1 );
/** Destructor */
~SGFile();

View File

@@ -20,17 +20,19 @@
//
// $Id$
#include <cstdlib>
#include <cstring>
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <simgear/debug/logstream.hxx>
#include <simgear/serial/serial.hxx>
#include "sg_serial.hxx"
SG_USING_STD(string);
using std::string;
SGSerial::SGSerial( const string& device_name, const string& baud_rate ) :
@@ -57,7 +59,7 @@ bool SGSerial::open( const SGProtocolDir d ) {
// cout << "fd = " << port.fd << endl;
if ( ! port.set_baud( atoi( baud.c_str() ) ) ) {
if ( ! port.set_baud( std::atoi( baud.c_str() ) ) ) {
SG_LOG( SG_IO, SG_ALERT, "Error setting baud: " << baud );
return false;
}
@@ -80,7 +82,7 @@ int SGSerial::read( char *buf, int length ) {
result = port.read_port( buf_ptr, length - save_len );
if ( result + save_len == length ) {
strncpy( buf, save_buf, length );
std::strncpy( buf, save_buf, length );
save_len = 0;
return length;
@@ -114,7 +116,7 @@ int SGSerial::readline( char *buf, int length ) {
// we found an end of line
// copy to external buffer
strncpy( buf, save_buf, result );
std::strncpy( buf, save_buf, result );
buf[result] = '\0';
SG_LOG( SG_IO, SG_INFO, "fg_serial line = " << buf );
@@ -142,7 +144,7 @@ int SGSerial::write( const char *buf, const int length ) {
// write null terminated string to port
int SGSerial::writestring( const char *str ) {
int length = strlen( str );
int length = std::strlen( str );
return write( str, length );
}

View File

@@ -36,17 +36,11 @@
#include <string>
// #ifdef SG_HAVE_STD_INCLUDES
// # include <ctime>
// #else
// # include <time.h>
// #endif
#include <simgear/serial/serial.hxx>
#include "iochannel.hxx"
SG_USING_STD(string);
using std::string;
/**
* A serial I/O class based on SGIOChannel.

View File

@@ -31,7 +31,7 @@
#include <strings.h>
#endif
#include STL_IOSTREAM
#include <iostream>
#include <simgear/debug/logstream.hxx>

View File

@@ -34,14 +34,14 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <simgear/math/sg_types.hxx>
#include <simgear/io/iochannel.hxx>
#include <plib/netSocket.h>
SG_USING_STD(string);
using std::string;
#define SG_MAX_SOCKET_QUEUE 32

View File

@@ -36,12 +36,12 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <simgear/math/sg_types.hxx>
#include <simgear/io/iochannel.hxx>
SG_USING_STD(string);
using std::string;
/**
* A UDP socket I/O class based on SGIOChannel and plib/net.

View File

@@ -5,7 +5,7 @@
#include <simgear/compiler.h>
#include <unistd.h>
#include STL_IOSTREAM
#include <iostream>
#include "sg_socket.hxx"
#include "lowlevel.hxx"
@@ -14,8 +14,8 @@ static const int sgEndianTest = 1;
#define sgIsLittleEndian (*((char *) &sgEndianTest ) != 0)
#define sgIsBigEndian (*((char *) &sgEndianTest ) == 0)
SG_USING_STD(cout);
SG_USING_STD(endl);
using std::cout;
using std::endl;
int main() {

View File

@@ -1,5 +1,5 @@
#include <simgear/compiler.h>
#include STL_IOSTREAM
#include <iostream>
#ifdef _WIN32
#include <windows.h>
@@ -7,6 +7,8 @@
#include <unistd.h>
#endif
#include <iostream>
#include <simgear/debug/logstream.hxx>
#include "sg_socket.hxx"
@@ -49,7 +51,7 @@ TcpClient::process()
sprintf( wbuf, "hello world\n" );
int length = channel->writestring( wbuf );
cout << "writestring returned " << length << "\n";
std::cout << "writestring returned " << length << "\n";
return true;
}
@@ -67,7 +69,7 @@ main()
TcpClient client( "localhost", "5500" );
if (!client.open())
{
cout << "client open failed\n";
std::cout << "client open failed\n";
return 0;
}

View File

@@ -1,12 +1,12 @@
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#include STL_STRING
#include STL_IOSTREAM
#include <string>
#include <iostream>
#include "sg_socket.hxx"
SG_USING_STD(string);
SG_USING_STD(cout);
using std::string;
using std::cout;
class TcpServer
{

View File

@@ -13,7 +13,7 @@ noinst_PROGRAMS = testmagvar
testmagvar_SOURCES = testmagvar.cxx
testmagvar_LDADD = \
$(top_builddir)/simgear/magvar/libsgmagvar.a \
libsgmagvar.a \
$(base_LIBS)
INCLUDES = -I$(top_srcdir)

View File

@@ -86,8 +86,6 @@
#include "coremag.hxx"
static const double pi = 3.14159265358979;
static const double a = 6378.137; /* semi-major axis (equatorial radius) of WGS84 ellipsoid */
static const double b = 6356.7523142; /* semi-minor axis referenced to the WGS84 ellipsoid */
static const double r_0 = 6371.2; /* standard Earth magnetic reference radius */
@@ -325,7 +323,7 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
}
/* Find geodetic field components: */
psi = theta - ((pi / 2.0) - lat);
psi = theta - ((M_PI / 2.0) - lat);
sinpsi = sin(psi);
cospsi = cos(psi);
X = -B_theta * cospsi - B_r * sinpsi;

View File

@@ -17,10 +17,10 @@ include_HEADERS = \
point3d.hxx \
polar3d.hxx \
sg_geodesy.hxx \
sg_memory.h \
sg_random.h \
sg_types.hxx \
vector.hxx \
Math.hxx \
SGBox.hxx \
SGCMath.hxx \
SGGeoc.hxx \
@@ -47,10 +47,9 @@ include_HEADERS = \
libsgmath_a_SOURCES = \
interpolater.cxx \
leastsqs.cxx \
polar3d.cxx \
sg_geodesy.cxx \
sg_random.c \
vector.cxx \
SGGeod.cxx \
SGGeodesy.cxx
INCLUDES = -I$(top_srcdir)

23
simgear/math/Math.hxx Normal file
View File

@@ -0,0 +1,23 @@
#ifndef SIMGEAR_MATH_MATH_HXX
#define SIMGEAR_MATH_MATH_HXX 1
namespace simgear
{
namespace math
{
/** Linear interpolation between two values.
*/
template<typename T>
inline T lerp(const T& x, const T& y, double alpha)
{
return x * (1.0 - alpha) + y * alpha;
}
template<typename T>
inline T lerp(const T& x, const T& y, float alpha)
{
return x * (1.0f - alpha) + y * alpha;
}
}
}
#endif

View File

@@ -20,12 +20,6 @@
#include <simgear/compiler.h>
#ifdef SG_HAVE_STD_INCLUDES
// We have cmath from the standard c++ lib available
#include <cmath>
#else
// We only have math.h with the c89 double functions.
#include <math.h>
#endif
#endif

View File

@@ -74,6 +74,11 @@ public:
/// Set the geocentric radius from the argument given in feet
void setRadiusFt(double radius);
SGGeoc advanceRadM(double course, double distance) const;
static double courseRad(const SGGeoc& from, const SGGeoc& to);
static double courseDeg(const SGGeoc& from, const SGGeoc& to);
static double distanceM(const SGGeoc& from, const SGGeoc& to);
private:
/// This one is private since construction is not unique if you do
/// not know the units of the arguments, use the factory methods for
@@ -201,7 +206,7 @@ SGGeoc::getLongitudeDeg(void) const
#ifdef SG_GEOC_NATIVE_DEGREE
return _lon;
#else
return _lon*SGD_DEGREES_TO_RADIANS;
return _lon*SGD_RADIANS_TO_DEGREES;
#endif
}
@@ -212,7 +217,7 @@ SGGeoc::setLongitudeDeg(double lon)
#ifdef SG_GEOC_NATIVE_DEGREE
_lon = lon;
#else
_lon = lon*SGD_RADIANS_TO_DEGREES;
_lon = lon*SGD_DEGREES_TO_RADIANS;
#endif
}
@@ -245,7 +250,7 @@ SGGeoc::getLatitudeDeg(void) const
#ifdef SG_GEOC_NATIVE_DEGREE
return _lat;
#else
return _lat*SGD_DEGREES_TO_RADIANS;
return _lat*SGD_RADIANS_TO_DEGREES;
#endif
}
@@ -256,7 +261,7 @@ SGGeoc::setLatitudeDeg(double lat)
#ifdef SG_GEOC_NATIVE_DEGREE
_lat = lat;
#else
_lat = lat*SGD_RADIANS_TO_DEGREES;
_lat = lat*SGD_DEGREES_TO_RADIANS;
#endif
}
@@ -288,6 +293,36 @@ SGGeoc::setRadiusFt(double radius)
_radius = radius*SG_FEET_TO_METER;
}
inline
SGGeoc
SGGeoc::advanceRadM(double course, double distance) const
{
SGGeoc result;
SGGeodesy::advanceRadM(*this, course, distance, result);
return result;
}
inline
double
SGGeoc::courseRad(const SGGeoc& from, const SGGeoc& to)
{
return SGGeodesy::courseRad(from, to);
}
inline
double
SGGeoc::courseDeg(const SGGeoc& from, const SGGeoc& to)
{
return SGMiscd::rad2deg(courseRad(from, to));
}
inline
double
SGGeoc::distanceM(const SGGeoc& from, const SGGeoc& to)
{
return SGGeodesy::distanceM(from, to);
}
/// Output to an ostream
template<typename char_type, typename traits_type>
inline

51
simgear/math/SGGeod.cxx Normal file
View File

@@ -0,0 +1,51 @@
// Copyright (C) 2008 Tim Moore timoore@redhat.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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.
//
#include "SGMath.hxx"
osg::Matrix SGGeod::makeSimulationFrameRelative()
{
SGQuatd hlOr = SGQuatd::fromLonLat(*this);
return osg::Matrix(hlOr.osg());
}
osg::Matrix SGGeod::makeSimulationFrame()
{
osg::Matrix result(makeSimulationFrameRelative());
SGVec3d coord;
SGGeodesy::SGGeodToCart(*this, coord);
result.setTrans(coord.osg());
return result;
}
osg::Matrix SGGeod::makeZUpFrameRelative()
{
osg::Matrix result(makeSimulationFrameRelative());
// 180 degree rotation around Y axis
osg::Quat flip(0.0, 1.0, 0.0, 0.0);
result.preMult(osg::Matrix(flip));
return result;
}
osg::Matrix SGGeod::makeZUpFrame()
{
osg::Matrix result(makeZUpFrameRelative());
SGVec3d coord;
SGGeodesy::SGGeodToCart(*this, coord);
result.setTrans(coord.osg());
return result;
}

View File

@@ -20,6 +20,8 @@
#include <simgear/constants.h>
#include <osg/Matrix>
// #define SG_GEOD_NATIVE_DEGREE
/// Class representing a geodetic location
@@ -78,6 +80,18 @@ public:
/// Set the geodetic elevation from the argument given in feet
void setElevationFt(double elevation);
// Create a local coordinate frame in the earth-centered frame of
// reference. X points north, Z points down.
// makeSimulationFrameRelative() only includes rotation.
osg::Matrix makeSimulationFrameRelative();
osg::Matrix makeSimulationFrame();
// Create a Z-up local coordinate frame in the earth-centered frame
// of reference. This is what scenery models, etc. expect.
// makeZUpFrameRelative() only includes rotation.
osg::Matrix makeZUpFrameRelative();
osg::Matrix makeZUpFrame();
private:
/// This one is private since construction is not unique if you do
/// not know the units of the arguments. Use the factory methods for

View File

@@ -155,3 +155,346 @@ SGGeodesy::SGGeocToCart(const SGGeoc& geoc, SGVec3<double>& cart)
double clon = cos(lon);
cart = geoc.getRadiusM()*SGVec3<double>(clat*clon, clat*slon, slat);
}
// Notes:
//
// The XYZ/cartesian coordinate system in use puts the X axis through
// zero lat/lon (off west Africa), the Z axis through the north pole,
// and the Y axis through 90 degrees longitude (in the Indian Ocean).
//
// All latitude and longitude values are in radians. Altitude is in
// meters, with zero on the WGS84 ellipsoid.
//
// The code below makes use of the notion of "squashed" space. This
// is a 2D cylindrical coordinate system where the radius from the Z
// axis is multiplied by SQUASH; the earth in this space is a perfect
// circle with a radius of POLRAD.
////////////////////////////////////////////////////////////////////////
//
// Direct and inverse distance functions
//
// Proceedings of the 7th International Symposium on Geodetic
// Computations, 1985
//
// "The Nested Coefficient Method for Accurate Solutions of Direct and
// Inverse Geodetic Problems With Any Length"
//
// Zhang Xue-Lian
// pp 747-763
//
// modified for FlightGear to use WGS84 only -- Norman Vine
static inline double M0( double e2 ) {
//double e4 = e2*e2;
return SGMiscd::pi()*0.5*(1.0 - e2*( 1.0/4.0 + e2*( 3.0/64.0 +
e2*(5.0/256.0) )));
}
// given, lat1, lon1, az1 and distance (s), calculate lat2, lon2
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
static int _geo_direct_wgs_84 ( double lat1, double lon1, double az1,
double s, double *lat2, double *lon2,
double *az2 )
{
double a = SGGeodesy::EQURAD, rf = SGGeodesy::iFLATTENING;
double testv = 1.0E-10;
double f = ( rf > 0.0 ? 1.0/rf : 0.0 );
double b = a*(1.0-f);
double e2 = f*(2.0-f);
double phi1 = SGMiscd::deg2rad(lat1), lam1 = SGMiscd::deg2rad(lon1);
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
double azm1 = SGMiscd::deg2rad(az1);
double sinaz1 = sin(azm1), cosaz1 = cos(azm1);
if( fabs(s) < 0.01 ) { // distance < centimeter => congruency
*lat2 = lat1;
*lon2 = lon1;
*az2 = 180.0 + az1;
if( *az2 > 360.0 ) *az2 -= 360.0;
return 0;
} else if( SGLimitsd::min() < fabs(cosphi1) ) { // non-polar origin
// u1 is reduced latitude
double tanu1 = sqrt(1.0-e2)*sinphi1/cosphi1;
double sig1 = atan2(tanu1,cosaz1);
double cosu1 = 1.0/sqrt( 1.0 + tanu1*tanu1 ), sinu1 = tanu1*cosu1;
double sinaz = cosu1*sinaz1, cos2saz = 1.0-sinaz*sinaz;
double us = cos2saz*e2/(1.0-e2);
// Terms
double ta = 1.0+us*(4096.0+us*(-768.0+us*(320.0-175.0*us)))/16384.0,
tb = us*(256.0+us*(-128.0+us*(74.0-47.0*us)))/1024.0,
tc = 0;
// FIRST ESTIMATE OF SIGMA (SIG)
double first = s/(b*ta); // !!
double sig = first;
double c2sigm, sinsig,cossig, temp,denom,rnumer, dlams, dlam;
do {
c2sigm = cos(2.0*sig1+sig);
sinsig = sin(sig); cossig = cos(sig);
temp = sig;
sig = first +
tb*sinsig*(c2sigm+tb*(cossig*(-1.0+2.0*c2sigm*c2sigm) -
tb*c2sigm*(-3.0+4.0*sinsig*sinsig)
*(-3.0+4.0*c2sigm*c2sigm)/6.0)
/4.0);
} while( fabs(sig-temp) > testv);
// LATITUDE OF POINT 2
// DENOMINATOR IN 2 PARTS (TEMP ALSO USED LATER)
temp = sinu1*sinsig-cosu1*cossig*cosaz1;
denom = (1.0-f)*sqrt(sinaz*sinaz+temp*temp);
// NUMERATOR
rnumer = sinu1*cossig+cosu1*sinsig*cosaz1;
*lat2 = SGMiscd::rad2deg(atan2(rnumer,denom));
// DIFFERENCE IN LONGITUDE ON AUXILARY SPHERE (DLAMS )
rnumer = sinsig*sinaz1;
denom = cosu1*cossig-sinu1*sinsig*cosaz1;
dlams = atan2(rnumer,denom);
// TERM C
tc = f*cos2saz*(4.0+f*(4.0-3.0*cos2saz))/16.0;
// DIFFERENCE IN LONGITUDE
dlam = dlams-(1.0-tc)*f*sinaz*(sig+tc*sinsig*
(c2sigm+
tc*cossig*(-1.0+2.0*
c2sigm*c2sigm)));
*lon2 = SGMiscd::rad2deg(lam1+dlam);
if (*lon2 > 180.0 ) *lon2 -= 360.0;
if (*lon2 < -180.0 ) *lon2 += 360.0;
// AZIMUTH - FROM NORTH
*az2 = SGMiscd::rad2deg(atan2(-sinaz,temp));
if ( fabs(*az2) < testv ) *az2 = 0.0;
if( *az2 < 0.0) *az2 += 360.0;
return 0;
} else { // phi1 == 90 degrees, polar origin
double dM = a*M0(e2) - s;
double paz = ( phi1 < 0.0 ? 180.0 : 0.0 );
double zero = 0.0f;
return _geo_direct_wgs_84( zero, lon1, paz, dM, lat2, lon2, az2 );
}
}
bool
SGGeodesy::direct(const SGGeod& p1, double course1,
double distance, SGGeod& p2, double& course2)
{
double lat2, lon2;
int ret = _geo_direct_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
course1, distance, &lat2, &lon2, &course2);
p2.setLatitudeDeg(lat2);
p2.setLongitudeDeg(lon2);
p2.setElevationM(0);
return ret == 0;
}
// given lat1, lon1, lat2, lon2, calculate starting and ending
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
// distance in meters
static int _geo_inverse_wgs_84( double lat1, double lon1, double lat2,
double lon2, double *az1, double *az2,
double *s )
{
double a = SGGeodesy::EQURAD, rf = SGGeodesy::iFLATTENING;
int iter=0;
double testv = 1.0E-10;
double f = ( rf > 0.0 ? 1.0/rf : 0.0 );
double b = a*(1.0-f);
// double e2 = f*(2.0-f); // unused in this routine
double phi1 = SGMiscd::deg2rad(lat1), lam1 = SGMiscd::deg2rad(lon1);
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
double phi2 = SGMiscd::deg2rad(lat2), lam2 = SGMiscd::deg2rad(lon2);
double sinphi2 = sin(phi2), cosphi2 = cos(phi2);
if( (fabs(lat1-lat2) < testv &&
( fabs(lon1-lon2) < testv) || fabs(lat1-90.0) < testv ) )
{
// TWO STATIONS ARE IDENTICAL : SET DISTANCE & AZIMUTHS TO ZERO */
*az1 = 0.0; *az2 = 0.0; *s = 0.0;
return 0;
} else if( fabs(cosphi1) < testv ) {
// initial point is polar
int k = _geo_inverse_wgs_84( lat2,lon2,lat1,lon1, az1,az2,s );
k = k; // avoid compiler error since return result is unused
b = *az1; *az1 = *az2; *az2 = b;
return 0;
} else if( fabs(cosphi2) < testv ) {
// terminal point is polar
double _lon1 = lon1 + 180.0f;
int k = _geo_inverse_wgs_84( lat1, lon1, lat1, _lon1,
az1, az2, s );
k = k; // avoid compiler error since return result is unused
*s /= 2.0;
*az2 = *az1 + 180.0;
if( *az2 > 360.0 ) *az2 -= 360.0;
return 0;
} else if( (fabs( fabs(lon1-lon2) - 180 ) < testv) &&
(fabs(lat1+lat2) < testv) )
{
// Geodesic passes through the pole (antipodal)
double s1,s2;
_geo_inverse_wgs_84( lat1,lon1, lat1,lon2, az1,az2, &s1 );
_geo_inverse_wgs_84( lat2,lon2, lat1,lon2, az1,az2, &s2 );
*az2 = *az1;
*s = s1 + s2;
return 0;
} else {
// antipodal and polar points don't get here
double dlam = lam2 - lam1, dlams = dlam;
double sdlams,cdlams, sig,sinsig,cossig, sinaz,
cos2saz, c2sigm;
double tc,temp, us,rnumer,denom, ta,tb;
double cosu1,sinu1, sinu2,cosu2;
// Reduced latitudes
temp = (1.0-f)*sinphi1/cosphi1;
cosu1 = 1.0/sqrt(1.0+temp*temp);
sinu1 = temp*cosu1;
temp = (1.0-f)*sinphi2/cosphi2;
cosu2 = 1.0/sqrt(1.0+temp*temp);
sinu2 = temp*cosu2;
do {
sdlams = sin(dlams), cdlams = cos(dlams);
sinsig = sqrt(cosu2*cosu2*sdlams*sdlams+
(cosu1*sinu2-sinu1*cosu2*cdlams)*
(cosu1*sinu2-sinu1*cosu2*cdlams));
cossig = sinu1*sinu2+cosu1*cosu2*cdlams;
sig = atan2(sinsig,cossig);
sinaz = cosu1*cosu2*sdlams/sinsig;
cos2saz = 1.0-sinaz*sinaz;
c2sigm = (sinu1 == 0.0 || sinu2 == 0.0 ? cossig :
cossig-2.0*sinu1*sinu2/cos2saz);
tc = f*cos2saz*(4.0+f*(4.0-3.0*cos2saz))/16.0;
temp = dlams;
dlams = dlam+(1.0-tc)*f*sinaz*
(sig+tc*sinsig*
(c2sigm+tc*cossig*(-1.0+2.0*c2sigm*c2sigm)));
if (fabs(dlams) > SGMiscd::pi() && iter++ > 50) {
return iter;
}
} while ( fabs(temp-dlams) > testv);
us = cos2saz*(a*a-b*b)/(b*b); // !!
// BACK AZIMUTH FROM NORTH
rnumer = -(cosu1*sdlams);
denom = sinu1*cosu2-cosu1*sinu2*cdlams;
*az2 = SGMiscd::rad2deg(atan2(rnumer,denom));
if( fabs(*az2) < testv ) *az2 = 0.0;
if(*az2 < 0.0) *az2 += 360.0;
// FORWARD AZIMUTH FROM NORTH
rnumer = cosu2*sdlams;
denom = cosu1*sinu2-sinu1*cosu2*cdlams;
*az1 = SGMiscd::rad2deg(atan2(rnumer,denom));
if( fabs(*az1) < testv ) *az1 = 0.0;
if(*az1 < 0.0) *az1 += 360.0;
// Terms a & b
ta = 1.0+us*(4096.0+us*(-768.0+us*(320.0-175.0*us)))/
16384.0;
tb = us*(256.0+us*(-128.0+us*(74.0-47.0*us)))/1024.0;
// GEODETIC DISTANCE
*s = b*ta*(sig-tb*sinsig*
(c2sigm+tb*(cossig*(-1.0+2.0*c2sigm*c2sigm)-tb*
c2sigm*(-3.0+4.0*sinsig*sinsig)*
(-3.0+4.0*c2sigm*c2sigm)/6.0)/
4.0));
return 0;
}
}
bool
SGGeodesy::inverse(const SGGeod& p1, const SGGeod& p2, double& course1,
double& course2, double& distance)
{
int ret = _geo_inverse_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
p2.getLatitudeDeg(), p2.getLongitudeDeg(),
&course1, &course2, &distance);
return ret == 0;
}
/// Geocentric routines
void
SGGeodesy::advanceRadM(const SGGeoc& geoc, double course, double distance,
SGGeoc& result)
{
result.setRadiusM(geoc.getRadiusM());
// lat=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
// IF (cos(lat)=0)
// lon=lon1 // endpoint a pole
// ELSE
// lon=mod(lon1-asin(sin(tc)*sin(d)/cos(lat))+pi,2*pi)-pi
// ENDIF
distance *= SG_METER_TO_NM * SG_NM_TO_RAD;
double sinDistance = sin(distance);
double cosDistance = cos(distance);
double sinLat = sin(geoc.getLatitudeRad()) * cosDistance +
cos(geoc.getLatitudeRad()) * sinDistance * cos(course);
sinLat = SGMiscd::clip(sinLat, -1, 1);
result.setLatitudeRad(asin(sinLat));
double cosLat = cos(result.getLatitudeRad());
if (cosLat <= SGLimitsd::min()) {
// endpoint a pole
result.setLongitudeRad(geoc.getLongitudeRad());
} else {
double tmp = SGMiscd::clip(sin(course) * sinDistance / cosLat, -1, 1);
double lon = SGMiscd::normalizeAngle(geoc.getLongitudeRad() - asin( tmp ));
result.setLongitudeRad(lon);
}
}
double
SGGeodesy::courseRad(const SGGeoc& from, const SGGeoc& to)
{
double diffLon = to.getLongitudeRad() - from.getLongitudeRad();
double sinLatFrom = sin(from.getLatitudeRad());
double cosLatFrom = cos(from.getLatitudeRad());
double sinLatTo = sin(to.getLatitudeRad());
double cosLatTo = cos(to.getLatitudeRad());
double x = cosLatTo*sin(diffLon);
double y = cosLatFrom*sinLatTo - sinLatFrom*cosLatTo*cos(diffLon);
// guard atan2 returning NaN's
if (fabs(x) <= SGLimitsd::min() && fabs(y) <= SGLimitsd::min())
return 0;
double c = atan2(x, y);
if (c >= 0)
return SGMiscd::twopi() - c;
else
return -c;
}
double
SGGeodesy::distanceM(const SGGeoc& from, const SGGeoc& to)
{
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
double cosLatFrom = cos(from.getLatitudeRad());
double cosLatTo = cos(to.getLatitudeRad());
double tmp1 = sin(0.5*(from.getLatitudeRad() - to.getLatitudeRad()));
double tmp2 = sin(0.5*(from.getLongitudeRad() - to.getLongitudeRad()));
double square = tmp1*tmp1 + cosLatFrom*cosLatTo*tmp2*tmp2;
double s = SGMiscd::min(sqrt(SGMiscd::max(square, 0)), 1);
return 2 * asin(s) * SG_RAD_TO_NM * SG_NM_TO_METER;
}

View File

@@ -45,6 +45,19 @@ public:
/// Takes a geocentric coordinate data and returns the cartesian
/// coordinates.
static void SGGeocToCart(const SGGeoc& geoc, SGVec3<double>& cart);
// Geodetic course/distance computation
static bool direct(const SGGeod& p1, double course1,
double distance, SGGeod& p2, double& course2);
static bool inverse(const SGGeod& p1, const SGGeod& p2, double& course1,
double& course2, double& distance);
// Geocentric course/distance computation
static void advanceRadM(const SGGeoc& geoc, double course, double distance,
SGGeoc& result);
static double courseRad(const SGGeoc& from, const SGGeoc& to);
static double distanceM(const SGGeoc& from, const SGGeoc& to);
};
#endif

View File

@@ -22,8 +22,9 @@
#include <iosfwd>
// FIXME, make it compile on IRIX
#include <osg/GL>
#undef GLUT_APIENTRY_DEFINED // GL/glut.h undef APIENTRY when this symbol is defined. osg/GL defines it (?).
//#include <osg/GL>
//#undef GLUT_APIENTRY_DEFINED // GL/glut.h undef APIENTRY when this symbol is defined. osg/GL defines it (?).
// This probably would work if we didn't use plib/pu.h that include GL/glut.h
// on its side.

View File

@@ -18,6 +18,10 @@
#ifndef SGVec2_H
#define SGVec2_H
#if defined ( __CYGWIN__ )
#include <ieeefp.h>
#endif
#include <osg/Vec2f>
#include <osg/Vec2d>

View File

@@ -25,7 +25,7 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sgstream.hxx>
@@ -33,7 +33,7 @@
#include "interpolater.hxx"
SG_USING_STD(string);
using std::string;
// Constructor -- starts with an empty table.
SGInterpTable::SGInterpTable()

View File

@@ -39,8 +39,8 @@
#include <map>
#include STL_STRING
SG_USING_STD(string);
#include <string>
using std::string;
class SGPropertyNode;

View File

@@ -37,41 +37,21 @@
#include <simgear/compiler.h>
#ifdef SG_MATH_EXCEPTION_CLASH
# define exception c_exception
#endif
#ifdef SG_HAVE_STD_INCLUDES
# include <iostream>
# include <cassert>
# include <cmath>
#else
# include <iostream.h>
# include <assert.h>
# include <math.h>
#endif
#include <ostream>
#include <istream>
#include <cassert>
#include <cmath>
#include "SGMath.hxx"
// I don't understand ... <math.h> or <cmath> should be included
// already depending on how you defined SG_HAVE_STD_INCLUDES, but I
// can go ahead and add this -- CLO
#ifdef __MWERKS__
SG_USING_NAMESPACE(std);
#endif
SG_USING_STD(ostream);
SG_USING_STD(istream);
const double fgPoint3_Epsilon = 0.0000001;
enum {PX, PY, PZ}; // axes
// Kludge for msvc++ 6.0 - requires forward decls of friend functions.
class Point3D;
istream& operator>> ( istream&, Point3D& );
ostream& operator<< ( ostream&, const Point3D& );
std::istream& operator>> ( std::istream&, Point3D& );
std::ostream& operator<< ( std::ostream&, const Point3D& );
Point3D operator- (const Point3D& p); // -p1
bool operator== (const Point3D& a, const Point3D& b); // p1 == p2?
@@ -141,8 +121,8 @@ public:
// friends
friend Point3D operator - (const Point3D& p); // -p1
friend bool operator == (const Point3D& a, const Point3D& b); // p1 == p2?
friend istream& operator>> ( istream&, Point3D& );
friend ostream& operator<< ( ostream&, const Point3D& );
friend std::istream& operator>> ( std::istream&, Point3D& );
friend std::ostream& operator<< ( std::ostream&, const Point3D& );
// Special functions
double distance3D(const Point3D& a) const; // distance between
@@ -151,8 +131,8 @@ public:
// input from stream
inline istream&
operator >> ( istream& in, Point3D& p)
inline std::istream&
operator >> ( std::istream& in, Point3D& p)
{
char c;
@@ -183,8 +163,8 @@ operator >> ( istream& in, Point3D& p)
return in;
}
inline ostream&
operator<< ( ostream& out, const Point3D& p )
inline std::ostream&
operator<< ( std::ostream& out, const Point3D& p )
{
return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
}

View File

@@ -1,225 +0,0 @@
// polar.cxx -- routines to deal with polar math and transformations
//
// Written by Curtis Olson, started June 1997.
//
// Copyright (C) 1997 Curtis L. Olson - http://www.flightgear.org/~curt
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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$
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <math.h>
#include <simgear/constants.h>
#include "polar3d.hxx"
/**
* Calculate new lon/lat given starting lon/lat, and offset radial, and
* distance. NOTE: starting point is specifed in radians, distance is
* specified in meters (and converted internally to radians)
* ... assumes a spherical world.
* @param orig specified in polar coordinates
* @param course offset radial
* @param dist offset distance
* @return destination point in polar coordinates
*/
Point3D calc_gc_lon_lat( const Point3D& orig, double course,
double dist ) {
Point3D result;
// lat=asin(sin(lat1)*cos(d)+cos(lat1)*sin(d)*cos(tc))
// IF (cos(lat)=0)
// lon=lon1 // endpoint a pole
// ELSE
// lon=mod(lon1-asin(sin(tc)*sin(d)/cos(lat))+pi,2*pi)-pi
// ENDIF
// printf("calc_lon_lat() offset.theta = %.2f offset.dist = %.2f\n",
// offset.theta, offset.dist);
dist *= SG_METER_TO_NM * SG_NM_TO_RAD;
result.sety( asin( sin(orig.y()) * cos(dist) +
cos(orig.y()) * sin(dist) * cos(course) ) );
if ( cos(result.y()) < SG_EPSILON ) {
result.setx( orig.x() ); // endpoint a pole
} else {
result.setx(
fmod(orig.x() - asin( sin(course) * sin(dist) /
cos(result.y()) )
+ SGD_PI, SGD_2PI) - SGD_PI );
}
return result;
}
/**
* Calculate course/dist given two spherical points.
* @param start starting point
* @param dest ending point
* @param course resulting course
* @param dist resulting distance
*/
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist )
{
if ( start == dest) {
*dist=0;
*course=0;
return;
}
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
double cos_start_y = cos( start.y() );
double tmp1 = sin( (start.y() - dest.y()) * 0.5 );
double tmp2 = sin( (start.x() - dest.x()) * 0.5 );
double d = 2.0 * asin( sqrt( tmp1 * tmp1 +
cos_start_y * cos(dest.y()) * tmp2 * tmp2));
*dist = d * SG_RAD_TO_NM * SG_NM_TO_METER;
#if 1
double c1 = atan2(
cos(dest.y())*sin(dest.x()-start.x()),
cos(start.y())*sin(dest.y())-
sin(start.y())*cos(dest.y())*cos(dest.x()-start.x()));
if (c1 >= 0)
*course = SGD_2PI-c1;
else
*course = -c1;
#else
// We obtain the initial course, tc1, (at point 1) from point 1 to
// point 2 by the following. The formula fails if the initial
// point is a pole. We can special case this with:
//
// IF (cos(lat1) < EPS) // EPS a small number ~ machine precision
// IF (lat1 > 0)
// tc1= pi // starting from N pole
// ELSE
// tc1= 0 // starting from S pole
// ENDIF
// ENDIF
//
// For starting points other than the poles:
//
// IF sin(lon2-lon1)<0
// tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
// ELSE
// tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
// ENDIF
// if ( cos(start.y()) < SG_EPSILON ) {
// doing it this way saves a transcendental call
double sin_start_y = sin( start.y() );
if ( fabs(1.0-sin_start_y) < SG_EPSILON ) {
// EPS a small number ~ machine precision
if ( start.y() > 0 ) {
*course = SGD_PI; // starting from N pole
} else {
*course = 0; // starting from S pole
}
} else {
// For starting points other than the poles:
// double tmp3 = sin(d)*cos_start_y);
// double tmp4 = sin(dest.y())-sin(start.y())*cos(d);
// double tmp5 = acos(tmp4/tmp3);
// Doing this way gaurentees that the temps are
// not stored into memory
double tmp5 = acos( (sin(dest.y()) - sin_start_y * cos(d)) /
(sin(d) * cos_start_y) );
// if ( sin( dest.x() - start.x() ) < 0 ) {
// the sin of the negative angle is just the opposite sign
// of the sin of the angle so tmp2 will have the opposite
// sign of sin( dest.x() - start.x() )
if ( tmp2 >= 0 ) {
*course = tmp5;
} else {
*course = SGD_2PI - tmp5;
}
}
#endif
}
#if 0
/**
* Calculate course/dist given two spherical points.
* @param start starting point
* @param dest ending point
* @param course resulting course
* @param dist resulting distance
*/
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist ) {
// d = 2*asin(sqrt((sin((lat1-lat2)/2))^2 +
// cos(lat1)*cos(lat2)*(sin((lon1-lon2)/2))^2))
double tmp1 = sin( (start.y() - dest.y()) / 2 );
double tmp2 = sin( (start.x() - dest.x()) / 2 );
double d = 2.0 * asin( sqrt( tmp1 * tmp1 +
cos(start.y()) * cos(dest.y()) * tmp2 * tmp2));
// We obtain the initial course, tc1, (at point 1) from point 1 to
// point 2 by the following. The formula fails if the initial
// point is a pole. We can special case this with:
//
// IF (cos(lat1) < EPS) // EPS a small number ~ machine precision
// IF (lat1 > 0)
// tc1= pi // starting from N pole
// ELSE
// tc1= 0 // starting from S pole
// ENDIF
// ENDIF
//
// For starting points other than the poles:
//
// IF sin(lon2-lon1)<0
// tc1=acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
// ELSE
// tc1=2*pi-acos((sin(lat2)-sin(lat1)*cos(d))/(sin(d)*cos(lat1)))
// ENDIF
double tc1;
if ( cos(start.y()) < SG_EPSILON ) {
// EPS a small number ~ machine precision
if ( start.y() > 0 ) {
tc1 = SGD_PI; // starting from N pole
} else {
tc1 = 0; // starting from S pole
}
}
// For starting points other than the poles:
double tmp3 = sin(d)*cos(start.y());
double tmp4 = sin(dest.y())-sin(start.y())*cos(d);
double tmp5 = acos(tmp4/tmp3);
if ( sin( dest.x() - start.x() ) < 0 ) {
tc1 = tmp5;
} else {
tc1 = SGD_2PI - tmp5;
}
*course = tc1;
*dist = d * SG_RAD_TO_NM * SG_NM_TO_METER;
}
#endif // 0

View File

@@ -32,56 +32,9 @@
# error This library requires C++
#endif
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
#include "SGMath.hxx"
/**
* Find the Altitude above the Ellipsoid (WGS84) given the Earth
* Centered Cartesian coordinate vector Distances are specified in
* meters.
* @param cp point specified in cartesian coordinates
* @return altitude above the (wgs84) earth in meters
*/
inline double sgGeodAltFromCart(const Point3D& p)
{
SGGeod geod;
SGGeodesy::SGCartToGeod(SGVec3<double>(p.x(), p.y(), p.z()), geod);
return geod.getElevationM();
}
/**
* Convert a polar coordinate to a cartesian coordinate. Lon and Lat
* must be specified in radians. The SG convention is for distances
* to be specified in meters
* @param p point specified in polar coordinates
* @return the same point in cartesian coordinates
*/
inline Point3D sgPolarToCart3d(const Point3D& p)
{
SGVec3<double> cart;
SGGeodesy::SGGeocToCart(SGGeoc::fromRadM(p.lon(), p.lat(), p.radius()), cart);
return Point3D::fromSGVec3(cart);
}
/**
* Convert a cartesian coordinate to polar coordinates (lon/lat
* specified in radians. Distances are specified in meters.
* @param cp point specified in cartesian coordinates
* @return the same point in polar coordinates
*/
inline Point3D sgCartToPolar3d(const Point3D& p)
{
SGGeoc geoc;
SGGeodesy::SGCartToGeoc(SGVec3<double>(p.x(), p.y(), p.z()), geoc);
return Point3D::fromSGGeoc(geoc);
}
/**
* Calculate new lon/lat given starting lon/lat, and offset radial, and
* distance. NOTE: starting point is specifed in radians, distance is
@@ -92,7 +45,8 @@ inline Point3D sgCartToPolar3d(const Point3D& p)
* @param dist offset distance
* @return destination point in polar coordinates
*/
Point3D calc_gc_lon_lat( const Point3D& orig, double course, double dist );
inline Point3D calc_gc_lon_lat(const Point3D& orig, double course, double dist)
{ return Point3D::fromSGGeoc(orig.toSGGeoc().advanceRadM(course, dist)); }
/**
@@ -102,20 +56,14 @@ Point3D calc_gc_lon_lat( const Point3D& orig, double course, double dist );
* @param course resulting course
* @param dist resulting distance
*/
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist );
#if 0
/**
* Calculate course/dist given two spherical points.
* @param start starting point
* @param dest ending point
* @param course resulting course
* @param dist resulting distance
*/
void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist );
#endif // 0
inline void calc_gc_course_dist( const Point3D& start, const Point3D& dest,
double *course, double *dist )
{
SGGeoc gs = start.toSGGeoc();
SGGeoc gd = dest.toSGGeoc();
*course = SGGeoc::courseRad(gs, gd);
*dist = SGGeoc::distanceM(gs, gd);
}
#endif // _POLAR3D_HXX

View File

@@ -1,283 +0,0 @@
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/constants.h>
#include "SGMath.hxx"
#include "sg_geodesy.hxx"
// Notes:
//
// The XYZ/cartesian coordinate system in use puts the X axis through
// zero lat/lon (off west Africa), the Z axis through the north pole,
// and the Y axis through 90 degrees longitude (in the Indian Ocean).
//
// All latitude and longitude values are in radians. Altitude is in
// meters, with zero on the WGS84 ellipsoid.
//
// The code below makes use of the notion of "squashed" space. This
// is a 2D cylindrical coordinate system where the radius from the Z
// axis is multiplied by SQUASH; the earth in this space is a perfect
// circle with a radius of POLRAD.
//
// Performance: with full optimization, a transformation from
// lat/lon/alt to XYZ and back takes 5263 CPU cycles on my 2.2GHz
// Pentium 4. About 83% of this is spent in the iterative sgCartToGeod()
// algorithm.
// These are hard numbers from the WGS84 standard. DON'T MODIFY
// unless you want to change the datum.
static const double EQURAD = 6378137;
static const double iFLATTENING = 298.257223563;
// These are derived quantities more useful to the code:
#if 0
static const double SQUASH = 1 - 1/iFLATTENING;
static const double STRETCH = 1/SQUASH;
static const double POLRAD = EQURAD * SQUASH;
#else
// High-precision versions of the above produced with an arbitrary
// precision calculator (the compiler might lose a few bits in the FPU
// operations). These are specified to 81 bits of mantissa, which is
// higher than any FPU known to me:
static const double SQUASH = 0.9966471893352525192801545;
static const double STRETCH = 1.0033640898209764189003079;
static const double POLRAD = 6356752.3142451794975639668;
#endif
////////////////////////////////////////////////////////////////////////
//
// Direct and inverse distance functions
//
// Proceedings of the 7th International Symposium on Geodetic
// Computations, 1985
//
// "The Nested Coefficient Method for Accurate Solutions of Direct and
// Inverse Geodetic Problems With Any Length"
//
// Zhang Xue-Lian
// pp 747-763
//
// modified for FlightGear to use WGS84 only -- Norman Vine
static const double GEOD_INV_PI = SGD_PI;
// s == distance
// az = azimuth
static inline double M0( double e2 ) {
//double e4 = e2*e2;
return GEOD_INV_PI*(1.0 - e2*( 1.0/4.0 + e2*( 3.0/64.0 +
e2*(5.0/256.0) )))/2.0;
}
// given, lat1, lon1, az1 and distance (s), calculate lat2, lon2
// and az2. Lat, lon, and azimuth are in degrees. distance in meters
int geo_direct_wgs_84 ( double lat1, double lon1, double az1,
double s, double *lat2, double *lon2,
double *az2 )
{
double a = EQURAD, rf = iFLATTENING;
double RADDEG = (GEOD_INV_PI)/180.0, testv = 1.0E-10;
double f = ( rf > 0.0 ? 1.0/rf : 0.0 );
double b = a*(1.0-f);
double e2 = f*(2.0-f);
double phi1 = lat1*RADDEG, lam1 = lon1*RADDEG;
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
double azm1 = az1*RADDEG;
double sinaz1 = sin(azm1), cosaz1 = cos(azm1);
if( fabs(s) < 0.01 ) { // distance < centimeter => congruency
*lat2 = lat1;
*lon2 = lon1;
*az2 = 180.0 + az1;
if( *az2 > 360.0 ) *az2 -= 360.0;
return 0;
} else if( cosphi1 ) { // non-polar origin
// u1 is reduced latitude
double tanu1 = sqrt(1.0-e2)*sinphi1/cosphi1;
double sig1 = atan2(tanu1,cosaz1);
double cosu1 = 1.0/sqrt( 1.0 + tanu1*tanu1 ), sinu1 = tanu1*cosu1;
double sinaz = cosu1*sinaz1, cos2saz = 1.0-sinaz*sinaz;
double us = cos2saz*e2/(1.0-e2);
// Terms
double ta = 1.0+us*(4096.0+us*(-768.0+us*(320.0-175.0*us)))/16384.0,
tb = us*(256.0+us*(-128.0+us*(74.0-47.0*us)))/1024.0,
tc = 0;
// FIRST ESTIMATE OF SIGMA (SIG)
double first = s/(b*ta); // !!
double sig = first;
double c2sigm, sinsig,cossig, temp,denom,rnumer, dlams, dlam;
do {
c2sigm = cos(2.0*sig1+sig);
sinsig = sin(sig); cossig = cos(sig);
temp = sig;
sig = first +
tb*sinsig*(c2sigm+tb*(cossig*(-1.0+2.0*c2sigm*c2sigm) -
tb*c2sigm*(-3.0+4.0*sinsig*sinsig)
*(-3.0+4.0*c2sigm*c2sigm)/6.0)
/4.0);
} while( fabs(sig-temp) > testv);
// LATITUDE OF POINT 2
// DENOMINATOR IN 2 PARTS (TEMP ALSO USED LATER)
temp = sinu1*sinsig-cosu1*cossig*cosaz1;
denom = (1.0-f)*sqrt(sinaz*sinaz+temp*temp);
// NUMERATOR
rnumer = sinu1*cossig+cosu1*sinsig*cosaz1;
*lat2 = atan2(rnumer,denom)/RADDEG;
// DIFFERENCE IN LONGITUDE ON AUXILARY SPHERE (DLAMS )
rnumer = sinsig*sinaz1;
denom = cosu1*cossig-sinu1*sinsig*cosaz1;
dlams = atan2(rnumer,denom);
// TERM C
tc = f*cos2saz*(4.0+f*(4.0-3.0*cos2saz))/16.0;
// DIFFERENCE IN LONGITUDE
dlam = dlams-(1.0-tc)*f*sinaz*(sig+tc*sinsig*
(c2sigm+
tc*cossig*(-1.0+2.0*
c2sigm*c2sigm)));
*lon2 = (lam1+dlam)/RADDEG;
if (*lon2 > 180.0 ) *lon2 -= 360.0;
if (*lon2 < -180.0 ) *lon2 += 360.0;
// AZIMUTH - FROM NORTH
*az2 = atan2(-sinaz,temp)/RADDEG;
if ( fabs(*az2) < testv ) *az2 = 0.0;
if( *az2 < 0.0) *az2 += 360.0;
return 0;
} else { // phi1 == 90 degrees, polar origin
double dM = a*M0(e2) - s;
double paz = ( phi1 < 0.0 ? 180.0 : 0.0 );
double zero = 0.0f;
return geo_direct_wgs_84( zero, lon1, paz, dM, lat2, lon2, az2 );
}
}
// given lat1, lon1, lat2, lon2, calculate starting and ending
// az1, az2 and distance (s). Lat, lon, and azimuth are in degrees.
// distance in meters
int geo_inverse_wgs_84( double lat1, double lon1, double lat2,
double lon2, double *az1, double *az2,
double *s )
{
double a = EQURAD, rf = iFLATTENING;
int iter=0;
double RADDEG = (GEOD_INV_PI)/180.0, testv = 1.0E-10;
double f = ( rf > 0.0 ? 1.0/rf : 0.0 );
double b = a*(1.0-f);
// double e2 = f*(2.0-f); // unused in this routine
double phi1 = lat1*RADDEG, lam1 = lon1*RADDEG;
double sinphi1 = sin(phi1), cosphi1 = cos(phi1);
double phi2 = lat2*RADDEG, lam2 = lon2*RADDEG;
double sinphi2 = sin(phi2), cosphi2 = cos(phi2);
if( (fabs(lat1-lat2) < testv &&
( fabs(lon1-lon2) < testv) || fabs(lat1-90.0) < testv ) )
{
// TWO STATIONS ARE IDENTICAL : SET DISTANCE & AZIMUTHS TO ZERO */
*az1 = 0.0; *az2 = 0.0; *s = 0.0;
return 0;
} else if( fabs(cosphi1) < testv ) {
// initial point is polar
int k = geo_inverse_wgs_84( lat2,lon2,lat1,lon1, az1,az2,s );
k = k; // avoid compiler error since return result is unused
b = *az1; *az1 = *az2; *az2 = b;
return 0;
} else if( fabs(cosphi2) < testv ) {
// terminal point is polar
double _lon1 = lon1 + 180.0f;
int k = geo_inverse_wgs_84( lat1, lon1, lat1, _lon1,
az1, az2, s );
k = k; // avoid compiler error since return result is unused
*s /= 2.0;
*az2 = *az1 + 180.0;
if( *az2 > 360.0 ) *az2 -= 360.0;
return 0;
} else if( (fabs( fabs(lon1-lon2) - 180 ) < testv) &&
(fabs(lat1+lat2) < testv) )
{
// Geodesic passes through the pole (antipodal)
double s1,s2;
geo_inverse_wgs_84( lat1,lon1, lat1,lon2, az1,az2, &s1 );
geo_inverse_wgs_84( lat2,lon2, lat1,lon2, az1,az2, &s2 );
*az2 = *az1;
*s = s1 + s2;
return 0;
} else {
// antipodal and polar points don't get here
double dlam = lam2 - lam1, dlams = dlam;
double sdlams,cdlams, sig,sinsig,cossig, sinaz,
cos2saz, c2sigm;
double tc,temp, us,rnumer,denom, ta,tb;
double cosu1,sinu1, sinu2,cosu2;
// Reduced latitudes
temp = (1.0-f)*sinphi1/cosphi1;
cosu1 = 1.0/sqrt(1.0+temp*temp);
sinu1 = temp*cosu1;
temp = (1.0-f)*sinphi2/cosphi2;
cosu2 = 1.0/sqrt(1.0+temp*temp);
sinu2 = temp*cosu2;
do {
sdlams = sin(dlams), cdlams = cos(dlams);
sinsig = sqrt(cosu2*cosu2*sdlams*sdlams+
(cosu1*sinu2-sinu1*cosu2*cdlams)*
(cosu1*sinu2-sinu1*cosu2*cdlams));
cossig = sinu1*sinu2+cosu1*cosu2*cdlams;
sig = atan2(sinsig,cossig);
sinaz = cosu1*cosu2*sdlams/sinsig;
cos2saz = 1.0-sinaz*sinaz;
c2sigm = (sinu1 == 0.0 || sinu2 == 0.0 ? cossig :
cossig-2.0*sinu1*sinu2/cos2saz);
tc = f*cos2saz*(4.0+f*(4.0-3.0*cos2saz))/16.0;
temp = dlams;
dlams = dlam+(1.0-tc)*f*sinaz*
(sig+tc*sinsig*
(c2sigm+tc*cossig*(-1.0+2.0*c2sigm*c2sigm)));
if (fabs(dlams) > GEOD_INV_PI && iter++ > 50) {
return iter;
}
} while ( fabs(temp-dlams) > testv);
us = cos2saz*(a*a-b*b)/(b*b); // !!
// BACK AZIMUTH FROM NORTH
rnumer = -(cosu1*sdlams);
denom = sinu1*cosu2-cosu1*sinu2*cdlams;
*az2 = atan2(rnumer,denom)/RADDEG;
if( fabs(*az2) < testv ) *az2 = 0.0;
if(*az2 < 0.0) *az2 += 360.0;
// FORWARD AZIMUTH FROM NORTH
rnumer = cosu2*sdlams;
denom = cosu1*sinu2-sinu1*cosu2*cdlams;
*az1 = atan2(rnumer,denom)/RADDEG;
if( fabs(*az1) < testv ) *az1 = 0.0;
if(*az1 < 0.0) *az1 += 360.0;
// Terms a & b
ta = 1.0+us*(4096.0+us*(-768.0+us*(320.0-175.0*us)))/
16384.0;
tb = us*(256.0+us*(-128.0+us*(74.0-47.0*us)))/1024.0;
// GEODETIC DISTANCE
*s = b*ta*(sig-tb*sinsig*
(c2sigm+tb*(cossig*(-1.0+2.0*c2sigm*c2sigm)-tb*
c2sigm*(-3.0+4.0*sinsig*sinsig)*
(-3.0+4.0*c2sigm*c2sigm)/6.0)/
4.0));
return 0;
}
}

View File

@@ -4,26 +4,8 @@
#include <simgear/math/point3d.hxx>
#include "SGMath.hxx"
/**
* Convert from geocentric coordinates to geodetic coordinates
* @param lat_geoc (in) Geocentric latitude, radians, + = North
* @param radius (in) C.G. radius to earth center (meters)
* @param lat_geod (out) Geodetic latitude, radians, + = North
* @param alt (out) C.G. altitude above mean sea level (meters)
* @param sea_level_r (out) radius from earth center to sea level at
* local vertical (surface normal) of C.G. (meters)
*/
inline void sgGeocToGeod(double lat_geoc, double radius,
double *lat_geod, double *alt, double *sea_level_r)
{
SGVec3<double> cart;
SGGeodesy::SGGeocToCart(SGGeoc::fromRadM(0, lat_geoc, radius), cart);
SGGeod geod;
SGGeodesy::SGCartToGeod(cart, geod);
*lat_geod = geod.getLatitudeRad();
*alt = geod.getElevationM();
*sea_level_r = SGGeodesy::SGGeodToSeaLevelRadius(geod);
}
// Compatibility header.
// Please use the SGGeodesy and SGMath functions directly.
/**
* Convert from geodetic coordinates to geocentric coordinates.
@@ -128,9 +110,17 @@ inline Point3D sgGeodToCart(const Point3D& geod)
* @param lon2 (out) degrees
* @param az2 (out) return course in degrees
*/
int geo_direct_wgs_84 ( double lat1, double lon1, double az1,
double s, double *lat2, double *lon2,
double *az2 );
inline int geo_direct_wgs_84 ( double lat1, double lon1, double az1,
double s, double *lat2, double *lon2,
double *az2 )
{
SGGeod p2;
if (!SGGeodesy::direct(SGGeod::fromDeg(lon1, lat1), az1, s, p2, *az2))
return 1;
*lat2 = p2.getLatitudeDeg();
*lon2 = p2.getLongitudeDeg();
return 0;
}
inline int geo_direct_wgs_84 ( double alt, double lat1,
double lon1, double az1,
double s, double *lat2, double *lon2,
@@ -149,12 +139,7 @@ inline int geo_direct_wgs_84 ( double alt, double lat1,
inline int geo_direct_wgs_84(const SGGeod& p1, double az1,
double s, SGGeod& p2, double *az2 )
{
double lat2, lon2;
int ret = geo_direct_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
az1, s, &lat2, &lon2, az2);
p2.setLatitudeDeg(lat2);
p2.setLongitudeDeg(lon2);
return ret;
return !SGGeodesy::direct(p1, az1, s, p2, *az2);
}
/**
@@ -169,9 +154,13 @@ inline int geo_direct_wgs_84(const SGGeod& p1, double az1,
* @param az2 (out) end heading degrees
* @param s (out) distance meters
*/
int geo_inverse_wgs_84( double lat1, double lon1, double lat2,
double lon2, double *az1, double *az2,
double *s );
inline int geo_inverse_wgs_84( double lat1, double lon1, double lat2,
double lon2, double *az1, double *az2,
double *s )
{
return !SGGeodesy::inverse(SGGeod::fromDeg(lon1, lat1),
SGGeod::fromDeg(lon2, lat2), *az1, *az2, *s);
}
inline int geo_inverse_wgs_84( double alt, double lat1,
double lon1, double lat2,
double lon2, double *az1, double *az2,
@@ -191,9 +180,7 @@ inline int geo_inverse_wgs_84( double alt, double lat1,
inline int geo_inverse_wgs_84(const SGGeod& p1, const SGGeod& p2,
double *az1, double *az2, double *s )
{
return geo_inverse_wgs_84(p1.getLatitudeDeg(), p1.getLongitudeDeg(),
p2.getLatitudeDeg(), p2.getLongitudeDeg(),
az1, az2, s);
return !SGGeodesy::inverse(p1, p2, *az1, *az2, *s);
}
#endif // _SG_GEODESY_HXX

View File

@@ -1,63 +0,0 @@
/**
* \file sg_memory.h
* memcpy/bcopy portability declarations (not actually used by anything
* as best as I can tell.
*/
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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 _SG_MEMORY_H
#define _SG_MEMORY_H
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#ifdef HAVE_MEMCPY
# ifdef HAVE_MEMORY_H
# include <memory.h>
# endif
# define sgmemcmp memcmp
# define sgmemcpy memcpy
# define sgmemzero(dest,len) memset(dest,0,len)
#elif defined(HAVE_BCOPY)
# define sgmemcmp bcmp
# define sgmemcpy(dest,src,n) bcopy(src,dest,n)
# define sgmemzero bzero
#else
/*
* Neither memcpy() or bcopy() available.
* Use substitutes provided be zlib.
*/
# include <zutil.h>
# define sgmemcmp zmemcmp
# define sgmemcpy zmemcpy
# define sgmemzero zmemzero
#endif
#endif // _SG_MEMORY_H

View File

@@ -21,50 +21,19 @@
// $Id$
/*
A C-program for MT19937, with initialization improved 2002/2/10.
Coded by Takuji Nishimura and Makoto Matsumoto.
This is a faster version by taking Shawn Cokus's optimization,
Matthe Bellew's simplification, Isaku Wada's real version.
Before using, initialize the state by using init_genrand(seed)
or init_by_array(init_key, key_length).
Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/*
* "Cleaned up" and simplified Mersenne Twister implementation.
* Vastly smaller and more easily understood and embedded. Stores the
* state in a user-maintained structure instead of static memory, so
* you can have more than one, or save snapshots of the RNG state.
* Lacks the "init_by_array()" feature of the original code in favor
* of the simpler 32 bit seed initialization. Lacks the floating
* point generator, which is an orthogonal problem not related to
* random number generation. Verified to be identical to the original
* MT199367ar code through the first 10M generated numbers.
*/
Any feedback is very welcome.
http://www.math.keio.ac.jp/matumoto/emt.html
email: matumoto@math.keio.ac.jp
*/
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
@@ -76,94 +45,65 @@
#include "sg_random.h"
/* Period parameters */
#define N 624
#define M 397
#define MATRIX_A 0x9908b0dfUL /* constant vector a */
#define UMASK 0x80000000UL /* most significant w-r bits */
#define LMASK 0x7fffffffUL /* least significant r bits */
#define MIXBITS(u,v) ( ((u) & UMASK) | ((v) & LMASK) )
#define TWIST(u,v) ((MIXBITS(u,v) >> 1) ^ ((v)&1UL ? MATRIX_A : 0UL))
// Structure for the random number functions.
mt random_seed;
static unsigned long state[N]; /* the array for the state vector */
static int left = 1;
static int initf = 0;
static unsigned long *next;
#define MT(i) mt->array[i]
/* initializes state[N] with a seed */
void init_genrand(unsigned long s)
void mt_init(mt *mt, unsigned int seed)
{
int j;
state[0]= s & 0xffffffffUL;
for (j=1; j<N; j++) {
state[j] = (1812433253UL * (state[j-1] ^ (state[j-1] >> 30)) + j);
/* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
/* In the previous versions, MSBs of the seed affect */
/* only MSBs of the array state[]. */
/* 2002/01/09 modified by Makoto Matsumoto */
state[j] &= 0xffffffffUL; /* for >32 bit machines */
}
left = 1; initf = 1;
int i;
MT(0)= seed;
for(i=1; i<MT_N; i++)
MT(i) = (1812433253 * (MT(i-1) ^ (MT(i-1) >> 30)) + i);
mt->index = MT_N+1;
}
static void next_state(void)
unsigned int mt_rand32(mt *mt)
{
unsigned long *p=state;
int j;
unsigned int i, y;
if(mt->index >= MT_N) {
for(i=0; i<MT_N; i++) {
y = (MT(i) & 0x80000000) | (MT((i+1)%MT_N) & 0x7fffffff);
MT(i) = MT((i+MT_M)%MT_N) ^ (y>>1) ^ (y&1 ? 0x9908b0df : 0);
}
mt->index = 0;
}
y = MT(mt->index++);
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680;
y ^= (y << 15) & 0xefc60000;
y ^= (y >> 18);
return y;
}
/* if init_genrand() has not been called, */
/* a default initial seed is used */
if (initf==0) init_genrand(5489UL);
left = N;
next = state;
for (j=N-M+1; --j; p++)
*p = p[M] ^ TWIST(p[0], p[1]);
for (j=M; --j; p++)
*p = p[M-N] ^ TWIST(p[0], p[1]);
*p = p[M-N] ^ TWIST(p[0], state[0]);
double mt_rand(mt *mt)
{
/* divided by 2^32-1 */
return (double)mt_rand32(mt) * (1.0/4294967295.0);
}
// Seed the random number generater with time() so we don't see the
// same sequence every time
void sg_srandom_time() {
init_genrand(time(NULL));
mt_init(&random_seed, (unsigned int) time(NULL));
}
// Seed the random number generater with time() in 10 minute intervals
// so we get the same sequence within 10 minutes interval.
// This is useful for synchronizing two display systems.
void sg_srandom_time_10() {
init_genrand(time(NULL) / 600);
mt_init(&random_seed, (unsigned int) time(NULL) / 600);
}
// Seed the random number generater with your own seed so can set up
// repeatable randomization.
void sg_srandom( unsigned int seed ) {
init_genrand( seed );
mt_init(&random_seed, seed);
}
// return a random number between [0.0, 1.0)
double sg_random() {
unsigned long y;
if (--left == 0)
next_state();
y = *next++;
/* Tempering */
y ^= (y >> 11);
y ^= (y << 7) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return (double)y * (1.0/4294967295.0);
/* divided by 2^32-1 */
return mt_rand(&random_seed);
}

View File

@@ -33,6 +33,31 @@ extern "C" {
#endif
#define MT_N 624
#define MT_M 397
/**
* Structure to hold MT algorithm state to easily allow independant
* sets of random numbers with different seeds.
*/
struct {unsigned int array[MT_N]; int index; } typedef mt;
/**
* Initialize a new MT state with a given seed.
*/
void mt_init(mt *mt, unsigned int seed);
/**
* Generate a new 32-bit random number based on the given MT state.
*/
unsigned int mt_rand32( mt *mt);
/**
* Generate a new random number between [0.0, 1.0) based
* on the given MT state.
*/
double mt_rand(mt *mt);
/**
* Seed the random number generater with time() so we don't see the
* same sequence every time.
@@ -51,7 +76,7 @@ void sg_srandom_time_10();
* repeatable randomization.
* @param seed random number generator seed
*/
void sg_srandom( unsigned int seed );
void sg_srandom(unsigned int seed );
/**
* Return a random number between [0.0, 1.0)

View File

@@ -35,13 +35,13 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <vector>
#include <simgear/math/point3d.hxx>
SG_USING_STD(vector);
SG_USING_STD(string);
using std::vector;
using std::string;
/** STL vector list of ints */
typedef vector < int > int_list;
@@ -63,25 +63,5 @@ typedef vector < string > string_list;
typedef string_list::iterator string_list_iterator;
typedef string_list::const_iterator const_string_list_iterator;
/**
* Simple 2d point class where members can be accessed as x, dist, or lon
* and y, theta, or lat
*/
class point2d {
public:
union {
double x;
double dist;
double lon;
};
union {
double y;
double theta;
double lat;
};
};
#endif // _SG_TYPES_HXX

View File

@@ -11,7 +11,8 @@ include_HEADERS = \
texcoord.hxx \
zfstream.hxx \
interpolator.hxx \
stdint.hxx
stdint.hxx \
PathOptions.hxx
libsgmisc_a_SOURCES = \
sg_path.cxx \
@@ -20,16 +21,23 @@ libsgmisc_a_SOURCES = \
tabbed_values.cxx \
texcoord.cxx \
zfstream.cxx \
interpolator.cxx
interpolator.cxx \
PathOptions.cxx
noinst_PROGRAMS = tabbed_value_test swap_test
tabbed_value_test_SOURCES = tabbed_values_test.cxx
tabbed_value_test_LDADD = \
$(top_builddir)/simgear/misc/libsgmisc.a \
libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
$(top_builddir)/simgear/debug/libsgdebug.a
$(top_builddir)/simgear/xml/libsgxml.a:
cd $(top_builddir)/simgear/xml && $(MAKE) $(AM_MAKEFLAGS) libsgxml.a
$(top_builddir)/simgear/debug/libsgdebug.a:
cd $(top_builddir)/simgear/debug && $(MAKE) $(AM_MAKEFLAGS) libsgdebug.a
swap_test_SOURCES = swap_test.cpp
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,33 @@
// PathOptions.cxx -- make an osgDB Options object from a path
// Copyright (C) 2007 Tim Moore timoore@redhat.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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$
#include <osgDB/Registry>
#include "PathOptions.hxx"
using namespace simgear;
osgDB::ReaderWriter::Options* simgear::makeOptionsFromPath(const SGPath& path)
{
using namespace osgDB;
ReaderWriter::Options *options
= new ReaderWriter::Options(*(Registry::instance()->getOptions()));
options->setDatabasePath(path.str());
return options;
}

View File

@@ -0,0 +1,30 @@
// PathOptions.hxx -- make an osgDB Options object from a path
// Copyright (C) 2007 Tim Moore timoore@redhat.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library 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
// Library 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 PATHOPTIONSHXX
#define PATHOPTIONSHXX 1
#include <osgDB/ReaderWriter>
#include <simgear/misc/sg_path.hxx>
namespace simgear
{
osgDB::ReaderWriter::Options* makeOptionsFromPath(const SGPath&);
}
#endif

View File

@@ -39,13 +39,8 @@
* define directory path separators
*/
#if defined( macintosh )
static const char sgDirPathSep = ':';
static const char sgDirPathSepBad = '/';
#else
static const char sgDirPathSep = '/';
static const char sgDirPathSepBad = '\\';
#endif
#if defined( WIN32 ) && !defined(__CYGWIN__)
static const char sgSearchPathSep = ';';
@@ -165,7 +160,7 @@ string SGPath::base() const {
}
}
// get the extention (everything after the final ".")
// get the extension (everything after the final ".")
// but make sure no "/" follows the "." character (otherwise it
// is has to be a directory name containing a ".").
string SGPath::extension() const {
@@ -193,10 +188,10 @@ bool SGPath::exists() const {
#endif
void SGPath::create_dir( mode_t mode ) {
int SGPath::create_dir( mode_t mode ) {
string_list dirlist = sgPathSplit(dir());
if ( dirlist.empty() )
return;
return -1;
string path = dirlist[0];
string_list path_elements = sgPathBranchSplit(path);
bool absolute = !path.empty() && path[0] == sgDirPathSep;
@@ -216,19 +211,21 @@ void SGPath::create_dir( mode_t mode ) {
dir.append(path_elements[i]);
}
if ( r == 0 ) {
return; // Directory already exists
return 0; // Directory already exists
}
if ( sgMkDir( dir.c_str(), mode) ) {
SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );
return;
return -2;
}
for(;i < path_elements.size(); i++) {
for(; i < path_elements.size(); i++) {
dir.append(path_elements[i]);
if ( sgMkDir( dir.c_str(), mode) ) {
SG_LOG( SG_IO, SG_ALERT, "Error creating directory: " + dir.str() );
break;
return -2;
}
}
return 0;
}
string_list sgPathBranchSplit( const string &dirpath ) {

View File

@@ -31,11 +31,11 @@
#include <sys/types.h>
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <simgear/math/sg_types.hxx>
SG_USING_STD(string);
using std::string;
#ifdef _MSC_VER
typedef int mode_t;
@@ -91,7 +91,7 @@ public:
/**
* Concatenate a string to the end of the path without inserting a
* path separator.
* @param p addtional path suffix
* @param p additional path suffix
*/
void concat( const string& p );
@@ -114,8 +114,8 @@ public:
string base() const;
/**
* Get the extention part of the path (everything after the final ".")
* @return the extention string
* Get the extension part of the path (everything after the final ".")
* @return the extension string
*/
string extension() const;
@@ -139,8 +139,9 @@ public:
/**
* Create the designated directory.
* @return 0 on success, or <0 on failure.
*/
void create_dir(mode_t mode);
int create_dir(mode_t mode);
private:

View File

@@ -21,18 +21,15 @@
// $Id$
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <ctype.h> // isspace()
#ifdef SG_HAVE_STD_INCLUDES
# include <cerrno>
#else
# include <errno.h>
#endif
#include <cerrno>
#include "sgstream.hxx"
using std::string;
using std::istream;
sg_gzifstream::sg_gzifstream()
: istream(&gzbuf)
{
@@ -106,11 +103,7 @@ skipeol( istream& in )
char c = '\0';
// skip to end of line.
#ifdef __MWERKS__
while ( in.get(c) && c != '\0' ) {
#else
while ( in.get(c) ) {
#endif
if ( (c == '\n') || (c == '\r') ) {
break;
}
@@ -122,17 +115,9 @@ skipeol( istream& in )
istream&
skipws( istream& in ) {
char c;
#ifdef __MWERKS__
while ( in.get(c) && c != '\0' ) {
#else
while ( in.get(c) ) {
#endif
#ifdef __MWERKS__
if ( ! isspace( c ) && c != '\n' ) {
#else
if ( ! isspace( c ) ) {
#endif
// put pack the non-space character
in.putback(c);
break;
@@ -147,11 +132,7 @@ skipcomment( istream& in )
while ( in )
{
// skip whitespace
#ifdef __MWERKS__
in >> ::skipws;
#else
in >> skipws;
#endif
char c;
if ( in.get( c ) && c != '#' )

View File

@@ -33,26 +33,16 @@
#include <simgear/compiler.h>
#if defined( SG_HAVE_STD_INCLUDES )
# include <istream>
#elif defined ( __BORLANDC__ )
# include <iostream>
#else
# include <istream.h>
#endif
#include STL_STRING
#include <string>
#include <simgear/misc/zfstream.hxx>
SG_USING_STD(string);
SG_USING_STD(istream);
/**
* An envelope class for gzifstream.
*/
class sg_gzifstream : private gzifstream_base, public istream
class sg_gzifstream : private gzifstream_base, public std::istream
{
public:
/** Default constructor */
@@ -64,7 +54,7 @@ public:
* @param name name of file
* @param io_mode file open mode(s) "or'd" together
*/
sg_gzifstream( const string& name,
sg_gzifstream( const std::string& name,
ios_openmode io_mode = ios_in | ios_binary );
/**
@@ -79,7 +69,7 @@ public:
* @param name name of file
* @param io_mode file open mode(s) "or'd" together
*/
void open( const string& name,
void open( const std::string& name,
ios_openmode io_mode = ios_in|ios_binary );
/**
@@ -108,14 +98,14 @@ private:
* An istream manipulator that skips to end of line.
* @param in input stream
*/
istream& skipeol( istream& in );
std::istream& skipeol( std::istream& in );
/**
* \relates sg_gzifstream
* An istream manipulator that skips over white space.
* @param in input stream
*/
istream& skipws( istream& in );
std::istream& skipws( std::istream& in );
/**
* \relates sg_gzifstream
@@ -123,7 +113,7 @@ istream& skipws( istream& in );
* Ignores comments that start with '#'.
* @param in input stream
*/
istream& skipcomment( istream& in );
std::istream& skipcomment( std::istream& in );
#endif /* _SGSTREAM_HXX */

View File

@@ -21,6 +21,8 @@
// $Id$
#include <ctype.h>
#include <cstring>
#include "strutils.hxx"
namespace simgear {
@@ -82,7 +84,7 @@ namespace simgear {
return split_whitespace( str, maxsplit );
vector<string> result;
int n = strlen( sep );
int n = std::strlen( sep );
if (n == 0)
{
// Error: empty separator string
@@ -96,7 +98,7 @@ namespace simgear {
while (i+n <= len)
{
if (s[i] == sep[0] && (n == 1 || memcmp(s+i, sep, n) == 0))
if (s[i] == sep[0] && (n == 1 || std::memcmp(s+i, sep, n) == 0))
{
result.push_back( str.substr(j,i-j) );
i = j = i + n;

View File

@@ -29,18 +29,14 @@
#include <simgear/compiler.h>
#include STL_STRING
#include <string>
#include <vector>
SG_USING_STD(vector);
using std::vector;
#ifdef SG_HAVE_STD_INCLUDES
# include <cstdlib>
#else
# include <stdlib.h>
#endif
#include <cstdlib>
SG_USING_STD(string);
using std::string;
namespace simgear {
namespace strutils {

View File

@@ -20,6 +20,8 @@
//
// $Id$
#include <cstdlib>
#include "tabbed_values.hxx"
#include "assert.h"
@@ -86,7 +88,7 @@ double SGTabbedValues::getDoubleAt(const unsigned int offset) const
/* this is safe because strtod will stop parsing when it sees an unrecogznied
character, which includes tab. */
return strtod(data, NULL);
return std::strtod(data, NULL);
}
long SGTabbedValues::getLongAt(const unsigned int offset) const
@@ -95,5 +97,5 @@ long SGTabbedValues::getLongAt(const unsigned int offset) const
if (!data || (*data == '\t'))
return 0;
return strtol(data, NULL, 0);
return std::strtol(data, NULL, 0);
}

View File

@@ -26,10 +26,10 @@
#include <simgear/compiler.h>
#include <vector>
#include STL_STRING
#include <string>
SG_USING_STD(vector);
SG_USING_STD(string);
using std::vector;
using std::string;
class SGTabbedValues
{

View File

@@ -4,12 +4,12 @@
#include <simgear/compiler.h>
#include STL_IOSTREAM
#include <iostream>
#include "tabbed_values.hxx"
SG_USING_STD(cout);
SG_USING_STD(cerr);
SG_USING_STD(endl);
using std::cout;
using std::cerr;
using std::endl;
int main (int ac, char ** av)

View File

@@ -145,12 +145,12 @@ enter this in the official comments in case I forget again. :-)
#include <simgear/compiler.h>
// #include STL_IOSTREAM
// #include <iostream>
#include "texcoord.hxx"
// SG_USING_STD(cout);
// SG_USING_STD(endl);
// using std::cout;
// using std::endl;
#define FG_STANDARD_TEXTURE_DIMENSION 1000.0 // meters
@@ -176,13 +176,19 @@ static inline Point3D basic_tex_coord( const Point3D& p,
// calculate "none stretching" texture coordinates
point_list sgCalcTexCoords( const SGBucket& b, const point_list& geod_nodes,
const int_list& fan, double scale )
{
return sgCalcTexCoords(b.get_center_lat(), geod_nodes, fan, scale);
}
point_list sgCalcTexCoords( double centerLat, const point_list& geod_nodes,
const int_list& fan, double scale )
{
// cout << "calculating texture coordinates for a specific fan of size = "
// << fan.size() << endl;
// calculate perimeter based on center of this degree (not center
// of bucket)
double clat = (int)b.get_center_lat();
double clat = (int)centerLat;
if ( clat > 0 ) {
clat = (int)clat + 0.5;
} else {

View File

@@ -49,5 +49,8 @@
point_list sgCalcTexCoords( const SGBucket& b, const point_list& geod_nodes,
const int_list& fan, double scale = 1.0 );
point_list sgCalcTexCoords( double centerLat, const point_list& geod_nodes,
const int_list& fan, double scale = 1.0 );
#endif // _TEXCOORD_HXX

View File

@@ -23,11 +23,7 @@
#include <simgear/compiler.h>
#ifdef SG_HAVE_STD_INCLUDES
# include <cerrno>
#else
# include <errno.h>
#endif
#include <cerrno>
#include <memory.h>
#include <stdio.h>
@@ -38,13 +34,9 @@
// Allocate memory for 'get' buffer and zero all buffer pointers.
//
gzfilebuf::gzfilebuf()
: streambuf(),
: std::streambuf(),
file(NULL),
#if defined( __MWERKS__ ) || __GNUC__ > 2
mode(ios_openmode(0)),
#else
mode(0),
#endif
own_file_descriptor(false),
ibuf_size(0),
ibuffer(0)
@@ -174,10 +166,10 @@ gzfilebuf::close()
// }
streampos
gzfilebuf::seekoff( streamoff, ios_seekdir, int )
std::streampos
gzfilebuf::seekoff( std::streamoff, ios_seekdir, int )
{
return streampos(EOF);
return std::streampos(EOF);
}
gzfilebuf::int_type

View File

@@ -31,75 +31,33 @@
#include <zlib.h>
#ifdef SG_HAVE_STD_INCLUDES
# include <streambuf>
# include <istream>
#include <streambuf>
#include <istream>
# define ios_openmode ios_base::openmode
# define ios_in ios_base::in
# define ios_out ios_base::out
# define ios_app ios_base::app
# define ios_binary ios_base::binary
#define ios_openmode std::ios_base::openmode
#define ios_in std::ios_base::in
#define ios_out std::ios_base::out
#define ios_app std::ios_base::app
#define ios_binary std::ios_base::binary
# define ios_seekdir ios_base::seekdir
#define ios_seekdir std::ios_base::seekdir
# define ios_badbit ios_base::badbit
# define ios_failbit ios_base::failbit
SG_USING_STD(streambuf);
SG_USING_STD(ios_base);
SG_USING_STD(streampos);
SG_USING_STD(streamoff);
#else
# ifdef SG_HAVE_STREAMBUF
# include <streambuf.h>
# include <istream.h>
# else
# include <iostream.h>
# endif
//# define ios_openmode ios::open_mode
# define ios_openmode int
# define ios_in ios::in
# define ios_out ios::out
# define ios_app ios::app
#if defined(__GNUC__) && __GNUC_MINOR__ < 8
# define ios_binary ios::bin
#else
# define ios_binary ios::binary
#endif
# define ios_seekdir ios::seek_dir
# define ios_badbit ios::badbit
# define ios_failbit ios::failbit
# include <simgear/sg_traits.hxx>
#endif // SG_HAVE_STD_INCLUDES
#define ios_badbit std::ios_base::badbit
#define ios_failbit std::ios_base::failbit
/**
* A C++ I/O streams interface to the zlib gz* functions.
*/
#ifdef SG_NEED_STREAMBUF_HACK
class gzfilebuf : public __streambuf
class gzfilebuf : public __streambuf {
typedef __streambuf parent;
#else
class gzfilebuf : public streambuf
class gzfilebuf : public std::streambuf {
typedef std::streambuf parent;
#endif
{
public:
#ifndef SG_HAVE_STD_INCLUDES
typedef char_traits<char> traits_type;
typedef char_traits<char>::int_type int_type;
// typedef char_traits<char>::pos_type pos_type;
// typedef char_traits<char>::off_type off_type;
#endif
/** Constructor */
gzfilebuf();
@@ -132,7 +90,7 @@ public:
bool is_open() const { return (file != NULL); }
/** @return stream position */
virtual streampos seekoff( streamoff off, ios_seekdir way, int which );
virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, int which );
/** sync the stream */
virtual int sync();
@@ -140,12 +98,8 @@ public:
protected:
virtual int_type underflow();
#ifndef SG_HAVE_STD_INCLUDES
virtual int_type overflow( int_type c = traits_type::eof() );
#else
virtual int_type overflow( int_type c = streambuf::traits_type::eof() );
#endif
virtual int_type overflow( int_type c = parent::traits_type::eof() );
private:
int_type flushbuf();

View File

@@ -16,7 +16,7 @@ static unsigned int fld(naContext c, unsigned char* s,
int i;
unsigned int fld = 0;
if(bit + flen > 8*slen) naRuntimeError(c, "bitfield out of bounds");
for(i=0; i<flen; i++) if(BIT(s, slen, i+bit)) fld |= (1<<i);
for(i=0; i<flen; i++) if(BIT(s, slen, bit+flen-i-1)) fld |= (1<<i);
return fld;
}
@@ -32,13 +32,13 @@ static void setfld(naContext c, unsigned char* s, int slen,
static naRef dofld(naContext c, int argc, naRef* args, int sign)
{
struct naStr* s = argc > 0 ? PTR(args[0]).str : 0;
naRef s = argc > 0 ? args[0] : naNil();
int bit = argc > 1 ? (int)naNumValue(args[1]).num : -1;
int len = argc > 2 ? (int)naNumValue(args[2]).num : -1;
unsigned int f;
if(!s || !MUTABLE(args[0]) || bit < 0 || len < 0)
if(!naIsString(s) || !MUTABLE(args[0]) || bit < 0 || len < 0)
naRuntimeError(c, "missing/bad argument to fld/sfld");
f = fld(c, s->data, s->len, bit, len);
f = fld(c, (void*)naStr_data(s), naStr_len(s), bit, len);
if(!sign) return naNum(f);
if(f & (1 << (len-1))) f |= ~((1<<len)-1); // sign extend
return naNum((signed int)f);
@@ -56,13 +56,13 @@ static naRef f_fld(naContext c, naRef me, int argc, naRef* args)
static naRef f_setfld(naContext c, naRef me, int argc, naRef* args)
{
struct naStr* s = argc > 0 ? PTR(args[0]).str : 0;
naRef s = argc > 0 ? args[0] : naNil();
int bit = argc > 1 ? (int)naNumValue(args[1]).num : -1;
int len = argc > 2 ? (int)naNumValue(args[2]).num : -1;
naRef val = argc > 3 ? naNumValue(args[3]) : naNil();
if(!argc || !MUTABLE(args[0])|| bit < 0 || len < 0 || IS_NIL(val))
naRuntimeError(c, "missing/bad argument to setfld");
setfld(c, s->data, s->len, bit, len, (unsigned int)val.num);
setfld(c, (void*)naStr_data(s), naStr_len(s), bit, len, (unsigned int)val.num);
return naNil();
}

View File

@@ -17,7 +17,7 @@
#endif
char* opStringDEBUG(int op);
void printOpDEBUG(int ip, int op);
void printStackDEBUG(struct Context* ctx);
void printStackDEBUG(naContext ctx);
////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
@@ -26,10 +26,10 @@ void printStackDEBUG(struct Context* ctx);
struct Globals* globals = 0;
static naRef bindFunction(struct Context* ctx, struct Frame* f, naRef code);
static naRef bindFunction(naContext ctx, struct Frame* f, naRef code);
#define ERR(c, msg) naRuntimeError((c),(msg))
void naRuntimeError(struct Context* c, const char* fmt, ...)
void naRuntimeError(naContext c, const char* fmt, ...)
{
va_list ap;
va_start(ap, fmt);
@@ -54,7 +54,7 @@ static naRef endToken()
return r;
}
static int boolify(struct Context* ctx, naRef r)
static int boolify(naContext ctx, naRef r)
{
if(IS_NUM(r)) return r.num != 0;
if(IS_NIL(r) || IS_END(r)) return 0;
@@ -68,7 +68,7 @@ static int boolify(struct Context* ctx, naRef r)
return 0;
}
static double numify(struct Context* ctx, naRef o)
static double numify(naContext ctx, naRef o)
{
double n;
if(IS_NUM(o)) return o.num;
@@ -79,7 +79,7 @@ static double numify(struct Context* ctx, naRef o)
return 0;
}
static naRef stringify(struct Context* ctx, naRef r)
static naRef stringify(naContext ctx, naRef r)
{
if(IS_STR(r)) return r;
if(IS_NUM(r)) return naStr_fromnum(naNewString(ctx), r.num);
@@ -87,7 +87,7 @@ static naRef stringify(struct Context* ctx, naRef r)
return naNil();
}
static int checkVec(struct Context* ctx, naRef vec, naRef idx)
static int checkVec(naContext ctx, naRef vec, naRef idx)
{
int i = (int)numify(ctx, idx);
if(i < 0) i += naVec_size(vec);
@@ -97,7 +97,7 @@ static int checkVec(struct Context* ctx, naRef vec, naRef idx)
return i;
}
static int checkStr(struct Context* ctx, naRef str, naRef idx)
static int checkStr(naContext ctx, naRef str, naRef idx)
{
int i = (int)numify(ctx, idx);
if(i < 0) i += naStr_len(str);
@@ -107,23 +107,22 @@ static int checkStr(struct Context* ctx, naRef str, naRef idx)
return i;
}
static naRef containerGet(struct Context* ctx, naRef box, naRef key)
static naRef containerGet(naContext ctx, naRef box, naRef key)
{
naRef result = naNil();
if(!IS_SCALAR(key)) ERR(ctx, "container index not scalar");
if(IS_HASH(box)) {
if(IS_HASH(box))
naHash_get(box, key, &result);
} else if(IS_VEC(box)) {
else if(IS_VEC(box))
result = naVec_get(box, checkVec(ctx, box, key));
} else if(IS_STR(box)) {
else if(IS_STR(box))
result = naNum((unsigned char)naStr_data(box)[checkStr(ctx, box, key)]);
} else {
else
ERR(ctx, "extract from non-container");
}
return result;
}
static void containerSet(struct Context* ctx, naRef box, naRef key, naRef val)
static void containerSet(naContext ctx, naRef box, naRef key, naRef val)
{
if(!IS_SCALAR(key)) ERR(ctx, "container index not scalar");
else if(IS_HASH(box)) naHash_set(box, key, val);
@@ -135,14 +134,14 @@ static void containerSet(struct Context* ctx, naRef box, naRef key, naRef val)
} else ERR(ctx, "insert into non-container");
}
static void initTemps(struct Context* c)
static void initTemps(naContext c)
{
c->tempsz = 4;
c->temps = naAlloc(c->tempsz * sizeof(struct naObj*));
c->ntemps = 0;
}
static void initContext(struct Context* c)
static void initContext(naContext c)
{
int i;
c->fTop = c->opTop = c->markTop = 0;
@@ -164,7 +163,7 @@ static void initContext(struct Context* c)
static void initGlobals()
{
int i;
struct Context* c;
naContext c;
globals = (struct Globals*)naAlloc(sizeof(struct Globals));
naBZero(globals, sizeof(struct Globals));
@@ -194,9 +193,9 @@ static void initGlobals()
naFreeContext(c);
}
struct Context* naNewContext()
naContext naNewContext()
{
struct Context* c;
naContext c;
if(globals == 0)
initGlobals();
@@ -209,7 +208,7 @@ struct Context* naNewContext()
initContext(c);
} else {
UNLOCK();
c = (struct Context*)naAlloc(sizeof(struct Context));
c = (naContext)naAlloc(sizeof(struct Context));
initTemps(c);
initContext(c);
LOCK();
@@ -221,16 +220,16 @@ struct Context* naNewContext()
return c;
}
struct Context* naSubContext(struct Context* super)
naContext naSubContext(naContext super)
{
struct Context* ctx = naNewContext();
naContext ctx = naNewContext();
if(super->callChild) naFreeContext(super->callChild);
ctx->callParent = super;
super->callChild = ctx;
return ctx;
}
void naFreeContext(struct Context* c)
void naFreeContext(naContext c)
{
c->ntemps = 0;
if(c->callChild) naFreeContext(c->callChild);
@@ -260,45 +259,66 @@ static void setupArgs(naContext ctx, struct Frame* f, naRef* args, int nargs)
naRuntimeError(ctx, "too few function args (have %d need %d)",
nargs, c->nArgs);
for(i=0; i<c->nArgs; i++)
naHash_newsym(PTR(f->locals).hash,
&c->constants[c->argSyms[i]], &args[i]);
naiHash_newsym(PTR(f->locals).hash,
&c->constants[ARGSYMS(c)[i]], &args[i]);
args += c->nArgs;
nargs -= c->nArgs;
for(i=0; i<c->nOptArgs; i++, nargs--) {
naRef val = nargs > 0 ? args[i] : c->constants[c->optArgVals[i]];
naRef val = nargs > 0 ? args[i] : c->constants[OPTARGVALS(c)[i]];
if(IS_CODE(val))
val = bindFunction(ctx, &ctx->fStack[ctx->fTop-2], val);
naHash_newsym(PTR(f->locals).hash, &c->constants[c->optArgSyms[i]],
naiHash_newsym(PTR(f->locals).hash, &c->constants[OPTARGSYMS(c)[i]],
&val);
}
args += c->nOptArgs;
if(c->needArgVector || nargs > 0) {
naRef argsv = naNewVector(ctx);
naVec_setsize(argsv, nargs > 0 ? nargs : 0);
naRef argv = naNewVector(ctx);
naVec_setsize(argv, nargs > 0 ? nargs : 0);
for(i=0; i<nargs; i++)
PTR(argsv).vec->rec->array[i] = *args++;
naHash_newsym(PTR(f->locals).hash, &c->restArgSym, &argsv);
PTR(argv).vec->rec->array[i] = *args++;
naiHash_newsym(PTR(f->locals).hash, &c->constants[c->restArgSym], &argv);
}
}
static struct Frame* setupFuncall(struct Context* ctx, int nargs, int mcall)
static void checkNamedArgs(naContext ctx, struct naCode* c, struct naHash* h)
{
naRef *frame;
int i;
naRef sym, rest, dummy;
for(i=0; i<c->nArgs; i++) {
sym = c->constants[ARGSYMS(c)[i]];
if(!naiHash_sym(h, PTR(sym).str, &dummy))
naRuntimeError(ctx, "Missing arg: %s", naStr_data(sym));
}
for(i=0; i<c->nOptArgs; i++) {
sym = c->constants[OPTARGSYMS(c)[i]];
if(!naiHash_sym(h, PTR(sym).str, &dummy))
naiHash_newsym(h, &sym, &c->constants[OPTARGVALS(c)[i]]);
}
if(c->needArgVector) {
sym = c->constants[c->restArgSym];
if(!naiHash_sym(h, PTR(sym).str, &dummy)) {
rest = naNewVector(ctx);
naiHash_newsym(h, &sym, &rest);
}
}
}
static struct Frame* setupFuncall(naContext ctx, int nargs, int mcall, int named)
{
naRef *args, func, code, obj = naNil();
struct Frame* f;
DBG(printf("setupFuncall(nargs:%d, mcall:%d)\n", nargs, mcall);)
int opf = ctx->opTop - nargs;
frame = &ctx->opStack[ctx->opTop - nargs - 1];
if(!IS_FUNC(frame[0]))
ERR(ctx, "function/method call invoked on uncallable object");
args = &ctx->opStack[opf];
func = ctx->opStack[--opf];
if(!IS_FUNC(func)) ERR(ctx, "function/method call on uncallable object");
code = PTR(func).func->code;
if(mcall) obj = ctx->opStack[--opf];
ctx->opFrame = opf;
ctx->opFrame = ctx->opTop - (nargs + 1 + mcall);
// Just do native calls right here
if(PTR(PTR(frame[0]).func->code).obj->type == T_CCODE) {
naRef obj = mcall ? frame[-1] : naNil();
naCFunction fp = PTR(PTR(frame[0]).func->code).ccode->fptr;
naRef result = (*fp)(ctx, obj, nargs, frame + 1);
if(IS_CCODE(code)) {
naRef result = (*PTR(code).ccode->fptr)(ctx, obj, nargs, args);
if(named) ERR(ctx, "native functions have no named arguments");
ctx->opTop = ctx->opFrame;
PUSH(result);
return &(ctx->fStack[ctx->fTop-1]);
@@ -306,23 +326,19 @@ static struct Frame* setupFuncall(struct Context* ctx, int nargs, int mcall)
if(ctx->fTop >= MAX_RECURSION) ERR(ctx, "call stack overflow");
// Note: assign nil first, otherwise the naNew() can cause a GC,
// which will now (after fTop++) see the *old* reference as a
// markable value!
f = &(ctx->fStack[ctx->fTop++]);
f->locals = f->func = naNil();
f->locals = naNewHash(ctx);
f->func = frame[0];
f = &(ctx->fStack[ctx->fTop]);
f->locals = named ? args[0] : naNewHash(ctx);
f->func = func;
f->ip = 0;
f->bp = ctx->opFrame;
if(mcall)
naHash_set(f->locals, globals->meRef, frame[-1]);
if(mcall) naHash_set(f->locals, globals->meRef, obj);
setupArgs(ctx, f, frame+1, nargs);
if(named) checkNamedArgs(ctx, PTR(code).code, PTR(f->locals).hash);
else setupArgs(ctx, f, args, nargs);
ctx->opTop = f->bp; // Pop the stack last, to avoid GC lossage
DBG(printf("Entering frame %d with %d args\n", ctx->fTop-1, nargs);)
ctx->fTop++;
ctx->opTop = f->bp; /* Pop the stack last, to avoid GC lossage */
return f;
}
@@ -350,7 +366,7 @@ static naRef evalCat(naContext ctx, naRef l, naRef r)
// When a code object comes out of the constant pool and shows up on
// the stack, it needs to be bound with the lexical context.
static naRef bindFunction(struct Context* ctx, struct Frame* f, naRef code)
static naRef bindFunction(naContext ctx, struct Frame* f, naRef code)
{
naRef result = naNewFunc(ctx, code);
PTR(result).func->namespace = f->locals;
@@ -367,7 +383,7 @@ static int getClosure(struct naFunc* c, naRef sym, naRef* result)
return 0;
}
static naRef getLocal2(struct Context* ctx, struct Frame* f, naRef sym)
static naRef getLocal2(naContext ctx, struct Frame* f, naRef sym)
{
naRef result;
if(!naHash_get(f->locals, sym, &result))
@@ -376,16 +392,15 @@ static naRef getLocal2(struct Context* ctx, struct Frame* f, naRef sym)
return result;
}
static void getLocal(struct Context* ctx, struct Frame* f,
naRef* sym, naRef* out)
static void getLocal(naContext ctx, struct Frame* f, naRef* sym, naRef* out)
{
struct naFunc* func;
struct naStr* str = PTR(*sym).str;
if(naHash_sym(PTR(f->locals).hash, str, out))
if(naiHash_sym(PTR(f->locals).hash, str, out))
return;
func = PTR(f->func).func;
while(func && PTR(func->namespace).hash) {
if(naHash_sym(PTR(func->namespace).hash, str, out))
if(naiHash_sym(PTR(func->namespace).hash, str, out))
return;
func = PTR(func->next).func;
}
@@ -399,19 +414,18 @@ static void getLocal(struct Context* ctx, struct Frame* f,
static int setClosure(naRef func, naRef sym, naRef val)
{
struct naFunc* c = PTR(func).func;
if(c == 0) { return 0; }
else if(naHash_tryset(c->namespace, sym, val)) { return 1; }
else { return setClosure(c->next, sym, val); }
if(c == 0) return 0;
if(naiHash_tryset(c->namespace, sym, val)) return 1;
return setClosure(c->next, sym, val);
}
static naRef setSymbol(struct Frame* f, naRef sym, naRef val)
static void setSymbol(struct Frame* f, naRef sym, naRef val)
{
// Try the locals first, if not already there try the closures in
// order. Finally put it in the locals if nothing matched.
if(!naHash_tryset(f->locals, sym, val))
if(!naiHash_tryset(f->locals, sym, val))
if(!setClosure(f->func, sym, val))
naHash_set(f->locals, sym, val);
return val;
}
// Funky API: returns null to indicate no member, an empty string to
@@ -424,19 +438,19 @@ static const char* getMember_r(naRef obj, naRef field, naRef* out, int count)
naRef p;
struct VecRec* pv;
if(--count < 0) return "too many parents";
if(!IS_HASH(obj)) return 0;
if(!IS_HASH(obj)) return "non-objects have no members";
if(naHash_get(obj, field, out)) return "";
if(!naHash_get(obj, globals->parentsRef, &p)) return 0;
if(!IS_VEC(p)) return "object \"parents\" field not vector";
pv = PTR(p).vec->rec;
for(i=0; i<pv->size; i++) {
for(i=0; pv && i<pv->size; i++) {
const char* err = getMember_r(pv->array[i], field, out, count);
if(err) return err; /* either an error or success */
}
return 0;
}
static void getMember(struct Context* ctx, naRef obj, naRef fld,
static void getMember(naContext ctx, naRef obj, naRef fld,
naRef* result, int count)
{
const char* err = getMember_r(obj, fld, result, count);
@@ -453,7 +467,7 @@ int naMember_get(naRef obj, naRef field, naRef* out)
// OP_EACH works like a vector get, except that it leaves the vector
// and index on the stack, increments the index after use, and
// pushes a nil if the index is beyond the end.
static void evalEach(struct Context* ctx, int useIndex)
static void evalEach(naContext ctx, int useIndex)
{
int idx = (int)(ctx->opStack[ctx->opTop-1].num);
naRef vec = ctx->opStack[ctx->opTop-2];
@@ -466,13 +480,49 @@ static void evalEach(struct Context* ctx, int useIndex)
PUSH(useIndex ? naNum(idx) : naVec_get(vec, idx));
}
#define ARG() cd->byteCode[f->ip++]
static void evalUnpack(naContext ctx, int count)
{
naRef vec = ctx->opStack[--ctx->opTop];
if(!IS_VEC(vec) || naVec_size(vec) < count)
ERR(ctx, "short or invalid multi-assignment vector");
while(count--) PUSH(naVec_get(vec, count));
}
// FIXME: unify with almost identical checkVec() above
static int vbound(naContext ctx, naRef v, naRef ir, int end)
{
int sz=naVec_size(v), i = IS_NIL(ir) ? (end ? -1 : 0) : numify(ctx, ir);
if(IS_NIL(ir) && !sz) return i;
if(i < 0) i += sz;
if(i < 0 || i >= sz)
naRuntimeError(ctx, "slice index %d out of bounds (size: %d)",
i, sz);
return i;
}
static void evalSlice(naContext ctx, naRef src, naRef dst, naRef idx)
{
if(!IS_VEC(src)) ERR(ctx, "cannot slice non-vector");
naVec_append(dst, naVec_get(src, checkVec(ctx, src, idx)));
}
static void evalSlice2(naContext ctx, naRef src, naRef dst,
naRef start, naRef endr)
{
int i, end;
if(!IS_VEC(src)) ERR(ctx, "cannot slice non-vector");
end = vbound(ctx, src, endr, 1);
for(i = vbound(ctx, src, start, 0); i<=end; i++)
naVec_append(dst, naVec_get(src, i));
}
#define ARG() BYTECODE(cd)[f->ip++]
#define CONSTARG() cd->constants[ARG()]
#define POP() ctx->opStack[--ctx->opTop]
#define STK(n) (ctx->opStack[ctx->opTop-(n)])
#define FIXFRAME() f = &(ctx->fStack[ctx->fTop-1]); \
cd = PTR(PTR(f->func).func->code).code;
static naRef run(struct Context* ctx)
#define SETFRAME(F) f = (F); cd = PTR(PTR(f->func).func->code).code;
#define FIXFRAME() SETFRAME(&(ctx->fStack[ctx->fTop-1]))
static naRef run(naContext ctx)
{
struct Frame* f;
struct naCode* cd;
@@ -485,23 +535,15 @@ static naRef run(struct Context* ctx)
FIXFRAME();
while(1) {
op = cd->byteCode[f->ip++];
op = BYTECODE(cd)[f->ip++];
DBG(printf("Stack Depth: %d\n", ctx->opTop));
DBG(printOpDEBUG(f->ip-1, op));
switch(op) {
case OP_POP:
ctx->opTop--;
break;
case OP_DUP:
PUSH(ctx->opStack[ctx->opTop-1]);
break;
case OP_DUP2:
PUSH(ctx->opStack[ctx->opTop-2]);
PUSH(ctx->opStack[ctx->opTop-2]);
break;
case OP_XCHG:
a = STK(1); STK(1) = STK(2); STK(2) = a;
break;
case OP_POP: ctx->opTop--; break;
case OP_DUP: PUSH(STK(1)); break;
case OP_DUP2: PUSH(STK(2)); PUSH(STK(2)); break;
case OP_XCHG: a=STK(1); STK(1)=STK(2); STK(2)=a; break;
case OP_XCHG2: a=STK(1); STK(1)=STK(2); STK(2)=STK(3); STK(3)=a; break;
#define BINOP(expr) do { \
double l = IS_NUM(STK(2)) ? STK(2).num : numify(ctx, STK(2)); \
@@ -525,7 +567,7 @@ static naRef run(struct Context* ctx)
break;
case OP_CAT:
STK(2) = evalCat(ctx, STK(2), STK(1));
ctx->opTop -= 1;
ctx->opTop--;
break;
case OP_NEG:
STK(1) = naNum(-numify(ctx, STK(1)));
@@ -570,79 +612,80 @@ static naRef run(struct Context* ctx)
PUSH(b);
break;
case OP_SETSYM:
STK(2) = setSymbol(f, STK(2), STK(1));
setSymbol(f, STK(1), STK(2));
ctx->opTop--;
break;
case OP_SETLOCAL:
naHash_set(f->locals, STK(2), STK(1));
STK(2) = STK(1); // FIXME: reverse order of arguments instead!
naHash_set(f->locals, STK(1), STK(2));
ctx->opTop--;
break;
case OP_MEMBER:
getMember(ctx, STK(1), CONSTARG(), &STK(1), 64);
break;
case OP_SETMEMBER:
if(!IS_HASH(STK(3))) ERR(ctx, "non-objects have no members");
naHash_set(STK(3), STK(2), STK(1));
STK(3) = STK(1); // FIXME: fix arg order instead
if(!IS_HASH(STK(2))) ERR(ctx, "non-objects have no members");
naHash_set(STK(2), STK(1), STK(3));
ctx->opTop -= 2;
break;
case OP_INSERT:
containerSet(ctx, STK(3), STK(2), STK(1));
STK(3) = STK(1); // FIXME: codegen order again...
containerSet(ctx, STK(2), STK(1), STK(3));
ctx->opTop -= 2;
break;
case OP_EXTRACT:
STK(2) = containerGet(ctx, STK(2), STK(1));
ctx->opTop--;
break;
case OP_SLICE:
evalSlice(ctx, STK(3), STK(2), STK(1));
ctx->opTop--;
break;
case OP_SLICE2:
evalSlice2(ctx, STK(4), STK(3), STK(2), STK(1));
ctx->opTop -= 2;
break;
case OP_JMPLOOP:
// Identical to JMP, except for locking
naCheckBottleneck();
f->ip = cd->byteCode[f->ip];
DBG(printf(" [Jump to: %d]\n", f->ip);)
f->ip = BYTECODE(cd)[f->ip];
DBG(printf(" [Jump to: %d]\n", f->ip));
break;
case OP_JMP:
f->ip = cd->byteCode[f->ip];
DBG(printf(" [Jump to: %d]\n", f->ip);)
f->ip = BYTECODE(cd)[f->ip];
DBG(printf(" [Jump to: %d]\n", f->ip));
break;
case OP_JIFEND:
arg = ARG();
if(IS_END(STK(1))) {
ctx->opTop--; // Pops **ONLY** if it's nil!
f->ip = arg;
DBG(printf(" [Jump to: %d]\n", f->ip);)
DBG(printf(" [Jump to: %d]\n", f->ip));
}
break;
case OP_JIFTRUE:
arg = ARG();
if(boolify(ctx, STK(1))) {
f->ip = arg;
DBG(printf(" [Jump to: %d]\n", f->ip);)
DBG(printf(" [Jump to: %d]\n", f->ip));
}
break;
case OP_JIFNOT:
arg = ARG();
if(!boolify(ctx, STK(1))) {
f->ip = arg;
DBG(printf(" [Jump to: %d]\n", f->ip);)
DBG(printf(" [Jump to: %d]\n", f->ip));
}
break;
case OP_JIFNOTPOP:
arg = ARG();
if(!boolify(ctx, POP())) {
f->ip = arg;
DBG(printf(" [Jump to: %d]\n", f->ip);)
DBG(printf(" [Jump to: %d]\n", f->ip));
}
break;
case OP_FCALL:
f = setupFuncall(ctx, ARG(), 0);
cd = PTR(PTR(f->func).func->code).code;
break;
case OP_MCALL:
f = setupFuncall(ctx, ARG(), 1);
cd = PTR(PTR(f->func).func->code).code;
break;
case OP_FCALL: SETFRAME(setupFuncall(ctx, ARG(), 0, 0)); break;
case OP_MCALL: SETFRAME(setupFuncall(ctx, ARG(), 1, 0)); break;
case OP_FCALLH: SETFRAME(setupFuncall(ctx, 1, 0, 1)); break;
case OP_MCALLH: SETFRAME(setupFuncall(ctx, 1, 1, 1)); break;
case OP_RETURN:
a = STK(1);
ctx->dieArg = naNil();
@@ -672,11 +715,14 @@ static naRef run(struct Context* ctx)
case OP_BREAK2: // same, but also pop the mark stack
ctx->opTop = ctx->markStack[--ctx->markTop];
break;
case OP_UNPACK:
evalUnpack(ctx, ARG());
break;
default:
ERR(ctx, "BUG: bad opcode");
}
ctx->ntemps = 0; // reset GC temp vector
DBG(printStackDEBUG(ctx);)
DBG(printStackDEBUG(ctx));
}
return naNil(); // unreachable
}
@@ -685,12 +731,12 @@ static naRef run(struct Context* ctx)
#undef STK
#undef FIXFRAME
void naSave(struct Context* ctx, naRef obj)
void naSave(naContext ctx, naRef obj)
{
naVec_append(globals->save, obj);
}
int naStackDepth(struct Context* ctx)
int naStackDepth(naContext ctx)
{
return ctx ? ctx->fTop + naStackDepth(ctx->callChild): 0;
}
@@ -703,22 +749,22 @@ static int findFrame(naContext ctx, naContext* out, int fn)
return ctx->fTop - 1 - (fn - sd);
}
int naGetLine(struct Context* ctx, int frame)
int naGetLine(naContext ctx, int frame)
{
struct Frame* f;
frame = findFrame(ctx, &ctx, frame);
f = &ctx->fStack[frame];
if(IS_FUNC(f->func) && IS_CODE(PTR(f->func).func->code)) {
struct naCode* c = PTR(PTR(f->func).func->code).code;
unsigned short* p = c->lineIps + c->nLines - 2;
while(p >= c->lineIps && p[0] > f->ip)
unsigned short* p = LINEIPS(c) + c->nLines - 2;
while(p >= LINEIPS(c) && p[0] > f->ip)
p -= 2;
return p[1];
}
return -1;
}
naRef naGetSourceFile(struct Context* ctx, int frame)
naRef naGetSourceFile(naContext ctx, int frame)
{
naRef f;
frame = findFrame(ctx, &ctx, frame);
@@ -727,10 +773,10 @@ naRef naGetSourceFile(struct Context* ctx, int frame)
return PTR(f).code->srcFile;
}
char* naGetError(struct Context* ctx)
char* naGetError(naContext ctx)
{
if(IS_STR(ctx->dieArg))
return (char*)PTR(ctx->dieArg).str->data;
return naStr_data(ctx->dieArg);
return ctx->error[0] ? ctx->error : 0;
}
@@ -745,9 +791,11 @@ naRef naBindFunction(naContext ctx, naRef code, naRef closure)
naRef naBindToContext(naContext ctx, naRef code)
{
naRef func = naNewFunc(ctx, code);
struct Frame* f = &ctx->fStack[ctx->fTop-1];
PTR(func).func->namespace = f->locals;
PTR(func).func->next = f->func;
if(ctx->fTop) {
struct Frame* f = &ctx->fStack[ctx->fTop-1];
PTR(func).func->namespace = f->locals;
PTR(func).func->next = f->func;
}
return func;
}
@@ -769,7 +817,7 @@ naRef naCall(naContext ctx, naRef func, int argc, naRef* args,
// naRuntimeError() calls end up here:
if(setjmp(ctx->jumpHandle)) {
if(!ctx->callParent) naModUnlock(ctx);
if(!ctx->callParent) naModUnlock();
return naNil();
}
@@ -792,14 +840,15 @@ naRef naCall(naContext ctx, naRef func, int argc, naRef* args,
ctx->opTop = ctx->markTop = 0;
ctx->fTop = 1;
ctx->fStack[0].func = func;
ctx->fStack[0].locals = locals;
ctx->fStack[0].ip = 0;
ctx->fStack[0].bp = ctx->opTop;
if(args) setupArgs(ctx, ctx->fStack, args, argc);
setupArgs(ctx, ctx->fStack, args, argc);
result = run(ctx);
if(!ctx->callParent) naModUnlock(ctx);
if(!ctx->callParent) naModUnlock();
return result;
}
@@ -812,7 +861,7 @@ naRef naContinue(naContext ctx)
ctx->error[0] = 0;
if(setjmp(ctx->jumpHandle)) {
if(!ctx->callParent) naModUnlock(ctx);
if(!ctx->callParent) naModUnlock();
else naRethrowError(ctx);
return naNil();
}

View File

@@ -19,14 +19,14 @@
#define OBJ_CACHE_SZ 1
enum {
OP_NOT, OP_MUL, OP_PLUS, OP_MINUS, OP_DIV, OP_NEG,
OP_CAT, OP_LT, OP_LTE, OP_GT, OP_GTE, OP_EQ, OP_NEQ, OP_EACH,
OP_JMP, OP_JMPLOOP, OP_JIFNOTPOP, OP_JIFEND, OP_FCALL, OP_MCALL,
OP_RETURN, OP_PUSHCONST, OP_PUSHONE, OP_PUSHZERO, OP_PUSHNIL, OP_POP,
OP_DUP, OP_XCHG, OP_INSERT, OP_EXTRACT, OP_MEMBER, OP_SETMEMBER,
OP_LOCAL, OP_SETLOCAL, OP_NEWVEC, OP_VAPPEND, OP_NEWHASH, OP_HAPPEND,
OP_MARK, OP_UNMARK, OP_BREAK, OP_SETSYM, OP_DUP2, OP_INDEX, OP_BREAK2,
OP_PUSHEND, OP_JIFTRUE, OP_JIFNOT
OP_NOT, OP_MUL, OP_PLUS, OP_MINUS, OP_DIV, OP_NEG, OP_CAT, OP_LT, OP_LTE,
OP_GT, OP_GTE, OP_EQ, OP_NEQ, OP_EACH, OP_JMP, OP_JMPLOOP, OP_JIFNOTPOP,
OP_JIFEND, OP_FCALL, OP_MCALL, OP_RETURN, OP_PUSHCONST, OP_PUSHONE,
OP_PUSHZERO, OP_PUSHNIL, OP_POP, OP_DUP, OP_XCHG, OP_INSERT, OP_EXTRACT,
OP_MEMBER, OP_SETMEMBER, OP_LOCAL, OP_SETLOCAL, OP_NEWVEC, OP_VAPPEND,
OP_NEWHASH, OP_HAPPEND, OP_MARK, OP_UNMARK, OP_BREAK, OP_SETSYM, OP_DUP2,
OP_INDEX, OP_BREAK2, OP_PUSHEND, OP_JIFTRUE, OP_JIFNOT, OP_FCALLH,
OP_MCALLH, OP_XCHG2, OP_UNPACK, OP_SLICE, OP_SLICE2
};
struct Frame {

View File

@@ -1,3 +1,4 @@
#include <string.h>
#include "parse.h"
#include "code.h"
@@ -6,7 +7,7 @@
// These are more sensical predicate names in most contexts in this file
#define LEFT(tok) ((tok)->children)
#define RIGHT(tok) ((tok)->lastChild)
#define BINARY(tok) (LEFT(tok) && RIGHT(tok) && LEFT(tok) != RIGHT(tok))
#define BINARY(tok) (LEFT(tok) && RIGHT(tok) && LEFT(tok)->next == RIGHT(tok))
// Forward references for recursion
static void genExpr(struct Parser* p, struct Token* t);
@@ -46,12 +47,7 @@ static int newConstant(struct Parser* p, naRef c)
naVec_append(p->cg->consts, c);
i = naVec_size(p->cg->consts) - 1;
if(i > 0xffff) naParseError(p, "too many constants in code block", 0);
return i;
}
static naRef getConstant(struct Parser* p, int idx)
{
return naVec_get(p->cg->consts, idx);
return i;
}
// Interns a scalar (!) constant and returns its index
@@ -68,6 +64,10 @@ static int internConstant(struct Parser* p, naRef c)
return newConstant(p, c);
}
/* FIXME: this API is fundamentally a resource leak, because symbols
* can't be deregistered. The "proper" way to do this would be to
* keep a reference count for each symbol, and decrement it when a
* code object referencing it is deleted. */
naRef naInternSymbol(naRef sym)
{
naRef result;
@@ -93,23 +93,16 @@ static int findConstantIndex(struct Parser* p, struct Token* t)
static int genScalarConstant(struct Parser* p, struct Token* t)
{
// These opcodes are for special-case use in other constructs, but
// we might as well use them here to save a few bytes in the
// instruction stream.
if(t->str == 0 && t->num == 1) {
emit(p, OP_PUSHONE);
} else if(t->str == 0 && t->num == 0) {
emit(p, OP_PUSHZERO);
} else {
int idx = findConstantIndex(p, t);
emitImmediate(p, OP_PUSHCONST, idx);
return idx;
}
return 0;
int idx;
if(t->str == 0 && t->num == 1) { emit(p, OP_PUSHONE); return 0; }
if(t->str == 0 && t->num == 0) { emit(p, OP_PUSHZERO); return 0; }
emitImmediate(p, OP_PUSHCONST, idx = findConstantIndex(p, t));
return idx;
}
static int genLValue(struct Parser* p, struct Token* t, int* cidx)
{
if(!t) naParseError(p, "bad lvalue", -1);
if(t->type == TOK_LPAR && t->rule != PREC_SUFFIX) {
return genLValue(p, LEFT(t), cidx); // Handle stuff like "(a) = 1"
} else if(t->type == TOK_SYMBOL) {
@@ -134,7 +127,7 @@ static int genLValue(struct Parser* p, struct Token* t, int* cidx)
static void genEqOp(int op, struct Parser* p, struct Token* t)
{
int cidx, setop = genLValue(p, LEFT(t), &cidx);
int cidx, n = 2, setop = genLValue(p, LEFT(t), &cidx);
if(setop == OP_SETMEMBER) {
emit(p, OP_DUP2);
emit(p, OP_POP);
@@ -142,10 +135,13 @@ static void genEqOp(int op, struct Parser* p, struct Token* t)
} else if(setop == OP_INSERT) {
emit(p, OP_DUP2);
emit(p, OP_EXTRACT);
} else // OP_SETSYM, OP_SETLOCAL
} else {
emitImmediate(p, OP_LOCAL, cidx);
n = 1;
}
genExpr(p, RIGHT(t));
emit(p, op);
emit(p, n == 1 ? OP_XCHG : OP_XCHG2);
emit(p, setop);
}
@@ -168,27 +164,29 @@ static void genArgList(struct Parser* p, struct naCode* c, struct Token* t)
{
naRef sym;
if(t->type == TOK_EMPTY) return;
if(!IDENTICAL(c->restArgSym, globals->argRef))
naParseError(p, "remainder must be last", t->line);
if(!IDENTICAL(p->cg->restArgSym, globals->argRef))
naParseError(p, "remainder must be last", t->line);
if(t->type == TOK_ELLIPSIS) {
if(LEFT(t)->type != TOK_SYMBOL)
naParseError(p, "bad function argument expression", t->line);
sym = naStr_fromdata(naNewString(p->context),
LEFT(t)->str, LEFT(t)->strlen);
c->restArgSym = naInternSymbol(sym);
p->cg->restArgSym = naInternSymbol(sym);
c->needArgVector = 1;
} else if(t->type == TOK_ASSIGN) {
if(LEFT(t)->type != TOK_SYMBOL)
naParseError(p, "bad function argument expression", t->line);
c->optArgSyms[c->nOptArgs] = findConstantIndex(p, LEFT(t));
c->optArgVals[c->nOptArgs++] = defArg(p, RIGHT(t));
p->cg->optArgSyms[c->nOptArgs] = findConstantIndex(p, LEFT(t));
p->cg->optArgVals[c->nOptArgs++] = defArg(p, RIGHT(t));
} else if(t->type == TOK_SYMBOL) {
if(c->nOptArgs)
naParseError(p, "optional arguments must be last", t->line);
if(c->nArgs >= MAX_FUNARGS)
naParseError(p, "too many named function arguments", t->line);
c->argSyms[c->nArgs++] = findConstantIndex(p, t);
p->cg->argSyms[c->nArgs++] = findConstantIndex(p, t);
} else if(t->type == TOK_COMMA) {
if(!LEFT(t) || !RIGHT(t))
naParseError(p, "empty function argument", t->line);
genArgList(p, c, LEFT(t));
genArgList(p, c, RIGHT(t));
} else
@@ -218,12 +216,12 @@ static void genLambda(struct Parser* p, struct Token* t)
static int genList(struct Parser* p, struct Token* t, int doAppend)
{
if(t->type == TOK_COMMA) {
if(!t || t->type == TOK_EMPTY) {
return 0;
} else if(t->type == TOK_COMMA) {
genExpr(p, LEFT(t));
if(doAppend) emit(p, OP_VAPPEND);
return 1 + genList(p, RIGHT(t), doAppend);
} else if(t->type == TOK_EMPTY) {
return 0;
} else {
genExpr(p, t);
if(doAppend) emit(p, OP_VAPPEND);
@@ -233,9 +231,9 @@ static int genList(struct Parser* p, struct Token* t, int doAppend)
static void genHashElem(struct Parser* p, struct Token* t)
{
if(t->type == TOK_EMPTY)
if(!t || t->type == TOK_EMPTY)
return;
if(t->type != TOK_COLON)
if(t->type != TOK_COLON || !LEFT(t))
naParseError(p, "bad hash/object initializer", t->line);
if(LEFT(t)->type == TOK_SYMBOL) genScalarConstant(p, LEFT(t));
else if(LEFT(t)->type == TOK_LITERAL) genExpr(p, LEFT(t));
@@ -246,31 +244,45 @@ static void genHashElem(struct Parser* p, struct Token* t)
static void genHash(struct Parser* p, struct Token* t)
{
if(t->type == TOK_COMMA) {
if(t && t->type == TOK_COMMA) {
genHashElem(p, LEFT(t));
genHash(p, RIGHT(t));
} else if(t->type != TOK_EMPTY) {
} else if(t && t->type != TOK_EMPTY) {
genHashElem(p, t);
}
}
static int isHashcall(struct Parser* p, struct Token* t)
{
if(t) {
int sep = LEFT(t) && t->type == TOK_COMMA ? t->children->type : t->type;
return sep == TOK_COLON;
}
return 0;
}
static void genFuncall(struct Parser* p, struct Token* t)
{
int op = OP_FCALL;
int nargs = 0;
int method = 0;
if(LEFT(t)->type == TOK_DOT) {
method = 1;
genExpr(p, LEFT(LEFT(t)));
emit(p, OP_DUP);
emitImmediate(p, OP_MEMBER, findConstantIndex(p, RIGHT(LEFT(t))));
op = OP_MCALL;
} else {
genExpr(p, LEFT(t));
}
if(RIGHT(t)) nargs = genList(p, RIGHT(t), 0);
emitImmediate(p, op, nargs);
if(isHashcall(p, RIGHT(t))) {
emit(p, OP_NEWHASH);
genHash(p, RIGHT(t));
emit(p, method ? OP_MCALLH : OP_FCALLH);
} else {
int nargs = genList(p, RIGHT(t), 0);
emitImmediate(p, method ? OP_MCALL : OP_FCALL, nargs);
}
}
static void pushLoop(struct Parser* p, struct Token* label)
static int startLoop(struct Parser* p, struct Token* label)
{
int i = p->cg->loopTop;
p->cg->loops[i].breakIP = 0xffffff;
@@ -278,13 +290,7 @@ static void pushLoop(struct Parser* p, struct Token* label)
p->cg->loops[i].label = label;
p->cg->loopTop++;
emit(p, OP_MARK);
}
static void popLoop(struct Parser* p)
{
p->cg->loopTop--;
if(p->cg->loopTop < 0) naParseError(p, "BUG: loop stack underflow", -1);
emit(p, OP_UNMARK);
return p->cg->codesz;
}
// Emit a jump operation, and return the location of the address in
@@ -351,10 +357,11 @@ static void genQuestion(struct Parser* p, struct Token* t)
fixJumpTarget(p, jumpEnd);
}
static int countSemis(struct Token* t)
static int countList(struct Token* t, int type)
{
if(!t || t->type != TOK_SEMI) return 0;
return 1 + countSemis(RIGHT(t));
int n;
for(n = 1; t && t->type == type; t = RIGHT(t)) n++;
return n;
}
static void genLoop(struct Parser* p, struct Token* body,
@@ -376,7 +383,8 @@ static void genLoop(struct Parser* p, struct Token* body,
if(update) { genExpr(p, update); emit(p, OP_POP); }
emitImmediate(p, OP_JMPLOOP, loopTop);
fixJumpTarget(p, jumpEnd);
popLoop(p);
p->cg->loopTop--;
emit(p, OP_UNMARK);
emit(p, OP_PUSHNIL); // Leave something on the stack
}
@@ -386,8 +394,7 @@ static void genForWhile(struct Parser* p, struct Token* init,
{
int loopTop, jumpEnd;
if(init) { genExpr(p, init); emit(p, OP_POP); }
pushLoop(p, label);
loopTop = p->cg->codesz;
loopTop = startLoop(p, label);
genExpr(p, test);
jumpEnd = emitJump(p, OP_JIFNOTPOP);
genLoop(p, body, update, label, loopTop, jumpEnd);
@@ -396,14 +403,13 @@ static void genForWhile(struct Parser* p, struct Token* init,
static void genWhile(struct Parser* p, struct Token* t)
{
struct Token *test=LEFT(t)->children, *body, *label=0;
int semis = countSemis(test);
if(semis == 1) {
int len = countList(test, TOK_SEMI);
if(len == 2) {
label = LEFT(test);
if(!label || label->type != TOK_SYMBOL)
naParseError(p, "bad loop label", t->line);
test = RIGHT(test);
}
else if(semis != 0)
} else if(len != 1)
naParseError(p, "too many semicolons in while test", t->line);
body = LEFT(RIGHT(t));
genForWhile(p, 0, test, 0, body, label);
@@ -413,17 +419,14 @@ static void genFor(struct Parser* p, struct Token* t)
{
struct Token *init, *test, *body, *update, *label=0;
struct Token *h = LEFT(t)->children;
int semis = countSemis(h);
if(semis == 3) {
int len = countList(h, TOK_SEMI);
if(len == 4) {
if(!LEFT(h) || LEFT(h)->type != TOK_SYMBOL)
naParseError(p, "bad loop label", h->line);
label = LEFT(h);
h=RIGHT(h);
} else if(semis != 2) {
} else if(len != 3)
naParseError(p, "wrong number of terms in for header", t->line);
}
// Parse tree hell :)
init = LEFT(h);
test = LEFT(RIGHT(h));
update = RIGHT(RIGHT(h));
@@ -436,13 +439,13 @@ static void genForEach(struct Parser* p, struct Token* t)
int loopTop, jumpEnd, assignOp, dummy;
struct Token *elem, *body, *vec, *label=0;
struct Token *h = LEFT(LEFT(t));
int semis = countSemis(h);
if(semis == 2) {
int len = countList(h, TOK_SEMI);
if(len == 3) {
if(!LEFT(h) || LEFT(h)->type != TOK_SYMBOL)
naParseError(p, "bad loop label", h->line);
label = LEFT(h);
h = RIGHT(h);
} else if (semis != 1) {
} else if (len != 2) {
naParseError(p, "wrong number of terms in foreach header", t->line);
}
elem = LEFT(h);
@@ -451,12 +454,10 @@ static void genForEach(struct Parser* p, struct Token* t)
genExpr(p, vec);
emit(p, OP_PUSHZERO);
pushLoop(p, label);
loopTop = p->cg->codesz;
loopTop = startLoop(p, label);
emit(p, t->type == TOK_FOREACH ? OP_EACH : OP_INDEX);
jumpEnd = emitJump(p, OP_JIFEND);
assignOp = genLValue(p, elem, &dummy);
emit(p, OP_XCHG);
emit(p, assignOp);
emit(p, OP_POP);
genLoop(p, body, 0, label, loopTop, jumpEnd);
@@ -510,47 +511,112 @@ static void newLineEntry(struct Parser* p, int line)
p->cg->lineIps[p->cg->nextLineIp++] = (unsigned short) line;
}
static int parListLen(struct Token* t)
{
if(t->type != TOK_LPAR || !LEFT(t) || LEFT(t)->type != TOK_COMMA) return 0;
return countList(LEFT(t), TOK_COMMA);
}
static void genCommaList(struct Parser* p, struct Token* t)
{
if(t->type != TOK_COMMA) { genExpr(p, t); return; }
genCommaList(p, RIGHT(t));
genExpr(p, LEFT(t));
}
static void genMultiLV(struct Parser* p, struct Token* t, int var)
{
if(!var) { emit(p, genLValue(p, t, &var)); return; }
if(t->type != TOK_SYMBOL) naParseError(p, "bad lvalue", t->line);
genScalarConstant(p, t);
emit(p, OP_SETLOCAL);
}
static void genAssign(struct Parser* p, struct Token* t)
{
struct Token *lv = LEFT(t), *rv = RIGHT(t);
int len, dummy, var=0;
if(parListLen(lv) || (lv->type == TOK_VAR && parListLen(RIGHT(lv)))) {
if(lv->type == TOK_VAR) { lv = RIGHT(lv); var = 1; }
len = parListLen(lv);
if(rv->type == TOK_LPAR) {
if(len != parListLen(rv))
naParseError(p, "bad assignment count", rv->line);
genCommaList(p, LEFT(rv));
} else {
genExpr(p, rv);
emitImmediate(p, OP_UNPACK, len);
}
for(t = LEFT(lv); t && t->type == TOK_COMMA; t = RIGHT(t)) {
genMultiLV(p, LEFT(t), var);
emit(p, OP_POP);
}
genMultiLV(p, t, var);
} else {
genExpr(p, rv);
emit(p, genLValue(p, lv, &dummy));
}
}
static void genSlice(struct Parser* p, struct Token* t)
{
if(!t || t->type==TOK_EMPTY) naParseError(p, "empty slice expression", -1);
if(t->type == TOK_COLON) {
if(LEFT(t)) genExpr(p, LEFT(t)); else emit(p, OP_PUSHNIL);
if(RIGHT(t)) genExpr(p, RIGHT(t)); else emit(p, OP_PUSHNIL);
emit(p, OP_SLICE2);
} else {
genExpr(p, t);
emit(p, OP_SLICE);
}
}
static void genExtract(struct Parser* p, struct Token* t)
{
genExpr(p, LEFT(t));
if(countList(RIGHT(t), TOK_COMMA) == 1 && RIGHT(t)->type != TOK_COLON) {
genExpr(p, RIGHT(t));
emit(p, OP_EXTRACT);
} else {
emit(p, OP_NEWVEC);
for(t = RIGHT(t); t->type == TOK_COMMA; t = RIGHT(t))
genSlice(p, LEFT(t));
genSlice(p, t);
emit(p, OP_XCHG);
emit(p, OP_POP);
}
}
static void genExpr(struct Parser* p, struct Token* t)
{
int i, dummy;
int i;
if(!t) naParseError(p, "parse error", -1); // throw line -1...
p->errLine = t->line; // ...to use this one instead
if(t->line != p->cg->lastLine)
newLineEntry(p, t->line);
p->cg->lastLine = t->line;
switch(t->type) {
case TOK_IF:
genIfElse(p, t);
break;
case TOK_QUESTION:
genQuestion(p, t);
break;
case TOK_WHILE:
genWhile(p, t);
break;
case TOK_FOR:
genFor(p, t);
break;
case TOK_FOREACH:
case TOK_FORINDEX:
case TOK_TOP: genExprList(p, LEFT(t)); break;
case TOK_IF: genIfElse(p, t); break;
case TOK_QUESTION: genQuestion(p, t); break;
case TOK_WHILE: genWhile(p, t); break;
case TOK_FOR: genFor(p, t); break;
case TOK_FUNC: genLambda(p, t); break;
case TOK_ASSIGN: genAssign(p, t); break;
case TOK_LITERAL: genScalarConstant(p, t); break;
case TOK_FOREACH: case TOK_FORINDEX:
genForEach(p, t);
break;
case TOK_BREAK: case TOK_CONTINUE:
genBreakContinue(p, t);
break;
case TOK_TOP:
genExprList(p, LEFT(t));
break;
case TOK_FUNC:
genLambda(p, t);
break;
case TOK_LPAR:
if(BINARY(t) || !RIGHT(t)) genFuncall(p, t); // function invocation
else genExpr(p, LEFT(t)); // simple parenthesis
if(BINARY(t) || !RIGHT(t)) genFuncall(p, t);
else genExpr(p, LEFT(t));
break;
case TOK_LBRA:
if(BINARY(t)) {
genBinOp(OP_EXTRACT, p, t); // a[i]
genExtract(p, t);
} else {
emit(p, OP_NEWVEC);
genList(p, LEFT(t), 1);
@@ -560,11 +626,6 @@ static void genExpr(struct Parser* p, struct Token* t)
emit(p, OP_NEWHASH);
genHash(p, LEFT(t));
break;
case TOK_ASSIGN:
i = genLValue(p, LEFT(t), &dummy);
genExpr(p, RIGHT(t));
emit(p, i); // use the op appropriate to the lvalue
break;
case TOK_RETURN:
if(RIGHT(t)) genExpr(p, RIGHT(t));
else emit(p, OP_PUSHNIL);
@@ -578,9 +639,6 @@ static void genExpr(struct Parser* p, struct Token* t)
case TOK_SYMBOL:
emitImmediate(p, OP_LOCAL, findConstantIndex(p, t));
break;
case TOK_LITERAL:
genScalarConstant(p, t);
break;
case TOK_MINUS:
if(BINARY(t)) {
genBinOp(OP_MINUS, p, t); // binary subtraction
@@ -603,7 +661,8 @@ static void genExpr(struct Parser* p, struct Token* t)
emitImmediate(p, OP_MEMBER, findConstantIndex(p, RIGHT(t)));
break;
case TOK_EMPTY: case TOK_NIL:
emit(p, OP_PUSHNIL); break; // *NOT* a noop!
emit(p, OP_PUSHNIL);
break;
case TOK_AND: case TOK_OR:
genShortCircuit(p, t);
break;
@@ -660,51 +719,42 @@ naRef naCodeGen(struct Parser* p, struct Token* block, struct Token* arglist)
genExprList(p, block);
emit(p, OP_RETURN);
// Now make a code object
codeObj = naNewCode(p->context);
code = PTR(codeObj).code;
// Parse the argument list, if any
code->restArgSym = globals->argRef;
p->cg->restArgSym = globals->argRef;
code->nArgs = code->nOptArgs = 0;
code->argSyms = code->optArgSyms = code->optArgVals = 0;
p->cg->argSyms = p->cg->optArgSyms = p->cg->optArgVals = 0;
code->needArgVector = 1;
if(arglist) {
code->argSyms = naParseAlloc(p, sizeof(int) * MAX_FUNARGS);
code->optArgSyms = naParseAlloc(p, sizeof(int) * MAX_FUNARGS);
code->optArgVals = naParseAlloc(p, sizeof(int) * MAX_FUNARGS);
p->cg->argSyms = naParseAlloc(p, sizeof(int) * MAX_FUNARGS);
p->cg->optArgSyms = naParseAlloc(p, sizeof(int) * MAX_FUNARGS);
p->cg->optArgVals = naParseAlloc(p, sizeof(int) * MAX_FUNARGS);
code->needArgVector = 0;
genArgList(p, code, arglist);
if(code->nArgs) {
int i, *nsyms;
nsyms = naAlloc(sizeof(int) * code->nArgs);
for(i=0; i<code->nArgs; i++) nsyms[i] = code->argSyms[i];
code->argSyms = nsyms;
} else code->argSyms = 0;
if(code->nOptArgs) {
int i, *nsyms, *nvals;
nsyms = naAlloc(sizeof(int) * code->nOptArgs);
nvals = naAlloc(sizeof(int) * code->nOptArgs);
for(i=0; i<code->nOptArgs; i++) nsyms[i] = code->optArgSyms[i];
for(i=0; i<code->nOptArgs; i++) nvals[i] = code->optArgVals[i];
code->optArgSyms = nsyms;
code->optArgVals = nvals;
} else code->optArgSyms = code->optArgVals = 0;
}
code->codesz = cg.codesz;
code->byteCode = naAlloc(cg.codesz * sizeof(unsigned short));
for(i=0; i < cg.codesz; i++)
code->byteCode[i] = cg.byteCode[i];
code->restArgSym = internConstant(p, p->cg->restArgSym);
/* Set the size fields and allocate the combined array buffer.
* Note cute trick with null pointer to get the array size. */
code->nConstants = naVec_size(cg.consts);
code->constants = naAlloc(code->nConstants * sizeof(naRef));
code->codesz = cg.codesz;
code->nLines = cg.nextLineIp;
code->srcFile = p->srcFile;
code->constants = 0;
code->constants = naAlloc((int)(size_t)(LINEIPS(code)+code->nLines));
for(i=0; i<code->nConstants; i++)
code->constants[i] = getConstant(p, i);
code->nLines = p->cg->nextLineIp;
code->lineIps = naAlloc(sizeof(unsigned short)*p->cg->nLineIps*2);
for(i=0; i<p->cg->nLineIps*2; i++)
code->lineIps[i] = p->cg->lineIps[i];
code->constants[i] = naVec_get(p->cg->consts, i);
for(i=0; i<code->nArgs; i++) ARGSYMS(code)[i] = cg.argSyms[i];
for(i=0; i<code->nOptArgs; i++) OPTARGSYMS(code)[i] = cg.optArgSyms[i];
for(i=0; i<code->nOptArgs; i++) OPTARGVALS(code)[i] = cg.optArgVals[i];
for(i=0; i<code->codesz; i++) BYTECODE(code)[i] = cg.byteCode[i];
for(i=0; i<code->nLines; i++) LINEIPS(code)[i] = cg.lineIps[i];
return codeObj;
}

View File

@@ -76,8 +76,7 @@ enum { T_STR, T_VEC, T_HASH, T_CODE, T_FUNC, T_CCODE, T_GHOST,
#define IS_GHOST(r) (IS_OBJ(r) && PTR(r).obj->type == T_GHOST)
#define IS_CONTAINER(r) (IS_VEC(r)||IS_HASH(r))
#define IS_SCALAR(r) (IS_NUM(r) || IS_STR(r))
#define IDENTICAL(a, b) (IS_REF(a) && IS_REF(b) \
&& PTR(a).obj == PTR(b).obj)
#define IDENTICAL(a, b) (IS_REF(a) && IS_REF(b) && PTR(a).obj == PTR(b).obj)
#define MUTABLE(r) (IS_STR(r) && PTR(r).str->hashcode == 0)
@@ -93,11 +92,18 @@ struct naObj {
GC_HEADER;
};
#define MAX_STR_EMBLEN 15
struct naStr {
GC_HEADER;
int len;
unsigned char* data;
char emblen; /* [0-15], or -1 to indicate "not embedded" */
unsigned int hashcode;
union {
unsigned char buf[16];
struct {
int len;
unsigned char* ptr;
} ref;
} data;
};
struct VecRec {
@@ -117,14 +123,6 @@ struct HashNode {
struct HashNode* next;
};
struct HashRec {
int size;
int dels;
int lgalloced;
struct HashNode* nodes;
struct HashNode* table[];
};
struct naHash {
GC_HEADER;
struct HashRec* rec;
@@ -132,22 +130,26 @@ struct naHash {
struct naCode {
GC_HEADER;
unsigned char nArgs;
unsigned char nOptArgs;
unsigned char needArgVector;
unsigned int nArgs : 5;
unsigned int nOptArgs : 5;
unsigned int needArgVector : 1;
unsigned short nConstants;
unsigned short nLines;
unsigned short codesz;
unsigned short* byteCode;
naRef* constants;
int* argSyms; // indices into constants
int* optArgSyms;
int* optArgVals;
unsigned short* lineIps; // pairs of {ip, line}
unsigned short restArgSym; // The "..." vector name, defaults to "arg"
unsigned short nLines;
naRef srcFile;
naRef restArgSym; // The "..." vector name, defaults to "arg"
naRef* constants;
};
/* naCode objects store their variable length arrays in a single block
* starting with their constants table. Compute indexes at runtime
* for space efficiency: */
#define BYTECODE(c) ((unsigned short*)((c)->constants+(c)->nConstants))
#define ARGSYMS(c) (BYTECODE(c)+(c)->codesz)
#define OPTARGSYMS(c) (ARGSYMS(c)+(c)->nArgs)
#define OPTARGVALS(c) (OPTARGSYMS(c)+(c)->nOptArgs)
#define LINEIPS(c) (OPTARGVALS(c)+(c)->nOptArgs)
struct naFunc {
GC_HEADER;
naRef code;
@@ -194,17 +196,19 @@ int naStr_parsenum(char* str, int len, double* result);
int naStr_tonum(naRef str, double* out);
naRef naStr_buf(naRef str, int len);
int naHash_tryset(naRef hash, naRef key, naRef val); // sets if exists
int naHash_sym(struct naHash* h, struct naStr* sym, naRef* out);
void naHash_newsym(struct naHash* h, naRef* sym, naRef* val);
int naiHash_tryset(naRef hash, naRef key, naRef val); // sets if exists
int naiHash_sym(struct naHash* h, struct naStr* sym, naRef* out);
void naiHash_newsym(struct naHash* h, naRef* sym, naRef* val);
void naGC_init(struct naPool* p, int type);
struct naObj** naGC_get(struct naPool* p, int n, int* nout);
void naGC_swapfree(void** target, void* val);
void naGC_freedead();
void naiGCMark(naRef r);
void naiGCMarkHash(naRef h);
void naStr_gcclean(struct naStr* s);
void naVec_gcclean(struct naVec* s);
void naHash_gcclean(struct naHash* s);
void naiGCHashClean(struct naHash* h);
#endif // _DATA_H

View File

@@ -88,6 +88,11 @@ void naModUnlock()
{
LOCK();
globals->nThreads--;
// We might be the "last" thread needed for collection. Since
// we're releasing our modlock to do something else for a while,
// wake someone else up to do it.
if(globals->waitCount == globals->nThreads)
naSemUp(globals->sem, 1);
UNLOCK();
}
@@ -120,12 +125,7 @@ void naCheckBottleneck()
static void naCode_gcclean(struct naCode* o)
{
naFree(o->byteCode); o->byteCode = 0;
naFree(o->constants); o->constants = 0;
naFree(o->argSyms); o->argSyms = 0;
naFree(o->optArgSyms); o->optArgSyms = 0;
naFree(o->optArgVals); o->optArgVals = 0;
naFree(o->lineIps); o->lineIps = 0;
}
static void naGhost_gcclean(struct naGhost* g)
@@ -140,7 +140,7 @@ static void freeelem(struct naPool* p, struct naObj* o)
switch(p->type) {
case T_STR: naStr_gcclean ((struct naStr*) o); break;
case T_VEC: naVec_gcclean ((struct naVec*) o); break;
case T_HASH: naHash_gcclean ((struct naHash*) o); break;
case T_HASH: naiGCHashClean ((struct naHash*) o); break;
case T_CODE: naCode_gcclean ((struct naCode*) o); break;
case T_GHOST: naGhost_gcclean((struct naGhost*)o); break;
}
@@ -220,21 +220,6 @@ static void markvec(naRef r)
mark(vr->array[i]);
}
static void markhash(naRef r)
{
int i;
struct HashRec* hr = PTR(r).hash->rec;
if(!hr) return;
for(i=0; i < (1<<hr->lgalloced); i++) {
struct HashNode* hn = hr->table[i];
while(hn) {
mark(hn->key);
mark(hn->val);
hn = hn->next;
}
}
}
// Sets the reference bit on the object, and recursively on all
// objects reachable from it. Uses the processor stack for recursion...
static void mark(naRef r)
@@ -250,7 +235,7 @@ static void mark(naRef r)
PTR(r).obj->mark = 1;
switch(PTR(r).obj->type) {
case T_VEC: markvec(r); break;
case T_HASH: markhash(r); break;
case T_HASH: naiGCMarkHash(r); break;
case T_CODE:
mark(PTR(r).code->srcFile);
for(i=0; i<PTR(r).code->nConstants; i++)
@@ -264,6 +249,11 @@ static void mark(naRef r)
}
}
void naiGCMark(naRef r)
{
mark(r);
}
// Collects all the unreachable objects into a free list, and
// allocates more space if needed.
static void reap(struct naPool* p)

View File

@@ -1,130 +1,193 @@
#include <string.h>
#include "nasal.h"
#include "data.h"
#define MIN_HASH_SIZE 4
/* A HashRec lives in a single allocated block. The layout is the
* header struct, then a table of 2^lgsz hash entries (key/value
* pairs), then an index table of 2*2^lgsz integers storing index
* values into the entry table. There are two tokens needed for
* "unused" and "used but empty". */
#define EQUAL(a, b) (IDENTICAL(a, b) || naEqual(a, b))
#define ENT_EMPTY -1
#define ENT_DELETED -2
#define HASH_MAGIC 2654435769u
typedef struct { naRef key, val; } HashEnt;
#define INSERT(hh, hkey, hval, hcol) do { \
unsigned int cc = (hcol), iidx=(hh)->size++; \
if(iidx < (1<<(hh)->lgalloced)) { \
struct HashNode* hnn = &(hh)->nodes[iidx]; \
hnn->key = (hkey); hnn->val = (hval); \
hnn->next = (hh)->table[cc]; \
(hh)->table[cc] = hnn; \
}} while(0)
typedef struct HashRec {
int size; /* number of active entries */
int lgsz; /* base-2 logarithm of the allocated (!) size */
int next; /* next entry to use */
} HashRec;
// Computes a hash code for a given scalar
static unsigned int hashcode(naRef r)
#define REC(h) (PTR(h).hash->rec)
#define POW2(n) (1<<(n))
#define NCELLS(hr) (2*POW2((hr)->lgsz))
#define ROUNDUPOFF(n,m) ((((n)+(m-1))/m)*m)-(n)
#define ALIGN(p,sz) (((char*)p)+ROUNDUPOFF(((size_t)p)%sz,sz))
#define ENTS(h) ((HashEnt*)ALIGN(&((HashRec*)h)[1],sizeof(naRef)))
#define TAB(h) ((int*)&(ENTS(h)[1<<(h)->lgsz]))
#define HBITS(hr,code) ((hr)->lgsz ? ((code)>>(32-(hr)->lgsz)) : 0)
#define LROT(h,n) (((h)<<n)|((h)>>((8*sizeof(h))-n)))
static unsigned int mix32(unsigned int h)
{
if(IS_NUM(r))
{
// Numbers get the number as a hash. Just use the bits and
// xor them together. Note assumption that sizeof(double) >=
// 2*sizeof(int).
unsigned int* p = (unsigned int*)&(r.num);
return p[0] ^ p[1];
} else if(PTR(r).str->hashcode) {
return PTR(r).str->hashcode;
} else {
// This is Daniel Bernstein's djb2 hash function that I found
// on the web somewhere. It appears to work pretty well.
unsigned int i, hash = 5831;
for(i=0; i<PTR(r).str->len; i++)
hash = (hash * 33) ^ PTR(r).str->data[i];
PTR(r).str->hashcode = hash;
return hash;
}
}
// Which column in a given hash does the key correspond to.
static unsigned int hashcolumn(struct HashRec* h, naRef key)
{
// Multiply by a big number, and take the top N bits. Note
// assumption that sizeof(unsigned int) == 4.
return (HASH_MAGIC * hashcode(key)) >> (32 - h->lgalloced);
}
static struct HashRec* resize(struct naHash* hash)
{
struct HashRec *h, *h0 = hash->rec;
int lga, cols, need = h0 ? h0->size - h0->dels : MIN_HASH_SIZE;
if(need < MIN_HASH_SIZE) need = MIN_HASH_SIZE;
for(lga=0; 1<<lga <= need; lga++);
cols = 1<<lga;
h = naAlloc(sizeof(struct HashRec) +
cols * (sizeof(struct HashNode*) + sizeof(struct HashNode)));
naBZero(h, sizeof(struct HashRec) + cols * sizeof(struct HashNode*));
h->lgalloced = lga;
h->nodes = (struct HashNode*)(((char*)h)
+ sizeof(struct HashRec)
+ cols * sizeof(struct HashNode*));
for(lga=0; h0 != 0 && lga<(1<<h0->lgalloced); lga++) {
struct HashNode* hn = h0->table[lga];
while(hn) {
INSERT(h, hn->key, hn->val, hashcolumn(h, hn->key));
hn = hn->next;
}
}
naGC_swapfree((void**)&hash->rec, h);
h ^= 0x2e63823a; h += LROT(h, 15); h -= LROT(h, 9);
h += LROT(h, 4); h -= LROT(h, 1); h ^= LROT(h, 2);
return h;
}
// Special, optimized version of naHash_get for the express purpose of
// looking up symbols in the local variables hash (OP_LOCAL is by far
// the most common opcode and deserves some special case
// optimization). Elides all the typing checks that are normally
// required, presumes that the key is a string and has had its
// hashcode precomputed, checks only for object identity, and inlines
// the column computation.
int naHash_sym(struct naHash* hash, struct naStr* sym, naRef* out)
static unsigned int hash32(const unsigned char* in, int len)
{
struct HashRec* h = hash->rec;
if(h) {
int col = (HASH_MAGIC * sym->hashcode) >> (32 - h->lgalloced);
struct HashNode* hn = h->table[col];
while(hn) {
if(PTR(hn->key).str == sym) {
*out = hn->val;
return 1;
}
hn = hn->next;
unsigned int h = len, val = 0;
int i, count = 0;
for(i=0; i<len; i++) {
val = (val<<8) ^ in[i];
if(++count == 4) {
h = mix32(h ^ val);
val = count = 0;
}
}
return mix32(h ^ val);
}
static unsigned int refhash(naRef key)
{
if(IS_STR(key)) {
struct naStr* s = PTR(key).str;
if(s->hashcode) return s->hashcode;
return s->hashcode = hash32((void*)naStr_data(key), naStr_len(key));
} else { /* must be a number */
union { double d; unsigned int u[2]; } n;
n.d = key.num == -0.0 ? 0.0 : key.num; /* remember negative zero! */
return mix32(mix32(n.u[0]) ^ n.u[1]);
}
}
static int equal(naRef a, naRef b)
{
if(IS_NUM(a)) return a.num == b.num;
if(PTR(a).obj == PTR(b).obj) return 1;
if(naStr_len(a) != naStr_len(b)) return 0;
return memcmp(naStr_data(a), naStr_data(b), naStr_len(a)) == 0;
}
/* Returns the index of a cell that either contains a matching key, or
* is the empty slot to receive a new insertion. */
static int findcell(struct HashRec *hr, naRef key, unsigned int hash)
{
int i, mask = POW2(hr->lgsz+1)-1, step = (2*hash+1) & mask;
for(i=HBITS(hr,hash); TAB(hr)[i] != ENT_EMPTY; i=(i+step)&mask)
if(TAB(hr)[i] != ENT_DELETED && equal(key, ENTS(hr)[TAB(hr)[i]].key))
break;
return i;
}
static void hashset(HashRec* hr, naRef key, naRef val)
{
int ent, cell = findcell(hr, key, refhash(key));
if((ent = TAB(hr)[cell]) == ENT_EMPTY) {
ent = hr->next++;
if(ent >= NCELLS(hr)) return; /* race protection, don't overrun */
TAB(hr)[cell] = ent;
hr->size++;
ENTS(hr)[ent].key = key;
}
ENTS(hr)[ent].val = val;
}
static int recsize(int lgsz)
{
HashRec hr;
hr.lgsz = lgsz;
return (int)((char*)&TAB(&hr)[POW2(lgsz+1)] - (char*)&hr) + sizeof(naRef);
}
static HashRec* resize(struct naHash* hash)
{
HashRec *hr = hash->rec, *hr2;
int i, lgsz = 0;
if(hr) {
int oldsz = hr->size;
while(oldsz) { oldsz >>= 1; lgsz++; }
}
hr2 = naAlloc(recsize(lgsz));
hr2->size = hr2->next = 0;
hr2->lgsz = lgsz;
for(i=0; i<(2*(1<<lgsz)); i++)
TAB(hr2)[i] = ENT_EMPTY;
for(i=0; hr && i < POW2(hr->lgsz+1); i++)
if(TAB(hr)[i] >= 0)
hashset(hr2, ENTS(hr)[TAB(hr)[i]].key, ENTS(hr)[TAB(hr)[i]].val);
naGC_swapfree((void*)&hash->rec, hr2);
return hr2;
}
int naHash_size(naRef h) { return REC(h) ? REC(h)->size : 0; }
int naHash_get(naRef hash, naRef key, naRef* out)
{
HashRec* hr = REC(hash);
if(hr) {
int ent, cell = findcell(hr, key, refhash(key));
if((ent = TAB(hr)[cell]) < 0) return 0;
*out = ENTS(hr)[ent].val;
return 1;
}
return 0;
}
static struct HashNode* find(struct naHash* hash, naRef key)
void naHash_set(naRef hash, naRef key, naRef val)
{
struct HashRec* h = hash->rec;
struct HashNode* hn;
if(!h) return 0;
for(hn = h->table[hashcolumn(h, key)]; hn; hn = hn->next)
if(EQUAL(key, hn->key))
return hn;
return 0;
HashRec* hr = REC(hash);
if(!hr || hr->next >= POW2(hr->lgsz))
hr = resize(PTR(hash).hash);
hashset(hr, key, val);
}
void naHash_delete(naRef hash, naRef key)
{
HashRec* hr = REC(hash);
if(hr) {
int cell = findcell(hr, key, refhash(key));
if(TAB(hr)[cell] >= 0) {
TAB(hr)[cell] = ENT_DELETED;
if(--hr->size < POW2(hr->lgsz-1))
resize(PTR(hash).hash);
}
}
}
void naHash_keys(naRef dst, naRef hash)
{
int i;
HashRec* hr = REC(hash);
for(i=0; hr && i < NCELLS(hr); i++)
if(TAB(hr)[i] >= 0)
naVec_append(dst, ENTS(hr)[TAB(hr)[i]].key);
}
void naiGCMarkHash(naRef hash)
{
int i;
HashRec* hr = REC(hash);
for(i=0; hr && i < NCELLS(hr); i++)
if(TAB(hr)[i] >= 0) {
naiGCMark(ENTS(hr)[TAB(hr)[i]].key);
naiGCMark(ENTS(hr)[TAB(hr)[i]].val);
}
}
// Make a temporary string on the stack
static void tmpStr(naRef* out, struct naStr* str, const char* key)
{
str->len = 0;
str->type = T_STR;
str->data = (unsigned char*)key;
str->hashcode = 0;
while(key[str->len]) str->len++;
*out = naNil();
str->hashcode = str->emblen = 0;
str->data.ref.ptr = (unsigned char*)key;
str->data.ref.len = strlen(key);
SETPTR(*out, str);
}
int naMember_cget(naRef obj, const char* field, naRef* out)
{
naRef key;
struct naStr str;
naRef key; struct naStr str;
tmpStr(&key, &str, field);
return naMember_get(obj, key, out);
}
@@ -134,124 +197,75 @@ naRef naHash_cget(naRef hash, char* key)
struct naStr str;
naRef result, key2;
tmpStr(&key2, &str, key);
if(naHash_get(hash, key2, &result))
return result;
return naNil();
return naHash_get(hash, key2, &result) ? result : naNil();
}
void naHash_cset(naRef hash, char* key, naRef val)
{
struct naStr str;
naRef key2;
naRef key2; struct naStr str;
tmpStr(&key2, &str, key);
naHash_tryset(hash, key2, val);
naiHash_tryset(hash, key2, val);
}
int naHash_get(naRef hash, naRef key, naRef* out)
int naiHash_tryset(naRef hash, naRef key, naRef val)
{
if(IS_HASH(hash)) {
struct HashNode* n = find(PTR(hash).hash, key);
if(n) { *out = n->val; return 1; }
HashRec* hr = REC(hash);
if(hr) {
int ent, cell = findcell(hr, key, refhash(key));
if((ent = TAB(hr)[cell]) >= 0) { ENTS(hr)[ent].val = val; return 1; }
}
return 0;
}
// Simpler version. Don't create a new node if the value isn't there
int naHash_tryset(naRef hash, naRef key, naRef val)
{
if(IS_HASH(hash)) {
struct HashNode* n = find(PTR(hash).hash, key);
if(n) n->val = val;
return n != 0;
}
return 0;
}
// Special purpose optimization for use in function call setups. Sets
// a value that is known *not* to be present in the hash table. As
// for naHash_sym, the key must be a string with a precomputed hash
// code.
void naHash_newsym(struct naHash* hash, naRef* sym, naRef* val)
{
int col;
struct HashRec* h = hash->rec;
while(!h || h->size >= 1<<h->lgalloced)
h = resize(hash);
col = (HASH_MAGIC * PTR(*sym).str->hashcode) >> (32 - h->lgalloced);
INSERT(h, *sym, *val, col);
}
// The cycle check is an integrity requirement for multithreading,
// where raced inserts can potentially cause cycles. This ensures
// that the "last" thread to hold a reference to an inserted node
// breaks any cycles that might have happened (at the expense of
// potentially dropping items out of the hash). Under normal
// circumstances, chains will be very short and this will be fast.
static void chkcycle(struct HashNode* node, int count)
{
struct HashNode* hn = node;
while(hn && (hn = hn->next) != 0)
if(count-- <= 0) { node->next = 0; return; }
}
void naHash_set(naRef hash, naRef key, naRef val)
{
int col;
struct HashRec* h;
struct HashNode* n;
if(!IS_HASH(hash)) return;
if((n = find(PTR(hash).hash, key))) { n->val = val; return; }
h = PTR(hash).hash->rec;
while(!h || h->size >= 1<<h->lgalloced)
h = resize(PTR(hash).hash);
col = hashcolumn(h, key);
INSERT(h, key, val, hashcolumn(h, key));
chkcycle(h->table[col], h->size - h->dels);
}
void naHash_delete(naRef hash, naRef key)
{
struct HashRec* h = PTR(hash).hash->rec;
int col;
struct HashNode *last=0, *hn;
if(!IS_HASH(hash) || !h) return;
col = hashcolumn(h, key);
hn = h->table[col];
while(hn) {
if(EQUAL(hn->key, key)) {
if(last == 0) h->table[col] = hn->next;
else last->next = hn->next;
h->dels++;
return;
}
last = hn;
hn = hn->next;
}
}
void naHash_keys(naRef dst, naRef hash)
{
int i;
struct HashRec* h = PTR(hash).hash->rec;
if(!IS_HASH(hash) || !h) return;
for(i=0; i<(1<<h->lgalloced); i++) {
struct HashNode* hn = h->table[i];
while(hn) {
naVec_append(dst, hn->key);
hn = hn->next;
}
}
}
int naHash_size(naRef hash)
{
struct HashRec* h = PTR(hash).hash->rec;
if(!IS_HASH(hash) || !h) return 0;
return h->size - h->dels;
}
void naHash_gcclean(struct naHash* h)
void naiGCHashClean(struct naHash* h)
{
naFree(h->rec);
h->rec = 0;
}
/* Optimized naHash_get for looking up local variables (OP_LOCAL is by
* far the most common opcode and deserves some special case
* optimization). Assumes that the key is an interned symbol
* (i.e. the hash code is precomputed, and we only need to test for
* pointer identity). */
int naiHash_sym(struct naHash* hash, struct naStr* sym, naRef* out)
{
HashRec* hr = hash->rec;
if(hr) {
int* tab = TAB(hr);
HashEnt* ents = ENTS(hr);
unsigned int hc = sym->hashcode;
int cell, mask = POW2(hr->lgsz+1) - 1, step = (2*hc+1) & mask;
for(cell=HBITS(hr,hc); tab[cell] != ENT_EMPTY; cell=(cell+step)&mask)
if(tab[cell]!=ENT_DELETED && sym==PTR(ents[tab[cell]].key).str) {
*out = ents[tab[cell]].val;
return 1;
}
}
return 0;
}
/* As above, a special naHash_set for setting local variables.
* Assumes that the key is interned, and also that it isn't already
* present in the hash. */
void naiHash_newsym(struct naHash* hash, naRef* sym, naRef* val)
{
HashRec* hr = hash->rec;
int mask, step, cell, ent;
struct naStr *s = PTR(*sym).str;
if(!hr || hr->next >= POW2(hr->lgsz))
hr = resize(hash);
mask = POW2(hr->lgsz+1) - 1;
step = (2*s->hashcode+1) & mask;
cell = HBITS(hr, s->hashcode);
while(TAB(hr)[cell] != ENT_EMPTY)
cell = (cell + step) & mask;
ent = hr->next++;
if(ent >= NCELLS(hr)) return; /* race protection, don't overrun */
TAB(hr)[cell] = ent;
hr->size++;
ENTS(hr)[TAB(hr)[cell]].key = *sym;
ENTS(hr)[TAB(hr)[cell]].val = *val;
}

View File

@@ -7,7 +7,7 @@
#include "iolib.h"
static void ghostDestroy(void* g);
naGhostType naIOGhostType = { ghostDestroy };
naGhostType naIOGhostType = { ghostDestroy, "iofile" };
static struct naIOGhost* ioghost(naRef r)
{
@@ -32,9 +32,9 @@ static naRef f_read(naContext c, naRef me, int argc, naRef* args)
naRef len = argc > 2 ? naNumValue(args[2]) : naNil();
if(!g || !MUTABLE(str) || !IS_NUM(len))
naRuntimeError(c, "bad argument to read()");
if(PTR(str).str->len < (int)len.num)
if(naStr_len(str) < (int)len.num)
naRuntimeError(c, "string not big enough for read");
return naNum(g->type->read(c, g->handle, (char*)PTR(str).str->data,
return naNum(g->type->read(c, g->handle, naStr_data(str),
(int)len.num));
}
@@ -44,8 +44,8 @@ static naRef f_write(naContext c, naRef me, int argc, naRef* args)
naRef str = argc > 1 ? args[1] : naNil();
if(!g || !IS_STR(str))
naRuntimeError(c, "bad argument to write()");
return naNum(g->type->write(c, g->handle, (char*)PTR(str).str->data,
PTR(str).str->len));
return naNum(g->type->write(c, g->handle, naStr_data(str),
naStr_len(str)));
}
static naRef f_seek(naContext c, naRef me, int argc, naRef* args)
@@ -134,8 +134,7 @@ static naRef f_open(naContext c, naRef me, int argc, naRef* args)
naRef file = argc > 0 ? naStringValue(c, args[0]) : naNil();
naRef mode = argc > 1 ? naStringValue(c, args[1]) : naNil();
if(!IS_STR(file)) naRuntimeError(c, "bad argument to open()");
f = fopen((char*)PTR(file).str->data,
IS_STR(mode) ? (const char*)PTR(mode).str->data : "rb");
f = fopen(naStr_data(file), IS_STR(mode) ? naStr_data(mode) : "rb");
if(!f) naRuntimeError(c, strerror(errno));
return naIOGhost(c, f);
}
@@ -143,7 +142,7 @@ static naRef f_open(naContext c, naRef me, int argc, naRef* args)
// frees buffer before tossing an error
static int getcguard(naContext ctx, FILE* f, void* buf)
{
char c;
int c;
naModUnlock(); c = fgetc(f); naModLock();
if(ferror(f)) {
naFree(buf);
@@ -159,8 +158,8 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
{
naRef result;
struct naIOGhost* g = argc==1 ? ioghost(args[0]) : 0;
int i=0, sz = 128;
char c, *buf;
int i=0, c, sz = 128;
char *buf;
if(!g || g->type != &naStdIOType)
naRuntimeError(ctx, "bad argument to readln()");
buf = naAlloc(sz);
@@ -168,7 +167,7 @@ static naRef f_readln(naContext ctx, naRef me, int argc, naRef* args)
c = getcguard(ctx, g->handle, buf);
if(c == EOF || c == '\n') break;
if(c == '\r') {
char c2 = getcguard(ctx, g->handle, buf);
int c2 = getcguard(ctx, g->handle, buf);
if(c2 != EOF && c2 != '\n')
if(EOF == ungetc(c2, g->handle))
break;
@@ -188,7 +187,7 @@ static naRef f_stat(naContext ctx, naRef me, int argc, naRef* args)
struct stat s;
naRef result, path = argc > 0 ? naStringValue(ctx, args[0]) : naNil();
if(!IS_STR(path)) naRuntimeError(ctx, "bad argument to stat()");
if(stat((char*)PTR(path).str->data, &s) < 0) {
if(stat(naStr_data(path), &s) < 0) {
if(errno == ENOENT) return naNil();
naRuntimeError(ctx, strerror(errno));
}

View File

@@ -1,7 +1,7 @@
#include "parse.h"
// Static table of recognized lexemes in the language
struct Lexeme {
static const struct Lexeme {
char* str;
int tok;
} LEXEMES[] = {
@@ -130,7 +130,6 @@ static void newToken(struct Parser* p, int pos, int type,
tok->str = str;
tok->strlen = slen;
tok->num = num;
tok->parent = &p->tree;
tok->next = 0;
tok->prev = last;
tok->children = 0;
@@ -182,6 +181,7 @@ static void sqEscape(char* buf, int len, int index, struct Parser* p,
}
// Ditto, but more complicated for double quotes.
/* FIXME: need to handle \b (8), \f (12), and \uXXXX for JSON compliance */
static void dqEscape(char* buf, int len, int index, struct Parser* p,
char* cOut, int* eatenOut)
{
@@ -256,25 +256,27 @@ static int lexHexLiteral(struct Parser* p, int index)
return i;
}
#define ISNUM(c) ((c) >= '0' && (c) <= '9')
#define ISHEX(c) (ISNUM(c) || ((c)>='a' && (c)<='f') || ((c)>='A' && (c)<='F'))
#define NUMSTART(c) (ISNUM(c) || (c) == '+' || (c) == '-')
static int lexNumLiteral(struct Parser* p, int index)
{
int len = p->len, i = index;
unsigned char* buf = (unsigned char*)p->buf;
double d;
if(i+1<len && buf[i+1] == 'x') return lexHexLiteral(p, index+2);
if(buf[i] == '0' && i+2<len && buf[i+1] == 'x' && ISHEX(buf[i+2]))
return lexHexLiteral(p, index+2);
while(i<len && buf[i] >= '0' && buf[i] <= '9') i++;
while(i<len && ISNUM(buf[i])) i++;
if(i<len && buf[i] == '.') {
i++;
while(i<len && buf[i] >= '0' && buf[i] <= '9') i++;
while(i<len && ISNUM(buf[i])) i++;
}
if(i<len && (buf[i] == 'e' || buf[i] == 'E')) {
if(i+1<len && (buf[i] == 'e' || buf[i] == 'E') && NUMSTART(buf[i+1])) {
i++;
if(i<len
&& (buf[i] == '-' || buf[i] == '+')
&& (i+1<len && buf[i+1] >= '0' && buf[i+1] <= '9')) i++;
while(i<len && buf[i] >= '0' && buf[i] <= '9') i++;
if(buf[i] == '-' || buf[i] == '+') i++;
while(i<len && ISNUM(buf[i])) i++;
}
naStr_parsenum(p->buf + index, i - index, &d);
newToken(p, index, TOK_LITERAL, 0, 0, d);
@@ -333,7 +335,6 @@ static int tryLexemes(struct Parser* p, int index, int* lexemeOut)
return best;
}
#define ISNUM(c) ((c) >= '0' && (c) <= '9')
void naLex(struct Parser* p)
{
int i = 0;

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