SFX.CPP 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837
  1. #include <string.h>
  2. #include <dos.h>
  3. #include "sfx.h"
  4. #include "db.h"
  5. #include "globals.h"
  6. #include "sound.h"
  7. #include "engine.h"
  8. #include "error.h"
  9. #include "fx_man.h"
  10. #include "player.h"
  11. #include "gameutil.h"
  12. #include "trig.h"
  13. #include "globals.h"
  14. #include "misc.h"
  15. #include "debug4g.h"
  16. // sample rate in samples / sec
  17. #define kSampleRate 11110
  18. // sound of sound in XY units / sec
  19. #define kSoundVel M2X(500.0)
  20. // sound of sound in XY units / frame interval
  21. #define kSoundVelFrame (kSoundVel * kFrameTicks / kTimerRate)
  22. // Intra-aural delay in seconds
  23. #define kIntraAuralTime 0.0008
  24. // Intra-aural distance based on delay and speed of sound
  25. #define kIntraAuralDist (kIntraAuralTime / 2 * kSoundVel)
  26. // 16:16 fixed point constant for convert XY distance to sample phase
  27. #define kDistPhase ((kSampleRate << 16) / kSoundVel)
  28. // scale value for all 3D sounds
  29. #define kVolScale 256
  30. // volume different between sound in front and behind pinna focus
  31. #define kBackFilter 0x8000
  32. // angle between forward and foci for pinna
  33. #define kPinnaAngle kAngle15
  34. static POINT2D earL, earR, earL0, earR0;
  35. static VECTOR2D earVL, earVR;
  36. static int lPhase, rPhase, lVol, rVol;
  37. static int lVel, rVel;
  38. struct SOUNDEFFECT
  39. {
  40. char *name;
  41. int relVol;
  42. int pitch;
  43. int pitchRange;
  44. RESHANDLE hResource;
  45. };
  46. SOUNDEFFECT soundEffect[ kSfxMax ] =
  47. {
  48. {"zipclose", 80, 0x10000, 0}, // kSfxZipOpen
  49. {"zipclose", 80, 0x08000, 0}, // kSfxZipClose
  50. {"ziplight", 80, 0x10000, 0}, // kSfxZipFlick
  51. {"saw_cock", 80, 0x10000, 0}, // kSfxShotCock
  52. {"saw_fir", 160, 0x10000, 0}, // kSfxShotFire
  53. {"saw_fir2", 160, 0x10000, 0}, // kSfxShotFire2
  54. {"saw_load", 80, 0x10000, 0}, // kSfxShotLoad
  55. {"flar_fir", 60, 0x10000, 0}, // kSfxFlareFire
  56. {"flar_fir", 60, 0x10000, 0}, // kSfxFlareFireUW
  57. {"", 80, 0x10000, 0}, // kSfxTomCock
  58. {"_gunb", 200, 0x10000, 0}, // kSfxTomFire
  59. {"spraycan", 80, 0x10000, 0}, // kSfxSprayPaint
  60. {"sprayflm", 80, 0x10000, 0}, // kSfxSprayFlame
  61. {"tnt_fuse", 80, 0x10000, 0}, // kSfxTNTFuse
  62. {"dol_stab", 80, 0x10000, 0}, // kSfxTNTDropProx
  63. {"tnt_arm", 80, 0x10000, 0}, // kSfxTNTArmProx
  64. {"tnt_det", 80, 0x10000, 0}, // kSfxTNTDetProx
  65. {"dol_stab", 80, 0x10000, 0}, // kSfxTNTDropRemote
  66. {"tnt_arm", 80, 0x10000, 0}, // kSfxTNTArmRemote
  67. {"tnt_det", 80, 0x10000, 0}, // kSfxTNTDetRemote
  68. {"tnt_toss", 40, 0x10000, 0}, // kSfxTNTToss
  69. {"dol_stab", 80, 0x10000, 0}, // kSfxVoodooHit
  70. {"dol_stab", 80, 0x10000, 0}, // kSfxVoodooHit2
  71. {"dol_stab", 80, 0x10000, 0}, // kSfxVoodooHit3
  72. {"dol_stab", 80, 0x10000, 0}, // kSfxVoodooHit4
  73. {"cult2", 80, 0x18000, 0}, // kSfxVoodooChant
  74. {"dol_stab", 80, 0x10000, 0}, // kSfxVoodooBreak
  75. {"dol_burn", 80, 0x10000, 0}, // kSfxVoodooBurn
  76. {"spr_cham", 80, 0x10000, 0}, // kSfxSpearLoad
  77. {"spr_fire", 80, 0x10000, 0}, // kSfxSpearFire
  78. {"spr_uw", 80, 0x10000, 0}, // kSfxSpearFireUW
  79. {"", 80, 0x10000, 0}, // kSfxBlasterFire
  80. {"pf_rock", 10, 0x10000, 0}, // kSfxForkStone
  81. {"pf_metal", 15, 0x10000, 0}, // kSfxForkMetal
  82. {"pf_wood", 10, 0x10000, 0}, // kSfxForkWood
  83. {"pf_flesh", 15, 0x10000, 0}, // kSfxForkFlesh
  84. {"", 80, 0x10000, 0}, // kSfxForkWater
  85. {"", 80, 0x10000, 0}, // kSfxForkDirt
  86. {"", 80, 0x10000, 0}, // kSfxForkClay
  87. {"", 80, 0x10000, 0}, // kSfxForkSnow
  88. {"", 80, 0x10000, 0}, // kSfxForkIce
  89. {"", 80, 0x10000, 0}, // kSfxForkLeaves
  90. {"", 80, 0x10000, 0}, // kSfxForkPlant
  91. {"", 80, 0x10000, 0}, // kSfxForkGoo
  92. {"", 80, 0x10000, 0}, // kSfxForkLava
  93. {"pf_uw_rk", 10, 0x10000, 0}, // kSfxForkStoneUW
  94. {"pf_uw_mt", 10, 0x10000, 0}, // kSfxForkMetalUW
  95. {"pf_uw_wd", 10, 0x10000, 0}, // kSfxForkWoodUW
  96. {"pf_uw_fl", 10, 0x10000, 0}, // kSfxForkFleshUW
  97. {"", 80, 0x10000, 0}, // kSfxForkDirtUW
  98. {"", 80, 0x10000, 0}, // kSfxForkClayUW
  99. {"", 80, 0x10000, 0}, // kSfxForkIceUW
  100. {"", 80, 0x10000, 0}, // kSfxForkLeavesUW
  101. {"", 80, 0x10000, 0}, // kSfxForkPlantUW
  102. {"tom_ston", 80, 0x10000, 0}, // kSfxBulletStone
  103. {"tom_metl", 80, 0x10000, 0}, // kSfxBulletMetal
  104. {"tom_wood", 80, 0x10000, 0}, // kSfxBulletWood
  105. {"tom_flsh", 80, 0x10000, 0}, // kSfxBulletFlesh
  106. {"tom_watr", 80, 0x10000, 0}, // kSfxBulletWater
  107. {"tom_wood", 80, 0x10000, 0}, // kSfxBulletDirt
  108. {"tom_wood", 80, 0x10000, 0}, // kSfxBulletClay
  109. {"tom_ston", 80, 0x10000, 0}, // kSfxBulletSnow
  110. {"tom_ston", 80, 0x10000, 0}, // kSfxBulletIce
  111. {"tom_ston", 80, 0x10000, 0}, // kSfxBulletLeaves
  112. {"tom_ston", 80, 0x10000, 0}, // kSfxBulletPlant
  113. {"tom_ston", 80, 0x10000, 0}, // kSfxBulletGoo
  114. {"tom_wood", 80, 0x10000, 0}, // kSfxBulletLava
  115. {"", 80, 0x10000, 0}, // kSfxBulletStoneUW
  116. {"", 80, 0x10000, 0}, // kSfxBulletMetalUW
  117. {"", 80, 0x10000, 0}, // kSfxBulletWoodUW
  118. {"", 80, 0x10000, 0}, // kSfxBulletFleshUW
  119. {"", 80, 0x10000, 0}, // kSfxBulletDirtUW
  120. {"", 80, 0x10000, 0}, // kSfxBulletClayUW
  121. {"", 80, 0x10000, 0}, // kSfxBulletIceUW
  122. {"", 80, 0x10000, 0}, // kSfxBulletLeavesUW
  123. {"", 80, 0x10000, 0}, // kSfxBulletPlantUW
  124. {"dmhack2", 60, 0x10000, 0}, // kSfxAxeAir
  125. {"", 80, 0x10000, 0}, // kSfxAxeStone
  126. {"", 80, 0x10000, 0}, // kSfxAxeMetal
  127. {"", 80, 0x10000, 0}, // kSfxAxeWood
  128. {"", 80, 0x10000, 0}, // kSfxAxeFlesh
  129. {"", 80, 0x10000, 0}, // kSfxAxeWater
  130. {"", 80, 0x10000, 0}, // kSfxAxeDirt
  131. {"", 80, 0x10000, 0}, // kSfxAxeClay
  132. {"", 80, 0x10000, 0}, // kSfxAxeSnow
  133. {"", 80, 0x10000, 0}, // kSfxAxeIce
  134. {"", 80, 0x10000, 0}, // kSfxAxeLeaves
  135. {"", 80, 0x10000, 0}, // kSfxAxePlant
  136. {"", 80, 0x10000, 0}, // kSfxAxeGoo
  137. {"", 80, 0x10000, 0}, // kSfxAxeLava
  138. {"", 80, 0x10000, 0}, // kSfxAxeStoneUW
  139. {"", 80, 0x10000, 0}, // kSfxAxeMetalUW
  140. {"", 80, 0x10000, 0}, // kSfxAxeWoodUW
  141. {"", 80, 0x10000, 0}, // kSfxAxeFleshUW
  142. {"", 80, 0x10000, 0}, // kSfxAxeDirtUW
  143. {"", 80, 0x10000, 0}, // kSfxAxeClayUW
  144. {"", 80, 0x10000, 0}, // kSfxAxeIceUW
  145. {"", 80, 0x10000, 0}, // kSfxAxeLeavesUW
  146. {"", 80, 0x10000, 0}, // kSfxAxePlantUW
  147. {"", 80, 0x10000, 0}, // kSfxClawStone
  148. {"", 80, 0x10000, 0}, // kSfxClawMetal
  149. {"", 80, 0x10000, 0}, // kSfxClawWood
  150. {"", 80, 0x10000, 0}, // kSfxClawFlesh
  151. {"", 80, 0x10000, 0}, // kSfxClawWater
  152. {"", 80, 0x10000, 0}, // kSfxClawDirt
  153. {"", 80, 0x10000, 0}, // kSfxClawClay
  154. {"", 80, 0x10000, 0}, // kSfxClawSnow
  155. {"", 80, 0x10000, 0}, // kSfxClawIce
  156. {"", 80, 0x10000, 0}, // kSfxClawLeaves
  157. {"", 80, 0x10000, 0}, // kSfxClawPlant
  158. {"", 80, 0x10000, 0}, // kSfxClawGoo
  159. {"", 80, 0x10000, 0}, // kSfxClawLava
  160. {"", 80, 0x10000, 0}, // kSfxClawStoneUW
  161. {"", 80, 0x10000, 0}, // kSfxClawMetalUW
  162. {"", 80, 0x10000, 0}, // kSfxClawWoodUW
  163. {"", 80, 0x10000, 0}, // kSfxClawFleshUW
  164. {"", 80, 0x10000, 0}, // kSfxClawDirtUW
  165. {"", 80, 0x10000, 0}, // kSfxClawClayUW
  166. {"", 80, 0x10000, 0}, // kSfxClawIceUW
  167. {"", 80, 0x10000, 0}, // kSfxClawLeavesUW
  168. {"", 80, 0x10000, 0}, // kSfxClawPlantUW
  169. {"footstn1", 80, 0x10000, 0}, // kSfxFootStone1
  170. {"footstn2", 80, 0x10000, 0}, // kSfxFootStone2
  171. {"footmtl1", 80, 0x10000, 0}, // kSfxFootMetal1
  172. {"footmtl2", 80, 0x10000, 0}, // kSfxFootMetal2
  173. {"footwod1", 80, 0x10000, 0}, // kSfxFootWood1
  174. {"footwod2", 80, 0x10000, 0}, // kSfxFootWood2
  175. {"footwtr1", 80, 0x10000, 0}, // kSfxFootFlesh1
  176. {"footwtr2", 80, 0x10000, 0}, // kSfxFootFlesh2
  177. {"footwtr1", 80, 0x10000, 0}, // kSfxFootWater1
  178. {"footwtr2", 80, 0x10000, 0}, // kSfxFootWater2
  179. {"footdrt1", 80, 0x10000, 0}, // kSfxFootDirt1
  180. {"footdrt2", 80, 0x10000, 0}, // kSfxFootDirt2
  181. {"footdrt1", 80, 0x10000, 0}, // kSfxFootClay1
  182. {"footdrt2", 80, 0x10000, 0}, // kSfxFootClay2
  183. {"footgrs1", 80, 0x10000, 0}, // kSfxFootSnow1
  184. {"footgrs2", 80, 0x10000, 0}, // kSfxFootSnow2
  185. {"footwtr1", 80, 0x10000, 0}, // kSfxFootIce1
  186. {"footwtr2", 80, 0x10000, 0}, // kSfxFootIce2
  187. {"footgrs2", 80, 0x10000, 0}, // kSfxFootLeaves
  188. {"footdrt1", 80, 0x10000, 0}, // kSfxFootCloth1
  189. {"footdrt2", 80, 0x10000, 0}, // kSfxFootCloth2
  190. {"footgrs1", 80, 0x10000, 0}, // kSfxFootPlant1
  191. {"footgrs2", 80, 0x10000, 0}, // kSfxFootPlant2
  192. {"footwtr1", 80, 0x10000, 0}, // kSfxFootGoo1
  193. {"footwtr2", 80, 0x10000, 0}, // kSfxFootGoo2
  194. {"footgrs1", 80, 0x10000, 0}, // kSfxFootLava1
  195. {"footgrs2", 80, 0x10000, 0}, // kSfxFootLava2
  196. {"lnd_stn", 80, 0x10000, 0}, // kSfxDudeLandStone
  197. {"lnd_metl", 80, 0x10000, 0}, // kSfxDudeLandMetal
  198. {"lnd_wood", 80, 0x10000, 0}, // kSfxDudeLandWood
  199. {"lnd_wtr", 80, 0x10000, 0}, // kSfxDudeLandFlesh
  200. {"lnd_wtr", 80, 0x10000, 0}, // kSfxDudeLandWater
  201. {"lnd_dirt", 80, 0x10000, 0}, // kSfxDudeLandDirt
  202. {"", 80, 0x10000, 0}, // kSfxDudeLandClay
  203. {"", 80, 0x10000, 0}, // kSfxDudeLandSnow
  204. {"", 80, 0x10000, 0}, // kSfxDudeLandIce
  205. {"", 80, 0x10000, 0}, // kSfxDudeLandLeaves
  206. {"", 80, 0x10000, 0}, // kSfxDudeLandCloth
  207. {"", 80, 0x10000, 0}, // kSfxDudeLandPlant
  208. {"", 80, 0x10000, 0}, // kSfxDudeLandGoo
  209. {"", 80, 0x10000, 0}, // kSfxDudeLandLava
  210. {"", 80, 0x10000, 0}, // kSfxBodyLandStone
  211. {"", 80, 0x10000, 0}, // kSfxBodyLandMetal
  212. {"", 80, 0x10000, 0}, // kSfxBodyLandWood
  213. {"", 80, 0x10000, 0}, // kSfxBodyLandFlesh
  214. {"", 80, 0x10000, 0}, // kSfxBodyLandWater
  215. {"", 80, 0x10000, 0}, // kSfxBodyLandDirt
  216. {"", 80, 0x10000, 0}, // kSfxBodyLandClay
  217. {"", 80, 0x10000, 0}, // kSfxBodyLandSnow
  218. {"", 80, 0x10000, 0}, // kSfxBodyLandIce
  219. {"", 80, 0x10000, 0}, // kSfxBodyLandLeaves
  220. {"", 80, 0x10000, 0}, // kSfxBodyLandCloth
  221. {"", 80, 0x10000, 0}, // kSfxBodyLandPlant
  222. {"", 80, 0x10000, 0}, // kSfxBodyLandGoo
  223. {"", 80, 0x10000, 0}, // kSfxBodyLandLava
  224. {"", 80, 0x10000, 0}, // kSfxGibLandStone
  225. {"", 80, 0x10000, 0}, // kSfxGibLandMetal
  226. {"", 80, 0x10000, 0}, // kSfxGibLandWood
  227. {"", 80, 0x10000, 0}, // kSfxGibLandFlesh
  228. {"", 80, 0x10000, 0}, // kSfxGibLandWater
  229. {"", 80, 0x10000, 0}, // kSfxGibLandDirt
  230. {"", 80, 0x10000, 0}, // kSfxGibLandClay
  231. {"", 80, 0x10000, 0}, // kSfxGibLandSnow
  232. {"", 80, 0x10000, 0}, // kSfxGibLandIce
  233. {"", 80, 0x10000, 0}, // kSfxGibLandLeaves
  234. {"", 80, 0x10000, 0}, // kSfxGibLandCloth
  235. {"", 80, 0x10000, 0}, // kSfxGibLandPlant
  236. {"", 80, 0x10000, 0}, // kSfxGibLandGoo
  237. {"", 80, 0x10000, 0}, // kSfxGibLandLava
  238. {"", 80, 0x10000, 0}, // kSfxSplashS
  239. {"", 80, 0x10000, 0}, // kSfxSplashM
  240. {"", 80, 0x10000, 0}, // kSfxSplashL
  241. {"arc1", 80, 0x10000, 0}, // kSfxArc1
  242. {"arc2", 80, 0x10000, 0}, // kSfxArc2
  243. {"arc3", 80, 0x10000, 0}, // kSfxArc3
  244. {"", 80, 0x10000, 0}, // kSfxBladeDrop
  245. {"", 80, 0x10000, 0}, // kSfxBladeSwipe
  246. {"bould3", 80, 0x10000, 0}, // kSfxBoulders
  247. {"_exploa", 200, 0x10000, 0}, // kSfxExplodeCS // exp_tnt
  248. {"exp_barl", 200, 0x10000, 0}, // kSfxExplodeCM
  249. {"exp_lrg", 400, 0x10000, 0}, // kSfxExplodeCL
  250. {"exp_tnt", 100, 0x10000, 0}, // kSfxExplodeFS
  251. {"exp_barl", 200, 0x10000, 0}, // kSfxExplodeFM
  252. {"exp_lrg", 400, 0x10000, 0}, // kSfxExplodeFL
  253. {"exp_uw1", 80, 0x10000, 0}, // kSfxExplode1UW
  254. {"exp_uw2", 80, 0x10000, 0}, // kSfxExplode2UW
  255. {"exp_uw1", 80, 0x10000, 0}, // kSfxExplode3UW
  256. {"", 80, 0x10000, 0}, // kSfxFireballPrefire
  257. {"", 80, 0x10000, 0}, // kSfxFireballFire
  258. {"dmpistol", 200, 0x10000, 0}, // kSfxMGFire
  259. {"_mgdie", 160, 0x10000, 0}, // kSfxMGDie
  260. {"", 80, 0x10000, 0}, // kSfxSawStart
  261. {"", 80, 0x10000, 0}, // kSfxSawRun
  262. {"", 80, 0x10000, 0}, // kSfxSawStop
  263. {"", 80, 0x10000, 0}, // kSfxSawCut
  264. {"", 80, 0x10000, 0}, // kSfxAmbientCave
  265. {"", 80, 0x10000, 0}, // kSfxAmbientFauna
  266. {"", 80, 0x10000, 0}, // kSfxAmbientMechanical
  267. {"rain2", 80, 0x10000, 0}, // kSfxAmbientRain
  268. {"undrwatr", 30, 0x10000, 0}, // kSfxAmbientUW
  269. {"", 80, 0x10000, 0}, // kSfxAmbientWind
  270. {"", 80, 0x10000, 0}, // kSfxAmbientMansion
  271. {"", 80, 0x10000, 0}, // kSfxAmbientCastle
  272. {"", 80, 0x10000, 0}, // kSfxAmbientRainIndoors
  273. {"", 80, 0x10000, 0}, // kSfxAmbientCreepy1
  274. {"", 80, 0x10000, 0}, // kSfxAmbientCreepy2
  275. {"", 80, 0x10000, 0}, // kSfxAmbientCreepy3
  276. {"bubrise", 80, 0x10000, 0}, // kSfxBubbles
  277. {"", 80, 0x10000, 0}, // kSfxCrickets
  278. {"dripsurf", 10, 0x10000, 0}, // kSfxDrip1
  279. {"dripwat4", 10, 0x10000, 0}, // kSfxDrip2
  280. {"dripwat5", 10, 0x10000, 0}, // kSfxDrip3
  281. {"", 80, 0x10000, 0}, // kSfxFrog
  282. {"", 80, 0x10000, 0}, // kSfxLeaves
  283. {"", 80, 0x10000, 0}, // kSfxOwl
  284. {"", 80, 0x10000, 0}, // kSfxRaven
  285. {"dmspawn", 80, 0x10000, 0}, // kSfxRespawn
  286. {"sewage", 80, 0x10000, 0}, // kSfxSewage
  287. {"thunder", 80, 0x10000, 0}, // kSfxThunder
  288. {"thunder2", 80, 0x10000, 0}, // kSfxThunder2
  289. {"", 80, 0x10000, 0}, // kSfxTrees
  290. {"waterlap", 80, 0x10000, 0}, // kSfxWaterLap
  291. {"water2", 80, 0x10000, 0}, // kSfxWaterStream
  292. {"bdy_burn", 50, 0x10000, 0}, // kSfxBurn
  293. {"flesh3", 80, 0x10000, 0}, // kSfxSizzle
  294. {"grandck3", 10, 0x10000, 0}, // kSfxTickTock
  295. {"gust1", 80, 0x10000, 0}, // kSfxGust1
  296. {"gust2", 80, 0x10000, 0}, // kSfxGust2
  297. {"gust3", 80, 0x10000, 0}, // kSfxGust3
  298. {"gust4", 80, 0x10000, 0}, // kSfxGust4
  299. {"", 80, 0x10000, 0}, // kSfxWhisper
  300. {"", 80, 0x10000, 0}, // kSfxLaugh
  301. {"chains", 80, 0x10000, 0}, // kSfxChains
  302. {"", 80, 0x10000, 0}, // kSfxMoan
  303. {"", 80, 0x10000, 0}, // kSfxSigh
  304. {"floorcr2", 80, 0x10000, 0}, // kSfxCreak
  305. {"", 80, 0x10000, 0}, // kSfxSqueak
  306. {"", 80, 0x10000, 0}, // kSfxScuffle
  307. {"", 80, 0x10000, 0}, // kSfxRumble
  308. {"", 80, 0x10000, 0}, // kSfxScream
  309. {"dorcreak", 80, 0x10000, 0}, // kSfxDoorCreak
  310. {"doorslid", 80, 0x10000, 0}, // kSfxDoorSlide
  311. {"floorcr2", 80, 0x10000, 0}, // kSfxFloorCreak
  312. {"gearstrt", 80, 0x10000, 0}, // kSfxGearStart
  313. {"geargrin", 80, 0x10000, 0}, // kSfxGearMove
  314. {"gearhalt", 80, 0x10000, 0}, // kSfxGearStop
  315. {"glashit2", 120, 0x10000, 0}, // kSfxGlassHit
  316. {"elevstrt", 80, 0x10000, 0}, // kSfxLiftStart
  317. {"elevmov", 80, 0x10000, 0}, // kSfxLiftMove
  318. {"elevstop", 80, 0x10000, 0}, // kSfxLiftStop
  319. {"chains", 80, 0x10000, 0}, // kSfxPadlock
  320. {"pottery", 80, 0x10000, 0}, // kSfxPotteryHit
  321. {"slabmove", 80, 0x10000, 0}, // kSfxSlabMove
  322. {"", 80, 0x10000, 0}, // kSfxSplat
  323. {"dooropen", 80, 0x10000, 0}, // kSfxSwingOpen
  324. {"doorclos", 80, 0x10000, 0}, // kSfxSwingShut
  325. {"switch5", 40, 0x10000, 0}, // kSfxSwitch1
  326. {"switch5", 40, 0x10000, 0}, // kSfxSwitch2
  327. {"switch5", 40, 0x10000, 0}, // kSfxSwitch3
  328. {"switch5", 40, 0x10000, 0}, // kSfxSwitch4
  329. {"", 80, 0x10000, 0}, // kSfxWoodBreak
  330. {"jump", 40, 0x10000, 0}, // kSfxPlayJump
  331. {"land", 40, 0x10000, 0}, // kSfxPlayLand
  332. {"", 80, 0x10000, 0}, // kSfxHunt
  333. {"pl_swim1", 80, 0x10000, 0}, // kSfxPlaySwim
  334. {"pl_uw_sw", 80, 0x10000, 0}, // kSfxPlaySwimUW
  335. {"breathe1", 80, 0x10000, 0}, // kSfxPlayBreathe1
  336. {"breathe2", 80, 0x10000, 0}, // kSfxPlayBreathe2
  337. {"_pain", 80, 0x10000, 0}, // kSfxPlayPain
  338. {"death", 80, 0x10000, 0}, // kSfxPlayDie
  339. {"bdy_splg", 80, 0x10000, 0}, // kSfxPlayDie2
  340. {"deathbrn", 80, 0x10000, 0}, // kSfxPlayDie3
  341. {"fall", 80, 0x10000, 0}, // kSfxPlayFall
  342. {"choke", 80, 0x10000, 0}, // kSfxPlayChoke
  343. {"choke2", 80, 0x10000, 0}, // kSfxPlayChoke2
  344. {"paingasp", 80, 0x10000, 0}, // kSfxPlayGasp
  345. {"hot_ouch", 80, 0x10000, 0}, // kSfxPlayHotFoot
  346. {"dol_lafs", 80, 0x10000, 0}, // kSfxPlayLaugh
  347. {"submerge", 80, 0x10000, 0}, // kSfxPlaySubmerge
  348. {"emerge", 80, 0x10000, 0}, // kSfxPlayEmerge
  349. {"pickup", 80, 0x10000, 0}, // kSfxPlayItemUp
  350. {"dmgetpow", 80, 0x10000, 0}, // kSfxPlayPowerUp
  351. {"dmradio", 80, 0x10000, 0}, // kSfxPlayMessage
  352. {"", 80, 0x10000, 0}, // kSfxCultSpot
  353. {"", 80, 0x10000, 0}, // kSfxCultSpot2
  354. {"", 80, 0x10000, 0}, // kSfxCultSpot3
  355. {"", 80, 0x10000, 0}, // kSfxCultSpot4
  356. {"", 80, 0x10000, 0}, // kSfxCultSpot5
  357. {"", 80, 0x10000, 0}, // kSfxSCultRoam
  358. {"", 80, 0x10000, 0}, // kSfxSCultRoam2
  359. {"", 80, 0x10000, 0}, // kSfxSCultRoam3
  360. {"", 80, 0x10000, 0}, // kSfxSCultRoam4
  361. {"", 80, 0x10000, 0}, // kSfxCultPain
  362. {"", 80, 0x10000, 0}, // kSfxCultPain2
  363. {"", 80, 0x10000, 0}, // kSfxCultPain3
  364. {"", 80, 0x10000, 0}, // kSfxCultPain4
  365. {"", 80, 0x10000, 0}, // kSfxCultPain5
  366. {"", 80, 0x10000, 0}, // kSfxCultDie
  367. {"", 80, 0x10000, 0}, // kSfxCultDie2
  368. {"", 80, 0x10000, 0}, // kSfxCultDie3
  369. {"tnt_toss", 40, 0x08000, 0}, // kSfxCultToss
  370. {"", 80, 0x10000, 0}, // kSfxCultGloat
  371. {"", 80, 0x10000, 0}, // kSfxCultGloat2
  372. {"", 80, 0x10000, 0}, // kSfxCultGloat3
  373. {"", 80, 0x10000, 0}, // kSfxCultGloat4
  374. {"", 80, 0x10000, 0}, // kSfxCultGloat5
  375. {"", 80, 0x10000, 0}, // kSfxCultGloat6
  376. {"", 80, 0x10000, 0}, // kSfxCultGloat7
  377. {"", 80, 0x10000, 0}, // kSfxCultGloat8
  378. {"", 80, 0x10000, 0}, // kSfxCultGloat9
  379. {"", 80, 0x10000, 0}, // kSfxCultGloat10
  380. {"", 80, 0x10000, 0}, // kSfxSCultAttack
  381. {"", 80, 0x10000, 0}, // kSfxTCultAttack
  382. {"", 80, 0x10000, 0}, // kSfxAZombSpot
  383. {"", 80, 0x10000, 0}, // kSfxAZombRoam
  384. {"", 80, 0x10000, 0}, // kSfxAZombPain
  385. {"", 80, 0x10000, 0}, // kSfxAZombDie
  386. {"", 80, 0x10000, 0}, // kSfxAZombDie2
  387. {"", 80, 0x10000, 0}, // kSfxAZombDie3
  388. {"dmhack2", 60, 0x10000, 0}, // kSfxAZombAttack
  389. {"", 80, 0x10000, 0}, // kSfxAZombMorph
  390. {"", 80, 0x10000, 0}, // kSfxFZombSpot
  391. {"", 80, 0x10000, 0}, // kSfxFZombRoam
  392. {"", 80, 0x10000, 0}, // kSfxFZombPain
  393. {"", 80, 0x10000, 0}, // kSfxFZombDie
  394. {"", 80, 0x10000, 0}, // kSfxFZombDie2
  395. {"", 80, 0x10000, 0}, // kSfxFZombDie3
  396. {"", 80, 0x10000, 0}, // kSfxFZombAttack
  397. {"", 80, 0x10000, 0}, // kSfxHoundSpot
  398. {"", 80, 0x10000, 0}, // kSfxHoundRoam
  399. {"", 80, 0x10000, 0}, // kSfxHoundPain
  400. {"", 80, 0x10000, 0}, // kSfxHoundDie
  401. {"", 80, 0x10000, 0}, // kSfxHoundDie2
  402. {"", 80, 0x10000, 0}, // kSfxHoundAttack
  403. {"", 80, 0x10000, 0}, // kSfxHoundAttack2
  404. {"", 80, 0x10000, 0}, // kSfxGargSpot
  405. {"", 80, 0x10000, 0}, // kSfxGargRoam
  406. {"", 80, 0x10000, 0}, // kSfxGargPain
  407. {"", 80, 0x10000, 0}, // kSfxGargDie
  408. {"", 80, 0x10000, 0}, // kSfxGargDie2
  409. {"", 80, 0x10000, 0}, // kSfxGargDie3
  410. {"gargoyle", 80, 0x10000, 0}, // kSfxGargAttack
  411. {"", 80, 0x10000, 0}, // kSfxGargAttack2
  412. {"", 80, 0x10000, 0}, // kSfxGargAttack3
  413. {"", 80, 0x10000, 0}, // kSfxGargMorph
  414. {"", 80, 0x10000, 0}, // kSfxEelSpot
  415. {"", 80, 0x10000, 0}, // kSfxEelRoam
  416. {"", 80, 0x10000, 0}, // kSfxEelPain
  417. {"", 80, 0x10000, 0}, // kSfxEelDie
  418. {"", 80, 0x10000, 0}, // kSfxEelAttack
  419. {"", 80, 0x10000, 0}, // kSfxPhantasmSpot
  420. {"", 80, 0x10000, 0}, // kSfxPhantasmRoam
  421. {"", 80, 0x10000, 0}, // kSfxPhantasmPain
  422. {"", 80, 0x10000, 0}, // kSfxPhantasmDie
  423. {"", 80, 0x10000, 0}, // kSfxPhantasmAttack
  424. {"", 80, 0x10000, 0}, // kSfxPhantasmMorph
  425. {"", 80, 0x10000, 0}, // kSfxGillSpot
  426. {"", 80, 0x10000, 0}, // kSfxGillRoam
  427. {"", 80, 0x10000, 0}, // kSfxGillPain
  428. {"", 80, 0x10000, 0}, // kSfxGillDie
  429. {"", 80, 0x10000, 0}, // kSfxGillAttack
  430. {"", 80, 0x10000, 0}, // kSfxSpiderSpot
  431. {"", 80, 0x10000, 0}, // kSfxSpiderRoam
  432. {"", 80, 0x10000, 0}, // kSfxSpiderPain
  433. {"", 80, 0x10000, 0}, // kSfxSpiderDie
  434. {"", 80, 0x10000, 0}, // kSfxSpiderAttack
  435. {"", 80, 0x10000, 0}, // kSfxSpiderBirth
  436. {"", 80, 0x10000, 0}, // kSfxHandRoam
  437. {"", 80, 0x10000, 0}, // kSfxHandDie
  438. {"bat", 80, 0x10000, 0}, // kSfxBatRoam
  439. {"", 80, 0x10000, 0}, // kSfxBatDie
  440. {"", 80, 0x10000, 0}, // kSfxRatRoam
  441. {"", 80, 0x10000, 0}, // kSfxRatDie
  442. {"", 80, 0x10000, 0}, // kSfxRatAttack
  443. {"", 80, 0x10000, 0}, // kSfxPodOpen
  444. {"", 80, 0x10000, 0}, // kSfxPodAttack
  445. {"", 80, 0x10000, 0}, // kSfxPodDie
  446. {"", 80, 0x10000, 0}, // kSfxPodDie2
  447. {"", 80, 0x10000, 0}, // kSfxTentUp
  448. {"", 80, 0x10000, 0}, // kSfxTentAttack
  449. {"", 80, 0x10000, 0}, // kSfxTentDie
  450. {"", 80, 0x10000, 0}, // kSfxCerbSpot
  451. {"", 80, 0x10000, 0}, // kSfxCerbSpot2
  452. {"", 80, 0x10000, 0}, // kSfxCerbRoam
  453. {"", 80, 0x10000, 0}, // kSfxCerbPain
  454. {"", 80, 0x10000, 0}, // kSfxCerbPain2
  455. {"", 80, 0x10000, 0}, // kSfxCerbDie
  456. {"", 80, 0x10000, 0}, // kSfxCerbDie2
  457. {"", 80, 0x10000, 0}, // kSfxCerbAttack
  458. {"", 80, 0x10000, 0}, // kSfxCerbAttack2
  459. {"", 80, 0x10000, 0}, // kSfxBossSpot
  460. {"", 80, 0x10000, 0}, // kSfxBossRoam
  461. {"", 80, 0x10000, 0}, // kSfxBossPain
  462. {"", 80, 0x10000, 0}, // kSfxBossDie
  463. {"", 80, 0x10000, 0} // kSfxBossAttack
  464. };
  465. struct SAMPLE3D
  466. {
  467. int hVoice;
  468. BYTE *pRaw;
  469. };
  470. struct VISBY
  471. {
  472. SAMPLE3D left, right;
  473. int id;
  474. int x, y, z;
  475. };
  476. VISBY Visby[kMaxXSprites];
  477. struct BONKLE
  478. {
  479. SAMPLE3D left, right;
  480. int x, y, z;
  481. };
  482. #define kMaxBonkles 64
  483. BONKLE Bonkle[kMaxBonkles];
  484. void sfxInit( void )
  485. {
  486. for (int i = 0; i < kSfxMax; i++)
  487. {
  488. if ( (soundEffect[i].hResource = gSysRes.Lookup(soundEffect[i].name, ".RAW")) == NULL )
  489. {
  490. dprintf("Missing sound resource: %s.RAW\n", soundEffect[i].name);
  491. }
  492. }
  493. }
  494. void sfxTerm( void )
  495. {
  496. }
  497. void sfxKillAllSounds( void )
  498. {
  499. }
  500. /*******************************************************************************
  501. Here is the equation for determining the frequency shift of a sound:
  502. Ú ¿
  503. ³ v + vL ³
  504. fL = fS ³ ÄÄÄÄÄÄ ³
  505. ³ v + vS ³
  506. À Ù
  507. Where:
  508. fL = frequency as heard by the listener
  509. fS = frequency of the source
  510. v = velocity of sound
  511. vL = velocity of listener
  512. vS = velocity of source
  513. Velocities are measured on a vector from the listener to the source.
  514. Speed of sound at STP = 343 m/s = 1126 ft/s.
  515. *******************************************************************************/
  516. /*
  517. #define kSoundVelocity ((double)kSampleRate / kTimerRate)
  518. int Freq( int velocity )
  519. {
  520. return kSampleRate * kSoundVelocity / (ClipLow(kSoundVelocity - velocity, 1));
  521. }
  522. */
  523. inline int FreqShift( int nPitch, int vL )
  524. {
  525. return muldiv(nPitch, kSoundVelFrame + vL, kSoundVelFrame);
  526. }
  527. static int Vol3d(int nAngle, int vol)
  528. {
  529. return vol - mulscale16(vol, kBackFilter / 2 - mulscale30(kBackFilter / 2, Cos(nAngle)));
  530. }
  531. void Calc3DValues( int x, int y, int z, int relVol )
  532. {
  533. int dx, dy, dz, dist, nAngle;
  534. dx = x - gMe->sprite->x;
  535. dy = y - gMe->sprite->y;
  536. dz = z - gMe->sprite->z;
  537. nAngle = getangle(dx, dy);
  538. dist = ClipLow(Dist3d(dx, dy, dz), 32);
  539. int monoVol = muldiv(relVol, kVolScale, dist);
  540. // normal vector for listener -> source
  541. dx = Cos(nAngle);
  542. dy = Sin(nAngle);
  543. int lDist = qdist(x - earL.x, y - earL.y);
  544. lVol = Vol3d(nAngle - (gMe->sprite->ang - kPinnaAngle), monoVol);
  545. lPhase = mulscale16r(lDist, kDistPhase);
  546. lVel = dmulscale30r(dx, earVL.dx, dy, earVL.dy);
  547. int rDist = qdist(x - earR.x, y - earR.y);
  548. rVol = Vol3d(nAngle - (gMe->sprite->ang + kPinnaAngle), monoVol);
  549. rPhase = mulscale16r(rDist, kDistPhase);
  550. rVel = dmulscale30r(dx, earVR.dx, dy, earVR.dy);
  551. }
  552. /*
  553. void UpdateSound( void )
  554. {
  555. if (lVoice > FX_Ok)
  556. {
  557. FX_SetPan(lVoice, lVol, lVol, 0);
  558. FX_SetFrequency(lVoice, Freq(lVel));
  559. }
  560. if (rVoice > FX_Ok)
  561. {
  562. FX_SetPan(rVoice, rVol, 0, rVol);
  563. FX_SetFrequency(rVoice, Freq(rVel));
  564. }
  565. }
  566. */
  567. void sfxStart3DSound( int nXSprite, int soundId, int nPitchOffset )
  568. {
  569. if ( gFXDevice == -1 )
  570. return;
  571. if ( soundId < 0 || soundId >= kSfxMax )
  572. ThrowError("Invalid sound ID", ES_ERROR);
  573. SOUNDEFFECT *pSoundEffect = &soundEffect[soundId];
  574. dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
  575. VISBY *pVisby = &Visby[nXSprite];
  576. // don't restart an actor sound if its already playing
  577. if ( (pVisby->left.hVoice > 0 | pVisby->right.hVoice > 0 ) && pVisby->id == soundId )
  578. return;
  579. pVisby->id = soundId;
  580. // if there is an active voice, kill the sound
  581. if ( pVisby->left.hVoice > 0 )
  582. {
  583. FX_StopSound(pVisby->left.hVoice);
  584. Resource::Free(pVisby->left.pRaw);
  585. pVisby->left.pRaw = NULL;
  586. }
  587. if ( pVisby->right.hVoice > 0 )
  588. {
  589. FX_StopSound(pVisby->right.hVoice);
  590. Resource::Free(pVisby->right.pRaw);
  591. pVisby->right.pRaw = NULL;
  592. }
  593. SPRITE *pSprite = &sprite[xsprite[nXSprite].reference];
  594. Calc3DValues(pSprite->x, pSprite->y, pSprite->z, pSoundEffect->relVol);
  595. RESHANDLE hResource = pSoundEffect->hResource;
  596. if ( hResource == NULL )
  597. {
  598. dprintf("sfxStart3DSound() called for missing sound #%d\n", soundId);
  599. return;
  600. }
  601. int sampleSize = gSysRes.Size(hResource);
  602. char *pRaw = (char *)gSysRes.Lock(hResource);
  603. int nPitch = kSampleRate;
  604. if ( nPitchOffset )
  605. nPitch += mulscale16(BiRandom(nPitchOffset), kSampleRate);
  606. pVisby->left.pRaw = (BYTE *)Resource::Alloc(sampleSize + lPhase);
  607. memset(pVisby->left.pRaw, 128, lPhase);
  608. memcpy(&pVisby->left.pRaw[lPhase], pRaw, sampleSize);
  609. pVisby->right.pRaw = (BYTE *)Resource::Alloc(sampleSize + rPhase);
  610. memset(pVisby->right.pRaw, 128, rPhase);
  611. memcpy(&pVisby->right.pRaw[rPhase], pRaw, sampleSize);
  612. gSysRes.Unlock(hResource);
  613. int nPriority = 1; // ASS seems to choke if this is less than 1, e.g., 0
  614. if ( lVol > nPriority )
  615. nPriority = lVol;
  616. if ( rVol > nPriority )
  617. nPriority = rVol;
  618. _disable(); // make sure the samples start in the same interval
  619. pVisby->left.hVoice = FX_PlayRaw(
  620. pVisby->left.pRaw, sampleSize + lPhase, FreqShift(nPitch, lVel), 0,
  621. lVol, lVol, 0, nPriority, (ulong)(&pVisby->left.hVoice));
  622. pVisby->right.hVoice = FX_PlayRaw(
  623. pVisby->right.pRaw, sampleSize + rPhase, FreqShift(nPitch, rVel), 0,
  624. rVol, 0, rVol, nPriority, (ulong)(&pVisby->right.hVoice));
  625. _enable(); // allow them to start
  626. }
  627. void sfxCreate3DSound( int x, int y, int z, int soundId, int nPitchOffset )
  628. {
  629. if ( gFXDevice == -1 )
  630. return;
  631. if ( soundId < 0 || soundId >= kSfxMax )
  632. ThrowError("Invalid sound ID", ES_ERROR);
  633. SOUNDEFFECT *pSoundEffect = &soundEffect[soundId];
  634. Calc3DValues(x, y, z, pSoundEffect->relVol);
  635. RESHANDLE hResource = pSoundEffect->hResource;
  636. if ( hResource == NULL )
  637. {
  638. dprintf("sfxCreate3DSound() called for missing sound #%d\n", soundId);
  639. return;
  640. }
  641. int sampleSize = gSysRes.Size(hResource);
  642. char *pRaw = (char *)gSysRes.Lock(hResource);
  643. int nPitch = kSampleRate;
  644. if ( nPitchOffset )
  645. nPitch += mulscale16(BiRandom(nPitchOffset), kSampleRate);
  646. for (int i = 0; i < kMaxBonkles; i++)
  647. if ( Bonkle[i].left.pRaw == NULL && Bonkle[i].right.pRaw == NULL )
  648. break;
  649. dassert(i < kMaxBonkles);
  650. BONKLE *pBonkle = &Bonkle[i];
  651. pBonkle->left.pRaw = (BYTE *)Resource::Alloc(sampleSize + lPhase);
  652. memset(pBonkle->left.pRaw, 128, lPhase);
  653. memcpy(&pBonkle->left.pRaw[lPhase], pRaw, sampleSize);
  654. pBonkle->right.pRaw = (BYTE *)Resource::Alloc(sampleSize + rPhase);
  655. memset(pBonkle->right.pRaw, 128, rPhase);
  656. memcpy(&pBonkle->right.pRaw[rPhase], pRaw, sampleSize);
  657. gSysRes.Unlock(hResource);
  658. int nPriority = 1; // ASS seems to choke if this is less than 1, e.g., 0
  659. if ( lVol > nPriority )
  660. nPriority = lVol;
  661. if ( rVol > nPriority )
  662. nPriority = rVol;
  663. _disable(); // make sure the samples start in the same interval
  664. pBonkle->left.hVoice = FX_PlayRaw(
  665. pBonkle->left.pRaw, sampleSize + lPhase, FreqShift(nPitch, lVel), 0,
  666. lVol, lVol, 0, nPriority, (ulong)(&pBonkle->left.hVoice));
  667. pBonkle->right.hVoice = FX_PlayRaw(
  668. pBonkle->right.pRaw, sampleSize + rPhase, FreqShift(nPitch, rVel), 0,
  669. rVol, 0, rVol, nPriority, (ulong)(&pBonkle->right.hVoice));
  670. _enable(); // allow them to start
  671. }
  672. void sfxKill3DSound( int nXSprite )
  673. {
  674. if ( gFXDevice == -1 )
  675. return;
  676. dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
  677. VISBY *pVisby = &Visby[nXSprite];
  678. // if there is an active voice, kill the sound
  679. if ( pVisby->left.hVoice > 0 )
  680. FX_StopSound(pVisby->left.hVoice);
  681. if ( pVisby->right.hVoice > 0 )
  682. FX_StopSound(pVisby->right.hVoice);
  683. }
  684. /*
  685. void sfxKillAll3DSounds( void )
  686. {
  687. }
  688. */
  689. // ear distance (in samples)
  690. #define kEarLX (int)(-kIntraAuralTime / 2 * kSampleRate)
  691. #define kEarRX (int)(+kIntraAuralTime / 2 * kSampleRate)
  692. void sfxUpdate3DSounds( void )
  693. {
  694. // update listener ear positions
  695. int earDX, earDY;
  696. earDX = mulscale30(Cos(gMe->sprite->ang + kAngle90), kIntraAuralDist);
  697. earDY = mulscale30(Sin(gMe->sprite->ang + kAngle90), kIntraAuralDist);
  698. earL0 = earL;
  699. earL.x = gMe->sprite->x - earDX;
  700. earL.y = gMe->sprite->y - earDY;
  701. earR0 = earR;
  702. earR.x = gMe->sprite->x + earDX;
  703. earR.y = gMe->sprite->y + earDY;
  704. // update ear velocities
  705. earVL.dx = earL.x - earL0.x;
  706. earVL.dy = earL.y - earL0.y;
  707. earVR.dx = earR.x - earR0.x;
  708. earVR.dy = earR.y - earR0.y;
  709. int i;
  710. for (i = 0; i < kMaxXSprites; i++)
  711. {
  712. if ( Visby[i].left.pRaw != NULL && Visby[i].left.hVoice <= 0 )
  713. {
  714. Resource::Free(Visby[i].left.pRaw);
  715. Visby[i].left.pRaw = NULL;
  716. }
  717. if ( Visby[i].right.pRaw != NULL && Visby[i].right.hVoice <= 0 )
  718. {
  719. Resource::Free(Visby[i].right.pRaw);
  720. Visby[i].right.pRaw = NULL;
  721. }
  722. }
  723. for (i = 0; i < kMaxBonkles; i++)
  724. {
  725. if (Bonkle[i].left.hVoice <= 0 && Bonkle[i].left.pRaw != NULL )
  726. {
  727. Resource::Free(Bonkle[i].left.pRaw);
  728. Bonkle[i].left.pRaw = NULL;
  729. }
  730. if (Bonkle[i].right.hVoice <= 0 && Bonkle[i].right.pRaw != NULL )
  731. {
  732. Resource::Free(Bonkle[i].right.pRaw);
  733. Bonkle[i].right.pRaw = NULL;
  734. }
  735. }
  736. }