/*
**	Command & Conquer Red Alert(tm)
**	Copyright 2025 Electronic Arts Inc.
**
**	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 3 of the License, or
**	(at your option) any later version.
**
**	This program is distributed in the hope that it will be useful,
**	but WITHOUT ANY WARRANTY; without even the implied warranty of
**	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**	GNU General Public License for more details.
**
**	You should have received a copy of the GNU General Public License
**	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

/* $Header:   F:\projects\c&c0\vcs\code\audio.cpv   4.78   03 Oct 1996 09:20:46   JOE_BOSTIC  $ */
/***********************************************************************************************
 ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
 ***********************************************************************************************
 *                                                                                             *
 *                 Project Name : Command & Conquer                                            *
 *                                                                                             *
 *                    File Name : AUDIO.CPP                                                    *
 *                                                                                             *
 *                   Programmer : Joe L. Bostic                                                *
 *                                                                                             *
 *                   Start Date : September 10, 1993                                           *
 *                                                                                             *
 *                  Last Update : September 15, 1996 [JLB]                                     *
 *                                                                                             *
 *---------------------------------------------------------------------------------------------*
 * Functions:                                                                                  *
 *   Is_Speaking -- Checks to see if the eva voice is still playing.                           *
 *   Sound_Effect -- General purpose sound player.                                             *
 *   Sound_Effect -- Plays a sound effect in the tactical map.                                 *
 *   Speak -- Computer speaks to the player.                                                   *
 *   Speak_AI -- Handles starting the EVA voices.                                              *
 *   Speech_Name -- Fetches the name for the voice specified.                                  *
 *   Stop_Speaking -- Forces the EVA voice to stop talking.                                    *
 *   Voc_From_Name -- Fetch VocType from ASCII name specified.                                 *
 *   Voc_Name -- Fetches the name for the sound effect.                                        *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#include	"function.h"


/***************************************************************************
**	Controls what special effects may occur on the sound effect.
*/
typedef enum {
	IN_NOVAR,			// No variation or alterations allowed.
	IN_VAR				// Infantry variance response modification.
} ContextType;

static struct {
	char const *	Name;		// Digitized voice file name.
	int				Priority;	// Playback priority of this sample.
	ContextType		Where;		// In what game context does this sample exist.
} SoundEffectName[VOC_COUNT] = {

	/*
	**	Civilian voices (technicians too).
	*/
	{"GIRLOKAY",	20,	IN_NOVAR},		//	VOC_GIRL_OKAY
	{"GIRLYEAH",	20,	IN_NOVAR},		//	VOC_GIRL_YEAH
	{"GUYOKAY1",	20,	IN_NOVAR},		//	VOC_GUY_OKAY
	{"GUYYEAH1",	20,	IN_NOVAR},		//	VOC_GUY_YEAH

	{"MINELAY1",	5,		IN_VAR},			// VOC_MINELAY1

	/*
	**	Infantry and vehicle responses.
	*/
	{"ACKNO",		20,	IN_VAR},	//	VOC_ACKNOWL			"acknowledged"
	{"AFFIRM1",		20,	IN_VAR},	//	VOC_AFFIRM			"affirmative"
	{"AWAIT1",		20,	IN_VAR},	//	VOC_AWAIT1			"awaiting orders"
	{"EAFFIRM1",	20,	IN_NOVAR},	// VOC_ENG_AFFIRM	Engineer: "affirmative"
	{"EENGIN1",		20,	IN_VAR},	//	VOC_ENG_ENG			Engineer: "engineering"
	{"NOPROB",		20,	IN_VAR},	// VOC_NO_PROB			"not a problem"
	{"READY",		20,	IN_VAR},	// VOC_READY			"ready and waiting"
	{"REPORT1",		20,	IN_VAR},	//	VOC_REPORT			"reporting"
	{"RITAWAY",		20,	IN_VAR},	// VOC_RIGHT_AWAY		"right away sir"
	{"ROGER",		20,	IN_VAR},	// VOC_ROGER			"roger"
	{"UGOTIT",		20,	IN_VAR},	// VOC_UGOTIT			"you got it"
	{"VEHIC1",		20,	IN_VAR},	//	VOC_VEHIC1			"vehicle reporting"
	{"YESSIR1",		20,	IN_VAR},	//	VOC_YESSIR			"yes sir"

	{"DEDMAN1", 	10,	IN_NOVAR},	// VOC_SCREAM1			short infantry scream
	{"DEDMAN2", 	10,	IN_NOVAR},	// VOC_SCREAM3			short infantry scream
	{"DEDMAN3", 	10,	IN_NOVAR},	// VOC_SCREAM4			short infantry scream
	{"DEDMAN4", 	10,	IN_NOVAR},	// VOC_SCREAM5			short infantry scream
	{"DEDMAN5", 	10,	IN_NOVAR},	// VOC_SCREAM6			short infantry scream
	{"DEDMAN6", 	10,	IN_NOVAR},	// VOC_SCREAM7			short infantry scream
	{"DEDMAN7", 	10,	IN_NOVAR},	// VOC_SCREAM10		short infantry scream
	{"DEDMAN8", 	10,	IN_NOVAR},	// VOC_SCREAM11		short infantry scream
	{"DEDMAN10", 	10,	IN_NOVAR},	// VOC_YELL1			long infantry scream

	{"CHRONO2",		5,		IN_NOVAR},	//	VOC_CHRONO			Chronosphere sound
	{"CANNON1",		1,		IN_NOVAR},	//	VOC_CANNON1			Cannon sound (medium).
	{"CANNON2",		1,		IN_NOVAR},	//	VOC_CANNON2			Cannon sound (short).
	{"IRONCUR1",	5,		IN_NOVAR},	// VOC_IRON1
	{"EMOVOUT1",	20,	IN_NOVAR},	//	VOC_ENG_MOVEOUT	Engineer: "movin' out"
	{"IRONCUR2",	5,		IN_NOVAR},	//	VOC_IRON2
	{"x",		1,		IN_NOVAR},
	{"x",		1,		IN_NOVAR},
	{"CHUTE1",		1,		IN_NOVAR},	//	VOC_CHUTE1			Wind swoosh sound.
	{"DOGY1",		5,		IN_NOVAR},	//	VOC_DOG_BARK		Dog bark.
	{"DOGW5",		10,	IN_NOVAR},	//	VOC_DOG_WHINE		Dog whine.
	{"DOGG5P",		10,	IN_NOVAR},	//	VOC_DOG_GROWL2		Strong dog growl.
	{"FIREBL3",		1,		IN_NOVAR},	//	VOC_FIRE_LAUNCH	Fireball launch sound.
	{"FIRETRT1",	1,		IN_NOVAR},	//	VOC_FIRE_EXPLODE	Fireball explode sound.
	{"GRENADE1",	1,		IN_NOVAR},	//	VOC_GRENADE_TOSS	Grenade toss.
	{"GUN11",		1,		IN_NOVAR},	//	VOC_GUN_5			5 round gun burst (slow).
	{"GUN13",		1,		IN_NOVAR},	//	VOC_GUN_7			7 round gun burst (fast).
	{"EYESSIR1",	20,	IN_NOVAR},	//	VOC_ENG_YES,		Engineer: "yes sir"
	{"GUN27",		1,		IN_NOVAR},	//	VOC_GUN_RIFLE		Rifle shot.
	{"HEAL2",		1,		IN_NOVAR},	//	VOC_HEAL				Healing effect.
	{"HYDROD1",		1,		IN_NOVAR},	//	VOC_DOOR				Hyrdrolic door.
	{"INVUL2",		1,		IN_NOVAR},	//	VOC_INVULNERABLE	Invulnerability effect.
	{"KABOOM1",		1,		IN_NOVAR},	//	VOC_KABOOM1			Long explosion (muffled).
	{"KABOOM12",	1,		IN_NOVAR},	//	VOC_KABOOM12		Very long explosion (muffled).
	{"KABOOM15",	1,		IN_NOVAR},	//	VOC_KABOOM15		Very long explosion (muffled).
	{"x",			1,		IN_NOVAR},
	{"KABOOM22",	1,		IN_NOVAR},	//	VOC_KABOOM22		Long explosion (sharp).
	{"x",			1,		IN_NOVAR},
	{"x",			1,		IN_NOVAR},
	{"MGUNINF1",	1,		IN_NOVAR},	//	VOC_GUN_5F			5 round gun burst (fast).
	{"MISSILE1",	1,		IN_NOVAR},	//	VOC_MISSILE_1		Missile with high tech effect.
	{"MISSILE6",	1,		IN_NOVAR},	//	VOC_MISSILE_2		Long missile launch.
	{"MISSILE7",	1,		IN_NOVAR},	//	VOC_MISSILE_3		Short missile launch.
	{"x",	1,		IN_NOVAR},
	{"PILLBOX1",	1,		IN_NOVAR},	//	VOC_GUN_5R			5 round gun burst (rattles).
	{"RABEEP1",		1,		IN_NOVAR},	//	VOC_BEEP				Generic beep sound.
	{"RAMENU1",		1,		IN_NOVAR},	//	VOC_CLICK			Generic click sound.
	{"SILENCER",	1,		IN_NOVAR},	//	VOC_SILENCER		Silencer.
	{"TANK5",		1,		IN_NOVAR},	//	VOC_CANNON6			Long muffled cannon shot.
	{"TANK6",		1,		IN_NOVAR},	//	VOC_CANNON7			Sharp mechanical cannon fire.
	{"TORPEDO1",	1,		IN_NOVAR},	//	VOC_TORPEDO			Torpedo launch.
	{"TURRET1",		1,		IN_NOVAR},	//	VOC_CANNON8			Sharp cannon fire.
	{"TSLACHG2",	10,	IN_NOVAR},	//	VOC_TESLA_POWER_UP	Hum charge up.
	{"TESLA1",		10,	IN_NOVAR},	//	VOC_TESLA_ZAP		Tesla zap effect.
	{"SQUISHY2",	10,	IN_NOVAR},	//	VOC_SQUISH			Squish effect.
	{"SCOLDY1",		10,	IN_NOVAR},	//	VOC_SCOLD			Scold bleep.
	{"RADARON2",	20,	IN_NOVAR},	//	VOC_RADAR_ON		Powering up electronics.
	{"RADARDN1",	10,	IN_NOVAR},	//	VOC_RADAR_OFF		B movie power down effect.
	{"PLACBLDG",	10,	IN_NOVAR},	//	VOC_PLACE_BUILDING_DOWN	Building slam down sound.
	{"KABOOM30",	1,		IN_NOVAR},	//	VOC_KABOOM30		Short explosion (HE).
	{"KABOOM25",	10,	IN_NOVAR},	//	VOC_KABOOM25		Short growling explosion.
	{"x",			10,	IN_NOVAR},
	{"DOGW7",		10,	IN_NOVAR},	//	VOC_DOG_HURT		Dog whine (loud).
	{"DOGW3PX",		10,	IN_NOVAR},	//	VOC_DOG_YES			Dog 'yes sir'.
	{"CRMBLE2",		10,	IN_NOVAR},	//	VOC_CRUMBLE			Building crumble.
	{"CASHUP1",		10,	IN_NOVAR},	//	VOC_MONEY_UP		Rising money tick.
	{"CASHDN1",		10,	IN_NOVAR},	//	VOC_MONEY_DOWN		Falling money tick.
	{"BUILD5",		10,	IN_NOVAR},	//	VOC_CONSTRUCTION	Building construction sound.
	{"BLEEP9",		10,	IN_NOVAR},	//	VOC_GAME_CLOSED	Long bleep.
	{"BLEEP6",		10,	IN_NOVAR},	//	VOC_INCOMING_MESSAGE	Soft happy warble.
	{"BLEEP5",		10,	IN_NOVAR},	//	VOC_SYS_ERROR		Sharp soft warble.
	{"BLEEP17",		10,	IN_NOVAR},	//	VOC_OPTIONS_CHANGED	Mid range soft warble.
	{"BLEEP13",		10,	IN_NOVAR},	//	VOC_GAME_FORMING	Long warble.
	{"BLEEP12",		10,	IN_NOVAR},	//	VOC_PLAYER_LEFT	Chirp sequence.
	{"BLEEP11",		10,	IN_NOVAR},	//	VOC_PLAYER_JOINED	Reverse chirp sequence.
	{"H2OBOMB2",	10,	IN_NOVAR},	//	VOC_DEPTH_CHARGE	Distant explosion sound.
	{"CASHTURN",	10,	IN_NOVAR},	//	VOC_CASHTURN		Airbrake.
	{"TUFFGUY1",	20,	IN_NOVAR},	//	VOC_TANYA_CHEW			Tanya: "Chew on this"
	{"ROKROLL1",	20,	IN_NOVAR},	//	VOC_TANYA_ROCK			Tanya: "Let's rock"
	{"LAUGH1",		20,	IN_NOVAR},	//	VOC_TANYA_LAUGH		Tanya: "ha ha ha"
	{"CMON1",		20,	IN_NOVAR},	//	VOC_TANYA_SHAKE		Tanya: "Shake it baby"
	{"BOMBIT1",		20,	IN_NOVAR},	//	VOC_TANYA_CHING		Tanya: "Cha Ching"
	{"GOTIT1",		20,	IN_NOVAR},	//	VOC_TANYA_GOT			Tanya: "That's all you got"
	{"KEEPEM1",		20,	IN_NOVAR},	//	VOC_TANYA_KISS			Tanya: "Kiss it bye bye"
	{"ONIT1",		20,	IN_NOVAR},	//	VOC_TANYA_THERE		Tanya: "I'm there"
	{"LEFTY1",		20,	IN_NOVAR},	//	VOC_TANYA_GIVE			Tanya: "Give it to me"
	{"YEAH1",		20,	IN_NOVAR},	//	VOC_TANYA_YEA			Tanya: "Yea?"
	{"YES1",			20,	IN_NOVAR},	//	VOC_TANYA_YES			Tanya: "Yes sir?"
	{"YO1",			20,	IN_NOVAR},	//	VOC_TANYA_WHATS		Tanya: "What's up."
	{"WALLKIL2",	5,		IN_NOVAR},	//	VOC_WALLKILL2			Crushing wall sound.
	{"x",			10,	IN_NOVAR},
	{"GUN5",			5,		IN_NOVAR},	//	VOC_TRIPLE_SHOT		Three quick shots in succession.
	{"SUBSHOW1",	5,		IN_NOVAR},	//	VOC_SUBSHOW				Submarine surface sound.
	{"EINAH1",		20,	IN_NOVAR},	//	VOC_E_AH,				Einstien "ah"
	{"EINOK1",		20,	IN_NOVAR},	//	VOC_E_OK,				Einstien "ok"
	{"EINYES1",		20,	IN_NOVAR},	//	VOC_E_YES,				Einstien "yes"
	{"MINE1",		10,	IN_NOVAR},	//	VOC_TRIP_MINE			mine explosion sound

	{"SCOMND1",		20,	IN_NOVAR},	//	VOC_SPY_COMMANDER		Spy: "commander?"
	{"SYESSIR1",	20,	IN_NOVAR},	//	VOC_SPY_YESSIR			Spy: "yes sir"
	{"SINDEED1",	20,	IN_NOVAR},	//	VOC_SPY_INDEED			Spy: "indeed"
	{"SONWAY1",		20,	IN_NOVAR},	//	VOC_SPY_ONWAY			Spy: "on my way"
	{"SKING1",		20,	IN_NOVAR},	//	VOC_SPY_KING			Spy: "for king and country"
	{"MRESPON1",	20,	IN_NOVAR},	//	VOC_MED_REPORTING		Medic: "reporting"
	{"MYESSIR1",	20,	IN_NOVAR},	//	VOC_MED_YESSIR			Medic: "yes sir"
	{"MAFFIRM1",	20,	IN_NOVAR},	//	VOC_MED_AFFIRM			Medic: "affirmative"
	{"MMOVOUT1",	20,	IN_NOVAR},	//	VOC_MED_MOVEOUT		Medic: "movin' out"
	{"BEEPSLCT",	10,	IN_NOVAR},	//	VOC_BEEP_SELECT		map selection beep

	{"SYEAH1",		20,	IN_NOVAR},	//	VOC_THIEF_YEA			Thief: "yea?"
	{"x",		20,	IN_NOVAR},
	{"x",		20,	IN_NOVAR},
	{"SMOUT1",		20,	IN_NOVAR},	//	VOC_THIEF_MOVEOUT		Thief: "movin' out"
	{"SOKAY1",		20,	IN_NOVAR},	//	VOC_THIEF_OKAY			Thief: "ok"
	{"x",		20,	IN_NOVAR},
	{"SWHAT1",		20,	IN_NOVAR},	//	VOC_THIEF_WHAT			Thief: "what"
	{"SAFFIRM1",	20,	IN_NOVAR},	//	VOC_THIEF_AFFIRM		Thief: "affirmative"
};


/***********************************************************************************************
 * Voc_From_Name -- Fetch VocType from ASCII name specified.                                   *
 *                                                                                             *
 *    This will find the corresponding VocType from the ASCII string specified. It does this   *
 *    by finding a root filename that matches the string.                                      *
 *                                                                                             *
 * INPUT:   name  -- Pointer to the ASCII string that will be converted into a VocType.        *
 *                                                                                             *
 * OUTPUT:  Returns with the VocType that matches the string specified. If no match could be   *
 *          found, then VOC_NONE is returned.                                                  *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   07/06/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
VocType Voc_From_Name(char const * name)
{
 #ifdef 0
	if (name == NULL) return(VOC_NONE);

	for (VocType voc = VOC_FIRST; voc < VOC_COUNT; voc++) {
		if (stricmp(name, SoundEffectName[voc].Name) == 0) {
			return(voc);
		}
	}

#endif
	return(VOC_NONE);

}


/***********************************************************************************************
 * Voc_Name -- Fetches the name for the sound effect.                                          *
 *                                                                                             *
 *    This routine returns the descriptive name of the sound effect. Currently, this is just   *
 *    the root of the file name.                                                               *
 *                                                                                             *
 * INPUT:   voc   -- The VocType that the corresponding name is requested.                     *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to the text string the represents the sound effect.         *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   05/06/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
char const * Voc_Name(VocType voc)
{
	if (voc == VOC_NONE) return("none");
	return(SoundEffectName[voc].Name);
}


/***********************************************************************************************
 * Sound_Effect -- Plays a sound effect in the tactical map.                                   *
 *                                                                                             *
 *    This routine is used when a sound effect occurs in the game world. It handles fading     *
 *    the sound according to distance.                                                         *
 *                                                                                             *
 * INPUT:   voc   -- The sound effect number to play.                                          *
 *                                                                                             *
 *          coord -- The world location that the sound originates from.                        *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/12/1994 JLB : Created.                                                                 *
 *   01/05/1995 JLB : Reduces sound more dramatically when off screen.                         *
 *   09/15/1996 JLB : Revamped volume logic.                                                   *
 *=============================================================================================*/
void Sound_Effect(VocType voc, COORDINATE coord, int variation)
{
  #ifdef 0
	CELL cell_pos = 0;
	int pan_value;

	if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
		return;
	}
	if (coord) {
		cell_pos = Coord_Cell(coord);
	}

	fixed volume = 1;
	pan_value = 0;
	if (coord && !Map.In_View(cell_pos)) {
		int distance = Distance(coord, Map.TacticalCoord) / CELL_LEPTON_W;
		fixed dfixed = fixed(distance, 128+64);
		dfixed.Sub_Saturate(1);
		volume = fixed(1) - dfixed;

		pan_value  = Cell_X(cell_pos);
		pan_value -= Coord_XCell(Map.TacticalCoord) + (Lepton_To_Cell(Map.TacLeptonWidth) / 2);
		if (ABS(pan_value) > Lepton_To_Cell(Map.TacLeptonWidth / 2)) {
			pan_value *= 0x8000;
			pan_value /= (MAP_CELL_W >> 2);
			pan_value = Bound(pan_value, -0x7FFF, 0x7FFF);
		} else {
			pan_value  = 0;
		}
	}

	Sound_Effect(voc, volume, variation, pan_value);
#endif
}


/***********************************************************************************************
 * Sound_Effect -- General purpose sound player.                                               *
 *                                                                                             *
 *    This is used for general purpose sound effects. These are sounds that occur outside      *
 *    of the game world. They do not have a corresponding game world location as their source. *
 *                                                                                             *
 * INPUT:   voc      -- The sound effect number to play.                                       *
 *                                                                                             *
 *          volume   -- The volume to assign to this sound effect.                             *
 *                                                                                             *
 * OUTPUT:  Returns with the sound handle (-1 if no sound was played).                         *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/12/1994 JLB : Created.                                                                 *
 *   11/12/1994 JLB : Handles cache logic.                                                     *
 *   05/04/1995 JLB : Variation adjustments.                                                   *
 *=============================================================================================*/
int Sound_Effect(VocType voc, fixed volume, int variation, signed short pan_value)
{
 #ifdef 0
	char name[_MAX_FNAME+_MAX_EXT];				// Working filename of sound effect.

	if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
		return(-1);
	}

	/*
	**	Alter the volume according to the game volume setting.
	*/
	volume = volume * Options.Volume;

	/*
	**	Fetch a pointer to the sound effect data. Modify the sound as appropriate and desired.
	*/
	char const * ext = ".AUD";
	if (SoundEffectName[voc].Where == IN_VAR) {

		/*
		**	For infantry, use a variation on the response. For vehicles, always
		**	use the vehicle response table.
		*/
		if (variation < 0) {
			if (ABS(variation) % 2) {
				ext = ".V00";
			} else {
				ext = ".V02";
			}
		} else {
			if (variation % 2) {
				ext = ".V01";
			} else {
				ext = ".V03";
			}
		}
	}
	_makepath(name, NULL, NULL, SoundEffectName[voc].Name, ext);
	void const * ptr = MFCD::Retrieve(name);

	/*
	**	If the sound data pointer is not null, then presume that it is valid.
	*/
	if (ptr != NULL) {
		volume.Sub_Saturate(1);
		return(Play_Sample(ptr, SoundEffectName[voc].Priority * volume, volume*256, pan_value));
//	} else {
//		Mono_Printf("Cannot find '%s'.\n", name);
	}
#endif
	return(-1);
}


/*
**	This elaborates all the EVA speech voices.
*/
static char const * Speech[VOX_COUNT] =  {
	"MISNWON1",		//	VOX_ACCOMPLISHED					mission accomplished
	"MISNLST1",		//	VOX_FAIL								your mission has failed
	"PROGRES1",		//	VOX_NO_FACTORY						unable to comply, building in progress
	"CONSCMP1",		//	VOX_CONSTRUCTION					construction complete
	"UNITRDY1",		//	VOX_UNIT_READY						unit ready
	"NEWOPT1",		//	VOX_NEW_CONSTRUCT					new construction options
	"NODEPLY1",		//	VOX_DEPLOY							cannot deploy here
	"STRCKIL1",		//	VOX_STRUCTURE_DESTROYED,		structure destroyed
	"NOPOWR1",		//	VOX_INSUFFICIENT_POWER,			insufficient power
	"NOFUNDS1",		//	VOX_NO_CASH							insufficient funds
	"BCT1",			//	VOX_CONTROL_EXIT					battle control terminated
	"REINFOR1",		//	VOX_REINFORCEMENTS				reinforcements have arrived
	"CANCLD1",		//	VOX_CANCELED						canceled
	"ABLDGIN1",		//	VOX_BUILDING						building
	"LOPOWER1",		//	VOX_LOW_POWER						low power
	"NOFUNDS1",		//	VOX_NEED_MO_MONEY					insufficent funds
	"BASEATK1",		//	VOX_BASE_UNDER_ATTACK			our base is under attack
	"NOBUILD1",		//	VOX_UNABLE_TO_BUILD				unable to build more
	"PRIBLDG1",		//	VOX_PRIMARY_SELECTED				primary building selected
	"none",
	"none",			//	VOX_SOVIET_CAPTURED				Allied building captured
	"UNITLST1",		// VOX_UNIT_LOST						unit lost
	"SLCTTGT1",		// VOX_SELECT_TARGET					select target
	"ENMYAPP1",		//	VOX_PREPARE							enemy approaching
	"SILOND1",		//	VOX_NEED_MO_CAPACITY				silos needed
	"ONHOLD1",		//	VOX_SUSPENDED						on hold
	"REPAIR1",		//	VOX_REPAIRING						repairing
	"none",
	"none",
	"AUNITL1",		//	VOX_AIRCRAFT_LOST					airborne unit lost
	"none",
	"AAPPRO1",		//	VOX_ALLIED_FORCES_APPROACHING	allied forces approaching
	"AARRIVE1",		// VOX_ALLIED_APPROACHING			allied reinforcements have arrived
	"none",
	"none",
	"BLDGINF1",		// VOX_BUILDING_INFILTRATED		building infiltrated
	"CHROCHR1",		// VOX_CHRONO_CHARGING				chronosphere charging
	"CHRORDY1",		// VOX_CHRONO_READY					chronosphere ready
	"CHROYES1",		// VOX_CHRONO_TEST					chronosphere test successful
	"CMDCNTR1",		//	VOX_HQ_UNDER_ATTACK				command center under attack
	"CNTLDED1",		//	VOX_CENTER_DEACTIVATED			control center deactivated
	"CONVYAP1",		//	VOX_CONVOY_APPROACHING			convoy approaching
	"CONVLST1",		// VOX_CONVOY_UNIT_LOST				convoy unit lost
	"XPLOPLC1",		//	VOX_EXPLOSIVE_PLACED				explosive charge placed
	"CREDIT1",		// VOX_MONEY_STOLEN					credits stolen
	"NAVYLST1",		// VOX_SHIP_LOST						naval unit lost
	"SATLNCH1",		//	VOX_SATALITE_LAUNCHED			satalite launched
	"PULSE1",		//	VOX_SONAR_AVAILABLE				sonar pulse available
	"none",
	"SOVFAPP1",		//	VOX_SOVIET_FORCES_APPROACHING	soviet forces approaching
	"SOVREIN1",		// VOX_SOVIET_REINFROCEMENTS		soviet reinforcements have arrived
	"TRAIN1",		//	VOX_TRAINING						training
	"AREADY1",		//	VOX_ABOMB_READY
	"ALAUNCH1",		//	VOX_ABOMB_LAUNCH
	"AARRIVN1",		//	VOX_ALLIES_N
	"AARRIVS1",		//	VOX_ALLIES_S
	"AARIVE1",		//	VOX_ALLIES_E
	"AARRIVW1",		//	VOX_ALLIES_W
	"1OBJMET1",		//	VOX_OBJECTIVE1
	"2OBJMET1",		//	VOX_OBJECTIVE2
	"3OBJMET1",		//	VOX_OBJECTIVE3
	"IRONCHG1",		//	VOX_IRON_CHARGING
	"IRONRDY1",		//	VOX_IRON_READY
	"KOSYRES1",		//	VOX_RESCUED
	"OBJNMET1",		//	VOX_OBJECTIVE_NOT
	"FLAREN1",		//	VOX_SIGNAL_N
	"FLARES1",		//	VOX_SIGNAL_S
	"FLAREE1",		//	VOX_SIGNAL_E
	"FLAREW1",		//	VOX_SIGNAL_W
	"SPYPLN1",		//	VOX_SPY_PLANE
	"TANYAF1",		//	VOX_FREED
	"ARMORUP1",		//	VOX_UPGRADE_ARMOR
	"FIREPO1",		//	VOX_UPGRADE_FIREPOWER
	"UNITSPD1",		//	VOX_UPGRADE_SPEED
	"MTIMEIN1",		//	VOX_MISSION_TIMER
	"UNITFUL1",		//	VOX_UNIT_FULL
	"UNITREP1",		//	VOX_UNIT_REPAIRED
	"40MINR",		//	VOX_TIME_40
	"30MINR",		//	VOX_TIME_30
	"20MINR",		//	VOX_TIME_20
	"10MINR",		//	VOX_TIME_10
	"5MINR",			//	VOX_TIME_5
	"4MINR",			//	VOX_TIME_4
	"3MINR",			//	VOX_TIME_3
	"2MINR",			//	VOX_TIME_2
	"1MINR",			//	VOX_TIME_1
	"TIMERNO1",		//	VOX_TIME_STOP
	"UNITSLD1",		//	VOX_UNIT_SOLD
	"TIMERGO1",		//	VOX_TIMER_STARTED
	"TARGRES1",		//	VOX_TARGET_RESCUED
	"TARGFRE1",		//	VOX_TARGET_FREED
	"TANYAR1",		//	VOX_TANYA_RESCUED
	"STRUSLD1",		//	VOX_STRUCTURE_SOLD
	"SOVFORC1",		//	VOX_SOVIET_FORCES_FALLEN
	"SOVEMP1",		//	VOX_SOVIET_SELECTED
	"SOVEFAL1",		//	VOX_SOVIET_EMPIRE_FALLEN
	"OPTERM1",		//	VOX_OPERATION_TERMINATED
	"OBJRCH1",		//	VOX_OBJECTIVE_REACHED
	"OBJNRCH1",		//	VOX_OBJECTIVE_NOT_REACHED
	"OBJMET1",		//	VOX_OBJECTIVE_MET
	"MERCR1",		//	VOX_MERCENARY_RESCUED
	"MERCF1",		//	VOX_MERCENARY_FREED
	"KOSYFRE1",		//	VOX_KOSOYGEN_FREED
	"FLARE1",		//	VOX_FLARE_DETECTED
	"COMNDOR1",		//	VOX_COMMANDO_RESCUED
	"COMNDOF1",		//	VOX_COMMANDO_FREED
	"BLDGPRG1",		//	VOX_BUILDING_IN_PROGRESS
	"ATPREP1",		//	VOX_ATOM_PREPPING
	"ASELECT1",		//	VOX_ALLIED_SELECTED
	"APREP1",		//	VOX_ABOMB_PREPPING
	"ATLNCH1",		//	VOX_ATOM_LAUNCHED
	"AFALLEN1",		//	VOX_ALLIED_FORCES_FALLEN
	"AAVAIL1",		//	VOX_ABOMB_AVAILABLE
	"AARRIVE1",		//	VOX_ALLIED_REINFORCEMENTS
	"SAVE1",			//	VOX_MISSION_SAVED
	"LOAD1"			//	VOX_MISSION_LOADED
};


static VoxType CurrentVoice = VOX_NONE;


/***********************************************************************************************
 * Speech_Name -- Fetches the name for the voice specified.                                    *
 *                                                                                             *
 *    Use this routine to fetch the ASCII name of the speech id specified. Typical use of this *
 *    would be to build a displayable list of the speech types. The trigger system uses this   *
 *    so that a speech type can be selected.                                                   *
 *                                                                                             *
 * INPUT:   speech   -- The speech type id to convert to ASCII string.                         *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to the speech ASCII representation of the speech id type.   *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   06/01/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
char const * Speech_Name(VoxType speech)
{
	if (speech == VOX_NONE) return("none");
	return(Speech[speech]);
}


/***********************************************************************************************
 * Speak -- Computer speaks to the player.                                                     *
 *                                                                                             *
 *    This routine is used to have the game computer (EVA) speak to the player.                *
 *                                                                                             *
 * INPUT:   voice -- The voice number to speak (see defines.h).                                *
 *                                                                                             *
 * OUTPUT:  Returns with the handle of the playing speech (-1 if no voice started).            *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   11/12/1994 JLB : Created.                                                                 *
 *=============================================================================================*/
void Speak(VoxType voice)
{
	if (!Debug_Quiet && Options.Volume != 0 && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) {
		SpeakQueue = voice;
		Speak_AI();
	}
}


/***********************************************************************************************
 * Speak_AI -- Handles starting the EVA voices.                                                *
 *                                                                                             *
 *    This starts the EVA voice talking as well. If there is any speech request in the queue,  *
 *    it will be started when the current voice is finished. Call this routine as often as     *
 *    possible (once per game tick is sufficient).                                             *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   12/27/1994 JLB : Created.                                                                 *
 *=============================================================================================*/
void Speak_AI(void)
{
	static VoxType _last = VOX_NONE;
	if (Debug_Quiet || SampleType == 0) return;

	if (!Is_Sample_Playing(SpeechBuffer)) {
		CurrentVoice = VOX_NONE;
		if (SpeakQueue != VOX_NONE) {
			if (SpeakQueue != _last) {
				char name[_MAX_FNAME+_MAX_EXT];

				_makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD");
				CCFileClass file(name);
				if (file.Is_Available() && file.Read(SpeechBuffer, SPEECH_BUFFER_SIZE)) {
					Play_Sample(SpeechBuffer, 254, Options.Volume * 256);
					CurrentVoice = SpeakQueue;
				}
				_last = SpeakQueue;
			} else {
				Play_Sample(SpeechBuffer, 254, Options.Volume * 256);
			}
			SpeakQueue = VOX_NONE;
		}
	}
}


/***********************************************************************************************
 * Stop_Speaking -- Forces the EVA voice to stop talking.                                      *
 *                                                                                             *
 *    Use this routine to immediately stop the EVA voice from speaking. It also clears out     *
 *    the pending voice queue.                                                                 *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  none                                                                               *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   12/27/1994 JLB : Created.                                                                 *
 *=============================================================================================*/
void Stop_Speaking(void)
{
	SpeakQueue = VOX_NONE;
	Stop_Sample_Playing(SpeechBuffer);
}


/***********************************************************************************************
 * Is_Speaking -- Checks to see if the eva voice is still playing.                             *
 *                                                                                             *
 *    Call this routine when the EVA voice being played needs to be checked. A typical use     *
 *    of this would be when some action needs to be delayed until the voice has finished --    *
 *    say the end of the game.                                                                 *
 *                                                                                             *
 * INPUT:   none                                                                               *
 *                                                                                             *
 * OUTPUT:  bool; Is the EVA voice still playing?                                              *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   03/12/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
bool Is_Speaking(void)
{
	Speak_AI();
	if (!Debug_Quiet && SampleType != 0 && (SpeakQueue != VOX_NONE || Is_Sample_Playing(SpeechBuffer))) {
		return(true);
	}
	return(false);
}
