- Fixed compilation with mingw again.

- Added multiple-choice sound sequences. These overcome one of the major
  deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
  compatible: Custom door sounds can now use different opening and closing
  sequences, for both normal and blazing speeds.
- Added a serializer for TArray.
- Added a countof macro to doomtype.h. See the1's blog to find out why
  it's implemented the way it is.
    <http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
  which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
  be included in the pointer cleanup scans.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
  select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
  their names rather than on their connection order. Using connection
  order was sensible when -net was the only way to start a network game,
  but with -host/-join, it's not so nice. Also, if there aren't enough
  players in the save, then the extra players will be spawned normally,
  so you can continue a saved game with more players than you started it
  with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
  ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
  delayonce, and restart. With these, it is basically possible to obsolete
  all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
  ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
  act like a redundant playrepeat. I have removed all the logic that
  caused playloop to play repeating sounds, and now it acts like an
  infinite sequence of play/delay commands until the sequence is
  stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
  the delay commands were timed incorrectly and varied depending on your
  framerate. Since this is useful for restarting looping sounds that got
  cut off, I have not changed this. Instead, the delay commands now
  record the tic when execution should resume, not the number of tics
  left to delay.


SVN r57 (trunk)
This commit is contained in:
Randy Heit 2006-04-21 01:22:55 +00:00
parent 66c663e9d8
commit 7e7ab6b4ec
51 changed files with 1431 additions and 950 deletions

View file

@ -179,6 +179,7 @@ OBJECTS += \
$(OBJDIR)/tempfiles.o \ $(OBJDIR)/tempfiles.o \
$(OBJDIR)/thingdef.o \ $(OBJDIR)/thingdef.o \
$(OBJDIR)/thingdef_codeptr.o \ $(OBJDIR)/thingdef_codeptr.o \
$(OBJDIR)/thingdef_exp.o \
$(OBJDIR)/v_collection.o \ $(OBJDIR)/v_collection.o \
$(OBJDIR)/v_draw.o \ $(OBJDIR)/v_draw.o \
$(OBJDIR)/v_font.o \ $(OBJDIR)/v_font.o \
@ -222,7 +223,6 @@ OBJECTS += \
$(OBJDIR)/a_chicken.o \ $(OBJDIR)/a_chicken.o \
$(OBJDIR)/a_clink.o \ $(OBJDIR)/a_clink.o \
$(OBJDIR)/a_dsparil.o \ $(OBJDIR)/a_dsparil.o \
$(OBJDIR)/a_hereticambience.o \
$(OBJDIR)/a_hereticarmor.o \ $(OBJDIR)/a_hereticarmor.o \
$(OBJDIR)/a_hereticartifacts.o \ $(OBJDIR)/a_hereticartifacts.o \
$(OBJDIR)/a_hereticdecorations.o \ $(OBJDIR)/a_hereticdecorations.o \
@ -344,6 +344,7 @@ OBJECTS += \
$(OBJDIR)/a_sharedmisc.o \ $(OBJDIR)/a_sharedmisc.o \
$(OBJDIR)/a_skies.o \ $(OBJDIR)/a_skies.o \
$(OBJDIR)/a_soundenvironment.o \ $(OBJDIR)/a_soundenvironment.o \
$(OBJDIR)/a_soundsequence.o \
$(OBJDIR)/a_spark.o \ $(OBJDIR)/a_spark.o \
$(OBJDIR)/a_splashes.o \ $(OBJDIR)/a_splashes.o \
$(OBJDIR)/a_waterzone.o \ $(OBJDIR)/a_waterzone.o \

View file

@ -164,7 +164,7 @@ ${COMPILER} "autostart.cpp a.nas blocks.nas misc.nas tmap.nas tmap2.nas tmap3.na
a_doomimp.cpp a_doomkeys.cpp a_doommisc.cpp a_doomplayer.cpp a_doomweaps.cpp \ a_doomimp.cpp a_doomkeys.cpp a_doommisc.cpp a_doomplayer.cpp a_doomweaps.cpp \
a_fatso.cpp a_keen.cpp a_lostsoul.cpp a_painelemental.cpp a_possessed.cpp \ a_fatso.cpp a_keen.cpp a_lostsoul.cpp a_painelemental.cpp a_possessed.cpp \
a_revenant.cpp a_scriptedmarine.cpp a_spidermaster.cpp doom_sbar.cpp a_beast.cpp \ a_revenant.cpp a_scriptedmarine.cpp a_spidermaster.cpp doom_sbar.cpp a_beast.cpp \
a_chicken.cpp a_clink.cpp a_dsparil.cpp a_hereticambience.cpp a_hereticarmor.cpp \ a_chicken.cpp a_clink.cpp a_dsparil.cpp a_hereticarmor.cpp \
a_hereticartifacts.cpp a_hereticdecorations.cpp a_hereticimp.cpp a_heretickeys.cpp \ a_hereticartifacts.cpp a_hereticdecorations.cpp a_hereticimp.cpp a_heretickeys.cpp \
a_hereticmisc.cpp a_hereticplayer.cpp a_hereticweaps.cpp a_ironlich.cpp \ a_hereticmisc.cpp a_hereticplayer.cpp a_hereticweaps.cpp a_ironlich.cpp \
a_knight.cpp a_mummy.cpp a_snake.cpp a_wizard.cpp heretic_sbar.cpp a_bats.cpp \ a_knight.cpp a_mummy.cpp a_snake.cpp a_wizard.cpp heretic_sbar.cpp a_bats.cpp \
@ -190,7 +190,7 @@ ${COMPILER} "autostart.cpp a.nas blocks.nas misc.nas tmap.nas tmap2.nas tmap3.na
a_camera.cpp a_debris.cpp a_decals.cpp a_flashfader.cpp a_fountain.cpp \ a_camera.cpp a_debris.cpp a_decals.cpp a_flashfader.cpp a_fountain.cpp \
a_hatetarget.cpp a_keys.cpp a_lightning.cpp a_movingcamera.cpp a_pickups.cpp \ a_hatetarget.cpp a_keys.cpp a_lightning.cpp a_movingcamera.cpp a_pickups.cpp \
a_quake.cpp a_secrettrigger.cpp a_sectoraction.cpp a_sharedmisc.cpp a_skies.cpp \ a_quake.cpp a_secrettrigger.cpp a_sectoraction.cpp a_sharedmisc.cpp a_skies.cpp \
a_soundenvironment.cpp a_spark.cpp a_splashes.cpp a_waterzone.cpp a_weaponpiece.cpp a_weapons.cpp \ a_soundenvironment.cpp a_soundsequence.cpp a_spark.cpp a_splashes.cpp a_waterzone.cpp a_weaponpiece.cpp a_weapons.cpp \
hudmessages.cpp shared_sbar.cpp fmopl.cpp mlkernel.cpp mlopl.cpp mlopl_io.cpp \ hudmessages.cpp shared_sbar.cpp fmopl.cpp mlkernel.cpp mlopl.cpp mlopl_io.cpp \
opl_mus_player.cpp fmodsound.cpp i_music.cpp i_sound.cpp music_cd.cpp \ opl_mus_player.cpp fmodsound.cpp i_music.cpp i_sound.cpp music_cd.cpp \
music_flac.cpp music_midi_midiout.cpp music_midi_stream.cpp music_midi_timidity.cpp \ music_flac.cpp music_midi_midiout.cpp music_midi_stream.cpp music_midi_timidity.cpp \

View file

@ -1,3 +1,55 @@
April 20, 2006
- Fixed compilation with mingw again.
- Added multiple-choice sound sequences. These overcome one of the major
deficiences of the Hexen-inherited SNDSEQ system while still being Hexen
compatible: Custom door sounds can now use different opening and closing
sequences, for both normal and blazing speeds.
- Moved the TArray serializer into farchive.h so that tarray.h doesn't need
farchive.h at all because GCC was much pickier than VC. Because of this,
I don't need the FArchive change I made yesterday that hid FArchive's
TArray usses behind pointers.
- Added a countof macro to doomtype.h. See the1's blog to find out why
it's implemented the way it is.
<http://blogs.msdn.com/the1/articles/210011.aspx>
- Added a new method to FRandom for getting random numbers larger than 255,
which lets me:
- Fixed: SNDSEQ delayrand commands could delay for no more than 255 tics.
- Fixed: If you're going to have sector_t.SoundTarget, then they need to
be included in the pointer cleanup scans.
April 19, 2006
- Added a serializer for TArray. This required I make a couple changes to
FArchive in order to avoid circular references between farchive.h and
tarray.h.
- Ported back newer name code from 2.1.
- Fixed: Using -warp with only one parameter in Doom and Heretic to
select a map on episode 1 no longer worked.
- New: Loading a multiplayer save now restores the players based on
their names rather than on their connection order. Using connection
order was sensible when -net was the only way to start a network game,
but with -host/-join, it's not so nice. Also, if there aren't enough
players in the save, then the extra players will be spawned normally,
so you can continue a saved game with more players than you started it
with.
- Added some new SNDSEQ commands to make it possible to define Heretic's
ambient sounds in SNDSEQ: volumerel, volumerand, slot, randomsequence,
delayonce, and restart. With these, it is basically possible to obsolete
all of the $ambient SNDINFO commands.
- Fixed: Sound sequences would only execute one command each time they were
ticked.
- Fixed: No bounds checking was done on the volume sound sequences played at.
- Fixed: The tic parameter to playloop was useless and caused it to
act like a redundant playrepeat. I have removed all the logic that
caused playloop to play repeating sounds, and now it acts like an
infinite sequence of play/delay commands until the sequence is
stopped.
- Fixed: Sound sequences were ticked every frame, not every tic, so all
the delay commands were timed incorrectly and varied depending on your
framerate. Since this is useful for restarting looping sounds that got
cut off, I have not changed this. Instead, the delay commands now
record the tic when execution should resume, not the number of tics
left to delay.
April 19, 2006 (Changes by Graf Zahl) April 19, 2006 (Changes by Graf Zahl)
- Fixed: Hexen's ammo display in the status bar cannot be refreshed - Fixed: Hexen's ammo display in the status bar cannot be refreshed
partially because the background patch has to be drawn always to partially because the background patch has to be drawn always to

View file

@ -248,13 +248,11 @@ bool AnnounceKill (AActor *killer, AActor *killee)
{ // Another player did the killing { // Another player did the killing
if (killee->player->userinfo.gender == GENDER_MALE) if (killee->player->userinfo.gender == GENDER_MALE)
{ // Only males can be castrated { // Only males can be castrated
choice = &KillSounds[rannum % choice = &KillSounds[rannum % countof(KillSounds)];
(sizeof(KillSounds)/sizeof(KillSounds[0]))];
} }
else else
{ {
choice = &KillSounds[rannum % choice = &KillSounds[rannum % (countof(KillSounds) - 1)];
(sizeof(KillSounds)/sizeof(KillSounds[0])-1)];
} }
killerName = killer->player->userinfo.netname; killerName = killer->player->userinfo.netname;

View file

@ -422,7 +422,7 @@ void C_DoCommand (const char *cmd, int keynum)
{ {
int i; int i;
for (i = sizeof(KeyConfCommands)/sizeof(KeyConfCommands[0])-1; i >= 0; --i) for (i = countof(KeyConfCommands)-1; i >= 0; --i)
{ {
if (strnicmp (beg, KeyConfCommands[i], len) == 0 && if (strnicmp (beg, KeyConfCommands[i], len) == 0 &&
KeyConfCommands[i][len] == 0) KeyConfCommands[i][len] == 0)

View file

@ -179,7 +179,7 @@ static FProduction *ParseExpression (FCommandLine &argv, int &parsept)
} }
else else
{ {
for (size_t i = 0; i < sizeof(Producers)/sizeof(Producers[0]); ++i) for (size_t i = 0; i < countof(Producers); ++i)
{ {
if (strcmp (Producers[i].Token, token) == 0) if (strcmp (Producers[i].Token, token) == 0)
{ {

View file

@ -1839,7 +1839,7 @@ static int PatchText (int oldSize)
} }
// If this sprite is used by a pickup, then the DehackedPickup sprite map // If this sprite is used by a pickup, then the DehackedPickup sprite map
// needs to be updated too. // needs to be updated too.
for (i = 0; (size_t)i < sizeof(DehSpriteMappings)/sizeof(DehSpriteMappings[0]); ++i) for (i = 0; (size_t)i < countof(DehSpriteMappings); ++i)
{ {
if (strncmp (DehSpriteMappings[i].Sprite, oldStr, 4) == 0) if (strncmp (DehSpriteMappings[i].Sprite, oldStr, 4) == 0)
{ {
@ -1853,7 +1853,7 @@ static int PatchText (int oldSize)
swap (DehSpriteMappings[i-1], DehSpriteMappings[i]); swap (DehSpriteMappings[i-1], DehSpriteMappings[i]);
--i; --i;
} }
while ((size_t)i < sizeof(DehSpriteMappings)/sizeof(DehSpriteMappings[0])-1 && while ((size_t)i < countof(DehSpriteMappings)-1 &&
strncmp (DehSpriteMappings[i+1].Sprite, newStr, 4) < 0) strncmp (DehSpriteMappings[i+1].Sprite, newStr, 4) < 0)
{ {
swap (DehSpriteMappings[i+1], DehSpriteMappings[i]); swap (DehSpriteMappings[i+1], DehSpriteMappings[i]);
@ -2359,10 +2359,10 @@ static bool LoadDehSupp ()
else if (CompareLabel ("ACTF", supp)) else if (CompareLabel ("ACTF", supp))
{ {
NumCodePtrs = GetWord (supp + 4); NumCodePtrs = GetWord (supp + 4);
if ((unsigned)NumCodePtrs != sizeof(CodePtrs)/sizeof(CodePtrs[0])) if ((unsigned)NumCodePtrs != countof(CodePtrs))
{ {
Printf ("DEHSUPP defines %d code pointers, but there should be %d\n", Printf ("DEHSUPP defines %d code pointers, but there should be %d\n",
NumCodePtrs, sizeof(CodePtrs)/sizeof(CodePtrs[0])); NumCodePtrs, countof(CodePtrs));
return false; return false;
} }
CodePtrNames = (CodePtrMap *)GetWordSpace (supp + 6, NumCodePtrs*2); CodePtrNames = (CodePtrMap *)GetWordSpace (supp + 6, NumCodePtrs*2);
@ -2670,7 +2670,7 @@ const TypeInfo *ADehackedPickup::DetermineType ()
// Look at the actor's current sprite to determine what kind of // Look at the actor's current sprite to determine what kind of
// item to pretend to me. // item to pretend to me.
int min = 0; int min = 0;
int max = sizeof(DehSpriteMappings)/sizeof(DehSpriteMappings[0]) - 1; int max = countof(DehSpriteMappings) - 1;
while (min <= max) while (min <= max)
{ {

View file

@ -2157,7 +2157,7 @@ void D_DoomMain (void)
{ {
ep = atoi (Args.GetArg(p+1)); ep = atoi (Args.GetArg(p+1));
map = p < Args.NumArgs() - 2 ? atoi (Args.GetArg(p+2)) : 10; map = p < Args.NumArgs() - 2 ? atoi (Args.GetArg(p+2)) : 10;
if ((unsigned)map > 9) if (map < 1 || map > 9)
{ {
map = ep; map = ep;
ep = 1; ep = 1;

View file

@ -730,14 +730,12 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info)
if (arc.IsStoring ()) if (arc.IsStoring ())
{ {
arc.Write (&info.netname, sizeof(info.netname)); arc.Write (&info.netname, sizeof(info.netname));
arc.Write (&info.team, sizeof(info.team));
} }
else else
{ {
arc.Read (&info.netname, sizeof(info.netname)); arc.Read (&info.netname, sizeof(info.netname));
arc.Read (&info.team, sizeof(info.team));
} }
arc << info.aimdist << info.color << info.skin << info.gender << info.neverswitch; arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch;
return arc; return arc;
} }

View file

@ -603,6 +603,14 @@ void DObject::PointerSubstitution (DObject *old, DObject *notOld)
if (playeringame[i]) if (playeringame[i])
players[i].FixPointers (old, notOld); players[i].FixPointers (old, notOld);
} }
for (i = 0; i < numsectors; ++i)
{
if (sectors[i].SoundTarget == old)
{
sectors[i].SoundTarget = static_cast<AActor *>(notOld);
}
}
} }
// Search for references to a single object and NULL them. // Search for references to a single object and NULL them.
@ -678,6 +686,18 @@ void DObject::DestroyScan ()
} while (++j); } while (++j);
} }
} }
for (i = 0; i < numsectors; ++i)
{
j = destroycount;
do
{
if (sectors[i].SoundTarget == *(destroybase + j))
{
sectors[i].SoundTarget = NULL;
}
} while (++j);
}
} }
void STACK_ARGS DObject::StaticShutdown () void STACK_ARGS DObject::StaticShutdown ()

View file

@ -180,4 +180,9 @@ struct PalEntry
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h #define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif #endif
template <typename T, size_t N>
char ( &_ArraySizeHelper( T (&array)[N] ))[N];
#define countof( array ) (sizeof( _ArraySizeHelper( array ) ))
#endif #endif

View file

@ -3,7 +3,7 @@
** **
** **
**--------------------------------------------------------------------------- **---------------------------------------------------------------------------
** Copyright 1998-2001 Randy Heit ** Copyright 1998-2006 Randy Heit
** All rights reserved. ** All rights reserved.
** **
** Redistribution and use in source and binary forms, with or without ** Redistribution and use in source and binary forms, with or without

View file

@ -916,6 +916,21 @@ FArchive &FArchive::operator<< (double &w)
return *this; return *this;
} }
FArchive &FArchive::operator<< (name &n)
{ // In an archive, a "name" is a string that might be stored multiple times,
// so it is only stored once. It is still treated as a normal string. In the
// rest of the game, a name is a unique identifier for a number.
if (m_Storing)
{
WriteName (n.GetChars());
}
else
{
n = name(ReadName());
}
return *this;
}
FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize) FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize)
{ {
WORD w; WORD w;

View file

@ -38,8 +38,7 @@
#include "doomtype.h" #include "doomtype.h"
#include "dobject.h" #include "dobject.h"
#include "tarray.h" #include "tarray.h"
#include "name.h"
class DObject;
class FFile class FFile
{ {
@ -179,6 +178,7 @@ virtual void Read (void *mem, unsigned int len);
FArchive& operator<< (float &f); FArchive& operator<< (float &f);
FArchive& operator<< (double &d); FArchive& operator<< (double &d);
FArchive& operator<< (char *&str); FArchive& operator<< (char *&str);
FArchive& operator<< (name &n);
FArchive& SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize); FArchive& SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize);
FArchive& SerializeObject (DObject *&object, TypeInfo *type); FArchive& SerializeObject (DObject *&object, TypeInfo *type);
FArchive& WriteObject (DObject *obj); FArchive& WriteObject (DObject *obj);
@ -280,12 +280,32 @@ inline FArchive &operator<< (FArchive &arc, PalEntry &p)
#include "dobject.h" #include "dobject.h"
template<class T> template<class T>
inline inline FArchive &operator<< (FArchive &arc, T* &object)
FArchive &operator<< (FArchive &arc, T* &object)
{ {
return arc.SerializeObject ((DObject*&)object, RUNTIME_CLASS(T)); return arc.SerializeObject ((DObject*&)object, RUNTIME_CLASS(T));
} }
FArchive &operator<< (FArchive &arc, const TypeInfo * &info); FArchive &operator<< (FArchive &arc, const TypeInfo * &info);
template<class T>
inline FArchive &operator<< (FArchive &arc, TArray<T> &self)
{
unsigned int i;
if (arc.IsStoring())
{
arc.WriteCount(self.Count);
}
else
{
DWORD numStored = arc.ReadCount();
self.Resize(numStored);
}
for (i = 0; i < self.Count; ++i)
{
arc << self.Array[i];
}
return arc;
}
#endif //__FARCHIVE_H__ #endif //__FARCHIVE_H__

View file

@ -1620,8 +1620,14 @@ void G_DoLoadGame ()
{ {
// Make a special case for the message printed for old savegames that don't // Make a special case for the message printed for old savegames that don't
// have this information. // have this information.
if (engine == NULL) Printf ("Savegame is from an incompatible version\n"); if (engine == NULL)
else Printf ("Savegame is from another ZDoom based engine\n"); {
Printf ("Savegame is from an incompatible version\n");
}
else
{
Printf ("Savegame is from another ZDoom-based engine\n");
}
delete png; delete png;
fclose (stdfile); fclose (stdfile);
return; return;

View file

@ -607,9 +607,9 @@ void A_Srcr2Decide (AActor *actor)
}; };
unsigned int chanceindex = actor->health / (actor->GetDefault()->health/8); unsigned int chanceindex = actor->health / (actor->GetDefault()->health/8);
if (chanceindex >= sizeof(chance)/sizeof(chance[0])) if (chanceindex >= countof(chance))
{ {
chanceindex = sizeof(chance)/sizeof(chance[0])-1; chanceindex = countof(chance) - 1;
} }
if (pr_s2d() < chance[chanceindex]) if (pr_s2d() < chance[chanceindex])

View file

@ -1,393 +0,0 @@
#include <stddef.h>
#include "actor.h"
#include "info.h"
#include "s_sound.h"
#include "m_random.h"
// I've had an instance where two machines got different values for
// this RNG. I don't know how, so I've just removed the name so that
// it won't count towards game consistancy.
static FRandom pr_afx;
// Scripted ambients --------------------------------------------------------
enum
{
afxcmd_play, // (sound)
afxcmd_playabsvol, // (sound, volume)
afxcmd_playrelvol, // (sound, volume)
afxcmd_delay, // (ticks)
afxcmd_delayrand, // (andbits)
afxcmd_end // ()
};
static ptrdiff_t AmbSndSeqInit[] =
{ // Startup
afxcmd_end
};
static ptrdiff_t AmbSndSeq1[] =
{ // Scream
afxcmd_play, (ptrdiff_t)"world/amb1",
afxcmd_end
};
static ptrdiff_t AmbSndSeq2[] =
{ // Squish
afxcmd_play, (ptrdiff_t)"world/amb2",
afxcmd_end
};
static ptrdiff_t AmbSndSeq3[] =
{ // Drops
afxcmd_play, (ptrdiff_t)"world/amb3",
afxcmd_delay, 16,
afxcmd_delayrand, 31,
afxcmd_play, (ptrdiff_t)"world/amb7",
afxcmd_delay, 16,
afxcmd_delayrand, 31,
afxcmd_play, (ptrdiff_t)"world/amb3",
afxcmd_delay, 16,
afxcmd_delayrand, 31,
afxcmd_play, (ptrdiff_t)"world/amb7",
afxcmd_delay, 16,
afxcmd_delayrand, 31,
afxcmd_play, (ptrdiff_t)"world/amb3",
afxcmd_delay, 16,
afxcmd_delayrand, 31,
afxcmd_play, (ptrdiff_t)"world/amb7",
afxcmd_delay, 16,
afxcmd_delayrand, 31,
afxcmd_end
};
static ptrdiff_t AmbSndSeq4[] =
{ // SlowFootSteps
afxcmd_play, (ptrdiff_t)"world/amb4",
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb4", -3,
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb4", -3,
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb4", -3,
afxcmd_delay, 15,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_end
};
static ptrdiff_t AmbSndSeq5[] =
{ // Heartbeat
afxcmd_play, (ptrdiff_t)"world/amb5",
afxcmd_delay, 35,
afxcmd_play, (ptrdiff_t)"world/amb5",
afxcmd_delay, 35,
afxcmd_play, (ptrdiff_t)"world/amb5",
afxcmd_delay, 35,
afxcmd_play, (ptrdiff_t)"world/amb5",
afxcmd_end
};
static ptrdiff_t AmbSndSeq6[] =
{ // Bells
afxcmd_play, (ptrdiff_t)"world/amb6",
afxcmd_delay, 17,
afxcmd_playrelvol, (ptrdiff_t)"world/amb6", -8,
afxcmd_delay, 17,
afxcmd_playrelvol, (ptrdiff_t)"world/amb6", -8,
afxcmd_delay, 17,
afxcmd_playrelvol, (ptrdiff_t)"world/amb6", -8,
afxcmd_end
};
static ptrdiff_t AmbSndSeq7[] =
{ // Growl
afxcmd_play, (ptrdiff_t)"world/amb12",
afxcmd_end
};
static ptrdiff_t AmbSndSeq8[] =
{ // Magic
afxcmd_play, (ptrdiff_t)"world/amb8",
afxcmd_end
};
static ptrdiff_t AmbSndSeq9[] =
{ // Laughter
afxcmd_play, (ptrdiff_t)"world/amb9",
afxcmd_delay, 16,
afxcmd_playrelvol, (ptrdiff_t)"world/amb9", -4,
afxcmd_delay, 16,
afxcmd_playrelvol, (ptrdiff_t)"world/amb9", -4,
afxcmd_delay, 16,
afxcmd_playrelvol, (ptrdiff_t)"world/amb10", -4,
afxcmd_delay, 16,
afxcmd_playrelvol, (ptrdiff_t)"world/amb10", -4,
afxcmd_delay, 16,
afxcmd_playrelvol, (ptrdiff_t)"world/amb10", -4,
afxcmd_end
};
static ptrdiff_t AmbSndSeq10[] =
{ // FastFootsteps
afxcmd_play, (ptrdiff_t)"world/amb4",
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb4", -3,
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb4", -3,
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb4", -3,
afxcmd_delay, 8,
afxcmd_playrelvol, (ptrdiff_t)"world/amb11", -3,
afxcmd_end
};
static ptrdiff_t *BaseAmbientSfx[] =
{
AmbSndSeqInit,
AmbSndSeq1, // Scream
AmbSndSeq2, // Squish
AmbSndSeq3, // Drops
AmbSndSeq4, // SlowFootsteps
AmbSndSeq5, // Heartbeat
AmbSndSeq6, // Bells
AmbSndSeq7, // Growl
AmbSndSeq8, // Magic
AmbSndSeq9, // Laughter
AmbSndSeq10 // FastFootsteps
};
#define NUMSNDSEQ (sizeof(BaseAmbientSfx)/sizeof(BaseAmbientSfx[0]))
// Master for all scripted ambient sounds on a level ------------------------
// Only one ambient will ever play at a time.
class AScriptedAmbientMaster : public AActor
{
DECLARE_STATELESS_ACTOR (AScriptedAmbientMaster, AActor)
public:
void BeginPlay ();
void Tick ();
void AddAmbient (size_t sfx);
void Serialize (FArchive &arc);
protected:
ptrdiff_t *AmbientSfx;
ptrdiff_t *AmbSfxPtr;
ptrdiff_t AmbSfxTics;
float AmbSfxVolume;
TArray<ptrdiff_t *> LevelAmbientSfx;
private:
byte LocateSfx (ptrdiff_t *ptr);
};
IMPLEMENT_STATELESS_ACTOR (AScriptedAmbientMaster, Heretic, -1, 0)
PROP_Flags (MF_NOSECTOR|MF_NOBLOCKMAP)
END_DEFAULTS
void AScriptedAmbientMaster::Serialize (FArchive &arc)
{
byte seq;
byte ofs;
DWORD i;
DWORD numsfx;
Super::Serialize (arc);
arc << AmbSfxTics << AmbSfxVolume;
if (arc.IsStoring ())
{
seq = LocateSfx (AmbientSfx);
ofs = (AmbSfxPtr && AmbientSfx) ? (BYTE)(AmbSfxPtr - AmbientSfx) : 255;
arc << seq << ofs;
arc.WriteCount ((DWORD)LevelAmbientSfx.Size ());
for (i = 0; i < LevelAmbientSfx.Size (); i++)
{
seq = LocateSfx (LevelAmbientSfx[i]);
arc << seq;
}
}
else
{
byte ofs;
arc << seq << ofs;
if (seq >= NUMSNDSEQ)
{
AmbientSfx = AmbSfxPtr = AmbSndSeqInit;
}
else
{
AmbientSfx = BaseAmbientSfx[seq];
AmbSfxPtr = ofs < 255 ? AmbientSfx + ofs : AmbSndSeqInit;
}
LevelAmbientSfx.Clear ();
numsfx = arc.ReadCount ();
for (i = 0; i < numsfx; i++)
{
arc << seq;
if (seq < NUMSNDSEQ)
{
ptrdiff_t *ptr = BaseAmbientSfx[seq];
LevelAmbientSfx.Push (ptr);
}
}
}
}
byte AScriptedAmbientMaster::LocateSfx (ptrdiff_t *ptr)
{
size_t i;
for (i = 0; i < NUMSNDSEQ; ++i)
{
if (BaseAmbientSfx[i] == ptr)
return (BYTE)i;
}
return 255;
}
void AScriptedAmbientMaster::BeginPlay ()
{
Super::BeginPlay ();
AmbientSfx = AmbSfxPtr = AmbSndSeqInit;
AmbSfxTics = 10*TICRATE;
AmbSfxVolume = 0.f;
LevelAmbientSfx.Clear ();
}
void AScriptedAmbientMaster::AddAmbient (size_t sfx)
{
if (sfx >= NUMSNDSEQ)
return;
ptrdiff_t *ptr = BaseAmbientSfx[sfx];
LevelAmbientSfx.Push (ptr);
}
void AScriptedAmbientMaster::Tick ()
{
// No need to call Super::Tick(), because the only effect this
// actor has on the world is aural.
ptrdiff_t cmd;
const char *sound;
bool done;
if (LevelAmbientSfx.Size () == 0)
{ // No ambient sound sequences on current level
Destroy ();
return;
}
if (--AmbSfxTics)
{
return;
}
done = false;
do
{
cmd = *AmbSfxPtr++;
switch (cmd)
{
case afxcmd_play:
sound = (const char *)(*AmbSfxPtr++);
AmbSfxVolume = (float)pr_afx() / 510.f;
S_Sound (this, CHAN_ITEM, sound, AmbSfxVolume, ATTN_NONE);
break;
case afxcmd_playabsvol:
sound = (const char *)(*AmbSfxPtr++);
AmbSfxVolume = (float)*AmbSfxPtr++ / 127.f;
S_Sound (this, CHAN_ITEM, sound, AmbSfxVolume, ATTN_NONE);
break;
case afxcmd_playrelvol:
sound = (const char *)(*AmbSfxPtr++);
AmbSfxVolume += (float)*AmbSfxPtr++ / 127.f;
if (AmbSfxVolume < 0.f)
{
AmbSfxVolume = 0.f;
}
else if (AmbSfxVolume > 1.f)
{
AmbSfxVolume = 1.f;
}
S_Sound (this, CHAN_ITEM, sound, AmbSfxVolume, ATTN_NONE);
break;
case afxcmd_delay:
AmbSfxTics = *AmbSfxPtr++;
done = true;
break;
case afxcmd_delayrand:
AmbSfxTics = pr_afx() & (*AmbSfxPtr++);
done = true;
break;
case afxcmd_end:
AmbSfxTics = 6*TICRATE + pr_afx();
AmbSfxPtr = LevelAmbientSfx[pr_afx() % LevelAmbientSfx.Size ()];
done = true;
break;
default:
DPrintf ("P_AmbientSound: Unknown afxcmd %ld", (long)cmd);
break;
}
} while (done == false);
}
// Individual ambient sound things ------------------------------------------
// They find a master (or create one if none found) and add the corresponding
// ambient sound to its list of effects and then destroy themselves.
class AScriptedAmbient : public AActor
{
DECLARE_STATELESS_ACTOR (AScriptedAmbient, AActor)
public:
void PostBeginPlay ();
};
IMPLEMENT_STATELESS_ACTOR (AScriptedAmbient, Heretic, -1, 0)
PROP_Flags (MF_NOSECTOR|MF_NOBLOCKMAP)
END_DEFAULTS
void AScriptedAmbient::PostBeginPlay ()
{
const size_t ambientNum = health - 1200;
if (ambientNum < NUMSNDSEQ)
{
AScriptedAmbientMaster *master;
TThinkerIterator<AScriptedAmbientMaster> locater;
master = locater.Next ();
if (master == NULL)
master = Spawn<AScriptedAmbientMaster> (0, 0, 0);
master->AddAmbient (ambientNum);
}
Destroy ();
}
#define ADD_AMBIENT(x) \
class AScriptedAmbient##x : public AScriptedAmbient { \
DECLARE_STATELESS_ACTOR (AScriptedAmbient##x, AScriptedAmbient) };\
IMPLEMENT_STATELESS_ACTOR (AScriptedAmbient##x, Heretic, 1199+x, 0) \
PROP_SpawnHealth (1200+x) \
END_DEFAULTS
ADD_AMBIENT (1);
ADD_AMBIENT (2);
ADD_AMBIENT (3);
ADD_AMBIENT (4);
ADD_AMBIENT (5);
ADD_AMBIENT (6);
ADD_AMBIENT (7);
ADD_AMBIENT (8);
ADD_AMBIENT (9);
ADD_AMBIENT (10);

View file

@ -303,7 +303,7 @@ void A_CentaurDropStuff (AActor *actor)
RUNTIME_CLASS(ACentaurShield) RUNTIME_CLASS(ACentaurShield)
}; };
for (int i = sizeof(DropTypes)/sizeof(DropTypes[0])-1; i >= 0; --i) for (int i = countof(DropTypes)-1; i >= 0; --i)
{ {
AActor *mo; AActor *mo;

View file

@ -626,7 +626,7 @@ void A_SerpentSpawnGibs (AActor *actor)
RUNTIME_CLASS(ASerpentGib1) RUNTIME_CLASS(ASerpentGib1)
}; };
for (int i = sizeof(GibTypes)/sizeof(GibTypes[0])-1; i >= 0; --i) for (int i = countof(GibTypes)-1; i >= 0; --i)
{ {
mo = Spawn (GibTypes[i], mo = Spawn (GibTypes[i],
actor->x+((pr_serpentgibs()-128)<<12), actor->x+((pr_serpentgibs()-128)<<12),

View file

@ -173,7 +173,7 @@ public:
#define BEGIN_DEFAULTS(actor,game,ednum,spawnid) \ #define BEGIN_DEFAULTS(actor,game,ednum,spawnid) \
BEGIN_DEFAULTS_PRE(actor) \ BEGIN_DEFAULTS_PRE(actor) \
RUNTIME_CLASS(actor), &actor::States[0], NULL, NULL, sizeof(actor::States)/sizeof(actor::States[0]), \ RUNTIME_CLASS(actor), &actor::States[0], NULL, NULL, countof(actor::States), \
BEGIN_DEFAULTS_POST(actor,game,ednum,spawnid) BEGIN_DEFAULTS_POST(actor,game,ednum,spawnid)
#define BEGIN_STATELESS_DEFAULTS(actor,game,ednum,spawnid) \ #define BEGIN_STATELESS_DEFAULTS(actor,game,ednum,spawnid) \

View file

@ -70,8 +70,6 @@
#define SELECTOR_XOFFSET (-28) #define SELECTOR_XOFFSET (-28)
#define SELECTOR_YOFFSET (-1) #define SELECTOR_YOFFSET (-1)
#define NUM_MENU_ITEMS(m) (sizeof(m)/sizeof(m[0]))
// TYPES ------------------------------------------------------------------- // TYPES -------------------------------------------------------------------
struct FSaveGameNode : public Node struct FSaveGameNode : public Node
@ -250,7 +248,7 @@ static oldmenuitem_t MainMenu[]=
static oldmenu_t MainDef = static oldmenu_t MainDef =
{ {
NUM_MENU_ITEMS (MainMenu), countof(MainMenu),
MainMenu, MainMenu,
M_DrawMainMenu, M_DrawMainMenu,
97,64, 97,64,
@ -271,7 +269,7 @@ static oldmenuitem_t HereticMainMenu[] =
static oldmenu_t HereticMainDef = static oldmenu_t HereticMainDef =
{ {
NUM_MENU_ITEMS (HereticMainMenu), countof(HereticMainMenu),
HereticMainMenu, HereticMainMenu,
M_DrawHereticMainMenu, M_DrawHereticMainMenu,
110, 56, 110, 56,
@ -334,7 +332,7 @@ static oldmenuitem_t FilesItems[] =
static oldmenu_t FilesMenu = static oldmenu_t FilesMenu =
{ {
NUM_MENU_ITEMS (FilesItems), countof(FilesItems),
FilesItems, FilesItems,
M_DrawFiles, M_DrawFiles,
110,60, 110,60,
@ -355,7 +353,7 @@ static oldmenuitem_t NewGameMenu[]=
static oldmenu_t NewDef = static oldmenu_t NewDef =
{ {
NUM_MENU_ITEMS (NewGameMenu), countof(NewGameMenu),
NewGameMenu, // oldmenuitem_t -> NewGameMenu, // oldmenuitem_t ->
M_DrawNewGame, // drawing routine -> M_DrawNewGame, // drawing routine ->
48,63, // x,y 48,63, // x,y
@ -376,7 +374,7 @@ static oldmenuitem_t HereticSkillItems[] =
static oldmenu_t HereticSkillMenu = static oldmenu_t HereticSkillMenu =
{ {
NUM_MENU_ITEMS (HereticSkillItems), countof(HereticSkillItems),
HereticSkillItems, HereticSkillItems,
M_DrawNewGame, M_DrawNewGame,
38, 30, 38, 30,
@ -421,7 +419,7 @@ static oldmenuitem_t PlayerSetupMenu[] =
static oldmenu_t PSetupDef = static oldmenu_t PSetupDef =
{ {
NUM_MENU_ITEMS (PlayerSetupMenu), countof(PlayerSetupMenu),
PlayerSetupMenu, PlayerSetupMenu,
M_PlayerSetupDrawer, M_PlayerSetupDrawer,
48, 47, 48, 47,
@ -462,7 +460,7 @@ static oldmenuitem_t LoadMenu[]=
static oldmenu_t LoadDef = static oldmenu_t LoadDef =
{ {
NUM_MENU_ITEMS(LoadMenu), countof(LoadMenu),
LoadMenu, LoadMenu,
M_DrawLoad, M_DrawLoad,
80,54, 80,54,
@ -486,7 +484,7 @@ static oldmenuitem_t SaveMenu[] =
static oldmenu_t SaveDef = static oldmenu_t SaveDef =
{ {
NUM_MENU_ITEMS(LoadMenu), countof(LoadMenu),
SaveMenu, SaveMenu,
M_DrawSave, M_DrawSave,
80,54, 80,54,

View file

@ -160,7 +160,7 @@ static menuitem_t ConfirmItems[] = {
static menu_t ConfirmMenu = { static menu_t ConfirmMenu = {
"PLEASE CONFIRM", "PLEASE CONFIRM",
3, 3,
sizeof(ConfirmItems)/sizeof(ConfirmItems[0]), countof(ConfirmItems),
140, 140,
ConfirmItems, ConfirmItems,
}; };
@ -208,7 +208,7 @@ menu_t OptionMenu =
{ {
"OPTIONS", "OPTIONS",
0, 0,
sizeof(OptionItems)/sizeof(OptionItems[0]), countof(OptionItems),
0, 0,
OptionItems, OptionItems,
}; };
@ -253,7 +253,7 @@ menu_t MouseMenu =
{ {
"MOUSE OPTIONS", "MOUSE OPTIONS",
0, 0,
sizeof(MouseItems)/sizeof(MouseItems[0]), countof(MouseItems),
0, 0,
MouseItems, MouseItems,
}; };
@ -349,7 +349,7 @@ menu_t JoystickMenu =
{ {
"JOYSTICK OPTIONS", "JOYSTICK OPTIONS",
0, 0,
sizeof(JoystickItems)/sizeof(JoystickItems[0]), countof(JoystickItems),
0, 0,
JoystickItems, JoystickItems,
}; };
@ -422,7 +422,7 @@ menu_t ControlsMenu =
{ {
"CUSTOMIZE CONTROLS", "CUSTOMIZE CONTROLS",
3, 3,
sizeof(ControlsItems)/sizeof(ControlsItems[0]), countof(ControlsItems),
0, 0,
ControlsItems, ControlsItems,
2, 2,
@ -519,7 +519,7 @@ menu_t VideoMenu =
{ {
"DISPLAY OPTIONS", "DISPLAY OPTIONS",
0, 0,
sizeof(VideoItems)/sizeof(VideoItems[0]), countof(VideoItems),
0, 0,
VideoItems, VideoItems,
}; };
@ -573,7 +573,7 @@ menu_t AutomapMenu =
{ {
"AUTOMAP OPTIONS", "AUTOMAP OPTIONS",
0, 0,
sizeof(AutomapItems)/sizeof(AutomapItems[0]), countof(AutomapItems),
0, 0,
AutomapItems, AutomapItems,
}; };
@ -651,7 +651,7 @@ menu_t MapColorsMenu =
{ {
"CUSTOMIZE MAP COLORS", "CUSTOMIZE MAP COLORS",
0, 0,
sizeof(MapColorsItems)/sizeof(MapColorsItems[0]), countof(MapColorsItems),
48, 48,
MapColorsItems, MapColorsItems,
}; };
@ -699,7 +699,7 @@ menu_t ColorPickerMenu =
{ {
"SELECT COLOR", "SELECT COLOR",
2, 2,
sizeof(ColorPickerItems)/sizeof(ColorPickerItems[0]), countof(ColorPickerItems),
0, 0,
ColorPickerItems, ColorPickerItems,
}; };
@ -931,7 +931,7 @@ static menu_t DMFlagsMenu =
{ {
"GAMEPLAY OPTIONS", "GAMEPLAY OPTIONS",
0, 0,
sizeof(DMFlagsItems)/sizeof(DMFlagsItems[0]), countof(DMFlagsItems),
0, 0,
DMFlagsItems, DMFlagsItems,
}; };
@ -963,7 +963,7 @@ static menu_t CompatibilityMenu =
{ {
"COMPATIBILITY OPTIONS", "COMPATIBILITY OPTIONS",
0, 0,
sizeof(CompatibilityItems)/sizeof(CompatibilityItems[0]), countof(CompatibilityItems),
0, 0,
CompatibilityItems, CompatibilityItems,
}; };
@ -1044,7 +1044,7 @@ static menu_t SoundMenu =
{ {
"SOUND OPTIONS", "SOUND OPTIONS",
0, 0,
sizeof(SoundItems)/sizeof(SoundItems[0]), countof(SoundItems),
0, 0,
SoundItems, SoundItems,
}; };
@ -1106,7 +1106,7 @@ static menu_t AdvSoundMenu =
{ {
"ADVANCED SOUND OPTIONS", "ADVANCED SOUND OPTIONS",
1, 1,
sizeof(AdvSoundItems)/sizeof(AdvSoundItems[0]), countof(AdvSoundItems),
0, 0,
AdvSoundItems, AdvSoundItems,
}; };
@ -2872,7 +2872,7 @@ void M_SaveCustomKeys (FConfigFile *config, char *section, char *subsection)
return; return;
// Start after the normal controls // Start after the normal controls
unsigned int i = sizeof(ControlsItems)/sizeof(ControlsItems[0]); unsigned int i = countof(ControlsItems);
unsigned int most = CustomControlsItems.Size(); unsigned int most = CustomControlsItems.Size();
while (i < most) while (i < most)
@ -2903,7 +2903,7 @@ CCMD (addkeysection)
return; return;
} }
const int numStdControls = sizeof(ControlsItems)/sizeof(ControlsItems[0]); const int numStdControls = countof(ControlsItems);
int i; int i;
if (ControlsMenu.items == ControlsItems) if (ControlsMenu.items == ControlsItems)

View file

@ -127,17 +127,33 @@ int FRandom::operator() ()
return (UpdateSeed (Seed) >> 20) & 255; return (UpdateSeed (Seed) >> 20) & 255;
} }
int FRandom::operator() (int mod)
{
if (mod <= 256)
{ // The mod is small enough, so a byte is enough to get a good number.
return (*this)() % mod;
}
else
{ // For mods > 256, construct a 32-bit int and modulo that.
int num = (*this)();
num = (num << 8) | (*this)();
num = (num << 8) | (*this)();
num = (num << 8) | (*this)();
return num % mod;
}
}
int FRandom::Random2 () int FRandom::Random2 ()
{ {
int t = (UpdateSeed (Seed) >> 20) & 255; int t = (*this)();
int u = (UpdateSeed (Seed) >> 20) & 255; int u = (*this)();
return t - u; return t - u;
} }
int FRandom::Random2 (int mask) int FRandom::Random2 (int mask)
{ {
int t = (UpdateSeed (Seed) >> 20) & mask; int t = (*this)();
int u = (UpdateSeed (Seed) >> 20) & mask; int u = (*this)();
return t - u; return t - u;
} }

View file

@ -63,9 +63,10 @@ public:
~FRandom (); ~FRandom ();
int operator() (); // Returns a random number in the range [0,255] int operator() (); // Returns a random number in the range [0,255]
int operator() (int mod); // Returns a random number in the range [0,mod)
int Random2(); // Returns rand# - rand# int Random2(); // Returns rand# - rand#
int Random2(int mask); // Returns (rand# & mask) - (rand# & mask) int Random2(int mask); // Returns (rand# & mask) - (rand# & mask)
int HitDice (int count); // HITDICE macro used in Heretic and Hexen int HitDice(int count); // HITDICE macro used in Heretic and Hexen
int Random() // synonym for () int Random() // synonym for ()
{ {

View file

@ -2,6 +2,14 @@
#include "name.h" #include "name.h"
#include "c_dispatch.h" #include "c_dispatch.h"
// Define the predefined names.
static const char *PredefinedNames[] =
{
#define xx(n) #n,
#include "namedef.h"
#undef xx
};
int name::Buckets[name::HASH_SIZE]; int name::Buckets[name::HASH_SIZE];
TArray<name::MainName> name::NameArray; TArray<name::MainName> name::NameArray;
bool name::Inited; bool name::Inited;
@ -14,6 +22,11 @@ int name::FindName (const char *text, bool noCreate)
{ {
if (!Inited) InitBuckets (); if (!Inited) InitBuckets ();
if (text == NULL)
{
return 0;
}
int hash = MakeKey (text) % HASH_SIZE; int hash = MakeKey (text) % HASH_SIZE;
int scanner = Buckets[hash]; int scanner = Buckets[hash];
@ -44,10 +57,17 @@ int name::FindName (const char *text, bool noCreate)
void name::InitBuckets () void name::InitBuckets ()
{ {
size_t i;
Inited = true; Inited = true;
for (int i = 0; i < HASH_SIZE; ++i) for (i = 0; i < HASH_SIZE; ++i)
{ {
Buckets[i] = -1; Buckets[i] = -1;
} }
name::FindName ("None", false); // 'None' is always name 0.
// Register built-in names. 'None' must be name 0.
for (i = 0; i < countof(PredefinedNames); ++i)
{
FindName (PredefinedNames[i], false);
}
} }

View file

@ -6,7 +6,9 @@
enum ENamedName enum ENamedName
{ {
NAME_None #define xx(n) NAME_##n,
#include "namedef.h"
#undef xx
}; };
class name class name

113
src/namedef.h Normal file
View file

@ -0,0 +1,113 @@
// 'None' must always be the first name.
xx(None)
// Hexen sound sequence names
xx(Platform)
xx(PlatformMetal)
xx(Silence)
xx(Lava)
xx(Water)
xx(Ice)
xx(Earth)
xx(PlatformMetal2)
xx(DoorNormal)
xx(DoorHeavy)
xx(DoorMetal)
xx(DoorCreak)
xx(DoorMetal2)
xx(Wind)
#if 0
xx(Super)
xx(Object)
// Special bosses A_BossDeath knows about
xx(Fatso)
xx(Arachnotron)
xx(BaronOfHell)
xx(Cyberdemon)
xx(SpiderMastermind)
xx(Ironlich)
xx(Minotaur)
xx(Sorcerer2)
// Standard player classes
xx(DoomPlayer)
xx(HereticPlayer)
xx(StrifePlayer)
xx(FighterPlayer)
xx(ClericPlayer)
xx(MagePlayer)
// Weapon names for the Strife status bar
xx(StrifeCrossbow)
xx(AssaultGun)
xx(FlameThrower)
xx(MiniMissileLauncher)
xx(StrifeGrenadeLauncher)
xx(Mauler)
// Flechette names for the different Hexen player classes
xx(ArtiPoisonBag1)
xx(ArtiPoisonBag2)
xx(ArtiPoisonBag3)
// P_SpawnMapThing checks for these as health items (I smell a FIXME)
xx(Berserk)
xx(Soulsphere)
xx(Megasphere) // also counts as armor for P_SpawnMapThing
// Standard animator names.
xx(Spawn)
xx(See)
xx(Pain)
xx(Melee)
xx(Missile)
xx(Crash)
xx(Death)
xx(Raise)
xx(Wound)
// Weapon animator names.
xx(Up)
xx(Down)
xx(Ready)
xx(Flash)
xx(Attack)
xx(HoldAttack)
xx(AltAttack)
xx(AltHoldAttack)
// Special death name for getting killed excessively. Could be used as
// a damage type if you wanted to force an extreme death.
xx(Extreme)
// Damage types
xx(Fire)
xx(Ice)
xx(Disintegrate)
xx(Water)
xx(Slime)
xx(Crush)
xx(Telefrag)
xx(Falling)
xx(Suicide)
xx(Exit)
xx(Railgun)
xx(Poison)
xx(Electric)
xx(BFGSplash)
xx(DrainLife) // A weapon like the Sigil that drains your life away.
xx(Massacre) // For death by a cheater!
//(Melee) already defined above, so don't define it again
// Compatible death names for the decorate parser.
xx(XDeath)
xx(BDeath)
xx(IDeath)
xx(EDeath)
// State names used by ASwitchableDecoration
xx(Active)
xx(Inactive)
#endif

View file

@ -1588,30 +1588,12 @@ void DLevelScript::PutFirst ()
int DLevelScript::Random (int min, int max) int DLevelScript::Random (int min, int max)
{ {
int num1, num2, num3, num4;
unsigned int num;
if (max < min) if (max < min)
{ {
swap (max, min); swap (max, min);
} }
if (max - min > 255) return min + pr_acs(max - min + 1);
{
num1 = pr_acs();
num2 = pr_acs();
num3 = pr_acs();
num4 = pr_acs();
num = ((num1 << 24) | (num2 << 16) | (num3 << 8) | num4);
}
else
{
num = pr_acs();
}
num %= (max - min + 1);
num += min;
return (int)num;
} }
int DLevelScript::ThingCount (int type, int tid) int DLevelScript::ThingCount (int type, int tid)
@ -3544,9 +3526,7 @@ int DLevelScript::RunScript ()
{ {
if (activationline) if (activationline)
{ {
SN_StartSequence ( SN_StartSequence (activationline->frontsector, lookup, 0);
activationline->frontsector,
lookup);
} }
} }
sp--; sp--;

View file

@ -63,16 +63,16 @@ void DCeiling::PlayCeilingSound ()
{ {
if (m_Sector->seqType >= 0) if (m_Sector->seqType >= 0)
{ {
SN_StartSequence (m_Sector, m_Sector->seqType, SEQ_PLATFORM); SN_StartSequence (m_Sector, m_Sector->seqType, SEQ_PLATFORM, 0);
} }
else else
{ {
if (m_Silent == 2) if (m_Silent == 2)
SN_StartSequence (m_Sector, "Silence"); SN_StartSequence (m_Sector, "Silence", 0);
else if (m_Silent == 1) else if (m_Silent == 1)
SN_StartSequence (m_Sector, "CeilingSemiSilent"); SN_StartSequence (m_Sector, "CeilingSemiSilent", 0);
else else
SN_StartSequence (m_Sector, "CeilingNormal"); SN_StartSequence (m_Sector, "CeilingNormal", 0);
} }
} }

View file

@ -205,47 +205,41 @@ void DDoor::Tick ()
// [RH] DoorSound: Plays door sound depending on direction and speed // [RH] DoorSound: Plays door sound depending on direction and speed
void DDoor::DoorSound (bool raise) const void DDoor::DoorSound (bool raise) const
{ {
const char *snd = ""; int choice;
// For multiple-selection sound sequences, the following choices are used:
// 0 Opening
// 1 Closing
// 2 Opening fast
// 3 Closing fast
choice = !raise;
if (m_Speed >= FRACUNIT*8)
{
choice += 2;
}
if (m_Sector->seqType >= 0) if (m_Sector->seqType >= 0)
{ {
SN_StartSequence (m_Sector, m_Sector->seqType, SEQ_DOOR); SN_StartSequence (m_Sector, m_Sector->seqType, SEQ_DOOR, choice);
} }
else else
{ {
const char *snd;
switch (gameinfo.gametype) switch (gameinfo.gametype)
{ {
default: /* Doom and Hexen */
default:
break;
case GAME_Hexen:
snd = "DoorNormal"; snd = "DoorNormal";
break; break;
case GAME_Heretic: case GAME_Heretic:
snd = raise ? "HereticDoorOpen" : "HereticDoorClose"; snd = "HereticDoor";
break;
case GAME_Doom:
if (m_Speed >= 8*FRACUNIT)
{
snd = raise ? "DoorOpenBlazing" : "DoorCloseBlazing";
}
else
{
snd = raise ? "DoorOpenNormal" : "DoorCloseNormal";
}
break; break;
case GAME_Strife: case GAME_Strife:
if (m_Speed >= FRACUNIT*8) snd = "DoorSmallMetal";
{
snd = raise ? "DoorOpenBlazing" : "DoorCloseBlazing";
}
else
{
snd = raise ? "DoorOpenSmallMetal" : "DoorCloseSmallMetal";
// Search the front top textures of 2-sided lines on the door sector // Search the front top textures of 2-sided lines on the door sector
// for a door sound to use. // for a door sound to use.
@ -258,41 +252,37 @@ void DDoor::DoorSound (bool raise) const
continue; continue;
texname = TexMan[sides[line->sidenum[0]].toptexture]->Name; texname = TexMan[sides[line->sidenum[0]].toptexture]->Name;
if (strncmp (texname, "DOR", 3) == 0) if (texname[0] == 'D' && texname[1] == 'O' && texname[2] == 'R')
{ {
switch (texname[3]) switch (texname[3])
{ {
case 'S': case 'S':
snd = raise ? "DoorOpenStone" : "DoorCloseStone"; snd = "DoorStone";
break; break;
case 'M': case 'M':
if (texname[4] == 'L') if (texname[4] == 'L')
{ {
snd = raise ? "DoorOpenLargeMetal" : "DoorCloseLargeMetal"; snd = "DoorLargeMetal";
} }
break; break;
case 'W': case 'W':
if (texname[4] == 'L') if (texname[4] == 'L')
{ {
snd = raise ? "DoorOpenLargeWood" : "DoorCloseLargeWood"; snd = "DoorLargeWood";
} }
else else
{ {
snd = raise ? "DoorOpenSmallWood" : "DoorCloseSmallWood"; snd = "DoorSmallWood";
} }
break; break;
} }
} }
} }
}
break; break;
} }
if (snd != NULL) SN_StartSequence (m_Sector, snd, choice);
{
SN_StartSequence (m_Sector, snd);
}
} }
} }
@ -532,7 +522,7 @@ bool DAnimatedDoor::StartClosing ()
m_Line2->flags |= ML_BLOCKING; m_Line2->flags |= ML_BLOCKING;
if (ani.CloseSound != NULL) if (ani.CloseSound != NULL)
{ {
SN_StartSequence (m_Sector, ani.CloseSound); SN_StartSequence (m_Sector, ani.CloseSound, 1);
} }
m_Status = Closing; m_Status = Closing;
@ -713,7 +703,7 @@ DAnimatedDoor::DAnimatedDoor (sector_t *sec, line_t *line, int speed, int delay)
MoveCeiling (2048*FRACUNIT, topdist, 1); MoveCeiling (2048*FRACUNIT, topdist, 1);
if (DoorAnimations[m_WhichDoorIndex].OpenSound != NULL) if (DoorAnimations[m_WhichDoorIndex].OpenSound != NULL)
{ {
SN_StartSequence (m_Sector, DoorAnimations[m_WhichDoorIndex].OpenSound); SN_StartSequence (m_Sector, DoorAnimations[m_WhichDoorIndex].OpenSound, 1);
} }
} }

View file

@ -280,11 +280,11 @@ static void StartFloorSound (sector_t *sec)
{ {
if (sec->seqType >= 0) if (sec->seqType >= 0)
{ {
SN_StartSequence (sec, sec->seqType, SEQ_PLATFORM); SN_StartSequence (sec, sec->seqType, SEQ_PLATFORM, 0);
} }
else else
{ {
SN_StartSequence (sec, "Floor"); SN_StartSequence (sec, "Floor", 0);
} }
} }

View file

@ -167,9 +167,9 @@ DPillar::DPillar (sector_t *sector, EPillar type, fixed_t speed,
} }
if (sector->seqType >= 0) if (sector->seqType >= 0)
SN_StartSequence (sector, sector->seqType, SEQ_PLATFORM); SN_StartSequence (sector, sector->seqType, SEQ_PLATFORM, 0);
else else
SN_StartSequence (sector, "Floor"); SN_StartSequence (sector, "Floor", 0);
} }
bool EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height, bool EV_DoPillar (DPillar::EPillar type, int tag, fixed_t speed, fixed_t height,

View file

@ -58,9 +58,9 @@ void DPlat::Serialize (FArchive &arc)
void DPlat::PlayPlatSound (const char *sound) void DPlat::PlayPlatSound (const char *sound)
{ {
if (m_Sector->seqType >= 0) if (m_Sector->seqType >= 0)
SN_StartSequence (m_Sector, m_Sector->seqType, SEQ_PLATFORM); SN_StartSequence (m_Sector, m_Sector->seqType, SEQ_PLATFORM, 0);
else else
SN_StartSequence (m_Sector, sound); SN_StartSequence (m_Sector, sound, 0);
} }
// //
@ -168,7 +168,7 @@ void DPlat::Tick ()
m_Status = down; m_Status = down;
if (m_Type == platToggle) if (m_Type == platToggle)
SN_StartSequence (m_Sector, "Silence"); SN_StartSequence (m_Sector, "Silence", 0);
else else
PlayPlatSound ("Platform"); PlayPlatSound ("Platform");
} }
@ -346,7 +346,7 @@ manual_plat:
plat->m_Low = sec->floorplane.PointToDist (spot, newheight); plat->m_Low = sec->floorplane.PointToDist (spot, newheight);
plat->m_High = sec->floorplane.d; plat->m_High = sec->floorplane.d;
plat->m_Status = DPlat::down; plat->m_Status = DPlat::down;
SN_StartSequence (sec, "Silence"); SN_StartSequence (sec, "Silence", 0);
break; break;
case DPlat::platDownToNearestFloor: case DPlat::platDownToNearestFloor:

View file

@ -46,23 +46,230 @@
#include "v_palette.h" #include "v_palette.h"
#include "a_sharedglobal.h" #include "a_sharedglobal.h"
extern void P_SpawnPlayer (mapthing2_t *mthing);
static void CopyPlayer (player_t *dst, player_t *src, const char *name);
static void ReadOnePlayer (FArchive &arc);
static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow);
static void SpawnExtraPlayers ();
// //
// P_ArchivePlayers // P_ArchivePlayers
// //
void P_SerializePlayers (FArchive &arc) void P_SerializePlayers (FArchive &arc)
{ {
BYTE numPlayers, numPlayersNow;
int i; int i;
for (i = 0; i < MAXPLAYERS; i++) // Count the number of players present right now.
for (numPlayersNow = 0, i = 0; i < MAXPLAYERS; ++i)
{ {
arc << playeringame[i];
if (playeringame[i]) if (playeringame[i])
{ {
++numPlayersNow;
}
}
if (arc.IsStoring())
{
// Record the number of players in this save.
arc << numPlayersNow;
// Record each player's name, followed by their data.
for (i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
{
arc.WriteString (players[i].userinfo.netname);
players[i].Serialize (arc); players[i].Serialize (arc);
} }
} }
}
else
{
arc << numPlayers;
// If there is only one player in the game, they go to the
// first player present, no matter what their name.
if (numPlayers == 1)
{
ReadOnePlayer (arc);
}
else
{
ReadMultiplePlayers (arc, numPlayers, numPlayersNow);
}
if (numPlayersNow > numPlayers)
{
SpawnExtraPlayers ();
}
}
}
static void ReadOnePlayer (FArchive &arc)
{
int i;
char *name = NULL;
bool didIt = false;
arc << name;
for (i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i])
{
if (!didIt)
{
didIt = true;
player_t playerTemp;
memset (&playerTemp, 0, sizeof(playerTemp));
playerTemp.Serialize (arc);
CopyPlayer (&players[i], &playerTemp, name);
}
else
{
if (players[i].mo != NULL)
{
players[i].mo->Destroy();
players[i].mo = NULL;
}
}
}
}
delete[] name;
}
static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNow)
{
// For two or more players, read each player into a temporary array.
int i, j;
char **nametemp = new char *[numPlayers];
player_t *playertemp = new player_t[numPlayers];
BYTE *tempPlayerUsed = new BYTE[numPlayers];
BYTE *playerUsed = new BYTE[MAXPLAYERS];
memset (playertemp, 0, numPlayers*sizeof(player_t));
for (i = 0; i < numPlayers; ++i)
{
nametemp[i] = NULL;
arc << nametemp[i];
playertemp[i].Serialize (arc);
tempPlayerUsed[i] = 0;
}
for (i = 0; i < MAXPLAYERS; ++i)
{
playerUsed[i] = playeringame[i] ? 0 : 2;
}
// Now try to match players from the savegame with players present
// based on their names. If two players in the savegame have the
// same name, then they are assigned to players in the current game
// on a first-come, first-served basis.
for (i = 0; i < numPlayers; ++i)
{
for (j = 0; j < MAXPLAYERS; ++j)
{
if (playerUsed[j] == 0 && stricmp(players[j].userinfo.netname, nametemp[i]) == 0)
{ // Found a match, so copy our temp player to the real player
Printf ("Found player %d (%s) at %d\n", i, nametemp[i], j);
CopyPlayer (&players[j], &playertemp[i], nametemp[i]);
playerUsed[j] = 1;
tempPlayerUsed[i] = 1;
break;
}
}
}
// Any players that didn't have matching names are assigned to existing
// players on a first-come, first-served basis.
for (i = 0; i < numPlayers; ++i)
{
if (tempPlayerUsed[i] == 0)
{
for (j = 0; j < MAXPLAYERS; ++j)
{
if (playerUsed[j] == 0)
{
Printf ("Assigned player %d (%s) to %d (%s)\n", i, nametemp[i], j, players[j].userinfo.netname);
CopyPlayer (&players[j], &playertemp[i], nametemp[i]);
playerUsed[j] = 1;
tempPlayerUsed[i] = 1;
break;
}
}
}
}
// Make sure any extra players don't have actors spawned yet.
for (j = 0; j < MAXPLAYERS; ++j)
{
if (playerUsed[j] == 0)
{
if (players[j].mo != NULL)
{
players[j].mo->Destroy();
players[j].mo = NULL;
}
}
}
delete[] playerUsed;
delete[] tempPlayerUsed;
delete[] playertemp;
for (i = 0; i < numPlayers; ++i)
{
delete[] nametemp[i];
}
delete[] nametemp;
}
static void CopyPlayer (player_t *dst, player_t *src, const char *name)
{
// The userinfo needs to be saved for real players, but it
// needs to come from the save for bots.
userinfo_t uibackup = dst->userinfo;
memcpy (dst, src, sizeof(player_t));
if (dst->isbot)
{
botinfo_t *thebot = bglobal.botinfo;
while (thebot && stricmp (name, thebot->name))
{
thebot = thebot->next;
}
if (thebot)
{
thebot->inuse = true;
}
bglobal.botnum++;
bglobal.botingame[dst - players] = true;
}
else
{
dst->userinfo = uibackup;
}
}
static void SpawnExtraPlayers ()
{
// If there are more players now than there were in the savegame,
// be sure to spawn the extra players.
int i;
if (deathmatch)
{
return;
}
for (i = 0; i < MAXPLAYERS; ++i)
{
if (playeringame[i] && players[i].mo == NULL)
{
players[i].playerstate = PST_ENTER;
P_SpawnPlayer (&playerstarts[i]);
}
}
} }
// //

View file

@ -1354,25 +1354,13 @@ void P_UnPredictPlayer ()
void player_s::Serialize (FArchive &arc) void player_s::Serialize (FArchive &arc)
{ {
int i; int i;
userinfo_t *ui;
userinfo_t dummy;
if (arc.IsStoring ()) arc << cls
{ << mo
arc.UserWriteClass (cls);
ui = &userinfo;
}
else
{
arc.UserReadClass (cls);
ui = &dummy;
}
arc << mo
<< camera << camera
<< playerstate << playerstate
<< cmd << cmd
<< *ui << userinfo
<< DesiredFOV << FOV << DesiredFOV << FOV
<< viewz << viewz
<< viewheight << viewheight
@ -1452,22 +1440,6 @@ void player_s::Serialize (FArchive &arc)
<< allround << allround
<< oldx << oldx
<< oldy; << oldy;
if (arc.IsLoading ())
{
if (consoleplayer != this - players)
{
userinfo = *ui;
}
botinfo_t *thebot = bglobal.botinfo;
while (thebot && stricmp (userinfo.netname, thebot->name))
thebot = thebot->next;
if (thebot)
{
thebot->inuse = true;
}
bglobal.botnum++;
bglobal.botingame[this - players] = true;
}
} }
else else
{ {

View file

@ -254,7 +254,7 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
} }
pe->m_Speed = (speed*direction*(ANGLE_90/64))>>3; pe->m_Speed = (speed*direction*(ANGLE_90/64))>>3;
poly->specialdata = pe; poly->specialdata = pe;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
while ( (mirror = GetPolyobjMirror( polyNum)) ) while ( (mirror = GetPolyobjMirror( polyNum)) )
{ {
@ -287,7 +287,7 @@ bool EV_RotatePoly (line_t *line, int polyNum, int speed, int byteAngle,
direction = -direction; direction = -direction;
pe->m_Speed = (speed*direction*(ANGLE_90/64))>>3; pe->m_Speed = (speed*direction*(ANGLE_90/64))>>3;
polyNum = mirror; polyNum = mirror;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
return true; return true;
} }
@ -360,7 +360,7 @@ bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle,
pe->m_Angle = an>>ANGLETOFINESHIFT; pe->m_Angle = an>>ANGLETOFINESHIFT;
pe->m_xSpeed = FixedMul (pe->m_Speed, finecosine[pe->m_Angle]); pe->m_xSpeed = FixedMul (pe->m_Speed, finecosine[pe->m_Angle]);
pe->m_ySpeed = FixedMul (pe->m_Speed, finesine[pe->m_Angle]); pe->m_ySpeed = FixedMul (pe->m_Speed, finesine[pe->m_Angle]);
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
// Do not interpolate very fast moving polyobjects. The minimum tic count is // Do not interpolate very fast moving polyobjects. The minimum tic count is
// 3 instead of 2, because the moving crate effect in Massmouth 2, Hostitality // 3 instead of 2, because the moving crate effect in Massmouth 2, Hostitality
@ -387,7 +387,7 @@ bool EV_MovePoly (line_t *line, int polyNum, int speed, angle_t angle,
pe->m_xSpeed = FixedMul (pe->m_Speed, finecosine[pe->m_Angle]); pe->m_xSpeed = FixedMul (pe->m_Speed, finecosine[pe->m_Angle]);
pe->m_ySpeed = FixedMul (pe->m_Speed, finesine[pe->m_Angle]); pe->m_ySpeed = FixedMul (pe->m_Speed, finesine[pe->m_Angle]);
polyNum = mirror; polyNum = mirror;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
if (dist/speed <= 2) if (dist/speed <= 2)
{ {
pe->StopInterpolation (); pe->StopInterpolation ();
@ -412,7 +412,7 @@ void DPolyDoor::Tick ()
if (!--m_Tics) if (!--m_Tics)
{ {
poly = GetPolyobj (m_PolyObj); poly = GetPolyobj (m_PolyObj);
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, m_Close);
} }
return; return;
} }
@ -462,7 +462,7 @@ void DPolyDoor::Tick ()
m_xSpeed = -m_xSpeed; m_xSpeed = -m_xSpeed;
m_ySpeed = -m_ySpeed; m_ySpeed = -m_ySpeed;
m_Close = false; m_Close = false;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
} }
break; break;
@ -509,7 +509,7 @@ void DPolyDoor::Tick ()
m_Dist = m_TotalDist - m_Dist; m_Dist = m_TotalDist - m_Dist;
m_Speed = -m_Speed; m_Speed = -m_Speed;
m_Close = false; m_Close = false;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
} }
break; break;
@ -552,7 +552,7 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle,
pd->m_Direction = angle >> ANGLETOFINESHIFT; pd->m_Direction = angle >> ANGLETOFINESHIFT;
pd->m_xSpeed = FixedMul (pd->m_Speed, finecosine[pd->m_Direction]); pd->m_xSpeed = FixedMul (pd->m_Speed, finecosine[pd->m_Direction]);
pd->m_ySpeed = FixedMul (pd->m_Speed, finesine[pd->m_Direction]); pd->m_ySpeed = FixedMul (pd->m_Speed, finesine[pd->m_Direction]);
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
else if (type == PODOOR_SWING) else if (type == PODOOR_SWING)
{ {
@ -560,7 +560,7 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle,
pd->m_Direction = 1; // ADD: PODOOR_SWINGL, PODOOR_SWINGR pd->m_Direction = 1; // ADD: PODOOR_SWINGL, PODOOR_SWINGR
pd->m_Speed = (speed*pd->m_Direction*(ANGLE_90/64))>>3; pd->m_Speed = (speed*pd->m_Direction*(ANGLE_90/64))>>3;
pd->m_Dist = pd->m_TotalDist = angle; pd->m_Dist = pd->m_TotalDist = angle;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
poly->specialdata = pd; poly->specialdata = pd;
@ -582,7 +582,7 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle,
pd->m_Direction = (angle + ANGLE_180) >> ANGLETOFINESHIFT; // reverse the angle pd->m_Direction = (angle + ANGLE_180) >> ANGLETOFINESHIFT; // reverse the angle
pd->m_xSpeed = FixedMul (pd->m_Speed, finecosine[pd->m_Direction]); pd->m_xSpeed = FixedMul (pd->m_Speed, finecosine[pd->m_Direction]);
pd->m_ySpeed = FixedMul (pd->m_Speed, finesine[pd->m_Direction]); pd->m_ySpeed = FixedMul (pd->m_Speed, finesine[pd->m_Direction]);
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
else if (type == PODOOR_SWING) else if (type == PODOOR_SWING)
{ {
@ -590,7 +590,7 @@ bool EV_OpenPolyDoor (line_t *line, int polyNum, int speed, angle_t angle,
pd->m_Direction = -1; // ADD: same as above pd->m_Direction = -1; // ADD: same as above
pd->m_Speed = (speed*pd->m_Direction*(ANGLE_90/64))>>3; pd->m_Speed = (speed*pd->m_Direction*(ANGLE_90/64))>>3;
pd->m_Dist = pd->m_TotalDist = angle; pd->m_Dist = pd->m_TotalDist = angle;
SN_StartSequence (poly, poly->seqType, SEQ_DOOR); SN_StartSequence (poly, poly->seqType, SEQ_DOOR, 0);
} }
polyNum = mirror; polyNum = mirror;
} }

View file

@ -645,9 +645,9 @@ void FTextureManager::AddTexturesLump (const void *lumpdata, int lumpsize, int p
// Check whether the amount of names reported is correct. // Check whether the amount of names reported is correct.
int lumplength = Wads.LumpLength(patcheslump); int lumplength = Wads.LumpLength(patcheslump);
if (numpatches > (lumplength-4)/8) if (numpatches > DWORD((lumplength-4)/8))
{ {
Printf("PNAMES lump is shorter than required (%ld entries reported but only %d bytes (%ld entries) long\n", Printf("PNAMES lump is shorter than required (%ld entries reported but only %d bytes (%d entries) long\n",
numpatches, lumplength, (lumplength-4)/8); numpatches, lumplength, (lumplength-4)/8);
// Truncate but continue reading. Who knows how many such lumps exist? // Truncate but continue reading. Who knows how many such lumps exist?
numpatches = (lumplength-4)/8; numpatches = (lumplength-4)/8;
@ -3204,7 +3204,7 @@ static void R_InitPatches ()
int i, j; int i, j;
char name[9]; char name[9];
for (i = sizeof(patches)/sizeof(patches[0]); i >= 0; --i) for (i = countof(patches); i >= 0; --i)
{ {
TexMan.AddPatch (patches[i]); TexMan.AddPatch (patches[i]);
} }
@ -3221,7 +3221,7 @@ static void R_InitPatches ()
} }
// Spinning power up icons for Heretic and Hexen // Spinning power up icons for Heretic and Hexen
for (j = sizeof(spinners)/sizeof(spinners[0])-1; j >= 0; --j) for (j = countof(spinners)-1; j >= 0; --j)
{ {
for (i = 0; i <= 15; ++i) for (i = 0; i <= 15; ++i)
{ {

View file

@ -525,7 +525,7 @@ int PolyClipper::DoMost (float x0, float y0, float x1, float y1, pmostcallbackty
CVAR(Bool, testpolymost, false, 0) CVAR(Bool, testpolymost, false, 0)
static int pmx, pmy; static int pmx, pmy;
static int pt, px0, py0, px1, py1; static int pt, px0, py0, px1, py1;
static struct { float x, y; } polypts[80]; static struct polypt { float x, y; } polypts[80];
static byte polysize[32]; static byte polysize[32];
static int numpoly, polypt; static int numpoly, polypt;
PolyClipper TestPoly; PolyClipper TestPoly;
@ -804,7 +804,7 @@ CCMD(initpolymosttest)
static void testpolycallback (double *dpx, double *dpy, int n, void *foo) static void testpolycallback (double *dpx, double *dpy, int n, void *foo)
{ {
if (numpoly == sizeof(polysize)) return; if (numpoly == sizeof(polysize)) return;
if (size_t(polypt + n) > sizeof(polypts)/sizeof(polypts[0])) return; if (size_t(polypt + n) > countof(polypts)) return;
polysize[numpoly++] = n; polysize[numpoly++] = n;
for (int i = 0; i < n; ++i) for (int i = 0; i < n; ++i)
{ {

View file

@ -55,7 +55,7 @@ static const FEAXField EAXFields[] =
{ 0, 0, 0, 0, 6 }, { 0, 0, 0, 0, 6 },
{ 0, 0, 0, 0, 7 } { 0, 0, 0, 0, 7 }
}; };
#define NUM_EAX_FIELDS (int(sizeof(EAXFields)/sizeof(EAXFields[0]))) #define NUM_EAX_FIELDS (int(countof(EAXFields)))
static const char *EAXFieldNames[NUM_EAX_FIELDS+2] = static const char *EAXFieldNames[NUM_EAX_FIELDS+2] =
{ {

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
//#include "actor.h" //#include "actor.h"
#include "s_sound.h" #include "s_sound.h"
#include "r_defs.h" #include "r_defs.h"
#include "name.h"
typedef enum { typedef enum {
SEQ_PLATFORM, SEQ_PLATFORM,
@ -16,52 +17,47 @@ typedef enum {
struct sector_t; struct sector_t;
void S_ParseSndSeq (int levellump);
void SN_StartSequence (AActor *mobj, int sequence, seqtype_t type);
void SN_StartSequence (AActor *mobj, const char *name);
void SN_StartSequence (sector_t *sector, int sequence, seqtype_t type);
void SN_StartSequence (sector_t *sector, const char *name);
void SN_StartSequence (fixed_t spot[3], int sequence, seqtype_t type);
void SN_StartSequence (fixed_t spot[3], const char *name);
void SN_StopSequence (AActor *mobj);
void SN_StopSequence (sector_t *sector);
void SN_StopSequence (fixed_t spot[3]);
void SN_UpdateActiveSequences (void);
void SN_StopAllSequences (void);
ptrdiff_t SN_GetSequenceOffset (int sequence, unsigned int *sequencePtr);
void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics,
float volume, int currentSoundID);
bool SN_IsMakingLoopingSound (sector_t *sector);
class DSeqNode : public DObject class DSeqNode : public DObject
{ {
DECLARE_CLASS (DSeqNode, DObject) DECLARE_CLASS (DSeqNode, DObject)
public: public:
virtual ~DSeqNode (); virtual ~DSeqNode ();
void Serialize (FArchive &arc); void Serialize (FArchive &arc);
void StopAndDestroy ();
void Destroy ();
void Tick ();
void ChangeData (int seqOffset, int delayTics, float volume, int currentSoundID);
void AddChoice (int seqnum, seqtype_t type);
name GetSequenceName() const;
virtual void MakeSound () {} virtual void MakeSound () {}
virtual void MakeLoopedSound () {} virtual void MakeLoopedSound () {}
virtual void *Source () { return NULL; } virtual void *Source () { return NULL; }
virtual bool IsPlaying () { return false; } virtual bool IsPlaying () { return false; }
void Tick (); virtual DSeqNode *SpawnChild (int seqnum) { return NULL; }
inline static DSeqNode *FirstSequence() { return SequenceListHead; } inline static DSeqNode *FirstSequence() { return SequenceListHead; }
inline DSeqNode *NextSequence() const { return m_Next; } inline DSeqNode *NextSequence() const { return m_Next; }
void ChangeData (int seqOffset, int delayTics, float volume, int currentSoundID);
static void SerializeSequences (FArchive &arc); static void SerializeSequences (FArchive &arc);
protected: protected:
DSeqNode (); DSeqNode ();
DSeqNode (int sequence); DSeqNode (int sequence, int modenum);
unsigned int *m_SequencePtr; SDWORD *m_SequencePtr;
int m_Sequence; int m_Sequence;
int m_CurrentSoundID; int m_CurrentSoundID;
int m_DelayTics; int m_DelayUntilTic;
float m_Volume; float m_Volume;
int m_StopSound; int m_StopSound;
int m_Atten; int m_Atten;
int m_ModeNum;
TArray<int> m_SequenceChoices;
DSeqNode *m_ChildSeqNode;
DSeqNode *m_ParentSeqNode;
private: private:
static DSeqNode *SequenceListHead; static DSeqNode *SequenceListHead;
@ -72,30 +68,31 @@ private:
friend void SN_StopAllSequences (void); friend void SN_StopAllSequences (void);
}; };
typedef struct struct FSoundSequence
{ {
char name[MAX_SNDNAME+1]; name SeqName;
int stopsound; name Slot;
unsigned int script[1]; // + more until end of sequence script int StopSound;
} sndseq_t; SDWORD Script[1]; // + more until end of sequence script
};
void SN_StartSequence (AActor *mobj, int sequence, seqtype_t type); void S_ParseSndSeq (int levellump);
void SN_StartSequence (AActor *mobj, const char *name); DSeqNode *SN_StartSequence (AActor *mobj, int sequence, seqtype_t type, int modenum, bool nostop=false);
void SN_StartSequence (sector_t *sector, int sequence, seqtype_t type); DSeqNode *SN_StartSequence (AActor *mobj, const char *name, int modenum);
void SN_StartSequence (sector_t *sector, const char *name); DSeqNode *SN_StartSequence (AActor *mobj, name seqname, int modenum);
void SN_StartSequence (polyobj_t *poly, int sequence, seqtype_t type); DSeqNode *SN_StartSequence (sector_t *sector, int sequence, seqtype_t type, int modenum, bool nostop=false);
void SN_StartSequence (polyobj_t *poly, const char *name); DSeqNode *SN_StartSequence (sector_t *sector, const char *name, int modenum);
DSeqNode *SN_StartSequence (polyobj_t *poly, int sequence, seqtype_t type, int modenum, bool nostop=false);
DSeqNode *SN_StartSequence (polyobj_t *poly, const char *name, int modenum);
void SN_StopSequence (AActor *mobj); void SN_StopSequence (AActor *mobj);
void SN_StopSequence (sector_t *sector); void SN_StopSequence (sector_t *sector);
void SN_StopSequence (polyobj_t *poly); void SN_StopSequence (polyobj_t *poly);
void SN_UpdateActiveSequences (void); void SN_UpdateActiveSequences (void);
ptrdiff_t SN_GetSequenceOffset (int sequence, unsigned int *sequencePtr); ptrdiff_t SN_GetSequenceOffset (int sequence, SDWORD *sequencePtr);
void SN_DoStop (void *); void SN_DoStop (void *);
void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics, void SN_ChangeNodeData (int nodeNum, int seqOffset, int delayTics,
float volume, int currentSoundID); float volume, int currentSoundID);
name SN_GetSequenceSlot (int sequence, seqtype_t type);
extern sndseq_t **Sequences; bool SN_IsMakingLoopingSound (sector_t *sector);
extern int ActiveSequences;
extern int NumSequences;
#endif //__S_SNDSEQ_H__ #endif //__S_SNDSEQ_H__

View file

@ -28,8 +28,6 @@
#include "d_event.h" #include "d_event.h"
#include "gi.h" #include "gi.h"
#define COUNT_CHEATS(l) (sizeof(l)/sizeof(l[0]))
EXTERN_CVAR (Bool, ticker); EXTERN_CVAR (Bool, ticker);
EXTERN_CVAR (Bool, noisedebug); EXTERN_CVAR (Bool, noisedebug);
EXTERN_CVAR (Int, am_cheat); EXTERN_CVAR (Int, am_cheat);
@ -241,22 +239,22 @@ BOOL ST_Responder (event_t *ev)
{ {
case GAME_Doom: case GAME_Doom:
cheats = DoomCheats; cheats = DoomCheats;
numcheats = COUNT_CHEATS(DoomCheats); numcheats = countof(DoomCheats);
break; break;
case GAME_Heretic: case GAME_Heretic:
cheats = HereticCheats; cheats = HereticCheats;
numcheats = COUNT_CHEATS(HereticCheats); numcheats = countof(HereticCheats);
break; break;
case GAME_Hexen: case GAME_Hexen:
cheats = HexenCheats; cheats = HexenCheats;
numcheats = COUNT_CHEATS(HexenCheats); numcheats = countof(HexenCheats);
break; break;
case GAME_Strife: case GAME_Strife:
cheats = StrifeCheats; cheats = StrifeCheats;
numcheats = COUNT_CHEATS(StrifeCheats); numcheats = countof(StrifeCheats);
break; break;
default: default:

View file

@ -284,7 +284,7 @@ static int STACK_ARGS flagcmp (const void * a, const void * b)
static flagdef *FindFlag (flagdef *flags, int numflags, const char *flag) static flagdef *FindFlag (flagdef *flags, int numflags, const char *flag)
{ {
int min = 0, max = numflags - 1;//sizeof(ActorFlags)/sizeof(ActorFlags[0])-1; int min = 0, max = numflags - 1;
while (min <= max) while (min <= max)
{ {
@ -697,11 +697,11 @@ static AFuncDesc * FindFunction(char * string)
if (!funcsorted) if (!funcsorted)
{ {
qsort(AFTable, sizeof(AFTable)/sizeof(AFTable[0]), sizeof(AFTable[0]), funccmp); qsort(AFTable, countof(AFTable), sizeof(AFTable[0]), funccmp);
funcsorted=true; funcsorted=true;
} }
int min = 0, max = sizeof(AFTable)/sizeof(AFTable[0])-1; int min = 0, max = countof(AFTable)-1;
while (min <= max) while (min <= max)
{ {

View file

@ -182,9 +182,9 @@ void uppercopy (char *to, const char *from)
} }
FWadCollection::FWadCollection () FWadCollection::FWadCollection ()
: FirstLumpIndex(NULL), NextLumpIndex(NULL), LumpInfo(NULL), Wads(NULL), : FirstLumpIndex(NULL), NextLumpIndex(NULL),
FirstLumpIndex_FullName(NULL), NextLumpIndex_FullName(NULL), FirstLumpIndex_FullName(NULL), NextLumpIndex_FullName(NULL),
NumLumps(0), NumWads(0) LumpInfo(NULL), Wads(NULL), NumLumps(0), NumWads(0)
{ {
} }
@ -650,13 +650,13 @@ void FWadCollection::AddFile (const char *filename, const char * data, int lengt
sprintf(path, "%s:", filename); sprintf(path, "%s:", filename);
char * wadstr = path+strlen(path); char * wadstr = path+strlen(path);
for(int i=0; i < EmbeddedWADs.Size(); i++) for(unsigned int i = 0; i < EmbeddedWADs.Size(); i++)
{ {
FZipFileInfo * zip_fh = EmbeddedWADs[i]; FZipFileInfo * zip_fh = EmbeddedWADs[i];
FZipLocalHeader localHeader; FZipLocalHeader localHeader;
*wadstr=0; *wadstr=0;
int len = LittleShort(zip_fh->wFileNameSize); size_t len = LittleShort(zip_fh->wFileNameSize);
if (len+strlen(path) > 255) len = 255-strlen(path); if (len+strlen(path) > 255) len = 255-strlen(path);
strncpy(wadstr, ((char*)zip_fh) + sizeof(FZipFileInfo), len); strncpy(wadstr, ((char*)zip_fh) + sizeof(FZipFileInfo), len);
wadstr[len]=0; wadstr[len]=0;
@ -1851,7 +1851,7 @@ FWadCollection::WadFileRecord::WadFileRecord (FILE *file)
} }
FWadCollection::WadFileRecord::WadFileRecord (const char * mem, int len) FWadCollection::WadFileRecord::WadFileRecord (const char * mem, int len)
: FileReader(), Name(NULL), FirstLump(0), LastLump(0), MemoryData(mem) : FileReader(), MemoryData(mem), Name(NULL), FirstLump(0), LastLump(0)
{ {
Length = len; Length = len;
FilePos = StartPos = 0; FilePos = StartPos = 0;

View file

@ -454,7 +454,7 @@ void SetupEnvControls (HWND hDlg)
{ {
size_t i; size_t i;
for (i = 0; i < sizeof(EnvControls)/sizeof(EnvControls[0]); ++i) for (i = 0; i < countof(EnvControls); ++i)
{ {
if (EnvControls[i].EditControl == 0) if (EnvControls[i].EditControl == 0)
continue; continue;
@ -469,7 +469,7 @@ void SetupEnvControls (HWND hDlg)
SetWindowLongPtr (EnvControls[i].EditHWND, GWLP_USERDATA, (LONG_PTR)&EnvControls[i]); SetWindowLongPtr (EnvControls[i].EditHWND, GWLP_USERDATA, (LONG_PTR)&EnvControls[i]);
SetWindowLongPtr (EnvControls[i].SliderHWND, GWLP_USERDATA, (LONG_PTR)&EnvControls[i]); SetWindowLongPtr (EnvControls[i].SliderHWND, GWLP_USERDATA, (LONG_PTR)&EnvControls[i]);
} }
for (i = 0; i < sizeof(EnvFlags)/sizeof(EnvFlags[0]); ++i) for (i = 0; i < countof(EnvFlags); ++i)
{ {
EnvFlags[i].CheckboxHWND = GetDlgItem (hDlg, EnvFlags[i].CheckboxControl); EnvFlags[i].CheckboxHWND = GetDlgItem (hDlg, EnvFlags[i].CheckboxControl);
SetWindowLongPtr (EnvFlags[i].CheckboxHWND, GWLP_USERDATA, (LONG_PTR)&EnvFlags[i]); SetWindowLongPtr (EnvFlags[i].CheckboxHWND, GWLP_USERDATA, (LONG_PTR)&EnvFlags[i]);
@ -517,7 +517,7 @@ void UpdateControls (ReverbContainer *env, HWND hDlg)
CurrentEnv = NULL; CurrentEnv = NULL;
for (i = 0; i < sizeof(EnvControls)/sizeof(EnvControls[0]); ++i) for (i = 0; i < countof(EnvControls); ++i)
{ {
EnvControl *ctrl = &EnvControls[i]; EnvControl *ctrl = &EnvControls[i];
@ -533,7 +533,7 @@ void UpdateControls (ReverbContainer *env, HWND hDlg)
EnableWindow (ctrl->EditHWND, !env->Builtin); EnableWindow (ctrl->EditHWND, !env->Builtin);
EnableWindow (ctrl->SliderHWND, !env->Builtin); EnableWindow (ctrl->SliderHWND, !env->Builtin);
} }
for (i = 0; i < sizeof(EnvFlags)/sizeof(EnvFlags[0]); ++i) for (i = 0; i < countof(EnvFlags); ++i)
{ {
SendMessage (EnvFlags[i].CheckboxHWND, BM_SETCHECK, SendMessage (EnvFlags[i].CheckboxHWND, BM_SETCHECK,
(env->Properties.Flags & EnvFlags[i].Flag) ? BST_CHECKED : BST_UNCHECKED, 0); (env->Properties.Flags & EnvFlags[i].Flag) ? BST_CHECKED : BST_UNCHECKED, 0);
@ -631,7 +631,7 @@ INT_PTR CALLBACK EAXProp (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_COMMAND: case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED && CurrentEnv != NULL) if (HIWORD(wParam) == BN_CLICKED && CurrentEnv != NULL)
{ {
for (size_t i = 0; i < sizeof(EnvFlags)/sizeof(EnvFlags[0]); ++i) for (size_t i = 0; i < countof(EnvFlags); ++i)
{ {
if ((HWND)lParam == EnvFlags[i].CheckboxHWND) if ((HWND)lParam == EnvFlags[i].CheckboxHWND)
{ {
@ -1052,7 +1052,7 @@ retry:
base = NULL; base = NULL;
} }
fprintf (f, "\"%s\" %u %u\n{\n", env->Name, HIBYTE(env->ID), LOBYTE(env->ID)); fprintf (f, "\"%s\" %u %u\n{\n", env->Name, HIBYTE(env->ID), LOBYTE(env->ID));
for (j = 0; j < sizeof(EnvControls)/sizeof(EnvControls[0]); ++j) for (j = 0; j < countof(EnvControls); ++j)
{ {
const EnvControl *ctl = &EnvControls[j]; const EnvControl *ctl = &EnvControls[j];
if (ctl->Name && if (ctl->Name &&
@ -1074,7 +1074,7 @@ retry:
} }
} }
} }
for (j = 0; j < sizeof(EnvFlags)/sizeof(EnvFlags[0]); ++j) for (j = 0; j < countof(EnvFlags); ++j)
{ {
if (EnvFlags[j].Flag & (env->Properties.Flags ^ base->Properties.Flags)) if (EnvFlags[j].Flag & (env->Properties.Flags ^ base->Properties.Flags))
{ {

View file

@ -1058,7 +1058,7 @@ void LoadJoystickConfig ()
{ {
if (SetJoystickSection (false)) if (SetJoystickSection (false))
{ {
for (size_t i = 0; i < sizeof(JoyConfigVars)/sizeof(JoyConfigVars[0]); ++i) for (size_t i = 0; i < countof(JoyConfigVars); ++i)
{ {
const char *val = GameConfig->GetValueForKey (JoyConfigVars[i]->GetName()); const char *val = GameConfig->GetValueForKey (JoyConfigVars[i]->GetName());
UCVarValue cval; UCVarValue cval;
@ -1077,7 +1077,7 @@ void SaveJoystickConfig ()
if (SetJoystickSection (true)) if (SetJoystickSection (true))
{ {
GameConfig->ClearCurrentSection (); GameConfig->ClearCurrentSection ();
for (size_t i = 0; i < sizeof(JoyConfigVars)/sizeof(JoyConfigVars[0]); ++i) for (size_t i = 0; i < countof(JoyConfigVars); ++i)
{ {
UCVarValue cval = JoyConfigVars[i]->GetGenericRep (CVAR_String); UCVarValue cval = JoyConfigVars[i]->GetGenericRep (CVAR_String);
GameConfig->SetValueForKey (JoyConfigVars[i]->GetName(), cval.String); GameConfig->SetValueForKey (JoyConfigVars[i]->GetName(), cval.String);

View file

@ -20,6 +20,13 @@ end
nostopcutoff nostopcutoff
end end
[DoorNormal
0 DoorOpenNormal
1 DoorCloseNormal
2 DoorOpenBlazing
3 DoorCloseBlazing
]
// Heretic Doors ------------------------------ // Heretic Doors ------------------------------
:HereticDoorOpen :HereticDoorOpen
@ -32,6 +39,13 @@ end
stopsound doors/dr1_clos stopsound doors/dr1_clos
end end
[HereticDoor
0 HereticDoorOpen
1 HereticDoorClose
2 HereticDoorOpen
3 HereticDoorClose
]
// Strife Doors ------------------------------- // Strife Doors -------------------------------
:DoorOpenStone :DoorOpenStone
@ -104,10 +118,59 @@ end
nostopcutoff nostopcutoff
end end
[DoorStone
0 DoorOpenStone
1 DoorCloseStone
2 DoorOpenBlazing
3 DoorCloseBlazing
]
[DoorLargeMetal
0 DoorOpenLargeMetal
1 DoorCloseLargeMetal
2 DoorOpenBlazing
3 DoorCloseBlazing
]
[DoorSmallMetal
0 DoorOpenSmallMetal
1 DoorCloseSmallMetal
2 DoorOpenBlazing
3 DoorCloseBlazing
]
[DoorLargeWood
0 DoorOpenLargeWood
1 DoorCloseLargeWood
2 DoorOpenBlazing
3 DoorCloseBlazing
]
[DoorSmallWood
0 DoorOpenSmallWood
1 DoorCloseSmallWood
2 DoorOpenBlazing
3 DoorCloseBlazing
]
[DoorAirlock
0 DoorOpenAirlock
1 DoorCloseAirlock
2 DoorOpenBlazing
3 DoorCloseBlazing
]
[DoorChain
0 DoorOpenChain
1 DoorCloseChain
2 DoorOpenBlazing
3 DoorCloseBlazing
]
// Not Doors ---------------------------------- // Not Doors ----------------------------------
:CeilingNormal :CeilingNormal
// playloop plats/pt1_mid 8
playrepeat plats/pt1_mid playrepeat plats/pt1_mid
end end
@ -116,16 +179,161 @@ end
end end
:Floor :Floor
// playloop plats/pt1_mid 8
playrepeat plats/pt1_mid playrepeat plats/pt1_mid
stopsound plats/pt1_stop stopsound plats/pt1_stop
end end
:Platform :Platform
playuntildone plats/pt1_strt playuntildone plats/pt1_strt
// playloop plats/pt1_mid 8
stopsound plats/pt1_stop stopsound plats/pt1_stop
end end
:Silence :Silence
end end
// Heretic Ambience ---------------------------
:HereticAmbience
// Heretic waits 10 seconds after level load before it starts
// playing any sounds.
delayonce 350
volumerand 0 50
attenuation none
randomsequence
delayrand 210 465
restart
end
// To be 100% correct, these sequences shouldn't actually wait for
// the last sound to stop playing, but I thought it would be nice
// to make them stand-alone so you don't always have to play them
// from inside HereticAmbience.
:AFX_Scream
environment 0
slot HereticAmbience
playuntildone world/amb1
end
:AFX_Squish
environment 1
slot HereticAmbience
playuntildone world/amb2
end
:AFX_Drops
environment 2
slot HereticAmbience
play world/amb3
delayrand 16 47
play world/amb7
delayrand 16 47
play world/amb3
delayrand 16 47
play world/amb7
delayrand 16 47
play world/amb3
delayrand 16 47
play world/amb7
delayrand 16 47
end
:AFX_SlowFootsteps
environment 3
slot HereticAmbience
playtime world/amb4 15
volumerel -2.36
playtime world/amb11 15
volumerel -2.36
playtime world/amb4 15
volumerel -2.36
playtime world/amb11 15
volumerel -2.36
playtime world/amb4 15
volumerel -2.36
playtime world/amb11 15
volumerel -2.36
playtime world/amb4 15
volumerel -2.36
playuntildone world/amb11
end
:AFX_Heartbeat
environment 4
slot HereticAmbience
playtime world/amb5 35
playtime world/amb5 35
playtime world/amb5 35
playuntildone world/amb5
end
:AFX_Bells
environment 5
slot HereticAmbience
playtime world/amb6 17
volumerel -6.3
playtime world/amb6 17
volumerel -6.3
playtime world/amb6 17
volumerel -6.3
playuntildone world/amb6
end
:AFX_Growl
environment 6
slot HereticAmbience
playuntildone world/amb12
end
:AFX_Magic
environment 7
slot HereticAmbience
playuntildone world/amb8
end
:AFX_Laughter
environment 8
slot HereticAmbience
playtime world/amb9 16
volumerel -3.15
playtime world/amb9 16
volumerel -3.15
playtime world/amb9 16
volumerel -3.15
playtime world/amb10 16
volumerel -3.15
playtime world/amb10 16
volumerel -3.15
playuntildone world/amb10
end
:AFX_FastFootsteps
environment 9
slot HereticAmbience
playtime world/amb4 8
volumerel -2.36
playtime world/amb11 8
volumerel -2.36
playtime world/amb4 8
volumerel -2.36
playtime world/amb11 8
volumerel -2.36
playtime world/amb4 8
volumerel -2.36
playtime world/amb11 8
volumerel -2.36
playtime world/amb4 8
volumerel -2.36
playuntildone world/amb11
end

View file

@ -1,6 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 8.00 Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = " zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}" Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = " zdoom", "zdoom.vcproj", "{8049475B-5C87-46F9-9358-635218A4EF18}"
ProjectSection(ProjectDependencies) = postProject ProjectSection(ProjectDependencies) = postProject
{1D179D4B-F008-431B-8C72-111F8372584F} = {1D179D4B-F008-431B-8C72-111F8372584F}
{F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63} = {F9D9E7D4-E1A2-4866-9E85-B1B14137EE63}
{873F2EEA-24DF-454C-B245-CB9738BA993E} = {873F2EEA-24DF-454C-B245-CB9738BA993E} {873F2EEA-24DF-454C-B245-CB9738BA993E} = {873F2EEA-24DF-454C-B245-CB9738BA993E}
EndProjectSection EndProjectSection

View file

@ -1987,6 +1987,9 @@
<File <File
RelativePath=".\src\name.h"> RelativePath=".\src\name.h">
</File> </File>
<File
RelativePath=".\src\namedef.h">
</File>
<File <File
RelativePath=".\src\nodebuild.h"> RelativePath=".\src\nodebuild.h">
</File> </File>
@ -2687,6 +2690,9 @@
<File <File
RelativePath="src\g_shared\a_soundenvironment.cpp"> RelativePath="src\g_shared\a_soundenvironment.cpp">
</File> </File>
<File
RelativePath=".\src\g_shared\a_soundsequence.cpp">
</File>
<File <File
RelativePath=".\src\g_shared\a_spark.cpp"> RelativePath=".\src\g_shared\a_spark.cpp">
<FileConfiguration <FileConfiguration
@ -3329,21 +3335,6 @@
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "/> AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "/>
</FileConfiguration> </FileConfiguration>
</File> </File>
<File
RelativePath=".\src\g_heretic\a_hereticambience.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
AdditionalOptions="&quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; &quot; /I /fmod/api/inc&quot; "/>
</FileConfiguration>
</File>
<File <File
RelativePath=".\src\g_heretic\a_hereticarmor.cpp"> RelativePath=".\src\g_heretic\a_hereticarmor.cpp">
<FileConfiguration <FileConfiguration