1211 lines
32 KiB
C
1211 lines
32 KiB
C
// Emacs style mode select -*- C++ -*-
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
// Copyright (C) 2001 by DooM Legacy Team.
|
|
//
|
|
// 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.
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
/// \file
|
|
/// \brief General driver for 3D sound system
|
|
///
|
|
/// Implementend via FMOD_SOUND API
|
|
|
|
#ifdef _WINDOWS
|
|
//#define WIN32_LEAN_AND_MEAN
|
|
#define RPC_NO_WINDOWS_H
|
|
#include <windows.h>
|
|
#else
|
|
#include <stdarg.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include <fcntl.h>
|
|
#endif
|
|
|
|
#include <stdio.h>
|
|
FILE *logstream = NULL;
|
|
|
|
#ifdef __MINGW32__
|
|
#include <FMOD/fmod.h>
|
|
#else
|
|
#include <fmod.h>
|
|
#endif
|
|
|
|
#ifdef FSOUND_INIT_DONTLATENCYADJUST //Alam: why didn't I think about this before? :)
|
|
#define FSOUND_Sample_Load(index,data,mode,length) FSOUND_Sample_Load(index,data,mode,0,length)
|
|
#else
|
|
#define OLDFMOD //Alam: Yea!
|
|
#endif
|
|
|
|
#ifdef __MINGW32__
|
|
#include <FMOD/fmod_errors.h>
|
|
#else
|
|
#include <fmod_errors.h> /* optional */
|
|
#endif
|
|
|
|
#define MAXCHANNEL 1024
|
|
|
|
#undef DEBUG_TO_FILE
|
|
#if defined ( HAVE_SDL ) && !defined ( LOGMESSAGES )
|
|
#define DEBUG_TO_FILE
|
|
#endif
|
|
|
|
#ifndef MORESTUFF
|
|
//#define MORESTUFF
|
|
#define REL2D
|
|
#endif
|
|
|
|
#define _CREATE_DLL_
|
|
#include "../../doomdef.h"
|
|
#include "../hw3dsdrv.h"
|
|
#define INT2CHAR(p) (char *)p + 8
|
|
|
|
//Doom sound sample format
|
|
#define FSOUND_UNORMAL (FSOUND_8BITS | FSOUND_MONO | FSOUND_UNSIGNED)
|
|
//Load Raw
|
|
#define FSOUND_RAWLOAD (FSOUND_LOADRAW | FSOUND_LOADMEMORY)
|
|
//Load Sample Raw from pointer
|
|
#define FSOUND_DOOMLOAD (FSOUND_UNORMAL | FSOUND_RAWLOAD)
|
|
//length of SFX
|
|
#define SFXLENGTH (sfx->length-8)
|
|
|
|
//SRB2 treats +X as east, +Y as north, +Z as up.
|
|
//FSOUND treats +X as right, +Y as up, and +Z as forwards.
|
|
//So SRB2's XZY is FSOUND's XYZ
|
|
//And FSOUND's XZY is SRB2's XYZ
|
|
|
|
static I_Error_t I_ErrorFMOD = NULL;
|
|
|
|
static FSOUND_SAMPLE *blankfmsample = NULL;
|
|
|
|
// Calculate sound pitching
|
|
static float recalc_pitch(INT32 doom_pitch)
|
|
{
|
|
#ifdef MORESTUFF
|
|
return (float)1;
|
|
#else
|
|
return doom_pitch < NORMAL_PITCH ?
|
|
(float)(doom_pitch + NORMAL_PITCH) / (NORMAL_PITCH * 2)
|
|
:(float)doom_pitch / (float)NORMAL_PITCH;
|
|
#endif
|
|
}
|
|
|
|
/***************************************************************
|
|
*
|
|
* DBG_Printf
|
|
* Output error messages to debug log if DEBUG_TO_FILE is defined,
|
|
* else do nothing
|
|
*
|
|
**************************************************************
|
|
*/
|
|
// -----------------+
|
|
// DBG_Printf : Output error messages to debug log if DEBUG_TO_FILE is defined,
|
|
// : else do nothing
|
|
// Returns :
|
|
// -----------------+
|
|
FUNCPRINTF void DBG_Printf(const char *lpFmt, ...)
|
|
{
|
|
#ifdef DEBUG_TO_FILE
|
|
char str[4096] = "";
|
|
va_list arglist;
|
|
|
|
va_start(arglist, lpFmt);
|
|
vsnprintf(str, 4096, lpFmt, arglist);
|
|
va_end(arglist);
|
|
|
|
if (logstream)
|
|
fwrite(str, strlen(str), 1, logstream);
|
|
#endif
|
|
}
|
|
|
|
// Start of head_relative system for FMOD3D
|
|
|
|
typedef struct rellistener_s
|
|
{
|
|
float pos[3];
|
|
INT32 active;
|
|
float vel[3];
|
|
|
|
} rellistener_s_t; //Easy
|
|
|
|
static rellistener_s_t rellistener[2]; //The 2 listeners
|
|
|
|
typedef struct relarray_s
|
|
{
|
|
INT32 handle; // handle number
|
|
INT32 chan; // real channel
|
|
INT32 listener; // for which listener
|
|
rellistener_s_t pos; // source position in 3D
|
|
} relarray_s_t;
|
|
|
|
static relarray_s_t relarray[STATIC_SOURCES_NUM+1]; // array of chans
|
|
|
|
|
|
//set listener
|
|
static void relset(INT32 which)
|
|
{
|
|
INT32 i;
|
|
|
|
if (which == -2 || which == -1)
|
|
{
|
|
which = -which;
|
|
|
|
memset(&rellistener[which-1], 0, sizeof (rellistener_s_t)); //Delete me
|
|
for (i = 0; i <= STATIC_SOURCES_NUM; i++)
|
|
{
|
|
if (relarray[i].pos.active && relarray[i].listener == which)
|
|
{
|
|
FSOUND_SetPaused(relarray[i].chan,true);
|
|
relarray[i].pos.active = false;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
else if (which == 1 || which ==2)
|
|
{
|
|
float pos[3], vel[3]; // Temp bin
|
|
which -= 1; //Hello!
|
|
|
|
//Get update
|
|
FSOUND_3D_Listener_GetAttributes(&pos[0],&vel[0],NULL,NULL,NULL,NULL,NULL,NULL);
|
|
memcpy(&rellistener[which].pos[0],&pos[0],sizeof (pos));
|
|
memcpy(&rellistener[which].vel[0],&vel[0],sizeof (vel));
|
|
|
|
if (!rellistener[which].active)
|
|
for (i = 0; i <= STATIC_SOURCES_NUM; i++)
|
|
{
|
|
if (!relarray[i].pos.active && relarray[i].listener == which)
|
|
{
|
|
FSOUND_SetPaused(relarray[i].chan,false);
|
|
relarray[i].pos.active = true;
|
|
}
|
|
}
|
|
|
|
rellistener[which].active = which;
|
|
}
|
|
else
|
|
{
|
|
memset(&rellistener[0], 0, sizeof (rellistener_s_t));
|
|
memset(&rellistener[1], 0, sizeof (rellistener_s_t));
|
|
}
|
|
}
|
|
|
|
//setup system
|
|
static void relsetup()
|
|
{
|
|
INT32 i;
|
|
|
|
// Setup the rel array for use
|
|
for (i = 0; i <= STATIC_SOURCES_NUM; i++)
|
|
{
|
|
relarray[i].handle = FSOUND_FREE;
|
|
relarray[i].chan = FSOUND_FREE;
|
|
relarray[i].listener = (i == 1 || i == 3)?2:1;
|
|
memset(&relarray[i].pos, 0, sizeof (rellistener_s_t));
|
|
}
|
|
|
|
// Set up the Listener array
|
|
relset(0);
|
|
}
|
|
|
|
|
|
//checkup for stack
|
|
static INT32 relstack(INT32 chan)
|
|
{
|
|
INT32 i;
|
|
|
|
for (i = 0; i <= STATIC_SOURCES_NUM; i++)
|
|
{
|
|
if (relarray[i].pos.active && relarray[i].handle == chan)
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
//checkup for fake rel chan
|
|
static INT32 relcheckup(INT32 chan)
|
|
{
|
|
INT32 i = relstack(chan);
|
|
|
|
if (i == -1)
|
|
return chan;
|
|
else
|
|
return relarray[i].chan;
|
|
}
|
|
|
|
//Update place rel chan's vol
|
|
static void relvol(INT32 chan)
|
|
{
|
|
INT32 vol = FSOUND_GetVolume(chan);
|
|
INT32 error = FSOUND_GetError();
|
|
|
|
if (chan == relcheckup(chan))
|
|
return;
|
|
|
|
if (!vol && error)
|
|
DBG_Printf("FMOD(relvol, FSOUND_GetVolume, Channel # %i): %s\n",chan,FMOD_ErrorString(error));
|
|
else if (!FSOUND_SetVolume(relcheckup(chan), vol))
|
|
DBG_Printf("FMOD(relvol, FSOUND_SetVolume, Channel # %i): %s\n",chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
|
|
//Copy rel chan
|
|
static INT32 relcopy(INT32 handle)
|
|
{
|
|
FSOUND_SAMPLE *fmsample = NULL;
|
|
INT32 chan = -1;
|
|
float pos[3];
|
|
float vel[3];
|
|
|
|
if (!FSOUND_3D_GetAttributes(handle,&pos[0],&vel[0]))
|
|
if (FSOUND_GetError() != FMOD_ERR_NONE) DBG_Printf("FMOD(relcopy, FSOUND_3D_GetAttributes, Channel # %i): %s\n",handle,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
fmsample = FSOUND_GetCurrentSample(handle);
|
|
|
|
if (fmsample)
|
|
{
|
|
#ifdef REL2D
|
|
if (!FSOUND_Sample_SetMode(fmsample, FSOUND_2D))
|
|
DBG_Printf("FMOD(relcopy, FSOUND_Sample_SetMode, handle# %i): %s\n",handle,FMOD_ErrorString(FSOUND_GetError()));
|
|
#endif
|
|
chan = FSOUND_PlaySoundEx(FSOUND_FREE,fmsample,NULL,true);
|
|
|
|
if (chan == -1)
|
|
{
|
|
if (FSOUND_GetError() != FMOD_ERR_NONE) DBG_Printf("FMOD(relcopy, FSOUND_PlaySoundEx, handle# %i): %s\n",handle,FMOD_ErrorString(FSOUND_GetError()));
|
|
return FSOUND_FREE;
|
|
}
|
|
#ifdef MORESTUFF
|
|
else
|
|
DBG_Printf("FMOD(relcopy, Main): Copy Handle#%i to channel#%i\n",handle,chan);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
if (FSOUND_GetError() != FMOD_ERR_NONE)
|
|
DBG_Printf("FMOD(relcopy, FSOUND_GetCurrentSample, handle# %i): %s\n",handle,FMOD_ErrorString(FSOUND_GetError()));
|
|
chan = FSOUND_PlaySoundEx(FSOUND_FREE,blankfmsample,NULL,true);
|
|
//return FSOUND_FREE;
|
|
}
|
|
|
|
if (FSOUND_GetCurrentSample(chan))
|
|
{
|
|
|
|
if (!FSOUND_SetCurrentPosition(chan, 0))
|
|
DBG_Printf("FMOD(relcopy, FSOUND_SetCurrentPosition, handle#%i, channel# %i): %s\n",handle,chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
#ifndef REL2D
|
|
if (!FSOUND_3D_SetAttributes(chan,pos,vel))
|
|
DBG_Printf("FMOD(relcopy, FSOUND_3D_SetAttributes, handle#%i, channel#%i): %s\n",handle,chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
#endif
|
|
/*
|
|
if (!FSOUND_SetReserved(chan, TURE))
|
|
DBG_Printf("FMOD(relcopy, FSOUND_SetReserved, handle#%i, channel# %i): %s\n",handle,chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
*/
|
|
return chan;
|
|
}
|
|
|
|
return FSOUND_FREE;
|
|
}
|
|
|
|
//update the rel chans
|
|
static void relupdate(INT32 handle)
|
|
{
|
|
if (handle == FSOUND_FREE)
|
|
{
|
|
INT32 stack;
|
|
|
|
for (stack = 0; stack <= STATIC_SOURCES_NUM;stack++)
|
|
{
|
|
//if (FSOUND_GetCurrentSample(relarray[stack].handle))
|
|
// relarray[stack].chan = relcopy(relarray[stack].handle);
|
|
|
|
if (relarray[stack].chan != FSOUND_FREE)
|
|
{
|
|
relarray[stack].pos.active = false;
|
|
relupdate(relarray[stack].chan);
|
|
}
|
|
else
|
|
relarray[stack].pos.active = false;
|
|
}
|
|
}
|
|
else if (handle == relcheckup(handle))
|
|
return;
|
|
#ifndef REL2D
|
|
else
|
|
{
|
|
float pos[3], vel[3];
|
|
INT32 stack = relstack(handle);
|
|
INT32 chan = relcheckup(handle);
|
|
INT32 which = relarray[stack].listener;
|
|
|
|
pos[0] = relarray[stack].pos.pos[0] + rellistener[which].pos[0];
|
|
pos[1] = relarray[stack].pos.pos[1] + rellistener[which].pos[1];
|
|
pos[2] = relarray[stack].pos.pos[2] + rellistener[which].pos[2];
|
|
vel[0] = relarray[stack].pos.vel[0] + rellistener[which].vel[0];
|
|
vel[1] = relarray[stack].pos.vel[1] + rellistener[which].vel[1];
|
|
vel[2] = relarray[stack].pos.vel[2] + rellistener[which].vel[2];
|
|
|
|
if (!FSOUND_3D_SetAttributes(chan,pos,vel))
|
|
DBG_Printf("FMOD(relupdate, FSOUND_3D_SetAttributes, Handle #%i,Channel #%i): %s\n",handle, chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
//Update place rel chan's pos
|
|
static void relplace(INT32 chan)
|
|
{
|
|
float pos[3], vel[3]; // Temp bin
|
|
|
|
if (chan == relcheckup(chan))
|
|
return;
|
|
|
|
if (!FSOUND_3D_GetAttributes(chan,&pos[0],&vel[0]))
|
|
{
|
|
if (FSOUND_GetError() != FMOD_ERR_NONE) DBG_Printf("FMOD(relplace, FSOUND_3D_GetAttributes, Channel # %i): %s\n",chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
else
|
|
{
|
|
INT32 stack = relstack(chan);
|
|
|
|
if (stack == -1)
|
|
return;
|
|
|
|
memcpy(&relarray[stack].pos.pos,&pos,sizeof (pos));
|
|
memcpy(&relarray[stack].pos.vel,&vel,sizeof (vel));
|
|
relupdate(chan);
|
|
}
|
|
}
|
|
|
|
//New rel chan
|
|
static void reladd(INT32 chan)
|
|
{
|
|
if (chan != relcheckup(chan))
|
|
return;
|
|
else
|
|
{
|
|
INT32 stack = STATIC_SOURCES_NUM;
|
|
{
|
|
if (relarray[0].handle == FSOUND_FREE)
|
|
stack = 0;
|
|
else if (relarray[1].handle == FSOUND_FREE)
|
|
stack = 1;
|
|
else if (relarray[2].handle == FSOUND_FREE)
|
|
stack = 2;
|
|
else if (relarray[3].handle == FSOUND_FREE)
|
|
stack = 3;
|
|
else if (relarray[4].handle == FSOUND_FREE)
|
|
stack = 4;
|
|
else if (relarray[5].handle == FSOUND_FREE)
|
|
stack = 5;
|
|
else
|
|
DBG_Printf("No more room in relarray\n");
|
|
}
|
|
|
|
relarray[stack].handle = chan;
|
|
relarray[stack].chan = relcopy(chan);
|
|
|
|
if (relarray[stack].chan != FSOUND_FREE)
|
|
{
|
|
relarray[stack].pos.active = true;
|
|
relupdate(chan);
|
|
}
|
|
else
|
|
relarray[stack].pos.active = false;
|
|
}
|
|
}
|
|
|
|
// End of head_relative system for FMOD3D
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Initialise driver and listener
|
|
*
|
|
*****************************************************************************/
|
|
EXPORT INT32 HWRAPI(Startup) (I_Error_t FatalErrorFunction, snddev_t *snd_dev)
|
|
{
|
|
boolean inited = false;
|
|
INT32 i = 0;
|
|
|
|
I_ErrorFMOD = FatalErrorFunction;
|
|
|
|
if (FSOUND_GetVersion() < FMOD_VERSION)
|
|
{
|
|
DBG_Printf("Error : You are using the wrong DLL version!\nYou should be using FMOD %.02f\n", FMOD_VERSION);
|
|
return inited;
|
|
}
|
|
else
|
|
DBG_Printf("S_FMOD Init(): FMOD_SOUND driver for SRB2 %s\n",VERSIONSTRING);
|
|
|
|
if (!FSOUND_SetMinHardwareChannels(STATIC_SOURCES_NUM*4))
|
|
DBG_Printf("FMOD(Startup,FSOUND_SetMinHardwareChannels,# of Channels Min: %i): %s\n",STATIC_SOURCES_NUM*4, FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_SetMaxHardwareChannels(0))
|
|
DBG_Printf("FMOD(Startup,FSOUND_SetMaxHardwareChannels,# of Channels Min: %i): %s\n",0, FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
for (i = 0; i < FSOUND_GetNumDrivers(); i++)
|
|
{
|
|
UINT32 caps = 0;
|
|
DBG_Printf("Driver Caps, if any\n");
|
|
|
|
if (FSOUND_GetDriverCaps(i, &caps))
|
|
{
|
|
DBG_Printf("FMOD: Driver# %d - %s\n", i+1, FSOUND_GetDriverName(i)); // print driver names
|
|
if (caps & FSOUND_CAPS_HARDWARE)
|
|
DBG_Printf("This sound hardware supports hardware accelerated 3d sound.\n");
|
|
|
|
if (caps & FSOUND_CAPS_EAX2)
|
|
DBG_Printf("This sound hardware supports hardware accelerated 3d sound with EAX 2 reverb.\n");
|
|
|
|
if (caps & FSOUND_CAPS_EAX3)
|
|
DBG_Printf("This sound hardware supports hardware accelerated 3d sound with EAX 3 reverb.\n");
|
|
}
|
|
else
|
|
DBG_Printf("FMOD(Startup,FSOUND_GetDriverCaps,%s): %s\n",FSOUND_GetDriverName(i), FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
#if defined (_WIN32) || defined (_WIN64)
|
|
if (!FSOUND_SetHWND(snd_dev->hWnd))
|
|
{
|
|
DBG_Printf("FMOD(Startup,FSOUND_SetHWND): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
return inited;
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
DBG_Printf("Initialising FMOD %.02f\n",FMOD_VERSION);
|
|
inited = FSOUND_Init(snd_dev->sample_rate,MAXCHANNEL,0);
|
|
}
|
|
|
|
if (!inited)
|
|
{
|
|
DBG_Printf("FMOD(Startup,Main): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
else
|
|
{
|
|
#ifdef OLDFMOD
|
|
DBG_Printf(" Maximum hardware mixing buffers %d\n", FSOUND_GetNumHardwareChannels());
|
|
#else
|
|
INT32 num2DC, num3DC, numDC;
|
|
|
|
if (FSOUND_GetNumHWChannels(&num2DC,&num3DC,&numDC))
|
|
{
|
|
DBG_Printf(" Maximum hardware 2D buffers %d\n", num2DC);
|
|
DBG_Printf(" Maximum hardware 3D buffers %d\n", num3DC);
|
|
DBG_Printf(" Maximum hardware mixing buffers %d\n", numDC);
|
|
}
|
|
else
|
|
DBG_Printf("FMOD(Startup,FSOUND_GetNumHWChannels): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
#endif
|
|
|
|
DBG_Printf("FMOD is up and running at %i KHZ\n",FSOUND_GetOutputRate());
|
|
DBG_Printf("Sound hardware capabilities:\n");
|
|
|
|
if (FSOUND_GetDriverName(FSOUND_GetDriver()))
|
|
DBG_Printf(" Driver is %s\n",FSOUND_GetDriverName(FSOUND_GetDriver()));
|
|
else
|
|
DBG_Printf("FMOD(Startup,FSOUND_GetDriverName): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
FSOUND_3D_SetDistanceFactor(1.0f/72.0f);
|
|
FSOUND_3D_SetRolloffFactor(0);
|
|
FSOUND_3D_SetRolloffFactor(1.6f);
|
|
#ifdef MORESTUFF
|
|
FSOUND_3D_SetDopplerFactor(0);
|
|
#endif
|
|
|
|
switch (FSOUND_GetOutput())
|
|
{
|
|
case FSOUND_OUTPUT_NOSOUND:
|
|
DBG_Printf("FMOD driver: NoSound driver, all calls to this succeed but do nothing.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_WINMM:
|
|
DBG_Printf("FMOD driver: Windows Multimedia driver.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_DSOUND:
|
|
DBG_Printf("FMOD driver: DirectSound driver. You need this to get EAX2 or EAX3 support, or FX api support.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_A3D:
|
|
DBG_Printf("FMOD driver: A3D driver.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_XBOX:
|
|
DBG_Printf("FMOD driver: Xbox driver\n");
|
|
break;
|
|
case FSOUND_OUTPUT_OSS:
|
|
DBG_Printf("FMOD driver: Linux/Unix OSS (Open Sound System) driver, i.e. the kernel sound drivers.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_ESD:
|
|
DBG_Printf("FMOD driver: Linux/Unix ESD (Enlightment Sound Daemon) driver.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_ALSA:
|
|
DBG_Printf("FMOD driver: Linux Alsa driver.\n");
|
|
break;
|
|
case FSOUND_OUTPUT_MAC:
|
|
DBG_Printf("FMOD driver: Mac SoundManager driver\n");
|
|
break;
|
|
case FSOUND_OUTPUT_PS2:
|
|
DBG_Printf("FMOD driver: PlayStation 2 driver\n");
|
|
break;
|
|
case FSOUND_OUTPUT_GC:
|
|
DBG_Printf("FMOD driver: Gamecube driver\n");
|
|
break;
|
|
case FSOUND_OUTPUT_NOSOUND_NONREALTIME:
|
|
DBG_Printf("FMOD driver: This is the same as nosound, but the sound generation is driven by FSOUND_Update\n");
|
|
break;
|
|
case FSOUND_OUTPUT_ASIO:
|
|
DBG_Printf("FMOD driver: Low latency ASIO driver\n");
|
|
break;
|
|
default:
|
|
DBG_Printf("FMOD driver: Unknown Sound Driver\n");
|
|
break;
|
|
}
|
|
|
|
relsetup();
|
|
|
|
blankfmsample = FSOUND_Sample_Alloc(FSOUND_UNMANAGED,1,FSOUND_UNORMAL,11025,127,FSOUND_STEREOPAN,127);
|
|
|
|
if (!blankfmsample)
|
|
DBG_Printf("FMOD(Startup,FSOUND_Sample_Alloc): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
else if (!FSOUND_Sample_SetMaxPlaybacks(blankfmsample,STATIC_SOURCES_NUM*2))
|
|
DBG_Printf("FMOD(Startup,FSOUND_Sample_SetMaxPlaybacks): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
return inited;
|
|
}
|
|
|
|
EXPORT void HWRAPI(Shutdown) (void)
|
|
{
|
|
DBG_Printf("Shuting down FMOD\n");
|
|
FSOUND_Sample_Free(blankfmsample);
|
|
DBG_Printf("Shutdown of FMOD done\n");
|
|
FSOUND_Close();
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Creates 3D source
|
|
*
|
|
******************************************************************************/
|
|
|
|
EXPORT INT32 HWRAPI (Add3DSource) (source3D_data_t *src, sfx_data_t *sfx)
|
|
{
|
|
FSOUND_SAMPLE *fmsample = NULL;
|
|
INT32 chan = -1;
|
|
float pos[3];
|
|
float vel[3];
|
|
#ifdef MORESTUFF
|
|
src->min_distance = MIN_DISTANCE;
|
|
src->max_distance = MAX_DISTANCE;
|
|
#endif
|
|
|
|
pos[0] = src->pos.x;
|
|
pos[1] = src->pos.z;
|
|
pos[2] = src->pos.y;
|
|
vel[0] = src->pos.momx;
|
|
vel[1] = src->pos.momz;
|
|
vel[2] = src->pos.momy;
|
|
if (sfx)
|
|
fmsample = FSOUND_Sample_Load(FSOUND_FREE, INT2CHAR(sfx->data), FSOUND_DOOMLOAD, SFXLENGTH);
|
|
else
|
|
fmsample = blankfmsample;
|
|
|
|
if (fmsample)
|
|
{
|
|
if (sfx && !FSOUND_Sample_SetDefaults(fmsample,
|
|
(INT32)((*((UINT16 *)sfx->data+1))*recalc_pitch(sfx->pitch)),
|
|
(sfx->volume == -1 ? 255 : sfx->volume),
|
|
(sfx->sep == NORMAL_SEP ? FSOUND_STEREOPAN : sfx->sep),
|
|
(sfx->priority)
|
|
)
|
|
)
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_Sample_SetDefaults, SFX's ID# %i): %s\n", sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
#if 0
|
|
if (!FSOUND_Sample_SetMinMaxDistance(fmsample, src->min_distance, src->max_distance))
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_Sample_SetMinMaxDistance, SFX's ID# %i): %s\n", sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
#endif
|
|
chan = FSOUND_PlaySoundEx(FSOUND_FREE,fmsample,NULL,true);
|
|
|
|
if (chan == -1)
|
|
{
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_PlaySoundEx, SFX's ID# %i): %s\n",sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
return chan;
|
|
}
|
|
else
|
|
{
|
|
if (!sfx)
|
|
DBG_Printf("FMOD(Add3DSource, Main): Added blank-sound added to channel %i\n",chan);
|
|
#ifdef MORESTUFF
|
|
else DBG_Printf("FMOD(Add3DSource, Main): Added sfxid# %i added to channel %i\n",sfx->id,chan);
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (sfx)
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_Sample_Load, sfxid# %i): %s\n",sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
else
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_Sample_Alloc): %s\n", FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
return chan;
|
|
}
|
|
|
|
if (FSOUND_GetCurrentSample(chan))
|
|
{
|
|
if (!FSOUND_SetCurrentPosition(chan, 0))
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_SetCurrentPosition, channel %i, sfxid# %i): %s\n", chan,sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_3D_SetAttributes(chan,pos,vel))
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_3D_SetAttributes, channel %i, sfxid# %i): %s\n", chan,sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_SetReserved(chan, (signed char)src->permanent))
|
|
DBG_Printf("FMOD(Add3DSource, FSOUND_SetReserved, channel %i, sfxid# %i): %s\n", chan,sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (src->head_relative) reladd(chan);
|
|
}
|
|
|
|
return chan;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Creates 2D (stereo) source
|
|
*
|
|
******************************************************************************/
|
|
EXPORT INT32 HWRAPI (Add2DSource) (sfx_data_t *sfx)
|
|
{
|
|
FSOUND_SAMPLE *fmsample = NULL;
|
|
INT32 chan = -1;
|
|
|
|
if (!sfx)
|
|
return chan;
|
|
|
|
fmsample = FSOUND_Sample_Load(FSOUND_FREE, INT2CHAR(sfx->data), FSOUND_DOOMLOAD, SFXLENGTH);
|
|
|
|
if (fmsample)
|
|
{
|
|
if (!FSOUND_Sample_SetDefaults(fmsample,
|
|
(INT32)((float)(*((UINT16 *)sfx->data+1)) * recalc_pitch(sfx->pitch)),
|
|
sfx->volume == -1 ? 255 : sfx->volume,
|
|
sfx->sep == NORMAL_SEP ? FSOUND_STEREOPAN : sfx->sep,
|
|
sfx->priority))
|
|
DBG_Printf("FMOD(Add2DSource, FSOUND_Sample_SetDefaults, sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_Sample_SetMode(fmsample,FSOUND_2D))
|
|
DBG_Printf("FMOD(Add2DSource, FSOUND_Sample_SetMode, sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
chan = FSOUND_PlaySoundEx(FSOUND_FREE,fmsample,NULL,true);
|
|
|
|
if (chan == -1)
|
|
{
|
|
DBG_Printf("FMOD(Add2DSource, FSOUND_PlaySoundEx, sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
return chan;
|
|
}
|
|
#ifdef MORESTUFF
|
|
else DBG_Printf("FMOD(Add2DSource, FSOUND_PlaySoundEx): sfxid# %i is playing on channel %i\n", sfx->id,chan);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
DBG_Printf("FMOD(Add2DSource,FSOUND_Sample_Load, sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
return chan;
|
|
}
|
|
|
|
if (FSOUND_GetCurrentSample(chan))
|
|
{
|
|
if (!FSOUND_SetCurrentPosition(chan, 0))
|
|
DBG_Printf("FMOD(Add2DSource, FSOUND_SetCurrentPosition, channel %i, sfxid# %i): %s\n", chan,sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
|
|
return chan;
|
|
}
|
|
|
|
EXPORT INT32 HWRAPI (StartSource) (INT32 chan)
|
|
{
|
|
FSOUND_SAMPLE *fmsample;
|
|
if (chan < 0)
|
|
return -1;
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (!fmsample)
|
|
return -1;
|
|
|
|
#ifdef MORESTUFF
|
|
if (FSOUND_Sample_GetMode(fmsample) & FSOUND_2D)
|
|
{
|
|
DBG_Printf("FMOD(StartSource,Main): Starting 2D channel %i?\n",chan);
|
|
//return -1;
|
|
}
|
|
else
|
|
{
|
|
DBG_Printf("FMOD(StartSource,Main): Starting 3D Channel %i?\n",chan);
|
|
//return -1;
|
|
}
|
|
#endif
|
|
|
|
if (FSOUND_GetPaused(relcheckup(chan)))
|
|
{
|
|
if (!FSOUND_SetPaused(relcheckup(chan), false))
|
|
DBG_Printf("FMOD(StartSource,FSOUND_SetPaused, channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
else if (relstack(chan) != -1)
|
|
relarray[relstack(chan)].pos.active = false;
|
|
}
|
|
else
|
|
DBG_Printf("FMOD(StartSource,FSOUND_GetPaused): Channel %i is playing already",chan);
|
|
|
|
return chan;
|
|
}
|
|
|
|
EXPORT void HWRAPI (StopSource) (INT32 chan)
|
|
{
|
|
FSOUND_SAMPLE *fmsample;
|
|
|
|
if (chan < 0)
|
|
return;
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (!fmsample)
|
|
return;
|
|
|
|
if (!FSOUND_GetPaused(relcheckup(chan)))
|
|
{
|
|
if (!FSOUND_SetPaused(relcheckup(chan),true))
|
|
{
|
|
DBG_Printf("FMOD(StopSource,FSOUND_SetPaused, channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
else if (relstack(chan) != -1)
|
|
{
|
|
relarray[relstack(chan)].pos.active = false;
|
|
}
|
|
}
|
|
#ifdef MORESTUFF
|
|
else
|
|
DBG_Printf("FMOD(StopSource,FSOUND_GetPaused): Channel %i is stopped already\n",chan);
|
|
#endif
|
|
}
|
|
|
|
EXPORT INT32 HWRAPI (GetHW3DSVersion) (void)
|
|
{
|
|
return VERSION;
|
|
}
|
|
|
|
EXPORT void HWRAPI (BeginFrameUpdate) (void)
|
|
{
|
|
FSOUND_Update();
|
|
}
|
|
|
|
EXPORT void HWRAPI (EndFrameUpdate) (void)
|
|
{
|
|
relupdate(FSOUND_FREE);
|
|
}
|
|
|
|
EXPORT INT32 HWRAPI (IsPlaying) (INT32 chan)
|
|
{
|
|
if (chan < 0)
|
|
return false;
|
|
|
|
if (!FSOUND_GetCurrentSample(chan))
|
|
return false;
|
|
|
|
return FSOUND_IsPlaying(relcheckup(chan));
|
|
}
|
|
|
|
/******************************************************************************
|
|
* UpdateListener
|
|
*
|
|
* Set up main listener properties:
|
|
* - position
|
|
* - orientation
|
|
* - velocity
|
|
*****************************************************************************/
|
|
EXPORT void HWRAPI (UpdateListener) (listener_data_t *data)
|
|
{
|
|
if (data)
|
|
{
|
|
float pos[3];
|
|
float vel[3];
|
|
double f_angle = 0;
|
|
if (data->f_angle) f_angle = (data->f_angle) / 180 * M_PI;
|
|
pos[0] = (float)data->x;
|
|
pos[1] = (float)data->z;
|
|
pos[2] = (float)data->y;
|
|
vel[0] = (float)data->momx;
|
|
vel[1] = (float)data->momz;
|
|
vel[2] = (float)data->momy;
|
|
|
|
FSOUND_3D_Listener_SetAttributes(pos,vel,(float)cos(f_angle),0.0f,(float)sin(f_angle), 0.0f , 1.0f, 0.0f);
|
|
relset(1);
|
|
}
|
|
else
|
|
{
|
|
relset(-1);
|
|
DBG_Printf("Error: 1st listener data is missing\n");
|
|
}
|
|
}
|
|
|
|
EXPORT void HWRAPI (UpdateListener2) (listener_data_t *data)
|
|
{
|
|
if (data)
|
|
{
|
|
float pos[3];
|
|
float vel[3];
|
|
double f_angle = 0;
|
|
if (data->f_angle) f_angle = (data->f_angle) / 180 * M_PI;
|
|
pos[0] = (float)data->x;
|
|
pos[1] = (float)data->z;
|
|
pos[2] = (float)data->y;
|
|
vel[0] = (float)data->momx;
|
|
vel[1] = (float)data->momz;
|
|
vel[2] = (float)data->momy;
|
|
|
|
FSOUND_3D_Listener_SetCurrent(1,2);
|
|
FSOUND_3D_Listener_SetAttributes(pos,vel,(float)cos(f_angle),0.0f,(float)sin(f_angle), 0.0f , 1.0f, 0.0f);
|
|
relset(2);
|
|
FSOUND_3D_Listener_SetCurrent(0,2);
|
|
}
|
|
else
|
|
{
|
|
relset(-2);
|
|
FSOUND_3D_Listener_SetCurrent(0,1);
|
|
}
|
|
}
|
|
|
|
EXPORT void HWRAPI (UpdateSourceVolume) (INT32 chan, INT32 vol)
|
|
{
|
|
if (chan < 0)
|
|
return;
|
|
|
|
if (!FSOUND_GetCurrentSample(chan))
|
|
return;
|
|
|
|
if (!FSOUND_SetVolume(chan,vol))
|
|
DBG_Printf("FMOD(UpdateSourceVolume, FSOUND_SetVolume, channel %i to volume %i): %s\n", chan,vol,FMOD_ErrorString(FSOUND_GetError()));
|
|
else
|
|
{
|
|
#ifdef MORESTUFF
|
|
DBG_Printf("FMOD(UpdateSourceVolume, Main): channel %i is set to the volume of %i", chan,vol);
|
|
#endif
|
|
relvol(chan);
|
|
}
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Update volume and separation (panning) of 2D source
|
|
*
|
|
*****************************************************************************/
|
|
EXPORT void HWRAPI (Update2DSoundParms) (INT32 chan, INT32 vol, INT32 sep)
|
|
{
|
|
FSOUND_SAMPLE *fmsample;
|
|
|
|
if (chan < 0)
|
|
return;
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (fmsample)
|
|
{
|
|
if (!FSOUND_Sample_GetMode(fmsample) & FSOUND_2D)
|
|
{
|
|
DBG_Printf("FMOD(Update2DSoundParms,Main): 2D Vol/Pan on 3D channel %i?\n",chan);
|
|
//return;
|
|
}
|
|
}
|
|
else
|
|
return;
|
|
|
|
if (!FSOUND_SetPaused(chan, true))
|
|
DBG_Printf("FMOD(Update2DSoundParms, FSOUND_SetPaused, Pause, channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_SetVolume(chan,vol))
|
|
DBG_Printf("FMOD(Update2DSoundParms, , channel %i to volume %i): %s\n", chan,vol,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_SetPan(chan, sep == NORMAL_SEP ? FSOUND_STEREOPAN : sep))
|
|
DBG_Printf("FMOD(Update2DSoundParms, FSOUND_SetPan, channel %i to sep %i): %s\n", chan,sep,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_SetPaused(chan, false))
|
|
DBG_Printf("FMOD(Update2DSoundParms, FSOUND_SetPaused, Resume, channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
|
|
// --------------------------------------------------------------------------
|
|
// Set the global volume for sound effects
|
|
// --------------------------------------------------------------------------
|
|
EXPORT void HWRAPI (SetGlobalSfxVolume) (INT32 vol)
|
|
{
|
|
INT32 realvol = (vol<<3)+(vol>>2);
|
|
|
|
FSOUND_SetSFXMasterVolume(realvol);
|
|
#ifdef MORESTUFF
|
|
DBG_Printf("FMOD(SetGlobalSfxVolume, Main, the volume is set to %i): %s\n", realvol,FMOD_ErrorString(FSOUND_GetError()));
|
|
#endif
|
|
}
|
|
|
|
//Alam_GBC: Not Used?
|
|
EXPORT INT32 HWRAPI (SetCone) (INT32 chan, cone_def_t *cone_def)
|
|
{
|
|
FSOUND_SAMPLE *fmsample;
|
|
|
|
if (chan < 0)
|
|
return -1;
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (fmsample)
|
|
{
|
|
if (FSOUND_Sample_GetMode(fmsample) & FSOUND_2D)
|
|
{
|
|
DBG_Printf("FMOD(Update3DSource,Main): 3D Cone on 2D Channel %i?\n",chan);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if (cone_def)
|
|
{
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
}
|
|
|
|
EXPORT void HWRAPI (Update3DSource) (INT32 chan, source3D_pos_t *sfx)
|
|
{
|
|
float pos[3];
|
|
float vel[3];
|
|
FSOUND_SAMPLE *fmsample;
|
|
|
|
pos[0] = sfx->x;
|
|
pos[1] = sfx->z;
|
|
pos[2] = sfx->y;
|
|
vel[0] = sfx->momx;
|
|
vel[1] = sfx->momz;
|
|
vel[2] = sfx->momy;
|
|
if (chan < 0)
|
|
return;
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (!fmsample)
|
|
return;
|
|
|
|
if (fmsample)
|
|
{
|
|
if (FSOUND_Sample_GetMode(fmsample) & FSOUND_2D)
|
|
{
|
|
//DBG_Printf("FMOD(Update3DSource,Main): 3D Pos/Vel on 2D Channel %i?\n",chan);
|
|
//return;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!FSOUND_3D_SetAttributes(chan,pos,vel))
|
|
DBG_Printf("FMOD(Update3DSource,FSOUND_3D_SetAttributes, onto channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
else
|
|
relplace(chan);
|
|
}
|
|
|
|
//-------------------------------------------------------------
|
|
// Load new sound data into source
|
|
//-------------------------------------------------------------
|
|
EXPORT INT32 HWRAPI (Reload3DSource) (INT32 handle, sfx_data_t *sfx)
|
|
{
|
|
source3D_data_t src;
|
|
float pos[3], vel[3];
|
|
INT32 chan = relcheckup(handle);
|
|
FSOUND_SAMPLE *fmsample;
|
|
|
|
if (handle < 0 || !sfx)
|
|
return -1;
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (!fmsample)
|
|
return -1;
|
|
|
|
if (FSOUND_Sample_GetMode(fmsample) & FSOUND_2D)
|
|
{
|
|
DBG_Printf("FMOD(Reload3DSource,Main): New 3D Sound on 2D Channel %i?\n",handle);
|
|
return -1;
|
|
}
|
|
#ifdef MORESTUFF
|
|
else
|
|
DBG_Printf("FMOD(Reload3DSource, Main, sending new sfx# %i to chan %i)\n",sfx->id,handle);
|
|
#endif
|
|
|
|
#ifdef OLDFMOD
|
|
src.min_distance = MIN_DISTANCE;
|
|
src.max_distance = MAX_DISTANCE;
|
|
#else
|
|
if (!FSOUND_3D_GetMinMaxDistance(handle,&src.min_distance,&src.min_distance))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_3D_GetMinMaxDistance, channel %i, for sfxid# %i): %s\n",handle, sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
#endif
|
|
src.head_relative = (handle != chan);
|
|
src.permanent = FSOUND_GetReserved(handle);
|
|
if (!FSOUND_3D_GetAttributes(handle,&pos[0],&vel[0]))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_3D_GetAttributes, channel %i, for sfxid# %i): %s\n",handle,sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
//if (handle == chan)
|
|
{
|
|
if (fmsample != blankfmsample) FSOUND_Sample_Free(fmsample);
|
|
}
|
|
//else
|
|
{
|
|
// fmsample = FSOUND_GetCurrentSample(handle);
|
|
}
|
|
|
|
fmsample = FSOUND_Sample_Load(FSOUND_FREE, INT2CHAR(sfx->data), FSOUND_DOOMLOAD, SFXLENGTH);
|
|
|
|
if (!FSOUND_StopSound(chan))
|
|
DBG_Printf("FMOD(Reload3DSource,FSOUND_StopSound, of channel %i for sfxid# %i): %s\n", handle,sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (fmsample)
|
|
{
|
|
if (!FSOUND_Sample_SetDefaults(fmsample,
|
|
(INT32)((float)(*((UINT16 *)sfx->data+1)) * recalc_pitch(sfx->pitch)),
|
|
sfx->volume == -1 ? 255 : sfx->volume,
|
|
sfx->sep == NORMAL_SEP ? FSOUND_STEREOPAN : sfx->sep,
|
|
sfx->priority))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_Sample_SetDefaults, for sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_Sample_SetMinMaxDistance(fmsample, src.min_distance, src.max_distance))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_Sample_SetMinMaxDistance, SFX's ID# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
chan = FSOUND_PlaySoundEx(chan,fmsample,NULL,true);
|
|
|
|
if (chan == -1)
|
|
{
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_PlaySoundEx, for sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
return chan;
|
|
}
|
|
|
|
if (FSOUND_GetCurrentSample(chan))
|
|
{
|
|
if (!FSOUND_SetCurrentPosition(chan, 0))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_SetCurrentPosition, channel %i, sfxid# %i): %s\n", chan,sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_3D_SetAttributes(chan,pos,vel))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_3D_SetAttributes, channel %i, sfxid# %i): %s\n", chan,sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (!FSOUND_SetReserved(chan, (signed char)src.permanent))
|
|
DBG_Printf("FMOD(Reload3DSource, FSOUND_SetReserved, channel %i, sfxid# %i): %s\n", chan,sfx?sfx->id:0,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
if (src.head_relative) relupdate(handle);
|
|
}
|
|
}
|
|
else
|
|
DBG_Printf("FMOD(Reload3DSource,FSOUND_Sample_Load, for sfxid# %i): %s\n", sfx->id,FMOD_ErrorString(FSOUND_GetError()));
|
|
|
|
return chan;
|
|
}
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Destroy source and remove it from stack if it is a 2D source.
|
|
* Otherwise put source into cache
|
|
*
|
|
*****************************************************************************/
|
|
EXPORT void HWRAPI (KillSource) (INT32 chan)
|
|
{
|
|
FSOUND_SAMPLE *fmsample;
|
|
INT32 relchan;
|
|
|
|
if (chan < 0)
|
|
return;
|
|
|
|
relchan = relcheckup(chan);
|
|
|
|
fmsample = FSOUND_GetCurrentSample(chan);
|
|
|
|
if (!fmsample)
|
|
return;
|
|
|
|
#ifdef MORESTUFF
|
|
if (FSOUND_IsPlaying(relchan))
|
|
if (!FSOUND_SetLoopMode(relchan, FSOUND_LOOP_OFF))
|
|
DBG_Printf("FMOD(KillSource,FSOUND_SetLoopMode, for channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError())); //Alam_GBC: looping off
|
|
else
|
|
#endif
|
|
if (!FSOUND_StopSound(relchan))
|
|
{
|
|
DBG_Printf("FMOD(KillSource,FSOUND_StopSound, for channel %i): %s\n", chan,FMOD_ErrorString(FSOUND_GetError()));
|
|
}
|
|
#ifdef MORESTUFF
|
|
else DBG_Printf("FMOD(KillSource, Main, for channel %i)\n", chan);
|
|
#endif
|
|
if (fmsample != blankfmsample) FSOUND_Sample_Free(fmsample);
|
|
}
|
|
|
|
#ifdef _WINDOWS
|
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, // handle to DLL module
|
|
DWORD fdwReason, // reason for calling function
|
|
LPVOID lpvReserved) // reserved
|
|
{
|
|
// Perform actions based on the reason for calling.
|
|
UNREFERENCED_PARAMETER(lpvReserved);
|
|
switch (fdwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
// Initialize once for each new process.
|
|
// Return FALSE to fail DLL load.
|
|
#ifdef DEBUG_TO_FILE
|
|
logstream = fopen("s_fmod.log", "wt");
|
|
if (logstream == NULL)
|
|
return FALSE;
|
|
#endif
|
|
DisableThreadLibraryCalls(hinstDLL);
|
|
break;
|
|
|
|
case DLL_THREAD_ATTACH:
|
|
// Do thread-specific initialization.
|
|
break;
|
|
|
|
case DLL_THREAD_DETACH:
|
|
// Do thread-specific cleanup.
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
// Perform any necessary cleanup.
|
|
#ifdef DEBUG_TO_FILE
|
|
if (logstream)
|
|
{
|
|
fclose(logstream);
|
|
logstream = NULL;
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
return TRUE; // Successful DLL_PROCESS_ATTACH.
|
|
}
|
|
#elif !defined (HAVE_SDL)
|
|
|
|
// **************************************************************************
|
|
// FUNCTIONS
|
|
// **************************************************************************
|
|
|
|
EXPORT void _init()
|
|
{
|
|
#ifdef DEBUG_TO_FILE
|
|
logstream = fopen("s_fmod.log","wt");
|
|
#endif
|
|
}
|
|
|
|
EXPORT void _fini()
|
|
{
|
|
#ifdef DEBUG_TO_FILE
|
|
if (logstream)
|
|
fclose(logstream);
|
|
#endif
|
|
}
|
|
#endif
|