mirror of
https://github.com/DrBeef/Raze.git
synced 2025-01-31 13:10:39 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
e248c158a8
41 changed files with 1668 additions and 237 deletions
|
@ -70,9 +70,6 @@ CVAR(Int, snd_hrtf, -1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
|
||||
CVAR(String, snd_backend, DEF_BACKEND, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
|
||||
// killough 2/21/98: optionally use varying pitched sounds
|
||||
CVAR (Bool, snd_pitched, false, CVAR_ARCHIVE)
|
||||
|
||||
SoundRenderer *GSnd;
|
||||
bool nosound;
|
||||
bool nosfx;
|
||||
|
@ -134,7 +131,7 @@ public:
|
|||
void SetMusicVolume (float volume)
|
||||
{
|
||||
}
|
||||
SoundHandle LoadSound(uint8_t *sfxdata, int length)
|
||||
SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end)
|
||||
{
|
||||
SoundHandle retval = { NULL };
|
||||
return retval;
|
||||
|
@ -178,11 +175,11 @@ public:
|
|||
}
|
||||
|
||||
// Starts a sound.
|
||||
FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ public:
|
|||
virtual bool IsNull() { return false; }
|
||||
virtual void SetSfxVolume (float volume) = 0;
|
||||
virtual void SetMusicVolume (float volume) = 0;
|
||||
virtual SoundHandle LoadSound(uint8_t *sfxdata, int length) = 0;
|
||||
virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end) = 0;
|
||||
SoundHandle LoadSoundVoc(uint8_t *sfxdata, int length);
|
||||
virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1) = 0;
|
||||
virtual void UnloadSound (SoundHandle sfx) = 0; // unloads a sound from memory
|
||||
|
@ -117,8 +117,8 @@ public:
|
|||
virtual SoundStream *CreateStream (SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata) = 0;
|
||||
|
||||
// Starts a sound.
|
||||
virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0;
|
||||
virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0;
|
||||
virtual FISoundChannel *StartSound (SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0;
|
||||
virtual FISoundChannel *StartSound3D (SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime = 0.f) = 0;
|
||||
|
||||
// Stops a sound channel.
|
||||
virtual void StopChannel (FISoundChannel *chan) = 0;
|
||||
|
|
|
@ -110,7 +110,6 @@ ReverbContainer *ForcedEnvironment;
|
|||
EXTERN_CVAR (Int, snd_channels)
|
||||
EXTERN_CVAR (Int, snd_samplerate)
|
||||
EXTERN_CVAR (Bool, snd_waterreverb)
|
||||
EXTERN_CVAR (Bool, snd_pitched)
|
||||
EXTERN_CVAR (Int, snd_hrtf)
|
||||
|
||||
|
||||
|
@ -527,8 +526,6 @@ public:
|
|||
|
||||
#define PITCH_MULT (0.7937005f) /* Approx. 4 semitones lower; what Nash suggested */
|
||||
|
||||
#define PITCH(pitch) (snd_pitched ? (pitch)/128.f : 1.f)
|
||||
|
||||
static size_t GetChannelCount(ChannelConfig chans)
|
||||
{
|
||||
switch(chans)
|
||||
|
@ -1099,7 +1096,7 @@ SoundHandle OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata, int length, int
|
|||
return retval;
|
||||
}
|
||||
|
||||
SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length)
|
||||
SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end)
|
||||
{
|
||||
SoundHandle retval = { NULL };
|
||||
ALenum format = AL_NONE;
|
||||
|
@ -1109,7 +1106,16 @@ SoundHandle OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length)
|
|||
uint32_t loop_start = 0, loop_end = ~0u;
|
||||
zmusic_bool startass = false, endass = false;
|
||||
|
||||
FindLoopTags(sfxdata, length, &loop_start, &startass, &loop_end, &endass);
|
||||
if (def_loop_start < 0)
|
||||
{
|
||||
FindLoopTags(sfxdata, length, &loop_start, &startass, &loop_end, &endass);
|
||||
}
|
||||
else
|
||||
{
|
||||
loop_start = def_loop_start;
|
||||
loop_end = def_loop_end;
|
||||
startass = endass = true;
|
||||
}
|
||||
auto decoder = CreateDecoder(sfxdata, length, true);
|
||||
if (!decoder)
|
||||
return retval;
|
||||
|
@ -1224,7 +1230,7 @@ SoundStream *OpenALSoundRenderer::CreateStream(SoundStreamCallback callback, int
|
|||
return stream;
|
||||
}
|
||||
|
||||
FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
{
|
||||
if(FreeSfx.Size() == 0)
|
||||
{
|
||||
|
@ -1270,9 +1276,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
|||
alSourcef(source, AL_ROOM_ROLLOFF_FACTOR, 0.f);
|
||||
}
|
||||
if(WasInWater && !(chanflags&SNDF_NOREVERB))
|
||||
alSourcef(source, AL_PITCH, PITCH(pitch)*PITCH_MULT);
|
||||
alSourcef(source, AL_PITCH, pitch * PITCH_MULT);
|
||||
else
|
||||
alSourcef(source, AL_PITCH, PITCH(pitch));
|
||||
alSourcef(source, AL_PITCH, pitch);
|
||||
|
||||
if(!reuse_chan || reuse_chan->StartTime == 0)
|
||||
{
|
||||
|
@ -1326,7 +1332,7 @@ FISoundChannel *OpenALSoundRenderer::StartSound(SoundHandle sfx, float vol, int
|
|||
}
|
||||
|
||||
FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener *listener, float vol,
|
||||
FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel,
|
||||
FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel,
|
||||
int channum, int chanflags, FISoundChannel *reuse_chan, float startTime)
|
||||
{
|
||||
float dist_sqr = (float)(pos - listener->position).LengthSquared();
|
||||
|
@ -1438,9 +1444,9 @@ FISoundChannel *OpenALSoundRenderer::StartSound3D(SoundHandle sfx, SoundListener
|
|||
alSourcef(source, AL_ROOM_ROLLOFF_FACTOR, 0.f);
|
||||
}
|
||||
if(WasInWater && !(chanflags&SNDF_NOREVERB))
|
||||
alSourcef(source, AL_PITCH, PITCH(pitch)*PITCH_MULT);
|
||||
alSourcef(source, AL_PITCH, pitch * PITCH_MULT);
|
||||
else
|
||||
alSourcef(source, AL_PITCH, PITCH(pitch));
|
||||
alSourcef(source, AL_PITCH, pitch);
|
||||
|
||||
if(!reuse_chan || reuse_chan->StartTime == 0)
|
||||
{
|
||||
|
@ -1762,7 +1768,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
|
|||
{
|
||||
ALuint source = GET_PTRID(schan->SysChannel);
|
||||
if (source && !(schan->ChanFlags & CHANF_UI))
|
||||
alSourcef(source, AL_PITCH, schan->Pitch / 128.0f * PITCH_MULT);
|
||||
alSourcef(source, AL_PITCH, schan->Pitch * PITCH_MULT);
|
||||
schan = schan->NextChan;
|
||||
}
|
||||
getALError();
|
||||
|
@ -1800,7 +1806,7 @@ void OpenALSoundRenderer::UpdateListener(SoundListener *listener)
|
|||
{
|
||||
ALuint source = GET_PTRID(schan->SysChannel);
|
||||
if (source && !(schan->ChanFlags & CHANF_UI))
|
||||
alSourcef(source, AL_PITCH, schan->Pitch / 128.0f);
|
||||
alSourcef(source, AL_PITCH, schan->Pitch);
|
||||
schan = schan->NextChan;
|
||||
}
|
||||
getALError();
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
|
||||
virtual void SetSfxVolume(float volume);
|
||||
virtual void SetMusicVolume(float volume);
|
||||
virtual SoundHandle LoadSound(uint8_t *sfxdata, int length);
|
||||
virtual SoundHandle LoadSound(uint8_t *sfxdata, int length, int def_loop_start, int def_loop_end);
|
||||
virtual SoundHandle LoadSoundRaw(uint8_t *sfxdata, int length, int frequency, int channels, int bits, int loopstart, int loopend = -1);
|
||||
virtual void UnloadSound(SoundHandle sfx);
|
||||
virtual unsigned int GetMSLength(SoundHandle sfx);
|
||||
|
@ -45,8 +45,8 @@ public:
|
|||
virtual SoundStream *CreateStream(SoundStreamCallback callback, int buffbytes, int flags, int samplerate, void *userdata);
|
||||
|
||||
// Starts a sound.
|
||||
virtual FISoundChannel *StartSound(SoundHandle sfx, float vol, int pitch, int chanflags, FISoundChannel *reuse_chan, float startTime);
|
||||
virtual FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, int pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime);
|
||||
FISoundChannel *StartSound(SoundHandle sfx, float vol, float pitch, int chanflags, FISoundChannel *reuse_chan, float startTime) override;
|
||||
FISoundChannel *StartSound3D(SoundHandle sfx, SoundListener *listener, float vol, FRolloffInfo *rolloff, float distscale, float pitch, int priority, const FVector3 &pos, const FVector3 &vel, int channum, int chanflags, FISoundChannel *reuse_chan, float startTime) override;
|
||||
|
||||
// Changes a channel's volume.
|
||||
virtual void ChannelVolume(FISoundChannel *chan, float volume);
|
||||
|
|
|
@ -49,6 +49,8 @@
|
|||
CVARD(Bool, snd_enabled, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "enables/disables sound effects")
|
||||
CVAR(Bool, i_soundinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
CVAR(Bool, i_pauseinbackground, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
||||
// killough 2/21/98: optionally use varying pitched sounds
|
||||
CVAR(Bool, snd_pitched, false, CVAR_ARCHIVE)
|
||||
|
||||
int SoundEnabled()
|
||||
{
|
||||
|
@ -368,6 +370,31 @@ FSoundID SoundEngine::ResolveSound(const void *, int, FSoundID soundid, float &a
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static float CalcPitch(int pitchmask, float defpitch, float defpitchmax)
|
||||
{
|
||||
if (defpitch > 0.0) // $PitchSet overrides $PitchShift
|
||||
{
|
||||
if (defpitchmax > 0.0 && defpitch != defpitchmax)
|
||||
{
|
||||
defpitch = (float)pr_soundpitch.GenRand_Real1() * (defpitchmax - defpitch) + defpitch;
|
||||
}
|
||||
return defpitch;
|
||||
}
|
||||
|
||||
// Vary the sfx pitches. Overridden by $PitchSet and A_StartSound.
|
||||
if (pitchmask != 0 && snd_pitched)
|
||||
{
|
||||
return (DEFAULT_PITCH - (pr_soundpitch() & pitchmask) + (pr_soundpitch() & pitchmask)) / (float)DEFAULT_PITCH;
|
||||
}
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// S_StartSound
|
||||
|
@ -386,7 +413,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
|
|||
EChanFlags chanflags = flags;
|
||||
int basepriority;
|
||||
FSoundID org_id;
|
||||
int pitch;
|
||||
FSoundChan *chan;
|
||||
FVector3 pos, vel;
|
||||
FRolloffInfo *rolloff;
|
||||
|
@ -419,7 +445,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
|
|||
float limit_range = sfx->LimitRange;
|
||||
float defpitch = sfx->DefPitch;
|
||||
float defpitchmax = sfx->DefPitchMax;
|
||||
auto pitchmask = sfx->PitchMask;
|
||||
rolloff = &sfx->Rolloff;
|
||||
|
||||
// Resolve player sounds, random sounds, and aliases
|
||||
|
@ -542,16 +567,7 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// Vary the sfx pitches. Overridden by $PitchSet and A_StartSound.
|
||||
if (pitchmask != 0)
|
||||
{
|
||||
pitch = DEFAULT_PITCH - (rand() & pitchmask) + (rand() & pitchmask);
|
||||
}
|
||||
else
|
||||
{
|
||||
pitch = DEFAULT_PITCH;
|
||||
}
|
||||
|
||||
float pitch = spitch > 0 ? spitch : CalcPitch(sfx->PitchMask, defpitch, defpitchmax);
|
||||
if (chanflags & CHANF_EVICTED)
|
||||
{
|
||||
chan = NULL;
|
||||
|
@ -614,27 +630,6 @@ FSoundChan *SoundEngine::StartSound(int type, const void *source,
|
|||
{
|
||||
chan->Source = source;
|
||||
}
|
||||
|
||||
if (spitch > 0.0) // A_StartSound has top priority over all others.
|
||||
SetPitch(chan, spitch);
|
||||
else if (defpitch > 0.0) // $PitchSet overrides $PitchShift
|
||||
{
|
||||
if (defpitchmax > 0.0)
|
||||
{
|
||||
if (defpitchmax < defpitch)
|
||||
std::swap(defpitch, defpitchmax);
|
||||
|
||||
if (defpitch != defpitchmax)
|
||||
{
|
||||
FRandom &rng = pr_soundpitch;
|
||||
int random = (rng)(0x7FFF);
|
||||
float frandom = random / float(0x7FFF);
|
||||
|
||||
defpitch = frandom * (defpitchmax - defpitch) + defpitch;
|
||||
}
|
||||
}
|
||||
SetPitch(chan, defpitch);
|
||||
}
|
||||
}
|
||||
|
||||
return chan;
|
||||
|
@ -774,7 +769,7 @@ sfxinfo_t *SoundEngine::LoadSound(sfxinfo_t *sfx)
|
|||
// If that fails, let the sound system try and figure it out.
|
||||
else
|
||||
{
|
||||
sfx->data = GSnd->LoadSound(sfxdata.Data(), size);
|
||||
sfx->data = GSnd->LoadSound(sfxdata.Data(), size, sfx->LoopStart, sfx->LoopEnd);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1077,7 +1072,7 @@ void SoundEngine::SetPitch(FSoundChan *chan, float pitch)
|
|||
{
|
||||
assert(chan != nullptr);
|
||||
GSnd->ChannelPitch(chan, max(0.0001f, pitch));
|
||||
chan->Pitch = max(1, int(float(DEFAULT_PITCH) * pitch));
|
||||
chan->Pitch = pitch;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -97,11 +97,13 @@ constexpr FSoundID INVALID_SOUND = FSoundID::fromInt(-1);
|
|||
bool bUsed = false;
|
||||
bool bSingular = false;
|
||||
bool bTentative = true;
|
||||
bool bExternal = false;
|
||||
|
||||
TArray<int> UserData;
|
||||
|
||||
int RawRate = 0; // Sample rate to use when bLoadRAW is true
|
||||
int LoopStart = -1; // -1 means no specific loop defined
|
||||
int LoopEnd = -1; // -1 means no specific loop defined
|
||||
|
||||
FSoundID link = NO_LINK;
|
||||
constexpr static FSoundID NO_LINK = FSoundID::fromInt(-1);
|
||||
|
@ -120,7 +122,7 @@ struct FSoundChan : public FISoundChannel
|
|||
float Volume;
|
||||
int EntChannel; // Actor's sound channel.
|
||||
int UserData; // Not used by the engine, the caller can use this to store some additional info.
|
||||
int16_t Pitch; // Pitch variation.
|
||||
float Pitch; // Pitch variation.
|
||||
int16_t NearLimit;
|
||||
int8_t Priority;
|
||||
uint8_t SourceType;
|
||||
|
|
|
@ -422,7 +422,7 @@ void FFont::ReadSheetFont(TArray<FolderEntry> &folderdata, int width, int height
|
|||
{
|
||||
for (int x = 0; x < numtex_x; x++)
|
||||
{
|
||||
auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * width, width, height);
|
||||
auto image = new FSheetTexture(sheetBitmaps.Size() - 1, x * width, y * height, width, height);
|
||||
FImageTexture *imgtex = new FImageTexture(image);
|
||||
auto gtex = MakeGameTexture(imgtex, nullptr, ETextureType::FontChar);
|
||||
gtex->SetWorldPanning(true);
|
||||
|
|
|
@ -239,6 +239,8 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
float uClipHeight;
|
||||
float uClipHeightDirection;
|
||||
int uShadowmapFilter;
|
||||
|
||||
int uLightBlendMode;
|
||||
};
|
||||
|
||||
uniform int uTextureMode;
|
||||
|
@ -332,6 +334,7 @@ bool FShader::Load(const char * name, const char * vert_prog_lump, const char *
|
|||
uniform sampler2D texture9;
|
||||
uniform sampler2D texture10;
|
||||
uniform sampler2D texture11;
|
||||
uniform sampler2D texture12;
|
||||
|
||||
// timer data
|
||||
uniform float timer;
|
||||
|
|
|
@ -4,6 +4,15 @@
|
|||
|
||||
struct HWDrawInfo;
|
||||
|
||||
enum class ELightBlendMode : uint8_t
|
||||
{
|
||||
CLAMP = 0,
|
||||
CLAMP_COLOR = 1,
|
||||
NOCLAMP = 2,
|
||||
|
||||
DEFAULT = CLAMP,
|
||||
};
|
||||
|
||||
struct HWViewpointUniforms
|
||||
{
|
||||
VSMatrix mProjectionMatrix;
|
||||
|
@ -19,6 +28,8 @@ struct HWViewpointUniforms
|
|||
float mClipHeightDirection = 0.f;
|
||||
int mShadowmapFilter = 1;
|
||||
|
||||
int mLightBlendMode = 0;
|
||||
|
||||
void CalcDependencies()
|
||||
{
|
||||
mNormalViewMatrix.computeNormalMatrix(mViewMatrix);
|
||||
|
|
|
@ -570,7 +570,8 @@ void PPColormap::Render(PPRenderState *renderstate, int fixedcm, float flash)
|
|||
|
||||
void PPTonemap::UpdateTextures()
|
||||
{
|
||||
if (gl_tonemap == Palette && !PaletteTexture.Data)
|
||||
// level.info->tonemap cannot be ETonemapMode::Palette, so it's fine to only check gl_tonemap here
|
||||
if (ETonemapMode((int)gl_tonemap) == ETonemapMode::Palette && !PaletteTexture.Data)
|
||||
{
|
||||
std::shared_ptr<void> data(new uint32_t[512 * 512], [](void *p) { delete[](uint32_t*)p; });
|
||||
|
||||
|
@ -598,7 +599,9 @@ void PPTonemap::UpdateTextures()
|
|||
|
||||
void PPTonemap::Render(PPRenderState *renderstate)
|
||||
{
|
||||
if (gl_tonemap == 0)
|
||||
ETonemapMode current_tonemap = (level_tonemap != ETonemapMode::None) ? level_tonemap : ETonemapMode((int)gl_tonemap);
|
||||
|
||||
if (current_tonemap == ETonemapMode::None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -606,14 +609,14 @@ void PPTonemap::Render(PPRenderState *renderstate)
|
|||
UpdateTextures();
|
||||
|
||||
PPShader *shader = nullptr;
|
||||
switch (gl_tonemap)
|
||||
switch (current_tonemap)
|
||||
{
|
||||
default:
|
||||
case Linear: shader = &LinearShader; break;
|
||||
case Reinhard: shader = &ReinhardShader; break;
|
||||
case HejlDawson: shader = &HejlDawsonShader; break;
|
||||
case Uncharted2: shader = &Uncharted2Shader; break;
|
||||
case Palette: shader = &PaletteShader; break;
|
||||
case ETonemapMode::Linear: shader = &LinearShader; break;
|
||||
case ETonemapMode::Reinhard: shader = &ReinhardShader; break;
|
||||
case ETonemapMode::HejlDawson: shader = &HejlDawsonShader; break;
|
||||
case ETonemapMode::Uncharted2: shader = &Uncharted2Shader; break;
|
||||
case ETonemapMode::Palette: shader = &PaletteShader; break;
|
||||
}
|
||||
|
||||
renderstate->PushGroup("tonemap");
|
||||
|
@ -622,7 +625,7 @@ void PPTonemap::Render(PPRenderState *renderstate)
|
|||
renderstate->Shader = shader;
|
||||
renderstate->Viewport = screen->mScreenViewport;
|
||||
renderstate->SetInputCurrent(0);
|
||||
if (gl_tonemap == Palette)
|
||||
if (current_tonemap == ETonemapMode::Palette)
|
||||
renderstate->SetInputTexture(1, &PaletteTexture);
|
||||
renderstate->SetOutputNext();
|
||||
renderstate->SetNoBlend();
|
||||
|
|
|
@ -13,6 +13,19 @@ typedef IntRect PPViewport;
|
|||
class PPTexture;
|
||||
class PPShader;
|
||||
|
||||
enum class ETonemapMode : uint8_t
|
||||
{
|
||||
None,
|
||||
Uncharted2,
|
||||
HejlDawson,
|
||||
Reinhard,
|
||||
Linear,
|
||||
Palette,
|
||||
NumTonemapModes
|
||||
};
|
||||
|
||||
|
||||
|
||||
enum class PPFilterMode { Nearest, Linear };
|
||||
enum class PPWrapMode { Clamp, Repeat };
|
||||
enum class PPTextureType { CurrentPipelineTexture, NextPipelineTexture, PPTexture, SceneColor, SceneFog, SceneNormal, SceneDepth, SwapChain, ShadowMap };
|
||||
|
@ -541,6 +554,7 @@ private:
|
|||
class PPTonemap
|
||||
{
|
||||
public:
|
||||
void SetTonemapMode(ETonemapMode tm) { level_tonemap = tm; }
|
||||
void Render(PPRenderState *renderstate);
|
||||
void ClearTonemapPalette() { PaletteTexture = {}; }
|
||||
|
||||
|
@ -554,17 +568,7 @@ private:
|
|||
PPShader HejlDawsonShader = { "shaders/pp/tonemap.fp", "#define HEJLDAWSON\n", {} };
|
||||
PPShader Uncharted2Shader = { "shaders/pp/tonemap.fp", "#define UNCHARTED2\n", {} };
|
||||
PPShader PaletteShader = { "shaders/pp/tonemap.fp", "#define PALETTE\n", {} };
|
||||
|
||||
enum TonemapMode
|
||||
{
|
||||
None,
|
||||
Uncharted2,
|
||||
HejlDawson,
|
||||
Reinhard,
|
||||
Linear,
|
||||
Palette,
|
||||
NumTonemapModes
|
||||
};
|
||||
ETonemapMode level_tonemap = ETonemapMode::None;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -840,8 +844,11 @@ public:
|
|||
PPCustomShaders customShaders;
|
||||
|
||||
|
||||
void SetTonemapMode(ETonemapMode tm) { tonemap.SetTonemapMode(tm); }
|
||||
void Pass1(PPRenderState *state, int fixedcm, int sceneWidth, int sceneHeight);
|
||||
void Pass2(PPRenderState* state, int fixedcm, float flash, int sceneWidth, int sceneHeight);
|
||||
};
|
||||
|
||||
|
||||
extern Postprocess hw_postprocess;
|
||||
|
||||
|
|
|
@ -175,6 +175,8 @@ static const char *shaderBindings = R"(
|
|||
float uClipHeight;
|
||||
float uClipHeightDirection;
|
||||
int uShadowmapFilter;
|
||||
|
||||
int uLightBlendMode;
|
||||
};
|
||||
|
||||
layout(set = 1, binding = 1, std140) uniform MatricesUBO {
|
||||
|
@ -244,6 +246,7 @@ static const char *shaderBindings = R"(
|
|||
layout(set = 2, binding = 8) uniform sampler2D texture9;
|
||||
layout(set = 2, binding = 9) uniform sampler2D texture10;
|
||||
layout(set = 2, binding = 10) uniform sampler2D texture11;
|
||||
layout(set = 2, binding = 11) uniform sampler2D texture12;
|
||||
|
||||
// This must match the PushConstants struct
|
||||
layout(push_constant) uniform PushConstants
|
||||
|
|
|
@ -438,10 +438,12 @@ template<typename I> void MapIteratorSetValue(I * self, expand_types_vm<typename
|
|||
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
|
||||
ACTION_RETURN_INT( MapIteratorGetKey(self) ); \
|
||||
} \
|
||||
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetValue , MapIteratorGetValue< FMapIterator_I32_Str > ) \
|
||||
DEFINE_ACTION_FUNCTION_NATIVE( FMapIterator_I32_Str , GetValue , MapIteratorGetValueString< FMapIterator_I32_Str > ) \
|
||||
{ \
|
||||
PARAM_SELF_STRUCT_PROLOGUE( FMapIterator_I32_Str ); \
|
||||
ACTION_RETURN_STRING( MapIteratorGetValue(self) ); \
|
||||
FString out; \
|
||||
MapIteratorGetValueString(self , out); \
|
||||
ACTION_RETURN_STRING( out ); \
|
||||
}
|
||||
|
||||
#define DEF_MAP_IT_S_S() \
|
||||
|
|
|
@ -133,12 +133,15 @@ FMaterial::FMaterial(FGameTexture * tx, int scaleflags)
|
|||
if (index >= FIRST_USER_SHADER)
|
||||
{
|
||||
const UserShaderDesc& usershader = usershaders[index - FIRST_USER_SHADER];
|
||||
if (tx->Layers && usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||
if (usershader.shaderType == mShaderIndex) // Only apply user shader if it matches the expected material
|
||||
{
|
||||
for (auto& texture : tx->Layers->CustomShaderTextures)
|
||||
if (tx->Layers)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
for (auto& texture : tx->Layers->CustomShaderTextures)
|
||||
{
|
||||
if (texture == nullptr) continue;
|
||||
mTextureLayers.Push({ texture.get(), 0 }); // scalability should be user-definable.
|
||||
}
|
||||
}
|
||||
mShaderIndex = index;
|
||||
}
|
||||
|
|
|
@ -418,19 +418,34 @@ void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, con
|
|||
// color, so find a duplicate pair of palette entries, make one of them a
|
||||
// duplicate of color 0, and remap every graphic so that it uses that entry
|
||||
// instead of entry 0.
|
||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* lastcolormap)
|
||||
{
|
||||
for (int i = 0; i < 256; i++) Remap[i] = i;
|
||||
PalEntry color0 = BaseColors[0];
|
||||
int i;
|
||||
|
||||
|
||||
// First try for an exact match of color 0. Only Hexen does not have one.
|
||||
for (i = 1; i < 256; ++i)
|
||||
if (!lastcolormap)
|
||||
{
|
||||
if (BaseColors[i] == color0)
|
||||
for (i = 1; i < 256; ++i)
|
||||
{
|
||||
Remap[0] = i;
|
||||
break;
|
||||
if (BaseColors[i] == color0)
|
||||
{
|
||||
Remap[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < 256; ++i)
|
||||
{
|
||||
if ((BaseColors[i] == color0) && (lastcolormap[i] == lastcolormap[0]))
|
||||
{
|
||||
Remap[0] = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -448,21 +463,44 @@ void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap)
|
|||
sortcopy[i] = (BaseColors[i] & 0xffffff) | (i << 24);
|
||||
}
|
||||
qsort(sortcopy, 256, 4, sortforremap);
|
||||
for (i = 255; i > 0; --i)
|
||||
if (!lastcolormap)
|
||||
{
|
||||
if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF))
|
||||
for (i = 255; i > 0; --i)
|
||||
{
|
||||
int new0 = sortcopy[i].a;
|
||||
int dup = sortcopy[i - 1].a;
|
||||
if (new0 > dup)
|
||||
if ((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF))
|
||||
{
|
||||
// Make the lower-numbered entry a copy of color 0. (Just because.)
|
||||
std::swap(new0, dup);
|
||||
int new0 = sortcopy[i].a;
|
||||
int dup = sortcopy[i - 1].a;
|
||||
if (new0 > dup)
|
||||
{
|
||||
// Make the lower-numbered entry a copy of color 0. (Just because.)
|
||||
std::swap(new0, dup);
|
||||
}
|
||||
Remap[0] = new0;
|
||||
Remap[new0] = dup;
|
||||
BaseColors[new0] = color0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 255; i > 0; --i)
|
||||
{
|
||||
if (((sortcopy[i] & 0xFFFFFF) == (sortcopy[i - 1] & 0xFFFFFF)) && (lastcolormap[sortcopy[i].a] == lastcolormap[sortcopy[i - 1].a]))
|
||||
{
|
||||
int new0 = sortcopy[i].a;
|
||||
int dup = sortcopy[i - 1].a;
|
||||
if (new0 > dup)
|
||||
{
|
||||
// Make the lower-numbered entry a copy of color 0. (Just because.)
|
||||
std::swap(new0, dup);
|
||||
}
|
||||
Remap[0] = new0;
|
||||
Remap[new0] = dup;
|
||||
BaseColors[new0] = color0;
|
||||
break;
|
||||
}
|
||||
Remap[0] = new0;
|
||||
Remap[new0] = dup;
|
||||
BaseColors[new0] = color0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ void DoBlending(const PalEntry* from, PalEntry* to, int count, int r, int g, int
|
|||
// Given an array of colors, fills in remap with values to remap the
|
||||
// passed array of colors to BaseColors. Used for loading palette downconversions of PNGs.
|
||||
void MakeRemap(uint32_t* BaseColors, const uint32_t* colors, uint8_t* remap, const uint8_t* useful, int numcolors);
|
||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap);
|
||||
void MakeGoodRemap(uint32_t* BaseColors, uint8_t* Remap, const uint8_t* cmapdata = nullptr);
|
||||
|
||||
// Colorspace conversion RGB <-> HSV
|
||||
void RGBtoHSV (float r, float g, float b, float *h, float *s, float *v);
|
||||
|
|
|
@ -165,6 +165,7 @@ bool G_Responder(event_t* ev);
|
|||
void HudScaleChanged();
|
||||
bool M_SetSpecialMenu(FName& menu, int param);
|
||||
void OnMenuOpen(bool makeSound);
|
||||
void DestroyAltHUD();
|
||||
|
||||
DStatusBarCore* StatusBar;
|
||||
|
||||
|
@ -622,6 +623,7 @@ int GameMain()
|
|||
}
|
||||
//DeleteScreenJob();
|
||||
if (gi) gi->FreeLevelData();
|
||||
DestroyAltHUD();
|
||||
DeinitMenus();
|
||||
if (StatusBar) StatusBar->Destroy();
|
||||
StatusBar = nullptr;
|
||||
|
|
|
@ -42,9 +42,11 @@
|
|||
#include "s_music.h"
|
||||
#include "sc_man.h"
|
||||
#include "s_soundinternal.h"
|
||||
#include "gamecontrol.h"
|
||||
#include <zmusic.h>
|
||||
|
||||
#include "raze_music.h"
|
||||
#include "games/duke/src/sounds.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
|
@ -56,7 +58,12 @@ enum SICommands
|
|||
SI_ConReserve,
|
||||
SI_Alias,
|
||||
SI_Limit,
|
||||
SI_Singular
|
||||
SI_Singular,
|
||||
SI_PitchSet,
|
||||
SI_PitchSetDuke,
|
||||
SI_DukeFlags,
|
||||
SI_Loop,
|
||||
SI_BloodRelVol,
|
||||
};
|
||||
|
||||
|
||||
|
@ -87,6 +94,11 @@ static const char *SICommandStrings[] =
|
|||
"$alias",
|
||||
"$limit",
|
||||
"$singular",
|
||||
"$pitchset",
|
||||
"$pitchsetduke",
|
||||
"$dukeflags",
|
||||
"$loop",
|
||||
"$bloodrelvol",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -287,6 +299,46 @@ static void S_AddSNDINFO (int lump)
|
|||
}
|
||||
break;
|
||||
|
||||
case SI_PitchSet: {
|
||||
// $pitchset <logical name> <pitch amount as float> [range maximum]
|
||||
FSoundID sfx;
|
||||
|
||||
sc.MustGetString();
|
||||
sfx = soundEngine->FindSoundTentative(sc.String);
|
||||
sc.MustGetFloat();
|
||||
auto sfxp = soundEngine->GetWritableSfx(sfx);
|
||||
sfxp->DefPitch = (float)sc.Float;
|
||||
if (sc.CheckFloat())
|
||||
{
|
||||
sfxp->DefPitchMax = (float)sc.Float;
|
||||
}
|
||||
else
|
||||
{
|
||||
sfxp->DefPitchMax = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SI_PitchSetDuke: {
|
||||
// $pitchset <logical name> <pitch amount as float> [range maximum]
|
||||
// Same as above, but uses Duke's value range of 1200 units per octave.
|
||||
FSoundID sfx;
|
||||
|
||||
sc.MustGetString();
|
||||
sfx = soundEngine->FindSoundTentative(sc.String);
|
||||
sc.MustGetFloat();
|
||||
auto sfxp = soundEngine->GetWritableSfx(sfx);
|
||||
sfxp->DefPitch = (float)pow(2, sc.Float / 1200.);
|
||||
if (sc.CheckFloat())
|
||||
{
|
||||
sfxp->DefPitchMax = (float)pow(2, sc.Float / 1200.);
|
||||
}
|
||||
else
|
||||
{
|
||||
sfxp->DefPitchMax = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SI_ConReserve: {
|
||||
// $conreserve <logical name> <resource id>
|
||||
|
@ -300,6 +352,75 @@ static void S_AddSNDINFO (int lump)
|
|||
break;
|
||||
}
|
||||
|
||||
case SI_DukeFlags: {
|
||||
static const char* dukeflags[] = { "LOOP", "MSFX", "TALK", "GLOBAL", nullptr};
|
||||
|
||||
// dukesound <logical name> <flag> <flag> <flag>..
|
||||
// Sets a pitch range for the sound.
|
||||
sc.MustGetString();
|
||||
auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT);
|
||||
int flags = 0;
|
||||
while (sc.GetString())
|
||||
{
|
||||
int bit = sc.MatchString(dukeflags);
|
||||
if (bit == -1) break;
|
||||
flags |= 1 << bit;
|
||||
}
|
||||
if (isDukeEngine())
|
||||
{
|
||||
auto sfx = soundEngine->GetWritableSfx(sfxid);
|
||||
if (sfx->UserData.Size() < Duke3d::kMaxUserData)
|
||||
{
|
||||
sfx->UserData.Resize(Duke3d::kMaxUserData);
|
||||
memset(sfx->UserData.Data(), 0, Duke3d::kMaxUserData * sizeof(int));
|
||||
}
|
||||
sfx->UserData[Duke3d::kFlags] = flags;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("'$dukeflags' is not available in the current game and will be ignored");
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case SI_Loop: {
|
||||
// loop <logical name> <start> <end>
|
||||
// Sets loop points for the given sound in samples. Only really useful for WAV - for Ogg and FLAC use the metadata they can contain.
|
||||
sc.MustGetString();
|
||||
auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT);
|
||||
auto sfx = soundEngine->GetWritableSfx(sfxid);
|
||||
sc.MustGetNumber();
|
||||
sfx->LoopStart = sc.Number;
|
||||
if (sc.CheckNumber())
|
||||
sfx->LoopEnd = sc.Number;
|
||||
break;
|
||||
}
|
||||
|
||||
case SI_BloodRelVol: {
|
||||
// bloodrelvol <logical name> <value>
|
||||
// Sets Blood's hacky volume modifier.
|
||||
sc.MustGetString();
|
||||
auto sfxid = soundEngine->FindSoundTentative(sc.String, DEFAULT_LIMIT);
|
||||
auto sfx = soundEngine->GetWritableSfx(sfxid);
|
||||
sc.MustGetNumber();
|
||||
if (isBlood())
|
||||
{
|
||||
auto sfx = soundEngine->GetWritableSfx(sfxid);
|
||||
if (sfx->UserData.Size() < 1)
|
||||
{
|
||||
sfx->UserData.Resize(1);
|
||||
}
|
||||
sfx->UserData[0] = sc.Number;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("'$bloodrelvol' is not available in the current game and will be ignored");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
{ // Got a logical sound mapping
|
||||
FString name (sc.String);
|
||||
|
|
|
@ -103,6 +103,17 @@ DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetSpriteLotag)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, SetSpriteSector)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DLevelPostProcessor);
|
||||
PARAM_UINT(sprite);
|
||||
PARAM_INT(sect);
|
||||
if (sprite < self->sprites->sprites.Size())
|
||||
self->sprites->sprites[sprite].sectp = §or[sect];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, ChangeSpriteFlags)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DLevelPostProcessor);
|
||||
|
|
|
@ -250,6 +250,7 @@ void HWDrawInfo::SetupView(FRenderState &state, float vx, float vy, float vz, bo
|
|||
SetViewMatrix(vp.HWAngles, vx, vy, vz, mirror, planemirror);
|
||||
SetCameraPos(vp.Pos);
|
||||
VPUniforms.CalcDependencies();
|
||||
VPUniforms.mLightBlendMode = 0;
|
||||
vpIndex = screen->mViewpoints->SetViewpoint(state, &VPUniforms);
|
||||
}
|
||||
|
||||
|
|
|
@ -1128,6 +1128,10 @@ int HWWall::CheckWallSprite(tspritetype* spr, tspritetype* last)
|
|||
|
||||
void HWWall::ProcessWallSprite(HWDrawInfo* di, tspritetype* spr, sectortype* sector)
|
||||
{
|
||||
if (spr->time == 1373)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
auto tex = TexMan.GetGameTexture(spr->spritetexture());
|
||||
if (!tex || !tex->isValid()) return;
|
||||
|
||||
|
|
|
@ -106,8 +106,8 @@ static void SerializeGlobals(FSerializer& arc)
|
|||
|
||||
static void SerializeSession(FSerializer& arc)
|
||||
{
|
||||
// In Duke we now have reliable sound names.
|
||||
if (isDukeEngine()) arc.SetUniqueSoundNames();
|
||||
// In Duke and Blood we now have reliable sound names.
|
||||
if (isDukeEngine() || isBlood()) arc.SetUniqueSoundNames();
|
||||
|
||||
arc.ReadObjects(false);
|
||||
SerializeMap(arc);
|
||||
|
|
|
@ -134,14 +134,18 @@ static DObject* DoCreateAltHUD(const FName classname)
|
|||
return althud;
|
||||
}
|
||||
|
||||
void CreateAltHUD()
|
||||
void DestroyAltHUD()
|
||||
{
|
||||
if (AltHud)
|
||||
{
|
||||
AltHud->Destroy();
|
||||
AltHud = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateAltHUD()
|
||||
{
|
||||
DestroyAltHUD();
|
||||
/*
|
||||
if (!hud_althud_forceinternal)
|
||||
AltHud = DoCreateAltHUD(gameinfo.althudclass);
|
||||
|
|
|
@ -386,7 +386,7 @@ void SEQINST::Update()
|
|||
if (snd.isvalid())
|
||||
{
|
||||
auto udata = soundEngine->GetUserData(snd);
|
||||
int relVol = udata ? udata[2] : 255;
|
||||
int relVol = udata ? udata[0] : 255;
|
||||
sfxPlay3DSoundCP(actor, sndId, -1, 0, 0, (surfSfxMove[surf][2] != relVol) ? relVol : surfSfxMove[surf][3]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,13 +147,12 @@ void GameInterface::UpdateSounds()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
FSoundID getSfx(FSoundID soundId, float& attenuation, int& pitch, int& relvol)
|
||||
FSoundID getSfx(FSoundID soundId, float& attenuation, int& relvol)
|
||||
{
|
||||
auto udata = soundEngine->GetUserData(soundId);
|
||||
if (pitch < 0) pitch = udata ? udata[0] : 0x10000;
|
||||
|
||||
if (relvol < 0) relvol = 0;
|
||||
else if (relvol == 0) relvol = udata && udata[2] ? udata[2] : 80;
|
||||
else if (relvol == 0) relvol = udata && udata[0] ? udata[0] : 80;
|
||||
if (relvol > 255) relvol = 255;
|
||||
// Limit the attenuation. More than 2.0 is simply too much.
|
||||
attenuation = relvol > 0 ? clamp(80.f / relvol, 0.f, 2.f) : 1.f;
|
||||
|
@ -177,7 +176,7 @@ void sfxPlay3DSound(const DVector3& pos, int soundId, sectortype* pSector)
|
|||
float attenuation;
|
||||
int pitch = -1;
|
||||
int relvol = 0;
|
||||
sid = getSfx(sid, attenuation, pitch, relvol);
|
||||
sid = getSfx(sid, attenuation, relvol);
|
||||
auto sfx = soundEngine->GetSfx(sid);
|
||||
EChanFlags flags = CHANF_OVERLAP;
|
||||
if (sfx && sfx->LoopStart >= 0) flags |= CHANF_LOOP;
|
||||
|
@ -194,14 +193,14 @@ void sfxPlay3DSound(const DVector3& pos, int soundId, sectortype* pSector)
|
|||
|
||||
void sfxPlay3DSoundCP(DBloodActor* pActor, int soundId, int playchannel, int playflags, int pitch, int volume)
|
||||
{
|
||||
if (!SoundEnabled() || soundId < 0 || !pActor) return;
|
||||
if (!SoundEnabled() || soundId <= 0 || !pActor) return;
|
||||
auto sid = soundEngine->FindSoundByResID(soundId);
|
||||
if (!sid.isvalid()) return;
|
||||
|
||||
auto svec = GetSoundPos(pActor->spr.pos);
|
||||
|
||||
float attenuation;
|
||||
sid = getSfx(sid, attenuation, pitch, volume);
|
||||
sid = getSfx(sid, attenuation, volume);
|
||||
if (volume == -1) volume = 80;
|
||||
|
||||
if (playchannel >= 0)
|
||||
|
|
|
@ -62,24 +62,42 @@ void ByteSwapSFX(SFX* pSFX)
|
|||
//
|
||||
// S_AddBloodSFX
|
||||
//
|
||||
// Registers a new sound with the name "<lumpname>.sfx"
|
||||
// Actual sound data is searched for in the ns_bloodraw namespace.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void S_AddBloodSFX(int lumpnum)
|
||||
{
|
||||
FSoundID sfxnum;
|
||||
|
||||
int resid = fileSystem.GetResourceId(lumpnum);
|
||||
sfxinfo_t* soundfx = nullptr;
|
||||
|
||||
sfxnum = soundEngine->FindSoundByResIDNoHash(resid);
|
||||
if (sfxnum.isvalid())
|
||||
{
|
||||
soundfx = soundEngine->GetWritableSfx(sfxnum);
|
||||
if (soundfx->UserData.Size() == 0)
|
||||
{
|
||||
soundfx->UserData.Resize(1);
|
||||
soundfx->UserData[1] = 80; // default for RelVol
|
||||
}
|
||||
if (!soundfx->bTentative) return; // sound was already defined.
|
||||
}
|
||||
|
||||
auto sfxlump = fileSystem.ReadFile(lumpnum);
|
||||
SFX* sfx = (SFX*)sfxlump.GetMem();
|
||||
ByteSwapSFX(sfx);
|
||||
|
||||
FStringf rawname("%s.raw", sfx->rawName);
|
||||
auto rawlump = fileSystem.FindFile(rawname);
|
||||
FSoundID sfxnum;
|
||||
|
||||
if (rawlump != -1)
|
||||
{
|
||||
sfxnum = soundEngine->AddSoundLump(sfx->rawName, rawlump, 0, fileSystem.GetResourceId(lumpnum), 6);
|
||||
auto soundfx = soundEngine->GetWritableSfx(sfxnum);
|
||||
if (!sfxnum.isvalid())
|
||||
{
|
||||
sfxnum = soundEngine->AddSoundLump(FStringf("SfxSound@%04d", resid), rawlump, 0, resid, 6); // use a generic name here in case sound replacements are being used.
|
||||
soundfx = soundEngine->GetWritableSfx(sfxnum);
|
||||
soundfx->UserData.Resize(1);
|
||||
}
|
||||
if (sfx->format < 5 || sfx->format > 12)
|
||||
{ // [0..4] + invalid formats
|
||||
soundfx->RawRate = 11025;
|
||||
|
@ -92,14 +110,18 @@ static void S_AddBloodSFX(int lumpnum)
|
|||
{ // [9..12]
|
||||
soundfx->RawRate = 44100;
|
||||
}
|
||||
soundfx->NearLimit = 6;
|
||||
soundfx->lumpnum = rawlump;
|
||||
soundfx->bLoadRAW = true;
|
||||
soundfx->bExternal = true;
|
||||
soundfx->bTentative = false;
|
||||
soundfx->LoopStart = LittleLong(sfx->loopStart);
|
||||
//S_sfx[sfxnum].Volume = sfx->relVol / 255.f; This cannot be done because this volume setting is optional.
|
||||
soundfx->UserData.Resize(3);
|
||||
// pitchrange is unused.
|
||||
if (sfx->pitch != 0x10000) soundfx->DefPitch = sfx->pitch / 65536.f;
|
||||
else soundfx->DefPitch = 0;
|
||||
int* udata = (int*)soundfx->UserData.Data();
|
||||
udata[0] = sfx->pitch;
|
||||
udata[1] = sfx->pitchRange;
|
||||
udata[2] = sfx->relVol;
|
||||
udata[0] = sfx->relVol;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,8 +144,7 @@ void sndInit(void)
|
|||
auto type = fileSystem.GetResourceType(i);
|
||||
if (!stricmp(type, "SFX"))
|
||||
{
|
||||
if (soundEngine->FindSoundByResID(fileSystem.GetResourceId(i)) == NO_SOUND)
|
||||
S_AddBloodSFX(i);
|
||||
S_AddBloodSFX(i);
|
||||
}
|
||||
else if (!stricmp(type, "WAV") || !stricmp(type, "OGG") || !stricmp(type, "FLAC") || !stricmp(type, "VOC"))
|
||||
{
|
||||
|
@ -193,7 +214,7 @@ void sndStartSample(unsigned int nSound, int nVolume, int nChannel, bool bLoop,
|
|||
if (nVolume < 0)
|
||||
{
|
||||
auto udata = soundEngine->GetUserData(snd);
|
||||
if (udata) nVolume = min(Scale(udata[2], 255, 100), 255);
|
||||
if (udata) nVolume = min(Scale(udata[0], 255, 100), 255);
|
||||
else nVolume = 255;
|
||||
}
|
||||
if (bLoop) chanflags |= CHANF_LOOP;
|
||||
|
|
|
@ -250,7 +250,7 @@ DDukeActor* aim(DDukeActor* actor, int abase)
|
|||
setFreeAimVelocity(vel, zvel, plr->Angles.getPitchWithView(), 16.);
|
||||
|
||||
HitInfo hit{};
|
||||
hitscan(plr->GetActor()->getPosWithOffsetZ().plusZ(4), actor->sector(), DVector3(actor->spr.Angles.Yaw.ToVector() * vel, zvel), hit, CLIPMASK1);
|
||||
hitscan(plr->GetActor()->getPosWithOffsetZ().plusZ(4), actor->sector(), DVector3(actor->spr.Angles.Yaw.ToVector() * vel, zvel * 64), hit, CLIPMASK1);
|
||||
|
||||
if (hit.actor() != nullptr)
|
||||
{
|
||||
|
|
|
@ -679,7 +679,7 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw
|
|||
double zoffs = 32;
|
||||
if (isWorldTour()) // Twentieth Anniversary World Tour
|
||||
zoffs *= (actor->spr.scale.Y * 0.8);
|
||||
pos.Z += zoffs;
|
||||
pos.Z -= zoffs;
|
||||
}
|
||||
else if (actor->spr.picnum == DTILE_BOSS2)
|
||||
{
|
||||
|
@ -687,7 +687,7 @@ static void shootrpg(DDukeActor *actor, int p, DVector3 pos, DAngle ang, int atw
|
|||
double zoffs = 24;
|
||||
if (isWorldTour()) // Twentieth Anniversary World Tour
|
||||
zoffs *= (actor->spr.scale.Y * 0.8);
|
||||
pos.Z -= zoffs;
|
||||
pos.Z += zoffs;
|
||||
}
|
||||
|
||||
double dist = (ps[j].GetActor()->spr.pos.XY() - actor->spr.pos.XY()).Length();
|
||||
|
|
|
@ -174,19 +174,6 @@ void S_CacheAllSounds(void)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
static inline int S_GetPitch(FSoundID soundid)
|
||||
{
|
||||
auto const* snd = soundEngine->GetUserData(soundid);
|
||||
if (!snd) return 0;
|
||||
int const range = abs(snd[kPitchEnd] - snd[kPitchStart]);
|
||||
return (range == 0) ? snd[kPitchStart] : min(snd[kPitchStart], snd[kPitchEnd]) + rand() % range;
|
||||
}
|
||||
|
||||
float S_ConvertPitch(int lpitch)
|
||||
{
|
||||
return powf(2, lpitch / 1200.f); // I hope I got this right that ASS uses a linear scale where 1200 is a full octave.
|
||||
}
|
||||
|
||||
int S_GetUserFlags(FSoundID soundid)
|
||||
{
|
||||
if (!soundEngine->isValidSoundId(soundid)) return 0;
|
||||
|
@ -222,7 +209,7 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
|
|||
if (sfx->UserData.Size() >= kMaxUserData)
|
||||
{
|
||||
auto& sndinf = sfx->UserData;
|
||||
settable = !!(sndinf[kFlags] & SF_CONDEFINED);
|
||||
settable = sfx->bExternal;
|
||||
}
|
||||
}
|
||||
if (!settable)
|
||||
|
@ -234,9 +221,6 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
|
|||
// Set everything to 0 to have default handling.
|
||||
sfx->UserData.Resize(kMaxUserData);
|
||||
auto& sndinf = sfx->UserData;
|
||||
sndinf[kPitchStart] = 0;
|
||||
sndinf[kPitchEnd] = 0;
|
||||
sndinf[kPriority] = 0; // Raze's sound engine does not use this.
|
||||
sndinf[kVolAdjust] = 0;
|
||||
sndinf[kWorldTourMapping] = 0;
|
||||
sndinf[kFlags] = 0;
|
||||
|
@ -245,10 +229,9 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
|
|||
|
||||
sfx->ResourceId = index;
|
||||
sfx->UserData.Resize(kMaxUserData);
|
||||
sfx->bExternal = true;
|
||||
auto& sndinf = sfx->UserData;
|
||||
sndinf[kFlags] = (type & ~SF_ONEINST_INTERNAL) | SF_CONDEFINED;
|
||||
if (sndinf[kFlags] & SF_LOOP)
|
||||
sndinf[kFlags] |= SF_ONEINST_INTERNAL;
|
||||
sndinf[kFlags] = (type & SF_CON_MASK);
|
||||
|
||||
// Take care of backslashes in sound names. Also double backslashes which occur in World Tour.
|
||||
FString fn = filename;
|
||||
|
@ -263,13 +246,14 @@ int S_DefineSound(unsigned index, const char *filename, int minpitch, int maxpit
|
|||
fn.Substitute(".ogg", ".voc");
|
||||
sfx->lumpnum = S_LookupSound(fn);
|
||||
}
|
||||
sndinf[kPitchStart] = clamp<int>(minpitch, INT16_MIN, INT16_MAX);
|
||||
sndinf[kPitchEnd] = clamp<int>(maxpitch, INT16_MIN, INT16_MAX);
|
||||
sndinf[kPriority] = priority & 255;
|
||||
if (minpitch != 0 || maxpitch != 0)
|
||||
{
|
||||
sfx->DefPitch = (float)pow(2, clamp<int>(minpitch, INT16_MIN, INT16_MAX) / 1200.);
|
||||
sfx->DefPitchMax = (float)pow(2, clamp<int>(maxpitch, INT16_MIN, INT16_MAX) / 1200.);
|
||||
}
|
||||
sndinf[kVolAdjust] = clamp<int>(distance, INT16_MIN, INT16_MAX);
|
||||
sndinf[kWorldTourMapping] = 0;
|
||||
sfx->Volume = volume;
|
||||
//sfx->NearLimit = index == TELEPORTER + 1? 6 : 0; // the teleporter sound cannot be unlimited due to how it gets used.
|
||||
sfx->bTentative = false;
|
||||
return 0;
|
||||
}
|
||||
|
@ -501,25 +485,20 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int
|
|||
|
||||
S_GetCamera(&campos, nullptr, &camsect);
|
||||
GetPositionInfo(actor, soundid, camsect, campos, pos, &sndist, &sndpos);
|
||||
int pitch = S_GetPitch(soundid);
|
||||
|
||||
auto sfx = soundEngine->GetSfx(soundid);
|
||||
bool explosion = ((userflags & (SF_GLOBAL | SF_DTAG)) == (SF_GLOBAL | SF_DTAG)) ||
|
||||
((sfx->ResourceId == PIPEBOMB_EXPLODE || sfx->ResourceId == LASERTRIP_EXPLODE || sfx->ResourceId == RPG_EXPLODE));
|
||||
|
||||
bool underwater = ps[screenpeek].insector() && ps[screenpeek].cursector->lotag == ST_2_UNDERWATER;
|
||||
if (explosion)
|
||||
{
|
||||
if (underwater)
|
||||
pitch -= 1024;
|
||||
}
|
||||
else
|
||||
float pitch = 0;
|
||||
if (!explosion)
|
||||
{
|
||||
if (sndist > 32767 && !issoundcontroller(actor) && (userflags & (SF_LOOP | SF_MSFX)) == 0)
|
||||
return -1;
|
||||
|
||||
if (underwater && (userflags & SF_TALK) == 0)
|
||||
pitch = -768;
|
||||
pitch = 0.64f;
|
||||
}
|
||||
|
||||
bool is_playing = soundEngine->GetSoundPlayingInfo(SOURCE_Any, nullptr, soundid);
|
||||
|
@ -528,7 +507,7 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int
|
|||
|
||||
int const repeatp = (userflags & SF_LOOP);
|
||||
|
||||
if (repeatp && (userflags & SF_ONEINST_INTERNAL) && is_playing)
|
||||
if (repeatp && is_playing)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -543,8 +522,16 @@ int S_PlaySound3D(FSoundID soundid, DDukeActor* actor, const DVector3& pos, int
|
|||
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
|
||||
float vol = attenuation == ATTN_NONE ? 0.8f : 1.f;
|
||||
if (currentCommentarySound != NO_SOUND) vol *= 0.25f;
|
||||
auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, S_ConvertPitch(pitch));
|
||||
if (chan) chan->UserData = (currentCommentarySound != NO_SOUND);
|
||||
auto chan = soundEngine->StartSound(SOURCE_Actor, actor, &sndpos, CHAN_AUTO, flags, soundid, vol, attenuation, nullptr, pitch);
|
||||
if (chan)
|
||||
{
|
||||
if (explosion && underwater)
|
||||
{
|
||||
pitch = float(chan->Pitch? chan->Pitch * (0.55 / 128) : 0.55); // todo: fix pitch storage in backend.
|
||||
soundEngine->SetPitch(chan, pitch);
|
||||
}
|
||||
chan->UserData = (currentCommentarySound != NO_SOUND);
|
||||
}
|
||||
return chan ? 0 : -1;
|
||||
}
|
||||
|
||||
|
@ -564,11 +551,9 @@ int S_PlaySound(FSoundID soundid, int channel, EChanFlags flags, float vol)
|
|||
if ((!(snd_speech & 1) && (userflags & SF_TALK)))
|
||||
return -1;
|
||||
|
||||
int const pitch = S_GetPitch(soundid);
|
||||
|
||||
if (userflags & SF_LOOP) flags |= CHANF_LOOP;
|
||||
if (currentCommentarySound != NO_SOUND) vol *= 0.25f;
|
||||
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr, S_ConvertPitch(pitch));
|
||||
auto chan = soundEngine->StartSound(SOURCE_None, nullptr, nullptr, channel, flags, soundid, vol, ATTN_NONE, nullptr);
|
||||
if (chan) chan->UserData = (currentCommentarySound != NO_SOUND);
|
||||
return chan ? 0 : -1;
|
||||
}
|
||||
|
|
|
@ -18,23 +18,20 @@ enum {
|
|||
SF_TALK = 4,
|
||||
SF_ADULT = 8,
|
||||
SF_GLOBAL = 16,
|
||||
SF_ONEINST_INTERNAL = 32,
|
||||
SF_CONDEFINED = 64,
|
||||
|
||||
SF_DTAG = 128,
|
||||
SF_CON_MASK = 159,
|
||||
};
|
||||
|
||||
enum esound_t
|
||||
{
|
||||
kPitchStart,
|
||||
kPitchEnd,
|
||||
kVolAdjust,
|
||||
kPriority,
|
||||
kFlags,
|
||||
kWorldTourMapping,
|
||||
kMaxUserData
|
||||
};
|
||||
|
||||
class DDukeActor;
|
||||
int S_PlaySound(FSoundID num, int channel = CHAN_AUTO, EChanFlags flags = 0, float vol = 0.8f);
|
||||
int S_PlaySound3D(FSoundID num, DDukeActor* spriteNum, const DVector3& pos, int channel = CHAN_AUTO, EChanFlags flags = 0);
|
||||
int S_PlayActorSound(FSoundID soundNum, DDukeActor* spriteNum, int channel = CHAN_AUTO, EChanFlags flags = 0);
|
||||
|
|
927
wadsrc/static/filter/blood/sndinfo.txt
Normal file
927
wadsrc/static/filter/blood/sndinfo.txt
Normal file
|
@ -0,0 +1,927 @@
|
|||
$conreserve AMB1 1
|
||||
$conreserve AMB2 2
|
||||
$conreserve AMB3 3
|
||||
$conreserve AMB4 4
|
||||
$conreserve AMB5 5
|
||||
$conreserve AMB6 6
|
||||
$conreserve AMB7 7
|
||||
$conreserve AMB8 8
|
||||
$conreserve AMB9 9
|
||||
$conreserve AMB10 10
|
||||
$conreserve AMB11 11
|
||||
$conreserve AMB12 12
|
||||
$conreserve AMB13 13
|
||||
$conreserve AMB14 14
|
||||
$conreserve AMB15 15
|
||||
$conreserve AMB16 16
|
||||
$conreserve AMB17 17
|
||||
$conreserve AMB18 18
|
||||
$conreserve AMB19 19
|
||||
$conreserve AMB20 20
|
||||
$conreserve AMB21 21
|
||||
$conreserve AMB22 22
|
||||
$conreserve AMB24 24
|
||||
$conreserve AMB25 25
|
||||
$conreserve AMB26 26
|
||||
$conreserve RAIN2 27
|
||||
$conreserve QAMB1 28
|
||||
$conreserve QAMB2 29
|
||||
$conreserve QAMB3 30
|
||||
$conreserve QAMB4 31
|
||||
$conreserve QAMB5 32
|
||||
$conreserve QAMB6 33
|
||||
$conreserve QAMB7 34
|
||||
$conreserve QAMB8 35
|
||||
$conreserve QAMB9 36
|
||||
$conreserve QAMB10 37
|
||||
$conreserve QAMB11 38
|
||||
$conreserve QAMB12 39
|
||||
$conreserve WATERLAP 40
|
||||
$conreserve WATER2 41
|
||||
$conreserve UNDERWAT 42
|
||||
$conreserve CHAIN1 43
|
||||
$conreserve CHAIN2 44
|
||||
$conreserve CHAIN4 46
|
||||
$conreserve CHAIN5 47
|
||||
$conreserve ERIEDRNE 48
|
||||
$conreserve SWAMP 49
|
||||
$conreserve TORCH 50
|
||||
$conreserve MTLDRN 52
|
||||
$conreserve HOWLING 54
|
||||
$conreserve GRGLNG 56
|
||||
$conreserve DRONE 57
|
||||
$conreserve 1WIND 58
|
||||
$conreserve CHANT 59
|
||||
$conreserve HRTBT 60
|
||||
$conreserve TRAIN1 61
|
||||
$conreserve CHAIN6 62
|
||||
$conreserve ICHANT 63
|
||||
$conreserve ELCLOOP1 64
|
||||
$conreserve MUZAK22 65
|
||||
$conreserve ERTHLOOP 66
|
||||
$conreserve FANLUP2 67
|
||||
$conreserve DORCREAK 100
|
||||
$conreserve DOOROPEN 101
|
||||
$conreserve RUSTDOOR 102
|
||||
$conreserve DOORSLID 103
|
||||
$conreserve GEARSTAR 104
|
||||
$conreserve ELEVMOVE 105
|
||||
$conreserve SLABMOVE 106
|
||||
$conreserve QAIRDOOR 107
|
||||
$conreserve QDOORMV1 110
|
||||
$conreserve QHYDRO1 111
|
||||
$conreserve QMEDPLAT 112
|
||||
$conreserve QPLAT1 113
|
||||
$conreserve CRYPTLP1 114
|
||||
$conreserve QTRAIN1 115
|
||||
$conreserve QWINCH2 116
|
||||
$conreserve CREAKSML 117
|
||||
$conreserve CREAKROT 118
|
||||
$conreserve CREAKSLD 119
|
||||
$conreserve SLIDOOR1 120
|
||||
$conreserve SLIDOOR2 121
|
||||
$conreserve FLSHDOR1 122
|
||||
$conreserve FLSHDOR2 123
|
||||
$conreserve CRYPTLP 124
|
||||
$conreserve GEARHALT 150
|
||||
$conreserve ELEVSTOP 151
|
||||
$conreserve ELEVSTRT 152
|
||||
$conreserve ELSTOP2 153
|
||||
$conreserve QBASESE2 155
|
||||
$conreserve QDDOOR2 156
|
||||
$conreserve QDRCLOS4 157
|
||||
$conreserve HYDRO2A 158
|
||||
$conreserve QPLAT2 159
|
||||
$conreserve QSTNDR2 160
|
||||
$conreserve DOORCLOS 162
|
||||
$conreserve ELSTOP3 163
|
||||
$conreserve HYDRO2 164
|
||||
$conreserve HYDRO3 165
|
||||
$conreserve HYDRO4 166
|
||||
$conreserve ELVSTR2 167
|
||||
$conreserve SLIDSTP1 168
|
||||
$conreserve SLIDSTP2 169
|
||||
$conreserve FLSHSTP1 170
|
||||
$conreserve FLSHSTP2 171
|
||||
$conreserve FART1 172
|
||||
$conreserve FART2 173
|
||||
$conreserve CRYPTSTP 174
|
||||
$conreserve SWITCH5 200
|
||||
$conreserve QBASETRY 201
|
||||
$conreserve BASEUSE 202
|
||||
$conreserve QLATCH2 203
|
||||
$conreserve RUNETRY 206
|
||||
$conreserve RUNEUSE 207
|
||||
$conreserve FLICK 208
|
||||
$conreserve SWTCHWRK 209
|
||||
$conreserve SWTCHBRK 210
|
||||
$conreserve SWITCH1 211
|
||||
$conreserve SWITCH2 212
|
||||
$conreserve SWITCH3 213
|
||||
$conreserve RUNETRY2 214
|
||||
$conreserve ICEVIO 218
|
||||
$conreserve CHANT1LP 219
|
||||
$conreserve CHANT2LP 220
|
||||
$conreserve 13CHA 221
|
||||
$conreserve 13CHU 222
|
||||
$conreserve 13DEATH 223
|
||||
$conreserve 13KILL 224
|
||||
$conreserve BUZZ2 225
|
||||
$conreserve SIREN1 226
|
||||
$conreserve FLYBY1 227
|
||||
$conreserve FLYBY2 228
|
||||
$conreserve MACHGUN2 229
|
||||
$conreserve MACHGUN3 230
|
||||
$conreserve TANK2 231
|
||||
$conreserve JEEP1 232
|
||||
$conreserve JEEP2 233
|
||||
$conreserve SHELL1 234
|
||||
$conreserve SHELL2 235
|
||||
$conreserve BCREAK1 236
|
||||
$conreserve BCREAK2 237
|
||||
$conreserve BCREAK3 238
|
||||
$conreserve BCREAK4 239
|
||||
$conreserve BRGLOOP 240
|
||||
$conreserve ICEMELO1 241
|
||||
$conreserve ICEMELO2 242
|
||||
$conreserve ICEMELO3 243
|
||||
$conreserve ICEMELLP 244
|
||||
$conreserve CRACK2 245
|
||||
$conreserve MOAN4 246
|
||||
$conreserve MOAN3 247
|
||||
$conreserve MOAN2LP 248
|
||||
$conreserve SPARK 249
|
||||
$conreserve ARC1 250
|
||||
$conreserve ARC2 251
|
||||
$conreserve ARC3 252
|
||||
$conreserve SEWAGE 253
|
||||
$conreserve THUNDER1 254
|
||||
$conreserve THUNDER2 255
|
||||
$conreserve QTHUNDER 256
|
||||
$conreserve CLOCK 257
|
||||
$conreserve GUST1 258
|
||||
$conreserve GUST2 259
|
||||
$conreserve GUST3 260
|
||||
$conreserve GUST4 261
|
||||
$conreserve CREAK 262
|
||||
$conreserve BUBRISE 263
|
||||
$conreserve ERTHRMBL 265
|
||||
$conreserve SINEWAVE 266
|
||||
$conreserve WHISPERS 267
|
||||
$conreserve MOANS 268
|
||||
$conreserve LAUGH 269
|
||||
$conreserve BELL 270
|
||||
$conreserve 1OWL 271
|
||||
$conreserve 2OWL 272
|
||||
$conreserve TRNCRASH 274
|
||||
$conreserve TRNBRAKE 275
|
||||
$conreserve TRNHRN 276
|
||||
$conreserve TRAINSTP 277
|
||||
$conreserve HUM 278
|
||||
$conreserve RIFF1 279
|
||||
$conreserve RIFF2 280
|
||||
$conreserve RIFF3 281
|
||||
$conreserve TICKET 282
|
||||
$conreserve HEYSTOP 283
|
||||
$conreserve PING 284
|
||||
$conreserve FLATLIN1 285
|
||||
$conreserve FLATLIN2 286
|
||||
$conreserve MOAN2 287
|
||||
$conreserve SCREAM 288
|
||||
$conreserve HELPME 289
|
||||
$conreserve SOBBING 290
|
||||
$conreserve ELECGEN2 291
|
||||
$conreserve TURBGEN2 292
|
||||
$conreserve SMALWOOF 293
|
||||
$conreserve SMALPAIN 294
|
||||
$conreserve AMBULONG 295
|
||||
$conreserve AMBUSHRT 296
|
||||
$conreserve BUZSLOW2 297
|
||||
$conreserve ELECPOP2 298
|
||||
$conreserve ELECPOP4 299
|
||||
$conreserve GLASHIT2 300
|
||||
$conreserve POTTERY 301
|
||||
$conreserve MGDIE 302
|
||||
$conreserve EXPLODCS 303
|
||||
$conreserve EXPLODCM 304
|
||||
$conreserve EXPLODCL 305
|
||||
$conreserve EXPLODFS 306
|
||||
$conreserve EXPLODFM 307
|
||||
$conreserve EXPLODFL 308
|
||||
$conreserve EXPLODUS 309
|
||||
$conreserve EXPLODUM 310
|
||||
$conreserve EXPLODUL 311
|
||||
$conreserve SPLNTWOD 312
|
||||
$conreserve SHATSTON 313
|
||||
$conreserve RENMETAL 314
|
||||
$conreserve SHRED1 315
|
||||
$conreserve SHRED2 316
|
||||
$conreserve BALLNPOP 317
|
||||
$conreserve HEADSQ 318
|
||||
$conreserve GIBSQ 319
|
||||
$conreserve NAPLMEX2 320
|
||||
$conreserve RESPAWN 350
|
||||
$conreserve BURN 351
|
||||
$conreserve SIZZLE 352
|
||||
$conreserve SIZZLE2 353
|
||||
$conreserve DRIP1 354
|
||||
$conreserve DRIP2 355
|
||||
$conreserve DRIP3 356
|
||||
$conreserve PUNT 357
|
||||
$conreserve BOULDERS 358
|
||||
$conreserve MGFIRE 359
|
||||
$conreserve PADLOCK 360
|
||||
$conreserve BURSTFLM 361
|
||||
$conreserve BLDSPRY1 362
|
||||
$conreserve RING 363
|
||||
$conreserve SNAKEHIS 364
|
||||
$conreserve SNAKEPIT 365
|
||||
$conreserve CASHREG 366
|
||||
$conreserve DIALTONE 367
|
||||
$conreserve BUSYSIG 368
|
||||
$conreserve TOILET 369
|
||||
$conreserve RECSCRAP 370
|
||||
$conreserve DRIP4 371
|
||||
$conreserve DRIP5 372
|
||||
$conreserve DRIP6 373
|
||||
$conreserve PAILKICK 374
|
||||
$conreserve SIZZLE1 375
|
||||
$conreserve SAWRUN 376
|
||||
$conreserve SAWCUT 377
|
||||
$conreserve SAWCOCK1 378
|
||||
$conreserve REAPPEAR 379
|
||||
$conreserve RESPAWN2 380
|
||||
$conreserve BLDSPT2 381
|
||||
$conreserve BLADEDRP 382
|
||||
$conreserve BDYPRTIM 383
|
||||
$conreserve BDYPTIM2 384
|
||||
$conreserve BLUDSPLT 385
|
||||
$conreserve ZIPOPEN 400
|
||||
$conreserve ZIPCLOSE 401
|
||||
$conreserve ZIPLIGHT 402
|
||||
$conreserve SHOTCOCK 410
|
||||
$conreserve SHOTFIRE 411
|
||||
$conreserve SHOTFIR2 412
|
||||
$conreserve SHOTLOAD 413
|
||||
$conreserve FLAREF 420
|
||||
$conreserve FLAREFUW 421
|
||||
$conreserve FLARAIR2 422
|
||||
$conreserve FLAR_WAT 423
|
||||
$conreserve TOMCOCK 430
|
||||
$conreserve _TOM 431
|
||||
$conreserve SPRAYCAN 440
|
||||
$conreserve SPRAYFIR 441
|
||||
$conreserve TNTFUSE 450
|
||||
$conreserve PROXARM 451
|
||||
$conreserve PROXDET 452
|
||||
$conreserve REMFIRE 453
|
||||
$conreserve REMDET 454
|
||||
$conreserve TNTTOSS 455
|
||||
$conreserve VOOSTAB 460
|
||||
$conreserve VOOCHANT 461
|
||||
$conreserve VOOBURN 462
|
||||
$conreserve VOOLAUGH 463
|
||||
$conreserve TESSNGFR 470
|
||||
$conreserve TESALTFR 471
|
||||
$conreserve ROTBAREL 472
|
||||
$conreserve SNGAIR2 473
|
||||
$conreserve ALTAIR2 474
|
||||
$conreserve TESALTF2 475
|
||||
$conreserve TESLA1 476
|
||||
$conreserve TALTAC3 477
|
||||
$conreserve TESLAZ1 478
|
||||
$conreserve TESLAZ2 479
|
||||
$conreserve BLASTER 480
|
||||
$conreserve BLASTARC 481
|
||||
$conreserve STAFFIRE 489
|
||||
$conreserve LLSNGFR3 490
|
||||
$conreserve LLALTFR2 491
|
||||
$conreserve LLCHARGE 492
|
||||
$conreserve SKULAIR4 493
|
||||
$conreserve LALTFR1 494
|
||||
$conreserve ACIDHIT1 495
|
||||
$conreserve ACIDHIT2 496
|
||||
$conreserve BEASTCLW 499
|
||||
$conreserve PSTONE 500
|
||||
$conreserve PMETAL 501
|
||||
$conreserve PWOOD 502
|
||||
$conreserve PFLESH 503
|
||||
$conreserve UPSTONE 504
|
||||
$conreserve UPMETAL 505
|
||||
$conreserve UPWOOD 506
|
||||
$conreserve UPFLESH 507
|
||||
$conreserve BSTONE 510
|
||||
$conreserve BMETAL 511
|
||||
$conreserve BWOOD 512
|
||||
$conreserve BFLESH 513
|
||||
$conreserve BWATER 514
|
||||
$conreserve RICOCHT1 515
|
||||
$conreserve RICOCHT2 516
|
||||
$conreserve RICOCHT3 517
|
||||
$conreserve TESSNGHT 518
|
||||
$conreserve TESALTHT 519
|
||||
$conreserve ELECDAM2 520
|
||||
$conreserve LLSNGHT2 521
|
||||
$conreserve LLALTHT 522
|
||||
$conreserve CLAW 530
|
||||
$conreserve LNDSTONE 600
|
||||
$conreserve LNDMETAL 601
|
||||
$conreserve LNDWOOD 602
|
||||
$conreserve LNDFLESH 603
|
||||
$conreserve LNDWATER 604
|
||||
$conreserve LNDDIRT 605
|
||||
$conreserve BODYHIT1 607
|
||||
$conreserve MTSHLS 608
|
||||
$conreserve SHTSHL 609
|
||||
$conreserve SHTSHL2 610
|
||||
$conreserve SHTSHL3 611
|
||||
$conreserve SHTSHL4 612
|
||||
$conreserve JUMP 700
|
||||
$conreserve LAND 701
|
||||
$conreserve HUNT1 702
|
||||
$conreserve HUNT2 703
|
||||
$conreserve HUNT3 704
|
||||
$conreserve HUNT4 705
|
||||
$conreserve UWBREATH 706
|
||||
$conreserve FRBREATH 707
|
||||
$conreserve SWIM 708
|
||||
$conreserve SWIMUW 709
|
||||
$conreserve PAIN1 710
|
||||
$conreserve PAIN2 711
|
||||
$conreserve PAIN3 712
|
||||
$conreserve PAIN4 713
|
||||
$conreserve PAIN5 714
|
||||
$conreserve PAIN6 715
|
||||
$conreserve DIE1 716
|
||||
$conreserve DIE2 717
|
||||
$conreserve DIE3 718
|
||||
$conreserve FALL 719
|
||||
$conreserve SUBMERGE 720
|
||||
$conreserve EMERGE 721
|
||||
$conreserve GASP 722
|
||||
$conreserve INHALE 723
|
||||
$conreserve UNDCHOKE 724
|
||||
$conreserve PLAY1100 725
|
||||
$conreserve PLAY1101 726
|
||||
$conreserve PLAY1102 727
|
||||
$conreserve PLAY1103 728
|
||||
$conreserve PLAY1104 729
|
||||
$conreserve PLAY1105 730
|
||||
$conreserve PLAY1106 731
|
||||
$conreserve PLAY1107 732
|
||||
$conreserve PLAY1108 733
|
||||
$conreserve PLAY1109 734
|
||||
$conreserve PLAY1110 735
|
||||
$conreserve PLAY1111 736
|
||||
$conreserve PLAY1112 737
|
||||
$conreserve PLAY1113 738
|
||||
$conreserve PLAY1114 739
|
||||
$conreserve PLAY1115 740
|
||||
$conreserve PLAY1116 741
|
||||
$conreserve PLAY1118 742
|
||||
$conreserve PLAY1119 743
|
||||
$conreserve PLAY1120 744
|
||||
$conreserve BST_FLSH 745
|
||||
$conreserve PLAYCHOK 746
|
||||
$conreserve PLAYCHK2 747
|
||||
$conreserve PICKUP 775
|
||||
$conreserve POWERUP 776
|
||||
$conreserve WEAPONUP 777
|
||||
$conreserve MESSAGE 778
|
||||
$conreserve PICKARMR 779
|
||||
$conreserve PICKHEAL 780
|
||||
$conreserve PICKKEY 781
|
||||
$conreserve AMMO 782
|
||||
$conreserve FFSTONE1 802
|
||||
$conreserve FFSTONE2 803
|
||||
$conreserve FFMETAL1 804
|
||||
$conreserve FFMETAL2 805
|
||||
$conreserve FFWOOD1 806
|
||||
$conreserve FFWOOD2 807
|
||||
$conreserve FFFLESH1 808
|
||||
$conreserve FFFLESH2 809
|
||||
$conreserve FFWATER1 810
|
||||
$conreserve FFWATER2 811
|
||||
$conreserve FFDIRT1 812
|
||||
$conreserve FFDIRT2 813
|
||||
$conreserve FFCLAY1 814
|
||||
$conreserve FFCLAY2 815
|
||||
$conreserve FFSNOW1 816
|
||||
$conreserve FFSNOW2 817
|
||||
$conreserve FFICE1 818
|
||||
$conreserve FFICE2 819
|
||||
$conreserve FFLEAF1 820
|
||||
$conreserve FFLEAF2 821
|
||||
$conreserve FFCLOTH1 822
|
||||
$conreserve FFCLOTH2 823
|
||||
$conreserve FFPLANT1 824
|
||||
$conreserve FFPLANT2 825
|
||||
$conreserve FFGOO1 826
|
||||
$conreserve FFGOO2 827
|
||||
$conreserve FFLAVA1 828
|
||||
$conreserve FFLAVA2 829
|
||||
$conreserve CULTTOSS 1000
|
||||
$conreserve CULTATT1 1001
|
||||
$conreserve CULTATT2 1002
|
||||
$conreserve CULTSPT1 1003
|
||||
$conreserve CULTSPT2 1004
|
||||
$conreserve CULTSPT3 1005
|
||||
$conreserve CULTSPT4 1006
|
||||
$conreserve CULTSPT5 1007
|
||||
$conreserve CULTROM1 1008
|
||||
$conreserve CULTROM2 1009
|
||||
$conreserve CULTROM3 1010
|
||||
$conreserve CULTROM4 1011
|
||||
$conreserve CULTROM5 1012
|
||||
$conreserve CULTPAN1 1013
|
||||
$conreserve CULTPAN2 1014
|
||||
$conreserve CULTPAN3 1015
|
||||
$conreserve CULTPAN4 1016
|
||||
$conreserve CULTPAN5 1017
|
||||
$conreserve CULTDIE1 1018
|
||||
$conreserve CULTDIE2 1019
|
||||
$conreserve CULTDIE3 1020
|
||||
$conreserve CULTGLO1 1021
|
||||
$conreserve CULTGLO2 1022
|
||||
$conreserve CULTGLO3 1023
|
||||
$conreserve CULTGLO4 1024
|
||||
$conreserve CULTFIR1 1031
|
||||
$conreserve CULTFIR2 1032
|
||||
$conreserve CULTFIR3 1033
|
||||
$conreserve TCLTTOSS 4000
|
||||
$conreserve TCLTATT1 4001
|
||||
$conreserve TCLTATT2 4002
|
||||
$conreserve TCLTSPT1 4003
|
||||
$conreserve TCLTSPT2 4004
|
||||
$conreserve TCLTSPT3 4005
|
||||
$conreserve TCLTSPT4 4006
|
||||
$conreserve TCLTSPT5 4007
|
||||
$conreserve TCLTROM1 4008
|
||||
$conreserve TCLTROM2 4009
|
||||
$conreserve TCLTROM3 4010
|
||||
$conreserve TCLTROM4 4011
|
||||
$conreserve TCLTROM5 4012
|
||||
$conreserve TCLTPAN1 4013
|
||||
$conreserve TCLTPAN2 4014
|
||||
$conreserve TCLTPAN3 4015
|
||||
$conreserve TCLTPAN4 4016
|
||||
$conreserve TCLTPAN5 4017
|
||||
$conreserve TCLTDIE1 4018
|
||||
$conreserve TCLTDIE2 4019
|
||||
$conreserve TCLTDIE3 4020
|
||||
$conreserve TCLTGLO1 4021
|
||||
$conreserve TCLTGLO2 4022
|
||||
$conreserve TCLTFIR1 4031
|
||||
$conreserve TCLTFIR2 4032
|
||||
$conreserve TCLTFIR3 4033
|
||||
$conreserve AZOMRISE 1100
|
||||
$conreserve AZOMSWIP 1101
|
||||
$conreserve AZOMSTND 1102
|
||||
$conreserve AZOMSPOT 1103
|
||||
$conreserve AZOMROAM 1104
|
||||
$conreserve AZOMMOAN 1105
|
||||
$conreserve AZOMPAIN 1106
|
||||
$conreserve AZOMDIE1 1107
|
||||
$conreserve AZOMDIE2 1108
|
||||
$conreserve AZOMDIE3 1109
|
||||
$conreserve FZOMSPOT 1200
|
||||
$conreserve FZOMROAM 1201
|
||||
$conreserve FZOMPAIN 1202
|
||||
$conreserve FZOMPUKE 1203
|
||||
$conreserve FZOMDIE1 1204
|
||||
$conreserve FZOMDIE2 1205
|
||||
$conreserve FZOMDIE3 1206
|
||||
$conreserve CLEAVER 1207
|
||||
$conreserve CERBSPOT 1300
|
||||
$conreserve CERBPAIN 1302
|
||||
$conreserve CERBDIE1 1303
|
||||
$conreserve CERBDIE2 1304
|
||||
$conreserve CERBDIE3 1305
|
||||
$conreserve HOUNDBIT 1306
|
||||
$conreserve HOUNDBT2 1307
|
||||
$conreserve HOUNDBT3 1308
|
||||
$conreserve FIRBALL 1309
|
||||
$conreserve GARGSPOT 1400
|
||||
$conreserve GARGROAM 1401
|
||||
$conreserve GARGPAIN 1402
|
||||
$conreserve GARGDIE1 1403
|
||||
$conreserve GARGDIE2 1404
|
||||
$conreserve GARGDIE3 1405
|
||||
$conreserve GARGCLAW 1406
|
||||
$conreserve GARGBLST 1407
|
||||
$conreserve GARGTHRO 1408
|
||||
$conreserve SARGSPOT 1450
|
||||
$conreserve SARGROAM 1451
|
||||
$conreserve SARGPAIN 1452
|
||||
$conreserve SARGDIE1 1453
|
||||
$conreserve SARGDIE2 1454
|
||||
$conreserve SARGDIE3 1455
|
||||
$conreserve SARGCLAW 1456
|
||||
$conreserve SARGBLST 1457
|
||||
$conreserve SARGTHRO 1458
|
||||
$conreserve EELSPOT 1500
|
||||
$conreserve EELROAM 1501
|
||||
$conreserve EELPAIN 1502
|
||||
$conreserve EELDIE1 1503
|
||||
$conreserve EELDIE2 1504
|
||||
$conreserve EELDIE3 1505
|
||||
$conreserve PHANSPOT 1600
|
||||
$conreserve PHANROAM 1601
|
||||
$conreserve PHANPAIN 1602
|
||||
$conreserve PHANDIE1 1603
|
||||
$conreserve PHANDIE3 1604
|
||||
$conreserve PHANDIE3A 1605
|
||||
$conreserve GILLSPOT 1700
|
||||
$conreserve GILLROAM 1701
|
||||
$conreserve GILLPAIN 1702
|
||||
$conreserve GILLDIE1 1703
|
||||
$conreserve GILLDIE2 1704
|
||||
$conreserve GILLDIE3 1705
|
||||
$conreserve SPIDSPOT 1800
|
||||
$conreserve SPIDROAM 1801
|
||||
$conreserve SPIDPAIN 1802
|
||||
$conreserve SPIDDIE1 1803
|
||||
$conreserve SPIDDIE2 1804
|
||||
$conreserve SPIDDIE3 1805
|
||||
$conreserve MSPIDIE 1850
|
||||
$conreserve MSPIPAN1 1851
|
||||
$conreserve MSPIPAN2 1852
|
||||
$conreserve MSPISPT1 1853
|
||||
$conreserve MSPISPT2 1854
|
||||
$conreserve HANDSPOT 1900
|
||||
$conreserve HANDROAM 1901
|
||||
$conreserve HANDPAIN 1902
|
||||
$conreserve HANDDIE1 1903
|
||||
$conreserve HANDDIE2 1904
|
||||
$conreserve HANDDIE3 1905
|
||||
$conreserve BATSPOT 2000
|
||||
$conreserve BATROAM 2001
|
||||
$conreserve BATPAIN 2002
|
||||
$conreserve BATDIE1 2003
|
||||
$conreserve BATDIE2 2004
|
||||
$conreserve BATDIE3 2005
|
||||
$conreserve BAT 2006
|
||||
$conreserve RATSPOT 2100
|
||||
$conreserve RATROAM 2101
|
||||
$conreserve RATPAIN 2102
|
||||
$conreserve RATDIE1 2103
|
||||
$conreserve RATDIE2 2104
|
||||
$conreserve RATDIE3 2105
|
||||
$conreserve PODSQUIS 2200
|
||||
$conreserve PODOPEN 2201
|
||||
$conreserve PODDIE1 2203
|
||||
$conreserve PODDIE2 2204
|
||||
$conreserve PODDIE3 2205
|
||||
$conreserve PODSWISH 2206
|
||||
$conreserve CERBSPOTA 2300
|
||||
$conreserve CERBROAM 2301
|
||||
$conreserve CERBPAIN2 2302
|
||||
$conreserve CERBPAIN3 2303
|
||||
$conreserve CERBDIE2A 2304
|
||||
$conreserve CERBDIE3A 2305
|
||||
$conreserve CERBDIE4 2306
|
||||
$conreserve TBBOW1 2350
|
||||
$conreserve TBBOW2 2351
|
||||
$conreserve TBKNEEL1 2352
|
||||
$conreserve TBKNEEL2 2353
|
||||
$conreserve TBKNEEL3 2354
|
||||
$conreserve TBKNEEL4 2355
|
||||
$conreserve TBWAIT1 2356
|
||||
$conreserve TBWAIT2 2357
|
||||
$conreserve TBLAUGH1 2360
|
||||
$conreserve TBLAUGH2 2361
|
||||
$conreserve TBLAUGH3 2362
|
||||
$conreserve TBLAUGH4 2363
|
||||
$conreserve TBLAUGH5 2364
|
||||
$conreserve TBSACRI1 2365
|
||||
$conreserve TBSACRI2 2366
|
||||
$conreserve TBSACRI3 2367
|
||||
$conreserve TBWORSH1 2368
|
||||
$conreserve TBWORSH2 2369
|
||||
$conreserve TBPAIN1 2370
|
||||
$conreserve TBPAIN2 2371
|
||||
$conreserve TBPAIN3 2372
|
||||
$conreserve TBPAIN4 2373
|
||||
$conreserve TBPAIN5 2374
|
||||
$conreserve TBPAIN6 2375
|
||||
$conreserve TBPAIN7 2377
|
||||
$conreserve TBDIES 2380
|
||||
$conreserve TCHNEVAP 2381
|
||||
$conreserve FLYBUZZ 2400
|
||||
$conreserve MFLY 2401
|
||||
$conreserve FPODCLOS 2450
|
||||
$conreserve FPODCOL2 2451
|
||||
$conreserve FPODEXP2 2452
|
||||
$conreserve FPODOPEN 2453
|
||||
$conreserve FPODSPIT 2454
|
||||
$conreserve FPODCLOS2 2470
|
||||
$conreserve PODCOL2 2471
|
||||
$conreserve PODEXP2 2472
|
||||
$conreserve NPODOPEN 2473
|
||||
$conreserve PODSPIT1 2474
|
||||
$conreserve PODSPIT2 2475
|
||||
$conreserve TENTDWN3 2500
|
||||
$conreserve TENTEXP 2501
|
||||
$conreserve TENTSWP4 2502
|
||||
$conreserve TENTUP3 2503
|
||||
$conreserve 1001 3000
|
||||
$conreserve 1002 3001
|
||||
$conreserve 1003 3002
|
||||
$conreserve 1004 3003
|
||||
$conreserve 1005 3004
|
||||
$conreserve 1006 3005
|
||||
$conreserve 1007 3006
|
||||
$conreserve 1008 3007
|
||||
$conreserve 1009 3008
|
||||
$conreserve 1010 3009
|
||||
$conreserve 1011 3010
|
||||
$conreserve 1012 3011
|
||||
$conreserve 1013 3012
|
||||
$conreserve 1014 3013
|
||||
$conreserve 1015 3014
|
||||
$conreserve 1016 3015
|
||||
$conreserve 1017 3016
|
||||
$conreserve 1018 3017
|
||||
$conreserve 1019 3018
|
||||
$conreserve 1020 3019
|
||||
$conreserve 1021 3020
|
||||
$conreserve 1022 3021
|
||||
$conreserve 1023 3022
|
||||
$conreserve 1024 3023
|
||||
$conreserve 1025 3024
|
||||
$conreserve 1026 3025
|
||||
$conreserve 1027 3026
|
||||
$conreserve 1028 3027
|
||||
$conreserve 1029 3028
|
||||
$conreserve 1030 3029
|
||||
$conreserve 1031 3030
|
||||
$conreserve 1032 3031
|
||||
$conreserve 1033 3032
|
||||
$conreserve 1034 3033
|
||||
$conreserve 1035 3034
|
||||
$conreserve 1036 3035
|
||||
$conreserve 1037 3036
|
||||
$conreserve 1038 3037
|
||||
$conreserve 1039 3038
|
||||
$conreserve 1040 3039
|
||||
$conreserve 1041 3040
|
||||
$conreserve 1042 3041
|
||||
$conreserve 1043 3042
|
||||
$conreserve 1044 3043
|
||||
$conreserve 1045 3044
|
||||
$conreserve 1046 3045
|
||||
$conreserve 1047 3046
|
||||
$conreserve 1048 3047
|
||||
$conreserve 1049 3048
|
||||
$conreserve 1050 3049
|
||||
$conreserve 1051 3050
|
||||
$conreserve 1052 3051
|
||||
$conreserve 1053 3052
|
||||
$conreserve 1054 3053
|
||||
$conreserve 1055 3054
|
||||
$conreserve 1056 3055
|
||||
$conreserve 1057 3056
|
||||
$conreserve 1059 3058
|
||||
$conreserve 1060 3059
|
||||
$conreserve 1061 3060
|
||||
$conreserve 1062 3061
|
||||
$conreserve 1063 3062
|
||||
$conreserve 1064 3063
|
||||
$conreserve 1065 3064
|
||||
$conreserve 1066 3065
|
||||
$conreserve 1067 3066
|
||||
$conreserve 1068 3067
|
||||
$conreserve 1069 3068
|
||||
$conreserve 1070 3069
|
||||
$conreserve 1071 3070
|
||||
$conreserve 1072 3071
|
||||
$conreserve 1073 3072
|
||||
$conreserve 1074 3073
|
||||
$conreserve 1075 3074
|
||||
$conreserve 1076 3075
|
||||
$conreserve 1077 3076
|
||||
$conreserve 1078 3077
|
||||
$conreserve 1079 3078
|
||||
$conreserve 1080 3079
|
||||
$conreserve 1081 3080
|
||||
$conreserve 1082 3081
|
||||
$conreserve 1083 3082
|
||||
$conreserve 1084 3083
|
||||
$conreserve 1085 3084
|
||||
$conreserve 1093 3100
|
||||
$conreserve 1094 3101
|
||||
$conreserve 1095 3102
|
||||
$conreserve 1097 3103
|
||||
$conreserve VO3011 3104
|
||||
$conreserve VO3024 3105
|
||||
$conreserve VO3026 3106
|
||||
$conreserve VO3030 3107
|
||||
$conreserve VO3033 3108
|
||||
$conreserve VO3034 3109
|
||||
$conreserve VO3035 3110
|
||||
$conreserve VO3039 3111
|
||||
$conreserve 2100 3200
|
||||
$conreserve 2101 3201
|
||||
$conreserve 2102 3202
|
||||
$conreserve 2103 3203
|
||||
$conreserve 2104 3204
|
||||
$conreserve 2105 3205
|
||||
$conreserve 2106 3206
|
||||
$conreserve 2107 3207
|
||||
$conreserve 2108 3208
|
||||
$conreserve 2109 3209
|
||||
$conreserve ZOMBIE 3210
|
||||
$conreserve 2111 3211
|
||||
$conreserve 2112 3212
|
||||
$conreserve 2113 3213
|
||||
$conreserve 2114 3214
|
||||
$conreserve 2116 3216
|
||||
$conreserve VO1 3300
|
||||
$conreserve VO2 3301
|
||||
$conreserve VO3 3302
|
||||
$conreserve VO4 3303
|
||||
$conreserve VO5 3304
|
||||
$conreserve VO6 3305
|
||||
$conreserve VO7 3306
|
||||
$conreserve VO8 3307
|
||||
$conreserve VO9 3308
|
||||
$conreserve VO10 3309
|
||||
$conreserve VO12 3310
|
||||
$conreserve VO13 3311
|
||||
$conreserve VO14 3312
|
||||
$conreserve VO15 3313
|
||||
$conreserve VO16 3314
|
||||
$conreserve VO17 3317
|
||||
$conreserve VO18 3318
|
||||
$conreserve VO19 3319
|
||||
$conreserve VO20 3320
|
||||
$conreserve VO21 3321
|
||||
$conreserve VO22 3322
|
||||
$conreserve VO23 3323
|
||||
$conreserve VO24 3324
|
||||
$conreserve VO25 3325
|
||||
$conreserve VO26 3326
|
||||
$conreserve VO27 3327
|
||||
$conreserve VO28 3328
|
||||
$conreserve VO29 3329
|
||||
$conreserve VO30 3330
|
||||
$conreserve VO31 3331
|
||||
$conreserve VO32 3332
|
||||
$conreserve VO33 3333
|
||||
$conreserve VO34 3334
|
||||
$conreserve VO35 3335
|
||||
$conreserve VO36 3336
|
||||
$conreserve VO37 3337
|
||||
$conreserve VO38 3338
|
||||
$conreserve VO39 3339
|
||||
$conreserve VO40 3340
|
||||
$conreserve VO41 3341
|
||||
$conreserve VO42 3342
|
||||
$conreserve VO43 3343
|
||||
$conreserve VO44 3344
|
||||
$conreserve ALIVE 3345
|
||||
$conreserve BONED 4100
|
||||
$conreserve CASTRA 4101
|
||||
$conreserve CREAMED 4102
|
||||
$conreserve DESTRO 4103
|
||||
$conreserve DICED 4104
|
||||
$conreserve DISEMBO 4105
|
||||
$conreserve FLATTE 4106
|
||||
$conreserve JUSTICE 4107
|
||||
$conreserve MADNESS 4108
|
||||
$conreserve DECIMAT 4109
|
||||
$conreserve KILLED 4110
|
||||
$conreserve MINCMEAT 4111
|
||||
$conreserve MASSACR 4112
|
||||
$conreserve MUTILA 4113
|
||||
$conreserve REAMED 4114
|
||||
$conreserve RIPPED 4115
|
||||
$conreserve SLAUGHT 4116
|
||||
$conreserve SLICED 4117
|
||||
$conreserve SMASHED 4118
|
||||
$conreserve SODOMIZ 4119
|
||||
$conreserve SPLATT 4120
|
||||
$conreserve SQUASH 4121
|
||||
$conreserve THROTTL 4122
|
||||
$conreserve WASTED 4123
|
||||
$conreserve 10 4124
|
||||
$conreserve OMNI24 4125
|
||||
$conreserve OMNI25 4126
|
||||
$conreserve OMNI26 4127
|
||||
$conreserve OMNI27 4128
|
||||
$conreserve OMNI32 4129
|
||||
$conreserve OMNI34 4130
|
||||
$conreserve OMNI35 4141
|
||||
$conreserve OMNI36 4132
|
||||
$conreserve OMNI37 4133
|
||||
$conreserve OMNI41 4134
|
||||
$conreserve OMNI43 4135
|
||||
$conreserve OMNI44 4136
|
||||
$conreserve OMNI5 4200
|
||||
$conreserve OMNI7 4202
|
||||
$conreserve OMNI8 4203
|
||||
$conreserve OMNI9 4204
|
||||
$conreserve OMNI12 4206
|
||||
$conreserve OMNI13 4207
|
||||
$conreserve OMNI16 4208
|
||||
$conreserve OMNI20 4210
|
||||
$conreserve OMNI21 4211
|
||||
$conreserve OMNI22 4212
|
||||
$conreserve OMNI23 4213
|
||||
$conreserve OMNI15A 4300
|
||||
$conreserve TAUNT0 4400
|
||||
$conreserve TAUNT1 4401
|
||||
$conreserve TAUNT2 4402
|
||||
$conreserve TAUNT3 4403
|
||||
$conreserve TAUNT4 4404
|
||||
$conreserve TAUNT5 4405
|
||||
$conreserve TAUNT6 4406
|
||||
$conreserve TAUNT7 4407
|
||||
$conreserve TAUNT8 4408
|
||||
$conreserve TAUNT9 4409
|
||||
$conreserve 3000 4500
|
||||
$conreserve 3001B 4502
|
||||
$conreserve 3002A 4503
|
||||
$conreserve 3002B 4504
|
||||
$conreserve 3002C 4505
|
||||
$conreserve 3002D 4506
|
||||
$conreserve 3003 4507
|
||||
$conreserve 3004B 4509
|
||||
$conreserve 3006 4511
|
||||
$conreserve 3007 4512
|
||||
$conreserve 3008 4513
|
||||
$conreserve 3009 4514
|
||||
$conreserve 3010 4515
|
||||
$conreserve 3011 4516
|
||||
$conreserve 3012 4517
|
||||
$conreserve 3013 4518
|
||||
$conreserve 3014 4519
|
||||
$conreserve 3015 4520
|
||||
$conreserve 3016A 4521
|
||||
$conreserve 3017 4523
|
||||
$conreserve 3018B 4525
|
||||
$conreserve 3019 4526
|
||||
$conreserve 3020 4527
|
||||
$conreserve 3021 4528
|
||||
$conreserve 3022B 4530
|
||||
$conreserve 3023A 4531
|
||||
$conreserve 3024 4533
|
||||
$conreserve 3025 4534
|
||||
$conreserve 3026 4535
|
||||
$conreserve 3027 4536
|
||||
$conreserve 3028 4537
|
||||
$conreserve 3029 4538
|
||||
$conreserve 3030 4539
|
||||
$conreserve 3031 4540
|
||||
$conreserve 3032 4541
|
||||
$conreserve 3033 4542
|
||||
$conreserve 3034 4543
|
||||
$conreserve 3035 4544
|
||||
$conreserve 3036 4545
|
||||
$conreserve 3037 4546
|
||||
$conreserve 3038 4547
|
||||
$conreserve 3039 4548
|
||||
$conreserve ICRYING 7000
|
||||
$conreserve ICRYING2 7001
|
||||
$conreserve IDONHME 7002
|
||||
$conreserve IGOAWAY2 7003
|
||||
$conreserve IGOAWAY3 7004
|
||||
$conreserve INOPLACE 7005
|
||||
$conreserve IPLEASE 7006
|
||||
$conreserve ISCREAM1 7007
|
||||
$conreserve ISCREAM2 7008
|
||||
$conreserve 8000 8000
|
||||
$conreserve 8001 8001
|
||||
$conreserve 8002 8002
|
||||
$conreserve 8003 8003
|
||||
$conreserve 8004 8004
|
||||
$conreserve 8005 8005
|
||||
$conreserve 8006 8006
|
||||
$conreserve 8007 8007
|
||||
$conreserve BEASTD4 9000
|
||||
$conreserve BEASTD3 9001
|
||||
$conreserve BEASTD2 9002
|
||||
$conreserve BEASTD1 9003
|
||||
$conreserve BEAST1 9004
|
||||
$conreserve BEAST2 9005
|
||||
$conreserve BEAST3 9006
|
||||
$conreserve CALEBM1 9007
|
||||
$conreserve CULTMO1 9008
|
||||
$conreserve ROAR1 9009
|
||||
$conreserve ROAR2 9010
|
||||
$conreserve ROAR3 9011
|
||||
$conreserve SLASH1 9012
|
||||
$conreserve SLASH2 9013
|
||||
$conreserve SLASH3 9014
|
||||
$conreserve T1005 10001
|
||||
$conreserve T1002 10000
|
||||
$conreserve STOMP3 9017
|
||||
$conreserve STOMP4 9016
|
||||
$conreserve STOM5 9015
|
||||
$conreserve T1006 10002
|
||||
$conreserve T1010 10003
|
||||
$conreserve T1011 10004
|
||||
$conreserve T1015 10005
|
||||
$conreserve T1051 10006
|
||||
$conreserve T1003 11000
|
||||
$conreserve T1013 11001
|
|
@ -117,7 +117,7 @@ switches
|
|||
comboswitch = "TECHSWITCH", "TECHSWITCHON"
|
||||
comboswitch = "ALIENSWITCH", "ALIENSWITCHON"
|
||||
accessswitch = "ACCESSSWITCH", "ACCESSSWITCHON", nofilter, oneway
|
||||
accessswitch = "ACCESSSWITCH2", "ACCESSSWITCH2", nofilter, oneway
|
||||
accessswitch = "ACCESSSWITCH2", "ACCESSSWITCH2ON", nofilter, oneway
|
||||
switch = "DIPSWITCH2", "DIPSWITCH2ON", shootable
|
||||
switch = "DIPSWITCH3", "DIPSWITCH3ON", shootable
|
||||
multiswitch = "MULTISWITCH", "MULTISWITCH_2", "MULTISWITCH_3", "MULTISWITCH_4"
|
||||
|
|
|
@ -325,7 +325,7 @@ float R_DoomLightingEquation(float light)
|
|||
// This is a lot more primitive than Doom's lighting...
|
||||
float numShades = float(uPalLightLevels & 255);
|
||||
float curshade = (1.0 - light) * (numShades - 1.0);
|
||||
float visibility = max(uGlobVis * uLightFactor * abs(z), 0.0);
|
||||
float visibility = max(uGlobVis * uLightFactor * z, 0.0);
|
||||
float shade = clamp((curshade + visibility), 0.0, numShades - 1.0);
|
||||
return clamp(shade * uLightDist, 0.0, 1.0);
|
||||
}
|
||||
|
@ -344,10 +344,86 @@ float R_DoomLightingEquation(float light)
|
|||
|
||||
//===========================================================================
|
||||
//
|
||||
// Check if light is in shadow according to its 1D shadow map
|
||||
// Check if light is in shadow
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
#ifdef SUPPORTS_RAYTRACING
|
||||
|
||||
bool traceHit(vec3 origin, vec3 direction, float dist)
|
||||
{
|
||||
rayQueryEXT rayQuery;
|
||||
rayQueryInitializeEXT(rayQuery, TopLevelAS, gl_RayFlagsTerminateOnFirstHitEXT, 0xFF, origin, 0.01f, direction, dist);
|
||||
while(rayQueryProceedEXT(rayQuery)) { }
|
||||
return rayQueryGetIntersectionTypeEXT(rayQuery, true) != gl_RayQueryCommittedIntersectionNoneEXT;
|
||||
}
|
||||
|
||||
vec2 softshadow[9 * 3] = vec2[](
|
||||
vec2( 0.0, 0.0),
|
||||
vec2(-2.0,-2.0),
|
||||
vec2( 2.0, 2.0),
|
||||
vec2( 2.0,-2.0),
|
||||
vec2(-2.0, 2.0),
|
||||
vec2(-1.0,-1.0),
|
||||
vec2( 1.0, 1.0),
|
||||
vec2( 1.0,-1.0),
|
||||
vec2(-1.0, 1.0),
|
||||
|
||||
vec2( 0.0, 0.0),
|
||||
vec2(-1.5,-1.5),
|
||||
vec2( 1.5, 1.5),
|
||||
vec2( 1.5,-1.5),
|
||||
vec2(-1.5, 1.5),
|
||||
vec2(-0.5,-0.5),
|
||||
vec2( 0.5, 0.5),
|
||||
vec2( 0.5,-0.5),
|
||||
vec2(-0.5, 0.5),
|
||||
|
||||
vec2( 0.0, 0.0),
|
||||
vec2(-1.25,-1.75),
|
||||
vec2( 1.75, 1.25),
|
||||
vec2( 1.25,-1.75),
|
||||
vec2(-1.75, 1.75),
|
||||
vec2(-0.75,-0.25),
|
||||
vec2( 0.25, 0.75),
|
||||
vec2( 0.75,-0.25),
|
||||
vec2(-0.25, 0.75)
|
||||
);
|
||||
|
||||
float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
||||
{
|
||||
float shadowIndex = abs(lightcolorA) - 1.0;
|
||||
if (shadowIndex >= 1024.0)
|
||||
return 1.0; // Don't cast rays for this light
|
||||
|
||||
vec3 origin = pixelpos.xzy;
|
||||
vec3 target = lightpos.xzy + 0.01; // nudge light position slightly as Doom maps tend to have their lights perfectly aligned with planes
|
||||
|
||||
vec3 direction = normalize(target - origin);
|
||||
float dist = distance(origin, target);
|
||||
|
||||
if (uShadowmapFilter <= 0)
|
||||
{
|
||||
return traceHit(origin, direction, dist) ? 0.0 : 1.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
vec3 v = (abs(direction.x) > abs(direction.y)) ? vec3(0.0, 1.0, 0.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 xdir = normalize(cross(direction, v));
|
||||
vec3 ydir = cross(direction, xdir);
|
||||
|
||||
float sum = 0.0;
|
||||
int step_count = uShadowmapFilter * 9;
|
||||
for (int i = 0; i <= step_count; i++)
|
||||
{
|
||||
vec3 pos = target + xdir * softshadow[i].x + ydir * softshadow[i].y;
|
||||
sum += traceHit(origin, normalize(pos - origin), dist) ? 0.0 : 1.0;
|
||||
}
|
||||
return sum / step_count;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#ifdef SUPPORTS_SHADOWMAPS
|
||||
|
||||
float shadowDirToU(vec2 dir)
|
||||
|
@ -491,6 +567,7 @@ float shadowAttenuation(vec4 lightpos, float lightcolorA)
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
float spotLightAttenuation(vec4 lightpos, vec3 spotdir, float lightCosInnerAngle, float lightCosOuterAngle)
|
||||
|
|
|
@ -5,11 +5,15 @@ layout(location = 2) in vec4 aColor;
|
|||
|
||||
layout(location = 0) out vec4 vTexCoord;
|
||||
layout(location = 1) out vec4 vColor;
|
||||
layout(location = 9) out vec3 vLightmap;
|
||||
|
||||
#ifndef SIMPLE // we do not need these for simple shaders
|
||||
layout(location = 3) in vec4 aVertex2;
|
||||
layout(location = 4) in vec4 aNormal;
|
||||
layout(location = 5) in vec4 aNormal2;
|
||||
layout(location = 6) in vec3 aLightmap;
|
||||
layout(location = 7) in vec4 aBoneWeight;
|
||||
layout(location = 8) in uvec4 aBoneSelector;
|
||||
|
||||
layout(location = 2) out vec4 pixelpos;
|
||||
layout(location = 3) out vec3 glowdist;
|
||||
|
@ -23,6 +27,14 @@ layout(location = 7) out vec4 ClipDistanceA;
|
|||
layout(location = 8) out vec4 ClipDistanceB;
|
||||
#endif
|
||||
|
||||
struct BonesResult
|
||||
{
|
||||
vec3 Normal;
|
||||
vec4 Position;
|
||||
};
|
||||
|
||||
BonesResult ApplyBones();
|
||||
|
||||
void main()
|
||||
{
|
||||
float ClipDistance0, ClipDistance1, ClipDistance2, ClipDistance3, ClipDistance4;
|
||||
|
@ -30,9 +42,11 @@ void main()
|
|||
vec2 parmTexCoord;
|
||||
vec4 parmPosition;
|
||||
|
||||
parmTexCoord = aTexCoord;
|
||||
parmPosition = aPosition;
|
||||
BonesResult bones = ApplyBones();
|
||||
|
||||
parmTexCoord = aTexCoord;
|
||||
parmPosition = bones.Position;
|
||||
|
||||
#ifndef SIMPLE
|
||||
vec4 worldcoord = ModelMatrix * mix(parmPosition, aVertex2, uInterpolationFactor);
|
||||
#else
|
||||
|
@ -51,6 +65,8 @@ void main()
|
|||
#endif
|
||||
|
||||
#ifndef SIMPLE
|
||||
vLightmap = aLightmap;
|
||||
|
||||
pixelpos.xyz = worldcoord.xyz;
|
||||
pixelpos.w = -eyeCoordPos.z/eyeCoordPos.w;
|
||||
|
||||
|
@ -78,14 +94,7 @@ void main()
|
|||
ClipDistance4 = worldcoord.y - ((uSplitBottomPlane.w + uSplitBottomPlane.x * worldcoord.x + uSplitBottomPlane.y * worldcoord.z) * uSplitBottomPlane.z);
|
||||
}
|
||||
|
||||
#ifdef HAS_UNIFORM_VERTEX_DATA
|
||||
if ((useVertexData & 2) == 0)
|
||||
vWorldNormal = NormalModelMatrix * vec4(normalize(uVertexNormal.xyz), 1.0);
|
||||
else
|
||||
vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0);
|
||||
#else
|
||||
vWorldNormal = NormalModelMatrix * vec4(normalize(mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor)), 1.0);
|
||||
#endif
|
||||
vWorldNormal = NormalModelMatrix * vec4(normalize(bones.Normal), 1.0);
|
||||
vEyeNormal = NormalViewMatrix * vec4(normalize(vWorldNormal.xyz), 1.0);
|
||||
#endif
|
||||
|
||||
|
@ -142,3 +151,66 @@ void main()
|
|||
|
||||
gl_PointSize = 1.0;
|
||||
}
|
||||
|
||||
#if !defined(SIMPLE)
|
||||
vec3 GetAttrNormal()
|
||||
{
|
||||
#ifdef HAS_UNIFORM_VERTEX_DATA
|
||||
if ((useVertexData & 2) == 0)
|
||||
return uVertexNormal.xyz;
|
||||
else
|
||||
return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor);
|
||||
#else
|
||||
return mix(aNormal.xyz, aNormal2.xyz, uInterpolationFactor);
|
||||
#endif
|
||||
}
|
||||
|
||||
void AddWeightedBone(uint boneIndex, float weight, inout vec4 position, inout vec3 normal)
|
||||
{
|
||||
if (weight != 0.0)
|
||||
{
|
||||
mat4 transform = bones[uBoneIndexBase + int(boneIndex)];
|
||||
mat3 rotation = mat3(transform);
|
||||
position += (transform * aPosition) * weight;
|
||||
normal += (rotation * aNormal.xyz) * weight;
|
||||
}
|
||||
}
|
||||
|
||||
BonesResult ApplyBones()
|
||||
{
|
||||
BonesResult result;
|
||||
if (uBoneIndexBase >= 0 && aBoneWeight != vec4(0.0))
|
||||
{
|
||||
result.Position = vec4(0.0);
|
||||
result.Normal = vec3(0.0);
|
||||
|
||||
// We use low precision input for our bone weights. Rescale so the sum still is 1.0
|
||||
float totalWeight = aBoneWeight.x + aBoneWeight.y + aBoneWeight.z + aBoneWeight.w;
|
||||
float weightMultiplier = 1.0 / totalWeight;
|
||||
vec4 boneWeight = aBoneWeight * weightMultiplier;
|
||||
|
||||
AddWeightedBone(aBoneSelector.x, boneWeight.x, result.Position, result.Normal);
|
||||
AddWeightedBone(aBoneSelector.y, boneWeight.y, result.Position, result.Normal);
|
||||
AddWeightedBone(aBoneSelector.z, boneWeight.z, result.Position, result.Normal);
|
||||
AddWeightedBone(aBoneSelector.w, boneWeight.w, result.Position, result.Normal);
|
||||
|
||||
result.Position.w = 1.0; // For numerical stability
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Position = aPosition;
|
||||
result.Normal = GetAttrNormal();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
BonesResult ApplyBones()
|
||||
{
|
||||
BonesResult result;
|
||||
result.Position = aPosition;
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,7 +59,21 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
|||
}
|
||||
}
|
||||
|
||||
vec3 frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
vec3 frag;
|
||||
|
||||
if ( uLightBlendMode == 1 )
|
||||
{ // COLOR_CORRECT_CLAMPING
|
||||
vec3 lightcolor = color + desaturate(dynlight).rgb;
|
||||
frag = material.Base.rgb * ((lightcolor / max(max(max(lightcolor.r, lightcolor.g), lightcolor.b), 1.4) * 1.4));
|
||||
}
|
||||
else if ( uLightBlendMode == 2 )
|
||||
{ // UNCLAMPED
|
||||
frag = material.Base.rgb * (color + desaturate(dynlight).rgb);
|
||||
}
|
||||
else
|
||||
{
|
||||
frag = material.Base.rgb * clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
}
|
||||
|
||||
if (uLightIndex >= 0)
|
||||
{
|
||||
|
|
|
@ -66,9 +66,25 @@ vec3 ProcessMaterialLight(Material material, vec3 color)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( uLightBlendMode == 1 )
|
||||
{ // COLOR_CORRECT_CLAMPING
|
||||
dynlight.rgb = color + desaturate(dynlight).rgb;
|
||||
specular.rgb = desaturate(specular).rgb;
|
||||
|
||||
dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4);
|
||||
dynlight.rgb = ((dynlight.rgb / max(max(max(dynlight.r, dynlight.g), dynlight.b), 1.4) * 1.4));
|
||||
specular.rgb = ((specular.rgb / max(max(max(specular.r, specular.g), specular.b), 1.4) * 1.4));
|
||||
}
|
||||
else if ( uLightBlendMode == 2 )
|
||||
{ // UNCLAMPED
|
||||
dynlight.rgb = color + desaturate(dynlight).rgb;
|
||||
specular.rgb = desaturate(specular).rgb;
|
||||
}
|
||||
else
|
||||
{
|
||||
dynlight.rgb = clamp(color + desaturate(dynlight).rgb, 0.0, 1.4);
|
||||
specular.rgb = clamp(desaturate(specular).rgb, 0.0, 1.4);
|
||||
}
|
||||
|
||||
vec3 frag = material.Base.rgb * dynlight.rgb + material.Specular * specular.rgb;
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ class DukeSoundController : DukeActor
|
|||
let sec = self.sector;
|
||||
if (self.lotag < 999 && sec.lotag >= 0 && sec.lotag < ST_9_SLIDING_ST_DOOR && snd_ambience && sec.floorz != sec.ceilingz)
|
||||
{
|
||||
int flags = Duke.GetSoundFlags(self.lotag);
|
||||
int flags = Duke.GetSoundFlags(Raze.FindSoundByResID(self.lotag));
|
||||
if (flags & Duke.SF_MSFX)
|
||||
{
|
||||
double distance = (p.actor.pos - self.pos).Length();
|
||||
|
|
|
@ -198,8 +198,8 @@ struct Duke native
|
|||
}
|
||||
else
|
||||
{
|
||||
if (align != -1) x -= myfont.StringWidth(text) * (align == 0 ? 0.2 : 0.4);
|
||||
Screen.DrawText(myfont, Font.CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.4, DTA_ScaleY, 0.4, DTA_Alpha, alpha);
|
||||
if (align != -1) x -= myfont.StringWidth(text) * (align == 0 ? 0.175 : 0.35);
|
||||
Screen.DrawText(myfont, Font.CR_UNTRANSLATED, x, y - 12, text, DTA_FullscreenScale, FSMode_Fit320x200, DTA_ScaleX, 0.35, DTA_ScaleY, 0.35, DTA_Alpha, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -495,6 +495,9 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
TextureID texBg;
|
||||
TextureID texOv[4];
|
||||
|
||||
double text_x;
|
||||
double val_x;
|
||||
|
||||
enum EScreenFlags
|
||||
{
|
||||
printTimeText = 1,
|
||||
|
@ -555,6 +558,37 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
return false;
|
||||
}
|
||||
|
||||
private void CalcLayout()
|
||||
{
|
||||
static const String texts[] = { "$TXT_YourTime", "$TXT_ParTime", "$TXT_3DRTIME", "$TXT_EnemiesKilled", "$TXT_EnemiesLeft", "$TXT_SECFND", "$TXT_SECMISS" };
|
||||
let myfont = Raze.PickSmallFont();
|
||||
let fact = screen.GetAspectRatio();
|
||||
let vwidth = 320 * 0.75 * fact;
|
||||
let left = 5 + (320 - vwidth) / 2;
|
||||
let twidth = 0.0;
|
||||
|
||||
text_x = 10;
|
||||
val_x = 151;
|
||||
for(int i = 0; i < texts.size(); i++)
|
||||
{
|
||||
twidth = max(twidth, myfont.StringWidth(texts[i]));
|
||||
}
|
||||
if (twidth > 140 && twidth < 156)
|
||||
{
|
||||
val_x += twidth - 140;
|
||||
}
|
||||
else if (twidth >= 156)
|
||||
{
|
||||
val_x = 166;
|
||||
text_x -= twidth - 156;
|
||||
if (text_x < left)
|
||||
{
|
||||
val_x += left - text_x;
|
||||
text_x = left;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override void Start()
|
||||
{
|
||||
Duke.PlayBonusMusic();
|
||||
|
@ -562,6 +596,7 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
|
||||
override void OnTick()
|
||||
{
|
||||
CalcLayout();
|
||||
if ((displaystate & printStatsAll) != printStatsAll)
|
||||
{
|
||||
if (ticks == 15 * 3)
|
||||
|
@ -610,23 +645,23 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
void PrintTime()
|
||||
{
|
||||
String tempbuf;
|
||||
Duke.GameText(10, 59 + 9, "$TXT_YourTime", 0);
|
||||
Duke.GameText(10, 69 + 9, "$TXT_ParTime", 0);
|
||||
Duke.GameText(text_x, 59 + 9, "$TXT_YourTime", 0);
|
||||
Duke.GameText(text_x, 69 + 9, "$TXT_ParTime", 0);
|
||||
if (!Raze.isNamWW2GI())
|
||||
Duke.GameText(10, 79 + 9, "$TXT_3DRTIME", 0);
|
||||
Duke.GameText(text_x, 79 + 9, "$TXT_3DRTIME", 0);
|
||||
|
||||
if (displaystate & printTimeVal)
|
||||
{
|
||||
tempbuf = FormatTime(stats.time);
|
||||
Duke.GameText((320 >> 2) + 71, 59 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 59 + 9, tempbuf, 0);
|
||||
|
||||
tempbuf = FormatTime(level.parTime);
|
||||
Duke.GameText((320 >> 2) + 71, 69 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 69 + 9, tempbuf, 0);
|
||||
|
||||
if (!Raze.isNamWW2GI())
|
||||
{
|
||||
tempbuf = FormatTime(level.designerTime);
|
||||
Duke.GameText((320 >> 2) + 71, 79 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 79 + 9, tempbuf, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -634,13 +669,13 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
void PrintKills()
|
||||
{
|
||||
String tempbuf;
|
||||
Duke.GameText(10, 94 + 9, "$TXT_EnemiesKilled", 0);
|
||||
Duke.GameText(10, 104 + 9, "$TXT_EnemiesLeft", 0);
|
||||
Duke.GameText(text_x, 94 + 9, "$TXT_EnemiesKilled", 0);
|
||||
Duke.GameText(text_x, 104 + 9, "$TXT_EnemiesLeft", 0);
|
||||
|
||||
if (displaystate & printKillsVal)
|
||||
{
|
||||
tempbuf = String.Format("%-3d", stats.kills);
|
||||
Duke.GameText((320 >> 2) + 70, 94 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 94 + 9, tempbuf, 0);
|
||||
|
||||
if (stats.maxkills < 0)
|
||||
{
|
||||
|
@ -650,22 +685,22 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
{
|
||||
tempbuf = String.Format("%-3d", max(0, stats.maxkills - stats.kills));
|
||||
}
|
||||
Duke.GameText((320 >> 2) + 70, 104 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 104 + 9, tempbuf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSecrets()
|
||||
{
|
||||
String tempbuf;
|
||||
Duke.GameText(10, 119 + 9, "$TXT_SECFND", 0);
|
||||
Duke.GameText(10, 129 + 9, "$TXT_SECMISS", 0);
|
||||
Duke.GameText(text_x, 119 + 9, "$TXT_SECFND", 0);
|
||||
Duke.GameText(text_x, 129 + 9, "$TXT_SECMISS", 0);
|
||||
|
||||
if (displaystate & printSecretsVal)
|
||||
{
|
||||
tempbuf = String.Format("%-3d", stats.secrets);
|
||||
Duke.GameText((320 >> 2) + 70, 119 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 119 + 9, tempbuf, 0);
|
||||
tempbuf = String.Format("%-3d", max(0, stats.maxsecrets - stats.secrets));
|
||||
Duke.GameText((320 >> 2) + 70, 129 + 9, tempbuf, 0);
|
||||
Duke.GameText(val_x, 129 + 9, tempbuf, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -675,19 +710,6 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
|
||||
Duke.GameText(160, 190, "$PRESSKEY", 8 - (sin(ticks * 4) * 8), 0);
|
||||
|
||||
if (displaystate & printTimeText)
|
||||
{
|
||||
PrintTime();
|
||||
}
|
||||
if (displaystate & printKillsText)
|
||||
{
|
||||
PrintKills();
|
||||
}
|
||||
if (displaystate & printSecretsText)
|
||||
{
|
||||
PrintSecrets();
|
||||
}
|
||||
|
||||
if (displaystate & dukeAnim)
|
||||
{
|
||||
switch (((ticks - dukeAnimStart) >> 2) % 15)
|
||||
|
@ -718,6 +740,20 @@ class DukeLevelSummaryScreen : SummaryScreenBase
|
|||
}
|
||||
}
|
||||
|
||||
if (displaystate & printTimeText)
|
||||
{
|
||||
PrintTime();
|
||||
}
|
||||
if (displaystate & printKillsText)
|
||||
{
|
||||
PrintKills();
|
||||
}
|
||||
if (displaystate & printSecretsText)
|
||||
{
|
||||
PrintSecrets();
|
||||
}
|
||||
|
||||
|
||||
if (lastmapname) Duke.BigText(160, 20 - 6, lastmapname, 0);
|
||||
Duke.BigText(160, 36 - 6, "$Completed", 0);
|
||||
}
|
||||
|
@ -738,6 +774,13 @@ class RRLevelSummaryScreen : SummaryScreenBase
|
|||
int exitSoundStart;
|
||||
TextureID texBg;
|
||||
|
||||
double text_x;
|
||||
double val_x;
|
||||
double val_x2;
|
||||
double press_x;
|
||||
double map_x;
|
||||
|
||||
|
||||
enum EFlags
|
||||
{
|
||||
printTimeText = 1,
|
||||
|
@ -792,6 +835,67 @@ class RRLevelSummaryScreen : SummaryScreenBase
|
|||
return false;
|
||||
}
|
||||
|
||||
private void CalcLayout()
|
||||
{
|
||||
static const String texts[] = { "$TXT_YerTime", "$TXT_ParTime", "$TXT_XTRTIME"};
|
||||
static const String texts2[] = { "$TXT_VarmintsKilled", "$TXT_VarmintsLeft", "$TXT_SECFND", "$TXT_SECMISS" };
|
||||
let myfont = Raze.PickBigFont();
|
||||
let fact = screen.GetAspectRatio();
|
||||
let vwidth = 320 * 0.75 * fact;
|
||||
let left = 5 + (320 - vwidth) / 2;
|
||||
let twidth = 0.0;
|
||||
let twidth1 = 0.0;
|
||||
|
||||
text_x = 30;
|
||||
val_x = 191;
|
||||
val_x2 = 231;
|
||||
for(int i = 0; i < texts.size(); i++)
|
||||
{
|
||||
twidth1 = max(twidth1, 0.35 * myfont.StringWidth(texts[i]));
|
||||
}
|
||||
for(int i = 0; i < texts2.size(); i++)
|
||||
{
|
||||
twidth = max(twidth, 0.35 * myfont.StringWidth(texts2[i]));
|
||||
}
|
||||
|
||||
if (twidth1 > 155 && twidth1 < 190 && twidth < 230)
|
||||
{
|
||||
Console.printf("small case: %f, %f", twidth, val_x);
|
||||
val_x = val_x2;
|
||||
return;
|
||||
}
|
||||
twidth = max(twidth, twidth1 + 40);
|
||||
|
||||
if (twidth >= 195 && twidth < 230)
|
||||
{
|
||||
val_x2 += twidth - 195;
|
||||
val_x = val_x2;
|
||||
}
|
||||
else if (twidth >= 230)
|
||||
{
|
||||
val_x2 = 266;
|
||||
text_x -= twidth - 230;
|
||||
if (text_x < left)
|
||||
{
|
||||
val_x2 += left - text_x;
|
||||
text_x = left;
|
||||
}
|
||||
val_x = val_x2;
|
||||
}
|
||||
|
||||
map_x = 80;
|
||||
let w = myfont.StringWidth(lastmapname) * 0.35;
|
||||
if (w > 320) map_x = -(w - 320) / 2;
|
||||
else if (w > 240) map_x = (320 - w) / 2;
|
||||
|
||||
press_x = 15;
|
||||
w = myfont.StringWidth("$PRESSKEY") * 0.35;
|
||||
if (w > 320) press_x = -(w - 320) / 2;
|
||||
else if (w > 300) press_x = (320 - w) / 2;
|
||||
|
||||
}
|
||||
|
||||
|
||||
override void OnTick()
|
||||
{
|
||||
if ((displaystate & printStatsAll) != printStatsAll)
|
||||
|
@ -841,33 +945,33 @@ class RRLevelSummaryScreen : SummaryScreenBase
|
|||
void PrintTime()
|
||||
{
|
||||
String tempbuf;
|
||||
Duke.BigText(30, 48, "$TXT_YerTime", -1);
|
||||
Duke.BigText(30, 64, "$TXT_ParTime", -1);
|
||||
Duke.BigText(30, 80, "$TXT_XTRTIME", -1);
|
||||
Duke.BigText(text_x, 48, "$TXT_YerTime", -1);
|
||||
Duke.BigText(text_x, 64, "$TXT_ParTime", -1);
|
||||
Duke.BigText(text_x, 80, "$TXT_XTRTIME", -1);
|
||||
|
||||
if (displaystate & printTimeVal)
|
||||
{
|
||||
tempbuf = FormatTime(stats.time);
|
||||
Duke.BigText(191, 48, tempbuf, -1);
|
||||
Duke.BigText(val_x, 48, tempbuf, -1);
|
||||
|
||||
tempbuf = FormatTime(level.parTime);
|
||||
Duke.BigText(191, 64, tempbuf, -1);
|
||||
Duke.BigText(val_x, 64, tempbuf, -1);
|
||||
|
||||
tempbuf = FormatTime(level.designerTime);
|
||||
Duke.BigText(191, 80, tempbuf, -1);
|
||||
Duke.BigText(val_x, 80, tempbuf, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintKills()
|
||||
{
|
||||
String tempbuf;
|
||||
Duke.BigText(30, 112, "$TXT_VarmintsKilled", -1);
|
||||
Duke.BigText(30, 128, "$TXT_VarmintsLeft", -1);
|
||||
Duke.BigText(text_x, 112, "$TXT_VarmintsKilled", -1);
|
||||
Duke.BigText(text_x, 128, "$TXT_VarmintsLeft", -1);
|
||||
|
||||
if (displaystate & printKillsVal)
|
||||
{
|
||||
tempbuf = String.Format("%-3d", stats.kills);
|
||||
Duke.BigText(231, 112, tempbuf, -1);
|
||||
Duke.BigText(val_x2, 112, tempbuf, -1);
|
||||
if (stats.maxkills < 0)
|
||||
{
|
||||
tempbuf = "$TXT_N_A";
|
||||
|
@ -876,31 +980,32 @@ class RRLevelSummaryScreen : SummaryScreenBase
|
|||
{
|
||||
tempbuf = String.Format("%-3d", max(0, stats.maxkills - stats.kills));
|
||||
}
|
||||
Duke.BigText(231, 128, tempbuf, -1);
|
||||
Duke.BigText(val_x2, 128, tempbuf, -1);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSecrets()
|
||||
{
|
||||
String tempbuf;
|
||||
Duke.BigText(30, 144, "$TXT_SECFND", -1);
|
||||
Duke.BigText(30, 160, "$TXT_SECMISS", -1);
|
||||
Duke.BigText(text_x, 144, "$TXT_SECFND", -1);
|
||||
Duke.BigText(text_x, 160, "$TXT_SECMISS", -1);
|
||||
|
||||
if (displaystate & printSecretsVal)
|
||||
{
|
||||
tempbuf = String.Format("%-3d", stats.secrets);
|
||||
Duke.BigText(231, 144, tempbuf, -1);
|
||||
Duke.BigText(val_x2, 144, tempbuf, -1);
|
||||
tempbuf = String.Format("%-3d", max(0, stats.maxsecrets - stats.secrets));
|
||||
Duke.BigText(231, 160, tempbuf, -1);
|
||||
Duke.BigText(val_x2, 160, tempbuf, -1);
|
||||
}
|
||||
}
|
||||
|
||||
override void Draw(double sr)
|
||||
{
|
||||
CalcLayout();
|
||||
Screen.DrawTexture(texBg, true, 0, 0, DTA_FullscreenEx, FSMode_ScaleToFit43, DTA_LegacyRenderStyle, STYLE_Normal);
|
||||
|
||||
Duke.BigText(80, 16, lastmapname, -1);
|
||||
Duke.BigText(15, 192, "$PRESSKEY", -1);
|
||||
Duke.BigText(map_x, 16, lastmapname, -1);
|
||||
Duke.BigText(press_x, 192, "$PRESSKEY", -1);
|
||||
|
||||
if (displaystate & printTimeText)
|
||||
{
|
||||
|
|
|
@ -12,6 +12,10 @@ class LevelCompatibility : LevelPostProcessor
|
|||
case 'b522da99f32a71ab31fc27aaba9b7f43': // Duke E2L1 World Tour
|
||||
SplitSector(37, 269, 274); // sector bleeds into another area.
|
||||
break;
|
||||
|
||||
case '459c71d47b5beaa058253e162fd5a5c2': // World Tour e5l1.map
|
||||
for(int i = 1373; i <= 1376; i++) SetSpriteSector(i, 860); // fix bad sector in a few sprites.
|
||||
break;
|
||||
|
||||
case 'c3bfb6a6e7cded2e5fe16cea86632d79': // CP07
|
||||
SplitSector(33, 192, 196); // sector bleeds into another area.
|
||||
|
|
|
@ -6,6 +6,7 @@ class LevelPostProcessor native play
|
|||
}
|
||||
|
||||
protected native void SetSpriteLotag(int sprite, int tag);
|
||||
protected native void SetSpriteSector(int sprite, int tag);
|
||||
protected native void ChangeSpriteFlags(int sprite, int set, int clear);
|
||||
protected native void sw_serp_continue();
|
||||
protected native void SplitSector(int sect, int wal1, int wal2);
|
||||
|
|
Loading…
Reference in a new issue