mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 22:11:43 +00:00
Merge branch 'master' into timidity++
# Conflicts: # src/sound/musicformats/music_midistream.cpp
This commit is contained in:
commit
4c0f68bcd4
41 changed files with 430 additions and 132 deletions
|
@ -886,6 +886,12 @@ public:
|
|||
|
||||
|
||||
// a full 3D version of the above
|
||||
double Distance3DSquared(AActor *other, bool absolute = false)
|
||||
{
|
||||
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
|
||||
return (Pos() - otherpos).LengthSquared();
|
||||
}
|
||||
|
||||
double Distance3D(AActor *other, bool absolute = false)
|
||||
{
|
||||
DVector3 otherpos = absolute ? other->Pos() : other->PosRelative(this);
|
||||
|
|
|
@ -92,6 +92,7 @@ enum
|
|||
CP_SETTHINGSKILLS,
|
||||
CP_SETSECTORTEXTURE,
|
||||
CP_SETSECTORLIGHT,
|
||||
CP_SETLINESECTORREF,
|
||||
};
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
@ -283,6 +284,18 @@ void ParseCompatibility()
|
|||
CompatParams.Push(sc.Number);
|
||||
}
|
||||
}
|
||||
else if (sc.Compare("setlinesectorref"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
CompatParams.Push(CP_SETLINESECTORREF);
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
sc.MustGetString();
|
||||
CompatParams.Push(sc.MustMatchString(LineSides));
|
||||
sc.MustGetNumber();
|
||||
CompatParams.Push(sc.Number);
|
||||
flags.CompatFlags[SLOT_BCOMPAT] |= BCOMPATF_REBUILDNODES;
|
||||
}
|
||||
else if (sc.Compare("clearlinespecial"))
|
||||
{
|
||||
if (flags.ExtCommandIndex == ~0u) flags.ExtCommandIndex = CompatParams.Size();
|
||||
|
@ -719,6 +732,22 @@ void SetCompatibilityParams()
|
|||
i += 3;
|
||||
break;
|
||||
}
|
||||
case CP_SETLINESECTORREF:
|
||||
{
|
||||
if ((unsigned)CompatParams[i + 1] < level.lines.Size())
|
||||
{
|
||||
line_t *line = &level.lines[CompatParams[i + 1]];
|
||||
assert(line != nullptr);
|
||||
side_t *side = line->sidedef[CompatParams[i + 2]];
|
||||
if (side != nullptr && (unsigned)CompatParams[i + 3] < level.sectors.Size())
|
||||
{
|
||||
side->sector = &level.sectors[CompatParams[i + 3]];
|
||||
}
|
||||
}
|
||||
i += 4;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2840,14 +2840,14 @@ static bool LoadDehSupp ()
|
|||
sc.MustGetString();
|
||||
PClassActor *actortype = static_cast<PClassActor *>(type);
|
||||
s.State = actortype->FindState(sc.String);
|
||||
if (s.State == NULL)
|
||||
if (s.State == NULL && addit)
|
||||
{
|
||||
sc.ScriptError("Invalid state '%s' in '%s'", sc.String, type->TypeName.GetChars());
|
||||
}
|
||||
|
||||
sc.MustGetStringName(",");
|
||||
sc.MustGetNumber();
|
||||
if (s.State == NULL || sc.Number < 1 || !actortype->OwnsState(s.State + sc.Number - 1))
|
||||
if (addit && (s.State == NULL || sc.Number < 1 || !actortype->OwnsState(s.State + sc.Number - 1)))
|
||||
{
|
||||
sc.ScriptError("Invalid state range in '%s'", type->TypeName.GetChars());
|
||||
}
|
||||
|
|
|
@ -40,15 +40,18 @@
|
|||
#include "cmdlib.h"
|
||||
#include "doomstat.h"
|
||||
#include "serializer.h"
|
||||
#include "vm.h"
|
||||
|
||||
EXTERN_CVAR(Int, con_scaletext)
|
||||
|
||||
IMPLEMENT_CLASS(DHUDMessage, false, true)
|
||||
|
||||
IMPLEMENT_POINTERS_START(DHUDMessage)
|
||||
IMPLEMENT_POINTER(Next)
|
||||
IMPLEMENT_CLASS(DHUDMessageBase, true, true)
|
||||
IMPLEMENT_POINTERS_START(DHUDMessageBase)
|
||||
IMPLEMENT_POINTER(Next)
|
||||
IMPLEMENT_POINTERS_END
|
||||
|
||||
|
||||
IMPLEMENT_CLASS(DHUDMessage, false, false)
|
||||
|
||||
IMPLEMENT_CLASS(DHUDMessageFadeOut, false, false)
|
||||
IMPLEMENT_CLASS(DHUDMessageFadeInOut, false, false)
|
||||
IMPLEMENT_CLASS(DHUDMessageTypeOnFadeOut, false, false)
|
||||
|
@ -57,6 +60,68 @@ IMPLEMENT_CLASS(DHUDMessageTypeOnFadeOut, false, false)
|
|||
* Basic HUD message. Appears and disappears without any special effects *
|
||||
*************************************************************************/
|
||||
|
||||
void DHUDMessageBase::Serialize(FSerializer &arc)
|
||||
{
|
||||
Super::Serialize(arc);
|
||||
arc("next", Next)
|
||||
("sbarid", SBarID);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DHUDMessageBase, Tick)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DHUDMessageBase);
|
||||
ACTION_RETURN_BOOL(self->Tick());
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DHUDMessageBase, ScreenSizeChanged)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DHUDMessageBase);
|
||||
self->ScreenSizeChanged();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DHUDMessageBase, Draw)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DHUDMessageBase);
|
||||
PARAM_INT(bottom);
|
||||
PARAM_INT(visibility);
|
||||
self->Draw(bottom, visibility);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool DHUDMessageBase::CallTick()
|
||||
{
|
||||
IFVIRTUAL(DHUDMessageBase, Tick)
|
||||
{
|
||||
VMValue params[] = { (DObject*)this };
|
||||
int retval;
|
||||
VMReturn ret; ret.IntAt(&retval);
|
||||
VMCall(func, params, countof(params), &ret, 1);
|
||||
return !!retval;
|
||||
}
|
||||
return Tick();
|
||||
}
|
||||
|
||||
void DHUDMessageBase::CallScreenSizeChanged()
|
||||
{
|
||||
IFVIRTUAL(DHUDMessageBase, ScreenSizeChanged)
|
||||
{
|
||||
VMValue params[] = { (DObject*)this };
|
||||
VMCall(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
else ScreenSizeChanged();
|
||||
}
|
||||
|
||||
void DHUDMessageBase::CallDraw(int bottom, int visibility)
|
||||
{
|
||||
IFVIRTUAL(DHUDMessageBase, Draw)
|
||||
{
|
||||
VMValue params[] = { (DObject*)this, bottom, visibility };
|
||||
VMCall(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
else Draw(bottom, visibility);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
//
|
||||
// DHUDMessage Constructor
|
||||
|
@ -130,7 +195,6 @@ DHUDMessage::DHUDMessage (FFont *font, const char *text, float x, float y, int h
|
|||
WrapWidth = 0;
|
||||
HandleAspect = true;
|
||||
Top = y;
|
||||
Next = NULL;
|
||||
Lines = NULL;
|
||||
HoldTics = (int)(holdTime * TICRATE);
|
||||
Tics = 0;
|
||||
|
@ -184,10 +248,8 @@ void DHUDMessage::Serialize(FSerializer &arc)
|
|||
("tics", Tics)
|
||||
("state", State)
|
||||
.Enum("textcolor", TextColor)
|
||||
("sbarid", SBarID)
|
||||
("sourcetext", SourceText)
|
||||
("font", Font)
|
||||
("next", Next)
|
||||
("hudwidth", HUDWidth)
|
||||
("hudheight", HUDHeight)
|
||||
("nowrap", NoWrap)
|
||||
|
|
|
@ -59,10 +59,34 @@ bool ST_IsLatencyVisible();
|
|||
|
||||
// HUD Message base object --------------------------------------------------
|
||||
|
||||
class DHUDMessage : public DObject
|
||||
// This is a mo-op base class to allow derived ZScript message types that can be managed by the status bar.
|
||||
class DHUDMessageBase : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DHUDMessage, DObject)
|
||||
DECLARE_CLASS(DHUDMessageBase, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
|
||||
public:
|
||||
virtual void Serialize(FSerializer &arc);
|
||||
virtual bool Tick() { return true; } // Returns true to indicate time for removal
|
||||
virtual void ScreenSizeChanged() {}
|
||||
virtual void Draw(int bottom, int visibility) {}
|
||||
|
||||
bool CallTick(); // Returns true to indicate time for removal
|
||||
void CallScreenSizeChanged();
|
||||
void CallDraw(int bottom, int visibility);
|
||||
|
||||
private:
|
||||
TObjPtr<DHUDMessageBase*> Next = nullptr;
|
||||
uint32_t SBarID = 0;
|
||||
friend class DBaseStatusBar;
|
||||
|
||||
};
|
||||
|
||||
// HUD Message --------------------------------------------------
|
||||
|
||||
class DHUDMessage : public DHUDMessageBase
|
||||
{
|
||||
DECLARE_CLASS (DHUDMessage, DHUDMessageBase)
|
||||
public:
|
||||
DHUDMessage (FFont *font, const char *text, float x, float y, int hudwidth, int hudheight,
|
||||
EColorRange textColor, float holdTime);
|
||||
|
@ -70,12 +94,12 @@ public:
|
|||
|
||||
virtual void Serialize(FSerializer &arc);
|
||||
|
||||
void Draw (int bottom, int visibility);
|
||||
virtual void Draw (int bottom, int visibility) override;
|
||||
virtual void ResetText (const char *text);
|
||||
virtual void DrawSetup ();
|
||||
virtual void DoDraw (int linenum, int x, int y, bool clean, int hudheight);
|
||||
virtual bool Tick (); // Returns true to indicate time for removal
|
||||
virtual void ScreenSizeChanged ();
|
||||
virtual bool Tick () override;
|
||||
virtual void ScreenSizeChanged () override;
|
||||
|
||||
void SetVisibility(int vis)
|
||||
{
|
||||
|
@ -130,11 +154,8 @@ protected:
|
|||
DHUDMessage () : SourceText(NULL) {}
|
||||
|
||||
private:
|
||||
TObjPtr<DHUDMessage*> Next;
|
||||
uint32_t SBarID;
|
||||
char *SourceText;
|
||||
|
||||
friend class DBaseStatusBar;
|
||||
};
|
||||
|
||||
// HUD message visibility flags
|
||||
|
@ -360,9 +381,9 @@ public:
|
|||
void SetSize(int reltop = 32, int hres = 320, int vres = 200, int hhres = -1, int hvres = -1);
|
||||
void OnDestroy() override;
|
||||
|
||||
void AttachMessage (DHUDMessage *msg, uint32_t id=0, int layer=HUDMSGLayer_Default);
|
||||
DHUDMessage *DetachMessage (DHUDMessage *msg);
|
||||
DHUDMessage *DetachMessage (uint32_t id);
|
||||
void AttachMessage (DHUDMessageBase *msg, uint32_t id=0, int layer=HUDMSGLayer_Default);
|
||||
DHUDMessageBase *DetachMessage (DHUDMessageBase *msg);
|
||||
DHUDMessageBase *DetachMessage (uint32_t id);
|
||||
void DetachAllMessages ();
|
||||
void ShowPlayerName ();
|
||||
double GetDisplacement() { return Displacement; }
|
||||
|
@ -455,7 +476,7 @@ private:
|
|||
void DrawWaiting () const;
|
||||
void SetDrawSize(int reltop, int hres, int vres);
|
||||
|
||||
TObjPtr<DHUDMessage*> Messages[NUM_HUDMSGLAYERS];
|
||||
TObjPtr<DHUDMessageBase*> Messages[NUM_HUDMSGLAYERS];
|
||||
|
||||
int BaseRelTop;
|
||||
int BaseSBarHorizontalResolution;
|
||||
|
|
|
@ -410,10 +410,10 @@ void DBaseStatusBar::OnDestroy ()
|
|||
{
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *msg = Messages[i];
|
||||
DHUDMessageBase *msg = Messages[i];
|
||||
while (msg)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
DHUDMessageBase *next = msg->Next;
|
||||
msg->Destroy();
|
||||
msg = next;
|
||||
}
|
||||
|
@ -594,14 +594,14 @@ void DBaseStatusBar::Tick ()
|
|||
{
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *msg = Messages[i];
|
||||
DHUDMessage **prev = &Messages[i];
|
||||
DHUDMessageBase *msg = Messages[i];
|
||||
DHUDMessageBase **prev = &Messages[i];
|
||||
|
||||
while (msg)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
DHUDMessageBase *next = msg->Next;
|
||||
|
||||
if (msg->Tick ())
|
||||
if (msg->CallTick ())
|
||||
{
|
||||
*prev = next;
|
||||
msg->Destroy();
|
||||
|
@ -662,10 +662,10 @@ void DBaseStatusBar::CallTick()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::AttachMessage (DHUDMessage *msg, uint32_t id, int layer)
|
||||
void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer)
|
||||
{
|
||||
DHUDMessage *old = NULL;
|
||||
DHUDMessage **prev;
|
||||
DHUDMessageBase *old = NULL;
|
||||
DHUDMessageBase **prev;
|
||||
DObject *container = this;
|
||||
|
||||
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
|
||||
|
@ -697,18 +697,28 @@ void DBaseStatusBar::AttachMessage (DHUDMessage *msg, uint32_t id, int layer)
|
|||
GC::WriteBarrier(container, msg);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, AttachMessage)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_OBJECT(msg, DHUDMessageBase);
|
||||
PARAM_UINT(id);
|
||||
PARAM_INT(layer);
|
||||
self->AttachMessage(msg, id, layer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DetachMessage
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
||||
DHUDMessageBase *DBaseStatusBar::DetachMessage (DHUDMessageBase *msg)
|
||||
{
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *probe = Messages[i];
|
||||
DHUDMessage **prev = &Messages[i];
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
DHUDMessageBase **prev = &Messages[i];
|
||||
|
||||
while (probe && probe != msg)
|
||||
{
|
||||
|
@ -725,12 +735,20 @@ DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
DHUDMessage *DBaseStatusBar::DetachMessage (uint32_t id)
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DetachMessage)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_OBJECT(msg, DHUDMessageBase);
|
||||
ACTION_RETURN_OBJECT(self->DetachMessage(msg));
|
||||
}
|
||||
|
||||
|
||||
DHUDMessageBase *DBaseStatusBar::DetachMessage (uint32_t id)
|
||||
{
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *probe = Messages[i];
|
||||
DHUDMessage **prev = &Messages[i];
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
DHUDMessageBase **prev = &Messages[i];
|
||||
|
||||
while (probe && probe->SBarID != id)
|
||||
{
|
||||
|
@ -747,6 +765,13 @@ DHUDMessage *DBaseStatusBar::DetachMessage (uint32_t id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DetachMessageID)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_INT(id);
|
||||
ACTION_RETURN_OBJECT(self->DetachMessage(id));
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC DetachAllMessages
|
||||
|
@ -757,18 +782,26 @@ void DBaseStatusBar::DetachAllMessages ()
|
|||
{
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *probe = Messages[i];
|
||||
DHUDMessageBase *probe = Messages[i];
|
||||
|
||||
Messages[i] = NULL;
|
||||
while (probe != NULL)
|
||||
{
|
||||
DHUDMessage *next = probe->Next;
|
||||
DHUDMessageBase *next = probe->Next;
|
||||
probe->Destroy();
|
||||
probe = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, DetachAllMessages)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
self->DetachAllMessages();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC ShowPlayerName
|
||||
|
@ -940,7 +973,7 @@ void DBaseStatusBar::FlashCrosshair ()
|
|||
|
||||
void DBaseStatusBar::DrawMessages (int layer, int bottom)
|
||||
{
|
||||
DHUDMessage *msg = Messages[layer];
|
||||
DHUDMessageBase *msg = Messages[layer];
|
||||
int visibility = 0;
|
||||
|
||||
if (viewactive)
|
||||
|
@ -953,8 +986,8 @@ void DBaseStatusBar::DrawMessages (int layer, int bottom)
|
|||
}
|
||||
while (msg)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
msg->Draw (bottom, visibility);
|
||||
DHUDMessageBase *next = msg->Next;
|
||||
msg->CallDraw (bottom, visibility);
|
||||
msg = next;
|
||||
}
|
||||
}
|
||||
|
@ -1307,10 +1340,10 @@ void DBaseStatusBar::ScreenSizeChanged ()
|
|||
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
DHUDMessage *message = Messages[i];
|
||||
DHUDMessageBase *message = Messages[i];
|
||||
while (message != NULL)
|
||||
{
|
||||
message->ScreenSizeChanged ();
|
||||
message->CallScreenSizeChanged ();
|
||||
message = message->Next;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ FGameConfigFile::FGameConfigFile ()
|
|||
SetValueForKey ("Path", "$PROGDIR", true);
|
||||
#else
|
||||
SetValueForKey ("Path", "$HOME/" GAME_DIR, true);
|
||||
SetValueForKey ("Path", SHARE_DIR, true);
|
||||
SetValueForKey ("Path", "/usr/local/share/doom", true);
|
||||
SetValueForKey ("Path", "/usr/local/share/games/doom", true);
|
||||
SetValueForKey ("Path", "/usr/share/doom", true);
|
||||
|
|
|
@ -209,9 +209,10 @@ static bool currentModelMatrixState;
|
|||
|
||||
void FRenderState::ApplyFixedFunction()
|
||||
{
|
||||
if (mTextureMode != ffTextureMode)
|
||||
int thistm = mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
|
||||
if (thistm != ffTextureMode)
|
||||
{
|
||||
ffTextureMode = mTextureMode;
|
||||
ffTextureMode = thistm;
|
||||
if (ffTextureMode == TM_CLAMPY) ffTextureMode = TM_MODULATE; // this cannot be replicated. Too bad if it creates visual artifacts
|
||||
gl_SetTextureMode(ffTextureMode);
|
||||
}
|
||||
|
|
|
@ -405,7 +405,6 @@ void F2DDrawer::Draw()
|
|||
|
||||
gl_SetRenderStyle(dt->mRenderStyle, !dt->mMasked, false);
|
||||
gl_RenderState.SetMaterial(dt->mTexture, CLAMP_XY_NOMIP, dt->mTranslation, -1, dt->mAlphaTexture);
|
||||
if (dt->mTexture->tex->bHasCanvas) gl_RenderState.SetTextureMode(TM_OPAQUE);
|
||||
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
glScissor(dt->mScissor[0], dt->mScissor[1], dt->mScissor[2], dt->mScissor[3]);
|
||||
|
|
|
@ -164,7 +164,7 @@ bool FRenderState::ApplyShader()
|
|||
activeShader->muFogEnabled.Set(fogset);
|
||||
activeShader->muPalLightLevels.Set(static_cast<int>(gl_bandedswlight) | (static_cast<int>(gl_fogmode) << 8));
|
||||
activeShader->muGlobVis.Set(GLRenderer->mGlobVis / 32.0f);
|
||||
activeShader->muTextureMode.Set(mTextureMode);
|
||||
activeShader->muTextureMode.Set(mTextureMode == TM_MODULATE && mTempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode);
|
||||
activeShader->muCameraPos.Set(mCameraPos.vec);
|
||||
activeShader->muLightParms.Set(mLightParms);
|
||||
activeShader->muFogColor.Set(mFogColor);
|
||||
|
|
|
@ -112,6 +112,7 @@ class FRenderState
|
|||
|
||||
int mEffectState;
|
||||
int mColormapState;
|
||||
int mTempTM = TM_MODULATE;
|
||||
|
||||
float stAlphaThreshold;
|
||||
int stSrcBlend, stDstBlend;
|
||||
|
@ -150,6 +151,14 @@ public:
|
|||
{
|
||||
if (mat->tex->UseBasePalette() || gl.legacyMode) translation = TRANSLATION(TRANSLATION_Standard, 8);
|
||||
}
|
||||
if (mat->tex->bHasCanvas)
|
||||
{
|
||||
mTempTM = TM_OPAQUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
mTempTM = TM_MODULATE;
|
||||
}
|
||||
mEffectState = overrideshader >= 0? overrideshader : mat->mShaderIndex;
|
||||
mShaderTimer = mat->tex->gl_info.shaderspeed;
|
||||
mat->Bind(clampmode, translation);
|
||||
|
|
|
@ -358,42 +358,46 @@ void GLDrawList::SortWallIntoPlane(SortNode * head,SortNode * sort)
|
|||
//
|
||||
//
|
||||
//==========================================================================
|
||||
void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort)
|
||||
void GLDrawList::SortSpriteIntoPlane(SortNode * head, SortNode * sort)
|
||||
{
|
||||
GLFlat * fh=&flats[drawitems[head->itemindex].index];
|
||||
GLSprite * ss=&sprites[drawitems[sort->itemindex].index];
|
||||
GLFlat * fh = &flats[drawitems[head->itemindex].index];
|
||||
GLSprite * ss = &sprites[drawitems[sort->itemindex].index];
|
||||
|
||||
bool ceiling = fh->z > r_viewpoint.Pos.Z;
|
||||
|
||||
if ((ss->z1>fh->z && ss->z2<fh->z) || ss->modelframe)
|
||||
auto hiz = ss->z1 > ss->z2 ? ss->z1 : ss->z2;
|
||||
auto loz = ss->z1 < ss->z2 ? ss->z1 : ss->z2;
|
||||
|
||||
if ((hiz > fh->z && loz < fh->z) || ss->modelframe)
|
||||
{
|
||||
// We have to split this sprite
|
||||
GLSprite s=*ss;
|
||||
GLSprite s = *ss;
|
||||
AddSprite(&s); // add a copy to avoid reallocation issues.
|
||||
|
||||
// Splitting is done in the shader with clip planes, if available
|
||||
|
||||
// Splitting is done in the shader with clip planes, if available.
|
||||
// The fallback here only really works for non-y-billboarded sprites.
|
||||
if (gl.flags & RFL_NO_CLIP_PLANES)
|
||||
{
|
||||
GLSprite * ss1;
|
||||
ss1=&sprites[sprites.Size()-1];
|
||||
ss=&sprites[drawitems[sort->itemindex].index]; // may have been reallocated!
|
||||
float newtexv=ss->vt + ((ss->vb-ss->vt)/(ss->z2-ss->z1))*(fh->z-ss->z1);
|
||||
ss1 = &sprites[sprites.Size() - 1];
|
||||
ss = &sprites[drawitems[sort->itemindex].index]; // may have been reallocated!
|
||||
float newtexv = ss->vt + ((ss->vb - ss->vt) / (ss->z2 - ss->z1))*(fh->z - ss->z1);
|
||||
|
||||
if (!ceiling)
|
||||
{
|
||||
ss->z1=ss1->z2=fh->z;
|
||||
ss->vt=ss1->vb=newtexv;
|
||||
ss->z1 = ss1->z2 = fh->z;
|
||||
ss->vt = ss1->vb = newtexv;
|
||||
}
|
||||
else
|
||||
{
|
||||
ss1->z1=ss->z2=fh->z;
|
||||
ss1->vt=ss->vb=newtexv;
|
||||
ss1->z1 = ss->z2 = fh->z;
|
||||
ss1->vt = ss->vb = newtexv;
|
||||
}
|
||||
}
|
||||
|
||||
SortNode * sort2=SortNodes.GetNew();
|
||||
memset(sort2,0,sizeof(SortNode));
|
||||
sort2->itemindex=drawitems.Size()-1;
|
||||
SortNode * sort2 = SortNodes.GetNew();
|
||||
memset(sort2, 0, sizeof(SortNode));
|
||||
sort2->itemindex = drawitems.Size() - 1;
|
||||
|
||||
head->AddToLeft(sort);
|
||||
head->AddToRight(sort2);
|
||||
|
@ -406,7 +410,6 @@ void GLDrawList::SortSpriteIntoPlane(SortNode * head,SortNode * sort)
|
|||
{
|
||||
head->AddToRight(sort);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1211,7 +1211,7 @@ void GLSprite::ProcessParticle (particle_t *particle, sector_t *sector)//, int s
|
|||
}
|
||||
|
||||
double timefrac = r_viewpoint.TicFrac;
|
||||
if (paused || bglobal.freeze)
|
||||
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||
timefrac = 0.;
|
||||
float xvf = (particle->Vel.X) * timefrac;
|
||||
float yvf = (particle->Vel.Y) * timefrac;
|
||||
|
|
|
@ -1060,8 +1060,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
// Draw the stuff
|
||||
//
|
||||
//
|
||||
if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent);
|
||||
else split.SplitWall(realfront, translucent);
|
||||
if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) split.PutWall(translucent);
|
||||
else split.SplitWall(front, translucent);
|
||||
|
||||
t=1;
|
||||
}
|
||||
|
@ -1074,8 +1074,8 @@ void GLWall::DoMidTexture(seg_t * seg, bool drawfogboundary,
|
|||
// Draw the stuff without splitting
|
||||
//
|
||||
//
|
||||
if (realfront->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent);
|
||||
else SplitWall(realfront, translucent);
|
||||
if (front->e->XFloor.lightlist.Size()==0 || mDrawer->FixedColormap) PutWall(translucent);
|
||||
else SplitWall(front, translucent);
|
||||
}
|
||||
alpha=1.0f;
|
||||
}
|
||||
|
@ -1437,7 +1437,7 @@ void GLWall::Process(seg_t *seg, sector_t * frontsector, sector_t * backsector)
|
|||
sector_t * segback;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (seg->linedef->Index() == 1)
|
||||
if (seg->linedef->Index() == 10)
|
||||
{
|
||||
int a = 0;
|
||||
}
|
||||
|
|
|
@ -244,6 +244,7 @@ struct FActorInfo
|
|||
PClassActor *Replacee = nullptr;
|
||||
FState *OwnedStates = nullptr;
|
||||
int NumOwnedStates = 0;
|
||||
bool SkipSuperSet = false;
|
||||
uint8_t GameFilter = GAME_Any;
|
||||
uint16_t SpawnID = 0;
|
||||
uint16_t ConversationID = 0;
|
||||
|
@ -287,7 +288,7 @@ struct FActorInfo
|
|||
};
|
||||
|
||||
// This is now merely a wrapper that adds actor-specific functionality to PClass.
|
||||
// No objects of this type will be created ever - its only use is to static_casr
|
||||
// No objects of this type will be created ever - its only use is to static_cast
|
||||
// PClass to it.
|
||||
class PClassActor : public PClass
|
||||
{
|
||||
|
@ -343,7 +344,7 @@ public:
|
|||
bool OwnsState(const FState *state)
|
||||
{
|
||||
auto i = ActorInfo();
|
||||
return state >= i->OwnedStates && state < i->OwnedStates + i->NumOwnedStates;
|
||||
return i != nullptr && state >= i->OwnedStates && state < i->OwnedStates + i->NumOwnedStates;
|
||||
}
|
||||
|
||||
PClassActor *GetReplacement(bool lookskill=true);
|
||||
|
|
|
@ -377,6 +377,8 @@ xx(MomZ)
|
|||
xx(Threshold)
|
||||
xx(DefThreshold)
|
||||
xx(Abs)
|
||||
xx(TeleportSpecial)
|
||||
xx(Teleport)
|
||||
xx(ACS_NamedExecuteWithResult)
|
||||
xx(CallACS)
|
||||
xx(Sqrt)
|
||||
|
|
|
@ -814,8 +814,8 @@ void FNodeBuilder::SplitSegs (uint32_t set, node_t &node, uint32_t splitseg, uin
|
|||
frac = InterceptVector (node, *seg);
|
||||
newvert.x = Vertices[seg->v1].x;
|
||||
newvert.y = Vertices[seg->v1].y;
|
||||
newvert.x += fixed_t(frac * double(Vertices[seg->v2].x - newvert.x));
|
||||
newvert.y += fixed_t(frac * double(Vertices[seg->v2].y - newvert.y));
|
||||
newvert.x += fixed_t(frac * (double(Vertices[seg->v2].x) - newvert.x));
|
||||
newvert.y += fixed_t(frac * (double(Vertices[seg->v2].y) - newvert.y));
|
||||
vertnum = VertexMap->SelectVertexClose (newvert);
|
||||
|
||||
if (vertnum != (unsigned int)seg->v1 && vertnum != (unsigned int)seg->v2)
|
||||
|
|
|
@ -91,6 +91,8 @@ struct FSimpleVert
|
|||
fixed_t x, y;
|
||||
};
|
||||
|
||||
typedef int64_t fixed64_t;
|
||||
|
||||
class FNodeBuilder
|
||||
{
|
||||
struct FPrivSeg
|
||||
|
@ -167,14 +169,14 @@ class FNodeBuilder
|
|||
FNodeBuilder &MyBuilder;
|
||||
TArray<int> *VertexGrid;
|
||||
|
||||
fixed_t MinX, MinY, MaxX, MaxY;
|
||||
fixed64_t MinX, MinY, MaxX, MaxY;
|
||||
int BlocksWide, BlocksTall;
|
||||
|
||||
enum { BLOCK_SHIFT = 8 + FRACBITS };
|
||||
enum { BLOCK_SIZE = 1 << BLOCK_SHIFT };
|
||||
|
||||
int InsertVertex (FPrivVert &vert);
|
||||
inline int GetBlock (fixed_t x, fixed_t y)
|
||||
inline int GetBlock (fixed64_t x, fixed64_t y)
|
||||
{
|
||||
assert (x >= MinX);
|
||||
assert (y >= MinY);
|
||||
|
|
|
@ -641,8 +641,8 @@ FNodeBuilder::FVertexMap::FVertexMap (FNodeBuilder &builder,
|
|||
MinY = miny;
|
||||
BlocksWide = int(((double(maxx) - minx + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
||||
BlocksTall = int(((double(maxy) - miny + 1) + (BLOCK_SIZE - 1)) / BLOCK_SIZE);
|
||||
MaxX = MinX + BlocksWide * BLOCK_SIZE - 1;
|
||||
MaxY = MinY + BlocksTall * BLOCK_SIZE - 1;
|
||||
MaxX = MinX + fixed64_t(BlocksWide) * BLOCK_SIZE - 1;
|
||||
MaxY = MinY + fixed64_t(BlocksTall) * BLOCK_SIZE - 1;
|
||||
VertexGrid = new TArray<int>[BlocksWide * BlocksTall];
|
||||
}
|
||||
|
||||
|
@ -703,10 +703,10 @@ int FNodeBuilder::FVertexMap::InsertVertex (FNodeBuilder::FPrivVert &vert)
|
|||
// If a vertex is near a block boundary, then it will be inserted on
|
||||
// both sides of the boundary so that SelectVertexClose can find
|
||||
// it by checking in only one block.
|
||||
fixed_t minx = MAX (MinX, vert.x - VERTEX_EPSILON);
|
||||
fixed_t maxx = MIN (MaxX, vert.x + VERTEX_EPSILON);
|
||||
fixed_t miny = MAX (MinY, vert.y - VERTEX_EPSILON);
|
||||
fixed_t maxy = MIN (MaxY, vert.y + VERTEX_EPSILON);
|
||||
fixed64_t minx = MAX (MinX, fixed64_t(vert.x) - VERTEX_EPSILON);
|
||||
fixed64_t maxx = MIN (MaxX, fixed64_t(vert.x) + VERTEX_EPSILON);
|
||||
fixed64_t miny = MAX (MinY, fixed64_t(vert.y) - VERTEX_EPSILON);
|
||||
fixed64_t maxy = MIN (MaxY, fixed64_t(vert.y) + VERTEX_EPSILON);
|
||||
|
||||
int blk[4] =
|
||||
{
|
||||
|
|
|
@ -898,7 +898,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
|||
}
|
||||
|
||||
// check if the actor can step through the ceiling portal. In this case one-sided lines in the current area should not block
|
||||
if (!cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling))
|
||||
// Use the same rules for stepping through a portal as for non-portal case.
|
||||
bool ismissile = (tm.thing->flags & MF_MISSILE) && !(tm.thing->flags6 & MF6_STEPMISSILE) && !(tm.thing->flags3 & MF3_FLOORHUGGER);
|
||||
if (!ismissile && !cres.line->frontsector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
double portz = cres.line->frontsector->GetPortalPlaneZ(sector_t::ceiling);
|
||||
if (tm.thing->Z() < portz && tm.thing->Z() + tm.thing->MaxStepHeight >= portz && tm.floorz < portz)
|
||||
|
@ -1008,7 +1010,9 @@ bool PIT_CheckLine(FMultiBlockLinesIterator &mit, FMultiBlockLinesIterator::Chec
|
|||
FLineOpening open;
|
||||
|
||||
P_LineOpening(open, tm.thing, ld, ref, &cres.Position, cres.portalflags);
|
||||
if (!tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling))
|
||||
// Use the same rules for stepping through a portal as for non-portal case.
|
||||
bool ismissile = (tm.thing->flags & MF_MISSILE) && !(tm.thing->flags6 & MF6_STEPMISSILE) && !(tm.thing->flags3 & MF3_FLOORHUGGER);
|
||||
if (!ismissile && !tm.thing->Sector->PortalBlocksMovement(sector_t::ceiling))
|
||||
{
|
||||
sector_t *oppsec = cres.line->frontsector == tm.thing->Sector ? cres.line->backsector : cres.line->frontsector;
|
||||
if (oppsec->PortalBlocksMovement(sector_t::ceiling))
|
||||
|
@ -2707,8 +2711,8 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
|||
FLinkContext ctx;
|
||||
DVector3 oldpos = thing->Pos();
|
||||
thing->UnlinkFromWorld(&ctx);
|
||||
thing->SetXYZ(thing->PosRelative(thing->Sector->GetOppositePortalGroup(sector_t::ceiling)));
|
||||
thing->Prev = thing->Pos() - oldpos;
|
||||
thing->SetXYZ(thing->PosRelative(tm.portalgroup));
|
||||
thing->Prev += thing->Pos() - oldpos;
|
||||
thing->Sector = P_PointInSector(thing->Pos());
|
||||
thing->PrevPortalGroup = thing->Sector->PortalGroup;
|
||||
thing->LinkToWorld(&ctx);
|
||||
|
|
|
@ -8127,6 +8127,20 @@ DEFINE_ACTION_FUNCTION(AActor, absangle) // should this be global?
|
|||
ACTION_RETURN_FLOAT(absangle(DAngle(a1), DAngle(a2)).Degrees);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Distance2DSquared)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT_NOT_NULL(other, AActor);
|
||||
ACTION_RETURN_FLOAT(self->Distance2DSquared(other));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Distance3DSquared)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT_NOT_NULL(other, AActor);
|
||||
ACTION_RETURN_FLOAT(self->Distance3DSquared(other));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, Distance2D)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
|
|
|
@ -35,7 +35,7 @@ EXTERN_CVAR(Int, gl_particles_style)
|
|||
void RenderPolyParticle::Render(PolyRenderThread *thread, const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t stencilValue)
|
||||
{
|
||||
double timefrac = r_viewpoint.TicFrac;
|
||||
if (paused || bglobal.freeze)
|
||||
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||
timefrac = 0.;
|
||||
DVector3 pos = particle->Pos + (particle->Vel * timefrac);
|
||||
double psize = particle->size / 8.0;
|
||||
|
|
|
@ -125,9 +125,17 @@ void FModelRenderer::RenderModel(float x, float y, float z, FSpriteModelFrame *s
|
|||
|
||||
// Applying model transformations:
|
||||
// 1) Applying actor angle, pitch and roll to the model
|
||||
if (smf->flags & MDL_USEROTATIONCENTER)
|
||||
{
|
||||
objectToWorldMatrix.translate(smf->rotationCenterX, smf->rotationCenterZ, smf->rotationCenterY);
|
||||
}
|
||||
objectToWorldMatrix.rotate(-angle, 0, 1, 0);
|
||||
objectToWorldMatrix.rotate(pitch, 0, 0, 1);
|
||||
objectToWorldMatrix.rotate(-roll, 1, 0, 0);
|
||||
if (smf->flags & MDL_USEROTATIONCENTER)
|
||||
{
|
||||
objectToWorldMatrix.translate(-smf->rotationCenterX, -smf->rotationCenterZ, -smf->rotationCenterY);
|
||||
}
|
||||
|
||||
// 2) Applying Doomsday like rotation of the weapon pickup models
|
||||
// The rotation angle is based on the elapsed time.
|
||||
|
@ -789,6 +797,13 @@ void gl_InitModels()
|
|||
{
|
||||
smf.flags |= MDL_DONTCULLBACKFACES;
|
||||
}
|
||||
else if (sc.Compare("userotationcenter"))
|
||||
{
|
||||
smf.flags |= MDL_USEROTATIONCENTER;
|
||||
smf.rotationCenterX = 0.;
|
||||
smf.rotationCenterY = 0.;
|
||||
smf.rotationCenterZ = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("Unrecognized string \"%s\"", sc.String);
|
||||
|
|
|
@ -447,6 +447,7 @@ enum
|
|||
MDL_USEACTORROLL = 64,
|
||||
MDL_BADROTATION = 128,
|
||||
MDL_DONTCULLBACKFACES = 256,
|
||||
MDL_USEROTATIONCENTER = 512,
|
||||
};
|
||||
|
||||
struct FSpriteModelFrame
|
||||
|
|
|
@ -677,7 +677,7 @@ void S_UnloadReverbDef ()
|
|||
Environments = &Off;
|
||||
}
|
||||
|
||||
CUSTOM_CVAR(Bool, eaxedit_test, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
|
||||
CUSTOM_CVAR(Bool, eaxedit_test, false, CVAR_NOINITCALL)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
|
|
|
@ -2304,6 +2304,7 @@ ExpEmit FxPreIncrDecr::Emit(VMFunctionBuilder *build)
|
|||
}
|
||||
|
||||
pointer.Free(build);
|
||||
value.Target = false; // This is for 'unrequesting' the address of a register variable. If not done here, passing a preincrement expression to a function will generate bad code.
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -7406,7 +7407,16 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
|
||||
if (arrayispointer)
|
||||
{
|
||||
arraytype = static_cast<PArray*>(Array->ValueType->toPointer()->PointedType);
|
||||
auto ptr = Array->ValueType->toPointer();
|
||||
if (ptr != nullptr)
|
||||
{
|
||||
arraytype = static_cast<PArray*>(ptr->PointedType);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScriptPosition.Message(MSG_ERROR, "Internal error when generating code for array access");
|
||||
return ExpEmit();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -7758,6 +7768,8 @@ FxExpression *FxFunctionCall::Resolve(FCompileContext& ctx)
|
|||
}
|
||||
else
|
||||
{
|
||||
// This alias is needed because Actor has a Teleport function.
|
||||
if (MethodName == NAME_TeleportSpecial) MethodName = NAME_Teleport;
|
||||
special = P_FindLineSpecial(MethodName.GetChars(), &min, &max);
|
||||
}
|
||||
if (special != 0 && min >= 0)
|
||||
|
|
|
@ -540,7 +540,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
|||
if (info->Size != actorclass->Size)
|
||||
{
|
||||
bag.ScriptPosition.Message(MSG_OPTERROR,
|
||||
"'skip_super' is only allowed in subclasses of AActor with no additional fields and will be ignored in type %s.", info->TypeName.GetChars());
|
||||
"'skip_super' is only allowed in subclasses of Actor with no additional fields and will be ignored in type %s.", info->TypeName.GetChars());
|
||||
return;
|
||||
}
|
||||
if (bag.StateSet)
|
||||
|
@ -552,6 +552,7 @@ DEFINE_PROPERTY(skip_super, 0, Actor)
|
|||
|
||||
*defaults = *GetDefault<AActor>();
|
||||
ResetBaggage (&bag, RUNTIME_CLASS(AActor));
|
||||
static_cast<PClassActor*>(bag.Info)->ActorInfo()->SkipSuperSet = true; // ZScript processes the states later so this property must be flagged for later handling.
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
@ -1968,7 +1968,10 @@ void PDynArray::SetPointerArray(void *base, unsigned offset, TArray<size_t> *spe
|
|||
void PDynArray::WriteValue(FSerializer &ar, const char *key, const void *addr) const
|
||||
{
|
||||
FArray *aray = (FArray*)addr;
|
||||
if (aray->Count > 0)
|
||||
// We may skip an empty array only if it gets stored under a named key.
|
||||
// If no name is given, i.e. it's part of an outer array's element list, even empty arrays must be stored,
|
||||
// because otherwise the array would lose its entry.
|
||||
if (aray->Count > 0 || key == nullptr)
|
||||
{
|
||||
if (ar.BeginArray(key))
|
||||
{
|
||||
|
|
|
@ -2872,7 +2872,18 @@ void ZCCCompiler::CompileStates()
|
|||
|
||||
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
|
||||
FStateDefinitions statedef;
|
||||
statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass));
|
||||
|
||||
if (static_cast<PClassActor*>(c->ClassType())->ActorInfo()->SkipSuperSet)
|
||||
{
|
||||
// SKIP_SUPER'ed actors only get the base states from AActor.
|
||||
statedef.MakeStateDefines(RUNTIME_CLASS(AActor));
|
||||
}
|
||||
else
|
||||
{
|
||||
statedef.MakeStateDefines(ValidateActor(c->ClassType()->ParentClass));
|
||||
}
|
||||
|
||||
|
||||
int numframes = 0;
|
||||
|
||||
for (auto s : c->States)
|
||||
|
|
|
@ -190,32 +190,32 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype)
|
|||
{
|
||||
try
|
||||
{
|
||||
switch (devtype)
|
||||
{
|
||||
switch (devtype)
|
||||
{
|
||||
case MDEV_GUS:
|
||||
return new TimidityMIDIDevice(Args);
|
||||
|
||||
case MDEV_MMAPI:
|
||||
case MDEV_MMAPI:
|
||||
#ifdef _WIN32
|
||||
return CreateWinMIDIDevice(mididevice);
|
||||
return CreateWinMIDIDevice(mididevice);
|
||||
#endif
|
||||
// Intentional fall-through for non-Windows systems.
|
||||
// Intentional fall-through for non-Windows systems.
|
||||
|
||||
case MDEV_FLUIDSYNTH:
|
||||
return new FluidSynthMIDIDevice(Args);
|
||||
case MDEV_FLUIDSYNTH:
|
||||
return new FluidSynthMIDIDevice(Args);
|
||||
|
||||
case MDEV_OPL:
|
||||
return new OPLMIDIDevice(Args);
|
||||
case MDEV_OPL:
|
||||
return new OPLMIDIDevice(Args);
|
||||
|
||||
case MDEV_TIMIDITY:
|
||||
return CreateTimidityPPMIDIDevice(Args);
|
||||
case MDEV_TIMIDITY:
|
||||
return CreateTimidityPPMIDIDevice(Args);
|
||||
|
||||
case MDEV_WILDMIDI:
|
||||
return new WildMIDIDevice(Args);
|
||||
case MDEV_WILDMIDI:
|
||||
return new WildMIDIDevice(Args);
|
||||
|
||||
default:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (CRecoverableError &err)
|
||||
{
|
||||
|
@ -721,6 +721,14 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time)
|
|||
if (InitialPlayback)
|
||||
{
|
||||
InitialPlayback = false;
|
||||
// Send the GS System Reset SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
events[2] = (MEVENT_LONGMSG << 24) | 6; // dwEvent
|
||||
events[3] = MAKE_ID(0xf0, 0x7e, 0x7f, 0x09); // dwParms[0]
|
||||
events[4] = MAKE_ID(0x01, 0xf7, 0x00, 0x00); // dwParms[1]
|
||||
events += 5;
|
||||
|
||||
// Send the full master volume SysEx message.
|
||||
events[0] = 0; // dwDeltaTime
|
||||
events[1] = 0; // dwStreamID
|
||||
|
|
|
@ -79,7 +79,7 @@ namespace swrenderer
|
|||
sector_t* heightsec = NULL;
|
||||
|
||||
double timefrac = r_viewpoint.TicFrac;
|
||||
if (paused || bglobal.freeze)
|
||||
if (paused || bglobal.freeze || (level.flags2 & LEVEL2_FROZEN))
|
||||
timefrac = 0.;
|
||||
|
||||
double ippx = particle->Pos.X + particle->Vel.X * timefrac;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "v_text.h"
|
||||
|
||||
|
@ -387,7 +388,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isspace(c))
|
||||
if (iswspace(c))
|
||||
{
|
||||
if (!lastWasSpace)
|
||||
{
|
||||
|
@ -420,12 +421,12 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
|||
start = space;
|
||||
space = NULL;
|
||||
|
||||
while (*start && isspace (*start) && *start != '\n')
|
||||
while (*start && iswspace (*start) && *start != '\n')
|
||||
start++;
|
||||
if (*start == '\n')
|
||||
start++;
|
||||
else
|
||||
while (*start && isspace (*start))
|
||||
while (*start && iswspace (*start))
|
||||
start++;
|
||||
string = start;
|
||||
}
|
||||
|
@ -443,7 +444,7 @@ FBrokenLines *V_BreakLines (FFont *font, int maxwidth, const uint8_t *string, bo
|
|||
while (s < string)
|
||||
{
|
||||
// If there is any non-white space in the remainder of the string, add it.
|
||||
if (!isspace (*s++))
|
||||
if (!iswspace (*s++))
|
||||
{
|
||||
auto i = Lines.Reserve(1);
|
||||
breakit (&Lines[i], font, start, string, linecolor);
|
||||
|
|
|
@ -868,3 +868,17 @@ CA3773ED313E8899311F3DD0CA195A68 // e3m6
|
|||
{
|
||||
shorttex
|
||||
}
|
||||
|
||||
FCCA97FC851F6473EAA069F74247B317 // pg-raw.wad map31
|
||||
{
|
||||
setlinesectorref 331 front 74
|
||||
setlinesectorref 326 front 74
|
||||
setlinesectorref 497 front 74
|
||||
setlinesectorref 474 front 74
|
||||
setlinesectorref 471 front 74
|
||||
setlinesectorref 327 front 74
|
||||
setlinesectorref 328 front 74
|
||||
setlinesectorref 329 front 74
|
||||
setsectortag 74 4
|
||||
setlinespecial 357 Transfer_Heights 4 2 0 0 0
|
||||
}
|
||||
|
|
|
@ -580,6 +580,8 @@ class Actor : Thinker native
|
|||
native void SetDamage(int dmg);
|
||||
native clearscope double Distance2D(Actor other) const;
|
||||
native clearscope double Distance3D(Actor other) const;
|
||||
native clearscope double Distance2DSquared(Actor other) const;
|
||||
native clearscope double Distance3DSquared(Actor other) const;
|
||||
native void SetOrigin(vector3 newpos, bool moving);
|
||||
native void SetXYZ(vector3 newpos);
|
||||
native Actor GetPointer(int aaptr);
|
||||
|
@ -1185,6 +1187,10 @@ class Actor : Thinker native
|
|||
{
|
||||
return ACS_ExecuteAlways(-int(script), mapnum, arg1, arg2, arg3);
|
||||
}
|
||||
int ACS_ScriptCall(name script, int arg1=0, int arg2=0, int arg3=0, int arg4=0)
|
||||
{
|
||||
return ACS_ExecuteWithResult(-int(script), arg1, arg2, arg3, arg4);
|
||||
}
|
||||
|
||||
States(Actor, Overlay, Weapon, Item)
|
||||
{
|
||||
|
|
|
@ -70,8 +70,13 @@ extend class Actor
|
|||
{
|
||||
if (mo.health > 0 && mo != self)
|
||||
{
|
||||
// other Keen not dead
|
||||
return;
|
||||
// Added check for Dehacked and repurposed inventory items.
|
||||
let inv = Inventory(mo);
|
||||
if (inv == null || inv.Owner == null)
|
||||
{
|
||||
// other Keen not dead
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
Door_Open(doortag, 16);
|
||||
|
|
|
@ -244,6 +244,11 @@ class Korax : Actor
|
|||
|
||||
void A_KoraxMissile()
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const class<Actor> choices[] =
|
||||
{
|
||||
"WraithFX1", "Demon1FX1", "Demon2FX1", "FireDemonMissile", "CentaurFX", "SerpentFX"
|
||||
|
@ -282,6 +287,11 @@ class Korax : Actor
|
|||
|
||||
void KoraxFire (Class<Actor> type, int arm)
|
||||
{
|
||||
if (!target)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static const int extension[] =
|
||||
{
|
||||
KORAX_ARM_EXTENSION_SHORT,
|
||||
|
|
|
@ -1931,22 +1931,6 @@ class PowerMorph : Powerup
|
|||
|
||||
int savedMorphTics = MorphedPlayer.morphTics;
|
||||
MorphedPlayer.UndoPlayerMorph (MorphedPlayer, 0, !!(MorphedPlayer.MorphStyle & MRF_UNDOALWAYS));
|
||||
|
||||
// Abort if unmorph failed; in that case,
|
||||
// set the usual retry timer and return.
|
||||
if (MorphedPlayer != null && MorphedPlayer.morphTics)
|
||||
{
|
||||
// Transfer retry timeout
|
||||
// to the powerup's timer.
|
||||
EffectTics = MorphedPlayer.morphTics;
|
||||
// Reload negative morph tics;
|
||||
// use actual value; it may
|
||||
// be in use for animation.
|
||||
MorphedPlayer.morphTics = savedMorphTics;
|
||||
// Try again some time later
|
||||
return;
|
||||
}
|
||||
// Unmorph suceeded
|
||||
MorphedPlayer = null;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class FastProjectile : Actor
|
|||
int count = 8;
|
||||
if (radius > 0)
|
||||
{
|
||||
while ( abs(Vel.X) > radius * count || abs(Vel.Y) > radius * count)
|
||||
while ( abs(Vel.X) >= radius * count || abs(Vel.Y) >= radius * count || abs(Vel.Z) >= height * count)
|
||||
{
|
||||
// we need to take smaller steps.
|
||||
count += count;
|
||||
|
|
|
@ -101,6 +101,12 @@ class InventoryBarState ui
|
|||
|
||||
}
|
||||
|
||||
class HUDMessageBase native ui
|
||||
{
|
||||
virtual native bool Tick();
|
||||
virtual native void ScreenSizeChanged();
|
||||
virtual native void Draw(int bottom, int visibility);
|
||||
}
|
||||
|
||||
class BaseStatusBar native ui
|
||||
{
|
||||
|
@ -291,6 +297,10 @@ class BaseStatusBar native ui
|
|||
|
||||
private HUDFont mSmallFont;
|
||||
|
||||
native void AttachMessage(HUDMessageBase msg);
|
||||
native HUDMessageBase DetachMessage(HUDMessageBase msg);
|
||||
native HUDMessageBase DetachMessageID(uint msgid);
|
||||
native void DetachAllMessages();
|
||||
|
||||
native void SetSize(int height, int vwidth, int vheight, int hwidth = -1, int hheight = -1);
|
||||
native Vector2 GetHUDScale();
|
||||
|
|
|
@ -559,6 +559,21 @@ object SoulSphere
|
|||
frame SOUL { light SOULSPHERE }
|
||||
}
|
||||
|
||||
pulselight MEGASPHERE
|
||||
{
|
||||
color 0.5 0.5 0.4
|
||||
size 60
|
||||
secondarySize 63
|
||||
interval 2.0
|
||||
offset 0 16 0
|
||||
attenuate 1
|
||||
}
|
||||
|
||||
object MegaSphere
|
||||
{
|
||||
frame MEGA { light MEGASPHERE }
|
||||
}
|
||||
|
||||
// Invulnerability Sphere
|
||||
pulselight INVULN
|
||||
{
|
||||
|
|
|
@ -559,6 +559,21 @@ object SoulSphere
|
|||
frame SOUL { light SOULSPHERE }
|
||||
}
|
||||
|
||||
pulselight MEGASPHERE
|
||||
{
|
||||
color 0.5 0.5 0.4
|
||||
size 60
|
||||
secondarySize 63
|
||||
interval 2.0
|
||||
offset 0 16 0
|
||||
attenuate 1
|
||||
}
|
||||
|
||||
object MegaSphere
|
||||
{
|
||||
frame MEGA { light MEGASPHERE }
|
||||
}
|
||||
|
||||
// Invulnerability Sphere
|
||||
pulselight INVULN
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue