mirror of
https://github.com/ZDoom/qzdoom-gpl.git
synced 2024-11-29 15:12:11 +00:00
This commit is contained in:
commit
a3ad22a460
13 changed files with 207 additions and 21 deletions
|
@ -708,11 +708,15 @@ protected:
|
||||||
class PStruct : public PNamedType
|
class PStruct : public PNamedType
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(PStruct, PNamedType);
|
DECLARE_CLASS(PStruct, PNamedType);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PStruct(FName name, PTypeBase *outer);
|
PStruct(FName name, PTypeBase *outer);
|
||||||
|
|
||||||
TArray<PField *> Fields;
|
TArray<PField *> Fields;
|
||||||
bool HasNativeFields;
|
bool HasNativeFields;
|
||||||
|
// Some internal structs require explicit construction and destruction of fields the VM cannot handle directly so use thes two functions for it.
|
||||||
|
VMFunction *mConstructor = nullptr;
|
||||||
|
VMFunction *mDestructor = nullptr;
|
||||||
|
|
||||||
virtual PField *AddField(FName name, PType *type, DWORD flags=0);
|
virtual PField *AddField(FName name, PType *type, DWORD flags=0);
|
||||||
virtual PField *AddNativeField(FName name, PType *type, size_t address, DWORD flags = 0, int bitvalue = 0);
|
virtual PField *AddNativeField(FName name, PType *type, size_t address, DWORD flags = 0, int bitvalue = 0);
|
||||||
|
|
|
@ -4408,6 +4408,8 @@ enum EACSFunctions
|
||||||
ACSF_DamageActor, // [arookas]
|
ACSF_DamageActor, // [arookas]
|
||||||
ACSF_SetActorFlag,
|
ACSF_SetActorFlag,
|
||||||
ACSF_SetTranslation,
|
ACSF_SetTranslation,
|
||||||
|
ACSF_GetActorFloorTexture,
|
||||||
|
ACSF_GetActorFloorTerrain,
|
||||||
|
|
||||||
|
|
||||||
// OpenGL stuff
|
// OpenGL stuff
|
||||||
|
@ -6100,6 +6102,35 @@ doplaysound: if (funcIndex == ACSF_PlayActorSound)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACSF_GetActorFloorTexture:
|
||||||
|
{
|
||||||
|
auto a = SingleActorFromTID(args[0], activator);
|
||||||
|
if (a != nullptr)
|
||||||
|
{
|
||||||
|
return GlobalACSStrings.AddString(TexMan[a->floorpic]->Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GlobalACSStrings.AddString("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ACSF_GetActorFloorTerrain:
|
||||||
|
{
|
||||||
|
auto a = SingleActorFromTID(args[0], activator);
|
||||||
|
if (a != nullptr)
|
||||||
|
{
|
||||||
|
return GlobalACSStrings.AddString(Terrains[a->floorterrain].Name);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return GlobalACSStrings.AddString("");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -261,7 +261,7 @@ bool P_CheckPosition(AActor *thing, const DVector2 &pos, FCheckPosition &tm, boo
|
||||||
AActor *P_CheckOnmobj (AActor *thing);
|
AActor *P_CheckOnmobj (AActor *thing);
|
||||||
void P_FakeZMovement (AActor *mo);
|
void P_FakeZMovement (AActor *mo);
|
||||||
bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);
|
bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor, FCheckPosition &tm, bool missileCheck = false);
|
||||||
bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor = NULL);
|
bool P_TryMove(AActor* thing, const DVector2 &pos, int dropoff, const secplane_t * onfloor = NULL, bool missilecheck = false);
|
||||||
|
|
||||||
bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags = 0);
|
bool P_CheckMove(AActor *thing, const DVector2 &pos, int flags = 0);
|
||||||
void P_ApplyTorque(AActor *mo);
|
void P_ApplyTorque(AActor *mo);
|
||||||
|
|
|
@ -84,6 +84,49 @@ TArray<spechit_t> spechit;
|
||||||
TArray<spechit_t> portalhit;
|
TArray<spechit_t> portalhit;
|
||||||
|
|
||||||
|
|
||||||
|
// FCheckPosition requires explicit contstruction and destruction when used in the VM
|
||||||
|
DEFINE_ACTION_FUNCTION(_FCheckPosition, _Constructor)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FCheckPosition);
|
||||||
|
new(self) FCheckPosition;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_FCheckPosition, _Destructor)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FCheckPosition);
|
||||||
|
self->~FCheckPosition();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_ACTION_FUNCTION(_FCheckPosition, ClearLastRipped)
|
||||||
|
{
|
||||||
|
PARAM_SELF_STRUCT_PROLOGUE(FCheckPosition);
|
||||||
|
self->LastRipped.Clear();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, thing);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, pos);
|
||||||
|
DEFINE_FIELD_NAMED_X(FCheckPosition, FCheckPosition, sector, cursector);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorz);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingz);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, dropoffz);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorpic);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorterrain);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floorsector);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingpic);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingsector);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, touchmidtex);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, abovemidtex);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, floatok);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, FromPMove);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, ceilingline);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, stepthing);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, DoRipping);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, portalstep);
|
||||||
|
DEFINE_FIELD_X(FCheckPosition, FCheckPosition, PushTime);
|
||||||
|
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
//
|
//
|
||||||
// CanCollideWith
|
// CanCollideWith
|
||||||
|
@ -1845,8 +1888,17 @@ DEFINE_ACTION_FUNCTION(AActor, CheckPosition)
|
||||||
PARAM_FLOAT(x);
|
PARAM_FLOAT(x);
|
||||||
PARAM_FLOAT(y);
|
PARAM_FLOAT(y);
|
||||||
PARAM_BOOL_DEF(actorsonly);
|
PARAM_BOOL_DEF(actorsonly);
|
||||||
|
PARAM_POINTER_DEF(tm, FCheckPosition);
|
||||||
|
if (tm)
|
||||||
|
{
|
||||||
|
ACTION_RETURN_BOOL(P_CheckPosition(self, DVector2(x, y), *tm, actorsonly));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ACTION_RETURN_BOOL(P_CheckPosition(self, DVector2(x, y), actorsonly));
|
ACTION_RETURN_BOOL(P_CheckPosition(self, DVector2(x, y), actorsonly));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -2637,10 +2689,10 @@ pushline:
|
||||||
|
|
||||||
bool P_TryMove(AActor *thing, const DVector2 &pos,
|
bool P_TryMove(AActor *thing, const DVector2 &pos,
|
||||||
int dropoff, // killough 3/15/98: allow dropoff as option
|
int dropoff, // killough 3/15/98: allow dropoff as option
|
||||||
const secplane_t *onfloor) // [RH] Let P_TryMove keep the thing on the floor
|
const secplane_t *onfloor, bool missilecheck) // [RH] Let P_TryMove keep the thing on the floor
|
||||||
{
|
{
|
||||||
FCheckPosition tm;
|
FCheckPosition tm;
|
||||||
return P_TryMove(thing, pos, dropoff, onfloor, tm);
|
return P_TryMove(thing, pos, dropoff, onfloor, tm, missilecheck);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_ACTION_FUNCTION(AActor, TryMove)
|
DEFINE_ACTION_FUNCTION(AActor, TryMove)
|
||||||
|
@ -2649,7 +2701,16 @@ DEFINE_ACTION_FUNCTION(AActor, TryMove)
|
||||||
PARAM_FLOAT(x);
|
PARAM_FLOAT(x);
|
||||||
PARAM_FLOAT(y);
|
PARAM_FLOAT(y);
|
||||||
PARAM_INT(dropoff);
|
PARAM_INT(dropoff);
|
||||||
ACTION_RETURN_BOOL(P_TryMove(self, DVector2(x, y), dropoff));
|
PARAM_BOOL_DEF(missilecheck);
|
||||||
|
PARAM_POINTER_DEF(tm, FCheckPosition);
|
||||||
|
if (tm == nullptr)
|
||||||
|
{
|
||||||
|
ACTION_RETURN_BOOL(P_TryMove(self, DVector2(x, y), dropoff, nullptr, missilecheck));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ACTION_RETURN_BOOL(P_TryMove(self, DVector2(x, y), dropoff, nullptr, *tm, missilecheck));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -5160,6 +5160,7 @@ ExpEmit FxRandom::Emit(VMFunctionBuilder *build)
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
|
||||||
|
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, ATAG_RNG));
|
||||||
|
@ -5410,6 +5411,7 @@ ExpEmit FxFRandom::Emit(VMFunctionBuilder *build)
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
|
||||||
|
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, ATAG_RNG));
|
||||||
|
@ -5504,6 +5506,7 @@ ExpEmit FxRandom2::Emit(VMFunctionBuilder *build)
|
||||||
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
assert(((PSymbolVMFunction *)sym)->Function != nullptr);
|
||||||
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
callfunc = ((PSymbolVMFunction *)sym)->Function;
|
||||||
|
|
||||||
|
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, ATAG_RNG));
|
||||||
|
@ -7801,6 +7804,7 @@ ExpEmit FxActionSpecialCall::Emit(VMFunctionBuilder *build)
|
||||||
ArgList.DeleteAndClear();
|
ArgList.DeleteAndClear();
|
||||||
ArgList.ShrinkToFit();
|
ArgList.ShrinkToFit();
|
||||||
|
|
||||||
|
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, ATAG_OBJECT), 2 + i, 0);
|
||||||
|
@ -8072,6 +8076,8 @@ ExpEmit FxVMFunctionCall::Emit(VMFunctionBuilder *build)
|
||||||
assert(build->Registers[REGT_POINTER].GetMostUsed() >= build->NumImplicits);
|
assert(build->Registers[REGT_POINTER].GetMostUsed() >= build->NumImplicits);
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
|
if (build->FramePointer.Fixed) EmitTail = false; // do not tail call if the stack is in use
|
||||||
|
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
{
|
{
|
||||||
ExpEmit reg;
|
ExpEmit reg;
|
||||||
|
@ -9508,6 +9514,19 @@ ExpEmit FxReturnStatement::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
ExpEmit out(0, REGT_NIL);
|
ExpEmit out(0, REGT_NIL);
|
||||||
|
|
||||||
|
// call the destructors for all structs requiring one.
|
||||||
|
// go in reverse order of construction
|
||||||
|
for (int i = build->ConstructedStructs.Size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
auto pstr = static_cast<PStruct*>(build->ConstructedStructs[i]->ValueType);
|
||||||
|
assert(pstr->mDestructor != nullptr);
|
||||||
|
ExpEmit reg(build, REGT_POINTER);
|
||||||
|
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(build->ConstructedStructs[i]->StackOffset));
|
||||||
|
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||||
|
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor, ATAG_OBJECT), 1, 0);
|
||||||
|
reg.Free(build);
|
||||||
|
}
|
||||||
|
|
||||||
// If we return nothing, use a regular RET opcode.
|
// If we return nothing, use a regular RET opcode.
|
||||||
// Otherwise just return the value we're given.
|
// Otherwise just return the value we're given.
|
||||||
if (Value == nullptr)
|
if (Value == nullptr)
|
||||||
|
@ -10173,6 +10192,19 @@ ExpEmit FxLocalVariableDeclaration::Emit(VMFunctionBuilder *build)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Init arrays and structs.
|
// Init arrays and structs.
|
||||||
|
if (ValueType->IsA(RUNTIME_CLASS(PStruct)))
|
||||||
|
{
|
||||||
|
auto pstr = static_cast<PStruct*>(ValueType);
|
||||||
|
if (pstr->mConstructor != nullptr)
|
||||||
|
{
|
||||||
|
ExpEmit reg(build, REGT_POINTER);
|
||||||
|
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
||||||
|
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||||
|
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mConstructor, ATAG_OBJECT), 1, 0);
|
||||||
|
reg.Free(build);
|
||||||
|
}
|
||||||
|
if (pstr->mDestructor != nullptr) build->ConstructedStructs.Push(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ExpEmit();
|
return ExpEmit();
|
||||||
}
|
}
|
||||||
|
@ -10184,6 +10216,22 @@ void FxLocalVariableDeclaration::Release(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
build->Registers[ValueType->GetRegType()].Return(RegNum, RegCount);
|
build->Registers[ValueType->GetRegType()].Return(RegNum, RegCount);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ValueType->IsA(RUNTIME_CLASS(PStruct)))
|
||||||
|
{
|
||||||
|
auto pstr = static_cast<PStruct*>(ValueType);
|
||||||
|
if (pstr->mDestructor != nullptr)
|
||||||
|
{
|
||||||
|
ExpEmit reg(build, REGT_POINTER);
|
||||||
|
build->Emit(OP_ADDA_RK, reg.RegNum, build->FramePointer.RegNum, build->GetConstantInt(StackOffset));
|
||||||
|
build->Emit(OP_PARAM, 0, reg.RegType, reg.RegNum);
|
||||||
|
build->Emit(OP_CALL_K, build->GetConstantAddress(pstr->mDestructor, ATAG_OBJECT), 1, 0);
|
||||||
|
reg.Free(build);
|
||||||
|
}
|
||||||
|
build->ConstructedStructs.Delete(build->ConstructedStructs.Find(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
// Stack space will not be released because that would make controlled destruction impossible.
|
// Stack space will not be released because that would make controlled destruction impossible.
|
||||||
// For that all local stack variables need to live for the entire execution of a function.
|
// For that all local stack variables need to live for the entire execution of a function.
|
||||||
}
|
}
|
||||||
|
|
|
@ -1993,6 +1993,7 @@ class FxLocalVariableDeclaration : public FxExpression
|
||||||
public:
|
public:
|
||||||
int StackOffset = -1;
|
int StackOffset = -1;
|
||||||
int RegNum = -1;
|
int RegNum = -1;
|
||||||
|
bool constructed = false;
|
||||||
|
|
||||||
FxLocalVariableDeclaration(PType *type, FName name, FxExpression *initval, int varflags, const FScriptPosition &p);
|
FxLocalVariableDeclaration(PType *type, FName name, FxExpression *initval, int varflags, const FScriptPosition &p);
|
||||||
~FxLocalVariableDeclaration();
|
~FxLocalVariableDeclaration();
|
||||||
|
|
|
@ -37,9 +37,7 @@
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define private public // this file needs public access to TArray's private 'Count' field so just hack the visibility qualifiers here
|
|
||||||
#include "tarray.h"
|
#include "tarray.h"
|
||||||
#undef private
|
|
||||||
#include "dobject.h"
|
#include "dobject.h"
|
||||||
#include "thingdef.h"
|
#include "thingdef.h"
|
||||||
// We need one specific type for each of the 7 integral VM types and instantiate the needed functions for each of them.
|
// We need one specific type for each of the 7 integral VM types and instantiate the needed functions for each of them.
|
||||||
|
@ -775,10 +773,10 @@ DEFINE_ACTION_FUNCTION(FDynArray_String, Clear)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_FIELD_NAMED(FDynArray_I8, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_I8, FArray, Count, Size)
|
||||||
DEFINE_FIELD_NAMED(FDynArray_I16, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_I16, FArray, Count, Size)
|
||||||
DEFINE_FIELD_NAMED(FDynArray_I32, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_I32, FArray, Count, Size)
|
||||||
DEFINE_FIELD_NAMED(FDynArray_F32, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_F32, FArray, Count, Size)
|
||||||
DEFINE_FIELD_NAMED(FDynArray_F64, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_F64, FArray, Count, Size)
|
||||||
DEFINE_FIELD_NAMED(FDynArray_Ptr, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_Ptr, FArray, Count, Size)
|
||||||
DEFINE_FIELD_NAMED(FDynArray_String, Count, Size) // clashes with type 'Inventory'.
|
DEFINE_FIELD_NAMED_X(DynArray_String, FArray, Count, Size)
|
||||||
|
|
|
@ -50,6 +50,8 @@
|
||||||
#include "zstring.h"
|
#include "zstring.h"
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "g_levellocals.h"
|
#include "g_levellocals.h"
|
||||||
|
#include "vm.h"
|
||||||
|
#include "p_checkposition.h"
|
||||||
|
|
||||||
static TArray<FPropertyInfo*> properties;
|
static TArray<FPropertyInfo*> properties;
|
||||||
static TArray<AFuncDesc> AFTable;
|
static TArray<AFuncDesc> AFTable;
|
||||||
|
@ -856,6 +858,14 @@ void InitThingdef()
|
||||||
qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp);
|
qsort(&AFTable[0], AFTable.Size(), sizeof(AFTable[0]), funccmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add the constructor and destructor to FCheckPosition.
|
||||||
|
auto fcp = NewStruct("FCheckPosition", nullptr);
|
||||||
|
fcp->mConstructor = *FindFunction(fcp, "_Constructor")->VMPointer;
|
||||||
|
fcp->mDestructor = *FindFunction(fcp, "_Destructor")->VMPointer;
|
||||||
|
fcp->Size = sizeof(FCheckPosition);
|
||||||
|
fcp->Align = alignof(FCheckPosition);
|
||||||
|
|
||||||
|
|
||||||
FieldTable.Clear();
|
FieldTable.Clear();
|
||||||
if (FieldTable.Size() == 0)
|
if (FieldTable.Size() == 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1116,9 +1116,9 @@ struct AFuncDesc
|
||||||
MSVC_FSEG FieldDesc const *const VMField_##icls##_##name##_HookPtr GCC_FSEG = &VMField_##icls##_##name;
|
MSVC_FSEG FieldDesc const *const VMField_##icls##_##name##_HookPtr GCC_FSEG = &VMField_##icls##_##name;
|
||||||
|
|
||||||
#define DEFINE_FIELD_NAMED_X(cls, icls, name, scriptname) \
|
#define DEFINE_FIELD_NAMED_X(cls, icls, name, scriptname) \
|
||||||
static const FieldDesc VMField_##icls##_##scriptname = { "A" #cls, #scriptname, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), 0 }; \
|
static const FieldDesc VMField_##cls##_##scriptname = { "A" #cls, #scriptname, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), 0 }; \
|
||||||
extern FieldDesc const *const VMField_##icls##_##scriptname##_HookPtr; \
|
extern FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr; \
|
||||||
MSVC_FSEG FieldDesc const *const VMField_##icls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##icls##_##scriptname;
|
MSVC_FSEG FieldDesc const *const VMField_##cls##_##scriptname##_HookPtr GCC_FSEG = &VMField_##cls##_##scriptname;
|
||||||
|
|
||||||
#define DEFINE_FIELD_X_BIT(cls, icls, name, bitval) \
|
#define DEFINE_FIELD_X_BIT(cls, icls, name, bitval) \
|
||||||
static const FieldDesc VMField_##icls##_##name = { "A" #cls, #name, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), bitval }; \
|
static const FieldDesc VMField_##icls##_##name = { "A" #cls, #name, (unsigned)myoffsetof(icls, name), (unsigned)sizeof(icls::name), bitval }; \
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
class VMFunctionBuilder;
|
class VMFunctionBuilder;
|
||||||
class FxExpression;
|
class FxExpression;
|
||||||
|
class FxLocalVariableDeclaration;
|
||||||
|
|
||||||
struct ExpEmit
|
struct ExpEmit
|
||||||
{
|
{
|
||||||
|
@ -92,6 +93,7 @@ public:
|
||||||
|
|
||||||
// keep the frame pointer, if needed, in a register because the LFP opcode is hideously inefficient, requiring more than 20 instructions on x64.
|
// keep the frame pointer, if needed, in a register because the LFP opcode is hideously inefficient, requiring more than 20 instructions on x64.
|
||||||
ExpEmit FramePointer;
|
ExpEmit FramePointer;
|
||||||
|
TArray<FxLocalVariableDeclaration *> ConstructedStructs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct AddrKonst
|
struct AddrKonst
|
||||||
|
|
|
@ -71,8 +71,8 @@ protected:
|
||||||
struct FArray
|
struct FArray
|
||||||
{
|
{
|
||||||
void *Array;
|
void *Array;
|
||||||
unsigned int Most;
|
|
||||||
unsigned int Count;
|
unsigned int Count;
|
||||||
|
unsigned int Most;
|
||||||
};
|
};
|
||||||
|
|
||||||
// T is the type stored in the array.
|
// T is the type stored in the array.
|
||||||
|
|
|
@ -1337,7 +1337,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE nothing, LPSTR cmdline, int n
|
||||||
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
|
_CrtSetDbgFlag (_CrtSetDbgFlag(0) | _CRTDBG_LEAK_CHECK_DF);
|
||||||
|
|
||||||
// Use this to break at a specific allocation number.
|
// Use this to break at a specific allocation number.
|
||||||
_crtBreakAlloc = 124459;
|
//_crtBreakAlloc = 53039;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DoMain (hInstance);
|
DoMain (hInstance);
|
||||||
|
|
|
@ -1,3 +1,34 @@
|
||||||
|
struct FCheckPosition
|
||||||
|
{
|
||||||
|
// in
|
||||||
|
native Actor thing;
|
||||||
|
native Vector3 pos;
|
||||||
|
|
||||||
|
// out
|
||||||
|
native Sector cursector;
|
||||||
|
native double floorz;
|
||||||
|
native double ceilingz;
|
||||||
|
native double dropoffz;
|
||||||
|
native TextureID floorpic;
|
||||||
|
native int floorterrain;
|
||||||
|
native Sector floorsector;
|
||||||
|
native TextureID ceilingpic;
|
||||||
|
native Sector ceilingsector;
|
||||||
|
native bool touchmidtex;
|
||||||
|
native bool abovemidtex;
|
||||||
|
native bool floatok;
|
||||||
|
native bool FromPMove;
|
||||||
|
native line ceilingline;
|
||||||
|
native Actor stepthing;
|
||||||
|
native bool DoRipping;
|
||||||
|
native bool portalstep;
|
||||||
|
|
||||||
|
native int PushTime;
|
||||||
|
|
||||||
|
native void ClearLastRipped();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class Actor : Thinker native
|
class Actor : Thinker native
|
||||||
{
|
{
|
||||||
const DEFAULT_HEALTH = 1000;
|
const DEFAULT_HEALTH = 1000;
|
||||||
|
@ -327,7 +358,7 @@ class Actor : Thinker native
|
||||||
native double BulletSlope(out FTranslatedLineTarget pLineTarget = null, int aimflags = 0);
|
native double BulletSlope(out FTranslatedLineTarget pLineTarget = null, int aimflags = 0);
|
||||||
native Actor AimTarget();
|
native Actor AimTarget();
|
||||||
native bool CheckMissileSpawn(double maxdist);
|
native bool CheckMissileSpawn(double maxdist);
|
||||||
native bool CheckPosition(Vector2 pos, bool actorsonly = false);
|
native bool CheckPosition(Vector2 pos, bool actorsonly = false, FCheckPosition tm = null);
|
||||||
native bool TestMobjLocation();
|
native bool TestMobjLocation();
|
||||||
native static Actor Spawn(class<Actor> type, vector3 pos = (0,0,0), int replace = NO_REPLACE);
|
native static Actor Spawn(class<Actor> type, vector3 pos = (0,0,0), int replace = NO_REPLACE);
|
||||||
native Actor SpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
|
native Actor SpawnMissile(Actor dest, class<Actor> type, Actor owner = null);
|
||||||
|
@ -388,7 +419,7 @@ class Actor : Thinker native
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
native bool TryMove(vector2 newpos, int dropoff);
|
native bool TryMove(vector2 newpos, int dropoff, bool missilecheck = false, FCheckPosition tm = null);
|
||||||
native void NewChaseDir();
|
native void NewChaseDir();
|
||||||
native void RandomChaseDir();
|
native void RandomChaseDir();
|
||||||
native bool CheckMissileRange();
|
native bool CheckMissileRange();
|
||||||
|
|
Loading…
Reference in a new issue