- Removed some debug output from SBarInfo::ParseSBarInfo().

- Fixed: Heretic linetype translations included the wrong file.
- Removed all 2D sound positioning code from s_sound.cpp. Everything uses
  FMOD's 3D engine now.
- Removed all the channel selection code from s_sound.cpp. FMOD has code to
  handle this sort of thing, so let's use it.
- Replaced S_StopSoundID() with S_CheckSingular(). There is no longer a limit
  on the number of copies of a particular sound that can be playing at once,
  aside from Strife's special singular sounds. (Sorry, Heretic and Hexen.)
  Consequently, the SNDINFO $limit command is now ignored.
- Removed ATTN_SURROUND, since FMOD Ex doesn't exactly support it, and it
  only worked as intended on stereo speakers anyway.
- Cleaned out ancient crud from i_sound.cpp.


SVN r826 (trunk)
This commit is contained in:
Randy Heit 2008-03-21 05:13:59 +00:00
parent ca43ea7345
commit 10920ffe75
26 changed files with 938 additions and 1128 deletions

View file

@ -1,3 +1,18 @@
March 20, 2008
- Removed some debug output from SBarInfo::ParseSBarInfo().
- Fixed: Heretic linetype translations included the wrong file.
- Removed all 2D sound positioning code from s_sound.cpp. Everything uses
FMOD's 3D engine now.
- Removed all the channel selection code from s_sound.cpp. FMOD has code to
handle this sort of thing, so let's use it.
- Replaced S_StopSoundID() with S_CheckSingular(). There is no longer a limit
on the number of copies of a particular sound that can be playing at once,
aside from Strife's special singular sounds. (Sorry, Heretic and Hexen.)
Consequently, the SNDINFO $limit command is now ignored.
- Removed ATTN_SURROUND, since FMOD Ex doesn't exactly support it, and it
only worked as intended on stereo speakers anyway.
- Cleaned out ancient crud from i_sound.cpp.
March 20, 2008 (Changes by Graf Zahl) March 20, 2008 (Changes by Graf Zahl)
- Fixed: A_CustomMissile with aimmode 2 ignored spawnofs_xy. - Fixed: A_CustomMissile with aimmode 2 ignored spawnofs_xy.
- Changed savegame versioning so that the written version is never lower - Changed savegame versioning so that the written version is never lower

View file

@ -662,6 +662,7 @@ public:
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks) TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
fixed_t floorclip; // value to use for floor clipping fixed_t floorclip; // value to use for floor clipping
SWORD tid; // thing identifier SWORD tid; // thing identifier
BYTE SoundChans; // Bitfield indicating which sound channels are playing.
BYTE special; // special BYTE special; // special
int args[5]; // special arguments int args[5]; // special arguments

View file

@ -186,7 +186,7 @@ void DoVoiceAnnounce (const char *sound)
if (LastAnnounceTime == 0 || LastAnnounceTime <= level.time-5) if (LastAnnounceTime == 0 || LastAnnounceTime <= level.time-5)
{ {
LastAnnounceTime = level.time; LastAnnounceTime = level.time;
S_Sound (CHAN_VOICE, sound, 1, ATTN_SURROUND); S_Sound (CHAN_VOICE, sound, 1, ATTN_NONE);
} }
} }

View file

@ -599,8 +599,6 @@ void F_StartCast (void)
// //
void F_CastTicker (void) void F_CastTicker (void)
{ {
int atten;
if (--casttics > 0 && caststate != NULL) if (--casttics > 0 && caststate != NULL)
return; // not time to change state yet return; // not time to change state yet
@ -615,11 +613,7 @@ void F_CastTicker (void)
castnum = 0; castnum = 0;
if (castorder[castnum].info->SeeSound) if (castorder[castnum].info->SeeSound)
{ {
if (castorder[castnum].info->flags2 & MF2_BOSS) S_SoundID (CHAN_VOICE, castorder[castnum].info->SeeSound, 1, ATTN_NONE);
atten = ATTN_SURROUND;
else
atten = ATTN_NONE;
S_SoundID (CHAN_VOICE, castorder[castnum].info->SeeSound, 1, atten);
} }
caststate = castorder[castnum].info->SeeState; caststate = castorder[castnum].info->SeeState;
// [RH] Skip monsters that have been hacked to no longer have attack states // [RH] Skip monsters that have been hacked to no longer have attack states
@ -736,8 +730,7 @@ bool F_CastResponder (event_t* ev)
} }
else if (castorder[castnum].info->DeathSound) else if (castorder[castnum].info->DeathSound)
{ {
S_SoundID (CHAN_VOICE, castorder[castnum].info->DeathSound, 1, S_SoundID (CHAN_VOICE, castorder[castnum].info->DeathSound, 1, ATTN_NONE);
castnum == 15 || castnum == 14 ? ATTN_SURROUND : ATTN_NONE);
} }
} }

View file

@ -174,12 +174,12 @@ END_DEFAULTS
void A_BrainAwake (AActor *self) void A_BrainAwake (AActor *self)
{ {
// killough 3/26/98: only generates sound now // killough 3/26/98: only generates sound now
S_Sound (self, CHAN_VOICE, "brain/sight", 1, ATTN_SURROUND); S_Sound (self, CHAN_VOICE, "brain/sight", 1, ATTN_NONE);
} }
void A_BrainPain (AActor *self) void A_BrainPain (AActor *self)
{ {
S_Sound (self, CHAN_VOICE, "brain/pain", 1, ATTN_SURROUND); S_Sound (self, CHAN_VOICE, "brain/pain", 1, ATTN_NONE);
} }
static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z) static void BrainishExplosion (fixed_t x, fixed_t y, fixed_t z)
@ -206,7 +206,7 @@ void A_BrainScream (AActor *self)
BrainishExplosion (x, self->y - 320*FRACUNIT, BrainishExplosion (x, self->y - 320*FRACUNIT,
128 + (pr_brainscream() << (FRACBITS + 1))); 128 + (pr_brainscream() << (FRACBITS + 1)));
} }
S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_SURROUND); S_Sound (self, CHAN_VOICE, "brain/death", 1, ATTN_NONE);
} }
void A_BrainExplode (AActor *self) void A_BrainExplode (AActor *self)
@ -264,7 +264,7 @@ void A_BrainSpit (AActor *self)
spit->reactiontime /= spit->state->GetTics(); spit->reactiontime /= spit->state->GetTics();
} }
S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_SURROUND); S_Sound (self, CHAN_WEAPON, "brain/spit", 1, ATTN_NONE);
} }
} }

View file

@ -49,7 +49,7 @@ void AFourthWeaponPiece::PlayPickupSound (AActor *toucher)
if (TempFourthWeapon != NULL) if (TempFourthWeapon != NULL)
{ {
// Play the build-sound full volume for all players // Play the build-sound full volume for all players
S_Sound (toucher, CHAN_ITEM, "WeaponBuild", 1, ATTN_SURROUND); S_Sound (toucher, CHAN_ITEM, "WeaponBuild", 1, ATTN_NONE);
} }
else else
{ {

View file

@ -1497,7 +1497,7 @@ END_DEFAULTS
void APowerDamage::InitEffect( ) void APowerDamage::InitEffect( )
{ {
// Use sound channel 5 to avoid interference with other actions. // Use sound channel 5 to avoid interference with other actions.
if (Owner != NULL) S_SoundID(Owner, 5, SeeSound, 1.0f, ATTN_SURROUND); if (Owner != NULL) S_SoundID(Owner, 5, SeeSound, 1.0f, ATTN_NONE);
} }
//=========================================================================== //===========================================================================
@ -1509,7 +1509,7 @@ void APowerDamage::InitEffect( )
void APowerDamage::EndEffect( ) void APowerDamage::EndEffect( )
{ {
// Use sound channel 5 to avoid interference with other actions. // Use sound channel 5 to avoid interference with other actions.
if (Owner != NULL) S_SoundID(Owner, 5, DeathSound, 1.0f, ATTN_SURROUND); if (Owner != NULL) S_SoundID(Owner, 5, DeathSound, 1.0f, ATTN_NONE);
} }
//=========================================================================== //===========================================================================
@ -1532,7 +1532,7 @@ void APowerDamage::ModifyDamage(int damage, FName damageType, int &newdamage, bo
damage = newdamage = FixedMul(damage, *pdf); damage = newdamage = FixedMul(damage, *pdf);
if (*pdf > 0 && damage == 0) damage = newdamage = 1; // don't allow zero damage as result of an underflow if (*pdf > 0 && damage == 0) damage = newdamage = 1; // don't allow zero damage as result of an underflow
if (Owner != NULL && *pdf > FRACUNIT) S_SoundID(Owner, 5, ActiveSound, 1.0f, ATTN_SURROUND); if (Owner != NULL && *pdf > FRACUNIT) S_SoundID(Owner, 5, ActiveSound, 1.0f, ATTN_NONE);
} }
} }
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive); if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);
@ -1553,7 +1553,7 @@ END_DEFAULTS
void APowerProtection::InitEffect( ) void APowerProtection::InitEffect( )
{ {
// Use sound channel 5 to avoid interference with other actions. // Use sound channel 5 to avoid interference with other actions.
if (Owner != NULL) S_SoundID(Owner, 5, SeeSound, 1.0f, ATTN_SURROUND); if (Owner != NULL) S_SoundID(Owner, 5, SeeSound, 1.0f, ATTN_NONE);
} }
//=========================================================================== //===========================================================================
@ -1565,7 +1565,7 @@ void APowerProtection::InitEffect( )
void APowerProtection::EndEffect( ) void APowerProtection::EndEffect( )
{ {
// Use sound channel 5 to avoid interference with other actions. // Use sound channel 5 to avoid interference with other actions.
if (Owner != NULL) S_SoundID(Owner, 5, DeathSound, 1.0f, ATTN_SURROUND); if (Owner != NULL) S_SoundID(Owner, 5, DeathSound, 1.0f, ATTN_NONE);
} }
//=========================================================================== //===========================================================================
@ -1587,7 +1587,7 @@ void APowerProtection::ModifyDamage(int damage, FName damageType, int &newdamage
if (pdf == NULL) pdf = &def; if (pdf == NULL) pdf = &def;
damage = newdamage = FixedMul(damage, *pdf); damage = newdamage = FixedMul(damage, *pdf);
if (Owner != NULL && *pdf < FRACUNIT) S_SoundID(Owner, 5, ActiveSound, 1.0f, ATTN_SURROUND); if (Owner != NULL && *pdf < FRACUNIT) S_SoundID(Owner, 5, ActiveSound, 1.0f, ATTN_NONE);
} }
} }
if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive); if (Inventory != NULL) Inventory->ModifyDamage(damage, damageType, newdamage, passive);

View file

@ -998,7 +998,7 @@ void AInventory::PlayPickupSound (AActor *toucher)
S_SoundID (toucher, CHAN_PICKUP, PickupSound, 1, S_SoundID (toucher, CHAN_PICKUP, PickupSound, 1,
(ItemFlags & IF_FANCYPICKUPSOUND) && (ItemFlags & IF_FANCYPICKUPSOUND) &&
(toucher == NULL || toucher->CheckLocalView (consoleplayer)) (toucher == NULL || toucher->CheckLocalView (consoleplayer))
? ATTN_SURROUND : ATTN_NORM); ? ATTN_NONE : ATTN_NORM);
} }
//=========================================================================== //===========================================================================

View file

@ -87,7 +87,6 @@ void SBarInfo::Load()
void SBarInfo::ParseSBarInfo(int lump) void SBarInfo::ParseSBarInfo(int lump)
{ {
gameType = gameinfo.gametype; gameType = gameinfo.gametype;
Printf("%d=%d", gameinfo.gametype, GAME_Any);
bool baseSet = false; bool baseSet = false;
FScanner sc(lump, Wads.GetLumpFullName(lump)); FScanner sc(lump, Wads.GetLumpFullName(lump));
sc.SetCMode(true); sc.SetCMode(true);

View file

@ -1951,7 +1951,7 @@ void M_QuitResponse(int ch)
{ {
if (gameinfo.quitSound) if (gameinfo.quitSound)
{ {
S_Sound (CHAN_VOICE, gameinfo.quitSound, 1, ATTN_SURROUND); S_Sound (CHAN_VOICE, gameinfo.quitSound, 1, ATTN_NONE);
I_WaitVBL (105); I_WaitVBL (105);
} }
} }

View file

@ -102,7 +102,6 @@ EXTERN_CVAR (Int, crosshair)
EXTERN_CVAR (Bool, freelook) EXTERN_CVAR (Bool, freelook)
EXTERN_CVAR (Int, snd_buffersize) EXTERN_CVAR (Int, snd_buffersize)
EXTERN_CVAR (Int, snd_samplerate) EXTERN_CVAR (Int, snd_samplerate)
EXTERN_CVAR (Bool, snd_3d)
EXTERN_CVAR (Bool, snd_waterreverb) EXTERN_CVAR (Bool, snd_waterreverb)
EXTERN_CVAR (Int, sv_smartaim) EXTERN_CVAR (Int, sv_smartaim)
@ -1143,7 +1142,7 @@ static value_t SampleRates[] =
{ 32000.f, "32000 Hz" }, { 32000.f, "32000 Hz" },
{ 44100.f, "44100 Hz" }, { 44100.f, "44100 Hz" },
{ 48000.f, "48000 Hz" }, { 48000.f, "48000 Hz" },
{ 65535.f, "65535 Hz" } { 96000.f, "96000 Hz" }
}; };
static value_t BufferSizes[] = static value_t BufferSizes[] =
@ -1175,11 +1174,10 @@ static menuitem_t SoundItems[] =
{ discrete, "Flip Stereo Channels", {&snd_flipstereo}, {2.0}, {0.0}, {0.0}, {OnOff} }, { discrete, "Flip Stereo Channels", {&snd_flipstereo}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ discrete, "Random Pitch Variations", {&snd_pitched}, {2.0}, {0.0}, {0.0}, {OnOff} }, { discrete, "Random Pitch Variations", {&snd_pitched}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ more, "Activate below settings", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)MakeSoundChanges} }, { more, "Activate below settings", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)MakeSoundChanges} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ discrete, "Sample Rate", {&snd_samplerate}, {8.0}, {0.0}, {0.0}, {SampleRates} }, { discrete, "Sample Rate", {&snd_samplerate}, {8.0}, {0.0}, {0.0}, {SampleRates} },
{ discrete, "Buffer Size", {&snd_buffersize}, {11.0}, {0.0}, {0.0}, {BufferSizes} }, { discrete, "Buffer Size", {&snd_buffersize}, {11.0}, {0.0}, {0.0}, {BufferSizes} },
{ discrete, "3D Sound", {&snd_3d}, {2.0}, {0.0}, {0.0}, {OnOff} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ more, "Advanced Options", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)AdvSoundOptions} }, { more, "Advanced Options", {NULL}, {0.0}, {0.0}, {0.0}, {(value_t *)AdvSoundOptions} },

View file

@ -1642,7 +1642,7 @@ void A_Look (AActor *actor)
{ {
if (actor->flags2 & MF2_BOSS) if (actor->flags2 & MF2_BOSS)
{ // full volume { // full volume
S_SoundID (actor, CHAN_VOICE, actor->SeeSound, 1, ATTN_SURROUND); S_SoundID (actor, CHAN_VOICE, actor->SeeSound, 1, ATTN_NONE);
} }
else else
{ {
@ -2396,7 +2396,7 @@ void A_Scream (AActor *actor)
if (actor->flags2 & MF2_BOSS) if (actor->flags2 & MF2_BOSS)
{ {
// full volume // full volume
S_SoundID (actor, CHAN_VOICE, actor->DeathSound, 1, ATTN_SURROUND); S_SoundID (actor, CHAN_VOICE, actor->DeathSound, 1, ATTN_NONE);
} }
else else
{ {

View file

@ -867,7 +867,7 @@ void A_LookEx (AActor *actor)
{ {
if (flags & LOF_FULLVOLSEESOUND) if (flags & LOF_FULLVOLSEESOUND)
{ // full volume { // full volume
S_SoundID (actor, CHAN_VOICE, actor->SeeSound, 1, ATTN_SURROUND); S_SoundID (actor, CHAN_VOICE, actor->SeeSound, 1, ATTN_NONE);
} }
else else
{ {

View file

@ -433,12 +433,25 @@ int S_AddSoundLump (const char *logicalname, int lump)
{ {
sfxinfo_t newsfx; sfxinfo_t newsfx;
memset (&newsfx.lumpnum, 0, sizeof(newsfx)-sizeof(newsfx.name)); newsfx.data = NULL;
newsfx.name = logicalname; newsfx.name = logicalname;
newsfx.lumpnum = lump; newsfx.lumpnum = lump;
newsfx.link = sfxinfo_t::NO_LINK; newsfx.next = 0;
newsfx.index = 0;
newsfx.frequency = 0;
newsfx.PitchMask = CurrentPitchMask; newsfx.PitchMask = CurrentPitchMask;
newsfx.MaxChannels = 2; newsfx.bRandomHeader = false;
newsfx.bPlayerReserve = false;
newsfx.bForce11025 = false;
newsfx.bForce22050 = false;
newsfx.bLoadRAW = false;
newsfx.bPlayerCompat = false;
newsfx.b16bit = false;
newsfx.bUsed = false;
newsfx.bSingular = false;
newsfx.bTentative = false;
newsfx.link = sfxinfo_t::NO_LINK;
return (int)S_sfx.Push (newsfx); return (int)S_sfx.Push (newsfx);
} }
@ -758,10 +771,10 @@ static void S_ClearSoundData()
if (GSnd != NULL) if (GSnd != NULL)
{ {
GSnd->StopAllChannels(); S_StopAllChannels();
for (i = 0; i < S_sfx.Size(); ++i) for (i = 0; i < S_sfx.Size(); ++i)
{ {
GSnd->UnloadSound (&S_sfx[i]); GSnd->UnloadSound(&S_sfx[i]);
} }
} }
S_sfx.Clear(); S_sfx.Clear();
@ -1087,15 +1100,12 @@ static void S_AddSNDINFO (int lump)
break; break;
case SI_Limit: { case SI_Limit: {
// $limit <logical name> <max channels> // $limit <logical name> <max channels> -- deprecated and ignored
int sfx; int sfx;
sc.MustGetString (); sc.MustGetString ();
sfx = S_FindSoundTentative (sc.String); sfx = S_FindSoundTentative (sc.String);
sc.MustGetNumber (); sc.MustGetNumber ();
//S_sfx[sfx].MaxChannels = clamp<BYTE> (sc.Number, 0, 255);
//Can't use clamp because of GCC bugs
S_sfx[sfx].MaxChannels = MIN (MAX (sc.Number, 0), 255);
} }
break; break;
@ -1858,20 +1868,15 @@ void AAmbientSound::Activate (AActor *activator)
if (!bActive) if (!bActive)
{ {
if (!(amb->type & 3) && !amb->periodmin) if ((amb->type & 3) == 0 && amb->periodmin == 0)
{ {
int sndnum = S_FindSound (amb->sound); int sndnum = S_FindSound(amb->sound);
if (sndnum == 0) if (sndnum == 0)
{ {
Destroy (); Destroy ();
return; return;
} }
sfxinfo_t *sfx = &S_sfx[sndnum]; amb->periodmin = Scale(GSnd->GetMSLength(&S_sfx[sndnum]), TICRATE, 1000);
// Make sure the sound has been loaded so we know how long it is
if (!sfx->data && GSnd != NULL)
GSnd->LoadSound (sfx);
amb->periodmin = (sfx->ms * TICRATE) / 1000;
} }
NextCheck = gametic; NextCheck = gametic;

File diff suppressed because it is too large Load diff

View file

@ -32,15 +32,17 @@ class FScanner;
// //
struct sfxinfo_t struct sfxinfo_t
{ {
FString name; // [RH] Sound name defined in SNDINFO
short lumpnum; // lump number of sfx
BYTE PitchMask;
BYTE MaxChannels;
// Next field is for use by the system sound interface. // Next field is for use by the system sound interface.
// A non-null data means the sound has been loaded. // A non-null data means the sound has been loaded.
void* data; void *data;
FString name; // [RH] Sound name defined in SNDINFO
int lumpnum; // lump number of sfx
unsigned int next, index; // [RH] For hashing
unsigned int frequency; // [RH] Preferred playback rate
BYTE PitchMask;
WORD bRandomHeader:1; WORD bRandomHeader:1;
WORD bPlayerReserve:1; WORD bPlayerReserve:1;
@ -54,18 +56,37 @@ struct sfxinfo_t
WORD bTentative:1; WORD bTentative:1;
WORD link; WORD link;
enum { NO_LINK = 0xffff }; enum { NO_LINK = 0xffff };
unsigned int ms; // [RH] length of sfx in milliseconds
unsigned int next, index; // [RH] For hashing
unsigned int frequency; // [RH] Preferred playback rate
unsigned int length; // [RH] Length of the sound in samples
}; };
// the complete set of sound effects // the complete set of sound effects
extern TArray<sfxinfo_t> S_sfx; extern TArray<sfxinfo_t> S_sfx;
// Information about one playing sound.
struct FSoundChan
{
void *SysChannel;// Channel information from the system interface.
FSoundChan *NextChan; // Next channel in this list.
FSoundChan **PrevChan; // Previous channel in this list.
AActor *Mover; // Used for velocity.
fixed_t *Pt; // Origin of sound.
sfxinfo_t *SfxInfo; // Sound information.
fixed_t X,Y,Z; // Origin if Mover is NULL.
int SoundID; // Sound ID of playing sound
int OrgID; // Sound ID of sound used to start this channel
float Volume;
BYTE EntChannel; // Actor's sound channel.
bool Loop;
bool Is3D;
bool ConstZ;
};
FSoundChan *S_GetChannel(void *syschan);
void S_ReturnChannel(FSoundChan *chan);
void S_LinkChannel(FSoundChan *chan, FSoundChan **head);
void S_UnlinkChannel(FSoundChan *chan);
// Initializes sound stuff, including volume // Initializes sound stuff, including volume
// Sets channels, SFX and music volume, // Sets channels, SFX and music volume,
// allocates channel buffer, sets S_sfx lookup. // allocates channel buffer, sets S_sfx lookup.
@ -108,7 +129,7 @@ void S_LoopedSoundID (fixed_t *pt, int channel, int sfxid, float volume, int att
// CHAN_VOICE is for oof, sight, or other voice sounds // CHAN_VOICE is for oof, sight, or other voice sounds
// CHAN_ITEM is for small things and item pickup // CHAN_ITEM is for small things and item pickup
// CHAN_BODY is for generic body sounds // CHAN_BODY is for generic body sounds
// CHAN_PICKUP is can optionally be set as a local sound only for "compatibility" // CHAN_PICKUP can optionally be set as a local sound only for "compatibility"
#define CHAN_AUTO 0 #define CHAN_AUTO 0
#define CHAN_WEAPON 1 #define CHAN_WEAPON 1
@ -127,14 +148,12 @@ void S_LoopedSoundID (fixed_t *pt, int channel, int sfxid, float volume, int att
#define ATTN_NORM 1 #define ATTN_NORM 1
#define ATTN_IDLE 2 #define ATTN_IDLE 2
#define ATTN_STATIC 3 // diminish very rapidly with distance #define ATTN_STATIC 3 // diminish very rapidly with distance
#define ATTN_SURROUND 4 // like ATTN_NONE, but plays in surround sound
int S_PickReplacement (int refid); int S_PickReplacement (int refid);
void S_CacheRandomSound (sfxinfo_t *sfx); void S_CacheRandomSound (sfxinfo_t *sfx);
// [RH] From Hexen. // Checks if a copy of this sound is already playing.
// Prevents too many of the same sound from playing simultaneously. bool S_CheckSingular (int sound_id);
bool S_StopSoundID (int sound_id, int priority, int limit, bool singular, fixed_t x, fixed_t y);
// Stops a sound emanating from one of an entity's channels // Stops a sound emanating from one of an entity's channels
void S_StopSound (AActor *ent, int channel); void S_StopSound (AActor *ent, int channel);

View file

@ -64,7 +64,11 @@ extern HWND Window;
#define PITCH(freq,pitch) (snd_pitched ? ((freq)*(pitch))/128.f : float(freq)) #define PITCH(freq,pitch) (snd_pitched ? ((freq)*(pitch))/128.f : float(freq))
// Just some extra for music and whatever // Just some extra for music and whatever
#define NUM_EXTRA_SOFTWARE_CHANNELS 8 #define NUM_EXTRA_SOFTWARE_CHANNELS 1
#define FIXED2FLOAT(x) ((x)/65536.f)
#define MAX_CHANNELS 256
#define ERRCHECK(x) #define ERRCHECK(x)
@ -104,7 +108,6 @@ EXTERN_CVAR (Int, snd_channels)
ReverbContainer *ForcedEnvironment; ReverbContainer *ForcedEnvironment;
CVAR (Int, snd_driver, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Int, snd_driver, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, snd_3d, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, snd_waterreverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, snd_waterreverb, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (String, snd_resampler, "Linear", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (String, snd_resampler, "Linear", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (String, snd_speakermode, "Auto", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (String, snd_speakermode, "Auto", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -244,9 +247,11 @@ class FMODStreamCapsule : public SoundStream
{ {
public: public:
FMODStreamCapsule(FMOD::Sound *stream, FMODSoundRenderer *owner) FMODStreamCapsule(FMOD::Sound *stream, FMODSoundRenderer *owner)
: Owner(owner), Stream(stream), Channel(NULL), DSP(NULL), : Owner(owner), Stream(NULL), Channel(NULL), DSP(NULL),
UserData(NULL), Callback(NULL) UserData(NULL), Callback(NULL)
{} {
SetStream(stream);
}
FMODStreamCapsule(void *udata, SoundStreamCallback callback, FMODSoundRenderer *owner) FMODStreamCapsule(void *udata, SoundStreamCallback callback, FMODSoundRenderer *owner)
: Owner(owner), Stream(NULL), Channel(NULL), DSP(NULL), : Owner(owner), Stream(NULL), Channel(NULL), DSP(NULL),
@ -263,7 +268,15 @@ public:
void SetStream(FMOD::Sound *stream) void SetStream(FMOD::Sound *stream)
{ {
float frequency;
Stream = stream; Stream = stream;
// As this interface is for music, make it super-high priority.
if (FMOD_OK == stream->getDefaults(&frequency, NULL, NULL, NULL))
{
stream->setDefaults(frequency, 1, 0, 0);
}
} }
bool Play(bool looping, float volume, bool normalize) bool Play(bool looping, float volume, bool normalize)
@ -278,14 +291,12 @@ public:
} }
Channel->setChannelGroup(Owner->MusicGroup); Channel->setChannelGroup(Owner->MusicGroup);
Channel->setVolume(volume); Channel->setVolume(volume);
if (Owner->Sound3D) // Ensure reverb is disabled.
{ // Ensure reverb is disabled when using 3D sound. FMOD_REVERB_CHANNELPROPERTIES reverb;
FMOD_REVERB_CHANNELPROPERTIES reverb; if (FMOD_OK == Channel->getReverbProperties(&reverb))
if (FMOD_OK == Channel->getReverbProperties(&reverb)) {
{ reverb.Room = -10000;
reverb.Room = -10000; Channel->setReverbProperties(&reverb);
Channel->setReverbProperties(&reverb);
}
} }
if (normalize) if (normalize)
{ // Attach a normalizer DSP unit to the channel. { // Attach a normalizer DSP unit to the channel.
@ -402,7 +413,7 @@ private:
FMODSoundRenderer::FMODSoundRenderer() FMODSoundRenderer::FMODSoundRenderer()
{ {
Init(); InitSuccess = Init();
} }
FMODSoundRenderer::~FMODSoundRenderer() FMODSoundRenderer::~FMODSoundRenderer()
@ -412,9 +423,15 @@ FMODSoundRenderer::~FMODSoundRenderer()
bool FMODSoundRenderer::IsValid() bool FMODSoundRenderer::IsValid()
{ {
return Sys != NULL; return InitSuccess;
} }
//==========================================================================
//
// FMODSoundRenderer :: Init
//
//==========================================================================
bool FMODSoundRenderer::Init() bool FMODSoundRenderer::Init()
{ {
FMOD_RESULT result; FMOD_RESULT result;
@ -426,8 +443,6 @@ bool FMODSoundRenderer::Init()
int eval; int eval;
ChannelMap = NULL;
NumChannels = 0;
SFXPaused = false; SFXPaused = false;
MusicGroup = NULL; MusicGroup = NULL;
SfxGroup = NULL; SfxGroup = NULL;
@ -445,8 +460,10 @@ bool FMODSoundRenderer::Init()
if (version < FMOD_VERSION) if (version < FMOD_VERSION)
{ {
Printf ("Error! You are using an old version of FMOD %08x.\n" Printf (" "TEXTCOLOR_ORANGE"Error! You are using an old version of FMOD (%x.%02x.%02x).\n"
"This program requires %08x\n", version, FMOD_VERSION); " "TEXTCOLOR_ORANGE"This program requires version %x.%02x.%02x\n",
version >> 16, (version >> 8) & 255, version & 255,
FMOD_VERSION >> 16, (FMOD_VERSION >> 8) & 255, FMOD_VERSION & 255);
return false; return false;
} }
@ -534,13 +551,13 @@ bool FMODSoundRenderer::Init()
{ {
initflags |= FMOD_INIT_ENABLE_DSPNET; initflags |= FMOD_INIT_ENABLE_DSPNET;
} }
result = Sys->init(100, initflags, 0); result = Sys->init(MAX_CHANNELS, initflags, 0);
if (result == FMOD_ERR_OUTPUT_CREATEBUFFER) if (result == FMOD_ERR_OUTPUT_CREATEBUFFER)
{ // The speaker mode selected isn't supported by this soundcard. Switch it back to stereo. { // The speaker mode selected isn't supported by this soundcard. Switch it back to stereo.
result = Sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO); result = Sys->setSpeakerMode(FMOD_SPEAKERMODE_STEREO);
ERRCHECK(result); ERRCHECK(result);
result = Sys->init(100, FMOD_INIT_NORMAL, 0); result = Sys->init(MAX_CHANNELS, initflags, 0);
ERRCHECK(result); ERRCHECK(result);
} }
if (result != FMOD_OK) if (result != FMOD_OK)
@ -563,39 +580,39 @@ bool FMODSoundRenderer::Init()
result = SPC_CreateCodec(Sys); result = SPC_CreateCodec(Sys);
if (snd_3d) float rolloff_factor;
{
float rolloff_factor;
Sound3D = true; if (gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Strife)
if (gameinfo.gametype == GAME_Doom || gameinfo.gametype == GAME_Strife) {
{ rolloff_factor = 1.7f;
rolloff_factor = 1.7f; }
} else if (gameinfo.gametype == GAME_Heretic)
else if (gameinfo.gametype == GAME_Heretic) {
{ rolloff_factor = 1.24f;
rolloff_factor = 1.24f;
}
else
{
rolloff_factor = 0.96f;
}
Sys->set3DSettings(1.f, 100.f, rolloff_factor);
} }
else else
{ {
Sound3D = false; rolloff_factor = 0.96f;
} }
Sys->set3DSettings(1.f, 100.f, rolloff_factor);
snd_sfxvolume.Callback (); snd_sfxvolume.Callback ();
return true; return true;
} }
//==========================================================================
//
// FMODSoundRenderer :: Shutdown
//
//==========================================================================
void FMODSoundRenderer::Shutdown() void FMODSoundRenderer::Shutdown()
{ {
if (Sys != NULL) if (Sys != NULL)
{ {
unsigned int i; unsigned int i;
S_StopAllChannels();
if (MusicGroup != NULL) if (MusicGroup != NULL)
{ {
MusicGroup->release(); MusicGroup->release();
@ -611,15 +628,9 @@ void FMODSoundRenderer::Shutdown()
SfxGroup->release(); SfxGroup->release();
SfxGroup = NULL; SfxGroup = NULL;
} }
if (ChannelMap)
{
delete[] ChannelMap;
ChannelMap = NULL;
}
NumChannels = 0;
// Free all loaded samples // Free all loaded samples
for (i = 0; i < S_sfx.Size (); i++) for (i = 0; i < S_sfx.Size(); i++)
{ {
if (S_sfx[i].data != NULL) if (S_sfx[i].data != NULL)
{ {
@ -633,6 +644,12 @@ void FMODSoundRenderer::Shutdown()
} }
} }
//==========================================================================
//
// FMODSoundRenderer :: PrintStatus
//
//==========================================================================
void FMODSoundRenderer::PrintStatus() void FMODSoundRenderer::PrintStatus()
{ {
FMOD_OUTPUTTYPE output; FMOD_OUTPUTTYPE output;
@ -675,9 +692,14 @@ void FMODSoundRenderer::PrintStatus()
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: "TEXTCOLOR_GREEN"%d\n", numoutputchannels); Printf (TEXTCOLOR_LIGHTBLUE "Software mixer channels: "TEXTCOLOR_GREEN"%d\n", numoutputchannels);
Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(ResamplerNames, resampler)); Printf (TEXTCOLOR_LIGHTBLUE "Software mixer resampler: "TEXTCOLOR_GREEN"%s\n", Enum_NameForNum(ResamplerNames, resampler));
} }
Printf("Using 3D sound: "TEXTCOLOR_GREEN"%s\n", Sound3D ? "yes" : "no");
} }
//==========================================================================
//
// FMODSoundRenderer :: DumpDriverCaps
//
//==========================================================================
void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency) void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int maxfrequency)
{ {
Printf (TEXTCOLOR_OLIVE " Min. frequency: "TEXTCOLOR_GREEN"%d\n", minfrequency); Printf (TEXTCOLOR_OLIVE " Min. frequency: "TEXTCOLOR_GREEN"%d\n", minfrequency);
@ -708,6 +730,12 @@ void FMODSoundRenderer::DumpDriverCaps(FMOD_CAPS caps, int minfrequency, int max
if (caps & FMOD_CAPS_REVERB_LIMITED) Printf("TEXTCOLOR_OLIVE Limited reverb\n"); if (caps & FMOD_CAPS_REVERB_LIMITED) Printf("TEXTCOLOR_OLIVE Limited reverb\n");
} }
//==========================================================================
//
// FMODSoundRenderer :: PrintDriversList
//
//==========================================================================
void FMODSoundRenderer::PrintDriversList() void FMODSoundRenderer::PrintDriversList()
{ {
int numdrivers; int numdrivers;
@ -726,6 +754,12 @@ void FMODSoundRenderer::PrintDriversList()
} }
} }
//==========================================================================
//
// FMODSoundRenderer :: GatherStats
//
//==========================================================================
FString FMODSoundRenderer::GatherStats() FString FMODSoundRenderer::GatherStats()
{ {
int channels; int channels;
@ -742,12 +776,24 @@ FString FMODSoundRenderer::GatherStats()
return out; return out;
} }
//==========================================================================
//
// FMODSoundRenderer :: MovieDisableSound
//
//==========================================================================
void FMODSoundRenderer::MovieDisableSound() void FMODSoundRenderer::MovieDisableSound()
{ {
I_ShutdownMusic(); I_ShutdownMusic();
Shutdown(); Shutdown();
} }
//==========================================================================
//
// FMODSoundRenderer :: MovieResumeSound
//
//==========================================================================
void FMODSoundRenderer::MovieResumeSound() void FMODSoundRenderer::MovieResumeSound()
{ {
Init(); Init();
@ -755,34 +801,35 @@ void FMODSoundRenderer::MovieResumeSound()
S_RestartMusic(); S_RestartMusic();
} }
//==========================================================================
//
// FMODSoundRenderer :: SetSfxVolume
//
//==========================================================================
void FMODSoundRenderer::SetSfxVolume(float volume) void FMODSoundRenderer::SetSfxVolume(float volume)
{ {
SfxGroup->setVolume(volume); SfxGroup->setVolume(volume);
} }
//==========================================================================
//
// FMODSoundRenderer :: SetMusicVolume
//
//==========================================================================
void FMODSoundRenderer::SetMusicVolume(float volume) void FMODSoundRenderer::SetMusicVolume(float volume)
{ {
MusicGroup->setVolume(volume); MusicGroup->setVolume(volume);
} }
int FMODSoundRenderer::GetNumChannels() //==========================================================================
{ //
int chancount; // FMODSoundRenderer :: CreateStream
//
if (FMOD_OK == Sys->getSoftwareChannels(&chancount)) // Creates a streaming sound that receives PCM data through a callback.
{ //
chancount = MIN<int>(snd_channels, chancount - NUM_EXTRA_SOFTWARE_CHANNELS); //==========================================================================
}
ChannelMap = new ChanMap[chancount];
for (int i = 0; i < chancount; i++)
{
ChannelMap[i].soundID = -1;
}
NumChannels = chancount;
return chancount;
}
SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata)
{ {
@ -836,6 +883,14 @@ SoundStream *FMODSoundRenderer::CreateStream (SoundStreamCallback callback, int
return capsule; return capsule;
} }
//==========================================================================
//
// FMODSoundRenderer :: OpenStream
//
// Creates a streaming sound from a file on disk.
//
//==========================================================================
SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int flags, int offset, int length) SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int flags, int offset, int length)
{ {
FMOD_MODE mode; FMOD_MODE mode;
@ -862,15 +917,14 @@ SoundStream *FMODSoundRenderer::OpenStream(const char *filename_or_data, int fla
return NULL; return NULL;
} }
//==========================================================================
// //
// vol range is 0-255 // FMODSoundRenderer :: StartSound
// sep range is 0-255, -1 for surround, -2 for full vol middle
// //
long FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, float sep, int pitch, int channel, bool looping, bool pausable) //==========================================================================
{
if (!ChannelMap)
return 0;
FSoundChan *FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, int pitch, bool looping, bool pausable)
{
int id = int(sfx - &S_sfx[0]); int id = int(sfx - &S_sfx[0]);
FMOD_RESULT result; FMOD_RESULT result;
FMOD_MODE mode; FMOD_MODE mode;
@ -884,43 +938,38 @@ long FMODSoundRenderer::StartSound(sfxinfo_t *sfx, float vol, float sep, int pit
{ {
result = chan->getMode(&mode); result = chan->getMode(&mode);
if (Sound3D) if (result != FMOD_OK)
{ // Make 2D sounds head relative. {
FMOD_VECTOR zero = { 0, 0, 0 }; assert(0);
mode = (mode & ~FMOD_3D_WORLDRELATIVE) | (FMOD_3D_HEADRELATIVE); mode = FMOD_SOFTWARE;
chan->set3DAttributes(&zero, &zero);
} }
mode = (mode & ~FMOD_3D) | FMOD_2D;
if (looping) if (looping)
{ {
mode |= FMOD_LOOP_NORMAL; mode = (mode & ~FMOD_LOOP_OFF) | FMOD_LOOP_NORMAL;
}
if (result == FMOD_OK)
{
chan->setMode(mode);
} }
chan->setMode(mode);
chan->setChannelGroup((pausable && !SFXPaused) ? PausableSfx : SfxGroup); chan->setChannelGroup((pausable && !SFXPaused) ? PausableSfx : SfxGroup);
chan->setFrequency(freq); chan->setFrequency(freq);
chan->setVolume(vol); chan->setVolume(vol);
chan->setPan(sep);
chan->setPaused(false); chan->setPaused(false);
ChannelMap[channel].channelID = chan; return CommonChannelSetup(chan, false);
ChannelMap[channel].soundID = id;
ChannelMap[channel].bIsLooping = looping;
return channel + 1;
} }
DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result);
return 0; return 0;
} }
long FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, int pitch, int channel, //==========================================================================
//
// FMODSoundRenderer :: StartSound3D
//
//==========================================================================
FSoundChan *FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, int pitch,
bool looping, float pos[3], float vel[3], bool pausable) bool looping, float pos[3], float vel[3], bool pausable)
{ {
if (!Sound3D || !ChannelMap)
return 0;
int id = int(sfx - &S_sfx[0]); int id = int(sfx - &S_sfx[0]);
FMOD_RESULT result; FMOD_RESULT result;
FMOD_MODE mode; FMOD_MODE mode;
@ -932,51 +981,110 @@ long FMODSoundRenderer::StartSound3D(sfxinfo_t *sfx, float vol, int pitch, int c
result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan); result = Sys->playSound(FMOD_CHANNEL_FREE, (FMOD::Sound *)sfx->data, true, &chan);
if (FMOD_OK == result) if (FMOD_OK == result)
{ {
result = chan->getMode(&mode);
if (result != FMOD_OK)
{
mode = FMOD_3D | FMOD_SOFTWARE;
}
if (looping) if (looping)
{ {
result = chan->getMode(&mode); mode = (mode & ~FMOD_LOOP_OFF) | FMOD_LOOP_NORMAL;
if (result == FMOD_OK) }
// If this sound is played at the same coordinates as the listener,
// make it head relative.
if (players[consoleplayer].camera != NULL)
{
float cpos[3];
cpos[0] = FIXED2FLOAT(players[consoleplayer].camera->x);
cpos[2] = FIXED2FLOAT(players[consoleplayer].camera->y);
cpos[1] = FIXED2FLOAT(players[consoleplayer].camera->z);
if (cpos[0] == pos[0] && cpos[1] == pos[1] && cpos[2] == pos[2])
{ {
mode |= FMOD_LOOP_NORMAL; mode = (mode & ~FMOD_3D_WORLDRELATIVE) | FMOD_3D_HEADRELATIVE;
chan->setMode(mode); pos[0] = 0;
pos[1] = 0;
pos[2] = 0;
} }
} }
chan->setMode(mode);
chan->setChannelGroup((pausable && !SFXPaused) ? PausableSfx : SfxGroup); chan->setChannelGroup((pausable && !SFXPaused) ? PausableSfx : SfxGroup);
chan->setFrequency(freq); chan->setFrequency(freq);
chan->setVolume(vol); chan->setVolume(vol);
chan->set3DAttributes((FMOD_VECTOR *)pos, (FMOD_VECTOR *)vel); chan->set3DAttributes((FMOD_VECTOR *)pos, (FMOD_VECTOR *)vel);
chan->setPaused(false); chan->setPaused(false);
ChannelMap[channel].channelID = chan; return CommonChannelSetup(chan, true);
ChannelMap[channel].soundID = id;
ChannelMap[channel].bIsLooping = looping;
return channel + 1;
} }
DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result); DPrintf ("Sound %s failed to play: %d\n", sfx->name.GetChars(), result);
return 0; return 0;
} }
void FMODSoundRenderer::StopSound(long handle) //==========================================================================
//
// FMODSoundRenderer :: CommonChannelSetup
//
// Assign an end callback to the channel and allocates a game channel for
// it.
//
//==========================================================================
FSoundChan *FMODSoundRenderer::CommonChannelSetup(FMOD::Channel *chan, bool is3d)
{ {
if (!handle || !ChannelMap) FSoundChan *schan = S_GetChannel(chan);
chan->setUserData(schan);
chan->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, ChannelEndCallback, 0);
schan->Is3D = is3d;
return schan;
}
//==========================================================================
//
// FMODSoundRenderer :: StopSound
//
//==========================================================================
void FMODSoundRenderer::StopSound(FSoundChan *chan)
{
if (chan == NULL)
return; return;
handle--; if (chan->SysChannel != NULL)
if (ChannelMap[handle].soundID != -1)
{ {
ChannelMap[handle].channelID->stop(); ((FMOD::Channel *)chan->SysChannel)->setCallback(FMOD_CHANNEL_CALLBACKTYPE_END, 0, 0);
ChannelMap[handle].soundID = -1; ((FMOD::Channel *)chan->SysChannel)->stop();
} }
S_ReturnChannel(chan);
} }
void FMODSoundRenderer::StopAllChannels() //==========================================================================
//
// FMODSoundRenderer :: ChannelEndCallback static
//
// Called when the channel finishes playing.
//
//==========================================================================
FMOD_RESULT F_CALLBACK FMODSoundRenderer::ChannelEndCallback
(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type,
int cmd, unsigned int data1, unsigned int data2)
{ {
for (int i = 1; i <= NumChannels; ++i) assert(type == FMOD_CHANNEL_CALLBACKTYPE_END);
FMOD::Channel *chan = (FMOD::Channel *)channel;
FSoundChan *schan;
if (chan->getUserData((void **)&schan) == FMOD_OK && schan != NULL)
{ {
StopSound(i); S_ReturnChannel(schan);
} }
return FMOD_OK;
} }
//==========================================================================
//
// FMODSoundRenderer :: SetSfxPaused
//
//==========================================================================
void FMODSoundRenderer::SetSfxPaused(bool paused) void FMODSoundRenderer::SetSfxPaused(bool paused)
{ {
@ -987,119 +1095,151 @@ void FMODSoundRenderer::SetSfxPaused(bool paused)
} }
} }
bool FMODSoundRenderer::IsPlayingSound(long handle) //==========================================================================
//
// FMODSoundRenderer :: UpdateSoundParams3D
//
//==========================================================================
void FMODSoundRenderer::UpdateSoundParams3D(FSoundChan *chan, float pos[3], float vel[3])
{ {
if (!handle || !ChannelMap) if (chan == NULL || chan->SysChannel == NULL)
return false; return;
handle--; FMOD::Channel *fchan = (FMOD::Channel *)chan->SysChannel;
if (ChannelMap[handle].channelID != NULL)
// Sounds at the same location as the listener should be head relative, others
// should be world relative.
if (players[consoleplayer].camera != NULL)
{ {
bool is; FMOD_MODE oldmode, mode;
float cpos[3];
if (FMOD_OK == ChannelMap[handle].channelID->isPlaying(&is)) cpos[0] = FIXED2FLOAT(players[consoleplayer].camera->x);
cpos[2] = FIXED2FLOAT(players[consoleplayer].camera->y);
cpos[1] = FIXED2FLOAT(players[consoleplayer].camera->z);
if (FMOD_OK != fchan->getMode(&oldmode))
{ {
return is; oldmode = FMOD_3D | FMOD_SOFTWARE;
}
if (cpos[0] == pos[0] && cpos[1] == pos[1] && cpos[2] == pos[2])
{
mode = (oldmode & ~FMOD_3D_WORLDRELATIVE) | FMOD_3D_HEADRELATIVE;
pos[0] = 0;
pos[1] = 0;
pos[2] = 0;
}
else
{
mode = (oldmode & ~FMOD_3D_HEADRELATIVE) | FMOD_3D_WORLDRELATIVE;
}
// Only set the mode if it changed.
if (((mode ^ oldmode) & (FMOD_3D_WORLDRELATIVE | FMOD_3D_HEADRELATIVE)) == 0)
{
fchan->setMode(mode);
} }
} }
return false;
fchan->set3DAttributes((FMOD_VECTOR *)pos, (FMOD_VECTOR *)vel);
} }
void FMODSoundRenderer::UpdateSoundParams(long handle, float vol, float sep, int pitch) //==========================================================================
{ //
if (!handle || !ChannelMap) // FMODSoundRenderer :: ResetEnvironment
return; //
//==========================================================================
handle--;
if (ChannelMap[handle].soundID == -1 || ChannelMap[handle].channelID == NULL)
return;
float freq = PITCH(S_sfx[ChannelMap[handle].soundID].frequency, pitch);
FMOD::Channel *chan = ChannelMap[handle].channelID;
chan->setPan(sep);
chan->setVolume(vol);
chan->setFrequency(freq);
}
void FMODSoundRenderer::UpdateSoundParams3D(long handle, float pos[3], float vel[3])
{
if (!handle || !ChannelMap)
return;
handle--;
if (ChannelMap[handle].soundID == -1 || ChannelMap[handle].channelID == NULL)
return;
ChannelMap[handle].channelID->set3DAttributes((FMOD_VECTOR *)pos, (FMOD_VECTOR *)vel);
}
void FMODSoundRenderer::ResetEnvironment() void FMODSoundRenderer::ResetEnvironment()
{ {
PrevEnvironment = NULL; PrevEnvironment = NULL;
} }
void FMODSoundRenderer::UpdateListener(AActor *listener) //==========================================================================
//
// FMODSoundRenderer :: UpdateListener
//
//==========================================================================
void FMODSoundRenderer::UpdateListener()
{ {
AActor *listener = players[consoleplayer].camera;
float angle; float angle;
FMOD_VECTOR pos, vel; FMOD_VECTOR pos, vel;
FMOD_VECTOR forward; FMOD_VECTOR forward;
FMOD_VECTOR up; FMOD_VECTOR up;
if(Sound3D && ChannelMap) if (listener == NULL)
{ {
vel.x = listener->momx * (TICRATE/65536.f); return;
vel.y = listener->momz * (TICRATE/65536.f); }
vel.z = listener->momy * (TICRATE/65536.f);
pos.x = listener->x / 65536.f;
pos.y = listener->z / 65536.f;
pos.z = listener->y / 65536.f;
angle = (float)(listener->angle) * ((float)PI / 2147483648.f); vel.x = listener->momx * (TICRATE/65536.f);
vel.y = listener->momz * (TICRATE/65536.f);
vel.z = listener->momy * (TICRATE/65536.f);
pos.x = listener->x / 65536.f;
pos.y = listener->z / 65536.f;
pos.z = listener->y / 65536.f;
forward.x = cosf(angle); angle = (float)(listener->angle) * ((float)PI / 2147483648.f);
forward.y = 0;
forward.z = sinf(angle);
up.x = 0; forward.x = cosf(angle);
up.y = 1; forward.y = 0;
up.z = 0; forward.z = sinf(angle);
Sys->set3DListenerAttributes(0, &pos, &vel, &forward, &up); up.x = 0;
up.y = 1;
up.z = 0;
bool underwater = false; Sys->set3DListenerAttributes(0, &pos, &vel, &forward, &up);
const ReverbContainer *env;
if (ForcedEnvironment) bool underwater = false;
const ReverbContainer *env;
if (ForcedEnvironment)
{
env = ForcedEnvironment;
}
else
{
underwater = (listener->waterlevel == 3 && snd_waterreverb);
assert (zones != NULL);
env = zones[listener->Sector->ZoneNumber].Environment;
if (env == NULL)
{ {
env = ForcedEnvironment; env = DefaultEnvironments[0];
} }
else if (env == DefaultEnvironments[0] && underwater)
{ {
underwater = (listener->waterlevel == 3 && snd_waterreverb); env = DefaultEnvironments[22];
assert (zones != NULL);
env = zones[listener->Sector->ZoneNumber].Environment;
if (env == NULL)
{
env = DefaultEnvironments[0];
}
if (env == DefaultEnvironments[0] && underwater)
{
env = DefaultEnvironments[22];
}
}
if (env != PrevEnvironment || env->Modified)
{
DPrintf ("Reverb Environment %s\n", env->Name);
const_cast<ReverbContainer*>(env)->Modified = false;
Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties));
PausableSfx->setPitch(underwater ? 0.64171f : 1);
PrevEnvironment = env;
} }
} }
if (env != PrevEnvironment || env->Modified)
{
DPrintf ("Reverb Environment %s\n", env->Name);
const_cast<ReverbContainer*>(env)->Modified = false;
Sys->setReverbProperties((FMOD_REVERB_PROPERTIES *)(&env->Properties));
PausableSfx->setPitch(underwater ? 0.64171f : 1);
PrevEnvironment = env;
}
}
//==========================================================================
//
// FMODSoundRenderer :: UpdateSounds
//
//==========================================================================
void FMODSoundRenderer::UpdateSounds()
{
Sys->update(); Sys->update();
} }
//==========================================================================
//
// FMODSoundRenderer :: LoadSound
//
//==========================================================================
void FMODSoundRenderer::LoadSound(sfxinfo_t *sfx) void FMODSoundRenderer::LoadSound(sfxinfo_t *sfx)
{ {
if (sfx->data == NULL) if (sfx->data == NULL)
@ -1109,6 +1249,12 @@ void FMODSoundRenderer::LoadSound(sfxinfo_t *sfx)
} }
} }
//==========================================================================
//
// FMODSoundRenderer :: UnloadSound
//
//==========================================================================
void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx) void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx)
{ {
if (sfx->data != NULL) if (sfx->data != NULL)
@ -1119,6 +1265,36 @@ void FMODSoundRenderer::UnloadSound(sfxinfo_t *sfx)
} }
} }
//==========================================================================
//
// FMODSoundRenderer :: GetMSLength
//
//==========================================================================
unsigned int FMODSoundRenderer::GetMSLength(sfxinfo_t *sfx)
{
if (sfx->data == NULL)
{
LoadSound(sfx);
}
if (sfx->data != NULL)
{
unsigned int length;
if (((FMOD::Sound *)sfx->data)->getLength(&length, FMOD_TIMEUNIT_MS) == FMOD_OK)
{
return length;
}
}
return 0; // Don't know.
}
//==========================================================================
//
// FMODSoundRenderer :: DoLoad
//
//==========================================================================
void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx) void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
{ {
BYTE *sfxdata; BYTE *sfxdata;
@ -1130,7 +1306,7 @@ void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), }; FMOD_CREATESOUNDEXINFO exinfo = { sizeof(exinfo), };
FMOD::Sound *sample; FMOD::Sound *sample;
samplemode = (Sound3D ? FMOD_3D : FMOD_2D) | FMOD_OPENMEMORY | FMOD_SOFTWARE; samplemode = FMOD_3D | FMOD_OPENMEMORY | FMOD_SOFTWARE;
sfxdata = NULL; sfxdata = NULL;
errcount = 0; errcount = 0;
@ -1177,7 +1353,6 @@ void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
} }
sfxstart = sfxdata + 8; sfxstart = sfxdata + 8;
} }
sfx->length = len;
exinfo.length = len; exinfo.length = len;
exinfo.numchannels = 1; exinfo.numchannels = 1;
@ -1222,32 +1397,15 @@ void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
freq = 11025; freq = 11025;
} }
sfx->frequency = (unsigned int)freq; sfx->frequency = (unsigned int)freq;
result = sample->getLength(&sfx->length, FMOD_TIMEUNIT_PCM);
if (result != FMOD_OK)
{
DPrintf("Failed getting sample length\n");
}
}
// Get sample length in milliseconds. I think this is only used for ambient sounds?
if (FMOD_OK != sample->getLength(&sfx->ms, FMOD_TIMEUNIT_MS))
{
sfx->ms = (sfx->length * 1000) / sfx->frequency;
} }
break; break;
} }
if (sfx->data) if (sfx->data)
{ {
DPrintf ("[%d Hz %d samples]\n", sfx->frequency, sfx->length); // Match s_sound.cpp min distance.
// Max distance is irrelevant.
if (Sound3D) sample->set3DMinMaxDistance(float(S_CLOSE_DIST), 10000.f);
{
// Match s_sound.cpp min distance.
// Max distance is irrelevant.
sample->set3DMinMaxDistance(float(S_CLOSE_DIST), float(MAX_SND_DIST)*2);
}
} }
if (sfxdata != NULL) if (sfxdata != NULL)
@ -1256,29 +1414,34 @@ void FMODSoundRenderer::DoLoad(void **slot, sfxinfo_t *sfx)
} }
} }
//==========================================================================
//
// FMODSoundRenderer :: getsfx
//
// Get the sound data from the WAD and register it with sound library
//
//==========================================================================
void FMODSoundRenderer::getsfx(sfxinfo_t *sfx) void FMODSoundRenderer::getsfx(sfxinfo_t *sfx)
{ {
unsigned int i; unsigned int i;
// Get the sound data from the WAD and register it with sound library
// If the sound doesn't exist, replace it with the empty sound. // If the sound doesn't exist, replace it with the empty sound.
if (sfx->lumpnum == -1) if (sfx->lumpnum == -1)
{ {
sfx->lumpnum = Wads.GetNumForName ("dsempty", ns_sounds); sfx->lumpnum = Wads.GetNumForName("dsempty", ns_sounds);
} }
// See if there is another sound already initialized with this lump. If so, // See if there is another sound already initialized with this lump. If so,
// then set this one up as a link, and don't load the sound again. // then set this one up as a link, and don't load the sound again.
for (i = 0; i < S_sfx.Size (); i++) for (i = 0; i < S_sfx.Size(); i++)
{ {
if (S_sfx[i].data && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum) if (S_sfx[i].data && S_sfx[i].link == sfxinfo_t::NO_LINK && S_sfx[i].lumpnum == sfx->lumpnum)
{ {
DPrintf ("Linked to %s (%d)\n", S_sfx[i].name.GetChars(), i); DPrintf ("Linked to %s (%d)\n", S_sfx[i].name.GetChars(), i);
sfx->link = i; sfx->link = i;
sfx->ms = S_sfx[i].ms;
return; return;
} }
} }
DoLoad (&sfx->data, sfx); DoLoad(&sfx->data, sfx);
} }

View file

@ -13,41 +13,35 @@ public:
void SetSfxVolume (float volume); void SetSfxVolume (float volume);
void SetMusicVolume (float volume); void SetMusicVolume (float volume);
int GetNumChannels ();
void LoadSound (sfxinfo_t *sfx); void LoadSound (sfxinfo_t *sfx);
void UnloadSound (sfxinfo_t *sfx); void UnloadSound (sfxinfo_t *sfx);
unsigned int GetMSLength(sfxinfo_t *sfx);
// Streaming sounds. PlayStream returns a channel handle that can be used with StopSound. // Streaming sounds.
SoundStream *CreateStream (SoundStreamCallback callback, int buffsamples, int flags, int samplerate, void *userdata); SoundStream *CreateStream (SoundStreamCallback callback, int buffsamples, int flags, int samplerate, void *userdata);
SoundStream *OpenStream (const char *filename, int flags, int offset, int length); SoundStream *OpenStream (const char *filename, int flags, int offset, int length);
long PlayStream (SoundStream *stream, int volume); long PlayStream (SoundStream *stream, int volume);
void StopStream (SoundStream *stream); void StopStream (SoundStream *stream);
// Starts a sound in a particular sound channel. // Starts a sound.
long StartSound (sfxinfo_t *sfx, float vol, float sep, int pitch, int channel, bool looping, bool pauseable); FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, bool looping, bool pauseable);
long StartSound3D (sfxinfo_t *sfx, float vol, int pitch, int channel, bool looping, float pos[3], float vel[3], bool pauseable); FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, int pitch, bool looping, float pos[3], float vel[3], bool pauseable);
// Stops a sound channel. // Stops a sound channel.
void StopSound (long handle); void StopSound (FSoundChan *chan);
// Stops all sounds.
void StopAllChannels ();
// Pauses or resumes all sound effect channels. // Pauses or resumes all sound effect channels.
void SetSfxPaused (bool paused); void SetSfxPaused (bool paused);
// Returns true if the channel is still playing a sound. // Updates the position of a sound channel.
bool IsPlayingSound (long handle); void UpdateSoundParams3D (FSoundChan *chan, float pos[3], float vel[3]);
// Updates the volume, separation, and pitch of a sound channel.
void UpdateSoundParams (long handle, float vol, float sep, int pitch);
void UpdateSoundParams3D (long handle, float pos[3], float vel[3]);
// For use by I_PlayMovie // For use by I_PlayMovie
void MovieDisableSound (); void MovieDisableSound ();
void MovieResumeSound (); void MovieResumeSound ();
void UpdateListener (AActor *listener); void UpdateListener ();
void UpdateSounds ();
void PrintStatus (); void PrintStatus ();
void PrintDriversList (); void PrintDriversList ();
@ -55,19 +49,15 @@ public:
void ResetEnvironment (); void ResetEnvironment ();
private: private:
// Maps sfx channels onto FMOD channels
struct ChanMap
{
int soundID; // sfx playing on this channel
FMOD::Channel *channelID;
bool bIsLooping;
} *ChannelMap;
int NumChannels;
unsigned int DriverCaps; unsigned int DriverCaps;
int OutputType; int OutputType;
bool SFXPaused; bool SFXPaused;
bool InitSuccess;
static FMOD_RESULT F_CALLBACK ChannelEndCallback
(FMOD_CHANNEL *channel, FMOD_CHANNEL_CALLBACKTYPE type, int cmd, unsigned int data1, unsigned int data2);
FSoundChan *CommonChannelSetup(FMOD::Channel *chan, bool is3d);
void DoLoad (void **slot, sfxinfo_t *sfx); void DoLoad (void **slot, sfxinfo_t *sfx);
void getsfx (sfxinfo_t *sfx); void getsfx (sfxinfo_t *sfx);

View file

@ -1,6 +1,6 @@
/* /*
** i_sound.cpp ** i_sound.cpp
** System interface for sound; uses fmod.dll ** Stubs for sound interfaces.
** **
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit ** Copyright 1998-2006 Randy Heit
@ -80,49 +80,8 @@ CVAR (String, snd_output, "default", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
// killough 2/21/98: optionally use varying pitched sounds // killough 2/21/98: optionally use varying pitched sounds
CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE) CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE)
// Maps sfx channels onto FMOD channels
static struct ChanMap
{
int soundID; // sfx playing on this channel
long channelID;
bool bIsLooping;
bool bIs3D;
unsigned int lastPos;
} *ChannelMap;
SoundRenderer *GSnd; SoundRenderer *GSnd;
static int numChannels;
static unsigned int DriverCaps;
static int OutputType;
static bool SoundDown = true;
#if 0
static const char *FmodErrors[] =
{
"No errors",
"Cannot call this command after FSOUND_Init. Call FSOUND_Close first.",
"This command failed because FSOUND_Init was not called",
"Error initializing output device.",
"Error initializing output device, but more specifically, the output device is already in use and cannot be reused.",
"Playing the sound failed.",
"Soundcard does not support the features needed for this soundsystem (16bit stereo output)",
"Error setting cooperative level for hardware.",
"Error creating hardware sound buffer.",
"File not found",
"Unknown file format",
"Error loading file",
"Not enough memory ",
"The version number of this file format is not supported",
"Incorrect mixer selected",
"An invalid parameter was passed to this function",
"Tried to use a3d and not an a3d hardware card, or dll didnt exist, try another output type.",
"Tried to use an EAX command on a non EAX enabled channel or output.",
"Failed to allocate a new channel"
};
#endif
// //
// SFX API // SFX API
@ -159,16 +118,6 @@ void I_InitSound ()
return; return;
} }
// clamp snd_samplerate to FMOD's limits
if (snd_samplerate < 4000)
{
snd_samplerate = 4000;
}
else if (snd_samplerate > 65535)
{
snd_samplerate = 65535;
}
GSnd = new FMODSoundRenderer; GSnd = new FMODSoundRenderer;
if (!GSnd->IsValid ()) if (!GSnd->IsValid ())
@ -237,12 +186,11 @@ ADD_STAT (sound)
} }
else else
{ {
return "no sound"; return "No sound";
} }
} }
SoundRenderer::SoundRenderer () SoundRenderer::SoundRenderer ()
: Sound3D (false)
{ {
} }
@ -250,23 +198,6 @@ SoundRenderer::~SoundRenderer ()
{ {
} }
long SoundRenderer::StartSound3D (sfxinfo_t *sfx, float vol, int pitch, int channel, bool looping, float pos[3], float vel[3], bool pauseable)
{
return 0;
}
void SoundRenderer::UpdateSoundParams3D (long handle, float pos[3], float vel[3])
{
}
void SoundRenderer::UpdateListener (AActor *listener)
{
}
void SoundRenderer::UpdateSounds ()
{
}
FString SoundRenderer::GatherStats () FString SoundRenderer::GatherStats ()
{ {
return "No stats for this sound renderer."; return "No stats for this sound renderer.";

View file

@ -69,48 +69,39 @@ public:
virtual void SetSfxVolume (float volume) = 0; virtual void SetSfxVolume (float volume) = 0;
virtual void SetMusicVolume (float volume) = 0; virtual void SetMusicVolume (float volume) = 0;
virtual int GetNumChannels () = 0; // Initialize channels
virtual void LoadSound (sfxinfo_t *sfx) = 0; // load a sound from disk virtual void LoadSound (sfxinfo_t *sfx) = 0; // load a sound from disk
virtual void UnloadSound (sfxinfo_t *sfx) = 0; // unloads a sound from memory virtual void UnloadSound (sfxinfo_t *sfx) = 0; // unloads a sound from memory
virtual unsigned int GetMSLength(sfxinfo_t *sfx) = 0; // Gets the length of a sound at its default frequency
// Streaming sounds. PlayStream returns a channel handle that can be used with StopSound. // Streaming sounds.
virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0; virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0;
virtual SoundStream *OpenStream (const char *filename, int flags, int offset, int length) = 0; virtual SoundStream *OpenStream (const char *filename, int flags, int offset, int length) = 0;
// Starts a sound in a particular sound channel. // Starts a sound.
virtual long StartSound (sfxinfo_t *sfx, float vol, float sep, int pitch, int channel, bool looping, bool pauseable) = 0; virtual FSoundChan *StartSound (sfxinfo_t *sfx, float vol, int pitch, bool looping, bool pauseable) = 0;
virtual long StartSound3D (sfxinfo_t *sfx, float vol, int pitch, int channel, bool looping, float pos[3], float vel[3], bool pauseable); virtual FSoundChan *StartSound3D (sfxinfo_t *sfx, float vol, int pitch, bool looping, float pos[3], float vel[3], bool pauseable) = 0;
// Stops a sound channel. // Stops a sound channel.
virtual void StopSound (long handle) = 0; virtual void StopSound (FSoundChan *chan) = 0;
// Stops all sounds.
virtual void StopAllChannels () = 0;
// Pauses or resumes all sound effect channels. // Pauses or resumes all sound effect channels.
virtual void SetSfxPaused (bool paused) = 0; virtual void SetSfxPaused (bool paused) = 0;
// Returns true if the channel is still playing a sound.
virtual bool IsPlayingSound (long handle) = 0;
// Updates the volume, separation, and pitch of a sound channel. // Updates the volume, separation, and pitch of a sound channel.
virtual void UpdateSoundParams (long handle, float vol, float sep, int pitch) = 0; virtual void UpdateSoundParams3D (FSoundChan *chan, float pos[3], float vel[3]) = 0;
virtual void UpdateSoundParams3D (long handle, float pos[3], float vel[3]);
// For use by I_PlayMovie // For use by I_PlayMovie
virtual void MovieDisableSound () = 0; virtual void MovieDisableSound () = 0;
virtual void MovieResumeSound () = 0; virtual void MovieResumeSound () = 0;
virtual void UpdateListener (AActor *listener); virtual void UpdateListener () = 0;
virtual void UpdateSounds (); virtual void UpdateSounds () = 0;
virtual bool IsValid () = 0; virtual bool IsValid () = 0;
virtual void PrintStatus () = 0; virtual void PrintStatus () = 0;
virtual void PrintDriversList () = 0; virtual void PrintDriversList () = 0;
virtual FString GatherStats (); virtual FString GatherStats ();
virtual void ResetEnvironment (); virtual void ResetEnvironment ();
bool Sound3D;
}; };
extern SoundRenderer *GSnd; extern SoundRenderer *GSnd;

View file

@ -319,11 +319,11 @@ void A_PlaySoundEx (AActor *self)
int attenuation; int attenuation;
switch (attenuation_raw) switch (attenuation_raw)
{ {
case -1: attenuation=ATTN_STATIC; break; // drop off rapidly case -1: attenuation = ATTN_STATIC; break; // drop off rapidly
default: default:
case 0: attenuation=ATTN_NORM; break; // normal case 0: attenuation = ATTN_NORM; break; // normal
case 1: attenuation=ATTN_NONE; break; // full volume case 1:
case 2: attenuation=ATTN_SURROUND; break; // full volume surround case 2: attenuation = ATTN_NONE; break; // full volume
} }
if (channel < NAME_Auto || channel > NAME_SoundSlot7) if (channel < NAME_Auto || channel > NAME_SoundSlot7)

View file

@ -6,11 +6,18 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
#ifdef _MSC_VER
#define CDECL __cdecl
#else
#define CDECL
#endif
#line 1 "parse.y" #line 1 "parse.y"
#include <malloc.h> #include <malloc.h>
#include "dehsupp.h" #include "dehsupp.h"
#line 14 "parse.c" #line 21 "parse.c"
/* Next is all token values, in a form suitable for use by makeheaders. /* Next is all token values, in a form suitable for use by makeheaders.
** This section will be null unless lemon is run with the -m switch. ** This section will be null unless lemon is run with the -m switch.
*/ */
@ -461,7 +468,7 @@ static void yyGrowStack(yyParser *p){
** A pointer to a parser. This pointer is used in subsequent calls ** A pointer to a parser. This pointer is used in subsequent calls
** to Parse and ParseFree. ** to Parse and ParseFree.
*/ */
void *ParseAlloc(void *(*mallocProc)(size_t)){ void *ParseAlloc(void *(CDECL *mallocProc)(size_t)){
yyParser *pParser; yyParser *pParser;
pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
if( pParser ){ if( pParser ){
@ -525,7 +532,7 @@ static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
case 33: /* RenderStyles */ case 33: /* RenderStyles */
#line 10 "parse.y" #line 10 "parse.y"
{ if ((yypminor->yy0).string) free((yypminor->yy0).string); } { if ((yypminor->yy0).string) free((yypminor->yy0).string); }
#line 529 "parse.c" #line 536 "parse.c"
break; break;
default: break; /* If no destructor action specified: do nothing */ default: break; /* If no destructor action specified: do nothing */
} }
@ -571,7 +578,7 @@ static int yy_pop_parser_stack(yyParser *pParser){
*/ */
void ParseFree( void ParseFree(
void *p, /* The parser to be deleted */ void *p, /* The parser to be deleted */
void (*freeProc)(void*) /* Function used to reclaim memory */ void (CDECL *freeProc)(void*) /* Function used to reclaim memory */
){ ){
yyParser *pParser = (yyParser*)p; yyParser *pParser = (yyParser*)p;
if( pParser==0 ) return; if( pParser==0 ) return;
@ -903,7 +910,7 @@ static void yy_reduce(
#line 21 "parse.y" #line 21 "parse.y"
{ {
} }
#line 907 "parse.c" #line 914 "parse.c"
break; break;
case 14: /* print_statement ::= PRINT LPAREN print_list RPAREN */ case 14: /* print_statement ::= PRINT LPAREN print_list RPAREN */
#line 39 "parse.y" #line 39 "parse.y"
@ -913,7 +920,7 @@ static void yy_reduce(
yy_destructor(11,&yymsp[-2].minor); yy_destructor(11,&yymsp[-2].minor);
yy_destructor(12,&yymsp[0].minor); yy_destructor(12,&yymsp[0].minor);
} }
#line 917 "parse.c" #line 924 "parse.c"
break; break;
case 17: /* print_list ::= print_item COMMA print_list */ case 17: /* print_list ::= print_item COMMA print_list */
case 60: /*state_map_list ::= state_map_list COMMA state_map_entry */ case 60: /*state_map_list ::= state_map_list COMMA state_map_entry */
@ -923,83 +930,83 @@ static void yy_reduce(
{ {
yy_destructor(13,&yymsp[-1].minor); yy_destructor(13,&yymsp[-1].minor);
} }
#line 927 "parse.c" #line 934 "parse.c"
break; break;
case 18: /* print_item ::= STRING */ case 18: /* print_item ::= STRING */
#line 47 "parse.y" #line 47 "parse.y"
{ printf ("%s", yymsp[0].minor.yy0.string); } { printf ("%s", yymsp[0].minor.yy0.string); }
#line 932 "parse.c" #line 939 "parse.c"
break; break;
case 19: /* print_item ::= exp */ case 19: /* print_item ::= exp */
#line 48 "parse.y" #line 48 "parse.y"
{ printf ("%d", yymsp[0].minor.yy64); } { printf ("%d", yymsp[0].minor.yy64); }
#line 937 "parse.c" #line 944 "parse.c"
break; break;
case 20: /* print_item ::= ENDL */ case 20: /* print_item ::= ENDL */
#line 49 "parse.y" #line 49 "parse.y"
{ printf ("\n"); yy_destructor(15,&yymsp[0].minor); { printf ("\n"); yy_destructor(15,&yymsp[0].minor);
} }
#line 943 "parse.c" #line 950 "parse.c"
break; break;
case 21: /* exp ::= NUM */ case 21: /* exp ::= NUM */
#line 52 "parse.y" #line 52 "parse.y"
{ yygotominor.yy64 = yymsp[0].minor.yy0.val; } { yygotominor.yy64 = yymsp[0].minor.yy0.val; }
#line 948 "parse.c" #line 955 "parse.c"
break; break;
case 22: /* exp ::= exp PLUS exp */ case 22: /* exp ::= exp PLUS exp */
#line 53 "parse.y" #line 53 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 + yymsp[0].minor.yy64; yy_destructor(5,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 + yymsp[0].minor.yy64; yy_destructor(5,&yymsp[-1].minor);
} }
#line 954 "parse.c" #line 961 "parse.c"
break; break;
case 23: /* exp ::= exp MINUS exp */ case 23: /* exp ::= exp MINUS exp */
#line 54 "parse.y" #line 54 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 - yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 - yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor);
} }
#line 960 "parse.c" #line 967 "parse.c"
break; break;
case 24: /* exp ::= exp MULTIPLY exp */ case 24: /* exp ::= exp MULTIPLY exp */
#line 55 "parse.y" #line 55 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 * yymsp[0].minor.yy64; yy_destructor(6,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 * yymsp[0].minor.yy64; yy_destructor(6,&yymsp[-1].minor);
} }
#line 966 "parse.c" #line 973 "parse.c"
break; break;
case 25: /* exp ::= exp DIVIDE exp */ case 25: /* exp ::= exp DIVIDE exp */
#line 56 "parse.y" #line 56 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 / yymsp[0].minor.yy64; yy_destructor(7,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 / yymsp[0].minor.yy64; yy_destructor(7,&yymsp[-1].minor);
} }
#line 972 "parse.c" #line 979 "parse.c"
break; break;
case 26: /* exp ::= exp OR exp */ case 26: /* exp ::= exp OR exp */
#line 57 "parse.y" #line 57 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 | yymsp[0].minor.yy64; yy_destructor(1,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 | yymsp[0].minor.yy64; yy_destructor(1,&yymsp[-1].minor);
} }
#line 978 "parse.c" #line 985 "parse.c"
break; break;
case 27: /* exp ::= exp AND exp */ case 27: /* exp ::= exp AND exp */
#line 58 "parse.y" #line 58 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 & yymsp[0].minor.yy64; yy_destructor(3,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 & yymsp[0].minor.yy64; yy_destructor(3,&yymsp[-1].minor);
} }
#line 984 "parse.c" #line 991 "parse.c"
break; break;
case 28: /* exp ::= exp XOR exp */ case 28: /* exp ::= exp XOR exp */
#line 59 "parse.y" #line 59 "parse.y"
{ yygotominor.yy64 = yymsp[-2].minor.yy64 ^ yymsp[0].minor.yy64; yy_destructor(2,&yymsp[-1].minor); { yygotominor.yy64 = yymsp[-2].minor.yy64 ^ yymsp[0].minor.yy64; yy_destructor(2,&yymsp[-1].minor);
} }
#line 990 "parse.c" #line 997 "parse.c"
break; break;
case 29: /* exp ::= MINUS exp */ case 29: /* exp ::= MINUS exp */
#line 60 "parse.y" #line 60 "parse.y"
{ yygotominor.yy64 = -yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor); { yygotominor.yy64 = -yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor);
} }
#line 996 "parse.c" #line 1003 "parse.c"
break; break;
case 30: /* exp ::= LPAREN exp RPAREN */ case 30: /* exp ::= LPAREN exp RPAREN */
#line 61 "parse.y" #line 61 "parse.y"
{ yygotominor.yy64 = yymsp[-1].minor.yy64; yy_destructor(11,&yymsp[-2].minor); { yygotominor.yy64 = yymsp[-1].minor.yy64; yy_destructor(11,&yymsp[-2].minor);
yy_destructor(12,&yymsp[0].minor); yy_destructor(12,&yymsp[0].minor);
} }
#line 1003 "parse.c" #line 1010 "parse.c"
break; break;
case 31: /* actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON */ case 31: /* actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON */
case 32: /*actions_def ::= Actions LBRACE error RBRACE SEMICOLON */ case 32: /*actions_def ::= Actions LBRACE error RBRACE SEMICOLON */
@ -1010,18 +1017,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1014 "parse.c" #line 1021 "parse.c"
break; break;
case 34: /* actions_list ::= SYM */ case 34: /* actions_list ::= SYM */
#line 68 "parse.y" #line 68 "parse.y"
{ AddAction (yymsp[0].minor.yy0.string); } { AddAction (yymsp[0].minor.yy0.string); }
#line 1019 "parse.c" #line 1026 "parse.c"
break; break;
case 35: /* actions_list ::= actions_list COMMA SYM */ case 35: /* actions_list ::= actions_list COMMA SYM */
#line 69 "parse.y" #line 69 "parse.y"
{ AddAction (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); { AddAction (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1025 "parse.c" #line 1032 "parse.c"
break; break;
case 36: /* org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON */ case 36: /* org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON */
case 37: /*org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON */ case 37: /*org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON */
@ -1032,18 +1039,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1036 "parse.c" #line 1043 "parse.c"
break; break;
case 39: /* org_heights_list ::= exp */ case 39: /* org_heights_list ::= exp */
#line 76 "parse.y" #line 76 "parse.y"
{ AddHeight (yymsp[0].minor.yy64); } { AddHeight (yymsp[0].minor.yy64); }
#line 1041 "parse.c" #line 1048 "parse.c"
break; break;
case 40: /* org_heights_list ::= org_heights_list COMMA exp */ case 40: /* org_heights_list ::= org_heights_list COMMA exp */
#line 77 "parse.y" #line 77 "parse.y"
{ AddHeight (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor); { AddHeight (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1047 "parse.c" #line 1054 "parse.c"
break; break;
case 41: /* action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON */ case 41: /* action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON */
case 42: /*action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON */ case 42: /*action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON */
@ -1054,18 +1061,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1058 "parse.c" #line 1065 "parse.c"
break; break;
case 44: /* action_list_list ::= SYM */ case 44: /* action_list_list ::= SYM */
#line 84 "parse.y" #line 84 "parse.y"
{ AddActionMap (yymsp[0].minor.yy0.string); } { AddActionMap (yymsp[0].minor.yy0.string); }
#line 1063 "parse.c" #line 1070 "parse.c"
break; break;
case 45: /* action_list_list ::= action_list_list COMMA SYM */ case 45: /* action_list_list ::= action_list_list COMMA SYM */
#line 85 "parse.y" #line 85 "parse.y"
{ AddActionMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); { AddActionMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1069 "parse.c" #line 1076 "parse.c"
break; break;
case 46: /* codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON */ case 46: /* codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON */
case 47: /*codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON */ case 47: /*codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON */
@ -1076,18 +1083,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1080 "parse.c" #line 1087 "parse.c"
break; break;
case 49: /* codep_conv_list ::= exp */ case 49: /* codep_conv_list ::= exp */
#line 92 "parse.y" #line 92 "parse.y"
{ AddCodeP (yymsp[0].minor.yy64); } { AddCodeP (yymsp[0].minor.yy64); }
#line 1085 "parse.c" #line 1092 "parse.c"
break; break;
case 50: /* codep_conv_list ::= codep_conv_list COMMA exp */ case 50: /* codep_conv_list ::= codep_conv_list COMMA exp */
#line 93 "parse.y" #line 93 "parse.y"
{ AddCodeP (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor); { AddCodeP (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1091 "parse.c" #line 1098 "parse.c"
break; break;
case 51: /* org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON */ case 51: /* org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON */
case 52: /*org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON */ case 52: /*org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON */
@ -1098,18 +1105,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1102 "parse.c" #line 1109 "parse.c"
break; break;
case 54: /* org_spr_names_list ::= SYM */ case 54: /* org_spr_names_list ::= SYM */
#line 100 "parse.y" #line 100 "parse.y"
{ AddSpriteName (yymsp[0].minor.yy0.string); } { AddSpriteName (yymsp[0].minor.yy0.string); }
#line 1107 "parse.c" #line 1114 "parse.c"
break; break;
case 55: /* org_spr_names_list ::= org_spr_names_list COMMA SYM */ case 55: /* org_spr_names_list ::= org_spr_names_list COMMA SYM */
#line 101 "parse.y" #line 101 "parse.y"
{ AddSpriteName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); { AddSpriteName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1113 "parse.c" #line 1120 "parse.c"
break; break;
case 56: /* state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON */ case 56: /* state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON */
case 57: /*state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON */ case 57: /*state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON */
@ -1120,32 +1127,32 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1124 "parse.c" #line 1131 "parse.c"
break; break;
case 61: /* state_map_entry ::= SYM COMMA state_type COMMA exp */ case 61: /* state_map_entry ::= SYM COMMA state_type COMMA exp */
#line 111 "parse.y" #line 111 "parse.y"
{ AddStateMap (yymsp[-4].minor.yy0.string, yymsp[-2].minor.yy64, yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-3].minor); { AddStateMap (yymsp[-4].minor.yy0.string, yymsp[-2].minor.yy64, yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-3].minor);
yy_destructor(13,&yymsp[-1].minor); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1131 "parse.c" #line 1138 "parse.c"
break; break;
case 62: /* state_type ::= FirstState */ case 62: /* state_type ::= FirstState */
#line 114 "parse.y" #line 114 "parse.y"
{ yygotominor.yy64 = 0; yy_destructor(27,&yymsp[0].minor); { yygotominor.yy64 = 0; yy_destructor(27,&yymsp[0].minor);
} }
#line 1137 "parse.c" #line 1144 "parse.c"
break; break;
case 63: /* state_type ::= SpawnState */ case 63: /* state_type ::= SpawnState */
#line 115 "parse.y" #line 115 "parse.y"
{ yygotominor.yy64 = 1; yy_destructor(28,&yymsp[0].minor); { yygotominor.yy64 = 1; yy_destructor(28,&yymsp[0].minor);
} }
#line 1143 "parse.c" #line 1150 "parse.c"
break; break;
case 64: /* state_type ::= DeathState */ case 64: /* state_type ::= DeathState */
#line 116 "parse.y" #line 116 "parse.y"
{ yygotominor.yy64 = 2; yy_destructor(29,&yymsp[0].minor); { yygotominor.yy64 = 2; yy_destructor(29,&yymsp[0].minor);
} }
#line 1149 "parse.c" #line 1156 "parse.c"
break; break;
case 65: /* sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON */ case 65: /* sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON */
case 66: /*sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON */ case 66: /*sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON */
@ -1156,18 +1163,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1160 "parse.c" #line 1167 "parse.c"
break; break;
case 68: /* sound_map_list ::= STRING */ case 68: /* sound_map_list ::= STRING */
#line 123 "parse.y" #line 123 "parse.y"
{ AddSoundMap (yymsp[0].minor.yy0.string); } { AddSoundMap (yymsp[0].minor.yy0.string); }
#line 1165 "parse.c" #line 1172 "parse.c"
break; break;
case 69: /* sound_map_list ::= sound_map_list COMMA STRING */ case 69: /* sound_map_list ::= sound_map_list COMMA STRING */
#line 124 "parse.y" #line 124 "parse.y"
{ AddSoundMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); { AddSoundMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1171 "parse.c" #line 1178 "parse.c"
break; break;
case 70: /* info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON */ case 70: /* info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON */
case 71: /*info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON */ case 71: /*info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON */
@ -1178,18 +1185,18 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1182 "parse.c" #line 1189 "parse.c"
break; break;
case 73: /* info_names_list ::= SYM */ case 73: /* info_names_list ::= SYM */
#line 131 "parse.y" #line 131 "parse.y"
{ AddInfoName (yymsp[0].minor.yy0.string); } { AddInfoName (yymsp[0].minor.yy0.string); }
#line 1187 "parse.c" #line 1194 "parse.c"
break; break;
case 74: /* info_names_list ::= info_names_list COMMA SYM */ case 74: /* info_names_list ::= info_names_list COMMA SYM */
#line 132 "parse.y" #line 132 "parse.y"
{ AddInfoName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); { AddInfoName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1193 "parse.c" #line 1200 "parse.c"
break; break;
case 75: /* thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON */ case 75: /* thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON */
case 76: /*thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON */ case 76: /*thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON */
@ -1200,14 +1207,14 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1204 "parse.c" #line 1211 "parse.c"
break; break;
case 80: /* thing_bits_entry ::= exp COMMA exp COMMA SYM */ case 80: /* thing_bits_entry ::= exp COMMA exp COMMA SYM */
#line 142 "parse.y" #line 142 "parse.y"
{ AddThingBits (yymsp[0].minor.yy0.string, yymsp[-4].minor.yy64, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-3].minor); { AddThingBits (yymsp[0].minor.yy0.string, yymsp[-4].minor.yy64, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-3].minor);
yy_destructor(13,&yymsp[-1].minor); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1211 "parse.c" #line 1218 "parse.c"
break; break;
case 81: /* render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON */ case 81: /* render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON */
case 82: /*render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON */ case 82: /*render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON */
@ -1218,13 +1225,13 @@ static void yy_reduce(
yy_destructor(19,&yymsp[-1].minor); yy_destructor(19,&yymsp[-1].minor);
yy_destructor(20,&yymsp[0].minor); yy_destructor(20,&yymsp[0].minor);
} }
#line 1222 "parse.c" #line 1229 "parse.c"
break; break;
case 86: /* render_styles_entry ::= exp COMMA SYM */ case 86: /* render_styles_entry ::= exp COMMA SYM */
#line 152 "parse.y" #line 152 "parse.y"
{ AddRenderStyle (yymsp[0].minor.yy0.string, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-1].minor); { AddRenderStyle (yymsp[0].minor.yy0.string, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-1].minor);
} }
#line 1228 "parse.c" #line 1235 "parse.c"
break; break;
}; };
yygoto = yyRuleInfo[yyruleno].lhs; yygoto = yyRuleInfo[yyruleno].lhs;
@ -1284,7 +1291,7 @@ static void yy_syntax_error(
#define TOKEN (yyminor.yy0) #define TOKEN (yyminor.yy0)
#line 8 "parse.y" #line 8 "parse.y"
yyerror("Syntax error"); yyerror("Syntax error");
#line 1288 "parse.c" #line 1295 "parse.c"
ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
} }

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?> <?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="8,00" Version="8.00"
Name="updaterevision" Name="updaterevision"
ProjectGUID="{6077B7D6-349F-4077-B552-3BC302EF5859}" ProjectGUID="{6077B7D6-349F-4077-B552-3BC302EF5859}"
RootNamespace="updaterevision" RootNamespace="updaterevision"
@ -95,6 +95,82 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="Release|Win32" Name="Release|Win32"
OutputDirectory="$(SolutionDir)$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(ConfigurationName)"
@ -172,82 +248,6 @@
Name="VCPostBuildEventTool" Name="VCPostBuildEventTool"
/> />
</Configuration> </Configuration>
<Configuration
Name="Debug|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
ConfigurationType="1"
CharacterSet="1"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TargetEnvironment="3"
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
MinimalRebuild="true"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="true"
DebugInformationFormat="3"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
LinkIncremental="2"
GenerateDebugInformation="true"
SubSystem="1"
TargetMachine="17"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration <Configuration
Name="Release|x64" Name="Release|x64"
OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)" OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"

View file

@ -198,11 +198,6 @@ weapons/bfgf dsbfg
weapons/bfgx dsrxplod weapons/bfgx dsrxplod
weapons/railgf railgf1 weapons/railgf railgf1
$limit weapons/plasmaf 0
$limit weapons/chngun 0
$limit weapons/rocklf 0 // because normal running is almost as fast as a rocket
$limit weapons/rocklx 0 // and the cyberdemon shoots 3 at once
//=========================================================================== //===========================================================================
// //
// MONSTER SOUNDS // MONSTER SOUNDS
@ -285,7 +280,6 @@ chainguy/death1 dspodth1
chainguy/death2 dspodth2 chainguy/death2 dspodth2
chainguy/death3 dspodth3 chainguy/death3 dspodth3
chainguy/attack dsshotgn chainguy/attack dsshotgn
$limit chainguy/attack 0
// Imp // Imp
@ -369,8 +363,6 @@ baby/walk dsbspwlk
baby/attack dsplasma baby/attack dsplasma
baby/shotx dsfirxpl baby/shotx dsfirxpl
$limit baby/attack 0
// Cyber Demon // Cyber Demon
cyber/sight dscybsit cyber/sight dscybsit
@ -456,10 +448,6 @@ misc/spawn dsitmbk // Item respawn
misc/chat dsradio // Doom 2 chat sound misc/chat dsradio // Doom 2 chat sound
misc/chat2 dstink // Chat sound for everything else misc/chat2 dstink // Chat sound for everything else
$limit misc/i_pkup 1
$limit misc/k_pkup 1
$limit misc/w_pkup 1
$limit misc/p_pkup 1
$pitchshift misc/i_pkup 0 $pitchshift misc/i_pkup 0
$pitchshift misc/k_pkup 0 $pitchshift misc/k_pkup 0
$pitchshift misc/chat2 0 $pitchshift misc/chat2 0
@ -549,21 +537,6 @@ weapons/phoenixshoot phosht
weapons/phoenixhit phohit weapons/phoenixhit phohit
weapons/phoenixpowshoot phopow weapons/phoenixpowshoot phopow
$limit weapons/gauntletson 0
$limit weapons/gauntletshit 0
$limit weapons/gauntletspowhit 0
$limit weapons/gauntletsactivate 0
$limit weapons/gauntletsuse 0
$limit weapons/maceexplode 0
$limit weapons/phoenixhit 0
$limit weapons/phoenixpowshoot 1
// [RH] Heretic didn't have these limitless, but they can sound bad if they're not
$limit weapons/bowhit 0
$limit weapons/hornrodshoot 0
$limit weapons/hornrodhit 0
$limit weapons/maceshoot 0
himp/sight impsit himp/sight impsit
himp/attack impat1 himp/attack impat1
himp/pain imppai himp/pain imppai
@ -573,17 +546,11 @@ himp/leaderattack impat2
misc/invuse artiuse misc/invuse artiuse
$limit misc/invuse 1
world/podexplode podexp world/podexplode podexp
world/podgrow newpod world/podgrow newpod
world/wind wind world/wind wind
world/waterfall waterfl world/waterfall waterfl
$limit world/podexplode 0
$limit world/podgrow 0
$limit world/wind 1
misc/i_pkup itemup misc/i_pkup itemup
misc/k_pkup keyup misc/k_pkup keyup
misc/p_pkup artiup misc/p_pkup artiup
@ -592,8 +559,6 @@ $alias misc/w_pkup *weaponlaugh
misc/rain ramrain misc/rain ramrain
misc/spawn respawn misc/spawn respawn
$limit misc/spawn 1
// //
// Minotaur sounds // Minotaur sounds
// //
@ -662,24 +627,10 @@ world/amb10 amb10
world/amb11 amb11 world/amb11 amb11
world/amb12 bstsit world/amb12 bstsit
$limit world/amb1 1
$limit world/amb2 1
$limit world/amb3 1
$limit world/amb4 1
$limit world/amb5 1
$limit world/amb6 1
$limit world/amb7 1
$limit world/amb8 1
$limit world/amb9 1
$limit world/amb10 1
$limit world/amb11 0
misc/chat chat misc/chat chat
misc/teleport telept misc/teleport telept
misc/ripslop ripslop misc/ripslop ripslop
$limit misc/chat 1
world/drip gloop world/drip gloop
world/watersplash gloop world/watersplash gloop
world/lavasizzle burn world/lavasizzle burn
@ -882,31 +833,6 @@ $alias minotaur/attack2 MaulatorHamSwing
$random BishopActiveSounds { BishopActive BishopSight } $random BishopActiveSounds { BishopActive BishopSight }
$random PigActive { PigActive1 PigActive2 } $random PigActive { PigActive1 PigActive2 }
$limit PlayerFighterFailedUse 1
$limit PlayerClericFailedUse 1
$limit PlayerMageFailedUse 1
$limit SorcererBallWoosh 4
$limit SorcererBallBounce 3
$limit SorcererBallExplode 3
$limit SorcererBallPop 3
$limit SorcererBigBallExplode 3
$limit Ambient1 1
$limit Ambient2 1
$limit Ambient3 1
$limit Ambient4 1
$limit Ambient5 1
$limit Ambient6 1
$limit Ambient7 1
$limit Ambient8 1
$limit Ambient9 1
$limit Ambient10 1
$limit Ambient11 1
$limit Ambient12 1
$limit Ambient13 1
$limit Ambient14 1
$limit Ambient15 1
$limit MysticIncant 4
$pitchshift PlayerMageNormalDeath 0 $pitchshift PlayerMageNormalDeath 0
$pitchshift PlayerMageCrazyDeath 0 $pitchshift PlayerMageCrazyDeath 0
$pitchshift PlayerMageExtreme1Death 0 $pitchshift PlayerMageExtreme1Death 0
@ -935,20 +861,6 @@ $alias menu/clear PlatformStop
// Hexen does not have ripslop sound like Heretic // Hexen does not have ripslop sound like Heretic
misc/ripslop dsempty misc/ripslop dsempty
$limit DoorCloseLight 4
$limit PuppyBeat 0
$limit CeantaurPain 0
$limit BishopPain 0
$limit SerpentPain 0
$limit DemonPain 0
$limit WraithPain 0
$limit MaulatorPain 0
$limit EttinPain 0
$limit FireDemonPain 0
$limit SorcererPain 0
$limit DragonPain 0
$endif // ifhexen $endif // ifhexen
//=========================================================================== //===========================================================================
@ -1040,10 +952,6 @@ world/waterfall dswfall
world/waterdrip dswdrip world/waterdrip dswdrip
world/watersplash dswsplsh world/watersplash dswsplsh
$limit world/river 1
$limit world/waterfall 1
$limit world/waterdrip 1
world/drip dsempty // These four satisfy the Heretic/Hexen terrain definitions world/drip dsempty // These four satisfy the Heretic/Hexen terrain definitions
world/sludgegloop dsempty world/sludgegloop dsempty
world/lavasizzle dsempty world/lavasizzle dsempty

View file

@ -177,15 +177,15 @@
Name="Map Translators" Name="Map Translators"
> >
<File <File
RelativePath=".\xlat\doomxlat.txt" RelativePath=".\xlat\doom.txt"
> >
</File> </File>
<File <File
RelativePath=".\xlat\hereticxlat.txt" RelativePath=".\xlat\heretic.txt"
> >
</File> </File>
<File <File
RelativePath=".\xlat\strifexlat.txt" RelativePath=".\xlat\strife.txt"
> >
</File> </File>
<Filter <Filter

View file

@ -1,4 +1,4 @@
include "xlat/doomxlat.txt" include "xlat/doom.txt"
7 = USE, Stairs_BuildUpDoom (tag, F_SLOW, 8) 7 = USE, Stairs_BuildUpDoom (tag, F_SLOW, 8)
8 = WALK, Stairs_BuildUpDoom (tag, F_SLOW, 8) 8 = WALK, Stairs_BuildUpDoom (tag, F_SLOW, 8)