- skriptified the skybox actors.

- fixed code generation for internal pointed arrays, they were missing a pointer dereference.
This commit is contained in:
Christoph Oelckers 2017-01-14 18:04:49 +01:00
parent a9ef73528d
commit 6dc1bb8475
7 changed files with 182 additions and 177 deletions

View file

@ -1163,7 +1163,6 @@ set (PCH_SOURCES
g_shared/a_lightning.cpp g_shared/a_lightning.cpp
g_shared/a_morph.cpp g_shared/a_morph.cpp
g_shared/a_quake.cpp g_shared/a_quake.cpp
g_shared/a_skies.cpp
g_shared/a_specialspot.cpp g_shared/a_specialspot.cpp
g_shared/hudmessages.cpp g_shared/hudmessages.cpp
g_shared/sbarinfo.cpp g_shared/sbarinfo.cpp

View file

@ -1,153 +0,0 @@
/*
** a_skies.cpp
** Skybox-related actors
**
**---------------------------------------------------------------------------
** Copyright 1998-2006 Randy Heit
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
#include "actor.h"
#include "a_sharedglobal.h"
#include "p_local.h"
#include "p_lnspec.h"
#include "r_sky.h"
#include "r_state.h"
#include "portal.h"
#include "g_levellocals.h"
// arg0 = Visibility*4 for this skybox
IMPLEMENT_CLASS(ASkyViewpoint, false, false)
// If this actor has no TID, make it the default sky box
void ASkyViewpoint::BeginPlay ()
{
Super::BeginPlay ();
if (tid == 0 && level.sectorPortals[0].mSkybox == nullptr)
{
level.sectorPortals[0].mSkybox = this;
level.sectorPortals[0].mDestination = Sector;
}
}
void ASkyViewpoint::OnDestroy ()
{
// remove all sector references to ourselves.
for (auto &s : level.sectorPortals)
{
if (s.mSkybox == this)
{
s.mSkybox = 0;
// This is necessary to entirely disable EE-style skyboxes
// if their viewpoint gets deleted.
s.mFlags |= PORTSF_SKYFLATONLY;
}
}
Super::OnDestroy();
}
IMPLEMENT_CLASS(ASkyCamCompat, false, false)
void ASkyCamCompat::BeginPlay()
{
// Do not call the SkyViewpoint's super method because it would trash our setup
AActor::BeginPlay();
}
//---------------------------------------------------------------------------
// arg0 = tid of matching SkyViewpoint
// A value of 0 means to use a regular stretched texture, in case
// there is a default SkyViewpoint in the level.
//
// arg1 = 0: set both floor and ceiling skybox
// = 1: set only ceiling skybox
// = 2: set only floor skybox
class ASkyPicker : public AActor
{
DECLARE_CLASS (ASkyPicker, AActor)
public:
void PostBeginPlay ();
};
IMPLEMENT_CLASS(ASkyPicker, false, false)
void ASkyPicker::PostBeginPlay ()
{
ASkyViewpoint *box;
Super::PostBeginPlay ();
if (args[0] == 0)
{
box = NULL;
}
else
{
TActorIterator<ASkyViewpoint> iterator (args[0]);
box = iterator.Next ();
}
if (box == NULL && args[0] != 0)
{
Printf ("Can't find SkyViewpoint %d for sector %d\n", args[0], Sector->sectornum);
}
else
{
int boxindex = P_GetSkyboxPortal(box);
// Do not override special portal types, only regular skies.
if (0 == (args[1] & 2))
{
if (Sector->GetPortalType(sector_t::ceiling) == PORTS_SKYVIEWPOINT)
Sector->Portals[sector_t::ceiling] = boxindex;
}
if (0 == (args[1] & 1))
{
if (Sector->GetPortalType(sector_t::floor) == PORTS_SKYVIEWPOINT)
Sector->Portals[sector_t::floor] = boxindex;
}
}
Destroy ();
}
//---------------------------------------------------------------------------
// Stacked sectors.
// arg0 = opacity of plane; 0 = invisible, 255 = fully opaque
IMPLEMENT_CLASS(AStackPoint, false, false)
void AStackPoint::BeginPlay ()
{
// Skip SkyViewpoint's initialization
AActor::BeginPlay ();
}

View file

@ -676,6 +676,12 @@ unsigned P_GetSkyboxPortal(AActor *actor)
return i; return i;
} }
DEFINE_ACTION_FUNCTION(FSectorPortal, GetSkyboxPortal)
{
PARAM_PROLOGUE;
PARAM_OBJECT(actor, AActor);
ACTION_RETURN_INT(P_GetSkyboxPortal(actor));
}
//============================================================================ //============================================================================
// //
// P_GetPortal // P_GetPortal

View file

@ -1620,6 +1620,17 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
if (fromtype->IsDescendantOf(totype)) goto basereturn; if (fromtype->IsDescendantOf(totype)) goto basereturn;
} }
} }
else if (basex->ValueType->IsA(RUNTIME_CLASS(PNativeStruct)) && ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast<PPointer*>(ValueType)->PointedType == basex->ValueType)
{
bool writable;
basex->RequestAddress(ctx, &writable);
basex->ValueType = ValueType;
auto x = basex;
basex = nullptr;
delete this;
return x;
}
else if (AreCompatiblePointerTypes(ValueType, basex->ValueType)) else if (AreCompatiblePointerTypes(ValueType, basex->ValueType))
{ {
goto basereturn; goto basereturn;
@ -6747,12 +6758,12 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx)
if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember)
{ {
auto parentfield = static_cast<FxStructMember *>(Array)->membervar; auto parentfield = static_cast<FxStructMember *>(Array)->membervar;
SizeAddr = unsigned(parentfield->Offset + parentfield->Type->Align); SizeAddr = parentfield->Offset + parentfield->Type->Align;
} }
else if (Array->ExprType == EFX_GlobalVariable) else if (Array->ExprType == EFX_GlobalVariable)
{ {
auto parentfield = static_cast<FxGlobalVariable *>(Array)->membervar; auto parentfield = static_cast<FxGlobalVariable *>(Array)->membervar;
SizeAddr = unsigned(parentfield->Offset + parentfield->Type->Align); SizeAddr = parentfield->Offset + parentfield->Type->Align;
} }
else else
{ {
@ -6836,12 +6847,16 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
{ {
arraytype = static_cast<PArray*>(Array->ValueType); arraytype = static_cast<PArray*>(Array->ValueType);
} }
ExpEmit start = Array->Emit(build); ExpEmit arrayvar = Array->Emit(build);
ExpEmit start;
ExpEmit bound; ExpEmit bound;
// For resizable arrays we even need to check the bounds if if the index is constant.
if (SizeAddr != ~0u) if (SizeAddr != ~0u)
{ {
arrayvar.Free(build);
start = ExpEmit(build, REGT_POINTER);
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
auto f = new PField(NAME_None, TypeUInt32, 0, SizeAddr); auto f = new PField(NAME_None, TypeUInt32, 0, SizeAddr);
if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember)
{ {
@ -6857,12 +6872,14 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
Array->ValueType = TypeUInt32; Array->ValueType = TypeUInt32;
bound = Array->Emit(build); bound = Array->Emit(build);
} }
else start = arrayvar;
if (index->isConstant()) if (index->isConstant())
{ {
unsigned indexval = static_cast<FxConstant *>(index)->GetValue().GetInt(); unsigned indexval = static_cast<FxConstant *>(index)->GetValue().GetInt();
assert(SizeAddr != ~0u || (indexval < arraytype->ElementCount && "Array index out of bounds")); assert(SizeAddr != ~0u || (indexval < arraytype->ElementCount && "Array index out of bounds"));
// For resizable arrays we even need to check the bounds if if the index is constant because they are not known at compile time.
if (SizeAddr != ~0u) if (SizeAddr != ~0u)
{ {
ExpEmit indexreg(build, REGT_INT); ExpEmit indexreg(build, REGT_INT);
@ -6948,19 +6965,11 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
if (AddressRequested) if (AddressRequested)
{ {
if (!start.Fixed) start.Free(build);
{ // do not clobber local variables.
build->Emit(OP_ADDA_RR, start.RegNum, start.RegNum, indexwork.RegNum); ExpEmit temp(build, start.RegType);
} build->Emit(OP_ADDA_RR, temp.RegNum, start.RegNum, indexwork.RegNum);
else return temp;
{
start.Free(build);
// do not clobber local variables.
ExpEmit temp(build, start.RegType);
build->Emit(OP_ADDA_RR, temp.RegNum, start.RegNum, indexwork.RegNum);
start = temp;
}
return start;
} }
else else
{ {

View file

@ -1438,7 +1438,7 @@ class FxArrayElement : public FxExpression
public: public:
FxExpression *Array; FxExpression *Array;
FxExpression *index; FxExpression *index;
unsigned SizeAddr; size_t SizeAddr;
bool AddressRequested; bool AddressRequested;
bool AddressWritable; bool AddressWritable;
bool arrayispointer = false; bool arrayispointer = false;

View file

@ -1,6 +1,22 @@
struct SectorPortal native struct SectorPortal native
{ {
enum EType
{
TYPE_SKYVIEWPOINT = 0, // a regular skybox
TYPE_STACKEDSECTORTHING, // stacked sectors with the thing method
TYPE_PORTAL, // stacked sectors with Sector_SetPortal
TYPE_LINKEDPORTAL, // linked portal (interactive)
TYPE_PLANE, // EE-style plane portal (not implemented in SW renderer)
TYPE_HORIZON, // EE-style horizon portal (not implemented in SW renderer)
};
enum EFlags
{
FLAG_SKYFLATONLY = 1, // portal is only active on skyflatnum
FLAG_INSKYBOX = 2, // to avoid recursion
};
native int mType; native int mType;
native int mFlags; native int mFlags;
native uint mPartner; native uint mPartner;
@ -10,6 +26,8 @@ struct SectorPortal native
native Vector2 mDisplacement; native Vector2 mDisplacement;
native double mPlaneZ; native double mPlaneZ;
native Actor mSkybox; native Actor mSkybox;
native static uint GetSkyboxPortal(Actor actor);
}; };
@ -264,7 +282,7 @@ struct Sector native
native SectorAction SecActTarget; native SectorAction SecActTarget;
native readonly uint Portals[2]; native uint Portals[2];
native readonly int PortalGroup; native readonly int PortalGroup;
native readonly int sectornum; native readonly int sectornum;

View file

@ -1,4 +1,40 @@
class SkyViewpoint : Actor native
/*
** a_skies.cpp
** Skybox-related actors
**
**---------------------------------------------------------------------------
** Copyright 1998-2016 Randy Heit
** Copyright 2006-2017 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, self list of conditions and the following disclaimer.
** 2. Redistributions in binary form must reproduce the above copyright
** notice, self list of conditions and the following disclaimer in the
** documentation and/or other materials provided with the distribution.
** 3. The name of the author may not be used to endorse or promote products
** derived from self software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**---------------------------------------------------------------------------
**
*/
class SkyViewpoint : Actor
{ {
default default
{ {
@ -7,9 +43,52 @@ class SkyViewpoint : Actor native
+NOGRAVITY +NOGRAVITY
+DONTSPLASH +DONTSPLASH
} }
// arg0 = Visibility*4 for self skybox
// If self actor has no TID, make it the default sky box
override void BeginPlay ()
{
Super.BeginPlay ();
if (tid == 0 && level.sectorPortals[0].mSkybox == null)
{
level.sectorPortals[0].mSkybox = self;
level.sectorPortals[0].mDestination = CurSector;
}
}
override void OnDestroy ()
{
// remove all sector references to ourselves.
for (int i = 0; i < level.sectorPortals.Size(); i++)
{
SectorPortal s = level.sectorPortals[i];
if (s.mSkybox == self)
{
s.mSkybox = null;
// This is necessary to entirely disable EE-style skyboxes
// if their viewpoint gets deleted.
s.mFlags |= SectorPortal.FLAG_SKYFLATONLY;
}
}
Super.OnDestroy();
}
} }
class SkyPicker : Actor native //---------------------------------------------------------------------------
// arg0 = tid of matching SkyViewpoint
// A value of 0 means to use a regular stretched texture, in case
// there is a default SkyViewpoint in the level.
//
// arg1 = 0: set both floor and ceiling skybox
// = 1: set only ceiling skybox
// = 2: set only floor skybox
class SkyPicker : Actor
{ {
default default
{ {
@ -18,14 +97,61 @@ class SkyPicker : Actor native
+NOGRAVITY +NOGRAVITY
+DONTSPLASH +DONTSPLASH
} }
override void PostBeginPlay ()
{
Actor box;
Super.PostBeginPlay ();
if (args[0] == 0)
{
box = null;
}
else
{
let it = ActorIterator.Create(args[0], "SkyViewpoint");
box = it.Next ();
}
if (box == null && args[0] != 0)
{
A_Log(format("Can't find SkyViewpoint %d for sector %d\n", args[0], CurSector.Index()));
}
else
{
int boxindex = SectorPortal.GetSkyboxPortal(box);
// Do not override special portal types, only regular skies.
if (0 == (args[1] & 2))
{
if (CurSector.GetPortalType(sector.ceiling) == SectorPortal.TYPE_SKYVIEWPOINT)
CurSector.Portals[sector.ceiling] = boxindex;
}
if (0 == (args[1] & 1))
{
if (CurSector.GetPortalType(sector.floor) == SectorPortal.TYPE_SKYVIEWPOINT)
CurSector.Portals[sector.floor] = boxindex;
}
}
Destroy ();
}
} }
class SkyCamCompat : SkyViewpoint native class SkyCamCompat : SkyViewpoint
{ {
override void BeginPlay ()
{
// Skip SkyViewpoint's initialization, Actor's is not needed here.
}
} }
class StackPoint : SkyViewpoint native class StackPoint : SkyViewpoint
{ {
override void BeginPlay ()
{
// Skip SkyViewpoint's initialization, Actor's is not needed here.
}
} }
class UpperStackLookOnly : StackPoint class UpperStackLookOnly : StackPoint