]> git.mxchange.org Git - flightgear.git/commitdiff
Merge FG_Lib as subdirectory
authorTim Moore <timoore@redhat.com>
Mon, 14 Sep 2009 11:34:43 +0000 (13:34 +0200)
committerTim Moore <timoore@redhat.com>
Mon, 14 Sep 2009 11:34:43 +0000 (13:34 +0200)
135 files changed:
1  2 
Lib/Audio/CHANGES
Lib/Audio/Makefile.am
Lib/Audio/NOTICE
Lib/Audio/README
Lib/Audio/README.freebsd
Lib/Audio/README.linux
Lib/Audio/README.openbsd
Lib/Audio/README.sgi
Lib/Audio/README.unix
Lib/Audio/README.win
Lib/Bucket/Makefile.am
Lib/Bucket/newbucket.cxx
Lib/Bucket/newbucket.hxx
Lib/Bucket/testbucket.cxx
Lib/CVSROOT/checkoutlist
Lib/CVSROOT/commitinfo
Lib/CVSROOT/cvswrappers
Lib/CVSROOT/editinfo
Lib/CVSROOT/loginfo
Lib/CVSROOT/modules
Lib/CVSROOT/notify
Lib/CVSROOT/rcsinfo
Lib/CVSROOT/taginfo
Lib/Debug/Makefile.am
Lib/Debug/debug_types.h
Lib/Debug/fg_debug.c
Lib/Debug/fg_debug.h
Lib/Debug/logstream.cxx
Lib/Debug/logstream.hxx
Lib/Debug/logtest.cxx
Lib/Lib/Makefile.am
Lib/Math/MAT3geom.c
Lib/Math/MAT3inv.c
Lib/Math/MAT3mat.c
Lib/Math/MAT3vec.c
Lib/Math/Makefile.am
Lib/Math/fg_geodesy.cxx
Lib/Math/fg_geodesy.hxx
Lib/Math/fg_random.c
Lib/Math/fg_random.h
Lib/Math/interpolater.cxx
Lib/Math/interpolater.hxx
Lib/Math/leastsqs.cxx
Lib/Math/leastsqs.hxx
Lib/Math/mat3.h
Lib/Math/mat3defs.h
Lib/Math/mat3err.h
Lib/Math/point3d.hxx
Lib/Math/polar3d.cxx
Lib/Math/polar3d.hxx
Lib/Math/vector.cxx
Lib/Math/vector.hxx
Lib/Misc/CREDITS
Lib/Misc/Makefile.am
Lib/Misc/fgstream.cxx
Lib/Misc/fgstream.hxx
Lib/Misc/stopwatch.hxx
Lib/Misc/strutils.cxx
Lib/Misc/strutils.hxx
Lib/Misc/zfstream.cxx
Lib/Misc/zfstream.hxx
Lib/PUI/Makefile.am
Lib/PUI/complex.cxx
Lib/PUI/pu.cxx
Lib/PUI/pu.h
Lib/PUI/puBox.cxx
Lib/PUI/puButton.cxx
Lib/PUI/puButtonBox.cxx
Lib/PUI/puDialogBox.cxx
Lib/PUI/puFrame.cxx
Lib/PUI/puInput.cxx
Lib/PUI/puInterface.cxx
Lib/PUI/puLocal.h
Lib/PUI/puMenuBar.cxx
Lib/PUI/puObject.cxx
Lib/PUI/puOneShot.cxx
Lib/PUI/puPopup.cxx
Lib/PUI/puPopupMenu.cxx
Lib/PUI/puSlider.cxx
Lib/PUI/puText.cxx
Lib/Serial/Makefile.am
Lib/Serial/serial.cxx
Lib/Serial/serial.hxx
Lib/Serial/testserial.cxx
Lib/XGL/Makefile.am
Lib/XGL/xgl.c
Lib/XGL/xgl.h
Lib/XGL/xglUtils.c
Lib/example/Makefile.am
Lib/example/example.cxx
Lib/src/Makefile.am
Lib/src/sl.h
Lib/src/slDSP.cxx
Lib/src/slEnvelope.cxx
Lib/src/slPortability.h
Lib/src/slSample.cxx
Lib/src/slSamplePlayer.cxx
Lib/src/slScheduler.cxx
Lib/src/sm.h
Lib/src/smMixer.cxx
Lib/zlib/ChangeLog
Lib/zlib/INDEX
Lib/zlib/Makefile.am
Lib/zlib/README
Lib/zlib/adler32.c
Lib/zlib/algorithm.txt
Lib/zlib/compress.c
Lib/zlib/crc32.c
Lib/zlib/deflate.c
Lib/zlib/deflate.h
Lib/zlib/descrip.mms
Lib/zlib/example.c
Lib/zlib/gzio.c
Lib/zlib/infblock.c
Lib/zlib/infblock.h
Lib/zlib/infcodes.c
Lib/zlib/infcodes.h
Lib/zlib/inffast.c
Lib/zlib/inffast.h
Lib/zlib/inffixed.h
Lib/zlib/inflate.c
Lib/zlib/inftrees.c
Lib/zlib/inftrees.h
Lib/zlib/infutil.c
Lib/zlib/infutil.h
Lib/zlib/maketree.c
Lib/zlib/minigzip.c
Lib/zlib/trees.c
Lib/zlib/trees.h
Lib/zlib/uncompr.c
Lib/zlib/zconf.h
Lib/zlib/zlib.3
Lib/zlib/zlib.h
Lib/zlib/zutil.c
Lib/zlib/zutil.h

index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c360107195cfac3cbf73fcbc43e63a4363229685
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..835577f82ec1dda275f8b46da8fa7e98ce6207d8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1 @@@
++SUBDIRS = src example
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ba95093a26ab2827042e35dbdbccdda5403713a0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8bf6b4daa7127b1d0dc6e3732f5457fbc237dab0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,9 @@@
++
++Hi!
++
++  This is the fifth prototype of Steve's 'SL' sound library.
++
++  Check out 'CHANGES' and the new HTML documentation.
++
++Steve
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..540c00e4f69ede583c16a1f8e8ef49c97ae9c222
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7df00e8f24a5c27e991306cff7fd81da1983ee12
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9ef788f36cb4c791d157915c021987a7d79b5c55
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c1c52e154e15038dda3c754d0282ed48613bb112
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..771e856d5dfce71bf464433a6999b2cb34b66e2d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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>
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a9d528227b93ea3610ed14f7e403dc7a3243052a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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;......
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..87f83785a1c225241f24e46f35f22633fdeee186
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2fbb32ec57756a0a93f2848cf49eb63f2dddb333
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3ef337d4a42065fa6c0612f3608f60527f8cee1e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0ffbf5d1ac50d469f906f46e0ed6879f22879038
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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;
++    }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b04b3501f5efd94313942eb7439457bc82f5a2f5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 '#'
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b19e7b7a63e8e90cdb49c43f02035646c4a76e0a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5047bf1c5a053ce46a0adc97b1698ea27cb51d99
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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:
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d78886c1522b6eae3470c13da218c3d8e197cf71
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..226e93771063fe5504eb2c55dd3bd629dd6c6e59
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cb9e9efc94b342879a5fff24b425473fc11edd01
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..34f0bc288808e56e499d0852a9bfc9a3214b02d9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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"
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..49e59f4d0df9b432c5b99c0b806378a77c9cd870
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..274a46dd5b61069f1cea62395178b09aa3120248
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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".
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f45c0bde73adfb7677744aa20b0ee596c55e5fc2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8be6350c180c0a0b82b19f33882a69d30f0903cf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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;
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ca236a3371264762236c001c4277782393a82ed1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++ *
++ */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..22adb912ab4136d0ce493737986a223a96e2f7b9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..182cafda13cd7a9c98510531643f3c9f0f609eac
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f79f1b88ac409464d689ba397ddd21235e574efc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b02c6b086beec56af1815eab4f525d736ae3a3fc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a0bdf9327a18aea9232a2628c4bc1ea371f1b8ce
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++if ENABLE_UNIX_SERIAL
++SERIAL_DIRS = Serial
++else
++SERIAL_DIRS =
++endif
++
++SUBDIRS = \
++      Bucket \
++      Debug \
++      Math \
++      Misc \
++      $(SERIAL_DIRS) \
++      XGL\
++      plib \
++      zlib
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..93e754b12d0d37d0e2dd93f298ba3a1fec031e7d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..874b2f3b0929e169ef22de0e2f76565f6ca107f5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4355f176904b28fc90b04c9fe4a3f6923553ef70
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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);
++   }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d760add5fe9e416fcf274c919adff3cde08e2a97
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..eda2bc005651cd30553a2b688e55dc6c87562e54
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..af10c101365b24c0a449795a0bd5f77bccabc307
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f863d39d83d43a8d26905675a86ca09e4cc4c07c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..31b24be7dcc86c99027b0f5f334b96dcc61b1576
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3ae53a0534947aa2378b266798fe1d03a32110dd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9aabeda2f433aeccf9576b542010e55524828164
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4260ba485123efb854f1df896c963406be9f9de0
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..28e2bd35a2443b1e036195bcce3c9a6119af5a5c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d8b40c80e33e9f2a3ba53f85ee04b87382351145
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
diff --cc Lib/Math/mat3.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e11896ce158d091f1445b08f5c5a515582535c8e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..dd4ceeb5e9385cbe7c42cb7602f41c4a83d1ea08
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7ac5740addb131dbab43f3b74a44b2643c29df7a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9752707797dec38fea62447dd5416e9fdb439647
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7958a83c28586bd450fd64d205d56dcf5021a557
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4118f2d2c8878fdc014a8cc4a049c484a6a827ff
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..22509cd605d54dd8f94029ca2a3d29d7d138a415
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..92e897c350c0668ba7e368c7006e7199f2a69b82
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b2528cdc2bac73e0e5ba64ec8eebcf482fc07c46
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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)
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e35acf4f281308231cd2a6a784c5dc7c9fcd8e9c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b695315cbef6374580b4e01fa22efaba5fe00bc8
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e8b7c0bb311d1573090fe67c627fb042b46c94a4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d3bcfade467064d311838940f8651c840710013d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..2f23d83f4919601a30a8b13ed2686fabb3980734
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b2c47a775bafc5a6c063d2ff1b2623b888c732d7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..38387cb892cd613a6aab4e83d7f72260dd412ea2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..714393456090e4393a03bf829b1d0a2e79b07e6d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..aa38a0cdbecc643f387a192e83c42c56a370d9e6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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)
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6c5d93a735461f47b6d124cd8b831979874e24d2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++}
++
++
diff --cc Lib/PUI/pu.cxx
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5e47cf054701261318f6f73f2742197b18bf6c43
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ) ;
++}
++
diff --cc Lib/PUI/pu.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..02f99adab6bbbb946d66ac70b7daea03d5e28f3d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d0d9262851826c0790dc72e552265a48ebd1b77d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ) ;
++  }
++}
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..66ded922b3eaa14a32293182c6965dd8ab887437
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 () ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f569ed78718f9309be9100978475a688bfebd5be
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ) ;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8ce592be073442e7c07e8784d015b1a085003b90
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,4 @@@
++
++#include "puLocal.h"
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8c57aa453000e3bfa837a5bed72eb133932b54e6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ) ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7d8de1a456b23817c06aef76cfa257949b4111b9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..500f829713423d1dc830cb508894c3889067d176
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++    }
++}
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a366d287328630489e3aaf1cd63918baf606a053
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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"
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..87a2299b4e8974eb1f88ec251bb60f5fb3330114
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 () ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..00fc5a26c61f35b6082d571906daad3e51a46213
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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." ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7d0f7c9bae37c9ad4a4f5b2e640a66cdf34e02af
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ) ;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..59a5fef5c9a32bf49848fecde6a744664b1a23b5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3 @@@
++
++#include "puLocal.h"
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0eed102316cf61b9660bec0670b017ffdae63c79
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..aeab8f17015c52c4dce05975e2c5d92c67440aca
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++    }
++  }
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..032c0162943fe4665c50fec19ac09118ed0ed5cc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,8 @@@
++
++#include "puLocal.h"
++
++void puText::draw ( int dx, int dy )
++{
++  draw_label ( dx, dy ) ;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..66a9f16625f74da881f743e20e19396b357259e2
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ed580f8afc7d492b896ddba0a57d45b8e9b41b0e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..3b2c60b68b4274a1302361a137060e3ca8167aaa
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
++//
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..c582c13c316dc916c230ccdc31bf0ca537bd202d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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;
++      }
++    }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..38aa0db882f51432d4b28b4da7efa7e20f2a5d53
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,5 @@@
++lib_LIBRARIES = libXGL.a
++
++libXGL_a_SOURCES = xgl.c xgl.h xglUtils.c
++
++INCLUDES += -I$(top_builddir) -I$(top_builddir)/Simulator
diff --cc Lib/XGL/xgl.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..653805240e350521569408ddc8b60d5f0e814469
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,3034 @@@
++#ifdef HAVE_CONFIG_H
++#  include <config.h>
++#endif
++
++#ifdef HAVE_WINDOWS_H
++#  include <windows.h>
++#endif
++
++#include "xgl.h"
++#include <GL/glut.h>
++
++#include <stdio.h>
++#include <stdlib.h>
++
++#ifdef HAVE_UNISTD_H
++#  include <unistd.h>
++#endif
++
++
++#ifdef XGL_TRACE
++
++#ifndef TRUE
++#define TRUE  1
++#define FALSE 0
++#endif
++
++GLboolean xglIsEnabled ( GLenum cap )
++{
++  if ( xglTraceIsEnabled("glIsEnabled") )
++    fprintf ( xglTraceFd, "  /* glIsEnabled ( (GLenum)%s ) ; */\n" , xglExpandGLenum ( (GLenum) cap ) ) ;
++
++  return glIsEnabled ( cap ) ;
++}
++
++GLboolean xglIsList ( GLuint list )
++{
++  if ( xglTraceIsEnabled("glIsList") )
++    fprintf ( xglTraceFd, "  /* glIsList ( (GLuint)%u ) ; */\n" , list ) ;
++
++  return glIsList ( list ) ;
++}
++
++GLenum xglGetError (  )
++{
++  if ( xglTraceIsEnabled("glGetError") )
++    fprintf ( xglTraceFd, "  /* glGetError (  ) ; */\n"  ) ;
++
++  return glGetError (  ) ;
++}
++
++GLint xglRenderMode ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glRenderMode") )
++    fprintf ( xglTraceFd, "  glRenderMode ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++
++  return glRenderMode ( mode ) ;
++}
++
++GLuint xglGenLists ( GLsizei range )
++{
++  if ( xglTraceIsEnabled("glGenLists") )
++    fprintf ( xglTraceFd, "  glGenLists ( (GLsizei)%d ) ;\n" , range ) ;
++
++  return glGenLists ( range ) ;
++}
++
++const GLubyte* xglGetString ( GLenum name )
++{
++  if ( xglTraceIsEnabled("glGetString") )
++    fprintf ( xglTraceFd, "  /* glGetString ( (GLenum)%s ) ; */\n" , xglExpandGLenum ( (GLenum) name ) ) ;
++
++  return glGetString ( name ) ;
++}
++
++void xglAccum ( GLenum op, GLfloat value )
++{
++  if ( xglTraceIsEnabled("glAccum") )
++    fprintf ( xglTraceFd, "  glAccum ( (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) op ), value ) ;
++  if ( xglExecuteIsEnabled("glAccum") )
++    glAccum ( op, value ) ;
++}
++
++void xglAlphaFunc ( GLenum func, GLclampf ref )
++{
++  if ( xglTraceIsEnabled("glAlphaFunc") )
++    fprintf ( xglTraceFd, "  glAlphaFunc ( (GLenum)%s, (GLclampf)%ff ) ;\n" , xglExpandGLenum ( (GLenum) func ), ref ) ;
++  if ( xglExecuteIsEnabled("glAlphaFunc") )
++    glAlphaFunc ( func, ref ) ;
++}
++
++void xglArrayElementEXT ( GLint i )
++{
++  if ( xglTraceIsEnabled("glArrayElementEXT") )
++    fprintf ( xglTraceFd, "  glArrayElementEXT ( (GLint)%d ) ;\n" , i ) ;
++#ifdef GL_VERSION_1_1
++    glArrayElement ( i ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glArrayElementEXT") )
++    glArrayElementEXT ( i ) ;
++#else
++  fprintf ( xglTraceFd, "  glArrayElementEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglBegin ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glBegin") )
++    fprintf ( xglTraceFd, "  glBegin ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glBegin") )
++    glBegin ( mode ) ;
++}
++
++void xglBitmap ( GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, GLubyte* bitmap )
++{
++  if ( xglTraceIsEnabled("glBitmap") )
++    fprintf ( xglTraceFd, "  glBitmap ( (GLsizei)%d, (GLsizei)%d, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLubyte *)0x%08x ) ;\n" , width, height, xorig, yorig, xmove, ymove, bitmap ) ;
++  if ( xglExecuteIsEnabled("glBitmap") )
++    glBitmap ( width, height, xorig, yorig, xmove, ymove, bitmap ) ;
++}
++
++void xglBlendColorEXT ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
++{
++  if ( xglTraceIsEnabled("glBlendColorEXT") )
++    fprintf ( xglTraceFd, "  glBlendColorEXT ( (GLclampf)%ff, (GLclampf)%ff, (GLclampf)%ff, (GLclampf)%ff ) ;\n" , red, green, blue, alpha ) ;
++#ifdef GL_EXT_blend_color
++  if ( xglExecuteIsEnabled("glBlendColorEXT") )
++    glBlendColorEXT ( red, green, blue, alpha ) ;
++#else
++  fprintf ( xglTraceFd, "  glBlendColorEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglBlendEquationEXT ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glBlendEquationEXT") )
++    fprintf ( xglTraceFd, "  glBlendEquationEXT ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++#ifdef GL_EXT_blend_minmax
++  if ( xglExecuteIsEnabled("glBlendEquationEXT") )
++    glBlendEquationEXT ( mode ) ;
++#else
++  fprintf ( xglTraceFd, "  glBlendEquationEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglBlendFunc ( GLenum sfactor, GLenum dfactor )
++{
++  if ( xglTraceIsEnabled("glBlendFunc") )
++    fprintf ( xglTraceFd, "  glBlendFunc ( (GLenum)%s, (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) sfactor ), xglExpandGLenum ( (GLenum) dfactor ) ) ;
++  if ( xglExecuteIsEnabled("glBlendFunc") )
++    glBlendFunc ( sfactor, dfactor ) ;
++}
++
++void xglCallList ( GLuint list )
++{
++  if ( xglTraceIsEnabled("glCallList") )
++    fprintf ( xglTraceFd, "  glCallList ( (GLuint)%u ) ;\n" , list ) ;
++  if ( xglExecuteIsEnabled("glCallList") )
++    glCallList ( list ) ;
++}
++
++void xglCallLists ( GLsizei n, GLenum type, GLvoid* lists )
++{
++  if ( xglTraceIsEnabled("glCallLists") )
++    fprintf ( xglTraceFd, "  glCallLists ( (GLsizei)%d, (GLenum)%s, (GLvoid *)0x%08x ) ;\n" , n, xglExpandGLenum ( (GLenum) type ), lists ) ;
++  if ( xglExecuteIsEnabled("glCallLists") )
++    glCallLists ( n, type, lists ) ;
++}
++
++
++void xglClear ( GLbitfield mask )
++{
++  if ( xglTraceIsEnabled("glClear") )
++    switch ( mask )
++    {
++      case GL_COLOR_BUFFER_BIT :
++        fprintf ( xglTraceFd, "  glClear ( GL_COLOR_BUFFER_BIT ) ;\n" ) ;
++        break ;
++      case GL_DEPTH_BUFFER_BIT :
++        fprintf ( xglTraceFd, "  glClear ( GL_DEPTH_BUFFER_BIT ) ;\n" ) ;
++        break ;
++      case GL_ACCUM_BUFFER_BIT :
++        fprintf ( xglTraceFd, "  glClear ( GL_ACCUM_BUFFER_BIT ) ;\n" ) ;
++        break ;
++      case GL_STENCIL_BUFFER_BIT :
++        fprintf ( xglTraceFd, "  glClear ( GL_STENCIL_BUFFER_BIT ) ;\n" ) ;
++        break ;
++      case (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT) :
++        fprintf ( xglTraceFd, "  glClear ( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT ) ;\n" ) ;
++        break ;
++
++      default :
++        fprintf ( xglTraceFd, "  glClear ( (GLbitfield)0x%08x ) ;\n" , mask ) ; break ;
++    }
++
++  if ( xglExecuteIsEnabled("glClear") )
++    glClear ( mask ) ;
++}
++
++
++void xglClearAccum ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
++{
++  if ( xglTraceIsEnabled("glClearAccum") )
++    fprintf ( xglTraceFd, "  glClearAccum ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glClearAccum") )
++    glClearAccum ( red, green, blue, alpha ) ;
++}
++
++void xglClearColor ( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha )
++{
++  if ( xglTraceIsEnabled("glClearColor") )
++    fprintf ( xglTraceFd, "  glClearColor ( (GLclampf)%ff, (GLclampf)%ff, (GLclampf)%ff, (GLclampf)%ff ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glClearColor") )
++    glClearColor ( red, green, blue, alpha ) ;
++}
++
++void xglClearDepth ( GLclampd depth )
++{
++  if ( xglTraceIsEnabled("glClearDepth") )
++    fprintf ( xglTraceFd, "  glClearDepth ( (GLclampd)%f ) ;\n" , depth ) ;
++  if ( xglExecuteIsEnabled("glClearDepth") )
++    glClearDepth ( depth ) ;
++}
++
++void xglClearIndex ( GLfloat c )
++{
++  if ( xglTraceIsEnabled("glClearIndex") )
++    fprintf ( xglTraceFd, "  glClearIndex ( (GLfloat)%ff ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glClearIndex") )
++    glClearIndex ( c ) ;
++}
++
++void xglClearStencil ( GLint s )
++{
++  if ( xglTraceIsEnabled("glClearStencil") )
++    fprintf ( xglTraceFd, "  glClearStencil ( (GLint)%d ) ;\n" , s ) ;
++  if ( xglExecuteIsEnabled("glClearStencil") )
++    glClearStencil ( s ) ;
++}
++
++void xglClipPlane ( GLenum plane, GLdouble* equation )
++{
++  if ( xglTraceIsEnabled("glClipPlane") )
++    fprintf ( xglTraceFd, "  glClipPlane ( (GLenum)%s, (GLdouble *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) plane ), equation ) ;
++  if ( xglExecuteIsEnabled("glClipPlane") )
++    glClipPlane ( plane, equation ) ;
++}
++
++void xglColor3b ( GLbyte red, GLbyte green, GLbyte blue )
++{
++  if ( xglTraceIsEnabled("glColor3b") )
++    fprintf ( xglTraceFd, "  glColor3b ( (GLbyte)%d, (GLbyte)%d, (GLbyte)%d ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3b") )
++    glColor3b ( red, green, blue ) ;
++}
++
++void xglColor3bv ( GLbyte* v )
++{
++  if ( xglTraceIsEnabled("glColor3bv") )
++    fprintf ( xglTraceFd, "  glColor3bv ( xglBuild3bv((GLbyte)%d,(GLbyte)%d,(GLbyte)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3bv") )
++    glColor3bv ( v ) ;
++}
++
++void xglColor3d ( GLdouble red, GLdouble green, GLdouble blue )
++{
++  if ( xglTraceIsEnabled("glColor3d") )
++    fprintf ( xglTraceFd, "  glColor3d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3d") )
++    glColor3d ( red, green, blue ) ;
++}
++
++void xglColor3dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glColor3dv") )
++    fprintf ( xglTraceFd, "  glColor3dv ( xglBuild3dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3dv") )
++    glColor3dv ( v ) ;
++}
++
++void xglColor3f ( GLfloat red, GLfloat green, GLfloat blue )
++{
++  if ( xglTraceIsEnabled("glColor3f") )
++    fprintf ( xglTraceFd, "  glColor3f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3f") )
++    glColor3f ( red, green, blue ) ;
++}
++
++void xglColor3fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glColor3fv") )
++    fprintf ( xglTraceFd, "  glColor3fv ( xglBuild3fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3fv") )
++    glColor3fv ( v ) ;
++}
++
++void xglColor3i ( GLint red, GLint green, GLint blue )
++{
++  if ( xglTraceIsEnabled("glColor3i") )
++    fprintf ( xglTraceFd, "  glColor3i ( (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3i") )
++    glColor3i ( red, green, blue ) ;
++}
++
++void xglColor3iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glColor3iv") )
++    fprintf ( xglTraceFd, "  glColor3iv ( xglBuild3iv((GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3iv") )
++    glColor3iv ( v ) ;
++}
++
++void xglColor3s ( GLshort red, GLshort green, GLshort blue )
++{
++  if ( xglTraceIsEnabled("glColor3s") )
++    fprintf ( xglTraceFd, "  glColor3s ( (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3s") )
++    glColor3s ( red, green, blue ) ;
++}
++
++void xglColor3sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glColor3sv") )
++    fprintf ( xglTraceFd, "  glColor3sv ( xglBuild3sv((GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3sv") )
++    glColor3sv ( v ) ;
++}
++
++void xglColor3ub ( GLubyte red, GLubyte green, GLubyte blue )
++{
++  if ( xglTraceIsEnabled("glColor3ub") )
++    fprintf ( xglTraceFd, "  glColor3ub ( (GLubyte)%u, (GLubyte)%u, (GLubyte)%u ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3ub") )
++    glColor3ub ( red, green, blue ) ;
++}
++
++void xglColor3ubv ( GLubyte* v )
++{
++  if ( xglTraceIsEnabled("glColor3ubv") )
++    fprintf ( xglTraceFd, "  glColor3ubv ( xglBuild3ubv((GLubyte)%d,(GLubyte)%d,(GLubyte)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3ubv") )
++    glColor3ubv ( v ) ;
++}
++
++void xglColor3ui ( GLuint red, GLuint green, GLuint blue )
++{
++  if ( xglTraceIsEnabled("glColor3ui") )
++    fprintf ( xglTraceFd, "  glColor3ui ( (GLuint)%u, (GLuint)%u, (GLuint)%u ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3ui") )
++    glColor3ui ( red, green, blue ) ;
++}
++
++void xglColor3uiv ( GLuint* v )
++{
++  if ( xglTraceIsEnabled("glColor3uiv") )
++    fprintf ( xglTraceFd, "  glColor3uiv ( xglBuild3uiv((GLuint)%d,(GLuint)%d,(GLuint)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3uiv") )
++    glColor3uiv ( v ) ;
++}
++
++void xglColor3us ( GLushort red, GLushort green, GLushort blue )
++{
++  if ( xglTraceIsEnabled("glColor3us") )
++    fprintf ( xglTraceFd, "  glColor3us ( (GLushort)%u, (GLushort)%u, (GLushort)%u ) ;\n" , red, green, blue ) ;
++  if ( xglExecuteIsEnabled("glColor3us") )
++    glColor3us ( red, green, blue ) ;
++}
++
++void xglColor3usv ( GLushort* v )
++{
++  if ( xglTraceIsEnabled("glColor3usv") )
++    fprintf ( xglTraceFd, "  glColor3usv ( xglBuild3usv((GLushort)%d,(GLushort)%d,(GLushort)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glColor3usv") )
++    glColor3usv ( v ) ;
++}
++
++void xglColor4b ( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha )
++{
++  if ( xglTraceIsEnabled("glColor4b") )
++    fprintf ( xglTraceFd, "  glColor4b ( (GLbyte)%d, (GLbyte)%d, (GLbyte)%d, (GLbyte)%d ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4b") )
++    glColor4b ( red, green, blue, alpha ) ;
++}
++
++void xglColor4bv ( GLbyte* v )
++{
++  if ( xglTraceIsEnabled("glColor4bv") )
++    fprintf ( xglTraceFd, "  glColor4bv ( xglBuild4bv((GLbyte)%d,(GLbyte)%d,(GLbyte)%d,(GLbyte)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4bv") )
++    glColor4bv ( v ) ;
++}
++
++void xglColor4d ( GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha )
++{
++  if ( xglTraceIsEnabled("glColor4d") )
++    fprintf ( xglTraceFd, "  glColor4d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4d") )
++    glColor4d ( red, green, blue, alpha ) ;
++}
++
++void xglColor4dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glColor4dv") )
++    fprintf ( xglTraceFd, "  glColor4dv ( xglBuild4dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4dv") )
++    glColor4dv ( v ) ;
++}
++
++void xglColor4f ( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha )
++{
++  if ( xglTraceIsEnabled("glColor4f") )
++    fprintf ( xglTraceFd, "  glColor4f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4f") )
++    glColor4f ( red, green, blue, alpha ) ;
++}
++
++void xglColor4fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glColor4fv") )
++    fprintf ( xglTraceFd, "  glColor4fv ( xglBuild4fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4fv") )
++    glColor4fv ( v ) ;
++}
++
++void xglColor4i ( GLint red, GLint green, GLint blue, GLint alpha )
++{
++  if ( xglTraceIsEnabled("glColor4i") )
++    fprintf ( xglTraceFd, "  glColor4i ( (GLint)%d, (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4i") )
++    glColor4i ( red, green, blue, alpha ) ;
++}
++
++void xglColor4iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glColor4iv") )
++    fprintf ( xglTraceFd, "  glColor4iv ( xglBuild4iv((GLint)%d,(GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4iv") )
++    glColor4iv ( v ) ;
++}
++
++void xglColor4s ( GLshort red, GLshort green, GLshort blue, GLshort alpha )
++{
++  if ( xglTraceIsEnabled("glColor4s") )
++    fprintf ( xglTraceFd, "  glColor4s ( (GLshort)%d, (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4s") )
++    glColor4s ( red, green, blue, alpha ) ;
++}
++
++void xglColor4sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glColor4sv") )
++    fprintf ( xglTraceFd, "  glColor4sv ( xglBuild4sv((GLshort)%d,(GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4sv") )
++    glColor4sv ( v ) ;
++}
++
++void xglColor4ub ( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha )
++{
++  if ( xglTraceIsEnabled("glColor4ub") )
++    fprintf ( xglTraceFd, "  glColor4ub ( (GLubyte)%u, (GLubyte)%u, (GLubyte)%u, (GLubyte)%u ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4ub") )
++    glColor4ub ( red, green, blue, alpha ) ;
++}
++
++void xglColor4ubv ( GLubyte* v )
++{
++  if ( xglTraceIsEnabled("glColor4ubv") )
++    fprintf ( xglTraceFd, "  glColor4ubv ( xglBuild4ubv((GLubyte)%d,(GLubyte)%d,(GLubyte)%d,(GLubyte)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4ubv") )
++    glColor4ubv ( v ) ;
++}
++
++void xglColor4ui ( GLuint red, GLuint green, GLuint blue, GLuint alpha )
++{
++  if ( xglTraceIsEnabled("glColor4ui") )
++    fprintf ( xglTraceFd, "  glColor4ui ( (GLuint)%u, (GLuint)%u, (GLuint)%u, (GLuint)%u ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4ui") )
++    glColor4ui ( red, green, blue, alpha ) ;
++}
++
++void xglColor4uiv ( GLuint* v )
++{
++  if ( xglTraceIsEnabled("glColor4uiv") )
++    fprintf ( xglTraceFd, "  glColor4uiv ( xglBuild4uiv((GLuint)%d,(GLuint)%d,(GLuint)%d,(GLuint)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4uiv") )
++    glColor4uiv ( v ) ;
++}
++
++void xglColor4us ( GLushort red, GLushort green, GLushort blue, GLushort alpha )
++{
++  if ( xglTraceIsEnabled("glColor4us") )
++    fprintf ( xglTraceFd, "  glColor4us ( (GLushort)%u, (GLushort)%u, (GLushort)%u, (GLushort)%u ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColor4us") )
++    glColor4us ( red, green, blue, alpha ) ;
++}
++
++void xglColor4usv ( GLushort* v )
++{
++  if ( xglTraceIsEnabled("glColor4usv") )
++    fprintf ( xglTraceFd, "  glColor4usv ( xglBuild4usv((GLushort)%d,(GLushort)%d,(GLushort)%d,(GLushort)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glColor4usv") )
++    glColor4usv ( v ) ;
++}
++
++void xglColorMask ( GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha )
++{
++  if ( xglTraceIsEnabled("glColorMask") )
++    fprintf ( xglTraceFd, "  glColorMask ( (GLboolean)%d, (GLboolean)%d, (GLboolean)%d, (GLboolean)%d ) ;\n" , red, green, blue, alpha ) ;
++  if ( xglExecuteIsEnabled("glColorMask") )
++    glColorMask ( red, green, blue, alpha ) ;
++}
++
++void xglColorMaterial ( GLenum face, GLenum mode )
++{
++  if ( xglTraceIsEnabled("glColorMaterial") )
++    fprintf ( xglTraceFd, "  glColorMaterial ( (GLenum)%s, (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glColorMaterial") )
++    glColorMaterial ( face, mode ) ;
++}
++
++void xglColorPointerEXT ( GLint size, GLenum type, GLsizei stride, GLsizei count, void* ptr )
++{
++  if ( xglTraceIsEnabled("glColorPointerEXT") )
++    fprintf ( xglTraceFd, "  glColorPointerEXT ( (GLint)%d, (GLenum)%s, (GLsizei)%d, (GLsizei)%d, (void *)0x%08x ) ;\n" , size, xglExpandGLenum ( (GLenum) type ), stride, count, ptr ) ;
++#ifdef GL_VERSION_1_1
++    glColorPointer ( size, type, stride, ptr ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glColorPointerEXT") )
++    glColorPointerEXT ( size, type, stride, count, ptr ) ;
++#else
++  fprintf ( xglTraceFd, "  glColorPointerEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglCopyPixels ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum type )
++{
++  if ( xglTraceIsEnabled("glCopyPixels") )
++    fprintf ( xglTraceFd, "  glCopyPixels ( (GLint)%d, (GLint)%d, (GLsizei)%d, (GLsizei)%d, (GLenum)%s ) ;\n" , x, y, width, height, xglExpandGLenum ( (GLenum) type ) ) ;
++  if ( xglExecuteIsEnabled("glCopyPixels") )
++    glCopyPixels ( x, y, width, height, type ) ;
++}
++
++void xglCullFace ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glCullFace") )
++    fprintf ( xglTraceFd, "  glCullFace ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glCullFace") )
++    glCullFace ( mode ) ;
++}
++
++void xglDeleteLists ( GLuint list, GLsizei range )
++{
++  if ( xglTraceIsEnabled("glDeleteLists") )
++    fprintf ( xglTraceFd, "  glDeleteLists ( (GLuint)%u, (GLsizei)%d ) ;\n" , list, range ) ;
++  if ( xglExecuteIsEnabled("glDeleteLists") )
++    glDeleteLists ( list, range ) ;
++}
++
++void xglDepthFunc ( GLenum func )
++{
++  if ( xglTraceIsEnabled("glDepthFunc") )
++    fprintf ( xglTraceFd, "  glDepthFunc ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) func ) ) ;
++  if ( xglExecuteIsEnabled("glDepthFunc") )
++    glDepthFunc ( func ) ;
++}
++
++void xglDepthMask ( GLboolean flag )
++{
++  if ( xglTraceIsEnabled("glDepthMask") )
++    fprintf ( xglTraceFd, "  glDepthMask ( (GLboolean)%d ) ;\n" , flag ) ;
++  if ( xglExecuteIsEnabled("glDepthMask") )
++    glDepthMask ( flag ) ;
++}
++
++void xglDepthRange ( GLclampd near_val, GLclampd far_val )
++{
++  if ( xglTraceIsEnabled("glDepthRange") )
++    fprintf ( xglTraceFd, "  glDepthRange ( (GLclampd)%f, (GLclampd)%f ) ;\n" , near_val, far_val ) ;
++  if ( xglExecuteIsEnabled("glDepthRange") )
++    glDepthRange ( near_val, far_val ) ;
++}
++
++void xglDisable ( GLenum cap )
++{
++  if ( xglTraceIsEnabled("glDisable") )
++    fprintf ( xglTraceFd, "  glDisable ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) cap ) ) ;
++  if ( xglExecuteIsEnabled("glDisable") )
++    glDisable ( cap ) ;
++}
++
++void xglDrawArraysEXT ( GLenum mode, GLint first, GLsizei count )
++{
++  if ( xglTraceIsEnabled("glDrawArraysEXT") )
++    fprintf ( xglTraceFd, "  glDrawArraysEXT ( (GLenum)%s, (GLint)%d, (GLsizei)%d ) ;\n" , xglExpandGLenum ( (GLenum) mode ), first, count ) ;
++#ifdef GL_VERSION_1_1
++    glDrawArrays ( mode, first, count ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glDrawArraysEXT") )
++    glDrawArraysEXT ( mode, first, count ) ;
++#else
++  fprintf ( xglTraceFd, "  glDrawArraysEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglDrawBuffer ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glDrawBuffer") )
++    fprintf ( xglTraceFd, "  glDrawBuffer ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glDrawBuffer") )
++    glDrawBuffer ( mode ) ;
++}
++
++void xglDrawPixels ( GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels )
++{
++  if ( xglTraceIsEnabled("glDrawPixels") )
++    fprintf ( xglTraceFd, "  glDrawPixels ( (GLsizei)%d, (GLsizei)%d, (GLenum)%s, (GLenum)%s, (GLvoid *)0x%08x ) ;\n" , width, height, xglExpandGLenum ( (GLenum) format ), xglExpandGLenum ( (GLenum) type ), pixels ) ;
++  if ( xglExecuteIsEnabled("glDrawPixels") )
++    glDrawPixels ( width, height, format, type, pixels ) ;
++}
++
++void xglEdgeFlag ( GLboolean flag )
++{
++  if ( xglTraceIsEnabled("glEdgeFlag") )
++    fprintf ( xglTraceFd, "  glEdgeFlag ( (GLboolean)%d ) ;\n" , flag ) ;
++  if ( xglExecuteIsEnabled("glEdgeFlag") )
++    glEdgeFlag ( flag ) ;
++}
++
++void xglEdgeFlagPointerEXT ( GLsizei stride, GLsizei count, GLboolean* ptr )
++{
++  if ( xglTraceIsEnabled("glEdgeFlagPointerEXT") )
++    fprintf ( xglTraceFd, "  glEdgeFlagPointerEXT ( (GLsizei)%d, (GLsizei)%d, (GLboolean *)0x%08x ) ;\n" , stride, count, ptr ) ;
++#ifdef GL_VERSION_1_1
++    glEdgeFlagPointer ( stride, ptr ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glEdgeFlagPointerEXT") )
++    glEdgeFlagPointerEXT ( stride, count, ptr ) ;
++#else
++  fprintf ( xglTraceFd, "  glEdgeFlagPointerEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglEdgeFlagv ( GLboolean* flag )
++{
++  if ( xglTraceIsEnabled("glEdgeFlagv") )
++    fprintf ( xglTraceFd, "  glEdgeFlagv ( (GLboolean *)0x%08x ) ;\n" , flag ) ;
++  if ( xglExecuteIsEnabled("glEdgeFlagv") )
++    glEdgeFlagv ( flag ) ;
++}
++
++void xglEnable ( GLenum cap )
++{
++  if ( xglTraceIsEnabled("glEnable") )
++    fprintf ( xglTraceFd, "  glEnable ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) cap ) ) ;
++  if ( xglExecuteIsEnabled("glEnable") )
++    glEnable ( cap ) ;
++}
++
++void xglEnd (  )
++{
++  if ( xglTraceIsEnabled("glEnd") )
++    fprintf ( xglTraceFd, "  glEnd (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glEnd") )
++    glEnd (  ) ;
++}
++
++void xglEndList (  )
++{
++  if ( xglTraceIsEnabled("glEndList") )
++    fprintf ( xglTraceFd, "  glEndList (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glEndList") )
++    glEndList (  ) ;
++}
++
++void xglEvalCoord1d ( GLdouble u )
++{
++  if ( xglTraceIsEnabled("glEvalCoord1d") )
++    fprintf ( xglTraceFd, "  glEvalCoord1d ( (GLdouble)%f ) ;\n" , u ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord1d") )
++    glEvalCoord1d ( u ) ;
++}
++
++void xglEvalCoord1dv ( GLdouble* u )
++{
++  if ( xglTraceIsEnabled("glEvalCoord1dv") )
++    fprintf ( xglTraceFd, "  glEvalCoord1dv ( xglBuild1dv((GLdouble)%f) ) ;\n" , u[0] ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord1dv") )
++    glEvalCoord1dv ( u ) ;
++}
++
++void xglEvalCoord1f ( GLfloat u )
++{
++  if ( xglTraceIsEnabled("glEvalCoord1f") )
++    fprintf ( xglTraceFd, "  glEvalCoord1f ( (GLfloat)%ff ) ;\n" , u ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord1f") )
++    glEvalCoord1f ( u ) ;
++}
++
++void xglEvalCoord1fv ( GLfloat* u )
++{
++  if ( xglTraceIsEnabled("glEvalCoord1fv") )
++    fprintf ( xglTraceFd, "  glEvalCoord1fv ( xglBuild1fv((GLfloat)%ff) ) ;\n" , u[0] ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord1fv") )
++    glEvalCoord1fv ( u ) ;
++}
++
++void xglEvalCoord2d ( GLdouble u, GLdouble v )
++{
++  if ( xglTraceIsEnabled("glEvalCoord2d") )
++    fprintf ( xglTraceFd, "  glEvalCoord2d ( (GLdouble)%f, (GLdouble)%f ) ;\n" , u, v ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord2d") )
++    glEvalCoord2d ( u, v ) ;
++}
++
++void xglEvalCoord2dv ( GLdouble* u )
++{
++  if ( xglTraceIsEnabled("glEvalCoord2dv") )
++    fprintf ( xglTraceFd, "  glEvalCoord2dv ( xglBuild2dv((GLdouble)%f,(GLdouble)%f) ) ;\n" , u[0], u[1] ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord2dv") )
++    glEvalCoord2dv ( u ) ;
++}
++
++void xglEvalCoord2f ( GLfloat u, GLfloat v )
++{
++  if ( xglTraceIsEnabled("glEvalCoord2f") )
++    fprintf ( xglTraceFd, "  glEvalCoord2f ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , u, v ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord2f") )
++    glEvalCoord2f ( u, v ) ;
++}
++
++void xglEvalCoord2fv ( GLfloat* u )
++{
++  if ( xglTraceIsEnabled("glEvalCoord2fv") )
++    fprintf ( xglTraceFd, "  glEvalCoord2fv ( xglBuild2fv((GLfloat)%ff,(GLfloat)%ff) ) ;\n" , u[0], u[1] ) ;
++  if ( xglExecuteIsEnabled("glEvalCoord2fv") )
++    glEvalCoord2fv ( u ) ;
++}
++
++void xglEvalMesh1 ( GLenum mode, GLint i1, GLint i2 )
++{
++  if ( xglTraceIsEnabled("glEvalMesh1") )
++    fprintf ( xglTraceFd, "  glEvalMesh1 ( (GLenum)%s, (GLint)%d, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) mode ), i1, i2 ) ;
++  if ( xglExecuteIsEnabled("glEvalMesh1") )
++    glEvalMesh1 ( mode, i1, i2 ) ;
++}
++
++void xglEvalMesh2 ( GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 )
++{
++  if ( xglTraceIsEnabled("glEvalMesh2") )
++    fprintf ( xglTraceFd, "  glEvalMesh2 ( (GLenum)%s, (GLint)%d, (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) mode ), i1, i2, j1, j2 ) ;
++  if ( xglExecuteIsEnabled("glEvalMesh2") )
++    glEvalMesh2 ( mode, i1, i2, j1, j2 ) ;
++}
++
++void xglEvalPoint1 ( GLint i )
++{
++  if ( xglTraceIsEnabled("glEvalPoint1") )
++    fprintf ( xglTraceFd, "  glEvalPoint1 ( (GLint)%d ) ;\n" , i ) ;
++  if ( xglExecuteIsEnabled("glEvalPoint1") )
++    glEvalPoint1 ( i ) ;
++}
++
++void xglEvalPoint2 ( GLint i, GLint j )
++{
++  if ( xglTraceIsEnabled("glEvalPoint2") )
++    fprintf ( xglTraceFd, "  glEvalPoint2 ( (GLint)%d, (GLint)%d ) ;\n" , i, j ) ;
++  if ( xglExecuteIsEnabled("glEvalPoint2") )
++    glEvalPoint2 ( i, j ) ;
++}
++
++void xglFeedbackBuffer ( GLsizei size, GLenum type, GLfloat* buffer )
++{
++  if ( xglTraceIsEnabled("glFeedbackBuffer") )
++    fprintf ( xglTraceFd, "  glFeedbackBuffer ( (GLsizei)%d, (GLenum)%s, (GLfloat *)0x%08x ) ;\n" , size, xglExpandGLenum ( (GLenum) type ), buffer ) ;
++  if ( xglExecuteIsEnabled("glFeedbackBuffer") )
++    glFeedbackBuffer ( size, type, buffer ) ;
++}
++
++void xglFinish (  )
++{
++  if ( xglTraceIsEnabled("glFinish") )
++    fprintf ( xglTraceFd, "  glFinish (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glFinish") )
++    glFinish (  ) ;
++}
++
++void xglFlush (  )
++{
++  if ( xglTraceIsEnabled("glFlush") )
++    fprintf ( xglTraceFd, "  glFlush (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glFlush") )
++    glFlush (  ) ;
++}
++
++void xglFogf ( GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glFogf") )
++    fprintf ( xglTraceFd, "  glFogf ( (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glFogf") )
++    glFogf ( pname, param ) ;
++}
++
++void xglFogfv ( GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glFogfv") )
++    fprintf ( xglTraceFd, "  glFogfv ( (GLenum)%s, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glFogfv") )
++    glFogfv ( pname, params ) ;
++}
++
++void xglFogi ( GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glFogi") )
++    fprintf ( xglTraceFd, "  glFogi ( (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glFogi") )
++    glFogi ( pname, param ) ;
++}
++
++void xglFogiv ( GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glFogiv") )
++    fprintf ( xglTraceFd, "  glFogiv ( (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glFogiv") )
++    glFogiv ( pname, params ) ;
++}
++
++void xglFrontFace ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glFrontFace") )
++    fprintf ( xglTraceFd, "  glFrontFace ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glFrontFace") )
++    glFrontFace ( mode ) ;
++}
++
++void xglFrustum ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val )
++{
++  if ( xglTraceIsEnabled("glFrustum") )
++    fprintf ( xglTraceFd, "  glFrustum ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , left, right, bottom, top, near_val, far_val ) ;
++  if ( xglExecuteIsEnabled("glFrustum") )
++    glFrustum ( left, right, bottom, top, near_val, far_val ) ;
++}
++
++void xglGetBooleanv ( GLenum pname, GLboolean* params )
++{
++  if ( xglTraceIsEnabled("glGetBooleanv") )
++    fprintf ( xglTraceFd, "  /* glGetBooleanv ( (GLenum)%s, (GLboolean *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetBooleanv") )
++    glGetBooleanv ( pname, params ) ;
++}
++
++void xglGetClipPlane ( GLenum plane, GLdouble* equation )
++{
++  if ( xglTraceIsEnabled("glGetClipPlane") )
++    fprintf ( xglTraceFd, "  /* glGetClipPlane ( (GLenum)%s, (GLdouble *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) plane ), equation ) ;
++  if ( xglExecuteIsEnabled("glGetClipPlane") )
++    glGetClipPlane ( plane, equation ) ;
++}
++
++void xglGetDoublev ( GLenum pname, GLdouble* params )
++{
++  if ( xglTraceIsEnabled("glGetDoublev") )
++    fprintf ( xglTraceFd, "  /* glGetDoublev ( (GLenum)%s, (GLdouble *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetDoublev") )
++    glGetDoublev ( pname, params ) ;
++}
++
++void xglGetFloatv ( GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetFloatv") )
++    fprintf ( xglTraceFd, "  /* glGetFloatv ( (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetFloatv") )
++    glGetFloatv ( pname, params ) ;
++}
++
++void xglGetIntegerv ( GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetIntegerv") )
++    fprintf ( xglTraceFd, "  /* glGetIntegerv ( (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetIntegerv") )
++    glGetIntegerv ( pname, params ) ;
++}
++
++void xglGetLightfv ( GLenum light, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetLightfv") )
++    fprintf ( xglTraceFd, "  /* glGetLightfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) light ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetLightfv") )
++    glGetLightfv ( light, pname, params ) ;
++}
++
++void xglGetLightiv ( GLenum light, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetLightiv") )
++    fprintf ( xglTraceFd, "  /* glGetLightiv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) light ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetLightiv") )
++    glGetLightiv ( light, pname, params ) ;
++}
++
++void xglGetMapdv ( GLenum target, GLenum query, GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glGetMapdv") )
++    fprintf ( xglTraceFd, "  /* glGetMapdv ( (GLenum)%s, (GLenum)%s, (GLdouble *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) query ), v ) ;
++  if ( xglExecuteIsEnabled("glGetMapdv") )
++    glGetMapdv ( target, query, v ) ;
++}
++
++void xglGetMapfv ( GLenum target, GLenum query, GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glGetMapfv") )
++    fprintf ( xglTraceFd, "  /* glGetMapfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) query ), v ) ;
++  if ( xglExecuteIsEnabled("glGetMapfv") )
++    glGetMapfv ( target, query, v ) ;
++}
++
++void xglGetMapiv ( GLenum target, GLenum query, GLint* v )
++{
++  if ( xglTraceIsEnabled("glGetMapiv") )
++    fprintf ( xglTraceFd, "  /* glGetMapiv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) query ), v ) ;
++  if ( xglExecuteIsEnabled("glGetMapiv") )
++    glGetMapiv ( target, query, v ) ;
++}
++
++void xglGetMaterialfv ( GLenum face, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetMaterialfv") )
++    fprintf ( xglTraceFd, "  /* glGetMaterialfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetMaterialfv") )
++    glGetMaterialfv ( face, pname, params ) ;
++}
++
++void xglGetMaterialiv ( GLenum face, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetMaterialiv") )
++    fprintf ( xglTraceFd, "  /* glGetMaterialiv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetMaterialiv") )
++    glGetMaterialiv ( face, pname, params ) ;
++}
++
++void xglGetPixelMapfv ( GLenum map, GLfloat* values )
++{
++  if ( xglTraceIsEnabled("glGetPixelMapfv") )
++    fprintf ( xglTraceFd, "  /* glGetPixelMapfv ( (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) map ), values ) ;
++  if ( xglExecuteIsEnabled("glGetPixelMapfv") )
++    glGetPixelMapfv ( map, values ) ;
++}
++
++void xglGetPixelMapuiv ( GLenum map, GLuint* values )
++{
++  if ( xglTraceIsEnabled("glGetPixelMapuiv") )
++    fprintf ( xglTraceFd, "  /* glGetPixelMapuiv ( (GLenum)%s, (GLuint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) map ), values ) ;
++  if ( xglExecuteIsEnabled("glGetPixelMapuiv") )
++    glGetPixelMapuiv ( map, values ) ;
++}
++
++void xglGetPixelMapusv ( GLenum map, GLushort* values )
++{
++  if ( xglTraceIsEnabled("glGetPixelMapusv") )
++    fprintf ( xglTraceFd, "  /* glGetPixelMapusv ( (GLenum)%s, (GLushort *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) map ), values ) ;
++  if ( xglExecuteIsEnabled("glGetPixelMapusv") )
++    glGetPixelMapusv ( map, values ) ;
++}
++
++void xglGetPointervEXT ( GLenum pname, void** params )
++{
++  if ( xglTraceIsEnabled("glGetPointervEXT") )
++    fprintf ( xglTraceFd, "  /* glGetPointervEXT ( (GLenum)%s, (void **)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++#ifdef GL_VERSION_1_1
++    glGetPointerv ( pname, params ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glGetPointervEXT") )
++    glGetPointervEXT ( pname, params ) ;
++#else
++  fprintf ( xglTraceFd, "  glGetPointervEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglGetPolygonStipple ( GLubyte* mask )
++{
++  if ( xglTraceIsEnabled("glGetPolygonStipple") )
++    fprintf ( xglTraceFd, "  /* glGetPolygonStipple ( (GLubyte *)0x%08x ) ; */\n" , mask ) ;
++  if ( xglExecuteIsEnabled("glGetPolygonStipple") )
++    glGetPolygonStipple ( mask ) ;
++}
++
++void xglGetTexEnvfv ( GLenum target, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetTexEnvfv") )
++    fprintf ( xglTraceFd, "  /* glGetTexEnvfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexEnvfv") )
++    glGetTexEnvfv ( target, pname, params ) ;
++}
++
++void xglGetTexEnviv ( GLenum target, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetTexEnviv") )
++    fprintf ( xglTraceFd, "  /* glGetTexEnviv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexEnviv") )
++    glGetTexEnviv ( target, pname, params ) ;
++}
++
++void xglGetTexGendv ( GLenum coord, GLenum pname, GLdouble* params )
++{
++  if ( xglTraceIsEnabled("glGetTexGendv") )
++    fprintf ( xglTraceFd, "  /* glGetTexGendv ( (GLenum)%s, (GLenum)%s, (GLdouble *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexGendv") )
++    glGetTexGendv ( coord, pname, params ) ;
++}
++
++void xglGetTexGenfv ( GLenum coord, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetTexGenfv") )
++    fprintf ( xglTraceFd, "  /* glGetTexGenfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexGenfv") )
++    glGetTexGenfv ( coord, pname, params ) ;
++}
++
++void xglGetTexGeniv ( GLenum coord, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetTexGeniv") )
++    fprintf ( xglTraceFd, "  /* glGetTexGeniv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexGeniv") )
++    glGetTexGeniv ( coord, pname, params ) ;
++}
++
++void xglGetTexImage ( GLenum target, GLint level, GLenum format, GLenum type, GLvoid* pixels )
++{
++  if ( xglTraceIsEnabled("glGetTexImage") )
++    fprintf ( xglTraceFd, "  /* glGetTexImage ( (GLenum)%s, (GLint)%d, (GLenum)%s, (GLenum)%s, (GLvoid *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), level, xglExpandGLenum ( (GLenum) format ), xglExpandGLenum ( (GLenum) type ), pixels ) ;
++  if ( xglExecuteIsEnabled("glGetTexImage") )
++    glGetTexImage ( target, level, format, type, pixels ) ;
++}
++
++void xglGetTexLevelParameterfv ( GLenum target, GLint level, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetTexLevelParameterfv") )
++    fprintf ( xglTraceFd, "  /* glGetTexLevelParameterfv ( (GLenum)%s, (GLint)%d, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), level, xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexLevelParameterfv") )
++    glGetTexLevelParameterfv ( target, level, pname, params ) ;
++}
++
++void xglGetTexLevelParameteriv ( GLenum target, GLint level, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetTexLevelParameteriv") )
++    fprintf ( xglTraceFd, "  /* glGetTexLevelParameteriv ( (GLenum)%s, (GLint)%d, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), level, xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexLevelParameteriv") )
++    glGetTexLevelParameteriv ( target, level, pname, params ) ;
++}
++
++void xglGetTexParameterfv ( GLenum target, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glGetTexParameterfv") )
++    fprintf ( xglTraceFd, "  /* glGetTexParameterfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexParameterfv") )
++    glGetTexParameterfv ( target, pname, params ) ;
++}
++
++void xglGetTexParameteriv ( GLenum target, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glGetTexParameteriv") )
++    fprintf ( xglTraceFd, "  /* glGetTexParameteriv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ; */\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glGetTexParameteriv") )
++    glGetTexParameteriv ( target, pname, params ) ;
++}
++
++void xglHint ( GLenum target, GLenum mode )
++{
++  if ( xglTraceIsEnabled("glHint") )
++    fprintf ( xglTraceFd, "  glHint ( (GLenum)%s, (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glHint") )
++    glHint ( target, mode ) ;
++}
++
++void xglIndexMask ( GLuint mask )
++{
++  if ( xglTraceIsEnabled("glIndexMask") )
++    fprintf ( xglTraceFd, "  glIndexMask ( (GLuint)%u ) ;\n" , mask ) ;
++  if ( xglExecuteIsEnabled("glIndexMask") )
++    glIndexMask ( mask ) ;
++}
++
++void xglIndexPointerEXT ( GLenum type, GLsizei stride, GLsizei count, void* ptr )
++{
++  if ( xglTraceIsEnabled("glIndexPointerEXT") )
++    fprintf ( xglTraceFd, "  glIndexPointerEXT ( (GLenum)%s, (GLsizei)%d, (GLsizei)%d, (void *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) type ), stride, count, ptr ) ;
++#ifdef GL_VERSION_1_1
++    glIndexPointer ( type, stride, ptr ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glIndexPointerEXT") )
++    glIndexPointerEXT ( type, stride, count, ptr ) ;
++#else
++  fprintf ( xglTraceFd, "  glIndexPointerEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglIndexd ( GLdouble c )
++{
++  if ( xglTraceIsEnabled("glIndexd") )
++    fprintf ( xglTraceFd, "  glIndexd ( (GLdouble)%f ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexd") )
++    glIndexd ( c ) ;
++}
++
++void xglIndexdv ( GLdouble* c )
++{
++  if ( xglTraceIsEnabled("glIndexdv") )
++    fprintf ( xglTraceFd, "  glIndexdv ( (GLdouble *)0x%08x ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexdv") )
++    glIndexdv ( c ) ;
++}
++
++void xglIndexf ( GLfloat c )
++{
++  if ( xglTraceIsEnabled("glIndexf") )
++    fprintf ( xglTraceFd, "  glIndexf ( (GLfloat)%ff ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexf") )
++    glIndexf ( c ) ;
++}
++
++void xglIndexfv ( GLfloat* c )
++{
++  if ( xglTraceIsEnabled("glIndexfv") )
++    fprintf ( xglTraceFd, "  glIndexfv ( (GLfloat *)0x%08x ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexfv") )
++    glIndexfv ( c ) ;
++}
++
++void xglIndexi ( GLint c )
++{
++  if ( xglTraceIsEnabled("glIndexi") )
++    fprintf ( xglTraceFd, "  glIndexi ( (GLint)%d ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexi") )
++    glIndexi ( c ) ;
++}
++
++void xglIndexiv ( GLint* c )
++{
++  if ( xglTraceIsEnabled("glIndexiv") )
++    fprintf ( xglTraceFd, "  glIndexiv ( (GLint *)0x%08x ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexiv") )
++    glIndexiv ( c ) ;
++}
++
++void xglIndexs ( GLshort c )
++{
++  if ( xglTraceIsEnabled("glIndexs") )
++    fprintf ( xglTraceFd, "  glIndexs ( (GLshort)%d ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexs") )
++    glIndexs ( c ) ;
++}
++
++void xglIndexsv ( GLshort* c )
++{
++  if ( xglTraceIsEnabled("glIndexsv") )
++    fprintf ( xglTraceFd, "  glIndexsv ( (GLshort *)0x%08x ) ;\n" , c ) ;
++  if ( xglExecuteIsEnabled("glIndexsv") )
++    glIndexsv ( c ) ;
++}
++
++void xglInitNames (  )
++{
++  if ( xglTraceIsEnabled("glInitNames") )
++    fprintf ( xglTraceFd, "  glInitNames (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glInitNames") )
++    glInitNames (  ) ;
++}
++
++void xglLightModelf ( GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glLightModelf") )
++    fprintf ( xglTraceFd, "  glLightModelf ( (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glLightModelf") )
++    glLightModelf ( pname, param ) ;
++}
++
++void xglLightModelfv ( GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glLightModelfv") )
++    fprintf ( xglTraceFd, "  glLightModelfv ( (GLenum)%s, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glLightModelfv") )
++    glLightModelfv ( pname, params ) ;
++}
++
++void xglLightModeli ( GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glLightModeli") )
++    fprintf ( xglTraceFd, "  glLightModeli ( (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glLightModeli") )
++    glLightModeli ( pname, param ) ;
++}
++
++void xglLightModeliv ( GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glLightModeliv") )
++    fprintf ( xglTraceFd, "  glLightModeliv ( (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glLightModeliv") )
++    glLightModeliv ( pname, params ) ;
++}
++
++void xglLightf ( GLenum light, GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glLightf") )
++    fprintf ( xglTraceFd, "  glLightf ( (GLenum)%s, (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) light ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glLightf") )
++    glLightf ( light, pname, param ) ;
++}
++
++void xglLightfv ( GLenum light, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glLightfv") )
++    fprintf ( xglTraceFd, "  glLightfv ( (GLenum)%s, (GLenum)%s, xglBuild4fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n",
++        xglExpandGLenum ( (GLenum) light ), xglExpandGLenum ( (GLenum) pname ), params[0], params[1], params[2], params[3] ) ;
++  if ( xglExecuteIsEnabled("glLightfv") )
++    glLightfv ( light, pname, params ) ;
++}
++
++void xglLighti ( GLenum light, GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glLighti") )
++    fprintf ( xglTraceFd, "  glLighti ( (GLenum)%s, (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) light ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glLighti") )
++    glLighti ( light, pname, param ) ;
++}
++
++void xglLightiv ( GLenum light, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glLightiv") )
++    fprintf ( xglTraceFd, "  glLightiv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) light ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glLightiv") )
++    glLightiv ( light, pname, params ) ;
++}
++
++void xglLineStipple ( GLint factor, GLushort pattern )
++{
++  if ( xglTraceIsEnabled("glLineStipple") )
++    fprintf ( xglTraceFd, "  glLineStipple ( (GLint)%d, (GLushort)%u ) ;\n" , factor, pattern ) ;
++  if ( xglExecuteIsEnabled("glLineStipple") )
++    glLineStipple ( factor, pattern ) ;
++}
++
++void xglLineWidth ( GLfloat width )
++{
++  if ( xglTraceIsEnabled("glLineWidth") )
++    fprintf ( xglTraceFd, "  glLineWidth ( (GLfloat)%ff ) ;\n" , width ) ;
++  if ( xglExecuteIsEnabled("glLineWidth") )
++    glLineWidth ( width ) ;
++}
++
++void xglListBase ( GLuint base )
++{
++  if ( xglTraceIsEnabled("glListBase") )
++    fprintf ( xglTraceFd, "  glListBase ( (GLuint)%u ) ;\n" , base ) ;
++  if ( xglExecuteIsEnabled("glListBase") )
++    glListBase ( base ) ;
++}
++
++void xglLoadIdentity (  )
++{
++  if ( xglTraceIsEnabled("glLoadIdentity") )
++    fprintf ( xglTraceFd, "  glLoadIdentity (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glLoadIdentity") )
++    glLoadIdentity (  ) ;
++}
++
++void xglLoadMatrixd ( GLdouble* m )
++{
++  if ( xglTraceIsEnabled("glLoadMatrixd") )
++  {
++    fprintf ( xglTraceFd, "  glLoadMatrixd ( xglBuildMatrixd(%f,%f,%f,%f,\n"    , m[ 0],m[ 1],m[ 2],m[ 3] ) ;
++    fprintf ( xglTraceFd, "                                  %f,%f,%f,%f,\n"    , m[ 4],m[ 5],m[ 6],m[ 7] ) ;
++    fprintf ( xglTraceFd, "                                  %f,%f,%f,%f,\n"    , m[ 8],m[ 9],m[10],m[11] ) ;
++    fprintf ( xglTraceFd, "                                  %f,%f,%f,%f) ) ;\n", m[12],m[13],m[14],m[15] ) ;
++  }
++
++  if ( xglExecuteIsEnabled("glLoadMatrixd") )
++    glLoadMatrixd ( m ) ;
++}
++
++void xglLoadMatrixf ( GLfloat* m )
++{
++  if ( xglTraceIsEnabled("glLoadMatrixf") )
++  {
++    fprintf ( xglTraceFd, "  glLoadMatrixf ( xglBuildMatrixf(%ff,%ff,%ff,%ff,\n"    , m[ 0],m[ 1],m[ 2],m[ 3] ) ;
++    fprintf ( xglTraceFd, "                                  %ff,%ff,%ff,%ff,\n"    , m[ 4],m[ 5],m[ 6],m[ 7] ) ;
++    fprintf ( xglTraceFd, "                                  %ff,%ff,%ff,%ff,\n"    , m[ 8],m[ 9],m[10],m[11] ) ;
++    fprintf ( xglTraceFd, "                                  %ff,%ff,%ff,%ff) ) ;\n", m[12],m[13],m[14],m[15] ) ;
++  }
++
++  if ( xglExecuteIsEnabled("glLoadMatrixf") )
++    glLoadMatrixf ( m ) ;
++}
++
++void xglLoadName ( GLuint name )
++{
++  if ( xglTraceIsEnabled("glLoadName") )
++    fprintf ( xglTraceFd, "  glLoadName ( (GLuint)%u ) ;\n" , name ) ;
++  if ( xglExecuteIsEnabled("glLoadName") )
++    glLoadName ( name ) ;
++}
++
++void xglLogicOp ( GLenum opcode )
++{
++  if ( xglTraceIsEnabled("glLogicOp") )
++    fprintf ( xglTraceFd, "  glLogicOp ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) opcode ) ) ;
++  if ( xglExecuteIsEnabled("glLogicOp") )
++    glLogicOp ( opcode ) ;
++}
++
++void xglMap1d ( GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, GLdouble* points )
++{
++  if ( xglTraceIsEnabled("glMap1d") )
++    fprintf ( xglTraceFd, "  glMap1d ( (GLenum)%s, (GLdouble)%f, (GLdouble)%f, (GLint)%d, (GLint)%d, (GLdouble *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), u1, u2, stride, order, points ) ;
++  if ( xglExecuteIsEnabled("glMap1d") )
++    glMap1d ( target, u1, u2, stride, order, points ) ;
++}
++
++void xglMap1f ( GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, GLfloat* points )
++{
++  if ( xglTraceIsEnabled("glMap1f") )
++    fprintf ( xglTraceFd, "  glMap1f ( (GLenum)%s, (GLfloat)%ff, (GLfloat)%ff, (GLint)%d, (GLint)%d, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), u1, u2, stride, order, points ) ;
++  if ( xglExecuteIsEnabled("glMap1f") )
++    glMap1f ( target, u1, u2, stride, order, points ) ;
++}
++
++void xglMap2d ( GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, GLdouble* points )
++{
++  if ( xglTraceIsEnabled("glMap2d") )
++    fprintf ( xglTraceFd, "  glMap2d ( (GLenum)%s, (GLdouble)%f, (GLdouble)%f, (GLint)%d, (GLint)%d, (GLdouble)%f, (GLdouble)%f, (GLint)%d, (GLint)%d, (GLdouble *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ) ;
++  if ( xglExecuteIsEnabled("glMap2d") )
++    glMap2d ( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ) ;
++}
++
++void xglMap2f ( GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, GLfloat* points )
++{
++  if ( xglTraceIsEnabled("glMap2f") )
++    fprintf ( xglTraceFd, "  glMap2f ( (GLenum)%s, (GLfloat)%ff, (GLfloat)%ff, (GLint)%d, (GLint)%d, (GLfloat)%ff, (GLfloat)%ff, (GLint)%d, (GLint)%d, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ) ;
++  if ( xglExecuteIsEnabled("glMap2f") )
++    glMap2f ( target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points ) ;
++}
++
++void xglMapGrid1d ( GLint un, GLdouble u1, GLdouble u2 )
++{
++  if ( xglTraceIsEnabled("glMapGrid1d") )
++    fprintf ( xglTraceFd, "  glMapGrid1d ( (GLint)%d, (GLdouble)%f, (GLdouble)%f ) ;\n" , un, u1, u2 ) ;
++  if ( xglExecuteIsEnabled("glMapGrid1d") )
++    glMapGrid1d ( un, u1, u2 ) ;
++}
++
++void xglMapGrid1f ( GLint un, GLfloat u1, GLfloat u2 )
++{
++  if ( xglTraceIsEnabled("glMapGrid1f") )
++    fprintf ( xglTraceFd, "  glMapGrid1f ( (GLint)%d, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , un, u1, u2 ) ;
++  if ( xglExecuteIsEnabled("glMapGrid1f") )
++    glMapGrid1f ( un, u1, u2 ) ;
++}
++
++void xglMapGrid2d ( GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2 )
++{
++  if ( xglTraceIsEnabled("glMapGrid2d") )
++    fprintf ( xglTraceFd, "  glMapGrid2d ( (GLint)%d, (GLdouble)%f, (GLdouble)%f, (GLint)%d, (GLdouble)%f, (GLdouble)%f ) ;\n" , un, u1, u2, vn, v1, v2 ) ;
++  if ( xglExecuteIsEnabled("glMapGrid2d") )
++    glMapGrid2d ( un, u1, u2, vn, v1, v2 ) ;
++}
++
++void xglMapGrid2f ( GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2 )
++{
++  if ( xglTraceIsEnabled("glMapGrid2f") )
++    fprintf ( xglTraceFd, "  glMapGrid2f ( (GLint)%d, (GLfloat)%ff, (GLfloat)%ff, (GLint)%d, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , un, u1, u2, vn, v1, v2 ) ;
++  if ( xglExecuteIsEnabled("glMapGrid2f") )
++    glMapGrid2f ( un, u1, u2, vn, v1, v2 ) ;
++}
++
++void xglMaterialf ( GLenum face, GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glMaterialf") )
++    fprintf ( xglTraceFd, "  glMaterialf ( (GLenum)%s, (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glMaterialf") )
++    glMaterialf ( face, pname, param ) ;
++}
++
++void xglMaterialfv ( GLenum face, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glMaterialfv") )
++    fprintf ( xglTraceFd, "  glMaterialfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glMaterialfv") )
++    glMaterialfv ( face, pname, params ) ;
++}
++
++void xglMateriali ( GLenum face, GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glMateriali") )
++    fprintf ( xglTraceFd, "  glMateriali ( (GLenum)%s, (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glMateriali") )
++    glMateriali ( face, pname, param ) ;
++}
++
++void xglMaterialiv ( GLenum face, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glMaterialiv") )
++    fprintf ( xglTraceFd, "  glMaterialiv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glMaterialiv") )
++    glMaterialiv ( face, pname, params ) ;
++}
++
++void xglMatrixMode ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glMatrixMode") )
++    fprintf ( xglTraceFd, "  glMatrixMode ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glMatrixMode") )
++    glMatrixMode ( mode ) ;
++}
++
++
++void xglMultMatrixd ( GLdouble* m )
++{
++  if ( xglTraceIsEnabled("glMultMatrixd") )
++  {
++    fprintf ( xglTraceFd, "  glMultMatrixd ( xglBuildMatrixd(%f,%f,%f,%f,\n"    , m[ 0],m[ 1],m[ 2],m[ 3] ) ;
++    fprintf ( xglTraceFd, "                                  %f,%f,%f,%f,\n"    , m[ 4],m[ 5],m[ 6],m[ 7] ) ;
++    fprintf ( xglTraceFd, "                                  %f,%f,%f,%f,\n"    , m[ 8],m[ 9],m[10],m[11] ) ;
++    fprintf ( xglTraceFd, "                                  %f,%f,%f,%f) ) ;\n", m[12],m[13],m[14],m[15] ) ;
++  }
++
++  if ( xglExecuteIsEnabled("glMultMatrixd") )
++    glMultMatrixd ( m ) ;
++}
++
++void xglMultMatrixf ( GLfloat* m )
++{
++  if ( xglTraceIsEnabled("glMultMatrixf") )
++  {
++    fprintf ( xglTraceFd, "  glMultMatrixf ( xglBuildMatrixf(%ff,%ff,%ff,%ff,\n"    , m[ 0],m[ 1],m[ 2],m[ 3] ) ;
++    fprintf ( xglTraceFd, "                                  %ff,%ff,%ff,%ff,\n"    , m[ 4],m[ 5],m[ 6],m[ 7] ) ;
++    fprintf ( xglTraceFd, "                                  %ff,%ff,%ff,%ff,\n"    , m[ 8],m[ 9],m[10],m[11] ) ;
++    fprintf ( xglTraceFd, "                                  %ff,%ff,%ff,%ff) ) ;\n", m[12],m[13],m[14],m[15] ) ;
++  }
++
++  if ( xglExecuteIsEnabled("glMultMatrixf") )
++    glMultMatrixf ( m ) ;
++}
++
++void xglNewList ( GLuint list, GLenum mode )
++{
++  if ( xglTraceIsEnabled("glNewList") )
++    fprintf ( xglTraceFd, "  glNewList ( (GLuint)%u, (GLenum)%s ) ;\n" , list, xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glNewList") )
++    glNewList ( list, mode ) ;
++}
++
++void xglNormal3b ( GLbyte nx, GLbyte ny, GLbyte nz )
++{
++  if ( xglTraceIsEnabled("glNormal3b") )
++    fprintf ( xglTraceFd, "  glNormal3b ( (GLbyte)%d, (GLbyte)%d, (GLbyte)%d ) ;\n" , nx, ny, nz ) ;
++  if ( xglExecuteIsEnabled("glNormal3b") )
++    glNormal3b ( nx, ny, nz ) ;
++}
++
++void xglNormal3bv ( GLbyte* v )
++{
++  if ( xglTraceIsEnabled("glNormal3bv") )
++    fprintf ( xglTraceFd, "  glNormal3bv ( xglBuild3bv((GLbyte)%d,(GLbyte)%d,(GLbyte)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glNormal3bv") )
++    glNormal3bv ( v ) ;
++}
++
++void xglNormal3d ( GLdouble nx, GLdouble ny, GLdouble nz )
++{
++  if ( xglTraceIsEnabled("glNormal3d") )
++    fprintf ( xglTraceFd, "  glNormal3d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , nx, ny, nz ) ;
++  if ( xglExecuteIsEnabled("glNormal3d") )
++    glNormal3d ( nx, ny, nz ) ;
++}
++
++void xglNormal3dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glNormal3dv") )
++    fprintf ( xglTraceFd, "  glNormal3dv ( xglBuild3dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glNormal3dv") )
++    glNormal3dv ( v ) ;
++}
++
++void xglNormal3f ( GLfloat nx, GLfloat ny, GLfloat nz )
++{
++  if ( xglTraceIsEnabled("glNormal3f") )
++    fprintf ( xglTraceFd, "  glNormal3f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , nx, ny, nz ) ;
++  if ( xglExecuteIsEnabled("glNormal3f") )
++    glNormal3f ( nx, ny, nz ) ;
++}
++
++void xglNormal3fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glNormal3fv") )
++    fprintf ( xglTraceFd, "  glNormal3fv ( xglBuild3fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glNormal3fv") )
++    glNormal3fv ( v ) ;
++}
++
++void xglNormal3i ( GLint nx, GLint ny, GLint nz )
++{
++  if ( xglTraceIsEnabled("glNormal3i") )
++    fprintf ( xglTraceFd, "  glNormal3i ( (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , nx, ny, nz ) ;
++  if ( xglExecuteIsEnabled("glNormal3i") )
++    glNormal3i ( nx, ny, nz ) ;
++}
++
++void xglNormal3iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glNormal3iv") )
++    fprintf ( xglTraceFd, "  glNormal3iv ( xglBuild3iv((GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glNormal3iv") )
++    glNormal3iv ( v ) ;
++}
++
++void xglNormal3s ( GLshort nx, GLshort ny, GLshort nz )
++{
++  if ( xglTraceIsEnabled("glNormal3s") )
++    fprintf ( xglTraceFd, "  glNormal3s ( (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , nx, ny, nz ) ;
++  if ( xglExecuteIsEnabled("glNormal3s") )
++    glNormal3s ( nx, ny, nz ) ;
++}
++
++void xglNormal3sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glNormal3sv") )
++    fprintf ( xglTraceFd, "  glNormal3sv ( xglBuild3sv((GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glNormal3sv") )
++    glNormal3sv ( v ) ;
++}
++
++void xglNormalPointerEXT ( GLenum type, GLsizei stride, GLsizei count, void* ptr )
++{
++  if ( xglTraceIsEnabled("glNormalPointerEXT") )
++    fprintf ( xglTraceFd, "  glNormalPointerEXT ( (GLenum)%s, (GLsizei)%d, (GLsizei)%d, (void *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) type ), stride, count, ptr ) ;
++#ifdef GL_VERSION_1_1
++    glNormalPointer ( type, stride, ptr ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glNormalPointerEXT") )
++    glNormalPointerEXT ( type, stride, count, ptr ) ;
++#else
++  fprintf ( xglTraceFd, "  glNormalPointerEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglOrtho ( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val )
++{
++  if ( xglTraceIsEnabled("glOrtho") )
++    fprintf ( xglTraceFd, "  glOrtho ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , left, right, bottom, top, near_val, far_val ) ;
++  if ( xglExecuteIsEnabled("glOrtho") )
++    glOrtho ( left, right, bottom, top, near_val, far_val ) ;
++}
++
++void xglPassThrough ( GLfloat token )
++{
++  if ( xglTraceIsEnabled("glPassThrough") )
++    fprintf ( xglTraceFd, "  glPassThrough ( (GLfloat)%ff ) ;\n" , token ) ;
++  if ( xglExecuteIsEnabled("glPassThrough") )
++    glPassThrough ( token ) ;
++}
++
++void xglPixelMapfv ( GLenum map, GLint mapsize, GLfloat* values )
++{
++  if ( xglTraceIsEnabled("glPixelMapfv") )
++    fprintf ( xglTraceFd, "  glPixelMapfv ( (GLenum)%s, (GLint)%d, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) map ), mapsize, values ) ;
++  if ( xglExecuteIsEnabled("glPixelMapfv") )
++    glPixelMapfv ( map, mapsize, values ) ;
++}
++
++void xglPixelMapuiv ( GLenum map, GLint mapsize, GLuint* values )
++{
++  if ( xglTraceIsEnabled("glPixelMapuiv") )
++    fprintf ( xglTraceFd, "  glPixelMapuiv ( (GLenum)%s, (GLint)%d, (GLuint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) map ), mapsize, values ) ;
++  if ( xglExecuteIsEnabled("glPixelMapuiv") )
++    glPixelMapuiv ( map, mapsize, values ) ;
++}
++
++void xglPixelMapusv ( GLenum map, GLint mapsize, GLushort* values )
++{
++  if ( xglTraceIsEnabled("glPixelMapusv") )
++    fprintf ( xglTraceFd, "  glPixelMapusv ( (GLenum)%s, (GLint)%d, (GLushort *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) map ), mapsize, values ) ;
++  if ( xglExecuteIsEnabled("glPixelMapusv") )
++    glPixelMapusv ( map, mapsize, values ) ;
++}
++
++void xglPixelStoref ( GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glPixelStoref") )
++    fprintf ( xglTraceFd, "  glPixelStoref ( (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glPixelStoref") )
++    glPixelStoref ( pname, param ) ;
++}
++
++void xglPixelStorei ( GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glPixelStorei") )
++    fprintf ( xglTraceFd, "  glPixelStorei ( (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glPixelStorei") )
++    glPixelStorei ( pname, param ) ;
++}
++
++void xglPixelTransferf ( GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glPixelTransferf") )
++    fprintf ( xglTraceFd, "  glPixelTransferf ( (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glPixelTransferf") )
++    glPixelTransferf ( pname, param ) ;
++}
++
++void xglPixelTransferi ( GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glPixelTransferi") )
++    fprintf ( xglTraceFd, "  glPixelTransferi ( (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glPixelTransferi") )
++    glPixelTransferi ( pname, param ) ;
++}
++
++void xglPixelZoom ( GLfloat xfactor, GLfloat yfactor )
++{
++  if ( xglTraceIsEnabled("glPixelZoom") )
++    fprintf ( xglTraceFd, "  glPixelZoom ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , xfactor, yfactor ) ;
++  if ( xglExecuteIsEnabled("glPixelZoom") )
++    glPixelZoom ( xfactor, yfactor ) ;
++}
++
++void xglPointSize ( GLfloat size )
++{
++  if ( xglTraceIsEnabled("glPointSize") )
++    fprintf ( xglTraceFd, "  glPointSize ( (GLfloat)%ff ) ;\n" , size ) ;
++  if ( xglExecuteIsEnabled("glPointSize") )
++    glPointSize ( size ) ;
++}
++
++void xglPolygonMode ( GLenum face, GLenum mode )
++{
++  if ( xglTraceIsEnabled("glPolygonMode") )
++    fprintf ( xglTraceFd, "  glPolygonMode ( (GLenum)%s, (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) face ), xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glPolygonMode") )
++    glPolygonMode ( face, mode ) ;
++}
++
++void xglPolygonOffsetEXT ( GLfloat factor, GLfloat bias )
++{
++  if ( xglTraceIsEnabled("glPolygonOffsetEXT") )
++    fprintf ( xglTraceFd, "  glPolygonOffsetEXT ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , factor, bias ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glPolygonOffsetEXT") )
++    glPolygonOffset ( factor, bias ) ;
++#else
++#ifdef GL_EXT_polygon_offset
++  if ( xglExecuteIsEnabled("glPolygonOffsetEXT") )
++    glPolygonOffsetEXT ( factor, bias ) ;
++#else
++  fprintf ( xglTraceFd, "  glPolygonOffsetEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglPolygonOffset ( GLfloat factor, GLfloat bias )
++{
++  if ( xglTraceIsEnabled("glPolygonOffset") )
++    fprintf ( xglTraceFd, "  glPolygonOffset ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , factor, bias ) ;
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glPolygonOffset") )
++    glPolygonOffset ( factor, bias ) ;
++#else
++#ifdef GL_EXT_polygon_offset
++  if ( xglExecuteIsEnabled("glPolygonOffset") )
++    glPolygonOffsetEXT ( factor, bias ) ;
++#else
++  fprintf ( xglTraceFd, "  glPolygonOffsetEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglPolygonStipple ( GLubyte* mask )
++{
++  if ( xglTraceIsEnabled("glPolygonStipple") )
++    fprintf ( xglTraceFd, "  glPolygonStipple ( (GLubyte *)0x%08x ) ;\n" , mask ) ;
++  if ( xglExecuteIsEnabled("glPolygonStipple") )
++    glPolygonStipple ( mask ) ;
++}
++
++void xglPopAttrib (  )
++{
++  if ( xglTraceIsEnabled("glPopAttrib") )
++    fprintf ( xglTraceFd, "  glPopAttrib (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glPopAttrib") )
++    glPopAttrib (  ) ;
++}
++
++void xglPopMatrix (  )
++{
++  if ( xglTraceIsEnabled("glPopMatrix") )
++    fprintf ( xglTraceFd, "  glPopMatrix (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glPopMatrix") )
++    glPopMatrix (  ) ;
++}
++
++void xglPopName (  )
++{
++  if ( xglTraceIsEnabled("glPopName") )
++    fprintf ( xglTraceFd, "  glPopName (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glPopName") )
++    glPopName (  ) ;
++}
++
++void xglPushAttrib ( GLbitfield mask )
++{
++  if ( xglTraceIsEnabled("glPushAttrib") )
++    fprintf ( xglTraceFd, "  glPushAttrib ( (GLbitfield)0x%08x ) ;\n" , mask ) ;
++  if ( xglExecuteIsEnabled("glPushAttrib") )
++    glPushAttrib ( mask ) ;
++}
++
++void xglPushMatrix (  )
++{
++  if ( xglTraceIsEnabled("glPushMatrix") )
++    fprintf ( xglTraceFd, "  glPushMatrix (  ) ;\n"  ) ;
++  if ( xglExecuteIsEnabled("glPushMatrix") )
++    glPushMatrix (  ) ;
++}
++
++void xglPushName ( GLuint name )
++{
++  if ( xglTraceIsEnabled("glPushName") )
++    fprintf ( xglTraceFd, "  glPushName ( (GLuint)%u ) ;\n" , name ) ;
++  if ( xglExecuteIsEnabled("glPushName") )
++    glPushName ( name ) ;
++}
++
++void xglRasterPos2d ( GLdouble x, GLdouble y )
++{
++  if ( xglTraceIsEnabled("glRasterPos2d") )
++    fprintf ( xglTraceFd, "  glRasterPos2d ( (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2d") )
++    glRasterPos2d ( x, y ) ;
++}
++
++void xglRasterPos2dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos2dv") )
++    fprintf ( xglTraceFd, "  glRasterPos2dv ( xglBuild2dv((GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2dv") )
++    glRasterPos2dv ( v ) ;
++}
++
++void xglRasterPos2f ( GLfloat x, GLfloat y )
++{
++  if ( xglTraceIsEnabled("glRasterPos2f") )
++    fprintf ( xglTraceFd, "  glRasterPos2f ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2f") )
++    glRasterPos2f ( x, y ) ;
++}
++
++void xglRasterPos2fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos2fv") )
++    fprintf ( xglTraceFd, "  glRasterPos2fv ( xglBuild2fv((GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2fv") )
++    glRasterPos2fv ( v ) ;
++}
++
++void xglRasterPos2i ( GLint x, GLint y )
++{
++  if ( xglTraceIsEnabled("glRasterPos2i") )
++    fprintf ( xglTraceFd, "  glRasterPos2i ( (GLint)%d, (GLint)%d ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2i") )
++    glRasterPos2i ( x, y ) ;
++}
++
++void xglRasterPos2iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos2iv") )
++    fprintf ( xglTraceFd, "  glRasterPos2iv ( xglBuild2iv((GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2iv") )
++    glRasterPos2iv ( v ) ;
++}
++
++void xglRasterPos2s ( GLshort x, GLshort y )
++{
++  if ( xglTraceIsEnabled("glRasterPos2s") )
++    fprintf ( xglTraceFd, "  glRasterPos2s ( (GLshort)%d, (GLshort)%d ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2s") )
++    glRasterPos2s ( x, y ) ;
++}
++
++void xglRasterPos2sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos2sv") )
++    fprintf ( xglTraceFd, "  glRasterPos2sv ( xglBuild2sv((GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos2sv") )
++    glRasterPos2sv ( v ) ;
++}
++
++void xglRasterPos3d ( GLdouble x, GLdouble y, GLdouble z )
++{
++  if ( xglTraceIsEnabled("glRasterPos3d") )
++    fprintf ( xglTraceFd, "  glRasterPos3d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3d") )
++    glRasterPos3d ( x, y, z ) ;
++}
++
++void xglRasterPos3dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos3dv") )
++    fprintf ( xglTraceFd, "  glRasterPos3dv ( xglBuild3dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3dv") )
++    glRasterPos3dv ( v ) ;
++}
++
++void xglRasterPos3f ( GLfloat x, GLfloat y, GLfloat z )
++{
++  if ( xglTraceIsEnabled("glRasterPos3f") )
++    fprintf ( xglTraceFd, "  glRasterPos3f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3f") )
++    glRasterPos3f ( x, y, z ) ;
++}
++
++void xglRasterPos3fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos3fv") )
++    fprintf ( xglTraceFd, "  glRasterPos3fv ( xglBuild3fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3fv") )
++    glRasterPos3fv ( v ) ;
++}
++
++void xglRasterPos3i ( GLint x, GLint y, GLint z )
++{
++  if ( xglTraceIsEnabled("glRasterPos3i") )
++    fprintf ( xglTraceFd, "  glRasterPos3i ( (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3i") )
++    glRasterPos3i ( x, y, z ) ;
++}
++
++void xglRasterPos3iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos3iv") )
++    fprintf ( xglTraceFd, "  glRasterPos3iv ( xglBuild3iv((GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3iv") )
++    glRasterPos3iv ( v ) ;
++}
++
++void xglRasterPos3s ( GLshort x, GLshort y, GLshort z )
++{
++  if ( xglTraceIsEnabled("glRasterPos3s") )
++    fprintf ( xglTraceFd, "  glRasterPos3s ( (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3s") )
++    glRasterPos3s ( x, y, z ) ;
++}
++
++void xglRasterPos3sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos3sv") )
++    fprintf ( xglTraceFd, "  glRasterPos3sv ( xglBuild3sv((GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos3sv") )
++    glRasterPos3sv ( v ) ;
++}
++
++void xglRasterPos4d ( GLdouble x, GLdouble y, GLdouble z, GLdouble w )
++{
++  if ( xglTraceIsEnabled("glRasterPos4d") )
++    fprintf ( xglTraceFd, "  glRasterPos4d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4d") )
++    glRasterPos4d ( x, y, z, w ) ;
++}
++
++void xglRasterPos4dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos4dv") )
++    fprintf ( xglTraceFd, "  glRasterPos4dv ( xglBuild4dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4dv") )
++    glRasterPos4dv ( v ) ;
++}
++
++void xglRasterPos4f ( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
++{
++  if ( xglTraceIsEnabled("glRasterPos4f") )
++    fprintf ( xglTraceFd, "  glRasterPos4f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4f") )
++    glRasterPos4f ( x, y, z, w ) ;
++}
++
++void xglRasterPos4fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos4fv") )
++    fprintf ( xglTraceFd, "  glRasterPos4fv ( xglBuild4fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4fv") )
++    glRasterPos4fv ( v ) ;
++}
++
++void xglRasterPos4i ( GLint x, GLint y, GLint z, GLint w )
++{
++  if ( xglTraceIsEnabled("glRasterPos4i") )
++    fprintf ( xglTraceFd, "  glRasterPos4i ( (GLint)%d, (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4i") )
++    glRasterPos4i ( x, y, z, w ) ;
++}
++
++void xglRasterPos4iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos4iv") )
++    fprintf ( xglTraceFd, "  glRasterPos4iv ( xglBuild4iv((GLint)%d,(GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4iv") )
++    glRasterPos4iv ( v ) ;
++}
++
++void xglRasterPos4s ( GLshort x, GLshort y, GLshort z, GLshort w )
++{
++  if ( xglTraceIsEnabled("glRasterPos4s") )
++    fprintf ( xglTraceFd, "  glRasterPos4s ( (GLshort)%d, (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4s") )
++    glRasterPos4s ( x, y, z, w ) ;
++}
++
++void xglRasterPos4sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glRasterPos4sv") )
++    fprintf ( xglTraceFd, "  glRasterPos4sv ( xglBuild4sv((GLshort)%d,(GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glRasterPos4sv") )
++    glRasterPos4sv ( v ) ;
++}
++
++void xglReadBuffer ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glReadBuffer") )
++    fprintf ( xglTraceFd, "  glReadBuffer ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glReadBuffer") )
++    glReadBuffer ( mode ) ;
++}
++
++void xglReadPixels ( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels )
++{
++  if ( xglTraceIsEnabled("glReadPixels") )
++    fprintf ( xglTraceFd, "  glReadPixels ( (GLint)%d, (GLint)%d, (GLsizei)%d, (GLsizei)%d, (GLenum)%s, (GLenum)%s, (GLvoid *)0x%08x ) ;\n" , x, y, width, height, xglExpandGLenum ( (GLenum) format ), xglExpandGLenum ( (GLenum) type ), pixels ) ;
++  if ( xglExecuteIsEnabled("glReadPixels") )
++    glReadPixels ( x, y, width, height, format, type, pixels ) ;
++}
++
++void xglRectd ( GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2 )
++{
++  if ( xglTraceIsEnabled("glRectd") )
++    fprintf ( xglTraceFd, "  glRectd ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x1, y1, x2, y2 ) ;
++  if ( xglExecuteIsEnabled("glRectd") )
++    glRectd ( x1, y1, x2, y2 ) ;
++}
++
++void xglRectdv ( GLdouble* v1, GLdouble* v2 )
++{
++  if ( xglTraceIsEnabled("glRectdv") )
++    fprintf ( xglTraceFd, "  glRectdv ( (GLdouble *)0x%08x, (GLdouble *)0x%08x ) ;\n" , v1, v2 ) ;
++  if ( xglExecuteIsEnabled("glRectdv") )
++    glRectdv ( v1, v2 ) ;
++}
++
++void xglRectf ( GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 )
++{
++  if ( xglTraceIsEnabled("glRectf") )
++    fprintf ( xglTraceFd, "  glRectf ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x1, y1, x2, y2 ) ;
++  if ( xglExecuteIsEnabled("glRectf") )
++    glRectf ( x1, y1, x2, y2 ) ;
++}
++
++void xglRectfv ( GLfloat* v1, GLfloat* v2 )
++{
++  if ( xglTraceIsEnabled("glRectfv") )
++    fprintf ( xglTraceFd, "  glRectfv ( (GLfloat *)0x%08x, (GLfloat *)0x%08x ) ;\n" , v1, v2 ) ;
++  if ( xglExecuteIsEnabled("glRectfv") )
++    glRectfv ( v1, v2 ) ;
++}
++
++void xglRecti ( GLint x1, GLint y1, GLint x2, GLint y2 )
++{
++  if ( xglTraceIsEnabled("glRecti") )
++    fprintf ( xglTraceFd, "  glRecti ( (GLint)%d, (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , x1, y1, x2, y2 ) ;
++  if ( xglExecuteIsEnabled("glRecti") )
++    glRecti ( x1, y1, x2, y2 ) ;
++}
++
++void xglRectiv ( GLint* v1, GLint* v2 )
++{
++  if ( xglTraceIsEnabled("glRectiv") )
++    fprintf ( xglTraceFd, "  glRectiv ( (GLint *)0x%08x, (GLint *)0x%08x ) ;\n" , v1, v2 ) ;
++  if ( xglExecuteIsEnabled("glRectiv") )
++    glRectiv ( v1, v2 ) ;
++}
++
++void xglRects ( GLshort x1, GLshort y1, GLshort x2, GLshort y2 )
++{
++  if ( xglTraceIsEnabled("glRects") )
++    fprintf ( xglTraceFd, "  glRects ( (GLshort)%d, (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , x1, y1, x2, y2 ) ;
++  if ( xglExecuteIsEnabled("glRects") )
++    glRects ( x1, y1, x2, y2 ) ;
++}
++
++void xglRectsv ( GLshort* v1, GLshort* v2 )
++{
++  if ( xglTraceIsEnabled("glRectsv") )
++    fprintf ( xglTraceFd, "  glRectsv ( (GLshort *)0x%08x, (GLshort *)0x%08x ) ;\n" , v1, v2 ) ;
++  if ( xglExecuteIsEnabled("glRectsv") )
++    glRectsv ( v1, v2 ) ;
++}
++
++void xglRotated ( GLdouble angle, GLdouble x, GLdouble y, GLdouble z )
++{
++  if ( xglTraceIsEnabled("glRotated") )
++    fprintf ( xglTraceFd, "  glRotated ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , angle, x, y, z ) ;
++  if ( xglExecuteIsEnabled("glRotated") )
++    glRotated ( angle, x, y, z ) ;
++}
++
++void xglRotatef ( GLfloat angle, GLfloat x, GLfloat y, GLfloat z )
++{
++  if ( xglTraceIsEnabled("glRotatef") )
++    fprintf ( xglTraceFd, "  glRotatef ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , angle, x, y, z ) ;
++  if ( xglExecuteIsEnabled("glRotatef") )
++    glRotatef ( angle, x, y, z ) ;
++}
++
++void xglScaled ( GLdouble x, GLdouble y, GLdouble z )
++{
++  if ( xglTraceIsEnabled("glScaled") )
++    fprintf ( xglTraceFd, "  glScaled ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glScaled") )
++    glScaled ( x, y, z ) ;
++}
++
++void xglScalef ( GLfloat x, GLfloat y, GLfloat z )
++{
++  if ( xglTraceIsEnabled("glScalef") )
++    fprintf ( xglTraceFd, "  glScalef ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glScalef") )
++    glScalef ( x, y, z ) ;
++}
++
++void xglScissor ( GLint x, GLint y, GLsizei width, GLsizei height )
++{
++  if ( xglTraceIsEnabled("glScissor") )
++    fprintf ( xglTraceFd, "  glScissor ( (GLint)%d, (GLint)%d, (GLsizei)%d, (GLsizei)%d ) ;\n" , x, y, width, height ) ;
++  if ( xglExecuteIsEnabled("glScissor") )
++    glScissor ( x, y, width, height ) ;
++}
++
++void xglSelectBuffer ( GLsizei size, GLuint* buffer )
++{
++  if ( xglTraceIsEnabled("glSelectBuffer") )
++    fprintf ( xglTraceFd, "  glSelectBuffer ( (GLsizei)%d, (GLuint *)0x%08x ) ;\n" , size, buffer ) ;
++  if ( xglExecuteIsEnabled("glSelectBuffer") )
++    glSelectBuffer ( size, buffer ) ;
++}
++
++void xglShadeModel ( GLenum mode )
++{
++  if ( xglTraceIsEnabled("glShadeModel") )
++    fprintf ( xglTraceFd, "  glShadeModel ( (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) mode ) ) ;
++  if ( xglExecuteIsEnabled("glShadeModel") )
++    glShadeModel ( mode ) ;
++}
++
++void xglStencilFunc ( GLenum func, GLint ref, GLuint mask )
++{
++  if ( xglTraceIsEnabled("glStencilFunc") )
++    fprintf ( xglTraceFd, "  glStencilFunc ( (GLenum)%s, (GLint)%d, (GLuint)%u ) ;\n" , xglExpandGLenum ( (GLenum) func ), ref, mask ) ;
++  if ( xglExecuteIsEnabled("glStencilFunc") )
++    glStencilFunc ( func, ref, mask ) ;
++}
++
++void xglStencilMask ( GLuint mask )
++{
++  if ( xglTraceIsEnabled("glStencilMask") )
++    fprintf ( xglTraceFd, "  glStencilMask ( (GLuint)%u ) ;\n" , mask ) ;
++  if ( xglExecuteIsEnabled("glStencilMask") )
++    glStencilMask ( mask ) ;
++}
++
++void xglStencilOp ( GLenum fail, GLenum zfail, GLenum zpass )
++{
++  if ( xglTraceIsEnabled("glStencilOp") )
++    fprintf ( xglTraceFd, "  glStencilOp ( (GLenum)%s, (GLenum)%s, (GLenum)%s ) ;\n" , xglExpandGLenum ( (GLenum) fail ), xglExpandGLenum ( (GLenum) zfail ), xglExpandGLenum ( (GLenum) zpass ) ) ;
++  if ( xglExecuteIsEnabled("glStencilOp") )
++    glStencilOp ( fail, zfail, zpass ) ;
++}
++
++void xglTexCoord1d ( GLdouble s )
++{
++  if ( xglTraceIsEnabled("glTexCoord1d") )
++    fprintf ( xglTraceFd, "  glTexCoord1d ( (GLdouble)%f ) ;\n" , s ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1d") )
++    glTexCoord1d ( s ) ;
++}
++
++void xglTexCoord1dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord1dv") )
++    fprintf ( xglTraceFd, "  glTexCoord1dv ( xglBuild1dv((GLdouble)%f) ) ;\n" , v[0] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1dv") )
++    glTexCoord1dv ( v ) ;
++}
++
++void xglTexCoord1f ( GLfloat s )
++{
++  if ( xglTraceIsEnabled("glTexCoord1f") )
++    fprintf ( xglTraceFd, "  glTexCoord1f ( (GLfloat)%ff ) ;\n" , s ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1f") )
++    glTexCoord1f ( s ) ;
++}
++
++void xglTexCoord1fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord1fv") )
++    fprintf ( xglTraceFd, "  glTexCoord1fv ( xglBuild1fv((GLfloat)%ff) ) ;\n" , v[0] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1fv") )
++    glTexCoord1fv ( v ) ;
++}
++
++void xglTexCoord1i ( GLint s )
++{
++  if ( xglTraceIsEnabled("glTexCoord1i") )
++    fprintf ( xglTraceFd, "  glTexCoord1i ( (GLint)%d ) ;\n" , s ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1i") )
++    glTexCoord1i ( s ) ;
++}
++
++void xglTexCoord1iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord1iv") )
++    fprintf ( xglTraceFd, "  glTexCoord1iv ( xglBuild1iv((GLint)%d) ) ;\n" , v[0] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1iv") )
++    glTexCoord1iv ( v ) ;
++}
++
++void xglTexCoord1s ( GLshort s )
++{
++  if ( xglTraceIsEnabled("glTexCoord1s") )
++    fprintf ( xglTraceFd, "  glTexCoord1s ( (GLshort)%d ) ;\n" , s ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1s") )
++    glTexCoord1s ( s ) ;
++}
++
++void xglTexCoord1sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord1sv") )
++    fprintf ( xglTraceFd, "  glTexCoord1sv ( xglBuild1sv((GLshort)%d) ) ;\n" , v[0] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord1sv") )
++    glTexCoord1sv ( v ) ;
++}
++
++void xglTexCoord2d ( GLdouble s, GLdouble t )
++{
++  if ( xglTraceIsEnabled("glTexCoord2d") )
++    fprintf ( xglTraceFd, "  glTexCoord2d ( (GLdouble)%f, (GLdouble)%f ) ;\n" , s, t ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2d") )
++    glTexCoord2d ( s, t ) ;
++}
++
++void xglTexCoord2dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord2dv") )
++    fprintf ( xglTraceFd, "  glTexCoord2dv ( xglBuild2dv((GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2dv") )
++    glTexCoord2dv ( v ) ;
++}
++
++void xglTexCoord2f ( GLfloat s, GLfloat t )
++{
++  if ( xglTraceIsEnabled("glTexCoord2f") )
++    fprintf ( xglTraceFd, "  glTexCoord2f ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , s, t ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2f") )
++    glTexCoord2f ( s, t ) ;
++}
++
++void xglTexCoord2fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord2fv") )
++    fprintf ( xglTraceFd, "  glTexCoord2fv ( xglBuild2fv((GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2fv") )
++    glTexCoord2fv ( v ) ;
++}
++
++void xglTexCoord2i ( GLint s, GLint t )
++{
++  if ( xglTraceIsEnabled("glTexCoord2i") )
++    fprintf ( xglTraceFd, "  glTexCoord2i ( (GLint)%d, (GLint)%d ) ;\n" , s, t ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2i") )
++    glTexCoord2i ( s, t ) ;
++}
++
++void xglTexCoord2iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord2iv") )
++    fprintf ( xglTraceFd, "  glTexCoord2iv ( xglBuild2iv((GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2iv") )
++    glTexCoord2iv ( v ) ;
++}
++
++void xglTexCoord2s ( GLshort s, GLshort t )
++{
++  if ( xglTraceIsEnabled("glTexCoord2s") )
++    fprintf ( xglTraceFd, "  glTexCoord2s ( (GLshort)%d, (GLshort)%d ) ;\n" , s, t ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2s") )
++    glTexCoord2s ( s, t ) ;
++}
++
++void xglTexCoord2sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord2sv") )
++    fprintf ( xglTraceFd, "  glTexCoord2sv ( xglBuild2sv((GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord2sv") )
++    glTexCoord2sv ( v ) ;
++}
++
++void xglTexCoord3d ( GLdouble s, GLdouble t, GLdouble r )
++{
++  if ( xglTraceIsEnabled("glTexCoord3d") )
++    fprintf ( xglTraceFd, "  glTexCoord3d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , s, t, r ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3d") )
++    glTexCoord3d ( s, t, r ) ;
++}
++
++void xglTexCoord3dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord3dv") )
++    fprintf ( xglTraceFd, "  glTexCoord3dv ( xglBuild3dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3dv") )
++    glTexCoord3dv ( v ) ;
++}
++
++void xglTexCoord3f ( GLfloat s, GLfloat t, GLfloat r )
++{
++  if ( xglTraceIsEnabled("glTexCoord3f") )
++    fprintf ( xglTraceFd, "  glTexCoord3f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , s, t, r ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3f") )
++    glTexCoord3f ( s, t, r ) ;
++}
++
++void xglTexCoord3fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord3fv") )
++    fprintf ( xglTraceFd, "  glTexCoord3fv ( xglBuild3fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3fv") )
++    glTexCoord3fv ( v ) ;
++}
++
++void xglTexCoord3i ( GLint s, GLint t, GLint r )
++{
++  if ( xglTraceIsEnabled("glTexCoord3i") )
++    fprintf ( xglTraceFd, "  glTexCoord3i ( (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , s, t, r ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3i") )
++    glTexCoord3i ( s, t, r ) ;
++}
++
++void xglTexCoord3iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord3iv") )
++    fprintf ( xglTraceFd, "  glTexCoord3iv ( xglBuild3iv((GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3iv") )
++    glTexCoord3iv ( v ) ;
++}
++
++void xglTexCoord3s ( GLshort s, GLshort t, GLshort r )
++{
++  if ( xglTraceIsEnabled("glTexCoord3s") )
++    fprintf ( xglTraceFd, "  glTexCoord3s ( (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , s, t, r ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3s") )
++    glTexCoord3s ( s, t, r ) ;
++}
++
++void xglTexCoord3sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord3sv") )
++    fprintf ( xglTraceFd, "  glTexCoord3sv ( xglBuild3sv((GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord3sv") )
++    glTexCoord3sv ( v ) ;
++}
++
++void xglTexCoord4d ( GLdouble s, GLdouble t, GLdouble r, GLdouble q )
++{
++  if ( xglTraceIsEnabled("glTexCoord4d") )
++    fprintf ( xglTraceFd, "  glTexCoord4d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , s, t, r, q ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4d") )
++    glTexCoord4d ( s, t, r, q ) ;
++}
++
++void xglTexCoord4dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord4dv") )
++    fprintf ( xglTraceFd, "  glTexCoord4dv ( xglBuild4dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4dv") )
++    glTexCoord4dv ( v ) ;
++}
++
++void xglTexCoord4f ( GLfloat s, GLfloat t, GLfloat r, GLfloat q )
++{
++  if ( xglTraceIsEnabled("glTexCoord4f") )
++    fprintf ( xglTraceFd, "  glTexCoord4f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , s, t, r, q ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4f") )
++    glTexCoord4f ( s, t, r, q ) ;
++}
++
++void xglTexCoord4fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord4fv") )
++    fprintf ( xglTraceFd, "  glTexCoord4fv ( xglBuild4fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4fv") )
++    glTexCoord4fv ( v ) ;
++}
++
++void xglTexCoord4i ( GLint s, GLint t, GLint r, GLint q )
++{
++  if ( xglTraceIsEnabled("glTexCoord4i") )
++    fprintf ( xglTraceFd, "  glTexCoord4i ( (GLint)%d, (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , s, t, r, q ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4i") )
++    glTexCoord4i ( s, t, r, q ) ;
++}
++
++void xglTexCoord4iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord4iv") )
++    fprintf ( xglTraceFd, "  glTexCoord4iv ( xglBuild4iv((GLint)%d,(GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4iv") )
++    glTexCoord4iv ( v ) ;
++}
++
++void xglTexCoord4s ( GLshort s, GLshort t, GLshort r, GLshort q )
++{
++  if ( xglTraceIsEnabled("glTexCoord4s") )
++    fprintf ( xglTraceFd, "  glTexCoord4s ( (GLshort)%d, (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , s, t, r, q ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4s") )
++    glTexCoord4s ( s, t, r, q ) ;
++}
++
++void xglTexCoord4sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glTexCoord4sv") )
++    fprintf ( xglTraceFd, "  glTexCoord4sv ( xglBuild4sv((GLshort)%d,(GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glTexCoord4sv") )
++    glTexCoord4sv ( v ) ;
++}
++
++void xglTexCoordPointerEXT ( GLint size, GLenum type, GLsizei stride, GLsizei count, void* ptr )
++{
++  if ( xglTraceIsEnabled("glTexCoordPointerEXT") )
++    fprintf ( xglTraceFd, "  glTexCoordPointerEXT ( (GLint)%d, (GLenum)%s, (GLsizei)%d, (GLsizei)%d, (void *)0x%08x ) ;\n" , size, xglExpandGLenum ( (GLenum) type ), stride, count, ptr ) ;
++#ifdef GL_VERSION_1_1
++    glTexCoordPointer ( size, type, stride, ptr ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glTexCoordPointerEXT") )
++    glTexCoordPointerEXT ( size, type, stride, count, ptr ) ;
++#else
++  fprintf ( xglTraceFd, "  glTexCoordPointerEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglTexEnvf ( GLenum target, GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glTexEnvf") )
++    fprintf ( xglTraceFd, "  glTexEnvf ( (GLenum)%s, (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glTexEnvf") )
++    glTexEnvf ( target, pname, param ) ;
++}
++
++void xglTexEnvfv ( GLenum target, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glTexEnvfv") )
++    fprintf ( xglTraceFd, "  glTexEnvfv ( (GLenum)%s, (GLenum)%s, xglBuild4fv(%ff,%ff,%ff,%ff) ) ;\n",
++                          xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params[0], params[1], params[2], params[3] ) ;
++  if ( xglExecuteIsEnabled("glTexEnvfv") )
++    glTexEnvfv ( target, pname, params ) ;
++}
++
++void xglTexEnvi ( GLenum target, GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glTexEnvi") )
++    fprintf ( xglTraceFd, "  glTexEnvi ( (GLenum)%s, (GLenum)%s, (GLint)%s ) ;\n",
++            xglExpandGLenum ( (GLenum) target ),
++            xglExpandGLenum ( (GLenum) pname ),
++            xglExpandGLenum ( (GLenum) param ) ) ;
++
++  if ( xglExecuteIsEnabled("glTexEnvi") )
++    glTexEnvi ( target, pname, param ) ;
++}
++
++void xglTexEnviv ( GLenum target, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glTexEnviv") )
++    fprintf ( xglTraceFd, "  glTexEnviv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glTexEnviv") )
++    glTexEnviv ( target, pname, params ) ;
++}
++
++void xglTexGend ( GLenum coord, GLenum pname, GLdouble param )
++{
++  if ( xglTraceIsEnabled("glTexGend") )
++    fprintf ( xglTraceFd, "  glTexGend ( (GLenum)%s, (GLenum)%s, (GLdouble)%f ) ;\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glTexGend") )
++    glTexGend ( coord, pname, param ) ;
++}
++
++void xglTexGendv ( GLenum coord, GLenum pname, GLdouble* params )
++{
++  if ( xglTraceIsEnabled("glTexGendv") )
++    fprintf ( xglTraceFd, "  glTexGendv ( (GLenum)%s, (GLenum)%s, (GLdouble *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glTexGendv") )
++    glTexGendv ( coord, pname, params ) ;
++}
++
++void xglTexGenf ( GLenum coord, GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glTexGenf") )
++    fprintf ( xglTraceFd, "  glTexGenf ( (GLenum)%s, (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glTexGenf") )
++    glTexGenf ( coord, pname, param ) ;
++}
++
++void xglTexGenfv ( GLenum coord, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glTexGenfv") )
++    fprintf ( xglTraceFd, "  glTexGenfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glTexGenfv") )
++    glTexGenfv ( coord, pname, params ) ;
++}
++
++void xglTexGeni ( GLenum coord, GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glTexGeni") )
++    fprintf ( xglTraceFd, "  glTexGeni ( (GLenum)%s, (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glTexGeni") )
++    glTexGeni ( coord, pname, param ) ;
++}
++
++void xglTexGeniv ( GLenum coord, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glTexGeniv") )
++    fprintf ( xglTraceFd, "  glTexGeniv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) coord ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glTexGeniv") )
++    glTexGeniv ( coord, pname, params ) ;
++}
++
++void xglTexImage1D ( GLenum target, GLint level, GLint components, GLsizei width, GLint border, GLenum format, GLenum type, GLvoid* pixels )
++{
++  if ( xglTraceIsEnabled("glTexImage1D") )
++    fprintf ( xglTraceFd, "  glTexImage1D ( (GLenum)%s, (GLint)%d, (GLint)%d, (GLsizei)%d, (GLint)%d, (GLenum)%s, (GLenum)%s, (GLvoid *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), level, components, width, border, xglExpandGLenum ( (GLenum) format ), xglExpandGLenum ( (GLenum) type ), pixels ) ;
++  if ( xglExecuteIsEnabled("glTexImage1D") )
++    glTexImage1D ( target, level, components, width, border, format, type, pixels ) ;
++}
++
++void xglTexImage2D ( GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLvoid* pixels )
++{
++  if ( xglTraceIsEnabled("glTexImage2D") )
++    fprintf ( xglTraceFd, "  glTexImage2D ( (GLenum)%s, (GLint)%d, (GLint)%d, (GLsizei)%d, (GLsizei)%d, (GLint)%d, (GLenum)%s, (GLenum)%s, (GLvoid *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), level, components, width, height, border, xglExpandGLenum ( (GLenum) format ), xglExpandGLenum ( (GLenum) type ), pixels ) ;
++  if ( xglExecuteIsEnabled("glTexImage2D") )
++    glTexImage2D ( target, level, components, width, height, border, format, type, pixels ) ;
++}
++
++void xglTexParameterf ( GLenum target, GLenum pname, GLfloat param )
++{
++  if ( xglTraceIsEnabled("glTexParameterf") )
++    fprintf ( xglTraceFd, "  glTexParameterf ( (GLenum)%s, (GLenum)%s, (GLfloat)%ff ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glTexParameterf") )
++    glTexParameterf ( target, pname, param ) ;
++}
++
++void xglTexParameterfv ( GLenum target, GLenum pname, GLfloat* params )
++{
++  if ( xglTraceIsEnabled("glTexParameterfv") )
++    fprintf ( xglTraceFd, "  glTexParameterfv ( (GLenum)%s, (GLenum)%s, (GLfloat *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glTexParameterfv") )
++    glTexParameterfv ( target, pname, params ) ;
++}
++
++void xglTexParameteri ( GLenum target, GLenum pname, GLint param )
++{
++  if ( xglTraceIsEnabled("glTexParameteri") )
++    fprintf ( xglTraceFd, "  glTexParameteri ( (GLenum)%s, (GLenum)%s, (GLint)%d ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), param ) ;
++  if ( xglExecuteIsEnabled("glTexParameteri") )
++    glTexParameteri ( target, pname, param ) ;
++}
++
++void xglTexParameteriv ( GLenum target, GLenum pname, GLint* params )
++{
++  if ( xglTraceIsEnabled("glTexParameteriv") )
++    fprintf ( xglTraceFd, "  glTexParameteriv ( (GLenum)%s, (GLenum)%s, (GLint *)0x%08x ) ;\n" , xglExpandGLenum ( (GLenum) target ), xglExpandGLenum ( (GLenum) pname ), params ) ;
++  if ( xglExecuteIsEnabled("glTexParameteriv") )
++    glTexParameteriv ( target, pname, params ) ;
++}
++
++void xglTranslated ( GLdouble x, GLdouble y, GLdouble z )
++{
++  if ( xglTraceIsEnabled("glTranslated") )
++    fprintf ( xglTraceFd, "  glTranslated ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glTranslated") )
++    glTranslated ( x, y, z ) ;
++}
++
++void xglTranslatef ( GLfloat x, GLfloat y, GLfloat z )
++{
++  if ( xglTraceIsEnabled("glTranslatef") )
++    fprintf ( xglTraceFd, "  glTranslatef ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glTranslatef") )
++    glTranslatef ( x, y, z ) ;
++}
++
++void xglVertex2d ( GLdouble x, GLdouble y )
++{
++  if ( xglTraceIsEnabled("glVertex2d") )
++    fprintf ( xglTraceFd, "  glVertex2d ( (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glVertex2d") )
++    glVertex2d ( x, y ) ;
++}
++
++void xglVertex2dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glVertex2dv") )
++    fprintf ( xglTraceFd, "  glVertex2dv ( xglBuild2dv((GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glVertex2dv") )
++    glVertex2dv ( v ) ;
++}
++
++void xglVertex2f ( GLfloat x, GLfloat y )
++{
++  if ( xglTraceIsEnabled("glVertex2f") )
++    fprintf ( xglTraceFd, "  glVertex2f ( (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glVertex2f") )
++    glVertex2f ( x, y ) ;
++}
++
++void xglVertex2fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glVertex2fv") )
++    fprintf ( xglTraceFd, "  glVertex2fv ( xglBuild2fv((GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glVertex2fv") )
++    glVertex2fv ( v ) ;
++}
++
++void xglVertex2i ( GLint x, GLint y )
++{
++  if ( xglTraceIsEnabled("glVertex2i") )
++    fprintf ( xglTraceFd, "  glVertex2i ( (GLint)%d, (GLint)%d ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glVertex2i") )
++    glVertex2i ( x, y ) ;
++}
++
++void xglVertex2iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glVertex2iv") )
++    fprintf ( xglTraceFd, "  glVertex2iv ( xglBuild2iv((GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glVertex2iv") )
++    glVertex2iv ( v ) ;
++}
++
++void xglVertex2s ( GLshort x, GLshort y )
++{
++  if ( xglTraceIsEnabled("glVertex2s") )
++    fprintf ( xglTraceFd, "  glVertex2s ( (GLshort)%d, (GLshort)%d ) ;\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glVertex2s") )
++    glVertex2s ( x, y ) ;
++}
++
++void xglVertex2sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glVertex2sv") )
++    fprintf ( xglTraceFd, "  glVertex2sv ( xglBuild2sv((GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1] ) ;
++  if ( xglExecuteIsEnabled("glVertex2sv") )
++    glVertex2sv ( v ) ;
++}
++
++void xglVertex3d ( GLdouble x, GLdouble y, GLdouble z )
++{
++  if ( xglTraceIsEnabled("glVertex3d") )
++    fprintf ( xglTraceFd, "  glVertex3d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glVertex3d") )
++    glVertex3d ( x, y, z ) ;
++}
++
++void xglVertex3dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glVertex3dv") )
++    fprintf ( xglTraceFd, "  glVertex3dv ( xglBuild3dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glVertex3dv") )
++    glVertex3dv ( v ) ;
++}
++
++void xglVertex3f ( GLfloat x, GLfloat y, GLfloat z )
++{
++  if ( xglTraceIsEnabled("glVertex3f") )
++    fprintf ( xglTraceFd, "  glVertex3f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glVertex3f") )
++    glVertex3f ( x, y, z ) ;
++}
++
++void xglVertex3fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glVertex3fv") )
++    fprintf ( xglTraceFd, "  glVertex3fv ( xglBuild3fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glVertex3fv") )
++    glVertex3fv ( v ) ;
++}
++
++void xglVertex3i ( GLint x, GLint y, GLint z )
++{
++  if ( xglTraceIsEnabled("glVertex3i") )
++    fprintf ( xglTraceFd, "  glVertex3i ( (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glVertex3i") )
++    glVertex3i ( x, y, z ) ;
++}
++
++void xglVertex3iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glVertex3iv") )
++    fprintf ( xglTraceFd, "  glVertex3iv ( xglBuild3iv((GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glVertex3iv") )
++    glVertex3iv ( v ) ;
++}
++
++void xglVertex3s ( GLshort x, GLshort y, GLshort z )
++{
++  if ( xglTraceIsEnabled("glVertex3s") )
++    fprintf ( xglTraceFd, "  glVertex3s ( (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , x, y, z ) ;
++  if ( xglExecuteIsEnabled("glVertex3s") )
++    glVertex3s ( x, y, z ) ;
++}
++
++void xglVertex3sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glVertex3sv") )
++    fprintf ( xglTraceFd, "  glVertex3sv ( xglBuild3sv((GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2] ) ;
++  if ( xglExecuteIsEnabled("glVertex3sv") )
++    glVertex3sv ( v ) ;
++}
++
++void xglVertex4d ( GLdouble x, GLdouble y, GLdouble z, GLdouble w )
++{
++  if ( xglTraceIsEnabled("glVertex4d") )
++    fprintf ( xglTraceFd, "  glVertex4d ( (GLdouble)%f, (GLdouble)%f, (GLdouble)%f, (GLdouble)%f ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glVertex4d") )
++    glVertex4d ( x, y, z, w ) ;
++}
++
++void xglVertex4dv ( GLdouble* v )
++{
++  if ( xglTraceIsEnabled("glVertex4dv") )
++    fprintf ( xglTraceFd, "  glVertex4dv ( xglBuild4dv((GLdouble)%f,(GLdouble)%f,(GLdouble)%f,(GLdouble)%f) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glVertex4dv") )
++    glVertex4dv ( v ) ;
++}
++
++void xglVertex4f ( GLfloat x, GLfloat y, GLfloat z, GLfloat w )
++{
++  if ( xglTraceIsEnabled("glVertex4f") )
++    fprintf ( xglTraceFd, "  glVertex4f ( (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff, (GLfloat)%ff ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glVertex4f") )
++    glVertex4f ( x, y, z, w ) ;
++}
++
++void xglVertex4fv ( GLfloat* v )
++{
++  if ( xglTraceIsEnabled("glVertex4fv") )
++    fprintf ( xglTraceFd, "  glVertex4fv ( xglBuild4fv((GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff,(GLfloat)%ff) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glVertex4fv") )
++    glVertex4fv ( v ) ;
++}
++
++void xglVertex4i ( GLint x, GLint y, GLint z, GLint w )
++{
++  if ( xglTraceIsEnabled("glVertex4i") )
++    fprintf ( xglTraceFd, "  glVertex4i ( (GLint)%d, (GLint)%d, (GLint)%d, (GLint)%d ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glVertex4i") )
++    glVertex4i ( x, y, z, w ) ;
++}
++
++void xglVertex4iv ( GLint* v )
++{
++  if ( xglTraceIsEnabled("glVertex4iv") )
++    fprintf ( xglTraceFd, "  glVertex4iv ( xglBuild4iv((GLint)%d,(GLint)%d,(GLint)%d,(GLint)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glVertex4iv") )
++    glVertex4iv ( v ) ;
++}
++
++void xglVertex4s ( GLshort x, GLshort y, GLshort z, GLshort w )
++{
++  if ( xglTraceIsEnabled("glVertex4s") )
++    fprintf ( xglTraceFd, "  glVertex4s ( (GLshort)%d, (GLshort)%d, (GLshort)%d, (GLshort)%d ) ;\n" , x, y, z, w ) ;
++  if ( xglExecuteIsEnabled("glVertex4s") )
++    glVertex4s ( x, y, z, w ) ;
++}
++
++void xglVertex4sv ( GLshort* v )
++{
++  if ( xglTraceIsEnabled("glVertex4sv") )
++    fprintf ( xglTraceFd, "  glVertex4sv ( xglBuild4sv((GLshort)%d,(GLshort)%d,(GLshort)%d,(GLshort)%d) ) ;\n" , v[0], v[1], v[2], v[3] ) ;
++  if ( xglExecuteIsEnabled("glVertex4sv") )
++    glVertex4sv ( v ) ;
++}
++
++void xglVertexPointerEXT ( GLint size, GLenum type, GLsizei stride, GLsizei count, void* ptr )
++{
++  if ( xglTraceIsEnabled("glVertexPointerEXT") )
++    fprintf ( xglTraceFd, "  glVertexPointerEXT ( (GLint)%d, (GLenum)%s, (GLsizei)%d, (GLsizei)%d, (void *)0x%08x ) ;\n" , size, xglExpandGLenum ( (GLenum) type ), stride, count, ptr ) ;
++#ifdef GL_VERSION_1_1
++    glVertexPointer ( size, type, stride, ptr ) ;
++#else
++#ifdef GL_EXT_vertex_array
++  if ( xglExecuteIsEnabled("glVertexPointerEXT") )
++    glVertexPointerEXT ( size, type, stride, count, ptr ) ;
++#else
++  fprintf ( xglTraceFd, "  glVertexPointerEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++#endif
++}
++
++void xglViewport ( GLint x, GLint y, GLsizei width, GLsizei height )
++{
++  if ( xglTraceIsEnabled("glViewport") )
++    fprintf ( xglTraceFd, "  glViewport ( (GLint)%d, (GLint)%d, (GLsizei)%d, (GLsizei)%d ) ;\n" , x, y, width, height ) ;
++  if ( xglExecuteIsEnabled("glViewport") )
++    glViewport ( x, y, width, height ) ;
++}
++
++void xglutAddMenuEntry ( char* label, int value )
++{
++  if ( xglTraceIsEnabled("glutAddMenuEntry") )
++    fprintf ( xglTraceFd, "  /* glutAddMenuEntry ( \"%s\", %d ) ; */\n" , label, value ) ;
++  if ( xglExecuteIsEnabled("glutAddMenuEntry") )
++    glutAddMenuEntry ( label, value ) ;
++}
++
++void xglutAttachMenu ( int button )
++{
++  if ( xglTraceIsEnabled("glutAttachMenu") )
++    fprintf ( xglTraceFd, "  /* glutAttachMenu ( %d ) ; */\n" , button ) ;
++  if ( xglExecuteIsEnabled("glutAttachMenu") )
++    glutAttachMenu ( button ) ;
++}
++
++int xglutCreateMenu ( void (*func)(int) )
++{
++  if ( xglTraceIsEnabled("glutCreateMenu") )
++    fprintf ( xglTraceFd, "  /* glutCreateMenu ( 0x%08x ) ; */\n" , func ) ;
++
++  return glutCreateMenu ( func ) ;
++}
++
++int xglutCreateWindow ( char* title )
++{
++  if ( xglTraceIsEnabled("glutCreateWindow") )
++    fprintf ( xglTraceFd, "  /* glutCreateWindow ( \"%s\" ) ; */\n" , title ) ;
++
++  return glutCreateWindow ( title ) ;
++}
++
++void xglutDisplayFunc ( void (*func)(void) )
++{
++  if ( xglTraceIsEnabled("glutDisplayFunc") )
++    fprintf ( xglTraceFd, "  /* glutDisplayFunc ( 0x%08x ) ; */\n" , func ) ;
++  if ( xglExecuteIsEnabled("glutDisplayFunc") )
++    glutDisplayFunc ( func ) ;
++}
++
++void xglutIdleFunc ( void (*func)(void) )
++{
++  if ( xglTraceIsEnabled("glutIdleFunc") )
++    fprintf ( xglTraceFd, "  /* glutIdleFunc ( 0x%08x ) ; */\n" , func ) ;
++  if ( xglExecuteIsEnabled("glutIdleFunc") )
++    glutIdleFunc ( func ) ;
++}
++
++void xglutInit ( int* argcp, char** argv )
++{
++  if(!xglTraceFd ) {     // Not defined by any other means, must be here
++    xglTraceFd = stdout; // avoid a crash from a NULL ptr.
++    }
++  if ( xglTraceIsEnabled("glutInit") )
++    fprintf ( xglTraceFd,
++              "  /* glutInit ( (int *)0x%08x, (char **)0x%08x ) ; */\n" ,
++              argcp, argv ) ;
++  if ( xglExecuteIsEnabled("glutInit") )
++    glutInit ( argcp, argv ) ;
++}
++
++void xglutInitDisplayMode ( unsigned int mode )
++{
++  if ( xglTraceIsEnabled("glutInitDisplayMode") )
++    fprintf ( xglTraceFd, "  /* glutInitDisplayMode ( %u ) ; */\n" , mode ) ;
++  if ( xglExecuteIsEnabled("glutInitDisplayMode") )
++    glutInitDisplayMode ( mode ) ;
++}
++
++void xglutInitWindowPosition ( int x, int y )
++{
++  if ( xglTraceIsEnabled("glutInitWindowPosition") )
++    fprintf ( xglTraceFd, "  /* glutInitWindowPosition ( %d, %d ) ; */\n" , x, y ) ;
++  if ( xglExecuteIsEnabled("glutInitWindowPosition") )
++    glutInitWindowPosition ( x, y ) ;
++}
++
++void xglutInitWindowSize ( int width, int height )
++{
++  if ( xglTraceIsEnabled("glutInitWindowSize") )
++    fprintf ( xglTraceFd, "  /* glutInitWindowSize ( %d, %d ) ; */\n" , width, height ) ;
++  if ( xglExecuteIsEnabled("glutInitWindowSize") )
++    glutInitWindowSize ( width, height ) ;
++}
++
++void xglutKeyboardFunc ( void (*func)(unsigned char key, int x, int y) )
++{
++  if ( xglTraceIsEnabled("glutKeyboardFunc") )
++    fprintf ( xglTraceFd, "  /* glutKeyboardFunc ( 0x%08x ) ; */\n" , func ) ;
++  if ( xglExecuteIsEnabled("glutKeyboardFunc") )
++    glutKeyboardFunc ( func ) ;
++}
++
++void xglutMainLoopUpdate (  )
++{
++  if ( xglTraceIsEnabled("glutMainLoopUpdate") )
++    fprintf ( xglTraceFd, "  /* glutMainLoopUpdate (  ) ; */\n"  ) ;
++  if ( xglExecuteIsEnabled("glutMainLoopUpdate") )
++    /* glutMainLoopUpdate (  ) ; */
++    printf("Steves glutMainLoopUpdate() hack not executed!!!!\n");
++}
++
++void xglutPostRedisplay (  )
++{
++  if ( xglTraceIsEnabled("glutPostRedisplay") )
++    fprintf ( xglTraceFd, "  /* glutPostRedisplay (  ) ; */\n"  ) ;
++  if ( xglExecuteIsEnabled("glutPostRedisplay") )
++    glutPostRedisplay (  ) ;
++}
++
++void xglutPreMainLoop (  )
++{
++  if ( xglTraceIsEnabled("glutPreMainLoop") )
++    fprintf ( xglTraceFd, "  /* glutPreMainLoop (  ) ; */\n"  ) ;
++  if ( xglExecuteIsEnabled("glutPreMainLoop") )
++    /* glutPreMainLoop (  ) ; */
++    printf("Steves glutPreLoopUpdate() hack not executed!!!!\n");
++
++}
++
++void xglutReshapeFunc ( void (*func)(int width, int height) )
++{
++  if ( xglTraceIsEnabled("glutReshapeFunc") )
++    fprintf ( xglTraceFd, "  /* glutReshapeFunc ( 0x%08x ) ; */\n" , func ) ;
++  if ( xglExecuteIsEnabled("glutReshapeFunc") )
++    glutReshapeFunc ( func ) ;
++}
++
++void xglutSwapBuffers ()
++{
++  if ( xglTraceIsEnabled("glutSwapBuffers") )
++    fprintf ( xglTraceFd, "  /* glutSwapBuffers (  ) ; */\n"  ) ;
++  if ( xglExecuteIsEnabled("glutSwapBuffers") )
++    glutSwapBuffers () ;
++}
++
++GLboolean xglAreTexturesResidentEXT ( GLsizei n, GLuint* textures, GLboolean* residences )
++{
++  if ( xglTraceIsEnabled("glAreTexturesResidentEXT") )
++    fprintf ( xglTraceFd, "  /* glAreTexturesResidentEXT ( (GLsizei)%d, (GLuint *)0x%08x, (GLboolean *)0x%08x ) ; */\n" , n, textures, residences ) ;
++
++#ifdef GL_TEXTURE_2D_BINDING_EXT
++  if ( xglExecuteIsEnabled("glAreTexturesResidentEXT") )
++    return glAreTexturesResidentEXT ( n, textures, residences ) ;
++#else
++  fprintf ( xglTraceFd, "  glAreTexturesResidentEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++
++  return TRUE ;
++}
++
++GLboolean xglIsTextureEXT ( GLuint texture )
++{
++  if ( xglTraceIsEnabled("glIsTextureEXT") )
++    fprintf ( xglTraceFd, "  /* glIsTextureEXT ( (GLuint)%u ) ; */\n" , texture ) ;
++
++#ifdef GL_TEXTURE_2D_BINDING_EXT
++  if ( xglExecuteIsEnabled("glIsTextureEXT") )
++    return glIsTextureEXT ( texture ) ;
++#else
++  fprintf ( xglTraceFd, "  glIsTextureEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++
++  return TRUE ;
++}
++
++void xglBindTextureEXT ( GLenum target, GLuint texture )
++{
++  if ( xglTraceIsEnabled("glBindTextureEXT") )
++    fprintf ( xglTraceFd, "  glBindTextureEXT ( (GLenum)%s, (GLuint)%u ) ;\n" , xglExpandGLenum ( (GLenum) target ), texture ) ;
++
++#ifdef GL_TEXTURE_2D_BINDING_EXT
++  if ( xglExecuteIsEnabled("glBindTextureEXT") )
++    glBindTextureEXT ( target, texture ) ;
++#else
++  fprintf ( xglTraceFd, "  glBindTextureEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglDeleteTexturesEXT ( GLsizei n, GLuint* textures )
++{
++  if ( xglTraceIsEnabled("glDeleteTexturesEXT") )
++    fprintf ( xglTraceFd, "  glDeleteTexturesEXT ( (GLsizei)%d, (GLuint *)0x%08x ) ;\n" , n, textures ) ;
++
++#ifdef GL_TEXTURE_2D_BINDING_EXT
++  if ( xglExecuteIsEnabled("glDeleteTexturesEXT") )
++    glDeleteTexturesEXT ( n, textures ) ;
++#else
++  fprintf ( xglTraceFd, "  glDeleteTextures isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglGenTexturesEXT ( GLsizei n, GLuint* textures )
++{
++  if ( xglTraceIsEnabled("glGenTexturesEXT") )
++    fprintf ( xglTraceFd, "  glGenTexturesEXT ( (GLsizei)%d, (GLuint *)0x%08x ) ;\n" , n, textures ) ;
++
++#ifdef GL_TEXTURE_2D_BINDING_EXT
++  if ( xglExecuteIsEnabled("glGenTexturesEXT") )
++    glGenTexturesEXT ( n, textures ) ;
++#else
++  fprintf ( xglTraceFd, "  glDeleteTexturesEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglPrioritizeTexturesEXT ( GLsizei n, GLuint* textures, GLclampf* priorities )
++{
++  if ( xglTraceIsEnabled("glPrioritizeTexturesEXT") )
++    fprintf ( xglTraceFd, "  glPrioritizeTexturesEXT ( (GLsizei)%d, (GLuint *)0x%08x, (GLclampf *)0x%08x ) ;\n" , n, textures, priorities ) ;
++
++#ifdef GL_TEXTURE_2D_BINDING_EXT
++  if ( xglExecuteIsEnabled("glPrioritizeTexturesEXT") )
++    glPrioritizeTexturesEXT ( n, textures, priorities ) ;
++#else
++  fprintf ( xglTraceFd, "  glPrioritizeTexturesEXT isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++
++GLboolean xglAreTexturesResident ( GLsizei n, GLuint* textures, GLboolean* residences )
++{
++  if ( xglTraceIsEnabled("glAreTexturesResident") )
++    fprintf ( xglTraceFd, "  /* glAreTexturesResident ( (GLsizei)%d, (GLuint *)0x%08x, (GLboolean *)0x%08x ) ; */\n" , n, textures, residences ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glAreTexturesResident") )
++    return glAreTexturesResident ( n, textures, residences ) ;
++#else
++  fprintf ( xglTraceFd, "  glAreTexturesResident isn't supported on this OpenGL!\n" ) ;
++#endif
++
++  return TRUE ;
++}
++
++GLboolean xglIsTexture ( GLuint texture )
++{
++  if ( xglTraceIsEnabled("glIsTexture") )
++    fprintf ( xglTraceFd, "  /* glIsTexture ( (GLuint)%u ) ; */\n" , texture ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glIsTexture") )
++    return glIsTexture ( texture ) ;
++#else
++  fprintf ( xglTraceFd, "  glIsTexture isn't supported on this OpenGL!\n" ) ;
++#endif
++
++  return TRUE ;
++}
++
++void xglBindTexture ( GLenum target, GLuint texture )
++{
++  if ( xglTraceIsEnabled("glBindTexture") )
++    fprintf ( xglTraceFd, "  glBindTexture ( (GLenum)%s, (GLuint)%u ) ;\n" , xglExpandGLenum ( (GLenum) target ), texture ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glBindTexture") )
++    glBindTexture ( target, texture ) ;
++#else
++  fprintf ( xglTraceFd, "  glBindTexture isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglDeleteTextures ( GLsizei n, GLuint* textures )
++{
++  if ( xglTraceIsEnabled("glDeleteTextures") )
++    fprintf ( xglTraceFd, "  glDeleteTextures ( (GLsizei)%d, (GLuint *)0x%08x ) ;\n" , n, textures ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glDeleteTextures") )
++    glDeleteTextures ( n, textures ) ;
++#else
++  fprintf ( xglTraceFd, "  glDeleteTextures isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglGenTextures ( GLsizei n, GLuint* textures )
++{
++  if ( xglTraceIsEnabled("glGenTextures") )
++    fprintf ( xglTraceFd, "  glGenTextures ( (GLsizei)%d, (GLuint *)0x%08x ) ;\n" , n, textures ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glGenTextures") )
++    glGenTextures ( n, textures ) ;
++#else
++  fprintf ( xglTraceFd, "  glDeleteTextures isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++void xglPrioritizeTextures ( GLsizei n, GLuint* textures, GLclampf* priorities )
++{
++  if ( xglTraceIsEnabled("glPrioritizeTextures") )
++    fprintf ( xglTraceFd, "  glPrioritizeTextures ( (GLsizei)%d, (GLuint *)0x%08x, (GLclampf *)0x%08x ) ;\n" , n, textures, priorities ) ;
++
++#ifdef GL_VERSION_1_1
++  if ( xglExecuteIsEnabled("glPrioritizeTextures") )
++    glPrioritizeTextures ( n, textures, priorities ) ;
++#else
++  fprintf ( xglTraceFd, "  glPrioritizeTextures isn't supported on this OpenGL!\n" ) ;
++#endif
++}
++
++#endif
++
diff --cc Lib/XGL/xgl.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..434ab09d6ec862d0560b13667b152e124a6bc093
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..56da165227b43fa15f7e76a05597b61f01b2820d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8528348b9ae3db49a23fe20e3d6b5bb775b7d7eb
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ae519786d935f8e1440c9ab5e6d60c38d67de1ac
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 () ;
++  }
++}
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..e9f4531780c7a4d73008dc8aead53f3ebab9bdd4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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.
diff --cc Lib/src/sl.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5cbbc2adfba1ea31b0e8b20d8ad1c39d6d5999bd
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a8a96d4dadc96a80c23e46d8100c9457008d4db7
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..13e726c4c6f11063dedc02677a5eac67ddae59a6
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++  }
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..08d780c144f40bc3cafee85920ed30d4bf9bfe92
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..386a3ce29721f71aa84422656172e032ccd76be4
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ;
++}
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..12eecaf6560479cd405184cc4d41ec80bae3c2d5
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 () ;
++    }
++  }
++}
++
++
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..5fe4caa91d4589a74519b938c11e17baa8c6fb0e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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 ) ;
++  }
++}
++
++
diff --cc Lib/src/sm.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f884cd0374c409616a6f684452fdbdabb5bd70af
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f7be007d7eb0693d0392d13c52a9ebbba614d459
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,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
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..57386a26f485d3896ba90984a9eb04df13f9f527
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,471 @@@
++
++              ChangeLog file for zlib
++
++Changes in 1.1.3 (9 July 1998)
++- fix "an inflate input buffer bug that shows up on rare but persistent
++  occasions" (Mark)
++- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
++- fix gzseek(..., SEEK_SET) in write mode
++- fix crc check after a gzeek (Frank Faubert)
++- fix miniunzip when the last entry in a zip file is itself a zip file
++  (J Lillge)
++- add contrib/asm586 and contrib/asm686 (Brian Raiter)
++  See http://www.muppetlabs.com/~breadbox/software/assembly.html
++- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
++- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
++- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
++- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
++- added a FAQ file
++
++- Support gzdopen on Mac with Metrowerks (Jason Linhart)
++- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
++- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
++- avoid some warnings with Borland C (Tom Tanner)
++- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
++- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
++- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
++- use libdir and includedir in Makefile.in (Tim Mooney)
++- support shared libraries on OSF1 V4 (Tim Mooney)
++- remove so_locations in "make clean"  (Tim Mooney)
++- fix maketree.c compilation error (Glenn, Mark)
++- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
++- new Makefile.riscos (Rich Walker)
++- initialize static descriptors in trees.c for embedded targets (Nick Smith)
++- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
++- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
++- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
++- fix maketree.c to allow clean compilation of inffixed.h (Mark)
++- fix parameter check in deflateCopy (Gunther Nikl)
++- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
++- Many portability patches by Christian Spieler:
++  . zutil.c, zutil.h: added "const" for zmem*
++  . Make_vms.com: fixed some typos
++  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
++  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
++  . msdos/Makefile.*: use model-dependent name for the built zlib library
++  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
++     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
++- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
++- replace __far with _far for better portability (Christian Spieler, Tom Lane)
++- fix test for errno.h in configure (Tim Newsham)
++
++Changes in 1.1.2 (19 March 98)
++- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
++  See http://www.winimage.com/zLibDll/unzip.html
++- preinitialize the inflate tables for fixed codes, to make the code
++  completely thread safe (Mark)
++- some simplifications and slight speed-up to the inflate code (Mark)
++- fix gzeof on non-compressed files (Allan Schrum)
++- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
++- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
++- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
++- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
++- do not wrap extern "C" around system includes (Tom Lane)
++- mention zlib binding for TCL in README (Andreas Kupries)
++- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
++- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
++- allow "configure --prefix $HOME" (Tim Mooney)
++- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
++- move Makefile.sas to amiga/Makefile.sas
++
++Changes in 1.1.1 (27 Feb 98)
++- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
++- remove block truncation heuristic which had very marginal effect for zlib
++  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
++  compression ratio on some files. This also allows inlining _tr_tally for
++  matches in deflate_slow.
++- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
++
++Changes in 1.1.0 (24 Feb 98)
++- do not return STREAM_END prematurely in inflate (John Bowler)
++- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
++- compile with -DFASTEST to get compression code optimized for speed only
++- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
++- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
++  on Sun but significant on HP)
++
++- add a pointer to experimental unzip library in README (Gilles Vollant)
++- initialize variable gcc in configure (Chris Herborth)
++
++Changes in 1.0.9 (17 Feb 1998)
++- added gzputs and gzgets functions
++- do not clear eof flag in gzseek (Mark Diekhans)
++- fix gzseek for files in transparent mode (Mark Diekhans)
++- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
++- replace EXPORT with ZEXPORT to avoid conflict with other programs
++- added compress2 in zconf.h, zlib.def, zlib.dnt
++- new asm code from Gilles Vollant in contrib/asm386
++- simplify the inflate code (Mark):
++ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
++ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
++ . ZALLOC the value area for huft_build() instead of using stack
++ . Simplify Z_FINISH check in inflate()
++
++- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
++- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
++- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
++  the declaration of FAR (Gilles VOllant)
++- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
++- read_buf buf parameter of type Bytef* instead of charf*
++- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
++- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
++- fix check for presence of directories in "make install" (Ian Willis)
++
++Changes in 1.0.8 (27 Jan 1998)
++- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
++- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
++- added compress2() to allow setting the compression level
++- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
++- use constant arrays for the static trees in trees.c instead of computing
++  them at run time (thanks to Ken Raeburn for this suggestion). To create
++  trees.h, compile with GEN_TREES_H and run "make test".
++- check return code of example in "make test" and display result
++- pass minigzip command line options to file_compress
++- simplifying code of inflateSync to avoid gcc 2.8 bug
++
++- support CC="gcc -Wall" in configure -s (QingLong)
++- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
++- fix test for shared library support to avoid compiler warnings
++- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
++- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
++- do not use fdopen for Metrowerks on Mac (Brad Pettit))
++- add checks for gzputc and gzputc in example.c
++- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
++- use const for the CRC table (Ken Raeburn)
++- fixed "make uninstall" for shared libraries
++- use Tracev instead of Trace in infblock.c
++- in example.c use correct compressed length for test_sync
++- suppress +vnocompatwarnings in configure for HPUX (not always supported)
++
++Changes in 1.0.7 (20 Jan 1998)
++- fix gzseek which was broken in write mode
++- return error for gzseek to negative absolute position
++- fix configure for Linux (Chun-Chung Chen)
++- increase stack space for MSC (Tim Wegner)
++- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
++- define EXPORTVA for gzprintf (Gilles Vollant)
++- added man page zlib.3 (Rick Rodgers)
++- for contrib/untgz, fix makedir() and improve Makefile
++
++- check gzseek in write mode in example.c
++- allocate extra buffer for seeks only if gzseek is actually called
++- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
++- add inflateSyncPoint in zconf.h
++- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
++
++Changes in 1.0.6 (19 Jan 1998)
++- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
++  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
++- Fix a deflate bug occuring only with compression level 0 (thanks to
++  Andy Buckler for finding this one).
++- In minigzip, pass transparently also the first byte for .Z files.
++- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
++- check Z_FINISH in inflate (thanks to Marc Schluper)
++- Implement deflateCopy (thanks to Adam Costello)
++- make static libraries by default in configure, add --shared option.
++- move MSDOS or Windows specific files to directory msdos
++- suppress the notion of partial flush to simplify the interface
++  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
++- suppress history buffer provided by application to simplify the interface
++  (this feature was not implemented anyway in 1.0.4)
++- next_in and avail_in must be initialized before calling inflateInit or
++  inflateInit2
++- add EXPORT in all exported functions (for Windows DLL)
++- added Makefile.nt (thanks to Stephen Williams)
++- added the unsupported "contrib" directory:
++   contrib/asm386/ by Gilles Vollant <info@winimage.com>
++      386 asm code replacing longest_match().
++   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
++        A C++ I/O streams interface to the zlib gz* functions
++   contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
++      Another C++ I/O streams interface
++   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
++      A very simple tar.gz file extractor using zlib
++   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
++        How to use compress(), uncompress() and the gz* functions from VB.
++- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
++  level) in minigzip (thanks to Tom Lane)
++
++- use const for rommable constants in deflate
++- added test for gzseek and gztell in example.c
++- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
++- add undocumented function zError to convert error code to string
++  (for Tim Smithers)
++- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
++- Use default memcpy for Symantec MSDOS compiler.
++- Add EXPORT keyword for check_func (needed for Windows DLL)
++- add current directory to LD_LIBRARY_PATH for "make test"
++- create also a link for libz.so.1
++- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
++- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
++- added -soname for Linux in configure (Chun-Chung Chen,
++- assign numbers to the exported functions in zlib.def (for Windows DLL)
++- add advice in zlib.h for best usage of deflateSetDictionary
++- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
++- allow compilation with ANSI keywords only enabled for TurboC in large model
++- avoid "versionString"[0] (Borland bug)
++- add NEED_DUMMY_RETURN for Borland
++- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
++- allow compilation with CC
++- defined STDC for OS/2 (David Charlap)       
++- limit external names to 8 chars for MVS (Thomas Lund)
++- in minigzip.c, use static buffers only for 16-bit systems
++- fix suffix check for "minigzip -d foo.gz"
++- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
++- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
++- added makelcc.bat for lcc-win32 (Tom St Denis)
++- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
++- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
++- check for unistd.h in configure (for off_t)
++- remove useless check parameter in inflate_blocks_free
++- avoid useless assignment of s->check to itself in inflate_blocks_new
++- do not flush twice in gzclose (thanks to Ken Raeburn)
++- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
++- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
++- work around buggy fclose on pipes for HP/UX
++- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
++- fix configure if CC is already equal to gcc
++
++Changes in 1.0.5 (3 Jan 98)
++- Fix inflate to terminate gracefully when fed corrupted or invalid data
++- Use const for rommable constants in inflate
++- Eliminate memory leaks on error conditions in inflate
++- Removed some vestigial code in inflate
++- Update web address in README
++  
++Changes in 1.0.4 (24 Jul 96)
++- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
++  bit, so the decompressor could decompress all the correct data but went
++  on to attempt decompressing extra garbage data. This affected minigzip too.
++- zlibVersion and gzerror return const char* (needed for DLL)
++- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
++- use z_error only for DEBUG (avoid problem with DLLs)
++
++Changes in 1.0.3 (2 Jul 96)
++- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
++  small and medium models; this makes the library incompatible with previous
++  versions for these models. (No effect in large model or on other systems.)
++- return OK instead of BUF_ERROR if previous deflate call returned with
++  avail_out as zero but there is nothing to do
++- added memcmp for non STDC compilers
++- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
++- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
++- better check for 16-bit mode MSC (avoids problem with Symantec)
++
++Changes in 1.0.2 (23 May 96)
++- added Windows DLL support
++- added a function zlibVersion (for the DLL support)
++- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
++- Bytef is define's instead of typedef'd only for Borland C
++- avoid reading uninitialized memory in example.c
++- mention in README that the zlib format is now RFC1950
++- updated Makefile.dj2
++- added algorithm.doc
++
++Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
++- fix array overlay in deflate.c which sometimes caused bad compressed data
++- fix inflate bug with empty stored block
++- fix MSDOS medium model which was broken in 0.99
++- fix deflateParams() which could generated bad compressed data.
++- Bytef is define'd instead of typedef'ed (work around Borland bug)
++- added an INDEX file
++- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
++  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
++- speed up adler32 for modern machines without auto-increment
++- added -ansi for IRIX in configure
++- static_init_done in trees.c is an int
++- define unlink as delete for VMS
++- fix configure for QNX
++- add configure branch for SCO and HPUX
++- avoid many warnings (unused variables, dead assignments, etc...)
++- no fdopen for BeOS
++- fix the Watcom fix for 32 bit mode (define FAR as empty)
++- removed redefinition of Byte for MKWERKS
++- work around an MWKERKS bug (incorrect merge of all .h files)
++
++Changes in 0.99 (27 Jan 96)
++- allow preset dictionary shared between compressor and decompressor
++- allow compression level 0 (no compression)
++- add deflateParams in zlib.h: allow dynamic change of compression level
++  and compression strategy.
++- test large buffers and deflateParams in example.c
++- add optional "configure" to build zlib as a shared library
++- suppress Makefile.qnx, use configure instead
++- fixed deflate for 64-bit systems (detected on Cray)
++- fixed inflate_blocks for 64-bit systems (detected on Alpha)
++- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
++- always return Z_BUF_ERROR when deflate() has nothing to do
++- deflateInit and inflateInit are now macros to allow version checking
++- prefix all global functions and types with z_ with -DZ_PREFIX
++- make falloc completely reentrant (inftrees.c)
++- fixed very unlikely race condition in ct_static_init
++- free in reverse order of allocation to help memory manager
++- use zlib-1.0/* instead of zlib/* inside the tar.gz
++- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
++  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
++- allow gzread on concatenated .gz files
++- deflateEnd now returns Z_DATA_ERROR if it was premature
++- deflate is finally (?) fully deterministic (no matches beyond end of input)
++- Document Z_SYNC_FLUSH
++- add uninstall in Makefile
++- Check for __cpluplus in zlib.h
++- Better test in ct_align for partial flush
++- avoid harmless warnings for Borland C++
++- initialize hash_head in deflate.c
++- avoid warning on fdopen (gzio.c) for HP cc -Aa
++- include stdlib.h for STDC compilers
++- include errno.h for Cray
++- ignore error if ranlib doesn't exist
++- call ranlib twice for NeXTSTEP
++- use exec_prefix instead of prefix for libz.a
++- renamed ct_* as _tr_* to avoid conflict with applications
++- clear z->msg in inflateInit2 before any error return
++- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
++- fixed typo in zconf.h (_GNUC__ => __GNUC__)
++- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
++- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
++- in fcalloc, normalize pointer if size > 65520 bytes
++- don't use special fcalloc for 32 bit Borland C++
++- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
++- use Z_BINARY instead of BINARY
++- document that gzclose after gzdopen will close the file
++- allow "a" as mode in gzopen.
++- fix error checking in gzread
++- allow skipping .gz extra-field on pipes
++- added reference to Perl interface in README
++- put the crc table in FAR data (I dislike more and more the medium model :)
++- added get_crc_table
++- added a dimension to all arrays (Borland C can't count).
++- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
++- guard against multiple inclusion of *.h (for precompiled header on Mac)
++- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
++- don't use unsized arrays to avoid silly warnings by Visual C++:
++     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
++     (what's wrong with far data in far model?).
++- define enum out of inflate_blocks_state to allow compilation with C++
++
++Changes in 0.95 (16 Aug 95)
++- fix MSDOS small and medium model (now easier to adapt to any compiler)
++- inlined send_bits
++- fix the final (:-) bug for deflate with flush (output was correct but
++  not completely flushed in rare occasions).
++- default window size is same for compression and decompression
++  (it's now sufficient to set MAX_WBITS in zconf.h).
++- voidp -> voidpf and voidnp -> voidp (for consistency with other
++  typedefs and because voidnp was not near in large model).
++
++Changes in 0.94 (13 Aug 95)
++- support MSDOS medium model
++- fix deflate with flush (could sometimes generate bad output)
++- fix deflateReset (zlib header was incorrectly suppressed)
++- added support for VMS
++- allow a compression level in gzopen()
++- gzflush now calls fflush
++- For deflate with flush, flush even if no more input is provided.
++- rename libgz.a as libz.a
++- avoid complex expression in infcodes.c triggering Turbo C bug
++- work around a problem with gcc on Alpha (in INSERT_STRING)
++- don't use inline functions (problem with some gcc versions)
++- allow renaming of Byte, uInt, etc... with #define.
++- avoid warning about (unused) pointer before start of array in deflate.c
++- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
++- avoid reserved word 'new' in trees.c
++
++Changes in 0.93 (25 June 95)
++- temporarily disable inline functions
++- make deflate deterministic
++- give enough lookahead for PARTIAL_FLUSH
++- Set binary mode for stdin/stdout in minigzip.c for OS/2
++- don't even use signed char in inflate (not portable enough)
++- fix inflate memory leak for segmented architectures
++
++Changes in 0.92 (3 May 95)
++- don't assume that char is signed (problem on SGI)
++- Clear bit buffer when starting a stored block
++- no memcpy on Pyramid
++- suppressed inftest.c
++- optimized fill_window, put longest_match inline for gcc
++- optimized inflate on stored blocks.
++- untabify all sources to simplify patches
++
++Changes in 0.91 (2 May 95)
++- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
++- Document the memory requirements in zconf.h
++- added "make install"
++- fix sync search logic in inflateSync
++- deflate(Z_FULL_FLUSH) now works even if output buffer too short
++- after inflateSync, don't scare people with just "lo world"
++- added support for DJGPP
++
++Changes in 0.9 (1 May 95)
++- don't assume that zalloc clears the allocated memory (the TurboC bug
++  was Mark's bug after all :)
++- let again gzread copy uncompressed data unchanged (was working in 0.71)
++- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
++- added a test of inflateSync in example.c
++- moved MAX_WBITS to zconf.h because users might want to change that.
++- document explicitly that zalloc(64K) on MSDOS must return a normalized
++  pointer (zero offset)
++- added Makefiles for Microsoft C, Turbo C, Borland C++
++- faster crc32()
++
++Changes in 0.8 (29 April 95)
++- added fast inflate (inffast.c)
++- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
++  is incompatible with previous versions of zlib which returned Z_OK.
++- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
++  (actually that was not a compiler bug, see 0.81 above)
++- gzread no longer reads one extra byte in certain cases
++- In gzio destroy(), don't reference a freed structure
++- avoid many warnings for MSDOS
++- avoid the ERROR symbol which is used by MS Windows
++
++Changes in 0.71 (14 April 95)
++- Fixed more MSDOS compilation problems :( There is still a bug with
++  TurboC large model.
++
++Changes in 0.7 (14 April 95)
++- Added full inflate support.
++- Simplified the crc32() interface. The pre- and post-conditioning
++  (one's complement) is now done inside crc32(). WARNING: this is
++  incompatible with previous versions; see zlib.h for the new usage.
++
++Changes in 0.61 (12 April 95)
++- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
++
++Changes in 0.6 (11 April 95)
++- added minigzip.c
++- added gzdopen to reopen a file descriptor as gzFile
++- added transparent reading of non-gziped files in gzread.
++- fixed bug in gzread (don't read crc as data)
++- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
++- don't allocate big arrays in the stack (for MSDOS)
++- fix some MSDOS compilation problems
++
++Changes in 0.5:
++- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
++  not yet Z_FULL_FLUSH.
++- support decompression but only in a single step (forced Z_FINISH)
++- added opaque object for zalloc and zfree.
++- added deflateReset and inflateReset
++- added a variable zlib_version for consistency checking.
++- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
++  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
++
++Changes in 0.4:
++- avoid "zip" everywhere, use zlib instead of ziplib.
++- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
++  if compression method == 8.
++- added adler32 and crc32
++- renamed deflateOptions as deflateInit2, call one or the other but not both
++- added the method parameter for deflateInit2.
++- added inflateInit2
++- simplied considerably deflateInit and inflateInit by not supporting
++  user-provided history buffer. This is supported only in deflateInit2
++  and inflateInit2.
++
++Changes in 0.3:
++- prefix all macro names with Z_
++- use Z_FINISH instead of deflateEnd to finish compression.
++- added Z_HUFFMAN_ONLY
++- added gzerror()
diff --cc Lib/zlib/INDEX
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8a24576640269b8f6d872232ad3947cc83e72d4e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,86 @@@
++ChangeLog             history of changes
++INDEX                 this file
++FAQ                   Frequently Asked Questions about zlib
++Make_vms.com          script for Vax/VMS
++Makefile              makefile for Unix (generated by configure)
++Makefile.in           makefile for Unix (template for configure)
++Makefile.riscos       makefile for RISCOS
++README                        guess what
++algorithm.txt         description of the (de)compression algorithm
++configure             configure script for Unix
++descrip.mms           makefile for Vax/VMS
++zlib.3                        mini man page for zlib (volunteers to write full
++                      man pages from zlib.h welcome. write to jloup@gzip.org)
++
++amiga/Makefile.sas    makefile for Amiga SAS/C
++amiga/Makefile.pup      makefile for Amiga powerUP SAS/C PPC
++
++msdos/Makefile.w32      makefile for Microsoft Visual C++ 32-bit
++msdos/Makefile.b32    makefile for Borland C++   32-bit
++msdos/Makefile.bor    makefile for Borland C/C++ 16-bit
++msdos/Makefile.dj2    makefile for DJGPP 2.x
++msdos/Makefile.emx    makefile for EMX 0.9c (32-bit DOS/OS2)
++msdos/Makefile.msc    makefile for Microsoft C 16-bit
++msdos/Makefile.tc     makefile for Turbo C
++msdos/Makefile.wat    makefile for Watcom C
++msdos/zlib.def                definition file for Windows DLL
++msdos/zlib.rc                 definition file for Windows DLL
++
++nt/Makefile.nt                makefile for Windows NT
++nt/zlib.dnt           definition file for Windows NT DLL
++nt/Makefile.emx               makefile for EMX 0.9c/RSXNT 1.41 (Win32 Intel)
++nt/Makefile.gcc               makefile for Windows NT using GCC (mingw32)
++
++
++              zlib public header files (must be kept):
++zconf.h
++zlib.h
++
++              private source files used to build the zlib library:
++adler32.c
++compress.c
++crc32.c
++deflate.c
++deflate.h
++gzio.c
++infblock.c
++infblock.h
++infcodes.c
++infcodes.h
++inffast.c
++inffast.h
++inflate.c
++inftrees.c
++inftrees.h
++infutil.c
++infutil.h
++maketree.c
++trees.c
++uncompr.c
++zutil.c
++zutil.h
++
++              source files for sample programs:
++example.c
++minigzip.c
++
++              unsupported contribution by third parties
++
++contrib/asm386/ by Gilles Vollant <info@winimage.com>
++      386 asm code replacing longest_match().
++
++contrib/minizip/ by Gilles Vollant <info@winimage.com>
++      Mini zip and unzip based on zlib
++        See http://www.winimage.com/zLibDll/unzip.html
++
++contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
++        A C++ I/O streams interface to the zlib gz* functions
++
++contrib/iostream2/  by Tyge Løvset <Tyge.Lovset@cmr.no>
++      Another C++ I/O streams interface
++
++contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
++      A very simple tar.gz extractor using zlib
++
++contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
++        How to use compress(), uncompress() and the gz* functions from VB.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..0c93862fcc2d3b5c2b452eab21e3018091c2f170
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,31 @@@
++EXTRA_DIST = ChangeLog INDEX Make_vms.com Makefile.riscos README \
++      algorithm.txt descrip.mms example.c maketree.c minigzip.c zlib.3
++
++lib_LIBRARIES = libz.a
++
++libz_a_SOURCES = \
++      adler32.c \
++      compress.c \
++      crc32.c \
++      deflate.c \
++      deflate.h \
++      gzio.c \
++      infblock.c \
++      infblock.h \
++      infcodes.c \
++      infcodes.h \
++      inffast.c \
++      inffast.h \
++      inffixed.h \
++      inflate.c \
++      inftrees.c \
++      inftrees.h \
++      infutil.c \
++      infutil.h \
++      trees.c \
++      trees.h \
++      uncompr.c \
++      zconf.h \
++      zlib.h \
++      zutil.c \
++      zutil.h
diff --cc Lib/zlib/README
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8ff458799b957b342558504fe44409197f23b034
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,148 @@@
++zlib 1.1.3 is a general purpose data compression library.  All the code
++is thread safe.  The data format used by the zlib library
++is described by RFCs (Request for Comments) 1950 to 1952 in the files 
++ftp://ds.internic.net/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate
++format) and rfc1952.txt (gzip format). These documents are also available in
++other formats from ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
++
++All functions of the compression library are documented in the file zlib.h
++(volunteer to write man pages welcome, contact jloup@gzip.org). A usage
++example of the library is given in the file example.c which also tests that
++the library is working correctly. Another example is given in the file
++minigzip.c. The compression library itself is composed of all source files
++except example.c and minigzip.c.
++
++To compile all files and run the test program, follow the instructions
++given at the top of Makefile. In short "make test; make install"
++should work for most machines. For Unix: "configure; make test; make install"
++For MSDOS, use one of the special makefiles such as Makefile.msc.
++For VMS, use Make_vms.com or descrip.mms.
++
++Questions about zlib should be sent to <zlib@quest.jpl.nasa.gov>, or to
++Gilles Vollant <info@winimage.com> for the Windows DLL version.
++The zlib home page is http://www.cdrom.com/pub/infozip/zlib/
++The official zlib ftp site is ftp://ftp.cdrom.com/pub/infozip/zlib/
++Before reporting a problem, please check those sites to verify that
++you have the latest version of zlib; otherwise get the latest version and
++check whether the problem still exists or not.
++
++Mark Nelson <markn@tiny.com> wrote an article about zlib for the Jan. 1997
++issue of  Dr. Dobb's Journal; a copy of the article is available in
++http://web2.airmail.net/markn/articles/zlibtool/zlibtool.htm
++
++The changes made in version 1.1.3 are documented in the file ChangeLog.
++The main changes since 1.1.2 are:
++
++- fix "an inflate input buffer bug that shows up on rare but persistent
++  occasions" (Mark)
++- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
++- fix gzseek(..., SEEK_SET) in write mode
++- fix crc check after a gzeek (Frank Faubert)
++- fix miniunzip when the last entry in a zip file is itself a zip file
++  (J Lillge)
++- add contrib/asm586 and contrib/asm686 (Brian Raiter)
++  See http://www.muppetlabs.com/~breadbox/software/assembly.html
++- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
++- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
++- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
++- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
++- added a FAQ file
++
++plus many changes for portability.
++
++Unsupported third party contributions are provided in directory "contrib".
++
++A Java implementation of zlib is available in the Java Development Kit 1.1
++http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
++See the zlib home page http://www.cdrom.com/pub/infozip/zlib/ for details.
++
++A Perl interface to zlib written by Paul Marquess <pmarquess@bfsec.bt.co.uk>
++is in the CPAN (Comprehensive Perl Archive Network) sites, such as:
++ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
++
++A Python interface to zlib written by A.M. Kuchling <amk@magnet.com>
++is available in Python 1.5 and later versions, see
++http://www.python.org/doc/lib/module-zlib.html
++
++A zlib binding for TCL written by Andreas Kupries <a.kupries@westend.com>
++is availlable at http://www.westend.com/~kupries/doc/trf/man/man.html
++
++An experimental package to read and write files in .zip format,
++written on top of zlib by Gilles Vollant <info@winimage.com>, is
++available at http://www.winimage.com/zLibDll/unzip.html
++and also in the contrib/minizip directory of zlib.
++
++
++Notes for some targets:
++
++- To build a Windows DLL version, include in a DLL project zlib.def, zlib.rc
++  and all .c files except example.c and minigzip.c; compile with -DZLIB_DLL
++  The zlib DLL support was initially done by Alessandro Iacopetti and is
++  now maintained by Gilles Vollant <info@winimage.com>. Check the zlib DLL
++  home page at http://www.winimage.com/zLibDll
++
++  From Visual Basic, you can call the DLL functions which do not take
++  a structure as argument: compress, uncompress and all gz* functions.
++  See contrib/visual-basic.txt for more information, or get
++  http://www.tcfb.com/dowseware/cmp-z-it.zip
++
++- For 64-bit Irix, deflate.c must be compiled without any optimization.
++  With -O, one libpng test fails. The test works in 32 bit mode (with
++  the -n32 compiler flag). The compiler bug has been reported to SGI.
++
++- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1   
++  it works when compiled with cc.
++
++- on Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1
++  is necessary to get gzprintf working correctly. This is done by configure.
++
++- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works
++  with other compilers. Use "make test" to check your compiler.
++
++- gzdopen is not supported on RISCOS, BEOS and by some Mac compilers.
++
++- For Turbo C the small model is supported only with reduced performance to
++  avoid any far allocation; it was tested with -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
++
++- For PalmOs, see http://www.cs.uit.no/~perm/PASTA/pilot/software.html
++  Per Harald Myrvang <perm@stud.cs.uit.no>
++
++
++Acknowledgments:
++
++  The deflate format used by zlib was defined by Phil Katz. The deflate
++  and zlib specifications were written by L. Peter Deutsch. Thanks to all the
++  people who reported problems and suggested various improvements in zlib;
++  they are too numerous to cite here.
++
++Copyright notice:
++
++ (C) 1995-1998 Jean-loup Gailly and Mark Adler
++
++  This software is provided 'as-is', without any express or implied
++  warranty.  In no event will the authors be held liable for any damages
++  arising from the use of this software.
++
++  Permission is granted to anyone to use this software for any purpose,
++  including commercial applications, and to alter it and redistribute it
++  freely, subject to the following restrictions:
++
++  1. The origin of this software must not be misrepresented; you must not
++     claim that you wrote the original software. If you use this software
++     in a product, an acknowledgment in the product documentation would be
++     appreciated but is not required.
++  2. Altered source versions must be plainly marked as such, and must not be
++     misrepresented as being the original software.
++  3. This notice may not be removed or altered from any source distribution.
++
++  Jean-loup Gailly        Mark Adler
++  jloup@gzip.org          madler@alumni.caltech.edu
++
++If you use the zlib library in a product, we would appreciate *not*
++receiving lengthy legal documents to sign. The sources are provided
++for free but without warranty of any kind.  The library has been
++entirely written by Jean-loup Gailly and Mark Adler; it does not
++include third-party code.
++
++If you redistribute modified sources, we would appreciate that you include
++in the file ChangeLog history information documenting your changes.
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..16cf9a703f7cdedc6715db64715254780ad6414d
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,48 @@@
++/* adler32.c -- compute the Adler-32 checksum of a data stream
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#include "zlib.h"
++
++#define BASE 65521L /* largest prime smaller than 65536 */
++#define NMAX 5552
++/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
++
++#define DO1(buf,i)  {s1 += buf[i]; s2 += s1;}
++#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
++#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
++#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
++#define DO16(buf)   DO8(buf,0); DO8(buf,8);
++
++/* ========================================================================= */
++uLong ZEXPORT adler32(adler, buf, len)
++    uLong adler;
++    const Bytef *buf;
++    uInt len;
++{
++    unsigned long s1 = adler & 0xffff;
++    unsigned long s2 = (adler >> 16) & 0xffff;
++    int k;
++
++    if (buf == Z_NULL) return 1L;
++
++    while (len > 0) {
++        k = len < NMAX ? len : NMAX;
++        len -= k;
++        while (k >= 16) {
++            DO16(buf);
++          buf += 16;
++            k -= 16;
++        }
++        if (k != 0) do {
++            s1 += *buf++;
++          s2 += s1;
++        } while (--k);
++        s1 %= BASE;
++        s2 %= BASE;
++    }
++    return (s2 << 16) | s1;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..cdc830b5deb8fbbcd41b653db1bb078d95854776
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,213 @@@
++1. Compression algorithm (deflate)
++
++The deflation algorithm used by gzip (also zip and zlib) is a variation of
++LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
++the input data.  The second occurrence of a string is replaced by a
++pointer to the previous string, in the form of a pair (distance,
++length).  Distances are limited to 32K bytes, and lengths are limited
++to 258 bytes. When a string does not occur anywhere in the previous
++32K bytes, it is emitted as a sequence of literal bytes.  (In this
++description, `string' must be taken as an arbitrary sequence of bytes,
++and is not restricted to printable characters.)
++
++Literals or match lengths are compressed with one Huffman tree, and
++match distances are compressed with another tree. The trees are stored
++in a compact form at the start of each block. The blocks can have any
++size (except that the compressed data for one block must fit in
++available memory). A block is terminated when deflate() determines that
++it would be useful to start another block with fresh trees. (This is
++somewhat similar to the behavior of LZW-based _compress_.)
++
++Duplicated strings are found using a hash table. All input strings of
++length 3 are inserted in the hash table. A hash index is computed for
++the next 3 bytes. If the hash chain for this index is not empty, all
++strings in the chain are compared with the current input string, and
++the longest match is selected.
++
++The hash chains are searched starting with the most recent strings, to
++favor small distances and thus take advantage of the Huffman encoding.
++The hash chains are singly linked. There are no deletions from the
++hash chains, the algorithm simply discards matches that are too old.
++
++To avoid a worst-case situation, very long hash chains are arbitrarily
++truncated at a certain length, determined by a runtime option (level
++parameter of deflateInit). So deflate() does not always find the longest
++possible match but generally finds a match which is long enough.
++
++deflate() also defers the selection of matches with a lazy evaluation
++mechanism. After a match of length N has been found, deflate() searches for
++a longer match at the next input byte. If a longer match is found, the
++previous match is truncated to a length of one (thus producing a single
++literal byte) and the process of lazy evaluation begins again. Otherwise,
++the original match is kept, and the next match search is attempted only N
++steps later.
++
++The lazy match evaluation is also subject to a runtime parameter. If
++the current match is long enough, deflate() reduces the search for a longer
++match, thus speeding up the whole process. If compression ratio is more
++important than speed, deflate() attempts a complete second search even if
++the first match is already long enough.
++
++The lazy match evaluation is not performed for the fastest compression
++modes (level parameter 1 to 3). For these fast modes, new strings
++are inserted in the hash table only when no match was found, or
++when the match is not too long. This degrades the compression ratio
++but saves time since there are both fewer insertions and fewer searches.
++
++
++2. Decompression algorithm (inflate)
++
++2.1 Introduction
++
++The real question is, given a Huffman tree, how to decode fast.  The most
++important realization is that shorter codes are much more common than
++longer codes, so pay attention to decoding the short codes fast, and let
++the long codes take longer to decode.
++
++inflate() sets up a first level table that covers some number of bits of
++input less than the length of longest code.  It gets that many bits from the
++stream, and looks it up in the table.  The table will tell if the next
++code is that many bits or less and how many, and if it is, it will tell
++the value, else it will point to the next level table for which inflate()
++grabs more bits and tries to decode a longer code.
++
++How many bits to make the first lookup is a tradeoff between the time it
++takes to decode and the time it takes to build the table.  If building the
++table took no time (and if you had infinite memory), then there would only
++be a first level table to cover all the way to the longest code.  However,
++building the table ends up taking a lot longer for more bits since short
++codes are replicated many times in such a table.  What inflate() does is
++simply to make the number of bits in the first table a variable, and set it
++for the maximum speed.
++
++inflate() sends new trees relatively often, so it is possibly set for a
++smaller first level table than an application that has only one tree for
++all the data.  For inflate, which has 286 possible codes for the
++literal/length tree, the size of the first table is nine bits.  Also the
++distance trees have 30 possible values, and the size of the first table is
++six bits.  Note that for each of those cases, the table ended up one bit
++longer than the ``average'' code length, i.e. the code length of an
++approximately flat code which would be a little more than eight bits for
++286 symbols and a little less than five bits for 30 symbols.  It would be
++interesting to see if optimizing the first level table for other
++applications gave values within a bit or two of the flat code size.
++
++
++2.2 More details on the inflate table lookup
++
++Ok, you want to know what this cleverly obfuscated inflate tree actually  
++looks like.  You are correct that it's not a Huffman tree.  It is simply a  
++lookup table for the first, let's say, nine bits of a Huffman symbol.  The  
++symbol could be as short as one bit or as long as 15 bits.  If a particular  
++symbol is shorter than nine bits, then that symbol's translation is duplicated
++in all those entries that start with that symbol's bits.  For example, if the  
++symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a  
++symbol is nine bits long, it appears in the table once.
++
++If the symbol is longer than nine bits, then that entry in the table points  
++to another similar table for the remaining bits.  Again, there are duplicated  
++entries as needed.  The idea is that most of the time the symbol will be short
++and there will only be one table look up.  (That's whole idea behind data  
++compression in the first place.)  For the less frequent long symbols, there  
++will be two lookups.  If you had a compression method with really long  
++symbols, you could have as many levels of lookups as is efficient.  For  
++inflate, two is enough.
++
++So a table entry either points to another table (in which case nine bits in  
++the above example are gobbled), or it contains the translation for the symbol  
++and the number of bits to gobble.  Then you start again with the next  
++ungobbled bit.
++
++You may wonder: why not just have one lookup table for how ever many bits the  
++longest symbol is?  The reason is that if you do that, you end up spending  
++more time filling in duplicate symbol entries than you do actually decoding.   
++At least for deflate's output that generates new trees every several 10's of  
++kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code  
++would take too long if you're only decoding several thousand symbols.  At the  
++other extreme, you could make a new table for every bit in the code.  In fact,
++that's essentially a Huffman tree.  But then you spend two much time  
++traversing the tree while decoding, even for short symbols.
++
++So the number of bits for the first lookup table is a trade of the time to  
++fill out the table vs. the time spent looking at the second level and above of
++the table.
++
++Here is an example, scaled down:
++
++The code being decoded, with 10 symbols, from 1 to 6 bits long:
++
++A: 0
++B: 10
++C: 1100
++D: 11010
++E: 11011
++F: 11100
++G: 11101
++H: 11110
++I: 111110
++J: 111111
++
++Let's make the first table three bits long (eight entries):
++
++000: A,1
++001: A,1
++010: A,1
++011: A,1
++100: B,2
++101: B,2
++110: -> table X (gobble 3 bits)
++111: -> table Y (gobble 3 bits)
++
++Each entry is what the bits decode to and how many bits that is, i.e. how  
++many bits to gobble.  Or the entry points to another table, with the number of
++bits to gobble implicit in the size of the table.
++
++Table X is two bits long since the longest code starting with 110 is five bits
++long:
++
++00: C,1
++01: C,1
++10: D,2
++11: E,2
++
++Table Y is three bits long since the longest code starting with 111 is six  
++bits long:
++
++000: F,2
++001: F,2
++010: G,2
++011: G,2
++100: H,2
++101: H,2
++110: I,3
++111: J,3
++
++So what we have here are three tables with a total of 20 entries that had to  
++be constructed.  That's compared to 64 entries for a single table.  Or  
++compared to 16 entries for a Huffman tree (six two entry tables and one four  
++entry table).  Assuming that the code ideally represents the probability of  
++the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
++to one lookup for the single table, or 1.66 lookups per symbol for the  
++Huffman tree.
++
++There, I think that gives you a picture of what's going on.  For inflate, the  
++meaning of a particular symbol is often more than just a letter.  It can be a  
++byte (a "literal"), or it can be either a length or a distance which  
++indicates a base value and a number of bits to fetch after the code that is  
++added to the base value.  Or it might be the special end-of-block code.  The  
++data structures created in inftrees.c try to encode all that information  
++compactly in the tables.
++
++
++Jean-loup Gailly        Mark Adler
++jloup@gzip.org          madler@alumni.caltech.edu
++
++
++References:
++
++[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
++Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
++pp. 337-343.
++
++``DEFLATE Compressed Data Format Specification'' available in
++ftp://ds.internic.net/rfc/rfc1951.txt
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..1cee470913d75a3fa74c998c5638920fc382ec07
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,68 @@@
++/* compress.c -- compress a memory buffer
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#include "zlib.h"
++
++/* ===========================================================================
++     Compresses the source buffer into the destination buffer. The level
++   parameter has the same meaning as in deflateInit.  sourceLen is the byte
++   length of the source buffer. Upon entry, destLen is the total size of the
++   destination buffer, which must be at least 0.1% larger than sourceLen plus
++   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
++
++     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
++   Z_STREAM_ERROR if the level parameter is invalid.
++*/
++int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
++    Bytef *dest;
++    uLongf *destLen;
++    const Bytef *source;
++    uLong sourceLen;
++    int level;
++{
++    z_stream stream;
++    int err;
++
++    stream.next_in = (Bytef*)source;
++    stream.avail_in = (uInt)sourceLen;
++#ifdef MAXSEG_64K
++    /* Check for source > 64K on 16-bit machine: */
++    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
++#endif
++    stream.next_out = dest;
++    stream.avail_out = (uInt)*destLen;
++    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
++
++    stream.zalloc = (alloc_func)0;
++    stream.zfree = (free_func)0;
++    stream.opaque = (voidpf)0;
++
++    err = deflateInit(&stream, level);
++    if (err != Z_OK) return err;
++
++    err = deflate(&stream, Z_FINISH);
++    if (err != Z_STREAM_END) {
++        deflateEnd(&stream);
++        return err == Z_OK ? Z_BUF_ERROR : err;
++    }
++    *destLen = stream.total_out;
++
++    err = deflateEnd(&stream);
++    return err;
++}
++
++/* ===========================================================================
++ */
++int ZEXPORT compress (dest, destLen, source, sourceLen)
++    Bytef *dest;
++    uLongf *destLen;
++    const Bytef *source;
++    uLong sourceLen;
++{
++    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..a91101a81c6ae58913d5f3266e8da4ff75eda936
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,162 @@@
++/* crc32.c -- compute the CRC-32 of a data stream
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#include "zlib.h"
++
++#define local static
++
++#ifdef DYNAMIC_CRC_TABLE
++
++local int crc_table_empty = 1;
++local uLongf crc_table[256];
++local void make_crc_table OF((void));
++
++/*
++  Generate a table for a byte-wise 32-bit CRC calculation on the polynomial:
++  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
++
++  Polynomials over GF(2) are represented in binary, one bit per coefficient,
++  with the lowest powers in the most significant bit.  Then adding polynomials
++  is just exclusive-or, and multiplying a polynomial by x is a right shift by
++  one.  If we call the above polynomial p, and represent a byte as the
++  polynomial q, also with the lowest power in the most significant bit (so the
++  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
++  where a mod b means the remainder after dividing a by b.
++
++  This calculation is done using the shift-register method of multiplying and
++  taking the remainder.  The register is initialized to zero, and for each
++  incoming bit, x^32 is added mod p to the register if the bit is a one (where
++  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
++  x (which is shifting right by one and adding x^32 mod p if the bit shifted
++  out is a one).  We start with the highest power (least significant bit) of
++  q and repeat for all eight bits of q.
++
++  The table is simply the CRC of all possible eight bit values.  This is all
++  the information needed to generate CRC's on data a byte at a time for all
++  combinations of CRC register values and incoming bytes.
++*/
++local void make_crc_table()
++{
++  uLong c;
++  int n, k;
++  uLong poly;            /* polynomial exclusive-or pattern */
++  /* terms of polynomial defining this crc (except x^32): */
++  static const Byte p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
++
++  /* make exclusive-or pattern from polynomial (0xedb88320L) */
++  poly = 0L;
++  for (n = 0; n < sizeof(p)/sizeof(Byte); n++)
++    poly |= 1L << (31 - p[n]);
++ 
++  for (n = 0; n < 256; n++)
++  {
++    c = (uLong)n;
++    for (k = 0; k < 8; k++)
++      c = c & 1 ? poly ^ (c >> 1) : c >> 1;
++    crc_table[n] = c;
++  }
++  crc_table_empty = 0;
++}
++#else
++/* ========================================================================
++ * Table of CRC-32's of all single-byte values (made by make_crc_table)
++ */
++local const uLongf crc_table[256] = {
++  0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
++  0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
++  0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
++  0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
++  0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
++  0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
++  0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
++  0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
++  0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
++  0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
++  0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
++  0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
++  0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
++  0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
++  0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
++  0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
++  0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
++  0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
++  0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
++  0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
++  0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
++  0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
++  0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
++  0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
++  0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
++  0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
++  0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
++  0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
++  0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
++  0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
++  0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
++  0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
++  0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
++  0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
++  0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
++  0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
++  0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
++  0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
++  0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
++  0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
++  0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
++  0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
++  0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
++  0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
++  0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
++  0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
++  0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
++  0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
++  0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
++  0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
++  0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
++  0x2d02ef8dL
++};
++#endif
++
++/* =========================================================================
++ * This function can be used by asm versions of crc32()
++ */
++const uLongf * ZEXPORT get_crc_table()
++{
++#ifdef DYNAMIC_CRC_TABLE
++  if (crc_table_empty) make_crc_table();
++#endif
++  return (const uLongf *)crc_table;
++}
++
++/* ========================================================================= */
++#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
++#define DO2(buf)  DO1(buf); DO1(buf);
++#define DO4(buf)  DO2(buf); DO2(buf);
++#define DO8(buf)  DO4(buf); DO4(buf);
++
++/* ========================================================================= */
++uLong ZEXPORT crc32(crc, buf, len)
++    uLong crc;
++    const Bytef *buf;
++    uInt len;
++{
++    if (buf == Z_NULL) return 0L;
++#ifdef DYNAMIC_CRC_TABLE
++    if (crc_table_empty)
++      make_crc_table();
++#endif
++    crc = crc ^ 0xffffffffL;
++    while (len >= 8)
++    {
++      DO8(buf);
++      len -= 8;
++    }
++    if (len) do {
++      DO1(buf);
++    } while (--len);
++    return crc ^ 0xffffffffL;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..25d5818e2ece934bfa178d6cf9de7c951876f2da
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1350 @@@
++/* deflate.c -- compress data using the deflation algorithm
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/*
++ *  ALGORITHM
++ *
++ *      The "deflation" process depends on being able to identify portions
++ *      of the input text which are identical to earlier input (within a
++ *      sliding window trailing behind the input currently being processed).
++ *
++ *      The most straightforward technique turns out to be the fastest for
++ *      most input files: try all possible matches and select the longest.
++ *      The key feature of this algorithm is that insertions into the string
++ *      dictionary are very simple and thus fast, and deletions are avoided
++ *      completely. Insertions are performed at each input character, whereas
++ *      string matches are performed only when the previous match ends. So it
++ *      is preferable to spend more time in matches to allow very fast string
++ *      insertions and avoid deletions. The matching algorithm for small
++ *      strings is inspired from that of Rabin & Karp. A brute force approach
++ *      is used to find longer strings when a small match has been found.
++ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
++ *      (by Leonid Broukhis).
++ *         A previous version of this file used a more sophisticated algorithm
++ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
++ *      time, but has a larger average cost, uses more memory and is patented.
++ *      However the F&G algorithm may be faster for some highly redundant
++ *      files if the parameter max_chain_length (described below) is too large.
++ *
++ *  ACKNOWLEDGEMENTS
++ *
++ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
++ *      I found it in 'freeze' written by Leonid Broukhis.
++ *      Thanks to many people for bug reports and testing.
++ *
++ *  REFERENCES
++ *
++ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
++ *      Available in ftp://ds.internic.net/rfc/rfc1951.txt
++ *
++ *      A description of the Rabin and Karp algorithm is given in the book
++ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
++ *
++ *      Fiala,E.R., and Greene,D.H.
++ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
++ *
++ */
++
++/* @(#) $Id$ */
++
++#include "deflate.h"
++
++const char deflate_copyright[] =
++   " deflate 1.1.3 Copyright 1995-1998 Jean-loup Gailly ";
++/*
++  If you use the zlib library in a product, an acknowledgment is welcome
++  in the documentation of your product. If for some reason you cannot
++  include such an acknowledgment, I would appreciate that you keep this
++  copyright string in the executable of your product.
++ */
++
++/* ===========================================================================
++ *  Function prototypes.
++ */
++typedef enum {
++    need_more,      /* block not completed, need more input or more output */
++    block_done,     /* block flush performed */
++    finish_started, /* finish started, need only more output at next deflate */
++    finish_done     /* finish done, accept no more input or output */
++} block_state;
++
++typedef block_state (*compress_func) OF((deflate_state *s, int flush));
++/* Compression function. Returns the block state after the call. */
++
++local void fill_window    OF((deflate_state *s));
++local block_state deflate_stored OF((deflate_state *s, int flush));
++local block_state deflate_fast   OF((deflate_state *s, int flush));
++local block_state deflate_slow   OF((deflate_state *s, int flush));
++local void lm_init        OF((deflate_state *s));
++local void putShortMSB    OF((deflate_state *s, uInt b));
++local void flush_pending  OF((z_streamp strm));
++local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
++#ifdef ASMV
++      void match_init OF((void)); /* asm code initialization */
++      uInt longest_match  OF((deflate_state *s, IPos cur_match));
++#else
++local uInt longest_match  OF((deflate_state *s, IPos cur_match));
++#endif
++
++#ifdef DEBUG
++local  void check_match OF((deflate_state *s, IPos start, IPos match,
++                            int length));
++#endif
++
++/* ===========================================================================
++ * Local data
++ */
++
++#define NIL 0
++/* Tail of hash chains */
++
++#ifndef TOO_FAR
++#  define TOO_FAR 4096
++#endif
++/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
++
++#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
++/* Minimum amount of lookahead, except at the end of the input file.
++ * See deflate.c for comments about the MIN_MATCH+1.
++ */
++
++/* Values for max_lazy_match, good_match and max_chain_length, depending on
++ * the desired pack level (0..9). The values given below have been tuned to
++ * exclude worst case performance for pathological files. Better values may be
++ * found for specific files.
++ */
++typedef struct config_s {
++   ush good_length; /* reduce lazy search above this match length */
++   ush max_lazy;    /* do not perform lazy search above this match length */
++   ush nice_length; /* quit search above this match length */
++   ush max_chain;
++   compress_func func;
++} config;
++
++local const config configuration_table[10] = {
++/*      good lazy nice chain */
++/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
++/* 1 */ {4,    4,  8,    4, deflate_fast}, /* maximum speed, no lazy matches */
++/* 2 */ {4,    5, 16,    8, deflate_fast},
++/* 3 */ {4,    6, 32,   32, deflate_fast},
++
++/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
++/* 5 */ {8,   16, 32,   32, deflate_slow},
++/* 6 */ {8,   16, 128, 128, deflate_slow},
++/* 7 */ {8,   32, 128, 256, deflate_slow},
++/* 8 */ {32, 128, 258, 1024, deflate_slow},
++/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* maximum compression */
++
++/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
++ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
++ * meaning.
++ */
++
++#define EQUAL 0
++/* result of memcmp for equal strings */
++
++struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
++
++/* ===========================================================================
++ * Update a hash value with the given input byte
++ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
++ *    input characters, so that a running hash key can be computed from the
++ *    previous key instead of complete recalculation each time.
++ */
++#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
++
++
++/* ===========================================================================
++ * Insert string str in the dictionary and set match_head to the previous head
++ * of the hash chain (the most recent string with same hash key). Return
++ * the previous length of the hash chain.
++ * If this file is compiled with -DFASTEST, the compression level is forced
++ * to 1, and no hash chains are maintained.
++ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
++ *    input characters and the first MIN_MATCH bytes of str are valid
++ *    (except for the last MIN_MATCH-1 bytes of the input file).
++ */
++#ifdef FASTEST
++#define INSERT_STRING(s, str, match_head) \
++   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
++    match_head = s->head[s->ins_h], \
++    s->head[s->ins_h] = (Pos)(str))
++#else
++#define INSERT_STRING(s, str, match_head) \
++   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
++    s->prev[(str) & s->w_mask] = match_head = s->head[s->ins_h], \
++    s->head[s->ins_h] = (Pos)(str))
++#endif
++
++/* ===========================================================================
++ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
++ * prev[] will be initialized on the fly.
++ */
++#define CLEAR_HASH(s) \
++    s->head[s->hash_size-1] = NIL; \
++    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
++
++/* ========================================================================= */
++int ZEXPORT deflateInit_(strm, level, version, stream_size)
++    z_streamp strm;
++    int level;
++    const char *version;
++    int stream_size;
++{
++    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
++                       Z_DEFAULT_STRATEGY, version, stream_size);
++    /* To do: ignore strm->next_in if we use it as window */
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
++                version, stream_size)
++    z_streamp strm;
++    int  level;
++    int  method;
++    int  windowBits;
++    int  memLevel;
++    int  strategy;
++    const char *version;
++    int stream_size;
++{
++    deflate_state *s;
++    int noheader = 0;
++    static const char* my_version = ZLIB_VERSION;
++
++    ushf *overlay;
++    /* We overlay pending_buf and d_buf+l_buf. This works since the average
++     * output size for (length,distance) codes is <= 24 bits.
++     */
++
++    if (version == Z_NULL || version[0] != my_version[0] ||
++        stream_size != sizeof(z_stream)) {
++      return Z_VERSION_ERROR;
++    }
++    if (strm == Z_NULL) return Z_STREAM_ERROR;
++
++    strm->msg = Z_NULL;
++    if (strm->zalloc == Z_NULL) {
++      strm->zalloc = zcalloc;
++      strm->opaque = (voidpf)0;
++    }
++    if (strm->zfree == Z_NULL) strm->zfree = zcfree;
++
++    if (level == Z_DEFAULT_COMPRESSION) level = 6;
++#ifdef FASTEST
++    level = 1;
++#endif
++
++    if (windowBits < 0) { /* undocumented feature: suppress zlib header */
++        noheader = 1;
++        windowBits = -windowBits;
++    }
++    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
++        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
++      strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
++        return Z_STREAM_ERROR;
++    }
++    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
++    if (s == Z_NULL) return Z_MEM_ERROR;
++    strm->state = (struct internal_state FAR *)s;
++    s->strm = strm;
++
++    s->noheader = noheader;
++    s->w_bits = windowBits;
++    s->w_size = 1 << s->w_bits;
++    s->w_mask = s->w_size - 1;
++
++    s->hash_bits = memLevel + 7;
++    s->hash_size = 1 << s->hash_bits;
++    s->hash_mask = s->hash_size - 1;
++    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
++
++    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
++    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
++    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
++
++    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
++
++    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
++    s->pending_buf = (uchf *) overlay;
++    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
++
++    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
++        s->pending_buf == Z_NULL) {
++        strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
++        deflateEnd (strm);
++        return Z_MEM_ERROR;
++    }
++    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
++    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
++
++    s->level = level;
++    s->strategy = strategy;
++    s->method = (Byte)method;
++
++    return deflateReset(strm);
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
++    z_streamp strm;
++    const Bytef *dictionary;
++    uInt  dictLength;
++{
++    deflate_state *s;
++    uInt length = dictLength;
++    uInt n;
++    IPos hash_head = 0;
++
++    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
++        strm->state->status != INIT_STATE) return Z_STREAM_ERROR;
++
++    s = strm->state;
++    strm->adler = adler32(strm->adler, dictionary, dictLength);
++
++    if (length < MIN_MATCH) return Z_OK;
++    if (length > MAX_DIST(s)) {
++      length = MAX_DIST(s);
++#ifndef USE_DICT_HEAD
++      dictionary += dictLength - length; /* use the tail of the dictionary */
++#endif
++    }
++    zmemcpy(s->window, dictionary, length);
++    s->strstart = length;
++    s->block_start = (long)length;
++
++    /* Insert all strings in the hash table (except for the last two bytes).
++     * s->lookahead stays null, so s->ins_h will be recomputed at the next
++     * call of fill_window.
++     */
++    s->ins_h = s->window[0];
++    UPDATE_HASH(s, s->ins_h, s->window[1]);
++    for (n = 0; n <= length - MIN_MATCH; n++) {
++      INSERT_STRING(s, n, hash_head);
++    }
++    if (hash_head) hash_head = 0;  /* to make compiler happy */
++    return Z_OK;
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateReset (strm)
++    z_streamp strm;
++{
++    deflate_state *s;
++    
++    if (strm == Z_NULL || strm->state == Z_NULL ||
++        strm->zalloc == Z_NULL || strm->zfree == Z_NULL) return Z_STREAM_ERROR;
++
++    strm->total_in = strm->total_out = 0;
++    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
++    strm->data_type = Z_UNKNOWN;
++
++    s = (deflate_state *)strm->state;
++    s->pending = 0;
++    s->pending_out = s->pending_buf;
++
++    if (s->noheader < 0) {
++        s->noheader = 0; /* was set to -1 by deflate(..., Z_FINISH); */
++    }
++    s->status = s->noheader ? BUSY_STATE : INIT_STATE;
++    strm->adler = 1;
++    s->last_flush = Z_NO_FLUSH;
++
++    _tr_init(s);
++    lm_init(s);
++
++    return Z_OK;
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateParams(strm, level, strategy)
++    z_streamp strm;
++    int level;
++    int strategy;
++{
++    deflate_state *s;
++    compress_func func;
++    int err = Z_OK;
++
++    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
++    s = strm->state;
++
++    if (level == Z_DEFAULT_COMPRESSION) {
++      level = 6;
++    }
++    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_HUFFMAN_ONLY) {
++      return Z_STREAM_ERROR;
++    }
++    func = configuration_table[s->level].func;
++
++    if (func != configuration_table[level].func && strm->total_in != 0) {
++      /* Flush the last buffer: */
++      err = deflate(strm, Z_PARTIAL_FLUSH);
++    }
++    if (s->level != level) {
++      s->level = level;
++      s->max_lazy_match   = configuration_table[level].max_lazy;
++      s->good_match       = configuration_table[level].good_length;
++      s->nice_match       = configuration_table[level].nice_length;
++      s->max_chain_length = configuration_table[level].max_chain;
++    }
++    s->strategy = strategy;
++    return err;
++}
++
++/* =========================================================================
++ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
++ * IN assertion: the stream state is correct and there is enough room in
++ * pending_buf.
++ */
++local void putShortMSB (s, b)
++    deflate_state *s;
++    uInt b;
++{
++    put_byte(s, (Byte)(b >> 8));
++    put_byte(s, (Byte)(b & 0xff));
++}   
++
++/* =========================================================================
++ * Flush as much pending output as possible. All deflate() output goes
++ * through this function so some applications may wish to modify it
++ * to avoid allocating a large strm->next_out buffer and copying into it.
++ * (See also read_buf()).
++ */
++local void flush_pending(strm)
++    z_streamp strm;
++{
++    unsigned len = strm->state->pending;
++
++    if (len > strm->avail_out) len = strm->avail_out;
++    if (len == 0) return;
++
++    zmemcpy(strm->next_out, strm->state->pending_out, len);
++    strm->next_out  += len;
++    strm->state->pending_out  += len;
++    strm->total_out += len;
++    strm->avail_out  -= len;
++    strm->state->pending -= len;
++    if (strm->state->pending == 0) {
++        strm->state->pending_out = strm->state->pending_buf;
++    }
++}
++
++/* ========================================================================= */
++int ZEXPORT deflate (strm, flush)
++    z_streamp strm;
++    int flush;
++{
++    int old_flush; /* value of flush param for previous deflate call */
++    deflate_state *s;
++
++    if (strm == Z_NULL || strm->state == Z_NULL ||
++      flush > Z_FINISH || flush < 0) {
++        return Z_STREAM_ERROR;
++    }
++    s = strm->state;
++
++    if (strm->next_out == Z_NULL ||
++        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
++      (s->status == FINISH_STATE && flush != Z_FINISH)) {
++        ERR_RETURN(strm, Z_STREAM_ERROR);
++    }
++    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
++
++    s->strm = strm; /* just in case */
++    old_flush = s->last_flush;
++    s->last_flush = flush;
++
++    /* Write the zlib header */
++    if (s->status == INIT_STATE) {
++
++        uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
++        uInt level_flags = (s->level-1) >> 1;
++
++        if (level_flags > 3) level_flags = 3;
++        header |= (level_flags << 6);
++      if (s->strstart != 0) header |= PRESET_DICT;
++        header += 31 - (header % 31);
++
++        s->status = BUSY_STATE;
++        putShortMSB(s, header);
++
++      /* Save the adler32 of the preset dictionary: */
++      if (s->strstart != 0) {
++          putShortMSB(s, (uInt)(strm->adler >> 16));
++          putShortMSB(s, (uInt)(strm->adler & 0xffff));
++      }
++      strm->adler = 1L;
++    }
++
++    /* Flush as much pending output as possible */
++    if (s->pending != 0) {
++        flush_pending(strm);
++        if (strm->avail_out == 0) {
++          /* Since avail_out is 0, deflate will be called again with
++           * more output space, but possibly with both pending and
++           * avail_in equal to zero. There won't be anything to do,
++           * but this is not an error situation so make sure we
++           * return OK instead of BUF_ERROR at next call of deflate:
++             */
++          s->last_flush = -1;
++          return Z_OK;
++      }
++
++    /* Make sure there is something to do and avoid duplicate consecutive
++     * flushes. For repeated and useless calls with Z_FINISH, we keep
++     * returning Z_STREAM_END instead of Z_BUFF_ERROR.
++     */
++    } else if (strm->avail_in == 0 && flush <= old_flush &&
++             flush != Z_FINISH) {
++        ERR_RETURN(strm, Z_BUF_ERROR);
++    }
++
++    /* User must not provide more input after the first FINISH: */
++    if (s->status == FINISH_STATE && strm->avail_in != 0) {
++        ERR_RETURN(strm, Z_BUF_ERROR);
++    }
++
++    /* Start a new block or continue the current one.
++     */
++    if (strm->avail_in != 0 || s->lookahead != 0 ||
++        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
++        block_state bstate;
++
++      bstate = (*(configuration_table[s->level].func))(s, flush);
++
++        if (bstate == finish_started || bstate == finish_done) {
++            s->status = FINISH_STATE;
++        }
++        if (bstate == need_more || bstate == finish_started) {
++          if (strm->avail_out == 0) {
++              s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
++          }
++          return Z_OK;
++          /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
++           * of deflate should use the same flush parameter to make sure
++           * that the flush is complete. So we don't have to output an
++           * empty block here, this will be done at next call. This also
++           * ensures that for a very small output buffer, we emit at most
++           * one empty block.
++           */
++      }
++        if (bstate == block_done) {
++            if (flush == Z_PARTIAL_FLUSH) {
++                _tr_align(s);
++            } else { /* FULL_FLUSH or SYNC_FLUSH */
++                _tr_stored_block(s, (char*)0, 0L, 0);
++                /* For a full flush, this empty block will be recognized
++                 * as a special marker by inflate_sync().
++                 */
++                if (flush == Z_FULL_FLUSH) {
++                    CLEAR_HASH(s);             /* forget history */
++                }
++            }
++            flush_pending(strm);
++          if (strm->avail_out == 0) {
++            s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
++            return Z_OK;
++          }
++        }
++    }
++    Assert(strm->avail_out > 0, "bug2");
++
++    if (flush != Z_FINISH) return Z_OK;
++    if (s->noheader) return Z_STREAM_END;
++
++    /* Write the zlib trailer (adler32) */
++    putShortMSB(s, (uInt)(strm->adler >> 16));
++    putShortMSB(s, (uInt)(strm->adler & 0xffff));
++    flush_pending(strm);
++    /* If avail_out is zero, the application will call deflate again
++     * to flush the rest.
++     */
++    s->noheader = -1; /* write the trailer only once! */
++    return s->pending != 0 ? Z_OK : Z_STREAM_END;
++}
++
++/* ========================================================================= */
++int ZEXPORT deflateEnd (strm)
++    z_streamp strm;
++{
++    int status;
++
++    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
++
++    status = strm->state->status;
++    if (status != INIT_STATE && status != BUSY_STATE &&
++      status != FINISH_STATE) {
++      return Z_STREAM_ERROR;
++    }
++
++    /* Deallocate in reverse order of allocations: */
++    TRY_FREE(strm, strm->state->pending_buf);
++    TRY_FREE(strm, strm->state->head);
++    TRY_FREE(strm, strm->state->prev);
++    TRY_FREE(strm, strm->state->window);
++
++    ZFREE(strm, strm->state);
++    strm->state = Z_NULL;
++
++    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
++}
++
++/* =========================================================================
++ * Copy the source state to the destination state.
++ * To simplify the source, this is not supported for 16-bit MSDOS (which
++ * doesn't have enough memory anyway to duplicate compression states).
++ */
++int ZEXPORT deflateCopy (dest, source)
++    z_streamp dest;
++    z_streamp source;
++{
++#ifdef MAXSEG_64K
++    return Z_STREAM_ERROR;
++#else
++    deflate_state *ds;
++    deflate_state *ss;
++    ushf *overlay;
++
++
++    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
++        return Z_STREAM_ERROR;
++    }
++
++    ss = source->state;
++
++    *dest = *source;
++
++    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
++    if (ds == Z_NULL) return Z_MEM_ERROR;
++    dest->state = (struct internal_state FAR *) ds;
++    *ds = *ss;
++    ds->strm = dest;
++
++    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
++    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
++    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
++    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
++    ds->pending_buf = (uchf *) overlay;
++
++    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
++        ds->pending_buf == Z_NULL) {
++        deflateEnd (dest);
++        return Z_MEM_ERROR;
++    }
++    /* following zmemcpy do not work for 16-bit MSDOS */
++    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
++    zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
++    zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
++    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
++
++    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
++    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
++    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
++
++    ds->l_desc.dyn_tree = ds->dyn_ltree;
++    ds->d_desc.dyn_tree = ds->dyn_dtree;
++    ds->bl_desc.dyn_tree = ds->bl_tree;
++
++    return Z_OK;
++#endif
++}
++
++/* ===========================================================================
++ * Read a new buffer from the current input stream, update the adler32
++ * and total number of bytes read.  All deflate() input goes through
++ * this function so some applications may wish to modify it to avoid
++ * allocating a large strm->next_in buffer and copying from it.
++ * (See also flush_pending()).
++ */
++local int read_buf(strm, buf, size)
++    z_streamp strm;
++    Bytef *buf;
++    unsigned size;
++{
++    unsigned len = strm->avail_in;
++
++    if (len > size) len = size;
++    if (len == 0) return 0;
++
++    strm->avail_in  -= len;
++
++    if (!strm->state->noheader) {
++        strm->adler = adler32(strm->adler, strm->next_in, len);
++    }
++    zmemcpy(buf, strm->next_in, len);
++    strm->next_in  += len;
++    strm->total_in += len;
++
++    return (int)len;
++}
++
++/* ===========================================================================
++ * Initialize the "longest match" routines for a new zlib stream
++ */
++local void lm_init (s)
++    deflate_state *s;
++{
++    s->window_size = (ulg)2L*s->w_size;
++
++    CLEAR_HASH(s);
++
++    /* Set the default configuration parameters:
++     */
++    s->max_lazy_match   = configuration_table[s->level].max_lazy;
++    s->good_match       = configuration_table[s->level].good_length;
++    s->nice_match       = configuration_table[s->level].nice_length;
++    s->max_chain_length = configuration_table[s->level].max_chain;
++
++    s->strstart = 0;
++    s->block_start = 0L;
++    s->lookahead = 0;
++    s->match_length = s->prev_length = MIN_MATCH-1;
++    s->match_available = 0;
++    s->ins_h = 0;
++#ifdef ASMV
++    match_init(); /* initialize the asm code */
++#endif
++}
++
++/* ===========================================================================
++ * Set match_start to the longest match starting at the given string and
++ * return its length. Matches shorter or equal to prev_length are discarded,
++ * in which case the result is equal to prev_length and match_start is
++ * garbage.
++ * IN assertions: cur_match is the head of the hash chain for the current
++ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
++ * OUT assertion: the match length is not greater than s->lookahead.
++ */
++#ifndef ASMV
++/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
++ * match.S. The code will be functionally equivalent.
++ */
++#ifndef FASTEST
++local uInt longest_match(s, cur_match)
++    deflate_state *s;
++    IPos cur_match;                             /* current match */
++{
++    unsigned chain_length = s->max_chain_length;/* max hash chain length */
++    register Bytef *scan = s->window + s->strstart; /* current string */
++    register Bytef *match;                       /* matched string */
++    register int len;                           /* length of current match */
++    int best_len = s->prev_length;              /* best match length so far */
++    int nice_match = s->nice_match;             /* stop if match long enough */
++    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
++        s->strstart - (IPos)MAX_DIST(s) : NIL;
++    /* Stop when cur_match becomes <= limit. To simplify the code,
++     * we prevent matches with the string of window index 0.
++     */
++    Posf *prev = s->prev;
++    uInt wmask = s->w_mask;
++
++#ifdef UNALIGNED_OK
++    /* Compare two bytes at a time. Note: this is not always beneficial.
++     * Try with and without -DUNALIGNED_OK to check.
++     */
++    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
++    register ush scan_start = *(ushf*)scan;
++    register ush scan_end   = *(ushf*)(scan+best_len-1);
++#else
++    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
++    register Byte scan_end1  = scan[best_len-1];
++    register Byte scan_end   = scan[best_len];
++#endif
++
++    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
++     * It is easy to get rid of this optimization if necessary.
++     */
++    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
++
++    /* Do not waste too much time if we already have a good match: */
++    if (s->prev_length >= s->good_match) {
++        chain_length >>= 2;
++    }
++    /* Do not look for matches beyond the end of the input. This is necessary
++     * to make deflate deterministic.
++     */
++    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
++
++    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
++
++    do {
++        Assert(cur_match < s->strstart, "no future");
++        match = s->window + cur_match;
++
++        /* Skip to next match if the match length cannot increase
++         * or if the match length is less than 2:
++         */
++#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
++        /* This code assumes sizeof(unsigned short) == 2. Do not use
++         * UNALIGNED_OK if your compiler uses a different size.
++         */
++        if (*(ushf*)(match+best_len-1) != scan_end ||
++            *(ushf*)match != scan_start) continue;
++
++        /* It is not necessary to compare scan[2] and match[2] since they are
++         * always equal when the other bytes match, given that the hash keys
++         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
++         * strstart+3, +5, ... up to strstart+257. We check for insufficient
++         * lookahead only every 4th comparison; the 128th check will be made
++         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
++         * necessary to put more guard bytes at the end of the window, or
++         * to check more often for insufficient lookahead.
++         */
++        Assert(scan[2] == match[2], "scan[2]?");
++        scan++, match++;
++        do {
++        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
++                 scan < strend);
++        /* The funny "do {}" generates better code on most compilers */
++
++        /* Here, scan <= window+strstart+257 */
++        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
++        if (*scan == *match) scan++;
++
++        len = (MAX_MATCH - 1) - (int)(strend-scan);
++        scan = strend - (MAX_MATCH-1);
++
++#else /* UNALIGNED_OK */
++
++        if (match[best_len]   != scan_end  ||
++            match[best_len-1] != scan_end1 ||
++            *match            != *scan     ||
++            *++match          != scan[1])      continue;
++
++        /* The check at best_len-1 can be removed because it will be made
++         * again later. (This heuristic is not always a win.)
++         * It is not necessary to compare scan[2] and match[2] since they
++         * are always equal when the other bytes match, given that
++         * the hash keys are equal and that HASH_BITS >= 8.
++         */
++        scan += 2, match++;
++        Assert(*scan == *match, "match[2]?");
++
++        /* We check for insufficient lookahead only every 8th comparison;
++         * the 256th check will be made at strstart+258.
++         */
++        do {
++        } while (*++scan == *++match && *++scan == *++match &&
++                 *++scan == *++match && *++scan == *++match &&
++                 *++scan == *++match && *++scan == *++match &&
++                 *++scan == *++match && *++scan == *++match &&
++                 scan < strend);
++
++        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
++
++        len = MAX_MATCH - (int)(strend - scan);
++        scan = strend - MAX_MATCH;
++
++#endif /* UNALIGNED_OK */
++
++        if (len > best_len) {
++            s->match_start = cur_match;
++            best_len = len;
++            if (len >= nice_match) break;
++#ifdef UNALIGNED_OK
++            scan_end = *(ushf*)(scan+best_len-1);
++#else
++            scan_end1  = scan[best_len-1];
++            scan_end   = scan[best_len];
++#endif
++        }
++    } while ((cur_match = prev[cur_match & wmask]) > limit
++             && --chain_length != 0);
++
++    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
++    return s->lookahead;
++}
++
++#else /* FASTEST */
++/* ---------------------------------------------------------------------------
++ * Optimized version for level == 1 only
++ */
++local uInt longest_match(s, cur_match)
++    deflate_state *s;
++    IPos cur_match;                             /* current match */
++{
++    register Bytef *scan = s->window + s->strstart; /* current string */
++    register Bytef *match;                       /* matched string */
++    register int len;                           /* length of current match */
++    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
++
++    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
++     * It is easy to get rid of this optimization if necessary.
++     */
++    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
++
++    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
++
++    Assert(cur_match < s->strstart, "no future");
++
++    match = s->window + cur_match;
++
++    /* Return failure if the match length is less than 2:
++     */
++    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
++
++    /* The check at best_len-1 can be removed because it will be made
++     * again later. (This heuristic is not always a win.)
++     * It is not necessary to compare scan[2] and match[2] since they
++     * are always equal when the other bytes match, given that
++     * the hash keys are equal and that HASH_BITS >= 8.
++     */
++    scan += 2, match += 2;
++    Assert(*scan == *match, "match[2]?");
++
++    /* We check for insufficient lookahead only every 8th comparison;
++     * the 256th check will be made at strstart+258.
++     */
++    do {
++    } while (*++scan == *++match && *++scan == *++match &&
++           *++scan == *++match && *++scan == *++match &&
++           *++scan == *++match && *++scan == *++match &&
++           *++scan == *++match && *++scan == *++match &&
++           scan < strend);
++
++    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
++
++    len = MAX_MATCH - (int)(strend - scan);
++
++    if (len < MIN_MATCH) return MIN_MATCH - 1;
++
++    s->match_start = cur_match;
++    return len <= s->lookahead ? len : s->lookahead;
++}
++#endif /* FASTEST */
++#endif /* ASMV */
++
++#ifdef DEBUG
++/* ===========================================================================
++ * Check that the match at match_start is indeed a match.
++ */
++local void check_match(s, start, match, length)
++    deflate_state *s;
++    IPos start, match;
++    int length;
++{
++    /* check that the match is indeed a match */
++    if (zmemcmp(s->window + match,
++                s->window + start, length) != EQUAL) {
++        fprintf(stderr, " start %u, match %u, length %d\n",
++              start, match, length);
++        do {
++          fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
++      } while (--length != 0);
++        z_error("invalid match");
++    }
++    if (z_verbose > 1) {
++        fprintf(stderr,"\\[%d,%d]", start-match, length);
++        do { putc(s->window[start++], stderr); } while (--length != 0);
++    }
++}
++#else
++#  define check_match(s, start, match, length)
++#endif
++
++/* ===========================================================================
++ * Fill the window when the lookahead becomes insufficient.
++ * Updates strstart and lookahead.
++ *
++ * IN assertion: lookahead < MIN_LOOKAHEAD
++ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
++ *    At least one byte has been read, or avail_in == 0; reads are
++ *    performed for at least two bytes (required for the zip translate_eol
++ *    option -- not supported here).
++ */
++local void fill_window(s)
++    deflate_state *s;
++{
++    register unsigned n, m;
++    register Posf *p;
++    unsigned more;    /* Amount of free space at the end of the window. */
++    uInt wsize = s->w_size;
++
++    do {
++        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
++
++        /* Deal with !@#$% 64K limit: */
++        if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
++            more = wsize;
++
++        } else if (more == (unsigned)(-1)) {
++            /* Very unlikely, but possible on 16 bit machine if strstart == 0
++             * and lookahead == 1 (input done one byte at time)
++             */
++            more--;
++
++        /* If the window is almost full and there is insufficient lookahead,
++         * move the upper half to the lower one to make room in the upper half.
++         */
++        } else if (s->strstart >= wsize+MAX_DIST(s)) {
++
++            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
++            s->match_start -= wsize;
++            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
++            s->block_start -= (long) wsize;
++
++            /* Slide the hash table (could be avoided with 32 bit values
++               at the expense of memory usage). We slide even when level == 0
++               to keep the hash table consistent if we switch back to level > 0
++               later. (Using level 0 permanently is not an optimal usage of
++               zlib, so we don't care about this pathological case.)
++             */
++          n = s->hash_size;
++          p = &s->head[n];
++          do {
++              m = *--p;
++              *p = (Pos)(m >= wsize ? m-wsize : NIL);
++          } while (--n);
++
++          n = wsize;
++#ifndef FASTEST
++          p = &s->prev[n];
++          do {
++              m = *--p;
++              *p = (Pos)(m >= wsize ? m-wsize : NIL);
++              /* If n is not on any hash chain, prev[n] is garbage but
++               * its value will never be used.
++               */
++          } while (--n);
++#endif
++            more += wsize;
++        }
++        if (s->strm->avail_in == 0) return;
++
++        /* If there was no sliding:
++         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
++         *    more == window_size - lookahead - strstart
++         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
++         * => more >= window_size - 2*WSIZE + 2
++         * In the BIG_MEM or MMAP case (not yet supported),
++         *   window_size == input_size + MIN_LOOKAHEAD  &&
++         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
++         * Otherwise, window_size == 2*WSIZE so more >= 2.
++         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
++         */
++        Assert(more >= 2, "more < 2");
++
++        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
++        s->lookahead += n;
++
++        /* Initialize the hash value now that we have some input: */
++        if (s->lookahead >= MIN_MATCH) {
++            s->ins_h = s->window[s->strstart];
++            UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
++#if MIN_MATCH != 3
++            Call UPDATE_HASH() MIN_MATCH-3 more times
++#endif
++        }
++        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
++         * but this is not important since only literal bytes will be emitted.
++         */
++
++    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
++}
++
++/* ===========================================================================
++ * Flush the current block, with given end-of-file flag.
++ * IN assertion: strstart is set to the end of the current match.
++ */
++#define FLUSH_BLOCK_ONLY(s, eof) { \
++   _tr_flush_block(s, (s->block_start >= 0L ? \
++                   (charf *)&s->window[(unsigned)s->block_start] : \
++                   (charf *)Z_NULL), \
++              (ulg)((long)s->strstart - s->block_start), \
++              (eof)); \
++   s->block_start = s->strstart; \
++   flush_pending(s->strm); \
++   Tracev((stderr,"[FLUSH]")); \
++}
++
++/* Same but force premature exit if necessary. */
++#define FLUSH_BLOCK(s, eof) { \
++   FLUSH_BLOCK_ONLY(s, eof); \
++   if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
++}
++
++/* ===========================================================================
++ * Copy without compression as much as possible from the input stream, return
++ * the current block state.
++ * This function does not insert new strings in the dictionary since
++ * uncompressible data is probably not useful. This function is used
++ * only for the level=0 compression option.
++ * NOTE: this function should be optimized to avoid extra copying from
++ * window to pending_buf.
++ */
++local block_state deflate_stored(s, flush)
++    deflate_state *s;
++    int flush;
++{
++    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
++     * to pending_buf_size, and each stored block has a 5 byte header:
++     */
++    ulg max_block_size = 0xffff;
++    ulg max_start;
++
++    if (max_block_size > s->pending_buf_size - 5) {
++        max_block_size = s->pending_buf_size - 5;
++    }
++
++    /* Copy as much as possible from input to output: */
++    for (;;) {
++        /* Fill the window as much as possible: */
++        if (s->lookahead <= 1) {
++
++            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
++                 s->block_start >= (long)s->w_size, "slide too late");
++
++            fill_window(s);
++            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
++
++            if (s->lookahead == 0) break; /* flush the current block */
++        }
++      Assert(s->block_start >= 0L, "block gone");
++
++      s->strstart += s->lookahead;
++      s->lookahead = 0;
++
++      /* Emit a stored block if pending_buf will be full: */
++      max_start = s->block_start + max_block_size;
++        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
++          /* strstart == 0 is possible when wraparound on 16-bit machine */
++          s->lookahead = (uInt)(s->strstart - max_start);
++          s->strstart = (uInt)max_start;
++            FLUSH_BLOCK(s, 0);
++      }
++      /* Flush if we may have to slide, otherwise block_start may become
++         * negative and the data will be gone:
++         */
++        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
++            FLUSH_BLOCK(s, 0);
++      }
++    }
++    FLUSH_BLOCK(s, flush == Z_FINISH);
++    return flush == Z_FINISH ? finish_done : block_done;
++}
++
++/* ===========================================================================
++ * Compress as much as possible from the input stream, return the current
++ * block state.
++ * This function does not perform lazy evaluation of matches and inserts
++ * new strings in the dictionary only for unmatched strings or for short
++ * matches. It is used only for the fast compression options.
++ */
++local block_state deflate_fast(s, flush)
++    deflate_state *s;
++    int flush;
++{
++    IPos hash_head = NIL; /* head of the hash chain */
++    int bflush;           /* set if current block must be flushed */
++
++    for (;;) {
++        /* Make sure that we always have enough lookahead, except
++         * at the end of the input file. We need MAX_MATCH bytes
++         * for the next match, plus MIN_MATCH bytes to insert the
++         * string following the next match.
++         */
++        if (s->lookahead < MIN_LOOKAHEAD) {
++            fill_window(s);
++            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
++              return need_more;
++          }
++            if (s->lookahead == 0) break; /* flush the current block */
++        }
++
++        /* Insert the string window[strstart .. strstart+2] in the
++         * dictionary, and set hash_head to the head of the hash chain:
++         */
++        if (s->lookahead >= MIN_MATCH) {
++            INSERT_STRING(s, s->strstart, hash_head);
++        }
++
++        /* Find the longest match, discarding those <= prev_length.
++         * At this point we have always match_length < MIN_MATCH
++         */
++        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
++            /* To simplify the code, we prevent matches with the string
++             * of window index 0 (in particular we have to avoid a match
++             * of the string with itself at the start of the input file).
++             */
++            if (s->strategy != Z_HUFFMAN_ONLY) {
++                s->match_length = longest_match (s, hash_head);
++            }
++            /* longest_match() sets match_start */
++        }
++        if (s->match_length >= MIN_MATCH) {
++            check_match(s, s->strstart, s->match_start, s->match_length);
++
++            _tr_tally_dist(s, s->strstart - s->match_start,
++                           s->match_length - MIN_MATCH, bflush);
++
++            s->lookahead -= s->match_length;
++
++            /* Insert new strings in the hash table only if the match length
++             * is not too large. This saves time but degrades compression.
++             */
++#ifndef FASTEST
++            if (s->match_length <= s->max_insert_length &&
++                s->lookahead >= MIN_MATCH) {
++                s->match_length--; /* string at strstart already in hash table */
++                do {
++                    s->strstart++;
++                    INSERT_STRING(s, s->strstart, hash_head);
++                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
++                     * always MIN_MATCH bytes ahead.
++                     */
++                } while (--s->match_length != 0);
++                s->strstart++; 
++            } else
++#endif
++          {
++                s->strstart += s->match_length;
++                s->match_length = 0;
++                s->ins_h = s->window[s->strstart];
++                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
++#if MIN_MATCH != 3
++                Call UPDATE_HASH() MIN_MATCH-3 more times
++#endif
++                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
++                 * matter since it will be recomputed at next deflate call.
++                 */
++            }
++        } else {
++            /* No match, output a literal byte */
++            Tracevv((stderr,"%c", s->window[s->strstart]));
++            _tr_tally_lit (s, s->window[s->strstart], bflush);
++            s->lookahead--;
++            s->strstart++; 
++        }
++        if (bflush) FLUSH_BLOCK(s, 0);
++    }
++    FLUSH_BLOCK(s, flush == Z_FINISH);
++    return flush == Z_FINISH ? finish_done : block_done;
++}
++
++/* ===========================================================================
++ * Same as above, but achieves better compression. We use a lazy
++ * evaluation for matches: a match is finally adopted only if there is
++ * no better match at the next window position.
++ */
++local block_state deflate_slow(s, flush)
++    deflate_state *s;
++    int flush;
++{
++    IPos hash_head = NIL;    /* head of hash chain */
++    int bflush;              /* set if current block must be flushed */
++
++    /* Process the input block. */
++    for (;;) {
++        /* Make sure that we always have enough lookahead, except
++         * at the end of the input file. We need MAX_MATCH bytes
++         * for the next match, plus MIN_MATCH bytes to insert the
++         * string following the next match.
++         */
++        if (s->lookahead < MIN_LOOKAHEAD) {
++            fill_window(s);
++            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
++              return need_more;
++          }
++            if (s->lookahead == 0) break; /* flush the current block */
++        }
++
++        /* Insert the string window[strstart .. strstart+2] in the
++         * dictionary, and set hash_head to the head of the hash chain:
++         */
++        if (s->lookahead >= MIN_MATCH) {
++            INSERT_STRING(s, s->strstart, hash_head);
++        }
++
++        /* Find the longest match, discarding those <= prev_length.
++         */
++        s->prev_length = s->match_length, s->prev_match = s->match_start;
++        s->match_length = MIN_MATCH-1;
++
++        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
++            s->strstart - hash_head <= MAX_DIST(s)) {
++            /* To simplify the code, we prevent matches with the string
++             * of window index 0 (in particular we have to avoid a match
++             * of the string with itself at the start of the input file).
++             */
++            if (s->strategy != Z_HUFFMAN_ONLY) {
++                s->match_length = longest_match (s, hash_head);
++            }
++            /* longest_match() sets match_start */
++
++            if (s->match_length <= 5 && (s->strategy == Z_FILTERED ||
++                 (s->match_length == MIN_MATCH &&
++                  s->strstart - s->match_start > TOO_FAR))) {
++
++                /* If prev_match is also MIN_MATCH, match_start is garbage
++                 * but we will ignore the current match anyway.
++                 */
++                s->match_length = MIN_MATCH-1;
++            }
++        }
++        /* If there was a match at the previous step and the current
++         * match is not better, output the previous match:
++         */
++        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
++            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
++            /* Do not insert strings in hash table beyond this. */
++
++            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
++
++            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
++                         s->prev_length - MIN_MATCH, bflush);
++
++            /* Insert in hash table all strings up to the end of the match.
++             * strstart-1 and strstart are already inserted. If there is not
++             * enough lookahead, the last two strings are not inserted in
++             * the hash table.
++             */
++            s->lookahead -= s->prev_length-1;
++            s->prev_length -= 2;
++            do {
++                if (++s->strstart <= max_insert) {
++                    INSERT_STRING(s, s->strstart, hash_head);
++                }
++            } while (--s->prev_length != 0);
++            s->match_available = 0;
++            s->match_length = MIN_MATCH-1;
++            s->strstart++;
++
++            if (bflush) FLUSH_BLOCK(s, 0);
++
++        } else if (s->match_available) {
++            /* If there was no match at the previous position, output a
++             * single literal. If there was a match but the current match
++             * is longer, truncate the previous match to a single literal.
++             */
++            Tracevv((stderr,"%c", s->window[s->strstart-1]));
++          _tr_tally_lit(s, s->window[s->strstart-1], bflush);
++          if (bflush) {
++                FLUSH_BLOCK_ONLY(s, 0);
++            }
++            s->strstart++;
++            s->lookahead--;
++            if (s->strm->avail_out == 0) return need_more;
++        } else {
++            /* There is no previous match to compare with, wait for
++             * the next step to decide.
++             */
++            s->match_available = 1;
++            s->strstart++;
++            s->lookahead--;
++        }
++    }
++    Assert (flush != Z_NO_FLUSH, "no flush?");
++    if (s->match_available) {
++        Tracevv((stderr,"%c", s->window[s->strstart-1]));
++        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
++        s->match_available = 0;
++    }
++    FLUSH_BLOCK(s, flush == Z_FINISH);
++    return flush == Z_FINISH ? finish_done : block_done;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..962676da8696da7f7afbd92b7951c20548d49759
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,318 @@@
++/* deflate.h -- internal compression state
++ * Copyright (C) 1995-1998 Jean-loup Gailly
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* @(#) $Id$ */
++
++#ifndef _DEFLATE_H
++#define _DEFLATE_H
++
++#include "zutil.h"
++
++/* ===========================================================================
++ * Internal compression state.
++ */
++
++#define LENGTH_CODES 29
++/* number of length codes, not counting the special END_BLOCK code */
++
++#define LITERALS  256
++/* number of literal bytes 0..255 */
++
++#define L_CODES (LITERALS+1+LENGTH_CODES)
++/* number of Literal or Length codes, including the END_BLOCK code */
++
++#define D_CODES   30
++/* number of distance codes */
++
++#define BL_CODES  19
++/* number of codes used to transfer the bit lengths */
++
++#define HEAP_SIZE (2*L_CODES+1)
++/* maximum heap size */
++
++#define MAX_BITS 15
++/* All codes must not exceed MAX_BITS bits */
++
++#define INIT_STATE    42
++#define BUSY_STATE   113
++#define FINISH_STATE 666
++/* Stream status */
++
++
++/* Data structure describing a single value and its code string. */
++typedef struct ct_data_s {
++    union {
++        ush  freq;       /* frequency count */
++        ush  code;       /* bit string */
++    } fc;
++    union {
++        ush  dad;        /* father node in Huffman tree */
++        ush  len;        /* length of bit string */
++    } dl;
++} FAR ct_data;
++
++#define Freq fc.freq
++#define Code fc.code
++#define Dad  dl.dad
++#define Len  dl.len
++
++typedef struct static_tree_desc_s  static_tree_desc;
++
++typedef struct tree_desc_s {
++    ct_data *dyn_tree;           /* the dynamic tree */
++    int     max_code;            /* largest code with non zero frequency */
++    static_tree_desc *stat_desc; /* the corresponding static tree */
++} FAR tree_desc;
++
++typedef ush Pos;
++typedef Pos FAR Posf;
++typedef unsigned IPos;
++
++/* A Pos is an index in the character window. We use short instead of int to
++ * save space in the various tables. IPos is used only for parameter passing.
++ */
++
++typedef struct internal_state {
++    z_streamp strm;      /* pointer back to this zlib stream */
++    int   status;        /* as the name implies */
++    Bytef *pending_buf;  /* output still pending */
++    ulg   pending_buf_size; /* size of pending_buf */
++    Bytef *pending_out;  /* next pending byte to output to the stream */
++    int   pending;       /* nb of bytes in the pending buffer */
++    int   noheader;      /* suppress zlib header and adler32 */
++    Byte  data_type;     /* UNKNOWN, BINARY or ASCII */
++    Byte  method;        /* STORED (for zip only) or DEFLATED */
++    int   last_flush;    /* value of flush param for previous deflate call */
++
++                /* used by deflate.c: */
++
++    uInt  w_size;        /* LZ77 window size (32K by default) */
++    uInt  w_bits;        /* log2(w_size)  (8..16) */
++    uInt  w_mask;        /* w_size - 1 */
++
++    Bytef *window;
++    /* Sliding window. Input bytes are read into the second half of the window,
++     * and move to the first half later to keep a dictionary of at least wSize
++     * bytes. With this organization, matches are limited to a distance of
++     * wSize-MAX_MATCH bytes, but this ensures that IO is always
++     * performed with a length multiple of the block size. Also, it limits
++     * the window size to 64K, which is quite useful on MSDOS.
++     * To do: use the user input buffer as sliding window.
++     */
++
++    ulg window_size;
++    /* Actual size of window: 2*wSize, except when the user input buffer
++     * is directly used as sliding window.
++     */
++
++    Posf *prev;
++    /* Link to older string with same hash index. To limit the size of this
++     * array to 64K, this link is maintained only for the last 32K strings.
++     * An index in this array is thus a window index modulo 32K.
++     */
++
++    Posf *head; /* Heads of the hash chains or NIL. */
++
++    uInt  ins_h;          /* hash index of string to be inserted */
++    uInt  hash_size;      /* number of elements in hash table */
++    uInt  hash_bits;      /* log2(hash_size) */
++    uInt  hash_mask;      /* hash_size-1 */
++
++    uInt  hash_shift;
++    /* Number of bits by which ins_h must be shifted at each input
++     * step. It must be such that after MIN_MATCH steps, the oldest
++     * byte no longer takes part in the hash key, that is:
++     *   hash_shift * MIN_MATCH >= hash_bits
++     */
++
++    long block_start;
++    /* Window position at the beginning of the current output block. Gets
++     * negative when the window is moved backwards.
++     */
++
++    uInt match_length;           /* length of best match */
++    IPos prev_match;             /* previous match */
++    int match_available;         /* set if previous match exists */
++    uInt strstart;               /* start of string to insert */
++    uInt match_start;            /* start of matching string */
++    uInt lookahead;              /* number of valid bytes ahead in window */
++
++    uInt prev_length;
++    /* Length of the best match at previous step. Matches not greater than this
++     * are discarded. This is used in the lazy match evaluation.
++     */
++
++    uInt max_chain_length;
++    /* To speed up deflation, hash chains are never searched beyond this
++     * length.  A higher limit improves compression ratio but degrades the
++     * speed.
++     */
++
++    uInt max_lazy_match;
++    /* Attempt to find a better match only when the current match is strictly
++     * smaller than this value. This mechanism is used only for compression
++     * levels >= 4.
++     */
++#   define max_insert_length  max_lazy_match
++    /* Insert new strings in the hash table only if the match length is not
++     * greater than this length. This saves time but degrades compression.
++     * max_insert_length is used only for compression levels <= 3.
++     */
++
++    int level;    /* compression level (1..9) */
++    int strategy; /* favor or force Huffman coding*/
++
++    uInt good_match;
++    /* Use a faster search when the previous match is longer than this */
++
++    int nice_match; /* Stop searching when current match exceeds this */
++
++                /* used by trees.c: */
++    /* Didn't use ct_data typedef below to supress compiler warning */
++    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
++    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
++    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
++
++    struct tree_desc_s l_desc;               /* desc. for literal tree */
++    struct tree_desc_s d_desc;               /* desc. for distance tree */
++    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
++
++    ush bl_count[MAX_BITS+1];
++    /* number of codes at each bit length for an optimal tree */
++
++    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
++    int heap_len;               /* number of elements in the heap */
++    int heap_max;               /* element of largest frequency */
++    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
++     * The same heap array is used to build all trees.
++     */
++
++    uch depth[2*L_CODES+1];
++    /* Depth of each subtree used as tie breaker for trees of equal frequency
++     */
++
++    uchf *l_buf;          /* buffer for literals or lengths */
++
++    uInt  lit_bufsize;
++    /* Size of match buffer for literals/lengths.  There are 4 reasons for
++     * limiting lit_bufsize to 64K:
++     *   - frequencies can be kept in 16 bit counters
++     *   - if compression is not successful for the first block, all input
++     *     data is still in the window so we can still emit a stored block even
++     *     when input comes from standard input.  (This can also be done for
++     *     all blocks if lit_bufsize is not greater than 32K.)
++     *   - if compression is not successful for a file smaller than 64K, we can
++     *     even emit a stored file instead of a stored block (saving 5 bytes).
++     *     This is applicable only for zip (not gzip or zlib).
++     *   - creating new Huffman trees less frequently may not provide fast
++     *     adaptation to changes in the input data statistics. (Take for
++     *     example a binary file with poorly compressible code followed by
++     *     a highly compressible string table.) Smaller buffer sizes give
++     *     fast adaptation but have of course the overhead of transmitting
++     *     trees more frequently.
++     *   - I can't count above 4
++     */
++
++    uInt last_lit;      /* running index in l_buf */
++
++    ushf *d_buf;
++    /* Buffer for distances. To simplify the code, d_buf and l_buf have
++     * the same number of elements. To use different lengths, an extra flag
++     * array would be necessary.
++     */
++
++    ulg opt_len;        /* bit length of current block with optimal trees */
++    ulg static_len;     /* bit length of current block with static trees */
++    uInt matches;       /* number of string matches in current block */
++    int last_eob_len;   /* bit length of EOB code for last block */
++
++#ifdef DEBUG
++    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
++    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
++#endif
++
++    ush bi_buf;
++    /* Output buffer. bits are inserted starting at the bottom (least
++     * significant bits).
++     */
++    int bi_valid;
++    /* Number of valid bits in bi_buf.  All bits above the last valid bit
++     * are always zero.
++     */
++
++} FAR deflate_state;
++
++/* Output a byte on the stream.
++ * IN assertion: there is enough room in pending_buf.
++ */
++#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
++
++
++#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
++/* Minimum amount of lookahead, except at the end of the input file.
++ * See deflate.c for comments about the MIN_MATCH+1.
++ */
++
++#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
++/* In order to simplify the code, particularly on 16 bit machines, match
++ * distances are limited to MAX_DIST instead of WSIZE.
++ */
++
++        /* in trees.c */
++void _tr_init         OF((deflate_state *s));
++int  _tr_tally        OF((deflate_state *s, unsigned dist, unsigned lc));
++void _tr_flush_block  OF((deflate_state *s, charf *buf, ulg stored_len,
++                        int eof));
++void _tr_align        OF((deflate_state *s));
++void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
++                          int eof));
++
++#define d_code(dist) \
++   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
++/* Mapping from a distance to a distance code. dist is the distance - 1 and
++ * must not have side effects. _dist_code[256] and _dist_code[257] are never
++ * used.
++ */
++
++#ifndef DEBUG
++/* Inline versions of _tr_tally for speed: */
++
++#if defined(GEN_TREES_H) || !defined(STDC)
++  extern uch _length_code[];
++  extern uch _dist_code[];
++#else
++  extern const uch _length_code[];
++  extern const uch _dist_code[];
++#endif
++
++# define _tr_tally_lit(s, c, flush) \
++  { uch cc = (c); \
++    s->d_buf[s->last_lit] = 0; \
++    s->l_buf[s->last_lit++] = cc; \
++    s->dyn_ltree[cc].Freq++; \
++    flush = (s->last_lit == s->lit_bufsize-1); \
++   }
++# define _tr_tally_dist(s, distance, length, flush) \
++  { uch len = (length); \
++    ush dist = (distance); \
++    s->d_buf[s->last_lit] = dist; \
++    s->l_buf[s->last_lit++] = len; \
++    dist--; \
++    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
++    s->dyn_dtree[d_code(dist)].Freq++; \
++    flush = (s->last_lit == s->lit_bufsize-1); \
++  }
++#else
++# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
++# define _tr_tally_dist(s, distance, length, flush) \
++              flush = _tr_tally(s, distance, length) 
++#endif
++
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..9d364598a2716431b789b260974354adaeafc771
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,48 @@@
++# descrip.mms: MMS description file for building zlib on VMS
++# written by Martin P.J. Zinser <m.zinser@gsi.de>
++
++cc_defs = 
++c_deb = 
++
++.ifdef __DECC__
++pref = /prefix=all
++.endif
++
++OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
++       deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
++       inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
++
++CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
++
++all : example.exe minigzip.exe
++        @ write sys$output " Example applications available"
++libz.olb : libz.olb($(OBJS))
++      @ write sys$output " libz available"
++
++example.exe : example.obj libz.olb
++              link example,libz.olb/lib
++
++minigzip.exe : minigzip.obj libz.olb
++              link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
++
++clean : 
++      delete *.obj;*,libz.olb;*
++
++
++# Other dependencies.
++adler32.obj : zutil.h zlib.h zconf.h
++compress.obj : zlib.h zconf.h
++crc32.obj : zutil.h zlib.h zconf.h
++deflate.obj : deflate.h zutil.h zlib.h zconf.h
++example.obj : zlib.h zconf.h
++gzio.obj : zutil.h zlib.h zconf.h
++infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
++infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
++inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
++inflate.obj : zutil.h zlib.h zconf.h infblock.h
++inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
++infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
++minigzip.obj : zlib.h zconf.h
++trees.obj : deflate.h zutil.h zlib.h zconf.h
++uncompr.obj : zlib.h zconf.h
++zutil.obj : zutil.h zlib.h zconf.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8307c841e4a83916b595a3ba744513305e54de9e
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,556 @@@
++/* example.c -- usage example of the zlib compression library
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#include <stdio.h>
++#include "zlib.h"
++
++#ifdef STDC
++#  include <string.h>
++#  include <stdlib.h>
++#else
++   extern void exit  OF((int));
++#endif
++
++#if defined(VMS) || defined(RISCOS)
++#  define TESTFILE "foo-gz"
++#else
++#  define TESTFILE "foo.gz"
++#endif
++
++#define CHECK_ERR(err, msg) { \
++    if (err != Z_OK) { \
++        fprintf(stderr, "%s error: %d\n", msg, err); \
++        exit(1); \
++    } \
++}
++
++const char hello[] = "hello, hello!";
++/* "hello world" would be more standard, but the repeated "hello"
++ * stresses the compression code better, sorry...
++ */
++
++const char dictionary[] = "hello";
++uLong dictId; /* Adler32 value of the dictionary */
++
++void test_compress      OF((Byte *compr, uLong comprLen,
++                          Byte *uncompr, uLong uncomprLen));
++void test_gzio          OF((const char *out, const char *in, 
++                          Byte *uncompr, int uncomprLen));
++void test_deflate       OF((Byte *compr, uLong comprLen));
++void test_inflate       OF((Byte *compr, uLong comprLen,
++                          Byte *uncompr, uLong uncomprLen));
++void test_large_deflate OF((Byte *compr, uLong comprLen,
++                          Byte *uncompr, uLong uncomprLen));
++void test_large_inflate OF((Byte *compr, uLong comprLen,
++                          Byte *uncompr, uLong uncomprLen));
++void test_flush         OF((Byte *compr, uLong *comprLen));
++void test_sync          OF((Byte *compr, uLong comprLen,
++                          Byte *uncompr, uLong uncomprLen));
++void test_dict_deflate  OF((Byte *compr, uLong comprLen));
++void test_dict_inflate  OF((Byte *compr, uLong comprLen,
++                          Byte *uncompr, uLong uncomprLen));
++int  main               OF((int argc, char *argv[]));
++
++/* ===========================================================================
++ * Test compress() and uncompress()
++ */
++void test_compress(compr, comprLen, uncompr, uncomprLen)
++    Byte *compr, *uncompr;
++    uLong comprLen, uncomprLen;
++{
++    int err;
++    uLong len = strlen(hello)+1;
++
++    err = compress(compr, &comprLen, (const Bytef*)hello, len);
++    CHECK_ERR(err, "compress");
++
++    strcpy((char*)uncompr, "garbage");
++
++    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
++    CHECK_ERR(err, "uncompress");
++
++    if (strcmp((char*)uncompr, hello)) {
++        fprintf(stderr, "bad uncompress\n");
++      exit(1);
++    } else {
++        printf("uncompress(): %s\n", (char *)uncompr);
++    }
++}
++
++/* ===========================================================================
++ * Test read/write of .gz files
++ */
++void test_gzio(out, in, uncompr, uncomprLen)
++    const char *out; /* compressed output file */
++    const char *in;  /* compressed input file */
++    Byte *uncompr;
++    int  uncomprLen;
++{
++    int err;
++    int len = strlen(hello)+1;
++    gzFile file;
++    z_off_t pos;
++
++    file = gzopen(out, "wb");
++    if (file == NULL) {
++        fprintf(stderr, "gzopen error\n");
++        exit(1);
++    }
++    gzputc(file, 'h');
++    if (gzputs(file, "ello") != 4) {
++        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
++      exit(1);
++    }
++    if (gzprintf(file, ", %s!", "hello") != 8) {
++        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
++      exit(1);
++    }
++    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
++    gzclose(file);
++
++    file = gzopen(in, "rb");
++    if (file == NULL) {
++        fprintf(stderr, "gzopen error\n");
++    }
++    strcpy((char*)uncompr, "garbage");
++
++    uncomprLen = gzread(file, uncompr, (unsigned)uncomprLen);
++    if (uncomprLen != len) {
++        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
++      exit(1);
++    }
++    if (strcmp((char*)uncompr, hello)) {
++        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
++      exit(1);
++    } else {
++        printf("gzread(): %s\n", (char *)uncompr);
++    }
++
++    pos = gzseek(file, -8L, SEEK_CUR);
++    if (pos != 6 || gztell(file) != pos) {
++      fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
++              (long)pos, (long)gztell(file));
++      exit(1);
++    }
++
++    if (gzgetc(file) != ' ') {
++      fprintf(stderr, "gzgetc error\n");
++      exit(1);
++    }
++
++    gzgets(file, (char*)uncompr, uncomprLen);
++    uncomprLen = strlen((char*)uncompr);
++    if (uncomprLen != 6) { /* "hello!" */
++        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
++      exit(1);
++    }
++    if (strcmp((char*)uncompr, hello+7)) {
++        fprintf(stderr, "bad gzgets after gzseek\n");
++      exit(1);
++    } else {
++        printf("gzgets() after gzseek: %s\n", (char *)uncompr);
++    }
++
++    gzclose(file);
++}
++
++/* ===========================================================================
++ * Test deflate() with small buffers
++ */
++void test_deflate(compr, comprLen)
++    Byte *compr;
++    uLong comprLen;
++{
++    z_stream c_stream; /* compression stream */
++    int err;
++    int len = strlen(hello)+1;
++
++    c_stream.zalloc = (alloc_func)0;
++    c_stream.zfree = (free_func)0;
++    c_stream.opaque = (voidpf)0;
++
++    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
++    CHECK_ERR(err, "deflateInit");
++
++    c_stream.next_in  = (Bytef*)hello;
++    c_stream.next_out = compr;
++
++    while (c_stream.total_in != (uLong)len && c_stream.total_out < comprLen) {
++        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
++        err = deflate(&c_stream, Z_NO_FLUSH);
++        CHECK_ERR(err, "deflate");
++    }
++    /* Finish the stream, still forcing small buffers: */
++    for (;;) {
++        c_stream.avail_out = 1;
++        err = deflate(&c_stream, Z_FINISH);
++        if (err == Z_STREAM_END) break;
++        CHECK_ERR(err, "deflate");
++    }
++
++    err = deflateEnd(&c_stream);
++    CHECK_ERR(err, "deflateEnd");
++}
++
++/* ===========================================================================
++ * Test inflate() with small buffers
++ */
++void test_inflate(compr, comprLen, uncompr, uncomprLen)
++    Byte *compr, *uncompr;
++    uLong comprLen, uncomprLen;
++{
++    int err;
++    z_stream d_stream; /* decompression stream */
++
++    strcpy((char*)uncompr, "garbage");
++
++    d_stream.zalloc = (alloc_func)0;
++    d_stream.zfree = (free_func)0;
++    d_stream.opaque = (voidpf)0;
++
++    d_stream.next_in  = compr;
++    d_stream.avail_in = 0;
++    d_stream.next_out = uncompr;
++
++    err = inflateInit(&d_stream);
++    CHECK_ERR(err, "inflateInit");
++
++    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
++        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
++        err = inflate(&d_stream, Z_NO_FLUSH);
++        if (err == Z_STREAM_END) break;
++        CHECK_ERR(err, "inflate");
++    }
++
++    err = inflateEnd(&d_stream);
++    CHECK_ERR(err, "inflateEnd");
++
++    if (strcmp((char*)uncompr, hello)) {
++        fprintf(stderr, "bad inflate\n");
++      exit(1);
++    } else {
++        printf("inflate(): %s\n", (char *)uncompr);
++    }
++}
++
++/* ===========================================================================
++ * Test deflate() with large buffers and dynamic change of compression level
++ */
++void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
++    Byte *compr, *uncompr;
++    uLong comprLen, uncomprLen;
++{
++    z_stream c_stream; /* compression stream */
++    int err;
++
++    c_stream.zalloc = (alloc_func)0;
++    c_stream.zfree = (free_func)0;
++    c_stream.opaque = (voidpf)0;
++
++    err = deflateInit(&c_stream, Z_BEST_SPEED);
++    CHECK_ERR(err, "deflateInit");
++
++    c_stream.next_out = compr;
++    c_stream.avail_out = (uInt)comprLen;
++
++    /* At this point, uncompr is still mostly zeroes, so it should compress
++     * very well:
++     */
++    c_stream.next_in = uncompr;
++    c_stream.avail_in = (uInt)uncomprLen;
++    err = deflate(&c_stream, Z_NO_FLUSH);
++    CHECK_ERR(err, "deflate");
++    if (c_stream.avail_in != 0) {
++        fprintf(stderr, "deflate not greedy\n");
++      exit(1);
++    }
++
++    /* Feed in already compressed data and switch to no compression: */
++    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
++    c_stream.next_in = compr;
++    c_stream.avail_in = (uInt)comprLen/2;
++    err = deflate(&c_stream, Z_NO_FLUSH);
++    CHECK_ERR(err, "deflate");
++
++    /* Switch back to compressing mode: */
++    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
++    c_stream.next_in = uncompr;
++    c_stream.avail_in = (uInt)uncomprLen;
++    err = deflate(&c_stream, Z_NO_FLUSH);
++    CHECK_ERR(err, "deflate");
++
++    err = deflate(&c_stream, Z_FINISH);
++    if (err != Z_STREAM_END) {
++        fprintf(stderr, "deflate should report Z_STREAM_END\n");
++      exit(1);
++    }
++    err = deflateEnd(&c_stream);
++    CHECK_ERR(err, "deflateEnd");
++}
++
++/* ===========================================================================
++ * Test inflate() with large buffers
++ */
++void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
++    Byte *compr, *uncompr;
++    uLong comprLen, uncomprLen;
++{
++    int err;
++    z_stream d_stream; /* decompression stream */
++
++    strcpy((char*)uncompr, "garbage");
++
++    d_stream.zalloc = (alloc_func)0;
++    d_stream.zfree = (free_func)0;
++    d_stream.opaque = (voidpf)0;
++
++    d_stream.next_in  = compr;
++    d_stream.avail_in = (uInt)comprLen;
++
++    err = inflateInit(&d_stream);
++    CHECK_ERR(err, "inflateInit");
++
++    for (;;) {
++        d_stream.next_out = uncompr;            /* discard the output */
++      d_stream.avail_out = (uInt)uncomprLen;
++        err = inflate(&d_stream, Z_NO_FLUSH);
++        if (err == Z_STREAM_END) break;
++        CHECK_ERR(err, "large inflate");
++    }
++
++    err = inflateEnd(&d_stream);
++    CHECK_ERR(err, "inflateEnd");
++
++    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
++        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
++      exit(1);
++    } else {
++        printf("large_inflate(): OK\n");
++    }
++}
++
++/* ===========================================================================
++ * Test deflate() with full flush
++ */
++void test_flush(compr, comprLen)
++    Byte *compr;
++    uLong *comprLen;
++{
++    z_stream c_stream; /* compression stream */
++    int err;
++    int len = strlen(hello)+1;
++
++    c_stream.zalloc = (alloc_func)0;
++    c_stream.zfree = (free_func)0;
++    c_stream.opaque = (voidpf)0;
++
++    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
++    CHECK_ERR(err, "deflateInit");
++
++    c_stream.next_in  = (Bytef*)hello;
++    c_stream.next_out = compr;
++    c_stream.avail_in = 3;
++    c_stream.avail_out = (uInt)*comprLen;
++    err = deflate(&c_stream, Z_FULL_FLUSH);
++    CHECK_ERR(err, "deflate");
++
++    compr[3]++; /* force an error in first compressed block */
++    c_stream.avail_in = len - 3;
++
++    err = deflate(&c_stream, Z_FINISH);
++    if (err != Z_STREAM_END) {
++        CHECK_ERR(err, "deflate");
++    }
++    err = deflateEnd(&c_stream);
++    CHECK_ERR(err, "deflateEnd");
++
++    *comprLen = c_stream.total_out;
++}
++
++/* ===========================================================================
++ * Test inflateSync()
++ */
++void test_sync(compr, comprLen, uncompr, uncomprLen)
++    Byte *compr, *uncompr;
++    uLong comprLen, uncomprLen;
++{
++    int err;
++    z_stream d_stream; /* decompression stream */
++
++    strcpy((char*)uncompr, "garbage");
++
++    d_stream.zalloc = (alloc_func)0;
++    d_stream.zfree = (free_func)0;
++    d_stream.opaque = (voidpf)0;
++
++    d_stream.next_in  = compr;
++    d_stream.avail_in = 2; /* just read the zlib header */
++
++    err = inflateInit(&d_stream);
++    CHECK_ERR(err, "inflateInit");
++
++    d_stream.next_out = uncompr;
++    d_stream.avail_out = (uInt)uncomprLen;
++
++    inflate(&d_stream, Z_NO_FLUSH);
++    CHECK_ERR(err, "inflate");
++
++    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
++    err = inflateSync(&d_stream);           /* but skip the damaged part */
++    CHECK_ERR(err, "inflateSync");
++
++    err = inflate(&d_stream, Z_FINISH);
++    if (err != Z_DATA_ERROR) {
++        fprintf(stderr, "inflate should report DATA_ERROR\n");
++        /* Because of incorrect adler32 */
++      exit(1);
++    }
++    err = inflateEnd(&d_stream);
++    CHECK_ERR(err, "inflateEnd");
++
++    printf("after inflateSync(): hel%s\n", (char *)uncompr);
++}
++
++/* ===========================================================================
++ * Test deflate() with preset dictionary
++ */
++void test_dict_deflate(compr, comprLen)
++    Byte *compr;
++    uLong comprLen;
++{
++    z_stream c_stream; /* compression stream */
++    int err;
++
++    c_stream.zalloc = (alloc_func)0;
++    c_stream.zfree = (free_func)0;
++    c_stream.opaque = (voidpf)0;
++
++    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
++    CHECK_ERR(err, "deflateInit");
++
++    err = deflateSetDictionary(&c_stream,
++                             (const Bytef*)dictionary, sizeof(dictionary));
++    CHECK_ERR(err, "deflateSetDictionary");
++
++    dictId = c_stream.adler;
++    c_stream.next_out = compr;
++    c_stream.avail_out = (uInt)comprLen;
++
++    c_stream.next_in = (Bytef*)hello;
++    c_stream.avail_in = (uInt)strlen(hello)+1;
++
++    err = deflate(&c_stream, Z_FINISH);
++    if (err != Z_STREAM_END) {
++        fprintf(stderr, "deflate should report Z_STREAM_END\n");
++      exit(1);
++    }
++    err = deflateEnd(&c_stream);
++    CHECK_ERR(err, "deflateEnd");
++}
++
++/* ===========================================================================
++ * Test inflate() with a preset dictionary
++ */
++void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
++    Byte *compr, *uncompr;
++    uLong comprLen, uncomprLen;
++{
++    int err;
++    z_stream d_stream; /* decompression stream */
++
++    strcpy((char*)uncompr, "garbage");
++
++    d_stream.zalloc = (alloc_func)0;
++    d_stream.zfree = (free_func)0;
++    d_stream.opaque = (voidpf)0;
++
++    d_stream.next_in  = compr;
++    d_stream.avail_in = (uInt)comprLen;
++
++    err = inflateInit(&d_stream);
++    CHECK_ERR(err, "inflateInit");
++
++    d_stream.next_out = uncompr;
++    d_stream.avail_out = (uInt)uncomprLen;
++
++    for (;;) {
++        err = inflate(&d_stream, Z_NO_FLUSH);
++        if (err == Z_STREAM_END) break;
++      if (err == Z_NEED_DICT) {
++          if (d_stream.adler != dictId) {
++              fprintf(stderr, "unexpected dictionary");
++              exit(1);
++          }
++          err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
++                                     sizeof(dictionary));
++      }
++        CHECK_ERR(err, "inflate with dict");
++    }
++
++    err = inflateEnd(&d_stream);
++    CHECK_ERR(err, "inflateEnd");
++
++    if (strcmp((char*)uncompr, hello)) {
++        fprintf(stderr, "bad inflate with dict\n");
++      exit(1);
++    } else {
++        printf("inflate with dictionary: %s\n", (char *)uncompr);
++    }
++}
++
++/* ===========================================================================
++ * Usage:  example [output.gz  [input.gz]]
++ */
++
++int main(argc, argv)
++    int argc;
++    char *argv[];
++{
++    Byte *compr, *uncompr;
++    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
++    uLong uncomprLen = comprLen;
++    static const char* myVersion = ZLIB_VERSION;
++
++    if (zlibVersion()[0] != myVersion[0]) {
++        fprintf(stderr, "incompatible zlib version\n");
++        exit(1);
++
++    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
++        fprintf(stderr, "warning: different zlib version\n");
++    }
++
++    compr    = (Byte*)calloc((uInt)comprLen, 1);
++    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
++    /* compr and uncompr are cleared to avoid reading uninitialized
++     * data and to ensure that uncompr compresses well.
++     */
++    if (compr == Z_NULL || uncompr == Z_NULL) {
++        printf("out of memory\n");
++      exit(1);
++    }
++    test_compress(compr, comprLen, uncompr, uncomprLen);
++
++    test_gzio((argc > 1 ? argv[1] : TESTFILE),
++              (argc > 2 ? argv[2] : TESTFILE),
++            uncompr, (int)uncomprLen);
++
++    test_deflate(compr, comprLen);
++    test_inflate(compr, comprLen, uncompr, uncomprLen);
++
++    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
++    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
++
++    test_flush(compr, &comprLen);
++    test_sync(compr, comprLen, uncompr, uncomprLen);
++    comprLen = uncomprLen;
++
++    test_dict_deflate(compr, comprLen);
++    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
++
++    exit(0);
++    return 0; /* to avoid warning */
++}
diff --cc Lib/zlib/gzio.c
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f7c336a55a0911bdd45fcd9caa10c8570b3c5d6c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,875 @@@
++/* gzio.c -- IO on .gz files
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h
++ *
++ * Compile this file with -DNO_DEFLATE to avoid the compression code.
++ */
++
++/* @(#) $Id$ */
++
++#include <stdio.h>
++
++#include "zutil.h"
++
++struct internal_state {int dummy;}; /* for buggy compilers */
++
++#ifndef Z_BUFSIZE
++#  ifdef MAXSEG_64K
++#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
++#  else
++#    define Z_BUFSIZE 16384
++#  endif
++#endif
++#ifndef Z_PRINTF_BUFSIZE
++#  define Z_PRINTF_BUFSIZE 4096
++#endif
++
++#define ALLOC(size) malloc(size)
++#define TRYFREE(p) {if (p) free(p);}
++
++static int gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
++
++/* gzip flag byte */
++#define ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
++#define HEAD_CRC     0x02 /* bit 1 set: header CRC present */
++#define EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
++#define ORIG_NAME    0x08 /* bit 3 set: original file name present */
++#define COMMENT      0x10 /* bit 4 set: file comment present */
++#define RESERVED     0xE0 /* bits 5..7: reserved */
++
++typedef struct gz_stream {
++    z_stream stream;
++    int      z_err;   /* error code for last stream operation */
++    int      z_eof;   /* set if end of input file */
++    FILE     *file;   /* .gz file */
++    Byte     *inbuf;  /* input buffer */
++    Byte     *outbuf; /* output buffer */
++    uLong    crc;     /* crc32 of uncompressed data */
++    char     *msg;    /* error message */
++    char     *path;   /* path name for debugging only */
++    int      transparent; /* 1 if input file is not a .gz file */
++    char     mode;    /* 'w' or 'r' */
++    long     startpos; /* start of compressed data in file (header skipped) */
++} gz_stream;
++
++
++local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
++local int do_flush        OF((gzFile file, int flush));
++local int    get_byte     OF((gz_stream *s));
++local void   check_header OF((gz_stream *s));
++local int    destroy      OF((gz_stream *s));
++local void   putLong      OF((FILE *file, uLong x));
++local uLong  getLong      OF((gz_stream *s));
++
++/* ===========================================================================
++     Opens a gzip (.gz) file for reading or writing. The mode parameter
++   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
++   or path name (if fd == -1).
++     gz_open return NULL if the file could not be opened or if there was
++   insufficient memory to allocate the (de)compression state; errno
++   can be checked to distinguish the two cases (if errno is zero, the
++   zlib error is Z_MEM_ERROR).
++*/
++local gzFile gz_open (path, mode, fd)
++    const char *path;
++    const char *mode;
++    int  fd;
++{
++    int err;
++    int level = Z_DEFAULT_COMPRESSION; /* compression level */
++    int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
++    char *p = (char*)mode;
++    gz_stream *s;
++    char fmode[80]; /* copy of mode, without the compression level */
++    char *m = fmode;
++
++    if (!path || !mode) return Z_NULL;
++
++    s = (gz_stream *)ALLOC(sizeof(gz_stream));
++    if (!s) return Z_NULL;
++
++    s->stream.zalloc = (alloc_func)0;
++    s->stream.zfree = (free_func)0;
++    s->stream.opaque = (voidpf)0;
++    s->stream.next_in = s->inbuf = Z_NULL;
++    s->stream.next_out = s->outbuf = Z_NULL;
++    s->stream.avail_in = s->stream.avail_out = 0;
++    s->file = NULL;
++    s->z_err = Z_OK;
++    s->z_eof = 0;
++    s->crc = crc32(0L, Z_NULL, 0);
++    s->msg = NULL;
++    s->transparent = 0;
++
++    s->path = (char*)ALLOC(strlen(path)+1);
++    if (s->path == NULL) {
++        return destroy(s), (gzFile)Z_NULL;
++    }
++    strcpy(s->path, path); /* do this early for debugging */
++
++    s->mode = '\0';
++    do {
++        if (*p == 'r') s->mode = 'r';
++        if (*p == 'w' || *p == 'a') s->mode = 'w';
++        if (*p >= '0' && *p <= '9') {
++          level = *p - '0';
++      } else if (*p == 'f') {
++        strategy = Z_FILTERED;
++      } else if (*p == 'h') {
++        strategy = Z_HUFFMAN_ONLY;
++      } else {
++          *m++ = *p; /* copy the mode */
++      }
++    } while (*p++ && m != fmode + sizeof(fmode));
++    if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
++    
++    if (s->mode == 'w') {
++#ifdef NO_DEFLATE
++        err = Z_STREAM_ERROR;
++#else
++        err = deflateInit2(&(s->stream), level,
++                           Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
++        /* windowBits is passed < 0 to suppress zlib header */
++
++        s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
++#endif
++        if (err != Z_OK || s->outbuf == Z_NULL) {
++            return destroy(s), (gzFile)Z_NULL;
++        }
++    } else {
++        s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
++
++        err = inflateInit2(&(s->stream), -MAX_WBITS);
++        /* windowBits is passed < 0 to tell that there is no zlib header.
++         * Note that in this case inflate *requires* an extra "dummy" byte
++         * after the compressed stream in order to complete decompression and
++         * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
++         * present after the compressed stream.
++         */
++        if (err != Z_OK || s->inbuf == Z_NULL) {
++            return destroy(s), (gzFile)Z_NULL;
++        }
++    }
++    s->stream.avail_out = Z_BUFSIZE;
++
++    errno = 0;
++    s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
++
++    if (s->file == NULL) {
++        return destroy(s), (gzFile)Z_NULL;
++    }
++    if (s->mode == 'w') {
++        /* Write a very simple .gz header:
++         */
++        fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
++             Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
++      s->startpos = 10L;
++      /* We use 10L instead of ftell(s->file) to because ftell causes an
++         * fflush on some systems. This version of the library doesn't use
++         * startpos anyway in write mode, so this initialization is not
++         * necessary.
++         */
++    } else {
++      check_header(s); /* skip the .gz header */
++      s->startpos = (ftell(s->file) - s->stream.avail_in);
++    }
++    
++    return (gzFile)s;
++}
++
++/* ===========================================================================
++     Opens a gzip (.gz) file for reading or writing.
++*/
++gzFile ZEXPORT gzopen (path, mode)
++    const char *path;
++    const char *mode;
++{
++    return gz_open (path, mode, -1);
++}
++
++/* ===========================================================================
++     Associate a gzFile with the file descriptor fd. fd is not dup'ed here
++   to mimic the behavio(u)r of fdopen.
++*/
++gzFile ZEXPORT gzdopen (fd, mode)
++    int fd;
++    const char *mode;
++{
++    char name[20];
++
++    if (fd < 0) return (gzFile)Z_NULL;
++    sprintf(name, "<fd:%d>", fd); /* for debugging */
++
++    return gz_open (name, mode, fd);
++}
++
++/* ===========================================================================
++ * Update the compression level and strategy
++ */
++int ZEXPORT gzsetparams (file, level, strategy)
++    gzFile file;
++    int level;
++    int strategy;
++{
++    gz_stream *s = (gz_stream*)file;
++
++    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
++
++    /* Make room to allow flushing */
++    if (s->stream.avail_out == 0) {
++
++      s->stream.next_out = s->outbuf;
++      if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
++          s->z_err = Z_ERRNO;
++      }
++      s->stream.avail_out = Z_BUFSIZE;
++    }
++
++    return deflateParams (&(s->stream), level, strategy);
++}
++
++/* ===========================================================================
++     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
++   for end of file.
++   IN assertion: the stream s has been sucessfully opened for reading.
++*/
++local int get_byte(s)
++    gz_stream *s;
++{
++    if (s->z_eof) return EOF;
++    if (s->stream.avail_in == 0) {
++      errno = 0;
++      s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
++      if (s->stream.avail_in == 0) {
++          s->z_eof = 1;
++          if (ferror(s->file)) s->z_err = Z_ERRNO;
++          return EOF;
++      }
++      s->stream.next_in = s->inbuf;
++    }
++    s->stream.avail_in--;
++    return *(s->stream.next_in)++;
++}
++
++/* ===========================================================================
++      Check the gzip header of a gz_stream opened for reading. Set the stream
++    mode to transparent if the gzip magic header is not present; set s->err
++    to Z_DATA_ERROR if the magic header is present but the rest of the header
++    is incorrect.
++    IN assertion: the stream s has already been created sucessfully;
++       s->stream.avail_in is zero for the first time, but may be non-zero
++       for concatenated .gz files.
++*/
++local void check_header(s)
++    gz_stream *s;
++{
++    int method; /* method byte */
++    int flags;  /* flags byte */
++    uInt len;
++    int c;
++
++    /* Check the gzip magic header */
++    for (len = 0; len < 2; len++) {
++      c = get_byte(s);
++      if (c != gz_magic[len]) {
++          if (len != 0) s->stream.avail_in++, s->stream.next_in--;
++          if (c != EOF) {
++              s->stream.avail_in++, s->stream.next_in--;
++              s->transparent = 1;
++          }
++          s->z_err = s->stream.avail_in != 0 ? Z_OK : Z_STREAM_END;
++          return;
++      }
++    }
++    method = get_byte(s);
++    flags = get_byte(s);
++    if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
++      s->z_err = Z_DATA_ERROR;
++      return;
++    }
++
++    /* Discard time, xflags and OS code: */
++    for (len = 0; len < 6; len++) (void)get_byte(s);
++
++    if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
++      len  =  (uInt)get_byte(s);
++      len += ((uInt)get_byte(s))<<8;
++      /* len is garbage if EOF but the loop below will quit anyway */
++      while (len-- != 0 && get_byte(s) != EOF) ;
++    }
++    if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
++      while ((c = get_byte(s)) != 0 && c != EOF) ;
++    }
++    if ((flags & COMMENT) != 0) {   /* skip the .gz file comment */
++      while ((c = get_byte(s)) != 0 && c != EOF) ;
++    }
++    if ((flags & HEAD_CRC) != 0) {  /* skip the header crc */
++      for (len = 0; len < 2; len++) (void)get_byte(s);
++    }
++    s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
++}
++
++ /* ===========================================================================
++ * Cleanup then free the given gz_stream. Return a zlib error code.
++   Try freeing in the reverse order of allocations.
++ */
++local int destroy (s)
++    gz_stream *s;
++{
++    int err = Z_OK;
++
++    if (!s) return Z_STREAM_ERROR;
++
++    TRYFREE(s->msg);
++
++    if (s->stream.state != NULL) {
++      if (s->mode == 'w') {
++#ifdef NO_DEFLATE
++          err = Z_STREAM_ERROR;
++#else
++          err = deflateEnd(&(s->stream));
++#endif
++      } else if (s->mode == 'r') {
++          err = inflateEnd(&(s->stream));
++      }
++    }
++    if (s->file != NULL && fclose(s->file)) {
++#ifdef ESPIPE
++      if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
++#endif
++          err = Z_ERRNO;
++    }
++    if (s->z_err < 0) err = s->z_err;
++
++    TRYFREE(s->inbuf);
++    TRYFREE(s->outbuf);
++    TRYFREE(s->path);
++    TRYFREE(s);
++    return err;
++}
++
++/* ===========================================================================
++     Reads the given number of uncompressed bytes from the compressed file.
++   gzread returns the number of bytes actually read (0 for end of file).
++*/
++int ZEXPORT gzread (file, buf, len)
++    gzFile file;
++    voidp buf;
++    unsigned len;
++{
++    gz_stream *s = (gz_stream*)file;
++    Bytef *start = (Bytef*)buf; /* starting point for crc computation */
++    Byte  *next_out; /* == stream.next_out but not forced far (for MSDOS) */
++
++    if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
++
++    if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
++    if (s->z_err == Z_STREAM_END) return 0;  /* EOF */
++
++    next_out = (Byte*)buf;
++    s->stream.next_out = (Bytef*)buf;
++    s->stream.avail_out = len;
++
++    while (s->stream.avail_out != 0) {
++
++      if (s->transparent) {
++          /* Copy first the lookahead bytes: */
++          uInt n = s->stream.avail_in;
++          if (n > s->stream.avail_out) n = s->stream.avail_out;
++          if (n > 0) {
++              zmemcpy(s->stream.next_out, s->stream.next_in, n);
++              next_out += n;
++              s->stream.next_out = next_out;
++              s->stream.next_in   += n;
++              s->stream.avail_out -= n;
++              s->stream.avail_in  -= n;
++          }
++          if (s->stream.avail_out > 0) {
++              s->stream.avail_out -= fread(next_out, 1, s->stream.avail_out,
++                                           s->file);
++          }
++          len -= s->stream.avail_out;
++          s->stream.total_in  += (uLong)len;
++          s->stream.total_out += (uLong)len;
++            if (len == 0) s->z_eof = 1;
++          return (int)len;
++      }
++        if (s->stream.avail_in == 0 && !s->z_eof) {
++
++            errno = 0;
++            s->stream.avail_in = fread(s->inbuf, 1, Z_BUFSIZE, s->file);
++            if (s->stream.avail_in == 0) {
++                s->z_eof = 1;
++              if (ferror(s->file)) {
++                  s->z_err = Z_ERRNO;
++                  break;
++              }
++            }
++            s->stream.next_in = s->inbuf;
++        }
++        s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
++
++      if (s->z_err == Z_STREAM_END) {
++          /* Check CRC and original size */
++          s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
++          start = s->stream.next_out;
++
++          if (getLong(s) != s->crc) {
++              s->z_err = Z_DATA_ERROR;
++          } else {
++              (void)getLong(s);
++                /* The uncompressed length returned by above getlong() may
++                 * be different from s->stream.total_out) in case of
++               * concatenated .gz files. Check for such files:
++               */
++              check_header(s);
++              if (s->z_err == Z_OK) {
++                  uLong total_in = s->stream.total_in;
++                  uLong total_out = s->stream.total_out;
++
++                  inflateReset(&(s->stream));
++                  s->stream.total_in = total_in;
++                  s->stream.total_out = total_out;
++                  s->crc = crc32(0L, Z_NULL, 0);
++              }
++          }
++      }
++      if (s->z_err != Z_OK || s->z_eof) break;
++    }
++    s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
++
++    return (int)(len - s->stream.avail_out);
++}
++
++
++/* ===========================================================================
++      Reads one byte from the compressed file. gzgetc returns this byte
++   or -1 in case of end of file or error.
++*/
++int ZEXPORT gzgetc(file)
++    gzFile file;
++{
++    unsigned char c;
++
++    return gzread(file, &c, 1) == 1 ? c : -1;
++}
++
++
++/* ===========================================================================
++      Reads bytes from the compressed file until len-1 characters are
++   read, or a newline character is read and transferred to buf, or an
++   end-of-file condition is encountered.  The string is then terminated
++   with a null character.
++      gzgets returns buf, or Z_NULL in case of error.
++
++      The current implementation is not optimized at all.
++*/
++char * ZEXPORT gzgets(file, buf, len)
++    gzFile file;
++    char *buf;
++    int len;
++{
++    char *b = buf;
++    if (buf == Z_NULL || len <= 0) return Z_NULL;
++
++    while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
++    *buf = '\0';
++    return b == buf && len > 0 ? Z_NULL : b;
++}
++
++
++#ifndef NO_DEFLATE
++/* ===========================================================================
++     Writes the given number of uncompressed bytes into the compressed file.
++   gzwrite returns the number of bytes actually written (0 in case of error).
++*/
++int ZEXPORT gzwrite (file, buf, len)
++    gzFile file;
++    const voidp buf;
++    unsigned len;
++{
++    gz_stream *s = (gz_stream*)file;
++
++    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
++
++    s->stream.next_in = (Bytef*)buf;
++    s->stream.avail_in = len;
++
++    while (s->stream.avail_in != 0) {
++
++        if (s->stream.avail_out == 0) {
++
++            s->stream.next_out = s->outbuf;
++            if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
++                s->z_err = Z_ERRNO;
++                break;
++            }
++            s->stream.avail_out = Z_BUFSIZE;
++        }
++        s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
++        if (s->z_err != Z_OK) break;
++    }
++    s->crc = crc32(s->crc, (const Bytef *)buf, len);
++
++    return (int)(len - s->stream.avail_in);
++}
++
++/* ===========================================================================
++     Converts, formats, and writes the args to the compressed file under
++   control of the format string, as in fprintf. gzprintf returns the number of
++   uncompressed bytes actually written (0 in case of error).
++*/
++#ifdef STDC
++#include <stdarg.h>
++
++int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
++{
++    char buf[Z_PRINTF_BUFSIZE];
++    va_list va;
++    int len;
++
++    va_start(va, format);
++#ifdef HAS_vsnprintf
++    (void)vsnprintf(buf, sizeof(buf), format, va);
++#else
++    (void)vsprintf(buf, format, va);
++#endif
++    va_end(va);
++    len = strlen(buf); /* some *sprintf don't return the nb of bytes written */
++    if (len <= 0) return 0;
++
++    return gzwrite(file, buf, (unsigned)len);
++}
++#else /* not ANSI C */
++
++int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
++                     a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
++    gzFile file;
++    const char *format;
++    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
++      a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
++{
++    char buf[Z_PRINTF_BUFSIZE];
++    int len;
++
++#ifdef HAS_snprintf
++    snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
++           a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
++#else
++    sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
++          a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
++#endif
++    len = strlen(buf); /* old sprintf doesn't return the nb of bytes written */
++    if (len <= 0) return 0;
++
++    return gzwrite(file, buf, len);
++}
++#endif
++
++/* ===========================================================================
++      Writes c, converted to an unsigned char, into the compressed file.
++   gzputc returns the value that was written, or -1 in case of error.
++*/
++int ZEXPORT gzputc(file, c)
++    gzFile file;
++    int c;
++{
++    unsigned char cc = (unsigned char) c; /* required for big endian systems */
++
++    return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
++}
++
++
++/* ===========================================================================
++      Writes the given null-terminated string to the compressed file, excluding
++   the terminating null character.
++      gzputs returns the number of characters written, or -1 in case of error.
++*/
++int ZEXPORT gzputs(file, s)
++    gzFile file;
++    const char *s;
++{
++    return gzwrite(file, (char*)s, (unsigned)strlen(s));
++}
++
++
++/* ===========================================================================
++     Flushes all pending output into the compressed file. The parameter
++   flush is as in the deflate() function.
++*/
++local int do_flush (file, flush)
++    gzFile file;
++    int flush;
++{
++    uInt len;
++    int done = 0;
++    gz_stream *s = (gz_stream*)file;
++
++    if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
++
++    s->stream.avail_in = 0; /* should be zero already anyway */
++
++    for (;;) {
++        len = Z_BUFSIZE - s->stream.avail_out;
++
++        if (len != 0) {
++            if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
++                s->z_err = Z_ERRNO;
++                return Z_ERRNO;
++            }
++            s->stream.next_out = s->outbuf;
++            s->stream.avail_out = Z_BUFSIZE;
++        }
++        if (done) break;
++        s->z_err = deflate(&(s->stream), flush);
++
++      /* Ignore the second of two consecutive flushes: */
++      if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
++
++        /* deflate has finished flushing only when it hasn't used up
++         * all the available space in the output buffer: 
++         */
++        done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
++ 
++        if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
++    }
++    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
++}
++
++int ZEXPORT gzflush (file, flush)
++     gzFile file;
++     int flush;
++{
++    gz_stream *s = (gz_stream*)file;
++    int err = do_flush (file, flush);
++
++    if (err) return err;
++    fflush(s->file);
++    return  s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
++}
++#endif /* NO_DEFLATE */
++
++/* ===========================================================================
++      Sets the starting position for the next gzread or gzwrite on the given
++   compressed file. The offset represents a number of bytes in the
++      gzseek returns the resulting offset location as measured in bytes from
++   the beginning of the uncompressed stream, or -1 in case of error.
++      SEEK_END is not implemented, returns error.
++      In this version of the library, gzseek can be extremely slow.
++*/
++z_off_t ZEXPORT gzseek (file, offset, whence)
++    gzFile file;
++    z_off_t offset;
++    int whence;
++{
++    gz_stream *s = (gz_stream*)file;
++
++    if (s == NULL || whence == SEEK_END ||
++      s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
++      return -1L;
++    }
++    
++    if (s->mode == 'w') {
++#ifdef NO_DEFLATE
++      return -1L;
++#else
++      if (whence == SEEK_SET) {
++          offset -= s->stream.total_in;
++      }
++      if (offset < 0) return -1L;
++
++      /* At this point, offset is the number of zero bytes to write. */
++      if (s->inbuf == Z_NULL) {
++          s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
++          zmemzero(s->inbuf, Z_BUFSIZE);
++      }
++      while (offset > 0)  {
++          uInt size = Z_BUFSIZE;
++          if (offset < Z_BUFSIZE) size = (uInt)offset;
++
++          size = gzwrite(file, s->inbuf, size);
++          if (size == 0) return -1L;
++
++          offset -= size;
++      }
++      return (z_off_t)s->stream.total_in;
++#endif
++    }
++    /* Rest of function is for reading only */
++
++    /* compute absolute position */
++    if (whence == SEEK_CUR) {
++      offset += s->stream.total_out;
++    }
++    if (offset < 0) return -1L;
++
++    if (s->transparent) {
++      /* map to fseek */
++      s->stream.avail_in = 0;
++      s->stream.next_in = s->inbuf;
++        if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
++
++      s->stream.total_in = s->stream.total_out = (uLong)offset;
++      return offset;
++    }
++
++    /* For a negative seek, rewind and use positive seek */
++    if ((uLong)offset >= s->stream.total_out) {
++      offset -= s->stream.total_out;
++    } else if (gzrewind(file) < 0) {
++      return -1L;
++    }
++    /* offset is now the number of bytes to skip. */
++
++    if (offset != 0 && s->outbuf == Z_NULL) {
++      s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
++    }
++    while (offset > 0)  {
++      int size = Z_BUFSIZE;
++      if (offset < Z_BUFSIZE) size = (int)offset;
++
++      size = gzread(file, s->outbuf, (uInt)size);
++      if (size <= 0) return -1L;
++      offset -= size;
++    }
++    return (z_off_t)s->stream.total_out;
++}
++
++/* ===========================================================================
++     Rewinds input file. 
++*/
++int ZEXPORT gzrewind (file)
++    gzFile file;
++{
++    gz_stream *s = (gz_stream*)file;
++    
++    if (s == NULL || s->mode != 'r') return -1;
++
++    s->z_err = Z_OK;
++    s->z_eof = 0;
++    s->stream.avail_in = 0;
++    s->stream.next_in = s->inbuf;
++    s->crc = crc32(0L, Z_NULL, 0);
++      
++    if (s->startpos == 0) { /* not a compressed file */
++      rewind(s->file);
++      return 0;
++    }
++
++    (void) inflateReset(&s->stream);
++    return fseek(s->file, s->startpos, SEEK_SET);
++}
++
++/* ===========================================================================
++     Returns the starting position for the next gzread or gzwrite on the
++   given compressed file. This position represents a number of bytes in the
++   uncompressed data stream.
++*/
++z_off_t ZEXPORT gztell (file)
++    gzFile file;
++{
++    return gzseek(file, 0L, SEEK_CUR);
++}
++
++/* ===========================================================================
++     Returns 1 when EOF has previously been detected reading the given
++   input stream, otherwise zero.
++*/
++int ZEXPORT gzeof (file)
++    gzFile file;
++{
++    gz_stream *s = (gz_stream*)file;
++    
++    return (s == NULL || s->mode != 'r') ? 0 : s->z_eof;
++}
++
++/* ===========================================================================
++   Outputs a long in LSB order to the given file
++*/
++local void putLong (file, x)
++    FILE *file;
++    uLong x;
++{
++    int n;
++    for (n = 0; n < 4; n++) {
++        fputc((int)(x & 0xff), file);
++        x >>= 8;
++    }
++}
++
++/* ===========================================================================
++   Reads a long in LSB order from the given gz_stream. Sets z_err in case
++   of error.
++*/
++local uLong getLong (s)
++    gz_stream *s;
++{
++    uLong x = (uLong)get_byte(s);
++    int c;
++
++    x += ((uLong)get_byte(s))<<8;
++    x += ((uLong)get_byte(s))<<16;
++    c = get_byte(s);
++    if (c == EOF) s->z_err = Z_DATA_ERROR;
++    x += ((uLong)c)<<24;
++    return x;
++}
++
++/* ===========================================================================
++     Flushes all pending output if necessary, closes the compressed file
++   and deallocates all the (de)compression state.
++*/
++int ZEXPORT gzclose (file)
++    gzFile file;
++{
++    int err;
++    gz_stream *s = (gz_stream*)file;
++
++    if (s == NULL) return Z_STREAM_ERROR;
++
++    if (s->mode == 'w') {
++#ifdef NO_DEFLATE
++      return Z_STREAM_ERROR;
++#else
++        err = do_flush (file, Z_FINISH);
++        if (err != Z_OK) return destroy((gz_stream*)file);
++
++        putLong (s->file, s->crc);
++        putLong (s->file, s->stream.total_in);
++#endif
++    }
++    return destroy((gz_stream*)file);
++}
++
++/* ===========================================================================
++     Returns the error message for the last error which occured on the
++   given compressed file. errnum is set to zlib error number. If an
++   error occured in the file system and not in the compression library,
++   errnum is set to Z_ERRNO and the application may consult errno
++   to get the exact error code.
++*/
++const char*  ZEXPORT gzerror (file, errnum)
++    gzFile file;
++    int *errnum;
++{
++    char *m;
++    gz_stream *s = (gz_stream*)file;
++
++    if (s == NULL) {
++        *errnum = Z_STREAM_ERROR;
++        return (const char*)ERR_MSG(Z_STREAM_ERROR);
++    }
++    *errnum = s->z_err;
++    if (*errnum == Z_OK) return (const char*)"";
++
++    m =  (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
++
++    if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
++
++    TRYFREE(s->msg);
++    s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
++    strcpy(s->msg, s->path);
++    strcat(s->msg, ": ");
++    strcat(s->msg, m);
++    return (const char*)s->msg;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f4920faa5ea06bee242cbb36c51e47ae0c82f434
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,398 @@@
++/* infblock.c -- interpret and process block types to last block
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include "zutil.h"
++#include "infblock.h"
++#include "inftrees.h"
++#include "infcodes.h"
++#include "infutil.h"
++
++struct inflate_codes_state {int dummy;}; /* for buggy compilers */
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++/* Table for deflate from PKZIP's appnote.txt. */
++local const uInt border[] = { /* Order of the bit length code lengths */
++        16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
++
++/*
++   Notes beyond the 1.93a appnote.txt:
++
++   1. Distance pointers never point before the beginning of the output
++      stream.
++   2. Distance pointers can point back across blocks, up to 32k away.
++   3. There is an implied maximum of 7 bits for the bit length table and
++      15 bits for the actual data.
++   4. If only one code exists, then it is encoded using one bit.  (Zero
++      would be more efficient, but perhaps a little confusing.)  If two
++      codes exist, they are coded using one bit each (0 and 1).
++   5. There is no way of sending zero distance codes--a dummy must be
++      sent if there are none.  (History: a pre 2.0 version of PKZIP would
++      store blocks with no distance codes, but this was discovered to be
++      too harsh a criterion.)  Valid only for 1.93a.  2.04c does allow
++      zero distance codes, which is sent as one code of zero bits in
++      length.
++   6. There are up to 286 literal/length codes.  Code 256 represents the
++      end-of-block.  Note however that the static length tree defines
++      288 codes just to fill out the Huffman codes.  Codes 286 and 287
++      cannot be used though, since there is no length base or extra bits
++      defined for them.  Similarily, there are up to 30 distance codes.
++      However, static trees define 32 codes (all 5 bits) to fill out the
++      Huffman codes, but the last two had better not show up in the data.
++   7. Unzip can check dynamic Huffman blocks for complete code sets.
++      The exception is that a single code would not be complete (see #4).
++   8. The five bits following the block type is really the number of
++      literal codes sent minus 257.
++   9. Length codes 8,16,16 are interpreted as 13 length codes of 8 bits
++      (1+6+6).  Therefore, to output three times the length, you output
++      three codes (1+1+1), whereas to output four times the same length,
++      you only need two codes (1+3).  Hmm.
++  10. In the tree reconstruction algorithm, Code = Code + Increment
++      only if BitLength(i) is not zero.  (Pretty obvious.)
++  11. Correction: 4 Bits: # of Bit Length codes - 4     (4 - 19)
++  12. Note: length code 284 can represent 227-258, but length code 285
++      really is 258.  The last length deserves its own, short code
++      since it gets used a lot in very redundant files.  The length
++      258 is special since 258 - 3 (the min match length) is 255.
++  13. The literal/length and distance code bit lengths are read as a
++      single stream of lengths.  It is possible (and advantageous) for
++      a repeat code (16, 17, or 18) to go across the boundary between
++      the two sets of lengths.
++ */
++
++
++void inflate_blocks_reset(s, z, c)
++inflate_blocks_statef *s;
++z_streamp z;
++uLongf *c;
++{
++  if (c != Z_NULL)
++    *c = s->check;
++  if (s->mode == BTREE || s->mode == DTREE)
++    ZFREE(z, s->sub.trees.blens);
++  if (s->mode == CODES)
++    inflate_codes_free(s->sub.decode.codes, z);
++  s->mode = TYPE;
++  s->bitk = 0;
++  s->bitb = 0;
++  s->read = s->write = s->window;
++  if (s->checkfn != Z_NULL)
++    z->adler = s->check = (*s->checkfn)(0L, (const Bytef *)Z_NULL, 0);
++  Tracev((stderr, "inflate:   blocks reset\n"));
++}
++
++
++inflate_blocks_statef *inflate_blocks_new(z, c, w)
++z_streamp z;
++check_func c;
++uInt w;
++{
++  inflate_blocks_statef *s;
++
++  if ((s = (inflate_blocks_statef *)ZALLOC
++       (z,1,sizeof(struct inflate_blocks_state))) == Z_NULL)
++    return s;
++  if ((s->hufts =
++       (inflate_huft *)ZALLOC(z, sizeof(inflate_huft), MANY)) == Z_NULL)
++  {
++    ZFREE(z, s);
++    return Z_NULL;
++  }
++  if ((s->window = (Bytef *)ZALLOC(z, 1, w)) == Z_NULL)
++  {
++    ZFREE(z, s->hufts);
++    ZFREE(z, s);
++    return Z_NULL;
++  }
++  s->end = s->window + w;
++  s->checkfn = c;
++  s->mode = TYPE;
++  Tracev((stderr, "inflate:   blocks allocated\n"));
++  inflate_blocks_reset(s, z, Z_NULL);
++  return s;
++}
++
++
++int inflate_blocks(s, z, r)
++inflate_blocks_statef *s;
++z_streamp z;
++int r;
++{
++  uInt t;               /* temporary storage */
++  uLong b;              /* bit buffer */
++  uInt k;               /* bits in bit buffer */
++  Bytef *p;             /* input data pointer */
++  uInt n;               /* bytes available there */
++  Bytef *q;             /* output window write pointer */
++  uInt m;               /* bytes to end of window or read pointer */
++
++  /* copy input/output information to locals (UPDATE macro restores) */
++  LOAD
++
++  /* process input based on current state */
++  while (1) switch (s->mode)
++  {
++    case TYPE:
++      NEEDBITS(3)
++      t = (uInt)b & 7;
++      s->last = t & 1;
++      switch (t >> 1)
++      {
++        case 0:                         /* stored */
++          Tracev((stderr, "inflate:     stored block%s\n",
++                 s->last ? " (last)" : ""));
++          DUMPBITS(3)
++          t = k & 7;                    /* go to byte boundary */
++          DUMPBITS(t)
++          s->mode = LENS;               /* get length of stored block */
++          break;
++        case 1:                         /* fixed */
++          Tracev((stderr, "inflate:     fixed codes block%s\n",
++                 s->last ? " (last)" : ""));
++          {
++            uInt bl, bd;
++            inflate_huft *tl, *td;
++
++            inflate_trees_fixed(&bl, &bd, &tl, &td, z);
++            s->sub.decode.codes = inflate_codes_new(bl, bd, tl, td, z);
++            if (s->sub.decode.codes == Z_NULL)
++            {
++              r = Z_MEM_ERROR;
++              LEAVE
++            }
++          }
++          DUMPBITS(3)
++          s->mode = CODES;
++          break;
++        case 2:                         /* dynamic */
++          Tracev((stderr, "inflate:     dynamic codes block%s\n",
++                 s->last ? " (last)" : ""));
++          DUMPBITS(3)
++          s->mode = TABLE;
++          break;
++        case 3:                         /* illegal */
++          DUMPBITS(3)
++          s->mode = BAD;
++          z->msg = (char*)"invalid block type";
++          r = Z_DATA_ERROR;
++          LEAVE
++      }
++      break;
++    case LENS:
++      NEEDBITS(32)
++      if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
++      {
++        s->mode = BAD;
++        z->msg = (char*)"invalid stored block lengths";
++        r = Z_DATA_ERROR;
++        LEAVE
++      }
++      s->sub.left = (uInt)b & 0xffff;
++      b = k = 0;                      /* dump bits */
++      Tracev((stderr, "inflate:       stored length %u\n", s->sub.left));
++      s->mode = s->sub.left ? STORED : (s->last ? DRY : TYPE);
++      break;
++    case STORED:
++      if (n == 0)
++        LEAVE
++      NEEDOUT
++      t = s->sub.left;
++      if (t > n) t = n;
++      if (t > m) t = m;
++      zmemcpy(q, p, t);
++      p += t;  n -= t;
++      q += t;  m -= t;
++      if ((s->sub.left -= t) != 0)
++        break;
++      Tracev((stderr, "inflate:       stored end, %lu total out\n",
++              z->total_out + (q >= s->read ? q - s->read :
++              (s->end - s->read) + (q - s->window))));
++      s->mode = s->last ? DRY : TYPE;
++      break;
++    case TABLE:
++      NEEDBITS(14)
++      s->sub.trees.table = t = (uInt)b & 0x3fff;
++#ifndef PKZIP_BUG_WORKAROUND
++      if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
++      {
++        s->mode = BAD;
++        z->msg = (char*)"too many length or distance symbols";
++        r = Z_DATA_ERROR;
++        LEAVE
++      }
++#endif
++      t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
++      if ((s->sub.trees.blens = (uIntf*)ZALLOC(z, t, sizeof(uInt))) == Z_NULL)
++      {
++        r = Z_MEM_ERROR;
++        LEAVE
++      }
++      DUMPBITS(14)
++      s->sub.trees.index = 0;
++      Tracev((stderr, "inflate:       table sizes ok\n"));
++      s->mode = BTREE;
++    case BTREE:
++      while (s->sub.trees.index < 4 + (s->sub.trees.table >> 10))
++      {
++        NEEDBITS(3)
++        s->sub.trees.blens[border[s->sub.trees.index++]] = (uInt)b & 7;
++        DUMPBITS(3)
++      }
++      while (s->sub.trees.index < 19)
++        s->sub.trees.blens[border[s->sub.trees.index++]] = 0;
++      s->sub.trees.bb = 7;
++      t = inflate_trees_bits(s->sub.trees.blens, &s->sub.trees.bb,
++                             &s->sub.trees.tb, s->hufts, z);
++      if (t != Z_OK)
++      {
++        ZFREE(z, s->sub.trees.blens);
++        r = t;
++        if (r == Z_DATA_ERROR)
++          s->mode = BAD;
++        LEAVE
++      }
++      s->sub.trees.index = 0;
++      Tracev((stderr, "inflate:       bits tree ok\n"));
++      s->mode = DTREE;
++    case DTREE:
++      while (t = s->sub.trees.table,
++             s->sub.trees.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))
++      {
++        inflate_huft *h;
++        uInt i, j, c;
++
++        t = s->sub.trees.bb;
++        NEEDBITS(t)
++        h = s->sub.trees.tb + ((uInt)b & inflate_mask[t]);
++        t = h->bits;
++        c = h->base;
++        if (c < 16)
++        {
++          DUMPBITS(t)
++          s->sub.trees.blens[s->sub.trees.index++] = c;
++        }
++        else /* c == 16..18 */
++        {
++          i = c == 18 ? 7 : c - 14;
++          j = c == 18 ? 11 : 3;
++          NEEDBITS(t + i)
++          DUMPBITS(t)
++          j += (uInt)b & inflate_mask[i];
++          DUMPBITS(i)
++          i = s->sub.trees.index;
++          t = s->sub.trees.table;
++          if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
++              (c == 16 && i < 1))
++          {
++            ZFREE(z, s->sub.trees.blens);
++            s->mode = BAD;
++            z->msg = (char*)"invalid bit length repeat";
++            r = Z_DATA_ERROR;
++            LEAVE
++          }
++          c = c == 16 ? s->sub.trees.blens[i - 1] : 0;
++          do {
++            s->sub.trees.blens[i++] = c;
++          } while (--j);
++          s->sub.trees.index = i;
++        }
++      }
++      s->sub.trees.tb = Z_NULL;
++      {
++        uInt bl, bd;
++        inflate_huft *tl, *td;
++        inflate_codes_statef *c;
++
++        bl = 9;         /* must be <= 9 for lookahead assumptions */
++        bd = 6;         /* must be <= 9 for lookahead assumptions */
++        t = s->sub.trees.table;
++        t = inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f),
++                                  s->sub.trees.blens, &bl, &bd, &tl, &td,
++                                  s->hufts, z);
++        ZFREE(z, s->sub.trees.blens);
++        if (t != Z_OK)
++        {
++          if (t == (uInt)Z_DATA_ERROR)
++            s->mode = BAD;
++          r = t;
++          LEAVE
++        }
++        Tracev((stderr, "inflate:       trees ok\n"));
++        if ((c = inflate_codes_new(bl, bd, tl, td, z)) == Z_NULL)
++        {
++          r = Z_MEM_ERROR;
++          LEAVE
++        }
++        s->sub.decode.codes = c;
++      }
++      s->mode = CODES;
++    case CODES:
++      UPDATE
++      if ((r = inflate_codes(s, z, r)) != Z_STREAM_END)
++        return inflate_flush(s, z, r);
++      r = Z_OK;
++      inflate_codes_free(s->sub.decode.codes, z);
++      LOAD
++      Tracev((stderr, "inflate:       codes end, %lu total out\n",
++              z->total_out + (q >= s->read ? q - s->read :
++              (s->end - s->read) + (q - s->window))));
++      if (!s->last)
++      {
++        s->mode = TYPE;
++        break;
++      }
++      s->mode = DRY;
++    case DRY:
++      FLUSH
++      if (s->read != s->write)
++        LEAVE
++      s->mode = DONE;
++    case DONE:
++      r = Z_STREAM_END;
++      LEAVE
++    case BAD:
++      r = Z_DATA_ERROR;
++      LEAVE
++    default:
++      r = Z_STREAM_ERROR;
++      LEAVE
++  }
++}
++
++
++int inflate_blocks_free(s, z)
++inflate_blocks_statef *s;
++z_streamp z;
++{
++  inflate_blocks_reset(s, z, Z_NULL);
++  ZFREE(z, s->window);
++  ZFREE(z, s->hufts);
++  ZFREE(z, s);
++  Tracev((stderr, "inflate:   blocks freed\n"));
++  return Z_OK;
++}
++
++
++void inflate_set_dictionary(s, d, n)
++inflate_blocks_statef *s;
++const Bytef *d;
++uInt  n;
++{
++  zmemcpy(s->window, d, n);
++  s->read = s->write = s->window + n;
++}
++
++
++/* Returns true if inflate is currently at the end of a block generated
++ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. 
++ * IN assertion: s != Z_NULL
++ */
++int inflate_blocks_sync_point(s)
++inflate_blocks_statef *s;
++{
++  return s->mode == LENS;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..bd25c807536f574b01b802baf2bb139e0c58d925
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,39 @@@
++/* infblock.h -- header to use infblock.c
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++struct inflate_blocks_state;
++typedef struct inflate_blocks_state FAR inflate_blocks_statef;
++
++extern inflate_blocks_statef * inflate_blocks_new OF((
++    z_streamp z,
++    check_func c,               /* check function */
++    uInt w));                   /* window size */
++
++extern int inflate_blocks OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    int));                      /* initial return code */
++
++extern void inflate_blocks_reset OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    uLongf *));                  /* check value on output */
++
++extern int inflate_blocks_free OF((
++    inflate_blocks_statef *,
++    z_streamp));
++
++extern void inflate_set_dictionary OF((
++    inflate_blocks_statef *s,
++    const Bytef *d,  /* dictionary */
++    uInt  n));       /* dictionary length */
++
++extern int inflate_blocks_sync_point OF((
++    inflate_blocks_statef *s));
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d4e5ee9a55439aa1c506572666ebbbbb07991d1c
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,257 @@@
++/* infcodes.c -- process literals and length/distance pairs
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include "zutil.h"
++#include "inftrees.h"
++#include "infblock.h"
++#include "infcodes.h"
++#include "infutil.h"
++#include "inffast.h"
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++typedef enum {        /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
++      START,    /* x: set up for LEN */
++      LEN,      /* i: get length/literal/eob next */
++      LENEXT,   /* i: getting length extra (have base) */
++      DIST,     /* i: get distance next */
++      DISTEXT,  /* i: getting distance extra */
++      COPY,     /* o: copying bytes in window, waiting for space */
++      LIT,      /* o: got literal, waiting for output space */
++      WASH,     /* o: got eob, possibly still output waiting */
++      END,      /* x: got eob and all data flushed */
++      BADCODE}  /* x: got error */
++inflate_codes_mode;
++
++/* inflate codes private state */
++struct inflate_codes_state {
++
++  /* mode */
++  inflate_codes_mode mode;      /* current inflate_codes mode */
++
++  /* mode dependent information */
++  uInt len;
++  union {
++    struct {
++      inflate_huft *tree;       /* pointer into tree */
++      uInt need;                /* bits needed */
++    } code;             /* if LEN or DIST, where in tree */
++    uInt lit;           /* if LIT, literal */
++    struct {
++      uInt get;                 /* bits to get for extra */
++      uInt dist;                /* distance back to copy from */
++    } copy;             /* if EXT or COPY, where and how much */
++  } sub;                /* submode */
++
++  /* mode independent information */
++  Byte lbits;           /* ltree bits decoded per branch */
++  Byte dbits;           /* dtree bits decoder per branch */
++  inflate_huft *ltree;          /* literal/length/eob tree */
++  inflate_huft *dtree;          /* distance tree */
++
++};
++
++
++inflate_codes_statef *inflate_codes_new(bl, bd, tl, td, z)
++uInt bl, bd;
++inflate_huft *tl;
++inflate_huft *td; /* need separate declaration for Borland C++ */
++z_streamp z;
++{
++  inflate_codes_statef *c;
++
++  if ((c = (inflate_codes_statef *)
++       ZALLOC(z,1,sizeof(struct inflate_codes_state))) != Z_NULL)
++  {
++    c->mode = START;
++    c->lbits = (Byte)bl;
++    c->dbits = (Byte)bd;
++    c->ltree = tl;
++    c->dtree = td;
++    Tracev((stderr, "inflate:       codes new\n"));
++  }
++  return c;
++}
++
++
++int inflate_codes(s, z, r)
++inflate_blocks_statef *s;
++z_streamp z;
++int r;
++{
++  uInt j;               /* temporary storage */
++  inflate_huft *t;      /* temporary pointer */
++  uInt e;               /* extra bits or operation */
++  uLong b;              /* bit buffer */
++  uInt k;               /* bits in bit buffer */
++  Bytef *p;             /* input data pointer */
++  uInt n;               /* bytes available there */
++  Bytef *q;             /* output window write pointer */
++  uInt m;               /* bytes to end of window or read pointer */
++  Bytef *f;             /* pointer to copy strings from */
++  inflate_codes_statef *c = s->sub.decode.codes;  /* codes state */
++
++  /* copy input/output information to locals (UPDATE macro restores) */
++  LOAD
++
++  /* process input and output based on current state */
++  while (1) switch (c->mode)
++  {             /* waiting for "i:"=input, "o:"=output, "x:"=nothing */
++    case START:         /* x: set up for LEN */
++#ifndef SLOW
++      if (m >= 258 && n >= 10)
++      {
++        UPDATE
++        r = inflate_fast(c->lbits, c->dbits, c->ltree, c->dtree, s, z);
++        LOAD
++        if (r != Z_OK)
++        {
++          c->mode = r == Z_STREAM_END ? WASH : BADCODE;
++          break;
++        }
++      }
++#endif /* !SLOW */
++      c->sub.code.need = c->lbits;
++      c->sub.code.tree = c->ltree;
++      c->mode = LEN;
++    case LEN:           /* i: get length/literal/eob next */
++      j = c->sub.code.need;
++      NEEDBITS(j)
++      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
++      DUMPBITS(t->bits)
++      e = (uInt)(t->exop);
++      if (e == 0)               /* literal */
++      {
++        c->sub.lit = t->base;
++        Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
++                 "inflate:         literal '%c'\n" :
++                 "inflate:         literal 0x%02x\n", t->base));
++        c->mode = LIT;
++        break;
++      }
++      if (e & 16)               /* length */
++      {
++        c->sub.copy.get = e & 15;
++        c->len = t->base;
++        c->mode = LENEXT;
++        break;
++      }
++      if ((e & 64) == 0)        /* next table */
++      {
++        c->sub.code.need = e;
++        c->sub.code.tree = t + t->base;
++        break;
++      }
++      if (e & 32)               /* end of block */
++      {
++        Tracevv((stderr, "inflate:         end of block\n"));
++        c->mode = WASH;
++        break;
++      }
++      c->mode = BADCODE;        /* invalid code */
++      z->msg = (char*)"invalid literal/length code";
++      r = Z_DATA_ERROR;
++      LEAVE
++    case LENEXT:        /* i: getting length extra (have base) */
++      j = c->sub.copy.get;
++      NEEDBITS(j)
++      c->len += (uInt)b & inflate_mask[j];
++      DUMPBITS(j)
++      c->sub.code.need = c->dbits;
++      c->sub.code.tree = c->dtree;
++      Tracevv((stderr, "inflate:         length %u\n", c->len));
++      c->mode = DIST;
++    case DIST:          /* i: get distance next */
++      j = c->sub.code.need;
++      NEEDBITS(j)
++      t = c->sub.code.tree + ((uInt)b & inflate_mask[j]);
++      DUMPBITS(t->bits)
++      e = (uInt)(t->exop);
++      if (e & 16)               /* distance */
++      {
++        c->sub.copy.get = e & 15;
++        c->sub.copy.dist = t->base;
++        c->mode = DISTEXT;
++        break;
++      }
++      if ((e & 64) == 0)        /* next table */
++      {
++        c->sub.code.need = e;
++        c->sub.code.tree = t + t->base;
++        break;
++      }
++      c->mode = BADCODE;        /* invalid code */
++      z->msg = (char*)"invalid distance code";
++      r = Z_DATA_ERROR;
++      LEAVE
++    case DISTEXT:       /* i: getting distance extra */
++      j = c->sub.copy.get;
++      NEEDBITS(j)
++      c->sub.copy.dist += (uInt)b & inflate_mask[j];
++      DUMPBITS(j)
++      Tracevv((stderr, "inflate:         distance %u\n", c->sub.copy.dist));
++      c->mode = COPY;
++    case COPY:          /* o: copying bytes in window, waiting for space */
++#ifndef __TURBOC__ /* Turbo C bug for following expression */
++      f = (uInt)(q - s->window) < c->sub.copy.dist ?
++          s->end - (c->sub.copy.dist - (q - s->window)) :
++          q - c->sub.copy.dist;
++#else
++      f = q - c->sub.copy.dist;
++      if ((uInt)(q - s->window) < c->sub.copy.dist)
++        f = s->end - (c->sub.copy.dist - (uInt)(q - s->window));
++#endif
++      while (c->len)
++      {
++        NEEDOUT
++        OUTBYTE(*f++)
++        if (f == s->end)
++          f = s->window;
++        c->len--;
++      }
++      c->mode = START;
++      break;
++    case LIT:           /* o: got literal, waiting for output space */
++      NEEDOUT
++      OUTBYTE(c->sub.lit)
++      c->mode = START;
++      break;
++    case WASH:          /* o: got eob, possibly more output */
++      if (k > 7)        /* return unused byte, if any */
++      {
++        Assert(k < 16, "inflate_codes grabbed too many bytes")
++        k -= 8;
++        n++;
++        p--;            /* can always return one */
++      }
++      FLUSH
++      if (s->read != s->write)
++        LEAVE
++      c->mode = END;
++    case END:
++      r = Z_STREAM_END;
++      LEAVE
++    case BADCODE:       /* x: got error */
++      r = Z_DATA_ERROR;
++      LEAVE
++    default:
++      r = Z_STREAM_ERROR;
++      LEAVE
++  }
++#ifdef NEED_DUMMY_RETURN
++  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
++#endif
++}
++
++
++void inflate_codes_free(c, z)
++inflate_codes_statef *c;
++z_streamp z;
++{
++  ZFREE(z, c);
++  Tracev((stderr, "inflate:       codes free\n"));
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6c750d896f92fbb783587c8987195fb9685c01f9
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,27 @@@
++/* infcodes.h -- header to use infcodes.c
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++struct inflate_codes_state;
++typedef struct inflate_codes_state FAR inflate_codes_statef;
++
++extern inflate_codes_statef *inflate_codes_new OF((
++    uInt, uInt,
++    inflate_huft *, inflate_huft *,
++    z_streamp ));
++
++extern int inflate_codes OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    int));
++
++extern void inflate_codes_free OF((
++    inflate_codes_statef *,
++    z_streamp ));
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..61a78ee933fcd7963fdb2c60638de2a4bda1947a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,170 @@@
++/* inffast.c -- process literals and length/distance pairs fast
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include "zutil.h"
++#include "inftrees.h"
++#include "infblock.h"
++#include "infcodes.h"
++#include "infutil.h"
++#include "inffast.h"
++
++struct inflate_codes_state {int dummy;}; /* for buggy compilers */
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++/* macros for bit input with no checking and for returning unused bytes */
++#define GRABBITS(j) {while(k<(j)){b|=((uLong)NEXTBYTE)<<k;k+=8;}}
++#define UNGRAB {c=z->avail_in-n;c=(k>>3)<c?k>>3:c;n+=c;p-=c;k-=c<<3;}
++
++/* Called with number of bytes left to write in window at least 258
++   (the maximum string length) and number of input bytes available
++   at least ten.  The ten bytes are six bytes for the longest length/
++   distance pair plus four bytes for overloading the bit buffer. */
++
++int inflate_fast(bl, bd, tl, td, s, z)
++uInt bl, bd;
++inflate_huft *tl;
++inflate_huft *td; /* need separate declaration for Borland C++ */
++inflate_blocks_statef *s;
++z_streamp z;
++{
++  inflate_huft *t;      /* temporary pointer */
++  uInt e;               /* extra bits or operation */
++  uLong b;              /* bit buffer */
++  uInt k;               /* bits in bit buffer */
++  Bytef *p;             /* input data pointer */
++  uInt n;               /* bytes available there */
++  Bytef *q;             /* output window write pointer */
++  uInt m;               /* bytes to end of window or read pointer */
++  uInt ml;              /* mask for literal/length tree */
++  uInt md;              /* mask for distance tree */
++  uInt c;               /* bytes to copy */
++  uInt d;               /* distance back to copy from */
++  Bytef *r;             /* copy source pointer */
++
++  /* load input, output, bit values */
++  LOAD
++
++  /* initialize masks */
++  ml = inflate_mask[bl];
++  md = inflate_mask[bd];
++
++  /* do until not enough input or output space for fast loop */
++  do {                          /* assume called with m >= 258 && n >= 10 */
++    /* get literal/length code */
++    GRABBITS(20)                /* max bits for literal/length code */
++    if ((e = (t = tl + ((uInt)b & ml))->exop) == 0)
++    {
++      DUMPBITS(t->bits)
++      Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
++                "inflate:         * literal '%c'\n" :
++                "inflate:         * literal 0x%02x\n", t->base));
++      *q++ = (Byte)t->base;
++      m--;
++      continue;
++    }
++    do {
++      DUMPBITS(t->bits)
++      if (e & 16)
++      {
++        /* get extra bits for length */
++        e &= 15;
++        c = t->base + ((uInt)b & inflate_mask[e]);
++        DUMPBITS(e)
++        Tracevv((stderr, "inflate:         * length %u\n", c));
++
++        /* decode distance base of block to copy */
++        GRABBITS(15);           /* max bits for distance code */
++        e = (t = td + ((uInt)b & md))->exop;
++        do {
++          DUMPBITS(t->bits)
++          if (e & 16)
++          {
++            /* get extra bits to add to distance base */
++            e &= 15;
++            GRABBITS(e)         /* get extra bits (up to 13) */
++            d = t->base + ((uInt)b & inflate_mask[e]);
++            DUMPBITS(e)
++            Tracevv((stderr, "inflate:         * distance %u\n", d));
++
++            /* do the copy */
++            m -= c;
++            if ((uInt)(q - s->window) >= d)     /* offset before dest */
++            {                                   /*  just copy */
++              r = q - d;
++              *q++ = *r++;  c--;        /* minimum count is three, */
++              *q++ = *r++;  c--;        /*  so unroll loop a little */
++            }
++            else                        /* else offset after destination */
++            {
++              e = d - (uInt)(q - s->window); /* bytes from offset to end */
++              r = s->end - e;           /* pointer to offset */
++              if (c > e)                /* if source crosses, */
++              {
++                c -= e;                 /* copy to end of window */
++                do {
++                  *q++ = *r++;
++                } while (--e);
++                r = s->window;          /* copy rest from start of window */
++              }
++            }
++            do {                        /* copy all or what's left */
++              *q++ = *r++;
++            } while (--c);
++            break;
++          }
++          else if ((e & 64) == 0)
++          {
++            t += t->base;
++            e = (t += ((uInt)b & inflate_mask[e]))->exop;
++          }
++          else
++          {
++            z->msg = (char*)"invalid distance code";
++            UNGRAB
++            UPDATE
++            return Z_DATA_ERROR;
++          }
++        } while (1);
++        break;
++      }
++      if ((e & 64) == 0)
++      {
++        t += t->base;
++        if ((e = (t += ((uInt)b & inflate_mask[e]))->exop) == 0)
++        {
++          DUMPBITS(t->bits)
++          Tracevv((stderr, t->base >= 0x20 && t->base < 0x7f ?
++                    "inflate:         * literal '%c'\n" :
++                    "inflate:         * literal 0x%02x\n", t->base));
++          *q++ = (Byte)t->base;
++          m--;
++          break;
++        }
++      }
++      else if (e & 32)
++      {
++        Tracevv((stderr, "inflate:         * end of block\n"));
++        UNGRAB
++        UPDATE
++        return Z_STREAM_END;
++      }
++      else
++      {
++        z->msg = (char*)"invalid literal/length code";
++        UNGRAB
++        UPDATE
++        return Z_DATA_ERROR;
++      }
++    } while (1);
++  } while (m >= 258 && n >= 10);
++
++  /* not enough input or output--restore pointers and return */
++  UNGRAB
++  UPDATE
++  return Z_OK;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..8facec553147642d165d2ba011ea5d13760b3aee
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,17 @@@
++/* inffast.h -- header to use inffast.c
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++extern int inflate_fast OF((
++    uInt,
++    uInt,
++    inflate_huft *,
++    inflate_huft *,
++    inflate_blocks_statef *,
++    z_streamp ));
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..77f7e76314521eefb9f74d40ced4e2c5b21e6992
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,151 @@@
++/* inffixed.h -- table for decoding fixed codes
++ * Generated automatically by the maketree.c program
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++local uInt fixed_bl = 9;
++local uInt fixed_bd = 5;
++local inflate_huft fixed_tl[] = {
++    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
++    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},192},
++    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},160},
++    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},224},
++    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},144},
++    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},208},
++    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},176},
++    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},240},
++    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
++    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},200},
++    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},168},
++    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},232},
++    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},152},
++    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},216},
++    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},184},
++    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},248},
++    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
++    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},196},
++    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},164},
++    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},228},
++    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},148},
++    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},212},
++    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},180},
++    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},244},
++    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},204},
++    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},172},
++    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},236},
++    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},156},
++    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},220},
++    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},188},
++    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},252},
++    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
++    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},194},
++    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},162},
++    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},226},
++    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},146},
++    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},210},
++    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},178},
++    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},242},
++    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
++    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},202},
++    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},170},
++    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},234},
++    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},154},
++    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},218},
++    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},186},
++    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},250},
++    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
++    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},198},
++    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},166},
++    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},230},
++    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},150},
++    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},214},
++    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},182},
++    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},246},
++    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},206},
++    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},174},
++    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},238},
++    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},158},
++    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},222},
++    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},190},
++    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},254},
++    {{{96,7}},256}, {{{0,8}},80}, {{{0,8}},16}, {{{84,8}},115},
++    {{{82,7}},31}, {{{0,8}},112}, {{{0,8}},48}, {{{0,9}},193},
++    {{{80,7}},10}, {{{0,8}},96}, {{{0,8}},32}, {{{0,9}},161},
++    {{{0,8}},0}, {{{0,8}},128}, {{{0,8}},64}, {{{0,9}},225},
++    {{{80,7}},6}, {{{0,8}},88}, {{{0,8}},24}, {{{0,9}},145},
++    {{{83,7}},59}, {{{0,8}},120}, {{{0,8}},56}, {{{0,9}},209},
++    {{{81,7}},17}, {{{0,8}},104}, {{{0,8}},40}, {{{0,9}},177},
++    {{{0,8}},8}, {{{0,8}},136}, {{{0,8}},72}, {{{0,9}},241},
++    {{{80,7}},4}, {{{0,8}},84}, {{{0,8}},20}, {{{85,8}},227},
++    {{{83,7}},43}, {{{0,8}},116}, {{{0,8}},52}, {{{0,9}},201},
++    {{{81,7}},13}, {{{0,8}},100}, {{{0,8}},36}, {{{0,9}},169},
++    {{{0,8}},4}, {{{0,8}},132}, {{{0,8}},68}, {{{0,9}},233},
++    {{{80,7}},8}, {{{0,8}},92}, {{{0,8}},28}, {{{0,9}},153},
++    {{{84,7}},83}, {{{0,8}},124}, {{{0,8}},60}, {{{0,9}},217},
++    {{{82,7}},23}, {{{0,8}},108}, {{{0,8}},44}, {{{0,9}},185},
++    {{{0,8}},12}, {{{0,8}},140}, {{{0,8}},76}, {{{0,9}},249},
++    {{{80,7}},3}, {{{0,8}},82}, {{{0,8}},18}, {{{85,8}},163},
++    {{{83,7}},35}, {{{0,8}},114}, {{{0,8}},50}, {{{0,9}},197},
++    {{{81,7}},11}, {{{0,8}},98}, {{{0,8}},34}, {{{0,9}},165},
++    {{{0,8}},2}, {{{0,8}},130}, {{{0,8}},66}, {{{0,9}},229},
++    {{{80,7}},7}, {{{0,8}},90}, {{{0,8}},26}, {{{0,9}},149},
++    {{{84,7}},67}, {{{0,8}},122}, {{{0,8}},58}, {{{0,9}},213},
++    {{{82,7}},19}, {{{0,8}},106}, {{{0,8}},42}, {{{0,9}},181},
++    {{{0,8}},10}, {{{0,8}},138}, {{{0,8}},74}, {{{0,9}},245},
++    {{{80,7}},5}, {{{0,8}},86}, {{{0,8}},22}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},118}, {{{0,8}},54}, {{{0,9}},205},
++    {{{81,7}},15}, {{{0,8}},102}, {{{0,8}},38}, {{{0,9}},173},
++    {{{0,8}},6}, {{{0,8}},134}, {{{0,8}},70}, {{{0,9}},237},
++    {{{80,7}},9}, {{{0,8}},94}, {{{0,8}},30}, {{{0,9}},157},
++    {{{84,7}},99}, {{{0,8}},126}, {{{0,8}},62}, {{{0,9}},221},
++    {{{82,7}},27}, {{{0,8}},110}, {{{0,8}},46}, {{{0,9}},189},
++    {{{0,8}},14}, {{{0,8}},142}, {{{0,8}},78}, {{{0,9}},253},
++    {{{96,7}},256}, {{{0,8}},81}, {{{0,8}},17}, {{{85,8}},131},
++    {{{82,7}},31}, {{{0,8}},113}, {{{0,8}},49}, {{{0,9}},195},
++    {{{80,7}},10}, {{{0,8}},97}, {{{0,8}},33}, {{{0,9}},163},
++    {{{0,8}},1}, {{{0,8}},129}, {{{0,8}},65}, {{{0,9}},227},
++    {{{80,7}},6}, {{{0,8}},89}, {{{0,8}},25}, {{{0,9}},147},
++    {{{83,7}},59}, {{{0,8}},121}, {{{0,8}},57}, {{{0,9}},211},
++    {{{81,7}},17}, {{{0,8}},105}, {{{0,8}},41}, {{{0,9}},179},
++    {{{0,8}},9}, {{{0,8}},137}, {{{0,8}},73}, {{{0,9}},243},
++    {{{80,7}},4}, {{{0,8}},85}, {{{0,8}},21}, {{{80,8}},258},
++    {{{83,7}},43}, {{{0,8}},117}, {{{0,8}},53}, {{{0,9}},203},
++    {{{81,7}},13}, {{{0,8}},101}, {{{0,8}},37}, {{{0,9}},171},
++    {{{0,8}},5}, {{{0,8}},133}, {{{0,8}},69}, {{{0,9}},235},
++    {{{80,7}},8}, {{{0,8}},93}, {{{0,8}},29}, {{{0,9}},155},
++    {{{84,7}},83}, {{{0,8}},125}, {{{0,8}},61}, {{{0,9}},219},
++    {{{82,7}},23}, {{{0,8}},109}, {{{0,8}},45}, {{{0,9}},187},
++    {{{0,8}},13}, {{{0,8}},141}, {{{0,8}},77}, {{{0,9}},251},
++    {{{80,7}},3}, {{{0,8}},83}, {{{0,8}},19}, {{{85,8}},195},
++    {{{83,7}},35}, {{{0,8}},115}, {{{0,8}},51}, {{{0,9}},199},
++    {{{81,7}},11}, {{{0,8}},99}, {{{0,8}},35}, {{{0,9}},167},
++    {{{0,8}},3}, {{{0,8}},131}, {{{0,8}},67}, {{{0,9}},231},
++    {{{80,7}},7}, {{{0,8}},91}, {{{0,8}},27}, {{{0,9}},151},
++    {{{84,7}},67}, {{{0,8}},123}, {{{0,8}},59}, {{{0,9}},215},
++    {{{82,7}},19}, {{{0,8}},107}, {{{0,8}},43}, {{{0,9}},183},
++    {{{0,8}},11}, {{{0,8}},139}, {{{0,8}},75}, {{{0,9}},247},
++    {{{80,7}},5}, {{{0,8}},87}, {{{0,8}},23}, {{{192,8}},0},
++    {{{83,7}},51}, {{{0,8}},119}, {{{0,8}},55}, {{{0,9}},207},
++    {{{81,7}},15}, {{{0,8}},103}, {{{0,8}},39}, {{{0,9}},175},
++    {{{0,8}},7}, {{{0,8}},135}, {{{0,8}},71}, {{{0,9}},239},
++    {{{80,7}},9}, {{{0,8}},95}, {{{0,8}},31}, {{{0,9}},159},
++    {{{84,7}},99}, {{{0,8}},127}, {{{0,8}},63}, {{{0,9}},223},
++    {{{82,7}},27}, {{{0,8}},111}, {{{0,8}},47}, {{{0,9}},191},
++    {{{0,8}},15}, {{{0,8}},143}, {{{0,8}},79}, {{{0,9}},255}
++  };
++local inflate_huft fixed_td[] = {
++    {{{80,5}},1}, {{{87,5}},257}, {{{83,5}},17}, {{{91,5}},4097},
++    {{{81,5}},5}, {{{89,5}},1025}, {{{85,5}},65}, {{{93,5}},16385},
++    {{{80,5}},3}, {{{88,5}},513}, {{{84,5}},33}, {{{92,5}},8193},
++    {{{82,5}},9}, {{{90,5}},2049}, {{{86,5}},129}, {{{192,5}},24577},
++    {{{80,5}},2}, {{{87,5}},385}, {{{83,5}},25}, {{{91,5}},6145},
++    {{{81,5}},7}, {{{89,5}},1537}, {{{85,5}},97}, {{{93,5}},24577},
++    {{{80,5}},4}, {{{88,5}},769}, {{{84,5}},49}, {{{92,5}},12289},
++    {{{82,5}},13}, {{{90,5}},3073}, {{{86,5}},193}, {{{192,5}},24577}
++  };
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..32e9b8de6797af89beaec309143ee059cbdf9abf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,366 @@@
++/* inflate.c -- zlib interface to inflate modules
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include "zutil.h"
++#include "infblock.h"
++
++struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
++
++typedef enum {
++      METHOD,   /* waiting for method byte */
++      FLAG,     /* waiting for flag byte */
++      DICT4,    /* four dictionary check bytes to go */
++      DICT3,    /* three dictionary check bytes to go */
++      DICT2,    /* two dictionary check bytes to go */
++      DICT1,    /* one dictionary check byte to go */
++      DICT0,    /* waiting for inflateSetDictionary */
++      BLOCKS,   /* decompressing blocks */
++      CHECK4,   /* four check bytes to go */
++      CHECK3,   /* three check bytes to go */
++      CHECK2,   /* two check bytes to go */
++      CHECK1,   /* one check byte to go */
++      DONE,     /* finished check, done */
++      BAD}      /* got an error--stay here */
++inflate_mode;
++
++/* inflate private state */
++struct internal_state {
++
++  /* mode */
++  inflate_mode  mode;   /* current inflate mode */
++
++  /* mode dependent information */
++  union {
++    uInt method;        /* if FLAGS, method byte */
++    struct {
++      uLong was;                /* computed check value */
++      uLong need;               /* stream check value */
++    } check;            /* if CHECK, check values to compare */
++    uInt marker;        /* if BAD, inflateSync's marker bytes count */
++  } sub;        /* submode */
++
++  /* mode independent information */
++  int  nowrap;          /* flag for no wrapper */
++  uInt wbits;           /* log2(window size)  (8..15, defaults to 15) */
++  inflate_blocks_statef 
++    *blocks;            /* current inflate_blocks state */
++
++};
++
++
++int ZEXPORT inflateReset(z)
++z_streamp z;
++{
++  if (z == Z_NULL || z->state == Z_NULL)
++    return Z_STREAM_ERROR;
++  z->total_in = z->total_out = 0;
++  z->msg = Z_NULL;
++  z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
++  inflate_blocks_reset(z->state->blocks, z, Z_NULL);
++  Tracev((stderr, "inflate: reset\n"));
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateEnd(z)
++z_streamp z;
++{
++  if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
++    return Z_STREAM_ERROR;
++  if (z->state->blocks != Z_NULL)
++    inflate_blocks_free(z->state->blocks, z);
++  ZFREE(z, z->state);
++  z->state = Z_NULL;
++  Tracev((stderr, "inflate: end\n"));
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateInit2_(z, w, version, stream_size)
++z_streamp z;
++int w;
++const char *version;
++int stream_size;
++{
++  if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
++      stream_size != sizeof(z_stream))
++      return Z_VERSION_ERROR;
++
++  /* initialize state */
++  if (z == Z_NULL)
++    return Z_STREAM_ERROR;
++  z->msg = Z_NULL;
++  if (z->zalloc == Z_NULL)
++  {
++    z->zalloc = zcalloc;
++    z->opaque = (voidpf)0;
++  }
++  if (z->zfree == Z_NULL) z->zfree = zcfree;
++  if ((z->state = (struct internal_state FAR *)
++       ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
++    return Z_MEM_ERROR;
++  z->state->blocks = Z_NULL;
++
++  /* handle undocumented nowrap option (no zlib header or check) */
++  z->state->nowrap = 0;
++  if (w < 0)
++  {
++    w = - w;
++    z->state->nowrap = 1;
++  }
++
++  /* set window size */
++  if (w < 8 || w > 15)
++  {
++    inflateEnd(z);
++    return Z_STREAM_ERROR;
++  }
++  z->state->wbits = (uInt)w;
++
++  /* create inflate_blocks state */
++  if ((z->state->blocks =
++      inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
++      == Z_NULL)
++  {
++    inflateEnd(z);
++    return Z_MEM_ERROR;
++  }
++  Tracev((stderr, "inflate: allocated\n"));
++
++  /* reset state */
++  inflateReset(z);
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateInit_(z, version, stream_size)
++z_streamp z;
++const char *version;
++int stream_size;
++{
++  return inflateInit2_(z, DEF_WBITS, version, stream_size);
++}
++
++
++#define NEEDBYTE {if(z->avail_in==0)return r;r=f;}
++#define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
++
++int ZEXPORT inflate(z, f)
++z_streamp z;
++int f;
++{
++  int r;
++  uInt b;
++
++  if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL)
++    return Z_STREAM_ERROR;
++  f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK;
++  r = Z_BUF_ERROR;
++  while (1) switch (z->state->mode)
++  {
++    case METHOD:
++      NEEDBYTE
++      if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"unknown compression method";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"invalid window size";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      z->state->mode = FLAG;
++    case FLAG:
++      NEEDBYTE
++      b = NEXTBYTE;
++      if (((z->state->sub.method << 8) + b) % 31)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"incorrect header check";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      Tracev((stderr, "inflate: zlib header ok\n"));
++      if (!(b & PRESET_DICT))
++      {
++        z->state->mode = BLOCKS;
++        break;
++      }
++      z->state->mode = DICT4;
++    case DICT4:
++      NEEDBYTE
++      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
++      z->state->mode = DICT3;
++    case DICT3:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
++      z->state->mode = DICT2;
++    case DICT2:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
++      z->state->mode = DICT1;
++    case DICT1:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE;
++      z->adler = z->state->sub.check.need;
++      z->state->mode = DICT0;
++      return Z_NEED_DICT;
++    case DICT0:
++      z->state->mode = BAD;
++      z->msg = (char*)"need dictionary";
++      z->state->sub.marker = 0;       /* can try inflateSync */
++      return Z_STREAM_ERROR;
++    case BLOCKS:
++      r = inflate_blocks(z->state->blocks, z, r);
++      if (r == Z_DATA_ERROR)
++      {
++        z->state->mode = BAD;
++        z->state->sub.marker = 0;       /* can try inflateSync */
++        break;
++      }
++      if (r == Z_OK)
++        r = f;
++      if (r != Z_STREAM_END)
++        return r;
++      r = f;
++      inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
++      if (z->state->nowrap)
++      {
++        z->state->mode = DONE;
++        break;
++      }
++      z->state->mode = CHECK4;
++    case CHECK4:
++      NEEDBYTE
++      z->state->sub.check.need = (uLong)NEXTBYTE << 24;
++      z->state->mode = CHECK3;
++    case CHECK3:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 16;
++      z->state->mode = CHECK2;
++    case CHECK2:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE << 8;
++      z->state->mode = CHECK1;
++    case CHECK1:
++      NEEDBYTE
++      z->state->sub.check.need += (uLong)NEXTBYTE;
++
++      if (z->state->sub.check.was != z->state->sub.check.need)
++      {
++        z->state->mode = BAD;
++        z->msg = (char*)"incorrect data check";
++        z->state->sub.marker = 5;       /* can't try inflateSync */
++        break;
++      }
++      Tracev((stderr, "inflate: zlib check ok\n"));
++      z->state->mode = DONE;
++    case DONE:
++      return Z_STREAM_END;
++    case BAD:
++      return Z_DATA_ERROR;
++    default:
++      return Z_STREAM_ERROR;
++  }
++#ifdef NEED_DUMMY_RETURN
++  return Z_STREAM_ERROR;  /* Some dumb compilers complain without this */
++#endif
++}
++
++
++int ZEXPORT inflateSetDictionary(z, dictionary, dictLength)
++z_streamp z;
++const Bytef *dictionary;
++uInt  dictLength;
++{
++  uInt length = dictLength;
++
++  if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
++    return Z_STREAM_ERROR;
++
++  if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
++  z->adler = 1L;
++
++  if (length >= ((uInt)1<<z->state->wbits))
++  {
++    length = (1<<z->state->wbits)-1;
++    dictionary += dictLength - length;
++  }
++  inflate_set_dictionary(z->state->blocks, dictionary, length);
++  z->state->mode = BLOCKS;
++  return Z_OK;
++}
++
++
++int ZEXPORT inflateSync(z)
++z_streamp z;
++{
++  uInt n;       /* number of bytes to look at */
++  Bytef *p;     /* pointer to bytes */
++  uInt m;       /* number of marker bytes found in a row */
++  uLong r, w;   /* temporaries to save total_in and total_out */
++
++  /* set up */
++  if (z == Z_NULL || z->state == Z_NULL)
++    return Z_STREAM_ERROR;
++  if (z->state->mode != BAD)
++  {
++    z->state->mode = BAD;
++    z->state->sub.marker = 0;
++  }
++  if ((n = z->avail_in) == 0)
++    return Z_BUF_ERROR;
++  p = z->next_in;
++  m = z->state->sub.marker;
++
++  /* search */
++  while (n && m < 4)
++  {
++    static const Byte mark[4] = {0, 0, 0xff, 0xff};
++    if (*p == mark[m])
++      m++;
++    else if (*p)
++      m = 0;
++    else
++      m = 4 - m;
++    p++, n--;
++  }
++
++  /* restore */
++  z->total_in += p - z->next_in;
++  z->next_in = p;
++  z->avail_in = n;
++  z->state->sub.marker = m;
++
++  /* return no joy or set up to restart on a new block */
++  if (m != 4)
++    return Z_DATA_ERROR;
++  r = z->total_in;  w = z->total_out;
++  inflateReset(z);
++  z->total_in = r;  z->total_out = w;
++  z->state->mode = BLOCKS;
++  return Z_OK;
++}
++
++
++/* Returns true if inflate is currently at the end of a block generated
++ * by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
++ * implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH
++ * but removes the length bytes of the resulting empty stored block. When
++ * decompressing, PPP checks that at the end of input packet, inflate is
++ * waiting for these length bytes.
++ */
++int ZEXPORT inflateSyncPoint(z)
++z_streamp z;
++{
++  if (z == Z_NULL || z->state == Z_NULL || z->state->blocks == Z_NULL)
++    return Z_STREAM_ERROR;
++  return inflate_blocks_sync_point(z->state->blocks);
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..ef1e0b6b873291725fd657ecb0cb65e9abaa1591
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,455 @@@
++/* inftrees.c -- generate Huffman trees for efficient decoding
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include "zutil.h"
++#include "inftrees.h"
++
++#if !defined(BUILDFIXED) && !defined(STDC)
++#  define BUILDFIXED   /* non ANSI compilers may not accept inffixed.h */
++#endif
++
++const char inflate_copyright[] =
++   " inflate 1.1.3 Copyright 1995-1998 Mark Adler ";
++/*
++  If you use the zlib library in a product, an acknowledgment is welcome
++  in the documentation of your product. If for some reason you cannot
++  include such an acknowledgment, I would appreciate that you keep this
++  copyright string in the executable of your product.
++ */
++struct internal_state  {int dummy;}; /* for buggy compilers */
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++
++local int huft_build OF((
++    uIntf *,            /* code lengths in bits */
++    uInt,               /* number of codes */
++    uInt,               /* number of "simple" codes */
++    const uIntf *,      /* list of base values for non-simple codes */
++    const uIntf *,      /* list of extra bits for non-simple codes */
++    inflate_huft * FAR*,/* result: starting table */
++    uIntf *,            /* maximum lookup bits (returns actual) */
++    inflate_huft *,     /* space for trees */
++    uInt *,             /* hufts used in space */
++    uIntf * ));         /* space for values */
++
++/* Tables for deflate from PKZIP's appnote.txt. */
++local const uInt cplens[31] = { /* Copy lengths for literal codes 257..285 */
++        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
++        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
++        /* see note #13 above about 258 */
++local const uInt cplext[31] = { /* Extra bits for literal codes 257..285 */
++        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
++        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; /* 112==invalid */
++local const uInt cpdist[30] = { /* Copy offsets for distance codes 0..29 */
++        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
++        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
++        8193, 12289, 16385, 24577};
++local const uInt cpdext[30] = { /* Extra bits for distance codes */
++        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
++        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
++        12, 12, 13, 13};
++
++/*
++   Huffman code decoding is performed using a multi-level table lookup.
++   The fastest way to decode is to simply build a lookup table whose
++   size is determined by the longest code.  However, the time it takes
++   to build this table can also be a factor if the data being decoded
++   is not very long.  The most common codes are necessarily the
++   shortest codes, so those codes dominate the decoding time, and hence
++   the speed.  The idea is you can have a shorter table that decodes the
++   shorter, more probable codes, and then point to subsidiary tables for
++   the longer codes.  The time it costs to decode the longer codes is
++   then traded against the time it takes to make longer tables.
++
++   This results of this trade are in the variables lbits and dbits
++   below.  lbits is the number of bits the first level table for literal/
++   length codes can decode in one step, and dbits is the same thing for
++   the distance codes.  Subsequent tables are also less than or equal to
++   those sizes.  These values may be adjusted either when all of the
++   codes are shorter than that, in which case the longest code length in
++   bits is used, or when the shortest code is *longer* than the requested
++   table size, in which case the length of the shortest code in bits is
++   used.
++
++   There are two different values for the two tables, since they code a
++   different number of possibilities each.  The literal/length table
++   codes 286 possible values, or in a flat code, a little over eight
++   bits.  The distance table codes 30 possible values, or a little less
++   than five bits, flat.  The optimum values for speed end up being
++   about one bit more than those, so lbits is 8+1 and dbits is 5+1.
++   The optimum values may differ though from machine to machine, and
++   possibly even between compilers.  Your mileage may vary.
++ */
++
++
++/* If BMAX needs to be larger than 16, then h and x[] should be uLong. */
++#define BMAX 15         /* maximum bit length of any code */
++
++local int huft_build(b, n, s, d, e, t, m, hp, hn, v)
++uIntf *b;               /* code lengths in bits (all assumed <= BMAX) */
++uInt n;                 /* number of codes (assumed <= 288) */
++uInt s;                 /* number of simple-valued codes (0..s-1) */
++const uIntf *d;         /* list of base values for non-simple codes */
++const uIntf *e;         /* list of extra bits for non-simple codes */
++inflate_huft * FAR *t;  /* result: starting table */
++uIntf *m;               /* maximum lookup bits, returns actual */
++inflate_huft *hp;       /* space for trees */
++uInt *hn;               /* hufts used in space */
++uIntf *v;               /* working area: values in order of bit length */
++/* Given a list of code lengths and a maximum table size, make a set of
++   tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR
++   if the given code set is incomplete (the tables are still built in this
++   case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of
++   lengths), or Z_MEM_ERROR if not enough memory. */
++{
++
++  uInt a;                       /* counter for codes of length k */
++  uInt c[BMAX+1];               /* bit length count table */
++  uInt f;                       /* i repeats in table every f entries */
++  int g;                        /* maximum code length */
++  int h;                        /* table level */
++  register uInt i;              /* counter, current code */
++  register uInt j;              /* counter */
++  register int k;               /* number of bits in current code */
++  int l;                        /* bits per table (returned in m) */
++  uInt mask;                    /* (1 << w) - 1, to avoid cc -O bug on HP */
++  register uIntf *p;            /* pointer into c[], b[], or v[] */
++  inflate_huft *q;              /* points to current table */
++  struct inflate_huft_s r;      /* table entry for structure assignment */
++  inflate_huft *u[BMAX];        /* table stack */
++  register int w;               /* bits before this table == (l * h) */
++  uInt x[BMAX+1];               /* bit offsets, then code stack */
++  uIntf *xp;                    /* pointer into x */
++  int y;                        /* number of dummy codes added */
++  uInt z;                       /* number of entries in current table */
++
++
++  /* Generate counts for each bit length */
++  p = c;
++#define C0 *p++ = 0;
++#define C2 C0 C0 C0 C0
++#define C4 C2 C2 C2 C2
++  C4                            /* clear c[]--assume BMAX+1 is 16 */
++  p = b;  i = n;
++  do {
++    c[*p++]++;                  /* assume all entries <= BMAX */
++  } while (--i);
++  if (c[0] == n)                /* null input--all zero length codes */
++  {
++    *t = (inflate_huft *)Z_NULL;
++    *m = 0;
++    return Z_OK;
++  }
++
++
++  /* Find minimum and maximum length, bound *m by those */
++  l = *m;
++  for (j = 1; j <= BMAX; j++)
++    if (c[j])
++      break;
++  k = j;                        /* minimum code length */
++  if ((uInt)l < j)
++    l = j;
++  for (i = BMAX; i; i--)
++    if (c[i])
++      break;
++  g = i;                        /* maximum code length */
++  if ((uInt)l > i)
++    l = i;
++  *m = l;
++
++
++  /* Adjust last length count to fill out codes, if needed */
++  for (y = 1 << j; j < i; j++, y <<= 1)
++    if ((y -= c[j]) < 0)
++      return Z_DATA_ERROR;
++  if ((y -= c[i]) < 0)
++    return Z_DATA_ERROR;
++  c[i] += y;
++
++
++  /* Generate starting offsets into the value table for each length */
++  x[1] = j = 0;
++  p = c + 1;  xp = x + 2;
++  while (--i) {                 /* note that i == g from above */
++    *xp++ = (j += *p++);
++  }
++
++
++  /* Make a table of values in order of bit lengths */
++  p = b;  i = 0;
++  do {
++    if ((j = *p++) != 0)
++      v[x[j]++] = i;
++  } while (++i < n);
++  n = x[g];                     /* set n to length of v */
++
++
++  /* Generate the Huffman codes and for each, make the table entries */
++  x[0] = i = 0;                 /* first Huffman code is zero */
++  p = v;                        /* grab values in bit order */
++  h = -1;                       /* no tables yet--level -1 */
++  w = -l;                       /* bits decoded == (l * h) */
++  u[0] = (inflate_huft *)Z_NULL;        /* just to keep compilers happy */
++  q = (inflate_huft *)Z_NULL;   /* ditto */
++  z = 0;                        /* ditto */
++
++  /* go through the bit lengths (k already is bits in shortest code) */
++  for (; k <= g; k++)
++  {
++    a = c[k];
++    while (a--)
++    {
++      /* here i is the Huffman code of length k bits for value *p */
++      /* make tables up to required level */
++      while (k > w + l)
++      {
++        h++;
++        w += l;                 /* previous table always l bits */
++
++        /* compute minimum size table less than or equal to l bits */
++        z = g - w;
++        z = z > (uInt)l ? l : z;        /* table size upper limit */
++        if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
++        {                       /* too few codes for k-w bit table */
++          f -= a + 1;           /* deduct codes from patterns left */
++          xp = c + k;
++          if (j < z)
++            while (++j < z)     /* try smaller tables up to z bits */
++            {
++              if ((f <<= 1) <= *++xp)
++                break;          /* enough codes to use up j bits */
++              f -= *xp;         /* else deduct codes from patterns */
++            }
++        }
++        z = 1 << j;             /* table entries for j-bit table */
++
++        /* allocate new table */
++        if (*hn + z > MANY)     /* (note: doesn't matter for fixed) */
++          return Z_MEM_ERROR;   /* not enough memory */
++        u[h] = q = hp + *hn;
++        *hn += z;
++
++        /* connect to last table, if there is one */
++        if (h)
++        {
++          x[h] = i;             /* save pattern for backing up */
++          r.bits = (Byte)l;     /* bits to dump before this table */
++          r.exop = (Byte)j;     /* bits in this table */
++          j = i >> (w - l);
++          r.base = (uInt)(q - u[h-1] - j);   /* offset to this table */
++          u[h-1][j] = r;        /* connect to last table */
++        }
++        else
++          *t = q;               /* first table is returned result */
++      }
++
++      /* set up table entry in r */
++      r.bits = (Byte)(k - w);
++      if (p >= v + n)
++        r.exop = 128 + 64;      /* out of values--invalid code */
++      else if (*p < s)
++      {
++        r.exop = (Byte)(*p < 256 ? 0 : 32 + 64);     /* 256 is end-of-block */
++        r.base = *p++;          /* simple code is just the value */
++      }
++      else
++      {
++        r.exop = (Byte)(e[*p - s] + 16 + 64);/* non-simple--look up in lists */
++        r.base = d[*p++ - s];
++      }
++
++      /* fill code-like entries with r */
++      f = 1 << (k - w);
++      for (j = i >> w; j < z; j += f)
++        q[j] = r;
++
++      /* backwards increment the k-bit code i */
++      for (j = 1 << (k - 1); i & j; j >>= 1)
++        i ^= j;
++      i ^= j;
++
++      /* backup over finished tables */
++      mask = (1 << w) - 1;      /* needed on HP, cc -O bug */
++      while ((i & mask) != x[h])
++      {
++        h--;                    /* don't need to update q */
++        w -= l;
++        mask = (1 << w) - 1;
++      }
++    }
++  }
++
++
++  /* Return Z_BUF_ERROR if we were given an incomplete table */
++  return y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK;
++}
++
++
++int inflate_trees_bits(c, bb, tb, hp, z)
++uIntf *c;               /* 19 code lengths */
++uIntf *bb;              /* bits tree desired/actual depth */
++inflate_huft * FAR *tb; /* bits tree result */
++inflate_huft *hp;       /* space for trees */
++z_streamp z;            /* for messages */
++{
++  int r;
++  uInt hn = 0;          /* hufts used in space */
++  uIntf *v;             /* work area for huft_build */
++
++  if ((v = (uIntf*)ZALLOC(z, 19, sizeof(uInt))) == Z_NULL)
++    return Z_MEM_ERROR;
++  r = huft_build(c, 19, 19, (uIntf*)Z_NULL, (uIntf*)Z_NULL,
++                 tb, bb, hp, &hn, v);
++  if (r == Z_DATA_ERROR)
++    z->msg = (char*)"oversubscribed dynamic bit lengths tree";
++  else if (r == Z_BUF_ERROR || *bb == 0)
++  {
++    z->msg = (char*)"incomplete dynamic bit lengths tree";
++    r = Z_DATA_ERROR;
++  }
++  ZFREE(z, v);
++  return r;
++}
++
++
++int inflate_trees_dynamic(nl, nd, c, bl, bd, tl, td, hp, z)
++uInt nl;                /* number of literal/length codes */
++uInt nd;                /* number of distance codes */
++uIntf *c;               /* that many (total) code lengths */
++uIntf *bl;              /* literal desired/actual bit depth */
++uIntf *bd;              /* distance desired/actual bit depth */
++inflate_huft * FAR *tl; /* literal/length tree result */
++inflate_huft * FAR *td; /* distance tree result */
++inflate_huft *hp;       /* space for trees */
++z_streamp z;            /* for messages */
++{
++  int r;
++  uInt hn = 0;          /* hufts used in space */
++  uIntf *v;             /* work area for huft_build */
++
++  /* allocate work area */
++  if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
++    return Z_MEM_ERROR;
++
++  /* build literal/length tree */
++  r = huft_build(c, nl, 257, cplens, cplext, tl, bl, hp, &hn, v);
++  if (r != Z_OK || *bl == 0)
++  {
++    if (r == Z_DATA_ERROR)
++      z->msg = (char*)"oversubscribed literal/length tree";
++    else if (r != Z_MEM_ERROR)
++    {
++      z->msg = (char*)"incomplete literal/length tree";
++      r = Z_DATA_ERROR;
++    }
++    ZFREE(z, v);
++    return r;
++  }
++
++  /* build distance tree */
++  r = huft_build(c + nl, nd, 0, cpdist, cpdext, td, bd, hp, &hn, v);
++  if (r != Z_OK || (*bd == 0 && nl > 257))
++  {
++    if (r == Z_DATA_ERROR)
++      z->msg = (char*)"oversubscribed distance tree";
++    else if (r == Z_BUF_ERROR) {
++#ifdef PKZIP_BUG_WORKAROUND
++      r = Z_OK;
++    }
++#else
++      z->msg = (char*)"incomplete distance tree";
++      r = Z_DATA_ERROR;
++    }
++    else if (r != Z_MEM_ERROR)
++    {
++      z->msg = (char*)"empty distance tree with lengths";
++      r = Z_DATA_ERROR;
++    }
++    ZFREE(z, v);
++    return r;
++#endif
++  }
++
++  /* done */
++  ZFREE(z, v);
++  return Z_OK;
++}
++
++
++/* build fixed tables only once--keep them here */
++#ifdef BUILDFIXED
++local int fixed_built = 0;
++#define FIXEDH 544      /* number of hufts used by fixed tables */
++local inflate_huft fixed_mem[FIXEDH];
++local uInt fixed_bl;
++local uInt fixed_bd;
++local inflate_huft *fixed_tl;
++local inflate_huft *fixed_td;
++#else
++#include "inffixed.h"
++#endif
++
++
++int inflate_trees_fixed(bl, bd, tl, td, z)
++uIntf *bl;               /* literal desired/actual bit depth */
++uIntf *bd;               /* distance desired/actual bit depth */
++inflate_huft * FAR *tl;  /* literal/length tree result */
++inflate_huft * FAR *td;  /* distance tree result */
++z_streamp z;             /* for memory allocation */
++{
++#ifdef BUILDFIXED
++  /* build fixed tables if not already */
++  if (!fixed_built)
++  {
++    int k;              /* temporary variable */
++    uInt f = 0;         /* number of hufts used in fixed_mem */
++    uIntf *c;           /* length list for huft_build */
++    uIntf *v;           /* work area for huft_build */
++
++    /* allocate memory */
++    if ((c = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
++      return Z_MEM_ERROR;
++    if ((v = (uIntf*)ZALLOC(z, 288, sizeof(uInt))) == Z_NULL)
++    {
++      ZFREE(z, c);
++      return Z_MEM_ERROR;
++    }
++
++    /* literal table */
++    for (k = 0; k < 144; k++)
++      c[k] = 8;
++    for (; k < 256; k++)
++      c[k] = 9;
++    for (; k < 280; k++)
++      c[k] = 7;
++    for (; k < 288; k++)
++      c[k] = 8;
++    fixed_bl = 9;
++    huft_build(c, 288, 257, cplens, cplext, &fixed_tl, &fixed_bl,
++               fixed_mem, &f, v);
++
++    /* distance table */
++    for (k = 0; k < 30; k++)
++      c[k] = 5;
++    fixed_bd = 5;
++    huft_build(c, 30, 0, cpdist, cpdext, &fixed_td, &fixed_bd,
++               fixed_mem, &f, v);
++
++    /* done */
++    ZFREE(z, v);
++    ZFREE(z, c);
++    fixed_built = 1;
++  }
++#endif
++  *bl = fixed_bl;
++  *bd = fixed_bd;
++  *tl = fixed_tl;
++  *td = fixed_td;
++  return Z_OK;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..85853e097b373d319cae33e4fb1c63ca04cf0ada
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,58 @@@
++/* inftrees.h -- header to use inftrees.c
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* Huffman code lookup table entry--this entry is four bytes for machines
++   that have 16-bit pointers (e.g. PC's in the small or medium model). */
++
++typedef struct inflate_huft_s FAR inflate_huft;
++
++struct inflate_huft_s {
++  union {
++    struct {
++      Byte Exop;        /* number of extra bits or operation */
++      Byte Bits;        /* number of bits in this code or subcode */
++    } what;
++    uInt pad;           /* pad structure to a power of 2 (4 bytes for */
++  } word;               /*  16-bit, 8 bytes for 32-bit int's) */
++  uInt base;            /* literal, length base, distance base,
++                           or table offset */
++};
++
++/* Maximum size of dynamic tree.  The maximum found in a long but non-
++   exhaustive search was 1004 huft structures (850 for length/literals
++   and 154 for distances, the latter actually the result of an
++   exhaustive search).  The actual maximum is not known, but the
++   value below is more than safe. */
++#define MANY 1440
++
++extern int inflate_trees_bits OF((
++    uIntf *,                    /* 19 code lengths */
++    uIntf *,                    /* bits tree desired/actual depth */
++    inflate_huft * FAR *,       /* bits tree result */
++    inflate_huft *,             /* space for trees */
++    z_streamp));                /* for messages */
++
++extern int inflate_trees_dynamic OF((
++    uInt,                       /* number of literal/length codes */
++    uInt,                       /* number of distance codes */
++    uIntf *,                    /* that many (total) code lengths */
++    uIntf *,                    /* literal desired/actual bit depth */
++    uIntf *,                    /* distance desired/actual bit depth */
++    inflate_huft * FAR *,       /* literal/length tree result */
++    inflate_huft * FAR *,       /* distance tree result */
++    inflate_huft *,             /* space for trees */
++    z_streamp));                /* for messages */
++
++extern int inflate_trees_fixed OF((
++    uIntf *,                    /* literal desired/actual bit depth */
++    uIntf *,                    /* distance desired/actual bit depth */
++    inflate_huft * FAR *,       /* literal/length tree result */
++    inflate_huft * FAR *,       /* distance tree result */
++    z_streamp));                /* for memory allocation */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..824dab57128486c77061637bcd6ffb62df47baa1
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,87 @@@
++/* inflate_util.c -- data and routines common to blocks and codes
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++#include "zutil.h"
++#include "infblock.h"
++#include "inftrees.h"
++#include "infcodes.h"
++#include "infutil.h"
++
++struct inflate_codes_state {int dummy;}; /* for buggy compilers */
++
++/* And'ing with mask[n] masks the lower n bits */
++uInt inflate_mask[17] = {
++    0x0000,
++    0x0001, 0x0003, 0x0007, 0x000f, 0x001f, 0x003f, 0x007f, 0x00ff,
++    0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff
++};
++
++
++/* copy as much as possible from the sliding window to the output area */
++int inflate_flush(s, z, r)
++inflate_blocks_statef *s;
++z_streamp z;
++int r;
++{
++  uInt n;
++  Bytef *p;
++  Bytef *q;
++
++  /* local copies of source and destination pointers */
++  p = z->next_out;
++  q = s->read;
++
++  /* compute number of bytes to copy as far as end of window */
++  n = (uInt)((q <= s->write ? s->write : s->end) - q);
++  if (n > z->avail_out) n = z->avail_out;
++  if (n && r == Z_BUF_ERROR) r = Z_OK;
++
++  /* update counters */
++  z->avail_out -= n;
++  z->total_out += n;
++
++  /* update check information */
++  if (s->checkfn != Z_NULL)
++    z->adler = s->check = (*s->checkfn)(s->check, q, n);
++
++  /* copy as far as end of window */
++  zmemcpy(p, q, n);
++  p += n;
++  q += n;
++
++  /* see if more to copy at beginning of window */
++  if (q == s->end)
++  {
++    /* wrap pointers */
++    q = s->window;
++    if (s->write == s->end)
++      s->write = s->window;
++
++    /* compute bytes to copy */
++    n = (uInt)(s->write - q);
++    if (n > z->avail_out) n = z->avail_out;
++    if (n && r == Z_BUF_ERROR) r = Z_OK;
++
++    /* update counters */
++    z->avail_out -= n;
++    z->total_out += n;
++
++    /* update check information */
++    if (s->checkfn != Z_NULL)
++      z->adler = s->check = (*s->checkfn)(s->check, q, n);
++
++    /* copy */
++    zmemcpy(p, q, n);
++    p += n;
++    q += n;
++  }
++
++  /* update pointers */
++  z->next_out = p;
++  s->read = q;
++
++  /* done */
++  return r;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..99d1135d06a3573784a48685c4c35f2b1fb2a6cf
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,98 @@@
++/* infutil.h -- types and macros common to blocks and codes
++ * Copyright (C) 1995-1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++#ifndef _INFUTIL_H
++#define _INFUTIL_H
++
++typedef enum {
++      TYPE,     /* get type bits (3, including end bit) */
++      LENS,     /* get lengths for stored */
++      STORED,   /* processing stored block */
++      TABLE,    /* get table lengths */
++      BTREE,    /* get bit lengths tree for a dynamic block */
++      DTREE,    /* get length, distance trees for a dynamic block */
++      CODES,    /* processing fixed or dynamic block */
++      DRY,      /* output remaining window bytes */
++      DONE,     /* finished last block, done */
++      BAD}      /* got a data error--stuck here */
++inflate_block_mode;
++
++/* inflate blocks semi-private state */
++struct inflate_blocks_state {
++
++  /* mode */
++  inflate_block_mode  mode;     /* current inflate_block mode */
++
++  /* mode dependent information */
++  union {
++    uInt left;          /* if STORED, bytes left to copy */
++    struct {
++      uInt table;               /* table lengths (14 bits) */
++      uInt index;               /* index into blens (or border) */
++      uIntf *blens;             /* bit lengths of codes */
++      uInt bb;                  /* bit length tree depth */
++      inflate_huft *tb;         /* bit length decoding tree */
++    } trees;            /* if DTREE, decoding info for trees */
++    struct {
++      inflate_codes_statef 
++         *codes;
++    } decode;           /* if CODES, current state */
++  } sub;                /* submode */
++  uInt last;            /* true if this block is the last block */
++
++  /* mode independent information */
++  uInt bitk;            /* bits in bit buffer */
++  uLong bitb;           /* bit buffer */
++  inflate_huft *hufts;  /* single malloc for tree space */
++  Bytef *window;        /* sliding window */
++  Bytef *end;           /* one byte after sliding window */
++  Bytef *read;          /* window read pointer */
++  Bytef *write;         /* window write pointer */
++  check_func checkfn;   /* check function */
++  uLong check;          /* check on output */
++
++};
++
++
++/* defines for inflate input/output */
++/*   update pointers and return */
++#define UPDBITS {s->bitb=b;s->bitk=k;}
++#define UPDIN {z->avail_in=n;z->total_in+=p-z->next_in;z->next_in=p;}
++#define UPDOUT {s->write=q;}
++#define UPDATE {UPDBITS UPDIN UPDOUT}
++#define LEAVE {UPDATE return inflate_flush(s,z,r);}
++/*   get bytes and bits */
++#define LOADIN {p=z->next_in;n=z->avail_in;b=s->bitb;k=s->bitk;}
++#define NEEDBYTE {if(n)r=Z_OK;else LEAVE}
++#define NEXTBYTE (n--,*p++)
++#define NEEDBITS(j) {while(k<(j)){NEEDBYTE;b|=((uLong)NEXTBYTE)<<k;k+=8;}}
++#define DUMPBITS(j) {b>>=(j);k-=(j);}
++/*   output bytes */
++#define WAVAIL (uInt)(q<s->read?s->read-q-1:s->end-q)
++#define LOADOUT {q=s->write;m=(uInt)WAVAIL;}
++#define WRAP {if(q==s->end&&s->read!=s->window){q=s->window;m=(uInt)WAVAIL;}}
++#define FLUSH {UPDOUT r=inflate_flush(s,z,r); LOADOUT}
++#define NEEDOUT {if(m==0){WRAP if(m==0){FLUSH WRAP if(m==0) LEAVE}}r=Z_OK;}
++#define OUTBYTE(a) {*q++=(Byte)(a);m--;}
++/*   load local pointers */
++#define LOAD {LOADIN LOADOUT}
++
++/* masks for lower bits (size given to avoid silly warnings with Visual C++) */
++extern uInt inflate_mask[17];
++
++/* copy as much as possible from the sliding window to the output area */
++extern int inflate_flush OF((
++    inflate_blocks_statef *,
++    z_streamp ,
++    int));
++
++struct internal_state      {int dummy;}; /* for buggy compilers */
++
++#endif
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..949d786418513e2c492ebeb53a9a67673158e49f
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,85 @@@
++/* maketree.c -- make inffixed.h table for decoding fixed codes
++ * Copyright (C) 1998 Mark Adler
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* This program is included in the distribution for completeness.
++   You do not need to compile or run this program since inffixed.h
++   is already included in the distribution.  To use this program
++   you need to compile zlib with BUILDFIXED defined and then compile
++   and link this program with the zlib library.  Then the output of
++   this program can be piped to inffixed.h. */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include "zutil.h"
++#include "inftrees.h"
++
++/* simplify the use of the inflate_huft type with some defines */
++#define exop word.what.Exop
++#define bits word.what.Bits
++
++/* generate initialization table for an inflate_huft structure array */
++void maketree(uInt b, inflate_huft *t)
++{
++  int i, e;
++
++  i = 0;
++  while (1)
++  {
++    e = t[i].exop;
++    if (e && (e & (16+64)) == 0)        /* table pointer */
++    {
++      fprintf(stderr, "maketree: cannot initialize sub-tables!\n");
++      exit(1);
++    }
++    if (i % 4 == 0)
++      printf("\n   ");
++    printf(" {{{%u,%u}},%u}", t[i].exop, t[i].bits, t[i].base);
++    if (++i == (1<<b))
++      break;
++    putchar(',');
++  }
++  puts("");
++}
++
++/* create the fixed tables in C initialization syntax */
++void main(void)
++{
++  int r;
++  uInt bl, bd;
++  inflate_huft *tl, *td;
++  z_stream z;
++
++  z.zalloc = zcalloc;
++  z.opaque = (voidpf)0;
++  z.zfree = zcfree;
++  r = inflate_trees_fixed(&bl, &bd, &tl, &td, &z);
++  if (r)
++  {
++    fprintf(stderr, "inflate_trees_fixed error %d\n", r);
++    return;
++  }
++  puts("/* inffixed.h -- table for decoding fixed codes");
++  puts(" * Generated automatically by the maketree.c program");
++  puts(" */");
++  puts("");
++  puts("/* WARNING: this file should *not* be used by applications. It is");
++  puts("   part of the implementation of the compression library and is");
++  puts("   subject to change. Applications should only use zlib.h.");
++  puts(" */");
++  puts("");
++  printf("local uInt fixed_bl = %d;\n", bl);
++  printf("local uInt fixed_bd = %d;\n", bd);
++  printf("local inflate_huft fixed_tl[] = {");
++  maketree(bl, tl);
++  puts("  };");
++  printf("local inflate_huft fixed_td[] = {");
++  maketree(bd, td);
++  puts("  };");
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..7215eaeb0fc42be602d34ed572ad44ad71f642db
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,320 @@@
++/* minigzip.c -- simulate gzip using the zlib compression library
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/*
++ * minigzip is a minimal implementation of the gzip utility. This is
++ * only an example of using zlib and isn't meant to replace the
++ * full-featured gzip. No attempt is made to deal with file systems
++ * limiting names to 14 or 8+3 characters, etc... Error checking is
++ * very limited. So use minigzip only for testing; use gzip for the
++ * real thing. On MSDOS, use only on file names without extension
++ * or in pipe mode.
++ */
++
++/* @(#) $Id$ */
++
++#include <stdio.h>
++#include "zlib.h"
++
++#ifdef STDC
++#  include <string.h>
++#  include <stdlib.h>
++#else
++   extern void exit  OF((int));
++#endif
++
++#ifdef USE_MMAP
++#  include <sys/types.h>
++#  include <sys/mman.h>
++#  include <sys/stat.h>
++#endif
++
++#if defined(MSDOS) || defined(OS2) || defined(WIN32)
++#  include <fcntl.h>
++#  include <io.h>
++#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
++#else
++#  define SET_BINARY_MODE(file)
++#endif
++
++#ifdef VMS
++#  define unlink delete
++#  define GZ_SUFFIX "-gz"
++#endif
++#ifdef RISCOS
++#  define unlink remove
++#  define GZ_SUFFIX "-gz"
++#  define fileno(file) file->__file
++#endif
++#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
++#  include <unix.h> /* for fileno */
++#endif
++
++#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
++  extern int unlink OF((const char *));
++#endif
++
++#ifndef GZ_SUFFIX
++#  define GZ_SUFFIX ".gz"
++#endif
++#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
++
++#define BUFLEN      16384
++#define MAX_NAME_LEN 1024
++
++#ifdef MAXSEG_64K
++#  define local static
++   /* Needed for systems with limitation on stack size. */
++#else
++#  define local
++#endif
++
++char *prog;
++
++void error            OF((const char *msg));
++void gz_compress      OF((FILE   *in, gzFile out));
++#ifdef USE_MMAP
++int  gz_compress_mmap OF((FILE   *in, gzFile out));
++#endif
++void gz_uncompress    OF((gzFile in, FILE   *out));
++void file_compress    OF((char  *file, char *mode));
++void file_uncompress  OF((char  *file));
++int  main             OF((int argc, char *argv[]));
++
++/* ===========================================================================
++ * Display error message and exit
++ */
++void error(msg)
++    const char *msg;
++{
++    fprintf(stderr, "%s: %s\n", prog, msg);
++    exit(1);
++}
++
++/* ===========================================================================
++ * Compress input to output then close both files.
++ */
++
++void gz_compress(in, out)
++    FILE   *in;
++    gzFile out;
++{
++    local char buf[BUFLEN];
++    int len;
++    int err;
++
++#ifdef USE_MMAP
++    /* Try first compressing with mmap. If mmap fails (minigzip used in a
++     * pipe), use the normal fread loop.
++     */
++    if (gz_compress_mmap(in, out) == Z_OK) return;
++#endif
++    for (;;) {
++        len = fread(buf, 1, sizeof(buf), in);
++        if (ferror(in)) {
++            perror("fread");
++            exit(1);
++        }
++        if (len == 0) break;
++
++        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
++    }
++    fclose(in);
++    if (gzclose(out) != Z_OK) error("failed gzclose");
++}
++
++#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
++
++/* Try compressing the input file at once using mmap. Return Z_OK if
++ * if success, Z_ERRNO otherwise.
++ */
++int gz_compress_mmap(in, out)
++    FILE   *in;
++    gzFile out;
++{
++    int len;
++    int err;
++    int ifd = fileno(in);
++    caddr_t buf;    /* mmap'ed buffer for the entire input file */
++    off_t buf_len;  /* length of the input file */
++    struct stat sb;
++
++    /* Determine the size of the file, needed for mmap: */
++    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
++    buf_len = sb.st_size;
++    if (buf_len <= 0) return Z_ERRNO;
++
++    /* Now do the actual mmap: */
++    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0); 
++    if (buf == (caddr_t)(-1)) return Z_ERRNO;
++
++    /* Compress the whole file at once: */
++    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
++
++    if (len != (int)buf_len) error(gzerror(out, &err));
++
++    munmap(buf, buf_len);
++    fclose(in);
++    if (gzclose(out) != Z_OK) error("failed gzclose");
++    return Z_OK;
++}
++#endif /* USE_MMAP */
++
++/* ===========================================================================
++ * Uncompress input to output then close both files.
++ */
++void gz_uncompress(in, out)
++    gzFile in;
++    FILE   *out;
++{
++    local char buf[BUFLEN];
++    int len;
++    int err;
++
++    for (;;) {
++        len = gzread(in, buf, sizeof(buf));
++        if (len < 0) error (gzerror(in, &err));
++        if (len == 0) break;
++
++        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
++          error("failed fwrite");
++      }
++    }
++    if (fclose(out)) error("failed fclose");
++
++    if (gzclose(in) != Z_OK) error("failed gzclose");
++}
++
++
++/* ===========================================================================
++ * Compress the given file: create a corresponding .gz file and remove the
++ * original.
++ */
++void file_compress(file, mode)
++    char  *file;
++    char  *mode;
++{
++    local char outfile[MAX_NAME_LEN];
++    FILE  *in;
++    gzFile out;
++
++    strcpy(outfile, file);
++    strcat(outfile, GZ_SUFFIX);
++
++    in = fopen(file, "rb");
++    if (in == NULL) {
++        perror(file);
++        exit(1);
++    }
++    out = gzopen(outfile, mode);
++    if (out == NULL) {
++        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
++        exit(1);
++    }
++    gz_compress(in, out);
++
++    unlink(file);
++}
++
++
++/* ===========================================================================
++ * Uncompress the given file and remove the original.
++ */
++void file_uncompress(file)
++    char  *file;
++{
++    local char buf[MAX_NAME_LEN];
++    char *infile, *outfile;
++    FILE  *out;
++    gzFile in;
++    int len = strlen(file);
++
++    strcpy(buf, file);
++
++    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
++        infile = file;
++        outfile = buf;
++        outfile[len-3] = '\0';
++    } else {
++        outfile = file;
++        infile = buf;
++        strcat(infile, GZ_SUFFIX);
++    }
++    in = gzopen(infile, "rb");
++    if (in == NULL) {
++        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
++        exit(1);
++    }
++    out = fopen(outfile, "wb");
++    if (out == NULL) {
++        perror(file);
++        exit(1);
++    }
++
++    gz_uncompress(in, out);
++
++    unlink(infile);
++}
++
++
++/* ===========================================================================
++ * Usage:  minigzip [-d] [-f] [-h] [-1 to -9] [files...]
++ *   -d : decompress
++ *   -f : compress with Z_FILTERED
++ *   -h : compress with Z_HUFFMAN_ONLY
++ *   -1 to -9 : compression level
++ */
++
++int main(argc, argv)
++    int argc;
++    char *argv[];
++{
++    int uncompr = 0;
++    gzFile file;
++    char outmode[20];
++
++    strcpy(outmode, "wb6 ");
++
++    prog = argv[0];
++    argc--, argv++;
++
++    while (argc > 0) {
++      if (strcmp(*argv, "-d") == 0)
++      uncompr = 1;
++      else if (strcmp(*argv, "-f") == 0)
++      outmode[3] = 'f';
++      else if (strcmp(*argv, "-h") == 0)
++      outmode[3] = 'h';
++      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
++             (*argv)[2] == 0)
++      outmode[2] = (*argv)[1];
++      else
++      break;
++      argc--, argv++;
++    }
++    if (argc == 0) {
++        SET_BINARY_MODE(stdin);
++        SET_BINARY_MODE(stdout);
++        if (uncompr) {
++            file = gzdopen(fileno(stdin), "rb");
++            if (file == NULL) error("can't gzdopen stdin");
++            gz_uncompress(file, stdout);
++        } else {
++            file = gzdopen(fileno(stdout), outmode);
++            if (file == NULL) error("can't gzdopen stdout");
++            gz_compress(stdin, file);
++        }
++    } else {
++        do {
++            if (uncompr) {
++                file_uncompress(*argv);
++            } else {
++                file_compress(*argv, outmode);
++            }
++        } while (argv++, --argc);
++    }
++    exit(0);
++    return 0; /* to avoid warning */
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..f01fb30d85515b8b74b997d826c01f10fd45a635
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1214 @@@
++/* trees.c -- output deflated data using Huffman coding
++ * Copyright (C) 1995-1998 Jean-loup Gailly
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/*
++ *  ALGORITHM
++ *
++ *      The "deflation" process uses several Huffman trees. The more
++ *      common source values are represented by shorter bit sequences.
++ *
++ *      Each code tree is stored in a compressed form which is itself
++ * a Huffman encoding of the lengths of all the code strings (in
++ * ascending order by source values).  The actual code strings are
++ * reconstructed from the lengths in the inflate process, as described
++ * in the deflate specification.
++ *
++ *  REFERENCES
++ *
++ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
++ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
++ *
++ *      Storer, James A.
++ *          Data Compression:  Methods and Theory, pp. 49-50.
++ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
++ *
++ *      Sedgewick, R.
++ *          Algorithms, p290.
++ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
++ */
++
++/* @(#) $Id$ */
++
++/* #define GEN_TREES_H */
++
++#include "deflate.h"
++
++#ifdef DEBUG
++#  include <ctype.h>
++#endif
++
++/* ===========================================================================
++ * Constants
++ */
++
++#define MAX_BL_BITS 7
++/* Bit length codes must not exceed MAX_BL_BITS bits */
++
++#define END_BLOCK 256
++/* end of block literal code */
++
++#define REP_3_6      16
++/* repeat previous bit length 3-6 times (2 bits of repeat count) */
++
++#define REPZ_3_10    17
++/* repeat a zero length 3-10 times  (3 bits of repeat count) */
++
++#define REPZ_11_138  18
++/* repeat a zero length 11-138 times  (7 bits of repeat count) */
++
++local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
++   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
++
++local const int extra_dbits[D_CODES] /* extra bits for each distance code */
++   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
++
++local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
++   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
++
++local const uch bl_order[BL_CODES]
++   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
++/* The lengths of the bit length codes are sent in order of decreasing
++ * probability, to avoid transmitting the lengths for unused bit length codes.
++ */
++
++#define Buf_size (8 * 2*sizeof(char))
++/* Number of bits used within bi_buf. (bi_buf might be implemented on
++ * more than 16 bits on some systems.)
++ */
++
++/* ===========================================================================
++ * Local data. These are initialized only once.
++ */
++
++#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
++
++#if defined(GEN_TREES_H) || !defined(STDC)
++/* non ANSI compilers may not accept trees.h */
++
++local ct_data static_ltree[L_CODES+2];
++/* The static literal tree. Since the bit lengths are imposed, there is no
++ * need for the L_CODES extra codes used during heap construction. However
++ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
++ * below).
++ */
++
++local ct_data static_dtree[D_CODES];
++/* The static distance tree. (Actually a trivial tree since all codes use
++ * 5 bits.)
++ */
++
++uch _dist_code[DIST_CODE_LEN];
++/* Distance codes. The first 256 values correspond to the distances
++ * 3 .. 258, the last 256 values correspond to the top 8 bits of
++ * the 15 bit distances.
++ */
++
++uch _length_code[MAX_MATCH-MIN_MATCH+1];
++/* length code for each normalized match length (0 == MIN_MATCH) */
++
++local int base_length[LENGTH_CODES];
++/* First normalized length for each code (0 = MIN_MATCH) */
++
++local int base_dist[D_CODES];
++/* First normalized distance for each code (0 = distance of 1) */
++
++#else
++#  include "trees.h"
++#endif /* GEN_TREES_H */
++
++struct static_tree_desc_s {
++    const ct_data *static_tree;  /* static tree or NULL */
++    const intf *extra_bits;      /* extra bits for each code or NULL */
++    int     extra_base;          /* base index for extra_bits */
++    int     elems;               /* max number of elements in the tree */
++    int     max_length;          /* max bit length for the codes */
++};
++
++local static_tree_desc  static_l_desc =
++{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
++
++local static_tree_desc  static_d_desc =
++{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
++
++local static_tree_desc  static_bl_desc =
++{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
++
++/* ===========================================================================
++ * Local (static) routines in this file.
++ */
++
++local void tr_static_init OF((void));
++local void init_block     OF((deflate_state *s));
++local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
++local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
++local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
++local void build_tree     OF((deflate_state *s, tree_desc *desc));
++local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
++local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
++local int  build_bl_tree  OF((deflate_state *s));
++local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
++                              int blcodes));
++local void compress_block OF((deflate_state *s, ct_data *ltree,
++                              ct_data *dtree));
++local void set_data_type  OF((deflate_state *s));
++local unsigned bi_reverse OF((unsigned value, int length));
++local void bi_windup      OF((deflate_state *s));
++local void bi_flush       OF((deflate_state *s));
++local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
++                              int header));
++
++#ifdef GEN_TREES_H
++local void gen_trees_header OF((void));
++#endif
++
++#ifndef DEBUG
++#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
++   /* Send a code of the given tree. c and tree must not have side effects */
++
++#else /* DEBUG */
++#  define send_code(s, c, tree) \
++     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
++       send_bits(s, tree[c].Code, tree[c].Len); }
++#endif
++
++/* ===========================================================================
++ * Output a short LSB first on the stream.
++ * IN assertion: there is enough room in pendingBuf.
++ */
++#define put_short(s, w) { \
++    put_byte(s, (uch)((w) & 0xff)); \
++    put_byte(s, (uch)((ush)(w) >> 8)); \
++}
++
++/* ===========================================================================
++ * Send a value on a given number of bits.
++ * IN assertion: length <= 16 and value fits in length bits.
++ */
++#ifdef DEBUG
++local void send_bits      OF((deflate_state *s, int value, int length));
++
++local void send_bits(s, value, length)
++    deflate_state *s;
++    int value;  /* value to send */
++    int length; /* number of bits */
++{
++    Tracevv((stderr," l %2d v %4x ", length, value));
++    Assert(length > 0 && length <= 15, "invalid length");
++    s->bits_sent += (ulg)length;
++
++    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
++     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
++     * unused bits in value.
++     */
++    if (s->bi_valid > (int)Buf_size - length) {
++        s->bi_buf |= (value << s->bi_valid);
++        put_short(s, s->bi_buf);
++        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
++        s->bi_valid += length - Buf_size;
++    } else {
++        s->bi_buf |= value << s->bi_valid;
++        s->bi_valid += length;
++    }
++}
++#else /* !DEBUG */
++
++#define send_bits(s, value, length) \
++{ int len = length;\
++  if (s->bi_valid > (int)Buf_size - len) {\
++    int val = value;\
++    s->bi_buf |= (val << s->bi_valid);\
++    put_short(s, s->bi_buf);\
++    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
++    s->bi_valid += len - Buf_size;\
++  } else {\
++    s->bi_buf |= (value) << s->bi_valid;\
++    s->bi_valid += len;\
++  }\
++}
++#endif /* DEBUG */
++
++
++#define MAX(a,b) (a >= b ? a : b)
++/* the arguments must not have side effects */
++
++/* ===========================================================================
++ * Initialize the various 'constant' tables.
++ */
++local void tr_static_init()
++{
++#if defined(GEN_TREES_H) || !defined(STDC)
++    static int static_init_done = 0;
++    int n;        /* iterates over tree elements */
++    int bits;     /* bit counter */
++    int length;   /* length value */
++    int code;     /* code value */
++    int dist;     /* distance index */
++    ush bl_count[MAX_BITS+1];
++    /* number of codes at each bit length for an optimal tree */
++
++    if (static_init_done) return;
++
++    /* For some embedded targets, global variables are not initialized: */
++    static_l_desc.static_tree = static_ltree;
++    static_l_desc.extra_bits = extra_lbits;
++    static_d_desc.static_tree = static_dtree;
++    static_d_desc.extra_bits = extra_dbits;
++    static_bl_desc.extra_bits = extra_blbits;
++
++    /* Initialize the mapping length (0..255) -> length code (0..28) */
++    length = 0;
++    for (code = 0; code < LENGTH_CODES-1; code++) {
++        base_length[code] = length;
++        for (n = 0; n < (1<<extra_lbits[code]); n++) {
++            _length_code[length++] = (uch)code;
++        }
++    }
++    Assert (length == 256, "tr_static_init: length != 256");
++    /* Note that the length 255 (match length 258) can be represented
++     * in two different ways: code 284 + 5 bits or code 285, so we
++     * overwrite length_code[255] to use the best encoding:
++     */
++    _length_code[length-1] = (uch)code;
++
++    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
++    dist = 0;
++    for (code = 0 ; code < 16; code++) {
++        base_dist[code] = dist;
++        for (n = 0; n < (1<<extra_dbits[code]); n++) {
++            _dist_code[dist++] = (uch)code;
++        }
++    }
++    Assert (dist == 256, "tr_static_init: dist != 256");
++    dist >>= 7; /* from now on, all distances are divided by 128 */
++    for ( ; code < D_CODES; code++) {
++        base_dist[code] = dist << 7;
++        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
++            _dist_code[256 + dist++] = (uch)code;
++        }
++    }
++    Assert (dist == 256, "tr_static_init: 256+dist != 512");
++
++    /* Construct the codes of the static literal tree */
++    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
++    n = 0;
++    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
++    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
++    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
++    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
++    /* Codes 286 and 287 do not exist, but we must include them in the
++     * tree construction to get a canonical Huffman tree (longest code
++     * all ones)
++     */
++    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
++
++    /* The static distance tree is trivial: */
++    for (n = 0; n < D_CODES; n++) {
++        static_dtree[n].Len = 5;
++        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
++    }
++    static_init_done = 1;
++
++#  ifdef GEN_TREES_H
++    gen_trees_header();
++#  endif
++#endif /* defined(GEN_TREES_H) || !defined(STDC) */
++}
++
++/* ===========================================================================
++ * Genererate the file trees.h describing the static trees.
++ */
++#ifdef GEN_TREES_H
++#  ifndef DEBUG
++#    include <stdio.h>
++#  endif
++
++#  define SEPARATOR(i, last, width) \
++      ((i) == (last)? "\n};\n\n" :    \
++       ((i) % (width) == (width)-1 ? ",\n" : ", "))
++
++void gen_trees_header()
++{
++    FILE *header = fopen("trees.h", "w");
++    int i;
++
++    Assert (header != NULL, "Can't open trees.h");
++    fprintf(header,
++          "/* header created automatically with -DGEN_TREES_H */\n\n");
++
++    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
++    for (i = 0; i < L_CODES+2; i++) {
++      fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
++              static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
++    }
++
++    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
++    for (i = 0; i < D_CODES; i++) {
++      fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
++              static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
++    }
++
++    fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
++    for (i = 0; i < DIST_CODE_LEN; i++) {
++      fprintf(header, "%2u%s", _dist_code[i],
++              SEPARATOR(i, DIST_CODE_LEN-1, 20));
++    }
++
++    fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
++    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
++      fprintf(header, "%2u%s", _length_code[i],
++              SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
++    }
++
++    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
++    for (i = 0; i < LENGTH_CODES; i++) {
++      fprintf(header, "%1u%s", base_length[i],
++              SEPARATOR(i, LENGTH_CODES-1, 20));
++    }
++
++    fprintf(header, "local const int base_dist[D_CODES] = {\n");
++    for (i = 0; i < D_CODES; i++) {
++      fprintf(header, "%5u%s", base_dist[i],
++              SEPARATOR(i, D_CODES-1, 10));
++    }
++
++    fclose(header);
++}
++#endif /* GEN_TREES_H */
++
++/* ===========================================================================
++ * Initialize the tree data structures for a new zlib stream.
++ */
++void _tr_init(s)
++    deflate_state *s;
++{
++    tr_static_init();
++
++    s->l_desc.dyn_tree = s->dyn_ltree;
++    s->l_desc.stat_desc = &static_l_desc;
++
++    s->d_desc.dyn_tree = s->dyn_dtree;
++    s->d_desc.stat_desc = &static_d_desc;
++
++    s->bl_desc.dyn_tree = s->bl_tree;
++    s->bl_desc.stat_desc = &static_bl_desc;
++
++    s->bi_buf = 0;
++    s->bi_valid = 0;
++    s->last_eob_len = 8; /* enough lookahead for inflate */
++#ifdef DEBUG
++    s->compressed_len = 0L;
++    s->bits_sent = 0L;
++#endif
++
++    /* Initialize the first block of the first file: */
++    init_block(s);
++}
++
++/* ===========================================================================
++ * Initialize a new block.
++ */
++local void init_block(s)
++    deflate_state *s;
++{
++    int n; /* iterates over tree elements */
++
++    /* Initialize the trees. */
++    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
++    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
++    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
++
++    s->dyn_ltree[END_BLOCK].Freq = 1;
++    s->opt_len = s->static_len = 0L;
++    s->last_lit = s->matches = 0;
++}
++
++#define SMALLEST 1
++/* Index within the heap array of least frequent node in the Huffman tree */
++
++
++/* ===========================================================================
++ * Remove the smallest element from the heap and recreate the heap with
++ * one less element. Updates heap and heap_len.
++ */
++#define pqremove(s, tree, top) \
++{\
++    top = s->heap[SMALLEST]; \
++    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
++    pqdownheap(s, tree, SMALLEST); \
++}
++
++/* ===========================================================================
++ * Compares to subtrees, using the tree depth as tie breaker when
++ * the subtrees have equal frequency. This minimizes the worst case length.
++ */
++#define smaller(tree, n, m, depth) \
++   (tree[n].Freq < tree[m].Freq || \
++   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
++
++/* ===========================================================================
++ * Restore the heap property by moving down the tree starting at node k,
++ * exchanging a node with the smallest of its two sons if necessary, stopping
++ * when the heap property is re-established (each father smaller than its
++ * two sons).
++ */
++local void pqdownheap(s, tree, k)
++    deflate_state *s;
++    ct_data *tree;  /* the tree to restore */
++    int k;               /* node to move down */
++{
++    int v = s->heap[k];
++    int j = k << 1;  /* left son of k */
++    while (j <= s->heap_len) {
++        /* Set j to the smallest of the two sons: */
++        if (j < s->heap_len &&
++            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
++            j++;
++        }
++        /* Exit if v is smaller than both sons */
++        if (smaller(tree, v, s->heap[j], s->depth)) break;
++
++        /* Exchange v with the smallest son */
++        s->heap[k] = s->heap[j];  k = j;
++
++        /* And continue down the tree, setting j to the left son of k */
++        j <<= 1;
++    }
++    s->heap[k] = v;
++}
++
++/* ===========================================================================
++ * Compute the optimal bit lengths for a tree and update the total bit length
++ * for the current block.
++ * IN assertion: the fields freq and dad are set, heap[heap_max] and
++ *    above are the tree nodes sorted by increasing frequency.
++ * OUT assertions: the field len is set to the optimal bit length, the
++ *     array bl_count contains the frequencies for each bit length.
++ *     The length opt_len is updated; static_len is also updated if stree is
++ *     not null.
++ */
++local void gen_bitlen(s, desc)
++    deflate_state *s;
++    tree_desc *desc;    /* the tree descriptor */
++{
++    ct_data *tree        = desc->dyn_tree;
++    int max_code         = desc->max_code;
++    const ct_data *stree = desc->stat_desc->static_tree;
++    const intf *extra    = desc->stat_desc->extra_bits;
++    int base             = desc->stat_desc->extra_base;
++    int max_length       = desc->stat_desc->max_length;
++    int h;              /* heap index */
++    int n, m;           /* iterate over the tree elements */
++    int bits;           /* bit length */
++    int xbits;          /* extra bits */
++    ush f;              /* frequency */
++    int overflow = 0;   /* number of elements with bit length too large */
++
++    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
++
++    /* In a first pass, compute the optimal bit lengths (which may
++     * overflow in the case of the bit length tree).
++     */
++    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
++
++    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
++        n = s->heap[h];
++        bits = tree[tree[n].Dad].Len + 1;
++        if (bits > max_length) bits = max_length, overflow++;
++        tree[n].Len = (ush)bits;
++        /* We overwrite tree[n].Dad which is no longer needed */
++
++        if (n > max_code) continue; /* not a leaf node */
++
++        s->bl_count[bits]++;
++        xbits = 0;
++        if (n >= base) xbits = extra[n-base];
++        f = tree[n].Freq;
++        s->opt_len += (ulg)f * (bits + xbits);
++        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
++    }
++    if (overflow == 0) return;
++
++    Trace((stderr,"\nbit length overflow\n"));
++    /* This happens for example on obj2 and pic of the Calgary corpus */
++
++    /* Find the first bit length which could increase: */
++    do {
++        bits = max_length-1;
++        while (s->bl_count[bits] == 0) bits--;
++        s->bl_count[bits]--;      /* move one leaf down the tree */
++        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
++        s->bl_count[max_length]--;
++        /* The brother of the overflow item also moves one step up,
++         * but this does not affect bl_count[max_length]
++         */
++        overflow -= 2;
++    } while (overflow > 0);
++
++    /* Now recompute all bit lengths, scanning in increasing frequency.
++     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
++     * lengths instead of fixing only the wrong ones. This idea is taken
++     * from 'ar' written by Haruhiko Okumura.)
++     */
++    for (bits = max_length; bits != 0; bits--) {
++        n = s->bl_count[bits];
++        while (n != 0) {
++            m = s->heap[--h];
++            if (m > max_code) continue;
++            if (tree[m].Len != (unsigned) bits) {
++                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
++                s->opt_len += ((long)bits - (long)tree[m].Len)
++                              *(long)tree[m].Freq;
++                tree[m].Len = (ush)bits;
++            }
++            n--;
++        }
++    }
++}
++
++/* ===========================================================================
++ * Generate the codes for a given tree and bit counts (which need not be
++ * optimal).
++ * IN assertion: the array bl_count contains the bit length statistics for
++ * the given tree and the field len is set for all tree elements.
++ * OUT assertion: the field code is set for all tree elements of non
++ *     zero code length.
++ */
++local void gen_codes (tree, max_code, bl_count)
++    ct_data *tree;             /* the tree to decorate */
++    int max_code;              /* largest code with non zero frequency */
++    ushf *bl_count;            /* number of codes at each bit length */
++{
++    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
++    ush code = 0;              /* running code value */
++    int bits;                  /* bit index */
++    int n;                     /* code index */
++
++    /* The distribution counts are first used to generate the code values
++     * without bit reversal.
++     */
++    for (bits = 1; bits <= MAX_BITS; bits++) {
++        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
++    }
++    /* Check that the bit counts in bl_count are consistent. The last code
++     * must be all ones.
++     */
++    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
++            "inconsistent bit counts");
++    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
++
++    for (n = 0;  n <= max_code; n++) {
++        int len = tree[n].Len;
++        if (len == 0) continue;
++        /* Now reverse the bits */
++        tree[n].Code = bi_reverse(next_code[len]++, len);
++
++        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
++             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
++    }
++}
++
++/* ===========================================================================
++ * Construct one Huffman tree and assigns the code bit strings and lengths.
++ * Update the total bit length for the current block.
++ * IN assertion: the field freq is set for all tree elements.
++ * OUT assertions: the fields len and code are set to the optimal bit length
++ *     and corresponding code. The length opt_len is updated; static_len is
++ *     also updated if stree is not null. The field max_code is set.
++ */
++local void build_tree(s, desc)
++    deflate_state *s;
++    tree_desc *desc; /* the tree descriptor */
++{
++    ct_data *tree         = desc->dyn_tree;
++    const ct_data *stree  = desc->stat_desc->static_tree;
++    int elems             = desc->stat_desc->elems;
++    int n, m;          /* iterate over heap elements */
++    int max_code = -1; /* largest code with non zero frequency */
++    int node;          /* new node being created */
++
++    /* Construct the initial heap, with least frequent element in
++     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
++     * heap[0] is not used.
++     */
++    s->heap_len = 0, s->heap_max = HEAP_SIZE;
++
++    for (n = 0; n < elems; n++) {
++        if (tree[n].Freq != 0) {
++            s->heap[++(s->heap_len)] = max_code = n;
++            s->depth[n] = 0;
++        } else {
++            tree[n].Len = 0;
++        }
++    }
++
++    /* The pkzip format requires that at least one distance code exists,
++     * and that at least one bit should be sent even if there is only one
++     * possible code. So to avoid special checks later on we force at least
++     * two codes of non zero frequency.
++     */
++    while (s->heap_len < 2) {
++        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
++        tree[node].Freq = 1;
++        s->depth[node] = 0;
++        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
++        /* node is 0 or 1 so it does not have extra bits */
++    }
++    desc->max_code = max_code;
++
++    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
++     * establish sub-heaps of increasing lengths:
++     */
++    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
++
++    /* Construct the Huffman tree by repeatedly combining the least two
++     * frequent nodes.
++     */
++    node = elems;              /* next internal node of the tree */
++    do {
++        pqremove(s, tree, n);  /* n = node of least frequency */
++        m = s->heap[SMALLEST]; /* m = node of next least frequency */
++
++        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
++        s->heap[--(s->heap_max)] = m;
++
++        /* Create a new node father of n and m */
++        tree[node].Freq = tree[n].Freq + tree[m].Freq;
++        s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
++        tree[n].Dad = tree[m].Dad = (ush)node;
++#ifdef DUMP_BL_TREE
++        if (tree == s->bl_tree) {
++            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
++                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
++        }
++#endif
++        /* and insert the new node in the heap */
++        s->heap[SMALLEST] = node++;
++        pqdownheap(s, tree, SMALLEST);
++
++    } while (s->heap_len >= 2);
++
++    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
++
++    /* At this point, the fields freq and dad are set. We can now
++     * generate the bit lengths.
++     */
++    gen_bitlen(s, (tree_desc *)desc);
++
++    /* The field len is now set, we can generate the bit codes */
++    gen_codes ((ct_data *)tree, max_code, s->bl_count);
++}
++
++/* ===========================================================================
++ * Scan a literal or distance tree to determine the frequencies of the codes
++ * in the bit length tree.
++ */
++local void scan_tree (s, tree, max_code)
++    deflate_state *s;
++    ct_data *tree;   /* the tree to be scanned */
++    int max_code;    /* and its largest code of non zero frequency */
++{
++    int n;                     /* iterates over all tree elements */
++    int prevlen = -1;          /* last emitted length */
++    int curlen;                /* length of current code */
++    int nextlen = tree[0].Len; /* length of next code */
++    int count = 0;             /* repeat count of the current code */
++    int max_count = 7;         /* max repeat count */
++    int min_count = 4;         /* min repeat count */
++
++    if (nextlen == 0) max_count = 138, min_count = 3;
++    tree[max_code+1].Len = (ush)0xffff; /* guard */
++
++    for (n = 0; n <= max_code; n++) {
++        curlen = nextlen; nextlen = tree[n+1].Len;
++        if (++count < max_count && curlen == nextlen) {
++            continue;
++        } else if (count < min_count) {
++            s->bl_tree[curlen].Freq += count;
++        } else if (curlen != 0) {
++            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
++            s->bl_tree[REP_3_6].Freq++;
++        } else if (count <= 10) {
++            s->bl_tree[REPZ_3_10].Freq++;
++        } else {
++            s->bl_tree[REPZ_11_138].Freq++;
++        }
++        count = 0; prevlen = curlen;
++        if (nextlen == 0) {
++            max_count = 138, min_count = 3;
++        } else if (curlen == nextlen) {
++            max_count = 6, min_count = 3;
++        } else {
++            max_count = 7, min_count = 4;
++        }
++    }
++}
++
++/* ===========================================================================
++ * Send a literal or distance tree in compressed form, using the codes in
++ * bl_tree.
++ */
++local void send_tree (s, tree, max_code)
++    deflate_state *s;
++    ct_data *tree; /* the tree to be scanned */
++    int max_code;       /* and its largest code of non zero frequency */
++{
++    int n;                     /* iterates over all tree elements */
++    int prevlen = -1;          /* last emitted length */
++    int curlen;                /* length of current code */
++    int nextlen = tree[0].Len; /* length of next code */
++    int count = 0;             /* repeat count of the current code */
++    int max_count = 7;         /* max repeat count */
++    int min_count = 4;         /* min repeat count */
++
++    /* tree[max_code+1].Len = -1; */  /* guard already set */
++    if (nextlen == 0) max_count = 138, min_count = 3;
++
++    for (n = 0; n <= max_code; n++) {
++        curlen = nextlen; nextlen = tree[n+1].Len;
++        if (++count < max_count && curlen == nextlen) {
++            continue;
++        } else if (count < min_count) {
++            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
++
++        } else if (curlen != 0) {
++            if (curlen != prevlen) {
++                send_code(s, curlen, s->bl_tree); count--;
++            }
++            Assert(count >= 3 && count <= 6, " 3_6?");
++            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
++
++        } else if (count <= 10) {
++            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
++
++        } else {
++            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
++        }
++        count = 0; prevlen = curlen;
++        if (nextlen == 0) {
++            max_count = 138, min_count = 3;
++        } else if (curlen == nextlen) {
++            max_count = 6, min_count = 3;
++        } else {
++            max_count = 7, min_count = 4;
++        }
++    }
++}
++
++/* ===========================================================================
++ * Construct the Huffman tree for the bit lengths and return the index in
++ * bl_order of the last bit length code to send.
++ */
++local int build_bl_tree(s)
++    deflate_state *s;
++{
++    int max_blindex;  /* index of last bit length code of non zero freq */
++
++    /* Determine the bit length frequencies for literal and distance trees */
++    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
++    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
++
++    /* Build the bit length tree: */
++    build_tree(s, (tree_desc *)(&(s->bl_desc)));
++    /* opt_len now includes the length of the tree representations, except
++     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
++     */
++
++    /* Determine the number of bit length codes to send. The pkzip format
++     * requires that at least 4 bit length codes be sent. (appnote.txt says
++     * 3 but the actual value used is 4.)
++     */
++    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
++        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
++    }
++    /* Update opt_len to include the bit length tree and counts */
++    s->opt_len += 3*(max_blindex+1) + 5+5+4;
++    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
++            s->opt_len, s->static_len));
++
++    return max_blindex;
++}
++
++/* ===========================================================================
++ * Send the header for a block using dynamic Huffman trees: the counts, the
++ * lengths of the bit length codes, the literal tree and the distance tree.
++ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
++ */
++local void send_all_trees(s, lcodes, dcodes, blcodes)
++    deflate_state *s;
++    int lcodes, dcodes, blcodes; /* number of codes for each tree */
++{
++    int rank;                    /* index in bl_order */
++
++    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
++    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
++            "too many codes");
++    Tracev((stderr, "\nbl counts: "));
++    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
++    send_bits(s, dcodes-1,   5);
++    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
++    for (rank = 0; rank < blcodes; rank++) {
++        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
++        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
++    }
++    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
++
++    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
++    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
++
++    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
++    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
++}
++
++/* ===========================================================================
++ * Send a stored block
++ */
++void _tr_stored_block(s, buf, stored_len, eof)
++    deflate_state *s;
++    charf *buf;       /* input block */
++    ulg stored_len;   /* length of input block */
++    int eof;          /* true if this is the last block for a file */
++{
++    send_bits(s, (STORED_BLOCK<<1)+eof, 3);  /* send block type */
++#ifdef DEBUG
++    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
++    s->compressed_len += (stored_len + 4) << 3;
++#endif
++    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
++}
++
++/* ===========================================================================
++ * Send one empty static block to give enough lookahead for inflate.
++ * This takes 10 bits, of which 7 may remain in the bit buffer.
++ * The current inflate code requires 9 bits of lookahead. If the
++ * last two codes for the previous block (real code plus EOB) were coded
++ * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
++ * the last real code. In this case we send two empty static blocks instead
++ * of one. (There are no problems if the previous block is stored or fixed.)
++ * To simplify the code, we assume the worst case of last real code encoded
++ * on one bit only.
++ */
++void _tr_align(s)
++    deflate_state *s;
++{
++    send_bits(s, STATIC_TREES<<1, 3);
++    send_code(s, END_BLOCK, static_ltree);
++#ifdef DEBUG
++    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
++#endif
++    bi_flush(s);
++    /* Of the 10 bits for the empty block, we have already sent
++     * (10 - bi_valid) bits. The lookahead for the last real code (before
++     * the EOB of the previous block) was thus at least one plus the length
++     * of the EOB plus what we have just sent of the empty static block.
++     */
++    if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
++        send_bits(s, STATIC_TREES<<1, 3);
++        send_code(s, END_BLOCK, static_ltree);
++#ifdef DEBUG
++        s->compressed_len += 10L;
++#endif
++        bi_flush(s);
++    }
++    s->last_eob_len = 7;
++}
++
++/* ===========================================================================
++ * Determine the best encoding for the current block: dynamic trees, static
++ * trees or store, and output the encoded block to the zip file.
++ */
++void _tr_flush_block(s, buf, stored_len, eof)
++    deflate_state *s;
++    charf *buf;       /* input block, or NULL if too old */
++    ulg stored_len;   /* length of input block */
++    int eof;          /* true if this is the last block for a file */
++{
++    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
++    int max_blindex = 0;  /* index of last bit length code of non zero freq */
++
++    /* Build the Huffman trees unless a stored block is forced */
++    if (s->level > 0) {
++
++       /* Check if the file is ascii or binary */
++      if (s->data_type == Z_UNKNOWN) set_data_type(s);
++
++      /* Construct the literal and distance trees */
++      build_tree(s, (tree_desc *)(&(s->l_desc)));
++      Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
++              s->static_len));
++
++      build_tree(s, (tree_desc *)(&(s->d_desc)));
++      Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
++              s->static_len));
++      /* At this point, opt_len and static_len are the total bit lengths of
++       * the compressed block data, excluding the tree representations.
++       */
++
++      /* Build the bit length tree for the above two trees, and get the index
++       * in bl_order of the last bit length code to send.
++       */
++      max_blindex = build_bl_tree(s);
++
++      /* Determine the best encoding. Compute first the block length in bytes*/
++      opt_lenb = (s->opt_len+3+7)>>3;
++      static_lenb = (s->static_len+3+7)>>3;
++
++      Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
++              opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
++              s->last_lit));
++
++      if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
++
++    } else {
++        Assert(buf != (char*)0, "lost buf");
++      opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
++    }
++
++#ifdef FORCE_STORED
++    if (buf != (char*)0) { /* force stored block */
++#else
++    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
++                       /* 4: two words for the lengths */
++#endif
++        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
++         * Otherwise we can't have processed more than WSIZE input bytes since
++         * the last block flush, because compression would have been
++         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
++         * transform a block into a stored block.
++         */
++        _tr_stored_block(s, buf, stored_len, eof);
++
++#ifdef FORCE_STATIC
++    } else if (static_lenb >= 0) { /* force static trees */
++#else
++    } else if (static_lenb == opt_lenb) {
++#endif
++        send_bits(s, (STATIC_TREES<<1)+eof, 3);
++        compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
++#ifdef DEBUG
++        s->compressed_len += 3 + s->static_len;
++#endif
++    } else {
++        send_bits(s, (DYN_TREES<<1)+eof, 3);
++        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
++                       max_blindex+1);
++        compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
++#ifdef DEBUG
++        s->compressed_len += 3 + s->opt_len;
++#endif
++    }
++    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
++    /* The above check is made mod 2^32, for files larger than 512 MB
++     * and uLong implemented on 32 bits.
++     */
++    init_block(s);
++
++    if (eof) {
++        bi_windup(s);
++#ifdef DEBUG
++        s->compressed_len += 7;  /* align on byte boundary */
++#endif
++    }
++    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
++           s->compressed_len-7*eof));
++}
++
++/* ===========================================================================
++ * Save the match info and tally the frequency counts. Return true if
++ * the current block must be flushed.
++ */
++int _tr_tally (s, dist, lc)
++    deflate_state *s;
++    unsigned dist;  /* distance of matched string */
++    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
++{
++    s->d_buf[s->last_lit] = (ush)dist;
++    s->l_buf[s->last_lit++] = (uch)lc;
++    if (dist == 0) {
++        /* lc is the unmatched char */
++        s->dyn_ltree[lc].Freq++;
++    } else {
++        s->matches++;
++        /* Here, lc is the match length - MIN_MATCH */
++        dist--;             /* dist = match distance - 1 */
++        Assert((ush)dist < (ush)MAX_DIST(s) &&
++               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
++               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
++
++        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
++        s->dyn_dtree[d_code(dist)].Freq++;
++    }
++
++#ifdef TRUNCATE_BLOCK
++    /* Try to guess if it is profitable to stop the current block here */
++    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
++        /* Compute an upper bound for the compressed length */
++        ulg out_length = (ulg)s->last_lit*8L;
++        ulg in_length = (ulg)((long)s->strstart - s->block_start);
++        int dcode;
++        for (dcode = 0; dcode < D_CODES; dcode++) {
++            out_length += (ulg)s->dyn_dtree[dcode].Freq *
++                (5L+extra_dbits[dcode]);
++        }
++        out_length >>= 3;
++        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
++               s->last_lit, in_length, out_length,
++               100L - out_length*100L/in_length));
++        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
++    }
++#endif
++    return (s->last_lit == s->lit_bufsize-1);
++    /* We avoid equality with lit_bufsize because of wraparound at 64K
++     * on 16 bit machines and because stored blocks are restricted to
++     * 64K-1 bytes.
++     */
++}
++
++/* ===========================================================================
++ * Send the block data compressed using the given Huffman trees
++ */
++local void compress_block(s, ltree, dtree)
++    deflate_state *s;
++    ct_data *ltree; /* literal tree */
++    ct_data *dtree; /* distance tree */
++{
++    unsigned dist;      /* distance of matched string */
++    int lc;             /* match length or unmatched char (if dist == 0) */
++    unsigned lx = 0;    /* running index in l_buf */
++    unsigned code;      /* the code to send */
++    int extra;          /* number of extra bits to send */
++
++    if (s->last_lit != 0) do {
++        dist = s->d_buf[lx];
++        lc = s->l_buf[lx++];
++        if (dist == 0) {
++            send_code(s, lc, ltree); /* send a literal byte */
++            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
++        } else {
++            /* Here, lc is the match length - MIN_MATCH */
++            code = _length_code[lc];
++            send_code(s, code+LITERALS+1, ltree); /* send the length code */
++            extra = extra_lbits[code];
++            if (extra != 0) {
++                lc -= base_length[code];
++                send_bits(s, lc, extra);       /* send the extra length bits */
++            }
++            dist--; /* dist is now the match distance - 1 */
++            code = d_code(dist);
++            Assert (code < D_CODES, "bad d_code");
++
++            send_code(s, code, dtree);       /* send the distance code */
++            extra = extra_dbits[code];
++            if (extra != 0) {
++                dist -= base_dist[code];
++                send_bits(s, dist, extra);   /* send the extra distance bits */
++            }
++        } /* literal or match pair ? */
++
++        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
++        Assert(s->pending < s->lit_bufsize + 2*lx, "pendingBuf overflow");
++
++    } while (lx < s->last_lit);
++
++    send_code(s, END_BLOCK, ltree);
++    s->last_eob_len = ltree[END_BLOCK].Len;
++}
++
++/* ===========================================================================
++ * Set the data type to ASCII or BINARY, using a crude approximation:
++ * binary if more than 20% of the bytes are <= 6 or >= 128, ascii otherwise.
++ * IN assertion: the fields freq of dyn_ltree are set and the total of all
++ * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
++ */
++local void set_data_type(s)
++    deflate_state *s;
++{
++    int n = 0;
++    unsigned ascii_freq = 0;
++    unsigned bin_freq = 0;
++    while (n < 7)        bin_freq += s->dyn_ltree[n++].Freq;
++    while (n < 128)    ascii_freq += s->dyn_ltree[n++].Freq;
++    while (n < LITERALS) bin_freq += s->dyn_ltree[n++].Freq;
++    s->data_type = (Byte)(bin_freq > (ascii_freq >> 2) ? Z_BINARY : Z_ASCII);
++}
++
++/* ===========================================================================
++ * Reverse the first len bits of a code, using straightforward code (a faster
++ * method would use a table)
++ * IN assertion: 1 <= len <= 15
++ */
++local unsigned bi_reverse(code, len)
++    unsigned code; /* the value to invert */
++    int len;       /* its bit length */
++{
++    register unsigned res = 0;
++    do {
++        res |= code & 1;
++        code >>= 1, res <<= 1;
++    } while (--len > 0);
++    return res >> 1;
++}
++
++/* ===========================================================================
++ * Flush the bit buffer, keeping at most 7 bits in it.
++ */
++local void bi_flush(s)
++    deflate_state *s;
++{
++    if (s->bi_valid == 16) {
++        put_short(s, s->bi_buf);
++        s->bi_buf = 0;
++        s->bi_valid = 0;
++    } else if (s->bi_valid >= 8) {
++        put_byte(s, (Byte)s->bi_buf);
++        s->bi_buf >>= 8;
++        s->bi_valid -= 8;
++    }
++}
++
++/* ===========================================================================
++ * Flush the bit buffer and align the output on a byte boundary
++ */
++local void bi_windup(s)
++    deflate_state *s;
++{
++    if (s->bi_valid > 8) {
++        put_short(s, s->bi_buf);
++    } else if (s->bi_valid > 0) {
++        put_byte(s, (Byte)s->bi_buf);
++    }
++    s->bi_buf = 0;
++    s->bi_valid = 0;
++#ifdef DEBUG
++    s->bits_sent = (s->bits_sent+7) & ~7;
++#endif
++}
++
++/* ===========================================================================
++ * Copy a stored block, storing first the length and its
++ * one's complement if requested.
++ */
++local void copy_block(s, buf, len, header)
++    deflate_state *s;
++    charf    *buf;    /* the input data */
++    unsigned len;     /* its length */
++    int      header;  /* true if block header must be written */
++{
++    bi_windup(s);        /* align on byte boundary */
++    s->last_eob_len = 8; /* enough lookahead for inflate */
++
++    if (header) {
++        put_short(s, (ush)len);   
++        put_short(s, (ush)~len);
++#ifdef DEBUG
++        s->bits_sent += 2*16;
++#endif
++    }
++#ifdef DEBUG
++    s->bits_sent += (ulg)len<<3;
++#endif
++    while (len--) {
++        put_byte(s, *buf++);
++    }
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..72facf900f7787e26fe05781e08ecf26b42fbd3a
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,128 @@@
++/* header created automatically with -DGEN_TREES_H */
++
++local const ct_data static_ltree[L_CODES+2] = {
++{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
++{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
++{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
++{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
++{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
++{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
++{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
++{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
++{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
++{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
++{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
++{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
++{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
++{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
++{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
++{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
++{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
++{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
++{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
++{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
++{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
++{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
++{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
++{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
++{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
++{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
++{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
++{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
++{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
++{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
++{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
++{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
++{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
++{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
++{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
++{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
++{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
++{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
++{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
++{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
++{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
++{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
++{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
++{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
++{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
++{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
++{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
++{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
++{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
++{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
++{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
++{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
++{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
++{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
++{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
++{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
++{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
++{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
++};
++
++local const ct_data static_dtree[D_CODES] = {
++{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
++{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
++{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
++{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
++{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
++{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
++};
++
++const uch _dist_code[DIST_CODE_LEN] = {
++ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
++ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
++10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
++11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
++12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
++13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
++13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
++14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
++14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
++14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
++15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
++18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
++23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
++24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
++27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
++28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
++28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
++28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
++29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
++};
++
++const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
++ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
++13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
++17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
++19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
++21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
++22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
++23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
++24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
++25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
++25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
++26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
++26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
++27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
++};
++
++local const int base_length[LENGTH_CODES] = {
++0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
++64, 80, 96, 112, 128, 160, 192, 224, 0
++};
++
++local const int base_dist[D_CODES] = {
++    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
++   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
++ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
++};
++
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..d1033213781eecf2dbd78f088b03845c5c13c085
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,58 @@@
++/* uncompr.c -- decompress a memory buffer
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#include "zlib.h"
++
++/* ===========================================================================
++     Decompresses the source buffer into the destination buffer.  sourceLen is
++   the byte length of the source buffer. Upon entry, destLen is the total
++   size of the destination buffer, which must be large enough to hold the
++   entire uncompressed data. (The size of the uncompressed data must have
++   been saved previously by the compressor and transmitted to the decompressor
++   by some mechanism outside the scope of this compression library.)
++   Upon exit, destLen is the actual size of the compressed buffer.
++     This function can be used to decompress a whole file at once if the
++   input file is mmap'ed.
++
++     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_BUF_ERROR if there was not enough room in the output
++   buffer, or Z_DATA_ERROR if the input data was corrupted.
++*/
++int ZEXPORT uncompress (dest, destLen, source, sourceLen)
++    Bytef *dest;
++    uLongf *destLen;
++    const Bytef *source;
++    uLong sourceLen;
++{
++    z_stream stream;
++    int err;
++
++    stream.next_in = (Bytef*)source;
++    stream.avail_in = (uInt)sourceLen;
++    /* Check for source > 64K on 16-bit machine: */
++    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
++
++    stream.next_out = dest;
++    stream.avail_out = (uInt)*destLen;
++    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
++
++    stream.zalloc = (alloc_func)0;
++    stream.zfree = (free_func)0;
++
++    err = inflateInit(&stream);
++    if (err != Z_OK) return err;
++
++    err = inflate(&stream, Z_FINISH);
++    if (err != Z_STREAM_END) {
++        inflateEnd(&stream);
++        return err == Z_OK ? Z_BUF_ERROR : err;
++    }
++    *destLen = stream.total_out;
++
++    err = inflateEnd(&stream);
++    return err;
++}
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6d450fc793dd867c5d4bf3966f316775bff32469
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,279 @@@
++/* zconf.h -- configuration of the zlib compression library
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#ifndef _ZCONF_H
++#define _ZCONF_H
++
++/*
++ * If you *really* need a unique prefix for all types and library functions,
++ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
++ */
++#ifdef Z_PREFIX
++#  define deflateInit_        z_deflateInit_
++#  define deflate     z_deflate
++#  define deflateEnd  z_deflateEnd
++#  define inflateInit_        z_inflateInit_
++#  define inflate     z_inflate
++#  define inflateEnd  z_inflateEnd
++#  define deflateInit2_       z_deflateInit2_
++#  define deflateSetDictionary z_deflateSetDictionary
++#  define deflateCopy z_deflateCopy
++#  define deflateReset        z_deflateReset
++#  define deflateParams       z_deflateParams
++#  define inflateInit2_       z_inflateInit2_
++#  define inflateSetDictionary z_inflateSetDictionary
++#  define inflateSync z_inflateSync
++#  define inflateSyncPoint z_inflateSyncPoint
++#  define inflateReset        z_inflateReset
++#  define compress    z_compress
++#  define compress2   z_compress2
++#  define uncompress  z_uncompress
++#  define adler32     z_adler32
++#  define crc32               z_crc32
++#  define get_crc_table z_get_crc_table
++
++#  define Byte                z_Byte
++#  define uInt                z_uInt
++#  define uLong               z_uLong
++#  define Bytef               z_Bytef
++#  define charf               z_charf
++#  define intf                z_intf
++#  define uIntf               z_uIntf
++#  define uLongf      z_uLongf
++#  define voidpf      z_voidpf
++#  define voidp               z_voidp
++#endif
++
++#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
++#  define WIN32
++#endif
++#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
++#  ifndef __32BIT__
++#    define __32BIT__
++#  endif
++#endif
++#if defined(__MSDOS__) && !defined(MSDOS)
++#  define MSDOS
++#endif
++
++/*
++ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
++ * than 64k bytes at a time (needed on systems with 16-bit int).
++ */
++#if defined(MSDOS) && !defined(__32BIT__)
++#  define MAXSEG_64K
++#endif
++#ifdef MSDOS
++#  define UNALIGNED_OK
++#endif
++
++#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32))  && !defined(STDC)
++#  define STDC
++#endif
++#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
++#  ifndef STDC
++#    define STDC
++#  endif
++#endif
++
++#ifndef STDC
++#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
++#    define const
++#  endif
++#endif
++
++/* Some Mac compilers merge all .h files incorrectly: */
++#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
++#  define NO_DUMMY_DECL
++#endif
++
++/* Old Borland C incorrectly complains about missing returns: */
++#if defined(__BORLANDC__) && (__BORLANDC__ < 0x500)
++#  define NEED_DUMMY_RETURN
++#endif
++
++
++/* Maximum value for memLevel in deflateInit2 */
++#ifndef MAX_MEM_LEVEL
++#  ifdef MAXSEG_64K
++#    define MAX_MEM_LEVEL 8
++#  else
++#    define MAX_MEM_LEVEL 9
++#  endif
++#endif
++
++/* Maximum value for windowBits in deflateInit2 and inflateInit2.
++ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
++ * created by gzip. (Files created by minigzip can still be extracted by
++ * gzip.)
++ */
++#ifndef MAX_WBITS
++#  define MAX_WBITS   15 /* 32K LZ77 window */
++#endif
++
++/* The memory requirements for deflate are (in bytes):
++            (1 << (windowBits+2)) +  (1 << (memLevel+9))
++ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
++ plus a few kilobytes for small objects. For example, if you want to reduce
++ the default memory requirements from 256K to 128K, compile with
++     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
++ Of course this will generally degrade compression (there's no free lunch).
++
++   The memory requirements for inflate are (in bytes) 1 << windowBits
++ that is, 32K for windowBits=15 (default value) plus a few kilobytes
++ for small objects.
++*/
++
++                        /* Type declarations */
++
++#ifndef OF /* function prototypes */
++#  ifdef STDC
++#    define OF(args)  args
++#  else
++#    define OF(args)  ()
++#  endif
++#endif
++
++/* The following definitions for FAR are needed only for MSDOS mixed
++ * model programming (small or medium model with some far allocations).
++ * This was tested only with MSC; for other MSDOS compilers you may have
++ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
++ * just define FAR to be empty.
++ */
++#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
++   /* MSC small or medium model */
++#  define SMALL_MEDIUM
++#  ifdef _MSC_VER
++#    define FAR _far
++#  else
++#    define FAR far
++#  endif
++#endif
++#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
++#  ifndef __32BIT__
++#    define SMALL_MEDIUM
++#    define FAR _far
++#  endif
++#endif
++
++/* Compile with -DZLIB_DLL for Windows DLL support */
++#if defined(ZLIB_DLL)
++#  if defined(_WINDOWS) || defined(WINDOWS)
++#    ifdef FAR
++#      undef FAR
++#    endif
++#    include <windows.h>
++#    define ZEXPORT  WINAPI
++#    ifdef WIN32
++#      define ZEXPORTVA  WINAPIV
++#    else
++#      define ZEXPORTVA  FAR _cdecl _export
++#    endif
++#  endif
++#  if defined (__BORLANDC__)
++#    if (__BORLANDC__ >= 0x0500) && defined (WIN32)
++#      include <windows.h>
++#      define ZEXPORT __declspec(dllexport) WINAPI
++#      define ZEXPORTRVA __declspec(dllexport) WINAPIV
++#    else
++#      if defined (_Windows) && defined (__DLL__)
++#        define ZEXPORT _export
++#        define ZEXPORTVA _export
++#      endif
++#    endif
++#  endif
++#endif
++
++#if defined (__BEOS__)
++#  if defined (ZLIB_DLL)
++#    define ZEXTERN extern __declspec(dllexport)
++#  else
++#    define ZEXTERN extern __declspec(dllimport)
++#  endif
++#endif
++
++#ifndef ZEXPORT
++#  define ZEXPORT
++#endif
++#ifndef ZEXPORTVA
++#  define ZEXPORTVA
++#endif
++#ifndef ZEXTERN
++#  define ZEXTERN extern
++#endif
++
++#ifndef FAR
++#   define FAR
++#endif
++
++#if !defined(MACOS) && !defined(TARGET_OS_MAC)
++typedef unsigned char  Byte;  /* 8 bits */
++#endif
++typedef unsigned int   uInt;  /* 16 bits or more */
++typedef unsigned long  uLong; /* 32 bits or more */
++
++#ifdef SMALL_MEDIUM
++   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
++#  define Bytef Byte FAR
++#else
++   typedef Byte  FAR Bytef;
++#endif
++typedef char  FAR charf;
++typedef int   FAR intf;
++typedef uInt  FAR uIntf;
++typedef uLong FAR uLongf;
++
++#ifdef STDC
++   typedef void FAR *voidpf;
++   typedef void     *voidp;
++#else
++   typedef Byte FAR *voidpf;
++   typedef Byte     *voidp;
++#endif
++
++#ifdef HAVE_UNISTD_H
++#  include <sys/types.h> /* for off_t */
++#  include <unistd.h>    /* for SEEK_* and off_t */
++#  define z_off_t  off_t
++#endif
++#ifndef SEEK_SET
++#  define SEEK_SET        0       /* Seek from beginning of file.  */
++#  define SEEK_CUR        1       /* Seek from current position.  */
++#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
++#endif
++#ifndef z_off_t
++#  define  z_off_t long
++#endif
++
++/* MVS linker does not support external names larger than 8 bytes */
++#if defined(__MVS__)
++#   pragma map(deflateInit_,"DEIN")
++#   pragma map(deflateInit2_,"DEIN2")
++#   pragma map(deflateEnd,"DEEND")
++#   pragma map(inflateInit_,"ININ")
++#   pragma map(inflateInit2_,"ININ2")
++#   pragma map(inflateEnd,"INEND")
++#   pragma map(inflateSync,"INSY")
++#   pragma map(inflateSetDictionary,"INSEDI")
++#   pragma map(inflate_blocks,"INBL")
++#   pragma map(inflate_blocks_new,"INBLNE")
++#   pragma map(inflate_blocks_free,"INBLFR")
++#   pragma map(inflate_blocks_reset,"INBLRE")
++#   pragma map(inflate_codes_free,"INCOFR")
++#   pragma map(inflate_codes,"INCO")
++#   pragma map(inflate_fast,"INFA")
++#   pragma map(inflate_flush,"INFLU")
++#   pragma map(inflate_mask,"INMA")
++#   pragma map(inflate_set_dictionary,"INSEDI2")
++#   pragma map(inflate_copyright,"INCOPY")
++#   pragma map(inflate_trees_bits,"INTRBI")
++#   pragma map(inflate_trees_dynamic,"INTRDY")
++#   pragma map(inflate_trees_fixed,"INTRFI")
++#   pragma map(inflate_trees_free,"INTRFR")
++#endif
++
++#endif /* _ZCONF_H */
diff --cc Lib/zlib/zlib.3
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..25c8495d25f1fd566305f221ce4826bc43eeaafc
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,107 @@@
++.TH ZLIB 3 "9 July 1998"
++.SH NAME
++zlib \- compression/decompression library
++.SH SYNOPSIS
++[see
++.I zlib.h
++for full description]
++.SH DESCRIPTION
++The
++.I zlib
++library is a general purpose data compression library.
++The code is thread safe.
++It provides in-memory compression and decompression functions,
++including integrity checks of the uncompressed data.
++This version of the library supports only one compression method (deflation)
++but other algorithms will be added later and will have the same stream interface.
++.LP
++Compression can be done in a single step if the buffers are large enough
++(for example if an input file is mmap'ed),
++or can be done by repeated calls of the compression function.
++In the latter case,
++the application must provide more input and/or consume the output
++(providing more output space) before each call.
++.LP
++The library also supports reading and writing files in
++.I gzip
++(.gz) format
++with an interface similar to that of stdio.
++.LP
++The library does not install any signal handler. The decoder checks
++the consistency of the compressed data, so the library should never
++crash even in case of corrupted input.
++.LP
++All functions of the compression library are documented in the file
++.IR zlib.h.
++The distribution source includes examples of use of the library
++the files
++.I example.c
++and
++.IR minigzip.c .
++.LP
++A Java implementation of
++.IR zlib
++is available in the Java Development Kit 1.1
++.IP
++http://www.javasoft.com/products/JDK/1.1/docs/api/Package-java.util.zip.html
++.LP
++A Perl interface to
++.IR zlib ,
++written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
++is available at CPAN (Comprehensive Perl Archive Network) sites,
++such as:
++.IP
++ftp://ftp.cis.ufl.edu/pub/perl/CPAN/modules/by-module/Compress/Compress-Zlib*
++.LP
++A Python interface to
++.IR zlib
++written by A.M. Kuchling <amk@magnet.com>
++is available from the Python Software Association sites, such as:
++.IP
++ftp://ftp.python.org/pub/python/contrib/Encoding/zlib*.tar.gz
++.SH "SEE ALSO"
++Questions about zlib should be sent to:
++.IP
++zlib@quest.jpl.nasa.gov
++or, if this fails, to the author addresses given below.
++The zlib home page is:
++.IP
++http://www.cdrom.com/pub/infozip/zlib/
++.LP
++The data format used by the zlib library is described by RFC
++(Request for Comments) 1950 to 1952 in the files: 
++.IP
++ftp://ds.internic.net/rfc/rfc1950.txt (zlib format)
++.br
++rfc1951.txt (deflate format)
++.br
++rfc1952.txt (gzip format)
++.LP
++These documents are also available in other formats from:
++.IP
++ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html
++.SH AUTHORS
++Version 1.1.3
++Copyright (C) 1995-1998 Jean-loup Gailly (jloup@gzip.org)
++and Mark Adler (madler@alumni.caltech.edu).
++.LP
++This software is provided "as-is,"
++without any express or implied warranty.
++In no event will the authors be held liable for any damages
++arising from the use of this software.
++See the distribution directory with respect to requirements
++governing redistribution.
++The deflate format used by
++.I zlib
++was defined by Phil Katz.
++The deflate and
++.I zlib
++specifications were written by L. Peter Deutsch.
++Thanks to all the people who reported problems and suggested various
++improvements in
++.IR zlib ;
++who are too numerous to cite here.
++.LP
++UNIX manual page by R. P. C. Rodgers,
++U.S. National Library of Medicine (rodgers@nlm.nih.gov).
++.\" end of man page
diff --cc Lib/zlib/zlib.h
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..49f56b43bc6c5bc89b103c4760a23330d6525086
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,893 @@@
++/* zlib.h -- interface of the 'zlib' general purpose compression library
++  version 1.1.3, July 9th, 1998
++
++  Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
++
++  This software is provided 'as-is', without any express or implied
++  warranty.  In no event will the authors be held liable for any damages
++  arising from the use of this software.
++
++  Permission is granted to anyone to use this software for any purpose,
++  including commercial applications, and to alter it and redistribute it
++  freely, subject to the following restrictions:
++
++  1. The origin of this software must not be misrepresented; you must not
++     claim that you wrote the original software. If you use this software
++     in a product, an acknowledgment in the product documentation would be
++     appreciated but is not required.
++  2. Altered source versions must be plainly marked as such, and must not be
++     misrepresented as being the original software.
++  3. This notice may not be removed or altered from any source distribution.
++
++  Jean-loup Gailly        Mark Adler
++  jloup@gzip.org          madler@alumni.caltech.edu
++
++
++  The data format used by the zlib library is described by RFCs (Request for
++  Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
++  (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
++*/
++
++#ifndef _ZLIB_H
++#define _ZLIB_H
++
++#include "zconf.h"
++
++#ifdef __cplusplus
++extern "C" {
++#endif
++
++#define ZLIB_VERSION "1.1.3"
++
++/* 
++     The 'zlib' compression library provides in-memory compression and
++  decompression functions, including integrity checks of the uncompressed
++  data.  This version of the library supports only one compression method
++  (deflation) but other algorithms will be added later and will have the same
++  stream interface.
++
++     Compression can be done in a single step if the buffers are large
++  enough (for example if an input file is mmap'ed), or can be done by
++  repeated calls of the compression function.  In the latter case, the
++  application must provide more input and/or consume the output
++  (providing more output space) before each call.
++
++     The library also supports reading and writing files in gzip (.gz) format
++  with an interface similar to that of stdio.
++
++     The library does not install any signal handler. The decoder checks
++  the consistency of the compressed data, so the library should never
++  crash even in case of corrupted input.
++*/
++
++typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
++typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
++
++struct internal_state;
++
++typedef struct z_stream_s {
++    Bytef    *next_in;  /* next input byte */
++    uInt     avail_in;  /* number of bytes available at next_in */
++    uLong    total_in;  /* total nb of input bytes read so far */
++
++    Bytef    *next_out; /* next output byte should be put there */
++    uInt     avail_out; /* remaining free space at next_out */
++    uLong    total_out; /* total nb of bytes output so far */
++
++    char     *msg;      /* last error message, NULL if no error */
++    struct internal_state FAR *state; /* not visible by applications */
++
++    alloc_func zalloc;  /* used to allocate the internal state */
++    free_func  zfree;   /* used to free the internal state */
++    voidpf     opaque;  /* private data object passed to zalloc and zfree */
++
++    int     data_type;  /* best guess about the data type: ascii or binary */
++    uLong   adler;      /* adler32 value of the uncompressed data */
++    uLong   reserved;   /* reserved for future use */
++} z_stream;
++
++typedef z_stream FAR *z_streamp;
++
++/*
++   The application must update next_in and avail_in when avail_in has
++   dropped to zero. It must update next_out and avail_out when avail_out
++   has dropped to zero. The application must initialize zalloc, zfree and
++   opaque before calling the init function. All other fields are set by the
++   compression library and must not be updated by the application.
++
++   The opaque value provided by the application will be passed as the first
++   parameter for calls of zalloc and zfree. This can be useful for custom
++   memory management. The compression library attaches no meaning to the
++   opaque value.
++
++   zalloc must return Z_NULL if there is not enough memory for the object.
++   If zlib is used in a multi-threaded application, zalloc and zfree must be
++   thread safe.
++
++   On 16-bit systems, the functions zalloc and zfree must be able to allocate
++   exactly 65536 bytes, but will not be required to allocate more than this
++   if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
++   pointers returned by zalloc for objects of exactly 65536 bytes *must*
++   have their offset normalized to zero. The default allocation function
++   provided by this library ensures this (see zutil.c). To reduce memory
++   requirements and avoid any allocation of 64K objects, at the expense of
++   compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
++
++   The fields total_in and total_out can be used for statistics or
++   progress reports. After compression, total_in holds the total size of
++   the uncompressed data and may be saved for use in the decompressor
++   (particularly if the decompressor wants to decompress everything in
++   a single step).
++*/
++
++                        /* constants */
++
++#define Z_NO_FLUSH      0
++#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
++#define Z_SYNC_FLUSH    2
++#define Z_FULL_FLUSH    3
++#define Z_FINISH        4
++/* Allowed flush values; see deflate() below for details */
++
++#define Z_OK            0
++#define Z_STREAM_END    1
++#define Z_NEED_DICT     2
++#define Z_ERRNO        (-1)
++#define Z_STREAM_ERROR (-2)
++#define Z_DATA_ERROR   (-3)
++#define Z_MEM_ERROR    (-4)
++#define Z_BUF_ERROR    (-5)
++#define Z_VERSION_ERROR (-6)
++/* Return codes for the compression/decompression functions. Negative
++ * values are errors, positive values are used for special but normal events.
++ */
++
++#define Z_NO_COMPRESSION         0
++#define Z_BEST_SPEED             1
++#define Z_BEST_COMPRESSION       9
++#define Z_DEFAULT_COMPRESSION  (-1)
++/* compression levels */
++
++#define Z_FILTERED            1
++#define Z_HUFFMAN_ONLY        2
++#define Z_DEFAULT_STRATEGY    0
++/* compression strategy; see deflateInit2() below for details */
++
++#define Z_BINARY   0
++#define Z_ASCII    1
++#define Z_UNKNOWN  2
++/* Possible values of the data_type field */
++
++#define Z_DEFLATED   8
++/* The deflate compression method (the only one supported in this version) */
++
++#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
++
++#define zlib_version zlibVersion()
++/* for compatibility with versions < 1.0.2 */
++
++                        /* basic functions */
++
++ZEXTERN const char * ZEXPORT zlibVersion OF((void));
++/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
++   If the first character differs, the library code actually used is
++   not compatible with the zlib.h header file used by the application.
++   This check is automatically made by deflateInit and inflateInit.
++ */
++
++/* 
++ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
++
++     Initializes the internal stream state for compression. The fields
++   zalloc, zfree and opaque must be initialized before by the caller.
++   If zalloc and zfree are set to Z_NULL, deflateInit updates them to
++   use default allocation functions.
++
++     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
++   1 gives best speed, 9 gives best compression, 0 gives no compression at
++   all (the input data is simply copied a block at a time).
++   Z_DEFAULT_COMPRESSION requests a default compromise between speed and
++   compression (currently equivalent to level 6).
++
++     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_STREAM_ERROR if level is not a valid compression level,
++   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
++   with the version assumed by the caller (ZLIB_VERSION).
++   msg is set to null if there is no error message.  deflateInit does not
++   perform any compression: this will be done by deflate().
++*/
++
++
++ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
++/*
++    deflate compresses as much data as possible, and stops when the input
++  buffer becomes empty or the output buffer becomes full. It may introduce some
++  output latency (reading input without producing any output) except when
++  forced to flush.
++
++    The detailed semantics are as follows. deflate performs one or both of the
++  following actions:
++
++  - Compress more input starting at next_in and update next_in and avail_in
++    accordingly. If not all input can be processed (because there is not
++    enough room in the output buffer), next_in and avail_in are updated and
++    processing will resume at this point for the next call of deflate().
++
++  - Provide more output starting at next_out and update next_out and avail_out
++    accordingly. This action is forced if the parameter flush is non zero.
++    Forcing flush frequently degrades the compression ratio, so this parameter
++    should be set only when necessary (in interactive applications).
++    Some output may be provided even if flush is not set.
++
++  Before the call of deflate(), the application should ensure that at least
++  one of the actions is possible, by providing more input and/or consuming
++  more output, and updating avail_in or avail_out accordingly; avail_out
++  should never be zero before the call. The application can consume the
++  compressed output when it wants, for example when the output buffer is full
++  (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
++  and with zero avail_out, it must be called again after making room in the
++  output buffer because there might be more output pending.
++
++    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
++  flushed to the output buffer and the output is aligned on a byte boundary, so
++  that the decompressor can get all input data available so far. (In particular
++  avail_in is zero after the call if enough output space has been provided
++  before the call.)  Flushing may degrade compression for some compression
++  algorithms and so it should be used only when necessary.
++
++    If flush is set to Z_FULL_FLUSH, all output is flushed as with
++  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
++  restart from this point if previous compressed data has been damaged or if
++  random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
++  the compression.
++
++    If deflate returns with avail_out == 0, this function must be called again
++  with the same value of the flush parameter and more output space (updated
++  avail_out), until the flush is complete (deflate returns with non-zero
++  avail_out).
++
++    If the parameter flush is set to Z_FINISH, pending input is processed,
++  pending output is flushed and deflate returns with Z_STREAM_END if there
++  was enough output space; if deflate returns with Z_OK, this function must be
++  called again with Z_FINISH and more output space (updated avail_out) but no
++  more input data, until it returns with Z_STREAM_END or an error. After
++  deflate has returned Z_STREAM_END, the only possible operations on the
++  stream are deflateReset or deflateEnd.
++  
++    Z_FINISH can be used immediately after deflateInit if all the compression
++  is to be done in a single step. In this case, avail_out must be at least
++  0.1% larger than avail_in plus 12 bytes.  If deflate does not return
++  Z_STREAM_END, then it must be called again as described above.
++
++    deflate() sets strm->adler to the adler32 checksum of all input read
++  so far (that is, total_in bytes).
++
++    deflate() may update data_type if it can make a good guess about
++  the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
++  binary. This field is only for information purposes and does not affect
++  the compression algorithm in any manner.
++
++    deflate() returns Z_OK if some progress has been made (more input
++  processed or more output produced), Z_STREAM_END if all input has been
++  consumed and all output has been produced (only when flush is set to
++  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
++  if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
++  (for example avail_in or avail_out was zero).
++*/
++
++
++ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
++/*
++     All dynamically allocated data structures for this stream are freed.
++   This function discards any unprocessed input and does not flush any
++   pending output.
++
++     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
++   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
++   prematurely (some input or output was discarded). In the error case,
++   msg may be set but then points to a static string (which must not be
++   deallocated).
++*/
++
++
++/* 
++ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
++
++     Initializes the internal stream state for decompression. The fields
++   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
++   the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
++   value depends on the compression method), inflateInit determines the
++   compression method from the zlib header and allocates all data structures
++   accordingly; otherwise the allocation will be deferred to the first call of
++   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
++   use default allocation functions.
++
++     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
++   version assumed by the caller.  msg is set to null if there is no error
++   message. inflateInit does not perform any decompression apart from reading
++   the zlib header if present: this will be done by inflate().  (So next_in and
++   avail_in may be modified, but next_out and avail_out are unchanged.)
++*/
++
++
++ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
++/*
++    inflate decompresses as much data as possible, and stops when the input
++  buffer becomes empty or the output buffer becomes full. It may some
++  introduce some output latency (reading input without producing any output)
++  except when forced to flush.
++
++  The detailed semantics are as follows. inflate performs one or both of the
++  following actions:
++
++  - Decompress more input starting at next_in and update next_in and avail_in
++    accordingly. If not all input can be processed (because there is not
++    enough room in the output buffer), next_in is updated and processing
++    will resume at this point for the next call of inflate().
++
++  - Provide more output starting at next_out and update next_out and avail_out
++    accordingly.  inflate() provides as much output as possible, until there
++    is no more input data or no more space in the output buffer (see below
++    about the flush parameter).
++
++  Before the call of inflate(), the application should ensure that at least
++  one of the actions is possible, by providing more input and/or consuming
++  more output, and updating the next_* and avail_* values accordingly.
++  The application can consume the uncompressed output when it wants, for
++  example when the output buffer is full (avail_out == 0), or after each
++  call of inflate(). If inflate returns Z_OK and with zero avail_out, it
++  must be called again after making room in the output buffer because there
++  might be more output pending.
++
++    If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
++  output as possible to the output buffer. The flushing behavior of inflate is
++  not specified for values of the flush parameter other than Z_SYNC_FLUSH
++  and Z_FINISH, but the current implementation actually flushes as much output
++  as possible anyway.
++
++    inflate() should normally be called until it returns Z_STREAM_END or an
++  error. However if all decompression is to be performed in a single step
++  (a single call of inflate), the parameter flush should be set to
++  Z_FINISH. In this case all pending input is processed and all pending
++  output is flushed; avail_out must be large enough to hold all the
++  uncompressed data. (The size of the uncompressed data may have been saved
++  by the compressor for this purpose.) The next operation on this stream must
++  be inflateEnd to deallocate the decompression state. The use of Z_FINISH
++  is never required, but can be used to inform inflate that a faster routine
++  may be used for the single inflate() call.
++
++     If a preset dictionary is needed at this point (see inflateSetDictionary
++  below), inflate sets strm-adler to the adler32 checksum of the
++  dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise 
++  it sets strm->adler to the adler32 checksum of all output produced
++  so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
++  an error code as described below. At the end of the stream, inflate()
++  checks that its computed adler32 checksum is equal to that saved by the
++  compressor and returns Z_STREAM_END only if the checksum is correct.
++
++    inflate() returns Z_OK if some progress has been made (more input processed
++  or more output produced), Z_STREAM_END if the end of the compressed data has
++  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
++  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
++  corrupted (input stream not conforming to the zlib format or incorrect
++  adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
++  (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
++  enough memory, Z_BUF_ERROR if no progress is possible or if there was not
++  enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
++  case, the application may then call inflateSync to look for a good
++  compression block.
++*/
++
++
++ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
++/*
++     All dynamically allocated data structures for this stream are freed.
++   This function discards any unprocessed input and does not flush any
++   pending output.
++
++     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
++   was inconsistent. In the error case, msg may be set but then points to a
++   static string (which must not be deallocated).
++*/
++
++                        /* Advanced functions */
++
++/*
++    The following functions are needed only in some special applications.
++*/
++
++/*   
++ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
++                                     int  level,
++                                     int  method,
++                                     int  windowBits,
++                                     int  memLevel,
++                                     int  strategy));
++
++     This is another version of deflateInit with more compression options. The
++   fields next_in, zalloc, zfree and opaque must be initialized before by
++   the caller.
++
++     The method parameter is the compression method. It must be Z_DEFLATED in
++   this version of the library.
++
++     The windowBits parameter is the base two logarithm of the window size
++   (the size of the history buffer).  It should be in the range 8..15 for this
++   version of the library. Larger values of this parameter result in better
++   compression at the expense of memory usage. The default value is 15 if
++   deflateInit is used instead.
++
++     The memLevel parameter specifies how much memory should be allocated
++   for the internal compression state. memLevel=1 uses minimum memory but
++   is slow and reduces compression ratio; memLevel=9 uses maximum memory
++   for optimal speed. The default value is 8. See zconf.h for total memory
++   usage as a function of windowBits and memLevel.
++
++     The strategy parameter is used to tune the compression algorithm. Use the
++   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
++   filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
++   string match).  Filtered data consists mostly of small values with a
++   somewhat random distribution. In this case, the compression algorithm is
++   tuned to compress them better. The effect of Z_FILTERED is to force more
++   Huffman coding and less string matching; it is somewhat intermediate
++   between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
++   the compression ratio but not the correctness of the compressed output even
++   if it is not set appropriately.
++
++      deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
++   method). msg is set to null if there is no error message.  deflateInit2 does
++   not perform any compression: this will be done by deflate().
++*/
++                            
++ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
++                                             const Bytef *dictionary,
++                                             uInt  dictLength));
++/*
++     Initializes the compression dictionary from the given byte sequence
++   without producing any compressed output. This function must be called
++   immediately after deflateInit, deflateInit2 or deflateReset, before any
++   call of deflate. The compressor and decompressor must use exactly the same
++   dictionary (see inflateSetDictionary).
++
++     The dictionary should consist of strings (byte sequences) that are likely
++   to be encountered later in the data to be compressed, with the most commonly
++   used strings preferably put towards the end of the dictionary. Using a
++   dictionary is most useful when the data to be compressed is short and can be
++   predicted with good accuracy; the data can then be compressed better than
++   with the default empty dictionary.
++
++     Depending on the size of the compression data structures selected by
++   deflateInit or deflateInit2, a part of the dictionary may in effect be
++   discarded, for example if the dictionary is larger than the window size in
++   deflate or deflate2. Thus the strings most likely to be useful should be
++   put at the end of the dictionary, not at the front.
++
++     Upon return of this function, strm->adler is set to the Adler32 value
++   of the dictionary; the decompressor may later use this value to determine
++   which dictionary has been used by the compressor. (The Adler32 value
++   applies to the whole dictionary even if only a subset of the dictionary is
++   actually used by the compressor.)
++
++     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
++   parameter is invalid (such as NULL dictionary) or the stream state is
++   inconsistent (for example if deflate has already been called for this stream
++   or if the compression method is bsort). deflateSetDictionary does not
++   perform any compression: this will be done by deflate().
++*/
++
++ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
++                                    z_streamp source));
++/*
++     Sets the destination stream as a complete copy of the source stream.
++
++     This function can be useful when several compression strategies will be
++   tried, for example when there are several ways of pre-processing the input
++   data with a filter. The streams that will be discarded should then be freed
++   by calling deflateEnd.  Note that deflateCopy duplicates the internal
++   compression state which can be quite large, so this strategy is slow and
++   can consume lots of memory.
++
++     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
++   (such as zalloc being NULL). msg is left unchanged in both source and
++   destination.
++*/
++
++ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
++/*
++     This function is equivalent to deflateEnd followed by deflateInit,
++   but does not free and reallocate all the internal compression state.
++   The stream will keep the same compression level and any other attributes
++   that may have been set by deflateInit2.
++
++      deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
++   stream state was inconsistent (such as zalloc or state being NULL).
++*/
++
++ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
++                                    int level,
++                                    int strategy));
++/*
++     Dynamically update the compression level and compression strategy.  The
++   interpretation of level and strategy is as in deflateInit2.  This can be
++   used to switch between compression and straight copy of the input data, or
++   to switch to a different kind of input data requiring a different
++   strategy. If the compression level is changed, the input available so far
++   is compressed with the old level (and may be flushed); the new level will
++   take effect only at the next call of deflate().
++
++     Before the call of deflateParams, the stream state must be set as for
++   a call of deflate(), since the currently available input may have to
++   be compressed and flushed. In particular, strm->avail_out must be non-zero.
++
++     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
++   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
++   if strm->avail_out was zero.
++*/
++
++/*   
++ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
++                                     int  windowBits));
++
++     This is another version of inflateInit with an extra parameter. The
++   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
++   before by the caller.
++
++     The windowBits parameter is the base two logarithm of the maximum window
++   size (the size of the history buffer).  It should be in the range 8..15 for
++   this version of the library. The default value is 15 if inflateInit is used
++   instead. If a compressed stream with a larger window size is given as
++   input, inflate() will return with the error code Z_DATA_ERROR instead of
++   trying to allocate a larger window.
++
++      inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
++   memLevel). msg is set to null if there is no error message.  inflateInit2
++   does not perform any decompression apart from reading the zlib header if
++   present: this will be done by inflate(). (So next_in and avail_in may be
++   modified, but next_out and avail_out are unchanged.)
++*/
++
++ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
++                                             const Bytef *dictionary,
++                                             uInt  dictLength));
++/*
++     Initializes the decompression dictionary from the given uncompressed byte
++   sequence. This function must be called immediately after a call of inflate
++   if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
++   can be determined from the Adler32 value returned by this call of
++   inflate. The compressor and decompressor must use exactly the same
++   dictionary (see deflateSetDictionary).
++
++     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
++   parameter is invalid (such as NULL dictionary) or the stream state is
++   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
++   expected one (incorrect Adler32 value). inflateSetDictionary does not
++   perform any decompression: this will be done by subsequent calls of
++   inflate().
++*/
++
++ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
++/* 
++    Skips invalid compressed data until a full flush point (see above the
++  description of deflate with Z_FULL_FLUSH) can be found, or until all
++  available input is skipped. No output is provided.
++
++    inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
++  if no more input was provided, Z_DATA_ERROR if no flush point has been found,
++  or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
++  case, the application may save the current current value of total_in which
++  indicates where valid compressed data was found. In the error case, the
++  application may repeatedly call inflateSync, providing more input each time,
++  until success or end of the input data.
++*/
++
++ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
++/*
++     This function is equivalent to inflateEnd followed by inflateInit,
++   but does not free and reallocate all the internal decompression state.
++   The stream will keep attributes that may have been set by inflateInit2.
++
++      inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
++   stream state was inconsistent (such as zalloc or state being NULL).
++*/
++
++
++                        /* utility functions */
++
++/*
++     The following utility functions are implemented on top of the
++   basic stream-oriented functions. To simplify the interface, some
++   default options are assumed (compression level and memory usage,
++   standard memory allocation functions). The source code of these
++   utility functions can easily be modified if you need special options.
++*/
++
++ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
++                                 const Bytef *source, uLong sourceLen));
++/*
++     Compresses the source buffer into the destination buffer.  sourceLen is
++   the byte length of the source buffer. Upon entry, destLen is the total
++   size of the destination buffer, which must be at least 0.1% larger than
++   sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
++   compressed buffer.
++     This function can be used to compress a whole file at once if the
++   input file is mmap'ed.
++     compress returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_BUF_ERROR if there was not enough room in the output
++   buffer.
++*/
++
++ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
++                                  const Bytef *source, uLong sourceLen,
++                                  int level));
++/*
++     Compresses the source buffer into the destination buffer. The level
++   parameter has the same meaning as in deflateInit.  sourceLen is the byte
++   length of the source buffer. Upon entry, destLen is the total size of the
++   destination buffer, which must be at least 0.1% larger than sourceLen plus
++   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
++
++     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
++   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
++   Z_STREAM_ERROR if the level parameter is invalid.
++*/
++
++ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
++                                   const Bytef *source, uLong sourceLen));
++/*
++     Decompresses the source buffer into the destination buffer.  sourceLen is
++   the byte length of the source buffer. Upon entry, destLen is the total
++   size of the destination buffer, which must be large enough to hold the
++   entire uncompressed data. (The size of the uncompressed data must have
++   been saved previously by the compressor and transmitted to the decompressor
++   by some mechanism outside the scope of this compression library.)
++   Upon exit, destLen is the actual size of the compressed buffer.
++     This function can be used to decompress a whole file at once if the
++   input file is mmap'ed.
++
++     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
++   enough memory, Z_BUF_ERROR if there was not enough room in the output
++   buffer, or Z_DATA_ERROR if the input data was corrupted.
++*/
++
++
++typedef voidp gzFile;
++
++ZEXTERN gzFile ZEXPORT gzopen  OF((const char *path, const char *mode));
++/*
++     Opens a gzip (.gz) file for reading or writing. The mode parameter
++   is as in fopen ("rb" or "wb") but can also include a compression level
++   ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
++   Huffman only compression as in "wb1h". (See the description
++   of deflateInit2 for more information about the strategy parameter.)
++
++     gzopen can be used to read a file which is not in gzip format; in this
++   case gzread will directly read from the file without decompression.
++
++     gzopen returns NULL if the file could not be opened or if there was
++   insufficient memory to allocate the (de)compression state; errno
++   can be checked to distinguish the two cases (if errno is zero, the
++   zlib error is Z_MEM_ERROR).  */
++
++ZEXTERN gzFile ZEXPORT gzdopen  OF((int fd, const char *mode));
++/*
++     gzdopen() associates a gzFile with the file descriptor fd.  File
++   descriptors are obtained from calls like open, dup, creat, pipe or
++   fileno (in the file has been previously opened with fopen).
++   The mode parameter is as in gzopen.
++     The next call of gzclose on the returned gzFile will also close the
++   file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
++   descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
++     gzdopen returns NULL if there was insufficient memory to allocate
++   the (de)compression state.
++*/
++
++ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
++/*
++     Dynamically update the compression level or strategy. See the description
++   of deflateInit2 for the meaning of these parameters.
++     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
++   opened for writing.
++*/
++
++ZEXTERN int ZEXPORT    gzread  OF((gzFile file, voidp buf, unsigned len));
++/*
++     Reads the given number of uncompressed bytes from the compressed file.
++   If the input file was not in gzip format, gzread copies the given number
++   of bytes into the buffer.
++     gzread returns the number of uncompressed bytes actually read (0 for
++   end of file, -1 for error). */
++
++ZEXTERN int ZEXPORT    gzwrite OF((gzFile file, 
++                                 const voidp buf, unsigned len));
++/*
++     Writes the given number of uncompressed bytes into the compressed file.
++   gzwrite returns the number of uncompressed bytes actually written
++   (0 in case of error).
++*/
++
++ZEXTERN int ZEXPORTVA   gzprintf OF((gzFile file, const char *format, ...));
++/*
++     Converts, formats, and writes the args to the compressed file under
++   control of the format string, as in fprintf. gzprintf returns the number of
++   uncompressed bytes actually written (0 in case of error).
++*/
++
++ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
++/*
++      Writes the given null-terminated string to the compressed file, excluding
++   the terminating null character.
++      gzputs returns the number of characters written, or -1 in case of error.
++*/
++
++ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
++/*
++      Reads bytes from the compressed file until len-1 characters are read, or
++   a newline character is read and transferred to buf, or an end-of-file
++   condition is encountered.  The string is then terminated with a null
++   character.
++      gzgets returns buf, or Z_NULL in case of error.
++*/
++
++ZEXTERN int ZEXPORT    gzputc OF((gzFile file, int c));
++/*
++      Writes c, converted to an unsigned char, into the compressed file.
++   gzputc returns the value that was written, or -1 in case of error.
++*/
++
++ZEXTERN int ZEXPORT    gzgetc OF((gzFile file));
++/*
++      Reads one byte from the compressed file. gzgetc returns this byte
++   or -1 in case of end of file or error.
++*/
++
++ZEXTERN int ZEXPORT    gzflush OF((gzFile file, int flush));
++/*
++     Flushes all pending output into the compressed file. The parameter
++   flush is as in the deflate() function. The return value is the zlib
++   error number (see function gzerror below). gzflush returns Z_OK if
++   the flush parameter is Z_FINISH and all output could be flushed.
++     gzflush should be called only when strictly necessary because it can
++   degrade compression.
++*/
++
++ZEXTERN z_off_t ZEXPORT    gzseek OF((gzFile file,
++                                    z_off_t offset, int whence));
++/* 
++      Sets the starting position for the next gzread or gzwrite on the
++   given compressed file. The offset represents a number of bytes in the
++   uncompressed data stream. The whence parameter is defined as in lseek(2);
++   the value SEEK_END is not supported.
++     If the file is opened for reading, this function is emulated but can be
++   extremely slow. If the file is opened for writing, only forward seeks are
++   supported; gzseek then compresses a sequence of zeroes up to the new
++   starting position.
++
++      gzseek returns the resulting offset location as measured in bytes from
++   the beginning of the uncompressed stream, or -1 in case of error, in
++   particular if the file is opened for writing and the new starting position
++   would be before the current position.
++*/
++
++ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
++/*
++     Rewinds the given file. This function is supported only for reading.
++
++   gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
++*/
++
++ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
++/*
++     Returns the starting position for the next gzread or gzwrite on the
++   given compressed file. This position represents a number of bytes in the
++   uncompressed data stream.
++
++   gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
++*/
++
++ZEXTERN int ZEXPORT gzeof OF((gzFile file));
++/*
++     Returns 1 when EOF has previously been detected reading the given
++   input stream, otherwise zero.
++*/
++
++ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
++/*
++     Flushes all pending output if necessary, closes the compressed file
++   and deallocates all the (de)compression state. The return value is the zlib
++   error number (see function gzerror below).
++*/
++
++ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
++/*
++     Returns the error message for the last error which occurred on the
++   given compressed file. errnum is set to zlib error number. If an
++   error occurred in the file system and not in the compression library,
++   errnum is set to Z_ERRNO and the application may consult errno
++   to get the exact error code.
++*/
++
++                        /* checksum functions */
++
++/*
++     These functions are not related to compression but are exported
++   anyway because they might be useful in applications using the
++   compression library.
++*/
++
++ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
++
++/*
++     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
++   return the updated checksum. If buf is NULL, this function returns
++   the required initial value for the checksum.
++   An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
++   much faster. Usage example:
++
++     uLong adler = adler32(0L, Z_NULL, 0);
++
++     while (read_buffer(buffer, length) != EOF) {
++       adler = adler32(adler, buffer, length);
++     }
++     if (adler != original_adler) error();
++*/
++
++ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
++/*
++     Update a running crc with the bytes buf[0..len-1] and return the updated
++   crc. If buf is NULL, this function returns the required initial value
++   for the crc. Pre- and post-conditioning (one's complement) is performed
++   within this function so it shouldn't be done by the application.
++   Usage example:
++
++     uLong crc = crc32(0L, Z_NULL, 0);
++
++     while (read_buffer(buffer, length) != EOF) {
++       crc = crc32(crc, buffer, length);
++     }
++     if (crc != original_crc) error();
++*/
++
++
++                        /* various hacks, don't look :) */
++
++/* deflateInit and inflateInit are macros to allow checking the zlib version
++ * and the compiler's view of z_stream:
++ */
++ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
++                                     const char *version, int stream_size));
++ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
++                                     const char *version, int stream_size));
++ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
++                                      int windowBits, int memLevel,
++                                      int strategy, const char *version,
++                                      int stream_size));
++ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
++                                      const char *version, int stream_size));
++#define deflateInit(strm, level) \
++        deflateInit_((strm), (level),       ZLIB_VERSION, sizeof(z_stream))
++#define inflateInit(strm) \
++        inflateInit_((strm),                ZLIB_VERSION, sizeof(z_stream))
++#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
++        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
++                      (strategy),           ZLIB_VERSION, sizeof(z_stream))
++#define inflateInit2(strm, windowBits) \
++        inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
++
++
++#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
++    struct internal_state {int dummy;}; /* hack for buggy compilers */
++#endif
++
++ZEXTERN const char   * ZEXPORT zError           OF((int err));
++ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp z));
++ZEXTERN const uLongf * ZEXPORT get_crc_table    OF((void));
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif /* _ZLIB_H */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..b3de4e8837023d2d05756b62895efbe849e45189
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,225 @@@
++/* zutil.c -- target dependent utility functions for the compression library
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h 
++ */
++
++/* @(#) $Id$ */
++
++#include "zutil.h"
++
++struct internal_state      {int dummy;}; /* for buggy compilers */
++
++#ifndef STDC
++extern void exit OF((int));
++#endif
++
++const char *z_errmsg[10] = {
++"need dictionary",     /* Z_NEED_DICT       2  */
++"stream end",          /* Z_STREAM_END      1  */
++"",                    /* Z_OK              0  */
++"file error",          /* Z_ERRNO         (-1) */
++"stream error",        /* Z_STREAM_ERROR  (-2) */
++"data error",          /* Z_DATA_ERROR    (-3) */
++"insufficient memory", /* Z_MEM_ERROR     (-4) */
++"buffer error",        /* Z_BUF_ERROR     (-5) */
++"incompatible version",/* Z_VERSION_ERROR (-6) */
++""};
++
++
++const char * ZEXPORT zlibVersion()
++{
++    return ZLIB_VERSION;
++}
++
++#ifdef DEBUG
++
++#  ifndef verbose
++#    define verbose 0
++#  endif
++int z_verbose = verbose;
++
++void z_error (m)
++    char *m;
++{
++    fprintf(stderr, "%s\n", m);
++    exit(1);
++}
++#endif
++
++/* exported to allow conversion of error code to string for compress() and
++ * uncompress()
++ */
++const char * ZEXPORT zError(err)
++    int err;
++{
++    return ERR_MSG(err);
++}
++
++
++#ifndef HAVE_MEMCPY
++
++void zmemcpy(dest, source, len)
++    Bytef* dest;
++    const Bytef* source;
++    uInt  len;
++{
++    if (len == 0) return;
++    do {
++        *dest++ = *source++; /* ??? to be unrolled */
++    } while (--len != 0);
++}
++
++int zmemcmp(s1, s2, len)
++    const Bytef* s1;
++    const Bytef* s2;
++    uInt  len;
++{
++    uInt j;
++
++    for (j = 0; j < len; j++) {
++        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
++    }
++    return 0;
++}
++
++void zmemzero(dest, len)
++    Bytef* dest;
++    uInt  len;
++{
++    if (len == 0) return;
++    do {
++        *dest++ = 0;  /* ??? to be unrolled */
++    } while (--len != 0);
++}
++#endif
++
++#ifdef __TURBOC__
++#if (defined( __BORLANDC__) || !defined(SMALL_MEDIUM)) && !defined(__32BIT__)
++/* Small and medium model in Turbo C are for now limited to near allocation
++ * with reduced MAX_WBITS and MAX_MEM_LEVEL
++ */
++#  define MY_ZCALLOC
++
++/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
++ * and farmalloc(64K) returns a pointer with an offset of 8, so we
++ * must fix the pointer. Warning: the pointer must be put back to its
++ * original form in order to free it, use zcfree().
++ */
++
++#define MAX_PTR 10
++/* 10*64K = 640K */
++
++local int next_ptr = 0;
++
++typedef struct ptr_table_s {
++    voidpf org_ptr;
++    voidpf new_ptr;
++} ptr_table;
++
++local ptr_table table[MAX_PTR];
++/* This table is used to remember the original form of pointers
++ * to large buffers (64K). Such pointers are normalized with a zero offset.
++ * Since MSDOS is not a preemptive multitasking OS, this table is not
++ * protected from concurrent access. This hack doesn't work anyway on
++ * a protected system like OS/2. Use Microsoft C instead.
++ */
++
++voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
++{
++    voidpf buf = opaque; /* just to make some compilers happy */
++    ulg bsize = (ulg)items*size;
++
++    /* If we allocate less than 65520 bytes, we assume that farmalloc
++     * will return a usable pointer which doesn't have to be normalized.
++     */
++    if (bsize < 65520L) {
++        buf = farmalloc(bsize);
++        if (*(ush*)&buf != 0) return buf;
++    } else {
++        buf = farmalloc(bsize + 16L);
++    }
++    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
++    table[next_ptr].org_ptr = buf;
++
++    /* Normalize the pointer to seg:0 */
++    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
++    *(ush*)&buf = 0;
++    table[next_ptr++].new_ptr = buf;
++    return buf;
++}
++
++void  zcfree (voidpf opaque, voidpf ptr)
++{
++    int n;
++    if (*(ush*)&ptr != 0) { /* object < 64K */
++        farfree(ptr);
++        return;
++    }
++    /* Find the original pointer */
++    for (n = 0; n < next_ptr; n++) {
++        if (ptr != table[n].new_ptr) continue;
++
++        farfree(table[n].org_ptr);
++        while (++n < next_ptr) {
++            table[n-1] = table[n];
++        }
++        next_ptr--;
++        return;
++    }
++    ptr = opaque; /* just to make some compilers happy */
++    Assert(0, "zcfree: ptr not found");
++}
++#endif
++#endif /* __TURBOC__ */
++
++
++#if defined(M_I86) && !defined(__32BIT__)
++/* Microsoft C in 16-bit mode */
++
++#  define MY_ZCALLOC
++
++#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
++#  define _halloc  halloc
++#  define _hfree   hfree
++#endif
++
++voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
++{
++    if (opaque) opaque = 0; /* to make compiler happy */
++    return _halloc((long)items, size);
++}
++
++void  zcfree (voidpf opaque, voidpf ptr)
++{
++    if (opaque) opaque = 0; /* to make compiler happy */
++    _hfree(ptr);
++}
++
++#endif /* MSC */
++
++
++#ifndef MY_ZCALLOC /* Any system without a special alloc function */
++
++#ifndef STDC
++extern voidp  calloc OF((uInt items, uInt size));
++extern void   free   OF((voidpf ptr));
++#endif
++
++voidpf zcalloc (opaque, items, size)
++    voidpf opaque;
++    unsigned items;
++    unsigned size;
++{
++    if (opaque) items += size - size; /* make compiler happy */
++    return (voidpf)calloc(items, size);
++}
++
++void  zcfree (opaque, ptr)
++    voidpf opaque;
++    voidpf ptr;
++{
++    free(ptr);
++    if (opaque) return; /* make compiler happy */
++}
++
++#endif /* MY_ZCALLOC */
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..6f2cb97ca11ff23c92c0e7a84079d6494ce81669
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,220 @@@
++/* zutil.h -- internal interface and configuration of the compression library
++ * Copyright (C) 1995-1998 Jean-loup Gailly.
++ * For conditions of distribution and use, see copyright notice in zlib.h
++ */
++
++/* WARNING: this file should *not* be used by applications. It is
++   part of the implementation of the compression library and is
++   subject to change. Applications should only use zlib.h.
++ */
++
++/* @(#) $Id$ */
++
++#ifndef _Z_UTIL_H
++#define _Z_UTIL_H
++
++#include "zlib.h"
++
++#ifdef STDC
++#  include <stddef.h>
++#  include <string.h>
++#  include <stdlib.h>
++#endif
++#ifdef NO_ERRNO_H
++    extern int errno;
++#else
++#   include <errno.h>
++#endif
++
++#ifndef local
++#  define local static
++#endif
++/* compile with -Dlocal if your debugger can't find static symbols */
++
++typedef unsigned char  uch;
++typedef uch FAR uchf;
++typedef unsigned short ush;
++typedef ush FAR ushf;
++typedef unsigned long  ulg;
++
++extern const char *z_errmsg[10]; /* indexed by 2-zlib_error */
++/* (size given to avoid silly warnings with Visual C++) */
++
++#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
++
++#define ERR_RETURN(strm,err) \
++  return (strm->msg = (char*)ERR_MSG(err), (err))
++/* To be used only when the state is known to be valid */
++
++        /* common constants */
++
++#ifndef DEF_WBITS
++#  define DEF_WBITS MAX_WBITS
++#endif
++/* default windowBits for decompression. MAX_WBITS is for compression only */
++
++#if MAX_MEM_LEVEL >= 8
++#  define DEF_MEM_LEVEL 8
++#else
++#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
++#endif
++/* default memLevel */
++
++#define STORED_BLOCK 0
++#define STATIC_TREES 1
++#define DYN_TREES    2
++/* The three kinds of block type */
++
++#define MIN_MATCH  3
++#define MAX_MATCH  258
++/* The minimum and maximum match lengths */
++
++#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
++
++        /* target dependencies */
++
++#ifdef MSDOS
++#  define OS_CODE  0x00
++#  if defined(__TURBOC__) || defined(__BORLANDC__)
++#    if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
++       /* Allow compilation with ANSI keywords only enabled */
++       void _Cdecl farfree( void *block );
++       void *_Cdecl farmalloc( unsigned long nbytes );
++#    else
++#     include <alloc.h>
++#    endif
++#  else /* MSC or DJGPP */
++#    include <malloc.h>
++#  endif
++#endif
++
++#ifdef OS2
++#  define OS_CODE  0x06
++#endif
++
++#ifdef WIN32 /* Window 95 & Windows NT */
++#  define OS_CODE  0x0b
++#endif
++
++#if defined(VAXC) || defined(VMS)
++#  define OS_CODE  0x02
++#  define F_OPEN(name, mode) \
++     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
++#endif
++
++#ifdef AMIGA
++#  define OS_CODE  0x01
++#endif
++
++#if defined(ATARI) || defined(atarist)
++#  define OS_CODE  0x05
++#endif
++
++#if defined(MACOS) || defined(TARGET_OS_MAC)
++#  define OS_CODE  0x07
++#  if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
++#    include <unix.h> /* for fdopen */
++#  else
++#    ifndef fdopen
++#      define fdopen(fd,mode) NULL /* No fdopen() */
++#    endif
++#  endif
++#endif
++
++#ifdef __50SERIES /* Prime/PRIMOS */
++#  define OS_CODE  0x0F
++#endif
++
++#ifdef TOPS20
++#  define OS_CODE  0x0a
++#endif
++
++#if defined(_BEOS_) || defined(RISCOS)
++#  define fdopen(fd,mode) NULL /* No fdopen() */
++#endif
++
++#if (defined(_MSC_VER) && (_MSC_VER > 600))
++#  define fdopen(fd,type)  _fdopen(fd,type)
++#endif
++
++
++        /* Common defaults */
++
++#ifndef OS_CODE
++#  define OS_CODE  0x03  /* assume Unix */
++#endif
++
++#ifndef F_OPEN
++#  define F_OPEN(name, mode) fopen((name), (mode))
++#endif
++
++         /* functions */
++
++#ifdef HAVE_STRERROR
++   extern char *strerror OF((int));
++#  define zstrerror(errnum) strerror(errnum)
++#else
++#  define zstrerror(errnum) ""
++#endif
++
++#if defined(pyr)
++#  define NO_MEMCPY
++#endif
++#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
++ /* Use our own functions for small and medium model with MSC <= 5.0.
++  * You may have to use the same strategy for Borland C (untested).
++  * The __SC__ check is for Symantec.
++  */
++#  define NO_MEMCPY
++#endif
++#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
++#  define HAVE_MEMCPY
++#endif
++#ifdef HAVE_MEMCPY
++#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
++#    define zmemcpy _fmemcpy
++#    define zmemcmp _fmemcmp
++#    define zmemzero(dest, len) _fmemset(dest, 0, len)
++#  else
++#    define zmemcpy memcpy
++#    define zmemcmp memcmp
++#    define zmemzero(dest, len) memset(dest, 0, len)
++#  endif
++#else
++   extern void zmemcpy  OF((Bytef* dest, const Bytef* source, uInt len));
++   extern int  zmemcmp  OF((const Bytef* s1, const Bytef* s2, uInt len));
++   extern void zmemzero OF((Bytef* dest, uInt len));
++#endif
++
++/* Diagnostic functions */
++#ifdef DEBUG
++#  include <stdio.h>
++   extern int z_verbose;
++   extern void z_error    OF((char *m));
++#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
++#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
++#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
++#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
++#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
++#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
++#else
++#  define Assert(cond,msg)
++#  define Trace(x)
++#  define Tracev(x)
++#  define Tracevv(x)
++#  define Tracec(c,x)
++#  define Tracecv(c,x)
++#endif
++
++
++typedef uLong (ZEXPORT *check_func) OF((uLong check, const Bytef *buf,
++                                     uInt len));
++voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
++void   zcfree  OF((voidpf opaque, voidpf ptr));
++
++#define ZALLOC(strm, items, size) \
++           (*((strm)->zalloc))((strm)->opaque, (items), (size))
++#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
++#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
++
++#endif /* _Z_UTIL_H */