mirror of
https://github.com/ZDoom/qzdoom.git
synced 2025-03-17 08:21:28 +00:00
Merge remote-tracking branch 'gzdoom/master'
This commit is contained in:
commit
ed4079c480
4 changed files with 78 additions and 25 deletions
|
@ -644,7 +644,7 @@ inline int PitchToACS(DAngle ang)
|
|||
|
||||
struct CallReturn
|
||||
{
|
||||
CallReturn(int pc, ScriptFunction *func, FBehavior *module, int32_t *locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
|
||||
CallReturn(int pc, ScriptFunction *func, FBehavior *module, const ACSLocalVariables &locals, ACSLocalArrays *arrays, bool discard, unsigned int runaway)
|
||||
: ReturnFunction(func),
|
||||
ReturnModule(module),
|
||||
ReturnLocals(locals),
|
||||
|
@ -656,7 +656,7 @@ struct CallReturn
|
|||
|
||||
ScriptFunction *ReturnFunction;
|
||||
FBehavior *ReturnModule;
|
||||
int32_t *ReturnLocals;
|
||||
ACSLocalVariables ReturnLocals;
|
||||
ACSLocalArrays *ReturnArrays;
|
||||
int ReturnAddress;
|
||||
int bDiscardResult;
|
||||
|
@ -761,6 +761,35 @@ protected:
|
|||
private:
|
||||
DLevelScript();
|
||||
|
||||
int getbyte(int *&pc)
|
||||
{
|
||||
CheckInstructionPointer(pc);
|
||||
|
||||
int res = *(uint8_t *)pc;
|
||||
pc = (int *)((uint8_t *)pc+1);
|
||||
return res;
|
||||
}
|
||||
|
||||
int getshort(int *&pc)
|
||||
{
|
||||
CheckInstructionPointer(pc);
|
||||
|
||||
int res = LittleShort( *(int16_t *)pc);
|
||||
pc = (int *)((uint8_t *)pc+2);
|
||||
return res;
|
||||
}
|
||||
|
||||
void CheckInstructionPointer(int *pc) const
|
||||
{
|
||||
const uint32_t offset = activeBehavior->PC2Ofs(pc);
|
||||
const uint32_t size = activeBehavior->GetDataSize();
|
||||
|
||||
if (offset >= size)
|
||||
{
|
||||
I_Error("Out of bounds instruction pointer in ACS VM");
|
||||
}
|
||||
}
|
||||
|
||||
friend class DACSThinker;
|
||||
};
|
||||
|
||||
|
@ -6896,7 +6925,7 @@ enum
|
|||
};
|
||||
|
||||
|
||||
#define NEXTWORD (LittleLong(*pc++))
|
||||
#define NEXTWORD (CheckInstructionPointer(pc), LittleLong(*pc++))
|
||||
#define NEXTBYTE (fmt==ACS_LittleEnhanced?getbyte(pc):NEXTWORD)
|
||||
#define NEXTSHORT (fmt==ACS_LittleEnhanced?getshort(pc):NEXTWORD)
|
||||
#define STACK(a) (Stack[sp - (a)])
|
||||
|
@ -6904,20 +6933,6 @@ enum
|
|||
// Direct instructions that take strings need to have the tag applied.
|
||||
#define TAGSTR(a) (a|activeBehavior->GetLibraryID())
|
||||
|
||||
inline int getbyte (int *&pc)
|
||||
{
|
||||
int res = *(uint8_t *)pc;
|
||||
pc = (int *)((uint8_t *)pc+1);
|
||||
return res;
|
||||
}
|
||||
|
||||
inline int getshort (int *&pc)
|
||||
{
|
||||
int res = LittleShort( *(int16_t *)pc);
|
||||
pc = (int *)((uint8_t *)pc+2);
|
||||
return res;
|
||||
}
|
||||
|
||||
static bool CharArrayParms(int &capacity, int &offset, int &a, FACSStackMemory& Stack, int &sp, bool ranged)
|
||||
{
|
||||
if (ranged)
|
||||
|
@ -6967,7 +6982,7 @@ static void SetMarineSprite(AActor *marine, PClassActor *source)
|
|||
int DLevelScript::RunScript ()
|
||||
{
|
||||
DACSThinker *controller = DACSThinker::ActiveThinker;
|
||||
int32_t *locals = &Localvars[0];
|
||||
ACSLocalVariables locals(Localvars);
|
||||
ACSLocalArrays noarrays;
|
||||
ACSLocalArrays *localarrays = &noarrays;
|
||||
ScriptFunction *activeFunction = NULL;
|
||||
|
@ -7335,7 +7350,6 @@ int DLevelScript::RunScript ()
|
|||
int i;
|
||||
ScriptFunction *func;
|
||||
FBehavior *module;
|
||||
int32_t *mylocals;
|
||||
|
||||
if(pcd == PCD_CALLSTACK)
|
||||
{
|
||||
|
@ -7364,9 +7378,9 @@ int DLevelScript::RunScript ()
|
|||
state = SCRIPT_PleaseRemove;
|
||||
break;
|
||||
}
|
||||
mylocals = locals;
|
||||
const ACSLocalVariables mylocals = locals;
|
||||
// The function's first argument is also its first local variable.
|
||||
locals = &Stack[sp - func->ArgCount];
|
||||
locals.Reset(&Stack[sp - func->ArgCount], func->ArgCount + func->LocalCount);
|
||||
// Make space on the stack for any other variables the function uses.
|
||||
for (i = 0; i < func->LocalCount; ++i)
|
||||
{
|
||||
|
@ -7405,7 +7419,7 @@ int DLevelScript::RunScript ()
|
|||
sp -= sizeof(CallReturn)/sizeof(int);
|
||||
retsp = &Stack[sp];
|
||||
activeBehavior->GetFunctionProfileData(activeFunction)->AddRun(runaway - ret->EntryInstrCount);
|
||||
sp = int(locals - &Stack[0]);
|
||||
sp = int(locals.GetPointer() - &Stack[0]);
|
||||
pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress);
|
||||
activeFunction = ret->ReturnFunction;
|
||||
activeBehavior = ret->ReturnModule;
|
||||
|
|
42
src/p_acs.h
42
src/p_acs.h
|
@ -147,6 +147,44 @@ struct ProfileCollector
|
|||
int Index;
|
||||
};
|
||||
|
||||
class ACSLocalVariables
|
||||
{
|
||||
public:
|
||||
ACSLocalVariables(TArray<int32_t> &variables)
|
||||
: memory(&variables[0])
|
||||
, count(variables.Size())
|
||||
{
|
||||
}
|
||||
|
||||
void Reset(int32_t *const memory, const size_t count)
|
||||
{
|
||||
// TODO: pointer sanity check?
|
||||
// TODO: constraints on count?
|
||||
|
||||
this->memory = memory;
|
||||
this->count = count;
|
||||
}
|
||||
|
||||
int32_t& operator[](const size_t index)
|
||||
{
|
||||
if (index >= count)
|
||||
{
|
||||
I_Error("Out of bounds access to local variables in ACS VM");
|
||||
}
|
||||
|
||||
return memory[index];
|
||||
}
|
||||
|
||||
const int32_t *GetPointer() const
|
||||
{
|
||||
return memory;
|
||||
}
|
||||
|
||||
private:
|
||||
int32_t *memory;
|
||||
size_t count;
|
||||
};
|
||||
|
||||
struct ACSLocalArrayInfo
|
||||
{
|
||||
unsigned int Size;
|
||||
|
@ -173,7 +211,7 @@ struct ACSLocalArrays
|
|||
}
|
||||
|
||||
// Bounds-checking Set and Get for local arrays
|
||||
void Set(int *locals, int arraynum, int arrayentry, int value)
|
||||
void Set(ACSLocalVariables &locals, int arraynum, int arrayentry, int value)
|
||||
{
|
||||
if ((unsigned int)arraynum < Count &&
|
||||
(unsigned int)arrayentry < Info[arraynum].Size)
|
||||
|
@ -181,7 +219,7 @@ struct ACSLocalArrays
|
|||
locals[Info[arraynum].Offset + arrayentry] = value;
|
||||
}
|
||||
}
|
||||
int Get(int *locals, int arraynum, int arrayentry)
|
||||
int Get(ACSLocalVariables &locals, int arraynum, int arrayentry)
|
||||
{
|
||||
if ((unsigned int)arraynum < Count &&
|
||||
(unsigned int)arrayentry < Info[arraynum].Size)
|
||||
|
|
|
@ -1044,7 +1044,7 @@ static void HandleReply(player_t *player, bool isconsole, int nodenum, int reply
|
|||
player->SetLogNumber(reply->LogNumber);
|
||||
}
|
||||
|
||||
if (replyText != NULL && isconsole)
|
||||
if (nullptr != replyText && '\0' != replyText[0] && isconsole)
|
||||
{
|
||||
TerminalResponse(replyText);
|
||||
}
|
||||
|
|
|
@ -168,6 +168,7 @@ class RandomSpawner : Actor
|
|||
newmobj.SpawnFlags = SpawnFlags & ~MTF_SECRET; // MTF_SECRET needs special treatment to avoid incrementing the secret counter twice. It had already been processed for the spawner itself.
|
||||
newmobj.HandleSpawnFlags();
|
||||
newmobj.SpawnFlags = SpawnFlags;
|
||||
newmobj.bCountSecret = SpawnFlags & MTF_SECRET; // "Transfer" count secret flag to spawned actor
|
||||
newmobj.ChangeTid(tid);
|
||||
newmobj.Vel = Vel;
|
||||
newmobj.master = master; // For things such as DamageMaster/DamageChildren, transfer mastery.
|
||||
|
|
Loading…
Reference in a new issue