1
0
Fork 0

Merge FG_Lib as subdirectory

This commit is contained in:
Tim Moore 2009-09-14 13:34:43 +02:00
commit a43bfeb037
135 changed files with 27246 additions and 0 deletions

139
Lib/Audio/CHANGES Normal file
View file

@ -0,0 +1,139 @@
/**********************************************\
* *
* W A R N I N G *
* *
* This file is now kept in reverse chronolog- *
* ical order so recent changes are now at the *
* top. *
* *
\**********************************************/
* 28th Sept 1889 -- Fixed a bug associated with exiting the
program with sounds still playing.
Fixed a bug associated with using the
package in the absence of a sound card.
Added a new member function "working"
which is the opposite of "not_working",
(as demanded by a bunch of rabid optimists)!
Fixed a couple of typo's in the manual.
* 23rd Sept 1998 -- The Good News: Finally got around to
getting the pitch envelope working. (Hooray)
The Bad News: This costs quite a bit in
performance - and it was a MAJOR rewrite
of significant parts of the internals,
so we may need some bug fixes.
This version is 0.5
* 7th July 1998 -- Fixed some error checking in slSample.cxx and
a missing declaration in sl.h
* 6th July 1998 -- Fixed an initialisation problem when
slScheduler was not a static/global.
Tom Knienieder's port to SGI/IRIX is now
working, documentation updated to reflect that.
* 16th June 1998 -- Added some slPortability.h fixes for
FreeBSD and the Cygnus WIN32 compiler.
Many thanks to Curt.
* 14th June 1998 -- Tom Knienieder's port to OpenBSD is now
working, documentation updated to reflect that.
Tom's improved Makefiles included, also some
example sound samples that were accidentally
left out of the release are now present.
A couple of typo's in the WIN32 section
have been fixed. The top level Makefile
now requires you to type 'make linux',
'make win' or 'make openbsd'.
* 13th June 1998 -- Tom Knienieder's port to WIN32 engine is now
working, documentation updated to reflect that
revised status. Some default constructor parameters
have changed, slDSP no longer supports setRate/setBps/setStereo.
You now have to delete the slDSP and recreate it with
new parameters. This makes porting a little easier.
'sound_test' renamed 'example'.
* 7th June 1998 -- Volume envelopes (and inverse volume envelopes)
now work correctly. Pan envelopes won't work
until stereo is implemented. Pitch and filter
envelopes turn out to be a major pain to implement
with the present slSceduler/slSamplePlayer interface,
so some significant internal changes are to be
expected.
Changed the CHANGES file to be in reverse
chronological order.
This version is officially SL v0.3 (beta)
* 3rd June 1998 -- Moved sample program and it's data files into
'example', moved documents into 'doc' and sources
into 'src'. Final library goes into 'lib'.
The entire preempting mechanism was broken -
now it's fixed.
Added a callback mechanism that allows
applications to know when a sound
loops, finishes playing, is pre-empted, etc.
New mechanisms added to stop/pause/resume a
playing sample.
All the documentation - and some of the code -
for slEnvelopes has been added, they don't
work yet - so don't bother with them for now.
Made some code a little more bullet-proof.
slSample's are now reference-counted so you
can't accidentally delete one while it's
playing without getting a FATAL error.
* 2nd June 1998 -- Fixed bug in initialisation that prevented SL
from functioning correctly in the case were there
is no sound card present.
This version is officially SL v0.2 (beta)
* 1st June 1998 -- Split library into two parts - libsm and
libsl. libsm contains only the Mixer class
since it is likely to be hard to port to
a lot of non-OSS systems - and most programs
won't need it anyway. Hence the documentation
has blossomed into three files and all the
'slMixer' references have turned into 'smMixer'.
Also, I finally got a hold of the OSS documentation,
which is a lot more complete - and straightened
me out on a few points. slDSP has changed
(internally) somewhat as a result and in particular,
you can no longer mess with the sampling rate,
stereo and bps settings after the slDSP or
slScheduler has been created. This also allows the
scheduler to enforce it's rule about only mono/8bps
operations.
I also added an 'autoMatch' function to the slSample
class to automagically match incoming samples to the
current slDSP/slScheduler. This makes using the library
a lot less painful and error-prone.
This version is officially SL v0.1 (beta)
We need a better name!
* 30th May 1998 -- Almost total rewrite, library can now
play multiple sounds without interruption,
supports '.WAV' and '.AU' file formats as
well as raw binary files. Able to copy with
much shorter safetyMargin on sound buffers,
and play without using the 'stop' call.
All class and external symbols now begin
with 'sl' or 'SL'. HTML documentation now
available.
* 27th May 1998 -- First hack

1
Lib/Audio/Makefile.am Normal file
View file

@ -0,0 +1 @@
SUBDIRS = src example

9
Lib/Audio/NOTICE Normal file
View file

@ -0,0 +1,9 @@
NOTICE: This Sound Library (SL) distribution contains source code that is
placed into the public domain without copyright. These programs are freely
distributable without licensing fees. These programs are provided without
guarantee or warrantee expressed or implied.
If you use SL in a commercial or shareware product, it would be nice if you
gave credit where it is due. If you make any modifications or improvements
to SL, I would greatly appreciate a copy of the improved code.

9
Lib/Audio/README Normal file
View file

@ -0,0 +1,9 @@
Hi!
This is the fifth prototype of Steve's 'SL' sound library.
Check out 'CHANGES' and the new HTML documentation.
Steve

13
Lib/Audio/README.freebsd Normal file
View file

@ -0,0 +1,13 @@
Building SL for Linux.
~~~~~~~~~~~~~~~~~~~~~~
% make freebsd
% su root
% make install
...that's all folks.
Header files go into /usr/include/SL (analogous to /usr/include/GL for graphics)
Library file(s) go into /usr/lib

13
Lib/Audio/README.linux Normal file
View file

@ -0,0 +1,13 @@
Building SL for Linux.
~~~~~~~~~~~~~~~~~~~~~~
% make linux
% su root
% make install
...that's all folks.
Header files go into /usr/include/SL (analogous to /usr/include/GL for graphics)
Library file(s) go into /usr/lib

13
Lib/Audio/README.openbsd Normal file
View file

@ -0,0 +1,13 @@
Building SL for OpenBSD.
~~~~~~~~~~~~~~~~~~~~~~~~
% make openbsd
% su root
% make install
...that's all folks.
Header files go into /usr/include/SL (analogous to /usr/include/GL for graphics)
Library file(s) go into /usr/lib

27
Lib/Audio/README.sgi Normal file
View file

@ -0,0 +1,27 @@
Building SL for SGI.
~~~~~~~~~~~~~~~~~~~~~~
There are two options, depending on whether you want to use GCC or
the standard SGI C++ compiler.
GNU G++:
% make sgigcc
% su root
% make install
SGI C++:
% make sgi
% su root
% make install
...that's all folks.
Header files go into /usr/include/SL (analogous to /usr/include/GL for graphics)
Library file(s) go into /usr/lib
When you link, be sure to include to -laudio

20
Lib/Audio/README.unix Normal file
View file

@ -0,0 +1,20 @@
Building SL for UNIX
~~~~~~~~~~~~~~~~~~~~
If your UNIX box is Linux or OpenBSD then
check out README.linux or README.openbsd.
If your UNIX box supports OSS (the Open
Sound System) then in principal, you should
only need to type:
% make oss
% su root
% make install
...however, your milage may vary. If you succeed
in getting a non-Linux, non-OpenBSD version to
work, I'd like to hear about it.
Steve Baker <sjbaker1@airmail.net>

15
Lib/Audio/README.win Normal file
View file

@ -0,0 +1,15 @@
Building SL for win32 (msvc)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
C:>nmake win32
don't forget to set the environment !
example:
set include=c:\msdev\include;
set lib=c:\msdev\lib
path c:\msdev\bin;c:\bin;c:\winnt;......

11
Lib/Bucket/Makefile.am Normal file
View file

@ -0,0 +1,11 @@
noinst_LIBRARIES = libBucket.a
libBucket_a_SOURCES = newbucket.cxx newbucket.hxx
bin_PROGRAMS = testbucket
testbucket_SOURCES = testbucket.cxx
testbucket_LDADD = $(top_builddir)/Lib/Bucket/libBucket.a
INCLUDES += -I$(top_builddir)

163
Lib/Bucket/newbucket.cxx Normal file
View file

@ -0,0 +1,163 @@
/**************************************************************************
* newbucket.hxx -- new bucket routines for better world modeling
*
* Written by Curtis L. Olson, started February 1999.
*
* Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
* (Log is kept at end of this file)
**************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "newbucket.hxx"
// Build the path name for this bucket
string FGBucket::gen_base_path() const {
// long int index;
int top_lon, top_lat, main_lon, main_lat;
char hem, pole;
char path[256];
// index = gen_index();
path[0] = '\0';
top_lon = lon / 10;
main_lon = lon;
if ( (lon < 0) && (top_lon * 10 != lon) ) {
top_lon -= 1;
}
top_lon *= 10;
if ( top_lon >= 0 ) {
hem = 'e';
} else {
hem = 'w';
top_lon *= -1;
}
if ( main_lon < 0 ) {
main_lon *= -1;
}
top_lat = lat / 10;
main_lat = lat;
if ( (lat < 0) && (top_lat * 10 != lat) ) {
top_lat -= 1;
}
top_lat *= 10;
if ( top_lat >= 0 ) {
pole = 'n';
} else {
pole = 's';
top_lat *= -1;
}
if ( main_lat < 0 ) {
main_lat *= -1;
}
sprintf(path, "%c%03d%c%02d/%c%03d%c%02d",
hem, top_lon, pole, top_lat,
hem, main_lon, pole, main_lat);
return path;
}
// find the bucket which is offset by the specified tile units in the
// X & Y direction. We need the current lon and lat to resolve
// ambiguities when going from a wider tile to a narrower one above or
// below. This assumes that we are feeding in
FGBucket fgBucketOffset( double dlon, double dlat, int dx, int dy ) {
FGBucket result( dlon, dlat );
double clat = result.get_center_lat() + dy * FG_BUCKET_SPAN;
// walk dy units in the lat direction
result.set_bucket( dlon, clat );
// find the lon span for the new latitude
double span = bucket_span( clat );
// walk dx units in the lon direction
result.set_bucket( dlon + dx * span, clat );
return result;
}
// calculate the offset between two buckets
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
// Latitude difference
double c1_lat = b1.get_center_lat();
double c2_lat = b2.get_center_lat();
double diff_lat = c2_lat - c1_lat;
#ifdef HAVE_RINT
*dy = (int)rint( diff_lat / FG_BUCKET_SPAN );
#else
if ( diff_lat > 0 ) {
*dy = (int)( diff_lat / FG_BUCKET_SPAN + 0.5 );
} else {
*dy = (int)( diff_lat / FG_BUCKET_SPAN - 0.5 );
}
#endif
// longitude difference
double c1_lon = b1.get_center_lon();
double c2_lon = b2.get_center_lon();
double diff_lon = c2_lon - c1_lon;
double span;
if ( bucket_span(c1_lat) <= bucket_span(c2_lat) ) {
span = bucket_span(c1_lat);
} else {
span = bucket_span(c2_lat);
}
#ifdef HAVE_RINT
*dx = (int)rint( diff_lon / span );
#else
if ( diff_lon > 0 ) {
*dx = (int)( diff_lon / span + 0.5 );
} else {
*dx = (int)( diff_lon / span - 0.5 );
}
#endif
}
// $Log$
// Revision 1.4 1999/03/27 05:34:05 curt
// Elimitated some const warnings from the compiler.
//
// Revision 1.3 1999/02/26 22:07:54 curt
// Added initial support for native SGI compilers.
//
// Revision 1.2 1999/02/11 01:09:33 curt
// Added a routine to calculate the offset in bucket units between two buckets.
//
// Revision 1.1 1999/02/08 23:52:16 curt
// Added a new "newbucket.[ch]xx" FGBucket class to replace the old
// fgBUCKET struct and C routines. This FGBucket class adjusts the tile
// width towards the poles to ensure the tiles are at least 8 miles wide.
//

360
Lib/Bucket/newbucket.hxx Normal file
View file

@ -0,0 +1,360 @@
/**************************************************************************
* newbucket.hxx -- new bucket routines for better world modeling
*
* Written by Curtis L. Olson, started February 1999.
*
* Copyright (C) 1999 Curtis L. Olson - curt@flightgear.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
* (Log is kept at end of this file)
**************************************************************************/
#ifndef _NEWBUCKET_HXX
#define _NEWBUCKET_HXX
#include <Include/compiler.h>
#include STL_STRING
#ifdef FG_HAVE_STD_INCLUDES
# include <cstdio> // sprintf()
# include <iostream>
#else
# include <stdio.h> // sprintf()
# include <iostream.h>
#endif
FG_USING_STD(string);
FG_USING_STD(ostream);
#include <Include/fg_constants.h>
#define FG_BUCKET_SPAN 0.125 // 1/8 of a degree
#define FG_HALF_BUCKET_SPAN 0.0625 // 1/2 of 1/8 of a degree = 1/16 = 0.0625
class FGBucket;
ostream& operator<< ( ostream&, const FGBucket& );
bool operator== ( const FGBucket&, const FGBucket& );
class FGBucket {
private:
double cx, cy; // centerpoint (lon, lat) in degrees of bucket
int lon; // longitude index (-180 to 179)
int lat; // latitude index (-90 to 89)
int x; // x subdivision (0 to 7)
int y; // y subdivision (0 to 7)
public:
// default constructor
FGBucket();
// create a bucket which would contain the specified lon/lat
FGBucket(const double lon, const double lat);
// create a bucket based on "long int" index
FGBucket(const long int bindex);
// create an impossible bucket if false
FGBucket(const bool is_good);
~FGBucket();
// Set the bucket params for the specified lat and lon
void set_bucket( double dlon, double dlat );
// Generate the unique scenery tile index for this bucket
long int gen_index();
string gen_index_str() const;
// Build the path name for this bucket
string gen_base_path() const;
// return the center lon of a tile
double get_center_lon() const;
// return width of the tile
double get_width() const;
// return the center lat of a tile
double get_center_lat() const;
// return height of the tile
double get_height() const;
// Informational methods
inline int get_lon() const { return lon; }
inline int get_lat() const { return lat; }
inline int get_x() const { return x; }
inline int get_y() const { return y; }
// friends
friend ostream& operator<< ( ostream&, const FGBucket& );
friend bool operator== ( const FGBucket&, const FGBucket& );
};
// return the horizontal tile span factor based on latitude
inline double bucket_span( double l ) {
if ( l >= 89.0 ) {
return 0.0;
} else if ( l >= 88.0 ) {
return 8.0;
} else if ( l >= 86.0 ) {
return 4.0;
} else if ( l >= 83.0 ) {
return 2.0;
} else if ( l >= 76.0 ) {
return 1.0;
} else if ( l >= 62.0 ) {
return 0.5;
} else if ( l >= 22.0 ) {
return 0.25;
} else if ( l >= -22.0 ) {
return 0.125;
} else if ( l >= -62.0 ) {
return 0.25;
} else if ( l >= -76.0 ) {
return 0.5;
} else if ( l >= -83.0 ) {
return 1.0;
} else if ( l >= -86.0 ) {
return 2.0;
} else if ( l >= -88.0 ) {
return 4.0;
} else if ( l >= -89.0 ) {
return 8.0;
} else {
return 0.0;
}
}
// Set the bucket params for the specified lat and lon
inline void FGBucket::set_bucket( double dlon, double dlat ) {
//
// latitude first
//
double span = bucket_span( dlat );
double diff = dlon - (double)(int)dlon;
// cout << "diff = " << diff << " span = " << span << endl;
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
lon = (int)dlon;
} else {
lon = (int)dlon - 1;
}
// find subdivision or super lon if needed
if ( span < FG_EPSILON ) {
// polar cap
lon = 0;
x = 0;
} else if ( span <= 1.0 ) {
x = (int)((dlon - lon) / span);
} else {
if ( (dlon >= 0) || (fabs(diff) < FG_EPSILON) ) {
lon = (int)( (int)(lon / span) * span);
} else {
// cout << " lon = " << lon
// << " tmp = " << (int)((lon-1) / span) << endl;
lon = (int)( (int)((lon + 1) / span) * span - span);
if ( lon < -180 ) {
lon = -180;
}
}
x = 0;
}
//
// then latitude
//
diff = dlat - (double)(int)dlat;
if ( (dlat >= 0) || (fabs(diff) < FG_EPSILON) ) {
lat = (int)dlat;
} else {
lat = (int)dlat - 1;
}
y = (int)((dlat - lat) * 8);
}
// default constructor
inline FGBucket::FGBucket() {}
// constructor for specified location
inline FGBucket::FGBucket(const double dlon, const double dlat) {
set_bucket(dlon, dlat);
}
// create an impossible bucket if false
inline FGBucket::FGBucket(const bool is_good) {
set_bucket(0.0, 0.0);
if ( !is_good ) {
lon = -1000;
}
}
// Parse a unique scenery tile index and find the lon, lat, x, and y
inline FGBucket::FGBucket(const long int bindex) {
long int index = bindex;
lon = index >> 14;
index -= lon << 14;
lon -= 180;
lat = index >> 6;
index -= lat << 6;
lat -= 90;
y = index >> 3;
index -= y << 3;
x = index;
}
// default destructor
inline FGBucket::~FGBucket() {}
// Generate the unique scenery tile index for this bucket
//
// The index is constructed as follows:
//
// 9 bits - to represent 360 degrees of longitude (-180 to 179)
// 8 bits - to represent 180 degrees of latitude (-90 to 89)
//
// Each 1 degree by 1 degree tile is further broken down into an 8x8
// grid. So we also need:
//
// 3 bits - to represent x (0 to 7)
// 3 bits - to represent y (0 to 7)
inline long int FGBucket::gen_index() {
return ((lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x;
}
inline string FGBucket::gen_index_str() const {
char tmp[20];
sprintf(tmp, "%ld",
(((long)lon + 180) << 14) + ((lat + 90) << 6) + (y << 3) + x);
return (string)tmp;
}
// return the center lon of a tile
inline double FGBucket::get_center_lon() const {
double span = bucket_span( lat + y / 8.0 + FG_HALF_BUCKET_SPAN );
if ( span >= 1.0 ) {
return lon + span / 2.0;
} else {
return lon + x * span + span / 2.0;
}
}
// return width of the tile
inline double FGBucket::get_width() const {
return bucket_span( get_center_lat() );
}
// return the center lat of a tile
inline double FGBucket::get_center_lat() const {
return lat + y / 8.0 + FG_HALF_BUCKET_SPAN;
}
// return height of the tile
inline double FGBucket::get_height() const {
return FG_BUCKET_SPAN;
}
// offset a bucket struct by the specified tile units in the X & Y
// direction
FGBucket fgBucketOffset( double dlon, double dlat, int x, int y );
// calculate the offset between two buckets
void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy );
/*
// Given a lat/lon, fill in the local tile index array
void fgBucketGenIdxArray(fgBUCKET *p1, fgBUCKET *tiles, int width, int height);
*/
inline ostream&
operator<< ( ostream& out, const FGBucket& b )
{
return out << b.lon << ":" << b.x << ", " << b.lat << ":" << b.y;
}
inline bool
operator== ( const FGBucket& b1, const FGBucket& b2 )
{
return ( b1.lon == b2.lon &&
b1.lat == b2.lat &&
b1.x == b2.x &&
b1.y == b2.y );
}
#endif // _NEWBUCKET_HXX
// $Log$
// Revision 1.8 1999/03/27 05:34:06 curt
// Elimitated some const warnings from the compiler.
//
// Revision 1.7 1999/03/25 19:01:51 curt
// Jettisoned old bucketutils.[ch] for newbucket.[ch]xx
//
// Revision 1.6 1999/03/15 17:58:41 curt
// MSVC++ portability tweaks contributed by Bernie Bright.
// Added using std::ostream declaration.
// Added forward declarations to work around a MSVC bug.
//
// Revision 1.5 1999/03/12 22:51:18 curt
// Added some informational methods.
//
// Revision 1.4 1999/03/02 01:01:43 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.3 1999/02/26 22:07:55 curt
// Added initial support for native SGI compilers.
//
// Revision 1.2 1999/02/11 01:09:34 curt
// Added a routine to calculate the offset in bucket units between two buckets.
//
// Revision 1.1 1999/02/08 23:52:16 curt
// Added a new "newbucket.[ch]xx" FGBucket class to replace the old
// fgBUCKET struct and C routines. This FGBucket class adjusts the tile
// width towards the poles to ensure the tiles are at least 8 miles wide.
//

32
Lib/Bucket/testbucket.cxx Normal file
View file

@ -0,0 +1,32 @@
// test new bucket routines
#include "newbucket.cxx"
main() {
double lat = 21.9625;
double lon = -110.0 + 0.0625;
/*
while ( lon < 180 ) {
FGBucket b1( lon, lat );
long int index = b1.gen_index();
FGBucket b2( index );
cout << lon << "," << lat << " ";
cout << b2 << " " << b2.get_center_lon() << ","
<< b2.get_center_lat() << endl;
lon += 0.125;
}
*/
FGBucket b1;
for ( int j = 2; j >= -2; j-- ) {
for ( int i = -2; i < 3; i++ ) {
b1 = fgBucketOffset(lon, lat, i, j);
cout << "(" << i << "," << j << ")" << b1 << "\t";
}
cout << endl;
}
}

13
Lib/CVSROOT/checkoutlist Normal file
View file

@ -0,0 +1,13 @@
# The "checkoutlist" file is used to support additional version controlled
# administrative files in $CVSROOT/CVSROOT, such as template files.
#
# The first entry on a line is a filename which will be checked out from
# the corresponding RCS file in the $CVSROOT/CVSROOT directory.
# The remainder of the line is an error message to use if the file cannot
# be checked out.
#
# File format:
#
# [<whitespace>]<filename><whitespace><error message><end-of-line>
#
# comment lines begin with '#'

15
Lib/CVSROOT/commitinfo Normal file
View file

@ -0,0 +1,15 @@
# The "commitinfo" file is used to control pre-commit checks.
# The filter on the right is invoked with the repository and a list
# of files to check. A non-zero exit of the filter program will
# cause the commit to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

22
Lib/CVSROOT/cvswrappers Normal file
View file

@ -0,0 +1,22 @@
# This file describes wrappers and other binary files to CVS.
#
# Wrappers are the concept where directories of files are to be
# treated as a single file. The intended use is to wrap up a wrapper
# into a single tar such that the tar archive can be treated as a
# single binary file in CVS.
#
# To solve the problem effectively, it was also necessary to be able to
# prevent rcsmerge from merging these files.
#
# Format of wrapper file ($CVSROOT/CVSROOT/cvswrappers or .cvswrappers)
#
# wildcard [option value][option value]...
#
# where option is one of
# -f from cvs filter value: path to filter
# -t to cvs filter value: path to filter
# -m update methodology value: MERGE or COPY
#
# and value is a single-quote delimited value.
#
# For example:

21
Lib/CVSROOT/editinfo Normal file
View file

@ -0,0 +1,21 @@
# The "editinfo" file is used to allow verification of logging
# information. It works best when a template (as specified in the
# rcsinfo file) is provided for the logging procedure. Given a
# template with locations for, a bug-id number, a list of people who
# reviewed the code before it can be checked in, and an external
# process to catalog the differences that were code reviewed, the
# following test can be applied to the code:
#
# Making sure that the entered bug-id number is correct.
# Validating that the code that was reviewed is indeed the code being
# checked in (using the bug-id number or a seperate review
# number to identify this particular code set.).
#
# If any of the above test failed, then the commit would be aborted.
#
# Actions such as mailing a copy of the report to each reviewer are
# better handled by an entry in the loginfo file.
#
# One thing that should be noted is the the ALL keyword is not
# supported. There can be only one entry that matches a given
# repository.

19
Lib/CVSROOT/loginfo Normal file
View file

@ -0,0 +1,19 @@
# The "loginfo" file is used to control where "cvs commit" log information is
# sent. The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, the remainder of the line is a
# filter program that should expect log information on its standard input
#
# If the repository name does not match any of the regular expressions in the
# first field of this file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".
#
# The filter program may use one and only one "%s" modifier (ala printf). If
# such a "%s" is specified in the filter program, a brief title is included
# (as one argument, enclosed in single quotes) showing the relative directory
# name and listing the modified file names.
#
# For example:
#DEFAULT (echo ""; who am i; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog

26
Lib/CVSROOT/modules Normal file
View file

@ -0,0 +1,26 @@
# Three different line formats are valid:
# key -a aliases...
# key [options] directory
# key [options] directory files...
#
# Where "options" are composed of:
# -i prog Run "prog" on "cvs commit" from top-level of module.
# -o prog Run "prog" on "cvs checkout" of module.
# -e prog Run "prog" on "cvs export" of module.
# -t prog Run "prog" on "cvs rtag" of module.
# -u prog Run "prog" on "cvs update" of module.
# -d dir Place module in directory "dir" instead of module name.
# -l Top-level directory only -- do not recurse.
#
# NOTE: If you change any of the "Run" options above, you'll have to
# release and re-checkout any working directories of these modules.
#
# And "directory" is a path to a directory relative to $CVSROOT.
#
# The "-a" option specifies an alias. An alias is interpreted as if
# everything on the right of the "-a" had been typed on the command line.
#
# You can encode a module within a module by using the special '&'
# character to interpose another module into the current module. This
# can be useful for creating a module that consists of many directories
# spread out over the entire source repository.

12
Lib/CVSROOT/notify Normal file
View file

@ -0,0 +1,12 @@
# The "notify" file controls where notifications from watches set by
# "cvs watch add" or "cvs edit" are sent. The first entry on a line is
# a regular expression which is tested against the directory that the
# change is being made to, relative to the $CVSROOT. If it matches,
# then the remainder of the line is a filter program that should contain
# one occurrence of %s for the user to notify, and information on its
# standard input.
#
# "ALL" or "DEFAULT" can be used in place of the regular expression.
#
# For example:
#ALL mail %s -s "CVS notification"

13
Lib/CVSROOT/rcsinfo Normal file
View file

@ -0,0 +1,13 @@
# The "rcsinfo" file is used to control templates with which the editor
# is invoked on commit and import.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being made to, relative to the
# $CVSROOT. For the first match that is found, then the remainder of the
# line is the name of the file that contains the template.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

20
Lib/CVSROOT/taginfo Normal file
View file

@ -0,0 +1,20 @@
# The "taginfo" file is used to control pre-tag checks.
# The filter on the right is invoked with the following arguments:
#
# $1 -- tagname
# $2 -- operation "add" for tag, "mov" for tag -F, and "del" for tag -d
# $3 -- repository
# $4-> file revision [file revision ...]
#
# A non-zero exit of the filter program will cause the tag to be aborted.
#
# The first entry on a line is a regular expression which is tested
# against the directory that the change is being committed to, relative
# to the $CVSROOT. For the first match that is found, then the remainder
# of the line is the name of the filter to run.
#
# If the repository name does not match any of the regular expressions in this
# file, the "DEFAULT" line is used, if it is specified.
#
# If the name "ALL" appears as a regular expression it is always used
# in addition to the first matching regex or "DEFAULT".

11
Lib/Debug/Makefile.am Normal file
View file

@ -0,0 +1,11 @@
EXTRA_DIST = logtest.cxx
noinst_LIBRARIES = libDebug.a
libDebug_a_SOURCES = \
debug_types.h \
logstream.cxx logstream.hxx
# fg_debug.c fg_debug.h \
INCLUDES += -I$(top_builddir)

37
Lib/Debug/debug_types.h Normal file
View file

@ -0,0 +1,37 @@
// NB: To add a dbg_class, add it here, and add it to the structure in
// fg_debug.c
typedef enum {
FG_NONE = 0x00000000,
FG_TERRAIN = 0x00000001,
FG_ASTRO = 0x00000002,
FG_FLIGHT = 0x00000004,
FG_INPUT = 0x00000008,
FG_GL = 0x00000010,
FG_VIEW = 0x00000020,
FG_COCKPIT = 0x00000040,
FG_GENERAL = 0x00000080,
FG_MATH = 0x00000100,
FG_EVENT = 0x00000200,
FG_AIRCRAFT = 0x00000400,
FG_AUTOPILOT = 0x00000800,
FG_SERIAL = 0x00001000,
FG_CLIPPER = 0x00002000,
FG_UNDEFD = 0x00004000, // For range checking
FG_ALL = 0xFFFFFFFF
} fgDebugClass;
// NB: To add a priority, add it here.
typedef enum {
FG_BULK, // For frequent messages
FG_DEBUG, // Less frequent debug type messages
FG_INFO, // Informatory messages
FG_WARN, // Possible impending problem
FG_ALERT // Very possible impending problem
// FG_EXIT, // Problem (no core)
// FG_ABORT // Abandon ship (core)
} fgDebugPriority;

310
Lib/Debug/fg_debug.c Normal file
View file

@ -0,0 +1,310 @@
/* -*- Mode: C++ -*-
*
* fg_debug.c -- Flight Gear debug utility functions
*
* Written by Paul Bleisch, started January 1998.
*
* Copyright (C) 1998 Paul Bleisch, pbleisch@acm.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
* (Log is kept at end of this file)
**************************************************************************/
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <Include/cmdargs.h> // Line to command line arguments
#include "fg_debug.h"
static int fg_DebugSem = 1;
fgDebugClass fg_DebugClass = FG_NONE; // Need visibility for
fgDebugPriority fg_DebugPriority = FG_INFO; // command line processing.
static fgDebugCallback fg_DebugCallback = NULL;
FILE *fg_DebugOutput = NULL; // Visibility needed for command line processor.
// This can be set to a FILE from the command
// line. If not, it will be set to stderr.
/* TODO: Actually make this thing thread safe */
#ifdef USETHREADS
#define FG_GRABDEBUGSEM while( --fg_DebugSem < 0 ) { fg_DebugSem++; }
#define FG_RELEASEDEBUGSEM fg_DebugSem++;
#else
#define FG_GRABDEBUGSEM
#define FG_RELEASEDEBUGSEM
#endif
/* Used for convienence initialization from env variables.
*/
static struct {
char *str;
fgDebugClass dbg_class;
} fg_DebugClasses[] = {
{ "FG_NONE", 0x00000000 },
{ "FG_TERRAIN", 0x00000001 },
{ "FG_ASTRO", 0x00000002 },
{ "FG_FLIGHT", 0x00000004 },
{ "FG_INPUT", 0x00000008 },
{ "FG_GL", 0x00000010 },
{ "FG_VIEW", 0x00000020 },
{ "FG_COCKPIT", 0x00000040 },
{ "FG_GENERAL", 0x00000080 },
{ "FG_MATH", 0x00000100 },
{ "FG_EVENT", 0x00000200 },
{ "FG_AIRCRAFT", 0x00000400 },
{ "FG_AUTOPILOT", 0x00000800 },
/* Do not edit below here, last entry should be null */
{ "FG_ALL", 0xFFFFFFFF },
{ NULL, 0 }
};
static fgDebugClass fgDebugStrToClass( char *str );
/* fgInitDebug =============================================================*/
void fgInitDebug( void ) {
char *pszClass, *pszPrio, *pszFile;
// Support for log file/alt debug output via command line, environment or
// reasonable default.
/*
if( strlen( logArgbuf ) > 3) { // First check for command line option
// Assumed that we will append.
fg_DebugOutput = fopen(logArgbuf, "a+" );
}
*/
if( !fg_DebugOutput ) { // If not set on command line, environment?
pszFile = getenv( "FG_DEBUGFILE" );
if( pszFile ) { // There is such an environmental variable.
fg_DebugOutput = fopen( pszFile, "a+" );
}
}
if( !fg_DebugOutput ) { // If neither command line nor environment
fg_DebugOutput = stderr; // then we use the fallback position
}
FG_GRABDEBUGSEM;
fg_DebugSem = fg_DebugSem; /* shut up GCC */
// Test command line option overridge of debug priority. If the value
// is in range (properly optioned) the we will override both defaults
// and the environmental value.
/*
if ((priorityArgValue >= FG_BULK) && (priorityArgValue <= FG_ABORT)) {
fg_DebugPriority = priorityArgValue;
} else { // Either not set or out of range. We will not warn the user.
*/
pszPrio = getenv( "FG_DEBUGPRIORITY" );
if( pszPrio ) {
fg_DebugPriority = atoi( pszPrio );
fprintf( stderr,
"fg_debug.c: Environment overrides default debug priority (%d)\n",
fg_DebugPriority );
}
/* } */
/*
if ((debugArgValue >= FG_ALL) && (debugArgValue < FG_UNDEFD)) {
fg_DebugPriority = priorityArgValue;
} else { // Either not set or out of range. We will not warn the user.
*/
pszClass = getenv( "FG_DEBUGCLASS" );
if( pszClass ) {
fg_DebugClass = fgDebugStrToClass( pszClass );
fprintf( stderr,
"fg_debug.c: Environment overrides default debug class (0x%08X)\n",
fg_DebugClass );
}
/* } */
FG_RELEASEDEBUGSEM;
}
/* fgDebugStrToClass ======================================================*/
fgDebugClass fgDebugStrToClass( char *str ) {
char *hex = "0123456789ABCDEF";
char *hexl = "0123456789abcdef";
char *pt, *p, *ph, ps = 1;
unsigned int val = 0, i;
if( str == NULL ) {
return 0;
}
/* Check for 0xXXXXXX notation */
p = strstr( str, "0x");
if( p ) {
p++; p++;
while (*p) {
ph = strchr(hex,*p);
if ( ph ) {
val <<= 4;
val += ph-hex;
p++;
} else {
ph = strchr(hexl,*p);
if ( ph ) {
val <<= 4;
val += ph-hex;
p++;
} else {
// fprintf( stderr, "Error in hex string '%s'\n", str );
return FG_NONE;
}
}
}
} else {
/* Must be in string format */
p = str;
ps = 1;
while( ps ) {
while( *p && (*p==' ' || *p=='\t') ) p++; /* remove whitespace */
pt = p; /* mark token */
while( *p && (*p!='|') ) p++; /* find OR or EOS */
ps = *p; /* save value at p so we can attempt to be bounds safe */
*p++ = 0; /* terminate token */
/* determine value for token */
i=0;
while( fg_DebugClasses[i].str &&
strncmp( fg_DebugClasses[i].str, pt,
strlen(fg_DebugClasses[i].str)) ) i++;
if( fg_DebugClasses[i].str == NULL ) {
fprintf( stderr,
"fg_debug.c: Could not find message class '%s'\n",
pt );
} else {
val |= fg_DebugClasses[i].dbg_class;
}
}
}
return (fgDebugClass)val;
}
/* fgSetDebugOutput =======================================================*/
void fgSetDebugOutput( FILE *out ) {
FG_GRABDEBUGSEM;
fflush( fg_DebugOutput );
fg_DebugOutput = out;
FG_RELEASEDEBUGSEM;
}
/* fgSetDebugLevels =======================================================*/
void fgSetDebugLevels( fgDebugClass dbg_class, fgDebugPriority prio ) {
FG_GRABDEBUGSEM;
fg_DebugClass = dbg_class;
fg_DebugPriority = prio;
FG_RELEASEDEBUGSEM;
}
/* fgRegisterDebugCallback ================================================*/
fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback ) {
fgDebugCallback old;
FG_GRABDEBUGSEM;
old = fg_DebugCallback;
fg_DebugCallback = callback;
FG_RELEASEDEBUGSEM;
return old;
}
/* fgPrintf ===============================================================*/
int fgPrintf( fgDebugClass dbg_class, fgDebugPriority prio, char *fmt, ... ) {
char szOut[1024+1];
va_list ap;
int ret = 0;
// If no action to take, then don't bother with the semaphore
// activity Slight speed benefit.
// printf("dbg_class = %d fg_DebugClass = %d\n", dbg_class, fg_DebugClass);
// printf("prio = %d fg_DebugPriority = %d\n", prio, fg_DebugPriority);
if( !(dbg_class & fg_DebugClass) ) {
// Failed to match a specific debug class
if ( prio < fg_DebugPriority ) {
// priority is less than requested
// "ret" is zero anyway. But we might think about changing
// it upon some error condition?
return ret;
}
}
FG_GRABDEBUGSEM;
/* ret = vsprintf( szOut, fmt, (&fmt+1)); (but it didn't work, thus ... */
va_start (ap, fmt);
ret = vsprintf( szOut, fmt, ap);
va_end (ap);
if( fg_DebugCallback!=NULL && fg_DebugCallback(dbg_class, prio, szOut) ) {
FG_RELEASEDEBUGSEM;
return ret;
} else {
fprintf( fg_DebugOutput, szOut );
FG_RELEASEDEBUGSEM;
if( prio == FG_EXIT ) {
exit(0);
} else if( prio == FG_ABORT ) {
abort();
}
}
return ret;
}
/* $Log$
/* Revision 1.4 1998/06/01 17:49:44 curt
/* Rewrote a slightly ambiguous code fragment (contributed by Charlie Hotchkiss)
/*
* Revision 1.3 1998/05/07 23:03:54 curt
* Added an entry for AUTOPILOT.
*
* Revision 1.2 1998/04/21 17:03:45 curt
* Prepairing for C++ integration.
*
* Revision 1.1 1998/04/18 03:52:04 curt
* Moved to Lib directory and created a libDebug.
*
* Revision 1.10 1998/03/14 00:31:21 curt
* Beginning initial terrain texturing experiments.
*
* Revision 1.9 1998/03/09 22:44:58 curt
* Modified so that you can specify FG_DEBUGCLASS ***or*** FG_DEBUG_PRIORITY
*
* Revision 1.8 1998/03/09 22:11:00 curt
* Processed through the format-o-matic.
*
* Revision 1.7 1998/02/16 13:39:43 curt
* Miscellaneous weekend tweaks. Fixed? a cache problem that caused whole
* tiles to occasionally be missing.
*
*/

156
Lib/Debug/fg_debug.h Normal file
View file

@ -0,0 +1,156 @@
/* -*- Mode: C++ -*-
*
* fg_debug.h -- Flight Gear debug utility functions
*
* Written by Paul Bleisch, started January 1998.
*
* Copyright (C) 1998 Paul Bleisch, pbleisch@acm.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* (Log is kept at end of this file)
**************************************************************************/
#error "use logstream"
#ifndef _FG_DEBUG_H
#define _FG_DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
/* NB: To add a dbg_class, add it here, and add it to the structure in
fg_debug.c */
typedef enum {
FG_NONE = 0x00000000,
FG_TERRAIN = 0x00000001,
FG_ASTRO = 0x00000002,
FG_FLIGHT = 0x00000004,
FG_INPUT = 0x00000008,
FG_GL = 0x00000010,
FG_VIEW = 0x00000020,
FG_COCKPIT = 0x00000040,
FG_GENERAL = 0x00000080,
FG_MATH = 0x00000100,
FG_EVENT = 0x00000200,
FG_AIRCRAFT = 0x00000400,
FG_AUTOPILOT = 0x00000800,
FG_UNDEFD = 0x00001000, // For range checking
FG_ALL = 0xFFFFFFFF
} fgDebugClass;
/* NB: To add a priority, add it here. */
typedef enum {
FG_BULK, /* For frequent messages */
FG_DEBUG, /* Less frequent debug type messages */
FG_INFO, /* Informatory messages */
FG_WARN, /* Possible impending problem */
FG_ALERT, /* Very possible impending problem */
FG_EXIT, /* Problem (no core) */
FG_ABORT /* Abandon ship (core) */
} fgDebugPriority;
/* Initialize the debuggin stuff. */
void fgInitDebug( void );
/* fgPrintf
Expects:
class fgDebugClass mask for this message.
prio fgDebugPriority of this message.
fmt printf like string format
... var args for fmt
Returns:
number of items in fmt handled.
This function works like the standard C library function printf() with
the addition of message classes and priorities (see fgDebugClasses
and fgDebugPriorities). These additions allow us to classify messages
and disable sets of messages at runtime. Only messages with a prio
greater than or equal to fg_DebugPriority and in the current debug class
(fg_DebugClass) are printed.
*/
int fgPrintf( fgDebugClass dbg_class, fgDebugPriority prio, char *fmt, ... );
/* fgSetDebugLevels()
Expects:
dbg_class Bitmask representing classes to display.
prio Minimum priority of messages to display.
*/
void fgSetDebugLevels( fgDebugClass dbg_class, fgDebugPriority prio );
/* fgSetDebugOutput()
Expects:
file A FILE* to a stream to send messages to.
It is assumed the file stream is open and writable. The system
defaults to stderr. The current stream is flushed but not
closed.
*/
void fgSetDebugOutput( FILE *out );
/* fgRegisterDebugCallback
Expects:
callback A function that takes parameters as defined by the
fgDebugCallback type.
Returns:
a pointer to the previously registered callback (if any)
Install a user defined debug log callback. This callback is called w
whenever fgPrintf is called. The parameters passed to the callback are
defined above by fgDebugCallback. outstr is the string that is to be
printed. If callback returns nonzero, it is assumed that the message
was handled fully by the callback and **fgPrintf need do no further
processing of the message.** Only one callback may be installed at a
time.
*/
//typedef int (*fgDebugCallback)(fgDebugClass, fgDebugPriority, char *outstr);
//fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback );
typedef int (*fgDebugCallback)( int DebugClass, int DebugPriority, char *outstr);
fgDebugCallback fgRegisterDebugCallback( fgDebugCallback callback );
// Leave these alone. Access intended for fg_debug and command line processing.
//
extern fgDebugClass fg_DebugClass;
extern fgDebugPriority fg_DebugPriority;
extern FILE * fg_DebugOutput;
#ifdef __cplusplus
}
#endif
#endif /* _FG_DEBUG_H */

71
Lib/Debug/logstream.cxx Normal file
View file

@ -0,0 +1,71 @@
// Stream based logging mechanism.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#include "logstream.hxx"
bool logbuf::logging_enabled = true;
fgDebugClass logbuf::logClass = FG_NONE;
fgDebugPriority logbuf::logPriority = FG_INFO;
streambuf* logbuf::sbuf = NULL;
logbuf::logbuf()
{
// if ( sbuf == NULL )
// sbuf = cerr.rdbuf();
}
logbuf::~logbuf()
{
if ( sbuf )
sync();
}
void
logbuf::set_sb( streambuf* sb )
{
if ( sbuf )
sync();
sbuf = sb;
}
void
logbuf::set_log_level( fgDebugClass c, fgDebugPriority p )
{
logClass = c;
logPriority = p;
}
void
logstream::setLogLevels( fgDebugClass c, fgDebugPriority p )
{
logbuf::set_log_level( c, p );
}
// $Log$
// Revision 1.2 1999/01/19 20:53:34 curt
// Portability updates by Bernie Bright.
//
// Revision 1.1 1998/11/06 21:20:41 curt
// Initial revision.
//

228
Lib/Debug/logstream.hxx Normal file
View file

@ -0,0 +1,228 @@
// Stream based logging mechanism.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _LOGSTREAM_H
#define _LOGSTREAM_H
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <Include/compiler.h>
#ifdef FG_HAVE_STD_INCLUDES
# include <streambuf>
# include <iostream>
#else
# include <iostream.h>
# include "Include/fg_traits.hxx"
#endif
#include "debug_types.h"
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
FG_USING_STD(streambuf);
FG_USING_STD(ostream);
FG_USING_STD(cerr);
FG_USING_STD(endl);
#endif
//
// TODO:
//
// 1. Change output destination. Done.
// 2. Make logbuf thread safe.
// 3. Read environment for default debugClass and debugPriority.
//
//-----------------------------------------------------------------------------
//
// logbuf is an output-only streambuf with the ability to disable sets of
// messages at runtime. Only messages with priority >= logbuf::logPriority
// and debugClass == logbuf::logClass are output.
//
class logbuf : public streambuf
{
public:
#ifndef FG_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) {}
logbuf();
~logbuf();
// Is logging enabled?
bool enabled() { return logging_enabled; }
// Set the logging level of subsequent messages.
void set_log_state( fgDebugClass c, fgDebugPriority p );
// Set the global logging level.
static void set_log_level( fgDebugClass c, fgDebugPriority p );
//
void set_sb( streambuf* sb );
protected:
inline virtual int sync();
int_type overflow( int ch );
// int xsputn( const char* s, istreamsize n );
private:
// The streambuf used for actual output. Defaults to cerr.rdbuf().
static streambuf* sbuf;
static bool logging_enabled;
static fgDebugClass logClass;
static fgDebugPriority logPriority;
private:
// Not defined.
logbuf( const logbuf& );
void operator= ( const logbuf& );
};
inline int
logbuf::sync()
{
#ifdef FG_HAVE_STD_INCLUDES
return sbuf->pubsync();
#else
return sbuf->sync();
#endif
}
inline void
logbuf::set_log_state( fgDebugClass c, fgDebugPriority p )
{
logging_enabled = ((c & logClass) != 0 && p >= logPriority);
}
inline logbuf::int_type
logbuf::overflow( int c )
{
return logging_enabled ? sbuf->sputc(c) : (EOF == 0 ? 1: 0);
}
//-----------------------------------------------------------------------------
//
// logstream manipulator for setting the log level of a message.
//
struct loglevel
{
loglevel( fgDebugClass c, fgDebugPriority p )
: logClass(c), logPriority(p) {}
fgDebugClass logClass;
fgDebugPriority logPriority;
};
//-----------------------------------------------------------------------------
//
// A helper class that ensures a streambuf and ostream are constructed and
// destroyed in the correct order. The streambuf must be created before the
// ostream but bases are constructed before members. Thus, making this class
// a private base of logstream, declared to the left of ostream, we ensure the
// correct order of construction and destruction.
//
struct logstream_base
{
// logstream_base( streambuf* sb ) : lbuf(sb) {}
logstream_base() {}
logbuf lbuf;
};
//-----------------------------------------------------------------------------
//
//
//
class logstream : private logstream_base, public ostream
{
public:
// The default is to send messages to cerr.
logstream( ostream& out )
// : logstream_base(out.rdbuf()),
: logstream_base(),
ostream(&lbuf) { lbuf.set_sb(out.rdbuf());}
void set_output( ostream& out ) { lbuf.set_sb( out.rdbuf() ); }
// Set the global log class and priority level.
void setLogLevels( fgDebugClass c, fgDebugPriority p );
// Output operator to capture the debug level and priority of a message.
inline ostream& operator<< ( const loglevel& l );
};
inline ostream&
logstream::operator<< ( const loglevel& l )
{
lbuf.set_log_state( l.logClass, l.logPriority );
return *this;
}
//-----------------------------------------------------------------------------
//
// Return the one and only logstream instance.
// We use a function instead of a global object so we are assured that cerr
// has been initialised.
//
inline logstream&
fglog()
{
static logstream logstrm( cerr );
return logstrm;
}
#ifdef FG_NDEBUG
# define FG_LOG(C,P,M)
#else
# define FG_LOG(C,P,M) fglog() << loglevel(C,P) << M << endl
#endif
#endif // _LOGSTREAM_H
// $Log$
// Revision 1.4 1999/03/02 01:01:47 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.3 1999/01/19 20:53:35 curt
// Portability updates by Bernie Bright.
//
// Revision 1.2 1998/11/07 19:07:02 curt
// Enable release builds using the --without-logging option to the configure
// script. Also a couple log message cleanups, plus some C to C++ comment
// conversion.
//
// Revision 1.1 1998/11/06 21:20:42 curt
// Initial revision.
//

34
Lib/Debug/logtest.cxx Normal file
View file

@ -0,0 +1,34 @@
#include <string>
#include "Debug/logstream.hxx"
int
main( int argc, char* argv[] )
{
fglog().setLogLevels( FG_ALL, FG_INFO );
FG_LOG( FG_TERRAIN, FG_BULK, "terrain::bulk" ); // shouldnt appear
FG_LOG( FG_TERRAIN, FG_DEBUG, "terrain::debug" ); // shouldnt appear
FG_LOG( FG_TERRAIN, FG_INFO, "terrain::info" );
FG_LOG( FG_TERRAIN, FG_WARN, "terrain::warn" );
FG_LOG( FG_TERRAIN, FG_ALERT, "terrain::alert" );
int i = 12345;
long l = 54321L;
double d = 3.14159;
string s = "Hello world!";
FG_LOG( FG_EVENT, FG_INFO, "event::info "
<< "i=" << i
<< ", l=" << l
<< ", d=" << d
<< ", d*l=" << d*l
<< ", s=\"" << s << "\"" );
// This shouldn't appear in log output:
FG_LOG( FG_EVENT, FG_DEBUG, "event::debug "
<< "- this should be seen - "
<< "d=" << d
<< ", s=\"" << s << "\"" );
return 0;
}

15
Lib/Lib/Makefile.am Normal file
View file

@ -0,0 +1,15 @@
if ENABLE_UNIX_SERIAL
SERIAL_DIRS = Serial
else
SERIAL_DIRS =
endif
SUBDIRS = \
Bucket \
Debug \
Math \
Misc \
$(SERIAL_DIRS) \
XGL\
plib \
zlib

168
Lib/Math/MAT3geom.c Normal file
View file

@ -0,0 +1,168 @@
/* #include "HEADERS.h" */
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that perform geometry-related operations
* on matrices.
* -------------------------------------------------------------------------*/
#include <Math/mat3defs.h>
/* -------------------------- Static Routines ---------------------------- */
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
/*
* This takes a matrix used to transform points, and returns a corresponding
* matrix that can be used to transform direction vectors (between points).
*/
void
MAT3direction_matrix(register double (*result_mat)[4], register double (*mat)[4])
{
register int i;
MAT3copy(result_mat, mat);
for (i = 0; i < 4; i++) result_mat[i][3] = result_mat[3][i] = 0.0;
result_mat[3][3] = 1.0;
}
/*
* This takes a matrix used to transform points, and returns a corresponding
* matrix that can be used to transform vectors that must remain perpendicular
* to planes defined by the points. It is useful when you are transforming
* some object that has both points and normals in its definition, and you
* only have the transformation matrix for the points. This routine returns
* FALSE if the normal matrix is uncomputable. Otherwise, it returns TRUE.
*
* Spike sez: "This is the adjoint for the non-homogeneous part of the
* transformation."
*/
int
MAT3normal_matrix(register double (*result_mat)[4], register double (*mat)[4])
{
register int ret;
MAT3mat tmp_mat;
MAT3direction_matrix(result_mat, mat);
if ( (ret = MAT3invert(tmp_mat, tmp_mat)) ) {
MAT3transpose(result_mat, tmp_mat);
}
return(ret);
}
/*
* Sets the given matrix to be a scale matrix for the given vector of
* scale values.
*/
void
MAT3scale(double (*result_mat)[4], double *scale)
{
MAT3identity(result_mat);
result_mat[0][0] = scale[0];
result_mat[1][1] = scale[1];
result_mat[2][2] = scale[2];
}
/*
* Sets up a matrix for a rotation about an axis given by the line from
* (0,0,0) to axis, through an angle (in radians).
* Looking along the axis toward the origin, the rotation is counter-clockwise.
*/
#define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
void
MAT3rotate(double (*result_mat)[4], double *axis, double angle_in_radians)
{
MAT3vec naxis, /* Axis of rotation, normalized */
base2, /* 2nd unit basis vec, perp to axis */
base3; /* 3rd unit basis vec, perp to axis & base2 */
double dot;
MAT3mat base_mat, /* Change-of-basis matrix */
base_mat_trans; /* Inverse of c-o-b matrix */
register int i;
/* Step 1: extend { axis } to a basis for 3-space: { axis, base2, base3 }
* which is orthonormal (all three have unit length, and all three are
* mutually orthogonal). Also should be oriented, i.e. axis cross base2 =
* base3, rather than -base3.
*
* Method: Find a vector linearly independent from axis. For this we
* either use the y-axis, or, if that is too close to axis, the
* z-axis. 'Too close' means that the dot product is too near to 1.
*/
MAT3_COPY_VEC(naxis, axis);
MAT3_NORMALIZE_VEC(naxis, dot);
if (dot == 0.0) {
/* ERR_ERROR(MAT3_errid, ERR_SEVERE,
(ERR_S, "Zero-length axis vector given to MAT3rotate")); */
return;
}
MAT3perp_vec(base2, naxis, TRUE);
MAT3cross_product(base3, naxis, base2);
/* Set up the change-of-basis matrix, and its inverse */
MAT3identity(base_mat);
MAT3identity(base_mat_trans);
MAT3identity(result_mat);
for (i = 0; i < 3; i++){
base_mat_trans[i][0] = base_mat[0][i] = naxis[i];
base_mat_trans[i][1] = base_mat[1][i] = base2[i];
base_mat_trans[i][2] = base_mat[2][i] = base3[i];
}
/* If T(u) = uR, where R is base_mat, then T(x-axis) = naxis,
* T(y-axis) = base2, and T(z-axis) = base3. The inverse of base_mat is
* its transpose. OK?
*/
result_mat[1][1] = result_mat[2][2] = cos(angle_in_radians);
result_mat[2][1] = -(result_mat[1][2] = sin(angle_in_radians));
MAT3mult(result_mat, base_mat_trans, result_mat);
MAT3mult(result_mat, result_mat, base_mat);
}
/*
* Sets the given matrix to be a translation matrix for the given vector of
* translation values.
*/
void
MAT3translate(double (*result_mat)[4], double *trans)
{
MAT3identity(result_mat);
result_mat[3][0] = trans[0];
result_mat[3][1] = trans[1];
result_mat[3][2] = trans[2];
}
/*
* Sets the given matrix to be a shear matrix for the given x and y shear
* values.
*/
void
MAT3shear(double (*result_mat)[4], double xshear, double yshear)
{
MAT3identity(result_mat);
result_mat[2][0] = xshear;
result_mat[2][1] = yshear;
}

311
Lib/Math/MAT3inv.c Normal file
View file

@ -0,0 +1,311 @@
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that operate solely on matrices.
* -------------------------------------------------------------------------*/
#include <Math/mat3defs.h>
/* -------------------------- Static Routines ---------------------------- */
#define SMALL 1e-20 /* Small enough to be considered zero */
/*
* Shuffles rows in inverse of 3x3. See comment in MAT3_inv3_second_col().
*/
static void
MAT3_inv3_swap( register double inv[3][3], int row0, int row1, int row2)
{
register int i, tempi;
double temp;
#define SWAP_ROWS(a, b) \
for (i = 0; i < 3; i++) SWAP(inv[a][i], inv[b][i], temp); \
SWAP(a, b, tempi)
if (row0 != 0){
if (row1 == 0) {
SWAP_ROWS(row0, row1);
}
else {
SWAP_ROWS(row0, row2);
}
}
if (row1 != 1) {
SWAP_ROWS(row1, row2);
}
}
/*
* Does Gaussian elimination on second column.
*/
static int
MAT3_inv3_second_col (register double source[3][3], register double inv[3][3], int row0)
{
register int row1, row2, i1, i2, i;
double temp;
double a, b;
/* Find which row to use */
if (row0 == 0) i1 = 1, i2 = 2;
else if (row0 == 1) i1 = 0, i2 = 2;
else i1 = 0, i2 = 1;
/* Find which is larger in abs. val.:the entry in [i1][1] or [i2][1] */
/* and use that value for pivoting. */
a = source[i1][1]; if (a < 0) a = -a;
b = source[i2][1]; if (b < 0) b = -b;
if (a > b) row1 = i1;
else row1 = i2;
row2 = (row1 == i1 ? i2 : i1);
/* Scale row1 in source */
if ((source[row1][1] < SMALL) && (source[row1][1] > -SMALL)) return(FALSE);
temp = 1.0 / source[row1][1];
source[row1][1] = 1.0;
source[row1][2] *= temp; /* source[row1][0] is zero already */
/* Scale row1 in inv */
inv[row1][row1] = temp; /* it used to be a 1.0 */
inv[row1][row0] *= temp;
/* Clear column one, source, and make corresponding changes in inv */
for (i = 0; i < 3; i++) if (i != row1) { /* for i = all rows but row1 */
temp = -source[i][1];
source[i][1] = 0.0;
source[i][2] += temp * source[row1][2];
inv[i][row1] = temp * inv[row1][row1];
inv[i][row0] += temp * inv[row1][row0];
}
/* Scale row2 in source */
if ((source[row2][2] < SMALL) && (source[row2][2] > -SMALL)) return(FALSE);
temp = 1.0 / source[row2][2];
source[row2][2] = 1.0; /* source[row2][*] is zero already */
/* Scale row2 in inv */
inv[row2][row2] = temp; /* it used to be a 1.0 */
inv[row2][row0] *= temp;
inv[row2][row1] *= temp;
/* Clear column one, source, and make corresponding changes in inv */
for (i = 0; i < 3; i++) if (i != row2) { /* for i = all rows but row2 */
temp = -source[i][2];
source[i][2] = 0.0;
inv[i][row0] += temp * inv[row2][row0];
inv[i][row1] += temp * inv[row2][row1];
inv[i][row2] += temp * inv[row2][row2];
}
/*
* Now all is done except that the inverse needs to have its rows shuffled.
* row0 needs to be moved to inv[0][*], row1 to inv[1][*], etc.
*
* We *didn't* do the swapping before the elimination so that we could more
* easily keep track of what ops are needed to be done in the inverse.
*/
MAT3_inv3_swap(inv, row0, row1, row2);
return(TRUE);
}
/*
* Fast inversion routine for 3 x 3 matrices. - Written by jfh.
*
* This takes 30 multiplies/divides, as opposed to 39 for Cramer's Rule.
* The algorithm consists of performing fast gaussian elimination, by never
* doing any operations where the result is guaranteed to be zero, or where
* one operand is guaranteed to be zero. This is done at the cost of clarity,
* alas.
*
* Returns 1 if the inverse was successful, 0 if it failed.
*/
static int
MAT3_invert3 (register double source[3][3], register double inv[3][3])
{
register int i, row0;
double temp;
double a, b, c;
inv[0][0] = inv[1][1] = inv[2][2] = 1.0;
inv[0][1] = inv[0][2] = inv[1][0] = inv[1][2] = inv[2][0] = inv[2][1] = 0.0;
/* attempt to find the largest entry in first column to use as pivot */
a = source[0][0]; if (a < 0) a = -a;
b = source[1][0]; if (b < 0) b = -b;
c = source[2][0]; if (c < 0) c = -c;
if (a > b) {
if (a > c) row0 = 0;
else row0 = 2;
}
else {
if (b > c) row0 = 1;
else row0 = 2;
}
/* Scale row0 of source */
if ((source[row0][0] < SMALL) && (source[row0][0] > -SMALL)) return(FALSE);
temp = 1.0 / source[row0][0];
source[row0][0] = 1.0;
source[row0][1] *= temp;
source[row0][2] *= temp;
/* Scale row0 of inverse */
inv[row0][row0] = temp; /* other entries are zero -- no effort */
/* Clear column zero of source, and make corresponding changes in inverse */
for (i = 0; i < 3; i++) if (i != row0) { /* for i = all rows but row0 */
temp = -source[i][0];
source[i][0] = 0.0;
source[i][1] += temp * source[row0][1];
source[i][2] += temp * source[row0][2];
inv[i][row0] = temp * inv[row0][row0];
}
/*
* We've now done gaussian elimination so that the source and
* inverse look like this:
*
* 1 * * * 0 0
* 0 * * * 1 0
* 0 * * * 0 1
*
* We now proceed to do elimination on the second column.
*/
if (! MAT3_inv3_second_col(source, inv, row0)) return(FALSE);
return(TRUE);
}
/*
* Finds a new pivot for a non-simple 4x4. See comments in MAT3invert().
*/
static int
MAT3_inv4_pivot (register MAT3mat src, MAT3vec r, double *s, int *swap)
{
register int i, j;
double temp, max;
*swap = -1;
if (MAT3_IS_ZERO(src[3][3])) {
/* Look for a different pivot element: one with largest abs value */
max = 0.0;
for (i = 0; i < 4; i++) {
if (src[i][3] > max) max = src[*swap = i][3];
else if (src[i][3] < -max) max = -src[*swap = i][3];
}
/* No pivot element available ! */
if (*swap < 0) return(FALSE);
else for (j = 0; j < 4; j++) SWAP(src[*swap][j], src[3][j], temp);
}
MAT3_SET_VEC (r, -src[0][3], -src[1][3], -src[2][3]);
*s = 1.0 / src[3][3];
src[0][3] = src[1][3] = src[2][3] = 0.0;
src[3][3] = 1.0;
MAT3_SCALE_VEC(src[3], src[3], *s);
for (i = 0; i < 3; i++) {
src[0][i] += r[0] * src[3][i];
src[1][i] += r[1] * src[3][i];
src[2][i] += r[2] * src[3][i];
}
return(TRUE);
}
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
/*
* This returns the inverse of the given matrix. The result matrix
* may be the same as the one to invert.
*
* Fast inversion routine for 4 x 4 matrices, written by jfh.
*
* Returns 1 if the inverse was successful, 0 if it failed.
*
* This routine has been specially tweaked to notice the following:
* If the matrix has the form
* * * * 0
* * * * 0
* * * * 0
* * * * 1
*
* (as do many matrices in graphics), then we compute the inverse of
* the upper left 3x3 matrix and use this to find the general inverse.
*
* In the event that the right column is not 0-0-0-1, we do gaussian
* elimination to make it so, then use the 3x3 inverse, and then do
* our gaussian elimination.
*/
int
MAT3invert(double (*result_mat)[4], double (*mat)[4])
{
MAT3mat src, inv;
register int i, j, simple;
double m[3][3], inv3[3][3], s, temp;
MAT3vec r, t;
int swap;
MAT3copy(src, mat);
MAT3identity(inv);
/* If last column is not (0,0,0,1), use special code */
simple = (mat[0][3] == 0.0 && mat[1][3] == 0.0 &&
mat[2][3] == 0.0 && mat[3][3] == 1.0);
if (! simple && ! MAT3_inv4_pivot(src, r, &s, &swap)) return(FALSE);
MAT3_COPY_VEC(t, src[3]); /* Translation vector */
/* Copy upper-left 3x3 matrix */
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) m[i][j] = src[i][j];
if (! MAT3_invert3(m, inv3)) return(FALSE);
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++) inv[i][j] = inv3[i][j];
for (i = 0; i < 3; i++) for (j = 0; j < 3; j++)
inv[3][i] -= t[j] * inv3[j][i];
if (! simple) {
/* We still have to undo our gaussian elimination from earlier on */
/* add r0 * first col to last col */
/* add r1 * 2nd col to last col */
/* add r2 * 3rd col to last col */
for (i = 0; i < 4; i++) {
inv[i][3] += r[0] * inv[i][0] + r[1] * inv[i][1] + r[2] * inv[i][2];
inv[i][3] *= s;
}
if (swap >= 0)
for (i = 0; i < 4; i++) SWAP(inv[i][swap], inv[i][3], temp);
}
MAT3copy(result_mat, inv);
return(TRUE);
}

116
Lib/Math/MAT3mat.c Normal file
View file

@ -0,0 +1,116 @@
/* #include "HEADERS.h" */
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that operate solely on matrices.
* -------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef WIN32
# ifndef HAVE_STL_SGI_PORT
# include <memory.h> /* required for memset() and memcpy() */
# endif
#endif
#include <string.h>
#include <Math/mat3defs.h>
MAT3mat identityMatrix = {
{ 1.0, 0.0, 0.0, 0.0 },
{ 0.0, 1.0, 0.0, 0.0 },
{ 0.0, 0.0, 1.0, 0.0 },
{ 0.0, 0.0, 0.0, 1.0 }
};
/* #include "macros.h" */
/* -------------------------- Static Routines ---------------------------- */
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
#if !defined( USE_XTRA_MAT3_INLINES )
/*
* This multiplies two matrices, producing a third, which may the same as
* either of the first two.
*/
void
MAT3mult (double (*result_mat)[4], register double (*mat1)[4], register double (*mat2)[4])
{
register int i, j;
MAT3mat tmp_mat;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] +
mat1[i][1] * mat2[1][j] +
mat1[i][2] * mat2[2][j] +
mat1[i][3] * mat2[3][j]);
MAT3copy (result_mat, tmp_mat);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
/*
* This returns the transpose of a matrix. The result matrix may be
* the same as the one to transpose.
*/
void
MAT3transpose (double (*result_mat)[4], register double (*mat)[4])
{
register int i, j;
MAT3mat tmp_mat;
for (i = 0; i < 4; i++)
for (j = 0; j < 4; j++)
tmp_mat[i][j] = mat[j][i];
MAT3copy (result_mat, tmp_mat);
}
/*
* This prints the given matrix to the given file pointer.
*/
void
MAT3print(double (*mat)[4], FILE *fp)
{
MAT3print_formatted(mat, fp, CNULL, CNULL, CNULL, CNULL);
}
/*
* This prints the given matrix to the given file pointer.
* use the format string to pass to fprintf. head and tail
* are printed at the beginning and end of each line.
*/
void
MAT3print_formatted(double (*mat)[4], FILE *fp, char *title, char *head, char *format, char *tail)
{
register int i, j;
/* This is to allow this to be called easily from a debugger */
if (fp == NULL) fp = stderr;
if (title == NULL) title = "MAT3 matrix:\n";
if (head == NULL) head = " ";
if (format == NULL) format = "%#8.4lf ";
if (tail == NULL) tail = "\n";
(void) fprintf(fp, title);
for (i = 0; i < 4; i++) {
(void) fprintf(fp, head);
for (j = 0; j < 4; j++) (void) fprintf(fp, format, mat[i][j]);
(void) fprintf(fp, tail);
}
}

154
Lib/Math/MAT3vec.c Normal file
View file

@ -0,0 +1,154 @@
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* --------------------------------------------------------------------------
* This file contains routines that operate on matrices and vectors, or
* vectors and vectors.
* -------------------------------------------------------------------------*/
/* #include "sphigslocal.h" */
/* -------------------------- Static Routines ---------------------------- */
/* ------------------------- Internal Routines --------------------------- */
/* -------------------------- Public Routines ---------------------------- */
/*
* Multiplies a vector by a matrix, setting the result vector.
* It assumes all homogeneous coordinates are 1.
* The two vectors involved may be the same.
*/
#include <Math/mat3.h>
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#if !defined( USE_XTRA_MAT3_INLINES )
void
MAT3mult_vec(double *result_vec, register double *vec, register double (*mat)[4])
{
MAT3vec tempvec;
register double *temp = tempvec;
temp[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] +
vec[2] * mat[2][0] + mat[3][0];
temp[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] +
vec[2] * mat[2][1] + mat[3][1];
temp[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] +
vec[2] * mat[2][2] + mat[3][2];
MAT3_COPY_VEC(result_vec, temp);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
/*
* Multiplies a vector of size 4 by a matrix, setting the result vector.
* The fourth element of the vector is the homogeneous coordinate, which
* may or may not be 1. If the "normalize" parameter is TRUE, then the
* result vector will be normalized so that the homogeneous coordinate is 1.
* The two vectors involved may be the same.
* This returns zero if the vector was to be normalized, but couldn't be.
*/
int
MAT3mult_hvec(double *result_vec, register double *vec, register double (*mat)[4], int normalize)
{
MAT3hvec tempvec;
double norm_fac;
register double *temp = tempvec;
register int ret = TRUE;
temp[0] = vec[0] * mat[0][0] + vec[1] * mat[1][0] +
vec[2] * mat[2][0] + vec[3] * mat[3][0];
temp[1] = vec[0] * mat[0][1] + vec[1] * mat[1][1] +
vec[2] * mat[2][1] + vec[3] * mat[3][1];
temp[2] = vec[0] * mat[0][2] + vec[1] * mat[1][2] +
vec[2] * mat[2][2] + vec[3] * mat[3][2];
temp[3] = vec[0] * mat[0][3] + vec[1] * mat[1][3] +
vec[2] * mat[2][3] + vec[3] * mat[3][3];
/* Normalize if asked for, possible, and necessary */
if (normalize) {
if (MAT3_IS_ZERO(temp[3])) {
#ifndef THINK_C
fprintf (stderr,
"Can't normalize vector: homogeneous coordinate is 0");
#endif
ret = FALSE;
}
else {
norm_fac = 1.0 / temp[3];
MAT3_SCALE_VEC(result_vec, temp, norm_fac);
result_vec[3] = 1.0;
}
}
else MAT3_COPY_HVEC(result_vec, temp);
return(ret);
}
#if !defined( USE_XTRA_MAT3_INLINES )
/*
* Sets the first vector to be the cross-product of the last two vectors.
*/
void
MAT3cross_product(double *result_vec, register double *vec1, register double *vec2)
{
MAT3vec tempvec;
register double *temp = tempvec;
temp[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1];
temp[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2];
temp[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0];
MAT3_COPY_VEC(result_vec, temp);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
/*
* Finds a vector perpendicular to vec and stores it in result_vec.
* Method: take any vector (we use <0,1,0>) and subtract the
* portion of it pointing in the vec direction. This doesn't
* work if vec IS <0,1,0> or is very near it. So if this is
* the case, use <0,0,1> instead.
* If "is_unit" is TRUE, the given vector is assumed to be unit length.
*/
#define SELECT .7071 /* selection constant (roughly .5*sqrt(2) */
void
MAT3perp_vec(double *result_vec, double *vec, int is_unit)
{
MAT3vec norm;
double dot;
MAT3_SET_VEC(result_vec, 0.0, 1.0, 0.0);
MAT3_COPY_VEC(norm, vec);
if (! is_unit) MAT3_NORMALIZE_VEC(norm, dot);
/* See if vector is too close to <0,1,0>. If so, use <0,0,1> */
if ((dot = MAT3_DOT_PRODUCT(norm, result_vec)) > SELECT || dot < -SELECT) {
result_vec[1] = 0.0;
result_vec[2] = 1.0;
dot = MAT3_DOT_PRODUCT(norm, result_vec);
}
/* Subtract off non-perpendicular part */
result_vec[0] -= dot * norm[0];
result_vec[1] -= dot * norm[1];
result_vec[2] -= dot * norm[2];
/* Make result unit length */
MAT3_NORMALIZE_VEC(result_vec, dot);
}

17
Lib/Math/Makefile.am Normal file
View file

@ -0,0 +1,17 @@
noinst_LIBRARIES = libMath.a
libMath_a_SOURCES = \
MAT3geom.c \
MAT3inv.c \
MAT3mat.c \
MAT3vec.c \
fg_geodesy.cxx fg_geodesy.hxx \
fg_random.c fg_random.h \
interpolater.cxx interpolater.hxx \
leastsqs.cxx leastsqs.hxx \
mat3.h mat3defs.h mat3err.h \
point3d.hxx \
polar3d.cxx polar3d.hxx \
vector.cxx vector.hxx
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib -I$(top_builddir)/Simulator

301
Lib/Math/fg_geodesy.cxx Normal file
View file

@ -0,0 +1,301 @@
// fg_geodesy.cxx -- routines to convert between geodetic and geocentric
// coordinate systems.
//
// Copied and adapted directly from LaRCsim/ls_geodesy.c
//
// See below for the complete original LaRCsim comments.
//
// $Id$
// (Log is kept at end of this file)
#include "Include/compiler.h"
#ifdef FG_HAVE_STD_INCLUDES
# include <cmath>
# include <cerrno>
#else
# include <math.h>
# include <errno.h>
#endif
#include <Include/fg_constants.h>
#include <Math/fg_geodesy.hxx>
#include <Math/point3d.hxx>
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
FG_USING_STD(cout);
#endif
// ONE_SECOND is pi/180/60/60, or about 100 feet at earths' equator
#define ONE_SECOND 4.848136811E-6
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
// INPUTS:
// lat_geoc Geocentric latitude, radians, + = North
// radius C.G. radius to earth center (meters)
//
// OUTPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
// sea_level_r radius from earth center to sea level at
// local vertical (surface normal) of C.G. (meters)
void fgGeocToGeod( double lat_geoc, double radius, double
*lat_geod, double *alt, double *sea_level_r )
{
double t_lat, x_alpha, mu_alpha, delt_mu, r_alpha, l_point, rho_alpha;
double sin_mu_a, denom,delt_lambda, lambda_sl, sin_lambda_sl;
if( ( (FG_PI_2 - lat_geoc) < ONE_SECOND ) // near North pole
|| ( (FG_PI_2 + lat_geoc) < ONE_SECOND ) ) // near South pole
{
*lat_geod = lat_geoc;
*sea_level_r = EQUATORIAL_RADIUS_M*E;
*alt = radius - *sea_level_r;
} else {
t_lat = tan(lat_geoc);
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
double tmp = RESQ_M - x_alpha * x_alpha;
if ( tmp < 0.0 ) { tmp = 0.0; }
mu_alpha = atan2(sqrt(tmp),E*x_alpha);
if (lat_geoc < 0) mu_alpha = - mu_alpha;
sin_mu_a = sin(mu_alpha);
delt_lambda = mu_alpha - lat_geoc;
r_alpha = x_alpha/cos(lat_geoc);
l_point = radius - r_alpha;
*alt = l_point*cos(delt_lambda);
// check for domain error
if ( errno == EDOM ) {
cout << "Domain ERROR in fgGeocToGeod!!!!\n";
*alt = 0.0;
}
denom = sqrt(1-EPS*EPS*sin_mu_a*sin_mu_a);
rho_alpha = EQUATORIAL_RADIUS_M*(1-EPS)/
(denom*denom*denom);
delt_mu = atan2(l_point*sin(delt_lambda),rho_alpha + *alt);
*lat_geod = mu_alpha - delt_mu;
lambda_sl = atan( E*E * tan(*lat_geod) ); // SL geoc. latitude
sin_lambda_sl = sin( lambda_sl );
*sea_level_r =
sqrt(RESQ_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
// check for domain error
if ( errno == EDOM ) {
cout << "Domain ERROR in fgGeocToGeod!!!!\n";
*sea_level_r = 0.0;
}
}
}
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
// INPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
//
// OUTPUTS:
// sl_radius SEA LEVEL radius to earth center (meters)
// (add Altitude to get true distance from earth center.
// lat_geoc Geocentric latitude, radians, + = North
//
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
double *lat_geoc )
{
double lambda_sl, sin_lambda_sl, cos_lambda_sl, sin_mu, cos_mu, px, py;
lambda_sl = atan( E*E * tan(lat_geod) ); // sea level geocentric latitude
sin_lambda_sl = sin( lambda_sl );
cos_lambda_sl = cos( lambda_sl );
sin_mu = sin(lat_geod); // Geodetic (map makers') latitude
cos_mu = cos(lat_geod);
*sl_radius =
sqrt(RESQ_M / (1 + ((1/(E*E))-1)*sin_lambda_sl*sin_lambda_sl));
py = *sl_radius*sin_lambda_sl + alt*sin_mu;
px = *sl_radius*cos_lambda_sl + alt*cos_mu;
*lat_geoc = atan2( py, px );
}
/***************************************************************************
TITLE: ls_geodesy
----------------------------------------------------------------------------
FUNCTION: Converts geocentric coordinates to geodetic positions
----------------------------------------------------------------------------
MODULE STATUS: developmental
----------------------------------------------------------------------------
GENEALOGY: Written as part of LaRCSim project by E. B. Jackson
----------------------------------------------------------------------------
DESIGNED BY: E. B. Jackson
CODED BY: E. B. Jackson
MAINTAINED BY: E. B. Jackson
----------------------------------------------------------------------------
MODIFICATION HISTORY:
DATE PURPOSE BY
930208 Modified to avoid singularity near polar region. EBJ
930602 Moved backwards calcs here from ls_step. EBJ
931214 Changed erroneous Latitude and Altitude variables to
*lat_geod and *alt in routine ls_geoc_to_geod. EBJ
940111 Changed header files from old ls_eom.h style to ls_types,
and ls_constants. Also replaced old DATA type with new
SCALAR type. EBJ
CURRENT RCS HEADER:
$Header$
$Log$
Revision 1.6 1999/03/02 01:01:49 curt
Tweaks for compiling with native SGI compilers.
Revision 1.5 1999/01/27 04:46:14 curt
Portability tweaks by Bernie Bright.
Revision 1.4 1998/11/20 01:00:36 curt
Patch in fgGeoc2Geod() to avoid a floating explosion.
point3d.hxx include math.h for FreeBSD
Revision 1.3 1998/11/11 00:18:36 curt
Check for domain error in fgGeoctoGeod()
Revision 1.2 1998/10/16 23:36:36 curt
c++-ifying.
Revision 1.1 1998/10/16 19:30:40 curt
Renamed .c -> .h so we can start adding c++ supporting routines.
Revision 1.6 1998/07/08 14:40:07 curt
polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
Updated fg_geodesy comments to reflect that routines expect and produce
meters.
Revision 1.5 1998/04/25 22:06:23 curt
Edited cvs log messages in source files ... bad bad bad!
Revision 1.4 1998/01/27 00:47:59 curt
Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
system and commandline/config file processing code.
Revision 1.3 1998/01/19 19:27:12 curt
Merged in make system changes from Bob Kuehne <rpk@sgi.com>
This should simplify things tremendously.
Revision 1.2 1997/12/15 23:54:54 curt
Add xgl wrappers for debugging.
Generate terrain normals on the fly.
Revision 1.1 1997/07/31 23:13:14 curt
Initial revision.
Revision 1.1 1997/05/29 00:09:56 curt
Initial Flight Gear revision.
* Revision 1.5 1994/01/11 18:47:05 bjax
* Changed include files to use types and constants, not ls_eom.h
* Also changed DATA type to SCALAR type.
*
* Revision 1.4 1993/12/14 21:06:47 bjax
* Removed global variable references Altitude and Latitude. EBJ
*
* Revision 1.3 1993/06/02 15:03:40 bjax
* Made new subroutine for calculating geodetic to geocentric; changed name
* of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
*
----------------------------------------------------------------------------
REFERENCES:
[ 1] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
Control and Simulation", Wiley and Sons, 1992.
ISBN 0-471-61397-5
----------------------------------------------------------------------------
CALLED BY: ls_aux
----------------------------------------------------------------------------
CALLS TO:
----------------------------------------------------------------------------
INPUTS:
lat_geoc Geocentric latitude, radians, + = North
radius C.G. radius to earth center, ft
----------------------------------------------------------------------------
OUTPUTS:
lat_geod Geodetic latitude, radians, + = North
alt C.G. altitude above mean sea level, ft
sea_level_r radius from earth center to sea level at
local vertical (surface normal) of C.G.
--------------------------------------------------------------------------*/
// $Log$
// Revision 1.6 1999/03/02 01:01:49 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.5 1999/01/27 04:46:14 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.4 1998/11/20 01:00:36 curt
// Patch in fgGeoc2Geod() to avoid a floating explosion.
// point3d.hxx include math.h for FreeBSD
//
// Revision 1.3 1998/11/11 00:18:36 curt
// Check for domain error in fgGeoctoGeod()
//
// Revision 1.2 1998/10/16 23:36:36 curt
// c++-ifying.
//
// Revision 1.1 1998/10/16 19:30:40 curt
// Renamed .c -> .h so we can start adding c++ supporting routines.
//
// Revision 1.6 1998/07/08 14:40:07 curt
// polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
// Updated fg_geodesy comments to reflect that routines expect and produce
// meters.
//
// Revision 1.5 1998/04/25 22:06:23 curt
// Edited cvs log messages in source files ... bad bad bad!
//
// Revision 1.4 1998/01/27 00:47:59 curt
// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
// system and commandline/config file processing code.
//
// Revision 1.3 1998/01/19 19:27:12 curt
// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
// This should simplify things tremendously.
//
// Revision 1.2 1997/12/15 23:54:54 curt
// Add xgl wrappers for debugging.
// Generate terrain normals on the fly.
//
// Revision 1.1 1997/07/31 23:13:14 curt
// Initial revision.
//

222
Lib/Math/fg_geodesy.hxx Normal file
View file

@ -0,0 +1,222 @@
// fg_geodesy.hxx -- routines to convert between geodetic and geocentric
// coordinate systems.
//
// Copied and adapted directly from LaRCsim/ls_geodesy.c
//
// See below for the complete original LaRCsim comments.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _FG_GEODESY_HXX
#define _FG_GEODESY_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <Math/point3d.hxx>
#include <Math/polar3d.hxx>
// fgGeocToGeod(lat_geoc, radius, *lat_geod, *alt, *sea_level_r)
// INPUTS:
// lat_geoc Geocentric latitude, radians, + = North
// radius C.G. radius to earth center (meters)
//
// OUTPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
// sea_level_r radius from earth center to sea level at
// local vertical (surface normal) of C.G. (meters)
void fgGeocToGeod( double lat_geoc, double radius, double
*lat_geod, double *alt, double *sea_level_r );
// fgGeodToGeoc( lat_geod, alt, *sl_radius, *lat_geoc )
// INPUTS:
// lat_geod Geodetic latitude, radians, + = North
// alt C.G. altitude above mean sea level (meters)
//
// OUTPUTS:
// sl_radius SEA LEVEL radius to earth center (meters)
// (add Altitude to get true distance from earth center.
// lat_geoc Geocentric latitude, radians, + = North
//
void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
double *lat_geoc );
// convert a geodetic point lon(radians), lat(radians), elev(meter) to
// a cartesian point
inline Point3D fgGeodToCart(const Point3D& geod) {
double gc_lon, gc_lat, sl_radius;
// printf("A geodetic point is (%.2f, %.2f, %.2f)\n",
// geod[0], geod[1], geod[2]);
gc_lon = geod.lon();
fgGeodToGeoc(geod.lat(), geod.radius(), &sl_radius, &gc_lat);
// printf("A geocentric point is (%.2f, %.2f, %.2f)\n", gc_lon,
// gc_lat, sl_radius+geod[2]);
Point3D pp = Point3D( gc_lon, gc_lat, sl_radius + geod.radius());
return fgPolarToCart3d(pp);
}
/***************************************************************************
TITLE: ls_geodesy
----------------------------------------------------------------------------
FUNCTION: Converts geocentric coordinates to geodetic positions
----------------------------------------------------------------------------
MODULE STATUS: developmental
----------------------------------------------------------------------------
GENEALOGY: Written as part of LaRCSim project by E. B. Jackson
----------------------------------------------------------------------------
DESIGNED BY: E. B. Jackson
CODED BY: E. B. Jackson
MAINTAINED BY: E. B. Jackson
----------------------------------------------------------------------------
MODIFICATION HISTORY:
DATE PURPOSE BY
930208 Modified to avoid singularity near polar region. EBJ
930602 Moved backwards calcs here from ls_step. EBJ
931214 Changed erroneous Latitude and Altitude variables to
*lat_geod and *alt in routine ls_geoc_to_geod. EBJ
940111 Changed header files from old ls_eom.h style to ls_types,
and ls_constants. Also replaced old DATA type with new
SCALAR type. EBJ
CURRENT RCS HEADER:
$Header$
$Log$
Revision 1.4 1999/01/27 04:46:15 curt
Portability tweaks by Bernie Bright.
Revision 1.3 1998/10/18 01:17:11 curt
Point3D tweaks.
Revision 1.2 1998/10/16 23:36:37 curt
c++-ifying.
Revision 1.1 1998/10/16 19:30:42 curt
Renamed .c -> .h so we can start adding c++ supporting routines.
Revision 1.4 1998/07/08 14:40:08 curt
polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
Updated fg_geodesy comments to reflect that routines expect and produce
meters.
Revision 1.3 1998/04/21 17:03:48 curt
Prepairing for C++ integration.
Revision 1.2 1998/01/22 02:59:38 curt
Changed #ifdef FILE_H to #ifdef _FILE_H
Revision 1.1 1997/07/31 23:13:14 curt
Initial revision.
Revision 1.1 1997/05/29 00:09:56 curt
Initial Flight Gear revision.
* Revision 1.5 1994/01/11 18:47:05 bjax
* Changed include files to use types and constants, not ls_eom.h
* Also changed DATA type to SCALAR type.
*
* Revision 1.4 1993/12/14 21:06:47 bjax
* Removed global variable references Altitude and Latitude. EBJ
*
* Revision 1.3 1993/06/02 15:03:40 bjax
* Made new subroutine for calculating geodetic to geocentric; changed name
* of forward conversion routine from ls_geodesy to ls_geoc_to_geod.
*
----------------------------------------------------------------------------
REFERENCES:
[ 1] Stevens, Brian L.; and Lewis, Frank L.: "Aircraft
Control and Simulation", Wiley and Sons, 1992.
ISBN 0-471-61397-5
----------------------------------------------------------------------------
CALLED BY: ls_aux
----------------------------------------------------------------------------
CALLS TO:
----------------------------------------------------------------------------
INPUTS:
lat_geoc Geocentric latitude, radians, + = North
radius C.G. radius to earth center, ft
----------------------------------------------------------------------------
OUTPUTS:
lat_geod Geodetic latitude, radians, + = North
alt C.G. altitude above mean sea level, ft
sea_level_r radius from earth center to sea level at
local vertical (surface normal) of C.G.
--------------------------------------------------------------------------*/
#endif // _FG_GEODESY_HXX
// $Log$
// Revision 1.4 1999/01/27 04:46:15 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.3 1998/10/18 01:17:11 curt
// Point3D tweaks.
//
// Revision 1.2 1998/10/16 23:36:37 curt
// c++-ifying.
//
// Revision 1.1 1998/10/16 19:30:42 curt
// Renamed .c -> .h so we can start adding c++ supporting routines.
//
// Revision 1.4 1998/07/08 14:40:08 curt
// polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
// Updated fg_geodesy comments to reflect that routines expect and produce
// meters.
//
// Revision 1.3 1998/04/21 17:03:48 curt
// Prepairing for C++ integration.
//
// Revision 1.2 1998/01/22 02:59:38 curt
// Changed #ifdef FILE_H to #ifdef _FILE_H
//
// Revision 1.1 1997/07/31 23:13:14 curt
// Initial revision.
//

114
Lib/Math/fg_random.c Normal file
View file

@ -0,0 +1,114 @@
// fg_random.c -- routines to handle random number generation
//
// Written by Curtis Olson, started July 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h> // for random(), srandom()
#include <time.h> // for time() to seed srandom()
#include "fg_random.h"
#ifndef HAVE_RAND
# ifdef sgi
# undef RAND_MAX
# define RAND_MAX 2147483647
# endif
#endif
#ifdef __SUNPRO_CC
extern "C" {
long int random(void);
void srandom(unsigned int seed);
}
#endif
// Seed the random number generater with time() so we don't see the
// same sequence every time
void fg_srandom(void) {
// fgPrintf( FG_MATH, FG_INFO, "Seeding random number generater\n");
#ifdef HAVE_RAND
srand(time(NULL));
#else
srandom(time(NULL));
#endif
}
// return a random number between [0.0, 1.0)
double fg_random(void) {
#ifdef HAVE_RAND
return(rand() / (double)RAND_MAX);
#else
return(random() / (double)RAND_MAX);
#endif
}
// $Log$
// Revision 1.10 1998/11/07 19:07:03 curt
// Enable release builds using the --without-logging option to the configure
// script. Also a couple log message cleanups, plus some C to C++ comment
// conversion.
//
// Revision 1.9 1998/11/06 21:17:26 curt
// Converted to new logstream debugging facility. This allows release
// builds with no messages at all (and no performance impact) by using
// the -DFG_NDEBUG flag.
//
// Revision 1.8 1998/04/25 22:06:23 curt
// Edited cvs log messages in source files ... bad bad bad!
//
// Revision 1.7 1998/04/24 00:43:13 curt
// Wrapped "#include <config.h>" in "#ifdef HAVE_CONFIG_H"
//
// Revision 1.6 1998/04/18 03:53:42 curt
// Miscellaneous Tweaks.
//
// Revision 1.5 1998/04/03 22:10:29 curt
// Converting to Gnu autoconf system.
//
// Revision 1.4 1998/02/03 23:20:28 curt
// Lots of little tweaks to fix various consistency problems discovered by
// Solaris' CC. Fixed a bug in fg_debug.c with how the fgPrintf() wrapper
// passed arguments along to the real printf(). Also incorporated HUD changes
// by Michele America.
//
// Revision 1.3 1998/01/27 00:47:59 curt
// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
// system and commandline/config file processing code.
//
// Revision 1.2 1997/12/30 20:47:48 curt
// Integrated new event manager with subsystem initializations.
//
// Revision 1.1 1997/07/30 16:04:09 curt
// Moved random routines from Utils/ to Math/
//
// Revision 1.1 1997/07/19 22:31:57 curt
// Initial revision.
//

70
Lib/Math/fg_random.h Normal file
View file

@ -0,0 +1,70 @@
// fg_random.h -- routines to handle random number generation
//
// Written by Curtis Olson, started July 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _FG_RANDOM_H
#define _FG_RANDOM_H
#ifdef __cplusplus
extern "C" {
#endif
// Seed the random number generater with time() so we don't see the
// same sequence every time
void fg_srandom(void);
// return a random number between [0.0, 1.0)
double fg_random(void);
#ifdef __cplusplus
}
#endif
#endif // _FG_RANDOM_H
// $Log$
// Revision 1.4 1998/11/07 19:07:04 curt
// Enable release builds using the --without-logging option to the configure
// script. Also a couple log message cleanups, plus some C to C++ comment
// conversion.
//
// Revision 1.3 1998/04/21 17:03:48 curt
// Prepairing for C++ integration.
//
// Revision 1.2 1998/01/22 02:59:38 curt
// Changed #ifdef FILE_H to #ifdef _FILE_H
//
// Revision 1.1 1997/07/30 16:04:09 curt
// Moved random routines from Utils/ to Math/
//
// Revision 1.2 1997/07/23 21:52:28 curt
// Put comments around the text after an #endif for increased portability.
//
// Revision 1.1 1997/07/19 22:31:57 curt
// Initial revision.
//

131
Lib/Math/interpolater.cxx Normal file
View file

@ -0,0 +1,131 @@
//
// interpolater.cxx -- routines to handle linear interpolation from a table of
// x,y The table must be sorted by "x" in ascending order
//
// Written by Curtis Olson, started April 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#include <Include/compiler.h>
#include STL_STRING
#include <Debug/logstream.hxx>
#include <Include/fg_zlib.h>
#include <Misc/fgstream.hxx>
#include "interpolater.hxx"
// Constructor -- loads the interpolation table from the specified
// file
fgINTERPTABLE::fgINTERPTABLE( const string& file ) {
FG_LOG( FG_MATH, FG_INFO, "Initializing Interpolator for " << file );
fg_gzifstream in( file );
if ( !in ) {
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << file );
exit(-1);
}
size = 0;
in >> skipcomment;
while ( ! in.eof() ){
if ( size < MAX_TABLE_SIZE ) {
in >> table[size][0] >> table[size][1];
size++;
} else {
FG_LOG( FG_MATH, FG_ALERT,
"fgInterpolateInit(): Exceed max table size = "
<< MAX_TABLE_SIZE );
exit(-1);
}
}
}
// Given an x value, linearly interpolate the y value from the table
double fgINTERPTABLE::interpolate(double x) {
int i;
double y;
i = 0;
while ( (x > table[i][0]) && (i < size) ) {
i++;
}
// printf ("i = %d ", i);
if ( (i == 0) && (x < table[0][0]) ) {
FG_LOG( FG_MATH, FG_ALERT,
"fgInterpolateInit(): lookup error, x to small = " << x );
return(0.0);
}
if ( x > table[i][0] ) {
FG_LOG( FG_MATH, FG_ALERT,
"fgInterpolateInit(): lookup error, x to big = " << x );
return(0.0);
}
// y = y1 + (y0 - y1)(x - x1) / (x0 - x1)
y = table[i][1] +
( (table[i-1][1] - table[i][1]) *
(x - table[i][0]) ) /
(table[i-1][0] - table[i][0]);
return(y);
}
// Destructor
fgINTERPTABLE::~fgINTERPTABLE( void ) {
}
// $Log$
// Revision 1.7 1999/02/26 22:08:03 curt
// Added initial support for native SGI compilers.
//
// Revision 1.6 1999/01/27 04:46:16 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.5 1998/11/06 21:17:27 curt
// Converted to new logstream debugging facility. This allows release
// builds with no messages at all (and no performance impact) by using
// the -DFG_NDEBUG flag.
//
// Revision 1.4 1998/05/13 18:24:25 curt
// Wrapped zlib calls so zlib can be optionally disabled.
//
// Revision 1.3 1998/04/25 15:05:01 curt
// Changed "r" to "rb" in gzopen() options. This fixes bad behavior in win32.
//
// Revision 1.2 1998/04/22 13:18:10 curt
// C++ - ified comments. Make file open errors fatal.
//
// Revision 1.1 1998/04/21 19:14:23 curt
// Modified Files:
// Makefile.am Makefile.in
// Added Files:
// interpolater.cxx interpolater.hxx
//

87
Lib/Math/interpolater.hxx Normal file
View file

@ -0,0 +1,87 @@
//
// interpolater.hxx -- routines to handle linear interpolation from a table of
// x,y The table must be sorted by "x" in ascending order
//
// Written by Curtis Olson, started April 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _INTERPOLATER_H
#define _INTERPOLATER_H
#ifndef __cplusplus
# error This library requires C++
#endif
#include "Include/compiler.h"
#include STL_STRING
FG_USING_STD(string);
#define MAX_TABLE_SIZE 32
class fgINTERPTABLE {
int size;
double table[MAX_TABLE_SIZE][2];
public:
// Constructor -- loads the interpolation table from the specified
// file
fgINTERPTABLE( const string& file );
// Given an x value, linearly interpolate the y value from the table
double interpolate(double x);
// Destructor
~fgINTERPTABLE( void );
};
#endif // _INTERPOLATER_H
// $Log$
// Revision 1.6 1999/03/02 01:01:50 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.5 1999/02/26 22:08:05 curt
// Added initial support for native SGI compilers.
//
// Revision 1.4 1999/01/27 04:46:17 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.3 1998/11/06 21:17:28 curt
// Converted to new logstream debugging facility. This allows release
// builds with no messages at all (and no performance impact) by using
// the -DFG_NDEBUG flag.
//
// Revision 1.2 1998/04/22 13:18:10 curt
// C++ - ified comments. Make file open errors fatal.
//
// Revision 1.1 1998/04/21 19:14:23 curt
// Modified Files:
// Makefile.am Makefile.in
// Added Files:
// interpolater.cxx interpolater.hxx
//

152
Lib/Math/leastsqs.cxx Normal file
View file

@ -0,0 +1,152 @@
// leastsqs.c -- Implements a simple linear least squares best fit routine
//
// Written by Curtis Olson, started September 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
//
#include <stdio.h>
#include "leastsqs.hxx"
/*
Least squares fit:
y = b0 + b1x
n*sum(xi*yi) - (sum(xi)*sum(yi))
b1 = --------------------------------
n*sum(xi^2) - (sum(xi))^2
b0 = sum(yi)/n - b1*(sum(xi)/n)
*/
double sum_xi, sum_yi, sum_xi_2, sum_xi_yi;
int sum_n;
void least_squares(double *x, double *y, int n, double *m, double *b) {
int i;
sum_xi = sum_yi = sum_xi_2 = sum_xi_yi = 0.0;
sum_n = n;
for ( i = 0; i < n; i++ ) {
sum_xi += x[i];
sum_yi += y[i];
sum_xi_2 += x[i] * x[i];
sum_xi_yi += x[i] * y[i];
}
/* printf("sum(xi)=%.2f sum(yi)=%.2f sum(xi^2)=%.2f sum(xi*yi)=%.2f\n",
sum_xi, sum_yi, sum_xi_2, sum_xi_yi); */
*m = ( (double)sum_n * sum_xi_yi - sum_xi * sum_yi ) /
( (double)sum_n * sum_xi_2 - sum_xi * sum_xi );
*b = (sum_yi / (double)sum_n) - (*m) * (sum_xi / (double)sum_n);
/* printf("slope = %.2f intercept = %.2f\n", *m, *b); */
}
/* incrimentally update existing values with a new data point */
void least_squares_update(double x, double y, double *m, double *b) {
++sum_n;
sum_xi += x;
sum_yi += y;
sum_xi_2 += x * x;
sum_xi_yi += x * y;
/* printf("sum(xi)=%.2f sum(yi)=%.2f sum(xi^2)=%.2f sum(xi*yi)=%.2f\n",
sum_xi, sum_yi, sum_xi_2, sum_xi_yi); */
*m = ( (double)sum_n * sum_xi_yi - sum_xi * sum_yi ) /
( (double)sum_n * sum_xi_2 - sum_xi * sum_xi );
*b = (sum_yi / (double)sum_n) - (*m) * (sum_xi / (double)sum_n);
/* printf("slope = %.2f intercept = %.2f\n", *m, *b); */
}
/*
return the least squares error:
(y[i] - y_hat[i])^2
-------------------
n
*/
double least_squares_error(double *x, double *y, int n, double m, double b) {
int i;
double error, sum;
sum = 0.0;
for ( i = 0; i < n; i++ ) {
error = y[i] - (m * x[i] + b);
sum += error * error;
// printf("%.2f %.2f\n", error, sum);
}
return ( sum / (double)n );
}
/*
return the maximum least squares error:
(y[i] - y_hat[i])^2
*/
double least_squares_max_error(double *x, double *y, int n, double m, double b){
int i;
double error, max_error;
max_error = 0.0;
for ( i = 0; i < n; i++ ) {
error = y[i] - (m * x[i] + b);
error = error * error;
if ( error > max_error ) {
max_error = error;
}
}
return ( max_error );
}
// $Log$
// Revision 1.1 1999/03/13 17:34:45 curt
// Moved to math subdirectory.
//
// Revision 1.2 1998/04/21 17:03:41 curt
// Prepairing for C++ integration.
//
// Revision 1.1 1998/04/08 22:57:24 curt
// Adopted Gnu automake/autoconf system.
//
// Revision 1.1 1998/03/19 02:54:47 curt
// Reorganized into a class lib called fgDEM.
//
// Revision 1.1 1997/10/13 17:02:35 curt
// Initial revision.
//

90
Lib/Math/leastsqs.hxx Normal file
View file

@ -0,0 +1,90 @@
// leastsqs.h -- Implements a simple linear least squares best fit routine
//
// Written by Curtis Olson, started September 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
///
#ifndef _LEASTSQS_H
#define _LEASTSQS_H
#ifndef __cplusplus
# error This library requires C++
#endif
/*
Least squares fit:
y = b0 + b1x
n*sum(xi*yi) - (sum(xi)*sum(yi))
b1 = --------------------------------
n*sum(xi^2) - (sum(xi))^2
b0 = sum(yi)/n - b1*(sum(xi)/n)
*/
void least_squares(double *x, double *y, int n, double *m, double *b);
/* incrimentally update existing values with a new data point */
void least_squares_update(double x, double y, double *m, double *b);
/*
return the least squares error:
(y[i] - y_hat[i])^2
-------------------
n
*/
double least_squares_error(double *x, double *y, int n, double m, double b);
/*
return the maximum least squares error:
(y[i] - y_hat[i])^2
*/
double least_squares_max_error(double *x, double *y, int n, double m, double b);
#endif // _LEASTSQS_H
// $Log$
// Revision 1.1 1999/03/13 17:34:45 curt
// Moved to math subdirectory.
//
// Revision 1.2 1998/04/21 17:03:42 curt
// Prepairing for C++ integration.
//
// Revision 1.1 1998/04/08 22:57:25 curt
// Adopted Gnu automake/autoconf system.
//
// Revision 1.1 1998/03/19 02:54:48 curt
// Reorganized into a class lib called fgDEM.
//
// Revision 1.1 1997/10/13 17:02:35 curt
// Initial revision.
//

208
Lib/Math/mat3.h Normal file
View file

@ -0,0 +1,208 @@
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
/* -------------------------------------------------------------------------
Public MAT3 include file
------------------------------------------------------------------------- */
#ifndef MAT3_HAS_BEEN_INCLUDED
#define MAT3_HAS_BEEN_INCLUDED
/* ----------------------------- Constants ------------------------------ */
/*
* Make sure the math library .h file is included, in case it wasn't.
*/
#ifndef HUGE
#include <math.h>
#endif
#include <stdio.h>
#include <string.h>
#include "Include/fg_memory.h"
#ifdef __cplusplus
extern "C" {
#endif
#define MAT3_DET0 -1 /* Indicates singular mat */
#define MAT3_EPSILON 1e-12 /* Close enough to zero */
#ifdef M_PI
# define MAT3_PI M_PI
#else
# define MAT3_PI 3.14159265358979323846
#endif
#define USE_XTRA_MAT3_INLINES
/* ------------------------------ Types --------------------------------- */
typedef double MAT3mat[4][4]; /* 4x4 matrix */
typedef double MAT3vec[3]; /* Vector */
typedef double MAT3hvec[4]; /* Vector with homogeneous coord */
/* ------------------------------ Macros -------------------------------- */
extern MAT3mat identityMatrix;
/* Tests if a number is within EPSILON of zero */
#define MAT3_IS_ZERO(N) ((N) < MAT3_EPSILON && (N) > -MAT3_EPSILON)
/* Sets a vector to the three given values */
#define MAT3_SET_VEC(V,X,Y,Z) ((V)[0]=(X), (V)[1]=(Y), (V)[2]=(Z))
/* Tests a vector for all components close to zero */
#define MAT3_IS_ZERO_VEC(V) (MAT3_IS_ZERO((V)[0]) && \
MAT3_IS_ZERO((V)[1]) && \
MAT3_IS_ZERO((V)[2]))
/* Dot product of two vectors */
#define MAT3_DOT_PRODUCT(V1,V2) \
((V1)[0]*(V2)[0] + (V1)[1]*(V2)[1] + (V1)[2]*(V2)[2])
/* Copy one vector to other */
#define MAT3_COPY_VEC(TO,FROM) ((TO)[0] = (FROM)[0], \
(TO)[1] = (FROM)[1], \
(TO)[2] = (FROM)[2])
/* Normalize vector to unit length, using TEMP as temporary variable.
* TEMP will be zero if vector has zero length */
#define MAT3_NORMALIZE_VEC(V,TEMP) \
if ((TEMP = sqrt(MAT3_DOT_PRODUCT(V,V))) > MAT3_EPSILON) { \
TEMP = 1.0 / TEMP; \
MAT3_SCALE_VEC(V,V,TEMP); \
} else TEMP = 0.0
/* Scale vector by given factor, storing result vector in RESULT_V */
#define MAT3_SCALE_VEC(RESULT_V,V,SCALE) \
MAT3_SET_VEC(RESULT_V, (V)[0]*(SCALE), (V)[1]*(SCALE), (V)[2]*(SCALE))
/* Adds vectors V1 and V2, storing result in RESULT_V */
#define MAT3_ADD_VEC(RESULT_V,V1,V2) \
MAT3_SET_VEC(RESULT_V, (V1)[0]+(V2)[0], (V1)[1]+(V2)[1], \
(V1)[2]+(V2)[2])
/* Subtracts vector V2 from V1, storing result in RESULT_V */
#define MAT3_SUB_VEC(RESULT_V,V1,V2) \
MAT3_SET_VEC(RESULT_V, (V1)[0]-(V2)[0], (V1)[1]-(V2)[1], \
(V1)[2]-(V2)[2])
/* Multiplies vectors V1 and V2, storing result in RESULT_V */
#define MAT3_MULT_VEC(RESULT_V,V1,V2) \
MAT3_SET_VEC(RESULT_V, (V1)[0]*(V2)[0], (V1)[1]*(V2)[1], \
(V1)[2]*(V2)[2])
/* Sets RESULT_V to the linear combination of V1 and V2, scaled by
* SCALE1 and SCALE2, respectively */
#define MAT3_LINEAR_COMB(RESULT_V,SCALE1,V1,SCALE2,V2) \
MAT3_SET_VEC(RESULT_V, (SCALE1)*(V1)[0] + (SCALE2)*(V2)[0], \
(SCALE1)*(V1)[1] + (SCALE2)*(V2)[1], \
(SCALE1)*(V1)[2] + (SCALE2)*(V2)[2])
/* Several of the vector macros are useful for homogeneous-coord vectors */
#define MAT3_SET_HVEC(V,X,Y,Z,W) ((V)[0]=(X), (V)[1]=(Y), \
(V)[2]=(Z), (V)[3]=(W))
#define MAT3_COPY_HVEC(TO,FROM) ((TO)[0] = (FROM)[0], \
(TO)[1] = (FROM)[1], \
(TO)[2] = (FROM)[2], \
(TO)[3] = (FROM)[3])
#define MAT3_SCALE_HVEC(RESULT_V,V,SCALE) \
MAT3_SET_HVEC(RESULT_V, (V)[0]*(SCALE), (V)[1]*(SCALE), \
(V)[2]*(SCALE), (V)[3]*(SCALE))
#define MAT3_ADD_HVEC(RESULT_V,V1,V2) \
MAT3_SET_HVEC(RESULT_V, (V1)[0]+(V2)[0], (V1)[1]+(V2)[1], \
(V1)[2]+(V2)[2], (V1)[3]+(V2)[3])
#define MAT3_SUB_HVEC(RESULT_V,V1,V2) \
MAT3_SET_HVEC(RESULT_V, (V1)[0]-(V2)[0], (V1)[1]-(V2)[1], \
(V1)[2]-(V2)[2], (V1)[3]-(V2)[3])
#define MAT3_MULT_HVEC(RESULT_V,V1,V2) \
MAT3_SET_HVEC(RESULT_V, (V1)[0]*(V2)[0], (V1)[1]*(V2)[1], \
(V1)[2]*(V2)[2], (V1)[3]*(V2)[3])
/* ------------------------------ Entries ------------------------------- */
#define MAT3identity(mat) fgmemcpy( mat, identityMatrix, sizeof(MAT3mat) )
#define MAT3zero(mat) fgmemzero( mat, sizeof(MAT3mat) )
#define MAT3copy(to, from) fgmemcpy( to, from, sizeof(MAT3mat) )
#if defined( USE_XTRA_MAT3_INLINES )
# define MAT3mult_vec( result_vec, vec, mat) { \
MAT3vec tempvec; \
tempvec[0]=vec[0]*mat[0][0]+vec[1]*mat[1][0]+vec[2]*mat[2][0]+mat[3][0]; \
tempvec[1]=vec[0]*mat[0][1]+vec[1]*mat[1][1]+vec[2]*mat[2][1]+mat[3][1]; \
tempvec[2]=vec[0]*mat[0][2]+vec[1]*mat[1][2]+vec[2]*mat[2][2]+mat[3][2]; \
result_vec[0] = tempvec[0]; \
result_vec[1] = tempvec[1]; \
result_vec[2] = tempvec[2]; \
}
# define MAT3cross_product(result_vec, vec1, vec2) { \
MAT3vec tempvec; \
tempvec[0] = vec1[1] * vec2[2] - vec1[2] * vec2[1]; \
tempvec[1] = vec1[2] * vec2[0] - vec1[0] * vec2[2]; \
tempvec[2] = vec1[0] * vec2[1] - vec1[1] * vec2[0]; \
result_vec[0] = tempvec[0]; \
result_vec[1] = tempvec[1]; \
result_vec[2] = tempvec[2]; \
}
# define MAT3mult( result_mat, mat1, mat2) { \
register int i, j; \
MAT3mat tmp_mat; \
for (i = 0; i < 4; i++) \
for (j = 0; j < 4; j++) \
tmp_mat[i][j] = (mat1[i][0] * mat2[0][j] + \
mat1[i][1] * mat2[1][j] + \
mat1[i][2] * mat2[2][j] + \
mat1[i][3] * mat2[3][j]); \
fgmemcpy(result_mat, tmp_mat, sizeof(MAT3mat)); \
}
#else // !defined( USE_XTRA_MAT3_INLINES )
/* In MAT3mat.c */
void MAT3mult(MAT3mat result, MAT3mat, MAT3mat);
void MAT3mult_vec(MAT3vec result_vec, MAT3vec vec, MAT3mat mat);
void MAT3cross_product(MAT3vec result,MAT3vec,MAT3vec);
#endif // defined( USE_XTRA_MAT3_INLINES )
/* In MAT3geom.c */
void MAT3direction_matrix (MAT3mat result_mat, MAT3mat mat);
int MAT3normal_matrix (MAT3mat result_mat, MAT3mat mat);
void MAT3rotate (MAT3mat result_mat, MAT3vec axis, double angle_in_radians);
void MAT3translate (MAT3mat result_mat, MAT3vec trans);
void MAT3scale (MAT3mat result_mat, MAT3vec scale);
void MAT3shear(MAT3mat result_mat, double xshear, double yshear);
void MAT3transpose (MAT3mat result, MAT3mat);
int MAT3invert (MAT3mat result, MAT3mat);
void MAT3print (MAT3mat, FILE *fp);
void MAT3print_formatted (MAT3mat, FILE *fp,
char *title, char *head, char *format, char *tail);
int MAT3equal( void );
double MAT3trace( void );
int MAT3power( void );
int MAT3column_reduce( void );
int MAT3kernel_basis( void );
/* In MAT3vec.c */
int MAT3mult_hvec (MAT3hvec result_vec, MAT3hvec vec, MAT3mat mat, int normalize);
void MAT3perp_vec(MAT3vec result_vec, MAT3vec vec, int is_unit);
#ifdef __cplusplus
}
#endif
#endif /* MAT3_HAS_BEEN_INCLUDED */

56
Lib/Math/mat3defs.h Normal file
View file

@ -0,0 +1,56 @@
/* Copyright 1988, Brown Computer Graphics Group. All Rights Reserved. */
#ifndef _MAT3DEFS_H
#define _MAT3DEFS_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
/* #include <Math/mat3err.h> */
#include <Math/mat3.h>
/* ----------------------------- Constants ------------------------------ */
#define FALSE 0
#define TRUE 1
#define CNULL ((char *) NULL)
/* ------------------------------ Macros -------------------------------- */
#define ALLOCN(P,T,N,M) \
if ((P = (T *) malloc((unsigned) (N) * sizeof(T))) == NULL) \
ERR_ERROR(MAT3_errid, ERR_FATAL, (ERR_ALLOC1, M)); \
else
#define FREE(P) free((char *) (P))
#define ABS(A) ((A) > 0 ? (A) : -(A))
#define MIN(A,B) ((A) < (B) ? (A) : (B))
#define MAX(A,B) ((A) > (B) ? (A) : (B))
#define SWAP(A,B,T) (T = A, A = B, B = T)
/* Is N within EPS of zero ? */
#define IS_ZERO(N,EPS) ((N) < EPS && (N) > -EPS)
/* Macros for lu routines */
#define LU_PERMUTE(p,i,j) { int LU_T; LU_T = p[i]; p[i] = p[j]; p[j] = LU_T; }
/* ------------------------- Internal Entries ---------------------------- */
/* ------------------------- Global Variables ---------------------------- */
/* extern ERRid *MAT3_errid; */
#ifdef __cplusplus
}
#endif
#endif /* _MAT3DEFS_H */

41
Lib/Math/mat3err.h Normal file
View file

@ -0,0 +1,41 @@
#ifndef _MAT3ERR_H
#define _MAT3ERR_H
#ifdef __cplusplus
extern "C" {
#endif
#include "sph_errtypes.h"
#ifdef THINK_C
/* We hide this from gnu's compiler, which doesn't understand it. */
void SPH__error (int errtype, ...);
#endif
#define ERR_ERROR(A,B,C) \
if (1) {char cstr[256]; sprintf C; SPH__error(ERR_MAT3_PACKAGE, cstr); } else
#define ERR_S cstr,"%s\n"
#define ERR_SI cstr,"%s: %d\n"
#define ERR_SS cstr,"%s: %s\n"
#define ERR_SEVERE 0
#define ERR_FATAL 0
#define ERR_ALLOC1 0
typedef int ERRid;
#define ERRregister_package(S) 100
#ifdef __cplusplus
}
#endif
#endif /* _MAT3ERR_H */

371
Lib/Math/point3d.hxx Normal file
View file

@ -0,0 +1,371 @@
// point3d.hxx -- a 3d point class.
//
// Adapted from algebra3 by Jean-Francois Doue, started October 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _POINT3D_HXX
#define _POINT3D_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include "Include/compiler.h"
#ifdef FG_MATH_EXCEPTION_CLASH
# define exception c_exception
#endif
#ifdef FG_HAVE_STD_INCLUDES
# include <iostream>
# include <cassert>
# include <cmath>
#else
# include <iostream.h>
# include <assert.h>
# include <math.h>
#endif
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
FG_USING_STD(ostream);
FG_USING_STD(istream);
#endif
// -rp- assert.h is buggy under MWCWP3, as multiple #include undef assert !
#ifdef __MWERKS__
# define assert(x)
#endif
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& );
Point3D operator- (const Point3D& p); // -p1
bool operator== (const Point3D& a, const Point3D& b); // p1 == p2?
///////////////////////////
//
// 3D Point
//
///////////////////////////
class Point3D {
protected:
double n[3];
public:
// Constructors
Point3D();
Point3D(const double x, const double y, const double z);
explicit Point3D(const double d);
Point3D(const Point3D &p);
// Assignment operators
Point3D& operator = ( const Point3D& p ); // assignment of a Point3D
Point3D& operator += ( const Point3D& p ); // incrementation by a Point3D
Point3D& operator -= ( const Point3D& p ); // decrementation by a Point3D
Point3D& operator *= ( const double d ); // multiplication by a constant
Point3D& operator /= ( const double d ); // division by a constant
void setx(const double x);
void sety(const double y);
void setz(const double z);
// Queries
double& operator [] ( int i); // indexing
double operator[] (int i) const; // read-only indexing
double x() const; // cartesian x
double y() const; // cartesian y
double z() const; // cartesian z
double lon() const; // polar longitude
double lat() const; // polar latitude
double radius() const; // polar radius
double elev() const; // geodetic elevation (if specifying a surface point)
// 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& );
// Special functions
double distance3D(const Point3D& a) const; // distance between
double distance3Dsquared(const Point3D& a) const; // distance between ^ 2
};
// input from stream
inline istream&
operator >> ( istream& in, Point3D& p)
{
char c;
in >> p.n[PX];
// read past optional comma
while ( in.get(c) ) {
if ( (c != ' ') && (c != ',') ) {
// push back on the stream
in.putback(c);
break;
}
}
in >> p.n[PY];
// read past optional comma
while ( in.get(c) ) {
if ( (c != ' ') && (c != ',') ) {
// push back on the stream
in.putback(c);
break;
}
}
in >> p.n[PZ];
return in;
}
inline ostream&
operator<< ( ostream& out, const Point3D& p )
{
return out << p.n[PX] << ", " << p.n[PY] << ", " << p.n[PZ];
}
///////////////////////////
//
// Point3D Member functions
//
///////////////////////////
// CONSTRUCTORS
inline Point3D::Point3D() {}
inline Point3D::Point3D(const double x, const double y, const double z)
{
n[PX] = x; n[PY] = y; n[PZ] = z;
}
inline Point3D::Point3D(const double d)
{
n[PX] = n[PY] = n[PZ] = d;
}
inline Point3D::Point3D(const Point3D& p)
{
n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ];
}
// ASSIGNMENT OPERATORS
inline Point3D& Point3D::operator = (const Point3D& p)
{
n[PX] = p.n[PX]; n[PY] = p.n[PY]; n[PZ] = p.n[PZ]; return *this;
}
inline Point3D& Point3D::operator += ( const Point3D& p )
{
n[PX] += p.n[PX]; n[PY] += p.n[PY]; n[PZ] += p.n[PZ]; return *this;
}
inline Point3D& Point3D::operator -= ( const Point3D& p )
{
n[PX] -= p.n[PX]; n[PY] -= p.n[PY]; n[PZ] -= p.n[PZ]; return *this;
}
inline Point3D& Point3D::operator *= ( const double d )
{
n[PX] *= d; n[PY] *= d; n[PZ] *= d; return *this;
}
inline Point3D& Point3D::operator /= ( const double d )
{
double d_inv = 1./d; n[PX] *= d_inv; n[PY] *= d_inv; n[PZ] *= d_inv;
return *this;
}
inline void Point3D::setx(const double x) {
n[PX] = x;
}
inline void Point3D::sety(const double y) {
n[PY] = y;
}
inline void Point3D::setz(const double z) {
n[PZ] = z;
}
// QUERIES
inline double& Point3D::operator [] ( int i)
{
assert(! (i < PX || i > PZ));
return n[i];
}
inline double Point3D::operator [] ( int i) const {
assert(! (i < PX || i > PZ));
return n[i];
}
inline double Point3D::x() const { return n[PX]; }
inline double Point3D::y() const { return n[PY]; }
inline double Point3D::z() const { return n[PZ]; }
inline double Point3D::lon() const { return n[PX]; }
inline double Point3D::lat() const { return n[PY]; }
inline double Point3D::radius() const { return n[PZ]; }
inline double Point3D::elev() const { return n[PZ]; }
// FRIENDS
inline Point3D operator - (const Point3D& a)
{
return Point3D(-a.n[PX],-a.n[PY],-a.n[PZ]);
}
inline Point3D operator + (const Point3D& a, const Point3D& b)
{
return Point3D(a) += b;
}
inline Point3D operator - (const Point3D& a, const Point3D& b)
{
return Point3D(a) -= b;
}
inline Point3D operator * (const Point3D& a, const double d)
{
return Point3D(a) *= d;
}
inline Point3D operator * (const double d, const Point3D& a)
{
return a*d;
}
inline Point3D operator / (const Point3D& a, const double d)
{
return Point3D(a) *= (1.0 / d );
}
inline bool operator == (const Point3D& a, const Point3D& b)
{
return
(a.n[PX] - b.n[PX]) < fgPoint3_Epsilon &&
(a.n[PY] - b.n[PY]) < fgPoint3_Epsilon &&
(a.n[PZ] - b.n[PZ]) < fgPoint3_Epsilon;
}
inline bool operator != (const Point3D& a, const Point3D& b)
{
return !(a == b);
}
// Special functions
inline double
Point3D::distance3D(const Point3D& a ) const
{
double x, y, z;
x = n[PX] - a.n[PX];
y = n[PY] - a.n[PY];
z = n[PZ] - a.n[PZ];
return sqrt(x*x + y*y + z*z);
}
inline double
Point3D::distance3Dsquared(const Point3D& a ) const
{
double x, y, z;
x = n[PX] - a.n[PX];
y = n[PY] - a.n[PY];
z = n[PZ] - a.n[PZ];
return(x*x + y*y + z*z);
}
#endif // _POINT3D_HXX
// $Log$
// Revision 1.10 1999/03/02 01:01:52 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.9 1999/02/01 21:08:28 curt
// Optimizations from Norman Vine.
//
// Revision 1.8 1999/01/27 04:46:18 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.7 1999/01/19 20:56:58 curt
// MacOS portability changes contributed by "Robert Puyol" <puyol@abvent.fr>
//
// Revision 1.6 1998/11/23 21:46:37 curt
// Borland portability tweaks.
//
// Revision 1.5 1998/11/20 01:00:38 curt
// Patch in fgGeoc2Geod() to avoid a floating explosion.
// point3d.hxx include math.h for FreeBSD
//
// Revision 1.4 1998/11/11 00:18:38 curt
// Check for domain error in fgGeoctoGeod()
//
// Revision 1.3 1998/10/20 18:21:49 curt
// Tweaks from Bernie Bright.
//
// Revision 1.2 1998/10/18 01:17:12 curt
// Point3D tweaks.
//
// Revision 1.1 1998/10/16 00:50:29 curt
// Added point3d.hxx to replace cheezy fgPoint3d struct.
//
//

110
Lib/Math/polar3d.cxx Normal file
View file

@ -0,0 +1,110 @@
// polar.cxx -- routines to deal with polar math and transformations
//
// Written by Curtis Olson, started June 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#include <math.h>
#include <stdio.h>
#include <Include/fg_constants.h>
#include "polar3d.hxx"
// Find the Altitude above the Ellipsoid (WGS84) given the Earth
// Centered Cartesian coordinate vector Distances are specified in
// meters.
double fgGeodAltFromCart(const Point3D& cp)
{
double t_lat, x_alpha, mu_alpha;
double lat_geoc, radius;
double result;
lat_geoc = FG_PI_2 - atan2( sqrt(cp.x()*cp.x() + cp.y()*cp.y()), cp.z() );
radius = sqrt( cp.x()*cp.x() + cp.y()*cp.y() + cp.z()*cp.z() );
if( ( (FG_PI_2 - lat_geoc) < ONE_SECOND ) // near North pole
|| ( (FG_PI_2 + lat_geoc) < ONE_SECOND ) ) // near South pole
{
result = radius - EQUATORIAL_RADIUS_M*E;
} else {
t_lat = tan(lat_geoc);
x_alpha = E*EQUATORIAL_RADIUS_M/sqrt(t_lat*t_lat + E*E);
mu_alpha = atan2(sqrt(RESQ_M - x_alpha*x_alpha),E*x_alpha);
if (lat_geoc < 0) {
mu_alpha = - mu_alpha;
}
result = (radius - x_alpha/cos(lat_geoc))*cos(mu_alpha - lat_geoc);
}
return(result);
}
// $Log$
// Revision 1.6 1999/01/27 04:46:19 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.5 1998/10/18 01:17:13 curt
// Point3D tweaks.
//
// Revision 1.4 1998/10/16 19:30:09 curt
// C++-ified the comments.
//
// Revision 1.3 1998/10/16 00:50:29 curt
// Added point3d.hxx to replace cheezy fgPoint3d struct.
//
// Revision 1.2 1998/08/24 20:04:11 curt
// Various "inline" code optimizations contributed by Norman Vine.
//
// Revision 1.1 1998/07/08 14:40:08 curt
// polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
// Updated fg_geodesy comments to reflect that routines expect and produce
// meters.
//
// Revision 1.2 1998/05/03 00:45:49 curt
// Commented out a debugging printf.
//
// Revision 1.1 1998/05/02 01:50:11 curt
// polar.[ch] renamed to polar3d.[ch]
//
// Revision 1.6 1998/04/25 22:06:23 curt
// Edited cvs log messages in source files ... bad bad bad!
//
// Revision 1.5 1998/01/27 00:48:00 curt
// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
// system and commandline/config file processing code.
//
// Revision 1.4 1998/01/19 19:27:12 curt
// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
// This should simplify things tremendously.
//
// Revision 1.3 1997/12/15 23:54:54 curt
// Add xgl wrappers for debugging.
// Generate terrain normals on the fly.
//
// Revision 1.2 1997/07/31 22:52:27 curt
// Working on redoing internal coordinate systems & scenery transformations.
//
// Revision 1.1 1997/07/07 21:02:36 curt
// Initial revision.

120
Lib/Math/polar3d.hxx Normal file
View file

@ -0,0 +1,120 @@
// polar.hxx -- routines to deal with polar math and transformations
//
// Written by Curtis Olson, started June 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _POLAR_HXX
#define _POLAR_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <Include/fg_constants.h>
#include <Math/point3d.hxx>
// Find the Altitude above the Ellipsoid (WGS84) given the Earth
// Centered Cartesian coordinate vector Distances are specified in
// meters.
double fgGeodAltFromCart(const Point3D& cp);
// Convert a polar coordinate to a cartesian coordinate. Lon and Lat
// must be specified in radians. The FG convention is for distances
// to be specified in meters
inline Point3D fgPolarToCart3d(const Point3D& p) {
double tmp = cos( p.lat() ) * p.radius();
return Point3D( cos( p.lon() ) * tmp,
sin( p.lon() ) * tmp,
sin( p.lat() ) * p.radius() );
}
// Convert a cartesian coordinate to polar coordinates (lon/lat
// specified in radians. Distances are specified in meters.
inline Point3D fgCartToPolar3d(const Point3D& cp) {
return Point3D( atan2( cp.y(), cp.x() ),
FG_PI_2 -
atan2( sqrt(cp.x()*cp.x() + cp.y()*cp.y()), cp.z() ),
sqrt(cp.x()*cp.x() + cp.y()*cp.y() + cp.z()*cp.z()) );
}
#endif // _POLAR_HXX
// $Log$
// Revision 1.5 1999/01/27 04:46:20 curt
// Portability tweaks by Bernie Bright.
//
// Revision 1.4 1998/10/16 19:30:07 curt
// C++-ified the comments.
//
// Revision 1.3 1998/10/16 00:50:30 curt
// Added point3d.hxx to replace cheezy fgPoint3d struct.
//
// Revision 1.2 1998/08/24 20:04:12 curt
// Various "inline" code optimizations contributed by Norman Vine.
//
// Revision 1.1 1998/07/08 14:40:09 curt
// polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
// Updated fg_geodesy comments to reflect that routines expect and produce
// meters.
//
// Revision 1.1 1998/05/02 01:50:11 curt
// polar.[ch] renamed to polar3d.[ch]
//
// Revision 1.9 1998/04/25 22:06:23 curt
// Edited cvs log messages in source files ... bad bad bad!
//
// Revision 1.8 1998/04/21 17:03:50 curt
// Prepairing for C++ integration.
//
// Revision 1.7 1998/01/27 00:48:00 curt
// Incorporated Paul Bleisch's <pbleisch@acm.org> new debug message
// system and commandline/config file processing code.
//
// Revision 1.6 1998/01/22 02:59:39 curt
// Changed #ifdef FILE_H to #ifdef _FILE_H
//
// Revision 1.5 1998/01/19 19:27:13 curt
// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
// This should simplify things tremendously.
//
// Revision 1.4 1997/12/15 23:54:55 curt
// Add xgl wrappers for debugging.
// Generate terrain normals on the fly.
//
// Revision 1.3 1997/07/31 22:52:28 curt
// Working on redoing internal coordinate systems & scenery transformations.
//
// Revision 1.2 1997/07/23 21:52:21 curt
// Put comments around the text after an #endif for increased portability.
//
// Revision 1.1 1997/07/07 21:02:37 curt
// Initial revision.
//

162
Lib/Math/vector.cxx Normal file
View file

@ -0,0 +1,162 @@
// vector.cxx -- additional vector routines
//
// Written by Curtis Olson, started December 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#include <math.h>
#include <stdio.h>
// #include <Include/fg_types.h>
#include "vector.hxx"
#include "mat3.h"
#if !defined( USE_XTRA_MAT3_INLINES )
// Map a vector onto the plane specified by normal
void map_vec_onto_cur_surface_plane(MAT3vec normal, MAT3vec v0, MAT3vec vec,
MAT3vec result)
{
MAT3vec u1, v, tmp;
// calculate a vector "u1" representing the shortest distance from
// the plane specified by normal and v0 to a point specified by
// "vec". "u1" represents both the direction and magnitude of
// this desired distance.
// u1 = ( (normal <dot> vec) / (normal <dot> normal) ) * normal
MAT3_SCALE_VEC( u1,
normal,
( MAT3_DOT_PRODUCT(normal, vec) /
MAT3_DOT_PRODUCT(normal, normal)
)
);
// printf(" vec = %.2f, %.2f, %.2f\n", vec[0], vec[1], vec[2]);
// printf(" v0 = %.2f, %.2f, %.2f\n", v0[0], v0[1], v0[2]);
// printf(" u1 = %.2f, %.2f, %.2f\n", u1[0], u1[1], u1[2]);
// calculate the vector "v" which is the vector "vec" mapped onto
// the plane specified by "normal" and "v0".
// v = v0 + vec - u1
MAT3_ADD_VEC(tmp, v0, vec);
MAT3_SUB_VEC(v, tmp, u1);
// printf(" v = %.2f, %.2f, %.2f\n", v[0], v[1], v[2]);
// Calculate the vector "result" which is "v" - "v0" which is a
// directional vector pointing from v0 towards v
// result = v - v0
MAT3_SUB_VEC(result, v, v0);
// printf(" result = %.2f, %.2f, %.2f\n",
// result[0], result[1], result[2]);
}
#endif // !defined( USE_XTRA_MAT3_INLINES )
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance from the point to the line
double fgPointLine(MAT3vec p, MAT3vec p0, MAT3vec d) {
MAT3vec u, u1, v;
double ud, dd, tmp;
// u = p - p0
MAT3_SUB_VEC(u, p, p0);
// calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
ud = MAT3_DOT_PRODUCT(u, d);
dd = MAT3_DOT_PRODUCT(d, d);
tmp = ud / dd;
MAT3_SCALE_VEC(u1, d, tmp);;
// v = u - u1 = vector from closest point on line, p1, to the
// original point, p.
MAT3_SUB_VEC(v, u, u1);
return sqrt(MAT3_DOT_PRODUCT(v, v));
}
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
double fgPointLineSquared(MAT3vec p, MAT3vec p0, MAT3vec d) {
MAT3vec u, u1, v;
double ud, dd, tmp;
// u = p - p0
MAT3_SUB_VEC(u, p, p0);
// calculate the projection, u1, of u along d.
// u1 = ( dot_prod(u, d) / dot_prod(d, d) ) * d;
ud = MAT3_DOT_PRODUCT(u, d);
dd = MAT3_DOT_PRODUCT(d, d);
tmp = ud / dd;
MAT3_SCALE_VEC(u1, d, tmp);;
// v = u - u1 = vector from closest point on line, p1, to the
// original point, p.
MAT3_SUB_VEC(v, u, u1);
return ( MAT3_DOT_PRODUCT(v, v) );
}
// $Log$
// Revision 1.6 1999/03/25 19:02:28 curt
// Minor optimization tweaks.
//
// Revision 1.5 1998/10/16 23:36:38 curt
// c++-ifying.
//
// Revision 1.4 1998/10/16 00:50:31 curt
// Added point3d.hxx to replace cheezy fgPoint3d struct.
//
// Revision 1.3 1998/08/24 20:04:12 curt
// Various "inline" code optimizations contributed by Norman Vine.
//
// Revision 1.2 1998/07/24 21:34:38 curt
// fgPointLine() rewritten into fgPointLineSquared() ... this ultimately saves
// us from doing a sqrt().
//
// Revision 1.1 1998/07/08 14:40:10 curt
// polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
// Updated fg_geodesy comments to reflect that routines expect and produce
// meters.
//
// Revision 1.3 1998/05/07 23:04:28 curt
// Added a blank formating line!
//
// Revision 1.2 1998/01/19 19:27:13 curt
// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
// This should simplify things tremendously.
//
// Revision 1.1 1997/12/22 04:13:17 curt
// Initial revision.
//

94
Lib/Math/vector.hxx Normal file
View file

@ -0,0 +1,94 @@
// vector.hxx -- additional vector routines
//
// Written by Curtis Olson, started December 1997.
//
// Copyright (C) 1997 Curtis L. Olson - curt@infoplane.com
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _VECTOR_HXX
#define _VECTOR_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include "mat3.h"
// Map a vector onto the plane specified by normal
#if defined( USE_XTRA_MAT3_INLINES )
# define map_vec_onto_cur_surface_plane(normal, v0, vec, result) { \
double scale = ((normal[0]*vec[0]+normal[1]*vec[1]+normal[2]*vec[2]) / \
(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2])); \
result[0] = vec[0]-normal[0]*scale; \
result[1] = vec[1]-normal[1]*scale; \
result[2] = vec[2]-normal[2]*scale; \
}
#else
void map_vec_onto_cur_surface_plane(MAT3vec normal, MAT3vec v0, MAT3vec vec,
MAT3vec result);
#endif //defined( USE_XTRA_MAT3_INLINES )
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance from the point to the line
double fgPointLine(MAT3vec p, MAT3vec p0, MAT3vec d);
// Given a point p, and a line through p0 with direction vector d,
// find the shortest distance (squared) from the point to the line
double fgPointLineSquared(MAT3vec p, MAT3vec p0, MAT3vec d);
#endif // _VECTOR_HXX
// $Log$
// Revision 1.4 1998/10/16 23:36:39 curt
// c++-ifying.
//
// Revision 1.3 1998/08/24 20:04:13 curt
// Various "inline" code optimizations contributed by Norman Vine.
//
// Revision 1.2 1998/07/24 21:34:38 curt
// fgPointLine() rewritten into fgPointLineSquared() ... this ultimately saves
// us from doing a sqrt().
//
// Revision 1.1 1998/07/08 14:40:10 curt
// polar3d.[ch] renamed to polar3d.[ch]xx, vector.[ch] renamed to vector.[ch]xx
// Updated fg_geodesy comments to reflect that routines expect and produce
// meters.
//
// Revision 1.4 1998/04/21 17:03:51 curt
// Prepairing for C++ integration.
//
// Revision 1.3 1998/01/22 02:59:39 curt
// Changed #ifdef FILE_H to #ifdef _FILE_H
//
// Revision 1.2 1998/01/19 19:27:14 curt
// Merged in make system changes from Bob Kuehne <rpk@sgi.com>
// This should simplify things tremendously.
//
// Revision 1.1 1997/12/22 04:13:18 curt
// Initial revision.
//

16
Lib/Misc/CREDITS Normal file
View file

@ -0,0 +1,16 @@
The following files were unashamedly borrowed from other projects:
zfstream.hxx
zfstream.cxx
zlib/contrib/iostream
stopwatch.hxx was (blitz/time.h)
blitz
Some modifications have been made to fit in with the FlightGear scheme of things.
As far as I'm aware they are all covered by GNU's licensing agreements.
Many thanks to their respective authors.
Bernie Bright (bbright@c031.aone.net.au)

11
Lib/Misc/Makefile.am Normal file
View file

@ -0,0 +1,11 @@
## Process this file with automake to produce Makefile.in
noinst_LIBRARIES = libMisc.a
libMisc_a_SOURCES = \
fgstream.cxx fgstream.hxx \
stopwatch.hxx \
strutils.cxx strutils.hxx \
zfstream.cxx zfstream.hxx
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib

151
Lib/Misc/fgstream.cxx Normal file
View file

@ -0,0 +1,151 @@
// zlib input file stream wrapper.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#include <ctype.h> // isspace()
#include <Misc/fgstream.hxx>
fg_gzifstream::fg_gzifstream()
: istream(&gzbuf)
{
}
//-----------------------------------------------------------------------------
//
// Open a possibly gzipped file for reading.
//
fg_gzifstream::fg_gzifstream( const string& name, ios_openmode io_mode )
: istream(&gzbuf)
{
this->open( name, io_mode );
}
//-----------------------------------------------------------------------------
//
// Attach a stream to an already opened file descriptor.
//
fg_gzifstream::fg_gzifstream( int fd, ios_openmode io_mode )
: istream(&gzbuf)
{
gzbuf.attach( fd, io_mode );
}
//-----------------------------------------------------------------------------
//
// Open a possibly gzipped file for reading.
// If the initial open fails and the filename has a ".gz" extension then
// remove the extension and try again.
// If the initial open fails and the filename doesn't have a ".gz" extension
// then append ".gz" and try again.
//
void
fg_gzifstream::open( const string& name, ios_openmode io_mode )
{
gzbuf.open( name.c_str(), io_mode );
if ( ! gzbuf.is_open() )
{
string s = name;
if ( s.substr( s.length() - 3, 3 ) == ".gz" )
{
// remove ".gz" suffix
s.replace( s.length() - 3, 3, "" );
// s.erase( s.length() - 3, 3 );
}
else
{
// Append ".gz" suffix
s += ".gz";
}
// Try again.
gzbuf.open( s.c_str(), io_mode );
}
}
void
fg_gzifstream::attach( int fd, ios_openmode io_mode )
{
gzbuf.attach( fd, io_mode );
}
//
// Manipulators
//
istream&
skipeol( istream& in )
{
char c = 0;
// skip to end of line.
while ( in.get(c) && (c != '\n' && c != '\r') )
;
// \r\n ?
return in;
}
istream&
skipws( istream& in )
{
char c;
while ( in.get(c) )
{
if ( ! isspace( c ) )
{
// put pack the non-space character
in.putback(c);
break;
}
}
return in;
}
istream&
skipcomment( istream& in )
{
while ( in )
{
// skip whitespace
in >> skipws;
char c;
if ( in.get( c ) && c != '#' )
{
// not a comment
in.putback(c);
break;
}
in >> skipeol;
}
return in;
}
// $Log$
// Revision 1.3 1998/11/06 14:05:12 curt
// More portability improvements by Bernie Bright.
//
// Revision 1.2 1998/09/24 15:22:17 curt
// Additional enhancements.
//
// Revision 1.1 1998/09/01 19:06:29 curt
// Initial revision.
//

129
Lib/Misc/fgstream.hxx Normal file
View file

@ -0,0 +1,129 @@
// zlib input file stream wrapper.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _FGSTREAM_HXX
#define _FGSTREAM_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include "Include/config.h"
#endif
#include <Include/compiler.h>
#if defined( FG_HAVE_STD_INCLUDES )
# include <istream>
#elif defined ( FG_HAVE_NATIVE_SGI_COMPILERS )
# include <CC/stream.h>
#else
# include <istream.h>
#endif
#include STL_STRING
#include "zfstream.hxx"
FG_USING_STD(string);
#ifndef FG_HAVE_NATIVE_SGI_COMPILERS
FG_USING_STD(istream);
#endif
//-----------------------------------------------------------------------------
//
// Envelope class for gzifstream.
//
class fg_gzifstream : private gzifstream_base, public istream
{
public:
//
fg_gzifstream();
// Attempt to open a file with and without ".gz" extension.
fg_gzifstream( const string& name,
ios_openmode io_mode = ios_in | ios_binary );
//
fg_gzifstream( int fd, ios_openmode io_mode = ios_in|ios_binary );
// Attempt to open a file with and without ".gz" extension.
void open( const string& name,
ios_openmode io_mode = ios_in|ios_binary );
void attach( int fd, ios_openmode io_mode = ios_in|ios_binary );
void close() { gzbuf.close(); }
bool is_open() { return gzbuf.is_open(); }
private:
// Not defined!
fg_gzifstream( const fg_gzifstream& );
void operator= ( const fg_gzifstream& );
};
// istream manipulator that skips to end of line.
istream& skipeol( istream& in );
// istream manipulator that skips over white space.
istream& skipws( istream& in );
// istream manipulator that skips comments and white space.
// A comment starts with '#'.
istream& skipcomment( istream& in );
#endif /* _FGSTREAM_HXX */
// $Log$
// Revision 1.9 1999/03/27 14:04:25 curt
// Added is_open() so we can check if the open() succeeded.
//
// Revision 1.8 1999/03/02 01:01:55 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.7 1999/02/26 22:08:08 curt
// Added initial support for native SGI compilers.
//
// Revision 1.6 1999/01/19 20:41:46 curt
// Portability updates contributed by Bernie Bright.
//
// Revision 1.5 1998/11/06 14:05:13 curt
// More portability improvements by Bernie Bright.
//
// Revision 1.4 1998/10/16 00:50:56 curt
// Remove leading _ from a couple defines.
//
// Revision 1.3 1998/10/13 00:10:06 curt
// More portability changes to help with windoze compilation problems.
//
// Revision 1.2 1998/09/24 15:22:18 curt
// Additional enhancements.
//
// Revision 1.1 1998/09/01 19:06:29 curt
// Initial revision.
//

141
Lib/Misc/stopwatch.hxx Normal file
View file

@ -0,0 +1,141 @@
/***************************************************************************
* stopwatch.hxx Timer class, for use in benchmarking
*
* Based on blitz/Timer.h
*
* $Id$
*
* Copyright (C) 1997,1998 Todd Veldhuizen <tveldhui@seurat.uwaterloo.ca>
*
* 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.
*
* Suggestions: blitz-suggest@cybervision.com
* Bugs: blitz-bugs@cybervision.com
*
* For more information, please see the Blitz++ Home Page:
* http://seurat.uwaterloo.ca/blitz/
*
***************************************************************************
* $Log$
* Revision 1.3 1998/11/20 01:01:03 curt
* FreeBSD support.
*
* Revision 1.2 1998/11/02 18:28:31 curt
* Additional win32 support.
*
* Revision 1.1 1998/09/01 19:06:30 curt
* Initial revision.
*
* Revision 1.4 1998/03/14 00:04:47 tveldhui
* 0.2-alpha-05
*
* Revision 1.3 1997/07/16 14:51:20 tveldhui
* Update: Alpha release 0.2 (Arrays)
*
* Revision 1.2 1997/01/24 14:42:00 tveldhui
* Periodic RCS update
*
*/
// This class is not portable to non System V platforms.
// It will need to be rewritten for Windows, NT, Mac.
// NEEDS_WORK
#ifndef _STOPWATCH_HXX
#define _STOPWATCH_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined(__linux__) && ! defined(HAVE_GETRUSAGE)
# define HAVE_GETRUSAGE
#endif
#if defined( WIN32 ) && defined( HAVE_GETRUSAGE )
# undef HAVE_GETRUSAGE
#endif // WIN32
#if defined( HAVE_GETRUSAGE )
# if defined( __FreeBSD__ )
# include <sys/types.h>
# endif
# include <sys/time.h>
# include <sys/resource.h>
# include <unistd.h>
#elif defined( WIN32 )
# include <windows.h>
#else
# include <time.h>
#endif
class StopWatch {
public:
StopWatch()
{
// state_ = uninitialized;
}
void start()
{
// state_ = running;
t1_ = systemTime();
}
void stop()
{
t2_ = systemTime();
// BZPRECONDITION(state_ == running);
// state_ = stopped;
}
double elapsedSeconds()
{
// BZPRECONDITION(state_ == stopped);
return t2_ - t1_;
}
private:
StopWatch(StopWatch&) { }
void operator=(StopWatch&) { }
double systemTime()
{
#if defined( HAVE_GETRUSAGE )
getrusage(RUSAGE_SELF, &resourceUsage_);
double seconds = resourceUsage_.ru_utime.tv_sec
+ resourceUsage_.ru_stime.tv_sec;
double micros = resourceUsage_.ru_utime.tv_usec
+ resourceUsage_.ru_stime.tv_usec;
return seconds + micros/1.0e6;
#elif defined( WIN32 )
return double(GetTickCount()) * double(1e-3);
#else
return clock() / (double) CLOCKS_PER_SEC;
#endif
}
// enum { uninitialized, running, stopped } state_;
#if defined( HAVE_GETRUSAGE )
struct rusage resourceUsage_;
#endif
double t1_, t2_;
};
#endif // _STOPWATCH_HXX

79
Lib/Misc/strutils.cxx Normal file
View file

@ -0,0 +1,79 @@
// String utilities.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "strutils.hxx"
const string whitespace = " \n\r\t";
//
string
trimleft( const string& s, const string& trimmings )
{
string result;
string::size_type pos = s.find_first_not_of( trimmings );
if ( pos != string::npos )
{
result.assign( s.substr( pos ) );
}
return result;
}
//
string
trimright( const string& s, const string& trimmings )
{
string result;
string::size_type pos = s.find_last_not_of( trimmings );
if ( pos == string::npos )
{
// Not found, return the original string.
result = s;
}
else
{
result.assign( s.substr( 0, pos+1 ) );
}
return result;
}
//
string
trim( const string& s, const string& trimmings )
{
return trimright( trimleft( s, trimmings ), trimmings );
}
// $Log$
// Revision 1.2 1998/10/18 01:17:15 curt
// Point3D tweaks.
//
// Revision 1.1 1998/09/01 19:06:30 curt
// Initial revision.
//

84
Lib/Misc/strutils.hxx Normal file
View file

@ -0,0 +1,84 @@
// String utilities.
//
// Written by Bernie Bright, 1998
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef STRUTILS_H
#define STRUTILS_H
#include <Include/compiler.h>
#include STL_STRING
#ifdef FG_HAVE_STD_INCLUDES
# include <cstdlib>
#else
# include <stdlib.h>
#endif
FG_USING_STD(string);
// Default characters to remove.
extern const string whitespace;
// Returns a string with trailing characters removed.
string trimleft( const string& s, const string& trimmings = whitespace );
// Returns a string with leading characters removed.
string trimright( const string& s, const string& trimmings = whitespace );
// Returns a string with leading and trailing characters removed.
string trim( const string& s, const string& trimmings = whitespace );
//-----------------------------------------------------------------------------
inline double
atof( const string& str )
{
return ::atof( str.c_str() );
}
inline int
atoi( const string& str )
{
return ::atoi( str.c_str() );
}
#endif // STRUTILS_H
// $Log$
// Revision 1.6 1999/03/02 01:01:56 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.5 1999/02/26 22:08:09 curt
// Added initial support for native SGI compilers.
//
// Revision 1.4 1999/01/19 20:41:47 curt
// Portability updates contributed by Bernie Bright.
//
// Revision 1.3 1998/10/16 00:50:57 curt
// Remove leading _ from a couple defines.
//
// Revision 1.2 1998/10/13 00:10:07 curt
// More portability changes to help with windoze compilation problems.
//
// Revision 1.1 1998/09/01 19:06:31 curt
// Initial revision.
//

317
Lib/Misc/zfstream.cxx Normal file
View file

@ -0,0 +1,317 @@
// A C++ I/O streams interface to the zlib gz* functions
//
// Written by Bernie Bright, 1998
// Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#include <memory.h>
#include "zfstream.hxx"
//
// Construct a gzfilebuf object.
// Allocate memory for 'get' buffer and zero all buffer pointers.
//
gzfilebuf::gzfilebuf()
: streambuf(),
file(NULL),
mode(0),
own_file_descriptor(false),
ibuf_size(0),
ibuffer(0)
{
// try {
ibuf_size = page_size / sizeof(char);
ibuffer = new char [ibuf_size];
// } catch (...) {
// delete [] ibuffer;
// }
// Null get and set pointers.
this->setg(0,0,0);
this->setp(0,0);
}
gzfilebuf::~gzfilebuf()
{
sync();
if ( own_file_descriptor )
this->close();
delete [] ibuffer;
}
void
gzfilebuf::cvt_iomode( char* p, ios_openmode io_mode )
{
// memset( char_mode, '\0', 10 );
// char* p = char_mode;
if ( io_mode & ios_in )
{
mode = ios_in;
*p++ = 'r';
}
else if ( io_mode & ios_app )
{
mode = ios_app;
*p++ = 'a';
}
else
{
mode = ios_out;
*p++ = 'w';
}
if ( io_mode & ios_binary )
{
mode |= ios_binary;
*p++ = 'b';
}
// Hard code the compression level
if ( io_mode & (ios_out | ios_app) )
{
*p++ = '9';
}
*p = '\0';
}
gzfilebuf*
gzfilebuf::open( const char *name, ios_openmode io_mode )
{
if ( is_open() )
return NULL;
char char_mode[10];
cvt_iomode( char_mode, io_mode );
if ( (file = gzopen(name, char_mode)) == NULL )
return NULL;
own_file_descriptor = true;
return this;
}
gzfilebuf*
gzfilebuf::attach( int file_descriptor, ios_openmode io_mode )
{
if ( is_open() )
return NULL;
char char_mode[10];
cvt_iomode( char_mode, io_mode );
if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
return NULL;
own_file_descriptor = false;
return this;
}
gzfilebuf*
gzfilebuf::close()
{
if ( is_open() )
{
sync();
gzclose( file );
file = NULL;
}
return this;
}
// int
// gzfilebuf::setcompressionlevel( int comp_level )
// {
// return gzsetparams(file, comp_level, -2);
// }
// int
// gzfilebuf::setcompressionstrategy( int comp_strategy )
// {
// return gzsetparams(file, -2, comp_strategy);
// }
streampos
gzfilebuf::seekoff( streamoff, ios_seekdir, int )
{
return streampos(EOF);
}
gzfilebuf::int_type
gzfilebuf::overflow( int_type )
{
#if 0
if ( !is_open() || !(mode & ios::out) )
return EOF;
if ( !base() )
{
if ( allocate() == EOF )
return EOF;
setg(0,0,0);
}
else
{
if (in_avail())
{
return EOF;
}
if (out_waiting())
{
if (flushbuf() == EOF)
return EOF;
}
}
int bl = blen();
setp( base(), base() + bl);
if ( c != EOF )
{
*pptr() = c;
pbump(1);
}
#endif
return 0;
}
int
gzfilebuf::sync()
{
if ( !is_open() )
return EOF;
if ( pptr() != 0 && pptr() > pbase() )
return flushbuf();
return 0;
}
gzfilebuf::int_type
gzfilebuf::flushbuf()
{
char* q = pbase();
int n = pptr() - q;
if ( gzwrite( file, q, n) < n )
return traits_type::eof();
setp(0,0);
return 0;
}
gzfilebuf::int_type
gzfilebuf::underflow()
{
// cerr << "gzfilebuf::underflow(): gptr()=" << (void*)gptr() << endl;
// Error if the file not open for reading.
if ( !is_open() || !(mode & ios_in) )
return traits_type::eof();
// If the input buffer is empty then try to fill it.
if ( gptr() != 0 && gptr() < egptr() )
{
return int_type(*gptr());
}
else
{
return fillbuf() == EOF ? traits_type::eof() : int_type(*gptr());
}
}
//
// Load the input buffer from the underlying gz file.
// Returns number of characters read, or EOF.
//
int
gzfilebuf::fillbuf()
{
int t = gzread( file, ibuffer, ibuf_size );
if ( t <= 0)
{
// disable get area
setg(0,0,0);
return EOF;
}
// Set the input (get) pointers
setg( ibuffer, ibuffer, ibuffer+t );
// cerr << "gzfilebuf::fillbuf():"
// << " t=" << t
// << ", ibuffer=" << (void*)ibuffer
// << ", ibuffer+t=" << (void*)(ibuffer+t) << endl;
return t;
}
#if 0
gzifstream::gzifstream()
: istream(&buffer), buffer()
{
clear( ios_badbit );
}
gzifstream::gzifstream( const char *name, ios_openmode io_mode )
: istream(&buffer), buffer()
{
this->open( name, io_mode );
}
gzifstream::gzifstream( int fd, ios_openmode io_mode )
: istream(&buffer), buffer()
{
buffer.attach( fd, io_mode );
}
gzifstream::~gzifstream()
{
}
void
gzifstream::open( const char *name, ios_openmode io_mode )
{
if ( !buffer.open( name, io_mode ) )
clear( ios_failbit | ios_badbit );
else
clear();
}
void
gzifstream::close()
{
if ( !buffer.close() )
clear( ios_failbit | ios_badbit );
}
#endif
// $Log$
// Revision 1.3 1999/01/19 20:41:48 curt
// Portability updates contributed by Bernie Bright.
//
// Revision 1.2 1998/11/06 14:05:14 curt
// More portability improvements by Bernie Bright.
//

177
Lib/Misc/zfstream.hxx Normal file
View file

@ -0,0 +1,177 @@
// A C++ I/O streams interface to the zlib gz* functions
//
// Written by Bernie Bright, 1998
// Based on zlib/contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
//
// Copyright (C) 1998 Bernie Bright - bbright@c031.aone.net.au
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _zfstream_hxx
#define _zfstream_hxx
#include "zlib/zlib.h"
#include "Include/compiler.h"
#ifdef FG_HAVE_STD_INCLUDES
# 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_seekdir ios_base::seekdir
# define ios_badbit ios_base::badbit
# define ios_failbit ios_base::failbit
FG_USING_STD(streambuf);
FG_USING_STD(ios_base);
FG_USING_STD(streampos);
FG_USING_STD(streamoff);
#else
# ifdef FG_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
#elif defined( FG_HAVE_NATIVE_SGI_COMPILERS )
# define ios_binary 0
#else
# define ios_binary ios::binary
#endif
# define ios_seekdir ios::seek_dir
# define ios_badbit ios::badbit
# define ios_failbit ios::failbit
# include "Include/fg_traits.hxx"
#endif // FG_HAVE_STD_INCLUDES
//-----------------------------------------------------------------------------
//
//
//
class gzfilebuf : public streambuf
{
public:
#ifndef FG_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
gzfilebuf();
virtual ~gzfilebuf();
gzfilebuf* open( const char* name, ios_openmode io_mode );
gzfilebuf* attach( int file_descriptor, ios_openmode io_mode );
gzfilebuf* close();
// int setcompressionlevel( int comp_level );
// int setcompressionstrategy( int comp_strategy );
bool is_open() const { return (file != NULL); }
virtual streampos seekoff( streamoff off, ios_seekdir way, int which );
virtual int sync();
protected:
virtual int_type underflow();
virtual int_type overflow( int_type c = traits_type::eof() );
private:
int_type flushbuf();
int fillbuf();
// Convert io_mode to "rwab" string.
void cvt_iomode( char* mode_str, ios_openmode io_mode );
private:
gzFile file;
ios_openmode mode;
bool own_file_descriptor;
// Get (input) buffer.
int ibuf_size;
char* ibuffer;
enum { page_size = 4096 };
private:
// Not defined
gzfilebuf( const gzfilebuf& );
void operator= ( const gzfilebuf& );
};
//-----------------------------------------------------------------------------
//
//
//
struct gzifstream_base
{
gzifstream_base() {}
gzfilebuf gzbuf;
};
#endif // _zfstream_hxx
// $Log$
// Revision 1.9 1999/03/08 22:00:12 curt
// Tweak for native SGI compilers.
//
// Revision 1.8 1999/02/26 22:08:10 curt
// Added initial support for native SGI compilers.
//
// Revision 1.7 1999/01/19 20:41:49 curt
// Portability updates contributed by Bernie Bright.
//
// Revision 1.6 1998/12/07 21:10:26 curt
// Portability improvements.
//
// Revision 1.5 1998/11/06 21:17:29 curt
// Converted to new logstream debugging facility. This allows release
// builds with no messages at all (and no performance impact) by using
// the -DFG_NDEBUG flag.
//
// Revision 1.4 1998/11/06 14:05:16 curt
// More portability improvements by Bernie Bright.
//

24
Lib/PUI/Makefile.am Normal file
View file

@ -0,0 +1,24 @@
noinst_LIBRARIES = libPUI.a
EXTRA_DIST = complex.cxx simple.cxx
libPUI_a_SOURCES = \
pu.h puLocal.h \
pu.cxx \
puBox.cxx \
puButton.cxx \
puButtonBox.cxx \
puDialogBox.cxx \
puFrame.cxx \
puInput.cxx \
puInterface.cxx \
puMenuBar.cxx \
puObject.cxx \
puOneShot.cxx \
puPopup.cxx \
puPopupMenu.cxx \
puSlider.cxx \
puText.cxx
INCLUDES += -I$(top_builddir)

332
Lib/PUI/complex.cxx Normal file
View file

@ -0,0 +1,332 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <math.h>
#include <GL/glut.h>
#include "pu.h"
/***********************************\
* *
* These are the PUI widget pointers *
* *
\***********************************/
puMenuBar *main_menu_bar ;
puButton *hide_menu_button ;
puDialogBox *dialog_box ;
puText *dialog_box_message ;
puOneShot *dialog_box_ok_button ;
puText *timer_text ;
puSlider *rspeedSlider;
/***********************************\
* *
* This is a generic tumbling cube *
* *
\***********************************/
GLfloat light_diffuse [] = {0.0, 1.0, 0.0, 1.0} ; /* Red diffuse light. */
GLfloat light_position[] = {1.0, 1.0, 1.0, 0.0} ; /* Infinite light location. */
GLfloat cube_n[6][3] = /* Normals */
{
{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0},
{ 0.0,-1.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 0.0,-1.0}
} ;
GLint cube_i[6][4] = /* Vertex indices */
{
{0, 1, 2, 3}, {3, 2, 6, 7}, {7, 6, 5, 4},
{4, 5, 1, 0}, {5, 6, 2, 1}, {7, 4, 0, 3}
} ;
GLfloat cube_v[8][3] = /* Vertices */
{
{-1.0,-1.0, 1.0}, {-1.0,-1.0,-1.0}, {-1.0, 1.0,-1.0}, {-1.0, 1.0, 1.0},
{ 1.0,-1.0, 1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, { 1.0, 1.0, 1.0}
} ;
static int firsttime;
void drawCube (void)
{
if ( firsttime )
{
/*
Deliberately do this only once - it's a better test of
PUI's attempts to leave the OpenGL state undisturbed
*/
firsttime = FALSE ;
glLightfv ( GL_LIGHT0, GL_DIFFUSE , light_diffuse ) ;
glLightfv ( GL_LIGHT0, GL_POSITION, light_position ) ;
glEnable ( GL_LIGHT0 ) ;
glEnable ( GL_LIGHTING ) ;
glEnable ( GL_DEPTH_TEST ) ;
glMatrixMode ( GL_PROJECTION ) ;
gluPerspective ( 40.0, 1.0, 1.0, 10.0 ) ;
glMatrixMode ( GL_MODELVIEW ) ;
gluLookAt ( 0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0 ) ;
glTranslatef ( 0.0, 0.0, -1.0 ) ;
glRotatef ( 60.0, 1.0, 0.0, 0.0 ) ;
}
glCullFace ( GL_FRONT ) ;
glEnable ( GL_CULL_FACE ) ;
// glRotatef ( 1.0f, 0.0, 0.0, 1.0 ) ; /* Tumble that cube! */
glBegin ( GL_QUADS ) ;
for ( int i = 0 ; i < 6 ; i++ )
{
glNormal3fv ( &cube_n[i][0] ) ;
glVertex3fv ( cube_v[cube_i[i][0]] ) ; glVertex3fv ( cube_v[cube_i[i][1]] ) ;
glVertex3fv ( cube_v[cube_i[i][2]] ) ; glVertex3fv ( cube_v[cube_i[i][3]] ) ;
}
glEnd () ;
}
/********************************\
* *
* End of cube renderer in OpenGL *
* *
\********************************/
/**************************************\
* *
* These three functions capture mouse *
* and keystrokes (special and mundane) *
* from GLUT and pass them on to PUI. *
* *
\**************************************/
static void specialfn ( int key, int, int )
{
puKeyboard ( key + PU_KEY_GLUT_SPECIAL_OFFSET, PU_DOWN ) ;
glutPostRedisplay () ;
}
static void keyfn ( unsigned char key, int, int )
{
puKeyboard ( key, PU_DOWN ) ;
glutPostRedisplay () ;
}
static void motionfn ( int x, int y )
{
puMouse ( x, y ) ;
glutPostRedisplay () ;
}
static void mousefn ( int button, int updown, int x, int y )
{
puMouse ( button, updown, x, y ) ;
glutPostRedisplay () ;
}
/**************************************\
* *
* This function redisplays the PUI and *
* the tumbling cube, flips the double *
* buffer and then asks GLUT to post a *
* redisplay command - so we re-render *
* at maximum rate. *
* *
\**************************************/
static void displayfn (void)
{
/* Clear the screen */
glClearColor ( 0.0, 0.0, 0.0, 1.0 ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ;
/* Draw the tumbling cube */
float val ; rspeedSlider->getValue ( &val ) ;
glRotatef( 4*val, 15.0, 10.0 , 5.0 );
drawCube () ;
/* Update the 'timer' */
time_t t = time ( NULL ) ;
timer_text -> setLabel ( ctime ( & t ) ) ;
/* Make PUI redraw */
puDisplay () ;
/* Off we go again... */
glutSwapBuffers () ;
glutPostRedisplay () ;
}
/***********************************\
* *
* Here are the PUI widget callback *
* functions. *
* *
\***********************************/
void hide_menu_cb ( puObject *cb )
{
if ( cb -> getValue () )
{
main_menu_bar -> reveal () ;
hide_menu_button->setLegend ( "Hide Menu" ) ;
}
else
{
main_menu_bar -> hide () ;
hide_menu_button->setLegend ( "Show Menu" ) ;
}
}
void go_away_cb ( puObject * )
{
/*
Delete the dialog box when its 'OK' button is pressed.
This seems to crash on MSVC compilers - probably because
I delete dialog_box - whose member function is calling
this function. Hence we return to something that is
in a distinctly 'iffy' state.
*/
delete dialog_box ;
dialog_box = NULL ;
}
void mk_dialog ( char *txt )
{
dialog_box = new puDialogBox ( 150, 50 ) ;
{
new puFrame ( 0, 0, 400, 100 ) ;
dialog_box_message = new puText ( 10, 70 ) ;
dialog_box_message -> setLabel ( txt ) ;
dialog_box_ok_button = new puOneShot ( 180, 10, 240, 50 ) ;
dialog_box_ok_button -> setLegend ( "OK" ) ;
dialog_box_ok_button -> makeReturnDefault ( TRUE ) ;
dialog_box_ok_button -> setCallback ( go_away_cb ) ;
}
dialog_box -> close () ;
dialog_box -> reveal () ;
}
void ni_cb ( puObject * )
{
mk_dialog ( "Sorry, that function isn't implemented" ) ;
}
void about_cb ( puObject * )
{
mk_dialog ( "This is the PUI 'complex' program" ) ;
}
void help_cb ( puObject * )
{
mk_dialog ( "Sorry, no help is available for this demo" ) ;
}
void edit_cb ( puObject * )
{
}
void exit_cb ( puObject * )
{
fprintf ( stderr, "Exiting PUI demo program.\n" ) ;
exit ( 1 ) ;
}
/* Menu bar entries: */
char *file_submenu [] = { "Exit", "Close", "--------", "Print", "--------", "Save", "New", NULL } ;
puCallback file_submenu_cb [] = { exit_cb, exit_cb, NULL, ni_cb , NULL, ni_cb, ni_cb, NULL } ;
char *edit_submenu [] = { "Edit text", NULL } ;
puCallback edit_submenu_cb [] = { edit_cb, NULL } ;
char *help_submenu [] = { "About...", "Help", NULL } ;
puCallback help_submenu_cb [] = { about_cb, help_cb, NULL } ;
void sliderCB( puObject *sliderObj)
{
glutPostRedisplay();
}
int main ( int argc, char **argv )
{
firsttime = TRUE;
#ifdef VOODOO
glutInitWindowPosition( 0, 0 ) ;
#endif
glutInitWindowSize ( 640, 480 ) ;
glutInit ( &argc, argv ) ;
glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ) ;
glutCreateWindow ( "Complex PUI Application" ) ;
glutDisplayFunc ( displayfn ) ;
glutKeyboardFunc ( keyfn ) ;
glutSpecialFunc ( specialfn ) ;
glutMouseFunc ( mousefn ) ;
glutMotionFunc ( motionfn ) ;
glutPassiveMotionFunc ( motionfn ) ;
glutIdleFunc ( displayfn ) ;
puInit () ;
#ifdef VOODOO
puShowCursor () ;
#endif
puSetDefaultStyle ( PUSTYLE_SMALL_SHADED ) ;
puSetDefaultColourScheme ( 0.8, 0.8, 0.8 ) ;
timer_text = new puText ( 300, 10 ) ;
timer_text -> setColour ( PUCOL_LABEL, 1.0, 1.0, 1.0 ) ;
/* Make a button to hide the menu bar */
hide_menu_button = new puButton ( 10, 10, 150, 50 ) ;
hide_menu_button->setValue ( TRUE ) ;
hide_menu_button->setLegend ( "Hide Menu" ) ;
hide_menu_button->setCallback ( hide_menu_cb ) ;
hide_menu_button->makeReturnDefault ( TRUE ) ;
/* Make the menu bar */
main_menu_bar = new puMenuBar () ;
{
main_menu_bar -> add_submenu ( "File", file_submenu, file_submenu_cb ) ;
main_menu_bar -> add_submenu ( "Edit", edit_submenu, edit_submenu_cb ) ;
main_menu_bar -> add_submenu ( "Help", help_submenu, help_submenu_cb ) ;
}
main_menu_bar -> close () ;
rspeedSlider = new puSlider (20,80,150,TRUE);
rspeedSlider->setDelta(0.1);
rspeedSlider->setCBMode( PUSLIDER_DELTA );
rspeedSlider->setCallback(sliderCB);
glutMainLoop () ;
return 0 ;
}

332
Lib/PUI/pu.cxx Normal file
View file

@ -0,0 +1,332 @@
#include "puLocal.h"
#ifdef PU_NOT_USING_GLUT
#include <assert.h>
#include <iostream.h>
#endif
#define PU_STRING_X_FUDGE 6
#define PU_STRING_Y_FUDGE 6
int puRefresh = TRUE ;
#ifdef PU_NOT_USING_GLUT
static int puWindowWidth = 400 ;
static int puWindowHeight = 400 ;
int puGetWindowHeight () { return puWindowHeight ; }
int puGetWindowWidth () { return puWindowWidth ; }
void puSetWindowSize ( int width, int height )
{
puWindowWidth = width ;
puWindowHeight = height ;
}
static int fontBase = 0;
static int fontSize[257];
#else
int puGetWindowHeight () { return glutGet ( (GLenum) GLUT_WINDOW_HEIGHT ) ; }
int puGetWindowWidth () { return glutGet ( (GLenum) GLUT_WINDOW_WIDTH ) ; }
void puSetWindowSize ( int width, int height )
{
fprintf ( stderr, "PUI: puSetWindowSize shouldn't be used with GLUT.\n" ) ;
}
#endif
puColour _puDefaultColourTable[] =
{
{ 0.5f, 0.5f, 0.5f, 1.0f }, /* PUCOL_FOREGROUND */
{ 0.3f, 0.3f, 0.3f, 1.0f }, /* PUCOL_BACKGROUND */
{ 0.7f, 0.7f, 0.7f, 1.0f }, /* PUCOL_HIGHLIGHT */
{ 0.0f, 0.0f, 0.0f, 1.0f }, /* PUCOL_LABEL */
{ 1.0f, 1.0f, 1.0f, 1.0f }, /* PUCOL_TEXT */
{ 0.0f, 0.0f, 0.0f, 0.0f } /* ILLEGAL */
} ;
puValue::~puValue () {}
static int _puCursor_enable = FALSE ;
static int _puCursor_x = 0 ;
static int _puCursor_y = 0 ;
static float _puCursor_bgcolour [4] = { 1.0f, 1.0f, 1.0f, 1.0f } ;
static float _puCursor_fgcolour [4] = { 0.0f, 0.0f, 0.0f, 1.0f } ;
void puHideCursor ( void ) { _puCursor_enable = FALSE ; }
void puShowCursor ( void ) { _puCursor_enable = TRUE ; }
int puCursorIsHidden ( void ) { return ! _puCursor_enable ; }
void puCursor ( int x, int y )
{
_puCursor_x = x ;
_puCursor_y = y ;
}
int puGetStringDescender ( void *fnt )
{
if ( fnt == NULL )
fnt = PUFONT_9_BY_15 ;
if ( fnt == PUFONT_8_BY_13 ) return 2 ;
if ( fnt == PUFONT_9_BY_15 ) return 3 ;
if ( fnt == PUFONT_TIMES_ROMAN_10 ) return 2 ;
if ( fnt == PUFONT_TIMES_ROMAN_24 ) return 5 ;
if ( fnt == PUFONT_HELVETICA_10 ) return 2 ;
if ( fnt == PUFONT_HELVETICA_12 ) return 3 ;
if ( fnt == PUFONT_HELVETICA_18 ) return 4 ;
return 0 ;
}
int puGetStringHeight ( void *fnt )
{
/* Height *excluding* descender */
if ( fnt == NULL )
fnt = PUFONT_9_BY_15 ;
if ( fnt == PUFONT_8_BY_13 ) return 9 ;
if ( fnt == PUFONT_9_BY_15 ) return 10 ;
if ( fnt == PUFONT_TIMES_ROMAN_10 ) return 7 ;
if ( fnt == PUFONT_TIMES_ROMAN_24 ) return 17 ;
if ( fnt == PUFONT_HELVETICA_10 ) return 8 ;
if ( fnt == PUFONT_HELVETICA_12 ) return 9 ;
if ( fnt == PUFONT_HELVETICA_18 ) return 14 ;
return 0 ;
}
int puGetStringWidth ( void *fnt, char *str )
{
if ( str == NULL )
return 0 ;
int res = 0 ;
#ifdef PU_NOT_USING_GLUT
while ( *str != '\0' )
{
res += fontSize [ *str ] ;
str++ ;
}
#else
if ( fnt == NULL )
fnt = PUFONT_9_BY_15 ;
while ( *str != '\0' )
{
res += glutBitmapWidth ( fnt, *str ) ;
str++ ;
}
#endif
return res ;
}
void puDrawString ( void *fnt, char *str, int x, int y )
{
if ( str == NULL )
return ;
glRasterPos2f((float)x, (float)y);
#ifdef PU_NOT_USING_GLUT
/*
Display a string:
indicate start of glyph display lists
*/
glListBase (fontBase);
/* Now draw the characters in a string */
int len = strlen(str);
glCallLists(len, GL_UNSIGNED_BYTE, str);
glListBase(0);
#else
if ( fnt == NULL )
fnt = PUFONT_9_BY_15 ;
while ( *str != '\0' )
{
glutBitmapCharacter ( fnt, *str ) ;
str++ ;
}
#endif
}
static void puDrawCursor ( int x, int y )
{
glColor4fv ( _puCursor_bgcolour ) ;
glBegin ( GL_TRIANGLES ) ;
glVertex2i ( x, y ) ;
glVertex2i ( x + 13, y - 4 ) ;
glVertex2i ( x + 4, y - 13 ) ;
glVertex2i ( x + 8, y - 3 ) ;
glVertex2i ( x + 17, y - 12 ) ;
glVertex2i ( x + 12, y - 17 ) ;
glVertex2i ( x + 12, y - 17 ) ;
glVertex2i ( x + 3, y - 8 ) ;
glVertex2i ( x + 8, y - 3 ) ;
glEnd () ;
glColor4fv ( _puCursor_fgcolour ) ;
glBegin ( GL_TRIANGLES ) ;
glVertex2i ( x+1, y-1 ) ;
glVertex2i ( x + 11, y - 4 ) ;
glVertex2i ( x + 4, y - 11 ) ;
glVertex2i ( x + 8, y - 5 ) ;
glVertex2i ( x + 15, y - 12 ) ;
glVertex2i ( x + 12, y - 15 ) ;
glVertex2i ( x + 12, y - 15 ) ;
glVertex2i ( x + 5, y - 8 ) ;
glVertex2i ( x + 8, y - 5 ) ;
glEnd () ;
}
void puInit ( void )
{
static int firsttime = TRUE ;
if ( firsttime )
{
puInterface *base_interface = new puInterface ( 0, 0 ) ;
puPushInterface ( base_interface ) ;
puPushLiveInterface ( base_interface ) ;
firsttime = FALSE ;
#ifdef PU_NOT_USING_GLUT
/* Create bitmaps for the device context font's first 256 glyphs */
fontBase = glGenLists(256);
assert(fontBase);
HDC hdc = wglGetCurrentDC();
/* Make the system font the device context's selected font */
SelectObject (hdc, GetStockObject (SYSTEM_FONT));
int *tempSize = &fontSize[1];
if ( ! GetCharWidth32 ( hdc, 1, 255, tempSize ) &&
! GetCharWidth ( hdc, 1, 255, tempSize ) )
{
LPVOID lpMsgBuf ;
FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL ) ;
fprintf ( stderr, "PUI: Error: %s\n", (char *)lpMsgBuf ) ;
LocalFree ( lpMsgBuf ) ;
}
wglUseFontBitmaps ( hdc, 0, 256, fontBase ) ;
#endif
}
}
static void puSetOpenGLState ( void )
{
int w = puGetWindowWidth () ;
int h = puGetWindowHeight () ;
glPushAttrib ( GL_ENABLE_BIT | GL_VIEWPORT_BIT | GL_TRANSFORM_BIT ) ;
glDisable ( GL_LIGHTING ) ;
glDisable ( GL_FOG ) ;
glDisable ( GL_TEXTURE_2D ) ;
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_CULL_FACE ) ;
glViewport ( 0, 0, w, h ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPushMatrix () ;
glLoadIdentity () ;
gluOrtho2D ( 0, w, 0, h ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix () ;
glLoadIdentity () ;
}
static void puRestoreOpenGLState ( void )
{
glMatrixMode ( GL_PROJECTION ) ;
glPopMatrix () ;
glMatrixMode ( GL_MODELVIEW ) ;
glPopMatrix () ;
glPopAttrib () ;
}
void puDisplay ( void )
{
puSetOpenGLState () ;
puGetUltimateLiveInterface () -> draw ( 0, 0 ) ;
int h = puGetWindowHeight () ;
if ( _puCursor_enable )
puDrawCursor ( _puCursor_x,
h - _puCursor_y ) ;
puRestoreOpenGLState () ;
}
int puKeyboard ( int key, int updown )
{
return puGetBaseLiveInterface () -> checkKey ( key, updown ) ;
}
static int last_buttons = 0 ;
int puMouse ( int button, int updown, int x, int y )
{
puCursor ( x, y ) ;
int h = puGetWindowHeight () ;
if ( updown == PU_DOWN )
last_buttons |= ( 1 << button ) ;
else
last_buttons &= ~( 1 << button ) ;
return puGetBaseLiveInterface () -> checkHit ( button, updown, x,
h - y ) ;
}
int puMouse ( int x, int y )
{
puCursor ( x, y ) ;
if ( last_buttons == 0 )
return FALSE ;
int button = (last_buttons & (1<<PU_LEFT_BUTTON )) ? PU_LEFT_BUTTON :
(last_buttons & (1<<PU_MIDDLE_BUTTON)) ? PU_MIDDLE_BUTTON :
(last_buttons & (1<<PU_RIGHT_BUTTON )) ? PU_RIGHT_BUTTON : 0 ;
int h = puGetWindowHeight () ;
return puGetBaseLiveInterface () -> checkHit ( button, PU_DRAG, x,
h - y ) ;
}

805
Lib/PUI/pu.h Normal file
View file

@ -0,0 +1,805 @@
#ifndef _PU_H_
#define _PU_H_
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef PU_NOT_USING_GLUT
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#else
#include <GL/glut.h>
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
/*
Webster's Dictionary (for American English) permits
Color or Colour as acceptable spellings - but
The Oxford English Dictionary (for English) only
permits Colour.
Hence, the logical thing to do is to use 'colour',
which *ought* to be acceptable on both sides of
the atlantic.
However, as a concession to the illogical:
*/
#define setColorScheme setColourScheme
#define setColor setColour
#define getColor getColour
#define puColor puColour
#define puSetColor puSetColour
#define puSetDefaultColorScheme puSetDefaultColourScheme
#define puGetDefaultColorScheme puGetDefaultColourScheme
typedef void *puFont ;
#ifdef PU_NOT_USING_GLUT
#define PU_LEFT_BUTTON 0
#define PU_LEFT_BUTTON 0
#define PU_MIDDLE_BUTTON 1
#define PU_RIGHT_BUTTON 2
#define PU_DOWN 0
#define PU_UP 1
#define PUFONT_8_BY_13 ((void*)3)
#define PUFONT_9_BY_15 ((void*)2)
#define PUFONT_TIMES_ROMAN_10 ((void*)4)
#define PUFONT_TIMES_ROMAN_24 ((void*)5)
#define PUFONT_HELVETICA_10 ((void*)6)
#define PUFONT_HELVETICA_12 ((void*)7)
#define PUFONT_HELVETICA_18 ((void*)8)
#else
#define PUFONT_8_BY_13 GLUT_BITMAP_8_BY_13
#define PUFONT_9_BY_15 GLUT_BITMAP_9_BY_15
#define PUFONT_TIMES_ROMAN_10 GLUT_BITMAP_TIMES_ROMAN_10
#define PUFONT_TIMES_ROMAN_24 GLUT_BITMAP_TIMES_ROMAN_24
#define PUFONT_HELVETICA_10 GLUT_BITMAP_HELVETICA_10
#define PUFONT_HELVETICA_12 GLUT_BITMAP_HELVETICA_12
#define PUFONT_HELVETICA_18 GLUT_BITMAP_HELVETICA_18
#define PU_LEFT_BUTTON GLUT_LEFT_BUTTON
#define PU_MIDDLE_BUTTON GLUT_MIDDLE_BUTTON
#define PU_RIGHT_BUTTON GLUT_RIGHT_BUTTON
#define PU_DOWN GLUT_DOWN
#define PU_UP GLUT_UP
#endif // PU_NOT_USING_GLUT
#define PU_UP_AND_DOWN 254
#define PU_DRAG 255
#define PU_CONTINUAL PU_DRAG
#define PU_KEY_GLUT_SPECIAL_OFFSET 256
#ifdef PU_NOT_USING_GLUT
#define PU_KEY_F1 (1 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F2 (2 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F3 (3 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F4 (4 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F5 (5 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F6 (6 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F7 (7 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F8 (8 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F9 (9 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F10 (10 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F11 (11 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F12 (12 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_LEFT (100 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_UP (101 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_RIGHT (102 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_DOWN (103 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_PAGE_UP (104 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_PAGE_DOWN (105 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_HOME (106 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_END (107 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_INSERT (108 + PU_KEY_GLUT_SPECIAL_OFFSET)
#else
#define PU_KEY_F1 (GLUT_KEY_F1 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F2 (GLUT_KEY_F2 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F3 (GLUT_KEY_F3 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F4 (GLUT_KEY_F4 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F5 (GLUT_KEY_F5 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F6 (GLUT_KEY_F6 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F7 (GLUT_KEY_F7 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F8 (GLUT_KEY_F8 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F9 (GLUT_KEY_F9 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F10 (GLUT_KEY_F10 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F11 (GLUT_KEY_F11 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_F12 (GLUT_KEY_F12 + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_LEFT (GLUT_KEY_LEFT + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_UP (GLUT_KEY_UP + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_RIGHT (GLUT_KEY_RIGHT + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_DOWN (GLUT_KEY_DOWN + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_PAGE_UP (GLUT_KEY_PAGE_UP + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_PAGE_DOWN (GLUT_KEY_PAGE_DOWN + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_HOME (GLUT_KEY_HOME + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_END (GLUT_KEY_END + PU_KEY_GLUT_SPECIAL_OFFSET)
#define PU_KEY_INSERT (GLUT_KEY_INSERT + PU_KEY_GLUT_SPECIAL_OFFSET)
#endif // PU_NOT_USING_GLUT
#define PUPLACE_DEFAULT PUPLACE_RIGHT
#define PUPLACE_ABOVE 0
#define PUPLACE_BELOW 1
#define PUPLACE_LEFT 2
#define PUPLACE_RIGHT 3
#define PUCOL_FOREGROUND 0
#define PUCOL_BACKGROUND 1
#define PUCOL_HIGHLIGHT 2
#define PUCOL_LABEL 3
#define PUCOL_LEGEND 4
#define PUCOL_MAX 5
#define PUSLIDER_CLICK 0
#define PUSLIDER_ALWAYS 1
#define PUSLIDER_DELTA 2
/* These styles may be negated to get 'highlighted' graphics */
#define PUSTYLE_DEFAULT PUSTYLE_SHADED
#define PUSTYLE_NONE 0
#define PUSTYLE_PLAIN 1
#define PUSTYLE_BEVELLED 2
#define PUSTYLE_BOXED 3
#define PUSTYLE_DROPSHADOW 4
#define PUSTYLE_SPECIAL_UNDERLINED 5
#define PUSTYLE_SMALL_BEVELLED 6
#define PUSTYLE_RADIO 7
#define PUSTYLE_SHADED 8
#define PUSTYLE_SMALL_SHADED 9
#define PUSTYLE_MAX 10
/* These are the gaps that we try to leave around text objects */
#define PUSTR_TGAP 5
#define PUSTR_BGAP 5
#define PUSTR_LGAP 5
#define PUSTR_RGAP 5
#define PUSTR_MAX_HEIGHT ( 25 + PUSTR_TGAP + PUSTR_BGAP )
#define PU_RADIO_BUTTON_SIZE 16
extern int puRefresh ;
#define PUCLASS_VALUE 0x00000001
#define PUCLASS_OBJECT 0x00000002
#define PUCLASS_INTERFACE 0x00000004
#define PUCLASS_FRAME 0x00000008
#define PUCLASS_TEXT 0x00000010
#define PUCLASS_BUTTON 0x00000020
#define PUCLASS_ONESHOT 0x00000040
#define PUCLASS_POPUP 0x00000080
#define PUCLASS_POPUPMENU 0x00000100
#define PUCLASS_MENUBAR 0x00000200
#define PUCLASS_INPUT 0x00000400
#define PUCLASS_BUTTONBOX 0x00000800
#define PUCLASS_SLIDER 0x00001000
#define PUCLASS_DIALOGBOX 0x00002000
/* This function is not required for GLUT programs */
void puSetWindowSize ( int width, int height ) ;
int puGetWindowHeight () ;
int puGetWindowWidth () ;
class puValue ;
class puObject ;
class puInterface ;
class puButtonBox ;
class puFrame ;
class puText ;
class puButton ;
class puOneShot ;
class puPopup ;
class puPopupMenu ;
class puMenuBar ;
class puInput ;
class puSlider ;
typedef float puColour [ 4 ] ; /* RGBA */
struct puBox
{
int min [ 2 ] ;
int max [ 2 ] ;
void draw ( int dx, int dy, int style, puColour colour[], int am_default ) ;
void extend ( puBox *bx ) ;
void empty ( void ) { min[0]=min[1]=1000000 ; max[0]=max[1]=-1000000 ; }
int isEmpty ( void ) { return min[0]>max[0] || min[1]>max[1] ; }
} ;
#define PUSTRING_MAX 80
/* If you change - or add to these, be sure to change _puDefaultColourTable */
extern puColour _puDefaultColourTable[] ;
inline void puSetColour ( puColour dst, puColour src )
{
dst[0] = src[0] ; dst[1] = src[1] ; dst[2] = src[2] ; dst[3] = src[3] ;
}
inline void puSetColour ( puColour c, float r, float g, float b, float a = 1.0f )
{
c [ 0 ] = r ; c [ 1 ] = g ; c [ 2 ] = b ; c [ 3 ] = a ;
}
void puInit ( void ) ;
void puDisplay ( void ) ;
int puMouse ( int button, int updown, int x, int y ) ;
int puMouse ( int x, int y ) ;
int puKeyboard ( int key, int updown ) ;
void puHideCursor ( void ) ;
void puShowCursor ( void ) ;
int puCursorIsHidden ( void ) ;
void puDrawString ( puFont fnt, char *str, int x, int y ) ;
int puGetStringWidth ( puFont fnt, char *str ) ;
int puGetStringHeight ( puFont fnt = NULL ) ;
int puGetStringDescender ( puFont fnt = NULL ) ;
class puValue
{
protected:
int type ;
int integer ;
float floater ;
char string [ PUSTRING_MAX ] ;
public:
puValue () { type = PUCLASS_VALUE ; clrValue () ; }
virtual ~puValue () ;
int getType ( void ) { return type ; }
char *getTypeString ( void ) ;
void clrValue ( void ) { setValue ( "" ) ; }
void setValue ( puValue *pv )
{
integer = pv -> integer ;
floater = pv -> floater ;
strcpy ( string, pv -> string ) ;
puRefresh = TRUE ;
}
void setValue ( int i ) { integer = i ; floater = (float) i ; sprintf ( string, "%d", i ) ; puRefresh = TRUE ; }
void setValue ( float f ) { integer = (int) f ; floater = f ; sprintf ( string, "%g", f ) ; puRefresh = TRUE ; }
void setValue ( char *s ) {
if ( s == NULL || s[0] == '\0' )
{
integer = 0 ;
floater = 0.0f ;
s = "" ;
}
else
{
integer = atoi(s) ;
floater = (float)atof(s) ;
if ( string != s ) strcpy ( string, s ) ;
}
puRefresh = TRUE ;
}
void getValue ( int *i ) { *i = integer ; }
void getValue ( float *f ) { *f = floater ; }
void getValue ( char **s ) { *s = string ; }
void getValue ( char *s ) { strcpy ( s, string ) ; }
int getValue ( void ) { return integer ; }
} ;
typedef void (*puCallback)(class puObject *) ;
void puSetDefaultStyle ( int style ) ;
int puGetDefaultStyle ( void ) ;
void puSetDefaultFonts ( puFont legendFont, puFont labelFont ) ;
void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont ) ;
void puSetDefaultColourScheme ( float r, float g, float b, float a = 1.0 ) ;
void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a = NULL );
class puObject : public puValue
{
protected:
puValue default_value ;
puBox bbox ; /* Bounding box of entire Object */
puBox abox ; /* Active (clickable) area */
puColour colour [ PUCOL_MAX ] ;
puInterface *parent ;
int active_mouse_edge ; /* is it PU_UP or PU_DOWN (or both) that activates this? */
int style ;
int visible ;
int active ;
int highlighted ;
int am_default ;
char *label ; puFont labelFont ; int labelPlace ;
char *legend ; puFont legendFont ;
void *user_data ;
puCallback cb ;
virtual void draw_label ( int dx, int dy ) ;
virtual int isHit ( int x, int y ) { return isVisible() && isActive() &&
x >= abox.min[0] &&
x <= abox.max[0] &&
y >= abox.min[1] &&
y <= abox.max[1] ; }
virtual void doHit ( int button, int updown, int x, int y ) ;
public:
puObject ( int minx, int miny, int maxx, int maxy ) ;
~puObject () ;
puObject *next ;
puObject *prev ;
puBox *getBBox ( void ) { return & bbox ; }
puBox *getABox ( void ) { return & abox ; }
void setPosition ( int x, int y )
{
if ( abox.isEmpty() )
{
abox.max[0] = abox.min[0] = x ;
abox.max[1] = abox.min[1] = y ;
}
else
{
abox.max[0] += x - abox.min[0] ;
abox.max[1] += y - abox.min[1] ;
abox.min[0] = x ;
abox.min[1] = y ;
}
recalc_bbox() ; puRefresh = TRUE ;
}
void setSize ( int w, int h )
{
abox.max[0] = abox.min[0] + w ;
abox.max[1] = abox.min[1] + h ;
recalc_bbox() ; puRefresh = TRUE ;
}
void getPosition ( int *x, int *y )
{
if ( abox . isEmpty () )
{
if ( x ) *x = 0 ;
if ( y ) *y = 0 ;
}
else
{
if ( x ) *x = abox.min[0] ;
if ( y ) *y = abox.min[1] ;
}
}
void getSize ( int *w, int *h )
{
if ( abox . isEmpty () )
{
if ( w ) *w = 0 ;
if ( h ) *h = 0 ;
}
else
{
if ( w ) *w = abox.max[0] - abox.min[0] ;
if ( h ) *h = abox.max[1] - abox.min[1] ;
}
}
virtual void recalc_bbox ( void ) ;
virtual int checkHit ( int button, int updown, int x, int y ) ;
virtual int checkKey ( int key , int updown ) ;
virtual void draw ( int dx, int dy ) = 0 ;
puInterface *getParent ( void ) { return parent ; }
puObject *getNextObject ( void ) { return next ; }
puObject *getPrevObject ( void ) { return prev ; }
void setCallback ( puCallback c ) { cb = c ; }
puCallback getCallback ( void ) { return cb ; }
void invokeCallback ( void ) { if ( cb ) (*cb)(this) ; }
void makeReturnDefault ( int def ) { am_default = def ; }
int isReturnDefault ( void ) { return am_default ; }
void setActiveDirn ( int e ) { active_mouse_edge = e ; }
int getActiveDirn ( void ) { return active_mouse_edge ; }
void setLegend ( char *l ) { legend = l ; recalc_bbox() ; puRefresh = TRUE ; }
char *getLegend ( void ) { return legend ; }
void setLegendFont ( puFont f ) { legendFont = f ; recalc_bbox() ; puRefresh = TRUE ; }
puFont getLegendFont ( void ) { return legendFont ; }
void setLabel ( char *l ) { label = l ; recalc_bbox() ; puRefresh = TRUE ; }
char *getLabel ( void ) { return label ; }
void setLabelFont ( puFont f ) { labelFont = f ; recalc_bbox() ; puRefresh = TRUE ; }
puFont getLabelFont ( void ) { return labelFont ; }
void setLabelPlace ( int lp ) { labelPlace = lp ; recalc_bbox() ; puRefresh = TRUE ; }
int getLabelPlace ( void ) { return labelPlace ; }
void activate ( void ) { if ( ! active ) { active = TRUE ; puRefresh = TRUE ; } }
void greyOut ( void ) { if ( active ) { active = FALSE ; puRefresh = TRUE ; } }
int isActive ( void ) { return active ; }
void highlight ( void ) { if ( ! highlighted ) { highlighted = TRUE ; puRefresh = TRUE ; } }
void lowlight ( void ) { if ( highlighted ) { highlighted = FALSE ; puRefresh = TRUE ; } }
int isHighlighted( void ){ return highlighted ; }
void reveal ( void ) { if ( ! visible ) { visible = TRUE ; puRefresh = TRUE ; } }
void hide ( void ) { if ( visible ) { visible = FALSE ; puRefresh = TRUE ; } }
int isVisible ( void ) { return visible ; }
void setStyle ( int which )
{
style = which ;
recalc_bbox () ;
puRefresh = TRUE ;
}
int getStyle ( void ) { return style ; }
void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
void setColour ( int which, float r, float g, float b, float a = 1.0f )
{
puSetColour ( colour [ which ], r, g, b, a ) ;
puRefresh = TRUE ;
}
void getColour ( int which, float *r, float *g, float *b, float *a = NULL )
{
if ( r ) *r = colour[which][0] ;
if ( g ) *g = colour[which][1] ;
if ( b ) *b = colour[which][2] ;
if ( a ) *a = colour[which][3] ;
}
void setUserData ( void *data ) { user_data = data ; }
void *getUserData ( void ) { return user_data ; }
void defaultValue ( void ) { setValue ( & default_value ) ; }
void setDefaultValue ( int i ) { default_value . setValue ( i ) ; }
void setDefaultValue ( float f ) { default_value . setValue ( f ) ; }
void setDefaultValue ( char *s ) { default_value . setValue ( s ) ; }
void getDefaultValue ( int *i ) { default_value . getValue ( i ) ; }
void getDefaultValue ( float *f ) { default_value . getValue ( f ) ; }
void getDefaultValue ( char **s ) { default_value . getValue ( s ) ; }
int getDefaultValue ( void ) { return default_value . getValue () ; }
} ;
/*
The 'live' interface stack is used for clicking and rendering.
*/
void puPushLiveInterface ( puInterface *in ) ;
void puPopLiveInterface ( void ) ;
int puNoLiveInterface ( void ) ;
puInterface *puGetBaseLiveInterface ( void ) ;
puInterface *puGetUltimateLiveInterface ( void ) ;
/*
The regular interface stack is used for adding widgets
*/
void puPushInterface ( puInterface *in ) ;
void puPopInterface ( void ) ;
int puNoInterface ( void ) ;
puInterface *puGetCurrInterface ( void ) ;
class puInterface : public puObject
{
protected:
int num_children ;
puObject *dlist ;
void doHit ( int button, int updown, int x, int y ) ;
public:
puInterface ( int x, int y ) : puObject ( x, y, x, y )
{
type |= PUCLASS_INTERFACE ;
dlist = NULL ;
num_children = 0 ;
puPushInterface ( this ) ;
puPushLiveInterface ( this ) ;
}
~puInterface () ;
void recalc_bbox ( void ) ;
virtual void add ( puObject *new_object ) ;
virtual void remove ( puObject *old_object ) ;
void draw ( int dx, int dy ) ;
int checkHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key , int updown ) ;
puObject *getFirstChild ( void ) { return dlist ; }
int getNumChildren ( void ) { return num_children ; }
virtual void close ( void )
{
if ( puGetCurrInterface () != this )
fprintf ( stderr, "PUI: puInterface::close() is mismatched!\n" ) ;
else
puPopInterface () ;
}
} ;
class puFrame : public puObject
{
protected:
virtual int isHit ( int /* x */, int /* y */ ) { return FALSE ; }
public:
void draw ( int dx, int dy ) ;
puFrame ( int minx, int miny, int maxx, int maxy ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_FRAME ;
}
} ;
class puText : public puObject
{
protected:
virtual int isHit ( int /* x */, int /* y */ ) { return FALSE ; }
public:
void draw ( int dx, int dy ) ;
puText ( int x, int y ) : puObject ( x, y, x, y )
{
type |= PUCLASS_TEXT ;
}
} ;
class puButton : public puObject
{
protected:
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
puButton ( int minx, int miny, char *l ) :
puObject ( minx, miny,
minx + puGetStringWidth ( NULL, l ) + PUSTR_LGAP + PUSTR_RGAP,
miny + puGetStringHeight () + puGetStringDescender () + PUSTR_TGAP + PUSTR_BGAP )
{
type |= PUCLASS_BUTTON ;
setLegend ( l ) ;
}
puButton ( int minx, int miny, int maxx, int maxy ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_BUTTON ;
}
} ;
class puSlider : public puObject
{
protected:
int vert ;
float last_cb_value ;
float cb_delta ;
int cb_mode ;
float slider_fraction ;
public:
void doHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
puSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puObject ( minx, miny, vertical ?
( minx + puGetStringWidth ( NULL, "W" ) +
PUSTR_LGAP + PUSTR_RGAP ) :
( minx + sz ),
vertical ?
( miny + sz ) :
( miny + puGetStringHeight () +
puGetStringDescender () +
PUSTR_TGAP + PUSTR_BGAP )
)
{
type |= PUCLASS_SLIDER ;
slider_fraction = 0.1f ;
getValue ( & last_cb_value ) ;
vert = vertical ;
cb_delta = 0.1f ;
cb_mode = PUSLIDER_ALWAYS ;
}
void setCBMode ( int m ) { cb_mode = m ; }
float getCBMode ( void ) { return (float)cb_mode ; }
int isVertical ( void ) { return vert ; }
void setDelta ( float f ) { cb_delta = (f<=0.0f) ? 0.1f : (f>=1.0f) ? 0.9f : f ; }
float getDelta ( void ) { return cb_delta ; }
void setSliderFraction ( float f ) { slider_fraction = (f<=0.0f) ? 0.1f : (f>=1.0f) ? 0.9f : f ; }
float getSliderFraction ( void ) { return slider_fraction ; }
} ;
class puOneShot : public puButton
{
protected:
public:
void doHit ( int button, int updown, int x, int y ) ;
puOneShot ( int minx, int miny, char *l ) : puButton ( minx, miny, l )
{
type |= PUCLASS_ONESHOT ;
}
puOneShot ( int minx, int miny, int maxx, int maxy ) :
puButton ( minx, miny, maxx, maxy )
{
type |= PUCLASS_ONESHOT ;
}
} ;
class puPopup : public puInterface
{
protected:
public:
puPopup ( int x, int y ) : puInterface ( x, y )
{
type |= PUCLASS_POPUP ;
hide () ;
}
} ;
class puPopupMenu : public puPopup
{
protected:
public:
puPopupMenu ( int x, int y ) : puPopup ( x, y )
{
type |= PUCLASS_POPUPMENU ;
}
puObject *add_item ( char *str, puCallback cb ) ;
int checkHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key , int updown ) ;
void close ( void ) ;
} ;
class puMenuBar : public puInterface
{
protected:
public:
puMenuBar ( int h = -1 ) :
puInterface ( 0, h < 0 ? puGetWindowHeight() -
( puGetStringHeight() + PUSTR_TGAP + PUSTR_BGAP ) : h )
{
type |= PUCLASS_MENUBAR ;
}
void add_submenu ( char *str, char *items[], puCallback cb[] ) ;
void close ( void ) ;
} ;
class puInput : public puObject
{
int accepting ;
int cursor_position ;
int select_start_position ;
int select_end_position ;
void normalize_cursors ( void ) ;
public:
void draw ( int dx, int dy ) ;
void doHit ( int button, int updown, int x, int y ) ;
int checkKey ( int key, int updown ) ;
int isAcceptingInput ( void ) { return accepting ; }
void rejectInput ( void ) { accepting = FALSE ; }
void acceptInput ( void ) { accepting = TRUE ;
cursor_position = strlen ( string ) ;
select_start_position = select_end_position = -1 ; }
int getCursor ( void ) { return cursor_position ; }
void setCursor ( int c ) { cursor_position = c ; }
void setSelectRegion ( int s, int e )
{
select_start_position = s ;
select_end_position = e ;
}
void getSelectRegion ( int *s, int *e )
{
if ( s ) *s = select_start_position ;
if ( e ) *e = select_end_position ;
}
puInput ( int minx, int miny, int maxx, int maxy ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_INPUT ;
accepting = FALSE ;
cursor_position = 0 ;
select_start_position = -1 ;
select_end_position = -1 ;
setColourScheme ( 0.8f, 0.7f, 0.7f ) ; /* Yeukky Pink */
}
} ;
class puButtonBox : public puObject
{
protected:
int one_only ;
int num_kids ;
char **button_labels ;
public:
puButtonBox ( int minx, int miny, int maxx, int maxy,
char **labels, int one_button ) ;
int isOneButton ( void ) { return one_only ; }
int checkKey ( int key , int updown ) ;
int checkHit ( int button, int updown, int x, int y ) ;
void draw ( int dx, int dy ) ;
} ;
class puDialogBox : public puPopup
{
protected:
public:
puDialogBox ( int x, int y ) : puPopup ( x, y )
{
type |= PUCLASS_DIALOGBOX ;
}
} ;
#endif

319
Lib/PUI/puBox.cxx Normal file
View file

@ -0,0 +1,319 @@
#include "puLocal.h"
#define PU_BEVEL 5
#define PU_SMALL_BEVEL 2
#define PU_DFLT_OFFSET 8
#define PU_BOX_WIDTH 2
#define PU_DROPSHADOW_OFFSET 5
void puBox::extend ( puBox *bx )
{
if ( bx -> isEmpty () ) return ;
if ( min[0]>bx->min[0] ) min[0] = bx->min[0] ;
if ( min[1]>bx->min[1] ) min[1] = bx->min[1] ;
if ( max[0]<bx->max[0] ) max[0] = bx->max[0] ;
if ( max[1]<bx->max[1] ) max[1] = bx->max[1] ;
}
void puBox::draw ( int dx, int dy, int style, puColour colour[], int am_default )
{
int hi, mid, lo ;
/* Colour assignments */
switch ( style )
{
case PUSTYLE_NONE :
return ;
case PUSTYLE_PLAIN :
case PUSTYLE_DROPSHADOW :
mid = PUCOL_FOREGROUND ;
lo = PUCOL_BACKGROUND ;
break ;
case PUSTYLE_SMALL_SHADED :
case PUSTYLE_SHADED :
case PUSTYLE_SMALL_BEVELLED :
case PUSTYLE_BEVELLED :
case PUSTYLE_BOXED :
case PUSTYLE_SPECIAL_UNDERLINED :
mid = PUCOL_FOREGROUND ;
hi = PUCOL_HIGHLIGHT ;
lo = PUCOL_BACKGROUND ;
break ;
case PUSTYLE_RADIO :
case -PUSTYLE_RADIO :
hi = PUCOL_HIGHLIGHT ;
lo = PUCOL_BACKGROUND ;
break ;
case -PUSTYLE_PLAIN :
case -PUSTYLE_DROPSHADOW :
mid = PUCOL_HIGHLIGHT ;
lo = PUCOL_BACKGROUND ;
break ;
case -PUSTYLE_SMALL_BEVELLED :
case -PUSTYLE_BEVELLED :
case -PUSTYLE_SMALL_SHADED :
case -PUSTYLE_SHADED :
case -PUSTYLE_BOXED :
case -PUSTYLE_SPECIAL_UNDERLINED :
mid = PUCOL_FOREGROUND ;
hi = PUCOL_BACKGROUND ;
lo = PUCOL_HIGHLIGHT ;
break ;
default :
fprintf ( stderr, "PUI: Unrecognised 'style' %d\n", style ) ;
return ;
}
switch ( abs(style) )
{
case PUSTYLE_PLAIN :
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + max[1] ) ;
break ;
case PUSTYLE_SMALL_BEVELLED :
case PUSTYLE_SMALL_SHADED :
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
glVertex2i ( dx + min[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glEnd () ;
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0], dy + min[1] ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
glEnd () ;
if ( abs(style) == PUSTYLE_SMALL_BEVELLED )
{
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0] + PU_SMALL_BEVEL, dy + min[1] + PU_SMALL_BEVEL,
dx + max[0] - PU_SMALL_BEVEL, dy + max[1] - PU_SMALL_BEVEL ) ;
}
else
{
glShadeModel(GL_SMOOTH);
glBegin(GL_POLYGON);
glColor4fv( colour [ mid ] );
glVertex2i( dx + min[0] + PU_SMALL_BEVEL , dy + min[1] + PU_SMALL_BEVEL );
if(style==PUSTYLE_SMALL_SHADED)
glColor4f( colour [mid][0] + (colour[lo][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[lo][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[lo][2] - colour[mid][2])/2.0f,
colour [lo][3] );
else
glColor4f( colour [mid][0] + (colour[hi][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[hi][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[hi][2] - colour[mid][2])/2.0f,
colour [hi][3] );
glVertex2i( dx + min[0] + PU_SMALL_BEVEL , dy + max[1] - PU_SMALL_BEVEL );
glColor4fv( colour [ mid ] );
glVertex2i( dx + max[0] - PU_SMALL_BEVEL , dy + max[1] - PU_SMALL_BEVEL );
if(style==-PUSTYLE_SMALL_SHADED)
glColor4f( colour [mid][0] + (colour[lo][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[lo][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[lo][2] - colour[mid][2])/2.0f,
colour [lo][3] );
else
glColor4f( colour [mid][0] + (colour[hi][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[hi][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[hi][2] - colour[mid][2])/2.0f,
colour [hi][3] );
glVertex2i( dx + max[0] - PU_SMALL_BEVEL , dy + min[1] + PU_SMALL_BEVEL );
glEnd();
glShadeModel(GL_FLAT);
if(style == -PUSTYLE_SMALL_SHADED)
{
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL , dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL/2 , dy + min[1] + PU_SMALL_BEVEL/2 ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL , dy + max[1] - PU_SMALL_BEVEL ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL/2 , dy + max[1] - PU_SMALL_BEVEL/2 ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL , dy + max[1] - PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL/2 , dy + max[1] - PU_SMALL_BEVEL/2 ) ;
glEnd () ;
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL/2 , dy + min[1] + PU_SMALL_BEVEL/2 ) ;
glVertex2i ( dx + min[0] + PU_SMALL_BEVEL , dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL/2 , dy + min[1] + PU_SMALL_BEVEL/2 ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL , dy + min[1] + PU_SMALL_BEVEL ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL/2 , dy + max[1] - PU_SMALL_BEVEL/2 ) ;
glVertex2i ( dx + max[0] - PU_SMALL_BEVEL , dy + max[1] - PU_SMALL_BEVEL ) ;
glEnd () ;
}
}
break ;
case PUSTYLE_BEVELLED :
case PUSTYLE_SHADED :
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_BEVEL, dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
glVertex2i ( dx + min[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glEnd () ;
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0], dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_BEVEL, dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + max[0], dy + min[1] ) ;
glVertex2i ( dx + max[0] - PU_BEVEL, dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + max[0], dy + max[1] ) ;
glVertex2i ( dx + max[0] - PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
glEnd () ;
if ( abs(style) == PUSTYLE_BEVELLED )
{
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0] + PU_BEVEL, dy + min[1] + PU_BEVEL,
dx + max[0] - PU_BEVEL, dy + max[1] - PU_BEVEL ) ;
}
else
{
glShadeModel(GL_SMOOTH);
glBegin(GL_POLYGON);
glColor4fv( colour [ mid ] );
glVertex2i( dx + min[0] + PU_BEVEL , dy + min[1] + PU_BEVEL );
if(style==PUSTYLE_SHADED)
glColor4f( colour [mid][0] + (colour[lo][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[lo][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[lo][2] - colour[mid][2])/2.0f,
colour [lo][3] );
else
glColor4f( colour [mid][0] + (colour[hi][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[hi][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[hi][2] - colour[mid][2])/2.0f,
colour [hi][3] );
glVertex2i( dx + min[0] + PU_BEVEL , dy + max[1] - PU_BEVEL );
glColor4fv( colour [ mid ] );
glVertex2i( dx + max[0] - PU_BEVEL , dy + max[1] - PU_BEVEL );
if(style==-PUSTYLE_SHADED)
glColor4f( colour [mid][0] + (colour[lo][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[lo][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[lo][2] - colour[mid][2])/2.0f,
colour [lo][3] );
else
glColor4f( colour [mid][0] + (colour[hi][0] - colour[mid][0])/2.0f,
colour [mid][1] + (colour[hi][1] - colour[mid][1])/2.0f,
colour [mid][2] + (colour[hi][2] - colour[mid][2])/2.0f,
colour [hi][3] );
glVertex2i( dx + max[0] - PU_BEVEL , dy + min[1] + PU_BEVEL );
glEnd();
glShadeModel(GL_FLAT);
if(style == -PUSTYLE_SHADED)
{
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_BEVEL , dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + min[0] + PU_BEVEL/2 , dy + min[1] + PU_BEVEL/2 ) ;
glVertex2i ( dx + min[0] + PU_BEVEL , dy + max[1] - PU_BEVEL ) ;
glVertex2i ( dx + min[0] + PU_BEVEL/2 , dy + max[1] - PU_BEVEL/2 ) ;
glVertex2i ( dx + max[0] - PU_BEVEL , dy + max[1] - PU_BEVEL ) ;
glVertex2i ( dx + max[0] - PU_BEVEL/2 , dy + max[1] - PU_BEVEL/2 ) ;
glEnd () ;
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUAD_STRIP ) ;
glVertex2i ( dx + min[0] + PU_BEVEL/2 , dy + min[1] + PU_BEVEL/2 ) ;
glVertex2i ( dx + min[0] + PU_BEVEL , dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + max[0] - PU_BEVEL/2 , dy + min[1] + PU_BEVEL/2 ) ;
glVertex2i ( dx + max[0] - PU_BEVEL , dy + min[1] + PU_BEVEL ) ;
glVertex2i ( dx + max[0] - PU_BEVEL/2 , dy + max[1] - PU_BEVEL/2 ) ;
glVertex2i ( dx + max[0] - PU_BEVEL , dy + max[1] - PU_BEVEL ) ;
glEnd () ;
}
}
break ;
case PUSTYLE_BOXED :
glColor4fv ( colour [ hi ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + max[1] ) ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0]+PU_BOX_WIDTH, dy + min[1]+PU_BOX_WIDTH,
dx + max[0]-PU_BOX_WIDTH, dy + max[1]-PU_BOX_WIDTH ) ;
break ;
case PUSTYLE_RADIO :
glColor4fv ( colour [ lo ] ) ;
glBegin ( GL_LINE_LOOP ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + PU_RADIO_BUTTON_SIZE ) ;
glVertex2i ( dx + min[0] , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glEnd () ;
if ( style < 0 )
{
glColor4fv ( colour [ hi ] ) ;
glBegin ( GL_QUADS ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + 2 ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE-2, dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glVertex2i ( dx + min[0] + PU_RADIO_BUTTON_SIZE/2, dy + min[1] + PU_RADIO_BUTTON_SIZE-2 ) ;
glVertex2i ( dx + min[0] + 2 , dy + min[1] + PU_RADIO_BUTTON_SIZE/2 ) ;
glEnd () ;
}
break ;
case PUSTYLE_SPECIAL_UNDERLINED :
glColor4fv ( colour [ hi ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + min[1]+2 ) ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0], dy + min[1]+1,
dx + max[0], dy + max[1] ) ;
break ;
case PUSTYLE_DROPSHADOW :
glColor4fv ( colour [ lo ] ) ;
glRecti ( dx + min[0] + PU_DROPSHADOW_OFFSET, dy + min[1] - PU_DROPSHADOW_OFFSET,
dx + max[0] + PU_DROPSHADOW_OFFSET, dy + max[1] - PU_DROPSHADOW_OFFSET ) ;
glColor4fv ( colour [ mid ] ) ;
glRecti ( dx + min[0], dy + min[1],
dx + max[0], dy + max[1] ) ;
break ;
}
if ( am_default )
{
glColor4fv ( colour [ PUCOL_BACKGROUND ] ) ;
glLineStipple ( 1, 0xF0F0 ) ;
glEnable ( GL_LINE_STIPPLE ) ;
glBegin ( GL_LINE_LOOP ) ;
glVertex2i ( dx + min[0] + PU_DFLT_OFFSET, dy + min[1] + PU_DFLT_OFFSET ) ;
glVertex2i ( dx + min[0] + PU_DFLT_OFFSET, dy + max[1] - PU_DFLT_OFFSET ) ;
glVertex2i ( dx + max[0] - PU_DFLT_OFFSET, dy + max[1] - PU_DFLT_OFFSET ) ;
glVertex2i ( dx + max[0] - PU_DFLT_OFFSET, dy + min[1] + PU_DFLT_OFFSET ) ;
glEnd () ;
glDisable ( GL_LINE_STIPPLE ) ;
}
}

61
Lib/PUI/puButton.cxx Normal file
View file

@ -0,0 +1,61 @@
#include "puLocal.h"
void puButton::draw ( int dx, int dy )
{
if ( !visible ) return ;
/* If button is pushed or highlighted - use inverse style for button itself */
int tempStyle;
if ( parent && ( ( parent->getType() & PUCLASS_POPUPMENU ) ||
( parent->getType() & PUCLASS_MENUBAR ) ) )
tempStyle = ( getValue() ^ highlighted ) ? PUSTYLE_SMALL_SHADED : style ;
else
tempStyle = ( getValue() ^ highlighted ) ? -style : style ;
abox . draw ( dx, dy, tempStyle, colour, isReturnDefault() ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */
int xx = ( abox.max[0] - abox.min[0] - puGetStringWidth(legendFont,legend) ) / 2 ;
int yy = ( abox.max[1] - abox.min[1] - puGetStringHeight(legendFont) ) / 2 ;
puDrawString ( legendFont, legend,
dx + abox.min[0] + xx,
dy + abox.min[1] + yy ) ;
draw_label ( dx, dy ) ;
}
void puButton::doHit ( int button, int updown, int, int )
{
if ( button == PU_LEFT_BUTTON )
{
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
{
lowlight () ;
setValue ( (int) ! getValue () ) ;
invokeCallback () ;
}
else
highlight () ;
}
else
lowlight () ;
}

100
Lib/PUI/puButtonBox.cxx Normal file
View file

@ -0,0 +1,100 @@
#include "puLocal.h"
puButtonBox::puButtonBox ( int minx, int miny, int maxx, int maxy,
char **labels, int one_button ) :
puObject ( minx, miny, maxx, maxy )
{
type |= PUCLASS_BUTTONBOX ;
one_only = one_button ;
button_labels = labels ;
for ( num_kids = 0 ; button_labels [ num_kids ] != NULL ; num_kids++ )
/* Count number of labels */ ;
}
int puButtonBox::checkKey ( int key, int updown )
{
if ( updown == PU_UP ||
! isReturnDefault() ||
( key != '\r' && key != '\n' ) )
return FALSE ;
int v = getValue () ;
if ( ! one_only )
v = ~v ;
else
if ( v++ > num_kids )
v = 0 ;
setValue ( v ) ;
invokeCallback() ;
return TRUE ;
}
int puButtonBox::checkHit ( int button, int updown, int x, int y )
{
if ( ! isHit ( x, y ) ||
( updown != active_mouse_edge &&
active_mouse_edge != PU_UP_AND_DOWN ) )
return FALSE ;
int i = num_kids - 1 - (( y - abox.min[1] - PUSTR_BGAP ) * num_kids ) /
( abox.max[1] - abox.min[1] - PUSTR_BGAP - PUSTR_TGAP ) ;
if ( i < 0 ) i = 0 ;
if ( i >= num_kids ) i = num_kids - 1 ;
if ( one_only )
setValue ( i ) ;
else
setValue ( getValue () ^ ( 1 << i ) ) ;
invokeCallback () ;
return TRUE ;
}
void puButtonBox::draw ( int dx, int dy )
{
if ( !visible ) return ;
abox . draw ( dx, dy, style, colour, isReturnDefault() ) ;
for ( int i = 0 ; i < num_kids ; i++ )
{
puBox tbox ;
tbox . min [ 0 ] = abox.min [ 0 ] + PUSTR_LGAP + PUSTR_LGAP ;
tbox . min [ 1 ] = abox.min [ 1 ] + ((abox.max[1]-abox.min[1]-PUSTR_TGAP-PUSTR_BGAP)/num_kids) * (num_kids-1-i) ;
tbox . max [ 0 ] = tbox.min [ 0 ] ;
tbox . max [ 1 ] = tbox.min [ 1 ] ;
if (( one_only && i == getValue() ) ||
( !one_only && ((1<<i) & getValue() ) != 0 ) )
tbox . draw ( dx, dy + PUSTR_BGAP + PUSTR_BGAP, -PUSTYLE_RADIO, colour, FALSE ) ;
else
tbox . draw ( dx, dy + PUSTR_BGAP + PUSTR_BGAP, PUSTYLE_RADIO, colour, FALSE ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */
puDrawString ( legendFont, button_labels[i],
dx + tbox.min[0] + PU_RADIO_BUTTON_SIZE + PUSTR_LGAP,
dy + tbox.min[1] + puGetStringDescender(legendFont) + PUSTR_BGAP + PUSTR_BGAP) ;
}
draw_label ( dx, dy ) ;
}

4
Lib/PUI/puDialogBox.cxx Normal file
View file

@ -0,0 +1,4 @@
#include "puLocal.h"

30
Lib/PUI/puFrame.cxx Normal file
View file

@ -0,0 +1,30 @@
#include "puLocal.h"
void puFrame::draw ( int dx, int dy )
{
if ( !visible ) return ;
abox . draw ( dx, dy, style, colour, FALSE ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */
int xx = ( abox.max[0] - abox.min[0] - puGetStringWidth ( legendFont, legend ) ) / 2 ;
puDrawString ( legendFont, legend,
dx + abox.min[0] + xx,
dy + abox.min[1] + puGetStringDescender ( legendFont ) + PUSTR_BGAP ) ;
draw_label ( dx, dy ) ;
}

226
Lib/PUI/puInput.cxx Normal file
View file

@ -0,0 +1,226 @@
#include "puLocal.h"
void puInput::normalize_cursors ( void )
{
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
int sl = strlen ( val ) ;
/* Clamp the positions to the limits of the text. */
if ( cursor_position < 0 ) cursor_position = 0 ;
if ( select_start_position < 0 ) select_start_position = 0 ;
if ( select_end_position < 0 ) select_end_position = 0 ;
if ( cursor_position > sl ) cursor_position = sl ;
if ( select_start_position > sl ) select_start_position = sl ;
if ( select_end_position > sl ) select_end_position = sl ;
/* Swap the ends of the select window if they get crossed over */
if ( select_end_position < select_start_position )
{
int tmp = select_end_position ;
select_end_position = select_start_position ;
select_start_position = tmp ;
}
}
void puInput::draw ( int dx, int dy )
{
normalize_cursors () ;
if ( !visible ) return ;
/* 3D Input boxes look nicest if they are always in inverse style. */
abox . draw ( dx, dy, ( (style==PUSTYLE_SMALL_BEVELLED ||
style==PUSTYLE_SMALL_SHADED) ) ? -style :
(accepting ? -style : style ), colour, FALSE ) ;
int xx = puGetStringWidth ( legendFont, " " ) ;
int yy = ( abox.max[1] - abox.min[1] - puGetStringHeight(legendFont) ) / 2 ;
if ( accepting )
{
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
/* Highlight the select area */
if ( select_end_position > 0 &&
select_end_position != select_start_position )
{
val [ select_end_position ] = '\0' ;
int cpos2 = puGetStringWidth ( legendFont, val ) + xx + dx + abox.min[0] ;
val [ select_start_position ] = '\0' ;
int cpos1 = puGetStringWidth ( legendFont, val ) + xx + dx + abox.min[0] ;
glColor3f ( 1.0f, 1.0f, 0.7f ) ;
glRecti ( cpos1, dy + abox.min[1] + 6 ,
cpos2, dy + abox.max[1] - 6 ) ;
}
}
/* Draw the text */
{
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
puDrawString ( legendFont, val,
dx + abox.min[0] + xx,
dy + abox.min[1] + yy ) ;
draw_label ( dx, dy ) ;
}
if ( accepting )
{
char val [ PUSTRING_MAX ] ;
getValue ( val ) ;
/* Draw the 'I' bar cursor. */
if ( cursor_position >= 0 )
{
val [ cursor_position ] = '\0' ;
int cpos = puGetStringWidth ( legendFont, val ) + xx + dx + abox.min[0] ;
glColor3f ( 0.1f, 0.1f, 1.0f ) ;
glBegin ( GL_LINES ) ;
glVertex2i ( cpos , dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos , dy + abox.max[1] - 7 ) ;
glVertex2i ( cpos - 1, dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos - 1, dy + abox.max[1] - 7 ) ;
glVertex2i ( cpos - 4, dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos + 3, dy + abox.min[1] + 7 ) ;
glVertex2i ( cpos - 4, dy + abox.max[1] - 7 ) ;
glVertex2i ( cpos + 3, dy + abox.max[1] - 7 ) ;
glEnd () ;
}
}
}
void puInput::doHit ( int button, int updown, int x, int /* y */ )
{
if ( button == PU_LEFT_BUTTON )
{
/* Most GUI's activate a button on button-UP not button-DOWN. */
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
{
lowlight () ;
char *strval ;
getValue ( & strval ) ;
char *tmpval = new char [ strlen(strval) + 1 ] ;
strcpy ( tmpval, strval ) ;
int i = strlen ( tmpval ) ;
while ( x <= puGetStringWidth ( legendFont, tmpval ) + abox.min[0] &&
i >= 0 )
tmpval[--i] = '\0' ;
accepting = TRUE ;
cursor_position = i ;
normalize_cursors () ;
invokeCallback () ;
}
else
highlight () ;
}
else
lowlight () ;
}
int puInput::checkKey ( int key, int updown )
{
(updown,updown);
if ( ! isAcceptingInput() || ! isActive () || ! isVisible () )
return FALSE ;
normalize_cursors () ;
char *p ;
switch ( key )
{
case PU_KEY_PAGE_UP :
case PU_KEY_PAGE_DOWN :
case PU_KEY_INSERT : return FALSE ;
case PU_KEY_UP :
case PU_KEY_DOWN :
case 0x1B /* ESC */ :
case '\t' :
case '\r' :
case '\n' : /* Carriage return/Line Feed/TAB -- End of input */
rejectInput () ;
normalize_cursors () ;
invokeCallback () ;
break ;
case '\b' : /* Backspace */
if ( cursor_position > 0 )
for ( p = & string [ --cursor_position ] ; *p != '\0' ; p++ )
*p = *(p+1) ;
break ;
case 0x7F : /* DEL */
if ( select_start_position != select_end_position )
{
char *p1 = & string [ select_start_position ] ;
char *p2 = & string [ select_end_position ] ;
while ( *p1 != '\0' )
*p1++ = *p2++ ;
select_end_position = select_start_position ;
}
else
for ( p = & string [ cursor_position ] ; *p != '\0' ; p++ )
*p = *(p+1) ;
break ;
case 0x15 /* ^U */ : string [ 0 ] = '\0' ; break ;
case PU_KEY_HOME : cursor_position = 0 ; break ;
case PU_KEY_END : cursor_position = PUSTRING_MAX ; break ;
case PU_KEY_LEFT : cursor_position-- ; break ;
case PU_KEY_RIGHT : cursor_position++ ; break ;
default:
if ( key < ' ' || key > 127 ) return FALSE ;
if ( strlen ( string ) >= PUSTRING_MAX )
return FALSE ;
for ( p = & string [ strlen(string) ] ;
p != &string[cursor_position] ; p-- )
*(p+1) = *p ;
*p = key ;
cursor_position++ ;
break ;
}
setValue ( string ) ;
normalize_cursors () ;
return TRUE ;
}

268
Lib/PUI/puInterface.cxx Normal file
View file

@ -0,0 +1,268 @@
#include "puLocal.h"
#define PUSTACK_MAX 100
static int currLiveInterface = -1 ;
static puInterface *liveInterfaceStack [ PUSTACK_MAX ] ;
static int currInterface = -1 ;
static puInterface *interfaceStack [ PUSTACK_MAX ] ;
void puPushLiveInterface ( puInterface *in )
{
if ( currLiveInterface < PUSTACK_MAX )
liveInterfaceStack [ ++currLiveInterface ] = in ;
else
fprintf ( stderr, "PUI: Too many live puInterfaces open at once!\n" ) ;
}
void puPushInterface ( puInterface *in )
{
if ( currInterface < PUSTACK_MAX )
interfaceStack [ ++currInterface ] = in ;
else
fprintf ( stderr, "PUI: Too many puInterfaces open at once!\n" ) ;
}
void puPopLiveInterface ( void )
{
if ( currLiveInterface > 0 )
--currLiveInterface ;
else
fprintf ( stderr, "PUI: Live puInterface stack is empty!\n" ) ;
}
void puPopInterface ( void )
{
if ( currInterface > 0 )
--currInterface ;
else
fprintf ( stderr, "PUI: puInterface stack is empty!\n" ) ;
}
int puNoLiveInterface ( void )
{
return currLiveInterface < 0 ;
}
int puNoInterface ( void )
{
return currInterface < 0 ;
}
puInterface *puGetUltimateLiveInterface ( void )
{
if ( currLiveInterface < 0 )
{
fprintf ( stderr, "PUI: No Live Interface!\n" ) ;
return NULL ;
}
return liveInterfaceStack [ 0 ] ;
}
puInterface *puGetBaseLiveInterface ( void )
{
if ( currLiveInterface < 0 )
{
fprintf ( stderr, "PUI: No Live Interface!\n" ) ;
return NULL ;
}
/*
Work down the interface stack until you
either get to the bottom or find a block
in the form of a puDialogBox.
*/
for ( int i = currLiveInterface ; i > 0 ; i-- )
if ( liveInterfaceStack [ i ] -> getType () & PUCLASS_DIALOGBOX )
return liveInterfaceStack [ i ] ;
return liveInterfaceStack [ 0 ] ;
}
puInterface *puGetCurrInterface ( void )
{
if ( currInterface < 0 )
{
fprintf ( stderr, "PUI: No Interface!\n" ) ;
return NULL ;
}
return interfaceStack [ currInterface ] ;
}
void puInterface::remove ( puObject *obj )
{
if ( dlist == NULL )
return ;
/* Are we the first object in the list */
if ( obj -> prev == NULL )
dlist = obj -> next ;
else
obj -> prev -> next = obj -> next ;
/* Are we the last object in the list */
if ( obj -> next != NULL )
obj -> next -> prev = obj -> prev ;
obj -> next = NULL ;
obj -> prev = NULL ;
num_children-- ;
recalc_bbox () ;
}
void puInterface::add ( puObject *new_obj )
{
if ( dlist == NULL )
{
dlist = new_obj ;
new_obj -> next = NULL ;
new_obj -> prev = NULL ;
}
else
{
puObject *last ;
for ( last = dlist ; last->next != NULL ; last = last->next )
/* Search for end of list. */ ;
last -> next = new_obj ;
new_obj -> prev = last ;
new_obj -> next = NULL ;
}
num_children++ ;
recalc_bbox () ;
}
int puInterface::checkKey ( int key, int updown )
{
if ( dlist == NULL || ! isVisible () || ! isActive () )
return FALSE ;
puObject *bo ;
/*
We have to walk the list backwards to ensure that
the click order is the same as the DRAW order.
*/
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
/* Find the last object in our list. */ ;
for ( ; bo != NULL ; bo = bo->prev )
if ( bo -> checkKey ( key, updown ) )
return TRUE ;
return FALSE ;
}
int puInterface::checkHit ( int button, int updown, int x, int y )
{
if ( dlist == NULL || ! isVisible () || ! isActive () )
return FALSE ;
/*
This might be a bit redundant - but it's too hard to keep
track of changing abox sizes when daughter objects are
changing sizes.
*/
recalc_bbox () ;
puObject *bo ;
x -= abox.min[0] ;
y -= abox.min[1] ;
/*
We have to walk the list backwards to ensure that
the click order is the same as the DRAW order.
*/
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
/* Find the last object in our list. */ ;
for ( ; bo != NULL ; bo = bo->prev )
if ( bo -> checkHit ( button, updown, x, y ) )
return TRUE ;
return FALSE ;
}
void puInterface::draw ( int dx, int dy )
{
if ( ! isVisible () )
return ;
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
{
/* June 16th, 98, Shammi :
* The next if statement checks if the object is
* a menu bar and makes sure it is repositioned
* correctly.
*/
if ( bo->getType() & PUCLASS_MENUBAR )
{
int obWidth, obHeight ;
bo -> getSize ( &obWidth, &obHeight ) ;
bo -> setPosition ( 0, puGetWindowHeight() - obHeight ) ;
}
bo -> draw ( dx + abox.min[0], dy + abox.min[1] ) ;
}
}
void puInterface::recalc_bbox ( void )
{
puBox contents ;
contents . empty () ;
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
contents . extend ( bo -> getBBox() ) ;
if ( contents . isEmpty () )
{
abox . max[0] = abox . min[0] ;
abox . max[1] = abox . min[1] ;
}
else
{
abox . max[0] = abox . min[0] + contents . max[0] ;
abox . max[1] = abox . min[1] + contents . max[1] ;
}
puObject::recalc_bbox () ;
}
void puInterface::doHit ( int, int, int, int )
{
}
puInterface::~puInterface ()
{
puPopLiveInterface () ;
puObject *bo = dlist ;
while ( bo != NULL ) {
puObject *tmp_bo = bo->next ;
delete bo ;
bo = tmp_bo ;
}
}

19
Lib/PUI/puLocal.h Normal file
View file

@ -0,0 +1,19 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
#include <math.h>
#ifndef PU_NOT_USING_GLUT
#include <GL/glut.h>
#endif
#include "pu.h"

83
Lib/PUI/puMenuBar.cxx Normal file
View file

@ -0,0 +1,83 @@
#include "puLocal.h"
void drop_down_the_menu ( puObject *b )
{
puPopupMenu *p = (puPopupMenu *) b -> getUserData () ;
if ( b -> getValue () )
p->reveal () ;
else
p->hide () ;
for ( puObject *child = b -> getParent () -> getFirstChild () ;
child != NULL ; child = child -> next )
{
if (( child -> getType() & PUCLASS_BUTTON ) != 0 && child != b ) child -> clrValue () ;
if (( child -> getType() & PUCLASS_POPUPMENU ) != 0 && child != p ) child -> hide () ;
}
}
void puMenuBar::add_submenu ( char *str, char *items[], puCallback cb[] )
{
int w, h ;
getSize ( &w, &h ) ;
puOneShot *b = new puOneShot ( w+10, 0, str ) ;
b -> setStyle ( PUSTYLE_SPECIAL_UNDERLINED ) ;
b -> setColourScheme ( colour[PUCOL_FOREGROUND][0],
colour[PUCOL_FOREGROUND][1],
colour[PUCOL_FOREGROUND][2],
colour[PUCOL_FOREGROUND][3] ) ;
b -> setCallback ( drop_down_the_menu ) ;
b -> setActiveDirn ( PU_UP_AND_DOWN ) ;
puPopupMenu *p = new puPopupMenu ( w+10, 0 ) ;
b -> setUserData ( p ) ;
for ( int i = 0 ; items[i] != NULL ; i++ )
p -> add_item ( items[i], cb[i] ) ;
p->close () ;
recalc_bbox () ;
}
void puMenuBar::close (void)
{
puInterface::close () ;
if ( dlist == NULL )
return ;
int width = 0 ;
puObject *ob ;
/*
Use alternate objects - which gets the puOneShot/puPopupMenu pairs
*/
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
{
int w, h ;
/* Reposition the button so it looks nice */
ob -> getSize ( &w, &h ) ;
ob -> setPosition ( width, 0 ) ;
ob = ob -> next ;
/* Reposition the submenu so it sits under the button */
int w2, h2 ;
ob -> getSize ( &w2, &h2 ) ;
ob -> setPosition ( width, -h2 ) ;
/* Next please! */
width += w ;
}
recalc_bbox () ;
}

222
Lib/PUI/puObject.cxx Normal file
View file

@ -0,0 +1,222 @@
#include "puLocal.h"
inline float clamp01 ( float x )
{
return (x >= 1.0f) ? 1.0f : x ;
}
static void load_colour_scheme ( float col[][4], float r, float g,
float b, float a )
{
puSetColour ( col [ PUCOL_FOREGROUND ], r, g, b, a ) ;
puSetColour ( col [ PUCOL_BACKGROUND ], r/2, g/2, b/2, a ) ;
puSetColour ( col [ PUCOL_HIGHLIGHT ], clamp01(r*1.3f), clamp01(g*1.3f),
clamp01(b*1.3f), a ) ;
if ( 4 * g + 3 * r + b > 0.5 )
puSetColour ( col [ PUCOL_LEGEND ], 0.0, 0.0, 0.0, a ) ;
else
puSetColour ( col [ PUCOL_LEGEND ], 1.0, 1.0, 1.0, a ) ;
}
static int defaultStyle = PUSTYLE_DEFAULT ;
static puFont defaultLegendFont = NULL ;
static puFont defaultLabelFont = NULL ;
static float defaultColourScheme [ 4 ] ;
void puSetDefaultStyle ( int style ) { defaultStyle = style ; }
int puGetDefaultStyle ( void ) { return defaultStyle ; }
void puSetDefaultFonts ( puFont legendFont, puFont labelFont )
{
defaultLegendFont = legendFont ;
defaultLabelFont = labelFont ;
}
void puGetDefaultFonts ( puFont *legendFont, puFont *labelFont )
{
if ( legendFont ) *legendFont = defaultLegendFont ;
if ( labelFont ) *labelFont = defaultLabelFont ;
}
void puSetDefaultColourScheme ( float r, float g, float b, float a )
{
defaultColourScheme[0] = r ;
defaultColourScheme[1] = g ;
defaultColourScheme[2] = b ;
defaultColourScheme[3] = a ;
load_colour_scheme ( _puDefaultColourTable, r, g, b, a ) ;
}
void puGetDefaultColourScheme ( float *r, float *g, float *b, float *a )
{
if ( r ) *r = defaultColourScheme[0] ;
if ( g ) *g = defaultColourScheme[1] ;
if ( b ) *b = defaultColourScheme[2] ;
if ( a ) *a = defaultColourScheme[3] ;
}
void puObject::setColourScheme ( float r, float g, float b, float a )
{
load_colour_scheme ( colour, r, g, b, a ) ;
}
puObject::puObject ( int minx, int miny, int maxx, int maxy ) : puValue ()
{
type |= PUCLASS_OBJECT ;
bbox.min[0] = abox.min[0] = minx ;
bbox.min[1] = abox.min[1] = miny ;
bbox.max[0] = abox.max[0] = maxx ;
bbox.max[1] = abox.max[1] = maxy ;
active_mouse_edge = PU_UP ;
style = defaultStyle ;
visible = active = TRUE ;
highlighted = FALSE ;
am_default = FALSE ;
cb = NULL ;
user_data = NULL ;
next = prev = NULL ;
label = NULL ;
labelPlace = PUPLACE_DEFAULT ;
labelFont = defaultLabelFont ;
legend = NULL ;
legendFont = defaultLegendFont ;
for ( int i = 0 ; i < PUCOL_MAX ; i++ )
puSetColour ( colour[i], _puDefaultColourTable[i] ) ;
if ( ! puNoInterface() )
{
parent = puGetCurrInterface() ;
parent -> add ( this ) ;
}
else
parent = NULL ;
}
puObject::~puObject ()
{
if ( parent != this && parent != NULL )
parent -> remove ( this ) ;
}
void puObject::recalc_bbox ( void )
{
bbox = abox ;
if ( label != NULL )
switch ( labelPlace )
{
case PUPLACE_ABOVE : bbox.max[1] += puGetStringHeight ( getLabelFont() ) + puGetStringDescender ( getLabelFont () ) + PUSTR_TGAP + PUSTR_BGAP ; break ;
case PUPLACE_BELOW : bbox.min[1] -= puGetStringHeight ( getLabelFont() ) + puGetStringDescender ( getLabelFont () ) + PUSTR_TGAP + PUSTR_BGAP ; break ;
case PUPLACE_LEFT : bbox.min[0] -= puGetStringWidth ( getLabelFont(), getLabel() ) + PUSTR_LGAP + PUSTR_RGAP ; break ;
case PUPLACE_RIGHT : bbox.max[0] += puGetStringWidth ( getLabelFont(), getLabel() ) + PUSTR_LGAP + PUSTR_RGAP ; break ;
}
if ( parent != NULL )
parent -> recalc_bbox () ;
}
void puObject::draw_label ( int dx, int dy )
{
if ( !visible ) return ;
/* If greyed out then halve the opacity when drawing the label */
if ( active )
glColor4fv ( colour [ PUCOL_LABEL ] ) ;
else
glColor4f ( colour [ PUCOL_LABEL ][0],
colour [ PUCOL_LABEL ][1],
colour [ PUCOL_LABEL ][2],
colour [ PUCOL_LABEL ][3] / 2.0f ) ; /* 50% more transparent */
switch ( labelPlace )
{
case PUPLACE_ABOVE : puDrawString ( labelFont, label, dx + abox.min[0] + PUSTR_LGAP, dy + abox.max[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
case PUPLACE_BELOW : puDrawString ( labelFont, label, dx + abox.min[0] + PUSTR_LGAP, dy + bbox.min[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
case PUPLACE_LEFT : puDrawString ( labelFont, label, dx + bbox.min[0] + PUSTR_LGAP, dy + abox.min[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
case PUPLACE_RIGHT : puDrawString ( labelFont, label, dx + abox.max[0] + PUSTR_LGAP, dy + abox.min[1] + puGetStringDescender(labelFont) + PUSTR_BGAP ) ; break ;
}
}
int puObject::checkKey ( int key, int updown )
{
if ( updown == PU_UP )
return FALSE ;
if ( isReturnDefault() && ( key == '\r' || key == '\n' ) )
{
checkHit ( PU_LEFT_BUTTON, PU_DOWN, (abox.min[0]+abox.max[0])/2,
(abox.min[1]+abox.max[1])/2 ) ;
checkHit ( PU_LEFT_BUTTON, PU_UP , (abox.min[0]+abox.max[0])/2,
(abox.min[1]+abox.max[1])/2 ) ;
return TRUE ;
}
return FALSE ;
}
void puObject::doHit ( int button, int updown, int x, int y )
{
(x,x);(y,y);
if ( button == PU_LEFT_BUTTON )
{
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN )
{
lowlight () ;
invokeCallback () ;
}
else
highlight () ;
}
else
lowlight () ;
}
int puObject::checkHit ( int button, int updown, int x, int y )
{
if ( isHit( x, y ) )
{
doHit ( button, updown, x, y ) ;
return TRUE ;
}
lowlight () ;
return FALSE ;
}
char *puValue::getTypeString ( void )
{
int i = getType () ;
if ( i & PUCLASS_DIALOGBOX ) return "puDialogBox" ;
if ( i & PUCLASS_SLIDER ) return "puSlider" ;
if ( i & PUCLASS_BUTTONBOX ) return "puButtonBox" ;
if ( i & PUCLASS_INPUT ) return "puInput" ;
if ( i & PUCLASS_MENUBAR ) return "puMenuBar" ;
if ( i & PUCLASS_POPUPMENU ) return "puPopupMenu" ;
if ( i & PUCLASS_POPUP ) return "puPopup" ;
if ( i & PUCLASS_ONESHOT ) return "puOneShot" ;
if ( i & PUCLASS_BUTTON ) return "puButton" ;
if ( i & PUCLASS_TEXT ) return "puText" ;
if ( i & PUCLASS_FRAME ) return "puFrame" ;
if ( i & PUCLASS_INTERFACE ) return "puInterface" ;
if ( i & PUCLASS_OBJECT ) return "puObject" ;
if ( i & PUCLASS_VALUE ) return "puValue" ;
return "Unknown Object type." ;
}

9
Lib/PUI/puOneShot.cxx Normal file
View file

@ -0,0 +1,9 @@
#include "puLocal.h"
void puOneShot::doHit ( int button, int updown, int x, int y )
{
puButton::doHit ( button, updown, x, y ) ;
setValue ( 0 ) ;
}

3
Lib/PUI/puPopup.cxx Normal file
View file

@ -0,0 +1,3 @@
#include "puLocal.h"

175
Lib/PUI/puPopupMenu.cxx Normal file
View file

@ -0,0 +1,175 @@
#include "puLocal.h"
#define PUMENU_BUTTON_HEIGHT 25
#define PUMENU_BUTTON_EXTRA_WIDTH 25
puObject *puPopupMenu::add_item ( char *str, puCallback cb )
{
int w, h ;
getSize ( &w, &h ) ;
puOneShot *b = new puOneShot ( 0, h, str ) ;
b->setStyle ( PUSTYLE_PLAIN ) ;
b->setColourScheme ( colour[PUCOL_FOREGROUND][0],
colour[PUCOL_FOREGROUND][1],
colour[PUCOL_FOREGROUND][2],
colour[PUCOL_FOREGROUND][3] ) ;
b->setCallback ( cb ) ;
recalc_bbox () ;
return b ;
}
void puPopupMenu::close ( void )
{
puPopup::close () ;
int widest = 0 ;
puObject *ob = dlist ;
/*
* June 17th, 1998, Shammi
* There seems to be some mismatch with the
* #define pumenusize and the actual size
* There seems to be some overlap resulting
* in more than one option being highlighted.
* By setting the size to the actual values,
* the overlap area seems to be less now.
*/
int w, h ;
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
{
ob -> getSize ( &w, &h ) ;
if ( w > widest ) widest = w ;
}
for ( ob = dlist ; ob != NULL ; ob = ob -> next )
{
ob -> getSize ( &w, &h ) ;
ob -> setSize ( widest, h ) ;
}
recalc_bbox () ;
}
int puPopupMenu::checkKey ( int key, int updown )
{
if ( dlist == NULL || ! isVisible () || ! isActive () )
return FALSE ;
if ( updown == PU_DOWN )
{
hide () ;
/* Turn everything off ready for next time. */
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
bo -> clrValue () ;
}
puObject *bo ;
/*
We have to walk the list backwards to ensure that
the click order is the same as the DRAW order.
*/
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
/* Find the last object in our list. */ ;
for ( ; bo != NULL ; bo = bo->prev )
if ( bo -> checkKey ( key, updown ) )
return TRUE ;
return FALSE ;
}
int puPopupMenu::checkHit ( int button, int updown, int x, int y )
{
if ( dlist == NULL || ! isVisible () || ! isActive () )
return FALSE ;
/* Must test 'isHit' before making the menu invisible! */
int hit = isHit ( x, y ) ;
/*
* June 17th, 1998, Shammi :
* There seemed to be a miscalculation with the menus initially
* Therefore I moved the recalculation stuff before the clearing.
*/
/*
This might be a bit redundant - but it's too hard to keep
track of changing abox sizes when daughter objects are
changing sizes.
*/
recalc_bbox();
x -= abox.min[0] ;
y -= abox.min[1] ;
/*
* June 17th, 1998, Shammi :
* Also clear the menu when the dragging the mouse and not hit.
*/
if ( updown == active_mouse_edge || active_mouse_edge == PU_UP_AND_DOWN ||
( updown == PU_DRAG && !hit ) )
{
/* June 17th, 1998, Shammi :
* Do not hide the menu if mouse is dragged out
*/
if ( updown != PU_DRAG )
hide () ;
/* Turn everything off ready for next time. */
/* June 17th, 1998, Shammi:
* Make sure we check for a hit, if the mouse is moved
* out of the menu.
*/
for ( puObject *bo = dlist ; bo != NULL ; bo = bo->next )
{
if ( ! hit )
bo -> checkHit ( button, updown, x , y ) ;
bo -> clrValue () ;
}
}
if ( ! hit )
return FALSE ;
puObject *bo ;
/*
We have to walk the list backwards to ensure that
the click order is the same as the DRAW order.
*/
/* June 17th, 1998, Shammi :
* If the mouse is dragged and the menuItem is not hit,
* clear it
*/
for ( bo = dlist ; bo->next != NULL ; bo = bo->next )
if ( updown == PU_DRAG && ! bo -> checkHit ( button, updown, x, y ) )
bo -> clrValue () ;
/* Find the last object in our list. */ ;
for ( ; bo != NULL ; bo = bo->prev )
if ( bo -> checkHit ( button, updown, x, y ) )
return TRUE ;
return FALSE ;
}

107
Lib/PUI/puSlider.cxx Normal file
View file

@ -0,0 +1,107 @@
#include "puLocal.h"
void puSlider::draw ( int dx, int dy )
{
if ( !visible ) return ;
abox . draw ( dx, dy,
(style==PUSTYLE_BEVELLED||
style==PUSTYLE_SHADED) ? -PUSTYLE_BOXED : -style,
colour, FALSE ) ;
int sd, od ;
if ( isVertical() ) { sd = 1 ; od = 0 ; } else { sd = 0 ; od = 1 ; }
int sz = abox.max [sd] - abox.min [sd] ;
float val ;
getValue ( & val ) ;
if ( val < 0.0f ) val = 0.0f ;
if ( val > 1.0f ) val = 1.0f ;
val *= (float) sz * (1.0f - slider_fraction) ;
puBox bx ;
bx . min [ sd ] = abox . min [ sd ] + (int) val ;
bx . max [ sd ] = (int) ( (float) bx . min [ sd ] + (float) sz * slider_fraction ) ;
bx . min [ od ] = abox . min [ od ] + 2 ;
bx . max [ od ] = abox . max [ od ] - 2 ;
bx . draw ( dx, dy, PUSTYLE_SMALL_SHADED, colour, FALSE ) ;
/* If greyed out then halve the opacity when drawing the label and legend */
if ( active )
glColor4fv ( colour [ PUCOL_LEGEND ] ) ;
else
glColor4f ( colour [ PUCOL_LEGEND ][0],
colour [ PUCOL_LEGEND ][1],
colour [ PUCOL_LEGEND ][2],
colour [ PUCOL_LEGEND ][3] / 2.0f ) ; /* 50% more transparent */
int xx = ( abox.max[0] - abox.min[0] - puGetStringWidth(legendFont,legend) ) / 2 ;
int yy = ( abox.max[1] - abox.min[1] - puGetStringHeight(legendFont) ) / 2 ;
puDrawString ( legendFont, legend,
dx + abox.min[0] + xx,
dy + abox.min[1] + yy ) ;
draw_label ( dx, dy ) ;
}
void puSlider::doHit ( int button, int updown, int x, int y )
{
if ( button == PU_LEFT_BUTTON )
{
int sd = isVertical() ;
int sz = abox.max [sd] - abox.min [sd] ;
int coord = isVertical() ? y : x ;
float next_value ;
if ( sz == 0 )
next_value = 0.5f ;
else
{
next_value = ( (float)coord - (float)abox.min[sd] - (float)sz * slider_fraction / 2.0f ) /
( (float) sz * (1.0f - slider_fraction) ) ;
}
next_value = (next_value < 0.0f) ? 0.0f : (next_value > 1.0) ? 1.0f : next_value ;
setValue ( next_value ) ;
switch ( cb_mode )
{
case PUSLIDER_CLICK :
if ( updown == active_mouse_edge )
{
last_cb_value = next_value ;
invokeCallback () ;
}
break ;
case PUSLIDER_DELTA :
if ( fabs ( last_cb_value - next_value ) >= cb_delta )
{
last_cb_value = next_value ;
invokeCallback () ;
}
break ;
case PUSLIDER_ALWAYS :
default :
last_cb_value = next_value ;
invokeCallback () ;
break ;
}
}
}

8
Lib/PUI/puText.cxx Normal file
View file

@ -0,0 +1,8 @@
#include "puLocal.h"
void puText::draw ( int dx, int dy )
{
draw_label ( dx, dy ) ;
}

13
Lib/Serial/Makefile.am Normal file
View file

@ -0,0 +1,13 @@
bin_PROGRAMS = testserial
noinst_LIBRARIES = libSerial.a
libSerial_a_SOURCES = serial.cxx serial.hxx
testserial_SOURCES = testserial.cxx
testserial_LDADD = \
$(top_builddir)/Lib/Serial/libSerial.a \
$(top_builddir)/Lib/Debug/libDebug.a
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Lib

381
Lib/Serial/serial.cxx Normal file
View file

@ -0,0 +1,381 @@
// serial.cxx -- Unix serial I/O support
//
// Written by Curtis Olson, started November 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include "Include/compiler.h"
#ifdef FG_HAVE_STD_INCLUDE
# include <cerrno>
#else
# include <errno.h>
#endif
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
// maybe include something???
#else
# include <termios.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
# include <unistd.h>
#endif
#include <Debug/logstream.hxx>
#include "serial.hxx"
fgSERIAL::fgSERIAL()
: dev_open(false)
{
// empty
}
fgSERIAL::fgSERIAL(const string& device, int baud) {
open_port(device);
if ( dev_open ) {
set_baud(baud);
}
}
fgSERIAL::~fgSERIAL() {
// closing the port here screws us up because if we would even so
// much as make a copy of an fgSERIAL object and then delete it,
// the file descriptor gets closed. Doh!!!
}
bool fgSERIAL::open_port(const string& device) {
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
fd = CreateFile( device.c_str(),
GENERIC_READ | GENERIC_WRITE,
0, // dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL );
if ( fd == INVALID_HANDLE_VALUE )
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
FG_LOG( FG_SERIAL, FG_ALERT, "Error opening serial device \""
<< device << "\" " << (const char*) lpMsgBuf );
LocalFree( lpMsgBuf );
return false;
}
dev_open = true;
return true;
#else
struct termios config;
fd = open(device.c_str(), O_RDWR | O_NONBLOCK);
cout << "Serial fd created = " << fd << endl;
if ( fd == -1 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Cannot open " << device
<< " for serial I/O" );
return false;
} else {
dev_open = true;
}
// set required port parameters
if ( tcgetattr( fd, &config ) != 0 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
return false;
}
// cfmakeraw( &config );
// cout << "config.c_iflag = " << config.c_iflag << endl;
// software flow control on
config.c_iflag |= IXON;
// config.c_iflag |= IXOFF;
// config.c_cflag |= CLOCAL;
#if ! defined( sgi )
// disable hardware flow control
config.c_cflag &= ~(CRTSCTS);
#endif
// cout << "config.c_iflag = " << config.c_iflag << endl;
if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
return false;
}
return true;
#endif
}
bool fgSERIAL::close_port() {
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
CloseHandle( fd );
#else
close(fd);
#endif
return true;
}
bool fgSERIAL::set_baud(int baud) {
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
return true;
#else
struct termios config;
speed_t speed = B9600;
if ( tcgetattr( fd, &config ) != 0 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Unable to poll port settings" );
return false;
}
if ( baud == 300 ) {
speed = B300;
} else if ( baud == 1200 ) {
speed = B1200;
} else if ( baud == 2400 ) {
speed = B2400;
} else if ( baud == 4800 ) {
speed = B4800;
} else if ( baud == 9600 ) {
speed = B9600;
} else if ( baud == 19200 ) {
speed = B19200;
} else if ( baud == 38400 ) {
speed = B38400;
} else if ( baud == 57600 ) {
speed = B57600;
} else if ( baud == 115200 ) {
speed = B115200;
#if defined( linux ) || defined( __FreeBSD__ )
} else if ( baud == 230400 ) {
speed = B230400;
#endif
} else {
FG_LOG( FG_SERIAL, FG_ALERT, "Unsupported baud rate " << baud );
return false;
}
if ( cfsetispeed( &config, speed ) != 0 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting input baud rate" );
return false;
}
if ( cfsetospeed( &config, speed ) != 0 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Problem setting output baud rate" );
return false;
}
if ( tcsetattr( fd, TCSANOW, &config ) != 0 ) {
FG_LOG( FG_SERIAL, FG_ALERT, "Unable to update port settings" );
return false;
}
return true;
#endif
}
string fgSERIAL::read_port() {
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
string result = "";
return result;
#else
const int max_count = 1024;
char buffer[max_count+1];
int count;
string result;
count = read(fd, buffer, max_count);
// cout << "read " << count << " bytes" << endl;
if ( count < 0 ) {
// error condition
if ( errno != EAGAIN ) {
FG_LOG( FG_SERIAL, FG_ALERT,
"Serial I/O on read, error number = " << errno );
}
return "";
} else {
buffer[count] = '\0';
result = buffer;
return result;
}
#endif
}
int fgSERIAL::write_port(const string& value) {
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
LPCVOID lpBuffer = value.c_str();
DWORD nNumberOfBytesToWrite = value.length();
DWORD lpNumberOfBytesWritten;
OVERLAPPED lpOverlapped;
if ( WriteFile( fd,
lpBuffer,
nNumberOfBytesToWrite,
&lpNumberOfBytesWritten,
&lpOverlapped ) == 0 )
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL );
FG_LOG( FG_SERIAL, FG_ALERT, "Serial I/O write error: "
<< (const char*) lpMsgBuf );
LocalFree( lpMsgBuf );
return int(lpNumberOfBytesWritten);
}
return int(lpNumberOfBytesWritten);
#else
static bool error = false;
int count;
if ( error ) {
// attempt some sort of error recovery
count = write(fd, "\n", 1);
if ( count == 1 ) {
// cout << "Serial error recover successful!\n";
error = false;
} else {
return 0;
}
}
count = write(fd, value.c_str(), value.length());
// cout << "write '" << value << "' " << count << " bytes" << endl;
if ( (int)count == (int)value.length() ) {
error = false;
} else {
error = true;
if ( errno == EAGAIN ) {
// ok ... in our context we don't really care if we can't
// write a string, we'll just get it the next time around
} else {
FG_LOG( FG_SERIAL, FG_ALERT,
"Serial I/O on write, error number = " << errno );
}
}
return count;
#endif
}
// $Log$
// Revision 1.9 1999/02/02 20:13:23 curt
// MSVC++ portability changes by Bernie Bright:
//
// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
// Simulator/Cockpit/hud.cxx: Added Standard headers
// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
// Simulator/Main/fg_init.cxx:
// Simulator/Main/GLUTmain.cxx:
// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
// Simulator/Objects/material.hxx:
// Simulator/Time/timestamp.hxx: VC++ friend kludge
// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
// Simulator/Main/views.hxx: Added a constant
//
// Revision 1.8 1999/01/20 13:42:21 curt
// Tweaked FDM interface.
// Testing check sum support for NMEA serial output.
//
// Revision 1.7 1998/12/04 01:24:35 curt
// Tweak for SGI portability.
//
// Revision 1.6 1998/11/30 17:15:29 curt
// Having the class destructor close the fd was a bad idea ... especially if you
// ever make a copy of the instance and then subsequently destroy either.
// close_port() is now a separate member function.
//
// Revision 1.5 1998/11/25 01:33:23 curt
// Remove call to cfmakeraw()
//
// Revision 1.4 1998/11/23 21:47:00 curt
// Cygnus tools compatibility tweaks.
//
// Revision 1.3 1998/11/19 13:52:54 curt
// port configuration tweaks & experiments.
//
// Revision 1.2 1998/11/19 03:35:43 curt
// Updates ...
//
// Revision 1.1 1998/11/16 13:53:02 curt
// Initial revision.
//

112
Lib/Serial/serial.hxx Normal file
View file

@ -0,0 +1,112 @@
// serial.hxx -- Unix serial I/O support
//
// Written by Curtis Olson, started November 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
// (Log is kept at end of this file)
#ifndef _SERIAL_HXX
#define _SERIAL_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
# include <windows.h>
#endif
#include <Include/compiler.h>
#include STL_STRING
FG_USING_STD(string);
// if someone know how to do this all with C++ streams let me know
// #include <stdio.h>
class fgSERIAL
{
#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ )
typedef HANDLE fd_type;
#else
typedef int fd_type;
#endif
private:
fd_type fd;
bool dev_open;
public:
fgSERIAL();
fgSERIAL(const string& device, int baud);
~fgSERIAL();
bool open_port(const string& device);
bool close_port();
bool set_baud(int baud);
string read_port();
int write_port(const string& value);
inline bool is_enabled() { return dev_open; }
};
#endif // _SERIAL_HXX
// $Log$
// Revision 1.5 1999/03/02 01:01:58 curt
// Tweaks for compiling with native SGI compilers.
//
// Revision 1.4 1999/02/26 22:08:13 curt
// Added initial support for native SGI compilers.
//
// Revision 1.3 1999/02/02 20:13:24 curt
// MSVC++ portability changes by Bernie Bright:
//
// Lib/Serial/serial.[ch]xx: Initial Windows support - incomplete.
// Simulator/Astro/stars.cxx: typo? included <stdio> instead of <cstdio>
// Simulator/Cockpit/hud.cxx: Added Standard headers
// Simulator/Cockpit/panel.cxx: Redefinition of default parameter
// Simulator/Flight/flight.cxx: Replaced cout with FG_LOG. Deleted <stdio.h>
// Simulator/Main/fg_init.cxx:
// Simulator/Main/GLUTmain.cxx:
// Simulator/Main/options.hxx: Shuffled <fg_serial.hxx> dependency
// Simulator/Objects/material.hxx:
// Simulator/Time/timestamp.hxx: VC++ friend kludge
// Simulator/Scenery/tile.[ch]xx: Fixed using std::X declarations
// Simulator/Main/views.hxx: Added a constant
//
// Revision 1.2 1998/11/30 17:15:30 curt
// Having the class destructor close the fd was a bad idea ... especially if you
// ever make a copy of the instance and then subsequently destroy either.
// close_port() is now a separate member function.
//
// Revision 1.1 1998/11/16 13:53:02 curt
// Initial revision.
//

30
Lib/Serial/testserial.cxx Normal file
View file

@ -0,0 +1,30 @@
#include <string>
#include <Debug/logstream.hxx>
#include "serial.hxx"
main () {
fgSERIAL port;
string value;
bool result;
fglog().setLogLevels( FG_ALL, FG_INFO );
cout << "start of main" << endl;
result = port.open_port("/dev/ttyS1");
cout << "opened port, result = " << result << endl;
result = port.set_baud(4800);
cout << "set baud, result = " << result << endl;
port.write_port("ATDT 626-9800\n");
while ( true ) {
value = port.read_port();
if ( value.length() ) {
cout << "-> " << value << endl;
}
}
}

5
Lib/XGL/Makefile.am Normal file
View file

@ -0,0 +1,5 @@
lib_LIBRARIES = libXGL.a
libXGL_a_SOURCES = xgl.c xgl.h xglUtils.c
INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator

3034
Lib/XGL/xgl.c Normal file

File diff suppressed because it is too large Load diff

837
Lib/XGL/xgl.h Normal file
View file

@ -0,0 +1,837 @@
#ifndef _XGL_H
#define _XGL_H
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/gl.h>
#include <GL/glu.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* xgl Utilities */
extern FILE *xglTraceFd ;
int xglTraceIsEnabled ( char *gl_function_name ) ;
int xglExecuteIsEnabled ( char *gl_function_name ) ;
char *xglExpandGLenum ( GLenum x ) ;
GLdouble *xglBuild1dv ( GLdouble v ) ;
GLfloat *xglBuild1fv ( GLfloat v ) ;
GLbyte *xglBuild1bv ( GLbyte v ) ;
GLint *xglBuild1iv ( GLint v ) ;
GLshort *xglBuild1sv ( GLshort v ) ;
GLubyte *xglBuild1ubv ( GLubyte v ) ;
GLuint *xglBuild1uiv ( GLuint v ) ;
GLushort *xglBuild1usv ( GLushort v ) ;
GLdouble *xglBuild2dv ( GLdouble v0, GLdouble v1 ) ;
GLfloat *xglBuild2fv ( GLfloat v0, GLfloat v1 ) ;
GLbyte *xglBuild2bv ( GLbyte v0, GLbyte v1 ) ;
GLint *xglBuild2iv ( GLint v0, GLint v1 ) ;
GLshort *xglBuild2sv ( GLshort v0, GLshort v1 ) ;
GLubyte *xglBuild2ubv ( GLubyte v0, GLubyte v1 ) ;
GLuint *xglBuild2uiv ( GLuint v0, GLuint v1 ) ;
GLushort *xglBuild2usv ( GLushort v0, GLushort v1 ) ;
GLdouble *xglBuild3dv ( GLdouble v0, GLdouble v1, GLdouble v2 ) ;
GLfloat *xglBuild3fv ( GLfloat v0, GLfloat v1, GLfloat v2 ) ;
GLbyte *xglBuild3bv ( GLbyte v0, GLbyte v1, GLbyte v2 ) ;
GLint *xglBuild3iv ( GLint v0, GLint v1, GLint v2 ) ;
GLshort *xglBuild3sv ( GLshort v0, GLshort v1, GLshort v2 ) ;
GLubyte *xglBuild3ubv ( GLubyte v0, GLubyte v1, GLubyte v2 ) ;
GLuint *xglBuild3uiv ( GLuint v0, GLuint v1, GLuint v2 ) ;
GLushort *xglBuild3usv ( GLushort v0, GLushort v1, GLushort v2 ) ;
GLdouble *xglBuild4dv ( GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3 ) ;
GLfloat *xglBuild4fv ( GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) ;
GLbyte *xglBuild4bv ( GLbyte v0, GLbyte v1, GLbyte v2, GLbyte v3 ) ;
GLint *xglBuild4iv ( GLint v0, GLint v1, GLint v2, GLint v3 ) ;
GLshort *xglBuild4sv ( GLshort v0, GLshort v1, GLshort v2, GLshort v3 ) ;
GLubyte *xglBuild4ubv ( GLubyte v0, GLubyte v1, GLubyte v2, GLubyte v3 ) ;
GLuint *xglBuild4uiv ( GLuint v0, GLuint v1, GLuint v2, GLuint v3 ) ;
GLushort *xglBuild4usv ( GLushort v0, GLushort v1, GLushort v2, GLushort v3 ) ;
GLfloat *xglBuildMatrixf ( GLfloat m0 , GLfloat m1 , GLfloat m2 , GLfloat m3 ,
GLfloat m4 , GLfloat m5 , GLfloat m6 , GLfloat m7 ,
GLfloat m8 , GLfloat m9 , GLfloat m10, GLfloat m11,
GLfloat m12, GLfloat m13, GLfloat m14, GLfloat m15 ) ;
GLdouble *xglBuildMatrixd ( GLdouble m0 , GLdouble m1 , GLdouble m2 , GLdouble m3 ,
GLdouble m4 , GLdouble m5 , GLdouble m6 , GLdouble m7 ,
GLdouble m8 , GLdouble m9 , GLdouble m10, GLdouble m11,
GLdouble m12, GLdouble m13, GLdouble m14, GLdouble m15 ) ;
/*
Conditionally compile all 'xgl' calls into standard 'gl' calls...
OR
Declare all possible 'xgl' calls as 'extern'.
*/
#ifndef XGL_TRACE
#define xglAccum glAccum
#define xglAlphaFunc glAlphaFunc
#ifdef GL_EXT_vertex_array
#define xglArrayElementEXT glArrayElementEXT
#endif
#define xglBegin glBegin
#define xglBitmap glBitmap
#ifdef GL_EXT_blend_color
#define xglBlendColorEXT glBlendColorEXT
#endif
#ifdef GL_EXT_blend_minmax
#define xglBlendEquationEXT glBlendEquationEXT
#endif
#define xglBlendFunc glBlendFunc
#define xglCallList glCallList
#define xglCallLists glCallLists
#define xglClear glClear
#define xglClearAccum glClearAccum
#define xglClearColor glClearColor
#define xglClearDepth glClearDepth
#define xglClearIndex glClearIndex
#define xglClearStencil glClearStencil
#define xglClipPlane glClipPlane
#define xglColor3b glColor3b
#define xglColor3bv glColor3bv
#define xglColor3d glColor3d
#define xglColor3dv glColor3dv
#define xglColor3f glColor3f
#define xglColor3fv glColor3fv
#define xglColor3i glColor3i
#define xglColor3iv glColor3iv
#define xglColor3s glColor3s
#define xglColor3sv glColor3sv
#define xglColor3ub glColor3ub
#define xglColor3ubv glColor3ubv
#define xglColor3ui glColor3ui
#define xglColor3uiv glColor3uiv
#define xglColor3us glColor3us
#define xglColor3usv glColor3usv
#define xglColor4b glColor4b
#define xglColor4bv glColor4bv
#define xglColor4d glColor4d
#define xglColor4dv glColor4dv
#define xglColor4f glColor4f
#define xglColor4fv glColor4fv
#define xglColor4i glColor4i
#define xglColor4iv glColor4iv
#define xglColor4s glColor4s
#define xglColor4sv glColor4sv
#define xglColor4ub glColor4ub
#define xglColor4ubv glColor4ubv
#define xglColor4ui glColor4ui
#define xglColor4uiv glColor4uiv
#define xglColor4us glColor4us
#define xglColor4usv glColor4usv
#define xglColorMask glColorMask
#define xglColorMaterial glColorMaterial
#ifdef GL_EXT_vertex_array
#define xglColorPointerEXT glColorPointerEXT
#endif
#define xglCopyPixels glCopyPixels
#define xglCullFace glCullFace
#define xglDeleteLists glDeleteLists
#define xglDepthFunc glDepthFunc
#define xglDepthMask glDepthMask
#define xglDepthRange glDepthRange
#define xglDisable glDisable
#ifdef GL_EXT_vertex_array
#define xglDrawArraysEXT glDrawArraysEXT
#endif
#define xglDrawBuffer glDrawBuffer
#define xglDrawPixels glDrawPixels
#define xglEdgeFlag glEdgeFlag
#ifdef GL_EXT_vertex_array
#define xglEdgeFlagPointerEXT glEdgeFlagPointerEXT
#endif
#define xglEdgeFlagv glEdgeFlagv
#define xglEnable glEnable
#define xglEnd glEnd
#define xglEndList glEndList
#define xglEvalCoord1d glEvalCoord1d
#define xglEvalCoord1dv glEvalCoord1dv
#define xglEvalCoord1f glEvalCoord1f
#define xglEvalCoord1fv glEvalCoord1fv
#define xglEvalCoord2d glEvalCoord2d
#define xglEvalCoord2dv glEvalCoord2dv
#define xglEvalCoord2f glEvalCoord2f
#define xglEvalCoord2fv glEvalCoord2fv
#define xglEvalMesh1 glEvalMesh1
#define xglEvalMesh2 glEvalMesh2
#define xglEvalPoint1 glEvalPoint1
#define xglEvalPoint2 glEvalPoint2
#define xglFeedbackBuffer glFeedbackBuffer
#define xglFinish glFinish
#define xglFlush glFlush
#define xglFogf glFogf
#define xglFogfv glFogfv
#define xglFogi glFogi
#define xglFogiv glFogiv
#define xglFrontFace glFrontFace
#define xglFrustum glFrustum
#define xglGenLists glGenLists
#define xglGetBooleanv glGetBooleanv
#define xglGetClipPlane glGetClipPlane
#define xglGetDoublev glGetDoublev
#define xglGetError glGetError
#define xglGetFloatv glGetFloatv
#define xglGetIntegerv glGetIntegerv
#define xglGetLightfv glGetLightfv
#define xglGetLightiv glGetLightiv
#define xglGetMapdv glGetMapdv
#define xglGetMapfv glGetMapfv
#define xglGetMapiv glGetMapiv
#define xglGetMaterialfv glGetMaterialfv
#define xglGetMaterialiv glGetMaterialiv
#define xglGetPixelMapfv glGetPixelMapfv
#define xglGetPixelMapuiv glGetPixelMapuiv
#define xglGetPixelMapusv glGetPixelMapusv
#ifdef GL_EXT_vertex_array
#define xglGetPointervEXT glGetPointervEXT
#endif
#define xglGetPolygonStipple glGetPolygonStipple
#define xglGetString glGetString
#define xglGetTexEnvfv glGetTexEnvfv
#define xglGetTexEnviv glGetTexEnviv
#define xglGetTexGendv glGetTexGendv
#define xglGetTexGenfv glGetTexGenfv
#define xglGetTexGeniv glGetTexGeniv
#define xglGetTexImage glGetTexImage
#define xglGetTexLevelParameterfv glGetTexLevelParameterfv
#define xglGetTexLevelParameteriv glGetTexLevelParameteriv
#define xglGetTexParameterfv glGetTexParameterfv
#define xglGetTexParameteriv glGetTexParameteriv
#define xglHint glHint
#define xglIndexMask glIndexMask
#ifdef GL_EXT_vertex_array
#define xglIndexPointerEXT glIndexPointerEXT
#endif
#define xglIndexd glIndexd
#define xglIndexdv glIndexdv
#define xglIndexf glIndexf
#define xglIndexfv glIndexfv
#define xglIndexi glIndexi
#define xglIndexiv glIndexiv
#define xglIndexs glIndexs
#define xglIndexsv glIndexsv
#define xglInitNames glInitNames
#define xglIsEnabled glIsEnabled
#define xglIsList glIsList
#define xglLightModelf glLightModelf
#define xglLightModelfv glLightModelfv
#define xglLightModeli glLightModeli
#define xglLightModeliv glLightModeliv
#define xglLightf glLightf
#define xglLightfv glLightfv
#define xglLighti glLighti
#define xglLightiv glLightiv
#define xglLineStipple glLineStipple
#define xglLineWidth glLineWidth
#define xglListBase glListBase
#define xglLoadIdentity glLoadIdentity
#define xglLoadMatrixd glLoadMatrixd
#define xglLoadMatrixf glLoadMatrixf
#define xglLoadName glLoadName
#define xglLogicOp glLogicOp
#define xglMap1d glMap1d
#define xglMap1f glMap1f
#define xglMap2d glMap2d
#define xglMap2f glMap2f
#define xglMapGrid1d glMapGrid1d
#define xglMapGrid1f glMapGrid1f
#define xglMapGrid2d glMapGrid2d
#define xglMapGrid2f glMapGrid2f
#define xglMaterialf glMaterialf
#define xglMaterialfv glMaterialfv
#define xglMateriali glMateriali
#define xglMaterialiv glMaterialiv
#define xglMatrixMode glMatrixMode
#define xglMultMatrixd glMultMatrixd
#define xglMultMatrixf glMultMatrixf
#define xglNewList glNewList
#define xglNormal3b glNormal3b
#define xglNormal3bv glNormal3bv
#define xglNormal3d glNormal3d
#define xglNormal3dv glNormal3dv
#define xglNormal3f glNormal3f
#ifdef DEBUGGING_NORMALS
#define xglNormal3fv(f) {\
float ff = (f)[0]*(f)[0]+(f)[1]*(f)[1]+(f)[2]*(f)[2];\
if ( ff < 0.9 || ff > 1.1 )\
{\
fprintf(stderr,"glNormal3fv Overflow: %f, %f, %f -> %f [%s,%s,%s]\n",\
(f)[0],(f)[1],(f)[2],ff,str1,str2,str3);\
normal_bombed = 1 ;\
}\
glNormal3fv(f);\
}
#else
#define xglNormal3fv glNormal3fv
#endif
#define xglNormal3i glNormal3i
#define xglNormal3iv glNormal3iv
#define xglNormal3s glNormal3s
#define xglNormal3sv glNormal3sv
#ifdef GL_EXT_vertex_array
#define xglNormalPointerEXT glNormalPointerEXT
#endif
#define xglOrtho glOrtho
#define xglPassThrough glPassThrough
#define xglPixelMapfv glPixelMapfv
#define xglPixelMapuiv glPixelMapuiv
#define xglPixelMapusv glPixelMapusv
#define xglPixelStoref glPixelStoref
#define xglPixelStorei glPixelStorei
#define xglPixelTransferf glPixelTransferf
#define xglPixelTransferi glPixelTransferi
#define xglPixelZoom glPixelZoom
#define xglPointSize glPointSize
#define xglPolygonMode glPolygonMode
#ifdef GL_EXT_polygon_offset
#define xglPolygonOffsetEXT glPolygonOffsetEXT
#endif
#define xglPolygonOffset glPolygonOffset
#define xglPolygonStipple glPolygonStipple
#define xglPopAttrib glPopAttrib
#define xglPopMatrix glPopMatrix
#define xglPopName glPopName
#define xglPushAttrib glPushAttrib
#define xglPushMatrix glPushMatrix
#define xglPushName glPushName
#define xglRasterPos2d glRasterPos2d
#define xglRasterPos2dv glRasterPos2dv
#define xglRasterPos2f glRasterPos2f
#define xglRasterPos2fv glRasterPos2fv
#define xglRasterPos2i glRasterPos2i
#define xglRasterPos2iv glRasterPos2iv
#define xglRasterPos2s glRasterPos2s
#define xglRasterPos2sv glRasterPos2sv
#define xglRasterPos3d glRasterPos3d
#define xglRasterPos3dv glRasterPos3dv
#define xglRasterPos3f glRasterPos3f
#define xglRasterPos3fv glRasterPos3fv
#define xglRasterPos3i glRasterPos3i
#define xglRasterPos3iv glRasterPos3iv
#define xglRasterPos3s glRasterPos3s
#define xglRasterPos3sv glRasterPos3sv
#define xglRasterPos4d glRasterPos4d
#define xglRasterPos4dv glRasterPos4dv
#define xglRasterPos4f glRasterPos4f
#define xglRasterPos4fv glRasterPos4fv
#define xglRasterPos4i glRasterPos4i
#define xglRasterPos4iv glRasterPos4iv
#define xglRasterPos4s glRasterPos4s
#define xglRasterPos4sv glRasterPos4sv
#define xglReadBuffer glReadBuffer
#define xglReadPixels glReadPixels
#define xglRectd glRectd
#define xglRectdv glRectdv
#define xglRectf glRectf
#define xglRectfv glRectfv
#define xglRecti glRecti
#define xglRectiv glRectiv
#define xglRects glRects
#define xglRectsv glRectsv
#define xglRenderMode glRenderMode
#define xglRotated glRotated
#define xglRotatef glRotatef
#define xglScaled glScaled
#define xglScalef glScalef
#define xglScissor glScissor
#define xglSelectBuffer glSelectBuffer
#define xglShadeModel glShadeModel
#define xglStencilFunc glStencilFunc
#define xglStencilMask glStencilMask
#define xglStencilOp glStencilOp
#define xglTexCoord1d glTexCoord1d
#define xglTexCoord1dv glTexCoord1dv
#define xglTexCoord1f glTexCoord1f
#define xglTexCoord1fv glTexCoord1fv
#define xglTexCoord1i glTexCoord1i
#define xglTexCoord1iv glTexCoord1iv
#define xglTexCoord1s glTexCoord1s
#define xglTexCoord1sv glTexCoord1sv
#define xglTexCoord2d glTexCoord2d
#define xglTexCoord2dv glTexCoord2dv
#define xglTexCoord2f glTexCoord2f
#define xglTexCoord2fv glTexCoord2fv
#define xglTexCoord2i glTexCoord2i
#define xglTexCoord2iv glTexCoord2iv
#define xglTexCoord2s glTexCoord2s
#define xglTexCoord2sv glTexCoord2sv
#define xglTexCoord3d glTexCoord3d
#define xglTexCoord3dv glTexCoord3dv
#define xglTexCoord3f glTexCoord3f
#define xglTexCoord3fv glTexCoord3fv
#define xglTexCoord3i glTexCoord3i
#define xglTexCoord3iv glTexCoord3iv
#define xglTexCoord3s glTexCoord3s
#define xglTexCoord3sv glTexCoord3sv
#define xglTexCoord4d glTexCoord4d
#define xglTexCoord4dv glTexCoord4dv
#define xglTexCoord4f glTexCoord4f
#define xglTexCoord4fv glTexCoord4fv
#define xglTexCoord4i glTexCoord4i
#define xglTexCoord4iv glTexCoord4iv
#define xglTexCoord4s glTexCoord4s
#define xglTexCoord4sv glTexCoord4sv
#ifdef GL_EXT_vertex_array
#define xglTexCoordPointerEXT glTexCoordPointerEXT
#endif
#define xglTexEnvf glTexEnvf
#define xglTexEnvfv glTexEnvfv
#define xglTexEnvi glTexEnvi
#define xglTexEnviv glTexEnviv
#define xglTexGend glTexGend
#define xglTexGendv glTexGendv
#define xglTexGenf glTexGenf
#define xglTexGenfv glTexGenfv
#define xglTexGeni glTexGeni
#define xglTexGeniv glTexGeniv
#define xglTexImage1D glTexImage1D
#define xglTexImage2D glTexImage2D
#define xglTexParameterf glTexParameterf
#define xglTexParameterfv glTexParameterfv
#define xglTexParameteri glTexParameteri
#define xglTexParameteriv glTexParameteriv
#define xglTranslated glTranslated
#define xglTranslatef glTranslatef
#define xglVertex2d glVertex2d
#define xglVertex2dv glVertex2dv
#define xglVertex2f glVertex2f
#define xglVertex2fv glVertex2fv
#define xglVertex2i glVertex2i
#define xglVertex2iv glVertex2iv
#define xglVertex2s glVertex2s
#define xglVertex2sv glVertex2sv
#define xglVertex3d glVertex3d
#define xglVertex3dv glVertex3dv
#define xglVertex3f glVertex3f
#define xglVertex3fv glVertex3fv
#define xglVertex3i glVertex3i
#define xglVertex3iv glVertex3iv
#define xglVertex3s glVertex3s
#define xglVertex3sv glVertex3sv
#define xglVertex4d glVertex4d
#define xglVertex4dv glVertex4dv
#define xglVertex4f glVertex4f
#define xglVertex4fv glVertex4fv
#define xglVertex4i glVertex4i
#define xglVertex4iv glVertex4iv
#define xglVertex4s glVertex4s
#define xglVertex4sv glVertex4sv
#ifdef GL_EXT_vertex_array
#define xglVertexPointerEXT glVertexPointerEXT
#endif
#define xglViewport glViewport
#ifdef GL_VERSION_1_1
#define xglAreTexturesResident glAreTexturesResident
#define xglIsTexture glIsTexture
#define xglBindTexture glBindTexture
#define xglDeleteTextures glDeleteTextures
#define xglGenTextures glGenTextures
#define xglPrioritizeTextures glPrioritizeTextures
#endif
#ifdef GL_EXT_texture_object
#define xglAreTexturesResidentEXT glAreTexturesResidentEXT
#define xglIsTextureEXT glIsTextureEXT
#define xglBindTextureEXT glBindTextureEXT
#define xglDeleteTexturesEXT glDeleteTexturesEXT
#define xglGenTexturesEXT glGenTexturesEXT
#define xglPrioritizeTexturesEXT glPrioritizeTexturesEXT
#endif
#define xglutAddMenuEntry glutAddMenuEntry
#define xglutAttachMenu glutAttachMenu
#define xglutCreateMenu glutCreateMenu
#define xglutCreateWindow glutCreateWindow
#define xglutDisplayFunc glutDisplayFunc
#define xglutIdleFunc glutIdleFunc
#define xglutInit glutInit
#define xglutInitDisplayMode glutInitDisplayMode
#define xglutInitWindowPosition glutInitWindowPosition
#define xglutInitWindowSize glutInitWindowSize
#define xglutKeyboardFunc glutKeyboardFunc
#define xglutMainLoopUpdate glutMainLoopUpdate
#define xglutPostRedisplay glutPostRedisplay
#define xglutPreMainLoop glutPreMainLoop
#define xglutReshapeFunc glutReshapeFunc
#define xglutSwapBuffers glutSwapBuffers
#else
GLboolean xglIsEnabled ( GLenum cap ) ;
GLboolean xglIsList ( GLuint list ) ;
GLenum xglGetError () ;
GLint xglRenderMode ( GLenum mode ) ;
GLuint xglGenLists ( GLsizei range ) ;
const GLubyte *xglGetString ( GLenum name ) ;
void xglAccum ( GLenum op, GLfloat value ) ;
void xglAlphaFunc ( GLenum func, GLclampf ref ) ;
void xglArrayElementEXT ( GLint i ) ;
void xglBegin ( GLenum mode ) ;
void xglBitmap ( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte *bitmap ) ;
void xglBlendColorEXT ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) ;
void xglBlendEquationEXT( GLenum mode ) ;
void xglBlendFunc ( GLenum sfactor, GLenum dfactor ) ;
void xglCallList ( GLuint list ) ;
void xglCallLists ( GLsizei n, GLenum type, GLvoid *lists ) ;
void xglClear ( GLbitfield mask ) ;
void xglClearAccum ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) ;
void xglClearColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) ;
void xglClearDepth ( GLclampd depth ) ;
void xglClearIndex ( GLfloat c ) ;
void xglClearStencil ( GLint s ) ;
void xglClipPlane ( GLenum plane, GLdouble *equation ) ;
void xglColor3b ( GLbyte red, GLbyte green, GLbyte blue ) ;
void xglColor3bv ( GLbyte *v ) ;
void xglColor3d ( GLdouble red, GLdouble green, GLdouble blue ) ;
void xglColor3dv ( GLdouble *v ) ;
void xglColor3f ( GLfloat red, GLfloat green, GLfloat blue ) ;
void xglColor3fv ( GLfloat *v ) ;
void xglColor3i ( GLint red, GLint green, GLint blue ) ;
void xglColor3iv ( GLint *v ) ;
void xglColor3s ( GLshort red, GLshort green, GLshort blue ) ;
void xglColor3sv ( GLshort *v ) ;
void xglColor3ub ( GLubyte red, GLubyte green, GLubyte blue ) ;
void xglColor3ubv ( GLubyte *v ) ;
void xglColor3ui ( GLuint red, GLuint green, GLuint blue ) ;
void xglColor3uiv ( GLuint *v ) ;
void xglColor3us ( GLushort red, GLushort green, GLushort blue ) ;
void xglColor3usv ( GLushort *v ) ;
void xglColor4b ( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha ) ;
void xglColor4bv ( GLbyte *v ) ;
void xglColor4d ( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha ) ;
void xglColor4dv ( GLdouble *v ) ;
void xglColor4f ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) ;
void xglColor4fv ( GLfloat *v ) ;
void xglColor4i ( GLint red, GLint green, GLint blue, GLint alpha ) ;
void xglColor4iv ( GLint *v ) ;
void xglColor4s ( GLshort red, GLshort green, GLshort blue, GLshort alpha ) ;
void xglColor4sv ( GLshort *v ) ;
void xglColor4ub ( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ) ;
void xglColor4ubv ( GLubyte *v ) ;
void xglColor4ui ( GLuint red, GLuint green, GLuint blue, GLuint alpha ) ;
void xglColor4uiv ( GLuint *v ) ;
void xglColor4us ( GLushort red, GLushort green, GLushort blue, GLushort alpha ) ;
void xglColor4usv ( GLushort *v ) ;
void xglColorMask ( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha ) ;
void xglColorMaterial ( GLenum face, GLenum mode ) ;
void xglColorPointerEXT ( GLint size, GLenum type, GLsizei stride, GLsizei count, void *ptr ) ;
void xglCopyPixels ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type ) ;
void xglCullFace ( GLenum mode ) ;
void xglDeleteLists ( GLuint list, GLsizei range ) ;
void xglDepthFunc ( GLenum func ) ;
void xglDepthMask ( GLboolean flag ) ;
void xglDepthRange ( GLclampd near_val, GLclampd far_val ) ;
void xglDisable ( GLenum cap ) ;
void xglDrawArraysEXT ( GLenum mode, GLint first, GLsizei count ) ;
void xglDrawBuffer ( GLenum mode ) ;
void xglDrawPixels ( GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ) ;
void xglEdgeFlag ( GLboolean flag ) ;
void xglEdgeFlagPointerEXT( GLsizei stride, GLsizei count, GLboolean *ptr ) ;
void xglEdgeFlagv ( GLboolean *flag ) ;
void xglEnable ( GLenum cap ) ;
void xglEnd () ;
void xglEndList () ;
void xglEvalCoord1d ( GLdouble u ) ;
void xglEvalCoord1dv ( GLdouble *u ) ;
void xglEvalCoord1f ( GLfloat u ) ;
void xglEvalCoord1fv ( GLfloat *u ) ;
void xglEvalCoord2d ( GLdouble u, GLdouble v ) ;
void xglEvalCoord2dv ( GLdouble *u ) ;
void xglEvalCoord2f ( GLfloat u, GLfloat v ) ;
void xglEvalCoord2fv ( GLfloat *u ) ;
void xglEvalMesh1 ( GLenum mode, GLint i1, GLint i2 ) ;
void xglEvalMesh2 ( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) ;
void xglEvalPoint1 ( GLint i ) ;
void xglEvalPoint2 ( GLint i, GLint j ) ;
void xglFeedbackBuffer ( GLsizei size, GLenum type, GLfloat *buffer ) ;
void xglFinish () ;
void xglFlush () ;
void xglFogf ( GLenum pname, GLfloat param ) ;
void xglFogfv ( GLenum pname, GLfloat *params ) ;
void xglFogi ( GLenum pname, GLint param ) ;
void xglFogiv ( GLenum pname, GLint *params ) ;
void xglFrontFace ( GLenum mode ) ;
void xglFrustum ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ) ;
void xglGetBooleanv ( GLenum pname, GLboolean *params ) ;
void xglGetClipPlane ( GLenum plane, GLdouble *equation ) ;
void xglGetDoublev ( GLenum pname, GLdouble *params ) ;
void xglGetFloatv ( GLenum pname, GLfloat *params ) ;
void xglGetIntegerv ( GLenum pname, GLint *params ) ;
void xglGetLightfv ( GLenum light, GLenum pname, GLfloat *params ) ;
void xglGetLightiv ( GLenum light, GLenum pname, GLint *params ) ;
void xglGetMapdv ( GLenum target, GLenum query, GLdouble *v ) ;
void xglGetMapfv ( GLenum target, GLenum query, GLfloat *v ) ;
void xglGetMapiv ( GLenum target, GLenum query, GLint *v ) ;
void xglGetMaterialfv ( GLenum face, GLenum pname, GLfloat *params ) ;
void xglGetMaterialiv ( GLenum face, GLenum pname, GLint *params ) ;
void xglGetPixelMapfv ( GLenum map, GLfloat *values ) ;
void xglGetPixelMapuiv ( GLenum map, GLuint *values ) ;
void xglGetPixelMapusv ( GLenum map, GLushort *values ) ;
void xglGetPointervEXT ( GLenum pname, void **params ) ;
void xglGetPolygonStipple( GLubyte *mask ) ;
void xglGetTexEnvfv ( GLenum target, GLenum pname, GLfloat *params ) ;
void xglGetTexEnviv ( GLenum target, GLenum pname, GLint *params ) ;
void xglGetTexGendv ( GLenum coord, GLenum pname, GLdouble *params ) ;
void xglGetTexGenfv ( GLenum coord, GLenum pname, GLfloat *params ) ;
void xglGetTexGeniv ( GLenum coord, GLenum pname, GLint *params ) ;
void xglGetTexImage ( GLenum target, GLint level, GLenum format, GLenum type, GLvoid *pixels ) ;
void xglGetTexLevelParameterfv ( GLenum target, GLint level, GLenum pname, GLfloat *params ) ;
void xglGetTexLevelParameteriv ( GLenum target, GLint level, GLenum pname, GLint *params ) ;
void xglGetTexParameterfv ( GLenum target, GLenum pname, GLfloat *params) ;
void xglGetTexParameteriv ( GLenum target, GLenum pname, GLint *params ) ;
void xglHint ( GLenum target, GLenum mode ) ;
void xglIndexMask ( GLuint mask ) ;
void xglIndexPointerEXT ( GLenum type, GLsizei stride, GLsizei count, void *ptr ) ;
void xglIndexd ( GLdouble c ) ;
void xglIndexdv ( GLdouble *c ) ;
void xglIndexf ( GLfloat c ) ;
void xglIndexfv ( GLfloat *c ) ;
void xglIndexi ( GLint c ) ;
void xglIndexiv ( GLint *c ) ;
void xglIndexs ( GLshort c ) ;
void xglIndexsv ( GLshort *c ) ;
void xglInitNames () ;
void xglLightModelf ( GLenum pname, GLfloat param ) ;
void xglLightModelfv ( GLenum pname, GLfloat *params ) ;
void xglLightModeli ( GLenum pname, GLint param ) ;
void xglLightModeliv ( GLenum pname, GLint *params ) ;
void xglLightf ( GLenum light, GLenum pname, GLfloat param ) ;
void xglLightfv ( GLenum light, GLenum pname, GLfloat *params ) ;
void xglLighti ( GLenum light, GLenum pname, GLint param ) ;
void xglLightiv ( GLenum light, GLenum pname, GLint *params ) ;
void xglLineStipple ( GLint factor, GLushort pattern ) ;
void xglLineWidth ( GLfloat width ) ;
void xglListBase ( GLuint base ) ;
void xglLoadIdentity () ;
void xglLoadMatrixd ( GLdouble *m ) ;
void xglLoadMatrixf ( GLfloat *m ) ;
void xglLoadName ( GLuint name ) ;
void xglLogicOp ( GLenum opcode ) ;
void xglMap1d ( GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, GLdouble *points ) ;
void xglMap1f ( GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, GLfloat *points ) ;
void xglMap2d ( GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble *points ) ;
void xglMap2f ( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat *points ) ;
void xglMapGrid1d ( GLint un, GLdouble u1, GLdouble u2 ) ;
void xglMapGrid1f ( GLint un, GLfloat u1, GLfloat u2 ) ;
void xglMapGrid2d ( GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2 ) ;
void xglMapGrid2f ( GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2 ) ;
void xglMaterialf ( GLenum face, GLenum pname, GLfloat param ) ;
void xglMaterialfv ( GLenum face, GLenum pname, GLfloat *params ) ;
void xglMateriali ( GLenum face, GLenum pname, GLint param ) ;
void xglMaterialiv ( GLenum face, GLenum pname, GLint *params ) ;
void xglMatrixMode ( GLenum mode ) ;
void xglMultMatrixd ( GLdouble *m ) ;
void xglMultMatrixf ( GLfloat *m ) ;
void xglNewList ( GLuint list, GLenum mode ) ;
void xglNormal3b ( GLbyte nx, GLbyte ny, GLbyte nz ) ;
void xglNormal3bv ( GLbyte *v ) ;
void xglNormal3d ( GLdouble nx, GLdouble ny, GLdouble nz ) ;
void xglNormal3dv ( GLdouble *v ) ;
void xglNormal3f ( GLfloat nx, GLfloat ny, GLfloat nz ) ;
void xglNormal3fv ( GLfloat *v ) ;
void xglNormal3i ( GLint nx, GLint ny, GLint nz ) ;
void xglNormal3iv ( GLint *v ) ;
void xglNormal3s ( GLshort nx, GLshort ny, GLshort nz ) ;
void xglNormal3sv ( GLshort *v ) ;
void xglNormalPointerEXT( GLenum type, GLsizei stride, GLsizei count, void *ptr ) ;
void xglOrtho ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val ) ;
void xglPassThrough ( GLfloat token ) ;
void xglPixelMapfv ( GLenum map, GLint mapsize, GLfloat *values ) ;
void xglPixelMapuiv ( GLenum map, GLint mapsize, GLuint *values ) ;
void xglPixelMapusv ( GLenum map, GLint mapsize, GLushort *values ) ;
void xglPixelStoref ( GLenum pname, GLfloat param ) ;
void xglPixelStorei ( GLenum pname, GLint param ) ;
void xglPixelTransferf ( GLenum pname, GLfloat param ) ;
void xglPixelTransferi ( GLenum pname, GLint param ) ;
void xglPixelZoom ( GLfloat xfactor, GLfloat yfactor ) ;
void xglPointSize ( GLfloat size ) ;
void xglPolygonMode ( GLenum face, GLenum mode ) ;
void xglPolygonOffsetEXT( GLfloat factor, GLfloat bias ) ;
void xglPolygonOffset ( GLfloat factor, GLfloat bias ) ;
void xglPolygonStipple ( GLubyte *mask ) ;
void xglPopAttrib () ;
void xglPopMatrix () ;
void xglPopName () ;
void xglPushAttrib ( GLbitfield mask ) ;
void xglPushMatrix () ;
void xglPushName ( GLuint name ) ;
void xglRasterPos2d ( GLdouble x, GLdouble y ) ;
void xglRasterPos2dv ( GLdouble *v ) ;
void xglRasterPos2f ( GLfloat x, GLfloat y ) ;
void xglRasterPos2fv ( GLfloat *v ) ;
void xglRasterPos2i ( GLint x, GLint y ) ;
void xglRasterPos2iv ( GLint *v ) ;
void xglRasterPos2s ( GLshort x, GLshort y ) ;
void xglRasterPos2sv ( GLshort *v ) ;
void xglRasterPos3d ( GLdouble x, GLdouble y, GLdouble z ) ;
void xglRasterPos3dv ( GLdouble *v ) ;
void xglRasterPos3f ( GLfloat x, GLfloat y, GLfloat z ) ;
void xglRasterPos3fv ( GLfloat *v ) ;
void xglRasterPos3i ( GLint x, GLint y, GLint z ) ;
void xglRasterPos3iv ( GLint *v ) ;
void xglRasterPos3s ( GLshort x, GLshort y, GLshort z ) ;
void xglRasterPos3sv ( GLshort *v ) ;
void xglRasterPos4d ( GLdouble x, GLdouble y, GLdouble z, GLdouble w ) ;
void xglRasterPos4dv ( GLdouble *v ) ;
void xglRasterPos4f ( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) ;
void xglRasterPos4fv ( GLfloat *v ) ;
void xglRasterPos4i ( GLint x, GLint y, GLint z, GLint w ) ;
void xglRasterPos4iv ( GLint *v ) ;
void xglRasterPos4s ( GLshort x, GLshort y, GLshort z, GLshort w ) ;
void xglRasterPos4sv ( GLshort *v ) ;
void xglReadBuffer ( GLenum mode ) ;
void xglReadPixels ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels ) ;
void xglRectd ( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 ) ;
void xglRectdv ( GLdouble *v1, GLdouble *v2 ) ;
void xglRectf ( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) ;
void xglRectfv ( GLfloat *v1, GLfloat *v2 ) ;
void xglRecti ( GLint x1, GLint y1, GLint x2, GLint y2 ) ;
void xglRectiv ( GLint *v1, GLint *v2 ) ;
void xglRects ( GLshort x1, GLshort y1, GLshort x2, GLshort y2 ) ;
void xglRectsv ( GLshort *v1, GLshort *v2 ) ;
void xglRotated ( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ) ;
void xglRotatef ( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) ;
void xglScaled ( GLdouble x, GLdouble y, GLdouble z ) ;
void xglScalef ( GLfloat x, GLfloat y, GLfloat z ) ;
void xglScissor ( GLint x, GLint y, GLsizei width, GLsizei height) ;
void xglSelectBuffer ( GLsizei size, GLuint *buffer ) ;
void xglShadeModel ( GLenum mode ) ;
void xglStencilFunc ( GLenum func, GLint ref, GLuint mask ) ;
void xglStencilMask ( GLuint mask ) ;
void xglStencilOp ( GLenum fail, GLenum zfail, GLenum zpass ) ;
void xglTexCoord1d ( GLdouble s ) ;
void xglTexCoord1dv ( GLdouble *v ) ;
void xglTexCoord1f ( GLfloat s ) ;
void xglTexCoord1fv ( GLfloat *v ) ;
void xglTexCoord1i ( GLint s ) ;
void xglTexCoord1iv ( GLint *v ) ;
void xglTexCoord1s ( GLshort s ) ;
void xglTexCoord1sv ( GLshort *v ) ;
void xglTexCoord2d ( GLdouble s, GLdouble t ) ;
void xglTexCoord2dv ( GLdouble *v ) ;
void xglTexCoord2f ( GLfloat s, GLfloat t ) ;
void xglTexCoord2fv ( GLfloat *v ) ;
void xglTexCoord2i ( GLint s, GLint t ) ;
void xglTexCoord2iv ( GLint *v ) ;
void xglTexCoord2s ( GLshort s, GLshort t ) ;
void xglTexCoord2sv ( GLshort *v ) ;
void xglTexCoord3d ( GLdouble s, GLdouble t, GLdouble r ) ;
void xglTexCoord3dv ( GLdouble *v ) ;
void xglTexCoord3f ( GLfloat s, GLfloat t, GLfloat r ) ;
void xglTexCoord3fv ( GLfloat *v ) ;
void xglTexCoord3i ( GLint s, GLint t, GLint r ) ;
void xglTexCoord3iv ( GLint *v ) ;
void xglTexCoord3s ( GLshort s, GLshort t, GLshort r ) ;
void xglTexCoord3sv ( GLshort *v ) ;
void xglTexCoord4d ( GLdouble s, GLdouble t, GLdouble r, GLdouble q ) ;
void xglTexCoord4dv ( GLdouble *v ) ;
void xglTexCoord4f ( GLfloat s, GLfloat t, GLfloat r, GLfloat q ) ;
void xglTexCoord4fv ( GLfloat *v ) ;
void xglTexCoord4i ( GLint s, GLint t, GLint r, GLint q ) ;
void xglTexCoord4iv ( GLint *v ) ;
void xglTexCoord4s ( GLshort s, GLshort t, GLshort r, GLshort q ) ;
void xglTexCoord4sv ( GLshort *v ) ;
void xglTexCoordPointerEXT( GLint size, GLenum type, GLsizei stride, GLsizei count, void *ptr ) ;
void xglTexEnvf ( GLenum target, GLenum pname, GLfloat param ) ;
void xglTexEnvfv ( GLenum target, GLenum pname, GLfloat *params ) ;
void xglTexEnvi ( GLenum target, GLenum pname, GLint param ) ;
void xglTexEnviv ( GLenum target, GLenum pname, GLint *params ) ;
void xglTexGend ( GLenum coord, GLenum pname, GLdouble param ) ;
void xglTexGendv ( GLenum coord, GLenum pname, GLdouble *params ) ;
void xglTexGenf ( GLenum coord, GLenum pname, GLfloat param ) ;
void xglTexGenfv ( GLenum coord, GLenum pname, GLfloat *params ) ;
void xglTexGeni ( GLenum coord, GLenum pname, GLint param ) ;
void xglTexGeniv ( GLenum coord, GLenum pname, GLint *params ) ;
void xglTexImage1D ( GLenum target, GLint level, GLint components, GLsizei width, GLint border, GLenum format, GLenum type, GLvoid *pixels ) ;
void xglTexImage2D ( GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid *pixels ) ;
void xglTexParameterf ( GLenum target, GLenum pname, GLfloat param ) ;
void xglTexParameterfv ( GLenum target, GLenum pname, GLfloat *params ) ;
void xglTexParameteri ( GLenum target, GLenum pname, GLint param ) ;
void xglTexParameteriv ( GLenum target, GLenum pname, GLint *params ) ;
void xglTranslated ( GLdouble x, GLdouble y, GLdouble z ) ;
void xglTranslatef ( GLfloat x, GLfloat y, GLfloat z ) ;
void xglVertex2d ( GLdouble x, GLdouble y ) ;
void xglVertex2dv ( GLdouble *v ) ;
void xglVertex2f ( GLfloat x, GLfloat y ) ;
void xglVertex2fv ( GLfloat *v ) ;
void xglVertex2i ( GLint x, GLint y ) ;
void xglVertex2iv ( GLint *v ) ;
void xglVertex2s ( GLshort x, GLshort y ) ;
void xglVertex2sv ( GLshort *v ) ;
void xglVertex3d ( GLdouble x, GLdouble y, GLdouble z ) ;
void xglVertex3dv ( GLdouble *v ) ;
void xglVertex3f ( GLfloat x, GLfloat y, GLfloat z ) ;
void xglVertex3fv ( GLfloat *v ) ;
void xglVertex3i ( GLint x, GLint y, GLint z ) ;
void xglVertex3iv ( GLint *v ) ;
void xglVertex3s ( GLshort x, GLshort y, GLshort z ) ;
void xglVertex3sv ( GLshort *v ) ;
void xglVertex4d ( GLdouble x, GLdouble y, GLdouble z, GLdouble w ) ;
void xglVertex4dv ( GLdouble *v ) ;
void xglVertex4f ( GLfloat x, GLfloat y, GLfloat z, GLfloat w ) ;
void xglVertex4fv ( GLfloat *v ) ;
void xglVertex4i ( GLint x, GLint y, GLint z, GLint w ) ;
void xglVertex4iv ( GLint *v ) ;
void xglVertex4s ( GLshort x, GLshort y, GLshort z, GLshort w ) ;
void xglVertex4sv ( GLshort *v ) ;
void xglVertexPointerEXT( GLint size, GLenum type, GLsizei stride, GLsizei count, void *ptr ) ;
void xglViewport ( GLint x, GLint y, GLsizei width, GLsizei height ) ;
void xglutAddMenuEntry ( char *label, int value ) ;
void xglutAttachMenu ( int button ) ;
int xglutCreateMenu ( void (*)(int) ) ;
int xglutCreateWindow ( char *title ) ;
void xglutDisplayFunc ( void (*)(void) ) ;
void xglutIdleFunc ( void (*)(void) ) ;
void xglutInit ( int *argcp, char **argv ) ;
void xglutInitDisplayMode ( unsigned int mode ) ;
void xglutInitWindowPosition ( int x, int y ) ;
void xglutInitWindowSize ( int width, int height ) ;
void xglutKeyboardFunc ( void (*)(unsigned char key, int x, int y) ) ;
void xglutMainLoopUpdate () ;
void xglutPostRedisplay () ;
void xglutPreMainLoop () ;
void xglutReshapeFunc ( void (*)(int width, int height) ) ;
void xglutSwapBuffers () ;
GLboolean xglAreTexturesResident( GLsizei n, GLuint *textures, GLboolean *residences ) ;
GLboolean xglIsTexture ( GLuint texture ) ;
void xglBindTexture ( GLenum target, GLuint texture ) ;
void xglDeleteTextures ( GLsizei n, GLuint *textures ) ;
void xglGenTextures ( GLsizei n, GLuint *textures ) ;
void xglPrioritizeTextures ( GLsizei n, GLuint *textures, GLclampf *priorities ) ;
GLboolean xglAreTexturesResidentEXT ( GLsizei n, GLuint *textures, GLboolean *residences ) ;
GLboolean xglIsTextureEXT ( GLuint texture ) ;
void xglBindTextureEXT ( GLenum target, GLuint texture ) ;
void xglDeleteTexturesEXT ( GLsizei n, GLuint *textures ) ;
void xglGenTexturesEXT ( GLsizei n, GLuint *textures ) ;
void xglPrioritizeTexturesEXT ( GLsizei n, GLuint *textures, GLclampf *priorities ) ;
#endif
#ifdef __cplusplus
}
#endif
#endif /* _XGL_H */

687
Lib/XGL/xglUtils.c Normal file
View file

@ -0,0 +1,687 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined( __CYGWIN__ ) && !defined( __CYGWIN32__ )
# if !defined( HAVE_STL_SGI_PORT ) && !defined( __MWERKS__ )
// Avoid malloc with STLport and MSL
# include <malloc.h>
# endif
#endif
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#include "xgl.h"
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif
int xglTraceOn = TRUE ;
#ifndef WIN32
FILE *xglTraceFd = stdout ;
#else /* WIN32 */
/* Bail for now, we just want it to compile I guess */
FILE *xglTraceFd = NULL;
#endif /* WIN32 */
struct GLenumLookup
{
GLenum val ;
char *name ;
} ;
static struct GLenumLookup glenum_string [] =
{
/*
Due to ambiguity - these are not in the table...
GL_NONE = , GL_ZERO = GL_FALSE = GL_POINTS = 0
GL_ONE = , GL_TRUE = GL_LINES = 1
*/
{ GL_2D ,"GL_2D" },
{ GL_2_BYTES ,"GL_2_BYTES" },
{ GL_3D ,"GL_3D" },
{ GL_3D_COLOR ,"GL_3D_COLOR" },
{ GL_3D_COLOR_TEXTURE ,"GL_3D_COLOR_TEXTURE" },
{ GL_3_BYTES ,"GL_3_BYTES" },
{ GL_4D_COLOR_TEXTURE ,"GL_4D_COLOR_TEXTURE" },
{ GL_4_BYTES ,"GL_4_BYTES" },
{ GL_ACCUM ,"GL_ACCUM" },
{ GL_ACCUM_ALPHA_BITS ,"GL_ACCUM_ALPHA_BITS" },
{ GL_ACCUM_BLUE_BITS ,"GL_ACCUM_BLUE_BITS" },
{ GL_ACCUM_CLEAR_VALUE ,"GL_ACCUM_CLEAR_VALUE" },
{ GL_ACCUM_GREEN_BITS ,"GL_ACCUM_GREEN_BITS" },
{ GL_ACCUM_RED_BITS ,"GL_ACCUM_RED_BITS" },
{ GL_ADD ,"GL_ADD" },
{ GL_ALPHA ,"GL_ALPHA" },
{ GL_ALPHA_BIAS ,"GL_ALPHA_BIAS" },
{ GL_ALPHA_BITS ,"GL_ALPHA_BITS" },
{ GL_ALPHA_SCALE ,"GL_ALPHA_SCALE" },
{ GL_ALPHA_TEST ,"GL_ALPHA_TEST" },
{ GL_ALPHA_TEST_FUNC ,"GL_ALPHA_TEST_FUNC" },
{ GL_ALPHA_TEST_REF ,"GL_ALPHA_TEST_REF" },
{ GL_ALWAYS ,"GL_ALWAYS" },
{ GL_AMBIENT ,"GL_AMBIENT" },
{ GL_AMBIENT_AND_DIFFUSE ,"GL_AMBIENT_AND_DIFFUSE" },
{ GL_AND ,"GL_AND" },
{ GL_AND_INVERTED ,"GL_AND_INVERTED" },
{ GL_AND_REVERSE ,"GL_AND_REVERSE" },
{ GL_ATTRIB_STACK_DEPTH ,"GL_ATTRIB_STACK_DEPTH" },
{ GL_AUTO_NORMAL ,"GL_AUTO_NORMAL" },
{ GL_AUX0 ,"GL_AUX0" },
{ GL_AUX1 ,"GL_AUX1" },
{ GL_AUX2 ,"GL_AUX2" },
{ GL_AUX3 ,"GL_AUX3" },
{ GL_AUX_BUFFERS ,"GL_AUX_BUFFERS" },
{ GL_BACK ,"GL_BACK" },
{ GL_BACK_LEFT ,"GL_BACK_LEFT" },
{ GL_BACK_RIGHT ,"GL_BACK_RIGHT" },
{ GL_BITMAP ,"GL_BITMAP" },
{ GL_BITMAP_TOKEN ,"GL_BITMAP_TOKEN" },
{ GL_BLEND ,"GL_BLEND" },
{ GL_BLEND_DST ,"GL_BLEND_DST" },
#ifdef GL_BLEND_COLOR_EXT
{ GL_BLEND_COLOR_EXT ,"GL_BLEND_COLOR_EXT" },
#endif
#ifdef GL_BLEND_EQUATION_EXT
{ GL_BLEND_EQUATION_EXT ,"GL_BLEND_EQUATION_EXT" },
#endif
{ GL_BLEND_SRC ,"GL_BLEND_SRC" },
{ GL_BLUE ,"GL_BLUE" },
{ GL_BLUE_BIAS ,"GL_BLUE_BIAS" },
{ GL_BLUE_BITS ,"GL_BLUE_BITS" },
{ GL_BLUE_SCALE ,"GL_BLUE_SCALE" },
{ GL_BYTE ,"GL_BYTE" },
{ GL_CCW ,"GL_CCW" },
{ GL_CLAMP ,"GL_CLAMP" },
{ GL_CLEAR ,"GL_CLEAR" },
{ GL_CLIP_PLANE0 ,"GL_CLIP_PLANE0" },
{ GL_CLIP_PLANE1 ,"GL_CLIP_PLANE1" },
{ GL_CLIP_PLANE2 ,"GL_CLIP_PLANE2" },
{ GL_CLIP_PLANE3 ,"GL_CLIP_PLANE3" },
{ GL_CLIP_PLANE4 ,"GL_CLIP_PLANE4" },
{ GL_CLIP_PLANE5 ,"GL_CLIP_PLANE5" },
{ GL_COEFF ,"GL_COEFF" },
{ GL_COLOR ,"GL_COLOR" },
#ifdef GL_COLOR_ARRAY_EXT
{ GL_COLOR_ARRAY_COUNT_EXT ,"GL_COLOR_ARRAY_COUNT_EXT" },
{ GL_COLOR_ARRAY_EXT ,"GL_COLOR_ARRAY_EXT" },
{ GL_COLOR_ARRAY_POINTER_EXT ,"GL_COLOR_ARRAY_POINTER_EXT" },
{ GL_COLOR_ARRAY_SIZE_EXT ,"GL_COLOR_ARRAY_SIZE_EXT" },
{ GL_COLOR_ARRAY_STRIDE_EXT ,"GL_COLOR_ARRAY_STRIDE_EXT" },
{ GL_COLOR_ARRAY_TYPE_EXT ,"GL_COLOR_ARRAY_TYPE_EXT" },
#endif
{ GL_COLOR_CLEAR_VALUE ,"GL_COLOR_CLEAR_VALUE" },
{ GL_COLOR_INDEX ,"GL_COLOR_INDEX" },
{ GL_COLOR_INDEXES ,"GL_COLOR_INDEXES" },
{ GL_COLOR_MATERIAL ,"GL_COLOR_MATERIAL" },
{ GL_COLOR_MATERIAL_FACE ,"GL_COLOR_MATERIAL_FACE" },
{ GL_COLOR_MATERIAL_PARAMETER ,"GL_COLOR_MATERIAL_PARAMETER" },
{ GL_COLOR_WRITEMASK ,"GL_COLOR_WRITEMASK" },
{ GL_COMPILE ,"GL_COMPILE" },
{ GL_COMPILE_AND_EXECUTE ,"GL_COMPILE_AND_EXECUTE" },
#ifdef GL_CONSTANT_ALPHA_EXT
{ GL_CONSTANT_ALPHA_EXT ,"GL_CONSTANT_ALPHA_EXT" },
#endif
{ GL_CONSTANT_ATTENUATION ,"GL_CONSTANT_ATTENUATION" },
#ifdef GL_CONSTANT_COLOR_EXT
{ GL_CONSTANT_COLOR_EXT ,"GL_CONSTANT_COLOR_EXT" },
#endif
{ GL_COPY ,"GL_COPY" },
{ GL_COPY_INVERTED ,"GL_COPY_INVERTED" },
{ GL_COPY_PIXEL_TOKEN ,"GL_COPY_PIXEL_TOKEN" },
{ GL_CULL_FACE ,"GL_CULL_FACE" },
{ GL_CULL_FACE_MODE ,"GL_CULL_FACE_MODE" },
{ GL_CURRENT_COLOR ,"GL_CURRENT_COLOR" },
{ GL_CURRENT_INDEX ,"GL_CURRENT_INDEX" },
{ GL_CURRENT_NORMAL ,"GL_CURRENT_NORMAL" },
{ GL_CURRENT_RASTER_COLOR ,"GL_CURRENT_RASTER_COLOR" },
{ GL_CURRENT_RASTER_DISTANCE ,"GL_CURRENT_RASTER_DISTANCE" },
{ GL_CURRENT_RASTER_INDEX ,"GL_CURRENT_RASTER_INDEX" },
{ GL_CURRENT_RASTER_POSITION ,"GL_CURRENT_RASTER_POSITION" },
{ GL_CURRENT_RASTER_POSITION_VALID,"GL_CURRENT_RASTER_POSITION_VALID" },
{ GL_CURRENT_RASTER_TEXTURE_COORDS,"GL_CURRENT_RASTER_TEXTURE_COORDS" },
{ GL_CURRENT_TEXTURE_COORDS ,"GL_CURRENT_TEXTURE_COORDS" },
{ GL_CW ,"GL_CW" },
{ GL_DECAL ,"GL_DECAL" },
{ GL_DECR ,"GL_DECR" },
{ GL_DEPTH ,"GL_DEPTH" },
{ GL_DEPTH_BIAS ,"GL_DEPTH_BIAS" },
{ GL_DEPTH_BITS ,"GL_DEPTH_BITS" },
{ GL_DEPTH_CLEAR_VALUE ,"GL_DEPTH_CLEAR_VALUE" },
{ GL_DEPTH_COMPONENT ,"GL_DEPTH_COMPONENT" },
{ GL_DEPTH_FUNC ,"GL_DEPTH_FUNC" },
{ GL_DEPTH_RANGE ,"GL_DEPTH_RANGE" },
{ GL_DEPTH_SCALE ,"GL_DEPTH_SCALE" },
{ GL_DEPTH_TEST ,"GL_DEPTH_TEST" },
{ GL_DEPTH_WRITEMASK ,"GL_DEPTH_WRITEMASK" },
{ GL_DIFFUSE ,"GL_DIFFUSE" },
{ GL_DITHER ,"GL_DITHER" },
{ GL_DOMAIN ,"GL_DOMAIN" },
{ GL_DONT_CARE ,"GL_DONT_CARE" },
{ GL_DOUBLEBUFFER ,"GL_DOUBLEBUFFER" },
#ifdef GL_DOUBLE_EXT
{ GL_DOUBLE_EXT ,"GL_DOUBLE_EXT" },
#endif
{ GL_DRAW_BUFFER ,"GL_DRAW_BUFFER" },
{ GL_DRAW_PIXEL_TOKEN ,"GL_DRAW_PIXEL_TOKEN" },
{ GL_DST_ALPHA ,"GL_DST_ALPHA" },
{ GL_DST_COLOR ,"GL_DST_COLOR" },
{ GL_EDGE_FLAG ,"GL_EDGE_FLAG" },
#ifdef GL_EDGE_FLAG_ARRAY_EXT
{ GL_EDGE_FLAG_ARRAY_COUNT_EXT,"GL_EDGE_FLAG_ARRAY_COUNT_EXT" },
{ GL_EDGE_FLAG_ARRAY_EXT ,"GL_EDGE_FLAG_ARRAY_EXT" },
{ GL_EDGE_FLAG_ARRAY_POINTER_EXT,"GL_EDGE_FLAG_ARRAY_POINTER_EXT" },
{ GL_EDGE_FLAG_ARRAY_STRIDE_EXT,"GL_EDGE_FLAG_ARRAY_STRIDE_EXT" },
#endif
{ GL_EMISSION ,"GL_EMISSION" },
{ GL_EQUAL ,"GL_EQUAL" },
{ GL_EQUIV ,"GL_EQUIV" },
{ GL_EXP ,"GL_EXP" },
{ GL_EXP2 ,"GL_EXP2" },
{ GL_EXTENSIONS ,"GL_EXTENSIONS" },
{ GL_EYE_LINEAR ,"GL_EYE_LINEAR" },
{ GL_EYE_PLANE ,"GL_EYE_PLANE" },
{ GL_FASTEST ,"GL_FASTEST" },
{ GL_FEEDBACK ,"GL_FEEDBACK" },
{ GL_FILL ,"GL_FILL" },
{ GL_FLAT ,"GL_FLAT" },
{ GL_FLOAT ,"GL_FLOAT" },
{ GL_FOG ,"GL_FOG" },
{ GL_FOG_COLOR ,"GL_FOG_COLOR" },
{ GL_FOG_DENSITY ,"GL_FOG_DENSITY" },
{ GL_FOG_END ,"GL_FOG_END" },
{ GL_FOG_HINT ,"GL_FOG_HINT" },
{ GL_FOG_INDEX ,"GL_FOG_INDEX" },
{ GL_FOG_MODE ,"GL_FOG_MODE" },
{ GL_FOG_START ,"GL_FOG_START" },
{ GL_FRONT ,"GL_FRONT" },
{ GL_FRONT_AND_BACK ,"GL_FRONT_AND_BACK" },
{ GL_FRONT_FACE ,"GL_FRONT_FACE" },
{ GL_FRONT_LEFT ,"GL_FRONT_LEFT" },
{ GL_FRONT_RIGHT ,"GL_FRONT_RIGHT" },
#ifdef GL_FUNC_ADD_EXT
{ GL_FUNC_ADD_EXT ,"GL_FUNC_ADD_EXT" },
{ GL_FUNC_REVERSE_SUBTRACT_EXT,"GL_FUNC_REVERSE_SUBTRACT_EXT" },
{ GL_FUNC_SUBTRACT_EXT ,"GL_FUNC_SUBTRACT_EXT" },
#endif
{ GL_GEQUAL ,"GL_GEQUAL" },
{ GL_GREATER ,"GL_GREATER" },
{ GL_GREEN ,"GL_GREEN" },
{ GL_GREEN_BIAS ,"GL_GREEN_BIAS" },
{ GL_GREEN_BITS ,"GL_GREEN_BITS" },
{ GL_GREEN_SCALE ,"GL_GREEN_SCALE" },
{ GL_INCR ,"GL_INCR" },
#ifdef GL_INDEX_ARRAY_EXT
{ GL_INDEX_ARRAY_COUNT_EXT ,"GL_INDEX_ARRAY_COUNT_EXT" },
{ GL_INDEX_ARRAY_EXT ,"GL_INDEX_ARRAY_EXT" },
{ GL_INDEX_ARRAY_POINTER_EXT ,"GL_INDEX_ARRAY_POINTER_EXT" },
{ GL_INDEX_ARRAY_STRIDE_EXT ,"GL_INDEX_ARRAY_STRIDE_EXT" },
{ GL_INDEX_ARRAY_TYPE_EXT ,"GL_INDEX_ARRAY_TYPE_EXT" },
#endif
{ GL_INDEX_BITS ,"GL_INDEX_BITS" },
{ GL_INDEX_CLEAR_VALUE ,"GL_INDEX_CLEAR_VALUE" },
{ GL_INDEX_MODE ,"GL_INDEX_MODE" },
{ GL_INDEX_OFFSET ,"GL_INDEX_OFFSET" },
{ GL_INDEX_SHIFT ,"GL_INDEX_SHIFT" },
{ GL_INDEX_WRITEMASK ,"GL_INDEX_WRITEMASK" },
{ GL_INT ,"GL_INT" },
{ GL_INVALID_ENUM ,"GL_INVALID_ENUM" },
{ GL_INVALID_OPERATION ,"GL_INVALID_OPERATION" },
{ GL_INVALID_VALUE ,"GL_INVALID_VALUE" },
{ GL_INVERT ,"GL_INVERT" },
{ GL_KEEP ,"GL_KEEP" },
{ GL_LEFT ,"GL_LEFT" },
{ GL_LEQUAL ,"GL_LEQUAL" },
{ GL_LESS ,"GL_LESS" },
{ GL_LIGHT0 ,"GL_LIGHT0" },
{ GL_LIGHT1 ,"GL_LIGHT1" },
{ GL_LIGHT2 ,"GL_LIGHT2" },
{ GL_LIGHT3 ,"GL_LIGHT3" },
{ GL_LIGHT4 ,"GL_LIGHT4" },
{ GL_LIGHT5 ,"GL_LIGHT5" },
{ GL_LIGHT6 ,"GL_LIGHT6" },
{ GL_LIGHT7 ,"GL_LIGHT7" },
{ GL_LIGHTING ,"GL_LIGHTING" },
{ GL_LIGHT_MODEL_AMBIENT ,"GL_LIGHT_MODEL_AMBIENT" },
{ GL_LIGHT_MODEL_LOCAL_VIEWER ,"GL_LIGHT_MODEL_LOCAL_VIEWER" },
{ GL_LIGHT_MODEL_TWO_SIDE ,"GL_LIGHT_MODEL_TWO_SIDE" },
{ GL_LINE ,"GL_LINE" },
{ GL_LINEAR ,"GL_LINEAR" },
{ GL_LINEAR_ATTENUATION ,"GL_LINEAR_ATTENUATION" },
{ GL_LINEAR_MIPMAP_LINEAR ,"GL_LINEAR_MIPMAP_LINEAR" },
{ GL_LINEAR_MIPMAP_NEAREST ,"GL_LINEAR_MIPMAP_NEAREST" },
{ GL_LINE_LOOP ,"GL_LINE_LOOP" },
{ GL_LINE_RESET_TOKEN ,"GL_LINE_RESET_TOKEN" },
{ GL_LINE_SMOOTH ,"GL_LINE_SMOOTH" },
{ GL_LINE_SMOOTH_HINT ,"GL_LINE_SMOOTH_HINT" },
{ GL_LINE_STIPPLE ,"GL_LINE_STIPPLE" },
{ GL_LINE_STIPPLE_PATTERN ,"GL_LINE_STIPPLE_PATTERN" },
{ GL_LINE_STIPPLE_REPEAT ,"GL_LINE_STIPPLE_REPEAT" },
{ GL_LINE_STRIP ,"GL_LINE_STRIP" },
{ GL_LINE_TOKEN ,"GL_LINE_TOKEN" },
{ GL_LINE_WIDTH ,"GL_LINE_WIDTH" },
{ GL_LINE_WIDTH_GRANULARITY ,"GL_LINE_WIDTH_GRANULARITY" },
{ GL_LINE_WIDTH_RANGE ,"GL_LINE_WIDTH_RANGE" },
{ GL_LIST_BASE ,"GL_LIST_BASE" },
{ GL_LIST_INDEX ,"GL_LIST_INDEX" },
{ GL_LIST_MODE ,"GL_LIST_MODE" },
{ GL_LOAD ,"GL_LOAD" },
{ GL_LOGIC_OP ,"GL_LOGIC_OP" },
{ GL_LOGIC_OP_MODE ,"GL_LOGIC_OP_MODE" },
{ GL_LUMINANCE ,"GL_LUMINANCE" },
{ GL_LUMINANCE_ALPHA ,"GL_LUMINANCE_ALPHA" },
{ GL_MAP1_COLOR_4 ,"GL_MAP1_COLOR_4" },
{ GL_MAP1_GRID_DOMAIN ,"GL_MAP1_GRID_DOMAIN" },
{ GL_MAP1_GRID_SEGMENTS ,"GL_MAP1_GRID_SEGMENTS" },
{ GL_MAP1_INDEX ,"GL_MAP1_INDEX" },
{ GL_MAP1_NORMAL ,"GL_MAP1_NORMAL" },
{ GL_MAP1_TEXTURE_COORD_1 ,"GL_MAP1_TEXTURE_COORD_1" },
{ GL_MAP1_TEXTURE_COORD_2 ,"GL_MAP1_TEXTURE_COORD_2" },
{ GL_MAP1_TEXTURE_COORD_3 ,"GL_MAP1_TEXTURE_COORD_3" },
{ GL_MAP1_TEXTURE_COORD_4 ,"GL_MAP1_TEXTURE_COORD_4" },
{ GL_MAP1_VERTEX_3 ,"GL_MAP1_VERTEX_3" },
{ GL_MAP1_VERTEX_4 ,"GL_MAP1_VERTEX_4" },
{ GL_MAP2_COLOR_4 ,"GL_MAP2_COLOR_4" },
{ GL_MAP2_GRID_DOMAIN ,"GL_MAP2_GRID_DOMAIN" },
{ GL_MAP2_GRID_SEGMENTS ,"GL_MAP2_GRID_SEGMENTS" },
{ GL_MAP2_INDEX ,"GL_MAP2_INDEX" },
{ GL_MAP2_NORMAL ,"GL_MAP2_NORMAL" },
{ GL_MAP2_TEXTURE_COORD_1 ,"GL_MAP2_TEXTURE_COORD_1" },
{ GL_MAP2_TEXTURE_COORD_2 ,"GL_MAP2_TEXTURE_COORD_2" },
{ GL_MAP2_TEXTURE_COORD_3 ,"GL_MAP2_TEXTURE_COORD_3" },
{ GL_MAP2_TEXTURE_COORD_4 ,"GL_MAP2_TEXTURE_COORD_4" },
{ GL_MAP2_VERTEX_3 ,"GL_MAP2_VERTEX_3" },
{ GL_MAP2_VERTEX_4 ,"GL_MAP2_VERTEX_4" },
{ GL_MAP_COLOR ,"GL_MAP_COLOR" },
{ GL_MAP_STENCIL ,"GL_MAP_STENCIL" },
{ GL_MATRIX_MODE ,"GL_MATRIX_MODE" },
{ GL_MAX_ATTRIB_STACK_DEPTH ,"GL_MAX_ATTRIB_STACK_DEPTH" },
{ GL_MAX_CLIP_PLANES ,"GL_MAX_CLIP_PLANES" },
{ GL_MAX_EVAL_ORDER ,"GL_MAX_EVAL_ORDER" },
#ifdef GL_MAX_EXT
{ GL_MAX_EXT ,"GL_MAX_EXT" },
#endif
{ GL_MAX_LIGHTS ,"GL_MAX_LIGHTS" },
{ GL_MAX_LIST_NESTING ,"GL_MAX_LIST_NESTING" },
{ GL_MAX_MODELVIEW_STACK_DEPTH,"GL_MAX_MODELVIEW_STACK_DEPTH" },
{ GL_MAX_NAME_STACK_DEPTH ,"GL_MAX_NAME_STACK_DEPTH" },
{ GL_MAX_PIXEL_MAP_TABLE ,"GL_MAX_PIXEL_MAP_TABLE" },
{ GL_MAX_PROJECTION_STACK_DEPTH,"GL_MAX_PROJECTION_STACK_DEPTH" },
{ GL_MAX_TEXTURE_SIZE ,"GL_MAX_TEXTURE_SIZE" },
{ GL_MAX_TEXTURE_STACK_DEPTH ,"GL_MAX_TEXTURE_STACK_DEPTH" },
{ GL_MAX_VIEWPORT_DIMS ,"GL_MAX_VIEWPORT_DIMS" },
#ifdef GL_MIN_EXT
{ GL_MIN_EXT ,"GL_MIN_EXT" },
#endif
{ GL_MODELVIEW ,"GL_MODELVIEW" },
{ GL_MODELVIEW_MATRIX ,"GL_MODELVIEW_MATRIX" },
{ GL_MODELVIEW_STACK_DEPTH ,"GL_MODELVIEW_STACK_DEPTH" },
{ GL_MODULATE ,"GL_MODULATE" },
{ GL_MULT ,"GL_MULT" },
{ GL_NAME_STACK_DEPTH ,"GL_NAME_STACK_DEPTH" },
{ GL_NAND ,"GL_NAND" },
{ GL_NEAREST ,"GL_NEAREST" },
{ GL_NEAREST_MIPMAP_LINEAR ,"GL_NEAREST_MIPMAP_LINEAR" },
{ GL_NEAREST_MIPMAP_NEAREST ,"GL_NEAREST_MIPMAP_NEAREST" },
{ GL_NEVER ,"GL_NEVER" },
{ GL_NICEST ,"GL_NICEST" },
{ GL_NOOP ,"GL_NOOP" },
{ GL_NOR ,"GL_NOR" },
{ GL_NORMALIZE ,"GL_NORMALIZE" },
#ifdef GL_NORMAL_ARRAY_EXT
{ GL_NORMAL_ARRAY_COUNT_EXT ,"GL_NORMAL_ARRAY_COUNT_EXT" },
{ GL_NORMAL_ARRAY_EXT ,"GL_NORMAL_ARRAY_EXT" },
{ GL_NORMAL_ARRAY_POINTER_EXT ,"GL_NORMAL_ARRAY_POINTER_EXT" },
{ GL_NORMAL_ARRAY_STRIDE_EXT ,"GL_NORMAL_ARRAY_STRIDE_EXT" },
{ GL_NORMAL_ARRAY_TYPE_EXT ,"GL_NORMAL_ARRAY_TYPE_EXT" },
#endif
{ GL_NOTEQUAL ,"GL_NOTEQUAL" },
{ GL_OBJECT_LINEAR ,"GL_OBJECT_LINEAR" },
{ GL_OBJECT_PLANE ,"GL_OBJECT_PLANE" },
#ifdef GL_ONE_MINUS_CONSTANT_ALPHA_EXT
{ GL_ONE_MINUS_CONSTANT_ALPHA_EXT,"GL_ONE_MINUS_CONSTANT_ALPHA_EXT" },
{ GL_ONE_MINUS_CONSTANT_COLOR_EXT,"GL_ONE_MINUS_CONSTANT_COLOR_EXT" },
#endif
{ GL_ONE_MINUS_DST_ALPHA ,"GL_ONE_MINUS_DST_ALPHA" },
{ GL_ONE_MINUS_DST_COLOR ,"GL_ONE_MINUS_DST_COLOR" },
{ GL_ONE_MINUS_SRC_ALPHA ,"GL_ONE_MINUS_SRC_ALPHA" },
{ GL_ONE_MINUS_SRC_COLOR ,"GL_ONE_MINUS_SRC_COLOR" },
{ GL_OR ,"GL_OR" },
{ GL_ORDER ,"GL_ORDER" },
{ GL_OR_INVERTED ,"GL_OR_INVERTED" },
{ GL_OR_REVERSE ,"GL_OR_REVERSE" },
{ GL_OUT_OF_MEMORY ,"GL_OUT_OF_MEMORY" },
{ GL_PACK_ALIGNMENT ,"GL_PACK_ALIGNMENT" },
{ GL_PACK_LSB_FIRST ,"GL_PACK_LSB_FIRST" },
{ GL_PACK_ROW_LENGTH ,"GL_PACK_ROW_LENGTH" },
{ GL_PACK_SKIP_PIXELS ,"GL_PACK_SKIP_PIXELS" },
{ GL_PACK_SKIP_ROWS ,"GL_PACK_SKIP_ROWS" },
{ GL_PACK_SWAP_BYTES ,"GL_PACK_SWAP_BYTES" },
{ GL_PASS_THROUGH_TOKEN ,"GL_PASS_THROUGH_TOKEN" },
{ GL_PERSPECTIVE_CORRECTION_HINT,"GL_PERSPECTIVE_CORRECTION_HINT" },
{ GL_PIXEL_MAP_A_TO_A ,"GL_PIXEL_MAP_A_TO_A" },
{ GL_PIXEL_MAP_A_TO_A_SIZE ,"GL_PIXEL_MAP_A_TO_A_SIZE" },
{ GL_PIXEL_MAP_B_TO_B ,"GL_PIXEL_MAP_B_TO_B" },
{ GL_PIXEL_MAP_B_TO_B_SIZE ,"GL_PIXEL_MAP_B_TO_B_SIZE" },
{ GL_PIXEL_MAP_G_TO_G ,"GL_PIXEL_MAP_G_TO_G" },
{ GL_PIXEL_MAP_G_TO_G_SIZE ,"GL_PIXEL_MAP_G_TO_G_SIZE" },
{ GL_PIXEL_MAP_I_TO_A ,"GL_PIXEL_MAP_I_TO_A" },
{ GL_PIXEL_MAP_I_TO_A_SIZE ,"GL_PIXEL_MAP_I_TO_A_SIZE" },
{ GL_PIXEL_MAP_I_TO_B ,"GL_PIXEL_MAP_I_TO_B" },
{ GL_PIXEL_MAP_I_TO_B_SIZE ,"GL_PIXEL_MAP_I_TO_B_SIZE" },
{ GL_PIXEL_MAP_I_TO_G ,"GL_PIXEL_MAP_I_TO_G" },
{ GL_PIXEL_MAP_I_TO_G_SIZE ,"GL_PIXEL_MAP_I_TO_G_SIZE" },
{ GL_PIXEL_MAP_I_TO_I ,"GL_PIXEL_MAP_I_TO_I" },
{ GL_PIXEL_MAP_I_TO_I_SIZE ,"GL_PIXEL_MAP_I_TO_I_SIZE" },
{ GL_PIXEL_MAP_I_TO_R ,"GL_PIXEL_MAP_I_TO_R" },
{ GL_PIXEL_MAP_I_TO_R_SIZE ,"GL_PIXEL_MAP_I_TO_R_SIZE" },
{ GL_PIXEL_MAP_R_TO_R ,"GL_PIXEL_MAP_R_TO_R" },
{ GL_PIXEL_MAP_R_TO_R_SIZE ,"GL_PIXEL_MAP_R_TO_R_SIZE" },
{ GL_PIXEL_MAP_S_TO_S ,"GL_PIXEL_MAP_S_TO_S" },
{ GL_PIXEL_MAP_S_TO_S_SIZE ,"GL_PIXEL_MAP_S_TO_S_SIZE" },
{ GL_POINT ,"GL_POINT" },
{ GL_POINT_SIZE ,"GL_POINT_SIZE" },
{ GL_POINT_SIZE_GRANULARITY ,"GL_POINT_SIZE_GRANULARITY" },
{ GL_POINT_SIZE_RANGE ,"GL_POINT_SIZE_RANGE" },
{ GL_POINT_SMOOTH ,"GL_POINT_SMOOTH" },
{ GL_POINT_SMOOTH_HINT ,"GL_POINT_SMOOTH_HINT" },
{ GL_POINT_TOKEN ,"GL_POINT_TOKEN" },
{ GL_POLYGON ,"GL_POLYGON" },
{ GL_POLYGON_MODE ,"GL_POLYGON_MODE" },
{ GL_POLYGON_SMOOTH ,"GL_POLYGON_SMOOTH" },
{ GL_POLYGON_SMOOTH_HINT ,"GL_POLYGON_SMOOTH_HINT" },
{ GL_POLYGON_STIPPLE ,"GL_POLYGON_STIPPLE" },
#ifdef GL_POLYGON_OFFSET_EXT
{ GL_POLYGON_OFFSET_BIAS_EXT ,"GL_POLYGON_OFFSET_BIAS_EXT" },
{ GL_POLYGON_OFFSET_EXT ,"GL_POLYGON_OFFSET_EXT" },
{ GL_POLYGON_OFFSET_FACTOR_EXT,"GL_POLYGON_OFFSET_FACTOR_EXT" },
#endif
{ GL_POLYGON_TOKEN ,"GL_POLYGON_TOKEN" },
{ GL_POSITION ,"GL_POSITION" },
{ GL_PROJECTION ,"GL_PROJECTION" },
{ GL_PROJECTION_MATRIX ,"GL_PROJECTION_MATRIX" },
{ GL_PROJECTION_STACK_DEPTH ,"GL_PROJECTION_STACK_DEPTH" },
{ GL_Q ,"GL_Q" },
{ GL_QUADRATIC_ATTENUATION ,"GL_QUADRATIC_ATTENUATION" },
{ GL_QUADS ,"GL_QUADS" },
{ GL_QUAD_STRIP ,"GL_QUAD_STRIP" },
{ GL_R ,"GL_R" },
{ GL_READ_BUFFER ,"GL_READ_BUFFER" },
{ GL_RED ,"GL_RED" },
{ GL_RED_BIAS ,"GL_RED_BIAS" },
{ GL_RED_BITS ,"GL_RED_BITS" },
{ GL_RED_SCALE ,"GL_RED_SCALE" },
{ GL_RENDER ,"GL_RENDER" },
{ GL_RENDERER ,"GL_RENDERER" },
{ GL_RENDER_MODE ,"GL_RENDER_MODE" },
{ GL_REPEAT ,"GL_REPEAT" },
{ GL_REPLACE ,"GL_REPLACE" },
#ifdef GL_REPLACE_EXT
{ GL_REPLACE_EXT ,"GL_REPLACE_EXT" },
#endif
{ GL_RETURN ,"GL_RETURN" },
{ GL_RGB ,"GL_RGB" },
{ GL_RGBA ,"GL_RGBA" },
{ GL_RGBA_MODE ,"GL_RGBA_MODE" },
{ GL_RIGHT ,"GL_RIGHT" },
{ GL_S ,"GL_S" },
{ GL_SCISSOR_BOX ,"GL_SCISSOR_BOX" },
{ GL_SCISSOR_TEST ,"GL_SCISSOR_TEST" },
{ GL_SELECT ,"GL_SELECT" },
{ GL_SET ,"GL_SET" },
{ GL_SHADE_MODEL ,"GL_SHADE_MODEL" },
{ GL_SHININESS ,"GL_SHININESS" },
{ GL_SHORT ,"GL_SHORT" },
{ GL_SMOOTH ,"GL_SMOOTH" },
{ GL_SPECULAR ,"GL_SPECULAR" },
{ GL_SPHERE_MAP ,"GL_SPHERE_MAP" },
{ GL_SPOT_CUTOFF ,"GL_SPOT_CUTOFF" },
{ GL_SPOT_DIRECTION ,"GL_SPOT_DIRECTION" },
{ GL_SPOT_EXPONENT ,"GL_SPOT_EXPONENT" },
{ GL_SRC_ALPHA ,"GL_SRC_ALPHA" },
{ GL_SRC_ALPHA_SATURATE ,"GL_SRC_ALPHA_SATURATE" },
{ GL_SRC_COLOR ,"GL_SRC_COLOR" },
{ GL_STACK_OVERFLOW ,"GL_STACK_OVERFLOW" },
{ GL_STACK_UNDERFLOW ,"GL_STACK_UNDERFLOW" },
{ GL_STENCIL ,"GL_STENCIL" },
{ GL_STENCIL_BITS ,"GL_STENCIL_BITS" },
{ GL_STENCIL_CLEAR_VALUE ,"GL_STENCIL_CLEAR_VALUE" },
{ GL_STENCIL_FAIL ,"GL_STENCIL_FAIL" },
{ GL_STENCIL_FUNC ,"GL_STENCIL_FUNC" },
{ GL_STENCIL_INDEX ,"GL_STENCIL_INDEX" },
{ GL_STENCIL_PASS_DEPTH_FAIL ,"GL_STENCIL_PASS_DEPTH_FAIL" },
{ GL_STENCIL_PASS_DEPTH_PASS ,"GL_STENCIL_PASS_DEPTH_PASS" },
{ GL_STENCIL_REF ,"GL_STENCIL_REF" },
{ GL_STENCIL_TEST ,"GL_STENCIL_TEST" },
{ GL_STENCIL_VALUE_MASK ,"GL_STENCIL_VALUE_MASK" },
{ GL_STENCIL_WRITEMASK ,"GL_STENCIL_WRITEMASK" },
{ GL_STEREO ,"GL_STEREO" },
{ GL_SUBPIXEL_BITS ,"GL_SUBPIXEL_BITS" },
{ GL_T ,"GL_T" },
{ GL_TEXTURE ,"GL_TEXTURE" },
{ GL_TEXTURE_1D ,"GL_TEXTURE_1D" },
{ GL_TEXTURE_2D ,"GL_TEXTURE_2D" },
{ GL_TEXTURE_BORDER ,"GL_TEXTURE_BORDER" },
{ GL_TEXTURE_BORDER_COLOR ,"GL_TEXTURE_BORDER_COLOR" },
{ GL_TEXTURE_COMPONENTS ,"GL_TEXTURE_COMPONENTS" },
#ifdef GL_TEXTURE_COORD_ARRAY_EXT
{ GL_TEXTURE_COORD_ARRAY_COUNT_EXT,"GL_TEXTURE_COORD_ARRAY_COUNT_EXT" },
{ GL_TEXTURE_COORD_ARRAY_EXT ,"GL_TEXTURE_COORD_ARRAY_EXT" },
{ GL_TEXTURE_COORD_ARRAY_POINTER_EXT,"GL_TEXTURE_COORD_ARRAY_POINTER_EXT" },
{ GL_TEXTURE_COORD_ARRAY_SIZE_EXT,"GL_TEXTURE_COORD_ARRAY_SIZE_EXT" },
{ GL_TEXTURE_COORD_ARRAY_STRIDE_EXT,"GL_TEXTURE_COORD_ARRAY_STRIDE_EXT" },
{ GL_TEXTURE_COORD_ARRAY_TYPE_EXT,"GL_TEXTURE_COORD_ARRAY_TYPE_EXT" },
#endif
{ GL_TEXTURE_ENV ,"GL_TEXTURE_ENV" },
{ GL_TEXTURE_ENV_COLOR ,"GL_TEXTURE_ENV_COLOR" },
{ GL_TEXTURE_ENV_MODE ,"GL_TEXTURE_ENV_MODE" },
{ GL_TEXTURE_GEN_MODE ,"GL_TEXTURE_GEN_MODE" },
{ GL_TEXTURE_GEN_Q ,"GL_TEXTURE_GEN_Q" },
{ GL_TEXTURE_GEN_R ,"GL_TEXTURE_GEN_R" },
{ GL_TEXTURE_GEN_S ,"GL_TEXTURE_GEN_S" },
{ GL_TEXTURE_GEN_T ,"GL_TEXTURE_GEN_T" },
{ GL_TEXTURE_HEIGHT ,"GL_TEXTURE_HEIGHT" },
{ GL_TEXTURE_MAG_FILTER ,"GL_TEXTURE_MAG_FILTER" },
{ GL_TEXTURE_MATRIX ,"GL_TEXTURE_MATRIX" },
{ GL_TEXTURE_MIN_FILTER ,"GL_TEXTURE_MIN_FILTER" },
{ GL_TEXTURE_STACK_DEPTH ,"GL_TEXTURE_STACK_DEPTH" },
{ GL_TEXTURE_WIDTH ,"GL_TEXTURE_WIDTH" },
{ GL_TEXTURE_WRAP_S ,"GL_TEXTURE_WRAP_S" },
{ GL_TEXTURE_WRAP_T ,"GL_TEXTURE_WRAP_T" },
{ GL_TRIANGLES ,"GL_TRIANGLES" },
{ GL_TRIANGLE_FAN ,"GL_TRIANGLE_FAN" },
{ GL_TRIANGLE_STRIP ,"GL_TRIANGLE_STRIP" },
{ GL_UNPACK_ALIGNMENT ,"GL_UNPACK_ALIGNMENT" },
{ GL_UNPACK_LSB_FIRST ,"GL_UNPACK_LSB_FIRST" },
{ GL_UNPACK_ROW_LENGTH ,"GL_UNPACK_ROW_LENGTH" },
{ GL_UNPACK_SKIP_PIXELS ,"GL_UNPACK_SKIP_PIXELS" },
{ GL_UNPACK_SKIP_ROWS ,"GL_UNPACK_SKIP_ROWS" },
{ GL_UNPACK_SWAP_BYTES ,"GL_UNPACK_SWAP_BYTES" },
{ GL_UNSIGNED_BYTE ,"GL_UNSIGNED_BYTE" },
{ GL_UNSIGNED_INT ,"GL_UNSIGNED_INT" },
{ GL_UNSIGNED_SHORT ,"GL_UNSIGNED_SHORT" },
{ GL_VENDOR ,"GL_VENDOR" },
{ GL_VERSION ,"GL_VERSION" },
#ifdef GL_VERTEX_ARRAY_EXT
{ GL_VERTEX_ARRAY_COUNT_EXT ,"GL_VERTEX_ARRAY_COUNT_EXT" },
{ GL_VERTEX_ARRAY_EXT ,"GL_VERTEX_ARRAY_EXT" },
{ GL_VERTEX_ARRAY_POINTER_EXT ,"GL_VERTEX_ARRAY_POINTER_EXT" },
{ GL_VERTEX_ARRAY_SIZE_EXT ,"GL_VERTEX_ARRAY_SIZE_EXT" },
{ GL_VERTEX_ARRAY_STRIDE_EXT ,"GL_VERTEX_ARRAY_STRIDE_EXT" },
{ GL_VERTEX_ARRAY_TYPE_EXT ,"GL_VERTEX_ARRAY_TYPE_EXT" },
#endif
{ GL_VIEWPORT ,"GL_VIEWPORT" },
{ GL_XOR ,"GL_XOR" },
{ GL_ZOOM_X ,"GL_ZOOM_X" },
{ GL_ZOOM_Y ,"GL_ZOOM_Y" },
/* Magic end-marker - do not remove! */
{ GL_ZERO, NULL }
} ;
int xglTraceIsEnabled ( char *gl_function_name )
{
static int frameno = 0 ;
static int countdown = 0 ;
if ( strcmp ( gl_function_name, "glutSwapBuffers" ) == 0 )
{
if ( countdown == 0 )
{
char s [ 100 ] ;
fprintf ( stderr, "\nContinue Tracing after frame %d [Yes,No,Countdown,eXit] ?", ++frameno ) ;
gets ( s ) ;
if ( s[0] == 'x' )
exit ( 1 ) ;
xglTraceOn = ( s[0] != 'n' && s[0] != 'c' ) ;
if ( s[0] == 'c' )
{
fprintf ( stderr, "\nHow many frames should I wait until I ask again?" ) ;
gets ( s ) ;
countdown = atoi(s) ;
}
fprintf ( xglTraceFd, "/* Frame %d - tracing %s */\n", frameno, xglTraceOn ? "ON" : "OFF" ) ;
}
else
countdown-- ;
}
return xglTraceOn ;
}
int xglExecuteIsEnabled ( char *gl_function_name )
{
return TRUE ;
}
char *xglExpandGLenum ( GLenum x )
{
static GLenum last_val = GL_NONE ;
static char *last_str = NULL ;
char *error_message;
int i;
/* Due to ambiguity - these are output as numbers...
GL_NONE = , GL_ZERO = GL_FALSE = GL_POINTS = 0
GL_ONE = , GL_TRUE = GL_LINES = 1
*/
if ( (int) x == 0 ) return "(GLenum) 0" ;
if ( (int) x == 1 ) return "(GLenum) 1" ;
if ( last_val == x ) return last_str ;
for ( i = 0 ; glenum_string [i].name != NULL ; i++ )
if ( glenum_string [i].val == x )
return glenum_string [i].name ;
/*
WARNING - this will leak memory - but it is an error condition,
so I suppose it's acceptable.
You can't declare the 'error_message' string as a
static - or else double errors will go mis-reported.
*/
error_message = (char *)malloc( 100 * sizeof(char) ) ;
sprintf ( error_message, "(GLenum) 0x%04x /* Illegal? */", (int) x ) ;
return error_message ;
}
static GLbyte b1 [ 1 ], b2 [ 2 ], b3 [ 3 ], b4 [ 4 ] ;
static GLdouble d1 [ 1 ], d2 [ 2 ], d3 [ 3 ], d4 [ 4 ] ;
static GLfloat f1 [ 1 ], f2 [ 2 ], f3 [ 3 ], f4 [ 4 ] ;
static GLint i1 [ 1 ], i2 [ 2 ], i3 [ 3 ], i4 [ 4 ] ;
static GLshort s1 [ 1 ], s2 [ 2 ], s3 [ 3 ], s4 [ 4 ] ;
static GLubyte ub1 [ 1 ], ub2 [ 2 ], ub3 [ 3 ], ub4 [ 4 ] ;
static GLuint ui1 [ 1 ], ui2 [ 2 ], ui3 [ 3 ], ui4 [ 4 ] ;
static GLushort us1 [ 1 ], us2 [ 2 ], us3 [ 3 ], us4 [ 4 ] ;
static GLdouble md [ 16 ] ;
static GLfloat mf [ 16 ] ;
GLdouble *xglBuild1dv ( GLdouble v ) { d1[0] = v ; return d1 ; }
GLfloat *xglBuild1fv ( GLfloat v ) { f1[0] = v ; return f1 ; }
GLbyte *xglBuild1bv ( GLbyte v ) { b1[0] = v ; return b1 ; }
GLint *xglBuild1iv ( GLint v ) { i1[0] = v ; return i1 ; }
GLshort *xglBuild1sv ( GLshort v ) { s1[0] = v ; return s1 ; }
GLubyte *xglBuild1ubv ( GLubyte v ) { ub1[0] = v ; return ub1 ; }
GLuint *xglBuild1uiv ( GLuint v ) { ui1[0] = v ; return ui1 ; }
GLushort *xglBuild1usv ( GLushort v ) { us1[0] = v ; return us1 ; }
GLdouble *xglBuild2dv ( GLdouble v0, GLdouble v1 ) { d2[0] = v0 ; d2[1] = v1 ; return d2 ; }
GLfloat *xglBuild2fv ( GLfloat v0, GLfloat v1 ) { f2[0] = v0 ; f2[1] = v1 ; return f2 ; }
GLbyte *xglBuild2bv ( GLbyte v0, GLbyte v1 ) { b2[0] = v0 ; b2[1] = v1 ; return b2 ; }
GLint *xglBuild2iv ( GLint v0, GLint v1 ) { i2[0] = v0 ; i2[1] = v1 ; return i2 ; }
GLshort *xglBuild2sv ( GLshort v0, GLshort v1 ) { s2[0] = v0 ; s2[1] = v1 ; return s2 ; }
GLubyte *xglBuild2ubv ( GLubyte v0, GLubyte v1 ) { ub2[0] = v0 ; ub2[1] = v1 ; return ub2 ; }
GLuint *xglBuild2uiv ( GLuint v0, GLuint v1 ) { ui2[0] = v0 ; ui2[1] = v1 ; return ui2 ; }
GLushort *xglBuild2usv ( GLushort v0, GLushort v1 ) { us2[0] = v0 ; us2[1] = v1 ; return us2 ; }
GLdouble *xglBuild3dv ( GLdouble v0, GLdouble v1, GLdouble v2 ) { d3[0] = v0 ; d3[1] = v1 ; d3[2] = v2 ; return d3 ; }
GLfloat *xglBuild3fv ( GLfloat v0, GLfloat v1, GLfloat v2 ) { f3[0] = v0 ; f3[1] = v1 ; f3[2] = v2 ; return f3 ; }
GLbyte *xglBuild3bv ( GLbyte v0, GLbyte v1, GLbyte v2 ) { b3[0] = v0 ; b3[1] = v1 ; b3[2] = v2 ; return b3 ; }
GLint *xglBuild3iv ( GLint v0, GLint v1, GLint v2 ) { i3[0] = v0 ; i3[1] = v1 ; i3[2] = v2 ; return i3 ; }
GLshort *xglBuild3sv ( GLshort v0, GLshort v1, GLshort v2 ) { s3[0] = v0 ; s3[1] = v1 ; s3[2] = v2 ; return s3 ; }
GLubyte *xglBuild3ubv ( GLubyte v0, GLubyte v1, GLubyte v2 ) { ub3[0] = v0 ; ub3[1] = v1 ; ub3[2] = v2 ; return ub3 ; }
GLuint *xglBuild3uiv ( GLuint v0, GLuint v1, GLuint v2 ) { ui3[0] = v0 ; ui3[1] = v1 ; ui3[2] = v2 ; return ui3 ; }
GLushort *xglBuild3usv ( GLushort v0, GLushort v1, GLushort v2 ) { us3[0] = v0 ; us3[1] = v1 ; us3[2] = v2 ; return us3 ; }
GLdouble *xglBuild4dv ( GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3 ) { d4[0] = v0 ; d4[1] = v1 ; d4[2] = v2 ; d4[3] = v3 ; return d4 ; }
GLfloat *xglBuild4fv ( GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3 ) { f4[0] = v0 ; f4[1] = v1 ; f4[2] = v2 ; f4[3] = v3 ; return f4 ; }
GLbyte *xglBuild4bv ( GLbyte v0, GLbyte v1, GLbyte v2, GLbyte v3 ) { b4[0] = v0 ; b4[1] = v1 ; b4[2] = v2 ; b4[3] = v3 ; return b4 ; }
GLint *xglBuild4iv ( GLint v0, GLint v1, GLint v2, GLint v3 ) { i4[0] = v0 ; i4[1] = v1 ; i4[2] = v2 ; i4[3] = v3 ; return i4 ; }
GLshort *xglBuild4sv ( GLshort v0, GLshort v1, GLshort v2, GLshort v3 ) { s4[0] = v0 ; s4[1] = v1 ; s4[2] = v2 ; s4[3] = v3 ; return s4 ; }
GLubyte *xglBuild4ubv ( GLubyte v0, GLubyte v1, GLubyte v2, GLubyte v3 ) { ub4[0] = v0 ; ub4[1] = v1 ; ub4[2] = v2 ; ub4[3] = v3 ; return ub4 ; }
GLuint *xglBuild4uiv ( GLuint v0, GLuint v1, GLuint v2, GLuint v3 ) { ui4[0] = v0 ; ui4[1] = v1 ; ui4[2] = v2 ; ui4[3] = v3 ; return ui4 ; }
GLushort *xglBuild4usv ( GLushort v0, GLushort v1, GLushort v2, GLushort v3 ) { us4[0] = v0 ; us4[1] = v1 ; us4[2] = v2 ; us4[3] = v3 ; return us4 ; }
GLdouble *xglBuildMatrixd ( GLdouble m0 , GLdouble m1 , GLdouble m2 , GLdouble m3 ,
GLdouble m4 , GLdouble m5 , GLdouble m6 , GLdouble m7 ,
GLdouble m8 , GLdouble m9 , GLdouble m10, GLdouble m11,
GLdouble m12, GLdouble m13, GLdouble m14, GLdouble m15 )
{
md[ 0] = m0 ; md[ 1] = m1 ; md[ 2] = m2 ; md[ 3] = m3 ;
md[ 4] = m4 ; md[ 5] = m5 ; md[ 6] = m6 ; md[ 7] = m7 ;
md[ 8] = m8 ; md[ 9] = m9 ; md[10] = m10 ; md[11] = m11 ;
md[12] = m12 ; md[13] = m13 ; md[14] = m14 ; md[15] = m15 ;
return md ;
}
GLfloat *xglBuildMatrixf ( GLfloat m0 , GLfloat m1 , GLfloat m2 , GLfloat m3 ,
GLfloat m4 , GLfloat m5 , GLfloat m6 , GLfloat m7 ,
GLfloat m8 , GLfloat m9 , GLfloat m10, GLfloat m11,
GLfloat m12, GLfloat m13, GLfloat m14, GLfloat m15 )
{
mf[ 0] = m0 ; mf[ 1] = m1 ; mf[ 2] = m2 ; mf[ 3] = m3 ;
mf[ 4] = m4 ; mf[ 5] = m5 ; mf[ 6] = m6 ; mf[ 7] = m7 ;
mf[ 8] = m8 ; mf[ 9] = m9 ; mf[10] = m10 ; mf[11] = m11 ;
mf[12] = m12 ; mf[13] = m13 ; mf[14] = m14 ; mf[15] = m15 ;
return mf ;
}

17
Lib/example/Makefile.am Normal file
View file

@ -0,0 +1,17 @@
bin_PROGRAMS = example
example_SOURCES = example.cxx
example_LDADD = \
$(top_builddir)/Lib/Audio/src/libsl.a \
$(top_builddir)/Lib/Audio/src/libsm.a
INCLUDES += -I$(top_builddir)/Lib/Audio/src
if ENABLE_IRIX_AUDIO
LIBS += -laudio
endif
if ENABLE_WIN32_AUDIO
LIBS += -lwinmm
endif

89
Lib/example/example.cxx Normal file
View file

@ -0,0 +1,89 @@
#include "sl.h"
#include "sm.h"
#include <math.h>
/*
Construct a sound scheduler and a mixer.
*/
slScheduler sched ( 8000 ) ;
smMixer mixer ;
int main ()
{
mixer . setMasterVolume ( 30 ) ;
sched . setSafetyMargin ( 0.128 ) ;
/* Just for fun, let's make a one second synthetic engine sample... */
Uchar buffer [ 8000 ] ;
for ( int i = 0 ; i < 8000 ; i++ )
{
/* Sum some sin waves and convert to range 0..1 */
float level = ( sin ( (double) i * 2.0 * M_PI / (8000.0/ 50.0) ) +
sin ( (double) i * 2.0 * M_PI / (8000.0/149.0) ) +
sin ( (double) i * 2.0 * M_PI / (8000.0/152.0) ) +
sin ( (double) i * 2.0 * M_PI / (8000.0/192.0) )
) / 8.0f + 0.5f ;
/* Convert to unsigned byte */
buffer [ i ] = (Uchar) ( level * 255.0 ) ;
}
/* Set up four samples and a loop */
slSample *s = new slSample ( buffer, 8000 ) ;
slSample *s1 = new slSample ( "scream.ub", & sched ) ;
slSample *s2 = new slSample ( "zzap.wav" , & sched ) ;
slSample *s3 = new slSample ( "cuckoo.au", & sched ) ;
slSample *s4 = new slSample ( "wheeee.ub", & sched ) ;
/* Mess about with some of the samples... */
s1 -> adjustVolume ( 2.2 ) ;
s2 -> adjustVolume ( 0.5 ) ;
s3 -> adjustVolume ( 0.2 ) ;
/* Play the engine sample continuously. */
sched . loopSample ( s ) ;
int tim = 0 ; /* My periodic event timer. */
while ( SL_TRUE )
{
tim++ ; /* Time passes */
if ( tim % 200 == 0 ) sched.playSample ( s1 ) ;
if ( tim % 180 == 0 ) sched.playSample ( s2 ) ;
if ( tim % 150 == 0 ) sched.playSample ( s3 ) ;
if ( tim % 120 == 0 ) sched.playSample ( s4 ) ;
/*
For the sake of realism, I'll delay for 1/30th second to
simulate a graphics update process.
*/
#ifdef WIN32
Sleep ( 1000 / 30 ) ; /* 30Hz */
#elif defined(sgi)
sginap( 3 ); /* ARG */
#else
usleep ( 1000000 / 30 ) ; /* 30Hz */
#endif
/*
This would normally be called just before the graphics buffer swap
- but it could be anywhere where it's guaranteed to get called
fairly often.
*/
sched . update () ;
}
}

10
Lib/src/Makefile.am Normal file
View file

@ -0,0 +1,10 @@
noinst_LIBRARIES = libsl.a libsm.a
libsl_a_SOURCES = \
sl.h slPortability.h \
slDSP.cxx slSample.cxx slEnvelope.cxx \
slSamplePlayer.cxx slScheduler.cxx
libsm_a_SOURCES = sm.h slPortability.h smMixer.cxx
INCLUDES += -I$(top_builddir) -I.

629
Lib/src/sl.h Normal file
View file

@ -0,0 +1,629 @@
#ifndef __SL_H__
#define __SL_H__ 1
#include "slPortability.h"
#ifdef SL_USING_OSS_AUDIO
#define SLDSP_DEFAULT_DEVICE "/dev/dsp"
#elif defined(WIN32)
#define SLDSP_DEFAULT_DEVICE "dsp"
#elif defined(__OpenBSD__)
#define SLDSP_DEFAULT_DEVICE "/dev/audio"
#elif defined(sgi)
#define SLDSP_DEFAULT_DEVICE "dsp" // dummy ...
#else
#error "Port me !"
#endif
# define SL_TRUE 1
# define SL_FALSE 0
typedef unsigned char Uchar ;
typedef unsigned short Ushort ;
#define SL_DEFAULT_SAMPLING_RATE 11025
class slSample ;
class slSamplePlayer ;
class slEnvelope ;
class slScheduler ;
class slDSP ;
extern char *__slPendingError ;
class slDSP
{
private:
int stereo ;
int rate ;
int bps ;
int error ;
int fd ;
#ifdef __OpenBSD__
audio_info_t ainfo; // ioctl structure
audio_offset_t audio_offset; // offset in audiostream
long counter; // counter-written packets
#elif defined(SL_USING_OSS_AUDIO)
audio_buf_info buff_info ;
#elif defined(sgi)
ALconfig config; // configuration stuff
ALport port; // .. we are here
#endif
#ifndef WIN32
int ioctl ( int cmd, int param = 0 )
{
if ( error ) return param ;
if ( ::ioctl ( fd, cmd, & param ) == -1 )
{
perror ( "slDSP: ioctl" ) ;
error = SL_TRUE ;
}
return param ;
}
#elif defined(WIN32)
HWAVEOUT hWaveOut; // device handle
WAVEFORMATEX Format; // open needs this
MMTIME mmt; // timing
WAVEHDR wavehdr[ 3 ]; // for round robin ..
int curr_header; // index of actual wavehdr
long counter; // counter-written packets
#endif
void open ( char *device, int _rate, int _stereo, int _bps ) ;
void close () ;
void getBufferInfo () ;
void write ( void *buffer, size_t length ) ;
protected:
void setError () { error = SL_TRUE ; }
int getDriverBufferSize () ;
public:
slDSP ( int _rate = SL_DEFAULT_SAMPLING_RATE,
int _stereo = SL_FALSE, int _bps = 8 )
{
open ( SLDSP_DEFAULT_DEVICE, _rate, _stereo, _bps ) ;
}
slDSP ( char *device, int _rate = SL_DEFAULT_SAMPLING_RATE,
int _stereo = SL_FALSE, int _bps = 8 )
{
open ( device, _rate, _stereo, _bps ) ;
}
~slDSP () { close () ; }
float secondsRemaining () ;
float secondsUsed () ;
void play ( void *buffer, size_t length ) { write ( buffer, length ) ; }
int working () { return !error ; }
int not_working () { return error ; }
int getBps () { return bps ; }
int getRate () { return rate ; }
int getStereo() { return stereo ; }
void sync () ;
void stop () ;
} ;
class slSample
{
int ref_count ;
protected:
char *comment;
int rate ;
int bps ;
int stereo ;
Uchar *buffer ;
int length ;
void init ()
{
ref_count = 0 ;
comment = NULL ;
buffer = NULL ;
length = 0 ;
rate = SL_DEFAULT_SAMPLING_RATE ;
bps = 8 ;
stereo = SL_FALSE ;
}
public:
slSample () { init () ; }
slSample ( Uchar *buff, int leng )
{
init () ;
setBuffer ( buff, leng ) ;
}
slSample ( char *fname, class slDSP *dsp = NULL )
{
init () ;
loadFile ( fname ) ;
autoMatch ( dsp ) ;
}
~slSample ()
{
if ( ref_count != 0 && __slPendingError == NULL )
__slPendingError =
"slSample: FATAL ERROR - Application deleted a sample while it was playing.\n" ;
delete buffer ;
}
void ref () { ref_count++ ; }
void unRef () { ref_count-- ; }
int getPlayCount () { return ref_count ; }
char *getComment () { return comment ; }
void setComment ( char *nc )
{
delete comment ;
comment = new char [ strlen ( nc ) + 1 ] ;
strcpy ( comment, nc ) ;
}
Uchar *getBuffer () { return buffer ; }
int getLength () { return length ; }
void autoMatch ( slDSP *dsp ) ;
void setBuffer ( Uchar *buff, int leng )
{
delete buffer ;
buffer = new Uchar [ leng ] ;
if ( buff != NULL )
memcpy ( buffer, buff, leng ) ;
length = leng ;
}
/* These routines only set flags - use changeXXX () to convert a sound */
void setRate ( int r ) { rate = r ; }
void setBps ( int b ) { bps = b ; }
void setStereo ( int s ) { stereo = s ; }
int getRate () { return rate ; }
int getBps () { return bps ; }
int getStereo () { return stereo ; }
float getDuration () { return (float) getLength() /
(float) ( (getStereo()?2.0f:1.0f)*
(getBps()/8.0f)*getRate() ) ; }
int loadFile ( char *fname ) ;
int loadRawFile ( char *fname ) ;
int loadAUFile ( char *fname ) ;
int loadWavFile ( char *fname ) ;
void changeRate ( int r ) ;
void changeBps ( int b ) ;
void changeStereo ( int s ) ;
void changeToUnsigned () ;
void adjustVolume ( float vol ) ;
void print ( FILE *fd )
{
if ( buffer == NULL )
{
fprintf ( fd, "Empty sample buffer\n" ) ;
}
else
{
fprintf ( fd, "\"%s\"\n",(getComment() == NULL ||
getComment()[0]=='\0') ? "Sample" : comment ) ;
fprintf ( fd, "%s, %d bits per sample.\n",
getStereo() ? "Stereo" : "Mono", getBps() ) ;
fprintf ( fd, "%gKHz sample rate.\n", (float) getRate() / 1000.0f ) ;
fprintf ( fd, "%d bytes of samples == %g seconds duration.\n", getLength(), getDuration() ) ;
}
}
} ;
enum slSampleStatus
{
SL_SAMPLE_WAITING, /* Sound hasn't started playing yet */
SL_SAMPLE_RUNNING, /* Sound has started playing */
SL_SAMPLE_DONE , /* Sound is complete */
SL_SAMPLE_PAUSED /* Sound hasn't started playing yet */
} ;
enum slPreemptMode
{
SL_SAMPLE_CONTINUE, /* Don't allow yourself to be preempted */
SL_SAMPLE_ABORT , /* Abort playing the sound when preempted */
SL_SAMPLE_RESTART , /* Restart the sound when load permits */
SL_SAMPLE_MUTE , /* Continue silently until load permits */
SL_SAMPLE_DELAY /* Pause until load permits */
} ;
enum slReplayMode
{
SL_SAMPLE_LOOP, /* Loop sound so that it plays forever */
SL_SAMPLE_ONE_SHOT /* Play sound just once */
} ;
enum slEvent
{
SL_EVENT_COMPLETE, /* Sound finished playing */
SL_EVENT_LOOPED, /* Sound looped back to the start */
SL_EVENT_PREEMPTED /* Sound was preempted */
} ;
typedef void (*slCallBack) ( slSample *, slEvent, int ) ;
class slEnvelope
{
public: /* SJB TESTING! */
float *time ;
float *value ;
int nsteps ;
int ref_count ;
slReplayMode replay_mode ;
int getStepDelta ( float *_time, float *delta ) ;
public:
slEnvelope ( int _nsteps, slReplayMode _rm, float *_times, float *_values )
{
ref_count = 0 ;
nsteps = _nsteps ;
time = new float [ nsteps ] ;
value = new float [ nsteps ] ;
memcpy ( time , _times , sizeof(float) * nsteps ) ;
memcpy ( value, _values, sizeof(float) * nsteps ) ;
replay_mode = _rm ;
}
slEnvelope ( int _nsteps = 1, slReplayMode _rm = SL_SAMPLE_ONE_SHOT )
{
ref_count = 0 ;
nsteps = _nsteps ;
time = new float [ nsteps ] ;
value = new float [ nsteps ] ;
for ( int i = 0 ; i < nsteps ; i++ )
time [ i ] = value [ i ] = 0.0 ;
replay_mode = _rm ;
}
~slEnvelope ()
{
if ( ref_count != 0 && __slPendingError == NULL )
__slPendingError =
"slEnvelope: FATAL ERROR - Application deleted an envelope while it was playing.\n" ;
delete time ;
delete value ;
}
void ref () { ref_count++ ; }
void unRef () { ref_count-- ; }
int getPlayCount () { return ref_count ; }
void setStep ( int n, float _time, float _value )
{
if ( n >= 0 && n < nsteps )
{
time [ n ] = _time ;
value [ n ] = _value ;
}
}
float getStepValue ( int s ) { return value [ s ] ; }
float getStepTime ( int s ) { return time [ s ] ; }
int getNumSteps () { return nsteps ; }
float getValue ( float _time ) ;
void applyToPitch ( Uchar *dst, slSamplePlayer *src, int nframes, int start, int next_env ) ;
void applyToInvPitch ( Uchar *dst, slSamplePlayer *src, int nframes, int start, int next_env ) ;
void applyToVolume ( Uchar *dst, Uchar *src, int nframes, int start ) ;
void applyToInvVolume ( Uchar *dst, Uchar *src, int nframes, int start ) ;
} ;
#define SL_MAX_PRIORITY 16
#define SL_MAX_SAMPLES 16
#define SL_MAX_CALLBACKS (SL_MAX_SAMPLES * 2)
#define SL_MAX_ENVELOPES 4
enum slEnvelopeType
{
SL_PITCH_ENVELOPE , SL_INVERSE_PITCH_ENVELOPE ,
SL_VOLUME_ENVELOPE, SL_INVERSE_VOLUME_ENVELOPE,
SL_FILTER_ENVELOPE, SL_INVERSE_FILTER_ENVELOPE,
SL_PAN_ENVELOPE , SL_INVERSE_PAN_ENVELOPE ,
SL_ECHO_ENVELOPE , SL_INVERSE_ECHO_ENVELOPE ,
SL_NULL_ENVELOPE
} ;
struct slPendingCallBack
{
slCallBack callback ;
slSample *sample ;
slEvent event ;
int magic ;
} ;
class slSamplePlayer
{
int lengthRemaining ; /* Sample frames remaining until repeat */
Uchar *bufferPos ; /* Sample frame to replay next */
slSample *sample ;
slEnvelope *env [ SL_MAX_ENVELOPES ] ;
slEnvelopeType env_type [ SL_MAX_ENVELOPES ] ;
int env_start_time [ SL_MAX_ENVELOPES ] ;
slReplayMode replay_mode ;
slPreemptMode preempt_mode ;
slSampleStatus status ;
int priority ;
slCallBack callback ;
int magic ;
void low_read ( int nframes, Uchar *dest ) ;
public:
slSamplePlayer ( slSample *s, slReplayMode rp_mode = SL_SAMPLE_ONE_SHOT,
int pri = 0, slPreemptMode pr_mode = SL_SAMPLE_DELAY,
int _magic = 0, slCallBack cb = NULL )
{
magic = _magic ;
sample = s ;
callback = cb ;
for ( int i = 0 ; i < SL_MAX_ENVELOPES ; i++ )
{
env [ i ] = NULL ;
env_type [ i ] = SL_NULL_ENVELOPE ;
}
if ( sample ) sample -> ref () ;
reset () ;
replay_mode = rp_mode ;
preempt_mode = pr_mode ;
priority = pri ;
}
~slSamplePlayer () ;
slPreemptMode getPreemptMode () { return preempt_mode ; }
int getPriority ()
{
return ( isRunning() &&
preempt_mode == SL_SAMPLE_CONTINUE ) ? (SL_MAX_PRIORITY+1) :
priority ;
}
int preempt ( int delay ) ;
void addEnvelope ( int i, slEnvelope *_env, slEnvelopeType _type ) ;
void pause ()
{
if ( status != SL_SAMPLE_DONE )
status = SL_SAMPLE_PAUSED ;
}
void resume ()
{
if ( status == SL_SAMPLE_PAUSED )
status = SL_SAMPLE_RUNNING ;
}
void reset ()
{
status = SL_SAMPLE_WAITING ;
lengthRemaining = sample->getLength () ;
bufferPos = sample->getBuffer () ;
}
void start ()
{
status = SL_SAMPLE_RUNNING ;
lengthRemaining = sample->getLength () ;
bufferPos = sample->getBuffer () ;
}
void stop ()
{
status = SL_SAMPLE_DONE ;
lengthRemaining = 0 ;
bufferPos = NULL ;
}
int getMagic () { return magic ; }
slSample *getSample () { return sample ; }
int isWaiting () { return status == SL_SAMPLE_WAITING ; }
int isPaused () { return status == SL_SAMPLE_PAUSED ; }
int isRunning () { return status == SL_SAMPLE_RUNNING ; }
int isDone () { return status == SL_SAMPLE_DONE ; }
void skip ( int nframes ) ;
void read ( int nframes, Uchar *dest, int next_env = 0 ) ;
} ;
class slScheduler : public slDSP
{
slPendingCallBack pending_callback [ SL_MAX_CALLBACKS ] ;
int num_pending_callbacks ;
float safety_margin ;
int mixer_buffer_size ;
Uchar *mixer_buffer ;
Uchar *spare_buffer0 ;
Uchar *spare_buffer1 ;
Uchar *spare_buffer2 ;
Uchar *mixer ;
int amount_left ;
slSamplePlayer *samplePlayer [ SL_MAX_SAMPLES ] ;
void init () ;
void mixBuffer ( slSamplePlayer *a,
slSamplePlayer *b ) ;
void mixBuffer ( slSamplePlayer *a,
slSamplePlayer *b,
slSamplePlayer *c ) ;
Uchar mix ( Uchar a, Uchar b )
{
register int r = a + b - 0x80 ;
return ( r > 255 ) ? 255 :
( r < 0 ) ? 0 : r ;
}
Uchar mix ( Uchar a, Uchar b, Uchar c )
{
register int r = a + b + c - 0x80 - 0x80 ;
return ( r > 255 ) ? 255 :
( r < 0 ) ? 0 : r ;
}
void realUpdate ( int dump_first = SL_FALSE ) ;
void initBuffers () ;
int now ;
static slScheduler *current ;
public:
slScheduler ( int _rate = SL_DEFAULT_SAMPLING_RATE ) : slDSP ( _rate, SL_FALSE, 8 ) { init () ; }
slScheduler ( char *device,
int _rate = SL_DEFAULT_SAMPLING_RATE ) : slDSP ( device, _rate, SL_FALSE, 8 ) { init () ; }
~slScheduler () ;
static slScheduler *getCurrent () { return current ; }
int getTimeNow () { return now ; }
float getElapsedTime ( int then ) { return (float)(now-then)/(float)getRate() ; }
void flushCallBacks () ;
void addCallBack ( slCallBack c, slSample *s, slEvent e, int m ) ;
void update () { realUpdate ( SL_FALSE ) ; }
void dumpUpdate () { realUpdate ( SL_TRUE ) ; }
void addSampleEnvelope ( slSample *s = NULL, int magic = 0,
int slot = 1, slEnvelope *e = NULL,
slEnvelopeType t = SL_VOLUME_ENVELOPE )
{
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
if ( samplePlayer [ i ] != NULL &&
( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
samplePlayer [ i ] -> addEnvelope ( slot, e, t ) ;
}
void resumeSample ( slSample *s = NULL, int magic = 0 )
{
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
if ( samplePlayer [ i ] != NULL &&
( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
samplePlayer [ i ] -> resume () ;
}
void pauseSample ( slSample *s = NULL, int magic = 0 )
{
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
if ( samplePlayer [ i ] != NULL &&
( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
samplePlayer [ i ] -> pause () ;
}
void stopSample ( slSample *s = NULL, int magic = 0 )
{
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
if ( samplePlayer [ i ] != NULL &&
( s == NULL || samplePlayer [ i ] -> getSample () == s ) &&
( magic == 0 || samplePlayer [ i ] -> getMagic () == magic ) )
samplePlayer [ i ] -> stop () ;
}
int loopSample ( slSample *s, int pri = 0, slPreemptMode mode = SL_SAMPLE_MUTE, int magic = 0, slCallBack cb = NULL )
{
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
if ( samplePlayer [ i ] == NULL )
{
samplePlayer [ i ] = new slSamplePlayer ( s, SL_SAMPLE_LOOP, pri, mode, magic, cb ) ;
return i ;
}
return -1 ;
}
int playSample ( slSample *s, int pri = 1, slPreemptMode mode = SL_SAMPLE_ABORT, int magic = 0, slCallBack cb = NULL )
{
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
if ( samplePlayer [ i ] == NULL )
{
samplePlayer [ i ] = new slSamplePlayer ( s, SL_SAMPLE_ONE_SHOT, pri, mode, magic, cb ) ;
return SL_TRUE ;
}
return SL_FALSE ;
}
void setSafetyMargin ( float seconds ) { safety_margin = seconds ; }
} ;
#endif

669
Lib/src/slDSP.cxx Normal file
View file

@ -0,0 +1,669 @@
#include "sl.h"
static int init_bytes ;
#ifdef SL_USING_OSS_AUDIO
/* ------------------------------------------------------------ */
/* OSSAUDIO - Linux, FreeBSD, etc */
/* ------------------------------------------------------------ */
void slDSP::open ( char *device, int _rate, int _stereo, int _bps )
{
fd = ::open ( device, O_WRONLY ) ;
if ( fd < 0 )
{
perror ( "slDSP: open" ) ;
error = SL_TRUE ;
stereo = SL_FALSE ;
bps = 1 ;
rate = 8000 ;
init_bytes = 0 ;
}
else
{
error = SL_FALSE ;
/* Set up a driver fragment size of 1024 (ie 2^10) */
ioctl ( SNDCTL_DSP_SETFRAGMENT, 0x7FFF000A ) ;
stereo = ioctl ( SOUND_PCM_WRITE_CHANNELS, _stereo ? 2 : 1 ) >= 2 ;
bps = ioctl ( SOUND_PCM_WRITE_BITS, _bps ) ;
rate = ioctl ( SOUND_PCM_WRITE_RATE, _rate ) ;
getBufferInfo () ;
init_bytes = buff_info.bytes ;
}
}
void slDSP::close ()
{
if ( fd >= 0 )
::close ( fd ) ;
}
int slDSP::getDriverBufferSize ()
{
if ( error )
return 0 ;
getBufferInfo () ;
return buff_info.fragsize ;
}
void slDSP::getBufferInfo ()
{
if ( error )
return ;
if ( ::ioctl ( fd, SNDCTL_DSP_GETOSPACE, & buff_info ) < 0 )
{
perror ( "slDSP: getBufferInfo" ) ;
error = SL_TRUE ;
return ;
}
}
void slDSP::write ( void *buffer, size_t length )
{
if ( error || length <= 0 )
return ;
int nwritten = ::write ( fd, (const char *) buffer, length ) ;
if ( nwritten < 0 )
perror ( "slDSP: write" ) ;
else
if ( nwritten != length )
perror ( "slDSP: short write" ) ;
}
float slDSP::secondsRemaining ()
{
if ( error )
return 0.0f ;
getBufferInfo () ;
int samples_left = buff_info.fragments * buff_info.fragsize ;
if ( stereo ) samples_left /= 2 ;
if ( bps == 16 ) samples_left /= 2 ;
return (float) samples_left / (float) rate ;
}
float slDSP::secondsUsed ()
{
if ( error )
return 0.0f ;
getBufferInfo () ;
int samples_used = init_bytes - buff_info.bytes ;
if ( stereo ) samples_used /= 2 ;
if ( bps == 16 ) samples_used /= 2 ;
return (float) samples_used / (float) rate ;
}
void slDSP::sync ()
{
if ( !error) ::ioctl ( fd, SOUND_PCM_SYNC , 0 ) ;
}
void slDSP::stop ()
{
if ( !error) ::ioctl ( fd, SOUND_PCM_RESET, 0 ) ;
}
#endif
#ifdef WIN32
/* ------------------------------------------------------------ */
/* win32 */
/* ------------------------------------------------------------ */
static void wperror(MMRESULT num)
{
char buffer[0xff]; // yes, this is hardcoded :-)
waveOutGetErrorText( num, buffer, sizeof(buffer)-1);
fprintf( stderr, "SlDSP: %s\n", buffer );
fflush ( stderr );
}
void CALLBACK waveOutProc( HWAVEOUT hwo, UINT uMsg,
DWORD dwInstance, DWORD dwParam1, DWORD dwParam2 )
{
switch( uMsg )
{
case WOM_CLOSE:
break;
case WOM_OPEN:
break;
case WOM_DONE:
waveOutUnprepareHeader( (HWAVEOUT)dwParam1,
(LPWAVEHDR)dwParam2, sizeof( WAVEHDR ));
break;
}
}
void slDSP::open ( char *device, int _rate, int _stereo, int _bps )
{
MMRESULT result;
hWaveOut = NULL;
curr_header = 0;
counter = 0;
Format.wFormatTag = WAVE_FORMAT_PCM;
Format.nChannels = _stereo ? 2 : 1;
Format.nSamplesPerSec = _rate;
Format.wBitsPerSample = _bps;
Format.nBlockAlign = 1;
Format.nAvgBytesPerSec = _rate * Format.nChannels;
Format.cbSize = 0;
result = waveOutOpen( & hWaveOut, WAVE_MAPPER, & Format, NULL,
0L, WAVE_FORMAT_QUERY );
if ( result != MMSYSERR_NOERROR )
{
wperror( result);
error = SL_TRUE ;
stereo = SL_FALSE ;
bps = _bps ;
rate = _rate ;
init_bytes = 0 ;
return;
}
// Now the hwaveouthandle "should" be valid
if ( ( result = waveOutOpen( & hWaveOut, WAVE_MAPPER,
(WAVEFORMATEX *)& Format, (DWORD)waveOutProc,
0L, CALLBACK_FUNCTION )) != MMSYSERR_NOERROR )
{
wperror( result);
error = SL_TRUE ;
stereo = SL_FALSE ;
bps = _bps ;
rate = _rate ;
init_bytes = 0 ;
return;
}
else
{
error = SL_FALSE ;
stereo = _stereo;
bps = _bps;
rate = _rate;
/* hmm ?! */
init_bytes = 1024*8;
}
}
void slDSP::close ()
{
if ( hWaveOut != NULL )
{
waveOutClose( hWaveOut );
hWaveOut = NULL;
}
}
int slDSP::getDriverBufferSize ()
{
if ( error )
return 0 ;
/* hmm ?! */
return 1024*8;
}
void slDSP::getBufferInfo ()
{
return ;
}
void slDSP::write ( void *buffer, size_t length )
{
MMRESULT result;
if ( error || length <= 0 )
return ;
wavehdr[curr_header].lpData = (LPSTR) buffer;
wavehdr[curr_header].dwBufferLength = (long) length;
wavehdr[curr_header].dwBytesRecorded = 0L;
wavehdr[curr_header].dwUser = NULL;
wavehdr[curr_header].dwFlags = 0;
wavehdr[curr_header].dwLoops = 0;
wavehdr[curr_header].lpNext = NULL;
wavehdr[curr_header].reserved = 0;
result = waveOutPrepareHeader( hWaveOut, & wavehdr[curr_header],
sizeof(WAVEHDR));
if ( result != MMSYSERR_NOERROR )
{
wperror ( result );
error = SL_TRUE;
}
result = waveOutWrite(hWaveOut, & wavehdr[curr_header],
sizeof(WAVEHDR));
if ( result != MMSYSERR_NOERROR )
{
wperror ( result );
error = SL_TRUE;
}
counter ++;
curr_header = ( curr_header + 1 ) % 3;
}
float slDSP::secondsRemaining ()
{
if ( error )
return 0.0f ;
return 0.0f ;
}
float slDSP::secondsUsed ()
{
int samples_used;
MMRESULT result;
float samp_time;
if ( error )
return 0.0f ;
mmt.wType = TIME_BYTES;
result = waveOutGetPosition( hWaveOut, &mmt, sizeof( mmt ));
if ( mmt.u.cb == 0 || counter == 0)
return (float)0.0;
samples_used = ( init_bytes * counter ) - mmt.u.cb;
if ( stereo ) samples_used /= 2 ;
if ( bps == 16 ) samples_used /= 2 ;
samp_time = (float) samples_used / (float) rate ;
//printf("%0.2f position=%ld total written=%ld\n",
// samp_time, mmt.u.cb, init_bytes * counter );
return samp_time;
}
void slDSP::sync ()
{
}
void slDSP::stop ()
{
if ( error )
return ;
waveOutReset( hWaveOut );
}
/* ------------------------------------------------------------ */
/* OpenBSD 2.3 this should be very close to SUN Audio */
/* ------------------------------------------------------------ */
#elif defined(__OpenBSD__)
void slDSP::open ( char *device, int _rate, int _stereo, int _bps )
{
counter = 0;
fd = ::open ( device, O_RDWR ) ;
if ( fd < 0 )
{
perror ( "slDSP: open" ) ;
error = SL_TRUE ;
}
else
{
if( ::ioctl( fd, AUDIO_GETINFO, &ainfo) == -1)
{
perror("slDSP: open - getinfo");
stereo = SL_FALSE ;
bps = 8 ;
rate = 8000 ;
init_bytes = 0 ;
return;
}
ainfo.play.sample_rate = _rate;
ainfo.play.precision = _bps;
ainfo.play.channels = _stereo ? 2 : 1;
ainfo.play.encoding = AUDIO_ENCODING_ULINEAR;
if( :: ioctl(fd, AUDIO_SETINFO, &ainfo) == -1)
{
perror("slDSP: open - setinfo");
stereo = SL_FALSE ;
bps = 8 ;
rate = 8000 ;
init_bytes = 0 ;
return;
}
rate = _rate;
stereo = _stereo;
bps = _bps;
error = SL_FALSE ;
getBufferInfo ();
// I could not change the size,
// so let's try this ...
init_bytes = 1024 * 8;
}
}
void slDSP::close ()
{
if ( fd >= 0 )
::close ( fd ) ;
}
int slDSP::getDriverBufferSize ()
{
if ( error )
return 0 ;
getBufferInfo () ;
// HW buffer is 0xffff on my box
//return ainfo.play.buffer_size;
return 1024 * 8;
}
void slDSP::getBufferInfo ()
{
if ( error )
return ;
if( ::ioctl( fd, AUDIO_GETINFO, &ainfo) < 0)
{
perror ( "slDSP: getBufferInfo" ) ;
error = SL_TRUE ;
return ;
}
if( ::ioctl( fd, AUDIO_GETOOFFS, &audio_offset ) < 0)
{
perror ( "slDSP: getBufferInfo" ) ;
error = SL_TRUE ;
return ;
}
}
void slDSP::write ( void *buffer, size_t length )
{
if ( error || length <= 0 )
return ;
int nwritten = ::write ( fd, (const char *) buffer, length ) ;
if ( nwritten < 0 )
perror ( "slDSP: write" ) ;
else if ( nwritten != length )
perror ( "slDSP: short write" ) ;
counter ++; /* hmmm */
}
float slDSP::secondsRemaining ()
{
return 0.0f ;
}
float slDSP::secondsUsed ()
{
/*
* original formula from Steve:
* -----------------------------
*
* int samples_used = init_bytes - buff_info.bytes ;
* | |
* | +--- current available
* | space in bytes !
* +---------------- available space
* when empty;
*
* sample_used contains the number of bytes which are
* "used" or in the DSP "pipeline".
*/
int samples_used;
if ( error )
return 0.0f ;
getBufferInfo () ;
//This is wrong: this is the hw queue in the kernel !
//samples_used = ainfo.play.buffer_size - audio_offset.offset ;
// This is: all data written minus where we are now in the queue
if ( counter == 0 )
return 0.0;
samples_used = ( counter * init_bytes ) - audio_offset.samples;
if ( stereo ) samples_used /= 2 ;
if ( bps == 16 ) samples_used /= 2 ;
return (float) samples_used / (float) rate ;
}
void slDSP::sync ()
{
if ( !error) ::ioctl ( fd, AUDIO_FLUSH , 0 ) ;
}
void slDSP::stop ()
{
// nothing found yet
}
/* ------------------------------------------------------------ */
/* SGI IRIX audio */
/* ------------------------------------------------------------ */
#elif defined(sgi)
void slDSP::open ( char *device, int _rate, int _stereo, int _bps )
{
if ( _bps != 8 )
{
perror ( "slDSP: supports only 8bit audio for sgi" ) ;
error = SL_TRUE;
return;
}
init_bytes = 1024 * 8;
config = ALnewconfig();
ALsetchannels ( config, _stereo ? AL_STEREO : AL_MONO );
ALsetwidth ( config, _bps == 8 ? AL_SAMPLE_8 : AL_SAMPLE_16 );
ALsetqueuesize( config, init_bytes );
port = ALopenport( device, "w", config );
if ( port == NULL )
{
perror ( "slDSP: open" ) ;
error = SL_TRUE ;
}
else
{
long params[2] = {AL_OUTPUT_RATE, 0 };
params[1] = _rate;
if ( ALsetparams(AL_DEFAULT_DEVICE, params, 2) != 0 )
{
perror ( "slDSP: open - ALsetparams" ) ;
error = SL_TRUE ;
return;
}
rate = _rate;
stereo = _stereo;
bps = _bps;
error = SL_FALSE ;
}
}
void slDSP::close ()
{
if ( port != NULL )
{
ALcloseport ( port );
ALfreeconfig( config );
port = NULL;
}
}
int slDSP::getDriverBufferSize ()
{
if ( error )
return 0 ;
return ALgetqueuesize( config );
}
void slDSP::getBufferInfo ()
{
if ( error )
return ;
}
void slDSP::write ( void *buffer, size_t length )
{
char *buf = (char *)buffer;
int i;
if ( error || length <= 0 )
return ;
// Steve: is this a problem ??
for ( i = 0; i < length; i ++ )
buf[i] = buf[i] >> 1;
ALwritesamps(port, (void *)buf, length );
}
float slDSP::secondsRemaining ()
{
int samples_remain;
if ( error )
return 0.0f ;
samples_remain = ALgetfillable(port);
if ( stereo ) samples_remain /= 2 ;
if ( bps == 16 ) samples_remain /= 2 ;
return (float) samples_remain / (float) rate ;
}
float slDSP::secondsUsed ()
{
int samples_used;
if ( error )
return 0.0f ;
samples_used = ALgetfilled(port);
if ( stereo ) samples_used /= 2 ;
if ( bps == 16 ) samples_used /= 2 ;
return (float) samples_used / (float) rate ;
}
void slDSP::sync ()
{
if ( error )
return ;
/* found this in the header file - but no description
* or example for the long parameter.
*/
// ALflush(ALport, long);
}
void slDSP::stop ()
{
}
#endif

170
Lib/src/slEnvelope.cxx Normal file
View file

@ -0,0 +1,170 @@
#include "sl.h"
float slEnvelope::getValue ( float _time )
{
float delta ;
int step = getStepDelta ( &_time, &delta ) ;
return delta * (_time - time[step]) + value[step] ;
}
int slEnvelope::getStepDelta ( float *_time, float *delta )
{
float tt ;
if ( replay_mode == SL_SAMPLE_LOOP )
{
tt = floor ( *_time / time [ nsteps-1 ] ) ;
*_time -= tt * time [ nsteps-1 ] ;
}
tt = *_time ;
if ( tt <= time[ 0 ] ) { *delta = 0.0f ; return 0 ; }
if ( tt >= time[nsteps-1] ) { *delta = 0.0f ; return nsteps-1 ; }
for ( int i = 1 ; i <= nsteps-1 ; i++ )
if ( tt <= time[i] )
{
float t1 = time[i-1] ; float v1 = value[i-1] ;
float t2 = time[ i ] ; float v2 = value[ i ] ;
if ( t1 == t2 )
{
*delta = 0.0f ;
return i ;
}
*delta = (v2-v1) / (t2-t1) ;
return i-1 ;
}
*delta = 0.0f ;
return nsteps - 1 ;
}
void slEnvelope::applyToPitch ( Uchar *dst, slSamplePlayer *src,
int nframes, int start, int next_env )
{
float delta ;
float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
int step = getStepDelta ( &_time, &delta ) ;
float _value = delta * (_time - time[step]) + value[step] ;
delta /= (float) slScheduler::getCurrent() -> getRate () ;
unsigned char tmp [ 512 ] ;
float pos = 0 ;
float npos = 0 ;
unsigned char last = 0x80 ;
while ( nframes-- )
{
npos += _value ;
_value += delta ;
int offset = (int) ( npos - pos ) ;
if ( offset > 512 )
offset = 512 ;
if ( offset < 1 )
*(dst++) = last ;
else
{
pos += offset ;
src -> read ( offset, tmp, next_env ) ;
*(dst++) = last = tmp [ offset-1 ] ;
}
}
}
void slEnvelope::applyToInvPitch ( Uchar *dst, slSamplePlayer *src,
int nframes, int start, int next_env )
{
float delta ;
float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
int step = getStepDelta ( &_time, &delta ) ;
float _value = delta * (_time - time[step]) + value[step] ;
delta /= (float) slScheduler::getCurrent() -> getRate () ;
unsigned char tmp [ 512 ] ;
float pos = 0 ;
float npos = 0 ;
unsigned char last = 0x80 ;
while ( nframes-- )
{
npos += 1.0 / _value ;
_value += delta ;
int offset = (int) ( npos - pos ) ;
if ( offset > 512 )
offset = 512 ;
if ( offset < 1 )
*(dst++) = last ;
else
{
pos += offset ;
src -> read ( offset, tmp, next_env ) ;
*(dst++) = last = tmp [ offset-1 ] ;
}
}
}
void slEnvelope::applyToVolume ( Uchar *dst, Uchar *src,
int nframes, int start )
{
float delta ;
float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
int step = getStepDelta ( &_time, &delta ) ;
float _value = delta * (_time - time[step]) + value[step] ;
delta /= (float) slScheduler::getCurrent() -> getRate () ;
while ( nframes-- )
{
register int res = (int)( (float)((int)*(src++)-0x80) * _value ) + 0x80 ;
_value += delta ;
*(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ;
}
}
void slEnvelope::applyToInvVolume ( Uchar *dst, Uchar *src,
int nframes, int start )
{
float delta ;
float _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
int step = getStepDelta ( &_time, &delta ) ;
float _value = delta * (_time - time[step]) + value[step] ;
delta /= (float) slScheduler::getCurrent() -> getRate () ;
delta = - delta ;
_value = 1.0 - _value ;
while ( nframes-- )
{
register int res = (int)( (float)((int)*(src++)-0x80) * _value ) + 0x80 ;
_value += delta ;
*(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ;
}
}

71
Lib/src/slPortability.h Normal file
View file

@ -0,0 +1,71 @@
#ifndef __SLPORTABILITY_H__
#define __SLPORTABILITY_H__ 1
/* ------------------------------------------------------------- */
/* OS specific includes and defines ... */
/* ------------------------------------------------------------- */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#undef VERSION
#include <stdio.h>
#include <stdlib.h>
#ifndef WIN32
#include <unistd.h>
#include <sys/ioctl.h>
#else
#include <windows.h>
#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ )
# define NEAR /* */
# define FAR /* */
#endif
#include <mmsystem.h>
#endif
#include <fcntl.h>
#include <sys/stat.h>
#include <string.h>
#include <math.h>
#if defined(__linux__) || defined(__FreeBSD__)
#define SL_USING_OSS_AUDIO 1
#endif
#ifdef SL_USING_OSS_AUDIO
#if defined(__linux__)
#include <linux/soundcard.h>
#elif defined(__FreeBSD__)
#include <machine/soundcard.h>
#else
/*
Tom thinks this file may be <sys/soundcard.h> under some
unixen - but that isn't where the OSS manuals say it
should be.
If you ever find out the truth, please email me:
Steve Baker <sjbaker1@airmail.net>
*/
#include <soundcard.h>
#endif
#endif
#ifdef __OpenBSD__
#include <sys/audioio.h>
#endif
#ifdef WIN32
#define strcasecmp stricmp /* Yes, Steve really does *HATE* Windoze */
#endif
/* Tom */
#ifdef sgi
#include <audio.h>
#endif
#endif

505
Lib/src/slSample.cxx Normal file
View file

@ -0,0 +1,505 @@
#include "sl.h"
#include <math.h>
void slSample::autoMatch ( slDSP *dsp )
{
if ( dsp == NULL ) return ;
changeRate ( dsp->getRate () ) ;
changeBps ( dsp->getBps () ) ;
changeStereo ( dsp->getStereo () ) ;
}
void slSample::adjustVolume ( float vol )
{
for ( int i = 0 ; i < length ; i++ )
{
int s = (int)(((float) buffer[i] - (float) 0x80) * vol) + 0x80 ;
buffer [ i ] = ( s > 255 ) ? 255 :
( s < 0 ) ? 0 : s ;
}
}
void slSample::changeRate ( int r )
{
if ( r == rate ) return ;
int length1 = length / (getBps ()/8) ;
int length2 = (int) ( (float) length1 * ( (float) r / (float) rate ) ) ;
Uchar *buffer2 = new Uchar [ length2 ] ;
float step = (float) length1 / (float) length2 ;
for ( int i = 0 ; i < length2 / (getBps()/8); i++ )
{
float pos = (float) i * step ;
int p1 = (int) floor ( pos ) ;
int p2 = (int) ceil ( pos ) ;
if ( stereo )
{
if ( ( p1 & 1 ) != ( i & 1 ) ) { pos++ ; p1++ ; p2++ ; }
p2++ ;
}
float ratio = pos - (float) p1 ;
float b1 = (getBps()==8) ?
(float) buffer [(p1<0)?0:(p1>=length1)?length1-1:p1] :
(float) ((Ushort*)buffer)[(p1<0)?0:(p1>=length1)?length1-1:p1] ;
float b2 = (getBps()==8) ?
(float) buffer [(p2<0)?0:(p2>=length1)?length1-1:p2] :
(float) ((Ushort*)buffer)[(p2<0)?0:(p2>=length1)?length1-1:p2] ;
float res = b1 * (1.0-ratio) + b2 * ratio ;
if ( getBps () == 8 )
buffer2 [ i ] = (Uchar) ( (res < 0) ? 0 : (res > 255) ? 255 : res ) ;
else
((Ushort *) buffer2 ) [ i ] =
(Ushort) ( (res < 0) ? 0 : (res > 65535) ? 65535 : res ) ;
}
rate = r ;
length = length2 ;
delete buffer ;
buffer = buffer2 ;
}
void slSample::changeToUnsigned ()
{
if ( getBps() == 16 )
{
int length2 = length / 2 ;
Ushort *buffer2 = (Ushort *) buffer ;
for ( int i = 0 ; i < length2 ; i++ )
buffer2 [ i ] = buffer2 [ i ] + 32768 ;
}
else
{
for ( int i = 0 ; i < length ; i++ )
buffer [ i ] = (buffer [ i ]>0x80) ? (buffer[i]-0x80) :
(0xFF-buffer[i]) ;
}
}
void slSample::changeBps ( int b )
{
if ( b == getBps () ) return ;
if ( b == 8 && getBps() == 16 )
{
length /= 2 ;
Uchar *buffer2 = new Uchar [ length ] ;
for ( int i = 0 ; i < length ; i++ )
buffer2 [ i ] = ((Ushort *)buffer) [ i ] >> 8 ;
delete buffer ;
buffer = buffer2 ;
setBps ( b ) ;
}
else
if ( b == 16 && getBps() == 8 )
{
Ushort *buffer2 = new Ushort [ length ] ;
for ( int i = 0 ; i < length ; i++ )
buffer2 [ i ] = buffer [ i ] << 8 ;
delete buffer ;
buffer = (Uchar *) buffer2 ;
length *= 2 ;
setBps ( b ) ;
}
}
void slSample::changeStereo ( int s )
{
if ( s == getStereo () )
return ;
if ( s && ! getStereo () )
{
if ( getBps () == 8 )
{
Uchar *buffer2 = new Uchar [ length * 2 ] ;
for ( int i = 0 ; i < length ; i++ )
buffer2 [ i*2 ] = buffer2 [ i*2+1 ] = buffer [ i ] ;
delete buffer ;
buffer = buffer2 ;
length *= 2 ;
setStereo ( SL_TRUE ) ;
}
else
{
Ushort *buffer2 = new Ushort [ length ] ;
for ( int i = 0 ; i < length / 2 ; i++ )
buffer2 [ i*2 ] = buffer2 [ i*2+1 ] = ((Ushort *) buffer) [ i ] ;
delete buffer ;
buffer = (Uchar *)buffer2 ;
length *= 2 ;
setStereo ( SL_TRUE ) ;
}
}
else
{
if ( getBps () == 8 )
{
Uchar *buffer2 = new Uchar [ length / 2 ] ;
for ( int i = 0 ; i < (length-1)/2 ; i++ )
buffer2 [ i ] = ((int)buffer [ i*2 ] + (int)buffer [ i*2 + 1 ] ) / 2 ;
delete buffer ;
buffer = buffer2 ;
length /= 2 ;
setStereo ( SL_FALSE ) ;
}
else
{
Ushort *buffer2 = new Ushort [ length / 4 ] ;
for ( int i = 0 ; i < (length-3) / 4 ; i++ )
buffer2 [ i ] = ((int)((Ushort *)buffer) [ i*2 ] +
(int)((Ushort *)buffer) [ i*2 + 1 ] ) / 2 ;
delete buffer ;
buffer = (Uchar *)buffer2 ;
length /= 4 ;
setStereo ( SL_FALSE ) ;
}
}
}
static void swap_Ushort ( Ushort *i )
{
*i = ((*i << 8) & 0xFF00) +
((*i >> 8) & 0x00FF) ;
}
static void swap_int ( int *i )
{
*i = ((*i << 24) & 0xFF000000) +
((*i << 8) & 0x00FF0000) +
((*i >> 8) & 0x0000FF00) +
((*i >> 24) & 0x000000FF) ;
}
int slSample::loadFile ( char *fname )
{
if ( strcasecmp ( & fname [ strlen ( fname ) - 4 ], ".wav" ) == 0 )
return loadWavFile ( fname ) ;
if ( strcasecmp ( & fname [ strlen ( fname ) - 3 ], ".au" ) == 0 )
return loadAUFile ( fname ) ;
if ( strcasecmp ( & fname [ strlen ( fname ) - 3 ], ".ub" ) == 0 )
return loadRawFile ( fname ) ;
fprintf ( stderr, "slSample:loadFile: Unknown file type for '%s'.\n",
fname ) ;
return SL_FALSE ;
}
int slSample::loadWavFile ( char *fname )
{
int found_header = SL_FALSE ;
int needs_swabbing = SL_FALSE ;
delete buffer ;
buffer = NULL ;
length = 0 ;
FILE *fd = fopen ( fname, "rb" ) ;
if ( fd == NULL )
{
fprintf ( stderr,
"slSample: loadWavFile: Cannot open '%s' for reading.\n",
fname ) ;
return SL_FALSE ;
}
char magic [ 8 ] ;
if ( fread ( magic, 4, 1, fd ) == 0 ||
magic[0] != 'R' || magic[1] != 'I' ||
magic[2] != 'F' || magic[3] != 'F' )
{
fprintf ( stderr, "slWavSample: File '%s' has wrong magic number\n", fname ) ;
fprintf ( stderr, " - it probably isn't in '.wav' format.\n" ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
int leng1 ;
if ( fread ( & leng1, sizeof(int), 1, fd ) == 0 )
{
fprintf ( stderr, "slSample: File '%s' has premature EOF in header\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
fread ( magic, 4, 1, fd ) ;
if ( magic[0] != 'W' || magic[1] != 'A' ||
magic[2] != 'V' || magic[3] != 'E' )
{
fprintf ( stderr, "slSample: File '%s' has no WAVE tag.\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
while ( ! feof ( fd ) )
{
fread ( magic, 4, 1, fd ) ;
if ( magic[0] == 'f' && magic[1] == 'm' &&
magic[2] == 't' && magic[3] == ' ' )
{
found_header = SL_TRUE ;
if ( fread ( & leng1, sizeof(int), 1, fd ) == 0 )
{
fprintf ( stderr, "slSample: File '%s' has premature EOF in header\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
if ( leng1 > 65536 )
{
needs_swabbing = SL_TRUE ;
swap_int ( & leng1 ) ;
}
Ushort header [ 8 ] ;
if ( leng1 != sizeof ( header ) )
fprintf ( stderr,
"slSample: File '%s' has unexpectedly long (%d byte) header\n",
fname, leng1 ) ;
fread ( & header, sizeof(header), 1, fd ) ;
for ( int junk = sizeof(header) ; junk < leng1 ; junk++ )
fgetc ( fd ) ;
if ( needs_swabbing )
{
swap_Ushort ( & header[0] ) ;
swap_Ushort ( & header[1] ) ;
swap_int ( (int *) & header[2] ) ;
swap_int ( (int *) & header[4] ) ;
swap_Ushort ( & header[6] ) ;
swap_Ushort ( & header[7] ) ;
}
if ( header [ 0 ] != 0x0001 )
{
fprintf ( stderr, "slSample: File '%s' is not WAVE_FORMAT_PCM!\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
setStereo ( header[1] > 1 ) ;
setRate ( *((int *) (& header[2])) ) ;
setBps ( header[7] ) ;
}
else
if ( magic[0] == 'd' && magic[1] == 'a' &&
magic[2] == 't' && magic[3] == 'a' )
{
if ( ! found_header )
{
fprintf ( stderr, "slSample: File '%s' has no data section\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
if ( fread ( & length, sizeof(int), 1, fd ) == 0 )
{
fprintf ( stderr, "slSample: File '%s' has premature EOF in data\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
if ( needs_swabbing )
swap_int ( & length ) ;
buffer = new Uchar [ length ] ;
fread ( buffer, 1, length, fd ) ;
if ( getBps () == 16 )
{
Ushort *b = (Ushort*) buffer ;
for ( int i = 0 ; i < length/2 ; i++ )
b [ i ] = (Ushort) ( (int)((short) b [ i ]) + 32768 ) ;
}
fclose ( fd ) ;
return SL_TRUE ;
}
}
fclose ( fd ) ;
return SL_FALSE ;
}
int slSample::loadAUFile ( char *fname )
{
delete buffer ;
buffer = NULL ;
length = 0 ;
FILE *fd = fopen ( fname, "rb" ) ;
if ( fd == NULL )
{
fprintf ( stderr,
"slSample: loadAUFile: Cannot open '%s' for reading.\n",
fname ) ;
return SL_FALSE ;
}
char magic [ 4 ] ;
if ( fread ( magic, 4, 1, fd ) == 0 ||
magic[0] != '.' || magic[1] != 's' ||
magic[2] != 'n' || magic[3] != 'd' )
{
fprintf ( stderr, "slSample: File '%s' has wrong magic number\n", fname ) ;
fprintf ( stderr, " - it probably isn't in '.au' format.\n" ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
int hdr_length ;
int dat_length ;
int nbytes ;
int irate ;
int nchans ;
if ( fread ( & hdr_length, sizeof(int), 1, fd ) == 0 ||
fread ( & dat_length, sizeof(int), 1, fd ) == 0 ||
fread ( & nbytes , sizeof(int), 1, fd ) == 0 ||
fread ( & irate , sizeof(int), 1, fd ) == 0 ||
fread ( & nchans , sizeof(int), 1, fd ) == 0 )
{
fprintf ( stderr, "slSample: File '%s' has premature EOF in header\n", fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
if ( hdr_length > 65536 )
{
swap_int ( & hdr_length ) ;
swap_int ( & dat_length ) ;
swap_int ( & nbytes ) ;
swap_int ( & irate ) ;
swap_int ( & nchans ) ;
}
bps = nbytes * 8 ;
stereo = (nchans>1) ;
rate = irate ;
if ( nbytes > 2 || nbytes <= 0 || hdr_length > 512 || hdr_length < 24 ||
irate > 65526 || irate <= 1000 || nchans < 1 || nchans > 2 )
{
fprintf ( stderr, "slSample: File '%s' has a very strange header\n", fname ) ;
fprintf ( stderr, " Header Length = %d\n", hdr_length ) ;
fprintf ( stderr, " Data Length = %d\n", dat_length ) ;
fprintf ( stderr, " Bytes/sample = %d\n", nbytes ) ;
fprintf ( stderr, " Sampling Rate = %dHz\n",irate ) ;
fprintf ( stderr, " Num Channels = %d\n", nchans ) ;
fprintf ( stderr, "\n" ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
if ( hdr_length > 24 )
{
delete comment ;
comment = new char [ hdr_length - 24 + 1 ] ;
fread ( comment, 1, hdr_length - 24, fd ) ;
}
if ( dat_length > 0 )
{
buffer = new Uchar [ dat_length ] ;
length = fread ( buffer, 1, dat_length, fd ) ;
if ( length != dat_length )
fprintf ( stderr, "slAUSample: File '%s' has premature EOF in data.\n", fname ) ;
}
fclose ( fd ) ;
return SL_TRUE ;
}
int slSample::loadRawFile ( char *fname )
{
delete buffer ;
buffer = NULL ;
length = 0 ;
FILE *fd = fopen ( fname, "rb" ) ;
if ( fd == NULL )
{
fprintf ( stderr,
"slSample: loadRawFile: Cannot open '%s' for reading.\n",
fname ) ;
return SL_FALSE ;
}
struct stat stat_buf ;
if ( fstat ( fileno ( fd ), & stat_buf ) != 0 )
{
fprintf ( stderr,
"slSample: loadRawFile: Cannot get status for '%s'.\n",
fname ) ;
fclose ( fd ) ;
return SL_FALSE ;
}
length = stat_buf . st_size ;
if ( length > 0 )
{
buffer = new Uchar [ length ] ;
length = fread ( buffer, 1, length, fd ) ;
}
bps = 8 ;
stereo = SL_FALSE ;
rate = 8000 ; /* Guess */
fclose ( fd ) ;
return SL_TRUE ;
}

188
Lib/src/slSamplePlayer.cxx Normal file
View file

@ -0,0 +1,188 @@
#include "sl.h"
void slSamplePlayer::addEnvelope ( int i, slEnvelope *_env, slEnvelopeType _type )
{
if ( i < 0 || i >= SL_MAX_ENVELOPES ) return ;
if ( env [ i ] != NULL )
env [ i ] -> unRef () ;
env [ i ] = _env ;
if ( _env != NULL )
env [ i ] -> ref () ;
env_type [ i ] = _type ;
env_start_time [ i ] = slScheduler::getCurrent() -> getTimeNow () ;
}
int slSamplePlayer::preempt ( int delay )
{
slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_PREEMPTED, magic ) ;
switch ( preempt_mode )
{
case SL_SAMPLE_CONTINUE: if ( isRunning() )
return SL_FALSE ;
/* FALLTHROUGH! */
case SL_SAMPLE_DELAY : break ;
case SL_SAMPLE_MUTE : skip ( delay ) ; break ;
case SL_SAMPLE_ABORT : stop () ; break ;
case SL_SAMPLE_RESTART : reset () ; break ;
}
return SL_TRUE ;
}
slSamplePlayer::~slSamplePlayer ()
{
if ( sample )
sample -> unRef () ;
slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_COMPLETE, magic ) ;
}
void slSamplePlayer::skip ( int nframes )
{
if ( nframes < lengthRemaining )
{
lengthRemaining -= nframes ;
bufferPos += nframes ;
}
else
if ( replay_mode == SL_SAMPLE_LOOP )
{
slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_LOOPED, magic ) ;
nframes -= lengthRemaining ;
while ( nframes >= sample->getLength () )
nframes -= sample->getLength () ;
lengthRemaining = sample->getLength() - nframes ;
bufferPos = & ( sample->getBuffer() [ nframes ] ) ;
}
else
stop () ;
}
void slSamplePlayer::read ( int nframes, Uchar *dst, int next_env )
{
/*
WARNING:
CO-RECURSIVE!
*/
/* Find the next envelope */
while ( next_env < SL_MAX_ENVELOPES && env [ next_env ] == NULL )
next_env++ ;
/*
If there are no fancy envelopes to process then return
the raw data.
*/
if ( next_env >= SL_MAX_ENVELOPES ) /* No fancy envelopes left */
{
low_read ( nframes, dst ) ;
return ;
}
/*
Envelope processing required...
Process the next envelope using data read recursively through
the remaining envelopes.
*/
switch ( env_type [ next_env ] )
{
/* For Volume envelopes, SRC and DST can be the same buffer */
case SL_INVERSE_VOLUME_ENVELOPE:
read ( nframes, dst, next_env+1 ) ;
env[ next_env ]->applyToInvVolume ( dst,dst,nframes,env_start_time[ next_env ] ) ;
break ;
case SL_VOLUME_ENVELOPE :
read ( nframes, dst, next_env+1 ) ;
env[ next_env ]->applyToVolume ( dst,dst,nframes,env_start_time[ next_env ] ) ;
break ;
case SL_INVERSE_PITCH_ENVELOPE :
env[ next_env ]->applyToInvPitch ( dst,this,nframes,env_start_time[ next_env ], next_env+1 ) ;
break ;
case SL_PITCH_ENVELOPE :
env[ next_env ]->applyToPitch ( dst,this,nframes,env_start_time[ next_env ], next_env+1 ) ;
break ;
case SL_INVERSE_FILTER_ENVELOPE:
case SL_FILTER_ENVELOPE :
read ( nframes, dst, next_env+1 ) ;
break ;
case SL_INVERSE_PAN_ENVELOPE :
case SL_PAN_ENVELOPE :
read ( nframes, dst, next_env+1 ) ;
break ;
case SL_INVERSE_ECHO_ENVELOPE :
case SL_ECHO_ENVELOPE :
read ( nframes, dst, next_env+1 ) ;
break ;
}
}
void slSamplePlayer::low_read ( int nframes, Uchar *dst )
{
if ( isWaiting() ) start () ;
if ( bufferPos == NULL ) /* Run out of sample & no repeats */
{
memset ( dst, 0x80, nframes ) ;
return ;
}
while ( SL_TRUE )
{
/*
If we can satisfy this request in one read (with data left in
the sample buffer ready for next time around) - then we are done...
*/
if ( nframes < lengthRemaining )
{
memcpy ( dst, bufferPos, nframes ) ;
bufferPos += nframes ;
lengthRemaining -= nframes ;
return ;
}
memcpy ( dst, bufferPos, lengthRemaining ) ;
bufferPos += lengthRemaining ;
dst += lengthRemaining ;
nframes -= lengthRemaining ;
lengthRemaining = 0 ;
if ( replay_mode == SL_SAMPLE_ONE_SHOT )
{
stop () ;
memset ( dst, 0x80, nframes ) ;
return ;
}
else
{
slScheduler::getCurrent() -> addCallBack ( callback, sample, SL_EVENT_LOOPED, magic ) ;
start () ;
}
}
}

253
Lib/src/slScheduler.cxx Normal file
View file

@ -0,0 +1,253 @@
#include "sl.h"
char *__slPendingError = NULL ;
slScheduler *slScheduler::current = NULL ;
void slScheduler::init ()
{
current = this ;
if ( not_working () )
{
fprintf ( stderr, "slScheduler: soundcard init failed.\n" ) ;
setError () ;
return ;
}
if ( getBps() != 8 )
{
fprintf ( stderr, "slScheduler: Needs a sound card that supports 8 bits per sample.\n" ) ;
setError () ;
return ;
}
if ( getStereo() )
{
fprintf ( stderr, "slScheduler: Needs a sound card that supports monophonic replay.\n" ) ;
setError () ;
return ;
}
for ( int i = 0 ; i < SL_MAX_SAMPLES ; i++ )
samplePlayer [ i ] = NULL ;
amount_left = 0 ;
now = 0 ;
num_pending_callbacks = 0 ;
safety_margin = 1.0 ;
mixer = NULL ;
mixer_buffer = NULL ;
spare_buffer0 = NULL ;
spare_buffer1 = NULL ;
spare_buffer2 = NULL ;
initBuffers () ;
}
void slScheduler::initBuffers ()
{
if ( not_working () )
return ;
delete mixer_buffer ;
delete spare_buffer0 ;
delete spare_buffer1 ;
delete spare_buffer2 ;
mixer_buffer_size = getDriverBufferSize () ;
mixer_buffer = new Uchar [ mixer_buffer_size ] ;
memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
spare_buffer0 = new Uchar [ mixer_buffer_size ] ;
spare_buffer1 = new Uchar [ mixer_buffer_size ] ;
spare_buffer2 = new Uchar [ mixer_buffer_size ] ;
}
slScheduler::~slScheduler ()
{
if ( current == this )
current = NULL ;
delete mixer_buffer ;
delete spare_buffer0 ;
delete spare_buffer1 ;
delete spare_buffer2 ;
}
void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb )
{
register int l = mixer_buffer_size ;
register Uchar *d = mixer_buffer ;
register Uchar *a = spare_buffer0 ;
register Uchar *b = spare_buffer1 ;
spa -> read ( l, a ) ;
spb -> read ( l, b ) ;
while ( l-- ) *d++ = mix ( *a++, *b++ ) ;
}
void slScheduler::mixBuffer ( slSamplePlayer *spa, slSamplePlayer *spb,
slSamplePlayer *spc )
{
register int l = mixer_buffer_size ;
register Uchar *d = mixer_buffer ;
register Uchar *a = spare_buffer0 ;
register Uchar *b = spare_buffer1 ;
register Uchar *c = spare_buffer2 ;
spa -> read ( l, a ) ;
spb -> read ( l, b ) ;
spc -> read ( l, c ) ;
while ( l-- ) *d++ = mix ( *a++, *b++, *c++ ) ;
}
void slScheduler::realUpdate ( int dump_first )
{
if ( not_working () )
return ;
if ( __slPendingError != NULL )
{
fprintf ( stderr, "%s", __slPendingError ) ;
exit ( 1 ) ;
}
int i ;
while ( secondsUsed() <= safety_margin )
{
slSamplePlayer *psp [ 3 ] ;
int pri [ 3 ] ;
pri [ 0 ] = pri [ 1 ] = pri [ 2 ] = -1 ;
for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
{
if ( samplePlayer [ i ] == NULL )
continue ;
/* Clean up dead sample players */
if ( samplePlayer [ i ] -> isDone () )
{
delete samplePlayer [ i ] ;
samplePlayer [ i ] = NULL ;
continue ;
}
if ( samplePlayer [ i ] -> isPaused () )
continue ;
int lowest = ( pri [0] <= pri [2] ) ?
(( pri [0] <= pri [1] ) ? 0 : 1 ) :
(( pri [1] <= pri [2] ) ? 1 : 2 ) ;
if ( samplePlayer[i]->getPriority() > pri[lowest] )
{
psp[lowest] = samplePlayer[i] ;
pri[lowest] = samplePlayer[i]->getPriority() ;
}
}
for ( i = 0 ; i < SL_MAX_SAMPLES ; i++ )
{
if ( samplePlayer [ i ] == NULL )
continue ;
if ( ! samplePlayer [ i ] -> isPaused () &&
samplePlayer [ i ] != psp[0] &&
samplePlayer [ i ] != psp[1] &&
samplePlayer [ i ] != psp[2] )
{
samplePlayer [ i ] -> preempt ( mixer_buffer_size ) ;
}
}
if ( pri[0] < 0 )
{
memset ( mixer_buffer, 0x80, mixer_buffer_size ) ;
amount_left = 0 ;
}
else
if ( pri[1] < 0 )
psp[0] -> read ( mixer_buffer_size, mixer_buffer ) ;
else
if ( pri[2] < 0 )
mixBuffer ( psp[0], psp[1] ) ;
else
mixBuffer ( psp[0], psp[1], psp[2] ) ;
if ( dump_first )
{
stop () ;
dump_first = SL_FALSE ;
}
play ( mixer_buffer, mixer_buffer_size ) ;
now += mixer_buffer_size ;
}
flushCallBacks () ;
}
void slScheduler::addCallBack ( slCallBack c, slSample *s, slEvent e, int m )
{
if ( not_working () )
return ;
if ( num_pending_callbacks >= SL_MAX_CALLBACKS )
{
fprintf ( stderr, "slScheduler: Too many pending callback events!\n" ) ;
return ;
}
slPendingCallBack *p = & ( pending_callback [ num_pending_callbacks++ ] ) ;
p -> callback = c ;
p -> sample = s ;
p -> event = e ;
p -> magic = m ;
}
void slScheduler::flushCallBacks ()
{
if ( not_working () )
return ;
/*
Execute all the callbacks that we accumulated
in this iteration.
This is done at the end of 'update' to reduce the risk
of nasty side-effects caused by 'unusual' activities
in the application's callback function.
*/
while ( num_pending_callbacks > 0 )
{
slPendingCallBack *p = & ( pending_callback [ --num_pending_callbacks ] ) ;
if ( p -> callback )
(*(p->callback))( p->sample, p->event, p->magic ) ;
}
}

89
Lib/src/sm.h Normal file
View file

@ -0,0 +1,89 @@
#ifndef __SM_H__
#define __SM_H__ 1
#include "slPortability.h"
#ifdef SL_USING_OSS_AUDIO
#define SMMIXER_DEFAULT_DEVICE "/dev/mixer"
// static char *labels [] = SOUND_DEVICE_LABELS;
#elif defined(WIN32)
#define SMMIXER_DEFAULT_DEVICE "mixer"
#else
#endif
# define SM_TRUE 1
# define SM_FALSE 0
typedef unsigned char Uchar ;
typedef unsigned short Ushort ;
class smMixer
{
private:
int devices ;
int error ;
int fd ;
#ifdef SL_USING_OSS_AUDIO
// static char *labels [] = SOUND_DEVICE_LABELS ;
int ioctl ( int cmd, int param = 0 )
{
if ( error ) return param ;
if ( ::ioctl ( fd, cmd, & param ) == -1 )
{
perror ( "smMixer: ioctl" ) ;
error = SM_TRUE ;
}
return param ;
}
#endif
void open ( char *device ) ;
void close () ;
public:
/* Tom */
smMixer ();
smMixer ( char *device );
~smMixer ();
int not_working ();
/* Volume controls are in integer percentages */
int getVolume ( int channel );
void setVolume ( int channel, int volume );
void getVolume ( int channel, int *left, int *right );
void setVolume ( int channel, int left, int right );
void setTreble ( int treble );
void setBass ( int bass );
void setMasterVolume ( int volume );
void setSynthVolume ( int volume );
void setPCMVolume ( int volume );
void setSpeakerVolume( int volume );
void setLineVolume ( int volume );
void setMicVolume ( int volume );
void setCDVolume ( int volume );
void setMasterVolume ( int left, int right );
void setSynthVolume ( int left, int right );
void setPCMVolume ( int left, int right );
void setSpeakerVolume( int left, int right );
void setLineVolume ( int left, int right );
void setMicVolume ( int left, int right );
void setCDVolume ( int left, int right );
} ;
#endif

256
Lib/src/smMixer.cxx Normal file
View file

@ -0,0 +1,256 @@
#include "sm.h"
#ifdef SL_USING_OSS_AUDIO
/* ------------------------------------------------------------ */
/* OSSAUDIO - Linux, FreeBSD */
/* ------------------------------------------------------------ */
void smMixer::open ( char *device )
{
fd = ::open ( device, O_WRONLY ) ;
if ( fd < 0 )
{
perror ( "smMixer: open" ) ;
error = SM_TRUE ;
}
else
error = SM_FALSE ;
devices = ioctl ( SOUND_MIXER_READ_DEVMASK ) ;
}
void smMixer::close ()
{
if ( fd >= 0 )
::close ( fd ) ;
}
smMixer::smMixer ()
{
open ( SMMIXER_DEFAULT_DEVICE ) ;
}
smMixer::smMixer ( char *device )
{
open ( device ) ;
}
smMixer::~smMixer ()
{
close () ;
}
int smMixer::not_working ()
{
return error ;
}
/* Volume controls are in integer percentages */
int smMixer::getVolume ( int channel )
{
return ioctl ( MIXER_READ ( channel ) ) & 0xFF ;
}
void smMixer::setVolume ( int channel, int volume )
{
ioctl ( MIXER_WRITE ( channel ), (( volume & 255 ) << 8 ) |
( volume & 255 ) ) ;
}
void smMixer::getVolume ( int channel, int *left, int *right )
{
int vv = ioctl ( MIXER_READ ( channel ) ) ;
if ( left ) *left = vv & 0xFF ;
if ( right ) *right = (vv>>8) & 0xFF ;
}
void smMixer::setVolume ( int channel, int left, int right )
{
ioctl ( MIXER_WRITE ( channel ), (( right & 255 ) << 8 ) |
( left & 255 ) ) ;
}
void smMixer::setTreble ( int treble )
{
setVolume ( SOUND_MIXER_TREBLE , treble ) ;
}
void smMixer::setBass ( int bass )
{
setVolume ( SOUND_MIXER_TREBLE , bass ) ;
}
void smMixer::setMasterVolume ( int volume )
{
setVolume ( SOUND_MIXER_VOLUME , volume ) ;
}
void smMixer::setSynthVolume ( int volume )
{
setVolume ( SOUND_MIXER_SYNTH , volume ) ;
}
void smMixer::setPCMVolume ( int volume )
{
setVolume ( SOUND_MIXER_PCM , volume ) ;
}
void smMixer::setSpeakerVolume( int volume )
{
setVolume ( SOUND_MIXER_SPEAKER, volume ) ;
}
void smMixer::setLineVolume ( int volume )
{
setVolume ( SOUND_MIXER_LINE , volume ) ;
}
void smMixer::setMicVolume ( int volume )
{
setVolume ( SOUND_MIXER_MIC , volume ) ;
}
void smMixer::setCDVolume ( int volume )
{
setVolume ( SOUND_MIXER_CD , volume ) ;
}
void smMixer::setMasterVolume ( int left, int right )
{
setVolume ( SOUND_MIXER_VOLUME , left, right ) ;
}
void smMixer::setSynthVolume ( int left, int right )
{
setVolume ( SOUND_MIXER_SYNTH , left, right ) ;
}
void smMixer::setPCMVolume ( int left, int right )
{
setVolume ( SOUND_MIXER_PCM , left, right ) ;
}
void smMixer::setSpeakerVolume( int left, int right )
{
setVolume ( SOUND_MIXER_SPEAKER, left, right ) ;
}
void smMixer::setLineVolume ( int left, int right )
{
setVolume ( SOUND_MIXER_LINE , left, right ) ;
}
void smMixer::setMicVolume ( int left, int right )
{
setVolume ( SOUND_MIXER_MIC , left, right ) ;
}
void smMixer::setCDVolume ( int left, int right )
{
setVolume ( SOUND_MIXER_CD , left, right ) ;
}
#elif defined(__OpenBSD__)
/* ------------------------------------------------------------ */
/* OpenBSD 2.3 */
/* ------------------------------------------------------------ */
void smMixer::open ( char *device )
{
}
void smMixer::close (){}
smMixer::smMixer () {}
smMixer::smMixer ( char * ) {}
smMixer::~smMixer () {}
int smMixer::not_working ()
{
return error ;
}
/* Volume controls are in integer percentages */
int smMixer::getVolume ( int ) { return 50 ; }
void smMixer::getVolume ( int, int *left, int *right )
{
if ( left ) *left = 50 ;
if ( right ) *right = 50 ;
}
void smMixer::setVolume ( int , int ) {}
void smMixer::setVolume ( int , int , int ){}
void smMixer::setTreble ( int ) {}
void smMixer::setBass ( int ) {}
void smMixer::setMasterVolume ( int ) {}
void smMixer::setSynthVolume ( int ) {}
void smMixer::setPCMVolume ( int ) {}
void smMixer::setSpeakerVolume( int ) {}
void smMixer::setLineVolume ( int ) {}
void smMixer::setMicVolume ( int ) {}
void smMixer::setCDVolume ( int ) {}
void smMixer::setMasterVolume ( int, int ) {}
void smMixer::setSynthVolume ( int, int ) {}
void smMixer::setPCMVolume ( int, int ) {}
void smMixer::setSpeakerVolume( int, int ) {}
void smMixer::setLineVolume ( int, int ) {}
void smMixer::setMicVolume ( int, int ) {}
void smMixer::setCDVolume ( int, int ) {}
#else
/* ------------------------------------------------------------ */
/* win32 */
/* ------------------------------------------------------------ */
void smMixer::open ( char * ) {}
void smMixer::close (){}
smMixer::smMixer () {}
smMixer::smMixer ( char * ) {}
smMixer::~smMixer () {}
int smMixer::not_working ()
{
return error ;
}
/* Volume controls are in integer percentages */
int smMixer::getVolume ( int ) { return 50 ; }
void smMixer::getVolume ( int, int *left, int *right )
{
if ( left ) *left = 50 ;
if ( right ) *right = 50 ;
}
void smMixer::setVolume ( int, int ) {}
void smMixer::setVolume ( int, int, int ){}
void smMixer::setTreble ( int ) {}
void smMixer::setBass ( int ) {}
void smMixer::setMasterVolume ( int ) {}
void smMixer::setSynthVolume ( int ) {}
void smMixer::setPCMVolume ( int ) {}
void smMixer::setSpeakerVolume( int ) {}
void smMixer::setLineVolume ( int ) {}
void smMixer::setMicVolume ( int ) {}
void smMixer::setCDVolume ( int ) {}
void smMixer::setMasterVolume ( int, int ) {}
void smMixer::setSynthVolume ( int, int ) {}
void smMixer::setPCMVolume ( int, int ) {}
void smMixer::setSpeakerVolume( int, int ) {}
void smMixer::setLineVolume ( int, int ) {}
void smMixer::setMicVolume ( int, int ) {}
void smMixer::setCDVolume ( int, int ) {}
#endif

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