2014-03-15 16:59:03 +00:00
|
|
|
// SONIC ROBO BLAST 2
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// Copyright (C) 1993-1996 by id Software, Inc.
|
|
|
|
// Copyright (C) 1998-2000 by DooM Legacy Team.
|
2021-05-07 15:45:56 +00:00
|
|
|
// Copyright (C) 1999-2021 by Sonic Team Junior.
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
|
|
|
// This program is free software distributed under the
|
|
|
|
// terms of the GNU General Public License, version 2.
|
|
|
|
// See the 'LICENSE' file for more details.
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// \file s_sound.h
|
|
|
|
/// \brief The not so system specific sound interface
|
|
|
|
|
|
|
|
#ifndef __S_SOUND__
|
|
|
|
#define __S_SOUND__
|
|
|
|
|
2018-08-23 16:51:45 +00:00
|
|
|
#include "i_sound.h" // musictype_t
|
2014-03-15 16:59:03 +00:00
|
|
|
#include "sounds.h"
|
|
|
|
#include "m_fixed.h"
|
|
|
|
#include "command.h"
|
|
|
|
#include "tables.h" // angle_t
|
|
|
|
|
2019-01-06 04:42:25 +00:00
|
|
|
#ifdef HAVE_OPENMPT
|
|
|
|
#include "libopenmpt/libopenmpt.h"
|
2020-05-12 17:40:51 +00:00
|
|
|
extern openmpt_module *openmpt_mhandle;
|
2019-01-06 04:42:25 +00:00
|
|
|
#endif
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// mask used to indicate sound origin is player item pickup
|
|
|
|
#define PICKUP_SOUND 0x8000
|
|
|
|
|
|
|
|
extern consvar_t stereoreverse;
|
2017-04-17 00:09:47 +00:00
|
|
|
extern consvar_t cv_soundvolume, cv_closedcaptioning, cv_digmusicvolume, cv_midimusicvolume;
|
2014-03-15 16:59:03 +00:00
|
|
|
extern consvar_t cv_numChannels;
|
2019-08-05 00:02:38 +00:00
|
|
|
|
2018-10-11 20:29:43 +00:00
|
|
|
extern consvar_t cv_resetmusic;
|
2019-08-05 00:02:38 +00:00
|
|
|
extern consvar_t cv_resetmusicbyheader;
|
|
|
|
|
2020-01-10 20:55:03 +00:00
|
|
|
extern consvar_t cv_1upsound;
|
|
|
|
|
2019-08-05 00:02:38 +00:00
|
|
|
#define RESETMUSIC (!modeattacking && \
|
|
|
|
(cv_resetmusicbyheader.value ? \
|
|
|
|
(mapheaderinfo[gamemap-1]->musforcereset != -1 ? mapheaderinfo[gamemap-1]->musforcereset : cv_resetmusic.value) \
|
|
|
|
: cv_resetmusic.value) \
|
|
|
|
)
|
|
|
|
|
2018-11-25 19:22:52 +00:00
|
|
|
extern consvar_t cv_gamedigimusic;
|
|
|
|
extern consvar_t cv_gamemidimusic;
|
|
|
|
extern consvar_t cv_gamesounds;
|
2020-05-13 23:20:21 +00:00
|
|
|
extern consvar_t cv_musicpref;
|
|
|
|
|
2019-10-24 00:21:09 +00:00
|
|
|
extern consvar_t cv_playmusicifunfocused;
|
|
|
|
extern consvar_t cv_playsoundsifunfocused;
|
|
|
|
|
2018-09-18 16:31:47 +00:00
|
|
|
#ifdef HAVE_OPENMPT
|
|
|
|
extern consvar_t cv_modfilter;
|
|
|
|
#endif
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2019-08-04 11:03:57 +00:00
|
|
|
#ifdef HAVE_MIXERX
|
|
|
|
extern consvar_t cv_midiplayer;
|
|
|
|
extern consvar_t cv_midisoundfontpath;
|
|
|
|
extern consvar_t cv_miditimiditypath;
|
|
|
|
#endif
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
extern CV_PossibleValue_t soundvolume_cons_t[];
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
SF_TOTALLYSINGLE = 1, // Only play one of these sounds at a time...GLOBALLY
|
|
|
|
SF_NOMULTIPLESOUND = 2, // Like SF_NOINTERRUPT, but doesnt care what the origin is
|
|
|
|
SF_OUTSIDESOUND = 4, // Volume is adjusted depending on how far away you are from 'outside'
|
|
|
|
SF_X4AWAYSOUND = 8, // Hear it from 4x the distance away
|
|
|
|
SF_X8AWAYSOUND = 16, // Hear it from 8x the distance away
|
|
|
|
SF_NOINTERRUPT = 32, // Only play this sound if it isn't already playing on the origin
|
|
|
|
SF_X2AWAYSOUND = 64, // Hear it from 2x the distance away
|
|
|
|
} soundflags_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
fixed_t x, y, z;
|
|
|
|
angle_t angle;
|
|
|
|
} listener_t;
|
|
|
|
|
2017-04-17 00:09:47 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
// sound information (if null, channel avail.)
|
|
|
|
sfxinfo_t *sfxinfo;
|
|
|
|
|
|
|
|
// origin of sound
|
|
|
|
const void *origin;
|
|
|
|
|
2020-09-23 03:51:01 +00:00
|
|
|
// initial volume of sound, which is applied after distance and direction
|
|
|
|
INT32 volume;
|
|
|
|
|
2017-04-17 00:09:47 +00:00
|
|
|
// handle of the sound being played
|
|
|
|
INT32 handle;
|
|
|
|
|
|
|
|
} channel_t;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
channel_t *c;
|
|
|
|
sfxinfo_t *s;
|
2017-04-29 15:27:52 +00:00
|
|
|
UINT16 t;
|
|
|
|
UINT8 b;
|
2017-04-17 00:09:47 +00:00
|
|
|
} caption_t;
|
|
|
|
|
2017-04-17 17:15:42 +00:00
|
|
|
#define NUMCAPTIONS 8
|
2017-04-29 11:58:40 +00:00
|
|
|
#define MAXCAPTIONTICS (2*TICRATE)
|
|
|
|
#define CAPTIONFADETICS 20
|
2017-04-17 17:15:42 +00:00
|
|
|
|
|
|
|
extern caption_t closedcaptions[NUMCAPTIONS];
|
2017-04-29 15:27:52 +00:00
|
|
|
void S_StartCaption(sfxenum_t sfx_id, INT32 cnum, UINT16 lifespan);
|
2017-04-29 15:40:07 +00:00
|
|
|
void S_ResetCaptions(void);
|
2017-04-17 00:09:47 +00:00
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// register sound vars and commands at game startup
|
|
|
|
void S_RegisterSoundStuff(void);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Initializes sound stuff, including volume
|
2018-08-23 16:30:47 +00:00
|
|
|
// Sets channels, SFX, allocates channel buffer, sets S_sfx lookup.
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
2018-08-23 16:30:47 +00:00
|
|
|
void S_InitSfxChannels(INT32 sfxVolume);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Per level startup code.
|
|
|
|
// Kills playing sounds at start of level, determines music if any, changes music.
|
|
|
|
//
|
|
|
|
void S_StopSounds(void);
|
|
|
|
void S_ClearSfx(void);
|
2019-08-04 11:03:57 +00:00
|
|
|
void S_StartEx(boolean reset);
|
|
|
|
#define S_Start() S_StartEx(false)
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Basically a W_GetNumForName that adds "ds" at the beginning of the string. Returns a lumpnum.
|
|
|
|
//
|
|
|
|
lumpnum_t S_GetSfxLumpNum(sfxinfo_t *sfx);
|
|
|
|
|
2019-10-24 00:21:09 +00:00
|
|
|
//
|
|
|
|
// Sound Status
|
|
|
|
//
|
|
|
|
|
|
|
|
boolean S_SoundDisabled(void);
|
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
|
|
|
// Start sound for thing at <origin> using <sound_id> from sounds.h
|
|
|
|
//
|
|
|
|
void S_StartSound(const void *origin, sfxenum_t sound_id);
|
|
|
|
|
|
|
|
// Will start a sound at a given volume.
|
|
|
|
void S_StartSoundAtVolume(const void *origin, sfxenum_t sound_id, INT32 volume);
|
|
|
|
|
|
|
|
// Stop sound for thing at <origin>
|
|
|
|
void S_StopSound(void *origin);
|
|
|
|
|
2018-08-23 15:51:23 +00:00
|
|
|
//
|
|
|
|
// Music Status
|
|
|
|
//
|
|
|
|
|
2018-08-23 16:30:47 +00:00
|
|
|
boolean S_DigMusicDisabled(void);
|
|
|
|
boolean S_MIDIMusicDisabled(void);
|
|
|
|
boolean S_MusicDisabled(void);
|
|
|
|
boolean S_MusicPlaying(void);
|
|
|
|
boolean S_MusicPaused(void);
|
2019-10-24 00:21:09 +00:00
|
|
|
boolean S_MusicNotInFocus(void);
|
2018-08-23 16:51:45 +00:00
|
|
|
musictype_t S_MusicType(void);
|
2018-08-25 12:03:05 +00:00
|
|
|
const char *S_MusicName(void);
|
2018-08-23 16:30:47 +00:00
|
|
|
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi);
|
|
|
|
#define S_DigExists(a) S_MusicExists(a, false, true)
|
|
|
|
#define S_MIDIExists(a) S_MusicExists(a, true, false)
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2020-05-14 11:17:58 +00:00
|
|
|
// Returns whether the preferred format a (true = MIDI, false = Digital)
|
|
|
|
// exists and is enabled for musicname b
|
2020-07-13 19:16:49 +00:00
|
|
|
#define S_PrefAvailable(a, b) (a ? \
|
2020-05-14 11:17:58 +00:00
|
|
|
(!S_MIDIMusicDisabled() && S_MIDIExists(b)) : \
|
|
|
|
(!S_DigMusicDisabled() && S_DigExists(b)))
|
|
|
|
|
2018-08-23 15:51:23 +00:00
|
|
|
//
|
2018-08-24 01:07:39 +00:00
|
|
|
// Music Effects
|
2018-08-23 15:51:23 +00:00
|
|
|
//
|
2018-08-18 21:17:53 +00:00
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
// Set Speed of Music
|
|
|
|
boolean S_SpeedMusic(float speed);
|
|
|
|
|
2019-11-05 19:50:49 +00:00
|
|
|
// Music definitions
|
Sound test is cool now!
https://cdn.discordapp.com/attachments/405336003239477249/641295998395613224/srb20042.gif
* Port MUSICDEFs from Kart.
* Safe to modify without modifying game, so we can put it in music.dta eventually.
* "Title", "AltTitle", "Authors" fields are self-evident.
* "Soundtestpage" and "Soundtestcond" are used to determine which sound test unlockable can play them (set with Unlockable's variable, just like Level Select).
* "Stoppingtime" and "BPM" both accept floats, and are used for presentation stuff on the sound test.
* Ironically, we don't share a single field name with them. Such is the case of differing foci, though, and I expect they'll change their implementation to match (since this is necessary for a sound test).
* Change how S_AddSoundFx works to avoid iterating through all of them, and to allow cv_soundtest to only scroll through defined slots (instead of the infinite wall of thok sounds when scrolling to the left).
* Change V_DrawFixedPatch to allow scaling on two seperate axes.
* Now called "V_DrawStretchyFixedPatch".
* "V_DrawFixedPatch" is a macro to V_DrawStretchyFixedPatch now (same scale on both axes).
* Available to Lua under v.drawStretched!
* Even works in GL!
* Bugfix: Add SR_PLAYER to SOC's menutypes_list.
Stay tuned for the merge request, where I put the onus on the Music Team to finish this off...
2019-11-05 16:23:46 +00:00
|
|
|
typedef struct musicdef_s
|
|
|
|
{
|
|
|
|
char name[7];
|
|
|
|
char title[32];
|
|
|
|
char alttitle[64];
|
|
|
|
char authors[256];
|
2019-11-05 19:50:49 +00:00
|
|
|
//char usage[256]; -- probably never going to be relevant to vanilla
|
|
|
|
/*
|
|
|
|
the trouble here is that kart combines what we call "title"
|
|
|
|
and "authors" into one string. we need to split it for sound
|
|
|
|
test reasons. they might split it later like we did, but...
|
|
|
|
*/
|
|
|
|
//char source[256];
|
Sound test is cool now!
https://cdn.discordapp.com/attachments/405336003239477249/641295998395613224/srb20042.gif
* Port MUSICDEFs from Kart.
* Safe to modify without modifying game, so we can put it in music.dta eventually.
* "Title", "AltTitle", "Authors" fields are self-evident.
* "Soundtestpage" and "Soundtestcond" are used to determine which sound test unlockable can play them (set with Unlockable's variable, just like Level Select).
* "Stoppingtime" and "BPM" both accept floats, and are used for presentation stuff on the sound test.
* Ironically, we don't share a single field name with them. Such is the case of differing foci, though, and I expect they'll change their implementation to match (since this is necessary for a sound test).
* Change how S_AddSoundFx works to avoid iterating through all of them, and to allow cv_soundtest to only scroll through defined slots (instead of the infinite wall of thok sounds when scrolling to the left).
* Change V_DrawFixedPatch to allow scaling on two seperate axes.
* Now called "V_DrawStretchyFixedPatch".
* "V_DrawFixedPatch" is a macro to V_DrawStretchyFixedPatch now (same scale on both axes).
* Available to Lua under v.drawStretched!
* Even works in GL!
* Bugfix: Add SR_PLAYER to SOC's menutypes_list.
Stay tuned for the merge request, where I put the onus on the Music Team to finish this off...
2019-11-05 16:23:46 +00:00
|
|
|
UINT8 soundtestpage;
|
|
|
|
INT16 soundtestcond; // +ve for map, -ve for conditionset, 0 for already here
|
|
|
|
tic_t stoppingtics;
|
|
|
|
fixed_t bpm;
|
2020-02-07 08:53:56 +00:00
|
|
|
UINT32 loop_ms;/* override LOOPPOINT/LOOPMS */
|
Sound test is cool now!
https://cdn.discordapp.com/attachments/405336003239477249/641295998395613224/srb20042.gif
* Port MUSICDEFs from Kart.
* Safe to modify without modifying game, so we can put it in music.dta eventually.
* "Title", "AltTitle", "Authors" fields are self-evident.
* "Soundtestpage" and "Soundtestcond" are used to determine which sound test unlockable can play them (set with Unlockable's variable, just like Level Select).
* "Stoppingtime" and "BPM" both accept floats, and are used for presentation stuff on the sound test.
* Ironically, we don't share a single field name with them. Such is the case of differing foci, though, and I expect they'll change their implementation to match (since this is necessary for a sound test).
* Change how S_AddSoundFx works to avoid iterating through all of them, and to allow cv_soundtest to only scroll through defined slots (instead of the infinite wall of thok sounds when scrolling to the left).
* Change V_DrawFixedPatch to allow scaling on two seperate axes.
* Now called "V_DrawStretchyFixedPatch".
* "V_DrawFixedPatch" is a macro to V_DrawStretchyFixedPatch now (same scale on both axes).
* Available to Lua under v.drawStretched!
* Even works in GL!
* Bugfix: Add SR_PLAYER to SOC's menutypes_list.
Stay tuned for the merge request, where I put the onus on the Music Team to finish this off...
2019-11-05 16:23:46 +00:00
|
|
|
boolean allowed; // question marks or listenable on sound test?
|
|
|
|
struct musicdef_s *next;
|
|
|
|
} musicdef_t;
|
|
|
|
|
|
|
|
extern musicdef_t soundtestsfx;
|
|
|
|
extern musicdef_t *musicdefstart;
|
|
|
|
extern musicdef_t **soundtestdefs;
|
|
|
|
extern INT32 numsoundtestdefs;
|
|
|
|
extern UINT8 soundtestpage;
|
|
|
|
|
|
|
|
void S_LoadMusicDefs(UINT16 wadnum);
|
|
|
|
void S_InitMusicDefs(void);
|
|
|
|
|
|
|
|
boolean S_PrepareSoundTest(void);
|
|
|
|
|
2018-08-23 15:51:23 +00:00
|
|
|
//
|
2018-08-24 01:07:39 +00:00
|
|
|
// Music Seeking
|
|
|
|
//
|
|
|
|
|
2018-08-18 18:18:29 +00:00
|
|
|
// Get Length of Music
|
|
|
|
UINT32 S_GetMusicLength(void);
|
|
|
|
|
2018-08-19 00:19:44 +00:00
|
|
|
// Set LoopPoint of Music
|
|
|
|
boolean S_SetMusicLoopPoint(UINT32 looppoint);
|
|
|
|
|
|
|
|
// Get LoopPoint of Music
|
|
|
|
UINT32 S_GetMusicLoopPoint(void);
|
|
|
|
|
2018-08-15 05:38:06 +00:00
|
|
|
// Set Position of Music
|
2018-08-15 06:10:46 +00:00
|
|
|
boolean S_SetMusicPosition(UINT32 position);
|
2018-08-15 05:38:06 +00:00
|
|
|
|
|
|
|
// Get Position of Music
|
2018-08-15 06:10:46 +00:00
|
|
|
UINT32 S_GetMusicPosition(void);
|
2018-08-15 05:38:06 +00:00
|
|
|
|
2019-08-04 11:03:57 +00:00
|
|
|
//
|
|
|
|
// Music Stacking (Jingles)
|
|
|
|
//
|
|
|
|
|
|
|
|
typedef struct musicstack_s
|
|
|
|
{
|
|
|
|
char musname[7];
|
|
|
|
UINT16 musflags;
|
|
|
|
boolean looping;
|
|
|
|
UINT32 position;
|
|
|
|
tic_t tic;
|
|
|
|
UINT16 status;
|
|
|
|
lumpnum_t mlumpnum;
|
2019-10-26 19:02:45 +00:00
|
|
|
boolean noposition; // force music stack resuming from zero (like music_stack_noposition)
|
2019-08-04 11:03:57 +00:00
|
|
|
|
|
|
|
struct musicstack_s *prev;
|
|
|
|
struct musicstack_s *next;
|
|
|
|
} musicstack_t;
|
|
|
|
|
2020-05-12 17:40:51 +00:00
|
|
|
extern char music_stack_nextmusname[7];
|
|
|
|
extern boolean music_stack_noposition;
|
|
|
|
extern UINT32 music_stack_fadeout;
|
|
|
|
extern UINT32 music_stack_fadein;
|
2019-08-04 11:03:57 +00:00
|
|
|
|
|
|
|
void S_SetStackAdjustmentStart(void);
|
|
|
|
void S_AdjustMusicStackTics(void);
|
|
|
|
void S_RetainMusic(const char *mname, UINT16 mflags, boolean looping, UINT32 position, UINT16 status);
|
|
|
|
boolean S_RecallMusic(UINT16 status, boolean fromfirst);
|
|
|
|
|
2018-08-24 01:07:39 +00:00
|
|
|
//
|
|
|
|
// Music Playback
|
2018-08-23 15:51:23 +00:00
|
|
|
//
|
|
|
|
|
2020-11-17 12:14:45 +00:00
|
|
|
/* this is for the sake of the hook */
|
|
|
|
struct MusicChange {
|
|
|
|
char * newname;
|
|
|
|
UINT16 * mflags;
|
|
|
|
boolean * looping;
|
|
|
|
UINT32 * position;
|
|
|
|
UINT32 * prefadems;
|
|
|
|
UINT32 * fadeinms;
|
|
|
|
};
|
|
|
|
|
2016-01-08 03:48:20 +00:00
|
|
|
// Start music track, arbitrary, given its name, and set whether looping
|
|
|
|
// note: music flags 12 bits for tracknum (gme, other formats with more than one track)
|
|
|
|
// 13-15 aren't used yet
|
2014-03-15 16:59:03 +00:00
|
|
|
// and the last bit we ignore (internal game flag for resetting music on reload)
|
2018-09-17 03:10:23 +00:00
|
|
|
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms);
|
|
|
|
#define S_ChangeMusicInternal(a,b) S_ChangeMusicEx(a,0,b,0,0,0)
|
|
|
|
#define S_ChangeMusic(a,b,c) S_ChangeMusicEx(a,b,c,0,0,0)
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
// Stops the music.
|
|
|
|
void S_StopMusic(void);
|
|
|
|
|
|
|
|
// Stop and resume music, during game PAUSE.
|
2016-01-08 03:48:20 +00:00
|
|
|
void S_PauseAudio(void);
|
|
|
|
void S_ResumeAudio(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2018-08-24 01:07:39 +00:00
|
|
|
//
|
|
|
|
// Music Fading
|
|
|
|
//
|
2018-08-15 06:01:34 +00:00
|
|
|
|
2018-08-24 01:07:39 +00:00
|
|
|
void S_SetInternalMusicVolume(INT32 volume);
|
2018-08-19 20:19:48 +00:00
|
|
|
void S_StopFadingMusic(void);
|
2018-08-21 12:53:51 +00:00
|
|
|
boolean S_FadeMusicFromVolume(UINT8 target_volume, INT16 source_volume, UINT32 ms);
|
|
|
|
#define S_FadeMusic(a, b) S_FadeMusicFromVolume(a, -1, b)
|
2018-09-17 03:10:23 +00:00
|
|
|
#define S_FadeInChangeMusic(a,b,c,d) S_ChangeMusicEx(a,b,c,0,0,d)
|
2018-08-20 02:05:23 +00:00
|
|
|
boolean S_FadeOutStopMusic(UINT32 ms);
|
2018-08-19 20:19:48 +00:00
|
|
|
|
2014-03-15 16:59:03 +00:00
|
|
|
//
|
|
|
|
// Updates music & sounds
|
|
|
|
//
|
|
|
|
void S_UpdateSounds(void);
|
2019-11-25 23:16:17 +00:00
|
|
|
void S_UpdateClosedCaptions(void);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
2016-06-12 19:58:03 +00:00
|
|
|
FUNCMATH fixed_t S_CalculateSoundDistance(fixed_t px1, fixed_t py1, fixed_t pz1, fixed_t px2, fixed_t py2, fixed_t pz2);
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
void S_SetSfxVolume(INT32 volume);
|
2018-08-23 15:51:23 +00:00
|
|
|
void S_SetMusicVolume(INT32 digvolume, INT32 seqvolume);
|
|
|
|
#define S_SetDigMusicVolume(a) S_SetMusicVolume(a,-1)
|
|
|
|
#define S_SetMIDIMusicVolume(a) S_SetMusicVolume(-1,a)
|
|
|
|
#define S_InitMusicVolume() S_SetMusicVolume(-1,-1)
|
2014-03-15 16:59:03 +00:00
|
|
|
|
|
|
|
INT32 S_OriginPlaying(void *origin);
|
|
|
|
INT32 S_IdPlaying(sfxenum_t id);
|
|
|
|
INT32 S_SoundPlaying(void *origin, sfxenum_t id);
|
|
|
|
|
|
|
|
void S_StartSoundName(void *mo, const char *soundname);
|
|
|
|
|
|
|
|
void S_StopSoundByID(void *origin, sfxenum_t sfx_id);
|
|
|
|
void S_StopSoundByNum(sfxenum_t sfxnum);
|
|
|
|
|
|
|
|
#ifndef HW3SOUND
|
|
|
|
#define S_StartAttackSound S_StartSound
|
|
|
|
#define S_StartScreamSound S_StartSound
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|