mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-27 06:12:19 +00:00
- fixed: The states parser tried to simplify the head node for random duration but it has to simplify the two value nodes separately.
- added jump by index to ZScript.
This commit is contained in:
parent
8ae7aae14a
commit
b6633bc489
6 changed files with 40 additions and 10 deletions
|
@ -718,6 +718,7 @@ public:
|
||||||
};
|
};
|
||||||
TArray<Variant> Variants;
|
TArray<Variant> Variants;
|
||||||
PClass *OwningClass = nullptr;
|
PClass *OwningClass = nullptr;
|
||||||
|
int StateCount = 0; // needed to process state indices later.
|
||||||
|
|
||||||
unsigned AddVariant(PPrototype *proto, TArray<DWORD> &argflags, TArray<FName> &argnames, VMFunction *impl, int flags);
|
unsigned AddVariant(PPrototype *proto, TArray<DWORD> &argflags, TArray<FName> &argnames, VMFunction *impl, int flags);
|
||||||
int GetImplicitArgs()
|
int GetImplicitArgs()
|
||||||
|
|
|
@ -1416,6 +1416,26 @@ FxExpression *FxTypeCast::Resolve(FCompileContext &ctx)
|
||||||
delete this;
|
delete this;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
else if (basex->IsNumeric() && basex->ValueType != TypeSound && basex->ValueType != TypeColor)
|
||||||
|
{
|
||||||
|
if (ctx.Function->SymbolName != NAME_None || !(ctx.Function->Variants[0].Flags & VARF_Action))
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "State jumps with index can only be used in anonymous state functions.");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
if (ctx.Function->StateCount != 1)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "State jumps with index cannot be used on multistate definitions");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
FxExpression *x = new FxRuntimeStateIndex(basex);
|
||||||
|
x = x->Resolve(ctx);
|
||||||
|
basex = nullptr;
|
||||||
|
delete this;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
else if (ValueType->IsKindOf(RUNTIME_CLASS(PClassPointer)))
|
||||||
{
|
{
|
||||||
|
@ -7859,6 +7879,12 @@ FxExpression *FxRuntimeStateIndex::Resolve(FCompileContext &ctx)
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
else if (Index->isConstant() && static_cast<FxConstant *>(Index) < 0)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "State index must be positive");
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
else if (Index->ValueType->GetRegType() != REGT_INT)
|
else if (Index->ValueType->GetRegType() != REGT_INT)
|
||||||
{ // Float.
|
{ // Float.
|
||||||
Index = new FxIntCast(Index, ctx.FromDecorate);
|
Index = new FxIntCast(Index, ctx.FromDecorate);
|
||||||
|
@ -7912,8 +7938,7 @@ static int BuiltinHandleRuntimeState(VMFrameStack *stack, VMValue *param, TArray
|
||||||
|
|
||||||
ExpEmit FxRuntimeStateIndex::Emit(VMFunctionBuilder *build)
|
ExpEmit FxRuntimeStateIndex::Emit(VMFunctionBuilder *build)
|
||||||
{
|
{
|
||||||
// This code can only be called from DECORATE, not ZSCRIPT so any function going through here
|
// This can only be called from inline state functions which must be VARF_Action.
|
||||||
// is an anoynmous one which are always marked as 'action'.
|
|
||||||
assert(build->NumImplicits >= NAP && build->Registers[REGT_POINTER].GetMostUsed() >= build->NumImplicits &&
|
assert(build->NumImplicits >= NAP && build->Registers[REGT_POINTER].GetMostUsed() >= build->NumImplicits &&
|
||||||
"FxRuntimeStateIndex is only valid inside action functions");
|
"FxRuntimeStateIndex is only valid inside action functions");
|
||||||
|
|
||||||
|
|
|
@ -322,7 +322,7 @@ do_stop:
|
||||||
endofstate:
|
endofstate:
|
||||||
if (ScriptCode != nullptr)
|
if (ScriptCode != nullptr)
|
||||||
{
|
{
|
||||||
auto funcsym = CreateAnonymousFunction(actor, nullptr, VARF_Method | VARF_Action);
|
auto funcsym = CreateAnonymousFunction(actor, nullptr, VARF_Method | VARF_Action, (int)statestring.Len());
|
||||||
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, ScriptCode, FStringf("%s.StateFunction.%d", actor->TypeName.GetChars(), bag.statedef.GetStateCount()), true);
|
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, ScriptCode, FStringf("%s.StateFunction.%d", actor->TypeName.GetChars(), bag.statedef.GetStateCount()), true);
|
||||||
}
|
}
|
||||||
int count = bag.statedef.AddStates(&state, statestring);
|
int count = bag.statedef.AddStates(&state, statestring);
|
||||||
|
|
|
@ -132,7 +132,7 @@ void SetImplicitArgs(TArray<PType *> *args, TArray<DWORD> *argflags, TArray<FNam
|
||||||
//
|
//
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags)
|
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags, int statecount)
|
||||||
{
|
{
|
||||||
TArray<PType *> rets(1);
|
TArray<PType *> rets(1);
|
||||||
TArray<PType *> args;
|
TArray<PType *> args;
|
||||||
|
@ -143,6 +143,7 @@ PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, i
|
||||||
SetImplicitArgs(&args, &argflags, &argnames, containingclass, flags);
|
SetImplicitArgs(&args, &argflags, &argnames, containingclass, flags);
|
||||||
|
|
||||||
PFunction *sym = new PFunction(containingclass, NAME_None); // anonymous functions do not have names.
|
PFunction *sym = new PFunction(containingclass, NAME_None); // anonymous functions do not have names.
|
||||||
|
sym->StateCount = statecount;
|
||||||
sym->AddVariant(NewPrototype(rets, args), argflags, argnames, nullptr, flags);
|
sym->AddVariant(NewPrototype(rets, args), argflags, argnames, nullptr, flags);
|
||||||
return sym;
|
return sym;
|
||||||
}
|
}
|
||||||
|
@ -201,7 +202,7 @@ void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto dmg = new FxReturnStatement(new FxIntCast(id, true), id->ScriptPosition);
|
auto dmg = new FxReturnStatement(new FxIntCast(id, true), id->ScriptPosition);
|
||||||
auto funcsym = CreateAnonymousFunction(info, TypeSInt32, VARF_Method);
|
auto funcsym = CreateAnonymousFunction(info, TypeSInt32, VARF_Method, 0);
|
||||||
defaults->DamageFunc = FunctionBuildList.AddFunction(funcsym, dmg, FStringf("%s.DamageFunction", info->TypeName.GetChars()), fromDecorate);
|
defaults->DamageFunc = FunctionBuildList.AddFunction(funcsym, dmg, FStringf("%s.DamageFunction", info->TypeName.GetChars()), fromDecorate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,7 +153,7 @@ FxExpression *ParseActions(FScanner &sc, FState state, FString statestring, Bagg
|
||||||
class FxVMFunctionCall *ParseAction(FScanner &sc, FState state, FString statestring, Baggage &bag);
|
class FxVMFunctionCall *ParseAction(FScanner &sc, FState state, FString statestring, Baggage &bag);
|
||||||
FName CheckCastKludges(FName in);
|
FName CheckCastKludges(FName in);
|
||||||
void SetImplicitArgs(TArray<PType *> *args, TArray<DWORD> *argflags, TArray<FName> *argnames, PClass *cls, DWORD funcflags);
|
void SetImplicitArgs(TArray<PType *> *args, TArray<DWORD> *argflags, TArray<FName> *argnames, PClass *cls, DWORD funcflags);
|
||||||
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags);
|
PFunction *CreateAnonymousFunction(PClass *containingclass, PType *returntype, int flags, int statecount);
|
||||||
PFunction *FindClassMemberFunction(PClass *cls, PClass *funccls, FName name, FScriptPosition &sc, bool *error);
|
PFunction *FindClassMemberFunction(PClass *cls, PClass *funccls, FName name, FScriptPosition &sc, bool *error);
|
||||||
void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate);
|
void CreateDamageFunction(PClassActor *info, AActor *defaults, FxExpression *id, bool fromDecorate);
|
||||||
|
|
||||||
|
|
|
@ -2248,6 +2248,7 @@ void ZCCCompiler::CompileStates()
|
||||||
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
|
FString statename; // The state builder wants the label as one complete string, not separated into tokens.
|
||||||
FStateDefinitions statedef;
|
FStateDefinitions statedef;
|
||||||
statedef.MakeStateDefines(dyn_cast<PClassActor>(c->Type()->ParentClass));
|
statedef.MakeStateDefines(dyn_cast<PClassActor>(c->Type()->ParentClass));
|
||||||
|
int numframes = 0;
|
||||||
|
|
||||||
for (auto s : c->States)
|
for (auto s : c->States)
|
||||||
{
|
{
|
||||||
|
@ -2279,13 +2280,15 @@ void ZCCCompiler::CompileStates()
|
||||||
// It is important to call CheckRandom before Simplify, because Simplify will resolve the function's name to nonsense
|
// It is important to call CheckRandom before Simplify, because Simplify will resolve the function's name to nonsense
|
||||||
if (CheckRandom(sl->Duration))
|
if (CheckRandom(sl->Duration))
|
||||||
{
|
{
|
||||||
auto func = static_cast<ZCC_ExprFuncCall *>(Simplify(sl->Duration, &c->Type()->Symbols, true));
|
auto func = static_cast<ZCC_ExprFuncCall *>(sl->Duration);
|
||||||
if (func->Parameters == func->Parameters->SiblingNext || func->Parameters != func->Parameters->SiblingNext->SiblingNext)
|
if (func->Parameters == func->Parameters->SiblingNext || func->Parameters != func->Parameters->SiblingNext->SiblingNext)
|
||||||
{
|
{
|
||||||
Error(sl, "Random duration requires exactly 2 parameters");
|
Error(sl, "Random duration requires exactly 2 parameters");
|
||||||
}
|
}
|
||||||
int v1 = GetInt(func->Parameters->Value);
|
auto p1 = Simplify(func->Parameters->Value, &c->Type()->Symbols, true);
|
||||||
int v2 = GetInt(static_cast<ZCC_FuncParm *>(func->Parameters->SiblingNext)->Value);
|
auto p2 = Simplify(static_cast<ZCC_FuncParm *>(func->Parameters->SiblingNext)->Value, &c->Type()->Symbols, true);
|
||||||
|
int v1 = GetInt(p1);
|
||||||
|
int v2 = GetInt(p2);
|
||||||
if (v1 > v2) std::swap(v1, v2);
|
if (v1 > v2) std::swap(v1, v2);
|
||||||
state.Tics = (int16_t)clamp<int>(v1, 0, INT16_MAX);
|
state.Tics = (int16_t)clamp<int>(v1, 0, INT16_MAX);
|
||||||
state.TicRange = (uint16_t)clamp<int>(v2 - v1, 0, UINT16_MAX);
|
state.TicRange = (uint16_t)clamp<int>(v2 - v1, 0, UINT16_MAX);
|
||||||
|
@ -2346,7 +2349,7 @@ void ZCCCompiler::CompileStates()
|
||||||
auto code = SetupActionFunction(static_cast<PClassActor *>(c->Type()), sl->Action);
|
auto code = SetupActionFunction(static_cast<PClassActor *>(c->Type()), sl->Action);
|
||||||
if (code != nullptr)
|
if (code != nullptr)
|
||||||
{
|
{
|
||||||
auto funcsym = CreateAnonymousFunction(c->Type(), nullptr, VARF_Method | VARF_Action);
|
auto funcsym = CreateAnonymousFunction(c->Type(), nullptr, VARF_Method | VARF_Action, (int)sl->Frames->Len());
|
||||||
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, code, FStringf("%s.StateFunction.%d", c->Type()->TypeName.GetChars(), statedef.GetStateCount()), false);
|
state.ActionFunc = FunctionBuildList.AddFunction(funcsym, code, FStringf("%s.StateFunction.%d", c->Type()->TypeName.GetChars(), statedef.GetStateCount()), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue