From aa6985b28a427b6c7a3a1c201810e0b623848444 Mon Sep 17 00:00:00 2001 From: David Spencer Date: Wed, 2 Mar 2016 23:28:44 +0000 Subject: games/jfsw: Updated for version 20160220_54912c4. Signed-off-by: David Spencer --- games/jfsw/README | 23 +- games/jfsw/jfsw.SlackBuild | 78 +- games/jfsw/jfsw.info | 18 +- games/jfsw/patches/disable_ambience.patch | 61 - games/jfsw/patches/jfbuild_src_20051009.patch | 125 - games/jfsw/patches/jfsw_src_20051009.patch | 4578 ------------------------- 6 files changed, 55 insertions(+), 4828 deletions(-) delete mode 100644 games/jfsw/patches/disable_ambience.patch delete mode 100644 games/jfsw/patches/jfbuild_src_20051009.patch delete mode 100644 games/jfsw/patches/jfsw_src_20051009.patch (limited to 'games/jfsw') diff --git a/games/jfsw/README b/games/jfsw/README index e6d6add77a..23ccdc457a 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 b0b50783ba..a061b0bb4d 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 # 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 bb68040667..e3b392ec17 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 221af6152d..0000000000 --- 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 5cf0cb2feb..0000000000 --- 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<> 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 -+#include -+ -+#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 -+#include -+#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 -+#include -+#include -+#include -+#include -+ -+#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 -+#include -+ -+#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 -+//#include -+#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 -+#include -+#include -+#include -+ -+#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 -- cgit v1.2.3