the MISSILE(EVEN)MORE flags still need to be accessible by ZScript for backwards compatibility.

Since these do not exist anymore an internal interface to Handle/CheckDeprecatedFlags was added.
This commit is contained in:
Christoph Oelckers 2024-10-03 12:32:09 +02:00
parent 8354c4a5c3
commit 3798fd815f
5 changed files with 190 additions and 103 deletions

View file

@ -278,6 +278,8 @@ xx(BuiltinNameToClass)
xx(BuiltinClassCast)
xx(BuiltinFunctionPtrCast)
xx(BuiltinFindTranslation)
xx(HandleDeprecatedFlags)
xx(CheckDeprecatedFlags)
xx(ScreenJobRunner)
xx(Action)

View file

@ -2828,10 +2828,17 @@ FxExpression *FxAssign::Resolve(FCompileContext &ctx)
// Special case: Assignment to a bitfield.
IsBitWrite = Base->GetBitValue();
if (IsBitWrite >= 0x10000)
{
// internal flags - need more here
IsBitWrite &= 0xffff;
}
return this;
}
ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
{
if (IsBitWrite < 64)
{
static const uint8_t loadops[] = { OP_LK, OP_LKF, OP_LKS, OP_LKP };
assert(Base->ValueType->GetRegType() == Right->ValueType->GetRegType());
@ -2887,7 +2894,6 @@ ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
{
build->Emit(OP_SBIT, pointer.RegNum, result.RegNum, 1 << IsBitWrite);
}
}
if (AddressRequested)
@ -2907,6 +2913,21 @@ ExpEmit FxAssign::Emit(VMFunctionBuilder *build)
return result;
}
}
else
{
VMFunction* callfunc;
auto sym = FindBuiltinFunction(NAME_HandleDeprecatedFlags);
assert(sym);
callfunc = sym->Variants[0].Implementation;
FunctionCallEmitter emitters(callfunc);
emitters.AddParameter(build, Base);
emitters.AddParameter(build, Right);
emitters.AddParameterIntConst(IsBitWrite - 64);
return emitters.EmitCall(build);
}
}
//==========================================================================
//
@ -2933,18 +2954,20 @@ FxExpression *FxAssignSelf::Resolve(FCompileContext &ctx)
}
ExpEmit FxAssignSelf::Emit(VMFunctionBuilder *build)
{
if (Assignment->IsBitWrite < 64)
{
ExpEmit pointer = Assignment->Address; // FxAssign should have already emitted it
if (!pointer.Target)
{
ExpEmit out(build, ValueType->GetRegType(), ValueType->GetRegCount());
if (Assignment->IsBitWrite != -1)
if (Assignment->IsBitWrite == -1)
{
build->Emit(OP_LBIT, out.RegNum, pointer.RegNum, 1 << Assignment->IsBitWrite);
build->Emit(ValueType->GetLoadOp(), out.RegNum, pointer.RegNum, build->GetConstantInt(0));
}
else
{
build->Emit(ValueType->GetLoadOp(), out.RegNum, pointer.RegNum, build->GetConstantInt(0));
build->Emit(OP_LBIT, out.RegNum, pointer.RegNum, 1 << Assignment->IsBitWrite);
}
return out;
}
@ -2953,6 +2976,21 @@ ExpEmit FxAssignSelf::Emit(VMFunctionBuilder *build)
return pointer;
}
}
else
{
VMFunction* callfunc;
auto sym = FindBuiltinFunction(NAME_CheckDeprecatedFlags);
assert(sym);
callfunc = sym->Variants[0].Implementation;
FunctionCallEmitter emitters(callfunc);
emitters.AddParameter(build, Assignment->Base);
emitters.AddParameterIntConst(Assignment->IsBitWrite - 64);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
}
}
//==========================================================================
@ -7727,6 +7765,8 @@ FxExpression *FxStructMember::Resolve(FCompileContext &ctx)
}
ExpEmit FxStructMember::Emit(VMFunctionBuilder *build)
{
if (membervar->BitValue < 64 || AddressRequested)
{
ExpEmit obj = classx->Emit(build);
assert(obj.RegType == REGT_POINTER);
@ -7779,6 +7819,21 @@ ExpEmit FxStructMember::Emit(VMFunctionBuilder *build)
obj.Free(build);
return loc;
}
else
{
VMFunction* callfunc;
auto sym = FindBuiltinFunction(NAME_CheckDeprecatedFlags);
assert(sym);
callfunc = sym->Variants[0].Implementation;
FunctionCallEmitter emitters(callfunc);
emitters.AddParameter(build, classx);
emitters.AddParameterIntConst(membervar->BitValue - 64);
emitters.AddReturn(REGT_INT);
return emitters.EmitCall(build);
}
}
//==========================================================================

View file

@ -920,6 +920,18 @@ void SynthesizeFlagFields()
{
cls->VMType->AddNativeField(FStringf("b%s", fl.Defs[i].name), (fl.Defs[i].fieldsize == 4 ? TypeSInt32 : TypeSInt16), fl.Defs[i].structoffset, fl.Defs[i].varflags, fl.Defs[i].flagbit);
}
else if (fl.Defs[i].flagbit == DEPF_MISSILEMORE || fl.Defs[i].flagbit == DEPF_MISSILEEVENMORE) // these need script side emulation because they have been around for many years.
{
auto field = cls->VMType->AddNativeField(FStringf("b%s", fl.Defs[i].name), TypeSInt32, 0, VARF_Native);
if (field)
{
// these are deprecated so flag accordingly with a proper message.
field->DeprecationMessage = "Use missilechancemult property instead";
field->mVersion = MakeVersion(4, 13, 0);
field->Flags |= VARF_Deprecated;
field->BitValue = fl.Defs[i].flagbit + 64;
}
}
}
}
}

View file

@ -361,6 +361,15 @@ void HandleDeprecatedFlags(AActor *actor, int set, int index)
}
}
// the interface here works on object, but currently all deprecated flags affect subclasses of Actor only
DEFINE_ACTION_FUNCTION_NATIVE(DObject, HandleDeprecatedFlags, HandleDeprecatedFlags)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(set);
PARAM_INT(index);
HandleDeprecatedFlags(self, set, index);
return 0;
}
//===========================================================================
//
// CheckDeprecatedFlags
@ -429,6 +438,13 @@ int CheckDeprecatedFlags(AActor *actor, int index)
return false; // Any entirely unknown flag is not set
}
DEFINE_ACTION_FUNCTION_NATIVE(DObject, CheckDeprecatedFlags, CheckDeprecatedFlags)
{
PARAM_SELF_PROLOGUE(AActor);
PARAM_INT(index);
ACTION_RETURN_INT(CheckDeprecatedFlags(self, index));
}
//==========================================================================
//
//

View file

@ -760,6 +760,8 @@ class Object native
private native static Class<Object> BuiltinNameToClass(Name nm, Class<Object> filter);
private native static Object BuiltinClassCast(Object inptr, Class<Object> test);
private native static Function<void> BuiltinFunctionPtrCast(Function<void> inptr, voidptr newtype);
private native static void HandleDeprecatedFlags(Object obj, bool set, int index);
private native static bool CheckDeprecatedFlags(Object obj, int index);
native static uint MSTime();
native static double MSTimeF();