mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-11 07:12:02 +00:00
This commit is contained in:
commit
7040bc2156
33 changed files with 294 additions and 406 deletions
|
@ -671,7 +671,7 @@ static int CreateSpawnFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
|||
I_Error("No class found for dehackednum %d!\n", value1+1);
|
||||
return 0;
|
||||
}
|
||||
int typereg = buildit.GetConstantAddress(InfoNames[value1-1], ATAG_OBJECT);
|
||||
int typereg = buildit.GetConstantAddress(InfoNames[value1-1]);
|
||||
int heightreg = buildit.GetConstantFloat(value2);
|
||||
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, typereg); // itemtype
|
||||
|
@ -724,7 +724,7 @@ static int CreatePlaySoundFunc(VMFunctionBuilder &buildit, int value1, int value
|
|||
// misc1 = state, misc2 = probability
|
||||
static int CreateRandomJumpFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||
{ // A_Jump
|
||||
int statereg = buildit.GetConstantAddress(FindState(value1), ATAG_STATE);
|
||||
int statereg = buildit.GetConstantAddress(FindState(value1));
|
||||
|
||||
buildit.EmitParamInt(value2); // maxchance
|
||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, statereg); // jumpto
|
||||
|
@ -813,7 +813,7 @@ void SetDehParams(FState *state, int codepointer)
|
|||
}
|
||||
// Emit code for action parameters.
|
||||
int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2);
|
||||
buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation, ATAG_OBJECT), numargs + argcount, 0);
|
||||
buildit.Emit(OP_TAIL_K, buildit.GetConstantAddress(sym->Variants[0].Implementation), numargs + argcount, 0);
|
||||
// Attach it to the state.
|
||||
VMScriptFunction *sfunc = new VMScriptFunction;
|
||||
buildit.MakeFunction(sfunc);
|
||||
|
|
|
@ -200,6 +200,14 @@ protected:
|
|||
enum { MetaClassNum = CLASSREG_PClass };
|
||||
|
||||
// Per-instance variables. There are four.
|
||||
#ifdef _DEBUG
|
||||
public:
|
||||
enum
|
||||
{
|
||||
MAGIC_ID = 0x1337cafe
|
||||
};
|
||||
uint32_t MagicID = MAGIC_ID; // only used by the VM for checking native function parameter types.
|
||||
#endif
|
||||
private:
|
||||
PClass *Class; // This object's type
|
||||
public:
|
||||
|
|
|
@ -780,6 +780,15 @@ PFloat::PFloat(unsigned int size)
|
|||
mDescriptiveName.Format("Float%d", size);
|
||||
if (size == 8)
|
||||
{
|
||||
#ifdef __i386__
|
||||
// According to System V i386 ABI alignment of double type is 4
|
||||
// GCC and Clang for 32-bit Intel targets follow this requirement
|
||||
// However GCC has -malign-double option to enable 8-byte alignment
|
||||
// So calculation of the actual alignment is needed
|
||||
struct AlignmentCheck { uint8_t i; double d; };
|
||||
Align = static_cast<unsigned int>(offsetof(AlignmentCheck, d));
|
||||
#endif // __i386__
|
||||
|
||||
SetDoubleSymbols();
|
||||
}
|
||||
else
|
||||
|
|
|
@ -363,7 +363,7 @@ static PClassActor * T_GetAmmo(const svalue_t &t)
|
|||
p=DefAmmo[ammonum];
|
||||
}
|
||||
auto am = PClass::FindActor(p);
|
||||
if (am == NULL || !am->IsKindOf(PClass::FindClass(NAME_Ammo)))
|
||||
if (am == NULL || !am->IsDescendantOf(PClass::FindClass(NAME_Ammo)))
|
||||
{
|
||||
script_error("unknown ammo type : %s", p);
|
||||
return NULL;
|
||||
|
@ -2436,7 +2436,7 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount)
|
|||
type = "BasicArmorPickup";
|
||||
}
|
||||
auto info = PClass::FindActor (type);
|
||||
if (info == NULL || !info->IsKindOf(RUNTIME_CLASS(AInventory)))
|
||||
if (info == NULL || !info->IsDescendantOf(RUNTIME_CLASS(AInventory)))
|
||||
{
|
||||
Printf ("Unknown inventory item: %s\n", type);
|
||||
return;
|
||||
|
|
|
@ -484,43 +484,6 @@ bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return)
|
|||
return !!res;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: CanPickup
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AInventory, CanPickup)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AInventory);
|
||||
PARAM_OBJECT(toucher, AActor);
|
||||
|
||||
if (!toucher)
|
||||
ACTION_RETURN_BOOL(false);
|
||||
|
||||
auto ai = self->GetClass();
|
||||
// Is the item restricted to certain player classes?
|
||||
if (ai->RestrictedToPlayerClass.Size() != 0)
|
||||
{
|
||||
for (unsigned i = 0; i < ai->RestrictedToPlayerClass.Size(); ++i)
|
||||
{
|
||||
if (toucher->IsKindOf(ai->RestrictedToPlayerClass[i]))
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
// Or is it forbidden to certain other classes?
|
||||
else
|
||||
{
|
||||
for (unsigned i = 0; i < ai->ForbiddenToPlayerClass.Size(); ++i)
|
||||
{
|
||||
if (toucher->IsKindOf(ai->ForbiddenToPlayerClass[i]))
|
||||
ACTION_RETURN_BOOL(false);
|
||||
}
|
||||
}
|
||||
ACTION_RETURN_BOOL(true);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// CCMD printinv
|
||||
|
|
|
@ -635,7 +635,7 @@ void InitAllPowerupEffects(AInventory *item)
|
|||
{
|
||||
if (item->IsKindOf(ptype))
|
||||
{
|
||||
IFVIRTUALPTRNAME(item, NAME_Powerup, EndEffect)
|
||||
IFVIRTUALPTRNAME(item, NAME_Powerup, InitEffect)
|
||||
{
|
||||
VMValue params[1] = { item };
|
||||
VMFrameStack stack;
|
||||
|
|
|
@ -38,7 +38,7 @@ void FLinearDepthShader::Bind()
|
|||
|
||||
if (!mShader)
|
||||
{
|
||||
mShader = std::make_unique<FShaderProgram>();
|
||||
mShader.reset(new FShaderProgram());
|
||||
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
||||
mShader->SetFragDataLocation(0, "FragColor");
|
||||
|
@ -66,7 +66,7 @@ void FSSAOShader::Bind()
|
|||
|
||||
if (!mShader)
|
||||
{
|
||||
mShader = std::make_unique<FShaderProgram>();
|
||||
mShader.reset(new FShaderProgram());
|
||||
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssao.fp", GetDefines(gl_ssao, multisample), 330);
|
||||
mShader->SetFragDataLocation(0, "FragColor");
|
||||
|
@ -142,7 +142,7 @@ void FSSAOCombineShader::Bind()
|
|||
|
||||
if (!mShader)
|
||||
{
|
||||
mShader = std::make_unique<FShaderProgram>();
|
||||
mShader.reset(new FShaderProgram());
|
||||
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
||||
mShader->SetFragDataLocation(0, "FragColor");
|
||||
|
|
|
@ -316,7 +316,7 @@ OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader()
|
|||
|
||||
bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height, HWFrameBuffer **outFramebuffer)
|
||||
{
|
||||
auto fb = std::make_unique<HWFrameBuffer>();
|
||||
std::unique_ptr<HWFrameBuffer> fb(new HWFrameBuffer());
|
||||
|
||||
GLint format = GL_RGBA16F;
|
||||
if (gl.es) format = GL_RGB;
|
||||
|
@ -357,7 +357,7 @@ bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int
|
|||
|
||||
bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragmentsrc, const FString &defines, HWPixelShader **outShader)
|
||||
{
|
||||
auto shader = std::make_unique<HWPixelShader>();
|
||||
std::unique_ptr<HWPixelShader> shader(new HWPixelShader());
|
||||
|
||||
shader->Program = glCreateProgram();
|
||||
if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return false; }
|
||||
|
@ -443,7 +443,7 @@ bool OpenGLSWFrameBuffer::CreatePixelShader(FString vertexsrc, FString fragments
|
|||
|
||||
bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer)
|
||||
{
|
||||
auto obj = std::make_unique<HWVertexBuffer>();
|
||||
std::unique_ptr<HWVertexBuffer> obj(new HWVertexBuffer());
|
||||
|
||||
obj->Size = size;
|
||||
|
||||
|
@ -474,7 +474,7 @@ bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVerte
|
|||
|
||||
bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer)
|
||||
{
|
||||
auto obj = std::make_unique<HWIndexBuffer>();
|
||||
std::unique_ptr<HWIndexBuffer> obj(new HWIndexBuffer());
|
||||
|
||||
obj->Size = size;
|
||||
|
||||
|
@ -494,7 +494,7 @@ bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBu
|
|||
|
||||
bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int height, int levels, int format, HWTexture **outTexture)
|
||||
{
|
||||
auto obj = std::make_unique<HWTexture>();
|
||||
std::unique_ptr<HWTexture> obj(new HWTexture());
|
||||
|
||||
obj->Format = format;
|
||||
|
||||
|
@ -532,7 +532,7 @@ bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int heig
|
|||
|
||||
OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::CopyCurrentScreen()
|
||||
{
|
||||
auto obj = std::make_unique<HWTexture>();
|
||||
std::unique_ptr<HWTexture> obj(new HWTexture());
|
||||
obj->Format = GL_RGBA16F;
|
||||
|
||||
GLint oldBinding = 0;
|
||||
|
@ -611,7 +611,7 @@ void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const FBVERTEX *vertices)
|
|||
|
||||
if (!StreamVertexBuffer)
|
||||
{
|
||||
StreamVertexBuffer = std::make_unique<HWVertexBuffer>();
|
||||
StreamVertexBuffer.reset(new HWVertexBuffer());
|
||||
glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray);
|
||||
glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer);
|
||||
glBindVertexArray(StreamVertexBuffer->VertexArray);
|
||||
|
@ -648,7 +648,7 @@ void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const BURNVERTEX *vertices
|
|||
|
||||
if (!StreamVertexBufferBurn)
|
||||
{
|
||||
StreamVertexBufferBurn = std::make_unique<HWVertexBuffer>();
|
||||
StreamVertexBufferBurn.reset(new HWVertexBuffer());
|
||||
glGenVertexArrays(1, (GLuint*)&StreamVertexBufferBurn->VertexArray);
|
||||
glGenBuffers(1, (GLuint*)&StreamVertexBufferBurn->Buffer);
|
||||
glBindVertexArray(StreamVertexBufferBurn->VertexArray);
|
||||
|
@ -679,7 +679,7 @@ void OpenGLSWFrameBuffer::DrawPoints(int count, const FBVERTEX *vertices)
|
|||
|
||||
if (!StreamVertexBuffer)
|
||||
{
|
||||
StreamVertexBuffer = std::make_unique<HWVertexBuffer>();
|
||||
StreamVertexBuffer.reset(new HWVertexBuffer());
|
||||
glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray);
|
||||
glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer);
|
||||
glBindVertexArray(StreamVertexBuffer->VertexArray);
|
||||
|
|
49
src/info.cpp
49
src/info.cpp
|
@ -76,7 +76,7 @@ bool FState::CallAction(AActor *self, AActor *stateowner, FStateParamInfo *info,
|
|||
{
|
||||
ActionCycles.Clock();
|
||||
|
||||
VMValue params[3] = { self, stateowner, VMValue(info, ATAG_GENERIC) };
|
||||
VMValue params[3] = { self, stateowner, VMValue(info) };
|
||||
// If the function returns a state, store it at *stateret.
|
||||
// If it doesn't return a state but stateret is non-NULL, we need
|
||||
// to set *stateret to NULL.
|
||||
|
@ -314,10 +314,6 @@ void PClassActor::DeriveData(PClass *newclass)
|
|||
*newa->PainChances = *PainChances;
|
||||
}
|
||||
|
||||
// Inventory stuff
|
||||
newa->ForbiddenToPlayerClass = ForbiddenToPlayerClass;
|
||||
newa->RestrictedToPlayerClass = RestrictedToPlayerClass;
|
||||
|
||||
newa->DisplayName = DisplayName;
|
||||
}
|
||||
|
||||
|
@ -589,49 +585,6 @@ void PClassActor::SetPainChance(FName type, int chance)
|
|||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PClassActor :: ReplaceClassRef
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
size_t PClassActor::PointerSubstitution(DObject *oldclass, DObject *newclass)
|
||||
{
|
||||
auto changed = Super::PointerSubstitution(oldclass, newclass);
|
||||
for (unsigned i = 0; i < VisibleToPlayerClass.Size(); i++)
|
||||
{
|
||||
if (VisibleToPlayerClass[i] == oldclass)
|
||||
{
|
||||
VisibleToPlayerClass[i] = static_cast<PClassActor*>(newclass);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < ForbiddenToPlayerClass.Size(); i++)
|
||||
{
|
||||
if (ForbiddenToPlayerClass[i] == oldclass)
|
||||
{
|
||||
ForbiddenToPlayerClass[i] = static_cast<PClassActor*>(newclass);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < RestrictedToPlayerClass.Size(); i++)
|
||||
{
|
||||
if (RestrictedToPlayerClass[i] == oldclass)
|
||||
{
|
||||
RestrictedToPlayerClass[i] = static_cast<PClassActor*>(newclass);
|
||||
changed++;
|
||||
}
|
||||
}
|
||||
AInventory *def = dyn_cast<AInventory>((AActor*)Defaults);
|
||||
if (def != NULL)
|
||||
{
|
||||
if (def->PickupFlash == oldclass) def->PickupFlash = static_cast<PClassActor *>(newclass);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DmgFactors :: CheckFactor
|
||||
|
|
|
@ -248,7 +248,6 @@ public:
|
|||
PClassActor();
|
||||
~PClassActor();
|
||||
|
||||
virtual size_t PointerSubstitution(DObject *oldclass, DObject *newclass);
|
||||
void BuildDefaults();
|
||||
void ApplyDefaults(uint8_t *defaults);
|
||||
void RegisterIDs();
|
||||
|
@ -292,10 +291,6 @@ public:
|
|||
FString SourceLumpName;
|
||||
FIntCVar *distancecheck;
|
||||
|
||||
// These are only valid for inventory items.
|
||||
TArray<PClassActor *> RestrictedToPlayerClass;
|
||||
TArray<PClassActor *> ForbiddenToPlayerClass;
|
||||
|
||||
// This is from PClassPlayerPawn
|
||||
FString DisplayName;
|
||||
|
||||
|
|
|
@ -576,7 +576,7 @@ bool M_ReadIDAT (FileReader *file, uint8_t *buffer, int width, int height, int p
|
|||
if (stream.avail_in == 0 && chunklen > 0)
|
||||
{
|
||||
stream.next_in = chunkbuffer;
|
||||
stream.avail_in = (uInt)file->Read (chunkbuffer, MIN<long>(chunklen,sizeof(chunkbuffer)));
|
||||
stream.avail_in = (uInt)file->Read (chunkbuffer, MIN<uint32_t>(chunklen,sizeof(chunkbuffer)));
|
||||
chunklen -= stream.avail_in;
|
||||
}
|
||||
|
||||
|
|
|
@ -902,3 +902,5 @@ xx(Player6)
|
|||
xx(Player7)
|
||||
xx(Player8)
|
||||
xx(PlayerChunk)
|
||||
xx(RestrictedToPlayerClass)
|
||||
xx(ForbiddenToPlayerClass)
|
||||
|
|
|
@ -153,7 +153,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
|||
VMReturn *wantret;
|
||||
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
|
||||
|
||||
params[2] = VMValue(&stp, ATAG_GENERIC);
|
||||
params[2] = VMValue(&stp);
|
||||
retval = true; // assume success
|
||||
wantret = NULL; // assume no return value wanted
|
||||
numret = 0;
|
||||
|
@ -2723,7 +2723,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem)
|
|||
PARAM_BOOL_DEF (useammo)
|
||||
PARAM_BOOL_DEF (transfer_translation);
|
||||
|
||||
if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetObject(nullptr);
|
||||
|
||||
if (missile == NULL)
|
||||
{
|
||||
|
@ -2760,7 +2760,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem)
|
|||
int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0);
|
||||
bool res = InitSpawnedItem(self, mo, flags); // for an inventory item's use state
|
||||
if (numret > 0) ret[0].SetInt(res);
|
||||
if (numret > 1) ret[1].SetPointer(mo, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetObject(mo);
|
||||
return MIN(numret, 2);
|
||||
|
||||
}
|
||||
|
@ -2787,7 +2787,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx)
|
|||
PARAM_INT_DEF (chance)
|
||||
PARAM_INT_DEF (tid)
|
||||
|
||||
if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetObject(nullptr);
|
||||
|
||||
if (missile == NULL)
|
||||
{
|
||||
|
@ -2852,7 +2852,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx)
|
|||
mo->Angles.Yaw = angle;
|
||||
}
|
||||
if (numret > 0) ret[0].SetInt(res);
|
||||
if (numret > 1) ret[1].SetPointer(mo, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetObject(mo);
|
||||
return MIN(numret, 2);
|
||||
}
|
||||
|
||||
|
@ -2872,7 +2872,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade)
|
|||
PARAM_FLOAT_DEF (zvel)
|
||||
PARAM_BOOL_DEF (useammo)
|
||||
|
||||
if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetObject(nullptr);
|
||||
|
||||
if (missile == NULL)
|
||||
{
|
||||
|
@ -2934,7 +2934,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade)
|
|||
if (!P_CheckMissileSpawn(bo, self->radius)) bo = nullptr;
|
||||
|
||||
if (numret > 0) ret[0].SetInt(true);
|
||||
if (numret > 1) ret[1].SetPointer(bo, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetObject(bo);
|
||||
return MIN(numret, 2);
|
||||
}
|
||||
else
|
||||
|
@ -4363,7 +4363,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CheckForReload)
|
|||
|
||||
if (numret > 0)
|
||||
{
|
||||
ret->SetPointer(NULL, ATAG_STATE);
|
||||
ret->SetPointer(NULL);
|
||||
numret = 1;
|
||||
}
|
||||
|
||||
|
@ -4381,7 +4381,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CheckForReload)
|
|||
// Go back to the refire frames, instead of continuing on to the reload frames.
|
||||
if (numret != 0)
|
||||
{
|
||||
ret->SetPointer(jump, ATAG_STATE);
|
||||
ret->SetPointer(jump);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -4903,7 +4903,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Teleport)
|
|||
}
|
||||
if (numret > 0)
|
||||
{
|
||||
ret[0].SetPointer(NULL, ATAG_STATE);
|
||||
ret[0].SetPointer(NULL);
|
||||
}
|
||||
|
||||
if (!ref)
|
||||
|
@ -5039,7 +5039,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Teleport)
|
|||
}
|
||||
if (numret > 0)
|
||||
{
|
||||
ret[0].SetPointer(teleport_state, ATAG_STATE);
|
||||
ret[0].SetPointer(teleport_state);
|
||||
}
|
||||
return numret;
|
||||
}
|
||||
|
@ -5337,7 +5337,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Warp)
|
|||
}
|
||||
if (numret > 0)
|
||||
{
|
||||
ret[0].SetPointer(NULL, ATAG_STATE);
|
||||
ret[0].SetPointer(NULL);
|
||||
}
|
||||
|
||||
if ((flags & WARPF_USETID))
|
||||
|
@ -5363,7 +5363,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Warp)
|
|||
// in this case, you have the statejump to help you handle all the success anyway.
|
||||
if (numret > 0)
|
||||
{
|
||||
ret[0].SetPointer(success_state, ATAG_STATE);
|
||||
ret[0].SetPointer(success_state);
|
||||
}
|
||||
}
|
||||
else if (numret > 1)
|
||||
|
|
|
@ -2054,7 +2054,7 @@ DEFINE_ACTION_FUNCTION(AActor, TestMobjZ)
|
|||
if (numret > 1)
|
||||
{
|
||||
numret = 2;
|
||||
ret[1].SetPointer(on, ATAG_OBJECT);
|
||||
ret[1].SetObject(on);
|
||||
}
|
||||
if (numret > 0)
|
||||
{
|
||||
|
@ -4685,7 +4685,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack)
|
|||
int acdmg;
|
||||
if (puffType == nullptr) puffType = PClass::FindActor("BulletPuff"); // P_LineAttack does not work without a puff to take info from.
|
||||
auto puff = P_LineAttack(self, angle, distance, pitch, damage, damageType, puffType, flags, victim, &acdmg);
|
||||
if (numret > 0) ret[0].SetPointer(puff, ATAG_OBJECT);
|
||||
if (numret > 0) ret[0].SetObject(puff);
|
||||
if (numret > 1) ret[1].SetInt(acdmg), numret = 2;
|
||||
return numret;
|
||||
}
|
||||
|
|
|
@ -7247,8 +7247,8 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnPlayerMissile)
|
|||
AActor *missileactor;
|
||||
if (numparam == 2) angle = self->Angles.Yaw;
|
||||
AActor *misl = P_SpawnPlayerMissile(self, x, y, z, type, angle, lt, &missileactor, nofreeaim, noautoaim, aimflags);
|
||||
if (numret > 0) ret[0].SetPointer(misl, ATAG_OBJECT);
|
||||
if (numret > 1) ret[1].SetPointer(missileactor, ATAG_OBJECT), numret = 2;
|
||||
if (numret > 0) ret[0].SetObject(misl);
|
||||
if (numret > 1) ret[1].SetObject(missileactor), numret = 2;
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -7695,7 +7695,7 @@ FDropItem *AActor::GetDropItems() const
|
|||
DEFINE_ACTION_FUNCTION(AActor, GetDropItems)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
ACTION_RETURN_OBJECT(self->GetDropItems());
|
||||
ACTION_RETURN_POINTER(self->GetDropItems());
|
||||
}
|
||||
|
||||
double AActor::GetGravity() const
|
||||
|
|
|
@ -112,7 +112,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestFloorSurrounding)
|
|||
vertex_t *v;
|
||||
double h = self->FindLowestFloorSurrounding(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestFloorSurrounding)
|
|||
vertex_t *v;
|
||||
double h = self->FindHighestFloorSurrounding(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -224,7 +224,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextHighestFloor)
|
|||
vertex_t *v;
|
||||
double h = self->FindNextHighestFloor(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -286,7 +286,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextLowestFloor)
|
|||
vertex_t *v;
|
||||
double h = self->FindNextLowestFloor(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -348,7 +348,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextLowestCeiling)
|
|||
vertex_t *v;
|
||||
double h = self->FindNextLowestCeiling(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextHighestCeiling)
|
|||
vertex_t *v;
|
||||
double h = self->FindNextHighestCeiling(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -459,7 +459,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingSurrounding)
|
|||
vertex_t *v;
|
||||
double h = self->FindLowestCeilingSurrounding(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -508,7 +508,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestCeilingSurrounding)
|
|||
vertex_t *v;
|
||||
double h = self->FindHighestCeilingSurrounding(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -744,7 +744,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestFloorPoint)
|
|||
vertex_t *v;
|
||||
double h = self->FindHighestFloorPoint(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -793,7 +793,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingPoint)
|
|||
vertex_t *v;
|
||||
double h = self->FindLowestCeilingPoint(&v);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(v, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(v);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -1207,7 +1207,7 @@ DEFINE_ACTION_FUNCTION(_Sector, HighestCeilingAt)
|
|||
sector_t *s;
|
||||
double h = self->HighestCeilingAt(DVector2(x, y), &s);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(s, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(s);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -1242,7 +1242,7 @@ DEFINE_ACTION_FUNCTION(_Sector, LowestFloorAt)
|
|||
sector_t *s;
|
||||
double h = self->LowestFloorAt(DVector2(x, y), &s);
|
||||
if (numret > 0) ret[0].SetFloat(h);
|
||||
if (numret > 1) ret[1].SetPointer(s, ATAG_GENERIC);
|
||||
if (numret > 1) ret[1].SetPointer(s);
|
||||
return numret;
|
||||
}
|
||||
|
||||
|
@ -1309,12 +1309,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextHighestCeilingAt)
|
|||
|
||||
if (numret > 2)
|
||||
{
|
||||
ret[2].SetPointer(resultff, ATAG_GENERIC);
|
||||
ret[2].SetPointer(resultff);
|
||||
numret = 3;
|
||||
}
|
||||
if (numret > 1)
|
||||
{
|
||||
ret[1].SetPointer(resultsec, ATAG_GENERIC);
|
||||
ret[1].SetPointer(resultsec);
|
||||
}
|
||||
if (numret > 0)
|
||||
{
|
||||
|
@ -1387,12 +1387,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
|
|||
|
||||
if (numret > 2)
|
||||
{
|
||||
ret[2].SetPointer(resultff, ATAG_GENERIC);
|
||||
ret[2].SetPointer(resultff);
|
||||
numret = 3;
|
||||
}
|
||||
if (numret > 1)
|
||||
{
|
||||
ret[1].SetPointer(resultsec, ATAG_GENERIC);
|
||||
ret[1].SetPointer(resultsec);
|
||||
}
|
||||
if (numret > 0)
|
||||
{
|
||||
|
|
|
@ -505,12 +505,13 @@ private:
|
|||
{
|
||||
// Load bgcolor
|
||||
uint32_t desttmp[2];
|
||||
if (mask0 & (1 << 31)) desttmp[0] = dest[x * 2];
|
||||
if (mask0 & (1 << 30)) desttmp[1] = dest[x * 2 + 1];
|
||||
|
||||
__m128i bgcolor;
|
||||
if (BlendT::Mode != (int)BlendModes::Opaque)
|
||||
{
|
||||
if (mask0 & (1 << 31)) desttmp[0] = dest[x * 2];
|
||||
if (mask0 & (1 << 30)) desttmp[1] = dest[x * 2 + 1];
|
||||
bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128());
|
||||
}
|
||||
else
|
||||
bgcolor = _mm_setzero_si128();
|
||||
|
||||
|
@ -593,12 +594,13 @@ private:
|
|||
{
|
||||
// Load bgcolor
|
||||
uint32_t desttmp[2];
|
||||
if (mask1 & (1 << 31)) desttmp[0] = dest[x * 2];
|
||||
if (mask1 & (1 << 30)) desttmp[1] = dest[x * 2 + 1];
|
||||
|
||||
__m128i bgcolor;
|
||||
if (BlendT::Mode != (int)BlendModes::Opaque)
|
||||
{
|
||||
if (mask1 & (1 << 31)) desttmp[0] = dest[x * 2];
|
||||
if (mask1 & (1 << 30)) desttmp[1] = dest[x * 2 + 1];
|
||||
bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128());
|
||||
}
|
||||
else
|
||||
bgcolor = _mm_setzero_si128();
|
||||
|
||||
|
|
|
@ -249,7 +249,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
|||
}
|
||||
if (!polyportal)
|
||||
{
|
||||
sectorPortals.push_back(std::make_unique<PolyDrawSectorPortal>(portal, ceiling));
|
||||
sectorPortals.push_back(std::unique_ptr<PolyDrawSectorPortal>(new PolyDrawSectorPortal(portal, ceiling)));
|
||||
polyportal = sectorPortals.back().get();
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
{
|
||||
if (PolyRenderer::Instance()->InsertSeenMirror(line->linedef))
|
||||
{
|
||||
linePortals.push_back(std::make_unique<PolyDrawLinePortal>(line->linedef));
|
||||
linePortals.push_back(std::unique_ptr<PolyDrawLinePortal>(new PolyDrawLinePortal(line->linedef)));
|
||||
polyportal = linePortals.back().get();
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
|||
}
|
||||
if (!polyportal)
|
||||
{
|
||||
linePortals.push_back(std::make_unique<PolyDrawLinePortal>(portal));
|
||||
linePortals.push_back(std::unique_ptr<PolyDrawLinePortal>(new PolyDrawLinePortal(portal)));
|
||||
polyportal = linePortals.back().get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -385,7 +385,7 @@ void FxExpression::EmitCompare(VMFunctionBuilder *build, bool invert, TArray<siz
|
|||
break;
|
||||
|
||||
case REGT_POINTER:
|
||||
build->Emit(OP_EQA_K, !invert, op.RegNum, build->GetConstantAddress(0, ATAG_GENERIC));
|
||||
build->Emit(OP_EQA_K, !invert, op.RegNum, build->GetConstantAddress(0));
|
||||
break;
|
||||
|
||||
case REGT_STRING:
|
||||
|
@ -587,16 +587,7 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build)
|
|||
}
|
||||
else if (regtype == REGT_POINTER)
|
||||
{
|
||||
VM_ATAG tag = ATAG_GENERIC;
|
||||
if (value.Type == TypeState)
|
||||
{
|
||||
tag = ATAG_STATE;
|
||||
}
|
||||
else if (value.Type->GetLoadOp() != OP_LP)
|
||||
{
|
||||
tag = ATAG_OBJECT;
|
||||
}
|
||||
out.RegNum = build->GetConstantAddress(value.pointer, tag);
|
||||
out.RegNum = build->GetConstantAddress(value.pointer);
|
||||
}
|
||||
else if (regtype == REGT_STRING)
|
||||
{
|
||||
|
@ -2998,7 +2989,7 @@ texcheck:
|
|||
auto * countptr = &ptr->Count;
|
||||
ExpEmit bndp(build, REGT_POINTER);
|
||||
ExpEmit bndc(build, REGT_INT);
|
||||
build->Emit(OP_LKP, bndp.RegNum, build->GetConstantAddress(countptr, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, bndp.RegNum, build->GetConstantAddress(countptr));
|
||||
build->Emit(OP_LW, bndc.RegNum, bndp.RegNum, build->GetConstantInt(0));
|
||||
build->Emit(OP_BOUND_R, to.RegNum, bndc.RegNum);
|
||||
bndp.Free(build);
|
||||
|
@ -4638,7 +4629,7 @@ void FxTypeCheck::EmitCompare(VMFunctionBuilder *build, bool invert, TArray<size
|
|||
{
|
||||
ExpEmit ares = EmitCommon(build);
|
||||
ares.Free(build);
|
||||
build->Emit(OP_EQA_K, !invert, ares.RegNum, build->GetConstantAddress(nullptr, ATAG_OBJECT));
|
||||
build->Emit(OP_EQA_K, !invert, ares.RegNum, build->GetConstantAddress(nullptr));
|
||||
patchspots_no.Push(build->Emit(OP_JMP, 0));
|
||||
}
|
||||
|
||||
|
@ -4706,7 +4697,7 @@ ExpEmit FxDynamicCast::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit castee = expr->Emit(build);
|
||||
castee.Free(build);
|
||||
ExpEmit ares(build, REGT_POINTER);
|
||||
build->Emit(OP_DYNCAST_K, ares.RegNum, castee.RegNum, build->GetConstantAddress(CastType, ATAG_OBJECT));
|
||||
build->Emit(OP_DYNCAST_K, ares.RegNum, castee.RegNum, build->GetConstantAddress(CastType));
|
||||
return ares;
|
||||
}
|
||||
|
||||
|
@ -5536,16 +5527,16 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
if (min != nullptr && max != nullptr)
|
||||
{
|
||||
EmitParameter(build, min, ScriptPosition);
|
||||
EmitParameter(build, max, ScriptPosition);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 3, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 1, 1);
|
||||
}
|
||||
|
||||
if (EmitTail)
|
||||
|
@ -5657,10 +5648,10 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
|
|||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
build->EmitParamInt(0);
|
||||
build->EmitParamInt(choices.Size() - 1);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 3, 1);
|
||||
|
||||
ExpEmit resultreg(build, REGT_INT);
|
||||
build->Emit(OP_RESULT, 0, REGT_INT, resultreg.RegNum);
|
||||
|
@ -5787,16 +5778,16 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
if (min != nullptr && max != nullptr)
|
||||
{
|
||||
EmitParameter(build, min, ScriptPosition);
|
||||
EmitParameter(build, max, ScriptPosition);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 3, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 1, 1);
|
||||
}
|
||||
|
||||
if (EmitTail)
|
||||
|
@ -5882,9 +5873,9 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
int opcode = (EmitTail ? OP_TAIL_K : OP_CALL_K);
|
||||
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng, ATAG_RNG));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(rng));
|
||||
EmitParameter(build, mask, ScriptPosition);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
||||
build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 1);
|
||||
|
||||
if (EmitTail)
|
||||
{
|
||||
|
@ -6661,7 +6652,7 @@ ExpEmit FxGlobalVariable::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
ExpEmit obj(build, REGT_POINTER);
|
||||
|
||||
build->Emit(OP_LKP, obj.RegNum, build->GetConstantAddress((void*)(intptr_t)membervar->Offset, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, obj.RegNum, build->GetConstantAddress((void*)(intptr_t)membervar->Offset));
|
||||
if (AddressRequested)
|
||||
{
|
||||
return obj;
|
||||
|
@ -6744,34 +6735,34 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
|
|||
switch (CVar->GetRealType())
|
||||
{
|
||||
case CVAR_Int:
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FIntCVar *>(CVar)->Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FIntCVar *>(CVar)->Value));
|
||||
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
|
||||
break;
|
||||
|
||||
case CVAR_Color:
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FColorCVar *>(CVar)->Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FColorCVar *>(CVar)->Value));
|
||||
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
|
||||
break;
|
||||
|
||||
case CVAR_Float:
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FFloatCVar *>(CVar)->Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FFloatCVar *>(CVar)->Value));
|
||||
build->Emit(OP_LSP, dest.RegNum, addr.RegNum, nul);
|
||||
break;
|
||||
|
||||
case CVAR_Bool:
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FBoolCVar *>(CVar)->Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FBoolCVar *>(CVar)->Value));
|
||||
build->Emit(OP_LBU, dest.RegNum, addr.RegNum, nul);
|
||||
break;
|
||||
|
||||
case CVAR_String:
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FStringCVar *>(CVar)->Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&static_cast<FStringCVar *>(CVar)->Value));
|
||||
build->Emit(OP_LCS, dest.RegNum, addr.RegNum, nul);
|
||||
break;
|
||||
|
||||
case CVAR_DummyBool:
|
||||
{
|
||||
auto cv = static_cast<FFlagCVar *>(CVar);
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value));
|
||||
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
|
||||
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
|
||||
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(1));
|
||||
|
@ -6781,7 +6772,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
|
|||
case CVAR_DummyInt:
|
||||
{
|
||||
auto cv = static_cast<FMaskCVar *>(CVar);
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value, ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, addr.RegNum, build->GetConstantAddress(&cv->ValueVar.Value));
|
||||
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
|
||||
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(cv->BitVal));
|
||||
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
|
||||
|
@ -6923,13 +6914,13 @@ FxStructMember::~FxStructMember()
|
|||
|
||||
bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
||||
{
|
||||
// Cannot take the address of metadata variables.
|
||||
AddressRequested = true;
|
||||
if (membervar->Flags & VARF_Meta)
|
||||
{
|
||||
return false;
|
||||
// Meta variables are read only.
|
||||
*writable = false;
|
||||
}
|
||||
AddressRequested = true;
|
||||
if (writable != nullptr)
|
||||
else if (writable != nullptr)
|
||||
{
|
||||
// [ZZ] original check.
|
||||
bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
|
||||
|
@ -7323,11 +7314,13 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
|||
|
||||
if (SizeAddr != ~0u)
|
||||
{
|
||||
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
||||
|
||||
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, ismeta? VARF_Meta : 0, SizeAddr);
|
||||
static_cast<FxMemberBase *>(Array)->membervar = f;
|
||||
static_cast<FxMemberBase *>(Array)->AddressRequested = false;
|
||||
Array->ValueType = TypeUInt32;
|
||||
|
@ -8544,14 +8537,14 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
|||
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||
if (EmitTail)
|
||||
{
|
||||
build->Emit(OP_TAIL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2 + i, 0);
|
||||
build->Emit(OP_TAIL_K, build->GetConstantAddress(callfunc), 2 + i, 0);
|
||||
ExpEmit call;
|
||||
call.Final = true;
|
||||
return call;
|
||||
}
|
||||
|
||||
ExpEmit dest(build, REGT_INT);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2 + i, 1);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 2 + i, 1);
|
||||
build->Emit(OP_RESULT, 0, REGT_INT, dest.RegNum);
|
||||
return dest;
|
||||
}
|
||||
|
@ -8941,7 +8934,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
if (selfside == FScopeBarrier::Side_PlainData)
|
||||
{
|
||||
// Check the self object against the calling function's flags at run time
|
||||
build->Emit(OP_SCOPE, selfemit.RegNum, outerside + 1, build->GetConstantAddress(vmfunc, ATAG_OBJECT));
|
||||
build->Emit(OP_SCOPE, selfemit.RegNum, outerside + 1, build->GetConstantAddress(vmfunc));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8967,7 +8960,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
// pass self as stateowner, otherwise all attempts of the subfunction to retrieve a state from a name would fail.
|
||||
build->Emit(OP_PARAM, 0, selfemit.RegType, selfemit.RegNum);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr, ATAG_GENERIC));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(nullptr));
|
||||
}
|
||||
count += 2;
|
||||
}
|
||||
|
@ -8985,7 +8978,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
|||
// Get a constant register for this function
|
||||
if (staticcall)
|
||||
{
|
||||
int funcaddr = build->GetConstantAddress(vmfunc, ATAG_OBJECT);
|
||||
int funcaddr = build->GetConstantAddress(vmfunc);
|
||||
// Emit the call
|
||||
if (EmitTail)
|
||||
{ // Tail call
|
||||
|
@ -10503,7 +10496,7 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset));
|
||||
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor, ATAG_OBJECT), 1, 0);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0);
|
||||
reg.Free(build);
|
||||
}
|
||||
|
||||
|
@ -10690,9 +10683,9 @@ int BuiltinNameToClass(VMValue *param, TArray<VMValue> &defaultparam, int numpar
|
|||
// Let the caller check this. Making this an error with a message is only taking away options from the user.
|
||||
cls = nullptr;
|
||||
}
|
||||
ret->SetPointer(const_cast<PClass *>(cls), ATAG_OBJECT);
|
||||
ret->SetObject(const_cast<PClass *>(cls));
|
||||
}
|
||||
else ret->SetPointer(nullptr, ATAG_OBJECT);
|
||||
else ret->SetObject(nullptr);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -10700,13 +10693,13 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
if (basex->ValueType != TypeName)
|
||||
{
|
||||
return ExpEmit(build->GetConstantAddress(nullptr, ATAG_OBJECT), REGT_POINTER, true);
|
||||
return ExpEmit(build->GetConstantAddress(nullptr), REGT_POINTER, true);
|
||||
}
|
||||
ExpEmit clsname = basex->Emit(build);
|
||||
assert(!clsname.Konst);
|
||||
ExpEmit dest(build, REGT_POINTER);
|
||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast<PClass *>(desttype), ATAG_OBJECT));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(const_cast<PClass *>(desttype)));
|
||||
|
||||
// Call the BuiltinNameToClass function to convert from 'name' to class.
|
||||
VMFunction *callfunc;
|
||||
|
@ -10716,7 +10709,7 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
|||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 2, 1);
|
||||
build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum);
|
||||
clsname.Free(build);
|
||||
return dest;
|
||||
|
@ -10815,7 +10808,7 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit clsname = basex->Emit(build);
|
||||
|
||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype, ATAG_OBJECT));
|
||||
build->Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, build->GetConstantAddress(desttype));
|
||||
|
||||
VMFunction *callfunc;
|
||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast);
|
||||
|
@ -10825,7 +10818,7 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
|
|||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||
clsname.Free(build);
|
||||
ExpEmit dest(build, REGT_POINTER);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(callfunc), 2, 1);
|
||||
build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum);
|
||||
return dest;
|
||||
}
|
||||
|
@ -11164,7 +11157,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
|||
|
||||
case REGT_POINTER:
|
||||
{
|
||||
build->Emit(OP_LKP, RegNum, build->GetConstantAddress(constval->GetValue().GetPointer(), ValueType->GetLoadOp() != OP_LP ? ATAG_OBJECT : ATAG_GENERIC));
|
||||
build->Emit(OP_LKP, RegNum, build->GetConstantAddress(constval->GetValue().GetPointer()));
|
||||
break;
|
||||
}
|
||||
case REGT_STRING:
|
||||
|
@ -11196,7 +11189,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
|||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
||||
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor, ATAG_OBJECT), 1, 0);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor), 1, 0);
|
||||
reg.Free(build);
|
||||
}
|
||||
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
|
||||
|
@ -11222,7 +11215,7 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
|
|||
ExpEmit reg(build, REGT_POINTER);
|
||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
||||
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor, ATAG_OBJECT), 1, 0);
|
||||
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor), 1, 0);
|
||||
reg.Free(build);
|
||||
}
|
||||
build->ConstructedStructs.Delete(build->ConstructedStructs.Find(this));
|
||||
|
@ -11304,7 +11297,7 @@ ExpEmit FxStaticArray::Emit(VMFunctionBuilder *build)
|
|||
{
|
||||
TArray<void*> cvalues;
|
||||
for (auto v : values) cvalues.Push(static_cast<FxConstant *>(v)->GetValue().GetPointer());
|
||||
StackOffset = build->AllocConstantsAddress(cvalues.Size(), &cvalues[0], ElementType->GetLoadOp() != OP_LP ? ATAG_OBJECT : ATAG_GENERIC);
|
||||
StackOffset = build->AllocConstantsAddress(cvalues.Size(), &cvalues[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ void VMFunctionBuilder::MakeFunction(VMScriptFunction *func)
|
|||
}
|
||||
if (AddressConstantList.Size() > 0)
|
||||
{
|
||||
FillAddressConstants(func->KonstA, func->KonstATags());
|
||||
FillAddressConstants(func->KonstA);
|
||||
}
|
||||
if (StringConstantList.Size() > 0)
|
||||
{
|
||||
|
@ -175,10 +175,9 @@ void VMFunctionBuilder::FillFloatConstants(double *konst)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void VMFunctionBuilder::FillAddressConstants(FVoidObj *konst, VM_ATAG *tags)
|
||||
void VMFunctionBuilder::FillAddressConstants(FVoidObj *konst)
|
||||
{
|
||||
memcpy(konst, &AddressConstantList[0], sizeof(void*) * AddressConstantList.Size());
|
||||
memcpy(tags, &AtagConstantList[0], sizeof(VM_ATAG) * AtagConstantList.Size());
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -258,7 +257,7 @@ unsigned VMFunctionBuilder::GetConstantString(FString val)
|
|||
}
|
||||
else
|
||||
{
|
||||
int loc = StringConstantList.Push(val);
|
||||
unsigned loc = StringConstantList.Push(val);
|
||||
StringConstantMap.Insert(val, loc);
|
||||
return loc;
|
||||
}
|
||||
|
@ -273,27 +272,18 @@ unsigned VMFunctionBuilder::GetConstantString(FString val)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
unsigned VMFunctionBuilder::GetConstantAddress(void *ptr, VM_ATAG tag)
|
||||
unsigned VMFunctionBuilder::GetConstantAddress(void *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
{ // Make all NULL pointers generic. (Or should we allow typed NULLs?)
|
||||
tag = ATAG_GENERIC;
|
||||
}
|
||||
AddrKonst *locp = AddressConstantMap.CheckKey(ptr);
|
||||
unsigned *locp = AddressConstantMap.CheckKey(ptr);
|
||||
if (locp != NULL)
|
||||
{
|
||||
// There should only be one tag associated with a memory location. Exceptions are made for null pointers that got allocated through constant arrays.
|
||||
assert(ptr == nullptr || locp->Tag == tag);
|
||||
return locp->KonstNum;
|
||||
return *locp;
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned locc = AddressConstantList.Push(ptr);
|
||||
AtagConstantList.Push(tag);
|
||||
|
||||
AddrKonst loc = { locc, tag };
|
||||
unsigned loc = AddressConstantList.Push(ptr);
|
||||
AddressConstantMap.Insert(ptr, loc);
|
||||
return loc.KonstNum;
|
||||
return loc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,16 +317,13 @@ unsigned VMFunctionBuilder::AllocConstantsFloat(unsigned count, double *values)
|
|||
return addr;
|
||||
}
|
||||
|
||||
unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs, VM_ATAG tag)
|
||||
unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs)
|
||||
{
|
||||
unsigned addr = AddressConstantList.Reserve(count);
|
||||
AtagConstantList.Reserve(count);
|
||||
memcpy(&AddressConstantList[addr], ptrs, count * sizeof(void *));
|
||||
for (unsigned i = 0; i < count; i++)
|
||||
{
|
||||
AtagConstantList[addr + i] = tag;
|
||||
AddrKonst loc = { addr+i, tag };
|
||||
AddressConstantMap.Insert(ptrs[i], loc);
|
||||
AddressConstantMap.Insert(ptrs[i], addr+i);
|
||||
}
|
||||
return addr;
|
||||
}
|
||||
|
|
|
@ -51,12 +51,12 @@ public:
|
|||
// Returns the constant register holding the value.
|
||||
unsigned GetConstantInt(int val);
|
||||
unsigned GetConstantFloat(double val);
|
||||
unsigned GetConstantAddress(void *ptr, VM_ATAG tag);
|
||||
unsigned GetConstantAddress(void *ptr);
|
||||
unsigned GetConstantString(FString str);
|
||||
|
||||
unsigned AllocConstantsInt(unsigned int count, int *values);
|
||||
unsigned AllocConstantsFloat(unsigned int count, double *values);
|
||||
unsigned AllocConstantsAddress(unsigned int count, void **ptrs, VM_ATAG tag);
|
||||
unsigned AllocConstantsAddress(unsigned int count, void **ptrs);
|
||||
unsigned AllocConstantsString(unsigned int count, FString *ptrs);
|
||||
|
||||
|
||||
|
@ -79,7 +79,7 @@ public:
|
|||
// Write out complete constant tables.
|
||||
void FillIntConstants(int *konst);
|
||||
void FillFloatConstants(double *konst);
|
||||
void FillAddressConstants(FVoidObj *konst, VM_ATAG *tags);
|
||||
void FillAddressConstants(FVoidObj *konst);
|
||||
void FillStringConstants(FString *strings);
|
||||
|
||||
// PARAM increases ActiveParam; CALL decreases it.
|
||||
|
@ -96,24 +96,17 @@ public:
|
|||
TArray<FxLocalVariableDeclaration *> ConstructedStructs;
|
||||
|
||||
private:
|
||||
struct AddrKonst
|
||||
{
|
||||
unsigned KonstNum;
|
||||
VM_ATAG Tag;
|
||||
};
|
||||
|
||||
TArray<FStatementInfo> LineNumbers;
|
||||
TArray<FxExpression *> StatementStack;
|
||||
|
||||
TArray<int> IntConstantList;
|
||||
TArray<double> FloatConstantList;
|
||||
TArray<void *> AddressConstantList;
|
||||
TArray<VM_ATAG> AtagConstantList;
|
||||
TArray<FString> StringConstantList;
|
||||
// These map from the constant value to its position in the constant table.
|
||||
TMap<int, unsigned> IntConstantMap;
|
||||
TMap<double, unsigned> FloatConstantMap;
|
||||
TMap<void *, AddrKonst> AddressConstantMap;
|
||||
TMap<void *, unsigned> AddressConstantMap;
|
||||
TMap<FString, unsigned> StringConstantMap;
|
||||
|
||||
int MaxParam;
|
||||
|
|
|
@ -243,7 +243,7 @@ void VMDumpConstants(FILE *out, const VMScriptFunction *func)
|
|||
{
|
||||
for (j = 0, k = i; j < 4 && k < func->NumKonstA; j++, k += kk)
|
||||
{
|
||||
mysnprintf(tmp, countof(tmp), "%3d. %p:%d", k, func->KonstA[k].v, func->KonstATags()[k]);
|
||||
mysnprintf(tmp, countof(tmp), "%3d. %p", k, func->KonstA[k].v);
|
||||
printf_wrapper(out, "%-22s", tmp);
|
||||
}
|
||||
printf_wrapper(out, "\n");
|
||||
|
@ -320,7 +320,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
switch (code[i].op)
|
||||
{
|
||||
case OP_JMP:
|
||||
case OP_TRY:
|
||||
//case OP_TRY:
|
||||
col = printf_wrapper(out, "%08x", (i + 1 + code[i].i24) << 2);
|
||||
break;
|
||||
|
||||
|
@ -498,7 +498,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
col = 30;
|
||||
}
|
||||
printf_wrapper(out, "%*c", 30 - col, ';');
|
||||
if (!cmp && (code[i].op == OP_JMP || code[i].op == OP_TRY || code[i].op == OP_PARAMI))
|
||||
if (!cmp && (code[i].op == OP_JMP || /*code[i].op == OP_TRY ||*/ code[i].op == OP_PARAMI))
|
||||
{
|
||||
printf_wrapper(out, "%d\n", code[i].i24);
|
||||
}
|
||||
|
|
|
@ -1090,12 +1090,14 @@ DEFINE_PROPERTY(distancecheck, S, Actor)
|
|||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
|
||||
{
|
||||
static_cast<PClassActor*>(info)->RestrictedToPlayerClass.Clear();
|
||||
auto restrictarray = (TArray<PClassActor*>*)defaults->ScriptVar(NAME_RestrictedToPlayerClass, nullptr);
|
||||
|
||||
restrictarray->Clear();
|
||||
for(int i = 0;i < PROP_PARM_COUNT;++i)
|
||||
{
|
||||
PROP_STRING_PARM(n, i);
|
||||
if (*n != 0)
|
||||
static_cast<PClassActor*>(info)->RestrictedToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn)));
|
||||
restrictarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1104,12 +1106,14 @@ DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
|
|||
//==========================================================================
|
||||
DEFINE_CLASS_PROPERTY(forbiddento, Ssssssssssssssssssss, Inventory)
|
||||
{
|
||||
static_cast<PClassActor*>(info)->ForbiddenToPlayerClass.Clear();
|
||||
auto forbidarray = (TArray<PClassActor*>*)defaults->ScriptVar(NAME_ForbiddenToPlayerClass, nullptr);
|
||||
|
||||
forbidarray->Clear();
|
||||
for(int i = 0;i < PROP_PARM_COUNT;++i)
|
||||
{
|
||||
PROP_STRING_PARM(n, i);
|
||||
if (*n != 0)
|
||||
static_cast<PClassActor*>(info)->ForbiddenToPlayerClass.Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn)));
|
||||
forbidarray->Push(FindClassTentative(n, RUNTIME_CLASS(APlayerPawn)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@ typedef unsigned short VM_UHALF;
|
|||
typedef signed short VM_SHALF;
|
||||
typedef unsigned int VM_UWORD;
|
||||
typedef signed int VM_SWORD;
|
||||
typedef VM_UBYTE VM_ATAG;
|
||||
|
||||
#define VM_EPSILON (1/65536.0)
|
||||
|
||||
|
@ -176,27 +175,6 @@ enum
|
|||
#define RET_FINAL (0x80) // Used with RET and RETI in the destination slot: this is the final return value
|
||||
|
||||
|
||||
// Tags for address registers
|
||||
enum
|
||||
{
|
||||
ATAG_GENERIC, // pointer to something; we don't care what
|
||||
ATAG_OBJECT, // pointer to an object; will be followed by GC
|
||||
|
||||
// The following are all for documentation during debugging and are
|
||||
// functionally no different than ATAG_GENERIC (meaning they are useless because they trigger asserts all over the place.)
|
||||
|
||||
/*
|
||||
ATAG_FRAMEPOINTER, // pointer to extra stack frame space for this function
|
||||
ATAG_DREGISTER, // pointer to a data register
|
||||
ATAG_FREGISTER, // pointer to a float register
|
||||
ATAG_SREGISTER, // pointer to a string register
|
||||
ATAG_AREGISTER, // pointer to an address register
|
||||
*/
|
||||
|
||||
ATAG_RNG, // pointer to FRandom
|
||||
ATAG_STATE = ATAG_GENERIC, // pointer to FState (cannot have its own type because there's no means to track inside the VM.)
|
||||
};
|
||||
|
||||
enum EVMAbortException
|
||||
{
|
||||
X_OTHER,
|
||||
|
@ -322,7 +300,6 @@ extern const VMOpInfo OpInfo[NUM_OPS];
|
|||
struct VMReturn
|
||||
{
|
||||
void *Location;
|
||||
VM_SHALF TagOfs; // for pointers: Offset from Location to ATag; set to 0 if the caller is native code and doesn't care
|
||||
VM_UBYTE RegType; // Same as VMParam RegType, except REGT_KONST is invalid; only used by asserts
|
||||
|
||||
void SetInt(int val)
|
||||
|
@ -366,38 +343,37 @@ struct VMReturn
|
|||
assert(RegType == REGT_STRING);
|
||||
*(FString *)Location = val;
|
||||
}
|
||||
void SetPointer(void *val, int tag)
|
||||
|
||||
void SetPointer(void *val)
|
||||
{
|
||||
assert(RegType == REGT_POINTER);
|
||||
*(void **)Location = val;
|
||||
}
|
||||
|
||||
void SetObject(DObject *val)
|
||||
{
|
||||
assert(RegType == REGT_POINTER);
|
||||
*(void **)Location = val;
|
||||
if (TagOfs != 0)
|
||||
{
|
||||
*((VM_ATAG *)Location + TagOfs) = tag;
|
||||
}
|
||||
}
|
||||
|
||||
void IntAt(int *loc)
|
||||
{
|
||||
Location = loc;
|
||||
TagOfs = 0;
|
||||
RegType = REGT_INT;
|
||||
}
|
||||
void FloatAt(double *loc)
|
||||
{
|
||||
Location = loc;
|
||||
TagOfs = 0;
|
||||
RegType = REGT_FLOAT;
|
||||
}
|
||||
void StringAt(FString *loc)
|
||||
{
|
||||
Location = loc;
|
||||
TagOfs = 0;
|
||||
RegType = REGT_STRING;
|
||||
}
|
||||
void PointerAt(void **loc)
|
||||
{
|
||||
Location = loc;
|
||||
TagOfs = 0;
|
||||
RegType = REGT_POINTER;
|
||||
}
|
||||
VMReturn() { }
|
||||
|
@ -415,7 +391,7 @@ struct VMValue
|
|||
union
|
||||
{
|
||||
int i;
|
||||
struct { void *a; int atag; };
|
||||
void *a;
|
||||
double f;
|
||||
struct { int pad[3]; VM_UBYTE Type; };
|
||||
struct { int foo[4]; } biggest;
|
||||
|
@ -456,19 +432,11 @@ struct VMValue
|
|||
VMValue(DObject *v)
|
||||
{
|
||||
a = v;
|
||||
atag = ATAG_OBJECT;
|
||||
Type = REGT_POINTER;
|
||||
}
|
||||
VMValue(void *v)
|
||||
{
|
||||
a = v;
|
||||
atag = ATAG_GENERIC;
|
||||
Type = REGT_POINTER;
|
||||
}
|
||||
VMValue(void *v, int tag)
|
||||
{
|
||||
a = v;
|
||||
atag = tag;
|
||||
Type = REGT_POINTER;
|
||||
}
|
||||
VMValue &operator=(const VMValue &o)
|
||||
|
@ -499,7 +467,6 @@ struct VMValue
|
|||
VMValue &operator=(DObject *v)
|
||||
{
|
||||
a = v;
|
||||
atag = ATAG_OBJECT;
|
||||
Type = REGT_POINTER;
|
||||
return *this;
|
||||
}
|
||||
|
@ -602,7 +569,7 @@ struct VMFrame
|
|||
int size = (sizeof(VMFrame) + 15) & ~15;
|
||||
size += numparam * sizeof(VMValue);
|
||||
size += numregf * sizeof(double);
|
||||
size += numrega * (sizeof(void *) + sizeof(VM_UBYTE));
|
||||
size += numrega * sizeof(void *);
|
||||
size += numregs * sizeof(FString);
|
||||
size += numregd * sizeof(int);
|
||||
if (numextra != 0)
|
||||
|
@ -613,9 +580,10 @@ struct VMFrame
|
|||
return size;
|
||||
}
|
||||
|
||||
int *GetRegD() const
|
||||
VMValue *GetParam() const
|
||||
{
|
||||
return (int *)(GetRegA() + NumRegA);
|
||||
assert(((size_t)this & 15) == 0 && "VM frame is unaligned");
|
||||
return (VMValue *)(((size_t)(this + 1) + 15) & ~15);
|
||||
}
|
||||
|
||||
double *GetRegF() const
|
||||
|
@ -633,25 +601,19 @@ struct VMFrame
|
|||
return (void **)(GetRegS() + NumRegS);
|
||||
}
|
||||
|
||||
VM_ATAG *GetRegATag() const
|
||||
int *GetRegD() const
|
||||
{
|
||||
return (VM_ATAG *)(GetRegD() + NumRegD);
|
||||
}
|
||||
|
||||
VMValue *GetParam() const
|
||||
{
|
||||
assert(((size_t)this & 15) == 0 && "VM frame is unaligned");
|
||||
return (VMValue *)(((size_t)(this + 1) + 15) & ~15);
|
||||
return (int *)(GetRegA() + NumRegA);
|
||||
}
|
||||
|
||||
void *GetExtra() const
|
||||
{
|
||||
VM_ATAG *ptag = GetRegATag();
|
||||
ptrdiff_t ofs = ptag - (VM_ATAG *)this;
|
||||
return (VM_UBYTE *)this + ((ofs + NumRegA + 15) & ~15);
|
||||
uint8_t *pbeg = (uint8_t*)(GetRegD() + NumRegD);
|
||||
ptrdiff_t ofs = pbeg - (uint8_t *)this;
|
||||
return (VM_UBYTE *)this + ((ofs + 15) & ~15);
|
||||
}
|
||||
|
||||
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VM_ATAG *&atag, VMValue *¶m) const
|
||||
void GetAllRegs(int *&d, double *&f, FString *&s, void **&a, VMValue *¶m) const
|
||||
{
|
||||
// Calling the individual functions produces suboptimal code. :(
|
||||
param = GetParam();
|
||||
|
@ -659,7 +621,6 @@ struct VMFrame
|
|||
s = (FString *)(f + NumRegF);
|
||||
a = (void **)(s + NumRegS);
|
||||
d = (int *)(a + NumRegA);
|
||||
atag = (VM_ATAG *)(d + NumRegD);
|
||||
}
|
||||
|
||||
void InitRegS();
|
||||
|
@ -669,18 +630,17 @@ struct VMRegisters
|
|||
{
|
||||
VMRegisters(const VMFrame *frame)
|
||||
{
|
||||
frame->GetAllRegs(d, f, s, a, atag, param);
|
||||
frame->GetAllRegs(d, f, s, a, param);
|
||||
}
|
||||
|
||||
VMRegisters(const VMRegisters &o)
|
||||
: d(o.d), f(o.f), s(o.s), a(o.a), atag(o.atag), param(o.param)
|
||||
: d(o.d), f(o.f), s(o.s), a(o.a), param(o.param)
|
||||
{ }
|
||||
|
||||
int *d;
|
||||
double *f;
|
||||
FString *s;
|
||||
void **a;
|
||||
VM_ATAG *atag;
|
||||
VMValue *param;
|
||||
};
|
||||
|
||||
|
@ -703,9 +663,6 @@ public:
|
|||
~VMScriptFunction();
|
||||
void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta, int numlinenumbers);
|
||||
|
||||
VM_ATAG *KonstATags() { return (VM_UBYTE *)(KonstA + NumKonstA); }
|
||||
const VM_ATAG *KonstATags() const { return (VM_UBYTE *)(KonstA + NumKonstA); }
|
||||
|
||||
VMOP *Code;
|
||||
FStatementInfo *LineInfo;
|
||||
FString SourceFileName;
|
||||
|
@ -810,14 +767,12 @@ public:
|
|||
void ParamObject(DObject *obj)
|
||||
{
|
||||
Reg.a[RegA] = obj;
|
||||
Reg.atag[RegA] = ATAG_OBJECT;
|
||||
RegA++;
|
||||
}
|
||||
|
||||
void ParamPointer(void *ptr, VM_ATAG atag)
|
||||
void ParamPointer(void *ptr)
|
||||
{
|
||||
Reg.a[RegA] = ptr;
|
||||
Reg.atag[RegA] = atag;
|
||||
RegA++;
|
||||
}
|
||||
|
||||
|
@ -852,8 +807,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
|||
// variable name <x> at position <p>
|
||||
void NullParam(const char *varname);
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool AssertObject(void * ob);
|
||||
#endif
|
||||
|
||||
#define PARAM_NULLCHECK(ptr, var) (ptr == nullptr? NullParam(#var), ptr : ptr)
|
||||
|
||||
#define ASSERTINT(p) assert((p).Type == REGT_INT)
|
||||
#define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT)
|
||||
#define ASSERTSTRING(p) assert((p).Type == REGT_STRING)
|
||||
#define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && AssertObject(p.a))
|
||||
#define ASSERTPOINTER(p) assert((p).Type == REGT_POINTER)
|
||||
|
||||
// For required parameters.
|
||||
#define PARAM_INT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); int x = param[p].i;
|
||||
#define PARAM_UINT_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); unsigned x = param[p].i;
|
||||
|
@ -868,19 +833,13 @@ void NullParam(const char *varname);
|
|||
#define PARAM_STATE_ACTION_AT(p,x) assert((p) < numparam); assert(param[p].Type == REGT_INT); FState *x = (FState *)StateLabels.GetState(param[p].i, stateowner->GetClass());
|
||||
#define PARAM_POINTER_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)param[p].a;
|
||||
#define PARAM_POINTERTYPE_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type x = (type )param[p].a;
|
||||
#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type)));
|
||||
#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base)));
|
||||
#define PARAM_OBJECT_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && AssertObject(param[p].a)); type *x = (type *)param[p].a; assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type)));
|
||||
#define PARAM_CLASS_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && AssertObject(param[p].a)); base::MetaClass *x = (base::MetaClass *)param[p].a; assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base)));
|
||||
#define PARAM_POINTER_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x);
|
||||
#define PARAM_OBJECT_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type)));
|
||||
#define PARAM_CLASS_NOT_NULL_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (param[p].atag == ATAG_OBJECT || param[p].a == NULL)); base::MetaClass *x = (base::MetaClass *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base)));
|
||||
#define PARAM_OBJECT_NOT_NULL_AT(p,x,type) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (AssertObject(param[p].a))); type *x = (type *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsKindOf(RUNTIME_CLASS(type)));
|
||||
#define PARAM_CLASS_NOT_NULL_AT(p,x,base) assert((p) < numparam); assert(param[p].Type == REGT_POINTER && (AssertObject(param[p].a))); base::MetaClass *x = (base::MetaClass *)PARAM_NULLCHECK(param[p].a, #x); assert(x == NULL || x->IsDescendantOf(RUNTIME_CLASS(base)));
|
||||
|
||||
#define PARAM_EXISTS(p) ((p) < numparam)
|
||||
#define ASSERTINT(p) assert((p).Type == REGT_INT)
|
||||
#define ASSERTFLOAT(p) assert((p).Type == REGT_FLOAT)
|
||||
#define ASSERTSTRING(p) assert((p).Type == REGT_STRING)
|
||||
#define ASSERTOBJECT(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_OBJECT || (p).a == nullptr))
|
||||
#define ASSERTPOINTER(p) assert((p).Type == REGT_POINTER && (p).atag == ATAG_GENERIC)
|
||||
#define ASSERTSTATE(p) assert((p).Type == REGT_POINTER && ((p).atag == ATAG_GENERIC || (p).atag == ATAG_STATE))
|
||||
|
||||
#define PARAM_INT_DEF_AT(p,x) int x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = param[p].i; } else { ASSERTINT(defaultparam[p]); x = defaultparam[p].i; }
|
||||
#define PARAM_BOOL_DEF_AT(p,x) bool x; if (PARAM_EXISTS(p)) { ASSERTINT(param[p]); x = !!param[p].i; } else { ASSERTINT(defaultparam[p]); x = !!defaultparam[p].i; }
|
||||
|
@ -1030,9 +989,9 @@ struct AFuncDesc
|
|||
|
||||
class AActor;
|
||||
|
||||
#define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_STATE); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_POINTER(v) do { void *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_GENERIC); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_OBJECT(v) do { auto state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state, ATAG_OBJECT); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_STATE(v) do { FState *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_POINTER(v) do { void *state = v; if (numret > 0) { assert(ret != NULL); ret->SetPointer(state); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_OBJECT(v) do { auto state = v; if (numret > 0) { assert(ret != NULL); ret->SetObject(state); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_FLOAT(v) do { double u = v; if (numret > 0) { assert(ret != nullptr); ret->SetFloat(u); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_VEC2(v) do { DVector2 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector2(u); return 1; } return 0; } while(0)
|
||||
#define ACTION_RETURN_VEC3(v) do { DVector3 u = v; if (numret > 0) { assert(ret != nullptr); ret[0].SetVector(u); return 1; } return 0; } while(0)
|
||||
|
@ -1062,7 +1021,7 @@ class AActor;
|
|||
PARAM_PROLOGUE; \
|
||||
PARAM_OBJECT(self, type);
|
||||
|
||||
// for structs we need to check for ATAG_GENERIC instead of ATAG_OBJECT
|
||||
// for structs we cannot do a class validation
|
||||
#define PARAM_SELF_STRUCT_PROLOGUE(type) \
|
||||
PARAM_PROLOGUE; \
|
||||
PARAM_POINTER(self, type);
|
||||
|
|
|
@ -82,7 +82,6 @@ void ThrowVMException(VMException *x);
|
|||
#define ASSERTF(x) assert((unsigned)(x) < f->NumRegF)
|
||||
#define ASSERTA(x) assert((unsigned)(x) < f->NumRegA)
|
||||
#define ASSERTS(x) assert((unsigned)(x) < f->NumRegS)
|
||||
#define ASSERTO(x) assert((unsigned)(x) < f->NumRegA && reg.atag[x] == ATAG_OBJECT)
|
||||
|
||||
#define ASSERTKD(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstD)
|
||||
#define ASSERTKF(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstF)
|
||||
|
@ -228,10 +227,29 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
|
|||
else
|
||||
{
|
||||
assert(p.Type == REGT_POINTER);
|
||||
calleereg.a[rega] = p.a;
|
||||
calleereg.atag[rega++] = p.atag;
|
||||
calleereg.a[rega++] = p.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
bool AssertObject(void * ob)
|
||||
{
|
||||
auto obj = (DObject*)ob;
|
||||
if (obj == nullptr) return true;
|
||||
#ifdef _MSC_VER
|
||||
__try
|
||||
{
|
||||
return obj->MagicID == DObject::MAGIC_ID;
|
||||
}
|
||||
__except (1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
// No SEH on non-Microsoft compilers. :(
|
||||
return obj->MagicID == DObject::MAGIC_ID;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -11,8 +11,8 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
#include "vmops.h"
|
||||
};
|
||||
#endif
|
||||
const VMOP *exception_frames[MAX_TRY_DEPTH];
|
||||
int try_depth = 0;
|
||||
//const VMOP *exception_frames[MAX_TRY_DEPTH];
|
||||
//int try_depth = 0;
|
||||
VMFrame *f = stack->TopFrame();
|
||||
VMScriptFunction *sfunc;
|
||||
const VMRegisters reg(f);
|
||||
|
@ -20,7 +20,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
const double *konstf;
|
||||
const FString *konsts;
|
||||
const FVoidObj *konsta;
|
||||
const VM_ATAG *konstatag;
|
||||
|
||||
if (f->Func != NULL && !(f->Func->VarFlags & VARF_Native))
|
||||
{
|
||||
|
@ -29,7 +28,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
konstf = sfunc->KonstF;
|
||||
konsts = sfunc->KonstS;
|
||||
konsta = sfunc->KonstA;
|
||||
konstatag = sfunc->KonstATags();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -38,7 +36,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
konstf = NULL;
|
||||
konsts = NULL;
|
||||
konsta = NULL;
|
||||
konstatag = NULL;
|
||||
}
|
||||
|
||||
void *ptr;
|
||||
|
@ -46,7 +43,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
|||
const double *fbp, *fcp;
|
||||
int a, b, c;
|
||||
|
||||
begin:
|
||||
//begin:
|
||||
try
|
||||
{
|
||||
#if !COMPGOTO
|
||||
|
@ -81,7 +78,6 @@ begin:
|
|||
OP(LKP):
|
||||
ASSERTA(a); ASSERTKA(BC);
|
||||
reg.a[a] = konsta[BC].v;
|
||||
reg.atag[a] = konstatag[BC];
|
||||
NEXTOP;
|
||||
|
||||
OP(LK_R) :
|
||||
|
@ -100,25 +96,21 @@ begin:
|
|||
ASSERTA(a); ASSERTD(B);
|
||||
b = reg.d[B] + C;
|
||||
reg.a[a] = konsta[b].v;
|
||||
reg.atag[a] = konstatag[b];
|
||||
NEXTOP;
|
||||
|
||||
OP(LFP):
|
||||
ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0);
|
||||
reg.a[a] = f->GetExtra();
|
||||
reg.atag[a] = ATAG_GENERIC; // using ATAG_FRAMEPOINTER will cause endless asserts.
|
||||
NEXTOP;
|
||||
|
||||
OP(CLSS):
|
||||
ASSERTA(a); ASSERTO(B);
|
||||
ASSERTA(a); ASSERTA(B);
|
||||
reg.a[a] = ((DObject*)reg.a[B])->GetClass(); // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer...
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
|
||||
OP(META):
|
||||
ASSERTA(a); ASSERTO(B);
|
||||
ASSERTA(a); ASSERTA(B);
|
||||
reg.a[a] = ((DObject*)reg.a[B])->GetClass()->Meta; // I wish this could be done without a special opcode but there's really no good way to guarantee initialization of the Class pointer...
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
|
||||
OP(LB):
|
||||
|
@ -217,37 +209,31 @@ begin:
|
|||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||
GETADDR(PB,KC,X_READ_NIL);
|
||||
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(LO_R):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||
GETADDR(PB,RC,X_READ_NIL);
|
||||
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(LOS):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||
GETADDR(PB,KC,X_READ_NIL);
|
||||
reg.a[a] = *(DObject **)ptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(LOS_R):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||
GETADDR(PB,RC,X_READ_NIL);
|
||||
reg.a[a] = *(DObject **)ptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(LP):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||
GETADDR(PB,KC,X_READ_NIL);
|
||||
reg.a[a] = *(void **)ptr;
|
||||
reg.atag[a] = ATAG_GENERIC;
|
||||
NEXTOP;
|
||||
OP(LP_R):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||
GETADDR(PB,RC,X_READ_NIL);
|
||||
reg.a[a] = *(void **)ptr;
|
||||
reg.atag[a] = ATAG_GENERIC;
|
||||
NEXTOP;
|
||||
OP(LV2):
|
||||
ASSERTF(a+1); ASSERTA(B); ASSERTKD(C);
|
||||
|
@ -442,7 +428,6 @@ begin:
|
|||
ASSERTA(a); ASSERTA(B);
|
||||
b = B;
|
||||
reg.a[a] = reg.a[b];
|
||||
reg.atag[a] = reg.atag[b];
|
||||
NEXTOP;
|
||||
}
|
||||
OP(MOVEV2):
|
||||
|
@ -466,25 +451,21 @@ begin:
|
|||
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
||||
b = B;
|
||||
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(DYNCAST_K) :
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
||||
b = B;
|
||||
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(DYNCASTC_R) :
|
||||
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
||||
b = B;
|
||||
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(DYNCASTC_K) :
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
||||
b = B;
|
||||
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
OP(CAST):
|
||||
if (C == CAST_I2F)
|
||||
|
@ -575,7 +556,7 @@ begin:
|
|||
break;
|
||||
case REGT_INT | REGT_ADDROF:
|
||||
assert(C < f->NumRegD);
|
||||
::new(param) VMValue(®.d[C], ATAG_GENERIC);
|
||||
::new(param) VMValue(®.d[C]);
|
||||
break;
|
||||
case REGT_INT | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstD);
|
||||
|
@ -587,7 +568,7 @@ begin:
|
|||
break;
|
||||
case REGT_STRING | REGT_ADDROF:
|
||||
assert(C < f->NumRegS);
|
||||
::new(param) VMValue(®.s[C], ATAG_GENERIC);
|
||||
::new(param) VMValue((void*)®.s[C]); // Note that this may not use the FString* version of the constructor!
|
||||
break;
|
||||
case REGT_STRING | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstS);
|
||||
|
@ -595,15 +576,15 @@ begin:
|
|||
break;
|
||||
case REGT_POINTER:
|
||||
assert(C < f->NumRegA);
|
||||
::new(param) VMValue(reg.a[C], reg.atag[C]);
|
||||
::new(param) VMValue(reg.a[C]);
|
||||
break;
|
||||
case REGT_POINTER | REGT_ADDROF:
|
||||
assert(C < f->NumRegA);
|
||||
::new(param) VMValue(®.a[C], ATAG_GENERIC);
|
||||
::new(param) VMValue(®.a[C]);
|
||||
break;
|
||||
case REGT_POINTER | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstA);
|
||||
::new(param) VMValue(konsta[C].v, konstatag[C]);
|
||||
::new(param) VMValue(konsta[C].v);
|
||||
break;
|
||||
case REGT_FLOAT:
|
||||
assert(C < f->NumRegF);
|
||||
|
@ -626,7 +607,7 @@ begin:
|
|||
break;
|
||||
case REGT_FLOAT | REGT_ADDROF:
|
||||
assert(C < f->NumRegF);
|
||||
::new(param) VMValue(®.f[C], ATAG_GENERIC);
|
||||
::new(param) VMValue(®.f[C]);
|
||||
break;
|
||||
case REGT_FLOAT | REGT_KONST:
|
||||
assert(C < sfunc->NumKonstF);
|
||||
|
@ -657,7 +638,6 @@ begin:
|
|||
|
||||
OP(CALL_K):
|
||||
ASSERTKA(a);
|
||||
assert(konstatag[a] == ATAG_OBJECT);
|
||||
ptr = konsta[a].o;
|
||||
goto Do_CALL;
|
||||
OP(CALL):
|
||||
|
@ -713,7 +693,6 @@ begin:
|
|||
NEXTOP;
|
||||
OP(TAIL_K):
|
||||
ASSERTKA(a);
|
||||
assert(konstatag[a] == ATAG_OBJECT);
|
||||
ptr = konsta[a].o;
|
||||
goto Do_TAILCALL;
|
||||
OP(TAIL):
|
||||
|
@ -825,10 +804,10 @@ begin:
|
|||
c = C;
|
||||
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
|
||||
reg.a[a] = cls->CreateNew();
|
||||
reg.atag[a] = ATAG_OBJECT;
|
||||
NEXTOP;
|
||||
}
|
||||
|
||||
#if 0
|
||||
OP(TRY):
|
||||
assert(try_depth < MAX_TRY_DEPTH);
|
||||
if (try_depth >= MAX_TRY_DEPTH)
|
||||
|
@ -842,7 +821,9 @@ begin:
|
|||
assert(a <= try_depth);
|
||||
try_depth -= a;
|
||||
NEXTOP;
|
||||
#endif
|
||||
OP(THROW):
|
||||
#if 0
|
||||
if (a == 0)
|
||||
{
|
||||
ASSERTA(B);
|
||||
|
@ -851,19 +832,22 @@ begin:
|
|||
else if (a == 1)
|
||||
{
|
||||
ASSERTKA(B);
|
||||
assert(konstatag[B] == ATAG_OBJECT);
|
||||
assert(AssertObject(konsta[B].o));
|
||||
ThrowVMException((VMException *)konsta[B].o);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ThrowAbortException(EVMAbortException(BC), nullptr);
|
||||
}
|
||||
NEXTOP;
|
||||
#if 0
|
||||
OP(CATCH):
|
||||
// This instruction is handled by our own catch handler and should
|
||||
// not be executed by the normal VM code.
|
||||
assert(0);
|
||||
NEXTOP;
|
||||
#endif
|
||||
|
||||
OP(BOUND):
|
||||
if (reg.d[a] >= BC)
|
||||
|
@ -1658,7 +1642,6 @@ begin:
|
|||
c = 0;
|
||||
}
|
||||
reg.a[a] = (VM_UBYTE *)reg.a[B] + c;
|
||||
reg.atag[a] = c == 0 ? reg.atag[B] : (int)ATAG_GENERIC;
|
||||
NEXTOP;
|
||||
OP(ADDA_RK):
|
||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||
|
@ -1683,6 +1666,7 @@ begin:
|
|||
NEXTOP;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
catch(VMException *exception)
|
||||
{
|
||||
// Try to find a handler for the exception.
|
||||
|
@ -1709,7 +1693,6 @@ begin:
|
|||
{
|
||||
assert(pc->a == 3);
|
||||
ASSERTKA(b);
|
||||
assert(konstatag[b] == ATAG_OBJECT);
|
||||
type = (PClass *)konsta[b].o;
|
||||
}
|
||||
ASSERTA(pc->c);
|
||||
|
@ -1718,7 +1701,6 @@ begin:
|
|||
// Found a handler. Store the exception in pC, skip the JMP,
|
||||
// and begin executing its code.
|
||||
reg.a[pc->c] = exception;
|
||||
reg.atag[pc->c] = ATAG_OBJECT;
|
||||
pc += 2;
|
||||
goto begin;
|
||||
}
|
||||
|
@ -1731,7 +1713,6 @@ begin:
|
|||
// Catch any type of VMException. This terminates the chain.
|
||||
ASSERTA(pc->c);
|
||||
reg.a[pc->c] = exception;
|
||||
reg.atag[pc->c] = ATAG_OBJECT;
|
||||
pc += 1;
|
||||
goto begin;
|
||||
}
|
||||
|
@ -1740,6 +1721,7 @@ begin:
|
|||
// Nothing caught it. Rethrow and let somebody else deal with it.
|
||||
throw;
|
||||
}
|
||||
#endif
|
||||
catch (CVMAbortException &err)
|
||||
{
|
||||
err.MaybePrintMessage();
|
||||
|
@ -1831,16 +1813,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c
|
|||
{
|
||||
ASSERTS(a); ASSERTA(b);
|
||||
if (reg.a[b] == nullptr) reg.s[a] = "null";
|
||||
else if (reg.atag[b] == ATAG_OBJECT)
|
||||
{
|
||||
auto op = static_cast<DObject*>(reg.a[b]);
|
||||
if (op->IsKindOf(RUNTIME_CLASS(PClass))) reg.s[a].Format("Class<%s>", static_cast<PClass*>(op)->TypeName.GetChars());
|
||||
else reg.s[a].Format("Object<%p>", ((DObject*)reg.a[b])->GetClass()->TypeName.GetChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
reg.s[a].Format("%s<%p>", "Pointer", reg.a[b]);
|
||||
}
|
||||
else reg.s[a].Format("%p", reg.a[b]);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1922,7 +1895,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return
|
|||
for (i = 0, ret = returns; i < numret; ++i, ++ret, ++retval)
|
||||
{
|
||||
assert(retval->op == OP_RESULT); // opcode
|
||||
ret->TagOfs = 0;
|
||||
ret->RegType = type = retval->b;
|
||||
regnum = retval->c;
|
||||
assert(!(type & REGT_KONST));
|
||||
|
@ -1950,7 +1922,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return
|
|||
assert(type == REGT_POINTER);
|
||||
assert(regnum < frame->NumRegA);
|
||||
ret->Location = ®.a[regnum];
|
||||
ret->TagOfs = (VM_SHALF)(&frame->GetRegATag()[regnum] - (VM_ATAG *)ret->Location);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2033,12 +2004,12 @@ static void SetReturn(const VMRegisters ®, VMFrame *frame, VMReturn *ret, VM_
|
|||
if (regtype & REGT_KONST)
|
||||
{
|
||||
assert(regnum < func->NumKonstA);
|
||||
ret->SetPointer(func->KonstA[regnum].v, func->KonstATags()[regnum]);
|
||||
ret->SetPointer(func->KonstA[regnum].v);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(regnum < frame->NumRegA);
|
||||
ret->SetPointer(reg.a[regnum], reg.atag[regnum]);
|
||||
ret->SetPointer(reg.a[regnum]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -97,7 +97,7 @@ void VMScriptFunction::Alloc(int numops, int numkonstd, int numkonstf, int numko
|
|||
numkonstd * sizeof(int) +
|
||||
numkonstf * sizeof(double) +
|
||||
numkonsts * sizeof(FString) +
|
||||
numkonsta * (sizeof(FVoidObj) + 1) +
|
||||
numkonsta * sizeof(FVoidObj) +
|
||||
numlinenumbers * sizeof(FStatementInfo));
|
||||
Code = (VMOP *)mem;
|
||||
mem = (void *)((VMOP *)mem + numops);
|
||||
|
|
|
@ -114,12 +114,12 @@ xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to
|
|||
xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning
|
||||
xx(NEW, new, RPRPI8, NOP, 0, 0),
|
||||
xx(NEW_K, new, RPKP, NOP, 0, 0),
|
||||
xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC
|
||||
xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack
|
||||
//xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC
|
||||
//xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack
|
||||
xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB
|
||||
// A == 1: Throw exception object pkB
|
||||
// A >= 2: Throw VM exception of type BC
|
||||
xx(CATCH, catch, CATCH, NOP, 0, 0), // A == 0: continue search on next try
|
||||
//xx(CATCH, catch, CATCH, NOP, 0, 0), // A == 0: continue search on next try
|
||||
// A == 1: continue execution at instruction immediately following CATCH (catches any exception)
|
||||
// A == 2: (pB == <type of exception thrown>) then pc++ ; next instruction must JMP to another CATCH
|
||||
// A == 3: (pkB == <type of exception thrown>) then pc++ ; next instruction must JMP to another CATCH
|
||||
|
|
|
@ -46,7 +46,7 @@ void *RenderMemory::AllocBytes(int size)
|
|||
}
|
||||
else
|
||||
{
|
||||
UsedBlocks.push_back(std::make_unique<MemoryBlock>());
|
||||
UsedBlocks.push_back(std::unique_ptr<MemoryBlock>(new MemoryBlock()));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,21 +60,21 @@ namespace swrenderer
|
|||
{
|
||||
Scene = scene;
|
||||
MainThread = mainThread;
|
||||
FrameMemory = std::make_unique<RenderMemory>();
|
||||
Viewport = std::make_unique<RenderViewport>();
|
||||
Light = std::make_unique<LightVisibility>();
|
||||
DrawQueue = std::make_shared<DrawerCommandQueue>(FrameMemory.get());
|
||||
OpaquePass = std::make_unique<RenderOpaquePass>(this);
|
||||
TranslucentPass = std::make_unique<RenderTranslucentPass>(this);
|
||||
SpriteList = std::make_unique<VisibleSpriteList>();
|
||||
Portal = std::make_unique<RenderPortal>(this);
|
||||
Clip3D = std::make_unique<Clip3DFloors>(this);
|
||||
PlayerSprites = std::make_unique<RenderPlayerSprites>(this);
|
||||
PlaneList = std::make_unique<VisiblePlaneList>(this);
|
||||
DrawSegments = std::make_unique<DrawSegmentList>(this);
|
||||
ClipSegments = std::make_unique<RenderClipSegment>();
|
||||
tc_drawers = std::make_unique<SWTruecolorDrawers>(DrawQueue);
|
||||
pal_drawers = std::make_unique<SWPalDrawers>(DrawQueue);
|
||||
FrameMemory.reset(new RenderMemory());
|
||||
Viewport.reset(new RenderViewport());
|
||||
Light.reset(new LightVisibility());
|
||||
DrawQueue.reset(new DrawerCommandQueue(FrameMemory.get()));
|
||||
OpaquePass.reset(new RenderOpaquePass(this));
|
||||
TranslucentPass.reset(new RenderTranslucentPass(this));
|
||||
SpriteList.reset(new VisibleSpriteList());
|
||||
Portal.reset(new RenderPortal(this));
|
||||
Clip3D.reset(new Clip3DFloors(this));
|
||||
PlayerSprites.reset(new RenderPlayerSprites(this));
|
||||
PlaneList.reset(new VisiblePlaneList(this));
|
||||
DrawSegments.reset(new DrawSegmentList(this));
|
||||
ClipSegments.reset(new RenderClipSegment());
|
||||
tc_drawers.reset(new SWTruecolorDrawers(DrawQueue));
|
||||
pal_drawers.reset(new SWPalDrawers(DrawQueue));
|
||||
}
|
||||
|
||||
RenderThread::~RenderThread()
|
||||
|
|
|
@ -61,7 +61,7 @@ namespace swrenderer
|
|||
|
||||
RenderScene::RenderScene()
|
||||
{
|
||||
Threads.push_back(std::make_unique<RenderThread>(this));
|
||||
Threads.push_back(std::unique_ptr<RenderThread>(new RenderThread(this)));
|
||||
}
|
||||
|
||||
RenderScene::~RenderScene()
|
||||
|
@ -289,7 +289,7 @@ namespace swrenderer
|
|||
{
|
||||
while (Threads.size() < (size_t)numThreads)
|
||||
{
|
||||
auto thread = std::make_unique<RenderThread>(this, false);
|
||||
std::unique_ptr<RenderThread> thread(new RenderThread(this, false));
|
||||
auto renderthread = thread.get();
|
||||
int start_run_id = run_id;
|
||||
thread->thread = std::thread([=]()
|
||||
|
|
|
@ -25,6 +25,8 @@ class Inventory : Actor native
|
|||
native bool bInitEffectFailed;
|
||||
meta String PickupMsg;
|
||||
meta int GiveQuest;
|
||||
meta array<class<Actor> > ForbiddenToPlayerClass;
|
||||
meta array<class<Actor> > RestrictedToPlayerClass;
|
||||
|
||||
property PickupMessage: PickupMsg;
|
||||
property GiveQuest: GiveQuest;
|
||||
|
@ -46,7 +48,6 @@ class Inventory : Actor native
|
|||
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG";
|
||||
}
|
||||
|
||||
native bool CanPickup(Actor toucher);
|
||||
native bool DoRespawn();
|
||||
native void BecomeItem();
|
||||
native void BecomePickup();
|
||||
|
@ -330,6 +331,36 @@ class Inventory : Actor native
|
|||
}
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: CanPickup
|
||||
//
|
||||
//===========================================================================
|
||||
|
||||
virtual bool CanPickup(Actor toucher)
|
||||
{
|
||||
if (toucher == null) return false;
|
||||
|
||||
int rsize = RestrictedToPlayerClass.Size();
|
||||
if (rsize > 0)
|
||||
{
|
||||
for (int i=0; i < rsize; i++)
|
||||
{
|
||||
if (toucher is RestrictedToPlayerClass[i]) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
rsize = ForbiddenToPlayerClass.Size();
|
||||
if (rsize > 0)
|
||||
{
|
||||
for (int i=0; i < rsize; i++)
|
||||
{
|
||||
if (toucher is ForbiddenToPlayerClass[i]) return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
// AInventory :: CallTryPickup
|
||||
|
|
Loading…
Reference in a new issue