mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- moved around some pieces of code to make sharing with Raze easier.
This commit is contained in:
parent
f8ac9a2662
commit
cf51508ce6
21 changed files with 96 additions and 74 deletions
|
@ -473,60 +473,6 @@ size_t DObject::PointerSubstitution (DObject *old, DObject *notOld)
|
|||
return changed;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This once was the main method for pointer cleanup, but
|
||||
// nowadays its only use is swapping out PlayerPawns.
|
||||
// This requires pointer fixing throughout all objects and a few
|
||||
// global variables, but it only needs to look at pointers that
|
||||
// can point to a player.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DObject::StaticPointerSubstitution (AActor *old, AActor *notOld)
|
||||
{
|
||||
DObject *probe;
|
||||
size_t changed = 0;
|
||||
int i;
|
||||
|
||||
if (old == nullptr) return;
|
||||
|
||||
// This is only allowed to replace players. For everything else the results are undefined.
|
||||
if (!old->IsKindOf(NAME_PlayerPawn) || (notOld != nullptr && !notOld->IsKindOf(NAME_PlayerPawn))) return;
|
||||
|
||||
// Go through all objects.
|
||||
i = 0;DObject *last=0;
|
||||
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
|
||||
{
|
||||
i++;
|
||||
changed += probe->PointerSubstitution(old, notOld);
|
||||
last = probe;
|
||||
}
|
||||
|
||||
// Go through players.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
AActor *replacement = notOld;
|
||||
auto &p = players[i];
|
||||
|
||||
if (p.mo == old) p.mo = replacement, changed++;
|
||||
if (p.poisoner.pp == old) p.poisoner = replacement, changed++;
|
||||
if (p.attacker.pp == old) p.attacker = replacement, changed++;
|
||||
if (p.camera.pp == old) p.camera = replacement, changed++;
|
||||
if (p.ConversationNPC.pp == old) p.ConversationNPC = replacement, changed++;
|
||||
if (p.ConversationPC == old) p.ConversationPC = replacement, changed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through sectors. Only the level this actor belongs to is relevant.
|
||||
for (auto &sec : old->Level->sectors)
|
||||
{
|
||||
if (sec.SoundTarget == old) sec.SoundTarget = notOld;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
|
|
@ -247,7 +247,6 @@ public:
|
|||
|
||||
// This is only needed for swapping out PlayerPawns and absolutely nothing else!
|
||||
virtual size_t PointerSubstitution (DObject *old, DObject *notOld);
|
||||
static void StaticPointerSubstitution (AActor *old, AActor *notOld);
|
||||
|
||||
PClass *GetClass() const
|
||||
{
|
||||
|
|
|
@ -276,8 +276,6 @@ void MarkArray(DObject **obj, size_t count)
|
|||
|
||||
static void MarkRoot()
|
||||
{
|
||||
int i;
|
||||
|
||||
Gray = NULL;
|
||||
Mark(StatusBar);
|
||||
M_MarkMenus();
|
||||
|
@ -288,7 +286,7 @@ static void MarkRoot()
|
|||
Level->Mark();
|
||||
|
||||
// Mark players.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
for (int i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
players[i].PropagateMark();
|
||||
|
|
|
@ -208,6 +208,11 @@ public:
|
|||
return GC::ReadBarrier(pp);
|
||||
}
|
||||
|
||||
T ForceGet() throw() //for situations where the read barrier needs to be skipped.
|
||||
{
|
||||
return pp;
|
||||
}
|
||||
|
||||
operator T() throw()
|
||||
{
|
||||
return GC::ReadBarrier(pp);
|
||||
|
|
|
@ -77,7 +77,7 @@ bool PClass::bVMOperational;
|
|||
// that does not work anymore. WP_NOCHANGE needs to point to a vaild object to work as intended.
|
||||
// This Object does not need to be garbage collected, though, but it needs to provide the proper structure so that the
|
||||
// GC can process it.
|
||||
AActor *WP_NOCHANGE;
|
||||
DObject *WP_NOCHANGE;
|
||||
DEFINE_GLOBAL(WP_NOCHANGE);
|
||||
|
||||
|
||||
|
@ -231,7 +231,7 @@ void PClass::StaticInit ()
|
|||
|
||||
// WP_NOCHANGE must point to a valid object, although it does not need to be a weapon.
|
||||
// A simple DObject is enough to give the GC the ability to deal with it, if subjected to it.
|
||||
WP_NOCHANGE = (AActor*)Create<DObject>();
|
||||
WP_NOCHANGE = Create<DObject>();
|
||||
WP_NOCHANGE->Release();
|
||||
}
|
||||
|
||||
|
|
|
@ -17,14 +17,14 @@ class VMException : public DObject
|
|||
|
||||
// An action function -------------------------------------------------------
|
||||
|
||||
struct FState;
|
||||
struct StateCallData;
|
||||
class VMFrameStack;
|
||||
struct VMValue;
|
||||
struct VMReturn;
|
||||
class VMFunction;
|
||||
class PClassType;
|
||||
struct FNamespaceManager;
|
||||
class PSymbol;
|
||||
class PField;
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#include "serializer.h"
|
||||
#include "types.h"
|
||||
#include "vm.h"
|
||||
#include "printf.h"
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
|
|
|
@ -34,9 +34,10 @@
|
|||
*/
|
||||
|
||||
#include "vmintern.h"
|
||||
#include "s_sound.h"
|
||||
#include "dthinker.h"
|
||||
#include "s_soundinternal.h"
|
||||
#include "types.h"
|
||||
#include "printf.h"
|
||||
#include "textureid.h"
|
||||
|
||||
|
||||
FTypeTable TypeTable;
|
||||
|
@ -1101,7 +1102,9 @@ PSpriteID::PSpriteID()
|
|||
void PSpriteID::WriteValue(FSerializer &ar, const char *key, const void *addr) const
|
||||
{
|
||||
int32_t val = *(int*)addr;
|
||||
#ifdef GZDOOM
|
||||
ar.Sprite(key, val, nullptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1113,7 +1116,9 @@ void PSpriteID::WriteValue(FSerializer &ar, const char *key, const void *addr) c
|
|||
bool PSpriteID::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||
{
|
||||
int32_t val;
|
||||
#ifdef GZDOOM
|
||||
ar.Sprite(key, val, nullptr);
|
||||
#endif
|
||||
*(int*)addr = val;
|
||||
return true;
|
||||
}
|
||||
|
@ -1184,7 +1189,7 @@ PSound::PSound()
|
|||
|
||||
void PSound::WriteValue(FSerializer &ar, const char *key,const void *addr) const
|
||||
{
|
||||
const char *cptr = S_GetSoundName(*(const FSoundID *)addr);
|
||||
const char *cptr = soundEngine->GetSoundName(*(const FSoundID *)addr);
|
||||
ar.StringPtr(key, cptr);
|
||||
}
|
||||
|
||||
|
@ -1358,7 +1363,7 @@ PObjectPointer::PObjectPointer(PClass *cls, bool isconst)
|
|||
loadOp = OP_LO;
|
||||
Flags |= TYPE_ObjectPointer;
|
||||
// Non-destroyed thinkers are always guaranteed to be linked into the thinker chain so we don't need the write barrier for them.
|
||||
if (cls && !cls->IsDescendantOf(RUNTIME_CLASS(DThinker))) storeOp = OP_SO;
|
||||
if (cls && !cls->IsDescendantOf(NAME_Thinker)) storeOp = OP_SO;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1458,7 +1463,9 @@ PStatePointer::PStatePointer()
|
|||
|
||||
void PStatePointer::WriteValue(FSerializer &ar, const char *key, const void *addr) const
|
||||
{
|
||||
#ifdef GZDOOM
|
||||
ar(key, *(FState **)addr);
|
||||
#endif
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1470,7 +1477,9 @@ void PStatePointer::WriteValue(FSerializer &ar, const char *key, const void *add
|
|||
bool PStatePointer::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
||||
{
|
||||
bool res = false;
|
||||
#ifdef GZDOOM
|
||||
::Serialize(ar, key, *(FState **)addr, nullptr, &res);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -1700,7 +1709,7 @@ bool PArray::ReadValue(FSerializer &ar, const char *key, void *addr) const
|
|||
{
|
||||
bool readsomething = false;
|
||||
unsigned count = ar.ArraySize();
|
||||
unsigned loop = MIN(count, ElementCount);
|
||||
unsigned loop = std::min(count, ElementCount);
|
||||
uint8_t *addrb = (uint8_t *)addr;
|
||||
for(unsigned i=0;i<loop;i++)
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "dobject.h"
|
||||
#include "serializer.h"
|
||||
#include "symbols.h"
|
||||
#include "scopebarrier.h"
|
||||
|
||||
// Variable/parameter/field flags -------------------------------------------
|
||||
|
|
|
@ -1515,7 +1515,7 @@ int FLevelLocals::FinishTravel ()
|
|||
pawn->flags2 &= ~MF2_BLASTED;
|
||||
if (oldpawn != nullptr)
|
||||
{
|
||||
DObject::StaticPointerSubstitution (oldpawn, pawn);
|
||||
StaticPointerSubstitution (oldpawn, pawn);
|
||||
oldpawn->Destroy();
|
||||
}
|
||||
if (pawndup != NULL)
|
||||
|
|
|
@ -50,6 +50,7 @@ struct FActorInfo;
|
|||
class FIntCVar;
|
||||
class FStateDefinitions;
|
||||
class FInternalLightAssociation;
|
||||
struct FState;
|
||||
|
||||
enum EStateDefineFlags
|
||||
{
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "v_text.h"
|
||||
|
||||
struct event_t;
|
||||
struct FState;
|
||||
|
||||
#define DECLARE_SUPER_CLASS(cls,parent) \
|
||||
private: \
|
||||
|
|
|
@ -1558,6 +1558,8 @@ struct FTranslatedLineTarget
|
|||
};
|
||||
|
||||
|
||||
void StaticPointerSubstitution(AActor* old, AActor* notOld);
|
||||
|
||||
#define S_FREETARGMOBJ 1
|
||||
|
||||
#endif // __P_MOBJ_H__
|
||||
|
|
|
@ -148,7 +148,7 @@ enum
|
|||
// The VM cannot deal with this as an invalid pointer because it performs a read barrier on every object pointer read.
|
||||
// This doesn't have to point to a valid weapon, though, because WP_NOCHANGE is never dereferenced, but it must point to a valid object
|
||||
// and the class descriptor just works fine for that.
|
||||
extern AActor *WP_NOCHANGE;
|
||||
extern DObject *WP_NOCHANGE;
|
||||
|
||||
|
||||
// [GRB] Custom player classes
|
||||
|
|
|
@ -2523,7 +2523,7 @@ void FParser::SF_PlayerWeapon()
|
|||
{
|
||||
wp->Destroy();
|
||||
// If the weapon is active pick a replacement. Legacy didn't do this!
|
||||
if (Level->Players[playernum]->PendingWeapon==wp) Level->Players[playernum]->PendingWeapon=WP_NOCHANGE;
|
||||
if (Level->Players[playernum]->PendingWeapon==wp) Level->Players[playernum]->PendingWeapon=(AActor*)WP_NOCHANGE;
|
||||
if (Level->Players[playernum]->ReadyWeapon==wp)
|
||||
{
|
||||
Level->Players[playernum]->ReadyWeapon=nullptr;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
struct sector_t;
|
||||
class AActor;
|
||||
class PClass;
|
||||
struct FState;
|
||||
|
||||
|
||||
enum dirtype_t
|
||||
|
|
|
@ -4922,6 +4922,62 @@ EXTERN_CVAR(Float, fov)
|
|||
|
||||
extern bool demonew;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// This once was the main method for pointer cleanup, but
|
||||
// nowadays its only use is swapping out PlayerPawns.
|
||||
// This requires pointer fixing throughout all objects and a few
|
||||
// global variables, but it only needs to look at pointers that
|
||||
// can point to a player.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void StaticPointerSubstitution(AActor* old, AActor* notOld)
|
||||
{
|
||||
DObject* probe;
|
||||
size_t changed = 0;
|
||||
int i;
|
||||
|
||||
if (old == nullptr) return;
|
||||
|
||||
// This is only allowed to replace players. For everything else the results are undefined.
|
||||
if (!old->IsKindOf(NAME_PlayerPawn) || (notOld != nullptr && !notOld->IsKindOf(NAME_PlayerPawn))) return;
|
||||
|
||||
// Go through all objects.
|
||||
i = 0; DObject* last = 0;
|
||||
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
|
||||
{
|
||||
i++;
|
||||
changed += probe->PointerSubstitution(old, notOld);
|
||||
last = probe;
|
||||
}
|
||||
|
||||
// Go through players.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
AActor* replacement = notOld;
|
||||
auto& p = players[i];
|
||||
|
||||
if (p.mo == old) p.mo = replacement, changed++;
|
||||
if (p.poisoner.ForceGet() == old) p.poisoner = replacement, changed++;
|
||||
if (p.attacker.ForceGet() == old) p.attacker = replacement, changed++;
|
||||
if (p.camera.ForceGet() == old) p.camera = replacement, changed++;
|
||||
if (p.ConversationNPC.ForceGet() == old) p.ConversationNPC = replacement, changed++;
|
||||
if (p.ConversationPC.ForceGet() == old) p.ConversationPC = replacement, changed++;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through sectors. Only the level this actor belongs to is relevant.
|
||||
for (auto& sec : old->Level->sectors)
|
||||
{
|
||||
if (sec.SoundTarget == old) sec.SoundTarget = notOld;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
|
||||
{
|
||||
player_t *p;
|
||||
|
@ -5184,7 +5240,7 @@ AActor *FLevelLocals::SpawnPlayer (FPlayerStart *mthing, int playernum, int flag
|
|||
if (sec.SoundTarget == oldactor) sec.SoundTarget = nullptr;
|
||||
}
|
||||
|
||||
DObject::StaticPointerSubstitution (oldactor, p->mo);
|
||||
StaticPointerSubstitution (oldactor, p->mo);
|
||||
|
||||
localEventManager->PlayerRespawned(PlayerNum(p));
|
||||
Behaviors.StartTypedScripts (SCRIPT_Respawn, p->mo, true);
|
||||
|
|
|
@ -996,7 +996,7 @@ void P_SetupPsprites(player_t *player, bool startweaponup)
|
|||
player->DestroyPSprites();
|
||||
|
||||
// Spawn the ready weapon
|
||||
player->PendingWeapon = !startweaponup ? player->ReadyWeapon : WP_NOCHANGE;
|
||||
player->PendingWeapon = !startweaponup ? player->ReadyWeapon : (AActor*)WP_NOCHANGE;
|
||||
P_BringUpWeapon (player);
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define WEAPONTOP 32.
|
||||
#define WEAPON_FUDGE_Y 0.375
|
||||
struct FTranslatedLineTarget;
|
||||
struct FState;
|
||||
|
||||
//
|
||||
// Overlay psprites are scaled shapes
|
||||
|
|
|
@ -1606,11 +1606,11 @@ DEFINE_ACTION_FUNCTION_NATIVE(AActor, A_BossDeath, A_BossDeath)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Substitute, DObject::StaticPointerSubstitution)
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(AActor, Substitute, StaticPointerSubstitution)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_OBJECT(replace, AActor);
|
||||
DObject::StaticPointerSubstitution(self, replace);
|
||||
StaticPointerSubstitution(self, replace);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@ const char *GetVersionString();
|
|||
#define GAMESIG "GZDOOM"
|
||||
#define BASEWAD "gzdoom.pk3"
|
||||
#define OPTIONALWAD "game_support.pk3"
|
||||
#define GZDOOM 1
|
||||
|
||||
// More stuff that needs to be different for derivatives.
|
||||
#define GAMENAME "GZDoom"
|
||||
|
|
Loading…
Reference in a new issue