reman3/Rayman_X/cpa/tempgrp/SND/src/sndseq.c

888 lines
34 KiB
C
Raw Blame History

/*
//////////////////////////////////////////////////////////////////////////
// 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*/