Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Simon 2023-01-16 21:16:26 +00:00
commit e248c158a8
41 changed files with 1668 additions and 237 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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;
}
//==========================================================================

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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();

View file

@ -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;

View file

@ -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

View file

@ -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() \

View file

@ -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;
}

View file

@ -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;
}
}
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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 = &sector[sect];
return 0;
}
DEFINE_ACTION_FUNCTION(DLevelPostProcessor, ChangeSpriteFlags)
{
PARAM_SELF_PROLOGUE(DLevelPostProcessor);

View file

@ -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);
}

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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]);
}
}

View file

@ -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)

View file

@ -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;

View file

@ -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)
{

View file

@ -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();

View file

@ -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;
}

View file

@ -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);

View 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

View file

@ -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"

View file

@ -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)

View file

@ -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

View file

@ -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)
{

View file

@ -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;

View file

@ -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();

View file

@ -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);
}
}

View file

@ -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)
{

View file

@ -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.

View file

@ -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);