mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-11 07:12:16 +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);
|
I_Error("No class found for dehackednum %d!\n", value1+1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int typereg = buildit.GetConstantAddress(InfoNames[value1-1], ATAG_OBJECT);
|
int typereg = buildit.GetConstantAddress(InfoNames[value1-1]);
|
||||||
int heightreg = buildit.GetConstantFloat(value2);
|
int heightreg = buildit.GetConstantFloat(value2);
|
||||||
|
|
||||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, typereg); // itemtype
|
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
|
// misc1 = state, misc2 = probability
|
||||||
static int CreateRandomJumpFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
static int CreateRandomJumpFunc(VMFunctionBuilder &buildit, int value1, int value2)
|
||||||
{ // A_Jump
|
{ // A_Jump
|
||||||
int statereg = buildit.GetConstantAddress(FindState(value1), ATAG_STATE);
|
int statereg = buildit.GetConstantAddress(FindState(value1));
|
||||||
|
|
||||||
buildit.EmitParamInt(value2); // maxchance
|
buildit.EmitParamInt(value2); // maxchance
|
||||||
buildit.Emit(OP_PARAM, 0, REGT_POINTER | REGT_KONST, statereg); // jumpto
|
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.
|
// Emit code for action parameters.
|
||||||
int argcount = MBFCodePointerFactories[codepointer](buildit, value1, value2);
|
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.
|
// Attach it to the state.
|
||||||
VMScriptFunction *sfunc = new VMScriptFunction;
|
VMScriptFunction *sfunc = new VMScriptFunction;
|
||||||
buildit.MakeFunction(sfunc);
|
buildit.MakeFunction(sfunc);
|
||||||
|
|
|
@ -200,6 +200,14 @@ protected:
|
||||||
enum { MetaClassNum = CLASSREG_PClass };
|
enum { MetaClassNum = CLASSREG_PClass };
|
||||||
|
|
||||||
// Per-instance variables. There are four.
|
// 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:
|
private:
|
||||||
PClass *Class; // This object's type
|
PClass *Class; // This object's type
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -780,6 +780,15 @@ PFloat::PFloat(unsigned int size)
|
||||||
mDescriptiveName.Format("Float%d", size);
|
mDescriptiveName.Format("Float%d", size);
|
||||||
if (size == 8)
|
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();
|
SetDoubleSymbols();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -363,7 +363,7 @@ static PClassActor * T_GetAmmo(const svalue_t &t)
|
||||||
p=DefAmmo[ammonum];
|
p=DefAmmo[ammonum];
|
||||||
}
|
}
|
||||||
auto am = PClass::FindActor(p);
|
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);
|
script_error("unknown ammo type : %s", p);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2436,7 +2436,7 @@ static void FS_GiveInventory (AActor *actor, const char * type, int amount)
|
||||||
type = "BasicArmorPickup";
|
type = "BasicArmorPickup";
|
||||||
}
|
}
|
||||||
auto info = PClass::FindActor (type);
|
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);
|
Printf ("Unknown inventory item: %s\n", type);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -484,43 +484,6 @@ bool AInventory::CallTryPickup(AActor *toucher, AActor **toucher_return)
|
||||||
return !!res;
|
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
|
// CCMD printinv
|
||||||
|
|
|
@ -635,7 +635,7 @@ void InitAllPowerupEffects(AInventory *item)
|
||||||
{
|
{
|
||||||
if (item->IsKindOf(ptype))
|
if (item->IsKindOf(ptype))
|
||||||
{
|
{
|
||||||
IFVIRTUALPTRNAME(item, NAME_Powerup, EndEffect)
|
IFVIRTUALPTRNAME(item, NAME_Powerup, InitEffect)
|
||||||
{
|
{
|
||||||
VMValue params[1] = { item };
|
VMValue params[1] = { item };
|
||||||
VMFrameStack stack;
|
VMFrameStack stack;
|
||||||
|
|
|
@ -38,7 +38,7 @@ void FLinearDepthShader::Bind()
|
||||||
|
|
||||||
if (!mShader)
|
if (!mShader)
|
||||||
{
|
{
|
||||||
mShader = std::make_unique<FShaderProgram>();
|
mShader.reset(new FShaderProgram());
|
||||||
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||||
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/lineardepth.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
||||||
mShader->SetFragDataLocation(0, "FragColor");
|
mShader->SetFragDataLocation(0, "FragColor");
|
||||||
|
@ -66,7 +66,7 @@ void FSSAOShader::Bind()
|
||||||
|
|
||||||
if (!mShader)
|
if (!mShader)
|
||||||
{
|
{
|
||||||
mShader = std::make_unique<FShaderProgram>();
|
mShader.reset(new FShaderProgram());
|
||||||
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||||
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssao.fp", GetDefines(gl_ssao, multisample), 330);
|
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssao.fp", GetDefines(gl_ssao, multisample), 330);
|
||||||
mShader->SetFragDataLocation(0, "FragColor");
|
mShader->SetFragDataLocation(0, "FragColor");
|
||||||
|
@ -142,7 +142,7 @@ void FSSAOCombineShader::Bind()
|
||||||
|
|
||||||
if (!mShader)
|
if (!mShader)
|
||||||
{
|
{
|
||||||
mShader = std::make_unique<FShaderProgram>();
|
mShader.reset(new FShaderProgram());
|
||||||
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
mShader->Compile(FShaderProgram::Vertex, "shaders/glsl/screenquad.vp", "", 330);
|
||||||
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
mShader->Compile(FShaderProgram::Fragment, "shaders/glsl/ssaocombine.fp", multisample ? "#define MULTISAMPLE\n" : "", 330);
|
||||||
mShader->SetFragDataLocation(0, "FragColor");
|
mShader->SetFragDataLocation(0, "FragColor");
|
||||||
|
|
|
@ -316,7 +316,7 @@ OpenGLSWFrameBuffer::HWPixelShader::~HWPixelShader()
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::CreateFrameBuffer(const FString &name, int width, int height, HWFrameBuffer **outFramebuffer)
|
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;
|
GLint format = GL_RGBA16F;
|
||||||
if (gl.es) format = GL_RGB;
|
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)
|
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();
|
shader->Program = glCreateProgram();
|
||||||
if (shader->Program == 0) { Printf("glCreateProgram failed. Disabling OpenGL hardware acceleration.\n"); return false; }
|
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)
|
bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVertexBuffer)
|
||||||
{
|
{
|
||||||
auto obj = std::make_unique<HWVertexBuffer>();
|
std::unique_ptr<HWVertexBuffer> obj(new HWVertexBuffer());
|
||||||
|
|
||||||
obj->Size = size;
|
obj->Size = size;
|
||||||
|
|
||||||
|
@ -474,7 +474,7 @@ bool OpenGLSWFrameBuffer::CreateVertexBuffer(int size, HWVertexBuffer **outVerte
|
||||||
|
|
||||||
bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer)
|
bool OpenGLSWFrameBuffer::CreateIndexBuffer(int size, HWIndexBuffer **outIndexBuffer)
|
||||||
{
|
{
|
||||||
auto obj = std::make_unique<HWIndexBuffer>();
|
std::unique_ptr<HWIndexBuffer> obj(new HWIndexBuffer());
|
||||||
|
|
||||||
obj->Size = size;
|
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)
|
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;
|
obj->Format = format;
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ bool OpenGLSWFrameBuffer::CreateTexture(const FString &name, int width, int heig
|
||||||
|
|
||||||
OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::CopyCurrentScreen()
|
OpenGLSWFrameBuffer::HWTexture *OpenGLSWFrameBuffer::CopyCurrentScreen()
|
||||||
{
|
{
|
||||||
auto obj = std::make_unique<HWTexture>();
|
std::unique_ptr<HWTexture> obj(new HWTexture());
|
||||||
obj->Format = GL_RGBA16F;
|
obj->Format = GL_RGBA16F;
|
||||||
|
|
||||||
GLint oldBinding = 0;
|
GLint oldBinding = 0;
|
||||||
|
@ -611,7 +611,7 @@ void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const FBVERTEX *vertices)
|
||||||
|
|
||||||
if (!StreamVertexBuffer)
|
if (!StreamVertexBuffer)
|
||||||
{
|
{
|
||||||
StreamVertexBuffer = std::make_unique<HWVertexBuffer>();
|
StreamVertexBuffer.reset(new HWVertexBuffer());
|
||||||
glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray);
|
glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray);
|
||||||
glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer);
|
glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer);
|
||||||
glBindVertexArray(StreamVertexBuffer->VertexArray);
|
glBindVertexArray(StreamVertexBuffer->VertexArray);
|
||||||
|
@ -648,7 +648,7 @@ void OpenGLSWFrameBuffer::DrawTriangleFans(int count, const BURNVERTEX *vertices
|
||||||
|
|
||||||
if (!StreamVertexBufferBurn)
|
if (!StreamVertexBufferBurn)
|
||||||
{
|
{
|
||||||
StreamVertexBufferBurn = std::make_unique<HWVertexBuffer>();
|
StreamVertexBufferBurn.reset(new HWVertexBuffer());
|
||||||
glGenVertexArrays(1, (GLuint*)&StreamVertexBufferBurn->VertexArray);
|
glGenVertexArrays(1, (GLuint*)&StreamVertexBufferBurn->VertexArray);
|
||||||
glGenBuffers(1, (GLuint*)&StreamVertexBufferBurn->Buffer);
|
glGenBuffers(1, (GLuint*)&StreamVertexBufferBurn->Buffer);
|
||||||
glBindVertexArray(StreamVertexBufferBurn->VertexArray);
|
glBindVertexArray(StreamVertexBufferBurn->VertexArray);
|
||||||
|
@ -679,7 +679,7 @@ void OpenGLSWFrameBuffer::DrawPoints(int count, const FBVERTEX *vertices)
|
||||||
|
|
||||||
if (!StreamVertexBuffer)
|
if (!StreamVertexBuffer)
|
||||||
{
|
{
|
||||||
StreamVertexBuffer = std::make_unique<HWVertexBuffer>();
|
StreamVertexBuffer.reset(new HWVertexBuffer());
|
||||||
glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray);
|
glGenVertexArrays(1, (GLuint*)&StreamVertexBuffer->VertexArray);
|
||||||
glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer);
|
glGenBuffers(1, (GLuint*)&StreamVertexBuffer->Buffer);
|
||||||
glBindVertexArray(StreamVertexBuffer->VertexArray);
|
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();
|
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 the function returns a state, store it at *stateret.
|
||||||
// If it doesn't return a state but stateret is non-NULL, we need
|
// If it doesn't return a state but stateret is non-NULL, we need
|
||||||
// to set *stateret to NULL.
|
// to set *stateret to NULL.
|
||||||
|
@ -314,10 +314,6 @@ void PClassActor::DeriveData(PClass *newclass)
|
||||||
*newa->PainChances = *PainChances;
|
*newa->PainChances = *PainChances;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inventory stuff
|
|
||||||
newa->ForbiddenToPlayerClass = ForbiddenToPlayerClass;
|
|
||||||
newa->RestrictedToPlayerClass = RestrictedToPlayerClass;
|
|
||||||
|
|
||||||
newa->DisplayName = DisplayName;
|
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
|
// DmgFactors :: CheckFactor
|
||||||
|
|
|
@ -248,7 +248,6 @@ public:
|
||||||
PClassActor();
|
PClassActor();
|
||||||
~PClassActor();
|
~PClassActor();
|
||||||
|
|
||||||
virtual size_t PointerSubstitution(DObject *oldclass, DObject *newclass);
|
|
||||||
void BuildDefaults();
|
void BuildDefaults();
|
||||||
void ApplyDefaults(uint8_t *defaults);
|
void ApplyDefaults(uint8_t *defaults);
|
||||||
void RegisterIDs();
|
void RegisterIDs();
|
||||||
|
@ -292,10 +291,6 @@ public:
|
||||||
FString SourceLumpName;
|
FString SourceLumpName;
|
||||||
FIntCVar *distancecheck;
|
FIntCVar *distancecheck;
|
||||||
|
|
||||||
// These are only valid for inventory items.
|
|
||||||
TArray<PClassActor *> RestrictedToPlayerClass;
|
|
||||||
TArray<PClassActor *> ForbiddenToPlayerClass;
|
|
||||||
|
|
||||||
// This is from PClassPlayerPawn
|
// This is from PClassPlayerPawn
|
||||||
FString DisplayName;
|
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)
|
if (stream.avail_in == 0 && chunklen > 0)
|
||||||
{
|
{
|
||||||
stream.next_in = chunkbuffer;
|
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;
|
chunklen -= stream.avail_in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -902,3 +902,5 @@ xx(Player6)
|
||||||
xx(Player7)
|
xx(Player7)
|
||||||
xx(Player8)
|
xx(Player8)
|
||||||
xx(PlayerChunk)
|
xx(PlayerChunk)
|
||||||
|
xx(RestrictedToPlayerClass)
|
||||||
|
xx(ForbiddenToPlayerClass)
|
||||||
|
|
|
@ -153,7 +153,7 @@ bool AStateProvider::CallStateChain (AActor *actor, FState *state)
|
||||||
VMReturn *wantret;
|
VMReturn *wantret;
|
||||||
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
|
FStateParamInfo stp = { state, STATE_StateChain, PSP_WEAPON };
|
||||||
|
|
||||||
params[2] = VMValue(&stp, ATAG_GENERIC);
|
params[2] = VMValue(&stp);
|
||||||
retval = true; // assume success
|
retval = true; // assume success
|
||||||
wantret = NULL; // assume no return value wanted
|
wantret = NULL; // assume no return value wanted
|
||||||
numret = 0;
|
numret = 0;
|
||||||
|
@ -2723,7 +2723,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem)
|
||||||
PARAM_BOOL_DEF (useammo)
|
PARAM_BOOL_DEF (useammo)
|
||||||
PARAM_BOOL_DEF (transfer_translation);
|
PARAM_BOOL_DEF (transfer_translation);
|
||||||
|
|
||||||
if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT);
|
if (numret > 1) ret[1].SetObject(nullptr);
|
||||||
|
|
||||||
if (missile == NULL)
|
if (missile == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2760,7 +2760,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItem)
|
||||||
int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0);
|
int flags = (transfer_translation ? SIXF_TRANSFERTRANSLATION : 0) + (useammo ? SIXF_SETMASTER : 0);
|
||||||
bool res = InitSpawnedItem(self, mo, flags); // for an inventory item's use state
|
bool res = InitSpawnedItem(self, mo, flags); // for an inventory item's use state
|
||||||
if (numret > 0) ret[0].SetInt(res);
|
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);
|
return MIN(numret, 2);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2787,7 +2787,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx)
|
||||||
PARAM_INT_DEF (chance)
|
PARAM_INT_DEF (chance)
|
||||||
PARAM_INT_DEF (tid)
|
PARAM_INT_DEF (tid)
|
||||||
|
|
||||||
if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT);
|
if (numret > 1) ret[1].SetObject(nullptr);
|
||||||
|
|
||||||
if (missile == NULL)
|
if (missile == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2852,7 +2852,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_SpawnItemEx)
|
||||||
mo->Angles.Yaw = angle;
|
mo->Angles.Yaw = angle;
|
||||||
}
|
}
|
||||||
if (numret > 0) ret[0].SetInt(res);
|
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);
|
return MIN(numret, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2872,7 +2872,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade)
|
||||||
PARAM_FLOAT_DEF (zvel)
|
PARAM_FLOAT_DEF (zvel)
|
||||||
PARAM_BOOL_DEF (useammo)
|
PARAM_BOOL_DEF (useammo)
|
||||||
|
|
||||||
if (numret > 1) ret[1].SetPointer(nullptr, ATAG_OBJECT);
|
if (numret > 1) ret[1].SetObject(nullptr);
|
||||||
|
|
||||||
if (missile == NULL)
|
if (missile == NULL)
|
||||||
{
|
{
|
||||||
|
@ -2934,7 +2934,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_ThrowGrenade)
|
||||||
if (!P_CheckMissileSpawn(bo, self->radius)) bo = nullptr;
|
if (!P_CheckMissileSpawn(bo, self->radius)) bo = nullptr;
|
||||||
|
|
||||||
if (numret > 0) ret[0].SetInt(true);
|
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);
|
return MIN(numret, 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4363,7 +4363,7 @@ DEFINE_ACTION_FUNCTION(AStateProvider, A_CheckForReload)
|
||||||
|
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
ret->SetPointer(NULL, ATAG_STATE);
|
ret->SetPointer(NULL);
|
||||||
numret = 1;
|
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.
|
// Go back to the refire frames, instead of continuing on to the reload frames.
|
||||||
if (numret != 0)
|
if (numret != 0)
|
||||||
{
|
{
|
||||||
ret->SetPointer(jump, ATAG_STATE);
|
ret->SetPointer(jump);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4903,7 +4903,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Teleport)
|
||||||
}
|
}
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
ret[0].SetPointer(NULL, ATAG_STATE);
|
ret[0].SetPointer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ref)
|
if (!ref)
|
||||||
|
@ -5039,7 +5039,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Teleport)
|
||||||
}
|
}
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
ret[0].SetPointer(teleport_state, ATAG_STATE);
|
ret[0].SetPointer(teleport_state);
|
||||||
}
|
}
|
||||||
return numret;
|
return numret;
|
||||||
}
|
}
|
||||||
|
@ -5337,7 +5337,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_Warp)
|
||||||
}
|
}
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
ret[0].SetPointer(NULL, ATAG_STATE);
|
ret[0].SetPointer(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & WARPF_USETID))
|
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.
|
// in this case, you have the statejump to help you handle all the success anyway.
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
ret[0].SetPointer(success_state, ATAG_STATE);
|
ret[0].SetPointer(success_state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (numret > 1)
|
else if (numret > 1)
|
||||||
|
|
|
@ -2054,7 +2054,7 @@ DEFINE_ACTION_FUNCTION(AActor, TestMobjZ)
|
||||||
if (numret > 1)
|
if (numret > 1)
|
||||||
{
|
{
|
||||||
numret = 2;
|
numret = 2;
|
||||||
ret[1].SetPointer(on, ATAG_OBJECT);
|
ret[1].SetObject(on);
|
||||||
}
|
}
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
|
@ -4685,7 +4685,7 @@ DEFINE_ACTION_FUNCTION(AActor, LineAttack)
|
||||||
int acdmg;
|
int acdmg;
|
||||||
if (puffType == nullptr) puffType = PClass::FindActor("BulletPuff"); // P_LineAttack does not work without a puff to take info from.
|
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);
|
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;
|
if (numret > 1) ret[1].SetInt(acdmg), numret = 2;
|
||||||
return numret;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7247,8 +7247,8 @@ DEFINE_ACTION_FUNCTION(AActor, SpawnPlayerMissile)
|
||||||
AActor *missileactor;
|
AActor *missileactor;
|
||||||
if (numparam == 2) angle = self->Angles.Yaw;
|
if (numparam == 2) angle = self->Angles.Yaw;
|
||||||
AActor *misl = P_SpawnPlayerMissile(self, x, y, z, type, angle, lt, &missileactor, nofreeaim, noautoaim, aimflags);
|
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 > 0) ret[0].SetObject(misl);
|
||||||
if (numret > 1) ret[1].SetPointer(missileactor, ATAG_OBJECT), numret = 2;
|
if (numret > 1) ret[1].SetObject(missileactor), numret = 2;
|
||||||
return numret;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7695,7 +7695,7 @@ FDropItem *AActor::GetDropItems() const
|
||||||
DEFINE_ACTION_FUNCTION(AActor, GetDropItems)
|
DEFINE_ACTION_FUNCTION(AActor, GetDropItems)
|
||||||
{
|
{
|
||||||
PARAM_SELF_PROLOGUE(AActor);
|
PARAM_SELF_PROLOGUE(AActor);
|
||||||
ACTION_RETURN_OBJECT(self->GetDropItems());
|
ACTION_RETURN_POINTER(self->GetDropItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
double AActor::GetGravity() const
|
double AActor::GetGravity() const
|
||||||
|
|
|
@ -112,7 +112,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestFloorSurrounding)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindLowestFloorSurrounding(&v);
|
double h = self->FindLowestFloorSurrounding(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestFloorSurrounding)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindHighestFloorSurrounding(&v);
|
double h = self->FindHighestFloorSurrounding(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextHighestFloor)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindNextHighestFloor(&v);
|
double h = self->FindNextHighestFloor(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextLowestFloor)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindNextLowestFloor(&v);
|
double h = self->FindNextLowestFloor(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -348,7 +348,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextLowestCeiling)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindNextLowestCeiling(&v);
|
double h = self->FindNextLowestCeiling(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +411,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindNextHighestCeiling)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindNextHighestCeiling(&v);
|
double h = self->FindNextHighestCeiling(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingSurrounding)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindLowestCeilingSurrounding(&v);
|
double h = self->FindLowestCeilingSurrounding(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +508,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestCeilingSurrounding)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindHighestCeilingSurrounding(&v);
|
double h = self->FindHighestCeilingSurrounding(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,7 +744,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindHighestFloorPoint)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindHighestFloorPoint(&v);
|
double h = self->FindHighestFloorPoint(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -793,7 +793,7 @@ DEFINE_ACTION_FUNCTION(_Sector, FindLowestCeilingPoint)
|
||||||
vertex_t *v;
|
vertex_t *v;
|
||||||
double h = self->FindLowestCeilingPoint(&v);
|
double h = self->FindLowestCeilingPoint(&v);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1207,7 +1207,7 @@ DEFINE_ACTION_FUNCTION(_Sector, HighestCeilingAt)
|
||||||
sector_t *s;
|
sector_t *s;
|
||||||
double h = self->HighestCeilingAt(DVector2(x, y), &s);
|
double h = self->HighestCeilingAt(DVector2(x, y), &s);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1242,7 +1242,7 @@ DEFINE_ACTION_FUNCTION(_Sector, LowestFloorAt)
|
||||||
sector_t *s;
|
sector_t *s;
|
||||||
double h = self->LowestFloorAt(DVector2(x, y), &s);
|
double h = self->LowestFloorAt(DVector2(x, y), &s);
|
||||||
if (numret > 0) ret[0].SetFloat(h);
|
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;
|
return numret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,12 +1309,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextHighestCeilingAt)
|
||||||
|
|
||||||
if (numret > 2)
|
if (numret > 2)
|
||||||
{
|
{
|
||||||
ret[2].SetPointer(resultff, ATAG_GENERIC);
|
ret[2].SetPointer(resultff);
|
||||||
numret = 3;
|
numret = 3;
|
||||||
}
|
}
|
||||||
if (numret > 1)
|
if (numret > 1)
|
||||||
{
|
{
|
||||||
ret[1].SetPointer(resultsec, ATAG_GENERIC);
|
ret[1].SetPointer(resultsec);
|
||||||
}
|
}
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
|
@ -1387,12 +1387,12 @@ DEFINE_ACTION_FUNCTION(_Sector, NextLowestFloorAt)
|
||||||
|
|
||||||
if (numret > 2)
|
if (numret > 2)
|
||||||
{
|
{
|
||||||
ret[2].SetPointer(resultff, ATAG_GENERIC);
|
ret[2].SetPointer(resultff);
|
||||||
numret = 3;
|
numret = 3;
|
||||||
}
|
}
|
||||||
if (numret > 1)
|
if (numret > 1)
|
||||||
{
|
{
|
||||||
ret[1].SetPointer(resultsec, ATAG_GENERIC);
|
ret[1].SetPointer(resultsec);
|
||||||
}
|
}
|
||||||
if (numret > 0)
|
if (numret > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -505,12 +505,13 @@ private:
|
||||||
{
|
{
|
||||||
// Load bgcolor
|
// Load bgcolor
|
||||||
uint32_t desttmp[2];
|
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;
|
__m128i bgcolor;
|
||||||
if (BlendT::Mode != (int)BlendModes::Opaque)
|
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());
|
bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
bgcolor = _mm_setzero_si128();
|
bgcolor = _mm_setzero_si128();
|
||||||
|
|
||||||
|
@ -593,12 +594,13 @@ private:
|
||||||
{
|
{
|
||||||
// Load bgcolor
|
// Load bgcolor
|
||||||
uint32_t desttmp[2];
|
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;
|
__m128i bgcolor;
|
||||||
if (BlendT::Mode != (int)BlendModes::Opaque)
|
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());
|
bgcolor = _mm_unpacklo_epi8(_mm_loadl_epi64((__m128i*)desttmp), _mm_setzero_si128());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
bgcolor = _mm_setzero_si128();
|
bgcolor = _mm_setzero_si128();
|
||||||
|
|
||||||
|
|
|
@ -249,7 +249,7 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &
|
||||||
}
|
}
|
||||||
if (!polyportal)
|
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();
|
polyportal = sectorPortals.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
||||||
{
|
{
|
||||||
if (PolyRenderer::Instance()->InsertSeenMirror(line->linedef))
|
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();
|
polyportal = linePortals.back().get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlan
|
||||||
}
|
}
|
||||||
if (!polyportal)
|
if (!polyportal)
|
||||||
{
|
{
|
||||||
linePortals.push_back(std::make_unique<PolyDrawLinePortal>(portal));
|
linePortals.push_back(std::unique_ptr<PolyDrawLinePortal>(new PolyDrawLinePortal(portal)));
|
||||||
polyportal = linePortals.back().get();
|
polyportal = linePortals.back().get();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -385,7 +385,7 @@ void FxExpression::EmitCompare(VMFunctionBuilder *build, bool invert, TArray<siz
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case REGT_POINTER:
|
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;
|
break;
|
||||||
|
|
||||||
case REGT_STRING:
|
case REGT_STRING:
|
||||||
|
@ -587,16 +587,7 @@ ExpEmit FxConstant::Emit(VMFunctionBuilder *build)
|
||||||
}
|
}
|
||||||
else if (regtype == REGT_POINTER)
|
else if (regtype == REGT_POINTER)
|
||||||
{
|
{
|
||||||
VM_ATAG tag = ATAG_GENERIC;
|
out.RegNum = build->GetConstantAddress(value.pointer);
|
||||||
if (value.Type == TypeState)
|
|
||||||
{
|
|
||||||
tag = ATAG_STATE;
|
|
||||||
}
|
|
||||||
else if (value.Type->GetLoadOp() != OP_LP)
|
|
||||||
{
|
|
||||||
tag = ATAG_OBJECT;
|
|
||||||
}
|
|
||||||
out.RegNum = build->GetConstantAddress(value.pointer, tag);
|
|
||||||
}
|
}
|
||||||
else if (regtype == REGT_STRING)
|
else if (regtype == REGT_STRING)
|
||||||
{
|
{
|
||||||
|
@ -2998,7 +2989,7 @@ texcheck:
|
||||||
auto * countptr = &ptr->Count;
|
auto * countptr = &ptr->Count;
|
||||||
ExpEmit bndp(build, REGT_POINTER);
|
ExpEmit bndp(build, REGT_POINTER);
|
||||||
ExpEmit bndc(build, REGT_INT);
|
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_LW, bndc.RegNum, bndp.RegNum, build->GetConstantInt(0));
|
||||||
build->Emit(OP_BOUND_R, to.RegNum, bndc.RegNum);
|
build->Emit(OP_BOUND_R, to.RegNum, bndc.RegNum);
|
||||||
bndp.Free(build);
|
bndp.Free(build);
|
||||||
|
@ -4638,7 +4629,7 @@ void FxTypeCheck::EmitCompare(VMFunctionBuilder *build, bool invert, TArray<size
|
||||||
{
|
{
|
||||||
ExpEmit ares = EmitCommon(build);
|
ExpEmit ares = EmitCommon(build);
|
||||||
ares.Free(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));
|
patchspots_no.Push(build->Emit(OP_JMP, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4706,7 +4697,7 @@ ExpEmit FxDynamicCast::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit castee = expr->Emit(build);
|
ExpEmit castee = expr->Emit(build);
|
||||||
castee.Free(build);
|
castee.Free(build);
|
||||||
ExpEmit ares(build, REGT_POINTER);
|
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;
|
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
|
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);
|
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)
|
if (min != nullptr && max != nullptr)
|
||||||
{
|
{
|
||||||
EmitParameter(build, min, ScriptPosition);
|
EmitParameter(build, min, ScriptPosition);
|
||||||
EmitParameter(build, max, ScriptPosition);
|
EmitParameter(build, max, ScriptPosition);
|
||||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
build->Emit(opcode, build->GetConstantAddress(callfunc), 3, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1);
|
build->Emit(opcode, build->GetConstantAddress(callfunc), 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EmitTail)
|
if (EmitTail)
|
||||||
|
@ -5657,10 +5648,10 @@ ExpEmit FxRandomPick::Emit(VMFunctionBuilder *build)
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
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(0);
|
||||||
build->EmitParamInt(choices.Size() - 1);
|
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);
|
ExpEmit resultreg(build, REGT_INT);
|
||||||
build->Emit(OP_RESULT, 0, REGT_INT, resultreg.RegNum);
|
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
|
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);
|
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)
|
if (min != nullptr && max != nullptr)
|
||||||
{
|
{
|
||||||
EmitParameter(build, min, ScriptPosition);
|
EmitParameter(build, min, ScriptPosition);
|
||||||
EmitParameter(build, max, ScriptPosition);
|
EmitParameter(build, max, ScriptPosition);
|
||||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 3, 1);
|
build->Emit(opcode, build->GetConstantAddress(callfunc), 3, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 1, 1);
|
build->Emit(opcode, build->GetConstantAddress(callfunc), 1, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EmitTail)
|
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
|
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);
|
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);
|
EmitParameter(build, mask, ScriptPosition);
|
||||||
build->Emit(opcode, build->GetConstantAddress(callfunc, ATAG_OBJECT), 2, 1);
|
build->Emit(opcode, build->GetConstantAddress(callfunc), 2, 1);
|
||||||
|
|
||||||
if (EmitTail)
|
if (EmitTail)
|
||||||
{
|
{
|
||||||
|
@ -6661,7 +6652,7 @@ ExpEmit FxGlobalVariable::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
ExpEmit obj(build, REGT_POINTER);
|
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)
|
if (AddressRequested)
|
||||||
{
|
{
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -6744,34 +6735,34 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
|
||||||
switch (CVar->GetRealType())
|
switch (CVar->GetRealType())
|
||||||
{
|
{
|
||||||
case CVAR_Int:
|
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);
|
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVAR_Color:
|
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);
|
build->Emit(OP_LW, dest.RegNum, addr.RegNum, nul);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVAR_Float:
|
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);
|
build->Emit(OP_LSP, dest.RegNum, addr.RegNum, nul);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVAR_Bool:
|
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);
|
build->Emit(OP_LBU, dest.RegNum, addr.RegNum, nul);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVAR_String:
|
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);
|
build->Emit(OP_LCS, dest.RegNum, addr.RegNum, nul);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CVAR_DummyBool:
|
case CVAR_DummyBool:
|
||||||
{
|
{
|
||||||
auto cv = static_cast<FFlagCVar *>(CVar);
|
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_LW, dest.RegNum, addr.RegNum, nul);
|
||||||
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
|
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
|
||||||
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(1));
|
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(1));
|
||||||
|
@ -6781,7 +6772,7 @@ ExpEmit FxCVar::Emit(VMFunctionBuilder *build)
|
||||||
case CVAR_DummyInt:
|
case CVAR_DummyInt:
|
||||||
{
|
{
|
||||||
auto cv = static_cast<FMaskCVar *>(CVar);
|
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_LW, dest.RegNum, addr.RegNum, nul);
|
||||||
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(cv->BitVal));
|
build->Emit(OP_AND_RK, dest.RegNum, dest.RegNum, build->GetConstantInt(cv->BitVal));
|
||||||
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
|
build->Emit(OP_SRL_RI, dest.RegNum, dest.RegNum, cv->BitNum);
|
||||||
|
@ -6923,13 +6914,13 @@ FxStructMember::~FxStructMember()
|
||||||
|
|
||||||
bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
bool FxStructMember::RequestAddress(FCompileContext &ctx, bool *writable)
|
||||||
{
|
{
|
||||||
// Cannot take the address of metadata variables.
|
AddressRequested = true;
|
||||||
if (membervar->Flags & VARF_Meta)
|
if (membervar->Flags & VARF_Meta)
|
||||||
{
|
{
|
||||||
return false;
|
// Meta variables are read only.
|
||||||
|
*writable = false;
|
||||||
}
|
}
|
||||||
AddressRequested = true;
|
else if (writable != nullptr)
|
||||||
if (writable != nullptr)
|
|
||||||
{
|
{
|
||||||
// [ZZ] original check.
|
// [ZZ] original check.
|
||||||
bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
|
bool bWritable = (AddressWritable && !ctx.CheckWritable(membervar->Flags) &&
|
||||||
|
@ -7323,11 +7314,13 @@ ExpEmit FxArrayElement::Emit(VMFunctionBuilder *build)
|
||||||
|
|
||||||
if (SizeAddr != ~0u)
|
if (SizeAddr != ~0u)
|
||||||
{
|
{
|
||||||
|
bool ismeta = Array->ExprType == EFX_ClassMember && static_cast<FxClassMember*>(Array)->membervar->Flags & VARF_Meta;
|
||||||
|
|
||||||
arrayvar.Free(build);
|
arrayvar.Free(build);
|
||||||
start = ExpEmit(build, REGT_POINTER);
|
start = ExpEmit(build, REGT_POINTER);
|
||||||
build->Emit(OP_LP, start.RegNum, arrayvar.RegNum, build->GetConstantInt(0));
|
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)->membervar = f;
|
||||||
static_cast<FxMemberBase *>(Array)->AddressRequested = false;
|
static_cast<FxMemberBase *>(Array)->AddressRequested = false;
|
||||||
Array->ValueType = TypeUInt32;
|
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 (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||||
if (EmitTail)
|
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;
|
ExpEmit call;
|
||||||
call.Final = true;
|
call.Final = true;
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExpEmit dest(build, REGT_INT);
|
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);
|
build->Emit(OP_RESULT, 0, REGT_INT, dest.RegNum);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
@ -8941,7 +8934,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
||||||
if (selfside == FScopeBarrier::Side_PlainData)
|
if (selfside == FScopeBarrier::Side_PlainData)
|
||||||
{
|
{
|
||||||
// Check the self object against the calling function's flags at run time
|
// 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.
|
// 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, 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;
|
count += 2;
|
||||||
}
|
}
|
||||||
|
@ -8985,7 +8978,7 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
||||||
// Get a constant register for this function
|
// Get a constant register for this function
|
||||||
if (staticcall)
|
if (staticcall)
|
||||||
{
|
{
|
||||||
int funcaddr = build->GetConstantAddress(vmfunc, ATAG_OBJECT);
|
int funcaddr = build->GetConstantAddress(vmfunc);
|
||||||
// Emit the call
|
// Emit the call
|
||||||
if (EmitTail)
|
if (EmitTail)
|
||||||
{ // Tail call
|
{ // Tail call
|
||||||
|
@ -10503,7 +10496,7 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit reg(build, REGT_POINTER);
|
ExpEmit reg(build, REGT_POINTER);
|
||||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset));
|
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_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);
|
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.
|
// Let the caller check this. Making this an error with a message is only taking away options from the user.
|
||||||
cls = nullptr;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10700,13 +10693,13 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
if (basex->ValueType != TypeName)
|
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);
|
ExpEmit clsname = basex->Emit(build);
|
||||||
assert(!clsname.Konst);
|
assert(!clsname.Konst);
|
||||||
ExpEmit dest(build, REGT_POINTER);
|
ExpEmit dest(build, REGT_POINTER);
|
||||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
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.
|
// Call the BuiltinNameToClass function to convert from 'name' to class.
|
||||||
VMFunction *callfunc;
|
VMFunction *callfunc;
|
||||||
|
@ -10716,7 +10709,7 @@ ExpEmit FxClassTypeCast::Emit(VMFunctionBuilder *build)
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
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);
|
build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum);
|
||||||
clsname.Free(build);
|
clsname.Free(build);
|
||||||
return dest;
|
return dest;
|
||||||
|
@ -10815,7 +10808,7 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit clsname = basex->Emit(build);
|
ExpEmit clsname = basex->Emit(build);
|
||||||
|
|
||||||
build->Emit(OP_PARAM, 0, clsname.RegType, clsname.RegNum);
|
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;
|
VMFunction *callfunc;
|
||||||
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast);
|
PSymbol *sym = FindBuiltinFunction(NAME_BuiltinClassCast, BuiltinClassCast);
|
||||||
|
@ -10825,7 +10818,7 @@ ExpEmit FxClassPtrCast::Emit(VMFunctionBuilder *build)
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
clsname.Free(build);
|
clsname.Free(build);
|
||||||
ExpEmit dest(build, REGT_POINTER);
|
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);
|
build->Emit(OP_RESULT, 0, REGT_POINTER, dest.RegNum);
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
@ -11164,7 +11157,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
|
|
||||||
case REGT_POINTER:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
case REGT_STRING:
|
case REGT_STRING:
|
||||||
|
@ -11196,7 +11189,7 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
ExpEmit reg(build, REGT_POINTER);
|
ExpEmit reg(build, REGT_POINTER);
|
||||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
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_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);
|
reg.Free(build);
|
||||||
}
|
}
|
||||||
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
|
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
|
||||||
|
@ -11222,7 +11215,7 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
|
||||||
ExpEmit reg(build, REGT_POINTER);
|
ExpEmit reg(build, REGT_POINTER);
|
||||||
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
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_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);
|
reg.Free(build);
|
||||||
}
|
}
|
||||||
build->ConstructedStructs.Delete(build->ConstructedStructs.Find(this));
|
build->ConstructedStructs.Delete(build->ConstructedStructs.Find(this));
|
||||||
|
@ -11304,7 +11297,7 @@ ExpEmit FxStaticArray::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
TArray<void*> cvalues;
|
TArray<void*> cvalues;
|
||||||
for (auto v : values) cvalues.Push(static_cast<FxConstant *>(v)->GetValue().GetPointer());
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ void VMFunctionBuilder::MakeFunction(VMScriptFunction *func)
|
||||||
}
|
}
|
||||||
if (AddressConstantList.Size() > 0)
|
if (AddressConstantList.Size() > 0)
|
||||||
{
|
{
|
||||||
FillAddressConstants(func->KonstA, func->KonstATags());
|
FillAddressConstants(func->KonstA);
|
||||||
}
|
}
|
||||||
if (StringConstantList.Size() > 0)
|
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(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
|
else
|
||||||
{
|
{
|
||||||
int loc = StringConstantList.Push(val);
|
unsigned loc = StringConstantList.Push(val);
|
||||||
StringConstantMap.Insert(val, loc);
|
StringConstantMap.Insert(val, loc);
|
||||||
return 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)
|
unsigned *locp = AddressConstantMap.CheckKey(ptr);
|
||||||
{ // Make all NULL pointers generic. (Or should we allow typed NULLs?)
|
|
||||||
tag = ATAG_GENERIC;
|
|
||||||
}
|
|
||||||
AddrKonst *locp = AddressConstantMap.CheckKey(ptr);
|
|
||||||
if (locp != NULL)
|
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.
|
return *locp;
|
||||||
assert(ptr == nullptr || locp->Tag == tag);
|
|
||||||
return locp->KonstNum;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned locc = AddressConstantList.Push(ptr);
|
unsigned loc = AddressConstantList.Push(ptr);
|
||||||
AtagConstantList.Push(tag);
|
|
||||||
|
|
||||||
AddrKonst loc = { locc, tag };
|
|
||||||
AddressConstantMap.Insert(ptr, loc);
|
AddressConstantMap.Insert(ptr, loc);
|
||||||
return loc.KonstNum;
|
return loc;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,16 +317,13 @@ unsigned VMFunctionBuilder::AllocConstantsFloat(unsigned count, double *values)
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs, VM_ATAG tag)
|
unsigned VMFunctionBuilder::AllocConstantsAddress(unsigned count, void **ptrs)
|
||||||
{
|
{
|
||||||
unsigned addr = AddressConstantList.Reserve(count);
|
unsigned addr = AddressConstantList.Reserve(count);
|
||||||
AtagConstantList.Reserve(count);
|
|
||||||
memcpy(&AddressConstantList[addr], ptrs, count * sizeof(void *));
|
memcpy(&AddressConstantList[addr], ptrs, count * sizeof(void *));
|
||||||
for (unsigned i = 0; i < count; i++)
|
for (unsigned i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
AtagConstantList[addr + i] = tag;
|
AddressConstantMap.Insert(ptrs[i], addr+i);
|
||||||
AddrKonst loc = { addr+i, tag };
|
|
||||||
AddressConstantMap.Insert(ptrs[i], loc);
|
|
||||||
}
|
}
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,12 @@ public:
|
||||||
// Returns the constant register holding the value.
|
// Returns the constant register holding the value.
|
||||||
unsigned GetConstantInt(int val);
|
unsigned GetConstantInt(int val);
|
||||||
unsigned GetConstantFloat(double val);
|
unsigned GetConstantFloat(double val);
|
||||||
unsigned GetConstantAddress(void *ptr, VM_ATAG tag);
|
unsigned GetConstantAddress(void *ptr);
|
||||||
unsigned GetConstantString(FString str);
|
unsigned GetConstantString(FString str);
|
||||||
|
|
||||||
unsigned AllocConstantsInt(unsigned int count, int *values);
|
unsigned AllocConstantsInt(unsigned int count, int *values);
|
||||||
unsigned AllocConstantsFloat(unsigned int count, double *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);
|
unsigned AllocConstantsString(unsigned int count, FString *ptrs);
|
||||||
|
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ public:
|
||||||
// Write out complete constant tables.
|
// Write out complete constant tables.
|
||||||
void FillIntConstants(int *konst);
|
void FillIntConstants(int *konst);
|
||||||
void FillFloatConstants(double *konst);
|
void FillFloatConstants(double *konst);
|
||||||
void FillAddressConstants(FVoidObj *konst, VM_ATAG *tags);
|
void FillAddressConstants(FVoidObj *konst);
|
||||||
void FillStringConstants(FString *strings);
|
void FillStringConstants(FString *strings);
|
||||||
|
|
||||||
// PARAM increases ActiveParam; CALL decreases it.
|
// PARAM increases ActiveParam; CALL decreases it.
|
||||||
|
@ -96,24 +96,17 @@ public:
|
||||||
TArray<FxLocalVariableDeclaration *> ConstructedStructs;
|
TArray<FxLocalVariableDeclaration *> ConstructedStructs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AddrKonst
|
|
||||||
{
|
|
||||||
unsigned KonstNum;
|
|
||||||
VM_ATAG Tag;
|
|
||||||
};
|
|
||||||
|
|
||||||
TArray<FStatementInfo> LineNumbers;
|
TArray<FStatementInfo> LineNumbers;
|
||||||
TArray<FxExpression *> StatementStack;
|
TArray<FxExpression *> StatementStack;
|
||||||
|
|
||||||
TArray<int> IntConstantList;
|
TArray<int> IntConstantList;
|
||||||
TArray<double> FloatConstantList;
|
TArray<double> FloatConstantList;
|
||||||
TArray<void *> AddressConstantList;
|
TArray<void *> AddressConstantList;
|
||||||
TArray<VM_ATAG> AtagConstantList;
|
|
||||||
TArray<FString> StringConstantList;
|
TArray<FString> StringConstantList;
|
||||||
// These map from the constant value to its position in the constant table.
|
// These map from the constant value to its position in the constant table.
|
||||||
TMap<int, unsigned> IntConstantMap;
|
TMap<int, unsigned> IntConstantMap;
|
||||||
TMap<double, unsigned> FloatConstantMap;
|
TMap<double, unsigned> FloatConstantMap;
|
||||||
TMap<void *, AddrKonst> AddressConstantMap;
|
TMap<void *, unsigned> AddressConstantMap;
|
||||||
TMap<FString, unsigned> StringConstantMap;
|
TMap<FString, unsigned> StringConstantMap;
|
||||||
|
|
||||||
int MaxParam;
|
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)
|
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, "%-22s", tmp);
|
||||||
}
|
}
|
||||||
printf_wrapper(out, "\n");
|
printf_wrapper(out, "\n");
|
||||||
|
@ -320,7 +320,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
||||||
switch (code[i].op)
|
switch (code[i].op)
|
||||||
{
|
{
|
||||||
case OP_JMP:
|
case OP_JMP:
|
||||||
case OP_TRY:
|
//case OP_TRY:
|
||||||
col = printf_wrapper(out, "%08x", (i + 1 + code[i].i24) << 2);
|
col = printf_wrapper(out, "%08x", (i + 1 + code[i].i24) << 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -498,7 +498,7 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
||||||
col = 30;
|
col = 30;
|
||||||
}
|
}
|
||||||
printf_wrapper(out, "%*c", 30 - col, ';');
|
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);
|
printf_wrapper(out, "%d\n", code[i].i24);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1090,12 +1090,14 @@ DEFINE_PROPERTY(distancecheck, S, Actor)
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
DEFINE_CLASS_PROPERTY(restrictedto, Ssssssssssssssssssss, Inventory)
|
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)
|
for(int i = 0;i < PROP_PARM_COUNT;++i)
|
||||||
{
|
{
|
||||||
PROP_STRING_PARM(n, i);
|
PROP_STRING_PARM(n, i);
|
||||||
if (*n != 0)
|
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)
|
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)
|
for(int i = 0;i < PROP_PARM_COUNT;++i)
|
||||||
{
|
{
|
||||||
PROP_STRING_PARM(n, i);
|
PROP_STRING_PARM(n, i);
|
||||||
if (*n != 0)
|
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 signed short VM_SHALF;
|
||||||
typedef unsigned int VM_UWORD;
|
typedef unsigned int VM_UWORD;
|
||||||
typedef signed int VM_SWORD;
|
typedef signed int VM_SWORD;
|
||||||
typedef VM_UBYTE VM_ATAG;
|
|
||||||
|
|
||||||
#define VM_EPSILON (1/65536.0)
|
#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
|
#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
|
enum EVMAbortException
|
||||||
{
|
{
|
||||||
X_OTHER,
|
X_OTHER,
|
||||||
|
@ -322,7 +300,6 @@ extern const VMOpInfo OpInfo[NUM_OPS];
|
||||||
struct VMReturn
|
struct VMReturn
|
||||||
{
|
{
|
||||||
void *Location;
|
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
|
VM_UBYTE RegType; // Same as VMParam RegType, except REGT_KONST is invalid; only used by asserts
|
||||||
|
|
||||||
void SetInt(int val)
|
void SetInt(int val)
|
||||||
|
@ -366,38 +343,37 @@ struct VMReturn
|
||||||
assert(RegType == REGT_STRING);
|
assert(RegType == REGT_STRING);
|
||||||
*(FString *)Location = val;
|
*(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);
|
assert(RegType == REGT_POINTER);
|
||||||
*(void **)Location = val;
|
*(void **)Location = val;
|
||||||
if (TagOfs != 0)
|
|
||||||
{
|
|
||||||
*((VM_ATAG *)Location + TagOfs) = tag;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IntAt(int *loc)
|
void IntAt(int *loc)
|
||||||
{
|
{
|
||||||
Location = loc;
|
Location = loc;
|
||||||
TagOfs = 0;
|
|
||||||
RegType = REGT_INT;
|
RegType = REGT_INT;
|
||||||
}
|
}
|
||||||
void FloatAt(double *loc)
|
void FloatAt(double *loc)
|
||||||
{
|
{
|
||||||
Location = loc;
|
Location = loc;
|
||||||
TagOfs = 0;
|
|
||||||
RegType = REGT_FLOAT;
|
RegType = REGT_FLOAT;
|
||||||
}
|
}
|
||||||
void StringAt(FString *loc)
|
void StringAt(FString *loc)
|
||||||
{
|
{
|
||||||
Location = loc;
|
Location = loc;
|
||||||
TagOfs = 0;
|
|
||||||
RegType = REGT_STRING;
|
RegType = REGT_STRING;
|
||||||
}
|
}
|
||||||
void PointerAt(void **loc)
|
void PointerAt(void **loc)
|
||||||
{
|
{
|
||||||
Location = loc;
|
Location = loc;
|
||||||
TagOfs = 0;
|
|
||||||
RegType = REGT_POINTER;
|
RegType = REGT_POINTER;
|
||||||
}
|
}
|
||||||
VMReturn() { }
|
VMReturn() { }
|
||||||
|
@ -415,7 +391,7 @@ struct VMValue
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct { void *a; int atag; };
|
void *a;
|
||||||
double f;
|
double f;
|
||||||
struct { int pad[3]; VM_UBYTE Type; };
|
struct { int pad[3]; VM_UBYTE Type; };
|
||||||
struct { int foo[4]; } biggest;
|
struct { int foo[4]; } biggest;
|
||||||
|
@ -456,19 +432,11 @@ struct VMValue
|
||||||
VMValue(DObject *v)
|
VMValue(DObject *v)
|
||||||
{
|
{
|
||||||
a = v;
|
a = v;
|
||||||
atag = ATAG_OBJECT;
|
|
||||||
Type = REGT_POINTER;
|
Type = REGT_POINTER;
|
||||||
}
|
}
|
||||||
VMValue(void *v)
|
VMValue(void *v)
|
||||||
{
|
{
|
||||||
a = v;
|
a = v;
|
||||||
atag = ATAG_GENERIC;
|
|
||||||
Type = REGT_POINTER;
|
|
||||||
}
|
|
||||||
VMValue(void *v, int tag)
|
|
||||||
{
|
|
||||||
a = v;
|
|
||||||
atag = tag;
|
|
||||||
Type = REGT_POINTER;
|
Type = REGT_POINTER;
|
||||||
}
|
}
|
||||||
VMValue &operator=(const VMValue &o)
|
VMValue &operator=(const VMValue &o)
|
||||||
|
@ -499,7 +467,6 @@ struct VMValue
|
||||||
VMValue &operator=(DObject *v)
|
VMValue &operator=(DObject *v)
|
||||||
{
|
{
|
||||||
a = v;
|
a = v;
|
||||||
atag = ATAG_OBJECT;
|
|
||||||
Type = REGT_POINTER;
|
Type = REGT_POINTER;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -602,7 +569,7 @@ struct VMFrame
|
||||||
int size = (sizeof(VMFrame) + 15) & ~15;
|
int size = (sizeof(VMFrame) + 15) & ~15;
|
||||||
size += numparam * sizeof(VMValue);
|
size += numparam * sizeof(VMValue);
|
||||||
size += numregf * sizeof(double);
|
size += numregf * sizeof(double);
|
||||||
size += numrega * (sizeof(void *) + sizeof(VM_UBYTE));
|
size += numrega * sizeof(void *);
|
||||||
size += numregs * sizeof(FString);
|
size += numregs * sizeof(FString);
|
||||||
size += numregd * sizeof(int);
|
size += numregd * sizeof(int);
|
||||||
if (numextra != 0)
|
if (numextra != 0)
|
||||||
|
@ -613,9 +580,10 @@ struct VMFrame
|
||||||
return size;
|
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
|
double *GetRegF() const
|
||||||
|
@ -633,25 +601,19 @@ struct VMFrame
|
||||||
return (void **)(GetRegS() + NumRegS);
|
return (void **)(GetRegS() + NumRegS);
|
||||||
}
|
}
|
||||||
|
|
||||||
VM_ATAG *GetRegATag() const
|
int *GetRegD() const
|
||||||
{
|
{
|
||||||
return (VM_ATAG *)(GetRegD() + NumRegD);
|
return (int *)(GetRegA() + NumRegA);
|
||||||
}
|
|
||||||
|
|
||||||
VMValue *GetParam() const
|
|
||||||
{
|
|
||||||
assert(((size_t)this & 15) == 0 && "VM frame is unaligned");
|
|
||||||
return (VMValue *)(((size_t)(this + 1) + 15) & ~15);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *GetExtra() const
|
void *GetExtra() const
|
||||||
{
|
{
|
||||||
VM_ATAG *ptag = GetRegATag();
|
uint8_t *pbeg = (uint8_t*)(GetRegD() + NumRegD);
|
||||||
ptrdiff_t ofs = ptag - (VM_ATAG *)this;
|
ptrdiff_t ofs = pbeg - (uint8_t *)this;
|
||||||
return (VM_UBYTE *)this + ((ofs + NumRegA + 15) & ~15);
|
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. :(
|
// Calling the individual functions produces suboptimal code. :(
|
||||||
param = GetParam();
|
param = GetParam();
|
||||||
|
@ -659,7 +621,6 @@ struct VMFrame
|
||||||
s = (FString *)(f + NumRegF);
|
s = (FString *)(f + NumRegF);
|
||||||
a = (void **)(s + NumRegS);
|
a = (void **)(s + NumRegS);
|
||||||
d = (int *)(a + NumRegA);
|
d = (int *)(a + NumRegA);
|
||||||
atag = (VM_ATAG *)(d + NumRegD);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitRegS();
|
void InitRegS();
|
||||||
|
@ -669,18 +630,17 @@ struct VMRegisters
|
||||||
{
|
{
|
||||||
VMRegisters(const VMFrame *frame)
|
VMRegisters(const VMFrame *frame)
|
||||||
{
|
{
|
||||||
frame->GetAllRegs(d, f, s, a, atag, param);
|
frame->GetAllRegs(d, f, s, a, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
VMRegisters(const VMRegisters &o)
|
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;
|
int *d;
|
||||||
double *f;
|
double *f;
|
||||||
FString *s;
|
FString *s;
|
||||||
void **a;
|
void **a;
|
||||||
VM_ATAG *atag;
|
|
||||||
VMValue *param;
|
VMValue *param;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -703,9 +663,6 @@ public:
|
||||||
~VMScriptFunction();
|
~VMScriptFunction();
|
||||||
void Alloc(int numops, int numkonstd, int numkonstf, int numkonsts, int numkonsta, int numlinenumbers);
|
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;
|
VMOP *Code;
|
||||||
FStatementInfo *LineInfo;
|
FStatementInfo *LineInfo;
|
||||||
FString SourceFileName;
|
FString SourceFileName;
|
||||||
|
@ -810,14 +767,12 @@ public:
|
||||||
void ParamObject(DObject *obj)
|
void ParamObject(DObject *obj)
|
||||||
{
|
{
|
||||||
Reg.a[RegA] = obj;
|
Reg.a[RegA] = obj;
|
||||||
Reg.atag[RegA] = ATAG_OBJECT;
|
|
||||||
RegA++;
|
RegA++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParamPointer(void *ptr, VM_ATAG atag)
|
void ParamPointer(void *ptr)
|
||||||
{
|
{
|
||||||
Reg.a[RegA] = ptr;
|
Reg.a[RegA] = ptr;
|
||||||
Reg.atag[RegA] = atag;
|
|
||||||
RegA++;
|
RegA++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,8 +807,18 @@ void VMDisasm(FILE *out, const VMOP *code, int codesize, const VMScriptFunction
|
||||||
// variable name <x> at position <p>
|
// variable name <x> at position <p>
|
||||||
void NullParam(const char *varname);
|
void NullParam(const char *varname);
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
|
bool AssertObject(void * ob);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define PARAM_NULLCHECK(ptr, var) (ptr == nullptr? NullParam(#var), ptr : ptr)
|
#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.
|
// 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_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;
|
#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_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_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_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_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 && (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_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_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_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 && (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_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 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_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; }
|
#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;
|
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_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, ATAG_GENERIC); 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->SetPointer(state, ATAG_OBJECT); 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_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_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)
|
#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_PROLOGUE; \
|
||||||
PARAM_OBJECT(self, type);
|
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) \
|
#define PARAM_SELF_STRUCT_PROLOGUE(type) \
|
||||||
PARAM_PROLOGUE; \
|
PARAM_PROLOGUE; \
|
||||||
PARAM_POINTER(self, type);
|
PARAM_POINTER(self, type);
|
||||||
|
|
|
@ -82,7 +82,6 @@ void ThrowVMException(VMException *x);
|
||||||
#define ASSERTF(x) assert((unsigned)(x) < f->NumRegF)
|
#define ASSERTF(x) assert((unsigned)(x) < f->NumRegF)
|
||||||
#define ASSERTA(x) assert((unsigned)(x) < f->NumRegA)
|
#define ASSERTA(x) assert((unsigned)(x) < f->NumRegA)
|
||||||
#define ASSERTS(x) assert((unsigned)(x) < f->NumRegS)
|
#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 ASSERTKD(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstD)
|
||||||
#define ASSERTKF(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstF)
|
#define ASSERTKF(x) assert(sfunc != NULL && (unsigned)(x) < sfunc->NumKonstF)
|
||||||
|
@ -228,10 +227,29 @@ void VMFillParams(VMValue *params, VMFrame *callee, int numparam)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(p.Type == REGT_POINTER);
|
assert(p.Type == REGT_POINTER);
|
||||||
calleereg.a[rega] = p.a;
|
calleereg.a[rega++] = p.a;
|
||||||
calleereg.atag[rega++] = p.atag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#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"
|
#include "vmops.h"
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
const VMOP *exception_frames[MAX_TRY_DEPTH];
|
//const VMOP *exception_frames[MAX_TRY_DEPTH];
|
||||||
int try_depth = 0;
|
//int try_depth = 0;
|
||||||
VMFrame *f = stack->TopFrame();
|
VMFrame *f = stack->TopFrame();
|
||||||
VMScriptFunction *sfunc;
|
VMScriptFunction *sfunc;
|
||||||
const VMRegisters reg(f);
|
const VMRegisters reg(f);
|
||||||
|
@ -20,7 +20,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
||||||
const double *konstf;
|
const double *konstf;
|
||||||
const FString *konsts;
|
const FString *konsts;
|
||||||
const FVoidObj *konsta;
|
const FVoidObj *konsta;
|
||||||
const VM_ATAG *konstatag;
|
|
||||||
|
|
||||||
if (f->Func != NULL && !(f->Func->VarFlags & VARF_Native))
|
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;
|
konstf = sfunc->KonstF;
|
||||||
konsts = sfunc->KonstS;
|
konsts = sfunc->KonstS;
|
||||||
konsta = sfunc->KonstA;
|
konsta = sfunc->KonstA;
|
||||||
konstatag = sfunc->KonstATags();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -38,7 +36,6 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
||||||
konstf = NULL;
|
konstf = NULL;
|
||||||
konsts = NULL;
|
konsts = NULL;
|
||||||
konsta = NULL;
|
konsta = NULL;
|
||||||
konstatag = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
@ -46,7 +43,7 @@ static int Exec(VMFrameStack *stack, const VMOP *pc, VMReturn *ret, int numret)
|
||||||
const double *fbp, *fcp;
|
const double *fbp, *fcp;
|
||||||
int a, b, c;
|
int a, b, c;
|
||||||
|
|
||||||
begin:
|
//begin:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
#if !COMPGOTO
|
#if !COMPGOTO
|
||||||
|
@ -81,7 +78,6 @@ begin:
|
||||||
OP(LKP):
|
OP(LKP):
|
||||||
ASSERTA(a); ASSERTKA(BC);
|
ASSERTA(a); ASSERTKA(BC);
|
||||||
reg.a[a] = konsta[BC].v;
|
reg.a[a] = konsta[BC].v;
|
||||||
reg.atag[a] = konstatag[BC];
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
||||||
OP(LK_R) :
|
OP(LK_R) :
|
||||||
|
@ -100,25 +96,21 @@ begin:
|
||||||
ASSERTA(a); ASSERTD(B);
|
ASSERTA(a); ASSERTD(B);
|
||||||
b = reg.d[B] + C;
|
b = reg.d[B] + C;
|
||||||
reg.a[a] = konsta[b].v;
|
reg.a[a] = konsta[b].v;
|
||||||
reg.atag[a] = konstatag[b];
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
||||||
OP(LFP):
|
OP(LFP):
|
||||||
ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0);
|
ASSERTA(a); assert(sfunc != NULL); assert(sfunc->ExtraSpace > 0);
|
||||||
reg.a[a] = f->GetExtra();
|
reg.a[a] = f->GetExtra();
|
||||||
reg.atag[a] = ATAG_GENERIC; // using ATAG_FRAMEPOINTER will cause endless asserts.
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
|
||||||
OP(CLSS):
|
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.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;
|
NEXTOP;
|
||||||
|
|
||||||
OP(META):
|
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.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;
|
NEXTOP;
|
||||||
|
|
||||||
OP(LB):
|
OP(LB):
|
||||||
|
@ -217,37 +209,31 @@ begin:
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||||
GETADDR(PB,KC,X_READ_NIL);
|
GETADDR(PB,KC,X_READ_NIL);
|
||||||
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
|
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LO_R):
|
OP(LO_R):
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||||
GETADDR(PB,RC,X_READ_NIL);
|
GETADDR(PB,RC,X_READ_NIL);
|
||||||
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
|
reg.a[a] = GC::ReadBarrier(*(DObject **)ptr);
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LOS):
|
OP(LOS):
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||||
GETADDR(PB,KC,X_READ_NIL);
|
GETADDR(PB,KC,X_READ_NIL);
|
||||||
reg.a[a] = *(DObject **)ptr;
|
reg.a[a] = *(DObject **)ptr;
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LOS_R):
|
OP(LOS_R):
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||||
GETADDR(PB,RC,X_READ_NIL);
|
GETADDR(PB,RC,X_READ_NIL);
|
||||||
reg.a[a] = *(DObject **)ptr;
|
reg.a[a] = *(DObject **)ptr;
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LP):
|
OP(LP):
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||||
GETADDR(PB,KC,X_READ_NIL);
|
GETADDR(PB,KC,X_READ_NIL);
|
||||||
reg.a[a] = *(void **)ptr;
|
reg.a[a] = *(void **)ptr;
|
||||||
reg.atag[a] = ATAG_GENERIC;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LP_R):
|
OP(LP_R):
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTD(C);
|
||||||
GETADDR(PB,RC,X_READ_NIL);
|
GETADDR(PB,RC,X_READ_NIL);
|
||||||
reg.a[a] = *(void **)ptr;
|
reg.a[a] = *(void **)ptr;
|
||||||
reg.atag[a] = ATAG_GENERIC;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(LV2):
|
OP(LV2):
|
||||||
ASSERTF(a+1); ASSERTA(B); ASSERTKD(C);
|
ASSERTF(a+1); ASSERTA(B); ASSERTKD(C);
|
||||||
|
@ -442,7 +428,6 @@ begin:
|
||||||
ASSERTA(a); ASSERTA(B);
|
ASSERTA(a); ASSERTA(B);
|
||||||
b = B;
|
b = B;
|
||||||
reg.a[a] = reg.a[b];
|
reg.a[a] = reg.a[b];
|
||||||
reg.atag[a] = reg.atag[b];
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
}
|
}
|
||||||
OP(MOVEV2):
|
OP(MOVEV2):
|
||||||
|
@ -466,25 +451,21 @@ begin:
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
||||||
b = B;
|
b = B;
|
||||||
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
|
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;
|
NEXTOP;
|
||||||
OP(DYNCAST_K) :
|
OP(DYNCAST_K) :
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
||||||
b = B;
|
b = B;
|
||||||
reg.a[a] = (reg.a[b] && ((DObject*)(reg.a[b]))->IsKindOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
|
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;
|
NEXTOP;
|
||||||
OP(DYNCASTC_R) :
|
OP(DYNCASTC_R) :
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
ASSERTA(a); ASSERTA(B); ASSERTA(C);
|
||||||
b = B;
|
b = B;
|
||||||
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(reg.a[C]))) ? reg.a[b] : nullptr;
|
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;
|
NEXTOP;
|
||||||
OP(DYNCASTC_K) :
|
OP(DYNCASTC_K) :
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
ASSERTA(a); ASSERTA(B); ASSERTKA(C);
|
||||||
b = B;
|
b = B;
|
||||||
reg.a[a] = (reg.a[b] && ((PClass*)(reg.a[b]))->IsDescendantOf((PClass*)(konsta[C].o))) ? reg.a[b] : nullptr;
|
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;
|
NEXTOP;
|
||||||
OP(CAST):
|
OP(CAST):
|
||||||
if (C == CAST_I2F)
|
if (C == CAST_I2F)
|
||||||
|
@ -575,7 +556,7 @@ begin:
|
||||||
break;
|
break;
|
||||||
case REGT_INT | REGT_ADDROF:
|
case REGT_INT | REGT_ADDROF:
|
||||||
assert(C < f->NumRegD);
|
assert(C < f->NumRegD);
|
||||||
::new(param) VMValue(®.d[C], ATAG_GENERIC);
|
::new(param) VMValue(®.d[C]);
|
||||||
break;
|
break;
|
||||||
case REGT_INT | REGT_KONST:
|
case REGT_INT | REGT_KONST:
|
||||||
assert(C < sfunc->NumKonstD);
|
assert(C < sfunc->NumKonstD);
|
||||||
|
@ -587,7 +568,7 @@ begin:
|
||||||
break;
|
break;
|
||||||
case REGT_STRING | REGT_ADDROF:
|
case REGT_STRING | REGT_ADDROF:
|
||||||
assert(C < f->NumRegS);
|
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;
|
break;
|
||||||
case REGT_STRING | REGT_KONST:
|
case REGT_STRING | REGT_KONST:
|
||||||
assert(C < sfunc->NumKonstS);
|
assert(C < sfunc->NumKonstS);
|
||||||
|
@ -595,15 +576,15 @@ begin:
|
||||||
break;
|
break;
|
||||||
case REGT_POINTER:
|
case REGT_POINTER:
|
||||||
assert(C < f->NumRegA);
|
assert(C < f->NumRegA);
|
||||||
::new(param) VMValue(reg.a[C], reg.atag[C]);
|
::new(param) VMValue(reg.a[C]);
|
||||||
break;
|
break;
|
||||||
case REGT_POINTER | REGT_ADDROF:
|
case REGT_POINTER | REGT_ADDROF:
|
||||||
assert(C < f->NumRegA);
|
assert(C < f->NumRegA);
|
||||||
::new(param) VMValue(®.a[C], ATAG_GENERIC);
|
::new(param) VMValue(®.a[C]);
|
||||||
break;
|
break;
|
||||||
case REGT_POINTER | REGT_KONST:
|
case REGT_POINTER | REGT_KONST:
|
||||||
assert(C < sfunc->NumKonstA);
|
assert(C < sfunc->NumKonstA);
|
||||||
::new(param) VMValue(konsta[C].v, konstatag[C]);
|
::new(param) VMValue(konsta[C].v);
|
||||||
break;
|
break;
|
||||||
case REGT_FLOAT:
|
case REGT_FLOAT:
|
||||||
assert(C < f->NumRegF);
|
assert(C < f->NumRegF);
|
||||||
|
@ -626,7 +607,7 @@ begin:
|
||||||
break;
|
break;
|
||||||
case REGT_FLOAT | REGT_ADDROF:
|
case REGT_FLOAT | REGT_ADDROF:
|
||||||
assert(C < f->NumRegF);
|
assert(C < f->NumRegF);
|
||||||
::new(param) VMValue(®.f[C], ATAG_GENERIC);
|
::new(param) VMValue(®.f[C]);
|
||||||
break;
|
break;
|
||||||
case REGT_FLOAT | REGT_KONST:
|
case REGT_FLOAT | REGT_KONST:
|
||||||
assert(C < sfunc->NumKonstF);
|
assert(C < sfunc->NumKonstF);
|
||||||
|
@ -657,7 +638,6 @@ begin:
|
||||||
|
|
||||||
OP(CALL_K):
|
OP(CALL_K):
|
||||||
ASSERTKA(a);
|
ASSERTKA(a);
|
||||||
assert(konstatag[a] == ATAG_OBJECT);
|
|
||||||
ptr = konsta[a].o;
|
ptr = konsta[a].o;
|
||||||
goto Do_CALL;
|
goto Do_CALL;
|
||||||
OP(CALL):
|
OP(CALL):
|
||||||
|
@ -713,7 +693,6 @@ begin:
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(TAIL_K):
|
OP(TAIL_K):
|
||||||
ASSERTKA(a);
|
ASSERTKA(a);
|
||||||
assert(konstatag[a] == ATAG_OBJECT);
|
|
||||||
ptr = konsta[a].o;
|
ptr = konsta[a].o;
|
||||||
goto Do_TAILCALL;
|
goto Do_TAILCALL;
|
||||||
OP(TAIL):
|
OP(TAIL):
|
||||||
|
@ -825,10 +804,10 @@ begin:
|
||||||
c = C;
|
c = C;
|
||||||
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
|
if (c) FScopeBarrier::ValidateNew(cls, c - 1);
|
||||||
reg.a[a] = cls->CreateNew();
|
reg.a[a] = cls->CreateNew();
|
||||||
reg.atag[a] = ATAG_OBJECT;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
OP(TRY):
|
OP(TRY):
|
||||||
assert(try_depth < MAX_TRY_DEPTH);
|
assert(try_depth < MAX_TRY_DEPTH);
|
||||||
if (try_depth >= MAX_TRY_DEPTH)
|
if (try_depth >= MAX_TRY_DEPTH)
|
||||||
|
@ -842,7 +821,9 @@ begin:
|
||||||
assert(a <= try_depth);
|
assert(a <= try_depth);
|
||||||
try_depth -= a;
|
try_depth -= a;
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
#endif
|
||||||
OP(THROW):
|
OP(THROW):
|
||||||
|
#if 0
|
||||||
if (a == 0)
|
if (a == 0)
|
||||||
{
|
{
|
||||||
ASSERTA(B);
|
ASSERTA(B);
|
||||||
|
@ -851,19 +832,22 @@ begin:
|
||||||
else if (a == 1)
|
else if (a == 1)
|
||||||
{
|
{
|
||||||
ASSERTKA(B);
|
ASSERTKA(B);
|
||||||
assert(konstatag[B] == ATAG_OBJECT);
|
assert(AssertObject(konsta[B].o));
|
||||||
ThrowVMException((VMException *)konsta[B].o);
|
ThrowVMException((VMException *)konsta[B].o);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ThrowAbortException(EVMAbortException(BC), nullptr);
|
ThrowAbortException(EVMAbortException(BC), nullptr);
|
||||||
}
|
}
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
#if 0
|
||||||
OP(CATCH):
|
OP(CATCH):
|
||||||
// This instruction is handled by our own catch handler and should
|
// This instruction is handled by our own catch handler and should
|
||||||
// not be executed by the normal VM code.
|
// not be executed by the normal VM code.
|
||||||
assert(0);
|
assert(0);
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
|
#endif
|
||||||
|
|
||||||
OP(BOUND):
|
OP(BOUND):
|
||||||
if (reg.d[a] >= BC)
|
if (reg.d[a] >= BC)
|
||||||
|
@ -1658,7 +1642,6 @@ begin:
|
||||||
c = 0;
|
c = 0;
|
||||||
}
|
}
|
||||||
reg.a[a] = (VM_UBYTE *)reg.a[B] + c;
|
reg.a[a] = (VM_UBYTE *)reg.a[B] + c;
|
||||||
reg.atag[a] = c == 0 ? reg.atag[B] : (int)ATAG_GENERIC;
|
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
OP(ADDA_RK):
|
OP(ADDA_RK):
|
||||||
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
ASSERTA(a); ASSERTA(B); ASSERTKD(C);
|
||||||
|
@ -1683,6 +1666,7 @@ begin:
|
||||||
NEXTOP;
|
NEXTOP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
catch(VMException *exception)
|
catch(VMException *exception)
|
||||||
{
|
{
|
||||||
// Try to find a handler for the exception.
|
// Try to find a handler for the exception.
|
||||||
|
@ -1709,7 +1693,6 @@ begin:
|
||||||
{
|
{
|
||||||
assert(pc->a == 3);
|
assert(pc->a == 3);
|
||||||
ASSERTKA(b);
|
ASSERTKA(b);
|
||||||
assert(konstatag[b] == ATAG_OBJECT);
|
|
||||||
type = (PClass *)konsta[b].o;
|
type = (PClass *)konsta[b].o;
|
||||||
}
|
}
|
||||||
ASSERTA(pc->c);
|
ASSERTA(pc->c);
|
||||||
|
@ -1718,7 +1701,6 @@ begin:
|
||||||
// Found a handler. Store the exception in pC, skip the JMP,
|
// Found a handler. Store the exception in pC, skip the JMP,
|
||||||
// and begin executing its code.
|
// and begin executing its code.
|
||||||
reg.a[pc->c] = exception;
|
reg.a[pc->c] = exception;
|
||||||
reg.atag[pc->c] = ATAG_OBJECT;
|
|
||||||
pc += 2;
|
pc += 2;
|
||||||
goto begin;
|
goto begin;
|
||||||
}
|
}
|
||||||
|
@ -1731,7 +1713,6 @@ begin:
|
||||||
// Catch any type of VMException. This terminates the chain.
|
// Catch any type of VMException. This terminates the chain.
|
||||||
ASSERTA(pc->c);
|
ASSERTA(pc->c);
|
||||||
reg.a[pc->c] = exception;
|
reg.a[pc->c] = exception;
|
||||||
reg.atag[pc->c] = ATAG_OBJECT;
|
|
||||||
pc += 1;
|
pc += 1;
|
||||||
goto begin;
|
goto begin;
|
||||||
}
|
}
|
||||||
|
@ -1740,6 +1721,7 @@ begin:
|
||||||
// Nothing caught it. Rethrow and let somebody else deal with it.
|
// Nothing caught it. Rethrow and let somebody else deal with it.
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
catch (CVMAbortException &err)
|
catch (CVMAbortException &err)
|
||||||
{
|
{
|
||||||
err.MaybePrintMessage();
|
err.MaybePrintMessage();
|
||||||
|
@ -1831,16 +1813,7 @@ static void DoCast(const VMRegisters ®, const VMFrame *f, int a, int b, int c
|
||||||
{
|
{
|
||||||
ASSERTS(a); ASSERTA(b);
|
ASSERTS(a); ASSERTA(b);
|
||||||
if (reg.a[b] == nullptr) reg.s[a] = "null";
|
if (reg.a[b] == nullptr) reg.s[a] = "null";
|
||||||
else if (reg.atag[b] == ATAG_OBJECT)
|
else reg.s[a].Format("%p", reg.a[b]);
|
||||||
{
|
|
||||||
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]);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1922,7 +1895,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return
|
||||||
for (i = 0, ret = returns; i < numret; ++i, ++ret, ++retval)
|
for (i = 0, ret = returns; i < numret; ++i, ++ret, ++retval)
|
||||||
{
|
{
|
||||||
assert(retval->op == OP_RESULT); // opcode
|
assert(retval->op == OP_RESULT); // opcode
|
||||||
ret->TagOfs = 0;
|
|
||||||
ret->RegType = type = retval->b;
|
ret->RegType = type = retval->b;
|
||||||
regnum = retval->c;
|
regnum = retval->c;
|
||||||
assert(!(type & REGT_KONST));
|
assert(!(type & REGT_KONST));
|
||||||
|
@ -1950,7 +1922,6 @@ static void FillReturns(const VMRegisters ®, VMFrame *frame, VMReturn *return
|
||||||
assert(type == REGT_POINTER);
|
assert(type == REGT_POINTER);
|
||||||
assert(regnum < frame->NumRegA);
|
assert(regnum < frame->NumRegA);
|
||||||
ret->Location = ®.a[regnum];
|
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)
|
if (regtype & REGT_KONST)
|
||||||
{
|
{
|
||||||
assert(regnum < func->NumKonstA);
|
assert(regnum < func->NumKonstA);
|
||||||
ret->SetPointer(func->KonstA[regnum].v, func->KonstATags()[regnum]);
|
ret->SetPointer(func->KonstA[regnum].v);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(regnum < frame->NumRegA);
|
assert(regnum < frame->NumRegA);
|
||||||
ret->SetPointer(reg.a[regnum], reg.atag[regnum]);
|
ret->SetPointer(reg.a[regnum]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -97,7 +97,7 @@ void VMScriptFunction::Alloc(int numops, int numkonstd, int numkonstf, int numko
|
||||||
numkonstd * sizeof(int) +
|
numkonstd * sizeof(int) +
|
||||||
numkonstf * sizeof(double) +
|
numkonstf * sizeof(double) +
|
||||||
numkonsts * sizeof(FString) +
|
numkonsts * sizeof(FString) +
|
||||||
numkonsta * (sizeof(FVoidObj) + 1) +
|
numkonsta * sizeof(FVoidObj) +
|
||||||
numlinenumbers * sizeof(FStatementInfo));
|
numlinenumbers * sizeof(FStatementInfo));
|
||||||
Code = (VMOP *)mem;
|
Code = (VMOP *)mem;
|
||||||
mem = (void *)((VMOP *)mem + numops);
|
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(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, new, RPRPI8, NOP, 0, 0),
|
||||||
xx(NEW_K, new, RPKP, 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(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(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
|
xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB
|
||||||
// A == 1: Throw exception object pkB
|
// A == 1: Throw exception object pkB
|
||||||
// A >= 2: Throw VM exception of type BC
|
// 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 == 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 == 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
|
// 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
|
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;
|
Scene = scene;
|
||||||
MainThread = mainThread;
|
MainThread = mainThread;
|
||||||
FrameMemory = std::make_unique<RenderMemory>();
|
FrameMemory.reset(new RenderMemory());
|
||||||
Viewport = std::make_unique<RenderViewport>();
|
Viewport.reset(new RenderViewport());
|
||||||
Light = std::make_unique<LightVisibility>();
|
Light.reset(new LightVisibility());
|
||||||
DrawQueue = std::make_shared<DrawerCommandQueue>(FrameMemory.get());
|
DrawQueue.reset(new DrawerCommandQueue(FrameMemory.get()));
|
||||||
OpaquePass = std::make_unique<RenderOpaquePass>(this);
|
OpaquePass.reset(new RenderOpaquePass(this));
|
||||||
TranslucentPass = std::make_unique<RenderTranslucentPass>(this);
|
TranslucentPass.reset(new RenderTranslucentPass(this));
|
||||||
SpriteList = std::make_unique<VisibleSpriteList>();
|
SpriteList.reset(new VisibleSpriteList());
|
||||||
Portal = std::make_unique<RenderPortal>(this);
|
Portal.reset(new RenderPortal(this));
|
||||||
Clip3D = std::make_unique<Clip3DFloors>(this);
|
Clip3D.reset(new Clip3DFloors(this));
|
||||||
PlayerSprites = std::make_unique<RenderPlayerSprites>(this);
|
PlayerSprites.reset(new RenderPlayerSprites(this));
|
||||||
PlaneList = std::make_unique<VisiblePlaneList>(this);
|
PlaneList.reset(new VisiblePlaneList(this));
|
||||||
DrawSegments = std::make_unique<DrawSegmentList>(this);
|
DrawSegments.reset(new DrawSegmentList(this));
|
||||||
ClipSegments = std::make_unique<RenderClipSegment>();
|
ClipSegments.reset(new RenderClipSegment());
|
||||||
tc_drawers = std::make_unique<SWTruecolorDrawers>(DrawQueue);
|
tc_drawers.reset(new SWTruecolorDrawers(DrawQueue));
|
||||||
pal_drawers = std::make_unique<SWPalDrawers>(DrawQueue);
|
pal_drawers.reset(new SWPalDrawers(DrawQueue));
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderThread::~RenderThread()
|
RenderThread::~RenderThread()
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace swrenderer
|
||||||
|
|
||||||
RenderScene::RenderScene()
|
RenderScene::RenderScene()
|
||||||
{
|
{
|
||||||
Threads.push_back(std::make_unique<RenderThread>(this));
|
Threads.push_back(std::unique_ptr<RenderThread>(new RenderThread(this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderScene::~RenderScene()
|
RenderScene::~RenderScene()
|
||||||
|
@ -289,7 +289,7 @@ namespace swrenderer
|
||||||
{
|
{
|
||||||
while (Threads.size() < (size_t)numThreads)
|
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();
|
auto renderthread = thread.get();
|
||||||
int start_run_id = run_id;
|
int start_run_id = run_id;
|
||||||
thread->thread = std::thread([=]()
|
thread->thread = std::thread([=]()
|
||||||
|
|
|
@ -25,6 +25,8 @@ class Inventory : Actor native
|
||||||
native bool bInitEffectFailed;
|
native bool bInitEffectFailed;
|
||||||
meta String PickupMsg;
|
meta String PickupMsg;
|
||||||
meta int GiveQuest;
|
meta int GiveQuest;
|
||||||
|
meta array<class<Actor> > ForbiddenToPlayerClass;
|
||||||
|
meta array<class<Actor> > RestrictedToPlayerClass;
|
||||||
|
|
||||||
property PickupMessage: PickupMsg;
|
property PickupMessage: PickupMsg;
|
||||||
property GiveQuest: GiveQuest;
|
property GiveQuest: GiveQuest;
|
||||||
|
@ -46,7 +48,6 @@ class Inventory : Actor native
|
||||||
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG";
|
Inventory.PickupMessage "$TXT_DEFAULTPICKUPMSG";
|
||||||
}
|
}
|
||||||
|
|
||||||
native bool CanPickup(Actor toucher);
|
|
||||||
native bool DoRespawn();
|
native bool DoRespawn();
|
||||||
native void BecomeItem();
|
native void BecomeItem();
|
||||||
native void BecomePickup();
|
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
|
// AInventory :: CallTryPickup
|
||||||
|
|
Loading…
Reference in a new issue