888 lines
34 KiB
C
888 lines
34 KiB
C
/*
|
||
//////////////////////////////////////////////////////////////////////////
|
||
// Module SEQUENCE.C //
|
||
//////////////////////////////////////////////////////////////////////////
|
||
*/
|
||
|
||
#include "SNDinc.h"
|
||
|
||
#include "sndres.h"
|
||
#include "sndseq.h"
|
||
#include "sndplay.h"
|
||
#include "sndthrd.h"
|
||
|
||
#if !defined(DISABLE_SEQUENCE) && !defined(NO_ACP_SOUND)
|
||
|
||
/*static int iCurrentSequence;*/
|
||
|
||
typedef struct _tdstInfoPlayingSequence
|
||
{
|
||
unsigned int iCurrentElement;
|
||
}
|
||
tdstInfoPlayingSequence;
|
||
|
||
|
||
/*-----------------------------------*/
|
||
/*- Partie concernant le Sequenceur -*/
|
||
/*-----------------------------------*/
|
||
|
||
#define NB_MAX_SEQUENCE 10
|
||
#define NO_ACTIVE_SEQUENCE -1
|
||
#define OFFSET_SEQ_VOICE 0x2000
|
||
#define MASK_OFFSET_SEQ_VOICE 0x0FFF
|
||
#define NO_SEQUENCE_VOICE 0x1110
|
||
#define MSG_ERR_SEQ "Sequence Device Error"
|
||
#define MSG_ERR_SEQ_FILE "Sequence File Error"
|
||
|
||
|
||
/* instance de l'application, liste principale de ressources*/
|
||
/****************************************/
|
||
#undef CPA_EXPORT
|
||
#if defined(CPA_WANTS_IMPORT)
|
||
#define CPA_EXPORT __declspec(dllimport)
|
||
#elif defined(CPA_WANTS_EXPORT)
|
||
#define CPA_EXPORT __declspec(dllexport)
|
||
#else
|
||
#define CPA_EXPORT
|
||
#endif
|
||
/****************************************/
|
||
/*extern CPA_EXPORT tdstSndPolyResource stMainResList;*/
|
||
|
||
/* Sauvegarde des elements interessant de la ressource active de la sequence*/
|
||
|
||
/*
|
||
typedef struct _tdstSequence {
|
||
SndBool bNoAvailableTrack;
|
||
tduRefRes uRefThisRes;
|
||
//tdstInfoTrackMem stRefCurrentRes;
|
||
tdstInfoTrackList * pstRefResList;
|
||
unsigned long ulNbLoops;
|
||
unsigned long ulStartLoop;
|
||
unsigned long ulEndLoop;
|
||
} tdstSequence;
|
||
*/
|
||
|
||
typedef struct _tdstActiveSequence tdstActiveSequence;
|
||
struct _tdstActiveSequence {
|
||
SndBool_field_decl(bActive); /*en cours de jeu*/
|
||
SndBool_field_decl(bValid); /*encore valide*/
|
||
SndBool_field_decl(bPaused);
|
||
SndBool_field_decl(bNoAvailableTrack);
|
||
SndBool *pbValid; /*ressource fille valide*/
|
||
tduRefRes uRefThisRes;
|
||
tdstInfoTrackMem * pstRefCurrentRes;
|
||
/* tdstInfoTrackList * pstRefResList; */
|
||
long lCurrentTrack; /*id de la ressource courante (0=1<>;...)*/
|
||
long lCurrentTrackVoice; /*voice bas_niveau*/
|
||
unsigned long ulNbLoops;
|
||
unsigned long ulStartLoop;
|
||
unsigned long ulEndLoop;
|
||
SoundParam* pstSoundParam; /*copie des parametres en cours*/
|
||
long lPrio;
|
||
SND_td_pfn_vSoundCallback pfnSoundCallback;
|
||
long lParSoundCallback;
|
||
SndBool bManagingSequence; /*TRUE quand transition en cours*/
|
||
};
|
||
|
||
|
||
/* tableau des sequences */
|
||
|
||
/*tdstSequence stSequence[NB_MAX_SEQUENCE];*/
|
||
static tdstActiveSequence stActiveSequence[NB_MAX_SEQUENCE];
|
||
|
||
static SndBool bSequenceDriverOk;
|
||
static unsigned char ucSequenceCapacities;
|
||
static unsigned long iNbSequences;
|
||
|
||
|
||
/* -------------------------------------------*/
|
||
/* VARIABLES CONCERNANT LA GESTION DES THREADS*/
|
||
|
||
#ifndef U64
|
||
HANDLE hSequenceThreadCallBack;
|
||
DWORD dwSequenceThreadIdCallBack;
|
||
|
||
DWORD dw_a5_Params[5];
|
||
DWORD dw_a2_threadParams[2];
|
||
#endif
|
||
|
||
/* prototypes des fonctions du module*/
|
||
|
||
/*SndBool SND_fn_bLoadSequence(tdstBlockResourceMem * ptrMem);*/
|
||
void SND_CALL SND_fn_vNextElement(long par);
|
||
|
||
long get_SoundParam_member_size(SoundParam *par)
|
||
{
|
||
return sizeof(SoundParam)+par->iNbLinks*sizeof(MicroLink);
|
||
}
|
||
|
||
void refresh_SoundParam_member(tdstActiveSequence *seq,SoundParam *new_par)
|
||
{
|
||
seq->pstSoundParam=SND_fn_pvReAllocSndEx(E_ucSndBlockMain,seq->pstSoundParam,get_SoundParam_member_size(new_par));
|
||
memcpy(seq->pstSoundParam,new_par,get_SoundParam_member_size(new_par));
|
||
}
|
||
|
||
void create_SoundParam_member(tdstActiveSequence *seq,SoundParam *new_par)
|
||
{
|
||
seq->pstSoundParam=SND_fn_pvMallocSndEx(E_ucSndBlockMain,get_SoundParam_member_size(new_par));
|
||
memcpy(seq->pstSoundParam,new_par,get_SoundParam_member_size(new_par));
|
||
}
|
||
|
||
void free_SoundParam_member(tdstActiveSequence *seq)
|
||
{
|
||
SND_fn_vFreeSndEx(E_ucSndBlockMain,seq->pstSoundParam);
|
||
}
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_bConvertIDListToPtrList*/
|
||
/**/
|
||
/* But : Met a jours la liste ACP de ressource de */
|
||
/* la sequence */
|
||
/* Entrees : */
|
||
/* czFileName : nom du fichier contenant les IDs des res*/
|
||
/* mem : BlockResourceMem lie a la sequence*/
|
||
/* Sorties : TRUE,FALSE suivant la reussite*/
|
||
/*------------------------------------------------------------*/
|
||
/* // Mise en commentaire pour cause de probleme avec stMainResList
|
||
SndBool SND_fn_bConvertIDListToPtrList( char * czFileName,tdstBlockResourceMem * mem)
|
||
{
|
||
tdstBlockResourceMem * pstCurrentBlockMem;
|
||
tdstSndPolyResource * pstMyMainRefResList;
|
||
tdstInfoTrackDisk * pstTrackDisk;
|
||
tdstInfoTrackMem * pstTrackMem;
|
||
tdstInfoTrackList * pstTrackList;
|
||
tdhSndFile hResFile;
|
||
unsigned long ulFileSize = 0,ulNbResources = 0,i;
|
||
unsigned long ul_InfoTrackDiskSize = sizeof(tdstInfoTrackDisk);
|
||
unsigned long ul_InfoTrackMemSize = sizeof(tdstInfoTrackMem);
|
||
|
||
SND_fn_bGetDirectorySnd(StrIdDirectory);
|
||
strcat((LPSTR)StrIdDirectory,(LPCSTR)czFileName);
|
||
hResFile = SND_fn_hOpenFileReadSnd(StrIdDirectory,OPENFILESND_READ);
|
||
|
||
#ifdef FILE_MODE_C_WIN95
|
||
if (hResFile != NULL)
|
||
#else
|
||
if (hResFile != FILE_SND_ERROR)
|
||
#endif
|
||
{
|
||
ulFileSize = SND_fn_dwFileSndLength(hResFile);
|
||
ulNbResources = ulFileSize / ul_InfoTrackDiskSize;
|
||
|
||
pstTrackDisk = (tdstInfoTrackDisk *)SND_fn_pvMallocSnd(ul_InfoTrackDiskSize*ulNbResources);
|
||
pstTrackMem = (tdstInfoTrackMem*)SND_fn_pvMallocSnd(ul_InfoTrackMemSize*ulNbResources);
|
||
|
||
if (SND_fn_dwReadFileSnd(hResFile,ulFileSize,(void*)pstTrackDisk) != ulFileSize)
|
||
{
|
||
SND_fn_vCloseFileSnd(hResFile);
|
||
SND_fn_vFreeSnd(pstTrackDisk);
|
||
SND_fn_vFreeSnd(pstTrackMem);
|
||
return FALSE;
|
||
}
|
||
|
||
// on recupere un pointeur sur la main liste
|
||
pstMyMainRefResList = &stMainResList;
|
||
// on initialise la liste sequence
|
||
pstTrackList = &(mem->uRes.stSequence.stResList);
|
||
M_LstInitAnchor(pstTrackList);
|
||
|
||
for (i=0;i<ulNbResources;i++)
|
||
{
|
||
// on positionne le pointeur courant sur le 1er element de la main liste
|
||
M_LstGetElementNumber(pstMyMainRefResList,pstCurrentBlockMem,0);
|
||
do
|
||
{
|
||
// si on trouve l'Id de ressource correspondant, on rajoute le pointeur
|
||
// sur la ressource dans la liste sequence
|
||
if (pstCurrentBlockMem->Id == pstTrackDisk->uRes.Id)
|
||
{
|
||
M_LstAddTail(pstTrackList,pstTrackMem);
|
||
pstTrackMem->uRes.pstPtr = pstCurrentBlockMem;
|
||
pstTrackMem->ulFadeIn = pstTrackDisk->ulFadeIn;
|
||
pstTrackMem->ulFadeOut = pstTrackDisk->ulFadeOut;
|
||
pstTrackMem->ulCrossFade = pstTrackDisk->ulCrossFade;
|
||
pstTrackMem++;
|
||
pstTrackDisk++;
|
||
break;
|
||
}
|
||
else
|
||
// La ressource n'est pas la bonne, on continue
|
||
pstCurrentBlockMem = M_LstNextElement(pstCurrentBlockMem);
|
||
}
|
||
while (pstCurrentBlockMem != NULL);
|
||
}
|
||
|
||
SND_fn_vCloseFileSnd(hResFile);
|
||
SND_fn_vFreeSnd(pstTrackDisk);
|
||
return TRUE;
|
||
}
|
||
return FALSE;
|
||
}
|
||
*/
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vConvertRsvDiskToMemSeq*/
|
||
/**/
|
||
/* But : Convertit un BlockResourceDisk en Mem*/
|
||
/* Entrees : */
|
||
/* disk : BlockResourceDisk lie a la sequence*/
|
||
/* mem : BlockResourceMem lie a la sequence*/
|
||
/* ptrBegin : pointeur void sur les donnees*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
|
||
|
||
void SND_fn_vConvertResDiskToMemSeq(tdstBlockResourceDisk *disk,tdstBlockResourceMem *mem,tdstInfoTrackList *ptr)
|
||
{
|
||
/*fred's version
|
||
pResMem->Id=pResDisk->Id;
|
||
pResMem->eType=pResDisk->eType;
|
||
pResMem->eStorage=pResDisk->eStorage;
|
||
pResMem->ucVolume=pResDisk->ucVolume;
|
||
|
||
// Set BRMem pointers:
|
||
pMemSeq=&pResMem->uRes.stSequence;
|
||
pDiskSeq=&pResDisk->uRes.stSequence;
|
||
|
||
pMemSeq->bLoop = pDiskSeq->bLoop;
|
||
pMemSeq->ulNbElements = pDiskSeq->ulNbElements;
|
||
pMemSeq->ulStartLoop = pDiskSeq->ulStartLoop;
|
||
pMemSeq->ulEndLoop = pDiskSeq->ulEndLoop;
|
||
pMemSeq->ulNbLoops = pDiskSeq->ulNbLoops;
|
||
*/
|
||
mem->Id=disk->Id;
|
||
mem->eType=disk->eType;
|
||
mem->eStorage=disk->eStorage;
|
||
mem->ucVolume=disk->ucVolume;
|
||
mem->bIsLoaded=TRUE;
|
||
|
||
|
||
mem->uRes.stSequence.bLoop = disk->uRes.stSequence.bLoop;
|
||
mem->uRes.stSequence.ulNbElements = disk->uRes.stSequence.ulNbElements;
|
||
|
||
if (disk->uRes.stSequence.bLoop)
|
||
{
|
||
mem->uRes.stSequence.ulStartLoop = disk->uRes.stSequence.ulStartLoop;
|
||
mem->uRes.stSequence.ulEndLoop = disk->uRes.stSequence.ulEndLoop;
|
||
mem->uRes.stSequence.ulNbLoops = disk->uRes.stSequence.ulNbLoops;
|
||
}
|
||
else
|
||
{
|
||
mem->uRes.stSequence.ulStartLoop = 0;
|
||
mem->uRes.stSequence.ulEndLoop = 0;
|
||
mem->uRes.stSequence.ulNbLoops = 0;
|
||
}
|
||
}
|
||
|
||
|
||
#ifndef NO_ACP_SCRIPT
|
||
SndBool SND_fn_bLoadResScriptSeq(tdstBlockResourceDisk *disk,tdstBlockResourceMem *mem)
|
||
{
|
||
SND_fn_vConvertResDiskToMemSeq(disk,mem,NULL);
|
||
return TRUE;
|
||
}
|
||
#endif
|
||
|
||
SndBool SND_fn_bLoadResBinarySeq(tdstBlockResourceDisk *_pBRDisk,tdstBlockResourceMem *_pBRMem,char *pDataBloc)
|
||
{
|
||
#ifndef NO_ACP_LDBIN
|
||
tdstInfoTrackMem *pTrackArray,*pTrackElement;
|
||
|
||
int iPos;
|
||
/* Convert the ulDataOffset member to a pointer:*/
|
||
pTrackArray=(tdstInfoTrackMem *)(pDataBloc + _pBRDisk->ulDataOffset);
|
||
|
||
SNDLST2_M_StaticSetFirstElement(&_pBRMem->uRes.stSequence.stResList,pTrackArray);
|
||
SNDLST2_M_StaticSetNumberOfElements(&_pBRMem->uRes.stSequence.stResList,
|
||
_pBRDisk->uRes.stSequence.ulNbElements);
|
||
|
||
/* Set pointers to range list:*/
|
||
/* SNDLST2_M_StaticSetMember(&_pBRMem->uRes.stSwitch,hFirstElement,pSwitchArray);*/
|
||
/* SNDLST2_M_StaticSetMember(&_pBRMem->uRes.stSwitch, lNumberOfElements, _pBRDisk->uRes.stSwitch.ulNbElements);*/
|
||
|
||
/* Reset pointers in track:*/
|
||
SNDLST2_M_StaticForEachElementOf( &_pBRMem->uRes.stSequence.stResList, pTrackElement, iPos)
|
||
{
|
||
pTrackElement->uRes.pstPtr=SND_fn_pGetBinRes(pTrackElement->uRes.Id);
|
||
}
|
||
|
||
SND_fn_vConvertResDiskToMemSeq(_pBRDisk,_pBRMem,NULL);
|
||
return TRUE;
|
||
#else
|
||
return FALSE;
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_iInitSeq*/
|
||
/**/
|
||
/* But : Realise les initialisations sequences*/
|
||
/* Entrees : neant */
|
||
/* Sorties : C_INIT_OK ou C_INIT_FAILED*/
|
||
/*------------------------------------------------------------*/
|
||
int SND_fn_iInitSeq(void)
|
||
{
|
||
int i;
|
||
|
||
for (i=0;i<NB_MAX_SEQUENCE;i++)
|
||
{
|
||
stActiveSequence[i].bActive = FALSE;
|
||
stActiveSequence[i].pstSoundParam=NULL;
|
||
stActiveSequence[i].bPaused = FALSE;
|
||
stActiveSequence[i].lCurrentTrack = -1;
|
||
stActiveSequence[i].lCurrentTrackVoice = 0;
|
||
stActiveSequence[i].ulNbLoops = 0;
|
||
stActiveSequence[i].ulStartLoop = 0;
|
||
stActiveSequence[i].ulEndLoop = 0;
|
||
stActiveSequence[i].lPrio = 0;
|
||
stActiveSequence[i].pfnSoundCallback= NULL;
|
||
stActiveSequence[i].lParSoundCallback=0;
|
||
stActiveSequence[i].bNoAvailableTrack = TRUE;
|
||
}
|
||
|
||
bSequenceDriverOk=TRUE;
|
||
ucSequenceCapacities = 0;
|
||
iNbSequences = 0;
|
||
|
||
return C_INIT_OK;
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_bTestInitSeq*/
|
||
/**/
|
||
/* But : init asynchrone*/
|
||
/* Entrees : */
|
||
/* Sorties : TRUE si l'init des sequences a eu lieu*/
|
||
/*------------------------------------------------------------*/
|
||
SndBool SND_fn_bTestInitSeq(void)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vDesInitSeq*/
|
||
/**/
|
||
/* But : libere les sequences*/
|
||
/* Entrees : neant*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
void SND_fn_vDesInitSeq(void)
|
||
{
|
||
int i;
|
||
|
||
for (i=0;i<NB_MAX_SEQUENCE;i++)
|
||
{
|
||
if (stActiveSequence[i].bActive)
|
||
free_SoundParam_member(&stActiveSequence[i]);
|
||
stActiveSequence[i].bActive = FALSE;
|
||
stActiveSequence[i].bPaused = FALSE;
|
||
stActiveSequence[i].lCurrentTrack = -1;
|
||
stActiveSequence[i].lCurrentTrackVoice = 0;
|
||
stActiveSequence[i].ulNbLoops = 0;
|
||
stActiveSequence[i].ulStartLoop = 0;
|
||
stActiveSequence[i].ulEndLoop = 0;
|
||
stActiveSequence[i].lPrio = 0;
|
||
stActiveSequence[i].pfnSoundCallback= NULL;
|
||
stActiveSequence[i].lParSoundCallback=0;
|
||
stActiveSequence[i].bNoAvailableTrack = TRUE;
|
||
}
|
||
}
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_iInitBnkSeq*/
|
||
/**/
|
||
/* But : Charge une bank sequence*/
|
||
/* Entrees : */
|
||
/* num : numero de la banque*/
|
||
/* Sorties : C_INIT_OK ou C_INIT_FAILED*/
|
||
/*------------------------------------------------------------*/
|
||
int SND_fn_iInitBnkSeq(long num)
|
||
{
|
||
return C_INIT_FAILED;
|
||
}
|
||
|
||
SndBool SND_fn_bTestInitBnkSeq(long num)
|
||
{
|
||
return FALSE;
|
||
}
|
||
|
||
void SND_fn_vDesInitBnkSeq(long num)
|
||
{
|
||
}
|
||
|
||
void SND_fn_vDesInitAllBnkSeq(void)
|
||
{
|
||
}
|
||
|
||
void SND_fn_vSetEffectSeq(long num)
|
||
{
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_iCdThreadCallBack*/
|
||
/**/
|
||
/* But : Procedure de la thread qui contient la fenetre qui traite les messages MCI*/
|
||
/* Entrees : void * : parametre inutilise*/
|
||
/* Sorties : void*/
|
||
/*------------------------------------------------------------*/
|
||
#ifndef U64
|
||
int WINAPI SND_fn_iSequenceThreadCallBack(long arglist)
|
||
{
|
||
long * pArg = (void *)arglist;
|
||
SND_td_pfn_vSoundCallback pfnCallback = (SND_td_pfn_vSoundCallback)pArg[0];
|
||
long lParCallback = pArg[1];
|
||
|
||
SND_fn_vEnterCriticalSectionThreadSnd();
|
||
|
||
if (pfnCallback != NULL)
|
||
(*pfnCallback)(lParCallback);
|
||
|
||
SND_fn_vQuitCriticalSectionThreadSnd();
|
||
|
||
return (0);
|
||
}
|
||
#endif
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_ulGetActiveSequence*/
|
||
/**/
|
||
/* But : Renvoie la voie physique de la sequence passee*/
|
||
/* en parametres*/
|
||
/* Entrees : */
|
||
/* uRes : Ressource dont on cherche la voie*/
|
||
/* Sorties : Voie physique (indice dans le tableau)*/
|
||
/*------------------------------------------------------------*/
|
||
/*
|
||
unsigned long fn_ulGetActiveSequence(tduRefRes uRes)
|
||
{
|
||
unsigned long i = 0;
|
||
while ((stSequence[i].uRefThisRes.pstPtr != uRes.pstPtr) && (++i < iNbSequences));
|
||
if (i == iNbSequences)
|
||
return ((unsigned long)NO_ACTIVE_SEQUENCE);
|
||
else
|
||
return (i);
|
||
}
|
||
*/
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_lPlaySeq*/
|
||
/**/
|
||
/* But : Joue la sequence specifiee par res*/
|
||
/* Entrees : */
|
||
/* res : ressource a jouer*/
|
||
/* par : pointeur sur les parametres sons*/
|
||
/* prio : priorite de la requete*/
|
||
/* fct : callback a appeler en fin de jeu*/
|
||
/* Sorties : voie theorique de play*/
|
||
/*------------------------------------------------------------*/
|
||
long SND_fn_lPlaySeq(tduRefRes res,SoundParam *par,long prio,SND_td_pfn_vSoundCallback fn_callback,long par_callback,SndBool* valid)
|
||
{
|
||
long voice;
|
||
tdstInfoTrackMem * pstFirstRes;
|
||
long result;/* = fn_ulGetActiveSequence(res);*/
|
||
SND_td_pfn_vSoundCallback temp_pfnSoundCallback;
|
||
long temp_lParSoundCallback;
|
||
|
||
if (valid!=NULL)
|
||
*valid=FALSE;
|
||
|
||
/*recherche d'une voie de sequence dispo*/
|
||
for (voice=0;voice<NB_MAX_SEQUENCE;voice++)
|
||
if (!stActiveSequence[voice].bActive) break;
|
||
if (voice==NB_MAX_SEQUENCE)
|
||
{
|
||
SND_M_DisplayErrorEx(E_uwSndTooManySequences,"",SNDERR_DISPLAY_IF_WANTED);
|
||
return C_PLAY_FAILED;
|
||
}
|
||
|
||
/*la voie <20> utiliser est "voice"*/
|
||
|
||
|
||
if (res.pstPtr->uRes.stSequence.ulNbElements != 0)
|
||
{/* la sequence est jouable (enfin presque)*/
|
||
if ((res.pstPtr->uRes.stSequence.ulStartLoop < res.pstPtr->uRes.stSequence.ulNbElements)
|
||
&& (res.pstPtr->uRes.stSequence.ulEndLoop < res.pstPtr->uRes.stSequence.ulNbElements))
|
||
{/* La boucle de sequence est valide*/
|
||
/* Si le nombre d'elements est non nul, on recupere le pointeur sur la premiere*/
|
||
/* ressource et on lance la ressource */
|
||
pstFirstRes=SNDLST2_M_StaticGetFirstElement(&(res.pstPtr->uRes.stSequence.stResList));
|
||
/*SNDLST2_M_GetElementNumber(&(res.pstPtr->uRes.stSequence.stResList),pstFirstRes,(long)res.pstPtr->uRes.stSequence.ulStartLoop);*/
|
||
stActiveSequence[voice].pstRefCurrentRes = pstFirstRes;
|
||
|
||
|
||
temp_pfnSoundCallback=SND_fn_vNextElement;
|
||
temp_lParSoundCallback=voice;
|
||
/*fade_in=pstFirstRes->ulFadeIn;fade_out=pstFirstRes->ulFadeOut*/
|
||
result = SND_fn_lPlaySnd(pstFirstRes->uRes,par,prio,temp_pfnSoundCallback,temp_lParSoundCallback,&(stActiveSequence[voice].bValid));
|
||
|
||
if (result != C_PLAY_FAILED)
|
||
{
|
||
/* on sauvegarde une reference a la ressource ainsi que la voie attribuee*/
|
||
/* qui est ???*/
|
||
stActiveSequence[voice].uRefThisRes = res;
|
||
stActiveSequence[voice].pstRefCurrentRes = pstFirstRes;
|
||
stActiveSequence[voice].ulNbLoops = res.pstPtr->uRes.stSequence.ulNbLoops;
|
||
stActiveSequence[voice].ulStartLoop = res.pstPtr->uRes.stSequence.ulStartLoop;
|
||
stActiveSequence[voice].ulEndLoop = res.pstPtr->uRes.stSequence.ulEndLoop;
|
||
stActiveSequence[voice].bNoAvailableTrack = FALSE;
|
||
stActiveSequence[voice].pbValid=valid;
|
||
stActiveSequence[voice].lPrio = prio;
|
||
create_SoundParam_member(&stActiveSequence[voice],par);
|
||
stActiveSequence[voice].pfnSoundCallback= fn_callback;
|
||
stActiveSequence[voice].lParSoundCallback= par_callback;
|
||
stActiveSequence[voice].bActive = TRUE;
|
||
stActiveSequence[voice].bPaused = FALSE;
|
||
stActiveSequence[voice].lCurrentTrack = 0;
|
||
stActiveSequence[voice].lCurrentTrackVoice = result;
|
||
stActiveSequence[voice].bManagingSequence= FALSE;
|
||
if (stActiveSequence[voice].pbValid!=NULL)
|
||
*(stActiveSequence[voice].pbValid)=TRUE;
|
||
return (voice);
|
||
}
|
||
else
|
||
{
|
||
stActiveSequence[voice].bActive = FALSE;
|
||
return (C_PLAY_FAILED);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
SND_M_DisplayError(E_uwSndInvalidStaticParamForResource,"");
|
||
return (C_PLAY_FAILED);
|
||
}
|
||
}
|
||
return (C_PLAY_FAILED);
|
||
}
|
||
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vNextElement*/
|
||
/**/
|
||
/* But : Passe a l'element suivant de la sequence*/
|
||
/* Entrees :neant */
|
||
/* lEndedTrack : NO_ACTIVE_SEQUENCE si la piste de la sequence n'est pas valide*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
void SND_CALL SND_fn_vNextElement(long voice)
|
||
{
|
||
tdstInfoTrackMem * pstNextRes=NULL;
|
||
long result;
|
||
unsigned long ulEndingTrack;/*dernier id de track valide*/
|
||
SND_td_pfn_vSoundCallback temp_pfnSoundCallback;
|
||
long temp_lParSoundCallback;
|
||
SndBool sequence_is_finished;
|
||
#ifndef U64
|
||
SECURITY_ATTRIBUTES sa;
|
||
#endif
|
||
int i;
|
||
|
||
stActiveSequence[voice].bManagingSequence=TRUE;/*blindage <20> l'entree*/
|
||
|
||
result=C_PLAY_FAILED;
|
||
sequence_is_finished=FALSE;
|
||
|
||
if (stActiveSequence[voice].bActive)/* || lEndedTrack == NO_ACTIVE_SEQUENCE)*/
|
||
{
|
||
do /*while (result == C_PLAY_FAILED)*/
|
||
{
|
||
/*l'ancien element n'est plus valide*/
|
||
stActiveSequence[voice].lCurrentTrackVoice = C_PLAY_FAILED;
|
||
|
||
/*trouver le nb d'elements de la sequence*/
|
||
if (stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.bLoop)
|
||
ulEndingTrack = stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.ulEndLoop;
|
||
else
|
||
ulEndingTrack = stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.ulNbElements-1;
|
||
|
||
/*la sequence est-elle finie*/
|
||
if (ulEndingTrack > (unsigned short)stActiveSequence[voice].lCurrentTrack)
|
||
{/*passage <20> l'element suivant de la sequence*/
|
||
pstNextRes = SNDLST2_M_StaticGetNextElement(stActiveSequence[voice].pstRefCurrentRes);
|
||
stActiveSequence[voice].lCurrentTrack++;
|
||
|
||
}
|
||
else
|
||
{/* reboulage ?*/
|
||
if ((stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.bLoop)
|
||
&& (stActiveSequence[voice].ulNbLoops--))
|
||
{
|
||
SNDLST2_M_StaticGetElementNumber(&(stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.stResList)
|
||
,pstNextRes
|
||
,(long)stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.ulStartLoop
|
||
,i);
|
||
stActiveSequence[voice].lCurrentTrack=(short)stActiveSequence[voice].uRefThisRes.pstPtr->uRes.stSequence.ulStartLoop;
|
||
}
|
||
else
|
||
{
|
||
/* la sequence est terminee, on appelle la callback, si elle n'a pas ete annulee*/
|
||
sequence_is_finished=TRUE;
|
||
stActiveSequence[voice].bActive=FALSE;
|
||
#ifndef U64
|
||
if (stActiveSequence[voice].pfnSoundCallback)
|
||
{
|
||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||
sa.bInheritHandle = TRUE;
|
||
sa.lpSecurityDescriptor = NULL;
|
||
dw_a2_threadParams[0] = (DWORD)stActiveSequence[voice].pfnSoundCallback;
|
||
dw_a2_threadParams[1] = (DWORD)stActiveSequence[voice].lParSoundCallback;
|
||
if (!(hSequenceThreadCallBack = CreateThread(&sa,0,(LPTHREAD_START_ROUTINE)SND_fn_iSequenceThreadCallBack,(LPVOID)dw_a2_threadParams,0,&dwSequenceThreadIdCallBack)))
|
||
SND_M_DisplayError(E_uwSndCDCreateThread,"");
|
||
stActiveSequence[voice].pfnSoundCallback = NULL;
|
||
stActiveSequence[voice].lParSoundCallback = 0;
|
||
}
|
||
#else
|
||
if (stActiveSequence[voice].pfnSoundCallback)
|
||
{
|
||
(*stActiveSequence[voice].pfnSoundCallback)(stActiveSequence[voice].lParSoundCallback);
|
||
stActiveSequence[voice].pfnSoundCallback = NULL;
|
||
stActiveSequence[voice].lParSoundCallback = 0;
|
||
}
|
||
#endif
|
||
}
|
||
}
|
||
|
||
if (!sequence_is_finished)
|
||
{
|
||
temp_pfnSoundCallback=SND_fn_vNextElement;
|
||
temp_lParSoundCallback=voice;
|
||
/*fade_in=pstNextRes->ulFadeIn;fade_out=pstNextRes->ulFadeOut*/
|
||
result=SND_fn_lPlaySnd(pstNextRes->uRes,stActiveSequence[voice].pstSoundParam,stActiveSequence[voice].lPrio,temp_pfnSoundCallback,temp_lParSoundCallback,&(stActiveSequence[voice].bValid));
|
||
|
||
if (result != C_PLAY_FAILED)
|
||
{/* on sauvegarde une reference a la ressource ainsi que la voie attribuee*/
|
||
stActiveSequence[voice].bActive = TRUE;
|
||
stActiveSequence[voice].pstRefCurrentRes = pstNextRes;
|
||
stActiveSequence[voice].lCurrentTrackVoice = result;
|
||
stActiveSequence[voice].bNoAvailableTrack = FALSE;
|
||
}
|
||
}
|
||
} while (!sequence_is_finished && (result==C_PLAY_FAILED));
|
||
}
|
||
|
||
if (sequence_is_finished || (result==C_PLAY_FAILED))
|
||
{
|
||
*(stActiveSequence[voice].pbValid)=FALSE;
|
||
}
|
||
|
||
stActiveSequence[voice].bManagingSequence=FALSE;/*blindage <20> la sortie*/
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vStopSeq*/
|
||
/**/
|
||
/* But : Stoppe une sequence*/
|
||
/* Entrees : */
|
||
/* voice : voie theorique a arreter*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
void SND_CALL SND_fn_vStopSeq(long voice)
|
||
{
|
||
#ifndef U64
|
||
SECURITY_ATTRIBUTES sa;
|
||
/*SND_fn_vWaitForValueThreadSnd((long*)&stActiveSequence[voice].bManagingSequence,FALSE);*/
|
||
#endif
|
||
if (stActiveSequence[voice].bActive)
|
||
{
|
||
stActiveSequence[voice].bActive=FALSE;
|
||
|
||
SND_fn_vStopSnd(stActiveSequence[voice].lCurrentTrackVoice);
|
||
|
||
#ifndef U64
|
||
if (stActiveSequence[voice].pfnSoundCallback)
|
||
{
|
||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||
sa.bInheritHandle = TRUE;
|
||
sa.lpSecurityDescriptor = NULL;
|
||
dw_a2_threadParams[0] = (DWORD)stActiveSequence[voice].pfnSoundCallback;
|
||
dw_a2_threadParams[1] = (DWORD)stActiveSequence[voice].lParSoundCallback;
|
||
if (!(hSequenceThreadCallBack = CreateThread(&sa,0,(LPTHREAD_START_ROUTINE)SND_fn_iSequenceThreadCallBack,(LPVOID)dw_a2_threadParams,0,&dwSequenceThreadIdCallBack)))
|
||
SND_M_DisplayError(E_uwSndCDCreateThread,"");
|
||
stActiveSequence[voice].pfnSoundCallback = NULL;
|
||
stActiveSequence[voice].lParSoundCallback = 0;
|
||
}
|
||
#else
|
||
if (stActiveSequence[voice].pfnSoundCallback)
|
||
{
|
||
(*stActiveSequence[voice].pfnSoundCallback)(stActiveSequence[voice].lParSoundCallback);
|
||
stActiveSequence[voice].pfnSoundCallback = NULL;
|
||
stActiveSequence[voice].lParSoundCallback = 0;
|
||
}
|
||
#endif
|
||
|
||
stActiveSequence[voice].bActive = FALSE;
|
||
*(stActiveSequence[voice].pbValid)= FALSE;
|
||
stActiveSequence[voice].lCurrentTrack = -1;
|
||
stActiveSequence[voice].lCurrentTrackVoice = 0;
|
||
}
|
||
}
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vPauseSeq*/
|
||
/**/
|
||
/* But : Pause la sequence de voie voice si active */
|
||
/* Entrees : */
|
||
/* voice : voie theorique a arreter*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
void SND_CALL SND_fn_vPauseSeq(long voice)
|
||
{
|
||
/*SND_fn_vWaitForValueThreadSnd((long*)&stActiveSequence[voice].bManagingSequence,FALSE);*/
|
||
|
||
if (stActiveSequence[voice].bActive)
|
||
{
|
||
/* Erreur, si la demande invoquee ne concerne pas la sequence active*/
|
||
if ((stActiveSequence[voice].bActive) && (!stActiveSequence[voice].bPaused))
|
||
{
|
||
SND_fn_vPauseSnd(stActiveSequence[voice].lCurrentTrackVoice);
|
||
stActiveSequence[voice].bPaused = TRUE;
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vResumeSeq*/
|
||
/**/
|
||
/* But : Resume la sequence en voie voice*/
|
||
/* Entrees : */
|
||
/* voice : voie theorique a resumer*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
void SND_CALL SND_fn_vResumeSeq(long voice)
|
||
{
|
||
/*SND_fn_vWaitForValueThreadSnd((long*)&stActiveSequence[voice].bManagingSequence,FALSE);*/
|
||
|
||
if (stActiveSequence[voice].bActive)
|
||
{
|
||
/* Erreur, si la demande invoquee ne concerne pas la sequence active*/
|
||
/* Erreur, si la sequence active n'etait pas en pause*/
|
||
if (stActiveSequence[voice].bPaused)
|
||
{
|
||
SND_fn_vResumeSnd(stActiveSequence[voice].lCurrentTrackVoice);
|
||
stActiveSequence[voice].bPaused = FALSE;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_vRemoveCallbackSeq*/
|
||
/**/
|
||
/* But : Enleve la callback precedement passee par play*/
|
||
/* Entrees : */
|
||
/* voice : voie theorique a virer*/
|
||
/* Sorties : neant*/
|
||
/*------------------------------------------------------------*/
|
||
void SND_CALL SND_fn_vRemoveCallbackSeq(long voice)
|
||
{
|
||
/*SND_fn_vWaitForValueThreadSnd((long*)&stActiveSequence[voice].bManagingSequence,FALSE);*/
|
||
|
||
if (stActiveSequence[voice].bActive)
|
||
{
|
||
stActiveSequence[voice].pfnSoundCallback= NULL;
|
||
stActiveSequence[voice].lParSoundCallback=0;
|
||
}
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_bSetParamSeq*/
|
||
/**/
|
||
/* But : */
|
||
/* Entrees : */
|
||
/* voice : voie theorique a resumer*/
|
||
/* par : nouveaux parametres son*/
|
||
/* Sorties : TRUE,FALSE*/
|
||
/*------------------------------------------------------------*/
|
||
SndBool SND_CALL SND_fn_bSetParamSeq(long voice,SoundParam *par)
|
||
{
|
||
/*SND_fn_vWaitForValueThreadSnd((long*)&stActiveSequence[voice].bManagingSequence,FALSE);*/
|
||
|
||
if (stActiveSequence[voice].bActive)
|
||
{
|
||
refresh_SoundParam_member(&stActiveSequence[voice],par);
|
||
return stActiveSequence[voice].bActive;
|
||
}
|
||
else
|
||
return FALSE;
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_bTestIsPlayingSeq*/
|
||
/**/
|
||
/* But : Teste si une sequence est active*/
|
||
/* Entrees : */
|
||
/* voice : voie theorique a resumer*/
|
||
/* Sorties : TRUE,FALSE*/
|
||
/*------------------------------------------------------------*/
|
||
SndBool SND_CALL SND_fn_bTestIsPlayingSeq(long voice)
|
||
{
|
||
/*SND_fn_vWaitForValueThreadSnd((long*)&stActiveSequence[voice].bManagingSequence,FALSE);*/
|
||
|
||
return (stActiveSequence[voice].bActive);
|
||
}
|
||
|
||
/*-----------------------------------------------------------*/
|
||
/* SND_fn_bLoadSequence*/
|
||
/**/
|
||
/* But : Initialise les parametres d'une sequence*/
|
||
/* en particulier*/
|
||
/* Entrees : */
|
||
/* ptrMem : BlockResourceMem lie a la sequence*/
|
||
/* Sorties : TRUE,FALSE*/
|
||
/*------------------------------------------------------------*/
|
||
/*
|
||
SndBool SND_fn_bLoadSequence(tdstBlockResourceMem * ptrMem)
|
||
{
|
||
stSequence[iNbSequences].bNoAvailableTrack = TRUE;
|
||
stSequence[iNbSequences].uRefThisRes.pstPtr = ptrMem;
|
||
stSequence[iNbSequences].pstRefResList = &(ptrMem->uRes.stSequence.stResList);
|
||
stSequence[iNbSequences].ulNbLoops = ptrMem->uRes.stSequence.ulNbLoops;
|
||
stSequence[iNbSequences].ulStartLoop = ptrMem->uRes.stSequence.ulStartLoop;
|
||
stSequence[iNbSequences].ulEndLoop = ptrMem->uRes.stSequence.ulEndLoop;
|
||
iNbSequences++;
|
||
return TRUE;
|
||
}
|
||
*/
|
||
|
||
/*---------------------------------------------------------*/
|
||
/* GetPos: retourne la position "theorique" de la ressource*/
|
||
/* exprime en seconde depuis le debut*/
|
||
/* different du temps absolu (car pitch, derive..)*/
|
||
/* Entree: voie concernee*/
|
||
/* Sortie: temps en S (SndReal)*/
|
||
/*----------------------------------------------------------*/
|
||
SndReal SND_CALL SND_fn_rGetPosSeq(long voie)
|
||
{
|
||
return SND_C_POS_UNKNOWN;
|
||
}
|
||
|
||
/*---------------------------------------------------------*/
|
||
/* GetLength: retourne la duree "theorique" de la ressource*/
|
||
/* exprime en seconde (constant pour une ressource donnee)*/
|
||
/* Entree: voie concernee*/
|
||
/* Sortie: duree en S (SndReal)*/
|
||
/*----------------------------------------------------------*/
|
||
SndReal SND_CALL SND_fn_rGetLengthSeq(long voie)
|
||
{
|
||
return SND_C_POS_UNKNOWN;
|
||
}
|
||
|
||
SndBool SND_fn_bSetResourceStaticVolumeSeq(tdstBlockResourceMem* pstRes,unsigned char ucVolume)
|
||
{
|
||
pstRes->ucVolume=ucVolume;
|
||
|
||
return TRUE;
|
||
}
|
||
|
||
|
||
#endif /*NO_ACP_SOUND*/
|
||
|