From: Tim Moore Date: Mon, 14 Sep 2009 11:34:43 +0000 (+0200) Subject: Merge FG_Lib as subdirectory X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=a43bfeb037938b06e08c1f2f663794d6e49aaf34;p=flightgear.git Merge FG_Lib as subdirectory --- a43bfeb037938b06e08c1f2f663794d6e49aaf34 diff --cc Lib/Audio/CHANGES index 000000000,000000000..c36010719 new file mode 100644 --- /dev/null +++ b/Lib/Audio/CHANGES @@@ -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 ++ diff --cc Lib/Audio/Makefile.am index 000000000,000000000..835577f82 new file mode 100644 --- /dev/null +++ b/Lib/Audio/Makefile.am @@@ -1,0 -1,0 +1,1 @@@ ++SUBDIRS = src example diff --cc Lib/Audio/NOTICE index 000000000,000000000..ba95093a2 new file mode 100644 --- /dev/null +++ b/Lib/Audio/NOTICE @@@ -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. ++ diff --cc Lib/Audio/README index 000000000,000000000..8bf6b4daa new file mode 100644 --- /dev/null +++ b/Lib/Audio/README @@@ -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 ++ diff --cc Lib/Audio/README.freebsd index 000000000,000000000..540c00e4f new file mode 100644 --- /dev/null +++ b/Lib/Audio/README.freebsd @@@ -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 ++ diff --cc Lib/Audio/README.linux index 000000000,000000000..7df00e8f2 new file mode 100644 --- /dev/null +++ b/Lib/Audio/README.linux @@@ -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 ++ diff --cc Lib/Audio/README.openbsd index 000000000,000000000..9ef788f36 new file mode 100644 --- /dev/null +++ b/Lib/Audio/README.openbsd @@@ -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 ++ diff --cc Lib/Audio/README.sgi index 000000000,000000000..c1c52e154 new file mode 100644 --- /dev/null +++ b/Lib/Audio/README.sgi @@@ -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 ++ ++ diff --cc Lib/Audio/README.unix index 000000000,000000000..771e856d5 new file mode 100644 --- /dev/null +++ b/Lib/Audio/README.unix @@@ -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 ++ diff --cc Lib/Audio/README.win index 000000000,000000000..a9d528227 new file mode 100644 --- /dev/null +++ b/Lib/Audio/README.win @@@ -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;...... diff --cc Lib/Bucket/Makefile.am index 000000000,000000000..87f83785a new file mode 100644 --- /dev/null +++ b/Lib/Bucket/Makefile.am @@@ -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) diff --cc Lib/Bucket/newbucket.cxx index 000000000,000000000..2fbb32ec5 new file mode 100644 --- /dev/null +++ b/Lib/Bucket/newbucket.cxx @@@ -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. ++// ++ diff --cc Lib/Bucket/newbucket.hxx index 000000000,000000000..3ef337d4a new file mode 100644 --- /dev/null +++ b/Lib/Bucket/newbucket.hxx @@@ -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 STL_STRING ++ ++#ifdef FG_HAVE_STD_INCLUDES ++# include // sprintf() ++# include ++#else ++# include // sprintf() ++# include ++#endif ++ ++FG_USING_STD(string); ++FG_USING_STD(ostream); ++ ++#include ++ ++ ++#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. ++// diff --cc Lib/Bucket/testbucket.cxx index 000000000,000000000..0ffbf5d1a new file mode 100644 --- /dev/null +++ b/Lib/Bucket/testbucket.cxx @@@ -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; ++ } ++} diff --cc Lib/CVSROOT/checkoutlist index 000000000,000000000..b04b3501f new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/checkoutlist @@@ -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: ++# ++# [] ++# ++# comment lines begin with '#' diff --cc Lib/CVSROOT/commitinfo index 000000000,000000000..b19e7b7a6 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/commitinfo @@@ -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". diff --cc Lib/CVSROOT/cvswrappers index 000000000,000000000..5047bf1c5 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/cvswrappers @@@ -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: diff --cc Lib/CVSROOT/editinfo index 000000000,000000000..d78886c15 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/editinfo @@@ -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. diff --cc Lib/CVSROOT/loginfo index 000000000,000000000..226e93771 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/loginfo @@@ -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 diff --cc Lib/CVSROOT/modules index 000000000,000000000..cb9e9efc9 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/modules @@@ -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. diff --cc Lib/CVSROOT/notify index 000000000,000000000..34f0bc288 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/notify @@@ -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" diff --cc Lib/CVSROOT/rcsinfo index 000000000,000000000..49e59f4d0 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/rcsinfo @@@ -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". diff --cc Lib/CVSROOT/taginfo index 000000000,000000000..274a46dd5 new file mode 100644 --- /dev/null +++ b/Lib/CVSROOT/taginfo @@@ -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". diff --cc Lib/Debug/Makefile.am index 000000000,000000000..f45c0bde7 new file mode 100644 --- /dev/null +++ b/Lib/Debug/Makefile.am @@@ -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) diff --cc Lib/Debug/debug_types.h index 000000000,000000000..8be6350c1 new file mode 100644 --- /dev/null +++ b/Lib/Debug/debug_types.h @@@ -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; ++ diff --cc Lib/Debug/fg_debug.c index 000000000,000000000..ca236a337 new file mode 100644 --- /dev/null +++ b/Lib/Debug/fg_debug.c @@@ -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 ++#include ++#include ++#include ++ ++#include // 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. ++ * ++ */ diff --cc Lib/Debug/fg_debug.h index 000000000,000000000..22adb912a new file mode 100644 --- /dev/null +++ b/Lib/Debug/fg_debug.h @@@ -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 ++ ++/* 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 */ ++ diff --cc Lib/Debug/logstream.cxx index 000000000,000000000..182cafda1 new file mode 100644 --- /dev/null +++ b/Lib/Debug/logstream.cxx @@@ -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. ++// diff --cc Lib/Debug/logstream.hxx index 000000000,000000000..f79f1b88a new file mode 100644 --- /dev/null +++ b/Lib/Debug/logstream.hxx @@@ -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 ++#endif ++ ++ ++#include ++ ++#ifdef FG_HAVE_STD_INCLUDES ++# include ++# include ++#else ++# include ++# 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 traits_type; ++ typedef char_traits::int_type int_type; ++ typedef char_traits::pos_type pos_type; ++ typedef char_traits::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. ++// diff --cc Lib/Debug/logtest.cxx index 000000000,000000000..b02c6b086 new file mode 100644 --- /dev/null +++ b/Lib/Debug/logtest.cxx @@@ -1,0 -1,0 +1,34 @@@ ++#include ++#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; ++} diff --cc Lib/Lib/Makefile.am index 000000000,000000000..a0bdf9327 new file mode 100644 --- /dev/null +++ b/Lib/Lib/Makefile.am @@@ -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 diff --cc Lib/Math/MAT3geom.c index 000000000,000000000..93e754b12 new file mode 100644 --- /dev/null +++ b/Lib/Math/MAT3geom.c @@@ -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 ++ ++/* -------------------------- 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; ++} ++ diff --cc Lib/Math/MAT3inv.c index 000000000,000000000..874b2f3b0 new file mode 100644 --- /dev/null +++ b/Lib/Math/MAT3inv.c @@@ -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 ++ ++/* -------------------------- 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); ++} diff --cc Lib/Math/MAT3mat.c index 000000000,000000000..4355f1769 new file mode 100644 --- /dev/null +++ b/Lib/Math/MAT3mat.c @@@ -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 ++#endif ++ ++#ifdef WIN32 ++# ifndef HAVE_STL_SGI_PORT ++# include /* required for memset() and memcpy() */ ++# endif ++#endif ++ ++#include ++#include ++ ++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); ++ } ++} diff --cc Lib/Math/MAT3vec.c index 000000000,000000000..d760add5f new file mode 100644 --- /dev/null +++ b/Lib/Math/MAT3vec.c @@@ -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 ++ ++#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); ++} diff --cc Lib/Math/Makefile.am index 000000000,000000000..eda2bc005 new file mode 100644 --- /dev/null +++ b/Lib/Math/Makefile.am @@@ -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 diff --cc Lib/Math/fg_geodesy.cxx index 000000000,000000000..af10c1013 new file mode 100644 --- /dev/null +++ b/Lib/Math/fg_geodesy.cxx @@@ -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 ++# include ++#else ++# include ++# include ++#endif ++ ++#include ++#include ++#include ++ ++#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 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 ++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 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 ++// 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. ++// ++ diff --cc Lib/Math/fg_geodesy.hxx index 000000000,000000000..f863d39d8 new file mode 100644 --- /dev/null +++ b/Lib/Math/fg_geodesy.hxx @@@ -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 ++#include ++ ++ ++// 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. ++// ++ diff --cc Lib/Math/fg_random.c index 000000000,000000000..31b24be7d new file mode 100644 --- /dev/null +++ b/Lib/Math/fg_random.c @@@ -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 ++#endif ++ ++#include ++#include // for random(), srandom() ++#include // 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 " 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 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. ++// diff --cc Lib/Math/fg_random.h index 000000000,000000000..3ae53a053 new file mode 100644 --- /dev/null +++ b/Lib/Math/fg_random.h @@@ -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. ++// diff --cc Lib/Math/interpolater.cxx index 000000000,000000000..9aabeda2f new file mode 100644 --- /dev/null +++ b/Lib/Math/interpolater.cxx @@@ -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 STL_STRING ++ ++#include ++#include ++#include ++ ++#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 ++// diff --cc Lib/Math/interpolater.hxx index 000000000,000000000..4260ba485 new file mode 100644 --- /dev/null +++ b/Lib/Math/interpolater.hxx @@@ -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 ++// diff --cc Lib/Math/leastsqs.cxx index 000000000,000000000..28e2bd35a new file mode 100644 --- /dev/null +++ b/Lib/Math/leastsqs.cxx @@@ -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 ++ ++#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. ++// diff --cc Lib/Math/leastsqs.hxx index 000000000,000000000..d8b40c80e new file mode 100644 --- /dev/null +++ b/Lib/Math/leastsqs.hxx @@@ -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 000000000,000000000..e11896ce1 new file mode 100644 --- /dev/null +++ b/Lib/Math/mat3.h @@@ -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 ++#endif ++#include ++ ++#include ++#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 */ ++ diff --cc Lib/Math/mat3defs.h index 000000000,000000000..dd4ceeb5e new file mode 100644 --- /dev/null +++ b/Lib/Math/mat3defs.h @@@ -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 ++/* #include */ ++#include ++ ++/* ----------------------------- 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 */ diff --cc Lib/Math/mat3err.h index 000000000,000000000..7ac5740ad new file mode 100644 --- /dev/null +++ b/Lib/Math/mat3err.h @@@ -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 */ diff --cc Lib/Math/point3d.hxx index 000000000,000000000..975270779 new file mode 100644 --- /dev/null +++ b/Lib/Math/point3d.hxx @@@ -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 ++# include ++# include ++#else ++# include ++# include ++# include ++#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" ++// ++// 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. ++// ++// diff --cc Lib/Math/polar3d.cxx index 000000000,000000000..7958a83c2 new file mode 100644 --- /dev/null +++ b/Lib/Math/polar3d.cxx @@@ -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 ++#include ++ ++#include ++ ++#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 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 ++// 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. ++ diff --cc Lib/Math/polar3d.hxx index 000000000,000000000..4118f2d2c new file mode 100644 --- /dev/null +++ b/Lib/Math/polar3d.hxx @@@ -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 ++ ++ ++// 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 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 ++// 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. ++// ++ diff --cc Lib/Math/vector.cxx index 000000000,000000000..22509cd60 new file mode 100644 --- /dev/null +++ b/Lib/Math/vector.cxx @@@ -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 ++#include ++ ++// #include ++ ++#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 vec) / (normal 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 ++// This should simplify things tremendously. ++// ++// Revision 1.1 1997/12/22 04:13:17 curt ++// Initial revision. ++// diff --cc Lib/Math/vector.hxx index 000000000,000000000..92e897c35 new file mode 100644 --- /dev/null +++ b/Lib/Math/vector.hxx @@@ -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 ++// This should simplify things tremendously. ++// ++// Revision 1.1 1997/12/22 04:13:18 curt ++// Initial revision. ++// ++ diff --cc Lib/Misc/CREDITS index 000000000,000000000..b2528cdc2 new file mode 100644 --- /dev/null +++ b/Lib/Misc/CREDITS @@@ -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) diff --cc Lib/Misc/Makefile.am index 000000000,000000000..e35acf4f2 new file mode 100644 --- /dev/null +++ b/Lib/Misc/Makefile.am @@@ -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 diff --cc Lib/Misc/fgstream.cxx index 000000000,000000000..b695315cb new file mode 100644 --- /dev/null +++ b/Lib/Misc/fgstream.cxx @@@ -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 // isspace() ++#include ++ ++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. ++// diff --cc Lib/Misc/fgstream.hxx index 000000000,000000000..e8b7c0bb3 new file mode 100644 --- /dev/null +++ b/Lib/Misc/fgstream.hxx @@@ -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 ++ ++#if defined( FG_HAVE_STD_INCLUDES ) ++# include ++#elif defined ( FG_HAVE_NATIVE_SGI_COMPILERS ) ++# include ++#else ++# include ++#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. ++// diff --cc Lib/Misc/stopwatch.hxx index 000000000,000000000..d3bcfade4 new file mode 100644 --- /dev/null +++ b/Lib/Misc/stopwatch.hxx @@@ -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 ++ * ++ * 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 ++# endif ++# include ++# include ++# include ++#elif defined( WIN32 ) ++# include ++#else ++# include ++#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 ++ diff --cc Lib/Misc/strutils.cxx index 000000000,000000000..2f23d83f4 new file mode 100644 --- /dev/null +++ b/Lib/Misc/strutils.cxx @@@ -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. ++// diff --cc Lib/Misc/strutils.hxx index 000000000,000000000..b2c47a775 new file mode 100644 --- /dev/null +++ b/Lib/Misc/strutils.hxx @@@ -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 STL_STRING ++ ++#ifdef FG_HAVE_STD_INCLUDES ++# include ++#else ++# include ++#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. ++// diff --cc Lib/Misc/zfstream.cxx index 000000000,000000000..38387cb89 new file mode 100644 --- /dev/null +++ b/Lib/Misc/zfstream.cxx @@@ -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 ++// ++// 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 ++#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. ++// diff --cc Lib/Misc/zfstream.hxx index 000000000,000000000..714393456 new file mode 100644 --- /dev/null +++ b/Lib/Misc/zfstream.hxx @@@ -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 ++// ++// 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 ++# include ++ ++# 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 ++# include ++# else ++# include ++# 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 traits_type; ++ typedef char_traits::int_type int_type; ++ typedef char_traits::pos_type pos_type; ++ typedef char_traits::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. ++// ++ diff --cc Lib/PUI/Makefile.am index 000000000,000000000..aa38a0cdb new file mode 100644 --- /dev/null +++ b/Lib/PUI/Makefile.am @@@ -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) ++ diff --cc Lib/PUI/complex.cxx index 000000000,000000000..6c5d93a73 new file mode 100644 --- /dev/null +++ b/Lib/PUI/complex.cxx @@@ -1,0 -1,0 +1,332 @@@ ++#include ++#include ++#include ++#include ++#ifdef WIN32 ++#include ++#else ++#include ++#endif ++#include ++#include ++#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 000000000,000000000..5e47cf054 new file mode 100644 --- /dev/null +++ b/Lib/PUI/pu.cxx @@@ -1,0 -1,0 +1,332 @@@ ++ ++#include "puLocal.h" ++ ++#ifdef PU_NOT_USING_GLUT ++#include ++#include ++#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< checkHit ( button, PU_DRAG, x, ++ h - y ) ; ++} ++ diff --cc Lib/PUI/pu.h index 000000000,000000000..02f99adab new file mode 100644 --- /dev/null +++ b/Lib/PUI/pu.h @@@ -1,0 -1,0 +1,805 @@@ ++#ifndef _PU_H_ ++#define _PU_H_ ++ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#ifdef HAVE_WINDOWS_H ++# include ++#endif ++ ++#include ++#include ++#include ++ ++#ifdef PU_NOT_USING_GLUT ++#include ++#include ++#include ++#else ++#include ++#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 ++ diff --cc Lib/PUI/puBox.cxx index 000000000,000000000..d0d926285 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puBox.cxx @@@ -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]max[0] ) max[0] = bx->max[0] ; ++ if ( max[1]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 ) ; ++ } ++} ++ ++ ++ diff --cc Lib/PUI/puButton.cxx index 000000000,000000000..66ded922b new file mode 100644 --- /dev/null +++ b/Lib/PUI/puButton.cxx @@@ -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 () ; ++} ++ ++ diff --cc Lib/PUI/puButtonBox.cxx index 000000000,000000000..f569ed787 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puButtonBox.cxx @@@ -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< 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 ; ++} ++ ++ diff --cc Lib/PUI/puInterface.cxx index 000000000,000000000..500f82971 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puInterface.cxx @@@ -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 ; ++ } ++} ++ ++ ++ diff --cc Lib/PUI/puLocal.h index 000000000,000000000..a366d2873 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puLocal.h @@@ -1,0 -1,0 +1,19 @@@ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#include ++#include ++#include ++#ifdef WIN32 ++#include ++#else ++#include ++#endif ++#include ++ ++#ifndef PU_NOT_USING_GLUT ++#include ++#endif ++#include "pu.h" ++ diff --cc Lib/PUI/puMenuBar.cxx index 000000000,000000000..87a2299b4 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puMenuBar.cxx @@@ -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 () ; ++} ++ ++ diff --cc Lib/PUI/puObject.cxx index 000000000,000000000..00fc5a26c new file mode 100644 --- /dev/null +++ b/Lib/PUI/puObject.cxx @@@ -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." ; ++} ++ ++ diff --cc Lib/PUI/puOneShot.cxx index 000000000,000000000..7d0f7c9ba new file mode 100644 --- /dev/null +++ b/Lib/PUI/puOneShot.cxx @@@ -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 ) ; ++} ++ diff --cc Lib/PUI/puPopup.cxx index 000000000,000000000..59a5fef5c new file mode 100644 --- /dev/null +++ b/Lib/PUI/puPopup.cxx @@@ -1,0 -1,0 +1,3 @@@ ++ ++#include "puLocal.h" ++ diff --cc Lib/PUI/puPopupMenu.cxx index 000000000,000000000..0eed10231 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puPopupMenu.cxx @@@ -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 ; ++} ++ ++ diff --cc Lib/PUI/puSlider.cxx index 000000000,000000000..aeab8f170 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puSlider.cxx @@@ -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 ; ++ } ++ } ++} ++ ++ diff --cc Lib/PUI/puText.cxx index 000000000,000000000..032c01629 new file mode 100644 --- /dev/null +++ b/Lib/PUI/puText.cxx @@@ -1,0 -1,0 +1,8 @@@ ++ ++#include "puLocal.h" ++ ++void puText::draw ( int dx, int dy ) ++{ ++ draw_label ( dx, dy ) ; ++} ++ diff --cc Lib/Serial/Makefile.am index 000000000,000000000..66a9f1662 new file mode 100644 --- /dev/null +++ b/Lib/Serial/Makefile.am @@@ -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 diff --cc Lib/Serial/serial.cxx index 000000000,000000000..ed580f8af new file mode 100644 --- /dev/null +++ b/Lib/Serial/serial.cxx @@@ -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 ++#endif ++ ++#include "Include/compiler.h" ++#ifdef FG_HAVE_STD_INCLUDE ++# include ++#else ++# include ++#endif ++ ++#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) ++ // maybe include something??? ++#else ++# include ++# include ++# include ++# include ++# include ++#endif ++ ++#include ++ ++#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 instead of ++// 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 ++// Simulator/Main/fg_init.cxx: ++// Simulator/Main/GLUTmain.cxx: ++// Simulator/Main/options.hxx: Shuffled 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. ++// diff --cc Lib/Serial/serial.hxx index 000000000,000000000..3b2c60b68 new file mode 100644 --- /dev/null +++ b/Lib/Serial/serial.hxx @@@ -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 ++#endif ++ ++#if defined( WIN32 ) && !defined( __CYGWIN__) && !defined( __CYGWIN32__ ) ++# include ++#endif ++ ++#include ++#include STL_STRING ++FG_USING_STD(string); ++ ++// if someone know how to do this all with C++ streams let me know ++// #include ++ ++ ++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 instead of ++// 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 ++// Simulator/Main/fg_init.cxx: ++// Simulator/Main/GLUTmain.cxx: ++// Simulator/Main/options.hxx: Shuffled 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. ++// diff --cc Lib/Serial/testserial.cxx index 000000000,000000000..c582c13c3 new file mode 100644 --- /dev/null +++ b/Lib/Serial/testserial.cxx @@@ -1,0 -1,0 +1,30 @@@ ++#include ++ ++#include ++ ++#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; ++ } ++ } ++} diff --cc Lib/XGL/Makefile.am index 000000000,000000000..38aa0db88 new file mode 100644 --- /dev/null +++ b/Lib/XGL/Makefile.am @@@ -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 000000000,000000000..653805240 new file mode 100644 --- /dev/null +++ b/Lib/XGL/xgl.c @@@ -1,0 -1,0 +1,3034 @@@ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#ifdef HAVE_WINDOWS_H ++# include ++#endif ++ ++#include "xgl.h" ++#include ++ ++#include ++#include ++ ++#ifdef HAVE_UNISTD_H ++# include ++#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 000000000,000000000..434ab09d6 new file mode 100644 --- /dev/null +++ b/Lib/XGL/xgl.h @@@ -1,0 -1,0 +1,837 @@@ ++#ifndef _XGL_H ++#define _XGL_H ++ ++ ++#ifdef HAVE_WINDOWS_H ++# include ++#endif ++ ++#include ++#include ++#include ++ ++ ++#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 */ diff --cc Lib/XGL/xglUtils.c index 000000000,000000000..56da16522 new file mode 100644 --- /dev/null +++ b/Lib/XGL/xglUtils.c @@@ -1,0 -1,0 +1,687 @@@ ++ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++ ++#include ++#include ++#include ++ ++#if !defined( __CYGWIN__ ) && !defined( __CYGWIN32__ ) ++# if !defined( HAVE_STL_SGI_PORT ) && !defined( __MWERKS__ ) ++// Avoid malloc with STLport and MSL ++# include ++# endif ++#endif ++ ++#ifdef HAVE_UNISTD_H ++# include ++#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 ; ++} ++ diff --cc Lib/example/Makefile.am index 000000000,000000000..8528348b9 new file mode 100644 --- /dev/null +++ b/Lib/example/Makefile.am @@@ -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 diff --cc Lib/example/example.cxx index 000000000,000000000..ae519786d new file mode 100644 --- /dev/null +++ b/Lib/example/example.cxx @@@ -1,0 -1,0 +1,89 @@@ ++ ++ ++#include "sl.h" ++#include "sm.h" ++#include ++ ++/* ++ 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 () ; ++ } ++} ++ diff --cc Lib/src/Makefile.am index 000000000,000000000..e9f453178 new file mode 100644 --- /dev/null +++ b/Lib/src/Makefile.am @@@ -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 000000000,000000000..5cbbc2adf new file mode 100644 --- /dev/null +++ b/Lib/src/sl.h @@@ -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 ++ diff --cc Lib/src/slDSP.cxx index 000000000,000000000..a8a96d4da new file mode 100644 --- /dev/null +++ b/Lib/src/slDSP.cxx @@@ -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 ++ diff --cc Lib/src/slEnvelope.cxx index 000000000,000000000..13e726c4c new file mode 100644 --- /dev/null +++ b/Lib/src/slEnvelope.cxx @@@ -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 ; ++ } ++} ++ ++ diff --cc Lib/src/slPortability.h index 000000000,000000000..08d780c14 new file mode 100644 --- /dev/null +++ b/Lib/src/slPortability.h @@@ -1,0 -1,0 +1,71 @@@ ++ ++#ifndef __SLPORTABILITY_H__ ++#define __SLPORTABILITY_H__ 1 ++ ++/* ------------------------------------------------------------- */ ++/* OS specific includes and defines ... */ ++/* ------------------------------------------------------------- */ ++ ++#ifdef HAVE_CONFIG_H ++# include ++#endif ++#undef VERSION ++ ++#include ++#include ++ ++#ifndef WIN32 ++#include ++#include ++#else ++#include ++#if defined( __CYGWIN__ ) || defined( __CYGWIN32__ ) ++# define NEAR /* */ ++# define FAR /* */ ++#endif ++#include ++#endif ++ ++#include ++#include ++#include ++#include ++ ++#if defined(__linux__) || defined(__FreeBSD__) ++#define SL_USING_OSS_AUDIO 1 ++#endif ++ ++#ifdef SL_USING_OSS_AUDIO ++#if defined(__linux__) ++#include ++#elif defined(__FreeBSD__) ++#include ++#else ++/* ++ Tom thinks this file may be 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 ++*/ ++#include ++#endif ++#endif ++ ++#ifdef __OpenBSD__ ++#include ++#endif ++ ++#ifdef WIN32 ++#define strcasecmp stricmp /* Yes, Steve really does *HATE* Windoze */ ++#endif ++ ++/* Tom */ ++ ++#ifdef sgi ++#include ++#endif ++ ++#endif ++ diff --cc Lib/src/slSample.cxx index 000000000,000000000..386a3ce29 new file mode 100644 --- /dev/null +++ b/Lib/src/slSample.cxx @@@ -1,0 -1,0 +1,505 @@@ ++ ++ ++#include "sl.h" ++#include ++ ++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 ; ++} ++ ++ diff --cc Lib/src/slSamplePlayer.cxx index 000000000,000000000..12eecaf65 new file mode 100644 --- /dev/null +++ b/Lib/src/slSamplePlayer.cxx @@@ -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 () ; ++ } ++ } ++} ++ ++ ++ diff --cc Lib/src/slScheduler.cxx index 000000000,000000000..5fe4caa91 new file mode 100644 --- /dev/null +++ b/Lib/src/slScheduler.cxx @@@ -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 000000000,000000000..f884cd037 new file mode 100644 --- /dev/null +++ b/Lib/src/sm.h @@@ -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 ++ diff --cc Lib/src/smMixer.cxx index 000000000,000000000..f7be007d7 new file mode 100644 --- /dev/null +++ b/Lib/src/smMixer.cxx @@@ -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 diff --cc Lib/zlib/ChangeLog index 000000000,000000000..57386a26f new file mode 100644 --- /dev/null +++ b/Lib/zlib/ChangeLog @@@ -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 ++ 386 asm code replacing longest_match(). ++ contrib/iostream/ by Kevin Ruland ++ A C++ I/O streams interface to the zlib gz* functions ++ contrib/iostream2/ by Tyge Løvset ++ Another C++ I/O streams interface ++ contrib/untgz/ by "Pedro A. Aranda Guti\irrez" ++ A very simple tar.gz file extractor using zlib ++ contrib/visual-basic.txt by Carlos Rios ++ 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 000000000,000000000..8a2457664 new file mode 100644 --- /dev/null +++ b/Lib/zlib/INDEX @@@ -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 ++ 386 asm code replacing longest_match(). ++ ++contrib/minizip/ by Gilles Vollant ++ Mini zip and unzip based on zlib ++ See http://www.winimage.com/zLibDll/unzip.html ++ ++contrib/iostream/ by Kevin Ruland ++ A C++ I/O streams interface to the zlib gz* functions ++ ++contrib/iostream2/ by Tyge Løvset ++ Another C++ I/O streams interface ++ ++contrib/untgz/ by "Pedro A. Aranda Guti\irrez" ++ A very simple tar.gz extractor using zlib ++ ++contrib/visual-basic.txt by Carlos Rios ++ How to use compress(), uncompress() and the gz* functions from VB. diff --cc Lib/zlib/Makefile.am index 000000000,000000000..0c93862fc new file mode 100644 --- /dev/null +++ b/Lib/zlib/Makefile.am @@@ -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 000000000,000000000..8ff458799 new file mode 100644 --- /dev/null +++ b/Lib/zlib/README @@@ -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 , or to ++Gilles Vollant 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 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 ++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 ++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 ++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 , 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 . 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 ++ ++ ++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. diff --cc Lib/zlib/adler32.c index 000000000,000000000..16cf9a703 new file mode 100644 --- /dev/null +++ b/Lib/zlib/adler32.c @@@ -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; ++} diff --cc Lib/zlib/algorithm.txt index 000000000,000000000..cdc830b5d new file mode 100644 --- /dev/null +++ b/Lib/zlib/algorithm.txt @@@ -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 diff --cc Lib/zlib/compress.c index 000000000,000000000..1cee47091 new file mode 100644 --- /dev/null +++ b/Lib/zlib/compress.c @@@ -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); ++} diff --cc Lib/zlib/crc32.c index 000000000,000000000..a91101a81 new file mode 100644 --- /dev/null +++ b/Lib/zlib/crc32.c @@@ -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; ++} diff --cc Lib/zlib/deflate.c index 000000000,000000000..25d5818e2 new file mode 100644 --- /dev/null +++ b/Lib/zlib/deflate.c @@@ -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)<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; ++} diff --cc Lib/zlib/deflate.h index 000000000,000000000..962676da8 new file mode 100644 --- /dev/null +++ b/Lib/zlib/deflate.h @@@ -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 diff --cc Lib/zlib/descrip.mms index 000000000,000000000..9d364598a new file mode 100644 --- /dev/null +++ b/Lib/zlib/descrip.mms @@@ -1,0 -1,0 +1,48 @@@ ++# descrip.mms: MMS description file for building zlib on VMS ++# written by Martin P.J. Zinser ++ ++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 diff --cc Lib/zlib/example.c index 000000000,000000000..8307c841e new file mode 100644 --- /dev/null +++ b/Lib/zlib/example.c @@@ -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 ++#include "zlib.h" ++ ++#ifdef STDC ++# include ++# include ++#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 000000000,000000000..f7c336a55 new file mode 100644 --- /dev/null +++ b/Lib/zlib/gzio.c @@@ -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 ++ ++#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); /* 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 ++ ++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; ++} diff --cc Lib/zlib/infblock.c index 000000000,000000000..f4920faa5 new file mode 100644 --- /dev/null +++ b/Lib/zlib/infblock.c @@@ -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; ++} diff --cc Lib/zlib/infblock.h index 000000000,000000000..bd25c8075 new file mode 100644 --- /dev/null +++ b/Lib/zlib/infblock.h @@@ -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)); diff --cc Lib/zlib/infcodes.c index 000000000,000000000..d4e5ee9a5 new file mode 100644 --- /dev/null +++ b/Lib/zlib/infcodes.c @@@ -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")); ++} diff --cc Lib/zlib/infcodes.h index 000000000,000000000..6c750d896 new file mode 100644 --- /dev/null +++ b/Lib/zlib/infcodes.h @@@ -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 )); ++ diff --cc Lib/zlib/inffast.c index 000000000,000000000..61a78ee93 new file mode 100644 --- /dev/null +++ b/Lib/zlib/inffast.c @@@ -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)<avail_in-n;c=(k>>3)>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; ++} diff --cc Lib/zlib/inffast.h index 000000000,000000000..8facec553 new file mode 100644 --- /dev/null +++ b/Lib/zlib/inffast.h @@@ -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 )); diff --cc Lib/zlib/inffixed.h index 000000000,000000000..77f7e7631 new file mode 100644 --- /dev/null +++ b/Lib/zlib/inffixed.h @@@ -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} ++ }; diff --cc Lib/zlib/inflate.c index 000000000,000000000..32e9b8de6 new file mode 100644 --- /dev/null +++ b/Lib/zlib/inflate.c @@@ -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<state->wbits)) ++ { ++ length = (1<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); ++} diff --cc Lib/zlib/inftrees.c index 000000000,000000000..ef1e0b6b8 new file mode 100644 --- /dev/null +++ b/Lib/zlib/inftrees.c @@@ -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; ++} diff --cc Lib/zlib/inftrees.h index 000000000,000000000..85853e097 new file mode 100644 --- /dev/null +++ b/Lib/zlib/inftrees.h @@@ -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 */ diff --cc Lib/zlib/infutil.c index 000000000,000000000..824dab571 new file mode 100644 --- /dev/null +++ b/Lib/zlib/infutil.c @@@ -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; ++} diff --cc Lib/zlib/infutil.h index 000000000,000000000..99d1135d0 new file mode 100644 --- /dev/null +++ b/Lib/zlib/infutil.h @@@ -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)<>=(j);k-=(j);} ++/* output bytes */ ++#define WAVAIL (uInt)(qread?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 diff --cc Lib/zlib/maketree.c index 000000000,000000000..949d78641 new file mode 100644 --- /dev/null +++ b/Lib/zlib/maketree.c @@@ -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 ++#include ++#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< ++#include "zlib.h" ++ ++#ifdef STDC ++# include ++# include ++#else ++ extern void exit OF((int)); ++#endif ++ ++#ifdef USE_MMAP ++# include ++# include ++# include ++#endif ++ ++#if defined(MSDOS) || defined(OS2) || defined(WIN32) ++# include ++# include ++# 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 /* 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 */ ++ ++/* 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 */ ++} diff --cc Lib/zlib/trees.c index 000000000,000000000..f01fb30d8 new file mode 100644 --- /dev/null +++ b/Lib/zlib/trees.c @@@ -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 ++#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< dist code (0..29) */ ++ dist = 0; ++ for (code = 0 ; code < 16; code++) { ++ base_dist[code] = dist; ++ for (n = 0; n < (1<>= 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 ++# 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<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++); ++ } ++} diff --cc Lib/zlib/trees.h index 000000000,000000000..72facf900 new file mode 100644 --- /dev/null +++ b/Lib/zlib/trees.h @@@ -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 ++}; ++ diff --cc Lib/zlib/uncompr.c index 000000000,000000000..d10332137 new file mode 100644 --- /dev/null +++ b/Lib/zlib/uncompr.c @@@ -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; ++} diff --cc Lib/zlib/zconf.h index 000000000,000000000..6d450fc79 new file mode 100644 --- /dev/null +++ b/Lib/zlib/zconf.h @@@ -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 ++# 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 ++# 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 /* for off_t */ ++# include /* 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 000000000,000000000..25c8495d2 new file mode 100644 --- /dev/null +++ b/Lib/zlib/zlib.3 @@@ -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 ++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 000000000,000000000..49f56b43b new file mode 100644 --- /dev/null +++ b/Lib/zlib/zlib.h @@@ -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 */ diff --cc Lib/zlib/zutil.c index 000000000,000000000..b3de4e883 new file mode 100644 --- /dev/null +++ b/Lib/zlib/zutil.c @@@ -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 */ diff --cc Lib/zlib/zutil.h index 000000000,000000000..6f2cb97ca new file mode 100644 --- /dev/null +++ b/Lib/zlib/zutil.h @@@ -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 ++# include ++# include ++#endif ++#ifdef NO_ERRNO_H ++ extern int errno; ++#else ++# include ++#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 ++# endif ++# else /* MSC or DJGPP */ ++# include ++# 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 /* 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 ++ 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 */