diff --git a/src/common/objects/dobject.cpp b/src/common/objects/dobject.cpp index e1ebc654b..b7d44a697 100644 --- a/src/common/objects/dobject.cpp +++ b/src/common/objects/dobject.cpp @@ -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; - } -} - //========================================================================== // // diff --git a/src/common/objects/dobject.h b/src/common/objects/dobject.h index d55a079e5..3c98d144b 100644 --- a/src/common/objects/dobject.h +++ b/src/common/objects/dobject.h @@ -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 { diff --git a/src/common/objects/dobjgc.cpp b/src/common/objects/dobjgc.cpp index 96128f2bd..de4614664 100644 --- a/src/common/objects/dobjgc.cpp +++ b/src/common/objects/dobjgc.cpp @@ -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(); diff --git a/src/common/objects/dobjgc.h b/src/common/objects/dobjgc.h index 8b8009eb7..5a181c736 100644 --- a/src/common/objects/dobjgc.h +++ b/src/common/objects/dobjgc.h @@ -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); diff --git a/src/common/objects/dobjtype.cpp b/src/common/objects/dobjtype.cpp index 247e7edd0..b0931297d 100644 --- a/src/common/objects/dobjtype.cpp +++ b/src/common/objects/dobjtype.cpp @@ -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(); + WP_NOCHANGE = Create(); WP_NOCHANGE->Release(); } diff --git a/src/common/objects/dobjtype.h b/src/common/objects/dobjtype.h index 3445e02ba..bd6fe1e6d 100644 --- a/src/common/objects/dobjtype.h +++ b/src/common/objects/dobjtype.h @@ -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 { diff --git a/src/common/scripting/core/symbols.cpp b/src/common/scripting/core/symbols.cpp index 64a52039f..c6e38551f 100644 --- a/src/common/scripting/core/symbols.cpp +++ b/src/common/scripting/core/symbols.cpp @@ -39,6 +39,7 @@ #include "serializer.h" #include "types.h" #include "vm.h" +#include "printf.h" // PUBLIC DATA DEFINITIONS ------------------------------------------------- diff --git a/src/common/scripting/core/types.cpp b/src/common/scripting/core/types.cpp index 726621716..5211bc956 100644 --- a/src/common/scripting/core/types.cpp +++ b/src/common/scripting/core/types.cpp @@ -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;iflags2 &= ~MF2_BLASTED; if (oldpawn != nullptr) { - DObject::StaticPointerSubstitution (oldpawn, pawn); + StaticPointerSubstitution (oldpawn, pawn); oldpawn->Destroy(); } if (pawndup != NULL) diff --git a/src/gamedata/info.h b/src/gamedata/info.h index 622ffe6a0..ad633f966 100644 --- a/src/gamedata/info.h +++ b/src/gamedata/info.h @@ -50,6 +50,7 @@ struct FActorInfo; class FIntCVar; class FStateDefinitions; class FInternalLightAssociation; +struct FState; enum EStateDefineFlags { diff --git a/src/intermission/intermission.h b/src/intermission/intermission.h index 69e753b32..be2d9a563 100644 --- a/src/intermission/intermission.h +++ b/src/intermission/intermission.h @@ -11,6 +11,7 @@ #include "v_text.h" struct event_t; +struct FState; #define DECLARE_SUPER_CLASS(cls,parent) \ private: \ diff --git a/src/playsim/actor.h b/src/playsim/actor.h index 91a582043..3ed12664a 100644 --- a/src/playsim/actor.h +++ b/src/playsim/actor.h @@ -1558,6 +1558,8 @@ struct FTranslatedLineTarget }; +void StaticPointerSubstitution(AActor* old, AActor* notOld); + #define S_FREETARGMOBJ 1 #endif // __P_MOBJ_H__ diff --git a/src/playsim/d_player.h b/src/playsim/d_player.h index 3bd6431aa..95ab1b893 100644 --- a/src/playsim/d_player.h +++ b/src/playsim/d_player.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 diff --git a/src/playsim/fragglescript/t_func.cpp b/src/playsim/fragglescript/t_func.cpp index 826d51908..277263854 100644 --- a/src/playsim/fragglescript/t_func.cpp +++ b/src/playsim/fragglescript/t_func.cpp @@ -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; diff --git a/src/playsim/p_enemy.h b/src/playsim/p_enemy.h index 3086cbb50..6826637e8 100644 --- a/src/playsim/p_enemy.h +++ b/src/playsim/p_enemy.h @@ -7,6 +7,7 @@ struct sector_t; class AActor; class PClass; +struct FState; enum dirtype_t diff --git a/src/playsim/p_mobj.cpp b/src/playsim/p_mobj.cpp index 80b430917..aae82eafb 100644 --- a/src/playsim/p_mobj.cpp +++ b/src/playsim/p_mobj.cpp @@ -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); diff --git a/src/playsim/p_pspr.cpp b/src/playsim/p_pspr.cpp index c282995e0..3ccc49f1e 100644 --- a/src/playsim/p_pspr.cpp +++ b/src/playsim/p_pspr.cpp @@ -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); } diff --git a/src/playsim/p_pspr.h b/src/playsim/p_pspr.h index f35bb7123..d39fdd2e4 100644 --- a/src/playsim/p_pspr.h +++ b/src/playsim/p_pspr.h @@ -40,6 +40,7 @@ #define WEAPONTOP 32. #define WEAPON_FUDGE_Y 0.375 struct FTranslatedLineTarget; +struct FState; // // Overlay psprites are scaled shapes diff --git a/src/scripting/vmthunks_actors.cpp b/src/scripting/vmthunks_actors.cpp index e20d9a056..8f233fc77 100644 --- a/src/scripting/vmthunks_actors.cpp +++ b/src/scripting/vmthunks_actors.cpp @@ -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; } diff --git a/src/version.h b/src/version.h index 24e0fbd96..92b4e7051 100644 --- a/src/version.h +++ b/src/version.h @@ -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"