
#ifndef __SOUND_H__
#define __SOUND_H__

// ============ Structures ===========
#ifndef __ISLSFX2_H__
#include <islsfx2.h>
#endif

typedef struct SOUND_BFF
{
	unsigned long id;
	int length;
	unsigned long name_crc;

// Followed immediately by a SBH file
	SfxBankType sbh;

}SOUND_BFF;

#define BFF_SBH_ID (('S'<<0) | ('B'<<8) | ('H'<<16) | (0<<24))


// ============ Top-End ===========

// Right at the start of main, before the loop
void soundSetup();

// Called from main, so no need to call in every cycle rou
void soundCycle();

void soundShutdown();
void soundUnlinkBFF(SOUND_BFF *sb);
void soundReset(void);
#ifdef DREAMCAST
void SpuSetCommonCDVolume(int volume);
#endif

// ============ Loading & Freeing ===========

extern char *lang_dirs[LANG_NUMLANGS];

// sound.c's bank-related functions return 0... for valid bank numbers, and -1 for non-valid
// (So default your bank numbers to -1, and set 'em to -1 on freeing 'em

// Same as islsfx2
#define MAX_SOUND_BANKS 16

// Leafnames, in upper case, please. This is "load-sbb into spu-ram", for later linkage to a sbh in a bff
int soundLoadJustBody(char *leafname);
// This won't be needed once we've put the sbh's into bff files, but for now, it's convenient
SfxBankType *soundLoadBodyAndHeader(char *leafname);
// A bff sound segment is just an SBH, which is assumed to link into a previously loaded & spu-transferred SBB
int soundLinkBFF(SOUND_BFF *sb);
void soundFreeBank(int i, int free);




// ============ Playing ===========


// For playing samples by direct call to islsfx2, the code you need is...
// Setup:-
//		SfxSampleType *samp;
//		samp = sfxFindSampleInAllBanks("smetbrk1");	// ok, lower case finds it...
// Play:-
//		sfxPlaySample(samp, 255, 255, 0);	// (left vol, right vol, pitch)

// Volume here is 0xllrr
int soundPlaySample(SfxSampleType *sample, short volume, int pitch);

// Volume here is 0...255
int soundPlaySamplePanFade(SfxSampleType *sample, int volume, int pitch,VECTOR *at);
int soundPlaySamplePanOnly(SfxSampleType *sample, int volume, int pitch,VECTOR *at);
int soundPlaySpeech(SfxSampleType *sample, int pitch);

void soundMaintainSamplePanFade(void);
void soundStopSample(SfxSampleType *pS);
void soundMuteAllChannels(void);


// =================================

#ifdef _WINDOWS
typedef void (*CdlCB)(u_char,u_char *);
#endif



// The struct is defined internally in islxa, so here's a Chicken Run copy...
typedef struct _XADataType {
#ifdef DREAMCAST
	long		oldCallback;
#else
	CdlCB		oldCallback;
#endif
	char		buffer[2340];
	int			currChannel;
	int			activeChannel;
	int			currSector;
	XAFileType	*currXA;
	XAFileType	*prevXA;
	int			prevChannel;
	int			prevSector;
} XADataType;
extern XADataType	XAData;



// There's a byte in the levinfo which contains one of these values, too
enum
{
	TUNE_5_COOPS_D,			// in
	TUNE_6_COOPS_N,			// in
	TUNE_9_COG,				// in
	TUNE_10_FLYMACHINE,		// in
	TUNE_11_MRST,			// in
	TUNE_7_WORKING,			// in
	TUNE_8_GOLF,			// in

	
	TUNE_1_INTRO = 8,		// in
	TUNE_4_FAILED,			// Y (catapult, fireworks, seesaw, engine, wings, construct) N (dogchase, eggs)
	TUNE_2_BRIEFING,		// moved, but in
	TUNE_3_COMPLETE,		// Y (catapult, fireworks, seesaw, engine, wings, construct) N (dogchase, eggs)
	TUNE_12_DIES,			// Y (locally only)
	TUNE_13_GAMEOVER,
	TUNE_14_SHORTGOLF,

// tbd - some sorting out of fileloads in options.c.

/*
	TUNE_1_INTRO,
	TUNE_5_COOPS_D,
	TUNE_6_COOPS_N,
	TUNE_7_WORKING,
	TUNE_8_GOLF,
	TUNE_9_COG,
	TUNE_10_FLYMACHINE,
	TUNE_11_MRST,

	TUNE_2_BRIEFING,
	TUNE_3_COMPLETE,
	TUNE_5_FAILED,
	TUNE_12_DIES,
	TUNE_13_GAMEOVER,
*/
	TUNE_AT1 = 16,
	TUNE_AT2,
	TUNE_AT3,
	TUNE_AT4,
	TUNE_AT5,
	TUNE_AT6,
	TUNE_AT7,
	TUNE_AT8

};

/*
5	4:49	CoopsD
6	4:03	CoopsN
9	3:00	CogChase
10	2:41	Flymachine
11	2:01	MrsTweedyDogChase
7	1:10	Work
8	1:08	Golf

1	0:51	Intro
4	0:50	Fowler Fail
2	0:36	Mac Brief
3	0:33	Fowler Complete
12	0:09	Dies
13	0:09	Game Over
*/

extern int music_playing;
extern int music_to_resume;
extern int music_queued;


void sound_XAInit();
void sound_XA_FindLangFiles(int lang);
void sound_LoadLanguageBank(int lang);
void sound_FreeLanguageBank();
int sound_LoadLanguageBankBody(int lang, char *leafname);

#define SOUND_XA_NOLOOP 128
void sound_XA_Start(int tune);
void sound_XA_StartFma(int tune);
void sound_XA_Stop();
void sound_XA_PauseForLoading();
void sound_XA_EnsurePaused();

// If "tune" is the same as the tune-to-resume, or if it's -1, then carry on where we left off
// (otherwise start from the beginning)

// IE - level switches can call this with any tune number & it'll continue or begin as appropriate
// And the inventory streamed-bank-swapper can call here with -1

void sound_XA_Resume(int tune);
void sound_XA_Queue(int tune);	// call sound_XA_start(a), sound_xa_queue(b) for (a) followed by (b) looping

void sound_XA_StartFadeOut(int n_frames);
void sound_XA_StartFadeIn(int n_frames);

void sound_XA_VolRefresh();	// call from menu when changing xa volume

#endif
