From 6dc1bb8475c5db6f629d4a6b60b2f6d95c3612dd Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sat, 14 Jan 2017 18:04:49 +0100 Subject: [PATCH] - skriptified the skybox actors. - fixed code generation for internal pointed arrays, they were missing a pointer dereference. --- src/CMakeLists.txt | 1 - src/g_shared/a_skies.cpp | 153 ----------------------- src/portal.cpp | 6 + src/scripting/codegeneration/codegen.cpp | 43 ++++--- src/scripting/codegeneration/codegen.h | 2 +- wadsrc/static/zscript/mapdata.txt | 20 ++- wadsrc/static/zscript/shared/skies.txt | 134 +++++++++++++++++++- 7 files changed, 182 insertions(+), 177 deletions(-) delete mode 100644 src/g_shared/a_skies.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 03fbfa73f..014c405b8 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1163,7 +1163,6 @@ set (PCH_SOURCES g_shared/a_lightning.cpp g_shared/a_morph.cpp g_shared/a_quake.cpp - g_shared/a_skies.cpp g_shared/a_specialspot.cpp g_shared/hudmessages.cpp g_shared/sbarinfo.cpp diff --git a/src/g_shared/a_skies.cpp b/src/g_shared/a_skies.cpp deleted file mode 100644 index 234597554..000000000 --- a/src/g_shared/a_skies.cpp +++ /dev/null @@ -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 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 (); -} - diff --git a/src/portal.cpp b/src/portal.cpp index fc5b555c4..43b7ef7b6 100644 --- a/src/portal.cpp +++ b/src/portal.cpp @@ -676,6 +676,12 @@ unsigned P_GetSkyboxPortal(AActor *actor) return i; } +DEFINE_ACTION_FUNCTION(FSectorPortal, GetSkyboxPortal) +{ + PARAM_PROLOGUE; + PARAM_OBJECT(actor, AActor); + ACTION_RETURN_INT(P_GetSkyboxPortal(actor)); +} //============================================================================ // // P_GetPortal diff --git a/src/scripting/codegeneration/codegen.cpp b/src/scripting/codegeneration/codegen.cpp index 2c4d1422a..61d86db80 100644 --- a/src/scripting/codegeneration/codegen.cpp +++ b/src/scripting/codegeneration/codegen.cpp @@ -1620,6 +1620,17 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx) if (fromtype->IsDescendantOf(totype)) goto basereturn; } } + else if (basex->ValueType->IsA(RUNTIME_CLASS(PNativeStruct)) && ValueType->IsKindOf(RUNTIME_CLASS(PPointer)) && static_cast(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)) { goto basereturn; @@ -6747,12 +6758,12 @@ FxExpression *FxArrayElement::Resolve(FCompileContext &ctx) if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) { auto parentfield = static_cast(Array)->membervar; - SizeAddr = unsigned(parentfield->Offset + parentfield->Type->Align); + SizeAddr = parentfield->Offset + parentfield->Type->Align; } else if (Array->ExprType == EFX_GlobalVariable) { auto parentfield = static_cast(Array)->membervar; - SizeAddr = unsigned(parentfield->Offset + parentfield->Type->Align); + SizeAddr = parentfield->Offset + parentfield->Type->Align; } else { @@ -6836,12 +6847,16 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) { arraytype = static_cast(Array->ValueType); } - ExpEmit start = Array->Emit(build); + ExpEmit arrayvar = Array->Emit(build); + ExpEmit start; ExpEmit bound; - // For resizable arrays we even need to check the bounds if if the index is constant. 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); if (Array->ExprType == EFX_ClassMember || Array->ExprType == EFX_StructMember) { @@ -6857,12 +6872,14 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) Array->ValueType = TypeUInt32; bound = Array->Emit(build); } + else start = arrayvar; if (index->isConstant()) { unsigned indexval = static_cast(index)->GetValue().GetInt(); 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) { ExpEmit indexreg(build, REGT_INT); @@ -6948,19 +6965,11 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build) if (AddressRequested) { - if (!start.Fixed) - { - build->Emit(OP_ADDA_RR, start.RegNum, start.RegNum, indexwork.RegNum); - } - else - { - 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; + start.Free(build); + // do not clobber local variables. + ExpEmit temp(build, start.RegType); + build->Emit(OP_ADDA_RR, temp.RegNum, start.RegNum, indexwork.RegNum); + return temp; } else { diff --git a/src/scripting/codegeneration/codegen.h b/src/scripting/codegeneration/codegen.h index 7e72176e7..0a1039926 100644 --- a/src/scripting/codegeneration/codegen.h +++ b/src/scripting/codegeneration/codegen.h @@ -1438,7 +1438,7 @@ class FxArrayElement : public FxExpression public: FxExpression *Array; FxExpression *index; - unsigned SizeAddr; + size_t SizeAddr; bool AddressRequested; bool AddressWritable; bool arrayispointer = false; diff --git a/wadsrc/static/zscript/mapdata.txt b/wadsrc/static/zscript/mapdata.txt index 148e2c1d5..b7589f8d4 100644 --- a/wadsrc/static/zscript/mapdata.txt +++ b/wadsrc/static/zscript/mapdata.txt @@ -1,6 +1,22 @@ 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 mFlags; native uint mPartner; @@ -10,6 +26,8 @@ struct SectorPortal native native Vector2 mDisplacement; native double mPlaneZ; native Actor mSkybox; + + native static uint GetSkyboxPortal(Actor actor); }; @@ -264,7 +282,7 @@ struct Sector native native SectorAction SecActTarget; - native readonly uint Portals[2]; + native uint Portals[2]; native readonly int PortalGroup; native readonly int sectornum; diff --git a/wadsrc/static/zscript/shared/skies.txt b/wadsrc/static/zscript/shared/skies.txt index 72b86b14f..c817a3994 100644 --- a/wadsrc/static/zscript/shared/skies.txt +++ b/wadsrc/static/zscript/shared/skies.txt @@ -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 { @@ -7,9 +43,52 @@ class SkyViewpoint : Actor native +NOGRAVITY +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 { @@ -18,14 +97,61 @@ class SkyPicker : Actor native +NOGRAVITY +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