AUDIO.CPP 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. //
  2. // Copyright 2020 Electronic Arts Inc.
  3. //
  4. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
  5. // software: you can redistribute it and/or modify it under the terms of
  6. // the GNU General Public License as published by the Free Software Foundation,
  7. // either version 3 of the License, or (at your option) any later version.
  8. // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
  9. // in the hope that it will be useful, but with permitted additional restrictions
  10. // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
  11. // distributed with this program. You should have received a copy of the
  12. // GNU General Public License along with permitted additional restrictions
  13. // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
  14. /* $Header: /CounterStrike/AUDIO.CPP 1 3/03/97 10:24a Joe_bostic $ */
  15. /***********************************************************************************************
  16. *** 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 ***
  17. ***********************************************************************************************
  18. * *
  19. * Project Name : Command & Conquer *
  20. * *
  21. * File Name : AUDIO.CPP *
  22. * *
  23. * Programmer : Joe L. Bostic *
  24. * *
  25. * Start Date : September 10, 1993 *
  26. * *
  27. * Last Update : November 1, 1996 [JLB] *
  28. * *
  29. *---------------------------------------------------------------------------------------------*
  30. * Functions: *
  31. * Is_Speaking -- Checks to see if the eva voice is still playing. *
  32. * Sound_Effect -- General purpose sound player. *
  33. * Sound_Effect -- Plays a sound effect in the tactical map. *
  34. * Speak -- Computer speaks to the player. *
  35. * Speak_AI -- Handles starting the EVA voices. *
  36. * Speech_Name -- Fetches the name for the voice specified. *
  37. * Stop_Speaking -- Forces the EVA voice to stop talking. *
  38. * Voc_From_Name -- Fetch VocType from ASCII name specified. *
  39. * Voc_Name -- Fetches the name for the sound effect. *
  40. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  41. #include "function.h"
  42. /*
  43. **
  44. **
  45. ** Win32lib stubs
  46. **
  47. **
  48. **
  49. */
  50. SFX_Type SoundType;
  51. Sample_Type SampleType;
  52. int File_Stream_Sample(char const *filename, BOOL real_time_start) { return 1; };
  53. int File_Stream_Sample_Vol(char const *filename, int volume, BOOL real_time_start) { return 1; };
  54. void __cdecl Sound_Callback(void) {};
  55. void __cdecl far maintenance_callback(void) {};
  56. void *Load_Sample(char const *filename) { return NULL; };
  57. long Load_Sample_Into_Buffer(char const *filename, void *buffer, long size) { return 0; }
  58. long Sample_Read(int fh, void *buffer, long size) { return 0; };
  59. void Free_Sample(void const *sample) {};
  60. BOOL Audio_Init(HWND window, int bits_per_sample, BOOL stereo, int rate, int reverse_channels) { return 0; };
  61. void Sound_End(void) {};
  62. void Stop_Sample(int handle) {};
  63. BOOL Sample_Status(int handle) { return 0; };
  64. BOOL Is_Sample_Playing(void const * sample) { return 0; };
  65. void Stop_Sample_Playing(void const * sample) {};
  66. int Play_Sample(void const *sample, int priority, int volume, signed short panloc) { return 1; };
  67. int Play_Sample_Handle(void const *sample, int priority, int volume, signed short panloc, int id) { return 1; };
  68. int Set_Sound_Vol(int volume) { return 0; };
  69. int Set_Score_Vol(int volume) { return 0; };
  70. void Fade_Sample(int handle, int ticks) {};
  71. int Get_Free_Sample_Handle(int priority) { return 1; };
  72. int Get_Digi_Handle(void) { return 1; }
  73. long Sample_Length(void const *sample) { return 0; };
  74. void Restore_Sound_Buffers(void) {};
  75. BOOL Set_Primary_Buffer_Format(void) { return 0; };
  76. BOOL Start_Primary_Sound_Buffer(BOOL forced) { return 0; };
  77. void Stop_Primary_Sound_Buffer(void) {};
  78. /***************************************************************************
  79. ** Controls what special effects may occur on the sound effect.
  80. */
  81. typedef enum {
  82. IN_NOVAR, // No variation or alterations allowed.
  83. IN_VAR // Infantry variance response modification.
  84. } ContextType;
  85. // static struct { // MBL 02.21.2019
  86. // Had to name the struct for VS 2017 distributed build. ST - 4/10/2019 3:59PM
  87. struct SoundEffectNameStruct {
  88. char const * Name; // Digitized voice file name.
  89. int Priority; // Playback priority of this sample.
  90. ContextType Where; // In what game context does this sample exist.
  91. } SoundEffectName[VOC_COUNT] = {
  92. /*
  93. ** Civilian voices (technicians too).
  94. */
  95. {"GIRLOKAY", 20, IN_NOVAR}, // VOC_GIRL_OKAY
  96. {"GIRLYEAH", 20, IN_NOVAR}, // VOC_GIRL_YEAH
  97. {"GUYOKAY1", 20, IN_NOVAR}, // VOC_GUY_OKAY
  98. {"GUYYEAH1", 20, IN_NOVAR}, // VOC_GUY_YEAH
  99. {"MINELAY1", 5, IN_VAR}, // VOC_MINELAY1
  100. /*
  101. ** Infantry and vehicle responses.
  102. */
  103. {"ACKNO", 20, IN_VAR}, // VOC_ACKNOWL "acknowledged"
  104. {"AFFIRM1", 20, IN_VAR}, // VOC_AFFIRM "affirmative"
  105. {"AWAIT1", 20, IN_VAR}, // VOC_AWAIT1 "awaiting orders"
  106. {"EAFFIRM1", 20, IN_NOVAR}, // VOC_ENG_AFFIRM Engineer: "affirmative"
  107. {"EENGIN1", 20, IN_NOVAR}, // VOC_ENG_ENG Engineer: "engineering"
  108. {"NOPROB", 20, IN_VAR}, // VOC_NO_PROB "not a problem"
  109. {"READY", 20, IN_VAR}, // VOC_READY "ready and waiting"
  110. {"REPORT1", 20, IN_VAR}, // VOC_REPORT "reporting"
  111. {"RITAWAY", 20, IN_VAR}, // VOC_RIGHT_AWAY "right away sir"
  112. {"ROGER", 20, IN_VAR}, // VOC_ROGER "roger"
  113. {"UGOTIT", 20, IN_VAR}, // VOC_UGOTIT "you got it"
  114. {"VEHIC1", 20, IN_VAR}, // VOC_VEHIC1 "vehicle reporting"
  115. {"YESSIR1", 20, IN_VAR}, // VOC_YESSIR "yes sir"
  116. {"DEDMAN1", 10, IN_NOVAR}, // VOC_SCREAM1 short infantry scream
  117. {"DEDMAN2", 10, IN_NOVAR}, // VOC_SCREAM3 short infantry scream
  118. {"DEDMAN3", 10, IN_NOVAR}, // VOC_SCREAM4 short infantry scream
  119. {"DEDMAN4", 10, IN_NOVAR}, // VOC_SCREAM5 short infantry scream
  120. {"DEDMAN5", 10, IN_NOVAR}, // VOC_SCREAM6 short infantry scream
  121. {"DEDMAN6", 10, IN_NOVAR}, // VOC_SCREAM7 short infantry scream
  122. {"DEDMAN7", 10, IN_NOVAR}, // VOC_SCREAM10 short infantry scream
  123. {"DEDMAN8", 10, IN_NOVAR}, // VOC_SCREAM11 short infantry scream
  124. {"DEDMAN10", 10, IN_NOVAR}, // VOC_YELL1 long infantry scream
  125. {"CHRONO2", 5, IN_NOVAR}, // VOC_CHRONO Chronosphere sound
  126. {"CANNON1", 1, IN_NOVAR}, // VOC_CANNON1 Cannon sound (medium).
  127. {"CANNON2", 1, IN_NOVAR}, // VOC_CANNON2 Cannon sound (short).
  128. {"IRONCUR9", 10, IN_NOVAR}, // VOC_IRON1
  129. {"EMOVOUT1", 20, IN_NOVAR}, // VOC_ENG_MOVEOUT Engineer: "movin' out"
  130. {"SONPULSE", 10, IN_NOVAR}, // VOC_SONAR
  131. {"SANDBAG2", 5, IN_NOVAR}, // VOC_SANDBAG sand bag crunch
  132. {"MINEBLO1", 5, IN_NOVAR}, // VOC_MINEBLOW weird mine explosion
  133. {"CHUTE1", 1, IN_NOVAR}, // VOC_CHUTE1 Wind swoosh sound.
  134. {"DOGY1", 5, IN_NOVAR}, // VOC_DOG_BARK Dog bark.
  135. {"DOGW5", 10, IN_NOVAR}, // VOC_DOG_WHINE Dog whine.
  136. {"DOGG5P", 10, IN_NOVAR}, // VOC_DOG_GROWL2 Strong dog growl.
  137. {"FIREBL3", 1, IN_NOVAR}, // VOC_FIRE_LAUNCH Fireball launch sound.
  138. {"FIRETRT1", 1, IN_NOVAR}, // VOC_FIRE_EXPLODE Fireball explode sound.
  139. {"GRENADE1", 1, IN_NOVAR}, // VOC_GRENADE_TOSS Grenade toss.
  140. {"GUN11", 1, IN_NOVAR}, // VOC_GUN_5 5 round gun burst (slow).
  141. {"GUN13", 1, IN_NOVAR}, // VOC_GUN_7 7 round gun burst (fast).
  142. {"EYESSIR1", 20, IN_NOVAR}, // VOC_ENG_YES, Engineer: "yes sir"
  143. {"GUN27", 1, IN_NOVAR}, // VOC_GUN_RIFLE Rifle shot.
  144. {"HEAL2", 1, IN_NOVAR}, // VOC_HEAL Healing effect.
  145. {"HYDROD1", 1, IN_NOVAR}, // VOC_DOOR Hyrdrolic door.
  146. {"INVUL2", 1, IN_NOVAR}, // VOC_INVULNERABLE Invulnerability effect.
  147. {"KABOOM1", 1, IN_NOVAR}, // VOC_KABOOM1 Long explosion (muffled).
  148. {"KABOOM12", 1, IN_NOVAR}, // VOC_KABOOM12 Very long explosion (muffled).
  149. {"KABOOM15", 1, IN_NOVAR}, // VOC_KABOOM15 Very long explosion (muffled).
  150. {"SPLASH9", 5, IN_NOVAR}, // VOC_SPLASH water splash
  151. {"KABOOM22", 1, IN_NOVAR}, // VOC_KABOOM22 Long explosion (sharp).
  152. {"AACANON3", 1, IN_NOVAR},
  153. {"TANDETH1", 10, IN_NOVAR},
  154. {"MGUNINF1", 1, IN_NOVAR}, // VOC_GUN_5F 5 round gun burst (fast).
  155. {"MISSILE1", 1, IN_NOVAR}, // VOC_MISSILE_1 Missile with high tech effect.
  156. {"MISSILE6", 1, IN_NOVAR}, // VOC_MISSILE_2 Long missile launch.
  157. {"MISSILE7", 1, IN_NOVAR}, // VOC_MISSILE_3 Short missile launch.
  158. {"x", 1, IN_NOVAR},
  159. {"PILLBOX1", 1, IN_NOVAR}, // VOC_GUN_5R 5 round gun burst (rattles).
  160. {"RABEEP1", 1, IN_NOVAR}, // VOC_BEEP Generic beep sound.
  161. {"RAMENU1", 1, IN_NOVAR}, // VOC_CLICK Generic click sound.
  162. {"SILENCER", 1, IN_NOVAR}, // VOC_SILENCER Silencer.
  163. {"TANK5", 1, IN_NOVAR}, // VOC_CANNON6 Long muffled cannon shot.
  164. {"TANK6", 1, IN_NOVAR}, // VOC_CANNON7 Sharp mechanical cannon fire.
  165. {"TORPEDO1", 1, IN_NOVAR}, // VOC_TORPEDO Torpedo launch.
  166. {"TURRET1", 1, IN_NOVAR}, // VOC_CANNON8 Sharp cannon fire.
  167. {"TSLACHG2", 10, IN_NOVAR}, // VOC_TESLA_POWER_UP Hum charge up.
  168. {"TESLA1", 10, IN_NOVAR}, // VOC_TESLA_ZAP Tesla zap effect.
  169. {"SQUISHY2", 10, IN_NOVAR}, // VOC_SQUISH Squish effect.
  170. {"SCOLDY1", 10, IN_NOVAR}, // VOC_SCOLD Scold bleep.
  171. {"RADARON2", 20, IN_NOVAR}, // VOC_RADAR_ON Powering up electronics.
  172. {"RADARDN1", 10, IN_NOVAR}, // VOC_RADAR_OFF B movie power down effect.
  173. {"PLACBLDG", 10, IN_NOVAR}, // VOC_PLACE_BUILDING_DOWN Building slam down sound.
  174. {"KABOOM30", 1, IN_NOVAR}, // VOC_KABOOM30 Short explosion (HE).
  175. {"KABOOM25", 10, IN_NOVAR}, // VOC_KABOOM25 Short growling explosion.
  176. {"x", 10, IN_NOVAR},
  177. {"DOGW7", 10, IN_NOVAR}, // VOC_DOG_HURT Dog whine (loud).
  178. {"DOGW3PX", 10, IN_NOVAR}, // VOC_DOG_YES Dog 'yes sir'.
  179. {"CRMBLE2", 10, IN_NOVAR}, // VOC_CRUMBLE Building crumble.
  180. {"CASHUP1", 10, IN_NOVAR}, // VOC_MONEY_UP Rising money tick.
  181. {"CASHDN1", 10, IN_NOVAR}, // VOC_MONEY_DOWN Falling money tick.
  182. {"BUILD5", 10, IN_NOVAR}, // VOC_CONSTRUCTION Building construction sound.
  183. {"BLEEP9", 10, IN_NOVAR}, // VOC_GAME_CLOSED Long bleep.
  184. {"BLEEP6", 10, IN_NOVAR}, // VOC_INCOMING_MESSAGE Soft happy warble.
  185. {"BLEEP5", 10, IN_NOVAR}, // VOC_SYS_ERROR Sharp soft warble.
  186. {"BLEEP17", 10, IN_NOVAR}, // VOC_OPTIONS_CHANGED Mid range soft warble.
  187. {"BLEEP13", 10, IN_NOVAR}, // VOC_GAME_FORMING Long warble.
  188. {"BLEEP12", 10, IN_NOVAR}, // VOC_PLAYER_LEFT Chirp sequence.
  189. {"BLEEP11", 10, IN_NOVAR}, // VOC_PLAYER_JOINED Reverse chirp sequence.
  190. {"H2OBOMB2", 10, IN_NOVAR}, // VOC_DEPTH_CHARGE Distant explosion sound.
  191. {"CASHTURN", 10, IN_NOVAR}, // VOC_CASHTURN Airbrake.
  192. {"TUFFGUY1", 20, IN_NOVAR}, // VOC_TANYA_CHEW Tanya: "Chew on this"
  193. {"ROKROLL1", 20, IN_NOVAR}, // VOC_TANYA_ROCK Tanya: "Let's rock"
  194. {"LAUGH1", 20, IN_NOVAR}, // VOC_TANYA_LAUGH Tanya: "ha ha ha"
  195. {"CMON1", 20, IN_NOVAR}, // VOC_TANYA_SHAKE Tanya: "Shake it baby"
  196. {"BOMBIT1", 20, IN_NOVAR}, // VOC_TANYA_CHING Tanya: "Cha Ching"
  197. {"GOTIT1", 20, IN_NOVAR}, // VOC_TANYA_GOT Tanya: "That's all you got"
  198. {"KEEPEM1", 20, IN_NOVAR}, // VOC_TANYA_KISS Tanya: "Kiss it bye bye"
  199. {"ONIT1", 20, IN_NOVAR}, // VOC_TANYA_THERE Tanya: "I'm there"
  200. {"LEFTY1", 20, IN_NOVAR}, // VOC_TANYA_GIVE Tanya: "Give it to me"
  201. {"YEAH1", 20, IN_NOVAR}, // VOC_TANYA_YEA Tanya: "Yea?"
  202. {"YES1", 20, IN_NOVAR}, // VOC_TANYA_YES Tanya: "Yes sir?"
  203. {"YO1", 20, IN_NOVAR}, // VOC_TANYA_WHATS Tanya: "What's up."
  204. {"WALLKIL2", 5, IN_NOVAR}, // VOC_WALLKILL2 Crushing wall sound.
  205. {"x", 10, IN_NOVAR},
  206. {"GUN5", 5, IN_NOVAR}, // VOC_TRIPLE_SHOT Three quick shots in succession.
  207. {"SUBSHOW1", 5, IN_NOVAR}, // VOC_SUBSHOW Submarine surface sound.
  208. {"EINAH1", 20, IN_NOVAR}, // VOC_E_AH, Einstien "ah"
  209. {"EINOK1", 20, IN_NOVAR}, // VOC_E_OK, Einstien "ok"
  210. {"EINYES1", 20, IN_NOVAR}, // VOC_E_YES, Einstien "yes"
  211. {"MINE1", 10, IN_NOVAR}, // VOC_TRIP_MINE mine explosion sound
  212. {"SCOMND1", 20, IN_NOVAR}, // VOC_SPY_COMMANDER Spy: "commander?"
  213. {"SYESSIR1", 20, IN_NOVAR}, // VOC_SPY_YESSIR Spy: "yes sir"
  214. {"SINDEED1", 20, IN_NOVAR}, // VOC_SPY_INDEED Spy: "indeed"
  215. {"SONWAY1", 20, IN_NOVAR}, // VOC_SPY_ONWAY Spy: "on my way"
  216. {"SKING1", 20, IN_NOVAR}, // VOC_SPY_KING Spy: "for king and country"
  217. {"MRESPON1", 20, IN_NOVAR}, // VOC_MED_REPORTING Medic: "reporting"
  218. {"MYESSIR1", 20, IN_NOVAR}, // VOC_MED_YESSIR Medic: "yes sir"
  219. {"MAFFIRM1", 20, IN_NOVAR}, // VOC_MED_AFFIRM Medic: "affirmative"
  220. {"MMOVOUT1", 20, IN_NOVAR}, // VOC_MED_MOVEOUT Medic: "movin' out"
  221. {"BEEPSLCT", 10, IN_NOVAR}, // VOC_BEEP_SELECT map selection beep
  222. {"SYEAH1", 20, IN_NOVAR}, // VOC_THIEF_YEA Thief: "yea?"
  223. {"ANTDIE", 20, IN_NOVAR}, // VOC_ANTDIE
  224. {"ANTBITE", 20, IN_NOVAR}, // VOC_ANTBITE
  225. {"SMOUT1", 20, IN_NOVAR}, // VOC_THIEF_MOVEOUT Thief: "movin' out"
  226. {"SOKAY1", 20, IN_NOVAR}, // VOC_THIEF_OKAY Thief: "ok"
  227. {"x", 20, IN_NOVAR},
  228. {"SWHAT1", 20, IN_NOVAR}, // VOC_THIEF_WHAT Thief: "what"
  229. {"SAFFIRM1", 20, IN_NOVAR}, // VOC_THIEF_AFFIRM Thief: "affirmative"
  230. //ADDED VG 2/24/97
  231. {"STAVCMDR", 20, IN_NOVAR},
  232. {"STAVCRSE", 20, IN_NOVAR},
  233. {"STAVYES", 20, IN_NOVAR},
  234. {"STAVMOV", 20, IN_NOVAR},
  235. {"BUZZY1", 20, IN_NOVAR},
  236. {"RAMBO1", 20, IN_NOVAR},
  237. {"RAMBO2", 20, IN_NOVAR},
  238. {"RAMBO3", 20, IN_NOVAR},
  239. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  240. {"MYES1", 20, IN_NOVAR}, // VOC_MECHYES1 Mechanic: "Yes sir!"
  241. {"MHOWDY1", 20, IN_NOVAR}, // VOC_MECHHOWDY1 Mechanic: "Howdy!"
  242. {"MRISE1", 20, IN_NOVAR}, // VOC_MECHRISE1 Mechanic: "Rise 'n shine!"
  243. {"MHUH1", 20, IN_NOVAR}, // VOC_MECHHUH1 Mechanic: "Huh?"
  244. {"MHEAR1", 20, IN_NOVAR}, // VOC_MECHHEAR1 Mechanic: "I Hear Ya!"
  245. {"MLAFF1", 20, IN_NOVAR}, // VOC_MECHLAFF1 Mechanic: guffaw
  246. {"MBOSS1", 20, IN_NOVAR}, // VOC_MECHBOSS1 Mechanic: "Sure Thing, Boss!"
  247. {"MYEEHAW1", 20, IN_NOVAR}, // VOC_MECHYEEHAW1 Mechanic: "Yee Haw!"
  248. {"MHOTDIG1", 20, IN_NOVAR}, // VOC_MECHHOTDIG1 Mechanic: "Hot Diggity Dog!"
  249. {"MWRENCH1", 20, IN_NOVAR}, // VOC_MECHWRENCH1 Mechanic: "I'll get my wrench."
  250. {"JBURN1", 20, IN_NOVAR}, // VOC_STBURN1 Shock Trooper: "Burn baby burn!"
  251. {"JCHRGE1", 20, IN_NOVAR}, // VOC_STCHRGE1 Shock Trooper: "Fully charged!"
  252. {"JCRISP1", 20, IN_NOVAR}, // VOC_STCRISP1 Shock Trooper: "Extra Crispy!"
  253. {"JDANCE1", 20, IN_NOVAR}, // VOC_STDANCE1 Shock Trooper: "Let's Dance!"
  254. {"JJUICE1", 20, IN_NOVAR}, // VOC_STJUICE1 Shock Trooper: "Got juice?"
  255. {"JJUMP1", 20, IN_NOVAR}, // VOC_STJUMP1 Shock Trooper: "Need a jump?"
  256. {"JLIGHT1", 20, IN_NOVAR}, // VOC_STLIGHT1 Shock Trooper: "Lights out!"
  257. {"JPOWER1", 20, IN_NOVAR}, // VOC_STPOWER1 Shock Trooper: "Power on!"
  258. {"JSHOCK1", 20, IN_NOVAR}, // VOC_STSHOCK1 Shock Trooper: "Shocking!"
  259. {"JYES1", 20, IN_NOVAR}, // VOC_STYES1 Shock Trooper: "Yesssss!"
  260. {"CHROTNK1", 20, IN_NOVAR}, // VOC_CHRONOTANK1 Chrono tank teleport
  261. {"FIXIT1", 20, IN_NOVAR}, // VOC_MECH_FIXIT1 Mechanic fixes something
  262. {"MADCHRG2", 20, IN_NOVAR}, // VOC_MAD_CHARGE MAD tank charges up
  263. {"MADEXPLO", 20, IN_NOVAR}, // VOC_MAD_EXPLODE MAD tank explodes
  264. {"SHKTROP1", 20, IN_NOVAR}, // VOC_SHOCK_TROOP1 Shock Trooper fires
  265. {"BEACON", 10, IN_NOVAR}, // VOC_BEACON Beacon sound.
  266. #endif
  267. };
  268. //
  269. // External handlers. MBL 06.17.2019
  270. //
  271. extern void On_Sound_Effect(int sound_index, int variation, COORDINATE coord, int house);
  272. // extern void On_Speech(int speech_index); MBL 02.06.2020
  273. extern void On_Speech(int speech_index, HouseClass *house);
  274. extern void On_Ping(const HouseClass* player_ptr, COORDINATE coord);
  275. /***********************************************************************************************
  276. * Voc_From_Name -- Fetch VocType from ASCII name specified. *
  277. * *
  278. * This will find the corresponding VocType from the ASCII string specified. It does this *
  279. * by finding a root filename that matches the string. *
  280. * *
  281. * INPUT: name -- Pointer to the ASCII string that will be converted into a VocType. *
  282. * *
  283. * OUTPUT: Returns with the VocType that matches the string specified. If no match could be *
  284. * found, then VOC_NONE is returned. *
  285. * *
  286. * WARNINGS: none *
  287. * *
  288. * HISTORY: *
  289. * 07/06/1996 JLB : Created. *
  290. *=============================================================================================*/
  291. VocType Voc_From_Name(char const * name)
  292. {
  293. if (name == NULL) return(VOC_NONE);
  294. for (VocType voc = VOC_FIRST; voc < VOC_COUNT; voc++) {
  295. if (stricmp(name, SoundEffectName[voc].Name) == 0) {
  296. return(voc);
  297. }
  298. }
  299. return(VOC_NONE);
  300. }
  301. /***********************************************************************************************
  302. * Voc_Name -- Fetches the name for the sound effect. *
  303. * *
  304. * This routine returns the descriptive name of the sound effect. Currently, this is just *
  305. * the root of the file name. *
  306. * *
  307. * INPUT: voc -- The VocType that the corresponding name is requested. *
  308. * *
  309. * OUTPUT: Returns with a pointer to the text string the represents the sound effect. *
  310. * *
  311. * WARNINGS: none *
  312. * *
  313. * HISTORY: *
  314. * 05/06/1996 JLB : Created. *
  315. *=============================================================================================*/
  316. char const * Voc_Name(VocType voc)
  317. {
  318. if (voc == VOC_NONE) return("none");
  319. return(SoundEffectName[voc].Name);
  320. }
  321. /***********************************************************************************************
  322. * Sound_Effect -- Plays a sound effect in the tactical map. *
  323. * *
  324. * This routine is used when a sound effect occurs in the game world. It handles fading *
  325. * the sound according to distance. *
  326. * *
  327. * INPUT: voc -- The sound effect number to play. *
  328. * *
  329. * coord -- The world location that the sound originates from. *
  330. * *
  331. * variation -- This is the optional variation number to use when playing special *
  332. * sound effects that have variations. For normal sound effects, this *
  333. * parameter is ignored. *
  334. * *
  335. * house -- This specifies the optional house override value to use when playing *
  336. * sound effects that have a variation. If not specified, then the current *
  337. * player is examined for the house variation to use. *
  338. * *
  339. * OUTPUT: none *
  340. * *
  341. * WARNINGS: none *
  342. * *
  343. * HISTORY: *
  344. * 11/12/1994 JLB : Created. *
  345. * 01/05/1995 JLB : Reduces sound more dramatically when off screen. *
  346. * 09/15/1996 JLB : Revamped volume logic. *
  347. * 11/01/1996 JLB : House override control. *
  348. *=============================================================================================*/
  349. void Sound_Effect(VocType voc, COORDINATE coord, int variation, HousesType house)
  350. {
  351. //
  352. // Intercept sound effect calls. MBL 06.17.2019
  353. //
  354. On_Sound_Effect((int)voc, variation, coord, (int)house);
  355. #if 0
  356. CELL cell_pos = 0;
  357. int pan_value;
  358. if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
  359. return;
  360. }
  361. if (coord) {
  362. cell_pos = Coord_Cell(coord);
  363. }
  364. fixed volume = 1;
  365. pan_value = 0;
  366. if (coord && !Map.In_View(cell_pos)) {
  367. int distance = Distance(coord, Map.TacticalCoord) / CELL_LEPTON_W;
  368. fixed dfixed = fixed(distance, 128+64);
  369. dfixed.Sub_Saturate(1);
  370. volume = fixed(1) - dfixed;
  371. pan_value = Cell_X(cell_pos);
  372. pan_value -= Coord_XCell(Map.TacticalCoord) + (Lepton_To_Cell(Map.TacLeptonWidth) / 2);
  373. if (ABS(pan_value) > Lepton_To_Cell(Map.TacLeptonWidth / 2)) {
  374. pan_value *= 0x8000;
  375. pan_value /= (MAP_CELL_W >> 2);
  376. pan_value = Bound(pan_value, -0x7FFF, 0x7FFF);
  377. } else {
  378. pan_value = 0;
  379. }
  380. }
  381. Sound_Effect(voc, volume, variation, pan_value, house);
  382. #endif
  383. }
  384. /***********************************************************************************************
  385. * Sound_Effect -- General purpose sound player. *
  386. * *
  387. * This is used for general purpose sound effects. These are sounds that occur outside *
  388. * of the game world. They do not have a corresponding game world location as their source. *
  389. * *
  390. * INPUT: voc -- The sound effect number to play. *
  391. * *
  392. * volume -- The volume to assign to this sound effect. *
  393. * *
  394. * variation -- This is the optional variation number to use when playing special *
  395. * sound effects that have variations. For normal sound effects, this *
  396. * parameter is ignored. *
  397. * *
  398. * house -- This specifies the optional house override value to use when playing *
  399. * sound effects that have a variation. If not specified, then the current *
  400. * player is examined for the house variation to use. *
  401. * *
  402. * OUTPUT: Returns with the sound handle (-1 if no sound was played). *
  403. * *
  404. * WARNINGS: none *
  405. * *
  406. * HISTORY: *
  407. * 11/12/1994 JLB : Created. *
  408. * 11/12/1994 JLB : Handles cache logic. *
  409. * 05/04/1995 JLB : Variation adjustments. *
  410. * 11/01/1996 JLB : House override control. *
  411. *=============================================================================================*/
  412. int Sound_Effect(VocType voc, fixed volume, int variation, signed short pan_value, HousesType house)
  413. {
  414. //
  415. // Intercept sound effect calls. MBL 06.17.2019
  416. //
  417. pan_value;
  418. COORDINATE coord = 0;
  419. On_Sound_Effect((int)voc, variation, coord, (int)house);
  420. #if 0
  421. char name[_MAX_FNAME+_MAX_EXT]; // Working filename of sound effect.
  422. if (Debug_Quiet || Options.Volume == 0 || voc == VOC_NONE || !SoundOn || SampleType == SAMPLE_NONE) {
  423. return(-1);
  424. }
  425. /*
  426. ** Alter the volume according to the game volume setting.
  427. */
  428. volume = volume * Options.Volume;
  429. /*
  430. ** Fetch a pointer to the sound effect data. Modify the sound as appropriate and desired.
  431. */
  432. char const * ext = ".AUD";
  433. if (SoundEffectName[voc].Where == IN_VAR) {
  434. /*
  435. ** If there is no forced house, then use the current player
  436. ** act like house.
  437. */
  438. if (house == HOUSE_NONE) {
  439. house = PlayerPtr->ActLike;
  440. }
  441. /*
  442. ** Change the extension based on the variation and house accent requested.
  443. */
  444. if (((1 << house) & HOUSEF_ALLIES) != 0) {
  445. /*
  446. ** For infantry, use a variation on the response. For vehicles, always
  447. ** use the vehicle response table.
  448. */
  449. if (variation < 0) {
  450. if (ABS(variation) % 2) {
  451. ext = ".V00";
  452. } else {
  453. ext = ".V02";
  454. }
  455. } else {
  456. if (variation % 2) {
  457. ext = ".V01";
  458. } else {
  459. ext = ".V03";
  460. }
  461. }
  462. } else {
  463. if (variation < 0) {
  464. if (ABS(variation) % 2) {
  465. ext = ".R00";
  466. } else {
  467. ext = ".R02";
  468. }
  469. } else {
  470. if (variation % 2) {
  471. ext = ".R01";
  472. } else {
  473. ext = ".R03";
  474. }
  475. }
  476. }
  477. }
  478. _makepath(name, NULL, NULL, SoundEffectName[voc].Name, ext);
  479. void const * ptr = MFCD::Retrieve(name);
  480. /*
  481. ** If the sound data pointer is not null, then presume that it is valid.
  482. */
  483. if (ptr != NULL) {
  484. volume.Sub_Saturate(1);
  485. return(Play_Sample(ptr, SoundEffectName[voc].Priority * volume, volume*256, pan_value));
  486. }
  487. #endif
  488. return(-1);
  489. }
  490. /*
  491. ** This elaborates all the EVA speech voices.
  492. */
  493. /*static PG*/ char const * Speech[VOX_COUNT] = {
  494. "MISNWON1", // VOX_ACCOMPLISHED mission accomplished
  495. "MISNLST1", // VOX_FAIL your mission has failed
  496. "PROGRES1", // VOX_NO_FACTORY unable to comply, building in progress
  497. "CONSCMP1", // VOX_CONSTRUCTION construction complete
  498. "UNITRDY1", // VOX_UNIT_READY unit ready
  499. "NEWOPT1", // VOX_NEW_CONSTRUCT new construction options
  500. "NODEPLY1", // VOX_DEPLOY cannot deploy here
  501. "STRCKIL1", // VOX_STRUCTURE_DESTROYED, structure destroyed
  502. "NOPOWR1", // VOX_INSUFFICIENT_POWER, insufficient power
  503. "NOFUNDS1", // VOX_NO_CASH insufficient funds
  504. "BCT1", // VOX_CONTROL_EXIT battle control terminated
  505. "REINFOR1", // VOX_REINFORCEMENTS reinforcements have arrived
  506. "CANCLD1", // VOX_CANCELED canceled
  507. "ABLDGIN1", // VOX_BUILDING building
  508. "LOPOWER1", // VOX_LOW_POWER low power
  509. "NOFUNDS1", // VOX_NEED_MO_MONEY insufficent funds
  510. "BASEATK1", // VOX_BASE_UNDER_ATTACK our base is under attack
  511. "NOBUILD1", // VOX_UNABLE_TO_BUILD unable to build more
  512. "PRIBLDG1", // VOX_PRIMARY_SELECTED primary building selected
  513. #ifdef FIXIT_CSII // checked - ajw 9/28/98
  514. #ifdef ENGLISH
  515. "TANK01", // VOX_MADTANK_DEPLOYED M.A.D. Tank Deployed
  516. #else
  517. "none",
  518. #endif
  519. #else
  520. "none",
  521. #endif
  522. "none", // VOX_SOVIET_CAPTURED Allied building captured
  523. "UNITLST1", // VOX_UNIT_LOST unit lost
  524. "SLCTTGT1", // VOX_SELECT_TARGET select target
  525. "ENMYAPP1", // VOX_PREPARE enemy approaching
  526. "SILOND1", // VOX_NEED_MO_CAPACITY silos needed
  527. "ONHOLD1", // VOX_SUSPENDED on hold
  528. "REPAIR1", // VOX_REPAIRING repairing
  529. "none",
  530. "none",
  531. "AUNITL1", // VOX_AIRCRAFT_LOST airborne unit lost
  532. "none",
  533. "AAPPRO1", // VOX_ALLIED_FORCES_APPROACHING allied forces approaching
  534. "AARRIVE1", // VOX_ALLIED_APPROACHING allied reinforcements have arrived
  535. "none",
  536. "none",
  537. "BLDGINF1", // VOX_BUILDING_INFILTRATED building infiltrated
  538. "CHROCHR1", // VOX_CHRONO_CHARGING chronosphere charging
  539. "CHRORDY1", // VOX_CHRONO_READY chronosphere ready
  540. "CHROYES1", // VOX_CHRONO_TEST chronosphere test successful
  541. "CMDCNTR1", // VOX_HQ_UNDER_ATTACK command center under attack
  542. "CNTLDED1", // VOX_CENTER_DEACTIVATED control center deactivated
  543. "CONVYAP1", // VOX_CONVOY_APPROACHING convoy approaching
  544. "CONVLST1", // VOX_CONVOY_UNIT_LOST convoy unit lost
  545. "XPLOPLC1", // VOX_EXPLOSIVE_PLACED explosive charge placed
  546. "CREDIT1", // VOX_MONEY_STOLEN credits stolen
  547. "NAVYLST1", // VOX_SHIP_LOST naval unit lost
  548. "SATLNCH1", // VOX_SATALITE_LAUNCHED satalite launched
  549. "PULSE1", // VOX_SONAR_AVAILABLE sonar pulse available
  550. "none",
  551. "SOVFAPP1", // VOX_SOVIET_FORCES_APPROACHING soviet forces approaching
  552. "SOVREIN1", // VOX_SOVIET_REINFROCEMENTS soviet reinforcements have arrived
  553. "TRAIN1", // VOX_TRAINING training
  554. "AREADY1", // VOX_ABOMB_READY
  555. "ALAUNCH1", // VOX_ABOMB_LAUNCH
  556. "AARRIVN1", // VOX_ALLIES_N
  557. "AARRIVS1", // VOX_ALLIES_S
  558. "AARIVE1", // VOX_ALLIES_E
  559. "AARRIVW1", // VOX_ALLIES_W
  560. "1OBJMET1", // VOX_OBJECTIVE1
  561. "2OBJMET1", // VOX_OBJECTIVE2
  562. "3OBJMET1", // VOX_OBJECTIVE3
  563. "IRONCHG1", // VOX_IRON_CHARGING
  564. "IRONRDY1", // VOX_IRON_READY
  565. "KOSYRES1", // VOX_RESCUED
  566. "OBJNMET1", // VOX_OBJECTIVE_NOT
  567. "FLAREN1", // VOX_SIGNAL_N
  568. "FLARES1", // VOX_SIGNAL_S
  569. "FLAREE1", // VOX_SIGNAL_E
  570. "FLAREW1", // VOX_SIGNAL_W
  571. "SPYPLN1", // VOX_SPY_PLANE
  572. "TANYAF1", // VOX_FREED
  573. "ARMORUP1", // VOX_UPGRADE_ARMOR
  574. "FIREPO1", // VOX_UPGRADE_FIREPOWER
  575. "UNITSPD1", // VOX_UPGRADE_SPEED
  576. "MTIMEIN1", // VOX_MISSION_TIMER
  577. "UNITFUL1", // VOX_UNIT_FULL
  578. "UNITREP1", // VOX_UNIT_REPAIRED
  579. "40MINR", // VOX_TIME_40
  580. "30MINR", // VOX_TIME_30
  581. "20MINR", // VOX_TIME_20
  582. "10MINR", // VOX_TIME_10
  583. "5MINR", // VOX_TIME_5
  584. "4MINR", // VOX_TIME_4
  585. "3MINR", // VOX_TIME_3
  586. "2MINR", // VOX_TIME_2
  587. "1MINR", // VOX_TIME_1
  588. "TIMERNO1", // VOX_TIME_STOP
  589. "UNITSLD1", // VOX_UNIT_SOLD
  590. "TIMERGO1", // VOX_TIMER_STARTED
  591. "TARGRES1", // VOX_TARGET_RESCUED
  592. "TARGFRE1", // VOX_TARGET_FREED
  593. "TANYAR1", // VOX_TANYA_RESCUED
  594. "STRUSLD1", // VOX_STRUCTURE_SOLD
  595. "SOVFORC1", // VOX_SOVIET_FORCES_FALLEN
  596. "SOVEMP1", // VOX_SOVIET_SELECTED
  597. "SOVEFAL1", // VOX_SOVIET_EMPIRE_FALLEN
  598. "OPTERM1", // VOX_OPERATION_TERMINATED
  599. "OBJRCH1", // VOX_OBJECTIVE_REACHED
  600. "OBJNRCH1", // VOX_OBJECTIVE_NOT_REACHED
  601. "OBJMET1", // VOX_OBJECTIVE_MET
  602. "MERCR1", // VOX_MERCENARY_RESCUED
  603. "MERCF1", // VOX_MERCENARY_FREED
  604. "KOSYFRE1", // VOX_KOSOYGEN_FREED
  605. "FLARE1", // VOX_FLARE_DETECTED
  606. "COMNDOR1", // VOX_COMMANDO_RESCUED
  607. "COMNDOF1", // VOX_COMMANDO_FREED
  608. "BLDGPRG1", // VOX_BUILDING_IN_PROGRESS
  609. "ATPREP1", // VOX_ATOM_PREPPING
  610. "ASELECT1", // VOX_ALLIED_SELECTED
  611. "APREP1", // VOX_ABOMB_PREPPING
  612. "ATLNCH1", // VOX_ATOM_LAUNCHED
  613. "AFALLEN1", // VOX_ALLIED_FORCES_FALLEN
  614. "AAVAIL1", // VOX_ABOMB_AVAILABLE
  615. "AARRIVE1", // VOX_ALLIED_REINFORCEMENTS
  616. "SAVE1", // VOX_MISSION_SAVED
  617. "LOAD1" // VOX_MISSION_LOADED
  618. };
  619. static VoxType CurrentVoice = VOX_NONE;
  620. /***********************************************************************************************
  621. * Speech_Name -- Fetches the name for the voice specified. *
  622. * *
  623. * Use this routine to fetch the ASCII name of the speech id specified. Typical use of this *
  624. * would be to build a displayable list of the speech types. The trigger system uses this *
  625. * so that a speech type can be selected. *
  626. * *
  627. * INPUT: speech -- The speech type id to convert to ASCII string. *
  628. * *
  629. * OUTPUT: Returns with a pointer to the speech ASCII representation of the speech id type. *
  630. * *
  631. * WARNINGS: none *
  632. * *
  633. * HISTORY: *
  634. * 06/01/1996 JLB : Created. *
  635. *=============================================================================================*/
  636. char const * Speech_Name(VoxType speech)
  637. {
  638. if (speech == VOX_NONE) return("none");
  639. return(Speech[speech]);
  640. }
  641. /***********************************************************************************************
  642. * Speak -- Computer speaks to the player. *
  643. * *
  644. * This routine is used to have the game computer (EVA) speak to the player. *
  645. * *
  646. * INPUT: voice -- The voice number to speak (see defines.h). *
  647. * *
  648. * OUTPUT: Returns with the handle of the playing speech (-1 if no voice started). *
  649. * *
  650. * WARNINGS: none *
  651. * *
  652. * HISTORY: *
  653. * 11/12/1994 JLB : Created. *
  654. *=============================================================================================*/
  655. // void Speak(VoxType voice) // MBL 02.06.2020
  656. void Speak(VoxType voice, HouseClass *house, COORDINATE coord)
  657. {
  658. // MBL 06.17.2019
  659. if (voice == VOX_NONE)
  660. {
  661. return;
  662. }
  663. //
  664. // Intercept speech calls. MBL 06.17.2019
  665. //
  666. // On_Speech((int)voice); // MBL 02.06.2020
  667. On_Speech((int)voice, house);
  668. if (coord) {
  669. On_Ping(house, coord);
  670. }
  671. #if 0
  672. if (!Debug_Quiet && Options.Volume != 0 && SampleType != 0 && voice != VOX_NONE && voice != SpeakQueue && voice != CurrentVoice && SpeakQueue == VOX_NONE) {
  673. SpeakQueue = voice;
  674. Speak_AI();
  675. }
  676. #endif
  677. }
  678. /***********************************************************************************************
  679. * Speak_AI -- Handles starting the EVA voices. *
  680. * *
  681. * This starts the EVA voice talking as well. If there is any speech request in the queue, *
  682. * it will be started when the current voice is finished. Call this routine as often as *
  683. * possible (once per game tick is sufficient). *
  684. * *
  685. * INPUT: none *
  686. * *
  687. * OUTPUT: none *
  688. * *
  689. * WARNINGS: none *
  690. * *
  691. * HISTORY: *
  692. * 12/27/1994 JLB : Created. *
  693. * 10/11/1996 JLB : Handles multiple speech buffers. *
  694. *=============================================================================================*/
  695. void Speak_AI(void)
  696. {
  697. // MBL 06.17.2019 KO
  698. #if 0
  699. static int _index = 0;
  700. if (Debug_Quiet || SampleType == 0) return;
  701. if (!Is_Sample_Playing(SpeechBuffer[_index])) {
  702. CurrentVoice = VOX_NONE;
  703. if (SpeakQueue != VOX_NONE) {
  704. /*
  705. ** Try to find a previously loaded copy of the EVA speech in one of the
  706. ** speech buffers.
  707. */
  708. void const * speech = NULL;
  709. for (int index = 0; index < ARRAY_SIZE(SpeechRecord); index++) {
  710. if (SpeechRecord[index] == SpeakQueue) break;
  711. }
  712. /*
  713. ** If a previous copy could not be located, then load the requested
  714. ** voice into the oldest buffer available.
  715. */
  716. if (speech == NULL) {
  717. _index = (_index + 1) % ARRAY_SIZE(SpeechRecord);
  718. char name[_MAX_FNAME+_MAX_EXT];
  719. _makepath(name, NULL, NULL, Speech[SpeakQueue], ".AUD");
  720. CCFileClass file(name);
  721. if (file.Is_Available() && file.Read(SpeechBuffer[_index], SPEECH_BUFFER_SIZE)) {
  722. speech = SpeechBuffer[_index];
  723. SpeechRecord[_index] = SpeakQueue;
  724. }
  725. }
  726. /*
  727. ** Since the speech file was loaded, play it.
  728. */
  729. if (speech != NULL) {
  730. Play_Sample(speech, 254, Options.Volume * 256);
  731. CurrentVoice = SpeakQueue;
  732. }
  733. SpeakQueue = VOX_NONE;
  734. }
  735. }
  736. #endif
  737. // MBL 06.18.2019
  738. if (SpeakQueue != VOX_NONE)
  739. {
  740. // On_Speech((int)SpeakQueue); // MBL 02.06.2020
  741. On_Speech((int)SpeakQueue, NULL);
  742. SpeakQueue = VOX_NONE;
  743. }
  744. }
  745. /***********************************************************************************************
  746. * Stop_Speaking -- Forces the EVA voice to stop talking. *
  747. * *
  748. * Use this routine to immediately stop the EVA voice from speaking. It also clears out *
  749. * the pending voice queue. *
  750. * *
  751. * INPUT: none *
  752. * *
  753. * OUTPUT: none *
  754. * *
  755. * WARNINGS: none *
  756. * *
  757. * HISTORY: *
  758. * 12/27/1994 JLB : Created. *
  759. *=============================================================================================*/
  760. void Stop_Speaking(void)
  761. {
  762. SpeakQueue = VOX_NONE;
  763. Stop_Sample_Playing(SpeechBuffer);
  764. }
  765. /***********************************************************************************************
  766. * Is_Speaking -- Checks to see if the eva voice is still playing. *
  767. * *
  768. * Call this routine when the EVA voice being played needs to be checked. A typical use *
  769. * of this would be when some action needs to be delayed until the voice has finished -- *
  770. * say the end of the game. *
  771. * *
  772. * INPUT: none *
  773. * *
  774. * OUTPUT: bool; Is the EVA voice still playing? *
  775. * *
  776. * WARNINGS: none *
  777. * *
  778. * HISTORY: *
  779. * 03/12/1995 JLB : Created. *
  780. *=============================================================================================*/
  781. bool Is_Speaking(void)
  782. {
  783. Speak_AI();
  784. if (!Debug_Quiet && SampleType != 0 && (SpeakQueue != VOX_NONE || Is_Sample_Playing(SpeechBuffer))) {
  785. return(true);
  786. }
  787. return(false);
  788. }