mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-29 23:23:07 +00:00
Merge branch 'master' of https://github.com/coelckers/gzdoom
# Conflicts: # src/r_things.cpp
This commit is contained in:
commit
378de3c109
46 changed files with 764 additions and 217 deletions
|
@ -2985,9 +2985,11 @@ static bool LoadDehSupp ()
|
|||
void FinishDehPatch ()
|
||||
{
|
||||
unsigned int touchedIndex;
|
||||
unsigned int nameindex = 0;
|
||||
|
||||
for (touchedIndex = 0; touchedIndex < TouchedActors.Size(); ++touchedIndex)
|
||||
{
|
||||
PClassActor *subclass;
|
||||
PClassActor *type = TouchedActors[touchedIndex];
|
||||
AActor *defaults1 = GetDefaultByType (type);
|
||||
if (!(defaults1->flags & MF_SPECIAL))
|
||||
|
@ -2997,9 +2999,16 @@ void FinishDehPatch ()
|
|||
|
||||
// Create a new class that will serve as the actual pickup
|
||||
char typeNameBuilder[32];
|
||||
mysnprintf (typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", touchedIndex);
|
||||
PClassActor *subclass = static_cast<PClassActor *>(RUNTIME_CLASS(ADehackedPickup)->
|
||||
CreateDerivedClass(typeNameBuilder, sizeof(ADehackedPickup)));
|
||||
//
|
||||
do
|
||||
{
|
||||
// Retry until we find a free name. This is unlikely to happen but not impossible.
|
||||
mysnprintf(typeNameBuilder, countof(typeNameBuilder), "DehackedPickup%d", nameindex++);
|
||||
subclass = static_cast<PClassActor *>(RUNTIME_CLASS(ADehackedPickup)->
|
||||
CreateDerivedClass(typeNameBuilder, sizeof(ADehackedPickup)));
|
||||
}
|
||||
while (subclass == nullptr);
|
||||
|
||||
AActor *defaults2 = GetDefaultByType (subclass);
|
||||
memcpy ((void *)defaults2, (void *)defaults1, sizeof(AActor));
|
||||
|
||||
|
|
|
@ -670,6 +670,20 @@ void PNamedType::GetTypeIDs(intptr_t &id1, intptr_t &id2) const
|
|||
id2 = TypeName;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PNamedType :: QualifiedName
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
FString PNamedType::QualifiedName() const
|
||||
{
|
||||
FString out;
|
||||
if (Outer != nullptr) out = Outer->QualifiedName();
|
||||
out << "::" << TypeName;
|
||||
return out;
|
||||
}
|
||||
|
||||
/* PInt *******************************************************************/
|
||||
|
||||
IMPLEMENT_CLASS(PInt)
|
||||
|
@ -1752,7 +1766,7 @@ PEnum::PEnum()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PEnum::PEnum(FName name, DObject *outer)
|
||||
PEnum::PEnum(FName name, PTypeBase *outer)
|
||||
: PNamedType(name, outer), ValueType(NULL)
|
||||
{
|
||||
}
|
||||
|
@ -1766,7 +1780,7 @@ PEnum::PEnum(FName name, DObject *outer)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PEnum *NewEnum(FName name, DObject *outer)
|
||||
PEnum *NewEnum(FName name, PTypeBase *outer)
|
||||
{
|
||||
size_t bucket;
|
||||
PType *etype = TypeTable.FindType(RUNTIME_CLASS(PEnum), (intptr_t)outer, (intptr_t)name, &bucket);
|
||||
|
@ -2149,7 +2163,7 @@ PStruct::PStruct()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PStruct::PStruct(FName name, DObject *outer)
|
||||
PStruct::PStruct(FName name, PTypeBase *outer)
|
||||
: PNamedType(name, outer)
|
||||
{
|
||||
}
|
||||
|
@ -2310,7 +2324,7 @@ size_t PStruct::PropagateMark()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
PStruct *NewStruct(FName name, DObject *outer)
|
||||
PStruct *NewStruct(FName name, PTypeBase *outer)
|
||||
{
|
||||
size_t bucket;
|
||||
PType *stype = TypeTable.FindType(RUNTIME_CLASS(PStruct), (intptr_t)outer, (intptr_t)name, &bucket);
|
||||
|
@ -2847,10 +2861,7 @@ void PClass::InsertIntoHash ()
|
|||
found = TypeTable.FindType(RUNTIME_CLASS(PClass), (intptr_t)Outer, TypeName, &bucket);
|
||||
if (found != NULL)
|
||||
{ // This type has already been inserted
|
||||
// ... but there is no need whatsoever to make it a fatal error!
|
||||
if (!strictdecorate) Printf (TEXTCOLOR_RED"Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
else I_Error("Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
TypeTable.ReplaceType(this, found, bucket);
|
||||
I_Error("Tried to register class '%s' more than once.\n", TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3015,15 +3026,23 @@ PClass *PClass::CreateDerivedClass(FName name, unsigned int size)
|
|||
PClass *existclass = static_cast<PClass *>(TypeTable.FindType(RUNTIME_CLASS(PClass), /*FIXME:Outer*/0, name, &bucket));
|
||||
|
||||
// This is a placeholder so fill it in
|
||||
if (existclass != NULL && (existclass->Size == TentativeClass))
|
||||
if (existclass != nullptr)
|
||||
{
|
||||
type = const_cast<PClass*>(existclass);
|
||||
if (!IsDescendantOf(type->ParentClass))
|
||||
if (existclass->Size == TentativeClass)
|
||||
{
|
||||
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||
type = const_cast<PClass*>(existclass);
|
||||
if (!IsDescendantOf(type->ParentClass))
|
||||
{
|
||||
I_Error("%s must inherit from %s but doesn't.", name.GetChars(), type->ParentClass->TypeName.GetChars());
|
||||
}
|
||||
DPrintf(DMSG_SPAMMY, "Defining placeholder class %s\n", name.GetChars());
|
||||
notnew = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// a different class with the same name already exists. Let the calling code deal with this.
|
||||
return nullptr;
|
||||
}
|
||||
DPrintf(DMSG_SPAMMY, "Defining placeholder class %s\n", name.GetChars());
|
||||
notnew = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3360,6 +3379,7 @@ CCMD(typetable)
|
|||
|
||||
// Symbol tables ------------------------------------------------------------
|
||||
|
||||
IMPLEMENT_ABSTRACT_CLASS(PTypeBase);
|
||||
IMPLEMENT_ABSTRACT_CLASS(PSymbol);
|
||||
IMPLEMENT_CLASS(PSymbolConst);
|
||||
IMPLEMENT_CLASS(PSymbolConstNumeric);
|
||||
|
|
|
@ -22,12 +22,28 @@ typedef std::pair<const class PType *, unsigned> FTypeAndOffset;
|
|||
|
||||
// Symbol information -------------------------------------------------------
|
||||
|
||||
class PSymbol : public DObject
|
||||
class PTypeBase : public DObject
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PSymbol, DObject);
|
||||
DECLARE_ABSTRACT_CLASS(PTypeBase, DObject)
|
||||
|
||||
public:
|
||||
virtual FString QualifiedName() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
};
|
||||
|
||||
class PSymbol : public PTypeBase
|
||||
{
|
||||
DECLARE_ABSTRACT_CLASS(PSymbol, PTypeBase);
|
||||
public:
|
||||
virtual ~PSymbol();
|
||||
|
||||
virtual FString QualifiedName() const
|
||||
{
|
||||
return SymbolName.GetChars();
|
||||
}
|
||||
|
||||
FName SymbolName;
|
||||
|
||||
protected:
|
||||
|
@ -153,13 +169,13 @@ extern PSymbolTable GlobalSymbols;
|
|||
|
||||
struct ZCC_ExprConstant;
|
||||
class PClassType;
|
||||
class PType : public DObject
|
||||
class PType : public PTypeBase
|
||||
{
|
||||
//DECLARE_ABSTRACT_CLASS_WITH_META(PType, DObject, PClassType);
|
||||
// We need to unravel the _WITH_META macro, since PClassType isn't defined yet,
|
||||
// and we can't define it until we've defined PClass. But we can't define that
|
||||
// without defining PType.
|
||||
DECLARE_ABSTRACT_CLASS(PType, DObject)
|
||||
DECLARE_ABSTRACT_CLASS(PType, PTypeBase)
|
||||
HAS_OBJECT_POINTERS;
|
||||
protected:
|
||||
enum { MetaClassNum = CLASSREG_PClassType };
|
||||
|
@ -332,14 +348,15 @@ class PNamedType : public PCompoundType
|
|||
DECLARE_ABSTRACT_CLASS(PNamedType, PCompoundType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
DObject *Outer; // object this type is contained within
|
||||
PTypeBase *Outer; // object this type is contained within
|
||||
FName TypeName; // this type's name
|
||||
|
||||
PNamedType() : Outer(NULL) {}
|
||||
PNamedType(FName name, DObject *outer) : Outer(outer), TypeName(name) {}
|
||||
PNamedType(FName name, PTypeBase *outer) : Outer(outer), TypeName(name) {}
|
||||
|
||||
virtual bool IsMatch(intptr_t id1, intptr_t id2) const;
|
||||
virtual void GetTypeIDs(intptr_t &id1, intptr_t &id2) const;
|
||||
virtual FString QualifiedName() const;
|
||||
};
|
||||
|
||||
// Basic types --------------------------------------------------------------
|
||||
|
@ -533,7 +550,7 @@ class PEnum : public PNamedType
|
|||
DECLARE_CLASS(PEnum, PNamedType);
|
||||
HAS_OBJECT_POINTERS;
|
||||
public:
|
||||
PEnum(FName name, DObject *outer);
|
||||
PEnum(FName name, PTypeBase *outer);
|
||||
|
||||
PType *ValueType;
|
||||
TMap<FName, int> Values;
|
||||
|
@ -610,7 +627,7 @@ class PStruct : public PNamedType
|
|||
{
|
||||
DECLARE_CLASS(PStruct, PNamedType);
|
||||
public:
|
||||
PStruct(FName name, DObject *outer);
|
||||
PStruct(FName name, PTypeBase *outer);
|
||||
|
||||
TArray<PField *> Fields;
|
||||
|
||||
|
@ -822,8 +839,8 @@ PDynArray *NewDynArray(PType *type);
|
|||
PPointer *NewPointer(PType *type);
|
||||
PClassPointer *NewClassPointer(PClass *restrict);
|
||||
PClassWaitingForParent *NewUnknownClass(FName myname, FName parentname);
|
||||
PEnum *NewEnum(FName name, DObject *outer);
|
||||
PStruct *NewStruct(FName name, DObject *outer);
|
||||
PEnum *NewEnum(FName name, PTypeBase *outer);
|
||||
PStruct *NewStruct(FName name, PTypeBase *outer);
|
||||
PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *> &argtypes);
|
||||
|
||||
// Built-in types -----------------------------------------------------------
|
||||
|
|
|
@ -2000,7 +2000,7 @@ void G_DoLoadGame ()
|
|||
{
|
||||
// delete the resource file if anything goes wrong in here.
|
||||
if (resfile != nullptr) delete resfile;
|
||||
return;
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1512,7 +1512,11 @@ void G_UnSnapshotLevel (bool hubLoad)
|
|||
if (level.info->isValid())
|
||||
{
|
||||
FSerializer arc;
|
||||
if (!arc.OpenReader(&level.info->Snapshot)) return;
|
||||
if (!arc.OpenReader(&level.info->Snapshot))
|
||||
{
|
||||
I_Error("Failed to load savegame");
|
||||
return;
|
||||
}
|
||||
|
||||
G_SerializeLevel (arc, hubLoad);
|
||||
level.FromSnapshot = true;
|
||||
|
|
|
@ -1187,12 +1187,12 @@ class CommandDrawNumber : public CommandDrawString
|
|||
|
||||
if (!(cvartype == CVAR_Bool || cvartype == CVAR_Int))
|
||||
{
|
||||
sc.ScriptMessage("CVar '%s' is not an int or bool", cvarName);
|
||||
sc.ScriptMessage("CVar '%s' is not an int or bool", cvarName.GetChars());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sc.ScriptMessage("CVar '%s' does not exist", cvarName);
|
||||
sc.ScriptMessage("CVar '%s' does not exist", cvarName.GetChars());
|
||||
}
|
||||
|
||||
if (parenthesized) sc.MustGetToken(')');
|
||||
|
|
|
@ -314,12 +314,12 @@ void FVoxelModel::MakeSlabPolys(int x, int y, kvxslab_t *voxptr, FVoxelMap &chec
|
|||
}
|
||||
if (cull & 4)
|
||||
{
|
||||
AddFace(x, y, z, x+1, y, z, x, y, z+c, x+1, y, z+c, *col, check);
|
||||
AddFace(x+1, y, z, x, y, z, x+1, y, z+c, x, y, z+c, *col, check);
|
||||
}
|
||||
if (cull & 8)
|
||||
{
|
||||
AddFace(x+1, y+1, z, x, y+1, z, x+1, y+1, z+c, x, y+1, z+c, *col, check);
|
||||
}
|
||||
AddFace(x, y+1, z, x+1, y+1, z, x, y+1, z+c, x+1, y+1, z+c, *col, check);
|
||||
}
|
||||
z+=c;
|
||||
col+=c;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#define __GL_RENDERBUFFERS_H
|
||||
|
||||
#include "gl/shaders/gl_shader.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
|
||||
class FGLBloomTextureLevel
|
||||
{
|
||||
|
|
|
@ -105,6 +105,8 @@ FGLRenderer::FGLRenderer(OpenGLFrameBuffer *fb)
|
|||
mTonemapPalette = nullptr;
|
||||
mBuffers = nullptr;
|
||||
mPresentShader = nullptr;
|
||||
mPresent3dCheckerShader = nullptr;
|
||||
mPresent3dColumnShader = nullptr;
|
||||
mPresent3dRowShader = nullptr;
|
||||
mBloomExtractShader = nullptr;
|
||||
mBloomCombineShader = nullptr;
|
||||
|
@ -139,6 +141,8 @@ void FGLRenderer::Initialize(int width, int height)
|
|||
mFXAAShader = new FFXAAShader;
|
||||
mFXAALumaShader = new FFXAALumaShader;
|
||||
mPresentShader = new FPresentShader();
|
||||
mPresent3dCheckerShader = new FPresent3DCheckerShader();
|
||||
mPresent3dColumnShader = new FPresent3DColumnShader();
|
||||
mPresent3dRowShader = new FPresent3DRowShader();
|
||||
m2DDrawer = new F2DDrawer;
|
||||
|
||||
|
@ -192,6 +196,8 @@ FGLRenderer::~FGLRenderer()
|
|||
}
|
||||
if (mBuffers) delete mBuffers;
|
||||
if (mPresentShader) delete mPresentShader;
|
||||
if (mPresent3dCheckerShader) delete mPresent3dCheckerShader;
|
||||
if (mPresent3dColumnShader) delete mPresent3dColumnShader;
|
||||
if (mPresent3dRowShader) delete mPresent3dRowShader;
|
||||
if (mBloomExtractShader) delete mBloomExtractShader;
|
||||
if (mBloomCombineShader) delete mBloomCombineShader;
|
||||
|
|
|
@ -31,6 +31,8 @@ class FLensShader;
|
|||
class FFXAALumaShader;
|
||||
class FFXAAShader;
|
||||
class FPresentShader;
|
||||
class FPresent3DCheckerShader;
|
||||
class FPresent3DColumnShader;
|
||||
class FPresent3DRowShader;
|
||||
class F2DDrawer;
|
||||
class FHardwareTexture;
|
||||
|
@ -109,6 +111,8 @@ public:
|
|||
FFXAALumaShader *mFXAALumaShader;
|
||||
FFXAAShader *mFXAAShader;
|
||||
FPresentShader *mPresentShader;
|
||||
FPresent3DCheckerShader *mPresent3dCheckerShader;
|
||||
FPresent3DColumnShader *mPresent3dColumnShader;
|
||||
FPresent3DRowShader *mPresent3dRowShader;
|
||||
|
||||
FTexture *gllight;
|
||||
|
|
|
@ -187,21 +187,18 @@ void GLFlat::DrawSubsector(subsector_t * sub)
|
|||
unsigned int vi[4];
|
||||
|
||||
vi[0] = 0;
|
||||
for (unsigned int i = 1; i < sub->numlines-1; i += 2)
|
||||
for (unsigned int i = 0; i < sub->numlines - 2; i += 2)
|
||||
{
|
||||
if (i < sub->numlines - 3)
|
||||
for (unsigned int j = 1; j < 4; j++)
|
||||
{
|
||||
for (unsigned int j = 1; j < 4; j++)
|
||||
{
|
||||
vi[j] = MIN(i + j, sub->numlines - 1);
|
||||
}
|
||||
for (unsigned int x = 0; x < 4; x++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[vi[x]].v1;
|
||||
qd.Set(x, vt->fX(), plane.plane.ZatPoint(vt) + dz, vt->fY(), vt->fX() / 64.f, -vt->fY() / 64.f);
|
||||
}
|
||||
qd.Render(GL_TRIANGLE_FAN);
|
||||
vi[j] = MIN(i + j, sub->numlines - 1);
|
||||
}
|
||||
for (unsigned int x = 0; x < 4; x++)
|
||||
{
|
||||
vertex_t *vt = sub->firstline[vi[x]].v1;
|
||||
qd.Set(x, vt->fX(), plane.plane.ZatPoint(vt) + dz, vt->fY(), vt->fX() / 64.f, -vt->fY() / 64.f);
|
||||
}
|
||||
qd.Render(GL_TRIANGLE_FAN);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -138,10 +138,10 @@ void GLSprite::CalculateVertices(FVector3 *v)
|
|||
mat.Rotate(0, 1, 0, - actor->Angles.Roll.Degrees);
|
||||
mat.Translate(-x, -z, -y);
|
||||
}
|
||||
v[0] = mat * FVector3(x1, z, y2);
|
||||
v[1] = mat * FVector3(x2, z, y2);
|
||||
v[2] = mat * FVector3(x1, z, y1);
|
||||
v[3] = mat * FVector3(x2, z, y1);
|
||||
v[0] = mat * FVector3(x2, z, y2);
|
||||
v[1] = mat * FVector3(x1, z, y2);
|
||||
v[2] = mat * FVector3(x2, z, y1);
|
||||
v[3] = mat * FVector3(x1, z, y1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,19 +129,20 @@ void FGLRenderer::DrawPSprite (player_t * player,DPSprite *psp, float sx, float
|
|||
y1 = viewwindowy + vh / 2 - (ftexturemid * scale);
|
||||
y2 = y1 + (r.height * scale) + 1;
|
||||
|
||||
if (!mirror)
|
||||
if (!(mirror) != !(psp->Flags & PSPF_FLIP))
|
||||
{
|
||||
fU1=tex->GetSpriteUL();
|
||||
fV1=tex->GetSpriteVT();
|
||||
fU2=tex->GetSpriteUR();
|
||||
fV2=tex->GetSpriteVB();
|
||||
fU2 = tex->GetSpriteUL();
|
||||
fV1 = tex->GetSpriteVT();
|
||||
fU1 = tex->GetSpriteUR();
|
||||
fV2 = tex->GetSpriteVB();
|
||||
}
|
||||
else
|
||||
{
|
||||
fU2=tex->GetSpriteUL();
|
||||
fV1=tex->GetSpriteVT();
|
||||
fU1=tex->GetSpriteUR();
|
||||
fV2=tex->GetSpriteVB();
|
||||
fU1 = tex->GetSpriteUL();
|
||||
fV1 = tex->GetSpriteVT();
|
||||
fU2 = tex->GetSpriteUR();
|
||||
fV2 = tex->GetSpriteVB();
|
||||
|
||||
}
|
||||
|
||||
if (tex->GetTransparent() || OverrideShader != -1)
|
||||
|
|
|
@ -38,23 +38,37 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_present3dRowshader.h"
|
||||
|
||||
void FPresentStereoShaderBase::Init(const char * vtx_shader_name, const char * program_name)
|
||||
{
|
||||
FPresentShaderBase::Init(vtx_shader_name, program_name);
|
||||
LeftEyeTexture.Init(mShader, "LeftEyeTexture");
|
||||
RightEyeTexture.Init(mShader, "RightEyeTexture");
|
||||
WindowPositionParity.Init(mShader, "WindowPositionParity");
|
||||
}
|
||||
|
||||
void FPresent3DCheckerShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders/glsl/present_checker3d.fp", "shaders/glsl/presentChecker3d");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
||||
void FPresent3DColumnShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
Init("shaders/glsl/present_column3d.fp", "shaders/glsl/presentColumn3d");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
||||
void FPresent3DRowShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330);
|
||||
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present_row3d.fp", "", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/presentRow3d");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
mShader.SetAttribLocation(1, "UV");
|
||||
LeftEyeTexture.Init(mShader, "LeftEyeTexture");
|
||||
RightEyeTexture.Init(mShader, "RightEyeTexture");
|
||||
InvGamma.Init(mShader, "InvGamma");
|
||||
Contrast.Init(mShader, "Contrast");
|
||||
Brightness.Init(mShader, "Brightness");
|
||||
Scale.Init(mShader, "UVScale");
|
||||
VerticalPixelOffset.Init(mShader, "VerticalPixelOffset");
|
||||
Init("shaders/glsl/present_row3d.fp", "shaders/glsl/presentRow3d");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
|
|
@ -29,22 +29,35 @@
|
|||
#define GL_PRESENT3DROWSHADER_H_
|
||||
|
||||
#include "gl_shaderprogram.h"
|
||||
#include "gl_presentshader.h"
|
||||
|
||||
class FPresent3DRowShader
|
||||
class FPresentStereoShaderBase : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
|
||||
FBufferedUniformSampler LeftEyeTexture;
|
||||
FBufferedUniformSampler RightEyeTexture;
|
||||
FBufferedUniform1f InvGamma;
|
||||
FBufferedUniform1f Contrast;
|
||||
FBufferedUniform1f Brightness;
|
||||
FBufferedUniform2f Scale;
|
||||
FBufferedUniform1i VerticalPixelOffset;
|
||||
FBufferedUniform1i WindowPositionParity;
|
||||
|
||||
private:
|
||||
FShaderProgram mShader;
|
||||
protected:
|
||||
void Init(const char * vtx_shader_name, const char * program_name) override;
|
||||
};
|
||||
|
||||
class FPresent3DCheckerShader : public FPresentStereoShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
};
|
||||
|
||||
class FPresent3DColumnShader : public FPresentStereoShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
};
|
||||
|
||||
class FPresent3DRowShader : public FPresentStereoShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
};
|
||||
|
||||
// GL_PRESENT3DROWSHADER_H_
|
||||
|
|
|
@ -36,21 +36,26 @@
|
|||
#include "gl/system/gl_cvars.h"
|
||||
#include "gl/shaders/gl_presentshader.h"
|
||||
|
||||
void FPresentShaderBase::Init(const char * vtx_shader_name, const char * program_name)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330);
|
||||
mShader.Compile(FShaderProgram::Fragment, vtx_shader_name, "", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link(program_name);
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
mShader.SetAttribLocation(1, "UV");
|
||||
InvGamma.Init(mShader, "InvGamma");
|
||||
Contrast.Init(mShader, "Contrast");
|
||||
Brightness.Init(mShader, "Brightness");
|
||||
Scale.Init(mShader, "UVScale");
|
||||
}
|
||||
|
||||
void FPresentShader::Bind()
|
||||
{
|
||||
if (!mShader)
|
||||
{
|
||||
mShader.Compile(FShaderProgram::Vertex, "shaders/glsl/screenquadscale.vp", "", 330);
|
||||
mShader.Compile(FShaderProgram::Fragment, "shaders/glsl/present.fp", "", 330);
|
||||
mShader.SetFragDataLocation(0, "FragColor");
|
||||
mShader.Link("shaders/glsl/present");
|
||||
mShader.SetAttribLocation(0, "PositionInProjection");
|
||||
mShader.SetAttribLocation(1, "UV");
|
||||
Init("shaders/glsl/present.fp", "shaders/glsl/present");
|
||||
InputTexture.Init(mShader, "InputTexture");
|
||||
InvGamma.Init(mShader, "InvGamma");
|
||||
Contrast.Init(mShader, "Contrast");
|
||||
Brightness.Init(mShader, "Brightness");
|
||||
Scale.Init(mShader, "UVScale");
|
||||
}
|
||||
mShader.Bind();
|
||||
}
|
||||
|
|
|
@ -3,19 +3,27 @@
|
|||
|
||||
#include "gl_shaderprogram.h"
|
||||
|
||||
class FPresentShader
|
||||
class FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind();
|
||||
virtual void Bind() = 0;
|
||||
|
||||
FBufferedUniformSampler InputTexture;
|
||||
FBufferedUniform1f InvGamma;
|
||||
FBufferedUniform1f Contrast;
|
||||
FBufferedUniform1f Brightness;
|
||||
FBufferedUniform2f Scale;
|
||||
|
||||
private:
|
||||
protected:
|
||||
virtual void Init(const char * vtx_shader_name, const char * program_name);
|
||||
FShaderProgram mShader;
|
||||
};
|
||||
|
||||
class FPresentShader : public FPresentShaderBase
|
||||
{
|
||||
public:
|
||||
void Bind() override;
|
||||
|
||||
FBufferedUniformSampler InputTexture;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -43,10 +43,25 @@
|
|||
EXTERN_CVAR(Float, vid_brightness)
|
||||
EXTERN_CVAR(Float, vid_contrast)
|
||||
EXTERN_CVAR(Bool, fullscreen)
|
||||
EXTERN_CVAR(Int, win_y) // pixel position of top of display window
|
||||
EXTERN_CVAR(Int, win_x) // screen pixel position of left of display window
|
||||
EXTERN_CVAR(Int, win_y) // screen pixel position of top of display window
|
||||
|
||||
namespace s3d {
|
||||
|
||||
/* static */
|
||||
const CheckerInterleaved3D& CheckerInterleaved3D::getInstance(float ipd)
|
||||
{
|
||||
static CheckerInterleaved3D instance(ipd);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const ColumnInterleaved3D& ColumnInterleaved3D::getInstance(float ipd)
|
||||
{
|
||||
static ColumnInterleaved3D instance(ipd);
|
||||
return instance;
|
||||
}
|
||||
|
||||
/* static */
|
||||
const RowInterleaved3D& RowInterleaved3D::getInstance(float ipd)
|
||||
{
|
||||
|
@ -54,11 +69,7 @@ const RowInterleaved3D& RowInterleaved3D::getInstance(float ipd)
|
|||
return instance;
|
||||
}
|
||||
|
||||
RowInterleaved3D::RowInterleaved3D(double ipdMeters)
|
||||
: TopBottom3D(ipdMeters)
|
||||
{}
|
||||
|
||||
void RowInterleaved3D::Present() const
|
||||
static void prepareInterleavedPresent(FPresentStereoShaderBase& shader)
|
||||
{
|
||||
GLRenderer->mBuffers->BindOutputFB();
|
||||
GLRenderer->ClearBorders();
|
||||
|
@ -79,39 +90,118 @@ void RowInterleaved3D::Present() const
|
|||
const GL_IRECT& box = GLRenderer->mOutputLetterbox;
|
||||
glViewport(box.left, box.top, box.width, box.height);
|
||||
|
||||
bool applyGamma = true;
|
||||
shader.Bind();
|
||||
shader.LeftEyeTexture.Set(0);
|
||||
shader.RightEyeTexture.Set(1);
|
||||
|
||||
GLRenderer->mPresent3dRowShader->Bind();
|
||||
GLRenderer->mPresent3dRowShader->LeftEyeTexture.Set(0);
|
||||
GLRenderer->mPresent3dRowShader->RightEyeTexture.Set(1);
|
||||
|
||||
if (!applyGamma || GLRenderer->framebuffer->IsHWGammaActive())
|
||||
if ( GLRenderer->framebuffer->IsHWGammaActive() )
|
||||
{
|
||||
GLRenderer->mPresent3dRowShader->InvGamma.Set(1.0f);
|
||||
GLRenderer->mPresent3dRowShader->Contrast.Set(1.0f);
|
||||
GLRenderer->mPresent3dRowShader->Brightness.Set(0.0f);
|
||||
shader.InvGamma.Set(1.0f);
|
||||
shader.Contrast.Set(1.0f);
|
||||
shader.Brightness.Set(0.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
GLRenderer->mPresent3dRowShader->InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||
GLRenderer->mPresent3dRowShader->Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
GLRenderer->mPresent3dRowShader->Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
shader.InvGamma.Set(1.0f / clamp<float>(Gamma, 0.1f, 4.f));
|
||||
shader.Contrast.Set(clamp<float>(vid_contrast, 0.1f, 3.f));
|
||||
shader.Brightness.Set(clamp<float>(vid_brightness, -0.8f, 0.8f));
|
||||
}
|
||||
GLRenderer->mPresent3dRowShader->Scale.Set(
|
||||
shader.Scale.Set(
|
||||
GLRenderer->mScreenViewport.width / (float)GLRenderer->mBuffers->GetWidth(),
|
||||
GLRenderer->mScreenViewport.height / (float)GLRenderer->mBuffers->GetHeight());
|
||||
}
|
||||
|
||||
// fixme: I don't know how to get absolute window position on Mac and Linux
|
||||
// fixme: I don't know how to get window border decoration size anywhere
|
||||
// So for now I'll hard code the border effect on my test machine.
|
||||
// Workaround for others is to fuss with vr_swap_eyes CVAR until it looks right.
|
||||
// Presumably the top/left window border on my test machine has an odd number of pixels
|
||||
// in the horizontal direction, and an even number in the vertical direction.
|
||||
#define WINDOW_BORDER_HORIZONTAL_PARITY 1
|
||||
#define WINDOW_BORDER_VERTICAL_PARITY 0
|
||||
|
||||
void CheckerInterleaved3D::Present() const
|
||||
{
|
||||
prepareInterleavedPresent(*GLRenderer->mPresent3dCheckerShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
int windowVOffset = 0;
|
||||
int windowHOffset = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!fullscreen) {
|
||||
I_SaveWindowedPos(); // update win_y CVAR
|
||||
windowHOffset = (win_x + WINDOW_BORDER_HORIZONTAL_PARITY) % 2;
|
||||
windowVOffset = (win_y + WINDOW_BORDER_VERTICAL_PARITY) % 2;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
GLRenderer->mPresent3dCheckerShader->WindowPositionParity.Set(
|
||||
(windowVOffset
|
||||
+ windowHOffset
|
||||
+ GLRenderer->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2 // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
);
|
||||
|
||||
GLRenderer->RenderScreenQuad();
|
||||
}
|
||||
|
||||
void s3d::CheckerInterleaved3D::AdjustViewports() const
|
||||
{
|
||||
// decrease the total pixel count by 2, but keep the same aspect ratio
|
||||
const float sqrt2 = 1.41421356237f;
|
||||
// Change size of renderbuffer, and align to screen
|
||||
GLRenderer->mSceneViewport.height /= sqrt2;
|
||||
GLRenderer->mSceneViewport.top /= sqrt2;
|
||||
GLRenderer->mSceneViewport.width /= sqrt2;
|
||||
GLRenderer->mSceneViewport.left /= sqrt2;
|
||||
|
||||
GLRenderer->mScreenViewport.height /= sqrt2;
|
||||
GLRenderer->mScreenViewport.top /= sqrt2;
|
||||
GLRenderer->mScreenViewport.width /= sqrt2;
|
||||
GLRenderer->mScreenViewport.left /= sqrt2;
|
||||
}
|
||||
|
||||
void ColumnInterleaved3D::Present() const
|
||||
{
|
||||
prepareInterleavedPresent(*GLRenderer->mPresent3dColumnShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
int windowHOffset = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (!fullscreen) {
|
||||
I_SaveWindowedPos(); // update win_y CVAR
|
||||
windowHOffset = (win_x + WINDOW_BORDER_HORIZONTAL_PARITY) % 2;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
GLRenderer->mPresent3dColumnShader->WindowPositionParity.Set(windowHOffset);
|
||||
|
||||
GLRenderer->RenderScreenQuad();
|
||||
}
|
||||
|
||||
void RowInterleaved3D::Present() const
|
||||
{
|
||||
prepareInterleavedPresent(*GLRenderer->mPresent3dRowShader);
|
||||
|
||||
// Compute absolute offset from top of screen to top of current display window
|
||||
// because we need screen-relative, not window-relative, scan line parity
|
||||
int windowVOffset = 0;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (! fullscreen) {
|
||||
I_SaveWindowedPos(); // update win_y CVAR
|
||||
windowVOffset = win_y;
|
||||
windowVOffset = (win_y + WINDOW_BORDER_VERTICAL_PARITY) % 2;
|
||||
}
|
||||
#endif // _WIN32
|
||||
|
||||
GLRenderer->mPresent3dRowShader->VerticalPixelOffset.Set(
|
||||
windowVOffset // fixme: vary with window location
|
||||
+ box.height % 2 // because we want the top pixel offset, but gl_FragCoord.y is the bottom pixel offset
|
||||
GLRenderer->mPresent3dRowShader->WindowPositionParity.Set(
|
||||
(windowVOffset
|
||||
+ GLRenderer->mOutputLetterbox.height + 1 // +1 because of origin at bottom
|
||||
) % 2
|
||||
);
|
||||
|
||||
GLRenderer->RenderScreenQuad();
|
||||
|
|
|
@ -42,15 +42,30 @@
|
|||
#include "gl/system/gl_system.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
|
||||
class FPresent3DRowShader;
|
||||
|
||||
namespace s3d {
|
||||
|
||||
class CheckerInterleaved3D : public SideBySideSquished
|
||||
{
|
||||
public:
|
||||
static const CheckerInterleaved3D& getInstance(float ipd);
|
||||
CheckerInterleaved3D(double ipdMeters) : SideBySideSquished(ipdMeters) {}
|
||||
void Present() const override;
|
||||
void AdjustViewports() const override;
|
||||
};
|
||||
|
||||
class ColumnInterleaved3D : public SideBySideSquished
|
||||
{
|
||||
public:
|
||||
static const ColumnInterleaved3D& getInstance(float ipd);
|
||||
ColumnInterleaved3D(double ipdMeters) : SideBySideSquished(ipdMeters) {}
|
||||
void Present() const override;
|
||||
};
|
||||
|
||||
class RowInterleaved3D : public TopBottom3D
|
||||
{
|
||||
public:
|
||||
static const RowInterleaved3D& getInstance(float ipd);
|
||||
RowInterleaved3D(double ipdMeters);
|
||||
RowInterleaved3D(double ipdMeters) : TopBottom3D(ipdMeters) {}
|
||||
void Present() const override;
|
||||
};
|
||||
|
||||
|
|
|
@ -107,6 +107,12 @@ const Stereo3DMode& Stereo3DMode::getCurrentMode()
|
|||
case 12:
|
||||
setCurrentMode(RowInterleaved3D::getInstance(vr_ipd));
|
||||
break;
|
||||
case 13:
|
||||
setCurrentMode(ColumnInterleaved3D::getInstance(vr_ipd));
|
||||
break;
|
||||
case 14:
|
||||
setCurrentMode(CheckerInterleaved3D::getInstance(vr_ipd));
|
||||
break;
|
||||
case 0:
|
||||
default:
|
||||
setCurrentMode(MonoView::getInstance());
|
||||
|
|
|
@ -5821,43 +5821,54 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
|||
// [ZK] A_Warp in ACS
|
||||
case ACSF_Warp:
|
||||
{
|
||||
int tid_dest = args[0];
|
||||
int xofs = args[1];
|
||||
int yofs = args[2];
|
||||
int zofs = args[3];
|
||||
int angle = args[4];
|
||||
int flags = args[5];
|
||||
const char *statename = argCount > 6 ? FBehavior::StaticLookupString(args[6]) : "";
|
||||
bool exact = argCount > 7 ? !!args[7] : false;
|
||||
int heightoffset = argCount > 8 ? args[8] : 0;
|
||||
int radiusoffset = argCount > 9 ? args[9] : 0;
|
||||
int pitch = argCount > 10 ? args[10] : 0;
|
||||
|
||||
FState *state = argCount > 6 ? activator->GetClass()->FindStateByString(statename, exact) : 0;
|
||||
|
||||
AActor *reference;
|
||||
if((flags & WARPF_USEPTR) && tid_dest != AAPTR_DEFAULT)
|
||||
if (nullptr == activator)
|
||||
{
|
||||
reference = COPY_AAPTR(activator, tid_dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
reference = SingleActorFromTID(tid_dest, activator);
|
||||
}
|
||||
|
||||
// If there is no activator or actor to warp to, fail.
|
||||
if (activator == NULL || !reference)
|
||||
return false;
|
||||
|
||||
if (P_Thing_Warp(activator, reference, ACSToDouble(xofs), ACSToDouble(yofs), ACSToDouble(zofs), ACSToAngle(angle), flags, ACSToDouble(heightoffset), ACSToDouble(radiusoffset), ACSToAngle(pitch)))
|
||||
{
|
||||
if (state && argCount > 6)
|
||||
{
|
||||
activator->SetState(state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
const int dest = args[0];
|
||||
const int flags = args[5];
|
||||
|
||||
AActor* const reference = ((flags & WARPF_USEPTR) && (AAPTR_DEFAULT != dest))
|
||||
? COPY_AAPTR(activator, dest)
|
||||
: SingleActorFromTID(dest, activator);
|
||||
|
||||
if (nullptr == reference)
|
||||
{
|
||||
// there is no actor to warp to
|
||||
return false;
|
||||
}
|
||||
|
||||
const double xofs = ACSToDouble(args[1]);
|
||||
const double yofs = ACSToDouble(args[2]);
|
||||
const double zofs = ACSToDouble(args[3]);
|
||||
const DAngle angle = ACSToAngle(args[4]);
|
||||
const double heightoffset = argCount > 8 ? ACSToDouble(args[8]) : 0.0;
|
||||
const double radiusoffset = argCount > 9 ? ACSToDouble(args[9]) : 0.0;
|
||||
const DAngle pitch = ACSToAngle(argCount > 10 ? args[10] : 0);
|
||||
|
||||
if (!P_Thing_Warp(activator, reference, xofs, yofs, zofs, angle, flags, heightoffset, radiusoffset, pitch))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (argCount > 6)
|
||||
{
|
||||
const char* const statename = FBehavior::StaticLookupString(args[6]);
|
||||
|
||||
if (nullptr != statename)
|
||||
{
|
||||
const bool exact = argCount > 7 && !!args[7];
|
||||
FState* const state = activator->GetClass()->FindStateByString(statename, exact);
|
||||
|
||||
if (nullptr != state)
|
||||
{
|
||||
activator->SetState(state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
case ACSF_GetMaxInventory:
|
||||
actor = SingleActorFromTID(args[0], activator);
|
||||
|
|
|
@ -215,6 +215,12 @@ DCeiling::DCeiling (sector_t *sec, double speed1, double speed2, int silent)
|
|||
m_Speed = m_Speed1 = speed1;
|
||||
m_Speed2 = speed2;
|
||||
m_Silent = silent;
|
||||
m_BottomHeight = 0;
|
||||
m_TopHeight = 0;
|
||||
m_Direction = 0;
|
||||
m_Texture = FNullTextureID();
|
||||
m_Tag = 0;
|
||||
m_OldDirection = 0;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
|
|
@ -635,6 +635,7 @@ void AActor::RemoveInventory(AInventory *item)
|
|||
|
||||
bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate, bool notakeinfinite)
|
||||
{
|
||||
amount = abs(amount);
|
||||
AInventory *item = FindInventory(itemclass);
|
||||
|
||||
if (item == NULL)
|
||||
|
@ -667,6 +668,7 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate
|
|||
item->IsKindOf(RUNTIME_CLASS(AAmmo)))
|
||||
{
|
||||
// Nothing to do here, except maybe res = false;? Would it make sense?
|
||||
result = false;
|
||||
}
|
||||
else if (!amount || amount>=item->Amount)
|
||||
{
|
||||
|
@ -686,11 +688,30 @@ bool AActor::TakeInventory(PClassActor *itemclass, int amount, bool fromdecorate
|
|||
|
||||
void AActor::DestroyAllInventory ()
|
||||
{
|
||||
while (Inventory != NULL)
|
||||
AInventory *inv = Inventory;
|
||||
if (inv != nullptr)
|
||||
{
|
||||
AInventory *item = Inventory;
|
||||
item->Destroy ();
|
||||
assert (item != Inventory);
|
||||
TArray<AInventory *> toDelete;
|
||||
|
||||
// Delete the list in a two stage approach.
|
||||
// This is necessary because an item may destroy another item (e.g. sister weapons)
|
||||
// which would break the list and leave parts of it undestroyed, maybe doing bad things later.
|
||||
while (inv != nullptr)
|
||||
{
|
||||
toDelete.Push(inv);
|
||||
AInventory *item = inv->Inventory;
|
||||
inv->Inventory = nullptr;
|
||||
inv->Owner = nullptr;
|
||||
inv = item;
|
||||
}
|
||||
for (auto p : toDelete)
|
||||
{
|
||||
// the item may already have been deleted by another one, so check this here to avoid problems.
|
||||
if (!(p->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
p->Destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1006,7 +1006,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayOffset)
|
|||
PARAM_FLOAT_OPT(wx) { wx = 0.; }
|
||||
PARAM_FLOAT_OPT(wy) { wy = 32.; }
|
||||
PARAM_INT_OPT(flags) { flags = 0; }
|
||||
A_OverlayOffset(self, layer, wx, wy, flags);
|
||||
A_OverlayOffset(self, ((layer != 0) ? layer : stateinfo->mPSPIndex), wx, wy, flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1033,10 +1033,10 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags)
|
|||
PARAM_INT(flags);
|
||||
PARAM_BOOL(set);
|
||||
|
||||
if (self->player == nullptr)
|
||||
if (!ACTION_CALL_FROM_PSPRITE())
|
||||
return 0;
|
||||
|
||||
DPSprite *pspr = self->player->FindPSprite(layer);
|
||||
DPSprite *pspr = self->player->FindPSprite(((layer != 0) ? layer : stateinfo->mPSPIndex));
|
||||
|
||||
if (pspr == nullptr)
|
||||
return 0;
|
||||
|
@ -1049,6 +1049,52 @@ DEFINE_ACTION_FUNCTION(AActor, A_OverlayFlags)
|
|||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC OverlayX/Y
|
||||
// Action function to return the X/Y of an overlay.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
static double GetOverlayPosition(AActor *self, int layer, bool gety)
|
||||
{
|
||||
if (layer)
|
||||
{
|
||||
DPSprite *pspr = self->player->FindPSprite(layer);
|
||||
|
||||
if (pspr != nullptr)
|
||||
{
|
||||
return gety ? (pspr->y) : (pspr->x);
|
||||
}
|
||||
}
|
||||
return 0.;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, OverlayX)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT(layer) { layer = 0; }
|
||||
|
||||
if (ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
double res = GetOverlayPosition(self, ((layer != 0) ? layer : stateinfo->mPSPIndex), false);
|
||||
ACTION_RETURN_FLOAT(res);
|
||||
}
|
||||
ACTION_RETURN_FLOAT(0.);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, OverlayY)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_INT_OPT(layer) { layer = 0; }
|
||||
|
||||
if (ACTION_CALL_FROM_PSPRITE())
|
||||
{
|
||||
double res = GetOverlayPosition(self, ((layer != 0) ? layer : stateinfo->mPSPIndex), true);
|
||||
ACTION_RETURN_FLOAT(res);
|
||||
}
|
||||
ACTION_RETURN_FLOAT(0.);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC OverlayID
|
||||
|
|
|
@ -58,6 +58,7 @@ enum PSPFlags
|
|||
PSPF_ADDBOB = 1 << 1,
|
||||
PSPF_POWDOUBLE = 1 << 2,
|
||||
PSPF_CVARFAST = 1 << 3,
|
||||
PSPF_FLIP = 1 << 6,
|
||||
};
|
||||
|
||||
class DPSprite : public DObject
|
||||
|
|
|
@ -130,6 +130,53 @@ void Mac_I_FatalError(const char* const message)
|
|||
}
|
||||
|
||||
|
||||
static void I_DetectOS()
|
||||
{
|
||||
SInt32 majorVersion = 0;
|
||||
Gestalt(gestaltSystemVersionMajor, &majorVersion);
|
||||
|
||||
SInt32 minorVersion = 0;
|
||||
Gestalt(gestaltSystemVersionMinor, &minorVersion);
|
||||
|
||||
SInt32 bugFixVersion = 0;
|
||||
Gestalt(gestaltSystemVersionBugFix, &bugFixVersion);
|
||||
|
||||
const char* name = "Unknown version";
|
||||
|
||||
if (10 == majorVersion) switch (minorVersion)
|
||||
{
|
||||
case 4: name = "Mac OS X Tiger"; break;
|
||||
case 5: name = "Mac OS X Leopard"; break;
|
||||
case 6: name = "Mac OS X Snow Leopard"; break;
|
||||
case 7: name = "Mac OS X Lion"; break;
|
||||
case 8: name = "OS X Mountain Lion"; break;
|
||||
case 9: name = "OS X Mavericks"; break;
|
||||
case 10: name = "OS X Yosemite"; break;
|
||||
case 11: name = "OS X El Capitan"; break;
|
||||
case 12: name = "macOS Sierra"; break;
|
||||
}
|
||||
|
||||
char release[16] = {};
|
||||
size_t size = sizeof release - 1;
|
||||
sysctlbyname("kern.osversion", release, &size, nullptr, 0);
|
||||
|
||||
const char* const architecture =
|
||||
#ifdef __i386__
|
||||
"32-bit Intel";
|
||||
#elif defined __x86_64__
|
||||
"64-bit Intel";
|
||||
#elif defined __ppc__
|
||||
"32-bit PowerPC";
|
||||
#elif defined __ppc64__
|
||||
"64-bit PowerPC";
|
||||
#else
|
||||
"Unknown";
|
||||
#endif
|
||||
|
||||
Printf("OS: %s %d.%d.%d (%s) %s\n", name, majorVersion, minorVersion, bugFixVersion, release, architecture);
|
||||
}
|
||||
|
||||
|
||||
DArgs* Args; // command line arguments
|
||||
|
||||
|
||||
|
@ -165,6 +212,8 @@ void OriginalMainTry(int argc, char** argv)
|
|||
progdir += "/";
|
||||
|
||||
C_InitConsole(80 * 8, 25 * 8, false);
|
||||
|
||||
I_DetectOS();
|
||||
D_DoomMain();
|
||||
}
|
||||
|
||||
|
|
|
@ -653,7 +653,7 @@ DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdi
|
|||
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
|
||||
{
|
||||
len = ReadVarLen(track);
|
||||
if (len >= (MAX_EVENTS-1)*3*4)
|
||||
if (len >= (MAX_EVENTS-1)*3*4 || DeviceType == MDEV_SNDSYS)
|
||||
{ // This message will never fit. Throw it away.
|
||||
track->TrackP += len;
|
||||
}
|
||||
|
|
|
@ -598,7 +598,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr
|
|||
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
|
||||
{
|
||||
len = track->ReadVarLen();
|
||||
if (len >= (MAX_EVENTS-1)*3*4)
|
||||
if (len >= (MAX_EVENTS-1)*3*4 || DeviceType == MDEV_SNDSYS)
|
||||
{ // This message will never fit. Throw it away.
|
||||
track->TrackP += len;
|
||||
}
|
||||
|
|
|
@ -528,7 +528,7 @@ DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay, ptrdif
|
|||
if (event == MIDI_SYSEX || event == MIDI_SYSEXEND)
|
||||
{
|
||||
len = track->ReadVarLen();
|
||||
if (len >= (MAX_EVENTS-1)*3*4)
|
||||
if (len >= (MAX_EVENTS-1)*3*4 || DeviceType == MDEV_SNDSYS)
|
||||
{ // This message will never fit. Throw it away.
|
||||
track->EventP += len;
|
||||
}
|
||||
|
|
|
@ -140,6 +140,7 @@ DEFINE_CLASS_PROPERTY(respawns, 0, FakeInventory)
|
|||
// Reads an old style decoration object
|
||||
//
|
||||
//==========================================================================
|
||||
PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FName typeName);
|
||||
|
||||
void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
||||
{
|
||||
|
@ -154,7 +155,7 @@ void ParseOldDecoration(FScanner &sc, EDefinitionType def)
|
|||
|
||||
sc.MustGetString();
|
||||
typeName = FName(sc.String);
|
||||
type = static_cast<PClassActor *>(parent->CreateDerivedClass (typeName, parent->Size));
|
||||
type = DecoDerivedClass(FScriptPosition(sc), parent, typeName);
|
||||
ResetBaggage(&bag, parent);
|
||||
bag.Info = type;
|
||||
#ifdef _DEBUG
|
||||
|
|
|
@ -68,13 +68,44 @@
|
|||
|
||||
TDeletingArray<class FxExpression *> ActorDamageFuncs;
|
||||
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
void InitThingdef();
|
||||
void ParseDecorate (FScanner &sc);
|
||||
void ParseDecorate(FScanner &ctx);
|
||||
|
||||
// STATIC FUNCTION PROTOTYPES --------------------------------------------
|
||||
PClassActor *QuestItemClasses[31];
|
||||
|
||||
EXTERN_CVAR(Bool, strictdecorate);
|
||||
|
||||
PClassActor *DecoDerivedClass(const FScriptPosition &sc, PClassActor *parent, FName typeName)
|
||||
{
|
||||
PClassActor *type = static_cast<PClassActor *>(parent->CreateDerivedClass(typeName, parent->Size));
|
||||
if (type == nullptr)
|
||||
{
|
||||
FString newname = typeName.GetChars();
|
||||
FString sourcefile = sc.FileName;
|
||||
|
||||
sourcefile.Substitute(":", "@");
|
||||
newname << '@' << sourcefile;
|
||||
if (strictdecorate)
|
||||
{
|
||||
sc.Message(MSG_ERROR, "Tried to define class '%s' more than once.", typeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
// Due to backwards compatibility issues this cannot be an unconditional error.
|
||||
sc.Message(MSG_WARNING, "Tried to define class '%s' more than once. Renaming class to '%s'", typeName.GetChars(), newname.GetChars());
|
||||
}
|
||||
type = static_cast<PClassActor *>(parent->CreateDerivedClass(newname, parent->Size));
|
||||
if (type == nullptr)
|
||||
{
|
||||
// This we cannot handle cleanly anymore. Let's just abort and forget about the odd mod out that was this careless.
|
||||
sc.Message(MSG_FATAL, "Tried to define class '%s' more than twice in the same file.", typeName.GetChars());
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
//==========================================================================
|
||||
//
|
||||
// Starts a new actor definition
|
||||
|
@ -141,7 +172,7 @@ PClassActor *CreateNewActor(const FScriptPosition &sc, FName typeName, FName par
|
|||
else
|
||||
{
|
||||
create:
|
||||
ti = static_cast<PClassActor *>(parent->CreateDerivedClass (typeName, parent->Size));
|
||||
ti = DecoDerivedClass(sc, parent, typeName);
|
||||
}
|
||||
|
||||
ti->Replacee = ti->Replacement = NULL;
|
||||
|
@ -428,6 +459,16 @@ void LoadActors ()
|
|||
while ((lump = Wads.FindLump ("DECORATE", &lastlump)) != -1)
|
||||
{
|
||||
FScanner sc(lump);
|
||||
|
||||
if (Wads.GetLumpFile(lump) == 0)
|
||||
{
|
||||
// define namespace 'zdoom'
|
||||
}
|
||||
else
|
||||
{
|
||||
// use namespace 'zdoom'
|
||||
}
|
||||
|
||||
ParseDecorate (sc);
|
||||
}
|
||||
FinishThingdef();
|
||||
|
@ -439,32 +480,3 @@ void LoadActors ()
|
|||
if (!batchrun) Printf("DECORATE parsing took %.2f ms\n", timer.TimeMS());
|
||||
// Base time: ~52 ms
|
||||
}
|
||||
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CreateDamageFunction
|
||||
//
|
||||
// Creates a damage function suitable for a constant, non-expressioned
|
||||
// value.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
VMScriptFunction *CreateDamageFunction(int dmg)
|
||||
{
|
||||
if (dmg == 0)
|
||||
{
|
||||
// For zero damage, do not create a function so that the special collision detection case still works as before.
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
VMFunctionBuilder build;
|
||||
build.Registers[REGT_POINTER].Get(1); // The self pointer
|
||||
build.EmitRetInt(0, false, dmg);
|
||||
build.EmitRetInt(1, true, 0);
|
||||
VMScriptFunction *sfunc = build.MakeFunction();
|
||||
sfunc->NumArgs = 1;
|
||||
return sfunc;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -164,14 +164,6 @@ inline void ResetBaggage (Baggage *bag, PClassActor *stateclass)
|
|||
bag->statedef.MakeStateDefines(stateclass);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Damage function creation
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
VMScriptFunction *CreateDamageFunction(int dmg);
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Action function lookup
|
||||
|
|
|
@ -2622,6 +2622,92 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_GiveToSiblings)
|
|||
ACTION_RETURN_INT(count);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_SetInventory
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_SetInventory)
|
||||
{
|
||||
PARAM_ACTION_PROLOGUE;
|
||||
PARAM_CLASS(itemtype, AInventory);
|
||||
PARAM_INT(amount);
|
||||
PARAM_INT_OPT(ptr) { ptr = AAPTR_DEFAULT; }
|
||||
PARAM_BOOL_OPT(beyondMax) { beyondMax = false; }
|
||||
|
||||
bool res = false;
|
||||
|
||||
if (itemtype == nullptr)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
AActor *mobj = COPY_AAPTR(self, ptr);
|
||||
|
||||
if (mobj == nullptr)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
AInventory *item = mobj->FindInventory(itemtype);
|
||||
|
||||
if (item != nullptr)
|
||||
{
|
||||
// A_SetInventory sets the absolute amount.
|
||||
// Subtract or set the appropriate amount as necessary.
|
||||
|
||||
if (amount == item->Amount)
|
||||
{
|
||||
// Nothing was changed.
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
else if (amount <= 0)
|
||||
{
|
||||
//Remove it all.
|
||||
res = (mobj->TakeInventory(itemtype, item->Amount, true, false));
|
||||
ACTION_RETURN_BOOL(res);
|
||||
}
|
||||
else if (amount < item->Amount)
|
||||
{
|
||||
int amt = abs(item->Amount - amount);
|
||||
res = (mobj->TakeInventory(itemtype, amt, true, false));
|
||||
ACTION_RETURN_BOOL(res);
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Amount = (beyondMax ? amount : clamp(amount, 0, item->MaxAmount));
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (amount <= 0)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
item = static_cast<AInventory *>(Spawn(itemtype));
|
||||
if (item == nullptr)
|
||||
{
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
item->Amount = amount;
|
||||
item->flags |= MF_DROPPED;
|
||||
item->ItemFlags |= IF_IGNORESKILL;
|
||||
item->ClearCounters();
|
||||
if (!item->CallTryPickup(mobj))
|
||||
{
|
||||
item->Destroy();
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
}
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// A_TakeInventory
|
||||
|
|
|
@ -4956,6 +4956,25 @@ FxExpression *FxRuntimeStateIndex::Resolve(FCompileContext &ctx)
|
|||
return this;
|
||||
}
|
||||
|
||||
static bool VerifyJumpTarget(AActor *stateowner, FStateParamInfo *stateinfo, int index)
|
||||
{
|
||||
PClassActor *cls = stateowner->GetClass();
|
||||
|
||||
while (cls != RUNTIME_CLASS(AActor))
|
||||
{
|
||||
// both calling and target state need to belong to the same class.
|
||||
if (cls->OwnsState(stateinfo->mCallingState))
|
||||
{
|
||||
return cls->OwnsState(stateinfo->mCallingState + index);
|
||||
}
|
||||
|
||||
// We can safely assume the ParentClass is of type PClassActor
|
||||
// since we stop when we see the Actor base class.
|
||||
cls = static_cast<PClassActor *>(cls->ParentClass);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, int numparam, VMReturn *ret, int numret)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
@ -4963,7 +4982,7 @@ static int DecoHandleRuntimeState(VMFrameStack *stack, VMValue *param, int numpa
|
|||
PARAM_POINTER(stateinfo, FStateParamInfo);
|
||||
PARAM_INT(index);
|
||||
|
||||
if (index == 0 || !stateowner->GetClass()->OwnsState(stateinfo->mCallingState + index))
|
||||
if (index == 0 || !VerifyJumpTarget(stateowner, stateinfo, index))
|
||||
{
|
||||
// Null is returned if the location was invalid which means that no jump will be performed
|
||||
// if used as return value
|
||||
|
|
|
@ -1435,7 +1435,7 @@ DEFINE_PROPERTY(spriterotation, F, Actor)
|
|||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(visibleangles, Ff, Actor)
|
||||
DEFINE_PROPERTY(visibleangles, FF, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(visstart, 0);
|
||||
PROP_DOUBLE_PARM(visend, 1);
|
||||
|
@ -1446,7 +1446,7 @@ DEFINE_PROPERTY(visibleangles, Ff, Actor)
|
|||
//==========================================================================
|
||||
//
|
||||
//==========================================================================
|
||||
DEFINE_PROPERTY(visiblepitch, Ff, Actor)
|
||||
DEFINE_PROPERTY(visiblepitch, FF, Actor)
|
||||
{
|
||||
PROP_DOUBLE_PARM(visstart, 0);
|
||||
PROP_DOUBLE_PARM(visend, 1);
|
||||
|
|
|
@ -52,7 +52,8 @@
|
|||
#include "v_palette.h"
|
||||
#include "d_player.h"
|
||||
|
||||
|
||||
CVAR( Float, blood_fade_scalar, 1.0f, CVAR_ARCHIVE ) // [SP] Pulled from Skulltag - changed default from 0.5 to 1.0
|
||||
CVAR( Float, pickup_fade_scalar, 1.0f, CVAR_ARCHIVE ) // [SP] Uses same logic as blood_fade_scalar except for pickups
|
||||
|
||||
// [RH] Amount of red flash for up to 114 damage points. Calculated by hand
|
||||
// using a logarithmic scale and my trusty HP48G.
|
||||
|
@ -113,6 +114,9 @@ void V_AddPlayerBlend (player_t *CPlayer, float blend[4], float maxinvalpha, int
|
|||
if (CPlayer->bonuscount)
|
||||
{
|
||||
cnt = CPlayer->bonuscount << 3;
|
||||
|
||||
// [SP] Allow player to tone down intensity of pickup flash.
|
||||
cnt = (int)( cnt * pickup_fade_scalar );
|
||||
|
||||
V_AddBlend (RPART(gameinfo.pickupcolor)/255.f, GPART(gameinfo.pickupcolor)/255.f,
|
||||
BPART(gameinfo.pickupcolor)/255.f, cnt > 128 ? 0.5f : cnt / 255.f, blend);
|
||||
|
@ -124,7 +128,10 @@ void V_AddPlayerBlend (player_t *CPlayer, float blend[4], float maxinvalpha, int
|
|||
if (painFlash.a != 0)
|
||||
{
|
||||
cnt = DamageToAlpha[MIN (113, CPlayer->damagecount * painFlash.a / 255)];
|
||||
|
||||
|
||||
// [BC] Allow users to tone down the intensity of the blood on the screen.
|
||||
cnt = (int)( cnt * blood_fade_scalar );
|
||||
|
||||
if (cnt)
|
||||
{
|
||||
if (cnt > maxpainblend)
|
||||
|
|
|
@ -162,11 +162,11 @@ ZCC_OpProto *ZCC_OpInfoType::FindBestProto(
|
|||
// [[float32 (op) int]] will choose the integer version instead of the floating point
|
||||
// version, which we do not want.
|
||||
int test_dist1 = dist1, test_dist2 = dist2;
|
||||
if (routes[0][cur_route1][0]->ConvertConstant == FtoD)
|
||||
if (test_dist1 > 0 && routes[0][cur_route1][0]->ConvertConstant == FtoD)
|
||||
{
|
||||
test_dist1--;
|
||||
}
|
||||
if (routes[1][cur_route2][0]->ConvertConstant == FtoD)
|
||||
if (test_dist2 > 0 && routes[1][cur_route2][0]->ConvertConstant == FtoD)
|
||||
{
|
||||
test_dist2--;
|
||||
}
|
||||
|
|
|
@ -58,6 +58,8 @@ ACTOR Actor native //: Thinker
|
|||
native float GetSpriteRotation(int ptr = AAPTR_DEFAULT);
|
||||
native int GetMissileDamage(int mask, int add, int ptr = AAPTR_DEFAULT);
|
||||
action native int OverlayID();
|
||||
action native float OverlayX(int layer = 0);
|
||||
action native float OverlayY(int layer = 0);
|
||||
|
||||
// Action functions
|
||||
// Meh, MBF redundant functions. Only for DeHackEd support.
|
||||
|
@ -209,6 +211,7 @@ ACTOR Actor native //: Thinker
|
|||
native state A_JumpIfTargetInsideMeleeRange(state label);
|
||||
native state A_JumpIfInventory(class<Inventory> itemtype, int itemamount, state label, int owner = AAPTR_DEFAULT);
|
||||
native state A_JumpIfArmorType(name Type, state label, int amount = 1);
|
||||
action native bool A_SetInventory(class<Inventory> itemtype, int amount, int ptr = AAPTR_DEFAULT, bool beyondMax = false);
|
||||
native bool A_GiveInventory(class<Inventory> itemtype, int amount = 0, int giveto = AAPTR_DEFAULT);
|
||||
native bool A_TakeInventory(class<Inventory> itemtype, int amount = 0, int flags = 0, int giveto = AAPTR_DEFAULT);
|
||||
action native bool A_SpawnItem(class<Actor> itemtype = "Unknown", float distance = 0, float zheight = 0, bool useammo = true, bool transfer_translation = false);
|
||||
|
|
|
@ -598,6 +598,7 @@ enum
|
|||
PSPF_ADDBOB = 1 << 1,
|
||||
PSPF_POWDOUBLE = 1 << 2,
|
||||
PSPF_CVARFAST = 1 << 3,
|
||||
PSPF_FLIP = 1 << 6,
|
||||
};
|
||||
|
||||
// Default psprite layers
|
||||
|
|
|
@ -75,12 +75,14 @@ ACTOR PointPusher
|
|||
{
|
||||
+NOBLOCKMAP
|
||||
+INVISIBLE
|
||||
+NOCLIP
|
||||
}
|
||||
|
||||
ACTOR PointPuller
|
||||
{
|
||||
+NOBLOCKMAP
|
||||
+INVISIBLE
|
||||
+NOCLIP
|
||||
}
|
||||
|
||||
// Bloody gibs -------------------------------------------------------------
|
||||
|
|
|
@ -1782,6 +1782,8 @@ DSPLYMNU_CAPFPS = "Rendering Interpolation";
|
|||
DSPLYMNU_COLUMNMETHOD = "Column render mode";
|
||||
DSPLYMNU_WIPETYPE = "Screen wipe style";
|
||||
DSPLYMNU_SHOWENDOOM = "Show ENDOOM screen";
|
||||
DSPLYMNU_BLOODFADE = "Blood Flash Intensity";
|
||||
DSPLYMNU_PICKUPFADE = "Pickup Flash Intensity";
|
||||
DSPLYMNU_PALLETEHACK = "DirectDraw palette hack"; // Not used
|
||||
DSPLYMNU_ATTACHEDSURFACES = "Use attached surfaces"; // Not used
|
||||
DSPLYMNU_STRETCHSKY = "Stretch short skies";
|
||||
|
@ -2706,6 +2708,8 @@ OPTVAL_SBSFULL = "Side-by-side Full";
|
|||
OPTVAL_SBSNARROW = "Side-by-side Narrow";
|
||||
OPTVAL_TOPBOTTOM = "Top/Bottom";
|
||||
OPTVAL_ROWINTERLEAVED = "Row Interleaved";
|
||||
OPTVAL_COLUMNINTERLEAVED = "Column Interleaved";
|
||||
OPTVAL_CHECKERBOARD = "Checkerboard";
|
||||
OPTVAL_QUADBUFFERED = "Quad-buffered";
|
||||
OPTVAL_UNCHARTED2 = "Uncharted 2";
|
||||
OPTVAL_HEJLDAWSON = "Hejl Dawson";
|
||||
|
|
|
@ -674,6 +674,9 @@ OptionMenu "VideoOptions"
|
|||
|
||||
Option "$DSPLYMNU_VSYNC", "vid_vsync", "OnOff"
|
||||
Option "$DSPLYMNU_CAPFPS", "cl_capfps", "OffOn"
|
||||
Slider "$DSPLYMNU_BLOODFADE", "blood_fade_scalar", 0.0, 1.0, 0.05, 1
|
||||
Slider "$DSPLYMNU_PICKUPFADE", "pickup_fade_scalar", 0.0, 1.0, 0.05, 1
|
||||
Option "$DSPLYMNU_COLUMNMETHOD", "r_columnmethod", "ColumnMethods"
|
||||
|
||||
StaticText " "
|
||||
Option "$DSPLYMNU_WIPETYPE", "wipetype", "Wipes"
|
||||
|
@ -704,6 +707,7 @@ OptionMenu "VideoOptions"
|
|||
Slider "$DSPLYMNU_MOVEBOB", "movebob", 0, 1.0, 0.05, 2
|
||||
Slider "$DSPLYMNU_STILLBOB", "stillbob", 0, 1.0, 0.05, 2
|
||||
Slider "$DSPLYMNU_BOBSPEED", "wbobspeed", 0, 2.0, 0.1, 2
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -180,6 +180,8 @@ OptionValue VRMode
|
|||
4, "$OPTVAL_SBSNARROW"
|
||||
11, "$OPTVAL_TOPBOTTOM"
|
||||
12, "$OPTVAL_ROWINTERLEAVED"
|
||||
13, "$OPTVAL_COLUMNINTERLEAVED"
|
||||
14, "$OPTVAL_CHECKERBOARD"
|
||||
5, "$OPTVAL_LEFTEYE"
|
||||
6, "$OPTVAL_RIGHTEYE"
|
||||
7, "$OPTVAL_QUADBUFFERED"
|
||||
|
|
37
wadsrc/static/shaders/glsl/present_checker3d.fp
Normal file
37
wadsrc/static/shaders/glsl/present_checker3d.fp
Normal file
|
@ -0,0 +1,37 @@
|
|||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D LeftEyeTexture;
|
||||
uniform sampler2D RightEyeTexture;
|
||||
uniform float InvGamma;
|
||||
uniform float Contrast;
|
||||
uniform float Brightness;
|
||||
uniform int WindowPositionParity; // top-of-window might not be top-of-screen
|
||||
|
||||
vec4 ApplyGamma(vec4 c)
|
||||
{
|
||||
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
|
||||
val += Brightness * 0.5;
|
||||
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
|
||||
return vec4(val, c.a);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int thisVerticalPixel = int(gl_FragCoord.y); // Bottom row is typically the right eye, when WindowHeight is even
|
||||
int thisHorizontalPixel = int(gl_FragCoord.x); // column
|
||||
bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row
|
||||
+ thisHorizontalPixel // and each column
|
||||
+ WindowPositionParity // because the window might not be aligned to the screen
|
||||
) % 2 == 0;
|
||||
vec4 inputColor;
|
||||
if (isLeftEye) {
|
||||
inputColor = texture(LeftEyeTexture, TexCoord);
|
||||
}
|
||||
else {
|
||||
// inputColor = vec4(0, 1, 0, 1);
|
||||
inputColor = texture(RightEyeTexture, TexCoord);
|
||||
}
|
||||
FragColor = ApplyGamma(inputColor);
|
||||
}
|
35
wadsrc/static/shaders/glsl/present_column3d.fp
Normal file
35
wadsrc/static/shaders/glsl/present_column3d.fp
Normal file
|
@ -0,0 +1,35 @@
|
|||
|
||||
in vec2 TexCoord;
|
||||
out vec4 FragColor;
|
||||
|
||||
uniform sampler2D LeftEyeTexture;
|
||||
uniform sampler2D RightEyeTexture;
|
||||
uniform float InvGamma;
|
||||
uniform float Contrast;
|
||||
uniform float Brightness;
|
||||
uniform int WindowPositionParity; // top-of-window might not be top-of-screen
|
||||
|
||||
vec4 ApplyGamma(vec4 c)
|
||||
{
|
||||
vec3 val = c.rgb * Contrast - (Contrast - 1.0) * 0.5;
|
||||
val += Brightness * 0.5;
|
||||
val = pow(max(val, vec3(0.0)), vec3(InvGamma));
|
||||
return vec4(val, c.a);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int thisHorizontalPixel = int(gl_FragCoord.x); // zero-based column index from left
|
||||
bool isLeftEye = (thisHorizontalPixel // because we want to alternate eye view on each column
|
||||
+ WindowPositionParity // because the window might not be aligned to the screen
|
||||
) % 2 == 0;
|
||||
vec4 inputColor;
|
||||
if (isLeftEye) {
|
||||
inputColor = texture(LeftEyeTexture, TexCoord);
|
||||
}
|
||||
else {
|
||||
// inputColor = vec4(0, 1, 0, 1);
|
||||
inputColor = texture(RightEyeTexture, TexCoord);
|
||||
}
|
||||
FragColor = ApplyGamma(inputColor);
|
||||
}
|
|
@ -7,7 +7,7 @@ uniform sampler2D RightEyeTexture;
|
|||
uniform float InvGamma;
|
||||
uniform float Contrast;
|
||||
uniform float Brightness;
|
||||
uniform int VerticalPixelOffset; // top-of-window might not be top-of-screen
|
||||
uniform int WindowPositionParity; // top-of-window might not be top-of-screen
|
||||
|
||||
vec4 ApplyGamma(vec4 c)
|
||||
{
|
||||
|
@ -19,9 +19,9 @@ vec4 ApplyGamma(vec4 c)
|
|||
|
||||
void main()
|
||||
{
|
||||
int thisVerticalPixel = int(gl_FragCoord.y + 1.0); // Bottom row is typically the right eye, when WindowHeight is even
|
||||
int thisVerticalPixel = int(gl_FragCoord.y); // Bottom row is typically the right eye, when WindowHeight is even
|
||||
bool isLeftEye = (thisVerticalPixel // because we want to alternate eye view on each row
|
||||
+ VerticalPixelOffset // because the window might not be aligned to the screen
|
||||
+ WindowPositionParity // because the window might not be aligned to the screen
|
||||
) % 2 == 0;
|
||||
vec4 inputColor;
|
||||
if (isLeftEye) {
|
||||
|
|
Loading…
Reference in a new issue