/* ** 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 . */ /* $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); }