Initial revision

This commit is contained in:
curt
1999-04-05 21:32:32 +00:00
parent a0e40c1fc1
commit 1eb87e7c73
136 changed files with 142 additions and 16521 deletions

View File

@@ -1,139 +0,0 @@
/**********************************************\
* *
* 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

View File

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

View File

@@ -1,9 +0,0 @@
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.

View File

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

View File

@@ -1,13 +0,0 @@
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

View File

@@ -1,13 +0,0 @@
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

View File

@@ -1,13 +0,0 @@
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

View File

@@ -1,27 +0,0 @@
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

View File

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

View File

@@ -1,15 +0,0 @@
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;......

View File

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

View File

@@ -1,15 +0,0 @@
# 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".

View File

@@ -1,22 +0,0 @@
# 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:

View File

@@ -1,21 +0,0 @@
# 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.

View File

@@ -1,19 +0,0 @@
# 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

View File

@@ -1,26 +0,0 @@
# 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.

View File

@@ -1,12 +0,0 @@
# 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"

View File

@@ -1,13 +0,0 @@
# 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".

View File

@@ -1,20 +0,0 @@
# 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".

View File

@@ -146,6 +146,9 @@ void fgBucketDiff( const FGBucket& b1, const FGBucket& b2, int *dx, int *dy ) {
// $Log$
// Revision 1.1 1999/04/05 21:32:34 curt
// Initial revision
//
// Revision 1.4 1999/03/27 05:34:05 curt
// Elimitated some const warnings from the compiler.
//

View File

@@ -330,6 +330,9 @@ operator== ( const FGBucket& b1, const FGBucket& b2 )
// $Log$
// Revision 1.1 1999/04/05 21:32:34 curt
// Initial revision
//
// Revision 1.8 1999/03/27 05:34:06 curt
// Elimitated some const warnings from the compiler.
//

View File

@@ -282,9 +282,12 @@ int fgPrintf( fgDebugClass dbg_class, fgDebugPriority prio, char *fmt, ... ) {
/* $Log$
/* Revision 1.4 1998/06/01 17:49:44 curt
/* Rewrote a slightly ambiguous code fragment (contributed by Charlie Hotchkiss)
/* Revision 1.1 1999/04/05 21:32:33 curt
/* Initial revision
/*
* 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.
*

View File

@@ -63,6 +63,9 @@ logstream::setLogLevels( fgDebugClass c, fgDebugPriority p )
}
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.2 1999/01/19 20:53:34 curt
// Portability updates by Bernie Bright.
//

View File

@@ -212,6 +212,9 @@ fglog()
#endif // _LOGSTREAM_H
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.4 1999/03/02 01:01:47 curt
// Tweaks for compiling with native SGI compilers.
//

View File

@@ -164,6 +164,9 @@ void fgGeodToGeoc( double lat_geod, double alt, double *sl_radius,
$Header$
$Log$
Revision 1.1 1999/04/05 21:32:33 curt
Initial revision
Revision 1.6 1999/03/02 01:01:49 curt
Tweaks for compiling with native SGI compilers.
@@ -256,6 +259,9 @@ Initial Flight Gear revision.
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.6 1999/03/02 01:01:49 curt
// Tweaks for compiling with native SGI compilers.
//

View File

@@ -114,6 +114,9 @@ inline Point3D fgGeodToCart(const Point3D& geod) {
$Header$
$Log$
Revision 1.1 1999/04/05 21:32:33 curt
Initial revision
Revision 1.4 1999/01/27 04:46:15 curt
Portability tweaks by Bernie Bright.
@@ -193,6 +196,9 @@ Initial Flight Gear revision.
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.4 1999/01/27 04:46:15 curt
// Portability tweaks by Bernie Bright.
//

View File

@@ -71,6 +71,9 @@ double fg_random(void) {
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// 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

View File

@@ -48,6 +48,9 @@ double fg_random(void);
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// 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

30
Lib/Math/geotest.c Normal file
View File

@@ -0,0 +1,30 @@
#include <Include/fg_constants.h>
#include <Math/fg_geodesy.h>
#include <stdio.h>
void
main( void )
{
double Lon, Alt, sl_radius;
double geodetic_Lat;
double geocentric_Lat;
Lon = -87.75 * DEG_TO_RAD;
geodetic_Lat = 41.83 * DEG_TO_RAD;
Alt = 1.5; /* km */
printf("Geodetic position = (%.8f, %.8f, %.8f)\n", Lon, geodetic_Lat, Alt);
fgGeodToGeoc( geodetic_Lat, Alt, &sl_radius, &geocentric_Lat );
printf("Geocentric position = (%.8f, %.8f, %.8f)\n", Lon, geocentric_Lat,
sl_radius + Alt);
printf("new sl_radius = %.8f\n", sl_radius);
fgGeocToGeod( geocentric_Lat, sl_radius + Alt, &geodetic_Lat,
&Alt, &sl_radius );
printf("Geodetic position = (%.8f, %.8f, %.8f)\n", Lon, geodetic_Lat, Alt);
printf("new sl_radius = %.8f\n", sl_radius);
}

View File

@@ -103,6 +103,9 @@ fgINTERPTABLE::~fgINTERPTABLE( void ) {
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.7 1999/02/26 22:08:03 curt
// Added initial support for native SGI compilers.
//

View File

@@ -62,6 +62,9 @@ public:
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.6 1999/03/02 01:01:50 curt
// Tweaks for compiling with native SGI compilers.
//

23
Lib/Math/inttest.cxx Normal file
View File

@@ -0,0 +1,23 @@
#include <stdio.h>
#include <Debug/fg_debug.h>
#include "interpolater.hxx"
main() {
fgINTERPTABLE test("test.table");
fgInitDebug();
printf("-1.0 = %.2f\n", test.interpolate(-1.0));
printf("0.0 = %.2f\n", test.interpolate(0.0));
printf("2.9 = %.2f\n", test.interpolate(2.9));
printf("3.0 = %.2f\n", test.interpolate(3.0));
printf("3.5 = %.2f\n", test.interpolate(3.5));
printf("4.0 = %.2f\n", test.interpolate(4.0));
printf("4.5 = %.2f\n", test.interpolate(4.5));
printf("5.2 = %.2f\n", test.interpolate(5.2));
printf("8.0 = %.2f\n", test.interpolate(8.0));
printf("8.5 = %.2f\n", test.interpolate(8.5));
printf("9.0 = %.2f\n", test.interpolate(9.0));
printf("10.0 = %.2f\n", test.interpolate(10.0));
}

View File

@@ -135,6 +135,9 @@ double least_squares_max_error(double *x, double *y, int n, double m, double b){
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.1 1999/03/13 17:34:45 curt
// Moved to math subdirectory.
//

View File

@@ -73,6 +73,9 @@ double least_squares_max_error(double *x, double *y, int n, double m, double b);
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.1 1999/03/13 17:34:45 curt
// Moved to math subdirectory.
//

View File

@@ -337,6 +337,9 @@ Point3D::distance3Dsquared(const Point3D& a ) const
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.10 1999/03/02 01:01:52 curt
// Tweaks for compiling with native SGI compilers.
//

View File

@@ -61,6 +61,9 @@ double fgGeodAltFromCart(const Point3D& cp)
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.6 1999/01/27 04:46:19 curt
// Portability tweaks by Bernie Bright.
//

View File

@@ -67,6 +67,9 @@ inline Point3D fgCartToPolar3d(const Point3D& cp) {
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.5 1999/01/27 04:46:20 curt
// Portability tweaks by Bernie Bright.
//

View File

@@ -129,6 +129,9 @@ double fgPointLineSquared(MAT3vec p, MAT3vec p0, MAT3vec d) {
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.6 1999/03/25 19:02:28 curt
// Minor optimization tweaks.
//

View File

@@ -63,6 +63,9 @@ double fgPointLineSquared(MAT3vec p, MAT3vec p0, MAT3vec d);
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.4 1998/10/16 23:36:39 curt
// c++-ifying.
//

View File

@@ -140,6 +140,9 @@ skipcomment( istream& in )
}
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.3 1998/11/06 14:05:12 curt
// More portability improvements by Bernie Bright.
//

View File

@@ -100,6 +100,9 @@ istream& skipcomment( istream& in );
#endif /* _FGSTREAM_HXX */
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.9 1999/03/27 14:04:25 curt
// Added is_open() so we can check if the open() succeeded.
//

View File

@@ -25,6 +25,9 @@
*
***************************************************************************
* $Log$
* Revision 1.1 1999/04/05 21:32:33 curt
* Initial revision
*
* Revision 1.3 1998/11/20 01:01:03 curt
* FreeBSD support.
*

View File

@@ -71,6 +71,9 @@ trim( const string& s, const string& trimmings )
}
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.2 1998/10/18 01:17:15 curt
// Point3D tweaks.
//

View File

@@ -64,6 +64,9 @@ atoi( const string& str )
#endif // STRUTILS_H
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.6 1999/03/02 01:01:56 curt
// Tweaks for compiling with native SGI compilers.
//

View File

@@ -309,6 +309,9 @@ gzifstream::close()
#endif
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.3 1999/01/19 20:41:48 curt
// Portability updates contributed by Bernie Bright.
//

View File

@@ -154,6 +154,9 @@ struct gzifstream_base
#endif // _zfstream_hxx
// $Log$
// Revision 1.1 1999/04/05 21:32:33 curt
// Initial revision
//
// Revision 1.9 1999/03/08 22:00:12 curt
// Tweak for native SGI compilers.
//

View File

@@ -336,6 +336,9 @@ int fgSERIAL::write_port(const string& value) {
// $Log$
// Revision 1.1 1999/04/05 21:32:34 curt
// Initial revision
//
// Revision 1.9 1999/02/02 20:13:23 curt
// MSVC++ portability changes by Bernie Bright:
//

View File

@@ -80,6 +80,9 @@ public:
// $Log$
// Revision 1.1 1999/04/05 21:32:34 curt
// Initial revision
//
// Revision 1.5 1999/03/02 01:01:58 curt
// Tweaks for compiling with native SGI compilers.
//

View File

@@ -1,24 +0,0 @@
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)

View File

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

View File

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

805
PUI/pu.h
View File

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

View File

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

View File

@@ -1,61 +0,0 @@
#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 () ;
}

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,268 +0,0 @@
#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 ;
}
}

View File

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

View File

@@ -1,83 +0,0 @@
#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 () ;
}

View File

@@ -1,222 +0,0 @@
#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." ;
}

View File

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

View File

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

View File

@@ -1,175 +0,0 @@
#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 ;
}

View File

@@ -1,107 +0,0 @@
#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 ;
}
}
}

View File

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

View File

@@ -1,17 +0,0 @@
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

View File

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

View File

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

629
src/sl.h
View File

@@ -1,629 +0,0 @@
#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

View File

@@ -1,669 +0,0 @@
#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

View File

@@ -1,170 +0,0 @@
#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 ;
}
}

View File

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

View File

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

View File

@@ -1,188 +0,0 @@
#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 () ;
}
}
}

View File

@@ -1,253 +0,0 @@
#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 ) ;
}
}

View File

@@ -1,89 +0,0 @@
#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

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