AUDIO.CPP.BAK 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656
  1. /*
  2. ** Command & Conquer Red Alert(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /* $Header: F:\projects\c&c0\vcs\code\audio.cpv 4.78 03 Oct 1996 09:20:46 JOE_BOSTIC $ */
  19. /***********************************************************************************************
  20. *** 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 ***
  21. ***********************************************************************************************
  22. * *
  23. * Project Name : Command & Conquer *
  24. * *
  25. * File Name : AUDIO.CPP *
  26. * *
  27. * Programmer : Joe L. Bostic *
  28. * *
  29. * Start Date : September 10, 1993 *
  30. * *
  31. * Last Update : September 15, 1996 [JLB] *
  32. * *
  33. *---------------------------------------------------------------------------------------------*
  34. * Functions: *
  35. * Is_Speaking -- Checks to see if the eva voice is still playing. *
  36. * Sound_Effect -- General purpose sound player. *
  37. * Sound_Effect -- Plays a sound effect in the tactical map. *
  38. * Speak -- Computer speaks to the player. *
  39. * Speak_AI -- Handles starting the EVA voices. *
  40. * Speech_Name -- Fetches the name for the voice specified. *
  41. * Stop_Speaking -- Forces the EVA voice to stop talking. *
  42. * Voc_From_Name -- Fetch VocType from ASCII name specified. *
  43. * Voc_Name -- Fetches the name for the sound effect. *
  44. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  45. #include "function.h"
  46. /***************************************************************************
  47. ** Controls what special effects may occur on the sound effect.
  48. */
  49. typedef enum {
  50. IN_NOVAR, // No variation or alterations allowed.
  51. IN_VAR // Infantry variance response modification.
  52. } ContextType;
  53. static struct {
  54. char const * Name; // Digitized voice file name.
  55. int Priority; // Playback priority of this sample.
  56. ContextType Where; // In what game context does this sample exist.
  57. } SoundEffectName[VOC_COUNT] = {
  58. /*
  59. ** Civilian voices (technicians too).
  60. */
  61. {"GIRLOKAY", 20, IN_NOVAR}, // VOC_GIRL_OKAY
  62. {"GIRLYEAH", 20, IN_NOVAR}, // VOC_GIRL_YEAH
  63. {"GUYOKAY1", 20, IN_NOVAR}, // VOC_GUY_OKAY
  64. {"GUYYEAH1", 20, IN_NOVAR}, // VOC_GUY_YEAH
  65. {"MINELAY1", 5, IN_VAR}, // VOC_MINELAY1
  66. /*
  67. ** Infantry and vehicle responses.
  68. */
  69. {"ACKNO", 20, IN_VAR}, // VOC_ACKNOWL "acknowledged"
  70. {"AFFIRM1", 20, IN_VAR}, // VOC_AFFIRM "affirmative"
  71. {"AWAIT1", 20, IN_VAR}, // VOC_AWAIT1 "awaiting orders"
  72. {"EAFFIRM1", 20, IN_NOVAR}, // VOC_ENG_AFFIRM Engineer: "affirmative"
  73. {"EENGIN1", 20, IN_VAR}, // VOC_ENG_ENG Engineer: "engineering"
  74. {"NOPROB", 20, IN_VAR}, // VOC_NO_PROB "not a problem"
  75. {"READY", 20, IN_VAR}, // VOC_READY "ready and waiting"
  76. {"REPORT1", 20, IN_VAR}, // VOC_REPORT "reporting"
  77. {"RITAWAY", 20, IN_VAR}, // VOC_RIGHT_AWAY "right away sir"
  78. {"ROGER", 20, IN_VAR}, // VOC_ROGER "roger"
  79. {"UGOTIT", 20, IN_VAR}, // VOC_UGOTIT "you got it"
  80. {"VEHIC1", 20, IN_VAR}, // VOC_VEHIC1 "vehicle reporting"
  81. {"YESSIR1", 20, IN_VAR}, // VOC_YESSIR "yes sir"
  82. {"DEDMAN1", 10, IN_NOVAR}, // VOC_SCREAM1 short infantry scream
  83. {"DEDMAN2", 10, IN_NOVAR}, // VOC_SCREAM3 short infantry scream
  84. {"DEDMAN3", 10, IN_NOVAR}, // VOC_SCREAM4 short infantry scream
  85. {"DEDMAN4", 10, IN_NOVAR}, // VOC_SCREAM5 short infantry scream
  86. {"DEDMAN5", 10, IN_NOVAR}, // VOC_SCREAM6 short infantry scream
  87. {"DEDMAN6", 10, IN_NOVAR}, // VOC_SCREAM7 short infantry scream
  88. {"DEDMAN7", 10, IN_NOVAR}, // VOC_SCREAM10 short infantry scream
  89. {"DEDMAN8", 10, IN_NOVAR}, // VOC_SCREAM11 short infantry scream
  90. {"DEDMAN10", 10, IN_NOVAR}, // VOC_YELL1 long infantry scream
  91. {"CHRONO2", 5, IN_NOVAR}, // VOC_CHRONO Chronosphere sound
  92. {"CANNON1", 1, IN_NOVAR}, // VOC_CANNON1 Cannon sound (medium).
  93. {"CANNON2", 1, IN_NOVAR}, // VOC_CANNON2 Cannon sound (short).
  94. {"IRONCUR1", 5, IN_NOVAR}, // VOC_IRON1
  95. {"EMOVOUT1", 20, IN_NOVAR}, // VOC_ENG_MOVEOUT Engineer: "movin' out"
  96. {"IRONCUR2", 5, IN_NOVAR}, // VOC_IRON2
  97. {"x", 1, IN_NOVAR},
  98. {"x", 1, IN_NOVAR},
  99. {"CHUTE1", 1, IN_NOVAR}, // VOC_CHUTE1 Wind swoosh sound.
  100. {"DOGY1", 5, IN_NOVAR}, // VOC_DOG_BARK Dog bark.
  101. {"DOGW5", 10, IN_NOVAR}, // VOC_DOG_WHINE Dog whine.
  102. {"DOGG5P", 10, IN_NOVAR}, // VOC_DOG_GROWL2 Strong dog growl.
  103. {"FIREBL3", 1, IN_NOVAR}, // VOC_FIRE_LAUNCH Fireball launch sound.
  104. {"FIRETRT1", 1, IN_NOVAR}, // VOC_FIRE_EXPLODE Fireball explode sound.
  105. {"GRENADE1", 1, IN_NOVAR}, // VOC_GRENADE_TOSS Grenade toss.
  106. {"GUN11", 1, IN_NOVAR}, // VOC_GUN_5 5 round gun burst (slow).
  107. {"GUN13", 1, IN_NOVAR}, // VOC_GUN_7 7 round gun burst (fast).
  108. {"EYESSIR1", 20, IN_NOVAR}, // VOC_ENG_YES, Engineer: "yes sir"
  109. {"GUN27", 1, IN_NOVAR}, // VOC_GUN_RIFLE Rifle shot.
  110. {"HEAL2", 1, IN_NOVAR}, // VOC_HEAL Healing effect.
  111. {"HYDROD1", 1, IN_NOVAR}, // VOC_DOOR Hyrdrolic door.
  112. {"INVUL2", 1, IN_NOVAR}, // VOC_INVULNERABLE Invulnerability effect.
  113. {"KABOOM1", 1, IN_NOVAR}, // VOC_KABOOM1 Long explosion (muffled).
  114. {"KABOOM12", 1, IN_NOVAR}, // VOC_KABOOM12 Very long explosion (muffled).
  115. {"KABOOM15", 1, IN_NOVAR}, // VOC_KABOOM15 Very long explosion (muffled).
  116. {"x", 1, IN_NOVAR},
  117. {"KABOOM22", 1, IN_NOVAR}, // VOC_KABOOM22 Long explosion (sharp).
  118. {"x", 1, IN_NOVAR},
  119. {"x", 1, IN_NOVAR},
  120. {"MGUNINF1", 1, IN_NOVAR}, // VOC_GUN_5F 5 round gun burst (fast).
  121. {"MISSILE1", 1, IN_NOVAR}, // VOC_MISSILE_1 Missile with high tech effect.
  122. {"MISSILE6", 1, IN_NOVAR}, // VOC_MISSILE_2 Long missile launch.
  123. {"MISSILE7", 1, IN_NOVAR}, // VOC_MISSILE_3 Short missile launch.
  124. {"x", 1, IN_NOVAR},
  125. {"PILLBOX1", 1, IN_NOVAR}, // VOC_GUN_5R 5 round gun burst (rattles).
  126. {"RABEEP1", 1, IN_NOVAR}, // VOC_BEEP Generic beep sound.
  127. {"RAMENU1", 1, IN_NOVAR}, // VOC_CLICK Generic click sound.
  128. {"SILENCER", 1, IN_NOVAR}, // VOC_SILENCER Silencer.
  129. {"TANK5", 1, IN_NOVAR}, // VOC_CANNON6 Long muffled cannon shot.
  130. {"TANK6", 1, IN_NOVAR}, // VOC_CANNON7 Sharp mechanical cannon fire.
  131. {"TORPEDO1", 1, IN_NOVAR}, // VOC_TORPEDO Torpedo launch.
  132. {"TURRET1", 1, IN_NOVAR}, // VOC_CANNON8 Sharp cannon fire.
  133. {"TSLACHG2", 10, IN_NOVAR}, // VOC_TESLA_POWER_UP Hum charge up.
  134. {"TESLA1", 10, IN_NOVAR}, // VOC_TESLA_ZAP Tesla zap effect.
  135. {"SQUISHY2", 10, IN_NOVAR}, // VOC_SQUISH Squish effect.
  136. {"SCOLDY1", 10, IN_NOVAR}, // VOC_SCOLD Scold bleep.
  137. {"RADARON2", 20, IN_NOVAR}, // VOC_RADAR_ON Powering up electronics.
  138. {"RADARDN1", 10, IN_NOVAR}, // VOC_RADAR_OFF B movie power down effect.
  139. {"PLACBLDG", 10, IN_NOVAR}, // VOC_PLACE_BUILDING_DOWN Building slam down sound.
  140. {"KABOOM30", 1, IN_NOVAR}, // VOC_KABOOM30 Short explosion (HE).
  141. {"KABOOM25", 10, IN_NOVAR}, // VOC_KABOOM25 Short growling explosion.
  142. {"x", 10, IN_NOVAR},
  143. {"DOGW7", 10, IN_NOVAR}, // VOC_DOG_HURT Dog whine (loud).
  144. {"DOGW3PX", 10, IN_NOVAR}, // VOC_DOG_YES Dog 'yes sir'.
  145. {"CRMBLE2", 10, IN_NOVAR}, // VOC_CRUMBLE Building crumble.
  146. {"CASHUP1", 10, IN_NOVAR}, // VOC_MONEY_UP Rising money tick.
  147. {"CASHDN1", 10, IN_NOVAR}, // VOC_MONEY_DOWN Falling money tick.
  148. {"BUILD5", 10, IN_NOVAR}, // VOC_CONSTRUCTION Building construction sound.
  149. {"BLEEP9", 10, IN_NOVAR}, // VOC_GAME_CLOSED Long bleep.
  150. {"BLEEP6", 10, IN_NOVAR}, // VOC_INCOMING_MESSAGE Soft happy warble.
  151. {"BLEEP5", 10, IN_NOVAR}, // VOC_SYS_ERROR Sharp soft warble.
  152. {"BLEEP17", 10, IN_NOVAR}, // VOC_OPTIONS_CHANGED Mid range soft warble.
  153. {"BLEEP13", 10, IN_NOVAR}, // VOC_GAME_FORMING Long warble.
  154. {"BLEEP12", 10, IN_NOVAR}, // VOC_PLAYER_LEFT Chirp sequence.
  155. {"BLEEP11", 10, IN_NOVAR}, // VOC_PLAYER_JOINED Reverse chirp sequence.
  156. {"H2OBOMB2", 10, IN_NOVAR}, // VOC_DEPTH_CHARGE Distant explosion sound.
  157. {"CASHTURN", 10, IN_NOVAR}, // VOC_CASHTURN Airbrake.
  158. {"TUFFGUY1", 20, IN_NOVAR}, // VOC_TANYA_CHEW Tanya: "Chew on this"
  159. {"ROKROLL1", 20, IN_NOVAR}, // VOC_TANYA_ROCK Tanya: "Let's rock"
  160. {"LAUGH1", 20, IN_NOVAR}, // VOC_TANYA_LAUGH Tanya: "ha ha ha"
  161. {"CMON1", 20, IN_NOVAR}, // VOC_TANYA_SHAKE Tanya: "Shake it baby"
  162. {"BOMBIT1", 20, IN_NOVAR}, // VOC_TANYA_CHING Tanya: "Cha Ching"
  163. {"GOTIT1", 20, IN_NOVAR}, // VOC_TANYA_GOT Tanya: "That's all you got"
  164. {"KEEPEM1", 20, IN_NOVAR}, // VOC_TANYA_KISS Tanya: "Kiss it bye bye"
  165. {"ONIT1", 20, IN_NOVAR}, // VOC_TANYA_THERE Tanya: "I'm there"
  166. {"LEFTY1", 20, IN_NOVAR}, // VOC_TANYA_GIVE Tanya: "Give it to me"
  167. {"YEAH1", 20, IN_NOVAR}, // VOC_TANYA_YEA Tanya: "Yea?"
  168. {"YES1", 20, IN_NOVAR}, // VOC_TANYA_YES Tanya: "Yes sir?"
  169. {"YO1", 20, IN_NOVAR}, // VOC_TANYA_WHATS Tanya: "What's up."
  170. {"WALLKIL2", 5, IN_NOVAR}, // VOC_WALLKILL2 Crushing wall sound.
  171. {"x", 10, IN_NOVAR},
  172. {"GUN5", 5, IN_NOVAR}, // VOC_TRIPLE_SHOT Three quick shots in succession.
  173. {"SUBSHOW1", 5, IN_NOVAR}, // VOC_SUBSHOW Submarine surface sound.
  174. {"EINAH1", 20, IN_NOVAR}, // VOC_E_AH, Einstien "ah"
  175. {"EINOK1", 20, IN_NOVAR}, // VOC_E_OK, Einstien "ok"
  176. {"EINYES1", 20, IN_NOVAR}, // VOC_E_YES, Einstien "yes"
  177. {"MINE1", 10, IN_NOVAR}, // VOC_TRIP_MINE mine explosion sound
  178. {"SCOMND1", 20, IN_NOVAR}, // VOC_SPY_COMMANDER Spy: "commander?"
  179. {"SYESSIR1", 20, IN_NOVAR}, // VOC_SPY_YESSIR Spy: "yes sir"
  180. {"SINDEED1", 20, IN_NOVAR}, // VOC_SPY_INDEED Spy: "indeed"
  181. {"SONWAY1", 20, IN_NOVAR}, // VOC_SPY_ONWAY Spy: "on my way"
  182. {"SKING1", 20, IN_NOVAR}, // VOC_SPY_KING Spy: "for king and country"
  183. {"MRESPON1", 20, IN_NOVAR}, // VOC_MED_REPORTING Medic: "reporting"
  184. {"MYESSIR1", 20, IN_NOVAR}, // VOC_MED_YESSIR Medic: "yes sir"
  185. {"MAFFIRM1", 20, IN_NOVAR}, // VOC_MED_AFFIRM Medic: "affirmative"
  186. {"MMOVOUT1", 20, IN_NOVAR}, // VOC_MED_MOVEOUT Medic: "movin' out"
  187. {"BEEPSLCT", 10, IN_NOVAR}, // VOC_BEEP_SELECT map selection beep
  188. {"SYEAH1", 20, IN_NOVAR}, // VOC_THIEF_YEA Thief: "yea?"
  189. {"x", 20, IN_NOVAR},
  190. {"x", 20, IN_NOVAR},
  191. {"SMOUT1", 20, IN_NOVAR}, // VOC_THIEF_MOVEOUT Thief: "movin' out"
  192. {"SOKAY1", 20, IN_NOVAR}, // VOC_THIEF_OKAY Thief: "ok"
  193. {"x", 20, IN_NOVAR},
  194. {"SWHAT1", 20, IN_NOVAR}, // VOC_THIEF_WHAT Thief: "what"
  195. {"SAFFIRM1", 20, IN_NOVAR}, // VOC_THIEF_AFFIRM Thief: "affirmative"
  196. };
  197. /***********************************************************************************************
  198. * Voc_From_Name -- Fetch VocType from ASCII name specified. *
  199. * *
  200. * This will find the corresponding VocType from the ASCII string specified. It does this *
  201. * by finding a root filename that matches the string. *
  202. * *
  203. * INPUT: name -- Pointer to the ASCII string that will be converted into a VocType. *
  204. * *
  205. * OUTPUT: Returns with the VocType that matches the string specified. If no match could be *
  206. * found, then VOC_NONE is returned. *
  207. * *
  208. * WARNINGS: none *
  209. * *
  210. * HISTORY: *
  211. * 07/06/1996 JLB : Created. *
  212. *=============================================================================================*/
  213. VocType Voc_From_Name(char const * name)
  214. {
  215. #ifdef 0
  216. if (name == NULL) return(VOC_NONE);
  217. for (VocType voc = VOC_FIRST; voc < VOC_COUNT; voc++) {
  218. if (stricmp(name, SoundEffectName[voc].Name) == 0) {
  219. return(voc);
  220. }
  221. }
  222. #endif
  223. return(VOC_NONE);
  224. }
  225. /***********************************************************************************************
  226. * Voc_Name -- Fetches the name for the sound effect. *
  227. * *
  228. * This routine returns the descriptive name of the sound effect. Currently, this is just *
  229. * the root of the file name. *
  230. * *
  231. * INPUT: voc -- The VocType that the corresponding name is requested. *
  232. * *
  233. * OUTPUT: Returns with a pointer to the text string the represents the sound effect. *
  234. * *
  235. * WARNINGS: none *
  236. * *
  237. * HISTORY: *
  238. * 05/06/1996 JLB : Created. *
  239. *=============================================================================================*/
  240. char const * Voc_Name(VocType voc)
  241. {
  242. if (voc == VOC_NONE) return("none");
  243. return(SoundEffectName[voc].Name);
  244. }
  245. /***********************************************************************************************
  246. * Sound_Effect -- Plays a sound effect in the tactical map. *
  247. * *
  248. * This routine is used when a sound effect occurs in the game world. It handles fading *
  249. * the sound according to distance. *
  250. * *
  251. * INPUT: voc -- The sound effect number to play. *
  252. * *
  253. * coord -- The world location that the sound originates from. *
  254. * *
  255. * OUTPUT: none *
  256. * *
  257. * WARNINGS: none *
  258. * *
  259. * HISTORY: *
  260. * 11/12/1994 JLB : Created. *
  261. * 01/05/1995 JLB : Reduces sound more dramatically when off screen. *
  262. * 09/15/1996 JLB : Revamped volume logic. *
  263. *=============================================================================================*/
  264. void Sound_Effect(VocType voc, COORDINATE coord, int variation)
  265. {
  266. #ifdef 0
  267. CELL cell_pos = 0;
  268. int pan_value;
  269. if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
  270. return;
  271. }
  272. if (coord) {
  273. cell_pos = Coord_Cell(coord);
  274. }
  275. fixed volume = 1;
  276. pan_value = 0;
  277. if (coord && !Map.In_View(cell_pos)) {
  278. int distance = Distance(coord, Map.TacticalCoord) / CELL_LEPTON_W;
  279. fixed dfixed = fixed(distance, 128+64);
  280. dfixed.Sub_Saturate(1);
  281. volume = fixed(1) - dfixed;
  282. pan_value = Cell_X(cell_pos);
  283. pan_value -= Coord_XCell(Map.TacticalCoord) + (Lepton_To_Cell(Map.TacLeptonWidth) / 2);
  284. if (ABS(pan_value) > Lepton_To_Cell(Map.TacLeptonWidth / 2)) {
  285. pan_value *= 0x8000;
  286. pan_value /= (MAP_CELL_W >> 2);
  287. pan_value = Bound(pan_value, -0x7FFF, 0x7FFF);
  288. } else {
  289. pan_value = 0;
  290. }
  291. }
  292. Sound_Effect(voc, volume, variation, pan_value);
  293. #endif
  294. }
  295. /***********************************************************************************************
  296. * Sound_Effect -- General purpose sound player. *
  297. * *
  298. * This is used for general purpose sound effects. These are sounds that occur outside *
  299. * of the game world. They do not have a corresponding game world location as their source. *
  300. * *
  301. * INPUT: voc -- The sound effect number to play. *
  302. * *
  303. * volume -- The volume to assign to this sound effect. *
  304. * *
  305. * OUTPUT: Returns with the sound handle (-1 if no sound was played). *
  306. * *
  307. * WARNINGS: none *
  308. * *
  309. * HISTORY: *
  310. * 11/12/1994 JLB : Created. *
  311. * 11/12/1994 JLB : Handles cache logic. *
  312. * 05/04/1995 JLB : Variation adjustments. *
  313. *=============================================================================================*/
  314. int Sound_Effect(VocType voc, fixed volume, int variation, signed short pan_value)
  315. {
  316. #ifdef 0
  317. char name[_MAX_FNAME+_MAX_EXT]; // Working filename of sound effect.
  318. if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
  319. return(-1);
  320. }
  321. /*
  322. ** Alter the volume according to the game volume setting.
  323. */
  324. volume = volume * Options.Volume;
  325. /*
  326. ** Fetch a pointer to the sound effect data. Modify the sound as appropriate and desired.
  327. */
  328. char const * ext = ".AUD";
  329. if (SoundEffectName[voc].Where == IN_VAR) {
  330. /*
  331. ** For infantry, use a variation on the response. For vehicles, always
  332. ** use the vehicle response table.
  333. */
  334. if (variation < 0) {
  335. if (ABS(variation) % 2) {
  336. ext = ".V00";
  337. } else {
  338. ext = ".V02";
  339. }
  340. } else {
  341. if (variation % 2) {
  342. ext = ".V01";
  343. } else {
  344. ext = ".V03";
  345. }
  346. }
  347. }
  348. _makepath(name, NULL, NULL, SoundEffectName[voc].Name, ext);
  349. void const * ptr = MFCD::Retrieve(name);
  350. /*
  351. ** If the sound data pointer is not null, then presume that it is valid.
  352. */
  353. if (ptr != NULL) {
  354. volume.Sub_Saturate(1);
  355. return(Play_Sample(ptr, SoundEffectName[voc].Priority * volume, volume*256, pan_value));
  356. // } else {
  357. // Mono_Printf("Cannot find '%s'.\n", name);
  358. }
  359. #endif
  360. return(-1);
  361. }
  362. /*
  363. ** This elaborates all the EVA speech voices.
  364. */
  365. static char const * Speech[VOX_COUNT] = {
  366. "MISNWON1", // VOX_ACCOMPLISHED mission accomplished
  367. "MISNLST1", // VOX_FAIL your mission has failed
  368. "PROGRES1", // VOX_NO_FACTORY unable to comply, building in progress
  369. "CONSCMP1", // VOX_CONSTRUCTION construction complete
  370. "UNITRDY1", // VOX_UNIT_READY unit ready
  371. "NEWOPT1", // VOX_NEW_CONSTRUCT new construction options
  372. "NODEPLY1", // VOX_DEPLOY cannot deploy here
  373. "STRCKIL1", // VOX_STRUCTURE_DESTROYED, structure destroyed
  374. "NOPOWR1", // VOX_INSUFFICIENT_POWER, insufficient power
  375. "NOFUNDS1", // VOX_NO_CASH insufficient funds
  376. "BCT1", // VOX_CONTROL_EXIT battle control terminated
  377. "REINFOR1", // VOX_REINFORCEMENTS reinforcements have arrived
  378. "CANCLD1", // VOX_CANCELED canceled
  379. "ABLDGIN1", // VOX_BUILDING building
  380. "LOPOWER1", // VOX_LOW_POWER low power
  381. "NOFUNDS1", // VOX_NEED_MO_MONEY insufficent funds
  382. "BASEATK1", // VOX_BASE_UNDER_ATTACK our base is under attack
  383. "NOBUILD1", // VOX_UNABLE_TO_BUILD unable to build more
  384. "PRIBLDG1", // VOX_PRIMARY_SELECTED primary building selected
  385. "none",
  386. "none", // VOX_SOVIET_CAPTURED Allied building captured
  387. "UNITLST1", // VOX_UNIT_LOST unit lost
  388. "SLCTTGT1", // VOX_SELECT_TARGET select target
  389. "ENMYAPP1", // VOX_PREPARE enemy approaching
  390. "SILOND1", // VOX_NEED_MO_CAPACITY silos needed
  391. "ONHOLD1", // VOX_SUSPENDED on hold
  392. "REPAIR1", // VOX_REPAIRING repairing
  393. "none",
  394. "none",
  395. "AUNITL1", // VOX_AIRCRAFT_LOST airborne unit lost
  396. "none",
  397. "AAPPRO1", // VOX_ALLIED_FORCES_APPROACHING allied forces approaching
  398. "AARRIVE1", // VOX_ALLIED_APPROACHING allied reinforcements have arrived
  399. "none",
  400. "none",
  401. "BLDGINF1", // VOX_BUILDING_INFILTRATED building infiltrated
  402. "CHROCHR1", // VOX_CHRONO_CHARGING chronosphere charging
  403. "CHRORDY1", // VOX_CHRONO_READY chronosphere ready
  404. "CHROYES1", // VOX_CHRONO_TEST chronosphere test successful
  405. "CMDCNTR1", // VOX_HQ_UNDER_ATTACK command center under attack
  406. "CNTLDED1", // VOX_CENTER_DEACTIVATED control center deactivated
  407. "CONVYAP1", // VOX_CONVOY_APPROACHING convoy approaching
  408. "CONVLST1", // VOX_CONVOY_UNIT_LOST convoy unit lost
  409. "XPLOPLC1", // VOX_EXPLOSIVE_PLACED explosive charge placed
  410. "CREDIT1", // VOX_MONEY_STOLEN credits stolen
  411. "NAVYLST1", // VOX_SHIP_LOST naval unit lost
  412. "SATLNCH1", // VOX_SATALITE_LAUNCHED satalite launched
  413. "PULSE1", // VOX_SONAR_AVAILABLE sonar pulse available
  414. "none",
  415. "SOVFAPP1", // VOX_SOVIET_FORCES_APPROACHING soviet forces approaching
  416. "SOVREIN1", // VOX_SOVIET_REINFROCEMENTS soviet reinforcements have arrived
  417. "TRAIN1", // VOX_TRAINING training
  418. "AREADY1", // VOX_ABOMB_READY
  419. "ALAUNCH1", // VOX_ABOMB_LAUNCH
  420. "AARRIVN1", // VOX_ALLIES_N
  421. "AARRIVS1", // VOX_ALLIES_S
  422. "AARIVE1", // VOX_ALLIES_E
  423. "AARRIVW1", // VOX_ALLIES_W
  424. "1OBJMET1", // VOX_OBJECTIVE1
  425. "2OBJMET1", // VOX_OBJECTIVE2
  426. "3OBJMET1", // VOX_OBJECTIVE3
  427. "IRONCHG1", // VOX_IRON_CHARGING
  428. "IRONRDY1", // VOX_IRON_READY
  429. "KOSYRES1", // VOX_RESCUED
  430. "OBJNMET1", // VOX_OBJECTIVE_NOT
  431. "FLAREN1", // VOX_SIGNAL_N
  432. "FLARES1", // VOX_SIGNAL_S
  433. "FLAREE1", // VOX_SIGNAL_E
  434. "FLAREW1", // VOX_SIGNAL_W
  435. "SPYPLN1", // VOX_SPY_PLANE
  436. "TANYAF1", // VOX_FREED
  437. "ARMORUP1", // VOX_UPGRADE_ARMOR
  438. "FIREPO1", // VOX_UPGRADE_FIREPOWER
  439. "UNITSPD1", // VOX_UPGRADE_SPEED
  440. "MTIMEIN1", // VOX_MISSION_TIMER
  441. "UNITFUL1", // VOX_UNIT_FULL
  442. "UNITREP1", // VOX_UNIT_REPAIRED
  443. "40MINR", // VOX_TIME_40
  444. "30MINR", // VOX_TIME_30
  445. "20MINR", // VOX_TIME_20
  446. "10MINR", // VOX_TIME_10
  447. "5MINR", // VOX_TIME_5
  448. "4MINR", // VOX_TIME_4
  449. "3MINR", // VOX_TIME_3
  450. "2MINR", // VOX_TIME_2
  451. "1MINR", // VOX_TIME_1
  452. "TIMERNO1", // VOX_TIME_STOP
  453. "UNITSLD1", // VOX_UNIT_SOLD
  454. "TIMERGO1", // VOX_TIMER_STARTED
  455. "TARGRES1", // VOX_TARGET_RESCUED
  456. "TARGFRE1", // VOX_TARGET_FREED
  457. "TANYAR1", // VOX_TANYA_RESCUED
  458. "STRUSLD1", // VOX_STRUCTURE_SOLD
  459. "SOVFORC1", // VOX_SOVIET_FORCES_FALLEN
  460. "SOVEMP1", // VOX_SOVIET_SELECTED
  461. "SOVEFAL1", // VOX_SOVIET_EMPIRE_FALLEN
  462. "OPTERM1", // VOX_OPERATION_TERMINATED
  463. "OBJRCH1", // VOX_OBJECTIVE_REACHED
  464. "OBJNRCH1", // VOX_OBJECTIVE_NOT_REACHED
  465. "OBJMET1", // VOX_OBJECTIVE_MET
  466. "MERCR1", // VOX_MERCENARY_RESCUED
  467. "MERCF1", // VOX_MERCENARY_FREED
  468. "KOSYFRE1", // VOX_KOSOYGEN_FREED
  469. "FLARE1", // VOX_FLARE_DETECTED
  470. "COMNDOR1", // VOX_COMMANDO_RESCUED
  471. "COMNDOF1", // VOX_COMMANDO_FREED
  472. "BLDGPRG1", // VOX_BUILDING_IN_PROGRESS
  473. "ATPREP1", // VOX_ATOM_PREPPING
  474. "ASELECT1", // VOX_ALLIED_SELECTED
  475. "APREP1", // VOX_ABOMB_PREPPING
  476. "ATLNCH1", // VOX_ATOM_LAUNCHED
  477. "AFALLEN1", // VOX_ALLIED_FORCES_FALLEN
  478. "AAVAIL1", // VOX_ABOMB_AVAILABLE
  479. "AARRIVE1", // VOX_ALLIED_REINFORCEMENTS
  480. "SAVE1", // VOX_MISSION_SAVED
  481. "LOAD1" // VOX_MISSION_LOADED
  482. };
  483. static VoxType CurrentVoice = VOX_NONE;
  484. /***********************************************************************************************
  485. * Speech_Name -- Fetches the name for the voice specified. *
  486. * *
  487. * Use this routine to fetch the ASCII name of the speech id specified. Typical use of this *
  488. * would be to build a displayable list of the speech types. The trigger system uses this *
  489. * so that a speech type can be selected. *
  490. * *
  491. * INPUT: speech -- The speech type id to convert to ASCII string. *
  492. * *
  493. * OUTPUT: Returns with a pointer to the speech ASCII representation of the speech id type. *
  494. * *
  495. * WARNINGS: none *
  496. * *
  497. * HISTORY: *
  498. * 06/01/1996 JLB : Created. *
  499. *=============================================================================================*/
  500. char const * Speech_Name(VoxType speech)
  501. {
  502. if (speech == VOX_NONE) return("none");
  503. return(Speech[speech]);
  504. }
  505. /***********************************************************************************************
  506. * Speak -- Computer speaks to the player. *
  507. * *
  508. * This routine is used to have the game computer (EVA) speak to the player. *
  509. * *
  510. * INPUT: voice -- The voice number to speak (see defines.h). *
  511. * *
  512. * OUTPUT: Returns with the handle of the playing speech (-1 if no voice started). *
  513. * *
  514. * WARNINGS: none *
  515. * *
  516. * HISTORY: *
  517. * 11/12/1994 JLB : Created. *
  518. *=============================================================================================*/
  519. void Speak(VoxType voice)
  520. {
  521. if (!Debug_Quiet && Options.Volume != 0 && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) {
  522. SpeakQueue = voice;
  523. Speak_AI();
  524. }
  525. }
  526. /***********************************************************************************************
  527. * Speak_AI -- Handles starting the EVA voices. *
  528. * *
  529. * This starts the EVA voice talking as well. If there is any speech request in the queue, *
  530. * it will be started when the current voice is finished. Call this routine as often as *
  531. * possible (once per game tick is sufficient). *
  532. * *
  533. * INPUT: none *
  534. * *
  535. * OUTPUT: none *
  536. * *
  537. * WARNINGS: none *
  538. * *
  539. * HISTORY: *
  540. * 12/27/1994 JLB : Created. *
  541. *=============================================================================================*/
  542. void Speak_AI(void)
  543. {
  544. static VoxType _last = VOX_NONE;
  545. if (Debug_Quiet || SampleType == 0) return;
  546. if (!Is_Sample_Playing(SpeechBuffer)) {
  547. CurrentVoice = VOX_NONE;
  548. if (SpeakQueue != VOX_NONE) {
  549. if (SpeakQueue != _last) {
  550. char name[_MAX_FNAME+_MAX_EXT];
  551. _makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD");
  552. CCFileClass file(name);
  553. if (file.Is_Available() && file.Read(SpeechBuffer, SPEECH_BUFFER_SIZE)) {
  554. Play_Sample(SpeechBuffer, 254, Options.Volume * 256);
  555. CurrentVoice = SpeakQueue;
  556. }
  557. _last = SpeakQueue;
  558. } else {
  559. Play_Sample(SpeechBuffer, 254, Options.Volume * 256);
  560. }
  561. SpeakQueue = VOX_NONE;
  562. }
  563. }
  564. }
  565. /***********************************************************************************************
  566. * Stop_Speaking -- Forces the EVA voice to stop talking. *
  567. * *
  568. * Use this routine to immediately stop the EVA voice from speaking. It also clears out *
  569. * the pending voice queue. *
  570. * *
  571. * INPUT: none *
  572. * *
  573. * OUTPUT: none *
  574. * *
  575. * WARNINGS: none *
  576. * *
  577. * HISTORY: *
  578. * 12/27/1994 JLB : Created. *
  579. *=============================================================================================*/
  580. void Stop_Speaking(void)
  581. {
  582. SpeakQueue = VOX_NONE;
  583. Stop_Sample_Playing(SpeechBuffer);
  584. }
  585. /***********************************************************************************************
  586. * Is_Speaking -- Checks to see if the eva voice is still playing. *
  587. * *
  588. * Call this routine when the EVA voice being played needs to be checked. A typical use *
  589. * of this would be when some action needs to be delayed until the voice has finished -- *
  590. * say the end of the game. *
  591. * *
  592. * INPUT: none *
  593. * *
  594. * OUTPUT: bool; Is the EVA voice still playing? *
  595. * *
  596. * WARNINGS: none *
  597. * *
  598. * HISTORY: *
  599. * 03/12/1995 JLB : Created. *
  600. *=============================================================================================*/
  601. bool Is_Speaking(void)
  602. {
  603. Speak_AI();
  604. if (!Debug_Quiet && SampleType != 0 && (SpeakQueue != VOX_NONE || Is_Sample_Playing(SpeechBuffer))) {
  605. return(true);
  606. }
  607. return(false);
  608. }