Initial revision
This commit is contained in:
139
Audio/CHANGES
139
Audio/CHANGES
@@ -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
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
SUBDIRS = src example
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;......
|
||||
@@ -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 '#'
|
||||
@@ -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".
|
||||
@@ -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:
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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"
|
||||
@@ -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".
|
||||
@@ -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".
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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
|
||||
@@ -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
30
Lib/Math/geotest.c
Normal 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);
|
||||
}
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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
23
Lib/Math/inttest.cxx
Normal 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));
|
||||
}
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
*
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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:
|
||||
//
|
||||
@@ -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.
|
||||
//
|
||||
@@ -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)
|
||||
|
||||
332
PUI/complex.cxx
332
PUI/complex.cxx
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
332
PUI/pu.cxx
332
PUI/pu.cxx
@@ -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
805
PUI/pu.h
@@ -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
|
||||
|
||||
319
PUI/puBox.cxx
319
PUI/puBox.cxx
@@ -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 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 () ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ) ;
|
||||
}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
#include "puLocal.h"
|
||||
|
||||
|
||||
@@ -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 ) ;
|
||||
}
|
||||
|
||||
|
||||
226
PUI/puInput.cxx
226
PUI/puInput.cxx
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 () ;
|
||||
}
|
||||
|
||||
|
||||
222
PUI/puObject.cxx
222
PUI/puObject.cxx
@@ -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." ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ) ;
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
#include "puLocal.h"
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
107
PUI/puSlider.cxx
107
PUI/puSlider.cxx
@@ -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 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
#include "puLocal.h"
|
||||
|
||||
void puText::draw ( int dx, int dy )
|
||||
{
|
||||
draw_label ( dx, dy ) ;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 () ;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
629
src/sl.h
@@ -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
|
||||
|
||||
669
src/slDSP.cxx
669
src/slDSP.cxx
@@ -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
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
505
src/slSample.cxx
505
src/slSample.cxx
@@ -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 ;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 () ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
89
src/sm.h
89
src/sm.h
@@ -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
Reference in New Issue
Block a user