859 lines
42 KiB
C++
859 lines
42 KiB
C++
//
|
|
// Copyright 2020 Electronic Arts Inc.
|
|
//
|
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
|
|
|
|
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
|
// in the hope that it will be useful, but with permitted additional restrictions
|
|
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
|
// distributed with this program. You should have received a copy of the
|
|
// GNU General Public License along with permitted additional restrictions
|
|
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
|
|
|
/* $Header: /CounterStrike/AUDIO.CPP 1 3/03/97 10:24a 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 : November 1, 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"
|
|
/*
|
|
**
|
|
**
|
|
** Win32lib stubs
|
|
**
|
|
**
|
|
**
|
|
*/
|
|
|
|
|
|
SFX_Type SoundType;
|
|
Sample_Type SampleType;
|
|
|
|
int File_Stream_Sample(char const *filename, BOOL real_time_start) { return 1; };
|
|
int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start) { return 1; };
|
|
void __cdecl Sound_Callback(void) {};
|
|
void __cdecl far maintenance_callback(void) {};
|
|
void *Load_Sample(char const *filename) { return NULL; };
|
|
long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size) { return 0; }
|
|
long Sample_Read(int fh, void *buffer, long size) { return 0; };
|
|
void Free_Sample(void const *sample) {};
|
|
BOOL Audio_Init(HWND window, int bits_per_sample, BOOL stereo, int rate, int reverse_channels) { return 0; };
|
|
void Sound_End(void) {};
|
|
void Stop_Sample(int handle) {};
|
|
BOOL Sample_Status(int handle) { return 0; };
|
|
BOOL Is_Sample_Playing(void const * sample) { return 0; };
|
|
void Stop_Sample_Playing(void const * sample) {};
|
|
int Play_Sample(void const *sample, int priority, int volume, signed short panloc) { return 1; };
|
|
int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id) { return 1; };
|
|
int Set_Sound_Vol(int volume) { return 0; };
|
|
int Set_Score_Vol(int volume) { return 0; };
|
|
void Fade_Sample(int handle, int ticks) {};
|
|
int Get_Free_Sample_Handle(int priority) { return 1; };
|
|
int Get_Digi_Handle(void) { return 1; }
|
|
long Sample_Length(void const *sample) { return 0; };
|
|
void Restore_Sound_Buffers(void) {};
|
|
BOOL Set_Primary_Buffer_Format(void) { return 0; };
|
|
BOOL Start_Primary_Sound_Buffer(BOOL forced) { return 0; };
|
|
void Stop_Primary_Sound_Buffer(void) {};
|
|
|
|
|
|
/***************************************************************************
|
|
** 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 { // MBL 02.21.2019
|
|
// Had to name the struct for VS 2017 distributed build. ST - 4/10/2019 3:59PM
|
|
struct SoundEffectNameStruct {
|
|
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_NOVAR}, // 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).
|
|
{"IRONCUR9", 10, IN_NOVAR}, // VOC_IRON1
|
|
{"EMOVOUT1", 20, IN_NOVAR}, // VOC_ENG_MOVEOUT Engineer: "movin' out"
|
|
{"SONPULSE", 10, IN_NOVAR}, // VOC_SONAR
|
|
{"SANDBAG2", 5, IN_NOVAR}, // VOC_SANDBAG sand bag crunch
|
|
{"MINEBLO1", 5, IN_NOVAR}, // VOC_MINEBLOW weird mine explosion
|
|
{"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).
|
|
{"SPLASH9", 5, IN_NOVAR}, // VOC_SPLASH water splash
|
|
{"KABOOM22", 1, IN_NOVAR}, // VOC_KABOOM22 Long explosion (sharp).
|
|
{"AACANON3", 1, IN_NOVAR},
|
|
{"TANDETH1", 10, 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?"
|
|
{"ANTDIE", 20, IN_NOVAR}, // VOC_ANTDIE
|
|
{"ANTBITE", 20, IN_NOVAR}, // VOC_ANTBITE
|
|
{"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"
|
|
//ADDED VG 2/24/97
|
|
{"STAVCMDR", 20, IN_NOVAR},
|
|
{"STAVCRSE", 20, IN_NOVAR},
|
|
{"STAVYES", 20, IN_NOVAR},
|
|
{"STAVMOV", 20, IN_NOVAR},
|
|
{"BUZZY1", 20, IN_NOVAR},
|
|
{"RAMBO1", 20, IN_NOVAR},
|
|
{"RAMBO2", 20, IN_NOVAR},
|
|
{"RAMBO3", 20, IN_NOVAR},
|
|
#ifdef FIXIT_CSII // checked - ajw 9/28/98
|
|
{"MYES1", 20, IN_NOVAR}, // VOC_MECHYES1 Mechanic: "Yes sir!"
|
|
{"MHOWDY1", 20, IN_NOVAR}, // VOC_MECHHOWDY1 Mechanic: "Howdy!"
|
|
{"MRISE1", 20, IN_NOVAR}, // VOC_MECHRISE1 Mechanic: "Rise 'n shine!"
|
|
{"MHUH1", 20, IN_NOVAR}, // VOC_MECHHUH1 Mechanic: "Huh?"
|
|
{"MHEAR1", 20, IN_NOVAR}, // VOC_MECHHEAR1 Mechanic: "I Hear Ya!"
|
|
{"MLAFF1", 20, IN_NOVAR}, // VOC_MECHLAFF1 Mechanic: guffaw
|
|
{"MBOSS1", 20, IN_NOVAR}, // VOC_MECHBOSS1 Mechanic: "Sure Thing, Boss!"
|
|
{"MYEEHAW1", 20, IN_NOVAR}, // VOC_MECHYEEHAW1 Mechanic: "Yee Haw!"
|
|
{"MHOTDIG1", 20, IN_NOVAR}, // VOC_MECHHOTDIG1 Mechanic: "Hot Diggity Dog!"
|
|
{"MWRENCH1", 20, IN_NOVAR}, // VOC_MECHWRENCH1 Mechanic: "I'll get my wrench."
|
|
|
|
{"JBURN1", 20, IN_NOVAR}, // VOC_STBURN1 Shock Trooper: "Burn baby burn!"
|
|
{"JCHRGE1", 20, IN_NOVAR}, // VOC_STCHRGE1 Shock Trooper: "Fully charged!"
|
|
{"JCRISP1", 20, IN_NOVAR}, // VOC_STCRISP1 Shock Trooper: "Extra Crispy!"
|
|
{"JDANCE1", 20, IN_NOVAR}, // VOC_STDANCE1 Shock Trooper: "Let's Dance!"
|
|
{"JJUICE1", 20, IN_NOVAR}, // VOC_STJUICE1 Shock Trooper: "Got juice?"
|
|
{"JJUMP1", 20, IN_NOVAR}, // VOC_STJUMP1 Shock Trooper: "Need a jump?"
|
|
{"JLIGHT1", 20, IN_NOVAR}, // VOC_STLIGHT1 Shock Trooper: "Lights out!"
|
|
{"JPOWER1", 20, IN_NOVAR}, // VOC_STPOWER1 Shock Trooper: "Power on!"
|
|
{"JSHOCK1", 20, IN_NOVAR}, // VOC_STSHOCK1 Shock Trooper: "Shocking!"
|
|
{"JYES1", 20, IN_NOVAR}, // VOC_STYES1 Shock Trooper: "Yesssss!"
|
|
|
|
{"CHROTNK1", 20, IN_NOVAR}, // VOC_CHRONOTANK1 Chrono tank teleport
|
|
{"FIXIT1", 20, IN_NOVAR}, // VOC_MECH_FIXIT1 Mechanic fixes something
|
|
{"MADCHRG2", 20, IN_NOVAR}, // VOC_MAD_CHARGE MAD tank charges up
|
|
{"MADEXPLO", 20, IN_NOVAR}, // VOC_MAD_EXPLODE MAD tank explodes
|
|
{"SHKTROP1", 20, IN_NOVAR}, // VOC_SHOCK_TROOP1 Shock Trooper fires
|
|
|
|
#endif
|
|
};
|
|
|
|
|
|
//
|
|
// External handlers. MBL 06.17.2019
|
|
//
|
|
extern void On_Sound_Effect(int sound_index, int variation, COORDINATE coord, int house);
|
|
// extern void On_Speech(int speech_index); MBL 02.06.2020
|
|
extern void On_Speech(int speech_index, HouseClass *house);
|
|
extern void On_Ping(const HouseClass* player_ptr, COORDINATE coord);
|
|
|
|
|
|
|
|
/***********************************************************************************************
|
|
* 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)
|
|
{
|
|
if (name == NULL) return(VOC_NONE);
|
|
|
|
for (VocType voc = VOC_FIRST; voc < VOC_COUNT; voc++) {
|
|
if (stricmp(name, SoundEffectName[voc].Name) == 0) {
|
|
return(voc);
|
|
}
|
|
}
|
|
|
|
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. *
|
|
* *
|
|
* variation -- This is the optional variation number to use when playing special *
|
|
* sound effects that have variations. For normal sound effects, this *
|
|
* parameter is ignored. *
|
|
* *
|
|
* house -- This specifies the optional house override value to use when playing *
|
|
* sound effects that have a variation. If not specified, then the current *
|
|
* player is examined for the house variation to use. *
|
|
* *
|
|
* 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. *
|
|
* 11/01/1996 JLB : House override control. *
|
|
*=============================================================================================*/
|
|
void Sound_Effect(VocType voc, COORDINATE coord, int variation, HousesType house)
|
|
{
|
|
//
|
|
// Intercept sound effect calls. MBL 06.17.2019
|
|
//
|
|
On_Sound_Effect((int)voc, variation, coord, (int)house);
|
|
|
|
#if 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, house);
|
|
#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. *
|
|
* *
|
|
* variation -- This is the optional variation number to use when playing special *
|
|
* sound effects that have variations. For normal sound effects, this *
|
|
* parameter is ignored. *
|
|
* *
|
|
* house -- This specifies the optional house override value to use when playing *
|
|
* sound effects that have a variation. If not specified, then the current *
|
|
* player is examined for the house variation to use. *
|
|
* *
|
|
* 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. *
|
|
* 11/01/1996 JLB : House override control. *
|
|
*=============================================================================================*/
|
|
int Sound_Effect(VocType voc, fixed volume, int variation, signed short pan_value, HousesType house)
|
|
{
|
|
//
|
|
// Intercept sound effect calls. MBL 06.17.2019
|
|
//
|
|
pan_value;
|
|
COORDINATE coord = 0;
|
|
On_Sound_Effect((int)voc, variation, coord, (int)house);
|
|
|
|
#if 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) {
|
|
|
|
/*
|
|
** If there is no forced house, then use the current player
|
|
** act like house.
|
|
*/
|
|
if (house == HOUSE_NONE) {
|
|
house = PlayerPtr->ActLike;
|
|
}
|
|
|
|
/*
|
|
** Change the extension based on the variation and house accent requested.
|
|
*/
|
|
if (((1 << house) & HOUSEF_ALLIES) != 0) {
|
|
|
|
/*
|
|
** 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";
|
|
}
|
|
}
|
|
} else {
|
|
if (variation < 0) {
|
|
if (ABS(variation) % 2) {
|
|
ext = ".R00";
|
|
} else {
|
|
ext = ".R02";
|
|
}
|
|
} else {
|
|
if (variation % 2) {
|
|
ext = ".R01";
|
|
} else {
|
|
ext = ".R03";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_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));
|
|
}
|
|
#endif
|
|
|
|
return(-1);
|
|
}
|
|
|
|
|
|
/*
|
|
** This elaborates all the EVA speech voices.
|
|
*/
|
|
/*static PG*/ 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
|
|
#ifdef FIXIT_CSII // checked - ajw 9/28/98
|
|
#ifdef ENGLISH
|
|
"TANK01", // VOX_MADTANK_DEPLOYED M.A.D. Tank Deployed
|
|
#else
|
|
"none",
|
|
#endif
|
|
#else
|
|
"none",
|
|
#endif
|
|
"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) // MBL 02.06.2020
|
|
void Speak(VoxType voice, HouseClass *house, COORDINATE coord)
|
|
{
|
|
// MBL 06.17.2019
|
|
if (voice == VOX_NONE)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Intercept speech calls. MBL 06.17.2019
|
|
//
|
|
|
|
// On_Speech((int)voice); // MBL 02.06.2020
|
|
On_Speech((int)voice, house);
|
|
if (coord) {
|
|
On_Ping(house, coord);
|
|
}
|
|
|
|
#if 0
|
|
if (!Debug_Quiet && Options.Volume != 0 && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) {
|
|
SpeakQueue = voice;
|
|
Speak_AI();
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
/***********************************************************************************************
|
|
* 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. *
|
|
* 10/11/1996 JLB : Handles multiple speech buffers. *
|
|
*=============================================================================================*/
|
|
void Speak_AI(void)
|
|
{
|
|
// MBL 06.17.2019 KO
|
|
#if 0
|
|
static int _index = 0;
|
|
if (Debug_Quiet || SampleType == 0) return;
|
|
|
|
if (!Is_Sample_Playing(SpeechBuffer[_index])) {
|
|
CurrentVoice = VOX_NONE;
|
|
if (SpeakQueue != VOX_NONE) {
|
|
|
|
/*
|
|
** Try to find a previously loaded copy of the EVA speech in one of the
|
|
** speech buffers.
|
|
*/
|
|
void const * speech = NULL;
|
|
for (int index = 0; index < ARRAY_SIZE(SpeechRecord); index++) {
|
|
if (SpeechRecord[index] == SpeakQueue) break;
|
|
}
|
|
|
|
/*
|
|
** If a previous copy could not be located, then load the requested
|
|
** voice into the oldest buffer available.
|
|
*/
|
|
if (speech == NULL) {
|
|
_index = (_index + 1) % ARRAY_SIZE(SpeechRecord);
|
|
|
|
char name[_MAX_FNAME+_MAX_EXT];
|
|
|
|
_makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD");
|
|
CCFileClass file(name);
|
|
if (file.Is_Available() && file.Read(SpeechBuffer[_index], SPEECH_BUFFER_SIZE)) {
|
|
speech = SpeechBuffer[_index];
|
|
SpeechRecord[_index] = SpeakQueue;
|
|
}
|
|
}
|
|
|
|
/*
|
|
** Since the speech file was loaded, play it.
|
|
*/
|
|
if (speech != NULL) {
|
|
Play_Sample(speech, 254, Options.Volume * 256);
|
|
CurrentVoice = SpeakQueue;
|
|
}
|
|
|
|
SpeakQueue = VOX_NONE;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// MBL 06.18.2019
|
|
if (SpeakQueue != VOX_NONE)
|
|
{
|
|
// On_Speech((int)SpeakQueue); // MBL 02.06.2020
|
|
On_Speech((int)SpeakQueue, NULL);
|
|
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);
|
|
}
|