aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--games/jfsw/README23
-rw-r--r--games/jfsw/jfsw.SlackBuild78
-rw-r--r--games/jfsw/jfsw.info18
-rw-r--r--games/jfsw/patches/disable_ambience.patch61
-rw-r--r--games/jfsw/patches/jfbuild_src_20051009.patch125
-rw-r--r--games/jfsw/patches/jfsw_src_20051009.patch4578
6 files changed, 55 insertions, 4828 deletions
diff --git a/games/jfsw/README b/games/jfsw/README
index e6d6add77ab8..23ccdc457ad3 100644
--- a/games/jfsw/README
+++ b/games/jfsw/README
@@ -12,22 +12,9 @@ For the full version, copy sw.grp from the game directory to
If you have sw.grp from the full version of the game, you may also want
to install jfsw_hires_pack for some graphic enhancements (don't bother
-trying, if all you have is the shareware sw.grp: it segfaults on startup).
+trying if all you have is the shareware sw.grp: it segfaults on startup).
-Note #1: There's no way to enable the mouse from the in-game menus. To
-enable the mouse, you must run the game at least once to create its
-config file (~/.jfsw/sw.cfg), then edit the config file and change
-ControllerType to 1. You probably also want to change MouseAimingOn to 1,
-for a more modern "mouselook" style of play.
-
-Note #2: The Ambience setting in the Sound Setup menu is permanently
-disabled, because the ambience code causes the game to crash.
-
-Note #3: Multiplayer does work (at least for LAN play). See
-/usr/doc/jsfw-$VERSION/releasenotes.html for multiplayer usage.
-
-Note #4 (for Slackware 64-bit users): The source includes x86 assembly
-code, so can't be built for any non-x86 architecture. If you're using
-x86_64, you might (or might not) be able to build jfsw on a 32-bit
-Slackware system and install it on x86_64 along with alienBOB's compat32
-packages and get it to run.
+Note #1: If you run into an issue turning left or right with the mouse,
+edit the config file (~/.jfsw/sw.cfg) and change MouseAnalogAxes0 to
+"analog_turning" and MouseAnalogAxes1 to "analog_moving". The digital
+axes should have "" values.
diff --git a/games/jfsw/jfsw.SlackBuild b/games/jfsw/jfsw.SlackBuild
index b0b50783bad3..a061b0bb4d61 100644
--- a/games/jfsw/jfsw.SlackBuild
+++ b/games/jfsw/jfsw.SlackBuild
@@ -3,11 +3,12 @@
# Slackware build script for jfsw
# Written by B. Watson (yalhcru@gmail.com)
+# Updated for Slackware 14.2 with the help of orbea <ovariegata@yahoo.com>
# Licensed under the WTFPL. See http://www.wtfpl.net/txt/copying/ for details.
PRGNAM=jfsw
-VERSION=${VERSION:-20051009}
+VERSION=${VERSION:-20160220_54912c4}
BUILD=${BUILD:-1}
TAG=${TAG:-_SBo}
@@ -24,61 +25,60 @@ TMP=${TMP:-/tmp/SBo}
PKG=$TMP/package-$PRGNAM
OUTPUT=${OUTPUT:-/tmp}
-# SLKCFLAGS is only used if FORCE_SLACK_CFLAGS=yes in the environment.
-# This is because the code has portability problems that might cause
-# trouble if built with CFLAGS other than the default ones in the Makefile.
-
if [ "$ARCH" = "i486" ]; then
SLKCFLAGS="-O2 -march=i486 -mtune=i686"
+ LIBDIRSUFFIX=""
elif [ "$ARCH" = "i686" ]; then
SLKCFLAGS="-O2 -march=i686 -mtune=i686"
+ LIBDIRSUFFIX=""
+elif [ "$ARCH" = "x86_64" ]; then
+ SLKCFLAGS="-O2 -fPIC"
+ LIBDIRSUFFIX="64"
else
- echo "Sorry, this package can't be built on $ARCH"
- exit 1
+ SLKCFLAGS="-O2"
+ LIBDIRSUFFIX=""
fi
set -e
-BUILD_PRGNAM=jfbuild
-BIN_NAME=sw
-
rm -rf $PKG
mkdir -p $TMP $PKG $OUTPUT
cd $TMP
-rm -rf ${PRGNAM}_src_${VERSION} ${BUILD_PRGNAM}_src_${VERSION} build
-unzip $CWD/${PRGNAM}_src_${VERSION}.zip
-unzip $CWD/${BUILD_PRGNAM}_src_${VERSION}.zip
-mv ${BUILD_PRGNAM}_src_${VERSION} build
-
-cd build
- # build engine compile fixes, from gentoo
- patch -p1 < $CWD/patches/jfbuild_src_20051009.patch
-cd -
-
-cd ${PRGNAM}_src_${VERSION}
-# compile fixes, from gentoo
-patch -p1 < $CWD/patches/jfsw_src_20051009.patch
-# permanently disable ambient sound option, since it doesn't work and
-# causes the game to lock up
-patch -p1 < $CWD/patches/disable_ambience.patch
-
+for TARNAM in \
+ jfsw-54912c4964a5d68d4fd68dba1d3affcfe2062766.tar.gz \
+ jfaudiolib-ea5613edadcf691a4867a750546f33ef84885fbf.tar.gz \
+ jfbuild-b129b7ee9ce468022610dc8194786c0bac1f66ef.tar.gz \
+ jfmact-f915216973de73c42c326fdd3b1734ac12316427.tar.gz \
+; do
+ SRCNAM=$(echo $TARNAM | sed -e 's/-.*//')
+ DERPY_TARNAM=$(echo $TARNAM | sed -e 's/.*-//')
+ COMMIT=$(basename $DERPY_TARNAM .tar.gz)
+ rm -rf $SRCNAM
+ tar xvf $CWD/$TARNAM || tar xvf $CWD/$DERPY_TARNAM
+ mv $SRCNAM-$COMMIT $SRCNAM
+done
+
+cd $PRGNAM
+mv \
+ $TMP/jfaudiolib \
+ $TMP/jfbuild \
+ $TMP/jfmact \
+ .
chown -R root:root .
find -L . \
- \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 -o -perm 511 \) \
- -exec chmod 755 {} \; -o \
- \( -perm 666 -o -perm 664 -o -perm 600 -o -perm 444 -o -perm 440 -o -perm 400 \) \
- -exec chmod 644 {} \;
-
-# I hate hard-coded assumptions that I have the same CPU you have...
-sed -i 's/-march=pentium//' Makefile ../build/Makefile
+ \( -perm 777 -o -perm 775 -o -perm 750 -o -perm 711 -o -perm 555 \
+ -o -perm 511 \) -exec chmod 755 {} \; -o \
+ \( -perm 666 -o -perm 664 -o -perm 640 -o -perm 600 -o -perm 444 \
+ -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \;
-if [ "${FORCE_SLACK_CFLAGS:-no}" = "yes" ]; then
- sed -i '/^\s\+debug=/s/=.*/='"$SLKCFLAGS"'/' Makefile ../build/Makefile
-fi
-
-make RELEASE=1
+make \
+ RELEASE=1 \
+ PREFIX=/usr/share/games/$PRGNAM \
+ CFLAGS="$SLKCFLAGS" \
+ CXXFLAGS="$SLKCFLAGS"
# no 'make install' target
+BIN_NAME=sw
mkdir -p $PKG/usr/games
install -s -m0755 -oroot -groot $BIN_NAME $PKG/usr/games
cd $PKG/usr/games
diff --git a/games/jfsw/jfsw.info b/games/jfsw/jfsw.info
index bb6804066715..e3b392ec17bd 100644
--- a/games/jfsw/jfsw.info
+++ b/games/jfsw/jfsw.info
@@ -1,12 +1,16 @@
PRGNAM="jfsw"
-VERSION="20051009"
+VERSION="20160220_54912c4"
HOMEPAGE="http://www.jonof.id.au/jfsw"
-DOWNLOAD="http://static.jonof.id.au/dl/buildport/jfsw_src_20051009.zip \
- http://static.jonof.id.au/dl/buildport/jfbuild_src_20051009.zip"
-MD5SUM="6b175daed0e459aac375e63de90097f0 \
- 44a943c0050bfd46ce1e6af24c951898"
-DOWNLOAD_x86_64="UNSUPPORTED"
+DOWNLOAD="https://github.com/jonof/jfsw/archive/54912c4964a5d68d4fd68dba1d3affcfe2062766.tar.gz \
+ https://github.com/jonof/jfaudiolib/archive/ea5613edadcf691a4867a750546f33ef84885fbf.tar.gz \
+ https://github.com/jonof/jfbuild/archive/b129b7ee9ce468022610dc8194786c0bac1f66ef.tar.gz \
+ https://github.com/jonof/jfmact/archive/f915216973de73c42c326fdd3b1734ac12316427.tar.gz"
+MD5SUM="ded58dc228640fbafa8d9cfb155cd783 \
+ 6224b79b42d3a20c31c1a25eedd85702 \
+ 9fab17bb9f119be304d4a8591d5be5d1 \
+ ad429cc636cba0c265a857c138a92a9d"
+DOWNLOAD_x86_64=""
MD5SUM_x86_64=""
-REQUIRES="eawpats"
+REQUIRES="freepats"
MAINTAINER="B. Watson"
EMAIL="yalhcru@gmail.com"
diff --git a/games/jfsw/patches/disable_ambience.patch b/games/jfsw/patches/disable_ambience.patch
deleted file mode 100644
index 221af6152daa..000000000000
--- a/games/jfsw/patches/disable_ambience.patch
+++ /dev/null
@@ -1,61 +0,0 @@
-diff -Naur jfsw_src_20051009.orig/source/game.c jfsw_src_20051009/source/game.c
---- jfsw_src_20051009.orig/source/game.c 2005-10-09 15:28:24.000000000 -0400
-+++ jfsw_src_20051009/source/game.c 2010-02-09 00:08:14.000000000 -0500
-@@ -197,7 +197,7 @@
- TRUE, // fx on
- TRUE, // Music on
- TRUE, // talking
--TRUE, // ambient
-+FALSE, // ambient
- FALSE, // Flip Stereo
-
- // Network game settings
-diff -Naur jfsw_src_20051009.orig/source/menus.c jfsw_src_20051009/source/menus.c
---- jfsw_src_20051009.orig/source/menus.c 2005-10-09 15:28:24.000000000 -0400
-+++ jfsw_src_20051009/source/menus.c 2010-02-09 00:26:35.000000000 -0500
-@@ -196,7 +196,7 @@
- {DefInert(0, NULL), OPT_XSIDE, OPT_LINE(3), 0, m_defshade, 0, NULL, NULL, NULL},
-
- //{DefButton(btn_talking, 0, "Talking"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
-- {DefButton(btn_ambience, 0, "Ambience"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
-+ {DefButton(btn_ambience, 0, "Ambience"), OPT_XS, OPT_LINE(4), 1, m_defshade, 0, NULL, MNU_DisableButton, NULL},
- {DefButton(btn_flipstereo, 0, "Flip Stereo"), OPT_XS, OPT_LINE(5), 1, m_defshade, 0, NULL, MNU_FxCheck, NULL},
- //{DefButton(btn_playcd, 0, "Play CD"), OPT_XS, OPT_LINE(6), 1, m_defshade, 0, NULL, NULL, NULL},
- {DefNone}
-@@ -2695,6 +2695,13 @@
- }
-
- BOOL
-+MNU_DisableButton(MenuItem *item)
-+ {
-+ SET(item->flags, mf_disabled);
-+ return (TRUE);
-+ }
-+
-+BOOL
- MNU_FxCheck(MenuItem *item)
- {
- if (FXDevice < 0 || !FxInitialized)
-diff -Naur jfsw_src_20051009.orig/source/menus.h jfsw_src_20051009/source/menus.h
---- jfsw_src_20051009.orig/source/menus.h 2005-10-09 15:28:24.000000000 -0400
-+++ jfsw_src_20051009/source/menus.h 2010-02-09 00:27:29.000000000 -0500
-@@ -289,6 +289,7 @@
-
- BOOL MNU_MusicFxCheck(MenuItem_p item);
- BOOL MNU_MusicCheck(MenuItem_p item);
-+BOOL MNU_DisableButton(MenuItem_p item);
- BOOL MNU_FxCheck(MenuItem_p item);
- BOOL MNU_MouseCheck(MenuItem_p item);
- BOOL MNU_BorderCheck(MenuItem_p item);
-diff -Naur jfsw_src_20051009.orig/source/swconfig.c jfsw_src_20051009/source/swconfig.c
---- jfsw_src_20051009.orig/source/swconfig.c 2005-10-09 15:28:24.000000000 -0400
-+++ jfsw_src_20051009/source/swconfig.c 2010-02-09 00:09:21.000000000 -0500
-@@ -170,7 +170,7 @@
-
- dummy = -1;
- SCRIPT_GetNumber( scripthandle, "Options", "Ambient",&dummy);
-- if (dummy != -1) gs.Ambient = dummy;
-+ gs.Ambient = 0;
-
- dummy = -1;
- SCRIPT_GetNumber( scripthandle, "Options", "FxOn",&dummy);
diff --git a/games/jfsw/patches/jfbuild_src_20051009.patch b/games/jfsw/patches/jfbuild_src_20051009.patch
deleted file mode 100644
index 5cf0cb2feb02..000000000000
--- a/games/jfsw/patches/jfbuild_src_20051009.patch
+++ /dev/null
@@ -1,125 +0,0 @@
-diff -Nur jfbuild_src_20051009.orig/include/editor.h jfbuild_src_20051009/include/editor.h
---- jfbuild_src_20051009.orig/include/editor.h 2005-10-09 15:23:02.000000000 +0200
-+++ jfbuild_src_20051009/include/editor.h 2005-10-10 15:06:18.000000000 +0200
-@@ -18,7 +18,7 @@
-
- extern short temppicnum, tempcstat, templotag, temphitag, tempextra;
- extern char tempshade, temppal, tempxrepeat, tempyrepeat;
--extern char somethingintab;
-+static char somethingintab;
-
- extern char buildkeys[NUMBUILDKEYS];
-
-diff -Nur jfbuild_src_20051009.orig/Makefile jfbuild_src_20051009/Makefile
---- jfbuild_src_20051009.orig/Makefile 2005-10-09 15:23:00.000000000 +0200
-+++ jfbuild_src_20051009/Makefile 2005-10-10 15:06:22.000000000 +0200
-@@ -27,7 +27,7 @@
- # Debugging options
- # RELEASE - 1 = no debugging
- # EFENCE - 1 = compile with Electric Fence for malloc() debugging
--RELEASE?=0
-+RELEASE?=1
- EFENCE?=0
-
- # SDK locations - adjust to match your setup
-diff -Nur jfbuild_src_20051009.orig/src/build.c jfbuild_src_20051009/src/build.c
---- jfbuild_src_20051009.orig/src/build.c 2005-10-09 15:23:00.000000000 +0200
-+++ jfbuild_src_20051009/src/build.c 2005-10-10 15:06:18.000000000 +0200
-@@ -86,7 +86,7 @@
-
- short temppicnum, tempcstat, templotag, temphitag, tempextra;
- char tempshade, temppal, tempvis, tempxrepeat, tempyrepeat;
--char somethingintab = 255;
-+static char somethingintab = 255;
-
- static char boardfilename[BMAX_PATH], selectedboardfilename[BMAX_PATH];
- static struct _directoryitem {
-diff -Nur jfbuild_src_20051009.orig/src/crc32.c jfbuild_src_20051009/src/crc32.c
---- jfbuild_src_20051009.orig/src/crc32.c 2005-10-09 15:23:00.000000000 +0200
-+++ jfbuild_src_20051009/src/crc32.c 2005-10-10 15:06:18.000000000 +0200
-@@ -73,16 +73,6 @@
- }
- }
-
--
--unsigned long crc32(unsigned char *blk, unsigned long len)
--{
-- unsigned long crc;
--
-- crc32init(&crc);
-- crc32block(&crc, blk, len);
-- return crc32finish(&crc);
--}
--
- void crc32init(unsigned long *crcvar)
- {
- if (!crcvar) return;
-diff -Nur jfbuild_src_20051009.orig/src/sdlayer.c jfbuild_src_20051009/src/sdlayer.c
---- jfbuild_src_20051009.orig/src/sdlayer.c 2005-10-09 15:23:00.000000000 +0200
-+++ jfbuild_src_20051009/src/sdlayer.c 2005-10-10 15:06:22.000000000 +0200
-@@ -24,6 +24,10 @@
- // undefine to restrict windowed resolutions to conventional sizes
- #define ANY_WINDOWED_SIZE
-
-+// fix for mousewheel
-+#define MWHEELTICKS 10
-+static unsigned long mwheelup, mwheeldown;
-+
- int _buildargc = 1;
- char **_buildargv = NULL;
- extern long app_main(long argc, char *argv[]);
-@@ -486,8 +490,8 @@
- initprintf("Initialising mouse\n");
-
- // grab input
-- grabmouse(1);
- moustat=1;
-+ grabmouse(1);
-
- return 0;
- }
-@@ -1363,14 +1367,22 @@
- case SDL_BUTTON_LEFT: j = 0; break;
- case SDL_BUTTON_RIGHT: j = 1; break;
- case SDL_BUTTON_MIDDLE: j = 2; break;
-- default: j = -1; break;
-+ default: j = ev.button.button; break;
- }
- if (j<0) break;
-
-- if (ev.button.state == SDL_PRESSED)
-+ if (ev.button.state == SDL_PRESSED) {
-+ if (ev.button.button == SDL_BUTTON_WHEELUP) {
-+ mwheelup = totalclock;
-+ }
-+ if (ev.button.button == SDL_BUTTON_WHEELDOWN) {
-+ mwheeldown = totalclock;
-+ }
- mouseb |= (1<<j);
-- else
-- mouseb &= ~(1<<j);
-+ }
-+ else {
-+ if (j < 4) mouseb &= ~(1<<j);
-+ }
-
- if (mousepresscallback)
- mousepresscallback(j+1, ev.button.state == SDL_PRESSED);
-@@ -1435,6 +1447,17 @@
-
- sampletimer();
-
-+ if (moustat) {
-+ if ((mwheelup) && (mwheelup <= (totalclock - MWHEELTICKS))) {
-+ mouseb &= ~16;
-+ mwheelup = 0;
-+ }
-+ if ((mwheeldown) && (mwheeldown <= (totalclock - MWHEELTICKS))) {
-+ mouseb &= ~32;
-+ mwheeldown = 0;
-+ }
-+ }
-+
- #ifdef HAVE_GTK2
- if (gtkenabled) update_startwin();
- #endif
diff --git a/games/jfsw/patches/jfsw_src_20051009.patch b/games/jfsw/patches/jfsw_src_20051009.patch
deleted file mode 100644
index 53f928992fd0..000000000000
--- a/games/jfsw/patches/jfsw_src_20051009.patch
+++ /dev/null
@@ -1,4578 +0,0 @@
-diff -Nur jfsw_src_20051009.orig/Makefile jfsw_src_20051009/Makefile
---- jfsw_src_20051009.orig/Makefile 2005-10-09 15:28:24.000000000 +0200
-+++ jfsw_src_20051009/Makefile 2005-10-10 15:02:08.000000000 +0200
-@@ -12,7 +12,7 @@
- NOASM = 0
-
- # Debugging options
--RELEASE?=0
-+RELEASE?=1
-
- # build locations
- SRC=source/
-@@ -56,11 +56,8 @@
- AUDIOLIB_FX=$(OBJ)mv_mix.$o \
- $(OBJ)mv_mix16.$o \
- $(OBJ)mvreverb.$o \
-- $(OBJ)pitch.$o \
-- $(OBJ)multivoc.$o \
- $(OBJ)ll_man.$o \
-- $(OBJ)fx_man.$o \
-- $(OBJ)dsoundout.$o
-+ $(OBJ)fx_man.$o
- AUDIOLIB_MUSIC=$(OBJ)midi.$o \
- $(OBJ)mpu401.$o \
- $(OBJ)music.$o
-@@ -157,9 +154,16 @@
- EDITOROBJS+= $(OBJ)buildres.$o
- endif
-
--ifeq ($(RENDERTYPE),SDL)
-- override CFLAGS+= $(subst -Dmain=SDL_main,,$(shell sdl-config --cflags))
-- AUDIOLIBOBJ=$(AUDIOLIB_MUSIC_STUB) $(AUDIOLIB_FX_STUB)
-+ifeq ($(RENDERTYPE),SDL)
-+ override CFLAGS+= $(subst -Dmain=SDL_main,,$(shell sdl-config --cflags) -D__cdecl=" ")
-+ LIBS+= $(shell sdl-config --libs) -lSDL_mixer
-+ AUDIOLIB_FX+= $(OBJ)dsl.$o \
-+ $(OBJ)nodpmi.$o \
-+ $(OBJ)unixpitch.$o \
-+ $(OBJ)unixvoc.$o
-+
-+ AUDIOLIB_MUSIC=$(OBJ)sdlmusic.$o $(OBJ)unixglob.$o
-+ AUDIOLIBOBJ=$(AUDIOLIB_MUSIC) $(AUDIOLIB_FX)
-
- ifeq (1,$(HAVE_GTK2))
- override CFLAGS+= -DHAVE_GTK2 $(shell pkg-config --cflags gtk+-2.0)
-@@ -170,7 +174,11 @@
- GAMEOBJS+= $(OBJ)game_icon.$o
- EDITOROBJS+= $(OBJ)build_icon.$o
- endif
--ifeq ($(RENDERTYPE),WIN)
-+ifeq ($(RENDERTYPE),WIN)
-+ AUDIOLIB_FX+= $(OBJ)audiolib_fx_fmod.$o \
-+ $(OBJ)dsoundout.$o \
-+ $(OBJ)pitch.$o \
-+ $(OBJ)multivoc.$o
- AUDIOLIBOBJ=$(AUDIOLIB_MUSIC) $(AUDIOLIB_FX)
- endif
-
-diff -Nur jfsw_src_20051009.orig/Makefile.deps jfsw_src_20051009/Makefile.deps
---- jfsw_src_20051009.orig/Makefile.deps 2005-10-09 15:28:24.000000000 +0200
-+++ jfsw_src_20051009/Makefile.deps 2005-10-10 15:02:08.000000000 +0200
-@@ -95,6 +95,11 @@
- $(OBJ)animlib.$o: $(SRC)jmact/animlib.c $(SRC)jmact/types.h $(SRC)jmact/develop.h $(SRC)jmact/util_lib.h $(SRC)jmact/animlib.h
-
- # jAudioLib objects
-+$(OBJ)dsl.$o: $(SRC)jaudiolib/dsl.c $(SRC)jaudiolib/util.h
-+$(OBJ)nodpmi.$o: $(SRC)jaudiolib/nodpmi.c $(SRC)jaudiolib/dpmi.h
-+$(OBJ)unixpitch.$o: $(SRC)jaudiolib/unixpitch.c $(SRC)jaudiolib/pitch.h
-+$(OBJ)unixvoc.$o: $(SRC)jaudiolib/unixvoc.c $(SRC)jaudiolib/usrhooks.h $(SRC)jaudiolib/linklist.h $(SRC)jaudiolib/pitch.h $(SRC)jaudiolib/multivoc.h $(SRC)jaudiolib/_multivc.h
-+
- $(OBJ)audiolib_fxstub.$o: $(SRC)jaudiolib/audiolib_fxstub.c $(SRC)jaudiolib/fx_man.h
- $(OBJ)audiolib_musicstub.$o: $(SRC)jaudiolib/audiolib_musicstub.c $(SRC)jaudiolib/music.h
-
-diff -Nur jfsw_src_20051009.orig/source/config.c jfsw_src_20051009/source/config.c
---- jfsw_src_20051009.orig/source/config.c 2005-10-09 15:28:26.000000000 +0200
-+++ jfsw_src_20051009/source/config.c 2005-10-10 15:02:08.000000000 +0200
-@@ -63,8 +63,8 @@
- //
- // Sound variables
- //
--int32 FXDevice = -1;
--int32 MusicDevice = -1;
-+int32 FXDevice = 1;
-+int32 MusicDevice = 1;
- int32 FXVolume = 192;
- int32 MusicVolume = 128;
- int32 NumVoices = 4;
-@@ -215,8 +215,8 @@
- ScreenWidth = 640;
- ScreenHeight = 480;
- ScreenBPP = 8;
-- FXDevice = -1;
-- MusicDevice = -1;
-+ FXDevice = 1;
-+ MusicDevice = 1;
- FXVolume = 192;
- MusicVolume = 128;
- NumVoices = 4;
-diff -Nur jfsw_src_20051009.orig/source/game.c jfsw_src_20051009/source/game.c
---- jfsw_src_20051009.orig/source/game.c 2005-10-09 15:28:24.000000000 +0200
-+++ jfsw_src_20051009/source/game.c 2005-10-10 15:02:05.000000000 +0200
-@@ -5182,7 +5182,10 @@
- angvel = info.dyaw >> 8;
- }
-
-- svel -= info.dx;
-+ if (!running) svel -= (info.dx / 8.75);
-+ else svel -= (info.dx / 4.375);
-+ if (!running) vel -= (info.dpitch / 8.75);
-+ else vel -= (info.dpitch / 4.375);
-
- switch (ControllerType)
- {
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/debugio.h jfsw_src_20051009/source/jaudiolib/debugio.h
---- jfsw_src_20051009.orig/source/jaudiolib/debugio.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/debugio.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,30 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+#ifndef __DEBUGIO_H
-+#define __DEBUGIO_H
-+
-+void DB_SetXY( int x, int y );
-+void DB_PutChar( char ch );
-+int DB_PrintString( char *string );
-+int DB_PrintNum( int number );
-+int DB_PrintUnsigned( unsigned long number, int radix );
-+int DB_printf( char *fmt, ... );
-+
-+#endif
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/dma.h jfsw_src_20051009/source/jaudiolib/dma.h
---- jfsw_src_20051009.orig/source/jaudiolib/dma.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/dma.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,83 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+/**********************************************************************
-+ file: DMA.H
-+
-+ author: James R. Dose
-+ date: February 4, 1994
-+
-+ Public header file for DMA.C
-+
-+ (c) Copyright 1994 James R. Dose. All Rights Reserved.
-+**********************************************************************/
-+
-+#ifndef __DMA_H
-+#define __DMA_H
-+
-+enum DMA_ERRORS
-+ {
-+ DMA_Error = -1,
-+ DMA_Ok = 0,
-+ DMA_ChannelOutOfRange,
-+ DMA_InvalidChannel
-+ };
-+
-+enum DMA_Modes
-+ {
-+ DMA_SingleShotRead,
-+ DMA_SingleShotWrite,
-+ DMA_AutoInitRead,
-+ DMA_AutoInitWrite
-+ };
-+
-+char *DMA_ErrorString
-+ (
-+ int ErrorNumber
-+ );
-+
-+int DMA_VerifyChannel
-+ (
-+ int channel
-+ );
-+
-+int DMA_SetupTransfer
-+ (
-+ int channel,
-+ char *address,
-+ int length,
-+ int mode
-+ );
-+
-+int DMA_EndTransfer
-+ (
-+ int channel
-+ );
-+
-+char *DMA_GetCurrentPos
-+ (
-+ int channel
-+ );
-+
-+int DMA_GetTransferCount
-+ (
-+ int channel
-+ );
-+
-+#endif
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/dpmi.h jfsw_src_20051009/source/jaudiolib/dpmi.h
---- jfsw_src_20051009.orig/source/jaudiolib/dpmi.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/dpmi.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,43 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+/**********************************************************************
-+ module: DPMI.H
-+
-+ author: James R. Dose
-+ date: March 31, 1994
-+
-+ Inline functions for performing DPMI calls.
-+
-+ (c) Copyright 1994 James R. Dose. All Rights Reserved.
-+**********************************************************************/
-+
-+#ifndef __DPMI_H
-+#define __DPMI_H
-+
-+enum DPMI_Errors
-+ {
-+ DPMI_Warning = -2,
-+ DPMI_Error = -1,
-+ DPMI_Ok = 0
-+ };
-+
-+int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length );
-+int DPMI_FreeDOSMemory( int descriptor );
-+#endif
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/dsl.c jfsw_src_20051009/source/jaudiolib/dsl.c
---- jfsw_src_20051009.orig/source/jaudiolib/dsl.c 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/dsl.c 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,257 @@
-+/*
-+Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
-+Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
-+
-+*/
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "dsl.h"
-+#include "util.h"
-+
-+#include "SDL.h"
-+#include "SDL_mixer.h"
-+
-+extern volatile int MV_MixPage;
-+
-+static int DSL_ErrorCode = DSL_Ok;
-+
-+static int mixer_initialized;
-+
-+static void ( *_CallBackFunc )( void );
-+static volatile char *_BufferStart;
-+static int _BufferSize;
-+static int _NumDivisions;
-+static int _SampleRate;
-+static int _remainder;
-+
-+static Mix_Chunk *blank;
-+static unsigned char *blank_buf;
-+
-+/*
-+possible todo ideas: cache sdl/sdl mixer error messages.
-+*/
-+
-+char *DSL_ErrorString( int ErrorNumber )
-+{
-+ char *ErrorString;
-+
-+ switch (ErrorNumber) {
-+ case DSL_Warning:
-+ case DSL_Error:
-+ ErrorString = DSL_ErrorString(DSL_ErrorCode);
-+ break;
-+
-+ case DSL_Ok:
-+ ErrorString = "SDL Driver ok.";
-+ break;
-+
-+ case DSL_SDLInitFailure:
-+ ErrorString = "SDL Audio initialization failed.";
-+ break;
-+
-+ case DSL_MixerActive:
-+ ErrorString = "SDL Mixer already initialized.";
-+ break;
-+
-+ case DSL_MixerInitFailure:
-+ ErrorString = "SDL Mixer initialization failed.";
-+ break;
-+
-+ default:
-+ ErrorString = "Unknown SDL Driver error.";
-+ break;
-+ }
-+
-+ return ErrorString;
-+}
-+
-+static void DSL_SetErrorCode(int ErrorCode)
-+{
-+ DSL_ErrorCode = ErrorCode;
-+}
-+
-+int DSL_Init( void )
-+{
-+ DSL_SetErrorCode(DSL_Ok);
-+
-+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
-+ DSL_SetErrorCode(DSL_SDLInitFailure);
-+
-+ return DSL_Error;
-+ }
-+
-+ return DSL_Ok;
-+}
-+
-+void DSL_Shutdown( void )
-+{
-+ DSL_StopPlayback();
-+}
-+
-+static void mixer_callback(int chan, void *stream, int len, void *udata)
-+{
-+ Uint8 *stptr;
-+ Uint8 *fxptr;
-+ int copysize;
-+
-+ /* len should equal _BufferSize, else this is screwed up */
-+
-+ stptr = (Uint8 *)stream;
-+
-+ if (_remainder > 0) {
-+ copysize = min(len, _remainder);
-+
-+ fxptr = (Uint8 *)(&_BufferStart[MV_MixPage *
-+ _BufferSize]);
-+
-+ memcpy(stptr, fxptr+(_BufferSize-_remainder), copysize);
-+
-+ len -= copysize;
-+ _remainder -= copysize;
-+
-+ stptr += copysize;
-+ }
-+
-+ while (len > 0) {
-+ /* new buffer */
-+
-+ _CallBackFunc();
-+
-+ fxptr = (Uint8 *)(&_BufferStart[MV_MixPage *
-+ _BufferSize]);
-+
-+ copysize = min(len, _BufferSize);
-+
-+ memcpy(stptr, fxptr, copysize);
-+
-+ len -= copysize;
-+
-+ stptr += copysize;
-+ }
-+
-+ _remainder = len;
-+}
-+
-+int DSL_BeginBufferedPlayback( char *BufferStart,
-+ int BufferSize, int NumDivisions, unsigned SampleRate,
-+ int MixMode, void ( *CallBackFunc )( void ) )
-+{
-+ Uint16 format;
-+ Uint8 *tmp;
-+ int channels;
-+ int chunksize;
-+
-+ if (mixer_initialized) {
-+ DSL_SetErrorCode(DSL_MixerActive);
-+
-+ return DSL_Error;
-+ }
-+
-+ _CallBackFunc = CallBackFunc;
-+ _BufferStart = BufferStart;
-+ _BufferSize = (BufferSize / NumDivisions);
-+ _NumDivisions = NumDivisions;
-+ _SampleRate = SampleRate;
-+
-+ _remainder = 0;
-+
-+ format = (MixMode & SIXTEEN_BIT) ? AUDIO_S16SYS : AUDIO_U8;
-+ channels = (MixMode & STEREO) ? 2 : 1;
-+
-+/*
-+ 23ms is typically ideal (11025,22050,44100)
-+ 46ms isn't bad
-+*/
-+
-+ chunksize = 512;
-+
-+ if (SampleRate >= 16000) chunksize *= 2;
-+ if (SampleRate >= 32000) chunksize *= 2;
-+
-+/*
-+// SDL mixer does this already
-+ if (MixMode & SIXTEEN_BIT) chunksize *= 2;
-+ if (MixMode & STEREO) chunksize *= 2;
-+*/
-+
-+ if (Mix_OpenAudio(SampleRate, format, channels, chunksize) < 0) {
-+ DSL_SetErrorCode(DSL_MixerInitFailure);
-+
-+ return DSL_Error;
-+ }
-+
-+/*
-+ Mix_SetPostMix(mixer_callback, NULL);
-+*/
-+ /* have to use a channel because postmix will overwrite the music... */
-+ Mix_RegisterEffect(0, mixer_callback, NULL, NULL);
-+
-+ /* create a dummy sample just to allocate that channel */
-+ blank_buf = (Uint8 *)malloc(4096);
-+ memset(blank_buf, 0, 4096);
-+
-+ blank = Mix_QuickLoad_RAW(blank_buf, 4096);
-+
-+ Mix_PlayChannel(0, blank, -1);
-+
-+ mixer_initialized = 1;
-+
-+ return DSL_Ok;
-+}
-+
-+void DSL_StopPlayback( void )
-+{
-+ if (mixer_initialized) {
-+ Mix_HaltChannel(0);
-+ }
-+
-+ if (blank != NULL) {
-+ Mix_FreeChunk(blank);
-+ }
-+
-+ blank = NULL;
-+
-+ if (blank_buf != NULL) {
-+ free(blank_buf);
-+ }
-+
-+ blank_buf = NULL;
-+
-+ if (mixer_initialized) {
-+ Mix_CloseAudio();
-+ }
-+
-+ mixer_initialized = 0;
-+}
-+
-+unsigned DSL_GetPlaybackRate( void )
-+{
-+ return _SampleRate;
-+}
-+
-+unsigned long DisableInterrupts( void )
-+{
-+ return 0;
-+}
-+
-+void RestoreInterrupts( unsigned long flags )
-+{
-+}
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/dsl.h jfsw_src_20051009/source/jaudiolib/dsl.h
---- jfsw_src_20051009.orig/source/jaudiolib/dsl.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/dsl.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
-+Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
-+
-+*/
-+#ifndef AUDIOLIB__DSL_H
-+#define AUDIOLIB__DSL_H
-+
-+#define MONO_8BIT 0
-+#define STEREO 1
-+#define SIXTEEN_BIT 2
-+#define STEREO_16BIT ( STEREO | SIXTEEN_BIT )
-+
-+enum DSL_ERRORS
-+ {
-+ DSL_Warning = -2,
-+ DSL_Error = -1,
-+ DSL_Ok = 0,
-+ DSL_SDLInitFailure,
-+ DSL_MixerActive,
-+ DSL_MixerInitFailure
-+ };
-+
-+char *DSL_ErrorString( int ErrorNumber );
-+int DSL_Init( void );
-+void DSL_StopPlayback( void );
-+unsigned DSL_GetPlaybackRate( void );
-+int DSL_BeginBufferedPlayback( char *BufferStart,
-+ int BufferSize, int NumDivisions, unsigned SampleRate,
-+ int MixMode, void ( *CallBackFunc )( void ) );
-+void DSL_Shutdown( void );
-+
-+#endif
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/interrup.h jfsw_src_20051009/source/jaudiolib/interrup.h
---- jfsw_src_20051009.orig/source/jaudiolib/interrup.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/interrup.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+/**********************************************************************
-+ module: INTERRUP.H
-+
-+ author: James R. Dose
-+ date: March 31, 1994
-+
-+ Inline functions for disabling and restoring the interrupt flag.
-+
-+ (c) Copyright 1994 James R. Dose. All Rights Reserved.
-+**********************************************************************/
-+
-+#ifndef __INTERRUPT_H
-+#define __INTERRUPT_H
-+
-+unsigned long DisableInterrupts( void );
-+void RestoreInterrupts( unsigned long flags );
-+
-+#ifdef PLAT_DOS
-+#pragma aux DisableInterrupts = \
-+ "pushfd", \
-+ "pop eax", \
-+ "cli" \
-+ modify [ eax ];
-+
-+#pragma aux RestoreInterrupts = \
-+ "push eax", \
-+ "popfd" \
-+ parm [ eax ];
-+#endif
-+
-+#endif
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/_multivc.h jfsw_src_20051009/source/jaudiolib/_multivc.h
---- jfsw_src_20051009.orig/source/jaudiolib/_multivc.h 2005-10-09 15:28:24.000000000 +0200
-+++ jfsw_src_20051009/source/jaudiolib/_multivc.h 2005-10-10 15:02:08.000000000 +0200
-@@ -67,8 +67,11 @@
- #define SILENCE_8BIT 0x80808080
- //#define SILENCE_16BIT_PAS 0
-
--//#define MixBufferSize 256
-+#ifdef WINDOWS
- #define MixBufferSize (MV_GetBufferSize(MV_RequestedMixRate))
-+#else
-+#define MixBufferSize 256
-+#endif
-
- #define NumberOfBuffers 16
- #define TotalBufferSize ( MixBufferSize * NumberOfBuffers )
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/nodpmi.c jfsw_src_20051009/source/jaudiolib/nodpmi.c
---- jfsw_src_20051009.orig/source/jaudiolib/nodpmi.c 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/nodpmi.c 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,50 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+/**********************************************************************
-+ module: NODPMI.C
-+
-+ Functions for faking DPMI calls.
-+
-+**********************************************************************/
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include "dpmi.h"
-+
-+#define TRUE ( 1 == 1 )
-+#define FALSE ( !TRUE )
-+
-+int DPMI_GetDOSMemory( void **ptr, int *descriptor, unsigned length )
-+{
-+ /* Lovely... */
-+
-+ *ptr = (void *)malloc(length);
-+
-+ *descriptor = (int) *ptr;
-+
-+ return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
-+}
-+
-+int DPMI_FreeDOSMemory( int descriptor )
-+{
-+ free((void *)descriptor);
-+
-+ return (descriptor == 0) ? DPMI_Error : DPMI_Ok;
-+}
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/platform.h jfsw_src_20051009/source/jaudiolib/platform.h
---- jfsw_src_20051009.orig/source/jaudiolib/platform.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/platform.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,60 @@
-+#ifndef _INCLUDE_PLATFORM_H_
-+#define _INCLUDE_PLATFORM_H_
-+
-+#if (!defined __EXPORT__)
-+#define __EXPORT__
-+#endif
-+
-+#if (defined __WATCOMC__)
-+#define snprintf _snprintf
-+#endif
-+
-+static __inline unsigned short _swap16(unsigned short D)
-+{
-+#if PLATFORM_MACOSX
-+ register unsigned short returnValue;
-+ __asm__ volatile("lhbrx %0,0,%1"
-+ : "=r" (returnValue)
-+ : "r" (&D)
-+ );
-+ return returnValue;
-+#else
-+ return((D<<8)|(D>>8));
-+#endif
-+}
-+
-+static __inline unsigned int _swap32(unsigned int D)
-+{
-+#if PLATFORM_MACOSX
-+ register unsigned int returnValue;
-+ __asm__ volatile("lwbrx %0,0,%1"
-+ : "=r" (returnValue)
-+ : "r" (&D)
-+ );
-+ return returnValue;
-+#else
-+ return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
-+#endif
-+}
-+
-+#if PLATFORM_MACOSX
-+#define PLATFORM_BIGENDIAN 1
-+#define BUILDSWAP_INTEL16(x) _swap16(x)
-+#define BUILDSWAP_INTEL32(x) _swap32(x)
-+#else
-+#if __BYTE_ORDER == __LITTLE_ENDIAN
-+#define PLATFORM_LITTLEENDIAN 1
-+#define BUILDSWAP_INTEL16(x) (x)
-+#define BUILDSWAP_INTEL32(x) (x)
-+#else
-+#define PLATFORM_BIGENDIAN 1
-+#define BUILDSWAP_INTEL16(x) _swap16(x)
-+#define BUILDSWAP_INTEL32(x) _swap32(x)
-+#endif
-+#endif
-+
-+extern int has_altivec; /* PowerPC-specific. */
-+
-+#endif /* !defined _INCLUDE_PLATFORM_H_ */
-+
-+/* end of platform.h ... */
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/sdlmusic.c jfsw_src_20051009/source/jaudiolib/sdlmusic.c
---- jfsw_src_20051009.orig/source/jaudiolib/sdlmusic.c 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/sdlmusic.c 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,480 @@
-+/*
-+Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
-+Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
-+
-+*/
-+/*
-+ * A reimplementation of Jim Dose's FX_MAN routines, using SDL_mixer 1.2.
-+ * Whee. FX_MAN is also known as the "Apogee Sound System", or "ASS" for
-+ * short. How strangely appropriate that seems.
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <assert.h>
-+
-+#include "types.h"
-+#include "file_lib.h"
-+#include "compat.h"
-+#include "cache1d.h"
-+
-+#ifndef MAX_PATH
-+#define MAX_PATH 256
-+#endif
-+
-+#if (defined __WATCOMC__)
-+// This is probably out of date. --ryan.
-+#include "dukesnd_watcom.h"
-+#endif
-+
-+#if (!defined __WATCOMC__)
-+#define cdecl
-+#endif
-+
-+#include "SDL.h"
-+#include "SDL_mixer.h"
-+#include "music.h"
-+
-+#define __FX_TRUE (1 == 1)
-+#define __FX_FALSE (!__FX_TRUE)
-+
-+#define DUKESND_DEBUG "DUKESND_DEBUG"
-+
-+#ifndef min
-+#define min(a, b) (((a) < (b)) ? (a) : (b))
-+#endif
-+
-+#ifndef max
-+#define max(a, b) (((a) > (b)) ? (a) : (b))
-+#endif
-+
-+void GetUnixPathFromEnvironment( char *fullname, int32 length, const char *filename );
-+
-+int MUSIC_ErrorCode = MUSIC_Ok;
-+
-+static char warningMessage[80];
-+static char errorMessage[80];
-+static int fx_initialized = 0;
-+static int numChannels = MIX_CHANNELS;
-+static void (*callback)(unsigned long);
-+static int reverseStereo = 0;
-+static int reverbDelay = 256;
-+static int reverbLevel = 0;
-+static int fastReverb = 0;
-+static FILE *debug_file = NULL;
-+static int initialized_debugging = 0;
-+static int mixerIsStereo = 1;
-+
-+// This gets called all over the place for information and debugging messages.
-+// If the user set the DUKESND_DEBUG environment variable, the messages
-+// go to the file that is specified in that variable. Otherwise, they
-+// are ignored for the expense of the function call. If DUKESND_DEBUG is
-+// set to "-" (without the quotes), then the output goes to stdout.
-+static void musdebug(const char *fmt, ...)
-+{
-+ va_list ap;
-+
-+ if (debug_file)
-+ {
-+ fprintf(debug_file, "DUKEMUS: ");
-+ va_start(ap, fmt);
-+ vfprintf(debug_file, fmt, ap);
-+ va_end(ap);
-+ fprintf(debug_file, "\n");
-+ fflush(debug_file);
-+ } // if
-+} // musdebug
-+
-+static void init_debugging(void)
-+{
-+ const char *envr;
-+
-+ if (initialized_debugging)
-+ return;
-+
-+ envr = getenv(DUKESND_DEBUG);
-+ if (envr != NULL)
-+ {
-+ if (strcmp(envr, "-") == 0)
-+ debug_file = stdout;
-+ else
-+ debug_file = fopen(envr, "w");
-+
-+ if (debug_file == NULL)
-+ fprintf(stderr, "DUKESND: -WARNING- Could not open debug file!\n");
-+ else
-+ setbuf(debug_file, NULL);
-+ } // if
-+
-+ initialized_debugging = 1;
-+} // init_debugging
-+
-+static void setWarningMessage(const char *msg)
-+{
-+ strncpy(warningMessage, msg, sizeof (warningMessage));
-+ // strncpy() doesn't add the null char if there isn't room...
-+ warningMessage[sizeof (warningMessage) - 1] = '\0';
-+ musdebug("Warning message set to [%s].", warningMessage);
-+} // setErrorMessage
-+
-+
-+static void setErrorMessage(const char *msg)
-+{
-+ strncpy(errorMessage, msg, sizeof (errorMessage));
-+ // strncpy() doesn't add the null char if there isn't room...
-+ errorMessage[sizeof (errorMessage) - 1] = '\0';
-+ musdebug("Error message set to [%s].", errorMessage);
-+} // setErrorMessage
-+
-+// The music functions...
-+
-+char *MUSIC_ErrorString(int ErrorNumber)
-+{
-+ switch (ErrorNumber)
-+ {
-+ case MUSIC_Warning:
-+ return(warningMessage);
-+
-+ case MUSIC_Error:
-+ return(errorMessage);
-+
-+ case MUSIC_Ok:
-+ return("OK; no error.");
-+
-+ case MUSIC_ASSVersion:
-+ return("Incorrect sound library version.");
-+
-+ case MUSIC_SoundCardError:
-+ return("General sound card error.");
-+
-+ case MUSIC_InvalidCard:
-+ return("Invalid sound card.");
-+
-+ case MUSIC_MidiError:
-+ return("MIDI error.");
-+
-+ case MUSIC_MPU401Error:
-+ return("MPU401 error.");
-+
-+ case MUSIC_TaskManError:
-+ return("Task Manager error.");
-+
-+ //case MUSIC_FMNotDetected:
-+ // return("FM not detected error.");
-+
-+ case MUSIC_DPMI_Error:
-+ return("DPMI error.");
-+
-+ default:
-+ return("Unknown error.");
-+ } // switch
-+
-+ assert(0); // shouldn't hit this point.
-+ return(NULL);
-+} // MUSIC_ErrorString
-+
-+
-+static int music_initialized = 0;
-+static int music_context = 0;
-+static int music_loopflag = MUSIC_PlayOnce;
-+static char *music_songdata = NULL;
-+static Mix_Music *music_musicchunk = NULL;
-+
-+int MUSIC_Init(int SoundCard, int Address)
-+{
-+ init_debugging();
-+
-+ musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address);
-+
-+ if (music_initialized)
-+ {
-+ setErrorMessage("Music system is already initialized.");
-+ return(MUSIC_Error);
-+ } // if
-+
-+ SoundCard = 1;
-+
-+ music_initialized = 1;
-+ return(MUSIC_Ok);
-+} // MUSIC_Init
-+
-+
-+int MUSIC_Shutdown(void)
-+{
-+ musdebug("shutting down sound subsystem.");
-+
-+ MUSIC_StopSong();
-+ music_context = 0;
-+ music_initialized = 0;
-+ music_loopflag = MUSIC_PlayOnce;
-+ return(MUSIC_Ok);
-+} // MUSIC_Shutdown
-+
-+
-+void MUSIC_SetMaxFMMidiChannel(int channel)
-+{
-+ musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);
-+} // MUSIC_SetMaxFMMidiChannel
-+
-+
-+void MUSIC_SetVolume(int volume)
-+{
-+ volume = max( 0, volume );
-+ volume = min( volume, 255 );
-+
-+ Mix_VolumeMusic(volume >> 1); // convert 0-255 to 0-128.
-+} // MUSIC_SetVolume
-+
-+
-+void MUSIC_SetMidiChannelVolume(int channel, int volume)
-+{
-+ musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);
-+} // MUSIC_SetMidiChannelVolume
-+
-+
-+void MUSIC_ResetMidiChannelVolumes(void)
-+{
-+ musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");
-+} // MUSIC_ResetMidiChannelVolumes
-+
-+
-+int MUSIC_GetVolume(void)
-+{
-+ return(Mix_VolumeMusic(-1) << 1); // convert 0-128 to 0-255.
-+} // MUSIC_GetVolume
-+
-+
-+void MUSIC_SetLoopFlag(int loopflag)
-+{
-+ music_loopflag = loopflag;
-+} // MUSIC_SetLoopFlag
-+
-+
-+int MUSIC_SongPlaying(void)
-+{
-+ return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);
-+} // MUSIC_SongPlaying
-+
-+
-+void MUSIC_Continue(void)
-+{
-+ if (Mix_PausedMusic())
-+ Mix_ResumeMusic();
-+ else if (music_songdata)
-+ MUSIC_PlaySong(music_songdata, MUSIC_PlayOnce);
-+} // MUSIC_Continue
-+
-+
-+void MUSIC_Pause(void)
-+{
-+ Mix_PauseMusic();
-+} // MUSIC_Pause
-+
-+
-+int MUSIC_StopSong(void)
-+{
-+ //if (!fx_initialized)
-+ if (!Mix_QuerySpec(NULL, NULL, NULL))
-+ {
-+ setErrorMessage("Need FX system initialized, too. Sorry.");
-+ return(MUSIC_Error);
-+ } // if
-+
-+ if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
-+ Mix_HaltMusic();
-+
-+ if (music_musicchunk)
-+ Mix_FreeMusic(music_musicchunk);
-+
-+ music_songdata = NULL;
-+ music_musicchunk = NULL;
-+ return(MUSIC_Ok);
-+} // MUSIC_StopSong
-+
-+
-+int MUSIC_PlaySong(unsigned char *song, int loopflag)
-+{
-+ //SDL_RWops *rw;
-+
-+ MUSIC_StopSong();
-+
-+ music_songdata = song;
-+
-+ // !!! FIXME: This could be a problem...SDL/SDL_mixer wants a RWops, which
-+ // !!! FIXME: is an i/o abstraction. Since we already have the MIDI data
-+ // !!! FIXME: in memory, we fake it with a memory-based RWops. None of
-+ // !!! FIXME: this is a problem, except the RWops wants to know how big
-+ // !!! FIXME: its memory block is (so it can do things like seek on an
-+ // !!! FIXME: offset from the end of the block), and since we don't have
-+ // !!! FIXME: this information, we have to give it SOMETHING.
-+
-+ /* !!! ARGH! There's no LoadMUS_RW ?!
-+ rw = SDL_RWFromMem((void *) song, (10 * 1024) * 1024); // yikes.
-+ music_musicchunk = Mix_LoadMUS_RW(rw);
-+ Mix_PlayMusic(music_musicchunk, (loopflag == MUSIC_PlayOnce) ? 0 : -1);
-+ */
-+
-+ return(MUSIC_Ok);
-+} // MUSIC_PlaySong
-+
-+
-+extern char ApogeePath[256] = "/tmp/";
-+
-+// Duke3D-specific. --ryan.
-+void PlayMusic(char *_filename)
-+{
-+ //char filename[MAX_PATH];
-+ //strcpy(filename, _filename);
-+ //FixFilePath(filename);
-+
-+ char filename[MAX_PATH];
-+ long handle;
-+ long size;
-+ void *song;
-+ long rc;
-+
-+ MUSIC_StopSong();
-+
-+ // Read from a groupfile, write it to disk so SDL_mixer can read it.
-+ // Lame. --ryan.
-+ handle = kopen4load(_filename, 0);
-+ if (handle == -1)
-+ return;
-+
-+ size = kfilelength(handle);
-+ if (size == -1)
-+ {
-+ kclose(handle);
-+ return;
-+ } // if
-+
-+ song = malloc(size);
-+ if (song == NULL)
-+ {
-+ kclose(handle);
-+ return;
-+ } // if
-+
-+ rc = kread(handle, song, size);
-+ kclose(handle);
-+ if (rc != size)
-+ {
-+ free(song);
-+ return;
-+ } // if
-+
-+ // save the file somewhere, so SDL_mixer can load it
-+ GetUnixPathFromEnvironment(filename, MAX_PATH, "tmpsong.mid");
-+ handle = SafeOpenWrite(filename, filetype_binary);
-+
-+ SafeWrite(handle, song, size);
-+ close(handle);
-+ free(song);
-+
-+ //music_songdata = song;
-+
-+ music_musicchunk = Mix_LoadMUS(filename);
-+ if (music_musicchunk != NULL)
-+ {
-+ // !!! FIXME: I set the music to loop. Hope that's okay. --ryan.
-+ Mix_PlayMusic(music_musicchunk, -1);
-+ } // if
-+}
-+
-+
-+void MUSIC_SetContext(int context)
-+{
-+ musdebug("STUB ... MUSIC_SetContext().\n");
-+ music_context = context;
-+} // MUSIC_SetContext
-+
-+
-+int MUSIC_GetContext(void)
-+{
-+ return(music_context);
-+} // MUSIC_GetContext
-+
-+
-+void MUSIC_SetSongTick(unsigned long PositionInTicks)
-+{
-+ musdebug("STUB ... MUSIC_SetSongTick().\n");
-+} // MUSIC_SetSongTick
-+
-+
-+void MUSIC_SetSongTime(unsigned long milliseconds)
-+{
-+ musdebug("STUB ... MUSIC_SetSongTime().\n");
-+}// MUSIC_SetSongTime
-+
-+
-+void MUSIC_SetSongPosition(int measure, int beat, int tick)
-+{
-+ musdebug("STUB ... MUSIC_SetSongPosition().\n");
-+} // MUSIC_SetSongPosition
-+
-+
-+void MUSIC_GetSongPosition(songposition *pos)
-+{
-+ musdebug("STUB ... MUSIC_GetSongPosition().\n");
-+} // MUSIC_GetSongPosition
-+
-+
-+void MUSIC_GetSongLength(songposition *pos)
-+{
-+ musdebug("STUB ... MUSIC_GetSongLength().\n");
-+} // MUSIC_GetSongLength
-+
-+
-+int MUSIC_FadeVolume(int tovolume, int milliseconds)
-+{
-+ Mix_FadeOutMusic(milliseconds);
-+ return(MUSIC_Ok);
-+} // MUSIC_FadeVolume
-+
-+
-+int MUSIC_FadeActive(void)
-+{
-+ return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);
-+} // MUSIC_FadeActive
-+
-+
-+void MUSIC_StopFade(void)
-+{
-+ musdebug("STUB ... MUSIC_StopFade().\n");
-+} // MUSIC_StopFade
-+
-+
-+void MUSIC_RerouteMidiChannel(int channel, int cdecl (*function)( int event, int c1, int c2 ))
-+{
-+ musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");
-+} // MUSIC_RerouteMidiChannel
-+
-+
-+void MUSIC_RegisterTimbreBank(unsigned char *timbres)
-+{
-+ musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");
-+} // MUSIC_RegisterTimbreBank
-+
-+
-+void MUSIC_Update(void)
-+{
-+}
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/unixglob.c jfsw_src_20051009/source/jaudiolib/unixglob.c
---- jfsw_src_20051009.orig/source/jaudiolib/unixglob.c 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/unixglob.c 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,152 @@
-+/*
-+Copyright (C) 2003-2004 Ryan C. Gordon. and James Bentler
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+Originally written by Ryan C. Gordon. (icculus@clutteredmind.org)
-+Adapted to work with JonoF's port by James Bentler (bentler@cs.umn.edu)
-+
-+*/
-+
-+static char ApogeePath[256] = "/tmp/";
-+
-+#define PATH_SEP_CHAR '/'
-+#define PATH_SEP_STR "/"
-+#define ROOTDIR "/"
-+#define CURDIR "./"
-+
-+#include "types.h"
-+#include "compat.h"
-+#include <dirent.h>
-+#include <errno.h>
-+
-+#define Error printf
-+
-+#ifndef MAX_PATH
-+#define MAX_PATH 256
-+#endif
-+
-+void FixFilePath(char *filename)
-+{
-+ char *ptr;
-+ char *lastsep = filename;
-+
-+ if ((!filename) || (*filename == '\0'))
-+ return;
-+
-+ if (access(filename, F_OK) == 0) /* File exists; we're good to go. */
-+ return;
-+
-+ for (ptr = filename; 1; ptr++)
-+ {
-+ if (*ptr == '\\')
-+ *ptr = PATH_SEP_CHAR;
-+
-+ if ((*ptr == PATH_SEP_CHAR) || (*ptr == '\0'))
-+ {
-+ char pch = *ptr;
-+ struct dirent *dent = NULL;
-+ DIR *dir;
-+
-+ if ((pch == PATH_SEP_CHAR) && (*(ptr + 1) == '\0'))
-+ return; /* eos is pathsep; we're done. */
-+
-+ if (lastsep == ptr)
-+ continue; /* absolute path; skip to next one. */
-+
-+ *ptr = '\0';
-+ if (lastsep == filename) {
-+ dir = opendir((*lastsep == PATH_SEP_CHAR) ? ROOTDIR : CURDIR);
-+
-+ if (*lastsep == PATH_SEP_CHAR) {
-+ lastsep++;
-+ }
-+ }
-+ else
-+ {
-+ *lastsep = '\0';
-+ dir = opendir(filename);
-+ *lastsep = PATH_SEP_CHAR;
-+ lastsep++;
-+ }
-+
-+ if (dir == NULL)
-+ {
-+ *ptr = PATH_SEP_CHAR;
-+ return; /* maybe dir doesn't exist? give up. */
-+ }
-+
-+ while ((dent = readdir(dir)) != NULL)
-+ {
-+ if (strcasecmp(dent->d_name, lastsep) == 0)
-+ {
-+ /* found match; replace it. */
-+ strcpy(lastsep, dent->d_name);
-+ break;
-+ }
-+ }
-+
-+ closedir(dir);
-+ *ptr = pch;
-+ lastsep = ptr;
-+
-+ if (dent == NULL)
-+ return; /* no match. oh well. */
-+
-+ if (pch == '\0') /* eos? */
-+ return;
-+ }
-+ }
-+}
-+
-+int32 SafeOpenWrite (const char *_filename, int32 filetype)
-+{
-+ int handle;
-+ char filename[MAX_PATH];
-+ strncpy(filename, _filename, sizeof (filename));
-+ filename[sizeof (filename) - 1] = '\0';
-+ FixFilePath(filename);
-+
-+ handle = open(filename,O_RDWR | O_BINARY | O_CREAT | O_TRUNC
-+ , S_IREAD | S_IWRITE);
-+
-+ if (handle == -1)
-+ Error ("Error opening %s: %s",filename,strerror(errno));
-+
-+ return handle;
-+}
-+
-+
-+void SafeWrite (int32 handle, void *buffer, int32 count)
-+{
-+ unsigned iocount;
-+
-+ while (count)
-+ {
-+ iocount = count > 0x8000 ? 0x8000 : count;
-+ if (write (handle,buffer,iocount) != (int)iocount)
-+ Error ("File write failure writing %ld bytes",count);
-+ buffer = (void *)( (byte *)buffer + iocount );
-+ count -= iocount;
-+ }
-+}
-+
-+
-+
-+void GetUnixPathFromEnvironment( char *fullname, int32 length, const char *filename )
-+{
-+ snprintf(fullname, length-1, "%s%s", ApogeePath, filename);
-+}
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/unixpitch.c jfsw_src_20051009/source/jaudiolib/unixpitch.c
---- jfsw_src_20051009.orig/source/jaudiolib/unixpitch.c 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/unixpitch.c 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,212 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+You should have received a copy of the GNU General Public License
-+along with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+/**********************************************************************
-+ module: PITCH.C
-+
-+ author: James R. Dose
-+ date: June 14, 1993
-+
-+ Routines for pitch scaling.
-+
-+ (c) Copyright 1993 James R. Dose. All Rights Reserved.
-+**********************************************************************/
-+
-+#include <stdlib.h>
-+//#include <math.h>
-+#include "dpmi.h"
-+#include "standard.h"
-+#include "pitch.h"
-+
-+#define MAXDETUNE 25
-+
-+static unsigned long PitchTable[ 12 ][ MAXDETUNE ] =
-+ {
-+ { 0x10000, 0x10097, 0x1012f, 0x101c7, 0x10260, 0x102f9, 0x10392, 0x1042c,
-+ 0x104c6, 0x10561, 0x105fb, 0x10696, 0x10732, 0x107ce, 0x1086a, 0x10907,
-+ 0x109a4, 0x10a41, 0x10adf, 0x10b7d, 0x10c1b, 0x10cba, 0x10d59, 0x10df8,
-+ 0x10e98 },
-+ { 0x10f38, 0x10fd9, 0x1107a, 0x1111b, 0x111bd, 0x1125f, 0x11302, 0x113a5,
-+ 0x11448, 0x114eb, 0x1158f, 0x11634, 0x116d8, 0x1177e, 0x11823, 0x118c9,
-+ 0x1196f, 0x11a16, 0x11abd, 0x11b64, 0x11c0c, 0x11cb4, 0x11d5d, 0x11e06,
-+ 0x11eaf },
-+ { 0x11f59, 0x12003, 0x120ae, 0x12159, 0x12204, 0x122b0, 0x1235c, 0x12409,
-+ 0x124b6, 0x12563, 0x12611, 0x126bf, 0x1276d, 0x1281c, 0x128cc, 0x1297b,
-+ 0x12a2b, 0x12adc, 0x12b8d, 0x12c3e, 0x12cf0, 0x12da2, 0x12e55, 0x12f08,
-+ 0x12fbc },
-+ { 0x1306f, 0x13124, 0x131d8, 0x1328d, 0x13343, 0x133f9, 0x134af, 0x13566,
-+ 0x1361d, 0x136d5, 0x1378d, 0x13846, 0x138fe, 0x139b8, 0x13a72, 0x13b2c,
-+ 0x13be6, 0x13ca1, 0x13d5d, 0x13e19, 0x13ed5, 0x13f92, 0x1404f, 0x1410d,
-+ 0x141cb },
-+ { 0x1428a, 0x14349, 0x14408, 0x144c8, 0x14588, 0x14649, 0x1470a, 0x147cc,
-+ 0x1488e, 0x14951, 0x14a14, 0x14ad7, 0x14b9b, 0x14c5f, 0x14d24, 0x14dea,
-+ 0x14eaf, 0x14f75, 0x1503c, 0x15103, 0x151cb, 0x15293, 0x1535b, 0x15424,
-+ 0x154ee },
-+ { 0x155b8, 0x15682, 0x1574d, 0x15818, 0x158e4, 0x159b0, 0x15a7d, 0x15b4a,
-+ 0x15c18, 0x15ce6, 0x15db4, 0x15e83, 0x15f53, 0x16023, 0x160f4, 0x161c5,
-+ 0x16296, 0x16368, 0x1643a, 0x1650d, 0x165e1, 0x166b5, 0x16789, 0x1685e,
-+ 0x16934 },
-+ { 0x16a09, 0x16ae0, 0x16bb7, 0x16c8e, 0x16d66, 0x16e3e, 0x16f17, 0x16ff1,
-+ 0x170ca, 0x171a5, 0x17280, 0x1735b, 0x17437, 0x17513, 0x175f0, 0x176ce,
-+ 0x177ac, 0x1788a, 0x17969, 0x17a49, 0x17b29, 0x17c09, 0x17cea, 0x17dcc,
-+ 0x17eae },
-+ { 0x17f91, 0x18074, 0x18157, 0x1823c, 0x18320, 0x18406, 0x184eb, 0x185d2,
-+ 0x186b8, 0x187a0, 0x18888, 0x18970, 0x18a59, 0x18b43, 0x18c2d, 0x18d17,
-+ 0x18e02, 0x18eee, 0x18fda, 0x190c7, 0x191b5, 0x192a2, 0x19391, 0x19480,
-+ 0x1956f },
-+ { 0x1965f, 0x19750, 0x19841, 0x19933, 0x19a25, 0x19b18, 0x19c0c, 0x19d00,
-+ 0x19df4, 0x19ee9, 0x19fdf, 0x1a0d5, 0x1a1cc, 0x1a2c4, 0x1a3bc, 0x1a4b4,
-+ 0x1a5ad, 0x1a6a7, 0x1a7a1, 0x1a89c, 0x1a998, 0x1aa94, 0x1ab90, 0x1ac8d,
-+ 0x1ad8b },
-+ { 0x1ae89, 0x1af88, 0x1b088, 0x1b188, 0x1b289, 0x1b38a, 0x1b48c, 0x1b58f,
-+ 0x1b692, 0x1b795, 0x1b89a, 0x1b99f, 0x1baa4, 0x1bbaa, 0x1bcb1, 0x1bdb8,
-+ 0x1bec0, 0x1bfc9, 0x1c0d2, 0x1c1dc, 0x1c2e6, 0x1c3f1, 0x1c4fd, 0x1c609,
-+ 0x1c716 },
-+ { 0x1c823, 0x1c931, 0x1ca40, 0x1cb50, 0x1cc60, 0x1cd70, 0x1ce81, 0x1cf93,
-+ 0x1d0a6, 0x1d1b9, 0x1d2cd, 0x1d3e1, 0x1d4f6, 0x1d60c, 0x1d722, 0x1d839,
-+ 0x1d951, 0x1da69, 0x1db82, 0x1dc9c, 0x1ddb6, 0x1ded1, 0x1dfec, 0x1e109,
-+ 0x1e225 },
-+ { 0x1e343, 0x1e461, 0x1e580, 0x1e6a0, 0x1e7c0, 0x1e8e0, 0x1ea02, 0x1eb24,
-+ 0x1ec47, 0x1ed6b, 0x1ee8f, 0x1efb4, 0x1f0d9, 0x1f1ff, 0x1f326, 0x1f44e,
-+ 0x1f576, 0x1f69f, 0x1f7c9, 0x1f8f3, 0x1fa1e, 0x1fb4a, 0x1fc76, 0x1fda3,
-+ 0x1fed1 }
-+ };
-+
-+
-+//static int PITCH_Installed = FALSE;
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: PITCH_Init
-+
-+ Initializes pitch table.
-+---------------------------------------------------------------------*/
-+/*
-+void PITCH_Init
-+ (
-+ void
-+ )
-+
-+ {
-+ int note;
-+ int detune;
-+
-+ if ( !PITCH_Installed )
-+ {
-+ for( note = 0; note < 12; note++ )
-+ {
-+ for( detune = 0; detune < MAXDETUNE; detune++ )
-+ {
-+ PitchTable[ note ][ detune ] = 0x10000 *
-+ pow( 2, ( note * MAXDETUNE + detune ) / ( 12.0 * MAXDETUNE ) );
-+ }
-+ }
-+
-+ PITCH_Installed = TRUE;
-+ }
-+ }
-+*/
-+
-+/**********************************************************************
-+
-+ Memory locked functions:
-+
-+**********************************************************************/
-+
-+
-+#define PITCH_LockStart PITCH_GetScale
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: PITCH_GetScale
-+
-+ Returns a fixed-point value to scale number the specified amount.
-+---------------------------------------------------------------------*/
-+
-+unsigned long PITCH_GetScale
-+ (
-+ int pitchoffset
-+ )
-+
-+ {
-+ unsigned long scale;
-+ int octaveshift;
-+ int noteshift;
-+ int note;
-+ int detune;
-+
-+// if ( !PITCH_Installed )
-+// {
-+// PITCH_Init();
-+// }
-+
-+ if ( pitchoffset == 0 )
-+ {
-+ return( PitchTable[ 0 ][ 0 ] );
-+ }
-+
-+ noteshift = pitchoffset % 1200;
-+ if ( noteshift < 0 )
-+ {
-+ noteshift += 1200;
-+ }
-+
-+ note = noteshift / 100;
-+ detune = ( noteshift % 100 ) / ( 100 / MAXDETUNE );
-+ octaveshift = ( pitchoffset - noteshift ) / 1200;
-+
-+ if ( detune < 0 )
-+ {
-+ detune += ( 100 / MAXDETUNE );
-+ note--;
-+ if ( note < 0 )
-+ {
-+ note += 12;
-+ octaveshift--;
-+ }
-+ }
-+
-+ scale = PitchTable[ note ][ detune ];
-+
-+ if ( octaveshift < 0 )
-+ {
-+ scale >>= -octaveshift;
-+ }
-+ else
-+ {
-+ scale <<= octaveshift;
-+ }
-+
-+ return( scale );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: PITCH_LockEnd
-+
-+ Used for determining the length of the functions to lock in memory.
-+---------------------------------------------------------------------*/
-+
-+static void PITCH_LockEnd
-+ (
-+ void
-+ )
-+
-+ {
-+ }
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/unixvoc.c jfsw_src_20051009/source/jaudiolib/unixvoc.c
---- jfsw_src_20051009.orig/source/jaudiolib/unixvoc.c 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/unixvoc.c 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,2877 @@
-+/*
-+Copyright (C) 1994-1995 Apogee Software, Ltd.
-+
-+This program is free software; you can redistribute it and/or
-+modify it under the terms of the GNU General Public License
-+as published by the Free Software Foundation; either version 2
-+of the License, or (at your option) any later version.
-+
-+This program is distributed in the hope that it will be useful,
-+but WITHOUT ANY WARRANTY; without even the implied warranty of
-+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-+
-+See the GNU General Public License for more details.
-+
-+ou should have received a copy of the GNU General Public License
-+long with this program; if not, write to the Free Software
-+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-+
-+*/
-+/**********************************************************************
-+ module: MULTIVOC.C
-+
-+ author: James R. Dose
-+ date: December 20, 1993
-+
-+ Routines to provide multichannel digitized sound playback for
-+ Sound Blaster compatible sound cards.
-+
-+ (c) Copyright 1993 James R. Dose. All Rights Reserved.
-+**********************************************************************/
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <time.h>
-+
-+#include "util.h"
-+#include "dpmi.h"
-+#include "usrhooks.h"
-+#include "interrup.h"
-+#include "dma.h"
-+#include "linklist.h"
-+#include "dsl.h"
-+
-+#include "pitch.h"
-+#include "multivoc.h"
-+#include "_multivc.h"
-+#include "debugio.h"
-+
-+// platform.h is from the build engine, but I need the byteswapping macros... --ryan.
-+#include "platform.h"
-+
-+#define RoundFixed( fixedval, bits ) \
-+ ( \
-+ ( \
-+ (fixedval) + ( 1 << ( (bits) - 1 ) )\
-+ ) >> (bits) \
-+ )
-+
-+#define IS_QUIET( ptr ) ( ( void * )( ptr ) == ( void * )&MV_VolumeTable[ 0 ] )
-+
-+static int MV_ReverbLevel;
-+static int MV_ReverbDelay;
-+static VOLUME16 *MV_ReverbTable = NULL;
-+
-+//static signed short MV_VolumeTable[ MV_MaxVolume + 1 ][ 256 ];
-+static signed short MV_VolumeTable[ 63 + 1 ][ 256 ];
-+
-+//static Pan MV_PanTable[ MV_NumPanPositions ][ MV_MaxVolume + 1 ];
-+static Pan MV_PanTable[ MV_NumPanPositions ][ 63 + 1 ];
-+
-+static int MV_Installed = FALSE;
-+static int MV_SoundCard = 1;
-+static int MV_TotalVolume = MV_MaxTotalVolume;
-+static int MV_MaxVoices = 1;
-+static int MV_Recording;
-+
-+static int MV_BufferSize = MixBufferSize;
-+static int MV_BufferLength;
-+
-+static int MV_NumberOfBuffers = NumberOfBuffers;
-+
-+static int MV_MixMode = MONO_8BIT;
-+static int MV_Channels = 1;
-+static int MV_Bits = 8;
-+
-+static int MV_Silence = SILENCE_8BIT;
-+static int MV_SwapLeftRight = FALSE;
-+
-+static int MV_RequestedMixRate;
-+static int MV_MixRate;
-+
-+static int MV_DMAChannel = -1;
-+static int MV_BuffShift;
-+
-+static int MV_TotalMemory;
-+
-+static int MV_BufferDescriptor;
-+static int MV_BufferEmpty[ NumberOfBuffers ];
-+char *MV_MixBuffer[ NumberOfBuffers + 1 ];
-+
-+static VoiceNode *MV_Voices = NULL;
-+
-+static volatile VoiceNode VoiceList;
-+static volatile VoiceNode VoicePool;
-+
-+/*static*/ int MV_MixPage = 0;
-+static int MV_VoiceHandle = MV_MinVoiceHandle;
-+
-+static void ( *MV_CallBackFunc )( unsigned long ) = NULL;
-+static void ( *MV_RecordFunc )( char *ptr, int length ) = NULL;
-+static void ( *MV_MixFunction )( VoiceNode *voice, int buffer );
-+
-+static int MV_MaxVolume = 63;
-+
-+char *MV_HarshClipTable;
-+char *MV_MixDestination;
-+short *MV_LeftVolume;
-+short *MV_RightVolume;
-+int MV_SampleSize = 1;
-+int MV_RightChannelOffset;
-+
-+unsigned long MV_MixPosition;
-+
-+int MV_ErrorCode = MV_Ok;
-+
-+#define MV_SetErrorCode( status ) \
-+ MV_ErrorCode = ( status );
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_ErrorString
-+
-+ Returns a pointer to the error message associated with an error
-+ number. A -1 returns a pointer the current error.
-+---------------------------------------------------------------------*/
-+
-+char *MV_ErrorString
-+ (
-+ int ErrorNumber
-+ )
-+
-+ {
-+ char *ErrorString;
-+
-+ switch( ErrorNumber )
-+ {
-+ case MV_Warning :
-+ case MV_Error :
-+ ErrorString = MV_ErrorString( MV_ErrorCode );
-+ break;
-+
-+ case MV_Ok :
-+ ErrorString = "Multivoc ok.";
-+ break;
-+
-+ case MV_UnsupportedCard :
-+ ErrorString = "Selected sound card is not supported by Multivoc.";
-+ break;
-+
-+ case MV_NotInstalled :
-+ ErrorString = "Multivoc not installed.";
-+ break;
-+
-+ case MV_NoVoices :
-+ ErrorString = "No free voices available to Multivoc.";
-+ break;
-+
-+ case MV_NoMem :
-+ ErrorString = "Out of memory in Multivoc.";
-+ break;
-+
-+ case MV_VoiceNotFound :
-+ ErrorString = "No voice with matching handle found.";
-+ break;
-+
-+ case MV_DPMI_Error :
-+ ErrorString = "DPMI Error in Multivoc.";
-+ break;
-+
-+ case MV_InvalidVOCFile :
-+ ErrorString = "Invalid VOC file passed in to Multivoc.";
-+ break;
-+
-+ case MV_InvalidWAVFile :
-+ ErrorString = "Invalid WAV file passed in to Multivoc.";
-+ break;
-+
-+ case MV_InvalidMixMode :
-+ ErrorString = "Invalid mix mode request in Multivoc.";
-+ break;
-+
-+ case MV_IrqFailure :
-+ ErrorString = "Playback failed, possibly due to an invalid or conflicting IRQ.";
-+ break;
-+
-+ case MV_DMAFailure :
-+ ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel.";
-+ break;
-+
-+ case MV_DMA16Failure :
-+ ErrorString = "Playback failed, possibly due to an invalid or conflicting DMA channel. \n"
-+ "Make sure the 16-bit DMA channel is correct.";
-+ break;
-+
-+ case MV_NullRecordFunction :
-+ ErrorString = "Null record function passed to MV_StartRecording.";
-+ break;
-+
-+ default :
-+ ErrorString = "Unknown Multivoc error code.";
-+ break;
-+ }
-+
-+ return( ErrorString );
-+ }
-+
-+
-+/**********************************************************************
-+
-+ Memory locked functions:
-+
-+**********************************************************************/
-+
-+
-+#define MV_LockStart MV_Mix
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_Mix
-+
-+ Mixes the sound into the buffer.
-+---------------------------------------------------------------------*/
-+
-+static void MV_Mix
-+ (
-+ VoiceNode *voice,
-+ int buffer
-+ )
-+
-+ {
-+ char *start;
-+ int length;
-+ long voclength;
-+ unsigned long position;
-+ unsigned long rate;
-+ unsigned long FixedPointBufferSize;
-+
-+ if ( ( voice->length == 0 ) &&
-+ ( voice->GetSound != NULL ) &&
-+ ( voice->GetSound( voice ) != KeepPlaying ) )
-+ {
-+ return;
-+ }
-+
-+ length = MixBufferSize;
-+ FixedPointBufferSize = voice->FixedPointBufferSize;
-+
-+ MV_MixDestination = MV_MixBuffer[ buffer ];
-+ MV_LeftVolume = voice->LeftVolume;
-+ MV_RightVolume = voice->RightVolume;
-+
-+ if ( ( MV_Channels == 2 ) && ( IS_QUIET( MV_LeftVolume ) ) )
-+ {
-+ MV_LeftVolume = MV_RightVolume;
-+ MV_MixDestination += MV_RightChannelOffset;
-+ }
-+
-+ // Add this voice to the mix
-+ while( length > 0 )
-+ {
-+ start = voice->sound;
-+ rate = voice->RateScale;
-+ position = voice->position;
-+
-+ // Check if the last sample in this buffer would be
-+ // beyond the length of the sample block
-+ if ( ( position + FixedPointBufferSize ) >= voice->length )
-+ {
-+ if ( position < voice->length )
-+ {
-+ voclength = ( voice->length - position + rate - 1 ) / rate;
-+ }
-+ else
-+ {
-+ voice->GetSound( voice );
-+ return;
-+ }
-+ }
-+ else
-+ {
-+ voclength = length;
-+ }
-+
-+ voice->mix( position, rate, start, voclength );
-+
-+ if ( voclength & 1 )
-+ {
-+ MV_MixPosition += rate;
-+ voclength -= 1;
-+ }
-+ voice->position = MV_MixPosition;
-+
-+ length -= voclength;
-+
-+ if ( voice->position >= voice->length )
-+ {
-+ // Get the next block of sound
-+ if ( voice->GetSound( voice ) != KeepPlaying )
-+ {
-+ return;
-+ }
-+
-+ if ( length > 0 )
-+ {
-+ // Get the position of the last sample in the buffer
-+ FixedPointBufferSize = voice->RateScale * ( length - 1 );
-+ }
-+ }
-+ }
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayVoice
-+
-+ Adds a voice to the play list.
-+---------------------------------------------------------------------*/
-+
-+void MV_PlayVoice
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ unsigned flags;
-+
-+ flags = DisableInterrupts();
-+ LL_SortedInsertion( &VoiceList, voice, prev, next, VoiceNode, priority );
-+
-+ RestoreInterrupts( flags );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_StopVoice
-+
-+ Removes the voice from the play list and adds it to the free list.
-+---------------------------------------------------------------------*/
-+
-+void MV_StopVoice
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ unsigned flags;
-+
-+ flags = DisableInterrupts();
-+
-+ // move the voice from the play list to the free list
-+ LL_Remove( voice, next, prev );
-+ LL_Add( (VoiceNode *)&VoicePool, voice, next, prev );
-+
-+ RestoreInterrupts( flags );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_ServiceVoc
-+
-+ Starts playback of the waiting buffer and mixes the next one.
-+---------------------------------------------------------------------*/
-+
-+// static int backcolor = 1;
-+
-+static int MV_ServiceVoc(int dummy_arg)
-+ {
-+ VoiceNode *voice;
-+ VoiceNode *next;
-+ char *buffer;
-+
-+ // Toggle which buffer we'll mix next
-+ MV_MixPage++;
-+ if ( MV_MixPage >= MV_NumberOfBuffers )
-+ {
-+ MV_MixPage -= MV_NumberOfBuffers;
-+ }
-+
-+ if ( MV_ReverbLevel == 0 )
-+ {
-+ // Initialize buffer
-+ //Commented out so that the buffer is always cleared.
-+ //This is so the guys at Echo Speech can mix into the
-+ //buffer even when no sounds are playing.
-+ //if ( !MV_BufferEmpty[ MV_MixPage ] )
-+ {
-+ ClearBuffer_DW( MV_MixBuffer[ MV_MixPage ], MV_Silence, MV_BufferSize >> 2 );
-+ MV_BufferEmpty[ MV_MixPage ] = TRUE;
-+ }
-+ }
-+ else
-+ {
-+ char *end;
-+ char *source;
-+ char *dest;
-+ int count;
-+ int length;
-+
-+ end = MV_MixBuffer[ 0 ] + MV_BufferLength;;
-+ dest = MV_MixBuffer[ MV_MixPage ];
-+ source = MV_MixBuffer[ MV_MixPage ] - MV_ReverbDelay;
-+ if ( source < MV_MixBuffer[ 0 ] )
-+ {
-+ source += MV_BufferLength;
-+ }
-+
-+ length = MV_BufferSize;
-+ while( length > 0 )
-+ {
-+ count = length;
-+ if ( source + count > end )
-+ {
-+ count = end - source;
-+ }
-+
-+ if ( MV_Bits == 16 )
-+ {
-+ if ( MV_ReverbTable != NULL )
-+ MV_16BitReverb( source, dest, (const VOLUME16 *)MV_ReverbTable, count / 2 );
-+ else
-+ MV_16BitReverbFast( source, dest, count / 2, MV_ReverbLevel );
-+ }
-+ else
-+ {
-+ if ( MV_ReverbTable != NULL )
-+ MV_8BitReverb( source, dest, (const VOLUME16 *)MV_ReverbTable, count );
-+ else
-+ MV_8BitReverbFast( source, dest, count, MV_ReverbLevel );
-+ }
-+
-+ // if we go through the loop again, it means that we've wrapped around the buffer
-+ source = MV_MixBuffer[ 0 ];
-+ dest += count;
-+ length -= count;
-+ }
-+ }
-+
-+ // Play any waiting voices
-+ for( voice = VoiceList.next; voice != &VoiceList; voice = next )
-+ {
-+// if ( ( voice < &MV_Voices[ 0 ] ) || ( voice > &MV_Voices[ 8 ] ) )
-+// {
-+// SetBorderColor(backcolor++);
-+// break;
-+// }
-+
-+ MV_BufferEmpty[ MV_MixPage ] = FALSE;
-+
-+ if (MV_MixFunction != NULL)
-+ MV_MixFunction( voice, MV_MixPage );
-+
-+ next = voice->next;
-+
-+ // Is this voice done?
-+ if ( !voice->Playing )
-+ {
-+ MV_StopVoice( voice );
-+
-+ if ( MV_CallBackFunc )
-+ {
-+ MV_CallBackFunc( voice->callbackval );
-+ }
-+ }
-+ }
-+ }
-+
-+
-+int leftpage = -1;
-+int rightpage = -1;
-+
-+void MV_ServiceGus( char **ptr, unsigned long *length )
-+ {
-+ if ( leftpage == MV_MixPage )
-+ {
-+ MV_ServiceVoc(0);
-+ }
-+
-+ leftpage = MV_MixPage;
-+
-+ *ptr = MV_MixBuffer[ MV_MixPage ];
-+ *length = MV_BufferSize;
-+ }
-+
-+void MV_ServiceRightGus( char **ptr, unsigned long *length )
-+ {
-+ if ( rightpage == MV_MixPage )
-+ {
-+ MV_ServiceVoc(0);
-+ }
-+
-+ rightpage = MV_MixPage;
-+
-+ *ptr = MV_MixBuffer[ MV_MixPage ] + MV_RightChannelOffset;
-+ *length = MV_BufferSize;
-+ }
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetNextVOCBlock
-+
-+ Interperate the information of a VOC format sound file.
-+---------------------------------------------------------------------*/
-+static __inline unsigned int get_le32(void *p0)
-+{
-+ //unsigned char *p = p0;
-+ //return p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24);
-+ unsigned int val = *((unsigned int *) p0);
-+ return(BUILDSWAP_INTEL32(val));
-+}
-+
-+static __inline unsigned int get_le16(void *p0)
-+{
-+ //unsigned char *p = p0;
-+ //return p[0] | (p[1]<<8);
-+ unsigned short val = *((unsigned short *) p0);
-+ return( (unsigned int) (BUILDSWAP_INTEL16(val)) );
-+}
-+
-+playbackstatus MV_GetNextVOCBlock
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ unsigned char *ptr;
-+ int blocktype=0;
-+ int lastblocktype=0;
-+ unsigned long blocklength=0l;
-+ unsigned long samplespeed=0l;
-+ unsigned int tc=0;
-+ int packtype=0;
-+ int voicemode=0;
-+ int done=0;
-+ unsigned BitsPerSample;
-+ unsigned Channels;
-+ unsigned Format;
-+
-+ if ( voice->BlockLength > 0 )
-+ {
-+ voice->position -= voice->length;
-+ voice->sound += voice->length >> 16;
-+ if ( voice->bits == 16 )
-+ {
-+ voice->sound += voice->length >> 16;
-+ }
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+ return( KeepPlaying );
-+ }
-+
-+ if ( ( voice->length > 0 ) && ( voice->LoopEnd != NULL ) &&
-+ ( voice->LoopStart != NULL ) )
-+ {
-+ voice->BlockLength = voice->LoopSize;
-+ voice->sound = voice->LoopStart;
-+ voice->position = 0;
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+ return( KeepPlaying );
-+ }
-+
-+ ptr = ( unsigned char * )voice->NextBlock;
-+
-+ voice->Playing = TRUE;
-+
-+ voicemode = 0;
-+ lastblocktype = 0;
-+ packtype = 0;
-+
-+ done = FALSE;
-+ while( !done )
-+ {
-+ // Stop playing if we get a NULL pointer
-+ if ( ptr == NULL )
-+ {
-+ voice->Playing = FALSE;
-+ done = TRUE;
-+ break;
-+ }
-+
-+ {
-+ unsigned tmp = get_le32(ptr);
-+ blocktype = tmp&255;
-+ blocklength = tmp>>8;
-+ }
-+ ptr += 4;
-+
-+ switch( blocktype )
-+ {
-+ case 0 :
-+ // End of data
-+ if ( ( voice->LoopStart == NULL ) ||
-+ ( (unsigned char *)voice->LoopStart >= ( ptr - 4 ) ) )
-+ {
-+ voice->Playing = FALSE;
-+ done = TRUE;
-+ }
-+ else
-+ {
-+ voice->BlockLength = ( ptr - 4 ) - (unsigned char *)voice->LoopStart;
-+ voice->sound = voice->LoopStart;
-+ voice->position = 0;
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+ return( KeepPlaying );
-+ }
-+ break;
-+
-+ case 1 :
-+ // Sound data block
-+ voice->bits = 8;
-+ if ( lastblocktype != 8 )
-+ {
-+ tc = ( unsigned int )*ptr << 8;
-+ packtype = *( ptr + 1 );
-+ }
-+
-+ ptr += 2;
-+ blocklength -= 2;
-+
-+ samplespeed = 256000000L / ( 65536 - tc );
-+
-+ // Skip packed or stereo data
-+ if ( ( packtype != 0 ) || ( voicemode != 0 ) )
-+ {
-+ ptr += blocklength;
-+ }
-+ else
-+ {
-+ done = TRUE;
-+ }
-+ voicemode = 0;
-+ break;
-+
-+ case 2 :
-+ // Sound continuation block
-+ samplespeed = voice->SamplingRate;
-+ done = TRUE;
-+ break;
-+
-+ case 3 :
-+ // Silence
-+ // Not implimented.
-+ ptr += blocklength;
-+ break;
-+
-+ case 4 :
-+ // Marker
-+ // Not implimented.
-+ ptr += blocklength;
-+ break;
-+
-+ case 5 :
-+ // ASCII string
-+ // Not implimented.
-+ ptr += blocklength;
-+ break;
-+
-+ case 6 :
-+ // Repeat begin
-+ if ( voice->LoopEnd == NULL )
-+ {
-+ voice->LoopCount = get_le16(ptr);
-+ voice->LoopStart = ptr + blocklength;
-+ }
-+ ptr += blocklength;
-+ break;
-+
-+ case 7 :
-+ // Repeat end
-+ ptr += blocklength;
-+ if ( lastblocktype == 6 )
-+ {
-+ voice->LoopCount = 0;
-+ }
-+ else
-+ {
-+ if ( ( voice->LoopCount > 0 ) && ( voice->LoopStart != NULL ) )
-+ {
-+ ptr = voice->LoopStart;
-+ if ( voice->LoopCount < 0xffff )
-+ {
-+ voice->LoopCount--;
-+ if ( voice->LoopCount == 0 )
-+ {
-+ voice->LoopStart = NULL;
-+ }
-+ }
-+ }
-+ }
-+ break;
-+
-+ case 8 :
-+ // Extended block
-+ voice->bits = 8;
-+ tc = get_le16(ptr);
-+ packtype = *( ptr + 2 );
-+ voicemode = *( ptr + 3 );
-+ ptr += blocklength;
-+ break;
-+
-+ case 9 :
-+ // New sound data block
-+ samplespeed = get_le32(ptr);
-+ BitsPerSample = ptr[4];
-+ Channels = ptr[5];
-+ Format = get_le16(ptr+6);
-+
-+ if ( ( BitsPerSample == 8 ) && ( Channels == 1 ) &&
-+ ( Format == VOC_8BIT ) )
-+ {
-+ ptr += 12;
-+ blocklength -= 12;
-+ voice->bits = 8;
-+ done = TRUE;
-+ }
-+ else if ( ( BitsPerSample == 16 ) && ( Channels == 1 ) &&
-+ ( Format == VOC_16BIT ) )
-+ {
-+ ptr += 12;
-+ blocklength -= 12;
-+ voice->bits = 16;
-+ done = TRUE;
-+ }
-+ else
-+ {
-+ ptr += blocklength;
-+ }
-+ break;
-+
-+ default :
-+ // Unknown data. Probably not a VOC file.
-+ voice->Playing = FALSE;
-+ done = TRUE;
-+ break;
-+ }
-+
-+ lastblocktype = blocktype;
-+ }
-+
-+ if ( voice->Playing )
-+ {
-+ voice->NextBlock = ptr + blocklength;
-+ voice->sound = ptr;
-+
-+ voice->SamplingRate = samplespeed;
-+ voice->RateScale = ( voice->SamplingRate * voice->PitchScale ) / MV_MixRate;
-+
-+ // Multiply by MixBufferSize - 1
-+ voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
-+ voice->RateScale;
-+
-+ if ( voice->LoopEnd != NULL )
-+ {
-+ if ( blocklength > ( unsigned long )voice->LoopEnd )
-+ {
-+ blocklength = ( unsigned long )voice->LoopEnd;
-+ }
-+ else
-+ {
-+ voice->LoopEnd = ( char * )blocklength;
-+ }
-+
-+ voice->LoopStart = voice->sound + ( unsigned long )voice->LoopStart;
-+ voice->LoopEnd = voice->sound + ( unsigned long )voice->LoopEnd;
-+ voice->LoopSize = voice->LoopEnd - voice->LoopStart;
-+ }
-+
-+ if ( voice->bits == 16 )
-+ {
-+ blocklength /= 2;
-+ }
-+
-+ voice->position = 0;
-+ voice->length = min( blocklength, 0x8000 );
-+ voice->BlockLength = blocklength - voice->length;
-+ voice->length <<= 16;
-+
-+ MV_SetVoiceMixMode( voice );
-+
-+ return( KeepPlaying );
-+ }
-+
-+ return( NoMoreData );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetNextDemandFeedBlock
-+
-+ Controls playback of demand fed data.
-+---------------------------------------------------------------------*/
-+
-+playbackstatus MV_GetNextDemandFeedBlock
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ if ( voice->BlockLength > 0 )
-+ {
-+ voice->position -= voice->length;
-+ voice->sound += voice->length >> 16;
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+
-+ return( KeepPlaying );
-+ }
-+
-+ if ( voice->DemandFeed == NULL )
-+ {
-+ return( NoMoreData );
-+ }
-+
-+ voice->position = 0;
-+ ( voice->DemandFeed )( &voice->sound, &voice->BlockLength );
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+
-+ if ( ( voice->length > 0 ) && ( voice->sound != NULL ) )
-+ {
-+ return( KeepPlaying );
-+ }
-+ return( NoMoreData );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetNextRawBlock
-+
-+ Controls playback of demand fed data.
-+---------------------------------------------------------------------*/
-+
-+playbackstatus MV_GetNextRawBlock
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ if ( voice->BlockLength <= 0 )
-+ {
-+ if ( voice->LoopStart == NULL )
-+ {
-+ voice->Playing = FALSE;
-+ return( NoMoreData );
-+ }
-+
-+ voice->BlockLength = voice->LoopSize;
-+ voice->NextBlock = voice->LoopStart;
-+ voice->length = 0;
-+ voice->position = 0;
-+ }
-+
-+ voice->sound = voice->NextBlock;
-+ voice->position -= voice->length;
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->NextBlock += voice->length;
-+ if ( voice->bits == 16 )
-+ {
-+ voice->NextBlock += voice->length;
-+ }
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+
-+ return( KeepPlaying );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetNextWAVBlock
-+
-+ Controls playback of demand fed data.
-+---------------------------------------------------------------------*/
-+
-+playbackstatus MV_GetNextWAVBlock
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ if ( voice->BlockLength <= 0 )
-+ {
-+ if ( voice->LoopStart == NULL )
-+ {
-+ voice->Playing = FALSE;
-+ return( NoMoreData );
-+ }
-+
-+ voice->BlockLength = voice->LoopSize;
-+ voice->NextBlock = voice->LoopStart;
-+ voice->length = 0;
-+ voice->position = 0;
-+ }
-+
-+ voice->sound = voice->NextBlock;
-+ voice->position -= voice->length;
-+ voice->length = min( voice->BlockLength, 0x8000 );
-+ voice->NextBlock += voice->length;
-+ if ( voice->bits == 16 )
-+ {
-+ voice->NextBlock += voice->length;
-+ }
-+ voice->BlockLength -= voice->length;
-+ voice->length <<= 16;
-+
-+ return( KeepPlaying );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_ServiceRecord
-+
-+ Starts recording of the waiting buffer.
-+---------------------------------------------------------------------*/
-+
-+static void MV_ServiceRecord
-+ (
-+ void
-+ )
-+
-+ {
-+ if ( MV_RecordFunc )
-+ {
-+ MV_RecordFunc( MV_MixBuffer[ 0 ] + MV_MixPage * MixBufferSize,
-+ MixBufferSize );
-+ }
-+
-+ // Toggle which buffer we'll mix next
-+ MV_MixPage++;
-+ if ( MV_MixPage >= NumberOfBuffers )
-+ {
-+ MV_MixPage = 0;
-+ }
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetVoice
-+
-+ Locates the voice with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+VoiceNode *MV_GetVoice
-+ (
-+ int handle
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ unsigned flags;
-+
-+ flags = DisableInterrupts();
-+
-+ for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
-+ {
-+ if ( handle == voice->handle )
-+ {
-+ break;
-+ }
-+ }
-+
-+ RestoreInterrupts( flags );
-+
-+ if ( voice == &VoiceList )
-+ {
-+ MV_SetErrorCode( MV_VoiceNotFound );
-+
-+ // SBF - should this return null?
-+ return NULL;
-+ }
-+
-+ return( voice );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_VoicePlaying
-+
-+ Checks if the voice associated with the specified handle is
-+ playing.
-+---------------------------------------------------------------------*/
-+
-+int MV_VoicePlaying
-+ (
-+ int handle
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( FALSE );
-+ }
-+
-+ voice = MV_GetVoice( handle );
-+
-+ if ( voice == NULL )
-+ {
-+ return( FALSE );
-+ }
-+
-+ return( TRUE );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_KillAllVoices
-+
-+ Stops output of all currently active voices.
-+---------------------------------------------------------------------*/
-+
-+int MV_KillAllVoices
-+ (
-+ void
-+ )
-+
-+ {
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ // Remove all the voices from the list
-+ while( VoiceList.next != &VoiceList )
-+ {
-+ MV_Kill( VoiceList.next->handle );
-+ }
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_Kill
-+
-+ Stops output of the voice associated with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+int MV_Kill
-+ (
-+ int handle
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ unsigned flags;
-+ unsigned long callbackval;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ flags = DisableInterrupts();
-+
-+ voice = MV_GetVoice( handle );
-+ if ( voice == NULL )
-+ {
-+ RestoreInterrupts( flags );
-+ MV_SetErrorCode( MV_VoiceNotFound );
-+ return( MV_Error );
-+ }
-+
-+ callbackval = voice->callbackval;
-+
-+ MV_StopVoice( voice );
-+
-+ RestoreInterrupts( flags );
-+
-+ if ( MV_CallBackFunc )
-+ {
-+ MV_CallBackFunc( callbackval );
-+ }
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_VoicesPlaying
-+
-+ Determines the number of currently active voices.
-+---------------------------------------------------------------------*/
-+
-+int MV_VoicesPlaying
-+ (
-+ void
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ int NumVoices = 0;
-+ unsigned flags;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( 0 );
-+ }
-+
-+ flags = DisableInterrupts();
-+
-+ for( voice = VoiceList.next; voice != &VoiceList; voice = voice->next )
-+ {
-+ NumVoices++;
-+ }
-+
-+ RestoreInterrupts( flags );
-+
-+ return( NumVoices );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_AllocVoice
-+
-+ Retrieve an inactive or lower priority voice for output.
-+---------------------------------------------------------------------*/
-+
-+VoiceNode *MV_AllocVoice
-+ (
-+ int priority
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ VoiceNode *node;
-+ unsigned flags;
-+
-+//return( NULL );
-+ if ( MV_Recording )
-+ {
-+ return( NULL );
-+ }
-+
-+ flags = DisableInterrupts();
-+
-+ // Check if we have any free voices
-+ if ( LL_Empty( &VoicePool, next, prev ) )
-+ {
-+ // check if we have a higher priority than a voice that is playing.
-+ voice = VoiceList.next;
-+ for( node = voice->next; node != &VoiceList; node = node->next )
-+ {
-+ if ( node->priority < voice->priority )
-+ {
-+ voice = node;
-+ }
-+ }
-+
-+ if ( priority >= voice->priority )
-+ {
-+ MV_Kill( voice->handle );
-+ }
-+ }
-+
-+ // Check if any voices are in the voice pool
-+ if ( LL_Empty( &VoicePool, next, prev ) )
-+ {
-+ // No free voices
-+ RestoreInterrupts( flags );
-+ return( NULL );
-+ }
-+
-+ voice = VoicePool.next;
-+ LL_Remove( voice, next, prev );
-+ RestoreInterrupts( flags );
-+
-+ // Find a free voice handle
-+ do
-+ {
-+ MV_VoiceHandle++;
-+ if ( MV_VoiceHandle < MV_MinVoiceHandle )
-+ {
-+ MV_VoiceHandle = MV_MinVoiceHandle;
-+ }
-+ }
-+ while( MV_VoicePlaying( MV_VoiceHandle ) );
-+
-+ voice->handle = MV_VoiceHandle;
-+
-+ return( voice );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_VoiceAvailable
-+
-+ Checks if a voice can be play at the specified priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_VoiceAvailable
-+ (
-+ int priority
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ VoiceNode *node;
-+ unsigned flags;
-+
-+ // Check if we have any free voices
-+ if ( !LL_Empty( &VoicePool, next, prev ) )
-+ {
-+ return( TRUE );
-+ }
-+
-+ flags = DisableInterrupts();
-+
-+ // check if we have a higher priority than a voice that is playing.
-+ voice = VoiceList.next;
-+ for( node = VoiceList.next; node != &VoiceList; node = node->next )
-+ {
-+ if ( node->priority < voice->priority )
-+ {
-+ voice = node;
-+ }
-+ }
-+
-+ RestoreInterrupts( flags );
-+
-+ if ( ( voice != &VoiceList ) && ( priority >= voice->priority ) )
-+ {
-+ return( TRUE );
-+ }
-+
-+ return( FALSE );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetVoicePitch
-+
-+ Sets the pitch for the specified voice.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetVoicePitch
-+ (
-+ VoiceNode *voice,
-+ unsigned long rate,
-+ int pitchoffset
-+ )
-+
-+ {
-+ voice->SamplingRate = rate;
-+ voice->PitchScale = PITCH_GetScale( pitchoffset );
-+ voice->RateScale = ( rate * voice->PitchScale ) / MV_MixRate;
-+
-+ // Multiply by MixBufferSize - 1
-+ voice->FixedPointBufferSize = ( voice->RateScale * MixBufferSize ) -
-+ voice->RateScale;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetPitch
-+
-+ Sets the pitch for the voice associated with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+int MV_SetPitch
-+ (
-+ int handle,
-+ int pitchoffset
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ voice = MV_GetVoice( handle );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_VoiceNotFound );
-+ return( MV_Error );
-+ }
-+
-+ MV_SetVoicePitch( voice, voice->SamplingRate, pitchoffset );
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetFrequency
-+
-+ Sets the frequency for the voice associated with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+int MV_SetFrequency
-+ (
-+ int handle,
-+ int frequency
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ voice = MV_GetVoice( handle );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_VoiceNotFound );
-+ return( MV_Error );
-+ }
-+
-+ MV_SetVoicePitch( voice, frequency, 0 );
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetVolumeTable
-+
-+ Returns a pointer to the volume table associated with the specified
-+ volume.
-+---------------------------------------------------------------------*/
-+
-+static short *MV_GetVolumeTable
-+ (
-+ int vol
-+ )
-+
-+ {
-+ int volume;
-+ short *table;
-+
-+ volume = MIX_VOLUME( vol );
-+
-+ table = (short *)&MV_VolumeTable[ volume ];
-+
-+ return( table );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetVoiceMixMode
-+
-+ Selects which method should be used to mix the voice.
-+---------------------------------------------------------------------*/
-+
-+static void MV_SetVoiceMixMode
-+ (
-+ VoiceNode *voice
-+ )
-+
-+ {
-+ unsigned flags;
-+ int test;
-+
-+ flags = DisableInterrupts();
-+
-+ test = T_DEFAULT;
-+ if ( MV_Bits == 8 )
-+ {
-+ test |= T_8BITS;
-+ }
-+
-+ if ( voice->bits == 16 )
-+ {
-+ test |= T_16BITSOURCE;
-+ }
-+
-+ if ( MV_Channels == 1 )
-+ {
-+ test |= T_MONO;
-+ }
-+ else
-+ {
-+ if ( IS_QUIET( voice->RightVolume ) )
-+ {
-+ test |= T_RIGHTQUIET;
-+ }
-+ else if ( IS_QUIET( voice->LeftVolume ) )
-+ {
-+ test |= T_LEFTQUIET;
-+ }
-+ }
-+
-+ // Default case
-+ voice->mix = MV_Mix8BitMono;
-+
-+ switch( test )
-+ {
-+ case T_8BITS | T_MONO | T_16BITSOURCE :
-+ voice->mix = MV_Mix8BitMono16;
-+ break;
-+
-+ case T_8BITS | T_MONO :
-+ voice->mix = MV_Mix8BitMono;
-+ break;
-+
-+ case T_8BITS | T_16BITSOURCE | T_LEFTQUIET :
-+ MV_LeftVolume = MV_RightVolume;
-+ voice->mix = MV_Mix8BitMono16;
-+ break;
-+
-+ case T_8BITS | T_LEFTQUIET :
-+ MV_LeftVolume = MV_RightVolume;
-+ voice->mix = MV_Mix8BitMono;
-+ break;
-+
-+ case T_8BITS | T_16BITSOURCE | T_RIGHTQUIET :
-+ voice->mix = MV_Mix8BitMono16;
-+ break;
-+
-+ case T_8BITS | T_RIGHTQUIET :
-+ voice->mix = MV_Mix8BitMono;
-+ break;
-+
-+ case T_8BITS | T_16BITSOURCE :
-+ voice->mix = MV_Mix8BitStereo16;
-+ break;
-+
-+ case T_8BITS :
-+ voice->mix = MV_Mix8BitStereo;
-+ break;
-+
-+ case T_MONO | T_16BITSOURCE :
-+ voice->mix = MV_Mix16BitMono16;
-+ break;
-+
-+ case T_MONO :
-+ voice->mix = MV_Mix16BitMono;
-+ break;
-+
-+ case T_16BITSOURCE | T_LEFTQUIET :
-+ MV_LeftVolume = MV_RightVolume;
-+ voice->mix = MV_Mix16BitMono16;
-+ break;
-+
-+ case T_LEFTQUIET :
-+ MV_LeftVolume = MV_RightVolume;
-+ voice->mix = MV_Mix16BitMono;
-+ break;
-+
-+ case T_16BITSOURCE | T_RIGHTQUIET :
-+ voice->mix = MV_Mix16BitMono16;
-+ break;
-+
-+ case T_RIGHTQUIET :
-+ voice->mix = MV_Mix16BitMono;
-+ break;
-+
-+ case T_16BITSOURCE :
-+ voice->mix = MV_Mix16BitStereo16;
-+ break;
-+
-+ case T_SIXTEENBIT_STEREO :
-+ voice->mix = MV_Mix16BitStereo;
-+ break;
-+
-+ default :
-+ voice->mix = MV_Mix8BitMono;
-+ }
-+
-+ RestoreInterrupts( flags );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetVoiceVolume
-+
-+ Sets the stereo and mono volume level of the voice associated
-+ with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetVoiceVolume
-+ (
-+ VoiceNode *voice,
-+ int vol,
-+ int left,
-+ int right
-+ )
-+
-+ {
-+ if ( MV_Channels == 1 )
-+ {
-+ left = vol;
-+ right = vol;
-+ }
-+
-+ if ( MV_SwapLeftRight )
-+ {
-+ // SBPro uses reversed panning
-+ voice->LeftVolume = MV_GetVolumeTable( right );
-+ voice->RightVolume = MV_GetVolumeTable( left );
-+ }
-+ else
-+ {
-+ voice->LeftVolume = MV_GetVolumeTable( left );
-+ voice->RightVolume = MV_GetVolumeTable( right );
-+ }
-+
-+ MV_SetVoiceMixMode( voice );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_EndLooping
-+
-+ Stops the voice associated with the specified handle from looping
-+ without stoping the sound.
-+---------------------------------------------------------------------*/
-+
-+int MV_EndLooping
-+ (
-+ int handle
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ unsigned flags;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ flags = DisableInterrupts();
-+
-+ voice = MV_GetVoice( handle );
-+ if ( voice == NULL )
-+ {
-+ RestoreInterrupts( flags );
-+ MV_SetErrorCode( MV_VoiceNotFound );
-+ return( MV_Warning );
-+ }
-+
-+ voice->LoopCount = 0;
-+ voice->LoopStart = NULL;
-+ voice->LoopEnd = NULL;
-+
-+ RestoreInterrupts( flags );
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetPan
-+
-+ Sets the stereo and mono volume level of the voice associated
-+ with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+int MV_SetPan
-+ (
-+ int handle,
-+ int vol,
-+ int left,
-+ int right
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ voice = MV_GetVoice( handle );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_VoiceNotFound );
-+ return( MV_Warning );
-+ }
-+
-+ MV_SetVoiceVolume( voice, vol, left, right );
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_Pan3D
-+
-+ Set the angle and distance from the listener of the voice associated
-+ with the specified handle.
-+---------------------------------------------------------------------*/
-+
-+int MV_Pan3D
-+ (
-+ int handle,
-+ int angle,
-+ int distance
-+ )
-+
-+ {
-+ int left;
-+ int right;
-+ int mid;
-+ int volume;
-+ int status;
-+
-+ if ( distance < 0 )
-+ {
-+ distance = -distance;
-+ angle += MV_NumPanPositions / 2;
-+ }
-+
-+ volume = MIX_VOLUME( distance );
-+
-+ // Ensure angle is within 0 - 31
-+ angle &= MV_MaxPanPosition;
-+
-+ left = MV_PanTable[ angle ][ volume ].left;
-+ right = MV_PanTable[ angle ][ volume ].right;
-+ mid = max( 0, 255 - distance );
-+
-+ status = MV_SetPan( handle, mid, left, right );
-+
-+ return( status );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetReverb
-+
-+ Sets the level of reverb to add to mix.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetReverb
-+ (
-+ int reverb
-+ )
-+
-+ {
-+ MV_ReverbLevel = MIX_VOLUME( reverb );
-+ MV_ReverbTable = &MV_VolumeTable[ MV_ReverbLevel ];
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetFastReverb
-+
-+ Sets the level of reverb to add to mix.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetFastReverb
-+ (
-+ int reverb
-+ )
-+
-+ {
-+ MV_ReverbLevel = max( 0, min( 16, reverb ) );
-+ MV_ReverbTable = NULL;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetMaxReverbDelay
-+
-+ Returns the maximum delay time for reverb.
-+---------------------------------------------------------------------*/
-+
-+int MV_GetMaxReverbDelay
-+ (
-+ void
-+ )
-+
-+ {
-+ int maxdelay;
-+
-+ maxdelay = MixBufferSize * MV_NumberOfBuffers;
-+
-+ return maxdelay;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetReverbDelay
-+
-+ Returns the current delay time for reverb.
-+---------------------------------------------------------------------*/
-+
-+int MV_GetReverbDelay
-+ (
-+ void
-+ )
-+
-+ {
-+ return MV_ReverbDelay / MV_SampleSize;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetReverbDelay
-+
-+ Sets the delay level of reverb to add to mix.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetReverbDelay
-+ (
-+ int delay
-+ )
-+
-+ {
-+ int maxdelay;
-+
-+ maxdelay = MV_GetMaxReverbDelay();
-+ MV_ReverbDelay = max( MixBufferSize, min( delay, maxdelay ) );
-+ MV_ReverbDelay *= MV_SampleSize;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetMixMode
-+
-+ Prepares Multivoc to play stereo of mono digitized sounds.
-+---------------------------------------------------------------------*/
-+
-+int MV_SetMixMode
-+ (
-+ int numchannels,
-+ int samplebits
-+ )
-+
-+ {
-+ int mode;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ mode = 0;
-+ if ( numchannels == 2 )
-+ {
-+ mode |= STEREO;
-+ }
-+ if ( samplebits == 16 )
-+ {
-+ mode |= SIXTEEN_BIT;
-+ }
-+
-+ MV_MixMode = mode;
-+
-+ MV_Channels = 1;
-+ if ( MV_MixMode & STEREO )
-+ {
-+ MV_Channels = 2;
-+ }
-+
-+ MV_Bits = 8;
-+ if ( MV_MixMode & SIXTEEN_BIT )
-+ {
-+ MV_Bits = 16;
-+ }
-+
-+ MV_BuffShift = 7 + MV_Channels;
-+ MV_SampleSize = sizeof( MONO8 ) * MV_Channels;
-+
-+ if ( MV_Bits == 8 )
-+ {
-+ MV_Silence = SILENCE_8BIT;
-+ }
-+ else
-+ {
-+ MV_Silence = SILENCE_16BIT;
-+ MV_BuffShift += 1;
-+ MV_SampleSize *= 2;
-+ }
-+
-+ MV_BufferSize = MixBufferSize * MV_SampleSize;
-+ MV_NumberOfBuffers = TotalBufferSize / MV_BufferSize;
-+ MV_BufferLength = TotalBufferSize;
-+
-+ MV_RightChannelOffset = MV_SampleSize / 2;
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_StartPlayback
-+
-+ Starts the sound playback engine.
-+---------------------------------------------------------------------*/
-+
-+int MV_StartPlayback
-+ (
-+ void
-+ )
-+
-+ {
-+ int status;
-+ int buffer;
-+
-+ // Initialize the buffers
-+ ClearBuffer_DW( MV_MixBuffer[ 0 ], MV_Silence, TotalBufferSize >> 2 );
-+ for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
-+ {
-+ MV_BufferEmpty[ buffer ] = TRUE;
-+ }
-+
-+ // Set the mix buffer variables
-+ MV_MixPage = 1;
-+
-+ MV_MixFunction = MV_Mix;
-+
-+ status = DSL_BeginBufferedPlayback( MV_MixBuffer[ 0 ],
-+ TotalBufferSize, MV_NumberOfBuffers,
-+ MV_RequestedMixRate, MV_MixMode, MV_ServiceVoc );
-+
-+ if ( status != DSL_Ok )
-+ {
-+ MV_SetErrorCode( MV_BlasterError );
-+ return( MV_Error );
-+ }
-+
-+ MV_MixRate = DSL_GetPlaybackRate();
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_StopPlayback
-+
-+ Stops the sound playback engine.
-+---------------------------------------------------------------------*/
-+
-+void MV_StopPlayback
-+ (
-+ void
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ VoiceNode *next;
-+ unsigned flags;
-+
-+ DSL_StopPlayback();
-+
-+ // Make sure all callbacks are done.
-+ flags = DisableInterrupts();
-+
-+ for( voice = VoiceList.next; voice != &VoiceList; voice = next )
-+ {
-+ next = voice->next;
-+
-+ MV_StopVoice( voice );
-+
-+ if ( MV_CallBackFunc )
-+ {
-+ MV_CallBackFunc( voice->callbackval );
-+ }
-+ }
-+
-+ RestoreInterrupts( flags );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_StartRecording
-+
-+ Starts the sound recording engine.
-+---------------------------------------------------------------------*/
-+
-+int MV_StartRecording
-+ (
-+ int MixRate,
-+ void ( *function )( char *ptr, int length )
-+ )
-+
-+ {
-+ MV_SetErrorCode( MV_UnsupportedCard );
-+ return( MV_Error );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_StopRecord
-+
-+ Stops the sound record engine.
-+---------------------------------------------------------------------*/
-+
-+void MV_StopRecord
-+ (
-+ void
-+ )
-+
-+ {
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_StartDemandFeedPlayback
-+
-+ Plays a digitized sound from a user controlled buffering system.
-+---------------------------------------------------------------------*/
-+
-+int MV_StartDemandFeedPlayback
-+ (
-+ void ( *function )( char **ptr, unsigned long *length ),
-+ int rate,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ // Request a voice from the voice pool
-+ voice = MV_AllocVoice( priority );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_NoVoices );
-+ return( MV_Error );
-+ }
-+
-+ voice->wavetype = DemandFeed;
-+ voice->bits = 8;
-+ voice->GetSound = MV_GetNextDemandFeedBlock;
-+ voice->NextBlock = NULL;
-+ voice->DemandFeed = function;
-+ voice->LoopStart = NULL;
-+ voice->LoopCount = 0;
-+ voice->BlockLength = 0;
-+ voice->position = 0;
-+ voice->sound = NULL;
-+ voice->length = 0;
-+ voice->BlockLength = 0;
-+ voice->Playing = TRUE;
-+ voice->next = NULL;
-+ voice->prev = NULL;
-+ voice->priority = priority;
-+ voice->callbackval = callbackval;
-+
-+ MV_SetVoicePitch( voice, rate, pitchoffset );
-+ MV_SetVoiceVolume( voice, vol, left, right );
-+ MV_PlayVoice( voice );
-+
-+ return( voice->handle );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayRaw
-+
-+ Begin playback of sound data with the given sound levels and
-+ priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayRaw
-+ (
-+ char *ptr,
-+ unsigned long length,
-+ unsigned rate,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ int status;
-+
-+ status = MV_PlayLoopedRaw( ptr, length, NULL, NULL, rate, pitchoffset,
-+ vol, left, right, priority, callbackval );
-+
-+ return( status );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayLoopedRaw
-+
-+ Begin playback of sound data with the given sound levels and
-+ priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayLoopedRaw
-+ (
-+ char *ptr,
-+ long length,
-+ char *loopstart,
-+ char *loopend,
-+ unsigned rate,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ // Request a voice from the voice pool
-+ voice = MV_AllocVoice( priority );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_NoVoices );
-+ return( MV_Error );
-+ }
-+
-+ voice->wavetype = Raw;
-+ voice->bits = 8;
-+ voice->GetSound = MV_GetNextRawBlock;
-+ voice->Playing = TRUE;
-+ voice->NextBlock = ptr;
-+ voice->position = 0;
-+ voice->BlockLength = length;
-+ voice->length = 0;
-+ voice->next = NULL;
-+ voice->prev = NULL;
-+ voice->priority = priority;
-+ voice->callbackval = callbackval;
-+ voice->LoopStart = loopstart;
-+ voice->LoopEnd = loopend;
-+ voice->LoopSize = ( voice->LoopEnd - voice->LoopStart ) + 1;
-+
-+ MV_SetVoicePitch( voice, rate, pitchoffset );
-+ MV_SetVoiceVolume( voice, vol, left, right );
-+ MV_PlayVoice( voice );
-+
-+ return( voice->handle );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayWAV
-+
-+ Begin playback of sound data with the given sound levels and
-+ priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayWAV
-+ (
-+ char *ptr,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ int status;
-+
-+ status = MV_PlayLoopedWAV( ptr, -1, -1, pitchoffset, vol, left, right,
-+ priority, callbackval );
-+
-+ return( status );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayWAV3D
-+
-+ Begin playback of sound data at specified angle and distance
-+ from listener.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayWAV3D
-+ (
-+ char *ptr,
-+ int pitchoffset,
-+ int angle,
-+ int distance,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ int left;
-+ int right;
-+ int mid;
-+ int volume;
-+ int status;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ if ( distance < 0 )
-+ {
-+ distance = -distance;
-+ angle += MV_NumPanPositions / 2;
-+ }
-+
-+ volume = MIX_VOLUME( distance );
-+
-+ // Ensure angle is within 0 - 31
-+ angle &= MV_MaxPanPosition;
-+
-+ left = MV_PanTable[ angle ][ volume ].left;
-+ right = MV_PanTable[ angle ][ volume ].right;
-+ mid = max( 0, 255 - distance );
-+
-+ status = MV_PlayWAV( ptr, pitchoffset, mid, left, right, priority,
-+ callbackval );
-+
-+ return( status );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayLoopedWAV
-+
-+ Begin playback of sound data with the given sound levels and
-+ priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayLoopedWAV
-+ (
-+ char *ptr,
-+ long loopstart,
-+ long loopend,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ riff_header *riff;
-+ format_header *format;
-+ data_header *data;
-+ VoiceNode *voice;
-+ int length;
-+ int absloopend;
-+ int absloopstart;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ riff = ( riff_header * )ptr;
-+
-+ if ( ( strncmp( riff->RIFF, "RIFF", 4 ) != 0 ) ||
-+ ( strncmp( riff->WAVE, "WAVE", 4 ) != 0 ) ||
-+ ( strncmp( riff->fmt, "fmt ", 4) != 0 ) )
-+ {
-+ MV_SetErrorCode( MV_InvalidWAVFile );
-+ return( MV_Error );
-+ }
-+
-+ format = ( format_header * )( riff + 1 );
-+ data = ( data_header * )( ( ( char * )format ) + riff->format_size );
-+
-+ // Check if it's PCM data.
-+ if ( format->wFormatTag != 1 )
-+ {
-+ MV_SetErrorCode( MV_InvalidWAVFile );
-+ return( MV_Error );
-+ }
-+
-+ if ( format->nChannels != 1 )
-+ {
-+ MV_SetErrorCode( MV_InvalidWAVFile );
-+ return( MV_Error );
-+ }
-+
-+ if ( ( format->nBitsPerSample != 8 ) &&
-+ ( format->nBitsPerSample != 16 ) )
-+ {
-+ MV_SetErrorCode( MV_InvalidWAVFile );
-+ return( MV_Error );
-+ }
-+
-+ if ( strncmp( data->DATA, "data", 4 ) != 0 )
-+ {
-+ MV_SetErrorCode( MV_InvalidWAVFile );
-+ return( MV_Error );
-+ }
-+
-+ // Request a voice from the voice pool
-+ voice = MV_AllocVoice( priority );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_NoVoices );
-+ return( MV_Error );
-+ }
-+
-+ voice->wavetype = WAV;
-+ voice->bits = format->nBitsPerSample;
-+ voice->GetSound = MV_GetNextWAVBlock;
-+
-+ length = data->size;
-+ absloopstart = loopstart;
-+ absloopend = loopend;
-+ if ( voice->bits == 16 )
-+ {
-+ loopstart *= 2;
-+ data->size &= ~1;
-+ loopend *= 2;
-+ length /= 2;
-+ }
-+
-+ loopend = min( loopend, (long)data->size );
-+ absloopend = min( absloopend, length );
-+
-+ voice->Playing = TRUE;
-+ voice->DemandFeed = NULL;
-+ voice->LoopStart = NULL;
-+ voice->LoopCount = 0;
-+ voice->position = 0;
-+ voice->length = 0;
-+ voice->BlockLength = absloopend;
-+ voice->NextBlock = ( char * )( data + 1 );
-+ voice->next = NULL;
-+ voice->prev = NULL;
-+ voice->priority = priority;
-+ voice->callbackval = callbackval;
-+ voice->LoopStart = voice->NextBlock + loopstart;
-+ voice->LoopEnd = voice->NextBlock + loopend;
-+ voice->LoopSize = absloopend - absloopstart;
-+
-+ if ( ( loopstart >= (long)data->size ) || ( loopstart < 0 ) )
-+ {
-+ voice->LoopStart = NULL;
-+ voice->LoopEnd = NULL;
-+ voice->BlockLength = length;
-+ }
-+
-+ MV_SetVoicePitch( voice, format->nSamplesPerSec, pitchoffset );
-+ MV_SetVoiceVolume( voice, vol, left, right );
-+ MV_PlayVoice( voice );
-+
-+ return( voice->handle );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayVOC3D
-+
-+ Begin playback of sound data at specified angle and distance
-+ from listener.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayVOC3D
-+ (
-+ char *ptr,
-+ int pitchoffset,
-+ int angle,
-+ int distance,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ int left;
-+ int right;
-+ int mid;
-+ int volume;
-+ int status;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ if ( distance < 0 )
-+ {
-+ distance = -distance;
-+ angle += MV_NumPanPositions / 2;
-+ }
-+
-+ volume = MIX_VOLUME( distance );
-+
-+ // Ensure angle is within 0 - 31
-+ angle &= MV_MaxPanPosition;
-+
-+ left = MV_PanTable[ angle ][ volume ].left;
-+ right = MV_PanTable[ angle ][ volume ].right;
-+ mid = max( 0, 255 - distance );
-+
-+ status = MV_PlayVOC( ptr, pitchoffset, mid, left, right, priority,
-+ callbackval );
-+
-+ return( status );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayVOC
-+
-+ Begin playback of sound data with the given sound levels and
-+ priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayVOC
-+ (
-+ char *ptr,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ int status;
-+
-+ status = MV_PlayLoopedVOC( ptr, -1, -1, pitchoffset, vol, left, right,
-+ priority, callbackval );
-+
-+ return( status );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_PlayLoopedVOC
-+
-+ Begin playback of sound data with the given sound levels and
-+ priority.
-+---------------------------------------------------------------------*/
-+
-+int MV_PlayLoopedVOC
-+ (
-+ char *ptr,
-+ long loopstart,
-+ long loopend,
-+ int pitchoffset,
-+ int vol,
-+ int left,
-+ int right,
-+ int priority,
-+ unsigned long callbackval
-+ )
-+
-+ {
-+ VoiceNode *voice;
-+ int status;
-+ unsigned short nextpos;
-+
-+ if ( !MV_Installed )
-+ {
-+ MV_SetErrorCode( MV_NotInstalled );
-+ return( MV_Error );
-+ }
-+
-+ // Make sure it's a valid VOC file.
-+ status = strncmp( ptr, "Creative Voice File", 19 );
-+ if ( status != 0 )
-+ {
-+ MV_SetErrorCode( MV_InvalidVOCFile );
-+ return( MV_Error );
-+ }
-+
-+ // Request a voice from the voice pool
-+ voice = MV_AllocVoice( priority );
-+ if ( voice == NULL )
-+ {
-+ MV_SetErrorCode( MV_NoVoices );
-+ return( MV_Error );
-+ }
-+
-+ voice->wavetype = VOC;
-+ voice->bits = 8;
-+ voice->GetSound = MV_GetNextVOCBlock;
-+
-+ nextpos = *( unsigned short * )( ptr + 0x14 );
-+ voice->NextBlock = ptr + BUILDSWAP_INTEL16(nextpos);
-+
-+ voice->DemandFeed = NULL;
-+ voice->LoopStart = NULL;
-+ voice->LoopCount = 0;
-+ voice->BlockLength = 0;
-+ voice->PitchScale = PITCH_GetScale( pitchoffset );
-+ voice->length = 0;
-+ voice->next = NULL;
-+ voice->prev = NULL;
-+ voice->priority = priority;
-+ voice->callbackval = callbackval;
-+ voice->LoopStart = ( char * )loopstart;
-+ voice->LoopEnd = ( char * )loopend;
-+ voice->LoopSize = loopend - loopstart + 1;
-+
-+ if ( loopstart < 0 )
-+ {
-+ voice->LoopStart = NULL;
-+ voice->LoopEnd = NULL;
-+ }
-+
-+ MV_SetVoiceVolume( voice, vol, left, right );
-+ MV_PlayVoice( voice );
-+
-+ return( voice->handle );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_LockEnd
-+
-+ Used for determining the length of the functions to lock in memory.
-+---------------------------------------------------------------------*/
-+
-+static void MV_LockEnd
-+ (
-+ void
-+ )
-+
-+ {
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_CreateVolumeTable
-+
-+ Create the table used to convert sound data to a specific volume
-+ level.
-+---------------------------------------------------------------------*/
-+
-+void MV_CreateVolumeTable
-+ (
-+ int index,
-+ int volume,
-+ int MaxVolume
-+ )
-+
-+ {
-+ int val;
-+ int level;
-+ int i;
-+
-+ level = ( volume * MaxVolume ) / MV_MaxTotalVolume;
-+ if ( MV_Bits == 16 )
-+ {
-+ for( i = 0; i < 65536; i += 256 )
-+ {
-+ val = i - 0x8000;
-+ val *= level;
-+ val /= MV_MaxVolume;
-+ MV_VolumeTable[ index ][ i / 256 ] = val;
-+ }
-+ }
-+ else
-+ {
-+ for( i = 0; i < 256; i++ )
-+ {
-+ val = i - 0x80;
-+ val *= level;
-+ val /= MV_MaxVolume;
-+ MV_VolumeTable[ volume ][ i ] = val;
-+ }
-+ }
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_CalcVolume
-+
-+ Create the table used to convert sound data to a specific volume
-+ level.
-+---------------------------------------------------------------------*/
-+
-+void MV_CalcVolume
-+ (
-+ int MaxVolume
-+ )
-+
-+ {
-+ int volume;
-+
-+ for( volume = 0; volume < 128; volume++ )
-+ {
-+ MV_HarshClipTable[ volume ] = 0;
-+ MV_HarshClipTable[ volume + 384 ] = 255;
-+ }
-+ for( volume = 0; volume < 256; volume++ )
-+ {
-+ MV_HarshClipTable[ volume + 128 ] = volume;
-+ }
-+
-+ // For each volume level, create a translation table with the
-+ // appropriate volume calculated.
-+ for( volume = 0; volume <= MV_MaxVolume; volume++ )
-+ {
-+ MV_CreateVolumeTable( volume, volume, MaxVolume );
-+ }
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_CalcPanTable
-+
-+ Create the table used to determine the stereo volume level of
-+ a sound located at a specific angle and distance from the listener.
-+---------------------------------------------------------------------*/
-+
-+void MV_CalcPanTable
-+ (
-+ void
-+ )
-+
-+ {
-+ int level;
-+ int angle;
-+ int distance;
-+ int HalfAngle;
-+ int ramp;
-+
-+ HalfAngle = ( MV_NumPanPositions / 2 );
-+
-+ for( distance = 0; distance <= MV_MaxVolume; distance++ )
-+ {
-+ level = ( 255 * ( MV_MaxVolume - distance ) ) / MV_MaxVolume;
-+ for( angle = 0; angle <= HalfAngle / 2; angle++ )
-+ {
-+ ramp = level - ( ( level * angle ) /
-+ ( MV_NumPanPositions / 4 ) );
-+
-+ MV_PanTable[ angle ][ distance ].left = ramp;
-+ MV_PanTable[ HalfAngle - angle ][ distance ].left = ramp;
-+ MV_PanTable[ HalfAngle + angle ][ distance ].left = level;
-+ MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].left = level;
-+
-+ MV_PanTable[ angle ][ distance ].right = level;
-+ MV_PanTable[ HalfAngle - angle ][ distance ].right = level;
-+ MV_PanTable[ HalfAngle + angle ][ distance ].right = ramp;
-+ MV_PanTable[ MV_MaxPanPosition - angle ][ distance ].right = ramp;
-+ }
-+ }
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetVolume
-+
-+ Sets the volume of digitized sound playback.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetVolume
-+ (
-+ int volume
-+ )
-+
-+ {
-+ volume = max( 0, volume );
-+ volume = min( volume, MV_MaxTotalVolume );
-+
-+ MV_TotalVolume = volume;
-+
-+ // Calculate volume table
-+ MV_CalcVolume( volume );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetVolume
-+
-+ Returns the volume of digitized sound playback.
-+---------------------------------------------------------------------*/
-+
-+int MV_GetVolume
-+ (
-+ void
-+ )
-+
-+ {
-+ return( MV_TotalVolume );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetCallBack
-+
-+ Set the function to call when a voice stops.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetCallBack
-+ (
-+ void ( *function )( unsigned long )
-+ )
-+
-+ {
-+ MV_CallBackFunc = function;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_SetReverseStereo
-+
-+ Set the orientation of the left and right channels.
-+---------------------------------------------------------------------*/
-+
-+void MV_SetReverseStereo
-+ (
-+ int setting
-+ )
-+
-+ {
-+ MV_SwapLeftRight = setting;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_GetReverseStereo
-+
-+ Returns the orientation of the left and right channels.
-+---------------------------------------------------------------------*/
-+
-+int MV_GetReverseStereo
-+ (
-+ void
-+ )
-+
-+ {
-+ return( MV_SwapLeftRight );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_TestPlayback
-+
-+ Checks if playback has started.
-+---------------------------------------------------------------------*/
-+
-+int MV_TestPlayback(void)
-+ {
-+ return MV_Ok;
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_Init
-+
-+ Perform the initialization of variables and memory used by
-+ Multivoc.
-+---------------------------------------------------------------------*/
-+
-+int MV_Init
-+ (
-+ int soundcard,
-+ int MixRate,
-+ int Voices,
-+ int numchannels,
-+ int samplebits
-+ )
-+
-+ {
-+ char *ptr;
-+ int status;
-+ int buffer;
-+ int index;
-+
-+ if ( MV_Installed )
-+ {
-+ MV_Shutdown();
-+ }
-+
-+ MV_SetErrorCode( MV_Ok );
-+
-+ MV_TotalMemory = Voices * sizeof( VoiceNode ) + sizeof( HARSH_CLIP_TABLE_8 );
-+ status = USRHOOKS_GetMem( ( void ** )&ptr, MV_TotalMemory );
-+ if ( status != USRHOOKS_Ok )
-+ {
-+ MV_SetErrorCode( MV_NoMem );
-+ return( MV_Error );
-+ }
-+
-+ MV_Voices = ( VoiceNode * )ptr;
-+ MV_HarshClipTable = ptr + ( MV_TotalMemory - sizeof( HARSH_CLIP_TABLE_8 ) );
-+
-+ // Set number of voices before calculating volume table
-+ MV_MaxVoices = Voices;
-+
-+ LL_Reset( (VoiceNode *)&VoiceList, next, prev );
-+ LL_Reset( (VoiceNode *)&VoicePool, next, prev );
-+
-+ for( index = 0; index < Voices; index++ )
-+ {
-+ LL_Add( (VoiceNode *)&VoicePool, &MV_Voices[ index ], next, prev );
-+ }
-+
-+ // Allocate mix buffer within 1st megabyte
-+ status = DPMI_GetDOSMemory( ( void ** )&ptr, &MV_BufferDescriptor,
-+ 2 * TotalBufferSize );
-+
-+ if ( status )
-+ {
-+ USRHOOKS_FreeMem( MV_Voices );
-+ MV_Voices = NULL;
-+ MV_TotalMemory = 0;
-+
-+ MV_SetErrorCode( MV_NoMem );
-+ return( MV_Error );
-+ }
-+
-+ MV_SetReverseStereo( FALSE );
-+
-+ // Initialize the sound card
-+ status = DSL_Init();
-+ if ( status != DSL_Ok )
-+ {
-+ MV_SetErrorCode( MV_BlasterError );
-+ }
-+
-+ if ( MV_ErrorCode != MV_Ok )
-+ {
-+ status = MV_ErrorCode;
-+
-+ USRHOOKS_FreeMem( MV_Voices );
-+ MV_Voices = NULL;
-+ MV_TotalMemory = 0;
-+
-+ DPMI_FreeDOSMemory( MV_BufferDescriptor );
-+
-+ MV_SetErrorCode( status );
-+ return( MV_Error );
-+ }
-+
-+ MV_SoundCard = soundcard;
-+ MV_Installed = TRUE;
-+ MV_CallBackFunc = NULL;
-+ MV_RecordFunc = NULL;
-+ MV_Recording = FALSE;
-+ MV_ReverbLevel = 0;
-+ MV_ReverbTable = NULL;
-+
-+ // Set the sampling rate
-+ MV_RequestedMixRate = MixRate;
-+
-+ // Set Mixer to play stereo digitized sound
-+ MV_SetMixMode( numchannels, samplebits );
-+ MV_ReverbDelay = MV_BufferSize * 3;
-+
-+ MV_MixBuffer[ MV_NumberOfBuffers ] = ptr;
-+ for( buffer = 0; buffer < MV_NumberOfBuffers; buffer++ )
-+ {
-+ MV_MixBuffer[ buffer ] = ptr;
-+ ptr += MV_BufferSize;
-+ }
-+
-+ // Calculate pan table
-+ MV_CalcPanTable();
-+
-+ MV_SetVolume( MV_MaxTotalVolume );
-+
-+ // Start the playback engine
-+ status = MV_StartPlayback();
-+ if ( status != MV_Ok )
-+ {
-+ // Preserve error code while we shutdown.
-+ status = MV_ErrorCode;
-+ MV_Shutdown();
-+ MV_SetErrorCode( status );
-+ return( MV_Error );
-+ }
-+
-+ if ( MV_TestPlayback() != MV_Ok )
-+ {
-+ status = MV_ErrorCode;
-+ MV_Shutdown();
-+ MV_SetErrorCode( status );
-+ return( MV_Error );
-+ }
-+
-+ return( MV_Ok );
-+ }
-+
-+
-+/*---------------------------------------------------------------------
-+ Function: MV_Shutdown
-+
-+ Restore any resources allocated by Multivoc back to the system.
-+---------------------------------------------------------------------*/
-+
-+int MV_Shutdown
-+ (
-+ void
-+ )
-+
-+ {
-+ int buffer;
-+ unsigned flags;
-+
-+ if ( !MV_Installed )
-+ {
-+ return( MV_Ok );
-+ }
-+
-+ flags = DisableInterrupts();
-+
-+ MV_KillAllVoices();
-+
-+ MV_Installed = FALSE;
-+
-+ // Stop the sound recording engine
-+ if ( MV_Recording )
-+ {
-+ MV_StopRecord();
-+ }
-+
-+ // Stop the sound playback engine
-+ MV_StopPlayback();
-+
-+ // Shutdown the sound card
-+ DSL_Shutdown();
-+
-+ RestoreInterrupts( flags );
-+
-+ // Free any voices we allocated
-+ USRHOOKS_FreeMem( MV_Voices );
-+ MV_Voices = NULL;
-+ MV_TotalMemory = 0;
-+
-+ LL_Reset( (VoiceNode *)&VoiceList, next, prev );
-+ LL_Reset( (VoiceNode *)&VoicePool, next, prev );
-+
-+ MV_MaxVoices = 1;
-+
-+ // Release the descriptor from our mix buffer
-+ DPMI_FreeDOSMemory( MV_BufferDescriptor );
-+ for( buffer = 0; buffer < NumberOfBuffers; buffer++ )
-+ {
-+ MV_MixBuffer[ buffer ] = NULL;
-+ }
-+
-+ return( MV_Ok );
-+ }
-diff -Nur jfsw_src_20051009.orig/source/jaudiolib/util.h jfsw_src_20051009/source/jaudiolib/util.h
---- jfsw_src_20051009.orig/source/jaudiolib/util.h 1970-01-01 01:00:00.000000000 +0100
-+++ jfsw_src_20051009/source/jaudiolib/util.h 2005-10-10 15:02:08.000000000 +0200
-@@ -0,0 +1,12 @@
-+#ifndef AUDIOLIB__UTIL_H
-+#define AUDIOLIB__UTIL_H
-+
-+#ifndef min
-+#define min(a, b) ((a) < (b) ? (a) : (b))
-+#endif
-+
-+#ifndef max
-+#define max(a, b) ((a) > (b) ? (a) : (b))
-+#endif
-+
-+#endif
-diff -Nur jfsw_src_20051009.orig/source/lists.h jfsw_src_20051009/source/lists.h
---- jfsw_src_20051009.orig/source/lists.h 2005-10-09 15:28:24.000000000 +0200
-+++ jfsw_src_20051009/source/lists.h 2005-10-10 15:02:08.000000000 +0200
-@@ -57,7 +57,7 @@
- ((LIST) nodep)->Next->Prev = ((LIST) nodep)->Prev)
-
-
-- #define TRAVERSE(l, o, n) ASSERT(((LIST)l)->Next && ((LIST)l)->Prev); for ((LIST) o = ((LIST)l)->Next; \
-+ #define TRAVERSE(l, o, n) ASSERT(((LIST)l)->Next && ((LIST)l)->Prev); for (o = ((LIST)l)->Next; \
- n = o->Next, (LIST) o != (LIST) l; \
- o = n)
-
-diff -Nur jfsw_src_20051009.orig/source/sounds.c jfsw_src_20051009/source/sounds.c
---- jfsw_src_20051009.orig/source/sounds.c 2005-10-09 15:28:24.000000000 +0200
-+++ jfsw_src_20051009/source/sounds.c 2005-10-10 15:02:08.000000000 +0200
-@@ -392,6 +392,7 @@
- if (DemoMode)
- return(MUSIC_Error);
-
-+#ifdef WINDOWS
- if (SongPtr)
- StopSong();
-
-@@ -412,7 +413,16 @@
- //DSPRINTF(ds,"Playing song");
- //MONO_PRINT(ds);
-
-- return((int)MUSIC_PlaySong(SongPtr, loopflag));
-+ return((int)MUSIC_PlaySong(SongPtr, loopflag));
-+
-+#else
-+ void PlayMusic(char *_filename);
-+ if(MusicDevice < 0) return;
-+
-+ // FIXME: I need this to get the music volume initialized (not sure why) -- Jim Bentler
-+ MUSIC_SetVolume( MusicVolume );
-+ PlayMusic(song_file_name);
-+#endif
- }
-
- VOID