mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-14 16:41:13 +00:00
- Added a big-endian fix for actor flag fields that aren't four bytes wide.
SVN r4251 (trunk)
This commit is contained in:
parent
40f7abb8e9
commit
9072c25e65
5 changed files with 99 additions and 32 deletions
|
@ -22,12 +22,15 @@ struct FFlagDef
|
||||||
unsigned int flagbit;
|
unsigned int flagbit;
|
||||||
const char *name;
|
const char *name;
|
||||||
int structoffset;
|
int structoffset;
|
||||||
|
int fieldsize;
|
||||||
};
|
};
|
||||||
|
|
||||||
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
|
FFlagDef *FindFlag (const PClass *type, const char *part1, const char *part2);
|
||||||
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index);
|
void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int index);
|
||||||
bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index);
|
bool CheckDeprecatedFlags(const AActor *actor, FActorInfo *info, int index);
|
||||||
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
const char *GetFlagName(unsigned int flagnum, int flagoffset);
|
||||||
|
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set);
|
||||||
|
INTBOOL CheckActorFlag(const AActor *actor, FFlagDef *fd);
|
||||||
|
|
||||||
#define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(AActor, flagvar))
|
#define FLAG_NAME(flagnum, flagvar) GetFlagName(flagnum, myoffsetof(AActor, flagvar))
|
||||||
|
|
||||||
|
|
|
@ -3629,14 +3629,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_ChangeFlag)
|
||||||
bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
bool linkchange = flagp == &self->flags && (fd->flagbit == MF_NOBLOCKMAP || fd->flagbit == MF_NOSECTOR);
|
||||||
|
|
||||||
if (linkchange) self->UnlinkFromWorld();
|
if (linkchange) self->UnlinkFromWorld();
|
||||||
if (expression)
|
ModActorFlag(self, fd, expression);
|
||||||
{
|
|
||||||
*flagp |= fd->flagbit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*flagp &= ~fd->flagbit;
|
|
||||||
}
|
|
||||||
if (linkchange) self->LinkToWorld();
|
if (linkchange) self->LinkToWorld();
|
||||||
}
|
}
|
||||||
kill_after = self->CountsAsKill();
|
kill_after = self->CountsAsKill();
|
||||||
|
@ -3721,13 +3714,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_CheckFlag)
|
||||||
|
|
||||||
if (fd != NULL)
|
if (fd != NULL)
|
||||||
{
|
{
|
||||||
if (fd->structoffset == -1)
|
if (CheckActorFlag(owner, fd))
|
||||||
{
|
|
||||||
if (CheckDeprecatedFlags(owner, cls->ActorInfo, fd->flagbit)) {
|
|
||||||
ACTION_JUMP(jumpto);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( fd->flagbit & *(DWORD*)(((char*)owner) + fd->structoffset))
|
|
||||||
{
|
{
|
||||||
ACTION_JUMP(jumpto);
|
ACTION_JUMP(jumpto);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,10 +55,10 @@ static TArray<FVariableInfo*> variables;
|
||||||
//==========================================================================
|
//==========================================================================
|
||||||
|
|
||||||
// [RH] Keep GCC quiet by not using offsetof on Actor types.
|
// [RH] Keep GCC quiet by not using offsetof on Actor types.
|
||||||
#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1 }
|
#define DEFINE_FLAG(prefix, name, type, variable) { prefix##_##name, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable) }
|
||||||
#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1 }
|
#define DEFINE_FLAG2(symbol, name, type, variable) { symbol, #name, (int)(size_t)&((type*)1)->variable - 1, sizeof(((type *)0)->variable) }
|
||||||
#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1 }
|
#define DEFINE_DEPRECATED_FLAG(name) { DEPF_##name, #name, -1, 0 }
|
||||||
#define DEFINE_DUMMY_FLAG(name) { DEPF_UNUSED, #name, -1 }
|
#define DEFINE_DUMMY_FLAG(name) { DEPF_UNUSED, #name, -1, 0 }
|
||||||
|
|
||||||
static FFlagDef ActorFlags[]=
|
static FFlagDef ActorFlags[]=
|
||||||
{
|
{
|
||||||
|
|
|
@ -441,15 +441,7 @@ void HandleActorFlag(FScanner &sc, Baggage &bag, const char *part1, const char *
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DWORD * flagvar = (DWORD*) ((char*)defaults + fd->structoffset);
|
ModActorFlag(defaults, fd, mod == '+');
|
||||||
if (mod == '+')
|
|
||||||
{
|
|
||||||
*flagvar |= fd->flagbit;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*flagvar &= ~fd->flagbit;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -95,6 +95,91 @@ static const PClass *FindClassTentative(const char *name, const char *ancestor)
|
||||||
return cls;
|
return cls;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Sets or clears a flag, taking field width into account.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
void ModActorFlag(AActor *actor, FFlagDef *fd, bool set)
|
||||||
|
{
|
||||||
|
// Little-Endian machines only need one case, because all field sizes
|
||||||
|
// start at the same address. (Unless the machine has unaligned access
|
||||||
|
// exceptions, in which case you'll need multiple cases for it too.)
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
if (fd->fieldsize == 4)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
DWORD *flagvar = (DWORD *)((char *)actor + fd->structoffset);
|
||||||
|
if (set)
|
||||||
|
{
|
||||||
|
*flagvar |= fd->flagbit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*flagvar &= ~fd->flagbit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
else if (fd->fieldsize == 2)
|
||||||
|
{
|
||||||
|
WORD *flagvar = (WORD *)((char *)actor + fd->structoffset);
|
||||||
|
if (set)
|
||||||
|
{
|
||||||
|
*flagvar |= fd->flagbit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*flagvar &= ~fd->flagbit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(fd->fieldsize == 1);
|
||||||
|
BYTE *flagvar = (BYTE *)((char *)actor + fd->structoffset);
|
||||||
|
if (set)
|
||||||
|
{
|
||||||
|
*flagvar |= fd->flagbit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*flagvar &= ~fd->flagbit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================
|
||||||
|
//
|
||||||
|
// Returns whether an actor flag is true or not.
|
||||||
|
//
|
||||||
|
//==========================================================================
|
||||||
|
|
||||||
|
INTBOOL CheckActorFlag(const AActor *owner, FFlagDef *fd)
|
||||||
|
{
|
||||||
|
if (fd->structoffset == -1)
|
||||||
|
{
|
||||||
|
return CheckDeprecatedFlags(owner, owner->GetClass()->ActorInfo, fd->flagbit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#ifdef __BIG_ENDIAN__
|
||||||
|
if (fd->fieldsize == 4)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
return fd->flagbit & *(DWORD *)(((char*)owner) + fd->structoffset);
|
||||||
|
}
|
||||||
|
#ifdef __BID_ENDIAN__
|
||||||
|
else if (fd->fieldsize == 2)
|
||||||
|
{
|
||||||
|
return fd->flagbit & *(WORD *)(((char*)owner) + fd->structoffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(fd->fieldsize == 1);
|
||||||
|
return fd->flagbit & *(BYTE *)(((char*)owner) + fd->structoffset);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//
|
//
|
||||||
// HandleDeprecatedFlags
|
// HandleDeprecatedFlags
|
||||||
|
@ -170,7 +255,7 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index)
|
bool CheckDeprecatedFlags(const AActor *actor, FActorInfo *info, int index)
|
||||||
{
|
{
|
||||||
// A deprecated flag is false if
|
// A deprecated flag is false if
|
||||||
// a) it hasn't been added here
|
// a) it hasn't been added here
|
||||||
|
@ -211,11 +296,11 @@ bool CheckDeprecatedFlags(AActor *actor, FActorInfo *info, int index)
|
||||||
return (actor->BounceFlags & (BOUNCE_TypeMask|BOUNCE_UseSeeSound)) == BOUNCE_DoomCompat;
|
return (actor->BounceFlags & (BOUNCE_TypeMask|BOUNCE_UseSeeSound)) == BOUNCE_DoomCompat;
|
||||||
|
|
||||||
case DEPF_PICKUPFLASH:
|
case DEPF_PICKUPFLASH:
|
||||||
return static_cast<AInventory*>(actor)->PickupFlash == PClass::FindClass("PickupFlash");
|
return static_cast<const AInventory*>(actor)->PickupFlash == PClass::FindClass("PickupFlash");
|
||||||
// A pure name lookup may or may not be more efficient, but I know no static identifier for PickupFlash.
|
// A pure name lookup may or may not be more efficient, but I know no static identifier for PickupFlash.
|
||||||
|
|
||||||
case DEPF_INTERHUBSTRIP:
|
case DEPF_INTERHUBSTRIP:
|
||||||
return !(static_cast<AInventory*>(actor)->InterHubAmount);
|
return !(static_cast<const AInventory*>(actor)->InterHubAmount);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // Any entirely unknown flag is not set
|
return false; // Any entirely unknown flag is not set
|
||||||
|
|
Loading…
Reference in a new issue