mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-22 20:21:26 +00:00
- Merged the GC branch back into the trunk, so now it can receive more
testing from the people who download SVN trunk builds. SVN r795 (trunk)
This commit is contained in:
parent
3bfcc5c09c
commit
f2660dc336
88 changed files with 2545 additions and 1527 deletions
115
docs/rh-log.txt
115
docs/rh-log.txt
|
@ -53,7 +53,7 @@ March 7, 2008
|
|||
hardware 3D support is used and default to false.
|
||||
- Removed the libFLAC source, since FMOD Ex has native FLAC support.
|
||||
- Removed the altsound code, since it was terribly gimped in comparison to
|
||||
the FMOD code. It's original purpose was to have been as a springboard for
|
||||
the FMOD code. Its original purpose was to have been as a springboard for
|
||||
writing a non-FMOD sound system for Unix-y systems, but that never
|
||||
happened.
|
||||
- Finished preliminary FMOD Ex support.
|
||||
|
@ -66,6 +66,15 @@ March 6, 2008
|
|||
it seems to have a working volume control.
|
||||
- Renamed music_midi_stream.cpp to music_midi_base.cpp.
|
||||
- Moved the WinMM MIDI code into a new container class.
|
||||
- Fixed: StatusBar and screen need to be barriered, because they are roots
|
||||
but can also change at runtime.
|
||||
- Fixed: Objects that are forcibly deleted outside the GC need to be removed
|
||||
from the gray list too.
|
||||
|
||||
March 5, 2008
|
||||
- Fixed: Thinkers needed write barriers when they were removed from their
|
||||
lists.
|
||||
- Fixed: DLevelScript::Link() and Unlink() needed write barriers.
|
||||
|
||||
March 4, 2008
|
||||
- Moved the identical code between the MUS and MIDI streamers into a new base
|
||||
|
@ -115,6 +124,20 @@ March 1, 2008 (Changes by Graf Zahl)
|
|||
- Gave Strife's instant death sector type its own damage type.
|
||||
|
||||
February 29, 2008
|
||||
- Changed the default GC parameters to make it run more aggressively.
|
||||
- Added NULL checks to the GC::WriteBarrier() wrappers.
|
||||
- Fixed: The DObject destructor set GC::SweepPos incorrectly if it pointed
|
||||
at that object being deleted.
|
||||
- Added "soft roots" to the garbage collector. These are similar in
|
||||
purpose to setting the OF_Fixed bit, but they behave as full-fledged roots
|
||||
as far as the collector is concerned, so any objects reachable through
|
||||
them will not be collected.
|
||||
- Added support for the OF_Fixed bit. This is ONLY for simple objects which
|
||||
do not contain pointers to other objects, because all it does is prevent
|
||||
an object that is otherwise dead from being freed. It does not include
|
||||
the object in the propagate stage if it is unreachable, so any objects
|
||||
that are only reachable through it will still be freed unless they are
|
||||
also fixed.
|
||||
- Fixed: R_SetupAddClampCol() checked add4cols' memory instead of
|
||||
adclamp4cols' memory when deciding if it should skip modification.
|
||||
|
||||
|
@ -125,6 +148,8 @@ February 28, 2008
|
|||
|
||||
February 27, 2008
|
||||
- Added assembly versions of rt_add4cols and rt_addclamp4cols.
|
||||
- Added a read barrier to FArchive::SerializeObject() to make sure that
|
||||
objects that are being euthanized are not stored in the archive.
|
||||
|
||||
February 26, 2008
|
||||
- Added an assembly version of rt_shaded4cols, since that's the main decal
|
||||
|
@ -139,12 +164,54 @@ February 26, 2008
|
|||
the translation in one step and the drawing in another. This lets me call
|
||||
the untranslated drawer to do the real drawing instead of mostly duplicating
|
||||
them. Performance wise, there is practically no difference from before.
|
||||
- Fixed: Using +stat from the command line caused a crash.
|
||||
- More write barriers and pointer declarations. Here are rules I've come up
|
||||
with so far for when write barriers can be ommitted:
|
||||
* Initializing pointers for a newly created object: A new object can never
|
||||
black, so none of its pointers that get set by the constructor (or code
|
||||
just following its creation) need to be behind write barriers.
|
||||
* Creating a new thinker and storing it in a pointer: The thinker
|
||||
constructor already puts it behind a write barrier when it links it into
|
||||
the thinker list, so you don't need to do it again.
|
||||
* As a corollary of the above: No pointers to thinkers should need to be
|
||||
behind write barriers, because it is incorrect to have a thinker that is
|
||||
live but not in a thinker list. I realized this while I was going through
|
||||
the long list of actor target references, so there are some write barriers
|
||||
for those in place already, since they don't hurt to have them around.
|
||||
As a consequence of the last point, I think I'm done placing write barriers
|
||||
in all their necessary places without even touching most of the code. I'm
|
||||
going to let it sit like this for a few days to see if I can think of a
|
||||
counter-example where a live thinker wouldn't be in a thinker list, but it
|
||||
feels correct to me right now.
|
||||
|
||||
February 25, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: The DECORATE expression evaluator's random function could produce
|
||||
incorrect results for ranges > 255. Changed so that FRandom's default
|
||||
implementation is used instead.
|
||||
|
||||
February 24, 2008
|
||||
- Fixed: DDecalFader::Tick() still referenced TheDecal even after destroying
|
||||
it.
|
||||
- Added write barriers around the thinker list insertions in dthinker.cpp.
|
||||
|
||||
February 23, 2008 (Changes by Graf Zahl)
|
||||
- Fixed: AWeaponPiece didn't declare its FullWeapon pointer as such.
|
||||
- Fixed: Hexen's random player class skill menu was missing the '$' indicating
|
||||
a string table identifier.
|
||||
- Fixed: DCorpsePointer::Serialize didn't call the super method.
|
||||
|
||||
February 22, 2008
|
||||
- Moved DSeqNode's and its children's destructor code into their Destroy()
|
||||
methods.
|
||||
- Moved DSectorEffect's destructor code into a Destroy() method.
|
||||
- Changed the myoffsetof definition to match DECLARE_POINTER's because GCC
|
||||
started complaining about its use in p_setup.cpp, though I'm not sure why.
|
||||
- Added a pointer list to DACSThinker so that the collector can find scripts
|
||||
instead of thinking they're all dead.
|
||||
- Added read barriers to sector_t's pointers.
|
||||
- Used the HAS_OBJECT_POINTERS macros to locate places to place TObjPtrs to
|
||||
form read barriers.
|
||||
|
||||
February 21, 2008
|
||||
- Fixed: DThinker::SerializeAll() did not serialize any thinkers in the
|
||||
FreshThinkers lists. These thinkers would still be saved in the savegame if
|
||||
|
@ -162,6 +229,30 @@ February 21, 2008
|
|||
work for GCC (and presumably VC++, though I never ran into that case with
|
||||
it) because it tried to stringify something that wasn't a macro argument.
|
||||
|
||||
February 20, 2008
|
||||
- Changed the DHUDMessage deletions into destroys.
|
||||
- Added read barriers to the pointers inside AActor.
|
||||
- Split the AActor::LastLook union into its constituent parts.
|
||||
|
||||
February 20, 2008 (Changes by Graf Zahl)
|
||||
- Added a modified version of Karate Chris's submission for killing specific
|
||||
monsters with the 'Kill' ccmd.
|
||||
|
||||
February 19, 2008
|
||||
- Added a rough initial garbage collector, based largely on Lua's. There are
|
||||
no write or read barriers in place yet, so it's not a very close
|
||||
approximation of the pointer cleaning code that was in place before, but it
|
||||
does collect stuff. But guess what! Nuts.wad ran at 1-2 FPS before. Now
|
||||
it's way, way more and easily stays above 35 FPS. The performance hit when
|
||||
the GC is running is pretty minimal compared to the old way, which was in
|
||||
many ways like a full garbage collection every tic.
|
||||
- Changed the status bars into DObjects.
|
||||
- Fixed: FBaseStatusBar::Tick() deleted hud messages instead of destroying
|
||||
them.
|
||||
- Changed the global Args object to a pointer to one.
|
||||
- Changed several DArgs deletions into destroys.
|
||||
- Removed DBoundingBox from the DObject hierarchy.
|
||||
|
||||
February 20, 2008 (Changes by Graf Zahl)
|
||||
- Added a modified version of Karate Chris's submission for killing specific
|
||||
monsters with the 'Kill' ccmd.
|
||||
|
@ -760,7 +851,7 @@ January 1, 2008
|
|||
- Fixed a D3D memory leak on every frame in windowed mode and the same thing
|
||||
for the screen wipes. Note to self: If it's an interface, be sure to
|
||||
Release it, because it will be AddRef'ed before being returned to you.
|
||||
- Moved the BlendView() call out of FBaseStatusBar::Draw() so that it can be
|
||||
- Moved the BlendView() call out of DBaseStatusBar::Draw() so that it can be
|
||||
applied before copying the 3D scene to the screen underneath the 2D parts.
|
||||
- Restored the console's darkening level to its old table-based amount.
|
||||
- Fixed D3DFB::SetColorOverlay()'s incorrect calculations.
|
||||
|
@ -4458,7 +4549,7 @@ April 18, 2006 (Changes by Graf Zahl)
|
|||
fighting the programmer.
|
||||
|
||||
April 18, 2006
|
||||
- Fixed: FBaseStatusBar::DrBNumber() should behave like Doom's
|
||||
- Fixed: DBaseStatusBar::DrBNumber() should behave like Doom's
|
||||
STlib_drawNum(), and FDoomStatusBarTexture::DrawToBar() should add
|
||||
the textures left offset to the x coordinate before drawing.
|
||||
These fix Twice Risen's status bar.
|
||||
|
@ -5271,7 +5362,7 @@ February 11, 2005
|
|||
|
||||
February 10, 2005
|
||||
- Fixed: The screen fading ACS commands did not work when viewing through a camera
|
||||
because FBaseStatusBar::BlendView() did not think there was a player to get those
|
||||
because DBaseStatusBar::BlendView() did not think there was a player to get those
|
||||
values from. Now, the blend comes from either the player viewing from or the
|
||||
console player if the current view is not from a player.
|
||||
- Fixed: Returning to a previously visited level in a hub with fewer players than you
|
||||
|
@ -5446,7 +5537,7 @@ January 26, 2005
|
|||
Unfortunately, I didn't bump the demo version between 2.0.63a and 2.0.90, so
|
||||
anything pre-2.0.97 won't play with 2.0.97, even though there's probably
|
||||
no changes that would cause desynching between 96 and 97. Oh well.
|
||||
- Fixed FBaseStatusBar::DrBNumber(Outer) to work when some of the big number
|
||||
- Fixed DBaseStatusBar::DrBNumber(Outer) to work when some of the big number
|
||||
graphics are missing.
|
||||
|
||||
January 15, 2005
|
||||
|
@ -5622,7 +5713,7 @@ December 18, 2004
|
|||
on top of the next digit.
|
||||
- Fixed: The Doom HUD drew the selected inventory item on top of the secondary
|
||||
ammo if both were present.
|
||||
- Moved the DrawPowerups() call out of FBaseStatusBar::Draw() and into
|
||||
- Moved the DrawPowerups() call out of DBaseStatusBar::Draw() and into
|
||||
DrawTopStuff(), so the Doom HUD key display won't cover them up
|
||||
- Fixed: If you started flying and then pressed the land key, you wouldn't be
|
||||
able to fly again until the Wings of Wrath wore off. This was done by changing
|
||||
|
@ -6478,7 +6569,7 @@ July 15, 2004
|
|||
- Updated to FMOD 3.73.
|
||||
|
||||
July 14, 2004
|
||||
- Moved the full-screen HUD coordinate logic out of FBaseStatusBar and into
|
||||
- Moved the full-screen HUD coordinate logic out of DBaseStatusBar and into
|
||||
DCanvas::DrawTexture. This is so that powerups can draw their status icons
|
||||
themselves without needing to hook into the status bar.
|
||||
- Reimplemented the Tome of Power.
|
||||
|
@ -7047,7 +7138,7 @@ December 12, 2003
|
|||
up okay in Doom.)
|
||||
- Added a fix to the blockmap tracers where all the blocks along the trace are
|
||||
crossed on their corners.
|
||||
- Fixed a potential crash in FBaseStatusBar::DrawMessages() when a HUD message
|
||||
- Fixed a potential crash in DBaseStatusBar::DrawMessages() when a HUD message
|
||||
removes itself as part of its drawing process.
|
||||
- Fixed: A few of the Strife weapons were erroneously defined with WIF_NOALERT.
|
||||
- Fixed: Sky textures defaulted to 0 if a map had a MAPINFO that did not
|
||||
|
@ -7195,7 +7286,7 @@ November 23, 2003
|
|||
things spawned afterward.
|
||||
- Added calls to SetWindowLongPtr to take away the window's border in
|
||||
fullscreen mode and put it back in windowed mode.
|
||||
- Fixed FBaseStatusBar::RepositionCoords() so that LilWhiteMouse's Chosen
|
||||
- Fixed DBaseStatusBar::RepositionCoords() so that LilWhiteMouse's Chosen
|
||||
ammo icons appear on the fullscreen HUD again.
|
||||
|
||||
November 21, 2003
|
||||
|
@ -7927,7 +8018,7 @@ July 30, 2003
|
|||
- Added nonexistant texture check to the warping texture setup.
|
||||
|
||||
July 28, 2003
|
||||
- Removed the ScaleCopy canvas from FBaseStatusBar, because everything is now
|
||||
- Removed the ScaleCopy canvas from DBaseStatusBar, because everything is now
|
||||
drawn to the screen directly even when the status bar is scaled.
|
||||
- Changed the pitch calculations in the DSimpleCanvas constructor to provide
|
||||
better wall drawing performance at all resolutions.
|
||||
|
@ -11069,7 +11160,7 @@ October 23, 2001
|
|||
torch lighting up the entire sky, so skies should ignore the setting of
|
||||
fixedlightlev.
|
||||
- Fixed the scaled status bar. I was simply forgetting to add the image
|
||||
offsets in FBaseStatusBar::DrawImage() before calling CopyToScreen().
|
||||
offsets in DBaseStatusBar::DrawImage() before calling CopyToScreen().
|
||||
- Added code to let decals move with sliding and rotating polyobjects.
|
||||
- Fixed: The wait console command waited one tic too few.
|
||||
- Fixed a resizing problem with playing movies windowed.
|
||||
|
@ -11889,7 +11980,7 @@ April 7, 2001
|
|||
big ammo count when switching to a weapon that does not use ammo.
|
||||
- Fixed: At certain screen heights, scaled status bars would not touch the
|
||||
bottom of the screen because of inaccuracy in the calculation of ::ST_Y
|
||||
in FBaseStatusBar::SetScaled().
|
||||
in DBaseStatusBar::SetScaled().
|
||||
- Added separate pickup sounds for health, armor, and ammo items.
|
||||
- Improved sound link resolution in S_StartSound() so that regular sounds
|
||||
can alias player sounds.
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# Makefile for snes_spc, derived from zlib/Makefile.mgw.
|
||||
|
||||
ifeq (Windows_NT,$(OS))
|
||||
CMD=1
|
||||
endif
|
||||
ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys)
|
||||
CMD=0
|
||||
endif
|
||||
ifeq (Windows_NT,$(OS))
|
||||
CMD=1
|
||||
endif
|
||||
ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys)
|
||||
CMD=0
|
||||
endif
|
||||
|
||||
STATICLIB = libsnes_spc.a
|
||||
|
||||
|
|
38
src/actor.h
38
src/actor.h
|
@ -543,9 +543,9 @@ public:
|
|||
bool CheckLocalView (int playernum) const;
|
||||
|
||||
// Finds the first item of a particular type.
|
||||
AInventory *FindInventory (const PClass *type) const;
|
||||
AInventory *FindInventory (FName type) const;
|
||||
template<class T> T *FindInventory () const
|
||||
AInventory *FindInventory (const PClass *type);
|
||||
AInventory *FindInventory (FName type);
|
||||
template<class T> T *FindInventory ()
|
||||
{
|
||||
return static_cast<T *> (FindInventory (RUNTIME_CLASS(T)));
|
||||
}
|
||||
|
@ -554,7 +554,7 @@ public:
|
|||
AInventory *GiveInventoryType (const PClass *type);
|
||||
|
||||
// Returns the first item held with IF_INVBAR set.
|
||||
AInventory *FirstInv () const;
|
||||
AInventory *FirstInv ();
|
||||
|
||||
// Tries to give the actor some ammo.
|
||||
bool GiveAmmo (const PClass *type, int amount);
|
||||
|
@ -570,7 +570,7 @@ public:
|
|||
void ConversationAnimation (int animnum);
|
||||
|
||||
// Make this actor hate the same things as another actor
|
||||
void CopyFriendliness (const AActor *other, bool changeTarget);
|
||||
void CopyFriendliness (AActor *other, bool changeTarget);
|
||||
|
||||
// Moves the other actor's inventory to this one
|
||||
void ObtainInventory (AActor *other);
|
||||
|
@ -645,35 +645,32 @@ public:
|
|||
BYTE movedir; // 0-7
|
||||
SBYTE visdir;
|
||||
SWORD movecount; // when 0, select a new dir
|
||||
AActor *target; // thing being chased/attacked (or NULL)
|
||||
TObjPtr<AActor> target; // thing being chased/attacked (or NULL)
|
||||
// also the originator for missiles
|
||||
AActor *lastenemy; // Last known enemy -- killogh 2/15/98
|
||||
AActor *LastHeard; // [RH] Last actor this one heard
|
||||
TObjPtr<AActor> lastenemy; // Last known enemy -- killogh 2/15/98
|
||||
TObjPtr<AActor> LastHeard; // [RH] Last actor this one heard
|
||||
SDWORD reactiontime; // if non 0, don't attack yet; used by
|
||||
// player to freeze a bit after teleporting
|
||||
SDWORD threshold; // if > 0, the target will be chased
|
||||
// no matter what (even if shot)
|
||||
player_s *player; // only valid if type of APlayerPawn
|
||||
union
|
||||
{
|
||||
AActor *Actor; // Actor last looked for (if TIDtoHate != 0)
|
||||
SDWORD PlayerNumber; // Player number last looked for
|
||||
} LastLook;
|
||||
TObjPtr<AActor> LastLookActor; // Actor last looked for (if TIDtoHate != 0)
|
||||
WORD SpawnPoint[3]; // For nightmare respawn
|
||||
WORD SpawnAngle;
|
||||
int skillrespawncount;
|
||||
AActor *tracer; // Thing being chased/attacked for tracers
|
||||
AActor *master; // Thing which spawned this one (prevents mutual attacks)
|
||||
TObjPtr<AActor> tracer; // Thing being chased/attacked for tracers
|
||||
TObjPtr<AActor> master; // Thing which spawned this one (prevents mutual attacks)
|
||||
fixed_t floorclip; // value to use for floor clipping
|
||||
SWORD tid; // thing identifier
|
||||
BYTE special; // special
|
||||
int args[5]; // special arguments
|
||||
|
||||
AActor *inext, **iprev;// Links to other mobjs in same bucket
|
||||
AActor *goal; // Monster's goal if not chasing anything
|
||||
TObjPtr<AActor> goal; // Monster's goal if not chasing anything
|
||||
BYTE waterlevel; // 0=none, 1=feet, 2=waist, 3=eyes
|
||||
BYTE boomwaterlevel; // splash information for non-swimmable water sectors
|
||||
BYTE MinMissileChance;// [RH] If a random # is > than this, then missile attack.
|
||||
SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0)
|
||||
WORD SpawnFlags;
|
||||
fixed_t meleerange; // specifies how far a melee attack reaches.
|
||||
fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore
|
||||
|
@ -684,9 +681,10 @@ public:
|
|||
int bouncecount; // Strife's grenades only bounce twice before exploding
|
||||
fixed_t gravity; // [GRB] Gravity factor
|
||||
int FastChaseStrafeCount;
|
||||
// [KS] These temporary-use properties are needed to allow A_LookEx to pass it's parameters to LookFor*InBlock in
|
||||
// P_BlockmapSearch so that friendly enemies and monsters that look for other monsters can find their targets properly.
|
||||
// If there's a cleaner way of doing this, feel free to remove these and use that method instead.
|
||||
// [KS] These temporary-use properties are needed to allow A_LookEx to pass its parameters to
|
||||
// LookFor*InBlock in P_BlockmapSearch so that friendly enemies and monsters that look for
|
||||
// other monsters can find their targets properly. If there's a cleaner way of doing this,
|
||||
// feel free to remove these and use that method instead.
|
||||
fixed_t LookExMinDist; // Minimum sight distance
|
||||
fixed_t LookExMaxDist; // Maximum sight distance
|
||||
angle_t LookExFOV; // Field of Vision
|
||||
|
@ -694,7 +692,7 @@ public:
|
|||
// a linked list of sectors where this object appears
|
||||
struct msecnode_s *touching_sectorlist; // phares 3/14/98
|
||||
|
||||
AInventory *Inventory; // [RH] This actor's inventory
|
||||
TObjPtr<AInventory> Inventory; // [RH] This actor's inventory
|
||||
DWORD InventoryID; // A unique ID to keep track of inventory items
|
||||
|
||||
//Added by MC:
|
||||
|
|
|
@ -117,7 +117,7 @@ public:
|
|||
botinfo_t *botinfo;
|
||||
int spawn_tries;
|
||||
int wanted_botnum;
|
||||
AActor *firstthing;
|
||||
TObjPtr<AActor> firstthing;
|
||||
|
||||
bool m_Thinking;
|
||||
|
||||
|
@ -141,8 +141,8 @@ protected:
|
|||
bool ctf;
|
||||
int loaded_bots;
|
||||
int t_join;
|
||||
AActor *body1;
|
||||
AActor *body2;
|
||||
TObjPtr<AActor> body1;
|
||||
TObjPtr<AActor> body2;
|
||||
bool observer; //Consoleplayer is observer.
|
||||
};
|
||||
|
||||
|
|
|
@ -453,16 +453,26 @@ void DCajunMaster::SetBodyAt (fixed_t x, fixed_t y, fixed_t z, int hostnum)
|
|||
if (hostnum == 1)
|
||||
{
|
||||
if (body1)
|
||||
{
|
||||
body1->SetOrigin (x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
body1 = Spawn ("CajunBodyNode", x, y, z, NO_REPLACE);
|
||||
GC::WriteBarrier(this, body1);
|
||||
}
|
||||
}
|
||||
else if (hostnum == 2)
|
||||
{
|
||||
if (body2)
|
||||
{
|
||||
body2->SetOrigin (x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
body2 = Spawn ("CajunBodyNode", x, y, z, NO_REPLACE);
|
||||
GC::WriteBarrier(this, body2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -94,9 +94,11 @@ DCajunMaster::~DCajunMaster()
|
|||
ForgetBots();
|
||||
if (getspawned != NULL)
|
||||
{
|
||||
delete getspawned;
|
||||
getspawned->Destroy();
|
||||
getspawned = NULL;
|
||||
}
|
||||
// FIXME: Make this object proper
|
||||
ObjectFlags |= OF_Cleanup | OF_YesReallyDelete;
|
||||
}
|
||||
|
||||
//This function is called every tick (from g_game.c),
|
||||
|
|
|
@ -229,7 +229,7 @@ CUSTOM_CVAR (Int, msgmidcolor2, 4, CVAR_ARCHIVE)
|
|||
static void maybedrawnow (bool tick, bool force)
|
||||
{
|
||||
// FIXME: Does not work right with hw2d
|
||||
if (ConsoleDrawing || !gotconback || screen->IsLocked () || screen->Accel2D)
|
||||
if (ConsoleDrawing || !gotconback || screen == NULL || screen->IsLocked () || screen->Accel2D)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1250,23 +1250,23 @@ CCMD (key)
|
|||
// These all begin with '+' as opposed to '-'.
|
||||
void C_ExecCmdLineParams ()
|
||||
{
|
||||
for (int currArg = 1; currArg < Args.NumArgs(); )
|
||||
for (int currArg = 1; currArg < Args->NumArgs(); )
|
||||
{
|
||||
if (*Args.GetArg (currArg++) == '+')
|
||||
if (*Args->GetArg (currArg++) == '+')
|
||||
{
|
||||
FString cmdString;
|
||||
int cmdlen = 1;
|
||||
int argstart = currArg - 1;
|
||||
|
||||
while (currArg < Args.NumArgs())
|
||||
while (currArg < Args->NumArgs())
|
||||
{
|
||||
if (*Args.GetArg (currArg) == '-' || *Args.GetArg (currArg) == '+')
|
||||
if (*Args->GetArg (currArg) == '-' || *Args->GetArg (currArg) == '+')
|
||||
break;
|
||||
currArg++;
|
||||
cmdlen++;
|
||||
}
|
||||
|
||||
cmdString = BuildString (cmdlen, Args.GetArgList (argstart));
|
||||
cmdString = BuildString (cmdlen, Args->GetArgList (argstart));
|
||||
if (!cmdString.IsEmpty())
|
||||
{
|
||||
C_DoCommand (&cmdString[1]);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
// the dec offsetof macro doesnt work very well...
|
||||
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
|
||||
#define myoffsetof(type,identifier) ((size_t)&((type *)1)->identifier - 1)
|
||||
|
||||
int Q_filelength (FILE *f);
|
||||
bool FileExists (const char *filename);
|
||||
|
|
|
@ -161,7 +161,7 @@ public:
|
|||
void DoPickupSpecial (AActor *toucher);
|
||||
private:
|
||||
const PClass *DetermineType ();
|
||||
AInventory *RealPickup;
|
||||
TObjPtr<AInventory> RealPickup;
|
||||
};
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (ADehackedPickup)
|
||||
|
|
|
@ -745,7 +745,6 @@ void D_DoomLoop ()
|
|||
if (singletics)
|
||||
{
|
||||
I_StartTic ();
|
||||
DObject::BeginFrame ();
|
||||
D_ProcessEvents ();
|
||||
G_BuildTiccmd (&netcmds[consoleplayer][maketic%BACKUPTICS]);
|
||||
//Added by MC: For some of that bot stuff. The main bot function.
|
||||
|
@ -774,7 +773,7 @@ void D_DoomLoop ()
|
|||
G_Ticker ();
|
||||
gametic++;
|
||||
maketic++;
|
||||
DObject::EndFrame ();
|
||||
GC::CheckGC ();
|
||||
Net_NewMakeTic ();
|
||||
}
|
||||
else
|
||||
|
@ -1644,7 +1643,7 @@ static EIWADType IdentifyVersion (const char *zdoom_wad)
|
|||
{
|
||||
WadStuff wads[sizeof(IWADNames)/sizeof(char *)];
|
||||
size_t foundwads[NUM_IWAD_TYPES] = { 0 };
|
||||
const char *iwadparm = Args.CheckValue ("-iwad");
|
||||
const char *iwadparm = Args->CheckValue ("-iwad");
|
||||
size_t numwads;
|
||||
int pickwad;
|
||||
size_t i;
|
||||
|
@ -1914,7 +1913,7 @@ static const char *BaseFileSearch (const char *file, const char *ext, bool lookf
|
|||
bool ConsiderPatches (const char *arg, const char *ext)
|
||||
{
|
||||
bool noDef = false;
|
||||
DArgs *files = Args.GatherFiles (arg, ext, false);
|
||||
DArgs *files = Args->GatherFiles (arg, ext, false);
|
||||
|
||||
if (files->NumArgs() > 0)
|
||||
{
|
||||
|
@ -1930,7 +1929,7 @@ bool ConsiderPatches (const char *arg, const char *ext)
|
|||
}
|
||||
noDef = true;
|
||||
}
|
||||
delete files;
|
||||
files->Destroy();
|
||||
return noDef;
|
||||
}
|
||||
|
||||
|
@ -2038,8 +2037,7 @@ void D_DoomMain (void)
|
|||
const IWADInfo *iwad_info;
|
||||
|
||||
srand(I_MSTime());
|
||||
|
||||
atterm (DObject::StaticShutdown);
|
||||
|
||||
PClass::StaticInit ();
|
||||
atterm (C_DeinitConsole);
|
||||
|
||||
|
@ -2121,19 +2119,19 @@ void D_DoomMain (void)
|
|||
execFiles = new DArgs;
|
||||
GameConfig->AddAutoexec (execFiles, GameNames[gameinfo.gametype]);
|
||||
D_MultiExec (execFiles, true);
|
||||
delete execFiles;
|
||||
execFiles->Destroy();
|
||||
|
||||
// Run .cfg files at the start of the command line.
|
||||
execFiles = Args.GatherFiles (NULL, ".cfg", false);
|
||||
execFiles = Args->GatherFiles (NULL, ".cfg", false);
|
||||
D_MultiExec (execFiles, true);
|
||||
delete execFiles;
|
||||
execFiles->Destroy();
|
||||
|
||||
C_ExecCmdLineParams (); // [RH] do all +set commands on the command line
|
||||
|
||||
DArgs *files = Args.GatherFiles ("-file", ".wad", true);
|
||||
DArgs *files1 = Args.GatherFiles (NULL, ".zip", false);
|
||||
DArgs *files2 = Args.GatherFiles (NULL, ".pk3", false);
|
||||
DArgs *files3 = Args.GatherFiles (NULL, ".txt", false);
|
||||
DArgs *files = Args->GatherFiles ("-file", ".wad", true);
|
||||
DArgs *files1 = Args->GatherFiles (NULL, ".zip", false);
|
||||
DArgs *files2 = Args->GatherFiles (NULL, ".pk3", false);
|
||||
DArgs *files3 = Args->GatherFiles (NULL, ".txt", false);
|
||||
if (files->NumArgs() > 0 || files1->NumArgs() > 0 || files2->NumArgs() > 0 || files3->NumArgs() > 0)
|
||||
{
|
||||
// Check for -file in shareware
|
||||
|
@ -2160,10 +2158,10 @@ void D_DoomMain (void)
|
|||
D_AddWildFile (files3->GetArg (i));
|
||||
}
|
||||
}
|
||||
delete files;
|
||||
delete files1;
|
||||
delete files2;
|
||||
delete files3;
|
||||
files->Destroy();
|
||||
files1->Destroy();
|
||||
files2->Destroy();
|
||||
files3->Destroy();
|
||||
|
||||
Printf ("W_Init: Init WADfiles.\n");
|
||||
Wads.InitMultipleFiles (&wadfiles);
|
||||
|
@ -2193,18 +2191,18 @@ void D_DoomMain (void)
|
|||
|
||||
Printf ("P_Init: Checking cmd-line parameters...\n");
|
||||
flags = dmflags;
|
||||
if (Args.CheckParm ("-nomonsters")) flags |= DF_NO_MONSTERS;
|
||||
if (Args.CheckParm ("-respawn")) flags |= DF_MONSTERS_RESPAWN;
|
||||
if (Args.CheckParm ("-fast")) flags |= DF_FAST_MONSTERS;
|
||||
if (Args->CheckParm ("-nomonsters")) flags |= DF_NO_MONSTERS;
|
||||
if (Args->CheckParm ("-respawn")) flags |= DF_MONSTERS_RESPAWN;
|
||||
if (Args->CheckParm ("-fast")) flags |= DF_FAST_MONSTERS;
|
||||
|
||||
devparm = !!Args.CheckParm ("-devparm");
|
||||
devparm = !!Args->CheckParm ("-devparm");
|
||||
|
||||
if (Args.CheckParm ("-altdeath"))
|
||||
if (Args->CheckParm ("-altdeath"))
|
||||
{
|
||||
deathmatch = 1;
|
||||
flags |= DF_ITEMS_RESPAWN;
|
||||
}
|
||||
else if (Args.CheckParm ("-deathmatch"))
|
||||
else if (Args->CheckParm ("-deathmatch"))
|
||||
{
|
||||
deathmatch = 1;
|
||||
flags |= DF_WEAPONS_STAY | DF_ITEMS_RESPAWN;
|
||||
|
@ -2223,27 +2221,27 @@ void D_DoomMain (void)
|
|||
}
|
||||
autostart = false;
|
||||
|
||||
const char *val = Args.CheckValue ("-skill");
|
||||
const char *val = Args->CheckValue ("-skill");
|
||||
if (val)
|
||||
{
|
||||
gameskill = val[0] - '1';
|
||||
autostart = true;
|
||||
}
|
||||
|
||||
p = Args.CheckParm ("-warp");
|
||||
if (p && p < Args.NumArgs() - 1)
|
||||
p = Args->CheckParm ("-warp");
|
||||
if (p && p < Args->NumArgs() - 1)
|
||||
{
|
||||
int ep, map;
|
||||
|
||||
if (gameinfo.flags & GI_MAPxx)
|
||||
{
|
||||
ep = 1;
|
||||
map = atoi (Args.GetArg(p+1));
|
||||
map = atoi (Args->GetArg(p+1));
|
||||
}
|
||||
else
|
||||
{
|
||||
ep = atoi (Args.GetArg(p+1));
|
||||
map = p < Args.NumArgs() - 2 ? atoi (Args.GetArg(p+2)) : 10;
|
||||
ep = atoi (Args->GetArg(p+1));
|
||||
map = p < Args->NumArgs() - 2 ? atoi (Args->GetArg(p+2)) : 10;
|
||||
if (map < 1 || map > 9)
|
||||
{
|
||||
map = ep;
|
||||
|
@ -2256,19 +2254,19 @@ void D_DoomMain (void)
|
|||
}
|
||||
|
||||
// [RH] Hack to handle +map
|
||||
p = Args.CheckParm ("+map");
|
||||
if (p && p < Args.NumArgs()-1)
|
||||
p = Args->CheckParm ("+map");
|
||||
if (p && p < Args->NumArgs()-1)
|
||||
{
|
||||
MapData * map = P_OpenMapData(Args.GetArg (p+1));
|
||||
MapData * map = P_OpenMapData(Args->GetArg (p+1));
|
||||
if (map == NULL)
|
||||
{
|
||||
Printf ("Can't find map %s\n", Args.GetArg (p+1));
|
||||
Printf ("Can't find map %s\n", Args->GetArg (p+1));
|
||||
}
|
||||
else
|
||||
{
|
||||
delete map;
|
||||
strncpy (startmap, Args.GetArg (p+1), 8);
|
||||
Args.GetArg (p)[0] = '-';
|
||||
strncpy (startmap, Args->GetArg (p+1), 8);
|
||||
Args->GetArg (p)[0] = '-';
|
||||
autostart = true;
|
||||
}
|
||||
}
|
||||
|
@ -2281,7 +2279,7 @@ void D_DoomMain (void)
|
|||
// We do not need to support -cdrom under Unix, because all the files
|
||||
// that would go to c:\\zdoomdat are already stored in .zdoom inside
|
||||
// the user's home directory.
|
||||
if (Args.CheckParm("-cdrom"))
|
||||
if (Args->CheckParm("-cdrom"))
|
||||
{
|
||||
Printf (GStrings("D_CDROM"));
|
||||
mkdir (CDROM_DIR, 0);
|
||||
|
@ -2293,7 +2291,7 @@ void D_DoomMain (void)
|
|||
UCVarValue value;
|
||||
static char one_hundred[] = "100";
|
||||
|
||||
value.String = Args.CheckValue ("-turbo");
|
||||
value.String = Args->CheckValue ("-turbo");
|
||||
if (value.String == NULL)
|
||||
value.String = one_hundred;
|
||||
else
|
||||
|
@ -2302,7 +2300,7 @@ void D_DoomMain (void)
|
|||
turbo.SetGenericRepDefault (value, CVAR_String);
|
||||
}
|
||||
|
||||
v = Args.CheckValue ("-timer");
|
||||
v = Args->CheckValue ("-timer");
|
||||
if (v)
|
||||
{
|
||||
double time = strtod (v, NULL);
|
||||
|
@ -2310,7 +2308,7 @@ void D_DoomMain (void)
|
|||
timelimit = (float)time;
|
||||
}
|
||||
|
||||
v = Args.CheckValue ("-avg");
|
||||
v = Args->CheckValue ("-avg");
|
||||
if (v)
|
||||
{
|
||||
Printf ("Austin Virtual Gaming: Levels will end after 20 minutes\n");
|
||||
|
@ -2420,10 +2418,10 @@ void D_DoomMain (void)
|
|||
}
|
||||
|
||||
//Added by MC:
|
||||
bglobal.getspawned = Args.GatherFiles ("-bots", "", false);
|
||||
bglobal.getspawned = Args->GatherFiles ("-bots", "", false);
|
||||
if (bglobal.getspawned->NumArgs() == 0)
|
||||
{
|
||||
delete bglobal.getspawned;
|
||||
bglobal.getspawned->Destroy();
|
||||
bglobal.getspawned = NULL;
|
||||
}
|
||||
else
|
||||
|
@ -2459,13 +2457,11 @@ void D_DoomMain (void)
|
|||
// [RH] Run any saved commands from the command line or autoexec.cfg now.
|
||||
gamestate = GS_FULLCONSOLE;
|
||||
Net_NewMakeTic ();
|
||||
DObject::BeginFrame ();
|
||||
DThinker::RunThinkers ();
|
||||
DObject::EndFrame ();
|
||||
gamestate = GS_STARTUP;
|
||||
|
||||
// start the apropriate game based on parms
|
||||
v = Args.CheckValue ("-record");
|
||||
v = Args->CheckValue ("-record");
|
||||
|
||||
if (v)
|
||||
{
|
||||
|
@ -2477,24 +2473,23 @@ void D_DoomMain (void)
|
|||
StartScreen = NULL;
|
||||
V_Init2();
|
||||
|
||||
files = Args.GatherFiles ("-playdemo", ".lmp", false);
|
||||
files = Args->GatherFiles ("-playdemo", ".lmp", false);
|
||||
if (files->NumArgs() > 0)
|
||||
{
|
||||
singledemo = true; // quit after one demo
|
||||
G_DeferedPlayDemo (files->GetArg (0));
|
||||
delete files;
|
||||
D_DoomLoop (); // never returns
|
||||
}
|
||||
delete files;
|
||||
files->Destroy();
|
||||
|
||||
v = Args.CheckValue ("-timedemo");
|
||||
v = Args->CheckValue ("-timedemo");
|
||||
if (v)
|
||||
{
|
||||
G_TimeDemo (v);
|
||||
D_DoomLoop (); // never returns
|
||||
}
|
||||
|
||||
v = Args.CheckValue ("-loadgame");
|
||||
v = Args->CheckValue ("-loadgame");
|
||||
if (v)
|
||||
{
|
||||
file = v;
|
||||
|
|
|
@ -921,6 +921,8 @@ void NetUpdate (void)
|
|||
BYTE *cmddata;
|
||||
bool resendOnly;
|
||||
|
||||
GC::CheckGC();
|
||||
|
||||
if (ticdup == 0)
|
||||
{
|
||||
return;
|
||||
|
@ -1586,7 +1588,7 @@ void D_CheckNetGame (void)
|
|||
|
||||
consoleplayer = doomcom.consoleplayer;
|
||||
|
||||
v = Args.CheckValue ("-netmode");
|
||||
v = Args->CheckValue ("-netmode");
|
||||
if (v != NULL)
|
||||
{
|
||||
NetMode = atoi (v) != 0 ? NET_PacketServer : NET_PeerToPeer;
|
||||
|
@ -1595,7 +1597,7 @@ void D_CheckNetGame (void)
|
|||
// [RH] Setup user info
|
||||
D_SetupUserInfo ();
|
||||
|
||||
if (Args.CheckParm ("-debugfile"))
|
||||
if (Args->CheckParm ("-debugfile"))
|
||||
{
|
||||
char filename[20];
|
||||
sprintf (filename,"debug%i.txt",consoleplayer);
|
||||
|
@ -1834,12 +1836,11 @@ void TryRunTics (void)
|
|||
D_DoAdvanceDemo ();
|
||||
}
|
||||
if (debugfile) fprintf (debugfile, "run tic %d\n", gametic);
|
||||
DObject::BeginFrame ();
|
||||
C_Ticker ();
|
||||
M_Ticker ();
|
||||
I_GetTime (true);
|
||||
G_Ticker ();
|
||||
DObject::EndFrame ();
|
||||
GC::CheckGC ();
|
||||
gametic++;
|
||||
|
||||
NetUpdate (); // check for new console commands
|
||||
|
|
|
@ -105,8 +105,8 @@ public:
|
|||
int crouchsprite;
|
||||
int MaxHealth;
|
||||
int RunHealth;
|
||||
AInventory *InvFirst; // first inventory item displayed on inventory bar
|
||||
AInventory *InvSel; // selected inventory item
|
||||
TObjPtr<AInventory> InvFirst; // first inventory item displayed on inventory bar
|
||||
TObjPtr<AInventory> InvSel; // selected inventory item
|
||||
|
||||
// [GRB] Player class properties
|
||||
fixed_t JumpZ;
|
||||
|
@ -192,6 +192,7 @@ public:
|
|||
|
||||
void Serialize (FArchive &arc);
|
||||
void FixPointers (const DObject *obj, DObject *replacement);
|
||||
size_t PropagateMark();
|
||||
|
||||
void SetLogNumber (int num);
|
||||
void SetLogText (const char *text);
|
||||
|
|
|
@ -110,7 +110,7 @@ struct DDecalThinker : public DThinker
|
|||
public:
|
||||
DDecalThinker (DBaseDecal *decal) : DThinker (STAT_DECALTHINKER), TheDecal (decal) {}
|
||||
void Serialize (FArchive &arc);
|
||||
DBaseDecal *TheDecal;
|
||||
TObjPtr<DBaseDecal> TheDecal;
|
||||
protected:
|
||||
DDecalThinker () : DThinker (STAT_DECALTHINKER) {}
|
||||
};
|
||||
|
@ -1143,6 +1143,7 @@ void DDecalFader::Tick ()
|
|||
{
|
||||
TheDecal->Destroy (); // remove the decal
|
||||
Destroy (); // remove myself
|
||||
return;
|
||||
}
|
||||
if (StartTrans == -1)
|
||||
{
|
||||
|
|
282
src/dobject.cpp
282
src/dobject.cpp
|
@ -47,6 +47,7 @@
|
|||
#include "r_state.h"
|
||||
#include "stats.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "dsectoreffect.h"
|
||||
|
||||
#include "autosegs.h"
|
||||
|
||||
|
@ -343,148 +344,120 @@ CCMD (dumpclasses)
|
|||
Printf ("%d classes shown, %d omitted\n", shown, omitted);
|
||||
}
|
||||
|
||||
TArray<DObject *> DObject::Objects (TArray<DObject *>::NoInit);
|
||||
TArray<unsigned int> DObject::FreeIndices (TArray<unsigned int>::NoInit);
|
||||
TArray<DObject *> DObject::ToDestroy (TArray<DObject *>::NoInit);
|
||||
bool DObject::Inactive;
|
||||
|
||||
void DObject::InPlaceConstructor (void *mem)
|
||||
{
|
||||
new ((EInPlace *)mem) DObject;
|
||||
}
|
||||
|
||||
DObject::DObject ()
|
||||
: ObjectFlags(0), Class(0)
|
||||
: Class(0), ObjectFlags(0)
|
||||
{
|
||||
if (FreeIndices.Pop (Index))
|
||||
Objects[Index] = this;
|
||||
else
|
||||
Index = Objects.Push (this);
|
||||
ObjectFlags = GC::CurrentWhite & OF_WhiteBits;
|
||||
ObjNext = GC::Root;
|
||||
GC::Root = this;
|
||||
}
|
||||
|
||||
DObject::DObject (PClass *inClass)
|
||||
: ObjectFlags(0), Class(inClass)
|
||||
: Class(inClass), ObjectFlags(0)
|
||||
{
|
||||
if (FreeIndices.Pop (Index))
|
||||
Objects[Index] = this;
|
||||
else
|
||||
Index = Objects.Push (this);
|
||||
ObjectFlags = GC::CurrentWhite & OF_WhiteBits;
|
||||
ObjNext = GC::Root;
|
||||
GC::Root = this;
|
||||
}
|
||||
|
||||
DObject::~DObject ()
|
||||
{
|
||||
if (!Inactive)
|
||||
if (!(ObjectFlags & OF_Cleanup))
|
||||
{
|
||||
if (!(ObjectFlags & OF_MassDestruction))
|
||||
{
|
||||
RemoveFromArray ();
|
||||
DestroyScan (this);
|
||||
}
|
||||
else if (!(ObjectFlags & OF_Cleanup))
|
||||
{
|
||||
// object is queued for deletion, but is not being deleted
|
||||
// by the destruction process, so remove it from the
|
||||
// ToDestroy array and do other necessary stuff.
|
||||
unsigned int i;
|
||||
DObject **probe;
|
||||
PClass *type = GetClass();
|
||||
|
||||
for (i = ToDestroy.Size() - 1; i-- > 0; )
|
||||
if (!(ObjectFlags & OF_YesReallyDelete))
|
||||
{
|
||||
Printf ("Warning: '%s' is freed outside the GC process.\n",
|
||||
type != NULL ? type->TypeName.GetChars() : "==some object==");
|
||||
}
|
||||
|
||||
// Find all pointers that reference this object and NULL them.
|
||||
PointerSubstitution(this, NULL);
|
||||
|
||||
// Now unlink this object from the GC list.
|
||||
for (probe = &GC::Root; *probe != NULL; probe = &((*probe)->ObjNext))
|
||||
{
|
||||
if (*probe == this)
|
||||
{
|
||||
if (ToDestroy[i] == this)
|
||||
*probe = ObjNext;
|
||||
if (&ObjNext == GC::SweepPos)
|
||||
{
|
||||
ToDestroy[i] = NULL;
|
||||
GC::SweepPos = probe;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If it's gray, also unlink it from the gray list.
|
||||
if (this->IsGray())
|
||||
{
|
||||
for (probe = &GC::Gray; *probe != NULL; probe = &((*probe)->GCNext))
|
||||
{
|
||||
if (*probe == this)
|
||||
{
|
||||
*probe = GCNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
DestroyScan (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DObject::Destroy ()
|
||||
{
|
||||
if (!Inactive)
|
||||
{
|
||||
if (!(ObjectFlags & OF_MassDestruction))
|
||||
{
|
||||
RemoveFromArray ();
|
||||
ObjectFlags |= OF_MassDestruction;
|
||||
ToDestroy.Push (this);
|
||||
}
|
||||
}
|
||||
else
|
||||
delete this;
|
||||
ObjectFlags |= OF_EuthanizeMe;
|
||||
}
|
||||
|
||||
void DObject::BeginFrame ()
|
||||
size_t DObject::PropagateMark()
|
||||
{
|
||||
StaleCycles = 0;
|
||||
StaleCount = 0;
|
||||
}
|
||||
|
||||
void DObject::EndFrame ()
|
||||
{
|
||||
clock (StaleCycles);
|
||||
if (ToDestroy.Size ())
|
||||
const PClass *info = GetClass();
|
||||
const size_t *offsets = info->FlatPointers;
|
||||
if (offsets == NULL)
|
||||
{
|
||||
StaleCount += (int)ToDestroy.Size ();
|
||||
DestroyScan ();
|
||||
//Printf ("Destroyed %d objects\n", ToDestroy.Size());
|
||||
|
||||
DObject *obj;
|
||||
while (ToDestroy.Pop (obj))
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
obj->ObjectFlags |= OF_Cleanup;
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
const_cast<PClass *>(info)->BuildFlatPointers();
|
||||
offsets = info->FlatPointers;
|
||||
}
|
||||
unclock (StaleCycles);
|
||||
}
|
||||
|
||||
void DObject::RemoveFromArray ()
|
||||
{
|
||||
if (Objects.Size() == Index + 1)
|
||||
while (*offsets != ~(size_t)0)
|
||||
{
|
||||
DObject *dummy;
|
||||
Objects.Pop (dummy);
|
||||
}
|
||||
else if (Objects.Size() > Index)
|
||||
{
|
||||
Objects[Index] = NULL;
|
||||
FreeIndices.Push (Index);
|
||||
GC::Mark((DObject **)((BYTE *)this + *offsets));
|
||||
offsets++;
|
||||
}
|
||||
return info->Size;
|
||||
}
|
||||
|
||||
void DObject::PointerSubstitution (DObject *old, DObject *notOld)
|
||||
{
|
||||
unsigned int i, highest;
|
||||
highest = Objects.Size ();
|
||||
DObject *probe;
|
||||
int i;
|
||||
|
||||
for (i = 0; i <= highest; i++)
|
||||
// Go through all objects.
|
||||
for (probe = GC::Root; probe != NULL; probe = probe->ObjNext)
|
||||
{
|
||||
DObject *current = i < highest ? Objects[i] : &bglobal;
|
||||
if (current)
|
||||
const PClass *info = probe->GetClass();
|
||||
const size_t *offsets = info->FlatPointers;
|
||||
if (offsets == NULL)
|
||||
{
|
||||
const PClass *info = current->GetClass();
|
||||
const size_t *offsets = info->FlatPointers;
|
||||
if (offsets == NULL)
|
||||
const_cast<PClass *>(info)->BuildFlatPointers();
|
||||
offsets = info->FlatPointers;
|
||||
}
|
||||
while (*offsets != ~(size_t)0)
|
||||
{
|
||||
if (*(DObject **)((BYTE *)probe + *offsets) == old)
|
||||
{
|
||||
const_cast<PClass *>(info)->BuildFlatPointers();
|
||||
offsets = info->FlatPointers;
|
||||
}
|
||||
while (*offsets != ~(size_t)0)
|
||||
{
|
||||
if (*(DObject **)((BYTE *)current + *offsets) == old)
|
||||
{
|
||||
*(DObject **)((BYTE *)current + *offsets) = notOld;
|
||||
}
|
||||
offsets++;
|
||||
*(DObject **)((BYTE *)probe + *offsets) = notOld;
|
||||
}
|
||||
offsets++;
|
||||
}
|
||||
}
|
||||
|
||||
// Go through the bodyque.
|
||||
for (i = 0; i < BODYQUESIZE; ++i)
|
||||
{
|
||||
if (bodyque[i] == old)
|
||||
|
@ -493,125 +466,32 @@ void DObject::PointerSubstitution (DObject *old, DObject *notOld)
|
|||
}
|
||||
}
|
||||
|
||||
// This is an ugly hack, but it's the best I can do for now.
|
||||
// Go through players.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
players[i].FixPointers (old, notOld);
|
||||
}
|
||||
|
||||
// Go through sectors.
|
||||
if (sectors != NULL)
|
||||
{
|
||||
for (i = 0; i < (unsigned int)numsectors; ++i)
|
||||
for (i = 0; i < numsectors; ++i)
|
||||
{
|
||||
if (sectors[i].SoundTarget == old)
|
||||
{
|
||||
sectors[i].SoundTarget = static_cast<AActor *>(notOld);
|
||||
}
|
||||
if (sectors[i].CeilingSkyBox == old)
|
||||
{
|
||||
sectors[i].CeilingSkyBox = static_cast<ASkyViewpoint *>(notOld);
|
||||
}
|
||||
if (sectors[i].FloorSkyBox == old)
|
||||
{
|
||||
sectors[i].FloorSkyBox = static_cast<ASkyViewpoint *>(notOld);
|
||||
}
|
||||
#define SECTOR_CHECK(f,t) \
|
||||
if (sectors[i].f == static_cast<t *>(old)) { sectors[i].f = static_cast<t *>(notOld); }
|
||||
SECTOR_CHECK( SoundTarget, AActor );
|
||||
SECTOR_CHECK( CeilingSkyBox, ASkyViewpoint );
|
||||
SECTOR_CHECK( FloorSkyBox, ASkyViewpoint );
|
||||
SECTOR_CHECK( SecActTarget, ASectorAction );
|
||||
SECTOR_CHECK( floordata, DSectorEffect );
|
||||
SECTOR_CHECK( ceilingdata, DSectorEffect );
|
||||
SECTOR_CHECK( lightingdata, DSectorEffect );
|
||||
#undef SECTOR_CHECK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Search for references to a single object and NULL them.
|
||||
// It should not be listed in ToDestroy.
|
||||
void DObject::DestroyScan (DObject *obj)
|
||||
{
|
||||
PointerSubstitution (obj, NULL);
|
||||
}
|
||||
|
||||
// Search for references to all objects scheduled for
|
||||
// destruction and NULL them.
|
||||
void DObject::DestroyScan ()
|
||||
{
|
||||
unsigned int i, highest;
|
||||
int j, destroycount;
|
||||
DObject **destroybase;
|
||||
destroycount = (int)ToDestroy.Size ();
|
||||
if (destroycount == 0)
|
||||
return;
|
||||
destroybase = &ToDestroy[0] + destroycount;
|
||||
destroycount = -destroycount;
|
||||
highest = Objects.Size ();
|
||||
|
||||
for (i = 0; i <= highest; i++)
|
||||
{
|
||||
DObject *current = i < highest ? Objects[i] : &bglobal;
|
||||
if (current)
|
||||
{
|
||||
const PClass *info = current->GetClass();
|
||||
const size_t *offsets = info->FlatPointers;
|
||||
if (offsets == NULL)
|
||||
{
|
||||
const_cast<PClass *>(info)->BuildFlatPointers();
|
||||
offsets = info->FlatPointers;
|
||||
}
|
||||
while (*offsets != ~(size_t)0)
|
||||
{
|
||||
j = destroycount;
|
||||
do
|
||||
{
|
||||
if (*(DObject **)((BYTE *)current + *offsets) == *(destroybase + j))
|
||||
{
|
||||
*(DObject **)((BYTE *)current + *offsets) = NULL;
|
||||
}
|
||||
} while (++j);
|
||||
offsets++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
j = destroycount;
|
||||
do
|
||||
{
|
||||
for (i = 0; i < BODYQUESIZE; ++i)
|
||||
{
|
||||
if (bodyque[i] == *(destroybase + j))
|
||||
{
|
||||
bodyque[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
} while (++j);
|
||||
|
||||
// This is an ugly hack, but it's the best I can do for now.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
{
|
||||
j = destroycount;
|
||||
do
|
||||
{
|
||||
players[i].FixPointers (*(destroybase + j), NULL);
|
||||
} while (++j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (unsigned int)numsectors; ++i)
|
||||
{
|
||||
j = destroycount;
|
||||
do
|
||||
{
|
||||
if (sectors[i].SoundTarget == *(destroybase + j))
|
||||
{
|
||||
sectors[i].SoundTarget = NULL;
|
||||
}
|
||||
} while (++j);
|
||||
}
|
||||
}
|
||||
|
||||
void DObject::StaticShutdown ()
|
||||
{
|
||||
Inactive = true;
|
||||
}
|
||||
|
||||
void DObject::Serialize (FArchive &arc)
|
||||
{
|
||||
ObjectFlags |= OF_SerialSuccess;
|
||||
|
|
302
src/dobject.h
302
src/dobject.h
|
@ -2,7 +2,7 @@
|
|||
** dobject.h
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2006 Randy Heit
|
||||
** Copyright 1998-2008 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
@ -48,7 +48,6 @@ class FArchive;
|
|||
|
||||
class DObject;
|
||||
class DArgs;
|
||||
class DBoundingBox;
|
||||
class DCanvas;
|
||||
class DConsoleCommand;
|
||||
class DConsoleAlias;
|
||||
|
@ -211,12 +210,205 @@ private: \
|
|||
|
||||
enum EObjectFlags
|
||||
{
|
||||
OF_MassDestruction = 0x00000001, // Object is queued for deletion
|
||||
OF_Cleanup = 0x00000002, // Object is being deconstructed as a result of a queued deletion
|
||||
OF_JustSpawned = 0x00000004, // Thinker was spawned this tic
|
||||
OF_SerialSuccess = 0x10000000 // For debugging Serialize() calls
|
||||
// GC flags
|
||||
OF_White0 = 1 << 0, // Object is white (type 0)
|
||||
OF_White1 = 1 << 1, // Object is white (type 1)
|
||||
OF_Black = 1 << 2, // Object is black
|
||||
OF_Fixed = 1 << 3, // Object is fixed (should not be collected)
|
||||
OF_Rooted = 1 << 4, // Object is soft-rooted
|
||||
OF_EuthanizeMe = 1 << 5, // Object wants to die
|
||||
OF_Cleanup = 1 << 6, // Object is now being deleted by the collector
|
||||
OF_YesReallyDelete = 1 << 7, // Object is being deleted outside the collector, and this is okay, so don't print a warning
|
||||
|
||||
OF_WhiteBits = OF_White0 | OF_White1,
|
||||
OF_MarkBits = OF_WhiteBits | OF_Black,
|
||||
|
||||
// Other flags
|
||||
OF_JustSpawned = 1 << 8, // Thinker was spawned this tic
|
||||
OF_SerialSuccess = 1 << 9, // For debugging Serialize() calls
|
||||
};
|
||||
|
||||
template<class T> class TObjPtr;
|
||||
|
||||
namespace GC
|
||||
{
|
||||
enum EGCState
|
||||
{
|
||||
GCS_Pause,
|
||||
GCS_Propagate,
|
||||
GCS_Sweep,
|
||||
GCS_Finalize
|
||||
};
|
||||
|
||||
// Number of bytes currently allocated through M_Malloc/M_Realloc.
|
||||
extern size_t AllocBytes;
|
||||
|
||||
// Amount of memory to allocate before triggering a collection.
|
||||
extern size_t Threshold;
|
||||
|
||||
// List of gray objects.
|
||||
extern DObject *Gray;
|
||||
|
||||
// List of every object.
|
||||
extern DObject *Root;
|
||||
|
||||
// Current white value for potentially-live objects.
|
||||
extern DWORD CurrentWhite;
|
||||
|
||||
// Current collector state.
|
||||
extern EGCState State;
|
||||
|
||||
// Position of GC sweep in the list of objects.
|
||||
extern DObject **SweepPos;
|
||||
|
||||
// Size of GC pause.
|
||||
extern int Pause;
|
||||
|
||||
// Size of GC steps.
|
||||
extern int StepMul;
|
||||
|
||||
// Current white value for known-dead objects.
|
||||
static inline DWORD OtherWhite()
|
||||
{
|
||||
return CurrentWhite ^ OF_WhiteBits;
|
||||
}
|
||||
|
||||
// Frees all objects, whether they're dead or not.
|
||||
void FreeAll();
|
||||
|
||||
// Does one collection step.
|
||||
void Step();
|
||||
|
||||
// Does a complete collection.
|
||||
void FullGC();
|
||||
|
||||
// Handles the grunt work for a write barrier.
|
||||
void Barrier(DObject *pointing, DObject *pointed);
|
||||
|
||||
// Handles a write barrier.
|
||||
static inline void WriteBarrier(DObject *pointing, DObject *pointed);
|
||||
|
||||
// Handles a write barrier for a pointer that isn't inside an object.
|
||||
static inline void WriteBarrier(DObject *pointed);
|
||||
|
||||
// Handles a read barrier.
|
||||
template<class T> inline T *ReadBarrier(T *&obj)
|
||||
{
|
||||
if (obj == NULL || !(obj->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
return obj;
|
||||
}
|
||||
return obj = NULL;
|
||||
}
|
||||
|
||||
// Check if it's time to collect, and do a collection step if it is.
|
||||
static inline void CheckGC()
|
||||
{
|
||||
if (AllocBytes >= Threshold)
|
||||
Step();
|
||||
}
|
||||
|
||||
// Marks a white object gray. If the object wants to die, the pointer
|
||||
// is NULLed instead.
|
||||
void Mark(DObject **obj);
|
||||
|
||||
// Soft-roots an object.
|
||||
void AddSoftRoot(DObject *obj);
|
||||
|
||||
// Unroots an object.
|
||||
void DelSoftRoot(DObject *obj);
|
||||
|
||||
template<class T> void Mark(T *&obj) { Mark((DObject **)&obj); }
|
||||
template<class T> void Mark(TObjPtr<T> &obj);
|
||||
}
|
||||
|
||||
// A template class to help with handling read barriers. It does not
|
||||
// handle write barriers, because those can be handled more efficiently
|
||||
// with knowledge of the object that holds the pointer.
|
||||
template<class T>
|
||||
class TObjPtr
|
||||
{
|
||||
T *p;
|
||||
public:
|
||||
TObjPtr() throw()
|
||||
{
|
||||
}
|
||||
TObjPtr(T *q) throw()
|
||||
: p(q)
|
||||
{
|
||||
}
|
||||
TObjPtr(const TObjPtr<T> &q) throw()
|
||||
: p(q.p)
|
||||
{
|
||||
}
|
||||
T *operator=(T *q) throw()
|
||||
{
|
||||
return p = q;
|
||||
// The caller must now perform a write barrier.
|
||||
}
|
||||
operator T*() throw()
|
||||
{
|
||||
return GC::ReadBarrier(p);
|
||||
}
|
||||
T &operator*()
|
||||
{
|
||||
T *q = GC::ReadBarrier(p);
|
||||
assert(q != NULL);
|
||||
return *q;
|
||||
}
|
||||
T **operator&() throw()
|
||||
{
|
||||
// Does not perform a read barrier. The only real use for this is with
|
||||
// the DECLARE_POINTER macro, where a read barrier would be a very bad
|
||||
// thing.
|
||||
return &p;
|
||||
}
|
||||
T *operator->() throw()
|
||||
{
|
||||
return GC::ReadBarrier(p);
|
||||
}
|
||||
bool operator<(T *u) throw()
|
||||
{
|
||||
return GC::ReadBarrier(p) < u;
|
||||
}
|
||||
bool operator<=(T *u) throw()
|
||||
{
|
||||
return GC::ReadBarrier(p) <= u;
|
||||
}
|
||||
bool operator>(T *u) throw()
|
||||
{
|
||||
return GC::ReadBarrier(p) > u;
|
||||
}
|
||||
bool operator>=(T *u) throw()
|
||||
{
|
||||
return GC::ReadBarrier(p) >= u;
|
||||
}
|
||||
bool operator!=(T *u) throw()
|
||||
{
|
||||
return GC::ReadBarrier(p) != u;
|
||||
}
|
||||
bool operator==(T *u) throw()
|
||||
{
|
||||
return GC::ReadBarrier(p) == u;
|
||||
}
|
||||
|
||||
template<class U> friend inline FArchive &operator<<(FArchive &arc, TObjPtr<U> &o);
|
||||
};
|
||||
|
||||
template<class T> inline FArchive &operator<<(FArchive &arc, TObjPtr<T> &o)
|
||||
{
|
||||
return arc << o.p;
|
||||
}
|
||||
|
||||
// Use barrier_cast instead of static_cast when you need to cast
|
||||
// the contents of a TObjPtr to a related type.
|
||||
template<class T,class U> inline T barrier_cast(TObjPtr<U> &o)
|
||||
{
|
||||
return static_cast<T>(static_cast<U *>(o));
|
||||
}
|
||||
|
||||
template<class T> void GC::Mark(TObjPtr<T> &obj) { GC::Mark((DObject **)&obj); }
|
||||
|
||||
class DObject
|
||||
{
|
||||
public:
|
||||
|
@ -227,12 +419,13 @@ public:
|
|||
private:
|
||||
typedef DObject ThisClass;
|
||||
|
||||
// Per-instance variables. There are three.
|
||||
public:
|
||||
DWORD ObjectFlags; // Flags for this object
|
||||
// Per-instance variables. There are four.
|
||||
private:
|
||||
PClass *Class; // This object's type
|
||||
unsigned int Index; // This object's index in the global object table
|
||||
public:
|
||||
DObject *ObjNext; // Keep track of all allocated objects
|
||||
DObject *GCNext; // Next object in this collection list
|
||||
DWORD ObjectFlags; // Flags for this object
|
||||
|
||||
public:
|
||||
DObject ();
|
||||
|
@ -250,16 +443,11 @@ public:
|
|||
|
||||
virtual void Destroy ();
|
||||
|
||||
static void BeginFrame ();
|
||||
static void EndFrame ();
|
||||
|
||||
// If you need to replace one object with another and want to
|
||||
// change any pointers from the old object to the new object,
|
||||
// use this method.
|
||||
static void PointerSubstitution (DObject *old, DObject *notOld);
|
||||
|
||||
static void StaticShutdown ();
|
||||
|
||||
PClass *GetClass() const
|
||||
{
|
||||
if (Class == NULL)
|
||||
|
@ -286,6 +474,60 @@ public:
|
|||
M_Free(mem);
|
||||
}
|
||||
|
||||
// GC fiddling
|
||||
|
||||
// An object is white if either white bit is set.
|
||||
bool IsWhite() const
|
||||
{
|
||||
return !!(ObjectFlags & OF_WhiteBits);
|
||||
}
|
||||
|
||||
bool IsBlack() const
|
||||
{
|
||||
return !!(ObjectFlags & OF_Black);
|
||||
}
|
||||
|
||||
// An object is gray if it isn't white or black.
|
||||
bool IsGray() const
|
||||
{
|
||||
return !(ObjectFlags & OF_MarkBits);
|
||||
}
|
||||
|
||||
// An object is dead if it's the other white.
|
||||
bool IsDead() const
|
||||
{
|
||||
return !!(ObjectFlags & GC::OtherWhite() & OF_WhiteBits);
|
||||
}
|
||||
|
||||
void ChangeWhite()
|
||||
{
|
||||
ObjectFlags ^= OF_WhiteBits;
|
||||
}
|
||||
|
||||
void MakeWhite()
|
||||
{
|
||||
ObjectFlags = (ObjectFlags & ~OF_MarkBits) | (GC::CurrentWhite & OF_WhiteBits);
|
||||
}
|
||||
|
||||
void White2Gray()
|
||||
{
|
||||
ObjectFlags &= ~OF_WhiteBits;
|
||||
}
|
||||
|
||||
void Black2Gray()
|
||||
{
|
||||
ObjectFlags &= ~OF_Black;
|
||||
}
|
||||
|
||||
void Gray2Black()
|
||||
{
|
||||
ObjectFlags |= OF_Black;
|
||||
}
|
||||
|
||||
// Marks all objects pointed to by this one. Returns the (approximate)
|
||||
// amount of memory used by this object.
|
||||
virtual size_t PropagateMark();
|
||||
|
||||
protected:
|
||||
// This form of placement new and delete is for use *only* by PClass's
|
||||
// CreateNew() method. Do not use them for some other purpose.
|
||||
|
@ -296,22 +538,26 @@ protected:
|
|||
|
||||
void operator delete (void *mem, EInPlace *)
|
||||
{
|
||||
free (mem);
|
||||
M_Free (mem);
|
||||
}
|
||||
|
||||
private:
|
||||
static TArray<DObject *> Objects;
|
||||
static TArray<unsigned int> FreeIndices;
|
||||
static TArray<DObject *> ToDestroy;
|
||||
|
||||
static void DestroyScan (DObject *obj);
|
||||
static void DestroyScan ();
|
||||
|
||||
void RemoveFromArray ();
|
||||
|
||||
static bool Inactive;
|
||||
};
|
||||
|
||||
static inline void GC::WriteBarrier(DObject *pointing, DObject *pointed)
|
||||
{
|
||||
if (pointed != NULL && pointed->IsWhite() && pointing->IsBlack())
|
||||
{
|
||||
Barrier(pointing, pointed);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void GC::WriteBarrier(DObject *pointed)
|
||||
{
|
||||
if (pointed != NULL && State == GCS_Propagate && pointed->IsWhite())
|
||||
{
|
||||
Barrier(NULL, pointed);
|
||||
}
|
||||
}
|
||||
|
||||
#include "dobjtype.h"
|
||||
|
||||
inline bool DObject::IsKindOf (const PClass *base) const
|
||||
|
|
623
src/dobjgc.cpp
Normal file
623
src/dobjgc.cpp
Normal file
|
@ -0,0 +1,623 @@
|
|||
/*
|
||||
** dobjgc.cpp
|
||||
** The garbage collector. Based largely on Lua's.
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 2008 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
** are met:
|
||||
**
|
||||
** 1. Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** 2. Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in the
|
||||
** documentation and/or other materials provided with the distribution.
|
||||
** 3. The name of the author may not be used to endorse or promote products
|
||||
** derived from this software without specific prior written permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
**---------------------------------------------------------------------------
|
||||
**
|
||||
*/
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "dobject.h"
|
||||
#include "templates.h"
|
||||
#include "b_bot.h"
|
||||
#include "p_local.h"
|
||||
#include "g_game.h"
|
||||
#include "r_data.h"
|
||||
#include "a_sharedglobal.h"
|
||||
#include "sbar.h"
|
||||
#include "stats.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "p_acs.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
@@ DEFAULT_GCPAUSE defines the default pause between garbage-collector cycles
|
||||
@* as a percentage.
|
||||
** CHANGE it if you want the GC to run faster or slower (higher values
|
||||
** mean larger pauses which mean slower collection.) You can also change
|
||||
** this value dynamically.
|
||||
*/
|
||||
#define DEFAULT_GCPAUSE 150 // 150% (wait for memory to increase by half before next GC)
|
||||
|
||||
/*
|
||||
@@ DEFAULT_GCMUL defines the default speed of garbage collection relative to
|
||||
@* memory allocation as a percentage.
|
||||
** CHANGE it if you want to change the granularity of the garbage
|
||||
** collection. (Higher values mean coarser collections. 0 represents
|
||||
** infinity, where each step performs a full collection.) You can also
|
||||
** change this value dynamically.
|
||||
*/
|
||||
#define DEFAULT_GCMUL 400 // GC runs 'quadruple the speed' of memory allocation
|
||||
|
||||
|
||||
#define GCSTEPSIZE 1024u
|
||||
#define GCSWEEPMAX 40
|
||||
#define GCSWEEPCOST 10
|
||||
#define GCFINALIZECOST 100
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
namespace GC
|
||||
{
|
||||
size_t AllocBytes;
|
||||
size_t Threshold;
|
||||
size_t Estimate;
|
||||
DObject *Gray;
|
||||
DObject *Root;
|
||||
DObject *SoftRoots;
|
||||
DObject **SweepPos;
|
||||
DWORD CurrentWhite = OF_White0 | OF_Fixed;
|
||||
EGCState State = GCS_Pause;
|
||||
int Pause = DEFAULT_GCPAUSE;
|
||||
int StepMul = DEFAULT_GCMUL;
|
||||
int StepCount;
|
||||
size_t Dept;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SetThreshold
|
||||
//
|
||||
// Sets the new threshold after a collection is finished.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void SetThreshold()
|
||||
{
|
||||
Threshold = (Estimate / 100) * Pause;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PropagateMark
|
||||
//
|
||||
// Marks the top-most gray object black and marks all objects it points to
|
||||
// gray.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
size_t PropagateMark()
|
||||
{
|
||||
DObject *obj = Gray;
|
||||
assert(obj->IsGray());
|
||||
obj->Gray2Black();
|
||||
Gray = obj->GCNext;
|
||||
return obj->PropagateMark();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// PropagateAll
|
||||
//
|
||||
// Empties the gray list by propagating every single object in it.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static size_t PropagateAll()
|
||||
{
|
||||
size_t m = 0;
|
||||
while (Gray != NULL)
|
||||
{
|
||||
m += PropagateMark();
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SweepList
|
||||
//
|
||||
// Runs a limited sweep on a list, returning the location where to resume
|
||||
// the sweep at next time.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static DObject **SweepList(DObject **p, size_t count)
|
||||
{
|
||||
static int scount;
|
||||
DObject *curr;
|
||||
int deadmask = OtherWhite();
|
||||
|
||||
while ((curr = *p) != NULL && count-- > 0)
|
||||
{
|
||||
if ((curr->ObjectFlags ^ OF_WhiteBits) & deadmask) // not dead?
|
||||
{
|
||||
assert(!curr->IsDead() || (curr->ObjectFlags & OF_Fixed));
|
||||
curr->MakeWhite(); // make it white (for next cycle)
|
||||
p = &curr->ObjNext;
|
||||
}
|
||||
else // must erase 'curr'
|
||||
{
|
||||
assert(curr->IsDead());
|
||||
*p = curr->ObjNext;
|
||||
if (!(curr->ObjectFlags & OF_EuthanizeMe))
|
||||
{ // The object must be destroyed before it can be finalized.
|
||||
assert(!curr->IsKindOf(RUNTIME_CLASS(DThinker)));
|
||||
curr->Destroy();
|
||||
}
|
||||
curr->ObjectFlags |= OF_Cleanup;
|
||||
delete curr;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Mark
|
||||
//
|
||||
// Mark a single object gray.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Mark(DObject **obj)
|
||||
{
|
||||
DObject *lobj = *obj;
|
||||
if (lobj != NULL)
|
||||
{
|
||||
if (lobj->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
*obj = NULL;
|
||||
}
|
||||
else if (lobj->IsWhite())
|
||||
{
|
||||
lobj->White2Gray();
|
||||
lobj->GCNext = Gray;
|
||||
Gray = lobj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// MarkRoot
|
||||
//
|
||||
// Mark the root set of objects.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void MarkRoot()
|
||||
{
|
||||
int i;
|
||||
|
||||
Gray = NULL;
|
||||
Mark(Args);
|
||||
Mark(screen);
|
||||
Mark(StatusBar);
|
||||
DThinker::MarkRoots();
|
||||
Mark(DACSThinker::ActiveThinker);
|
||||
for (i = 0; i < BODYQUESIZE; ++i)
|
||||
{
|
||||
Mark(bodyque[i]);
|
||||
}
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (playeringame[i])
|
||||
players[i].PropagateMark();
|
||||
}
|
||||
if (sectors != NULL)
|
||||
{
|
||||
for (i = 0; i < numsectors; ++i)
|
||||
{
|
||||
Mark(sectors[i].SoundTarget);
|
||||
Mark(sectors[i].CeilingSkyBox);
|
||||
Mark(sectors[i].FloorSkyBox);
|
||||
Mark(sectors[i].SecActTarget);
|
||||
Mark(sectors[i].floordata);
|
||||
Mark(sectors[i].ceilingdata);
|
||||
Mark(sectors[i].lightingdata);
|
||||
}
|
||||
}
|
||||
{ // Silly bots
|
||||
DObject *foo = &bglobal;
|
||||
Mark(foo);
|
||||
}
|
||||
// Add soft roots
|
||||
if (SoftRoots != NULL)
|
||||
{
|
||||
DObject **probe = &SoftRoots->ObjNext;
|
||||
while (*probe != NULL)
|
||||
{
|
||||
DObject *soft = *probe;
|
||||
probe = &soft->ObjNext;
|
||||
if ((soft->ObjectFlags & (OF_Rooted | OF_EuthanizeMe)) == OF_Rooted)
|
||||
{
|
||||
Mark(soft);
|
||||
}
|
||||
}
|
||||
}
|
||||
State = GCS_Propagate;
|
||||
StepCount = 0;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Atomic
|
||||
//
|
||||
// If their were any propagations that needed to be done atomicly, they
|
||||
// would go here. It also sets things up for the sweep state.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void Atomic()
|
||||
{
|
||||
// Flip current white
|
||||
CurrentWhite = OtherWhite();
|
||||
SweepPos = &Root;
|
||||
State = GCS_Sweep;
|
||||
Estimate = AllocBytes;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// SingleStep
|
||||
//
|
||||
// Performs one step of the collector.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static size_t SingleStep()
|
||||
{
|
||||
switch (State)
|
||||
{
|
||||
case GCS_Pause:
|
||||
MarkRoot(); // Start a new collection
|
||||
return 0;
|
||||
|
||||
case GCS_Propagate:
|
||||
if (Gray != NULL)
|
||||
{
|
||||
return PropagateMark();
|
||||
}
|
||||
else
|
||||
{ // no more gray objects
|
||||
Atomic(); // finish mark phase
|
||||
return 0;
|
||||
}
|
||||
|
||||
case GCS_Sweep: {
|
||||
size_t old = AllocBytes;
|
||||
SweepPos = SweepList(SweepPos, GCSWEEPMAX);
|
||||
if (*SweepPos == NULL)
|
||||
{ // Nothing more to sweep?
|
||||
State = GCS_Finalize;
|
||||
}
|
||||
assert(old >= AllocBytes);
|
||||
Estimate -= old - AllocBytes;
|
||||
return GCSWEEPMAX * GCSWEEPCOST;
|
||||
}
|
||||
|
||||
case GCS_Finalize:
|
||||
State = GCS_Pause; // end collection
|
||||
Dept = 0;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Step
|
||||
//
|
||||
// Performs enough single steps to cover GCSTEPSIZE * StepMul% bytes of
|
||||
// memory.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Step()
|
||||
{
|
||||
size_t lim = (GCSTEPSIZE/100) * StepMul;
|
||||
size_t olim;
|
||||
if (lim == 0)
|
||||
{
|
||||
lim = (~(size_t)0) / 2; // no limit
|
||||
}
|
||||
Dept += AllocBytes - Threshold;
|
||||
do
|
||||
{
|
||||
olim = lim;
|
||||
lim -= SingleStep();
|
||||
} while (olim > lim && State != GCS_Pause);
|
||||
if (State != GCS_Pause)
|
||||
{
|
||||
if (Dept < GCSTEPSIZE)
|
||||
{
|
||||
Threshold = AllocBytes + GCSTEPSIZE; // - lim/StepMul
|
||||
}
|
||||
else
|
||||
{
|
||||
Dept -= GCSTEPSIZE;
|
||||
Threshold = AllocBytes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(AllocBytes >= Estimate);
|
||||
SetThreshold();
|
||||
}
|
||||
StepCount++;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// FullGC
|
||||
//
|
||||
// Collects everything in one fell swoop.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void FullGC()
|
||||
{
|
||||
if (State <= GCS_Propagate)
|
||||
{
|
||||
// Reset sweep mark to sweep all elements (returning them to white)
|
||||
SweepPos = &Root;
|
||||
// Reset other collector lists
|
||||
Gray = NULL;
|
||||
State = GCS_Sweep;
|
||||
}
|
||||
// Finish any pending sweep phase
|
||||
while (State != GCS_Finalize)
|
||||
{
|
||||
SingleStep();
|
||||
}
|
||||
MarkRoot();
|
||||
while (State != GCS_Pause)
|
||||
{
|
||||
SingleStep();
|
||||
}
|
||||
SetThreshold();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// Barrier
|
||||
//
|
||||
// Implements a write barrier to maintain the invariant that a black node
|
||||
// never points to a white node by making the node pointed at gray.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void Barrier(DObject *pointing, DObject *pointed)
|
||||
{
|
||||
assert(pointing == NULL || (pointing->IsBlack() && !pointing->IsDead()));
|
||||
assert(pointed->IsWhite() && !pointed->IsDead());
|
||||
assert(State != GCS_Finalize && State != GCS_Pause);
|
||||
// The invariant only needs to be maintained in the propagate state.
|
||||
if (State == GCS_Propagate)
|
||||
{
|
||||
pointed->White2Gray();
|
||||
pointed->GCNext = Gray;
|
||||
Gray = pointed;
|
||||
}
|
||||
// In other states, we can mark the pointing object white so this
|
||||
// barrier won't be triggered again, saving a few cycles in the future.
|
||||
else if (pointing != NULL)
|
||||
{
|
||||
pointing->MakeWhite();
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// AddSoftRoot
|
||||
//
|
||||
// Marks an object as a soft root. A soft root behaves exactly like a root
|
||||
// in MarkRoot, except it can be added at run-time.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void AddSoftRoot(DObject *obj)
|
||||
{
|
||||
DObject **probe;
|
||||
|
||||
// Are there any soft roots yet?
|
||||
if (SoftRoots == NULL)
|
||||
{
|
||||
// Create a new object to root the soft roots off of, and stick
|
||||
// it at the end of the object list, so we know that anything
|
||||
// before it is not a soft root.
|
||||
SoftRoots = new DObject;
|
||||
SoftRoots->ObjectFlags |= OF_Fixed;
|
||||
probe = &Root;
|
||||
while (*probe != NULL)
|
||||
{
|
||||
probe = &(*probe)->ObjNext;
|
||||
}
|
||||
Root = SoftRoots->ObjNext;
|
||||
SoftRoots->ObjNext = NULL;
|
||||
*probe = SoftRoots;
|
||||
}
|
||||
// Mark this object as rooted and move it after the SoftRoots marker.
|
||||
probe = &Root;
|
||||
while (*probe != NULL && *probe != obj)
|
||||
{
|
||||
probe = &(*probe)->ObjNext;
|
||||
}
|
||||
*probe = (*probe)->ObjNext;
|
||||
obj->ObjNext = SoftRoots->ObjNext;
|
||||
SoftRoots->ObjNext = obj;
|
||||
obj->ObjectFlags |= OF_Rooted;
|
||||
WriteBarrier(obj);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// DelSoftRoot
|
||||
//
|
||||
// Unroots an object so that it must be reachable or it will get collected.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void DelSoftRoot(DObject *obj)
|
||||
{
|
||||
DObject **probe;
|
||||
|
||||
if (!(obj->ObjectFlags & OF_Rooted))
|
||||
{ // Not rooted, so nothing to do.
|
||||
return;
|
||||
}
|
||||
obj->ObjectFlags &= ~OF_Rooted;
|
||||
// Move object out of the soft roots part of the list.
|
||||
probe = &SoftRoots;
|
||||
while (*probe != NULL && *probe != obj)
|
||||
{
|
||||
probe = &(*probe)->ObjNext;
|
||||
}
|
||||
if (*probe == obj)
|
||||
{
|
||||
*probe = obj->ObjNext;
|
||||
obj->ObjNext = Root;
|
||||
Root = obj;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ADD_STAT(gc)
|
||||
{
|
||||
static const char *StateStrings[] = {
|
||||
" Pause ",
|
||||
"Propagate",
|
||||
" Sweep ",
|
||||
"Finalize " };
|
||||
FString out;
|
||||
out.Format("[%s] Alloc:%6uK Thresh:%6uK Est:%6uK Steps: %d",
|
||||
StateStrings[GC::State],
|
||||
(GC::AllocBytes + 1023) >> 10,
|
||||
(GC::Threshold + 1023) >> 10,
|
||||
(GC::Estimate + 1023) >> 10,
|
||||
GC::StepCount);
|
||||
if (GC::State != GC::GCS_Pause)
|
||||
{
|
||||
out.AppendFormat(" %uK", (GC::Dept + 1023) >> 10);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CCMD gc
|
||||
//
|
||||
// Controls various aspects of the collector.
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
CCMD(gc)
|
||||
{
|
||||
if (argv.argc() == 1)
|
||||
{
|
||||
Printf ("Usage: gc stop|now|full|pause [size]|stepmul [size]\n");
|
||||
return;
|
||||
}
|
||||
if (stricmp(argv[1], "stop") == 0)
|
||||
{
|
||||
GC::Threshold = ~(size_t)0 - 2;
|
||||
}
|
||||
else if (stricmp(argv[1], "now") == 0)
|
||||
{
|
||||
GC::Threshold = GC::AllocBytes;
|
||||
}
|
||||
else if (stricmp(argv[1], "full") == 0)
|
||||
{
|
||||
GC::FullGC();
|
||||
}
|
||||
else if (stricmp(argv[1], "pause") == 0)
|
||||
{
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("Current GC pause is %d\n", GC::Pause);
|
||||
}
|
||||
else
|
||||
{
|
||||
GC::Pause = MAX(1,atoi(argv[2]));
|
||||
}
|
||||
}
|
||||
else if (stricmp(argv[1], "stepmul") == 0)
|
||||
{
|
||||
if (argv.argc() == 2)
|
||||
{
|
||||
Printf ("Current GC stepmul is %d\n", GC::StepMul);
|
||||
}
|
||||
else
|
||||
{
|
||||
GC::StepMul = MAX(100, atoi(argv[2]));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -33,7 +33,7 @@ DSectorEffect::DSectorEffect ()
|
|||
m_Sector = NULL;
|
||||
}
|
||||
|
||||
DSectorEffect::~DSectorEffect ()
|
||||
void DSectorEffect::Destroy()
|
||||
{
|
||||
if (m_Sector)
|
||||
{
|
||||
|
@ -52,6 +52,7 @@ DSectorEffect::~DSectorEffect ()
|
|||
m_Sector->lightingdata = NULL;
|
||||
}
|
||||
}
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
DSectorEffect::DSectorEffect (sector_t *sector)
|
||||
|
|
|
@ -10,9 +10,9 @@ class DSectorEffect : public DThinker
|
|||
DECLARE_CLASS (DSectorEffect, DThinker)
|
||||
public:
|
||||
DSectorEffect (sector_t *sector);
|
||||
~DSectorEffect ();
|
||||
|
||||
void Serialize (FArchive &arc);
|
||||
void Destroy();
|
||||
|
||||
sector_t *GetSector() const { return m_Sector; }
|
||||
|
||||
|
|
|
@ -155,6 +155,14 @@ DThinker::DThinker (int statnum) throw()
|
|||
{
|
||||
statnum = MAX_STATNUM;
|
||||
}
|
||||
if (FreshThinkers[statnum].TailPred->Pred != NULL)
|
||||
{
|
||||
GC::WriteBarrier(static_cast<DThinker*>(FreshThinkers[statnum].Tail, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
GC::WriteBarrier(this);
|
||||
}
|
||||
FreshThinkers[statnum].AddTail (this);
|
||||
}
|
||||
|
||||
|
@ -179,6 +187,16 @@ void DThinker::Destroy ()
|
|||
Super::Destroy ();
|
||||
}
|
||||
|
||||
void DThinker::Remove()
|
||||
{
|
||||
if (Pred->Pred != NULL && Succ->Succ != NULL)
|
||||
{
|
||||
GC::WriteBarrier(static_cast<DThinker *>(Pred), static_cast<DThinker *>(Succ));
|
||||
GC::WriteBarrier(static_cast<DThinker *>(Succ), static_cast<DThinker *>(Pred));
|
||||
}
|
||||
Node::Remove();
|
||||
}
|
||||
|
||||
void DThinker::PostBeginPlay ()
|
||||
{
|
||||
}
|
||||
|
@ -205,6 +223,8 @@ DThinker *DThinker::FirstThinker (int statnum)
|
|||
|
||||
void DThinker::ChangeStatNum (int statnum)
|
||||
{
|
||||
List *list;
|
||||
|
||||
if ((unsigned)statnum > MAX_STATNUM)
|
||||
{
|
||||
statnum = MAX_STATNUM;
|
||||
|
@ -212,12 +232,44 @@ void DThinker::ChangeStatNum (int statnum)
|
|||
Remove ();
|
||||
if ((ObjectFlags & OF_JustSpawned) && statnum >= STAT_FIRST_THINKING)
|
||||
{
|
||||
FreshThinkers[statnum].AddTail (this);
|
||||
list = &FreshThinkers[statnum];
|
||||
}
|
||||
else
|
||||
{
|
||||
Thinkers[statnum].AddTail (this);
|
||||
list = &Thinkers[statnum];
|
||||
}
|
||||
if (list->TailPred->Pred != NULL)
|
||||
{
|
||||
GC::WriteBarrier(static_cast<DThinker*>(list->Tail, this));
|
||||
}
|
||||
else
|
||||
{
|
||||
GC::WriteBarrier(this);
|
||||
}
|
||||
list->AddTail(this);
|
||||
}
|
||||
|
||||
// Mark the first thinker of each list
|
||||
void DThinker::MarkRoots()
|
||||
{
|
||||
for (int i = 0; i <= MAX_STATNUM; ++i)
|
||||
{
|
||||
DThinker *t = static_cast<DThinker *>(Thinkers[i].Head);
|
||||
GC::Mark(t);
|
||||
t = static_cast<DThinker *>(FreshThinkers[i].Head);
|
||||
GC::Mark(t);
|
||||
}
|
||||
}
|
||||
|
||||
size_t DThinker::PropagateMark()
|
||||
{
|
||||
// Mark the next thinker in my list
|
||||
if (Succ != NULL && Succ->Succ != NULL)
|
||||
{
|
||||
DThinker *t = static_cast<DThinker *>(Succ);
|
||||
GC::Mark(t);
|
||||
}
|
||||
return Super::PropagateMark();
|
||||
}
|
||||
|
||||
// Destroy every thinker
|
||||
|
@ -225,7 +277,6 @@ void DThinker::DestroyAllThinkers ()
|
|||
{
|
||||
int i;
|
||||
|
||||
DObject::BeginFrame ();
|
||||
for (i = 0; i <= MAX_STATNUM; i++)
|
||||
{
|
||||
if (i != STAT_TRAVELLING)
|
||||
|
@ -234,7 +285,7 @@ void DThinker::DestroyAllThinkers ()
|
|||
DestroyThinkersInList (FreshThinkers[i].Head);
|
||||
}
|
||||
}
|
||||
DObject::EndFrame ();
|
||||
GC::FullGC ();
|
||||
}
|
||||
|
||||
// Destroy all thinkers except for player-controlled actors
|
||||
|
@ -244,7 +295,6 @@ void DThinker::DestroyMostThinkers ()
|
|||
{
|
||||
int i;
|
||||
|
||||
DObject::BeginFrame ();
|
||||
for (i = 0; i <= MAX_STATNUM; i++)
|
||||
{
|
||||
if (i != STAT_TRAVELLING)
|
||||
|
@ -253,7 +303,7 @@ void DThinker::DestroyMostThinkers ()
|
|||
DestroyMostThinkersInList (FreshThinkers[i], i);
|
||||
}
|
||||
}
|
||||
DObject::EndFrame ();
|
||||
GC::FullGC ();
|
||||
}
|
||||
|
||||
void DThinker::DestroyThinkersInList (Node *node)
|
||||
|
@ -327,6 +377,14 @@ int DThinker::TickThinkers (List *list, List *dest)
|
|||
if (dest != NULL)
|
||||
{ // Move thinker from this list to the destination list
|
||||
node->Remove ();
|
||||
if (dest->TailPred->Pred != NULL)
|
||||
{
|
||||
GC::WriteBarrier(static_cast<DThinker*>(dest->Tail, thinker));
|
||||
}
|
||||
else
|
||||
{
|
||||
GC::WriteBarrier(thinker);
|
||||
}
|
||||
dest->AddTail (node);
|
||||
}
|
||||
thinker->PostBeginPlay ();
|
||||
|
@ -336,7 +394,7 @@ int DThinker::TickThinkers (List *list, List *dest)
|
|||
I_Error ("There is a thinker in the fresh list that has already ticked.\n");
|
||||
}
|
||||
|
||||
if (!(thinker->ObjectFlags & OF_MassDestruction))
|
||||
if (!(thinker->ObjectFlags & OF_EuthanizeMe))
|
||||
{ // Only tick thinkers not scheduled for destruction
|
||||
thinker->Tick ();
|
||||
}
|
||||
|
|
|
@ -49,13 +49,14 @@ class FThinkerIterator;
|
|||
enum { MAX_STATNUM = 127 };
|
||||
|
||||
// Doubly linked list of thinkers
|
||||
class DThinker : public DObject, public Node
|
||||
class DThinker : public DObject, private Node
|
||||
{
|
||||
DECLARE_CLASS (DThinker, DObject)
|
||||
|
||||
public:
|
||||
DThinker (int statnum = MAX_STATNUM) throw();
|
||||
void Destroy ();
|
||||
size_t PropagateMark();
|
||||
virtual ~DThinker ();
|
||||
virtual void Tick ();
|
||||
virtual void PostBeginPlay (); // Called just before the first tick
|
||||
|
@ -67,6 +68,7 @@ public:
|
|||
static void DestroyAllThinkers ();
|
||||
static void DestroyMostThinkers ();
|
||||
static void SerializeAll (FArchive &arc, bool keepPlayers);
|
||||
static void MarkRoots();
|
||||
|
||||
static DThinker *FirstThinker (int statnum);
|
||||
|
||||
|
@ -75,6 +77,7 @@ private:
|
|||
static void DestroyMostThinkersInList (List &list, int stat);
|
||||
static int TickThinkers (List *list, List *dest); // Returns: # of thinkers ticked
|
||||
static void SaveList(FArchive &arc, Node *node);
|
||||
void Remove();
|
||||
|
||||
static List Thinkers[MAX_STATNUM+1]; // Current thinkers
|
||||
static List FreshThinkers[MAX_STATNUM+1]; // Newly created thinkers
|
||||
|
|
|
@ -1004,9 +1004,17 @@ FArchive &FArchive::SerializePointer (void *ptrbase, BYTE **ptr, DWORD elemSize)
|
|||
FArchive &FArchive::SerializeObject (DObject *&object, PClass *type)
|
||||
{
|
||||
if (IsStoring ())
|
||||
{
|
||||
if (object != (DObject*)~0)
|
||||
{
|
||||
GC::ReadBarrier(object);
|
||||
}
|
||||
return WriteObject (object);
|
||||
}
|
||||
else
|
||||
{
|
||||
return ReadObject (object, type);
|
||||
}
|
||||
}
|
||||
|
||||
FArchive &FArchive::WriteObject (DObject *obj)
|
||||
|
|
|
@ -315,7 +315,7 @@ void A_SpawnFly (AActor *self)
|
|||
if (newmobj->SeeState != NULL && P_LookForPlayers (newmobj, true))
|
||||
newmobj->SetState (newmobj->SeeState);
|
||||
|
||||
if (!(newmobj->ObjectFlags & OF_MassDestruction))
|
||||
if (!(newmobj->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
// telefrag anything in this spot
|
||||
P_TeleportMove (newmobj, newmobj->x, newmobj->y, newmobj->z, true);
|
||||
|
|
|
@ -27,10 +27,11 @@
|
|||
EXTERN_CVAR (Bool, vid_fps)
|
||||
|
||||
|
||||
class FDoomStatusBar : public FBaseStatusBar
|
||||
class DDoomStatusBar : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DDoomStatusBar, DBaseStatusBar)
|
||||
public:
|
||||
FDoomStatusBar () : FBaseStatusBar (32)
|
||||
DDoomStatusBar () : DBaseStatusBar (32)
|
||||
{
|
||||
static const char *sharedLumpNames[] =
|
||||
{
|
||||
|
@ -44,8 +45,8 @@ public:
|
|||
};
|
||||
FTexture *tex;
|
||||
|
||||
FBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
tex = FBaseStatusBar::Images[imgBNumbers];
|
||||
DBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
tex = DBaseStatusBar::Images[imgBNumbers];
|
||||
BigWidth = tex->GetWidth();
|
||||
BigHeight = tex->GetHeight();
|
||||
|
||||
|
@ -53,7 +54,7 @@ public:
|
|||
bEvilGrin = false;
|
||||
}
|
||||
|
||||
~FDoomStatusBar ()
|
||||
~DDoomStatusBar ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -126,7 +127,7 @@ public:
|
|||
|
||||
void MultiplayerChanged ()
|
||||
{
|
||||
FBaseStatusBar::MultiplayerChanged ();
|
||||
DBaseStatusBar::MultiplayerChanged ();
|
||||
if (multiplayer)
|
||||
{
|
||||
// set face background color
|
||||
|
@ -138,7 +139,7 @@ public:
|
|||
{
|
||||
player_t *oldplayer = CPlayer;
|
||||
|
||||
FBaseStatusBar::AttachToPlayer (player);
|
||||
DBaseStatusBar::AttachToPlayer (player);
|
||||
if (oldplayer != CPlayer)
|
||||
{
|
||||
SetFace (&skins[CPlayer->userinfo.skin]);
|
||||
|
@ -153,14 +154,14 @@ public:
|
|||
|
||||
void Tick ()
|
||||
{
|
||||
FBaseStatusBar::Tick ();
|
||||
DBaseStatusBar::Tick ();
|
||||
RandomNumber = M_Random ();
|
||||
UpdateFace ();
|
||||
}
|
||||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
FBaseStatusBar::Draw (state);
|
||||
DBaseStatusBar::Draw (state);
|
||||
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
|
@ -375,7 +376,7 @@ private:
|
|||
void DrawArm (int on, int picnum, int x, int y, bool drawBackground)
|
||||
{
|
||||
int w;
|
||||
FTexture *pic = on ? FBaseStatusBar::Images[imgSmNumbers + 2 + picnum] : Images[imgGNUM2 + picnum];
|
||||
FTexture *pic = on ? DBaseStatusBar::Images[imgSmNumbers + 2 + picnum] : Images[imgGNUM2 + picnum];
|
||||
|
||||
if (pic != NULL)
|
||||
{
|
||||
|
@ -555,7 +556,7 @@ private:
|
|||
|
||||
void DrawInventoryBar ()
|
||||
{
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
||||
// If the player has no artifacts, don't draw the bar
|
||||
|
@ -602,7 +603,7 @@ private:
|
|||
|
||||
void DrawFullScreenStuff ()
|
||||
{
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
int i;
|
||||
int ammotop;
|
||||
|
||||
|
@ -1041,7 +1042,9 @@ private:
|
|||
bool bEvilGrin;
|
||||
};
|
||||
|
||||
FDoomStatusBar::FDoomStatusBarTexture::FDoomStatusBarTexture ()
|
||||
IMPLEMENT_CLASS(DDoomStatusBar)
|
||||
|
||||
DDoomStatusBar::FDoomStatusBarTexture::FDoomStatusBarTexture ()
|
||||
{
|
||||
BaseTexture = TexMan["STBAR"];
|
||||
if (BaseTexture==NULL)
|
||||
|
@ -1057,7 +1060,7 @@ FDoomStatusBar::FDoomStatusBarTexture::FDoomStatusBarTexture ()
|
|||
STBFremap = NULL;
|
||||
}
|
||||
|
||||
const BYTE *FDoomStatusBar::FDoomStatusBarTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
const BYTE *DDoomStatusBar::FDoomStatusBarTexture::GetColumn (unsigned int column, const Span **spans_out)
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
|
@ -1068,7 +1071,7 @@ const BYTE *FDoomStatusBar::FDoomStatusBarTexture::GetColumn (unsigned int colum
|
|||
return Pixels + column*Height;
|
||||
}
|
||||
|
||||
const BYTE *FDoomStatusBar::FDoomStatusBarTexture::GetPixels ()
|
||||
const BYTE *DDoomStatusBar::FDoomStatusBarTexture::GetPixels ()
|
||||
{
|
||||
if (Pixels == NULL)
|
||||
{
|
||||
|
@ -1077,7 +1080,7 @@ const BYTE *FDoomStatusBar::FDoomStatusBarTexture::GetPixels ()
|
|||
return Pixels;
|
||||
}
|
||||
|
||||
void FDoomStatusBar::FDoomStatusBarTexture::Unload ()
|
||||
void DDoomStatusBar::FDoomStatusBarTexture::Unload ()
|
||||
{
|
||||
if (Pixels != NULL)
|
||||
{
|
||||
|
@ -1086,13 +1089,13 @@ void FDoomStatusBar::FDoomStatusBarTexture::Unload ()
|
|||
}
|
||||
}
|
||||
|
||||
FDoomStatusBar::FDoomStatusBarTexture::~FDoomStatusBarTexture ()
|
||||
DDoomStatusBar::FDoomStatusBarTexture::~FDoomStatusBarTexture ()
|
||||
{
|
||||
Unload ();
|
||||
}
|
||||
|
||||
|
||||
void FDoomStatusBar::FDoomStatusBarTexture::MakeTexture ()
|
||||
void DDoomStatusBar::FDoomStatusBarTexture::MakeTexture ()
|
||||
{
|
||||
Pixels = new BYTE[Width*Height];
|
||||
const BYTE *pix = BaseTexture->GetPixels();
|
||||
|
@ -1103,7 +1106,7 @@ void FDoomStatusBar::FDoomStatusBarTexture::MakeTexture ()
|
|||
if (multiplayer) DrawToBar("STFBANY", 143, 1, STBFremap? STBFremap->Remap : NULL);
|
||||
}
|
||||
|
||||
int FDoomStatusBar::FDoomStatusBarTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y)
|
||||
int DDoomStatusBar::FDoomStatusBarTexture::CopyTrueColorPixels(BYTE *buffer, int buf_pitch, int buf_height, int x, int y)
|
||||
{
|
||||
FTexture *tex;
|
||||
|
||||
|
@ -1136,7 +1139,7 @@ int FDoomStatusBar::FDoomStatusBarTexture::CopyTrueColorPixels(BYTE *buffer, int
|
|||
|
||||
|
||||
|
||||
void FDoomStatusBar::FDoomStatusBarTexture::DrawToBar (const char *name, int x, int y, const BYTE *colormap_in)
|
||||
void DDoomStatusBar::FDoomStatusBarTexture::DrawToBar (const char *name, int x, int y, const BYTE *colormap_in)
|
||||
{
|
||||
FTexture *pic;
|
||||
BYTE colormap[256];
|
||||
|
@ -1165,14 +1168,14 @@ void FDoomStatusBar::FDoomStatusBarTexture::DrawToBar (const char *name, int x,
|
|||
}
|
||||
}
|
||||
|
||||
void FDoomStatusBar::FDoomStatusBarTexture::SetPlayerRemap(FRemapTable *remap)
|
||||
void DDoomStatusBar::FDoomStatusBarTexture::SetPlayerRemap(FRemapTable *remap)
|
||||
{
|
||||
Unload();
|
||||
KillNative();
|
||||
STBFremap = remap;
|
||||
}
|
||||
|
||||
FBaseStatusBar *CreateDoomStatusBar ()
|
||||
DBaseStatusBar *CreateDoomStatusBar ()
|
||||
{
|
||||
return new FDoomStatusBar;
|
||||
return new DDoomStatusBar;
|
||||
}
|
||||
|
|
|
@ -1850,7 +1850,7 @@ FString G_BuildSaveName (const char *prefix, int slot)
|
|||
const char *leader;
|
||||
const char *slash = "";
|
||||
|
||||
if (NULL != (leader = Args.CheckValue ("-savedir")))
|
||||
if (NULL != (leader = Args->CheckValue ("-savedir")))
|
||||
{
|
||||
size_t len = strlen (leader);
|
||||
if (leader[len-1] != '\\' && leader[len-1] != '/')
|
||||
|
@ -1859,7 +1859,7 @@ FString G_BuildSaveName (const char *prefix, int slot)
|
|||
}
|
||||
}
|
||||
#ifndef unix
|
||||
else if (Args.CheckParm ("-cdrom"))
|
||||
else if (Args->CheckParm ("-cdrom"))
|
||||
{
|
||||
leader = CDROM_DIR "/";
|
||||
}
|
||||
|
@ -2205,7 +2205,7 @@ void G_RecordDemo (char* name)
|
|||
strcpy (demoname, name);
|
||||
FixPathSeperator (demoname);
|
||||
DefaultExtension (demoname, ".lmp");
|
||||
v = Args.CheckValue ("-maxdemo");
|
||||
v = Args->CheckValue ("-maxdemo");
|
||||
maxdemosize = 0x20000;
|
||||
demobuffer = (BYTE *)M_Malloc (maxdemosize);
|
||||
|
||||
|
@ -2510,8 +2510,8 @@ void G_DoPlayDemo (void)
|
|||
//
|
||||
void G_TimeDemo (char* name)
|
||||
{
|
||||
nodrawers = !!Args.CheckParm ("-nodraw");
|
||||
noblit = !!Args.CheckParm ("-noblit");
|
||||
nodrawers = !!Args->CheckParm ("-nodraw");
|
||||
noblit = !!Args->CheckParm ("-noblit");
|
||||
timingdemo = true;
|
||||
singletics = true;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class APod : public AActor
|
|||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
void BeginPlay ();
|
||||
AActor *Generator;
|
||||
TObjPtr<AActor> Generator;
|
||||
|
||||
void Serialize (FArchive &arc);
|
||||
};
|
||||
|
|
|
@ -803,7 +803,7 @@ public:
|
|||
protected:
|
||||
bool DoRespawn ();
|
||||
int NumMaceSpots;
|
||||
AActor *FirstSpot;
|
||||
TObjPtr<AActor> FirstSpot;
|
||||
private:
|
||||
|
||||
friend void A_SpawnMace (AActor *self);
|
||||
|
|
|
@ -84,10 +84,12 @@ const BYTE *FHereticShader::GetPixels ()
|
|||
}
|
||||
|
||||
|
||||
class FHereticStatusBar : public FBaseStatusBar
|
||||
class DHereticStatusBar : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DHereticStatusBar, DBaseStatusBar)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
FHereticStatusBar () : FBaseStatusBar (42)
|
||||
DHereticStatusBar () : DBaseStatusBar (42)
|
||||
{
|
||||
static const char *hereticLumpNames[NUM_HERETICSB_IMAGES] =
|
||||
{
|
||||
|
@ -118,7 +120,7 @@ public:
|
|||
hereticLumpNames[5] = "LIFEBAR";
|
||||
}
|
||||
|
||||
FBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
DBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
Images.Init (hereticLumpNames, NUM_HERETICSB_IMAGES);
|
||||
|
||||
oldarti = NULL;
|
||||
|
@ -136,7 +138,7 @@ public:
|
|||
ArtifactFlash = 0;
|
||||
}
|
||||
|
||||
~FHereticStatusBar ()
|
||||
~DHereticStatusBar ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -144,7 +146,7 @@ public:
|
|||
{
|
||||
int curHealth;
|
||||
|
||||
FBaseStatusBar::Tick ();
|
||||
DBaseStatusBar::Tick ();
|
||||
if (level.time & 1)
|
||||
{
|
||||
ChainWiggle = pr_chainwiggle() & 1;
|
||||
|
@ -174,7 +176,7 @@ public:
|
|||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
FBaseStatusBar::Draw (state);
|
||||
DBaseStatusBar::Draw (state);
|
||||
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
|
@ -316,6 +318,7 @@ private:
|
|||
|| (oldarti != NULL && oldartiCount != oldarti->Amount))
|
||||
{
|
||||
oldarti = CPlayer->mo->InvSel;
|
||||
GC::WriteBarrier(this, oldarti);
|
||||
oldartiCount = oldarti != NULL ? oldarti->Amount : 0;
|
||||
ArtiRefresh = screen->GetPageCount ();
|
||||
}
|
||||
|
@ -422,6 +425,8 @@ private:
|
|||
oldammo2 = ammo2;
|
||||
oldammocount1 = ammocount1;
|
||||
oldammocount2 = ammocount2;
|
||||
GC::WriteBarrier(this, ammo1);
|
||||
GC::WriteBarrier(this, ammo2);
|
||||
AmmoRefresh = screen->GetPageCount ();
|
||||
}
|
||||
if (AmmoRefresh)
|
||||
|
@ -475,7 +480,7 @@ private:
|
|||
|
||||
void DrawInventoryBar ()
|
||||
{
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
||||
DrawImage (Images[imgINVBAR], 34, 2);
|
||||
|
@ -517,7 +522,7 @@ private:
|
|||
|
||||
void DrawFullScreenStuff ()
|
||||
{
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
FTexture *pic;
|
||||
int i;
|
||||
|
||||
|
@ -713,8 +718,8 @@ private:
|
|||
static const char patcharti[][10];
|
||||
static const char ammopic[][10];
|
||||
|
||||
AInventory *oldarti;
|
||||
AAmmo *oldammo1, *oldammo2;
|
||||
TObjPtr<AInventory> oldarti;
|
||||
TObjPtr<AAmmo> oldammo1, oldammo2;
|
||||
int oldammocount1, oldammocount2;
|
||||
int oldartiCount;
|
||||
int oldfrags;
|
||||
|
@ -773,7 +778,13 @@ private:
|
|||
char ArmorRefresh;
|
||||
};
|
||||
|
||||
FBaseStatusBar *CreateHereticStatusBar ()
|
||||
IMPLEMENT_POINTY_CLASS(DHereticStatusBar)
|
||||
DECLARE_POINTER(oldarti)
|
||||
DECLARE_POINTER(oldammo1)
|
||||
DECLARE_POINTER(oldammo2)
|
||||
END_POINTERS
|
||||
|
||||
DBaseStatusBar *CreateHereticStatusBar ()
|
||||
{
|
||||
return new FHereticStatusBar;
|
||||
return new DHereticStatusBar;
|
||||
}
|
||||
|
|
|
@ -386,6 +386,7 @@ bool AHolySpirit::SpecialBlastHandling (AActor *source, fixed_t strength)
|
|||
{
|
||||
tracer = target;
|
||||
target = source;
|
||||
GC::WriteBarrier(this, source);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -706,7 +706,7 @@ void A_SorcBallOrbit(AActor *ball)
|
|||
int x,y;
|
||||
angle_t angle, baseangle;
|
||||
int mode = ball->target->args[3];
|
||||
AHeresiarch *parent = static_cast<AHeresiarch *> (ball->target);
|
||||
AHeresiarch *parent = barrier_cast<AHeresiarch *>(ball->target);
|
||||
int dist = parent->radius - (ball->radius<<1);
|
||||
angle_t prevangle = ball->special1;
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ protected:
|
|||
virtual bool MatchPlayerClass (AActor *toucher);
|
||||
const PClass *FourthWeaponClass;
|
||||
int PieceValue;
|
||||
AInventory *TempFourthWeapon;
|
||||
TObjPtr<AInventory> TempFourthWeapon;
|
||||
bool PrivateShouldStay ();
|
||||
};
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ public:
|
|||
void Activate (AActor *activator);
|
||||
void Deactivate (AActor *activator);
|
||||
|
||||
ADirtClump *DirtClump;
|
||||
TObjPtr<ADirtClump> DirtClump;
|
||||
};
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (AThrustFloor)
|
||||
|
|
|
@ -249,7 +249,7 @@ int ATelOtherFX1::DoSpecialDamage (AActor *target, int damage)
|
|||
{
|
||||
target->RemoveFromHash ();
|
||||
LineSpecials[target->special] (NULL, level.flags & LEVEL_ACTOWNSPECIAL
|
||||
? target : this->target, false, target->args[0], target->args[1],
|
||||
? target : (AActor *)(this->target), false, target->args[0], target->args[1],
|
||||
target->args[2], target->args[3], target->args[4]);
|
||||
target->special = 0;
|
||||
}
|
||||
|
|
|
@ -119,10 +119,12 @@ void FManaBar::MakeTexture ()
|
|||
memset (Pixels + 25+24+24, color0, run);
|
||||
}
|
||||
|
||||
class FHexenStatusBar : public FBaseStatusBar
|
||||
class DHexenStatusBar : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DHexenStatusBar, DBaseStatusBar)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
FHexenStatusBar () : FBaseStatusBar (38)
|
||||
DHexenStatusBar () : DBaseStatusBar (38)
|
||||
{
|
||||
static const char *hexenLumpNames[NUM_HEXENSB_IMAGES] =
|
||||
{
|
||||
|
@ -166,7 +168,7 @@ public:
|
|||
"INRED5", "INRED6", "INRED7", "INRED8", "INRED9"
|
||||
};
|
||||
|
||||
FBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES + 10);
|
||||
DBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES + 10);
|
||||
Images.Init (hexenLumpNames, NUM_HEXENSB_IMAGES);
|
||||
ClassImages[0].Init (classLumpNames[0], NUM_HEXENCLASSSB_IMAGES);
|
||||
ClassImages[1].Init (classLumpNames[1], NUM_HEXENCLASSSB_IMAGES);
|
||||
|
@ -201,7 +203,7 @@ public:
|
|||
AmmoRefresh = 0;
|
||||
}
|
||||
|
||||
~FHexenStatusBar ()
|
||||
~DHexenStatusBar ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -209,7 +211,7 @@ public:
|
|||
{
|
||||
int curHealth;
|
||||
|
||||
FBaseStatusBar::Tick ();
|
||||
DBaseStatusBar::Tick ();
|
||||
if (CPlayer->mo == NULL)
|
||||
{
|
||||
curHealth = 0;
|
||||
|
@ -242,7 +244,7 @@ public:
|
|||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
FBaseStatusBar::Draw (state);
|
||||
DBaseStatusBar::Draw (state);
|
||||
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
|
@ -309,7 +311,7 @@ public:
|
|||
|
||||
void AttachToPlayer (player_s *player)
|
||||
{
|
||||
FBaseStatusBar::AttachToPlayer (player);
|
||||
DBaseStatusBar::AttachToPlayer (player);
|
||||
if (player->mo != NULL)
|
||||
{
|
||||
if (player->mo->IsKindOf (PClass::FindClass(NAME_MagePlayer)))
|
||||
|
@ -395,6 +397,7 @@ private:
|
|||
|| (oldarti != NULL && oldartiCount != oldarti->Amount))
|
||||
{
|
||||
oldarti = CPlayer->mo->InvSel;
|
||||
GC::WriteBarrier(this, oldarti);
|
||||
oldartiCount = oldarti != NULL ? oldarti->Amount : 0;
|
||||
ArtiRefresh = screen->GetPageCount ();
|
||||
}
|
||||
|
@ -521,12 +524,14 @@ private:
|
|||
AmmoRefresh = screen->GetPageCount ();
|
||||
oldammo1 = ammo1;
|
||||
oldammocount1 = ammocount1;
|
||||
GC::WriteBarrier(this, ammo1);
|
||||
}
|
||||
if (ammo2 != oldammo2 || ammocount2 != oldammocount2)
|
||||
{
|
||||
AmmoRefresh = screen->GetPageCount ();
|
||||
oldammo2 = ammo2;
|
||||
oldammocount2 = ammocount2;
|
||||
GC::WriteBarrier(this, ammo2);
|
||||
}
|
||||
|
||||
if (AmmoRefresh)
|
||||
|
@ -705,7 +710,7 @@ private:
|
|||
|
||||
void DrawInventoryBar ()
|
||||
{
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
||||
DrawImage (Images[imgINVBAR], 38, 0);
|
||||
|
@ -772,6 +777,7 @@ private:
|
|||
if (keys[i] != oldkeys[i])
|
||||
{
|
||||
oldkeys[i] = keys[i];
|
||||
GC::WriteBarrier(this, keys[i]);
|
||||
different = true;
|
||||
}
|
||||
}
|
||||
|
@ -880,7 +886,7 @@ private:
|
|||
|
||||
void DrawFullScreenStuff ()
|
||||
{
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
||||
// Health
|
||||
|
@ -1051,9 +1057,9 @@ private:
|
|||
static const char patcharti[][10];
|
||||
static const char ammopic[][10];
|
||||
|
||||
AInventory *oldarti;
|
||||
AAmmo *oldammo1, *oldammo2;
|
||||
AKey *oldkeys[5];
|
||||
TObjPtr<AInventory> oldarti;
|
||||
TObjPtr<AAmmo> oldammo1, oldammo2;
|
||||
TObjPtr<AKey> oldkeys[5];
|
||||
int oldammocount1, oldammocount2;
|
||||
int oldartiCount;
|
||||
int oldfrags;
|
||||
|
@ -1155,7 +1161,18 @@ private:
|
|||
FManaBar ManaVial2Pic;
|
||||
};
|
||||
|
||||
FBaseStatusBar *CreateHexenStatusBar ()
|
||||
IMPLEMENT_POINTY_CLASS(DHexenStatusBar)
|
||||
DECLARE_POINTER(oldarti)
|
||||
DECLARE_POINTER(oldammo1)
|
||||
DECLARE_POINTER(oldammo2)
|
||||
DECLARE_POINTER(oldkeys[0])
|
||||
DECLARE_POINTER(oldkeys[1])
|
||||
DECLARE_POINTER(oldkeys[2])
|
||||
DECLARE_POINTER(oldkeys[3])
|
||||
DECLARE_POINTER(oldkeys[4])
|
||||
END_POINTERS
|
||||
|
||||
DBaseStatusBar *CreateHexenStatusBar ()
|
||||
{
|
||||
return new FHexenStatusBar;
|
||||
return new DHexenStatusBar;
|
||||
}
|
||||
|
|
|
@ -1536,12 +1536,12 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
delete StatusBar;
|
||||
StatusBar->Destroy();
|
||||
StatusBar = NULL;
|
||||
}
|
||||
if (bTitleLevel)
|
||||
{
|
||||
StatusBar = new FBaseStatusBar (0);
|
||||
StatusBar = new DBaseStatusBar (0);
|
||||
}
|
||||
else if (SBarInfoScript != NULL)
|
||||
{
|
||||
|
@ -1588,9 +1588,10 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
}
|
||||
else
|
||||
{
|
||||
StatusBar = new FBaseStatusBar (0);
|
||||
StatusBar = new DBaseStatusBar (0);
|
||||
}
|
||||
}
|
||||
GC::WriteBarrier(StatusBar);
|
||||
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
||||
StatusBar->NewGame ();
|
||||
setsizeneeded = true;
|
||||
|
|
|
@ -332,7 +332,7 @@ public:
|
|||
DCorpsePointer (AActor *ptr);
|
||||
void Destroy ();
|
||||
void Serialize (FArchive &arc);
|
||||
AActor *Corpse;
|
||||
TObjPtr<AActor> Corpse;
|
||||
DWORD Count; // Only the first corpse pointer's count is valid.
|
||||
private:
|
||||
DCorpsePointer () {}
|
||||
|
|
|
@ -52,10 +52,10 @@ static int ImpactCount;
|
|||
|
||||
CVAR (Bool, cl_spreaddecals, true, CVAR_ARCHIVE)
|
||||
|
||||
// They also overload floorclip to be the fractional distance from the
|
||||
// left edge of the side. This distance is stored as a 2.30 fixed pt number.
|
||||
IMPLEMENT_POINTY_CLASS (DBaseDecal)
|
||||
DECLARE_POINTER(WallNext)
|
||||
END_POINTERS
|
||||
|
||||
IMPLEMENT_CLASS (DBaseDecal)
|
||||
IMPLEMENT_CLASS (DImpactDecal)
|
||||
|
||||
DBaseDecal::DBaseDecal ()
|
||||
|
|
|
@ -137,7 +137,7 @@ bool P_UndoPlayerMorph (player_t *player, bool force)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
mo = static_cast<APlayerPawn *>(pmo->tracer);
|
||||
mo = barrier_cast<APlayerPawn *>(pmo->tracer);
|
||||
mo->SetOrigin (pmo->x, pmo->y, pmo->z);
|
||||
mo->flags |= MF_SOLID;
|
||||
pmo->flags &= ~MF_SOLID;
|
||||
|
|
|
@ -61,7 +61,7 @@ public:
|
|||
|
||||
void Serialize (FArchive &arc);
|
||||
|
||||
AInterpolationPoint *Next;
|
||||
TObjPtr<AInterpolationPoint> Next;
|
||||
};
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (AInterpolationPoint)
|
||||
|
@ -181,7 +181,7 @@ protected:
|
|||
void Serialize (FArchive &arc);
|
||||
|
||||
bool bActive, bJustStepped;
|
||||
AInterpolationPoint *PrevNode, *CurrNode;
|
||||
TObjPtr<AInterpolationPoint> PrevNode, CurrNode;
|
||||
float Time; // Runs from 0.0 to 1.0 between CurrNode and CurrNode->Next
|
||||
int HoldTime;
|
||||
};
|
||||
|
@ -289,8 +289,8 @@ void APathFollower::Activate (AActor *activator)
|
|||
{
|
||||
if (!bActive)
|
||||
{
|
||||
CurrNode = static_cast<AInterpolationPoint *>(target);
|
||||
PrevNode = static_cast<AInterpolationPoint *>(lastenemy);
|
||||
CurrNode = barrier_cast<AInterpolationPoint *>(target);
|
||||
PrevNode = barrier_cast<AInterpolationPoint *>(lastenemy);
|
||||
|
||||
if (CurrNode != NULL)
|
||||
{
|
||||
|
@ -638,7 +638,7 @@ public:
|
|||
protected:
|
||||
bool Interpolate ();
|
||||
|
||||
AActor *Activator;
|
||||
TObjPtr<AActor> Activator;
|
||||
};
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (AMovingCamera)
|
||||
|
|
|
@ -101,7 +101,7 @@ bool AAmmo::HandlePickup (AInventory *item)
|
|||
(Owner->player->ReadyWeapon == NULL ||
|
||||
(Owner->player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)))
|
||||
{
|
||||
AWeapon *best = static_cast<APlayerPawn *>(Owner)->BestWeapon (GetClass());
|
||||
AWeapon *best = barrier_cast<APlayerPawn *>(Owner)->BestWeapon (GetClass());
|
||||
if (best != NULL && (Owner->player->ReadyWeapon == NULL ||
|
||||
best->SelectionOrder < Owner->player->ReadyWeapon->SelectionOrder))
|
||||
{
|
||||
|
@ -1052,7 +1052,7 @@ PalEntry AInventory::GetBlend ()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *AInventory::PrevItem () const
|
||||
AInventory *AInventory::PrevItem ()
|
||||
{
|
||||
AInventory *item = Owner->Inventory;
|
||||
|
||||
|
@ -1071,7 +1071,7 @@ AInventory *AInventory::PrevItem () const
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *AInventory::PrevInv () const
|
||||
AInventory *AInventory::PrevInv ()
|
||||
{
|
||||
AInventory *lastgood = NULL;
|
||||
AInventory *item = Owner->Inventory;
|
||||
|
@ -1094,7 +1094,7 @@ AInventory *AInventory::PrevInv () const
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
AInventory *AInventory::NextInv () const
|
||||
AInventory *AInventory::NextInv ()
|
||||
{
|
||||
AInventory *item = Inventory;
|
||||
|
||||
|
|
|
@ -124,11 +124,11 @@ public:
|
|||
virtual const char *PickupMessage ();
|
||||
virtual void PlayPickupSound (AActor *toucher);
|
||||
|
||||
AInventory *PrevItem () const; // Returns the item preceding this one in the list.
|
||||
AInventory *PrevInv () const; // Returns the previous item with IF_INVBAR set.
|
||||
AInventory *NextInv () const; // Returns the next item with IF_INVBAR set.
|
||||
AInventory *PrevItem(); // Returns the item preceding this one in the list.
|
||||
AInventory *PrevInv(); // Returns the previous item with IF_INVBAR set.
|
||||
AInventory *NextInv(); // Returns the next item with IF_INVBAR set.
|
||||
|
||||
AActor *Owner; // Who owns this item? NULL if it's still a pickup.
|
||||
TObjPtr<AActor> Owner; // Who owns this item? NULL if it's still a pickup.
|
||||
int Amount; // Amount of item this instance has
|
||||
int MaxAmount; // Max amount of item this instance can have
|
||||
int RespawnTics; // Tics from pickup time to respawn time
|
||||
|
@ -217,8 +217,8 @@ public:
|
|||
fixed_t MoveCombatDist; // Used by bots, but do they *really* need it?
|
||||
|
||||
// In-inventory instance variables
|
||||
AAmmo *Ammo1, *Ammo2;
|
||||
AWeapon *SisterWeapon;
|
||||
TObjPtr<AAmmo> Ammo1, Ammo2;
|
||||
TObjPtr<AWeapon> SisterWeapon;
|
||||
|
||||
bool bAltFire; // Set when this weapon's alternate fire is used.
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ void ASectorAction::Deactivate (AActor *source)
|
|||
bool ASectorAction::TriggerAction (AActor *triggerer, int activationType)
|
||||
{
|
||||
if (tracer != NULL)
|
||||
return static_cast<ASectorAction *>(tracer)->TriggerAction (triggerer, activationType);
|
||||
return barrier_cast<ASectorAction *>(tracer)->TriggerAction (triggerer, activationType);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ struct side_s;
|
|||
class DBaseDecal : public DThinker
|
||||
{
|
||||
DECLARE_CLASS (DBaseDecal, DThinker)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DBaseDecal ();
|
||||
DBaseDecal (fixed_t z);
|
||||
|
@ -147,7 +148,7 @@ protected:
|
|||
float Blends[2][4];
|
||||
int TotalTics;
|
||||
int StartTic;
|
||||
AActor *ForWho;
|
||||
TObjPtr<AActor> ForWho;
|
||||
|
||||
void SetBlend (float time);
|
||||
DFlashFader ();
|
||||
|
@ -163,7 +164,7 @@ public:
|
|||
void Serialize (FArchive &arc);
|
||||
void Tick ();
|
||||
|
||||
AActor *m_Spot;
|
||||
TObjPtr<AActor> m_Spot;
|
||||
fixed_t m_TremorRadius, m_DamageRadius;
|
||||
int m_Intensity;
|
||||
int m_Countdown;
|
||||
|
@ -195,7 +196,7 @@ public:
|
|||
void Die (AActor *source, AActor *inflictor);
|
||||
void Destroy ();
|
||||
|
||||
AActor *UnmorphedMe;
|
||||
TObjPtr<AActor> UnmorphedMe;
|
||||
int UnmorphTime;
|
||||
DWORD FlagsSave;
|
||||
};
|
||||
|
|
|
@ -27,7 +27,11 @@ IMPLEMENT_STATELESS_ACTOR (AWeaponHolder, Any, -1, 0)
|
|||
PROP_Inventory_FlagsSet (IF_UNDROPPABLE)
|
||||
END_DEFAULTS
|
||||
|
||||
IMPLEMENT_STATELESS_ACTOR (AWeaponPiece, Any, -1, 0)
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (AWeaponPiece)
|
||||
DECLARE_POINTER (FullWeapon)
|
||||
END_POINTERS
|
||||
BEGIN_STATELESS_DEFAULTS (AWeaponPiece, Any, -1, 0)
|
||||
END_DEFAULTS
|
||||
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
class AWeaponPiece : public AInventory
|
||||
{
|
||||
DECLARE_CLASS (AWeaponPiece, AInventory)
|
||||
HAS_OBJECT_POINTERS
|
||||
protected:
|
||||
bool PrivateShouldStay ();
|
||||
public:
|
||||
|
@ -13,5 +14,5 @@ public:
|
|||
|
||||
int PieceValue;
|
||||
const PClass * WeaponClass;
|
||||
AWeapon * FullWeapon;
|
||||
TObjPtr<AWeapon> FullWeapon;
|
||||
};
|
||||
|
|
|
@ -370,7 +370,7 @@ bool AWeapon::CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo)
|
|||
bool gotSome = CheckAmmo (PrimaryFire, false) || CheckAmmo (AltFire, false);
|
||||
if (!gotSome && autoSwitch)
|
||||
{
|
||||
static_cast<APlayerPawn *> (Owner)->PickNewWeapon (NULL);
|
||||
barrier_cast<APlayerPawn *>(Owner)->PickNewWeapon (NULL);
|
||||
}
|
||||
return gotSome;
|
||||
}
|
||||
|
@ -402,7 +402,7 @@ bool AWeapon::CheckAmmo (int fireMode, bool autoSwitch, bool requireAmmo)
|
|||
// out of ammo, pick a weapon to change to
|
||||
if (autoSwitch)
|
||||
{
|
||||
static_cast<APlayerPawn *> (Owner)->PickNewWeapon (NULL);
|
||||
barrier_cast<APlayerPawn *>(Owner)->PickNewWeapon (NULL);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,10 @@
|
|||
|
||||
EXTERN_CVAR (Int, con_scaletext)
|
||||
|
||||
IMPLEMENT_CLASS (DHUDMessage)
|
||||
IMPLEMENT_POINTY_CLASS (DHUDMessage)
|
||||
DECLARE_POINTER(Next)
|
||||
END_POINTERS
|
||||
|
||||
IMPLEMENT_CLASS (DHUDMessageFadeOut)
|
||||
IMPLEMENT_CLASS (DHUDMessageFadeInOut)
|
||||
IMPLEMENT_CLASS (DHUDMessageTypeOnFadeOut)
|
||||
|
|
|
@ -55,6 +55,7 @@ class AWeapon;
|
|||
class DHUDMessage : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DHUDMessage, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DHUDMessage (const char *text, float x, float y, int hudwidth, int hudheight,
|
||||
EColorRange textColor, float holdTime);
|
||||
|
@ -84,11 +85,11 @@ protected:
|
|||
DHUDMessage () : SourceText(NULL) {}
|
||||
|
||||
private:
|
||||
DHUDMessage *Next;
|
||||
TObjPtr<DHUDMessage> Next;
|
||||
DWORD SBarID;
|
||||
char *SourceText;
|
||||
|
||||
friend class FBaseStatusBar;
|
||||
friend class DBaseStatusBar;
|
||||
};
|
||||
|
||||
class DHUDMessageFadeOut : public DHUDMessage
|
||||
|
@ -149,8 +150,10 @@ protected:
|
|||
class FTexture;
|
||||
class AAmmo;
|
||||
|
||||
class FBaseStatusBar
|
||||
class DBaseStatusBar : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DBaseStatusBar, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
// Popup screens for Strife's status bar
|
||||
enum
|
||||
|
@ -162,8 +165,8 @@ public:
|
|||
POP_Status
|
||||
};
|
||||
|
||||
FBaseStatusBar (int reltop);
|
||||
virtual ~FBaseStatusBar ();
|
||||
DBaseStatusBar (int reltop);
|
||||
void Destroy ();
|
||||
|
||||
void SetScaled (bool scale);
|
||||
|
||||
|
@ -246,20 +249,21 @@ public:
|
|||
player_s *CPlayer;
|
||||
|
||||
private:
|
||||
DBaseStatusBar() {}
|
||||
bool RepositionCoords (int &x, int &y, int xo, int yo, const int w, const int h) const;
|
||||
void DrawMessages (int bottom) const;
|
||||
void DrawMessages (int bottom);
|
||||
void DrawConsistancy () const;
|
||||
|
||||
static BYTE DamageToAlpha[114];
|
||||
|
||||
DHUDMessage *Messages;
|
||||
TObjPtr<DHUDMessage> Messages;
|
||||
bool ShowLog;
|
||||
};
|
||||
|
||||
extern FBaseStatusBar *StatusBar;
|
||||
extern DBaseStatusBar *StatusBar;
|
||||
|
||||
FBaseStatusBar *CreateDoomStatusBar ();
|
||||
FBaseStatusBar *CreateHereticStatusBar ();
|
||||
FBaseStatusBar *CreateHexenStatusBar ();
|
||||
FBaseStatusBar *CreateStrifeStatusBar ();
|
||||
FBaseStatusBar *CreateCustomStatusBar ();
|
||||
DBaseStatusBar *CreateDoomStatusBar ();
|
||||
DBaseStatusBar *CreateHereticStatusBar ();
|
||||
DBaseStatusBar *CreateHexenStatusBar ();
|
||||
DBaseStatusBar *CreateStrifeStatusBar ();
|
||||
DBaseStatusBar *CreateCustomStatusBar ();
|
||||
|
|
|
@ -1238,10 +1238,11 @@ SBarInfoBlock::SBarInfoBlock()
|
|||
}
|
||||
|
||||
//SBarInfo Display
|
||||
class FSBarInfo : public FBaseStatusBar
|
||||
class DSBarInfo : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DSBarInfo, DBaseStatusBar)
|
||||
public:
|
||||
FSBarInfo () : FBaseStatusBar (SBarInfoScript->height),
|
||||
DSBarInfo () : DBaseStatusBar (SBarInfoScript->height),
|
||||
shader_horz_normal(false, false),
|
||||
shader_horz_reverse(false, true),
|
||||
shader_vert_normal(true, false),
|
||||
|
@ -1279,7 +1280,7 @@ public:
|
|||
artiflash = 4;
|
||||
}
|
||||
|
||||
~FSBarInfo ()
|
||||
~DSBarInfo ()
|
||||
{
|
||||
Images.Uninit();
|
||||
Faces.Uninit();
|
||||
|
@ -1287,7 +1288,7 @@ public:
|
|||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
FBaseStatusBar::Draw(state);
|
||||
DBaseStatusBar::Draw(state);
|
||||
int hud = 2;
|
||||
if(state == HUD_StatusBar)
|
||||
{
|
||||
|
@ -1341,7 +1342,7 @@ public:
|
|||
void AttachToPlayer (player_t *player)
|
||||
{
|
||||
player_t *oldplayer = CPlayer;
|
||||
FBaseStatusBar::AttachToPlayer(player);
|
||||
DBaseStatusBar::AttachToPlayer(player);
|
||||
if (oldplayer != CPlayer)
|
||||
{
|
||||
SetFace(&skins[CPlayer->userinfo.skin], "STF");
|
||||
|
@ -1350,7 +1351,7 @@ public:
|
|||
|
||||
void Tick ()
|
||||
{
|
||||
FBaseStatusBar::Tick();
|
||||
DBaseStatusBar::Tick();
|
||||
if(level.time & 1)
|
||||
chainWiggle = pr_chainwiggle() & 1;
|
||||
getNewFace(M_Random());
|
||||
|
@ -2310,7 +2311,7 @@ private:
|
|||
void DrawInventoryBar(int type, int num, int x, int y, bool alwaysshow,
|
||||
int counterx, int countery, EColorRange translation, bool drawArtiboxes, bool noArrows, bool alwaysshowcounter)
|
||||
{ //yes, there is some Copy & Paste here too
|
||||
const AInventory *item;
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
||||
// If the player has no artifacts, don't draw the bar
|
||||
|
@ -2408,7 +2409,9 @@ private:
|
|||
FBarShader shader_vert_reverse;
|
||||
};
|
||||
|
||||
FBaseStatusBar *CreateCustomStatusBar ()
|
||||
IMPLEMENT_CLASS(DSBarInfo);
|
||||
|
||||
DBaseStatusBar *CreateCustomStatusBar ()
|
||||
{
|
||||
return new FSBarInfo;
|
||||
return new DSBarInfo;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@
|
|||
#define XHAIRPICKUPSIZE (FRACUNIT*2+XHAIRSHRINKSIZE)
|
||||
#define POWERUPICONSIZE 32
|
||||
|
||||
IMPLEMENT_POINTY_CLASS(DBaseStatusBar)
|
||||
DECLARE_POINTER(Messages)
|
||||
END_POINTERS
|
||||
|
||||
EXTERN_CVAR (Bool, am_showmonsters)
|
||||
EXTERN_CVAR (Bool, am_showsecrets)
|
||||
EXTERN_CVAR (Bool, am_showitems)
|
||||
|
@ -62,7 +66,7 @@ EXTERN_CVAR (Bool, noisedebug)
|
|||
EXTERN_CVAR (Bool, hud_scale)
|
||||
EXTERN_CVAR (Int, con_scaletext)
|
||||
|
||||
FBaseStatusBar *StatusBar;
|
||||
DBaseStatusBar *StatusBar;
|
||||
|
||||
extern int setblocks;
|
||||
|
||||
|
@ -126,7 +130,7 @@ CVAR (Bool, idmypos, false, 0);
|
|||
|
||||
// [RH] Amount of red flash for up to 114 damage points. Calculated by hand
|
||||
// using a logarithmic scale and my trusty HP48G.
|
||||
BYTE FBaseStatusBar::DamageToAlpha[114] =
|
||||
BYTE DBaseStatusBar::DamageToAlpha[114] =
|
||||
{
|
||||
0, 8, 16, 23, 30, 36, 42, 47, 53, 58, 62, 67, 71, 75, 79,
|
||||
83, 87, 90, 94, 97, 100, 103, 107, 109, 112, 115, 118, 120, 123, 125,
|
||||
|
@ -144,7 +148,7 @@ BYTE FBaseStatusBar::DamageToAlpha[114] =
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
FBaseStatusBar::FBaseStatusBar (int reltop)
|
||||
DBaseStatusBar::DBaseStatusBar (int reltop)
|
||||
{
|
||||
Centering = false;
|
||||
FixedOrigin = false;
|
||||
|
@ -160,11 +164,11 @@ FBaseStatusBar::FBaseStatusBar (int reltop)
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Destructor
|
||||
// PROP Destroy
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
FBaseStatusBar::~FBaseStatusBar ()
|
||||
void DBaseStatusBar::Destroy ()
|
||||
{
|
||||
DHUDMessage *msg;
|
||||
|
||||
|
@ -172,9 +176,10 @@ FBaseStatusBar::~FBaseStatusBar ()
|
|||
while (msg)
|
||||
{
|
||||
DHUDMessage *next = msg->Next;
|
||||
delete msg;
|
||||
msg->Destroy();
|
||||
msg = next;
|
||||
}
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -183,7 +188,7 @@ FBaseStatusBar::~FBaseStatusBar ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::SetScaled (bool scale)
|
||||
void DBaseStatusBar::SetScaled (bool scale)
|
||||
{
|
||||
Scaled = RelTop != 0 && (SCREENWIDTH != 320 && scale);
|
||||
if (!Scaled)
|
||||
|
@ -225,7 +230,7 @@ void FBaseStatusBar::SetScaled (bool scale)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::AttachToPlayer (player_s *player)
|
||||
void DBaseStatusBar::AttachToPlayer (player_s *player)
|
||||
{
|
||||
CPlayer = player;
|
||||
SB_state = screen->GetPageCount ();
|
||||
|
@ -237,7 +242,7 @@ void FBaseStatusBar::AttachToPlayer (player_s *player)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
int FBaseStatusBar::GetPlayer ()
|
||||
int DBaseStatusBar::GetPlayer ()
|
||||
{
|
||||
return int(CPlayer - players);
|
||||
}
|
||||
|
@ -248,7 +253,7 @@ int FBaseStatusBar::GetPlayer ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::MultiplayerChanged ()
|
||||
void DBaseStatusBar::MultiplayerChanged ()
|
||||
{
|
||||
SB_state = screen->GetPageCount ();
|
||||
}
|
||||
|
@ -259,7 +264,7 @@ void FBaseStatusBar::MultiplayerChanged ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::Tick ()
|
||||
void DBaseStatusBar::Tick ()
|
||||
{
|
||||
DHUDMessage *msg = Messages;
|
||||
DHUDMessage **prev = &Messages;
|
||||
|
@ -271,7 +276,7 @@ void FBaseStatusBar::Tick ()
|
|||
if (msg->Tick ())
|
||||
{
|
||||
*prev = next;
|
||||
delete msg;
|
||||
msg->Destroy();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -297,15 +302,16 @@ void FBaseStatusBar::Tick ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
||||
void DBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
||||
{
|
||||
DHUDMessage *old = NULL;
|
||||
DHUDMessage **prev;
|
||||
DObject *container = this;
|
||||
|
||||
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
|
||||
if (old != NULL)
|
||||
{
|
||||
delete old;
|
||||
old->Destroy();
|
||||
}
|
||||
|
||||
prev = &Messages;
|
||||
|
@ -315,12 +321,14 @@ void FBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
|||
// it gets drawn back to front.)
|
||||
while (*prev != NULL && (*prev)->SBarID > id)
|
||||
{
|
||||
container = *prev;
|
||||
prev = &(*prev)->Next;
|
||||
}
|
||||
|
||||
msg->Next = *prev;
|
||||
msg->SBarID = id;
|
||||
*prev = msg;
|
||||
GC::WriteBarrier(container, msg);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -329,7 +337,7 @@ void FBaseStatusBar::AttachMessage (DHUDMessage *msg, DWORD id)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DHUDMessage *FBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
||||
DHUDMessage *DBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
DHUDMessage **prev = &Messages;
|
||||
|
@ -349,7 +357,7 @@ DHUDMessage *FBaseStatusBar::DetachMessage (DHUDMessage *msg)
|
|||
return probe;
|
||||
}
|
||||
|
||||
DHUDMessage *FBaseStatusBar::DetachMessage (DWORD id)
|
||||
DHUDMessage *DBaseStatusBar::DetachMessage (DWORD id)
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
DHUDMessage **prev = &Messages;
|
||||
|
@ -375,7 +383,7 @@ DHUDMessage *FBaseStatusBar::DetachMessage (DWORD id)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DetachAllMessages ()
|
||||
void DBaseStatusBar::DetachAllMessages ()
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
|
||||
|
@ -383,7 +391,7 @@ void FBaseStatusBar::DetachAllMessages ()
|
|||
while (probe != NULL)
|
||||
{
|
||||
DHUDMessage *next = probe->Next;
|
||||
delete probe;
|
||||
probe->Destroy();
|
||||
probe = next;
|
||||
}
|
||||
}
|
||||
|
@ -394,7 +402,7 @@ void FBaseStatusBar::DetachAllMessages ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool FBaseStatusBar::CheckMessage (DHUDMessage *msg)
|
||||
bool DBaseStatusBar::CheckMessage (DHUDMessage *msg)
|
||||
{
|
||||
DHUDMessage *probe = Messages;
|
||||
while (probe && probe != msg)
|
||||
|
@ -410,7 +418,7 @@ bool FBaseStatusBar::CheckMessage (DHUDMessage *msg)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::ShowPlayerName ()
|
||||
void DBaseStatusBar::ShowPlayerName ()
|
||||
{
|
||||
EColorRange color;
|
||||
|
||||
|
@ -427,7 +435,7 @@ void FBaseStatusBar::ShowPlayerName ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawImage (FTexture *img,
|
||||
void DBaseStatusBar::DrawImage (FTexture *img,
|
||||
int x, int y, FRemapTable *translation) const
|
||||
{
|
||||
if (img != NULL)
|
||||
|
@ -448,7 +456,7 @@ void FBaseStatusBar::DrawImage (FTexture *img,
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawDimImage (FTexture *img,
|
||||
void DBaseStatusBar::DrawDimImage (FTexture *img,
|
||||
int x, int y, bool dimmed) const
|
||||
{
|
||||
if (img != NULL)
|
||||
|
@ -469,7 +477,7 @@ void FBaseStatusBar::DrawDimImage (FTexture *img,
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawFadedImage (FTexture *img,
|
||||
void DBaseStatusBar::DrawFadedImage (FTexture *img,
|
||||
int x, int y, fixed_t shade) const
|
||||
{
|
||||
if (img != NULL)
|
||||
|
@ -491,7 +499,7 @@ void FBaseStatusBar::DrawFadedImage (FTexture *img,
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawPartialImage (FTexture *img, int wx, int ww) const
|
||||
void DBaseStatusBar::DrawPartialImage (FTexture *img, int wx, int ww) const
|
||||
{
|
||||
if (img != NULL)
|
||||
{
|
||||
|
@ -511,7 +519,7 @@ void FBaseStatusBar::DrawPartialImage (FTexture *img, int wx, int ww) const
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrINumber (signed int val, int x, int y, int imgBase) const
|
||||
void DBaseStatusBar::DrINumber (signed int val, int x, int y, int imgBase) const
|
||||
{
|
||||
int oldval;
|
||||
|
||||
|
@ -551,7 +559,7 @@ void FBaseStatusBar::DrINumber (signed int val, int x, int y, int imgBase) const
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrBNumber (signed int val, int x, int y, int size) const
|
||||
void DBaseStatusBar::DrBNumber (signed int val, int x, int y, int size) const
|
||||
{
|
||||
bool neg;
|
||||
int i, w;
|
||||
|
@ -611,7 +619,7 @@ void FBaseStatusBar::DrBNumber (signed int val, int x, int y, int size) const
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrSmallNumber (int val, int x, int y) const
|
||||
void DBaseStatusBar::DrSmallNumber (int val, int x, int y) const
|
||||
{
|
||||
int digit = 0;
|
||||
|
||||
|
@ -642,7 +650,7 @@ void FBaseStatusBar::DrSmallNumber (int val, int x, int y) const
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrINumberOuter (signed int val, int x, int y, bool center, int w) const
|
||||
void DBaseStatusBar::DrINumberOuter (signed int val, int x, int y, bool center, int w) const
|
||||
{
|
||||
bool negative = false;
|
||||
|
||||
|
@ -706,7 +714,7 @@ void FBaseStatusBar::DrINumberOuter (signed int val, int x, int y, bool center,
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrBNumberOuter (signed int val, int x, int y, int size) const
|
||||
void DBaseStatusBar::DrBNumberOuter (signed int val, int x, int y, int size) const
|
||||
{
|
||||
int xpos;
|
||||
int w;
|
||||
|
@ -813,7 +821,7 @@ void FBaseStatusBar::DrBNumberOuter (signed int val, int x, int y, int size) con
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrBNumberOuterFont (signed int val, int x, int y, int size) const
|
||||
void DBaseStatusBar::DrBNumberOuterFont (signed int val, int x, int y, int size) const
|
||||
{
|
||||
int xpos;
|
||||
int w, v;
|
||||
|
@ -914,7 +922,7 @@ void FBaseStatusBar::DrBNumberOuterFont (signed int val, int x, int y, int size)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrSmallNumberOuter (int val, int x, int y, bool center) const
|
||||
void DBaseStatusBar::DrSmallNumberOuter (int val, int x, int y, bool center) const
|
||||
{
|
||||
int digit = 0;
|
||||
|
||||
|
@ -946,7 +954,7 @@ void FBaseStatusBar::DrSmallNumberOuter (int val, int x, int y, bool center) con
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::RefreshBackground () const
|
||||
void DBaseStatusBar::RefreshBackground () const
|
||||
{
|
||||
int x, x2, y, ratio;
|
||||
|
||||
|
@ -981,7 +989,7 @@ void FBaseStatusBar::RefreshBackground () const
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawCrosshair ()
|
||||
void DBaseStatusBar::DrawCrosshair ()
|
||||
{
|
||||
static DWORD prevcolor = 0xffffffff;
|
||||
static int palettecolor = 0;
|
||||
|
@ -1072,7 +1080,7 @@ void FBaseStatusBar::DrawCrosshair ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::FlashCrosshair ()
|
||||
void DBaseStatusBar::FlashCrosshair ()
|
||||
{
|
||||
CrosshairSize = XHAIRPICKUPSIZE;
|
||||
}
|
||||
|
@ -1083,7 +1091,7 @@ void FBaseStatusBar::FlashCrosshair ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawMessages (int bottom) const
|
||||
void DBaseStatusBar::DrawMessages (int bottom)
|
||||
{
|
||||
DHUDMessage *msg = Messages;
|
||||
while (msg)
|
||||
|
@ -1100,7 +1108,7 @@ void FBaseStatusBar::DrawMessages (int bottom) const
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::Draw (EHudState state)
|
||||
void DBaseStatusBar::Draw (EHudState state)
|
||||
{
|
||||
char line[64+10];
|
||||
|
||||
|
@ -1254,7 +1262,7 @@ void FBaseStatusBar::Draw (EHudState state)
|
|||
}
|
||||
|
||||
|
||||
void FBaseStatusBar::DrawLog ()
|
||||
void DBaseStatusBar::DrawLog ()
|
||||
{
|
||||
int hudwidth, hudheight;
|
||||
|
||||
|
@ -1318,7 +1326,7 @@ void FBaseStatusBar::DrawLog ()
|
|||
}
|
||||
}
|
||||
|
||||
bool FBaseStatusBar::MustDrawLog(EHudState)
|
||||
bool DBaseStatusBar::MustDrawLog(EHudState)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -1329,7 +1337,7 @@ bool FBaseStatusBar::MustDrawLog(EHudState)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawTopStuff (EHudState state)
|
||||
void DBaseStatusBar::DrawTopStuff (EHudState state)
|
||||
{
|
||||
if (demoplayback && demover != DEMOGAMEVERSION)
|
||||
{
|
||||
|
@ -1360,7 +1368,7 @@ void FBaseStatusBar::DrawTopStuff (EHudState state)
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::DrawPowerups ()
|
||||
void DBaseStatusBar::DrawPowerups ()
|
||||
{
|
||||
// Each icon gets a 32x32 block to draw itself in.
|
||||
int x, y;
|
||||
|
@ -1388,7 +1396,7 @@ SV_AddBlend
|
|||
[RH] This is from Q2.
|
||||
=============
|
||||
*/
|
||||
void FBaseStatusBar::AddBlend (float r, float g, float b, float a, float v_blend[4])
|
||||
void DBaseStatusBar::AddBlend (float r, float g, float b, float a, float v_blend[4])
|
||||
{
|
||||
float a2, a3;
|
||||
|
||||
|
@ -1409,7 +1417,7 @@ void FBaseStatusBar::AddBlend (float r, float g, float b, float a, float v_blend
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void FBaseStatusBar::BlendView (float blend[4])
|
||||
void DBaseStatusBar::BlendView (float blend[4])
|
||||
{
|
||||
int cnt;
|
||||
|
||||
|
@ -1480,7 +1488,7 @@ void FBaseStatusBar::BlendView (float blend[4])
|
|||
(int)(blend[2] * 255.0f), (int)(blend[3] * 256.0f));
|
||||
}
|
||||
|
||||
void FBaseStatusBar::DrawConsistancy () const
|
||||
void DBaseStatusBar::DrawConsistancy () const
|
||||
{
|
||||
static bool firsttime = true;
|
||||
int i;
|
||||
|
@ -1524,37 +1532,37 @@ void FBaseStatusBar::DrawConsistancy () const
|
|||
}
|
||||
}
|
||||
|
||||
void FBaseStatusBar::FlashItem (const PClass *itemtype)
|
||||
void DBaseStatusBar::FlashItem (const PClass *itemtype)
|
||||
{
|
||||
}
|
||||
|
||||
void FBaseStatusBar::SetFace (void *)
|
||||
void DBaseStatusBar::SetFace (void *)
|
||||
{
|
||||
}
|
||||
|
||||
void FBaseStatusBar::NewGame ()
|
||||
void DBaseStatusBar::NewGame ()
|
||||
{
|
||||
}
|
||||
|
||||
void FBaseStatusBar::SetInteger (int pname, int param)
|
||||
void DBaseStatusBar::SetInteger (int pname, int param)
|
||||
{
|
||||
}
|
||||
|
||||
void FBaseStatusBar::ShowPop (int popnum)
|
||||
void DBaseStatusBar::ShowPop (int popnum)
|
||||
{
|
||||
ShowLog = (popnum == POP_Log && !ShowLog);
|
||||
}
|
||||
|
||||
void FBaseStatusBar::ReceivedWeapon (AWeapon *weapon)
|
||||
void DBaseStatusBar::ReceivedWeapon (AWeapon *weapon)
|
||||
{
|
||||
}
|
||||
|
||||
void FBaseStatusBar::Serialize (FArchive &arc)
|
||||
void DBaseStatusBar::Serialize (FArchive &arc)
|
||||
{
|
||||
arc << Messages;
|
||||
}
|
||||
|
||||
void FBaseStatusBar::ScreenSizeChanged ()
|
||||
void DBaseStatusBar::ScreenSizeChanged ()
|
||||
{
|
||||
st_scale.Callback ();
|
||||
SB_state = screen->GetPageCount ();
|
||||
|
@ -1576,7 +1584,7 @@ void FBaseStatusBar::ScreenSizeChanged ()
|
|||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
AInventory *FBaseStatusBar::ValidateInvFirst (int numVisible) const
|
||||
AInventory *DBaseStatusBar::ValidateInvFirst (int numVisible) const
|
||||
{
|
||||
AInventory *item;
|
||||
int i;
|
||||
|
@ -1660,14 +1668,14 @@ AInventory *FBaseStatusBar::ValidateInvFirst (int numVisible) const
|
|||
|
||||
//============================================================================
|
||||
//
|
||||
// FBaseStatusBar :: GetCurrentAmmo
|
||||
// DBaseStatusBar :: GetCurrentAmmo
|
||||
//
|
||||
// Returns the types and amounts of ammo used by the current weapon. If the
|
||||
// weapon only uses one type of ammo, it is always returned as ammo1.
|
||||
//
|
||||
//============================================================================
|
||||
|
||||
void FBaseStatusBar::GetCurrentAmmo (AAmmo *&ammo1, AAmmo *&ammo2, int &ammocount1, int &ammocount2) const
|
||||
void DBaseStatusBar::GetCurrentAmmo (AAmmo *&ammo1, AAmmo *&ammo2, int &ammocount1, int &ammocount2) const
|
||||
{
|
||||
if (CPlayer->ReadyWeapon != NULL)
|
||||
{
|
||||
|
|
|
@ -180,10 +180,11 @@ void FHealthBar::FillBar (int min, int max, BYTE light, BYTE dark)
|
|||
}
|
||||
}
|
||||
|
||||
class FStrifeStatusBar : public FBaseStatusBar
|
||||
class DStrifeStatusBar : public DBaseStatusBar
|
||||
{
|
||||
DECLARE_CLASS(DStrifeStatusBar, DBaseStatusBar)
|
||||
public:
|
||||
FStrifeStatusBar () : FBaseStatusBar (32)
|
||||
DStrifeStatusBar () : DBaseStatusBar (32)
|
||||
{
|
||||
static const char *sharedLumpNames[] =
|
||||
{
|
||||
|
@ -196,11 +197,11 @@ public:
|
|||
"INVFONG7", "INVFONG8", "INVFONG9"
|
||||
};
|
||||
|
||||
FBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
DBaseStatusBar::Images.Init (sharedLumpNames, NUM_BASESB_IMAGES);
|
||||
DoCommonInit ();
|
||||
}
|
||||
|
||||
~FStrifeStatusBar ()
|
||||
~DStrifeStatusBar ()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -216,7 +217,7 @@ public:
|
|||
|
||||
void Draw (EHudState state)
|
||||
{
|
||||
FBaseStatusBar::Draw (state);
|
||||
DBaseStatusBar::Draw (state);
|
||||
|
||||
if (state == HUD_Fullscreen)
|
||||
{
|
||||
|
@ -235,7 +236,7 @@ public:
|
|||
|
||||
void ShowPop (int popnum)
|
||||
{
|
||||
FBaseStatusBar::ShowPop(popnum);
|
||||
DBaseStatusBar::ShowPop(popnum);
|
||||
if (popnum == CurrentPop)
|
||||
{
|
||||
if (popnum == POP_Keys)
|
||||
|
@ -310,7 +311,7 @@ private:
|
|||
|
||||
void Tick ()
|
||||
{
|
||||
FBaseStatusBar::Tick ();
|
||||
DBaseStatusBar::Tick ();
|
||||
|
||||
if (ItemFlash > 0)
|
||||
{
|
||||
|
@ -845,7 +846,9 @@ private:
|
|||
fixed_t ItemFlash;
|
||||
};
|
||||
|
||||
FBaseStatusBar *CreateStrifeStatusBar ()
|
||||
IMPLEMENT_CLASS(DStrifeStatusBar);
|
||||
|
||||
DBaseStatusBar *CreateStrifeStatusBar ()
|
||||
{
|
||||
return new FStrifeStatusBar;
|
||||
return new DStrifeStatusBar;
|
||||
}
|
||||
|
|
|
@ -525,7 +525,7 @@ FString FGameConfigFile::GetConfigPath (bool tryProg)
|
|||
char *pathval;
|
||||
FString path;
|
||||
|
||||
pathval = Args.CheckValue ("-config");
|
||||
pathval = Args->CheckValue ("-config");
|
||||
if (pathval != NULL)
|
||||
return FString(pathval);
|
||||
|
||||
|
@ -578,7 +578,7 @@ FString FGameConfigFile::GetConfigPath (bool tryProg)
|
|||
|
||||
if (path.IsEmpty())
|
||||
{
|
||||
if (Args.CheckParm ("-cdrom"))
|
||||
if (Args->CheckParm ("-cdrom"))
|
||||
return CDROM_DIR "\\zdoom.ini";
|
||||
|
||||
path = progdir;
|
||||
|
@ -625,7 +625,7 @@ void FGameConfigFile::AddAutoexec (DArgs *list, const char *game)
|
|||
FString path;
|
||||
|
||||
#ifndef unix
|
||||
if (Args.CheckParm ("-cdrom"))
|
||||
if (Args->CheckParm ("-cdrom"))
|
||||
{
|
||||
path = CDROM_DIR "\\autoexec.cfg";
|
||||
}
|
||||
|
|
|
@ -564,7 +564,7 @@ void HostGame (int i)
|
|||
int node;
|
||||
int gotack[MAXNETNODES+1];
|
||||
|
||||
if ((i == Args.NumArgs() - 1) || !(numplayers = atoi (Args.GetArg(i+1))))
|
||||
if ((i == Args->NumArgs() - 1) || !(numplayers = atoi (Args->GetArg(i+1))))
|
||||
{ // No player count specified, assume 2
|
||||
numplayers = 2;
|
||||
}
|
||||
|
@ -742,15 +742,15 @@ bool Guest_WaitForOthers (void *userdata)
|
|||
|
||||
void JoinGame (int i)
|
||||
{
|
||||
if ((i == Args.NumArgs() - 1) ||
|
||||
(Args.GetArg(i+1)[0] == '-') ||
|
||||
(Args.GetArg(i+1)[0] == '+'))
|
||||
if ((i == Args->NumArgs() - 1) ||
|
||||
(Args->GetArg(i+1)[0] == '-') ||
|
||||
(Args->GetArg(i+1)[0] == '+'))
|
||||
I_FatalError ("You need to specify the host machine's address");
|
||||
|
||||
StartNetwork (true);
|
||||
|
||||
// Host is always node 1
|
||||
BuildAddress (&sendaddress[1], Args.GetArg(i+1));
|
||||
BuildAddress (&sendaddress[1], Args->GetArg(i+1));
|
||||
sendplayer[1] = 0;
|
||||
doomcom.numnodes = 2;
|
||||
|
||||
|
@ -789,7 +789,7 @@ void I_InitNetwork (void)
|
|||
memset (&doomcom, 0, sizeof(doomcom));
|
||||
|
||||
// set up for network
|
||||
v = Args.CheckValue ("-dup");
|
||||
v = Args->CheckValue ("-dup");
|
||||
if (v)
|
||||
{
|
||||
doomcom.ticdup = clamp (atoi (v), 1, MAXTICDUP);
|
||||
|
@ -799,12 +799,12 @@ void I_InitNetwork (void)
|
|||
doomcom.ticdup = 1;
|
||||
}
|
||||
|
||||
if (Args.CheckParm ("-extratic"))
|
||||
if (Args->CheckParm ("-extratic"))
|
||||
doomcom.extratics = 1;
|
||||
else
|
||||
doomcom.extratics = 0;
|
||||
|
||||
v = Args.CheckValue ("-port");
|
||||
v = Args->CheckValue ("-port");
|
||||
if (v)
|
||||
{
|
||||
DOOMPORT = atoi (v);
|
||||
|
@ -814,11 +814,11 @@ void I_InitNetwork (void)
|
|||
// parse network game options,
|
||||
// player 1: -host <numplayers>
|
||||
// player x: -join <player 1's address>
|
||||
if ( (i = Args.CheckParm ("-host")) )
|
||||
if ( (i = Args->CheckParm ("-host")) )
|
||||
{
|
||||
HostGame (i);
|
||||
}
|
||||
else if ( (i = Args.CheckParm ("-join")) )
|
||||
else if ( (i = Args->CheckParm ("-join")) )
|
||||
{
|
||||
JoinGame (i);
|
||||
}
|
||||
|
|
|
@ -33,18 +33,8 @@
|
|||
*/
|
||||
|
||||
#include "i_system.h"
|
||||
#include "stats.h"
|
||||
#include <malloc.h>
|
||||
|
||||
ADD_STAT(mem)
|
||||
{
|
||||
FString out;
|
||||
out.Format("Alloc: %uKB", (AllocBytes + 1023) >> 10);
|
||||
return out;
|
||||
}
|
||||
|
||||
size_t AllocBytes;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#define _NORMAL_BLOCK 0
|
||||
#define _malloc_dbg(s,b,f,l) malloc(s)
|
||||
|
@ -62,7 +52,7 @@ void *M_Malloc(size_t size)
|
|||
if (block == NULL)
|
||||
I_FatalError("Could not malloc %u bytes", size);
|
||||
|
||||
AllocBytes += _msize(block);
|
||||
GC::AllocBytes += _msize(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -70,14 +60,14 @@ void *M_Realloc(void *memblock, size_t size)
|
|||
{
|
||||
if (memblock != NULL)
|
||||
{
|
||||
AllocBytes -= _msize(memblock);
|
||||
GC::AllocBytes -= _msize(memblock);
|
||||
}
|
||||
void *block = realloc(memblock, size);
|
||||
if (block == NULL)
|
||||
{
|
||||
I_FatalError("Could not realloc %u bytes", size);
|
||||
}
|
||||
AllocBytes += _msize(block);
|
||||
GC::AllocBytes += _msize(block);
|
||||
return block;
|
||||
}
|
||||
#else
|
||||
|
@ -92,7 +82,7 @@ void *M_Malloc_Dbg(size_t size, const char *file, int lineno)
|
|||
if (block == NULL)
|
||||
I_FatalError("Could not malloc %u bytes", size);
|
||||
|
||||
AllocBytes += _msize(block);
|
||||
GC::AllocBytes += _msize(block);
|
||||
return block;
|
||||
}
|
||||
|
||||
|
@ -100,14 +90,14 @@ void *M_Realloc_Dbg(void *memblock, size_t size, const char *file, int lineno)
|
|||
{
|
||||
if (memblock != NULL)
|
||||
{
|
||||
AllocBytes -= _msize(memblock);
|
||||
GC::AllocBytes -= _msize(memblock);
|
||||
}
|
||||
void *block = _realloc_dbg(memblock, size, _NORMAL_BLOCK, file, lineno);
|
||||
if (block == NULL)
|
||||
{
|
||||
I_FatalError("Could not realloc %u bytes", size);
|
||||
}
|
||||
AllocBytes += _msize(block);
|
||||
GC::AllocBytes += _msize(block);
|
||||
return block;
|
||||
}
|
||||
#endif
|
||||
|
@ -116,7 +106,7 @@ void M_Free (void *block)
|
|||
{
|
||||
if (block != NULL)
|
||||
{
|
||||
AllocBytes -= _msize(block);
|
||||
GC::AllocBytes -= _msize(block);
|
||||
free(block);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,7 +53,4 @@ void *M_Realloc (void *memblock, size_t size);
|
|||
|
||||
void M_Free (void *memblock);
|
||||
|
||||
// Number of bytes currently allocated through M_Malloc/M_Realloc
|
||||
extern size_t AllocBytes;
|
||||
|
||||
#endif //__M_ALLOC_H__
|
||||
|
|
|
@ -71,6 +71,6 @@ private:
|
|||
void CopyArgs (int argc, char **argv);
|
||||
};
|
||||
|
||||
extern DArgs Args;
|
||||
extern DArgs *Args;
|
||||
|
||||
#endif //__M_ARGV_H__
|
||||
|
|
|
@ -26,20 +26,18 @@
|
|||
|
||||
#include "m_bbox.h"
|
||||
|
||||
IMPLEMENT_CLASS (DBoundingBox)
|
||||
|
||||
DBoundingBox::DBoundingBox ()
|
||||
FBoundingBox::FBoundingBox ()
|
||||
{
|
||||
ClearBox ();
|
||||
}
|
||||
|
||||
void DBoundingBox::ClearBox ()
|
||||
void FBoundingBox::ClearBox ()
|
||||
{
|
||||
m_Box[BOXTOP] = m_Box[BOXRIGHT] = FIXED_MIN;
|
||||
m_Box[BOXBOTTOM] = m_Box[BOXLEFT] = FIXED_MAX;
|
||||
}
|
||||
|
||||
void DBoundingBox::AddToBox (fixed_t x, fixed_t y)
|
||||
void FBoundingBox::AddToBox (fixed_t x, fixed_t y)
|
||||
{
|
||||
if (x < m_Box[BOXLEFT])
|
||||
m_Box[BOXLEFT] = x;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#define __M_BBOX_H__
|
||||
|
||||
#include "doomtype.h"
|
||||
#include "dobject.h"
|
||||
#include "m_fixed.h"
|
||||
|
||||
|
||||
|
@ -37,11 +36,10 @@ enum
|
|||
}; // bbox coordinates
|
||||
|
||||
|
||||
class DBoundingBox : public DObject
|
||||
class FBoundingBox
|
||||
{
|
||||
DECLARE_CLASS (DBoundingBox, DObject)
|
||||
public:
|
||||
DBoundingBox();
|
||||
FBoundingBox();
|
||||
|
||||
void ClearBox ();
|
||||
void AddToBox (fixed_t x, fixed_t y);
|
||||
|
|
|
@ -150,9 +150,9 @@ void M_FindResponseFile (void)
|
|||
{
|
||||
int i;
|
||||
|
||||
for (i = 1; i < Args.NumArgs(); i++)
|
||||
for (i = 1; i < Args->NumArgs(); i++)
|
||||
{
|
||||
if (Args.GetArg(i)[0] == '@')
|
||||
if (Args->GetArg(i)[0] == '@')
|
||||
{
|
||||
char **argv;
|
||||
char *file;
|
||||
|
@ -165,14 +165,14 @@ void M_FindResponseFile (void)
|
|||
int index;
|
||||
|
||||
// READ THE RESPONSE FILE INTO MEMORY
|
||||
handle = fopen (Args.GetArg(i) + 1,"rb");
|
||||
handle = fopen (Args->GetArg(i) + 1,"rb");
|
||||
if (!handle)
|
||||
{ // [RH] Make this a warning, not an error.
|
||||
Printf ("No such response file (%s)!", Args.GetArg(i) + 1);
|
||||
Printf ("No such response file (%s)!", Args->GetArg(i) + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
Printf ("Found response file %s!\n", Args.GetArg(i) + 1);
|
||||
Printf ("Found response file %s!\n", Args->GetArg(i) + 1);
|
||||
fseek (handle, 0, SEEK_END);
|
||||
size = ftell (handle);
|
||||
fseek (handle, 0, SEEK_SET);
|
||||
|
@ -182,7 +182,7 @@ void M_FindResponseFile (void)
|
|||
fclose (handle);
|
||||
|
||||
argsize = ParseCommandLine (file, &argcinresp, NULL);
|
||||
argc = argcinresp + Args.NumArgs() - 1;
|
||||
argc = argcinresp + Args->NumArgs() - 1;
|
||||
|
||||
if (argc != 0)
|
||||
{
|
||||
|
@ -191,21 +191,21 @@ void M_FindResponseFile (void)
|
|||
ParseCommandLine (file, NULL, argv+i);
|
||||
|
||||
for (index = 0; index < i; ++index)
|
||||
argv[index] = Args.GetArg (index);
|
||||
argv[index] = Args->GetArg (index);
|
||||
|
||||
for (index = i + 1, i += argcinresp; index < Args.NumArgs (); ++index)
|
||||
argv[i++] = Args.GetArg (index);
|
||||
for (index = i + 1, i += argcinresp; index < Args->NumArgs (); ++index)
|
||||
argv[i++] = Args->GetArg (index);
|
||||
|
||||
DArgs newargs (i, argv);
|
||||
Args = newargs;
|
||||
Args->Destroy();
|
||||
Args = new DArgs(i, argv);
|
||||
}
|
||||
|
||||
delete[] file;
|
||||
|
||||
// DISPLAY ARGS
|
||||
Printf ("%d command-line args:\n", Args.NumArgs ());
|
||||
for (k = 1; k < Args.NumArgs (); k++)
|
||||
Printf ("%s\n", Args.GetArg (k));
|
||||
Printf ("%d command-line args:\n", Args->NumArgs ());
|
||||
for (k = 1; k < Args->NumArgs (); k++)
|
||||
Printf ("%s\n", Args->GetArg (k));
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ void M_ScreenShot (const char *filename)
|
|||
if (filename == NULL || filename[0] == '\0')
|
||||
{
|
||||
#ifndef unix
|
||||
if (Args.CheckParm ("-cdrom"))
|
||||
if (Args->CheckParm ("-cdrom"))
|
||||
{
|
||||
autoname = CDROM_DIR "\\";
|
||||
}
|
||||
|
|
|
@ -106,7 +106,7 @@ struct CallReturn
|
|||
};
|
||||
|
||||
static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module,
|
||||
bool lineSide, int arg0, int arg1, int arg2, int always, bool delay);
|
||||
bool lineSide, int arg0, int arg1, int arg2, int always);
|
||||
|
||||
struct FBehavior::ArrayInfo
|
||||
{
|
||||
|
@ -456,7 +456,7 @@ private:
|
|||
sector_t *Sector;
|
||||
fixed_t WatchD, LastD;
|
||||
int Special, Arg0, Arg1, Arg2, Arg3, Arg4;
|
||||
AActor *Activator;
|
||||
TObjPtr<AActor> Activator;
|
||||
line_t *Line;
|
||||
bool LineSide;
|
||||
bool bCeiling;
|
||||
|
@ -1530,7 +1530,7 @@ void FBehavior::StartTypedScripts (WORD type, AActor *activator, bool always, in
|
|||
if (ptr->Type == type)
|
||||
{
|
||||
DLevelScript *runningScript = P_GetScriptGoing (activator, NULL, ptr->Number,
|
||||
ptr, this, 0, arg1, 0, 0, always, true);
|
||||
ptr, this, 0, arg1, 0, 0, always);
|
||||
if (runNow)
|
||||
{
|
||||
runningScript->RunScript ();
|
||||
|
@ -1557,7 +1557,10 @@ void FBehavior::StaticStopMyScripts (AActor *actor)
|
|||
|
||||
//---- The ACS Interpreter ----//
|
||||
|
||||
IMPLEMENT_CLASS (DACSThinker)
|
||||
IMPLEMENT_POINTY_CLASS (DACSThinker)
|
||||
DECLARE_POINTER(LastScript)
|
||||
DECLARE_POINTER(Scripts)
|
||||
END_POINTERS
|
||||
|
||||
DACSThinker *DACSThinker::ActiveThinker = NULL;
|
||||
|
||||
|
@ -1579,13 +1582,6 @@ DACSThinker::DACSThinker ()
|
|||
|
||||
DACSThinker::~DACSThinker ()
|
||||
{
|
||||
DLevelScript *script = Scripts;
|
||||
while (script)
|
||||
{
|
||||
DLevelScript *next = script->next;
|
||||
script->Destroy ();
|
||||
script = next;
|
||||
}
|
||||
Scripts = NULL;
|
||||
ActiveThinker = NULL;
|
||||
}
|
||||
|
@ -1647,7 +1643,9 @@ void DACSThinker::StopScriptsFor (AActor *actor)
|
|||
}
|
||||
|
||||
IMPLEMENT_POINTY_CLASS (DLevelScript)
|
||||
DECLARE_POINTER (activator)
|
||||
DECLARE_POINTER(next)
|
||||
DECLARE_POINTER(prev)
|
||||
DECLARE_POINTER(activator)
|
||||
END_POINTERS
|
||||
|
||||
void DLevelScript::Serialize (FArchive &arc)
|
||||
|
@ -1713,13 +1711,25 @@ void DLevelScript::Unlink ()
|
|||
DACSThinker *controller = DACSThinker::ActiveThinker;
|
||||
|
||||
if (controller->LastScript == this)
|
||||
{
|
||||
controller->LastScript = prev;
|
||||
GC::WriteBarrier(controller, prev);
|
||||
}
|
||||
if (controller->Scripts == this)
|
||||
{
|
||||
controller->Scripts = next;
|
||||
GC::WriteBarrier(controller, next);
|
||||
}
|
||||
if (prev)
|
||||
{
|
||||
prev->next = next;
|
||||
GC::WriteBarrier(prev, next);
|
||||
}
|
||||
if (next)
|
||||
{
|
||||
next->prev = prev;
|
||||
GC::WriteBarrier(next, prev);
|
||||
}
|
||||
}
|
||||
|
||||
void DLevelScript::Link ()
|
||||
|
@ -1727,12 +1737,19 @@ void DLevelScript::Link ()
|
|||
DACSThinker *controller = DACSThinker::ActiveThinker;
|
||||
|
||||
next = controller->Scripts;
|
||||
GC::WriteBarrier(this, next);
|
||||
if (controller->Scripts)
|
||||
{
|
||||
controller->Scripts->prev = this;
|
||||
GC::WriteBarrier(controller->Scripts, this);
|
||||
}
|
||||
prev = NULL;
|
||||
controller->Scripts = this;
|
||||
GC::WriteBarrier(controller, this);
|
||||
if (controller->LastScript == NULL)
|
||||
{
|
||||
controller->LastScript = this;
|
||||
}
|
||||
}
|
||||
|
||||
void DLevelScript::PutLast ()
|
||||
|
@ -4852,9 +4869,9 @@ int DLevelScript::RunScript ()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (activator->IsKindOf (RUNTIME_CLASS(AScriptedMarine)))
|
||||
if (activator != NULL && activator->IsKindOf (RUNTIME_CLASS(AScriptedMarine)))
|
||||
{
|
||||
static_cast<AScriptedMarine *>(activator)->SetWeapon (
|
||||
barrier_cast<AScriptedMarine *>(activator)->SetWeapon (
|
||||
(AScriptedMarine::EMarineWeapon)STACK(1));
|
||||
}
|
||||
}
|
||||
|
@ -4879,9 +4896,9 @@ int DLevelScript::RunScript ()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (activator->IsKindOf (RUNTIME_CLASS(AScriptedMarine)))
|
||||
if (activator != NULL && activator->IsKindOf (RUNTIME_CLASS(AScriptedMarine)))
|
||||
{
|
||||
static_cast<AScriptedMarine *>(activator)->SetSprite (type);
|
||||
barrier_cast<AScriptedMarine *>(activator)->SetSprite (type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5114,7 +5131,7 @@ int DLevelScript::RunScript ()
|
|||
|
||||
if (STACK(3) == 0)
|
||||
{
|
||||
state = RUNTIME_TYPE(activator)->ActorInfo->FindState (statelist.Size(), &statelist[0], !!STACK(1));
|
||||
state = activator->GetClass()->ActorInfo->FindState (statelist.Size(), &statelist[0], !!STACK(1));
|
||||
if (state != NULL)
|
||||
{
|
||||
activator->SetState (state);
|
||||
|
@ -5133,7 +5150,7 @@ int DLevelScript::RunScript ()
|
|||
|
||||
while ( (actor = iterator.Next ()) )
|
||||
{
|
||||
state = RUNTIME_TYPE(actor)->ActorInfo->FindState (statelist.Size(), &statelist[0], !!STACK(1));
|
||||
state = actor->GetClass()->ActorInfo->FindState (statelist.Size(), &statelist[0], !!STACK(1));
|
||||
if (state != NULL)
|
||||
{
|
||||
actor->SetState (state);
|
||||
|
@ -5309,7 +5326,6 @@ int DLevelScript::RunScript ()
|
|||
Unlink ();
|
||||
if (controller->RunningScripts[script] == this)
|
||||
controller->RunningScripts[script] = NULL;
|
||||
this->Destroy ();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5326,7 +5342,7 @@ int DLevelScript::RunScript ()
|
|||
#undef PushtoStack
|
||||
|
||||
static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module,
|
||||
bool backSide, int arg0, int arg1, int arg2, int always, bool delay)
|
||||
bool backSide, int arg0, int arg1, int arg2, int always)
|
||||
{
|
||||
DACSThinker *controller = DACSThinker::ActiveThinker;
|
||||
|
||||
|
@ -5340,11 +5356,11 @@ static DLevelScript *P_GetScriptGoing (AActor *who, line_t *where, int num, cons
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return new DLevelScript (who, where, num, code, module, backSide, arg0, arg1, arg2, always, delay);
|
||||
return new DLevelScript (who, where, num, code, module, backSide, arg0, arg1, arg2, always);
|
||||
}
|
||||
|
||||
DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module,
|
||||
bool backside, int arg0, int arg1, int arg2, int always, bool delay)
|
||||
bool backside, int arg0, int arg1, int arg2, int always)
|
||||
: activeBehavior (module)
|
||||
{
|
||||
if (DACSThinker::ActiveThinker == NULL)
|
||||
|
@ -5363,17 +5379,12 @@ DLevelScript::DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr
|
|||
backSide = backside;
|
||||
activefont = SmallFont;
|
||||
hudwidth = hudheight = 0;
|
||||
if (delay)
|
||||
{
|
||||
// From Hexen: Give the world some time to set itself up before running open scripts.
|
||||
//script->state = SCRIPT_Delayed;
|
||||
//script->statedata = TICRATE;
|
||||
state = SCRIPT_Running;
|
||||
}
|
||||
else
|
||||
{
|
||||
state = SCRIPT_Running;
|
||||
}
|
||||
state = SCRIPT_Running;
|
||||
// Hexen waited one second before executing any open scripts. I didn't realize
|
||||
// this when I wrote my ACS implementation. Now that I know, it's still best to
|
||||
// run them right away because there are several map properties that can't be
|
||||
// set in an editor. If an open script sets them, it looks dumb if a second
|
||||
// goes by while they're in their default state.
|
||||
|
||||
if (!always)
|
||||
DACSThinker::ActiveThinker->RunningScripts[num] = this;
|
||||
|
@ -5414,7 +5425,7 @@ void P_DoDeferedScripts ()
|
|||
NULL, def->script,
|
||||
scriptdata, module,
|
||||
0, def->arg0, def->arg1, def->arg2,
|
||||
def->type == acsdefered_t::defexealways, true);
|
||||
def->type == acsdefered_t::defexealways);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5487,7 +5498,7 @@ int P_StartScript (AActor *who, line_t *where, int script, char *map, bool backS
|
|||
}
|
||||
}
|
||||
DLevelScript *runningScript = P_GetScriptGoing (who, where, script,
|
||||
scriptdata, module, backSide, arg0, arg1, arg2, always, false);
|
||||
scriptdata, module, backSide, arg0, arg1, arg2, always);
|
||||
if (runningScript != NULL)
|
||||
{
|
||||
if (wantResultCode)
|
||||
|
|
|
@ -638,7 +638,7 @@ public:
|
|||
|
||||
|
||||
DLevelScript (AActor *who, line_t *where, int num, const ScriptPtr *code, FBehavior *module,
|
||||
bool backSide, int arg0, int arg1, int arg2, int always, bool delay);
|
||||
bool backSide, int arg0, int arg1, int arg2, int always);
|
||||
~DLevelScript ();
|
||||
|
||||
void Serialize (FArchive &arc);
|
||||
|
@ -655,7 +655,7 @@ protected:
|
|||
int *pc;
|
||||
EScriptState state;
|
||||
int statedata;
|
||||
AActor *activator;
|
||||
TObjPtr<AActor> activator;
|
||||
line_t *activationline;
|
||||
bool backSide;
|
||||
FFont *activefont;
|
||||
|
@ -701,6 +701,7 @@ inline FArchive &operator<< (FArchive &arc, DLevelScript::EScriptState &state)
|
|||
class DACSThinker : public DThinker
|
||||
{
|
||||
DECLARE_CLASS (DACSThinker, DThinker)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DACSThinker ();
|
||||
~DACSThinker ();
|
||||
|
|
|
@ -69,7 +69,7 @@ void DDoor::Tick ()
|
|||
if (m_Sector->floorplane.d != m_OldFloorDist)
|
||||
{
|
||||
if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) ||
|
||||
!((DPlat*)m_Sector->floordata)->IsLift())
|
||||
!(barrier_cast<DPlat*>(m_Sector->floordata))->IsLift())
|
||||
{
|
||||
m_OldFloorDist = m_Sector->floorplane.d;
|
||||
m_BotDist = m_Sector->ceilingplane.PointToDist (m_BotSpot,
|
||||
|
@ -340,7 +340,7 @@ DDoor::DDoor (sector_t *sec, EVlDoor type, fixed_t speed, int delay, int lightTa
|
|||
}
|
||||
|
||||
if (!m_Sector->floordata || !m_Sector->floordata->IsKindOf(RUNTIME_CLASS(DPlat)) ||
|
||||
!((DPlat*)m_Sector->floordata)->IsLift())
|
||||
!(barrier_cast<DPlat*>(m_Sector->floordata))->IsLift())
|
||||
{
|
||||
height = sec->FindHighestFloorPoint (&m_BotSpot);
|
||||
m_BotDist = sec->ceilingplane.PointToDist (m_BotSpot, height);
|
||||
|
@ -384,7 +384,7 @@ bool EV_DoDoor (DDoor::EVlDoor type, line_t *line, AActor *thing,
|
|||
{
|
||||
if (sec->ceilingdata->IsKindOf (RUNTIME_CLASS(DDoor)))
|
||||
{
|
||||
DDoor *door = static_cast<DDoor *>(sec->ceilingdata);
|
||||
DDoor *door = barrier_cast<DDoor *>(sec->ceilingdata);
|
||||
|
||||
// ONLY FOR "RAISE" DOORS, NOT "OPEN"s
|
||||
if (door->m_Type == DDoor::doorRaise && type == DDoor::doorRaise)
|
||||
|
@ -761,7 +761,7 @@ bool EV_SlidingDoor (line_t *line, AActor *actor, int tag, int speed, int delay)
|
|||
|
||||
if (sec->ceilingdata->IsA (RUNTIME_CLASS(DAnimatedDoor)))
|
||||
{
|
||||
DAnimatedDoor *door = static_cast<DAnimatedDoor *> (sec->ceilingdata);
|
||||
DAnimatedDoor *door = barrier_cast<DAnimatedDoor *>(sec->ceilingdata);
|
||||
if (door->m_Status == DAnimatedDoor::Waiting)
|
||||
{
|
||||
return door->StartClosing();
|
||||
|
|
|
@ -1133,22 +1133,22 @@ bool P_LookForTID (AActor *actor, INTBOOL allaround)
|
|||
actor->reactiontime = 0;
|
||||
|
||||
actor->target = other;
|
||||
actor->LastLook.Actor = other;
|
||||
actor->LastLookActor = other;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The actor's TID could change because of death or because of
|
||||
// Thing_ChangeTID. If it's not what we expect, then don't use
|
||||
// it as a base for the iterator.
|
||||
if (actor->LastLook.Actor != NULL &&
|
||||
actor->LastLook.Actor->tid != actor->TIDtoHate)
|
||||
if (actor->LastLookActor != NULL &&
|
||||
actor->LastLookActor->tid != actor->TIDtoHate)
|
||||
{
|
||||
actor->LastLook.Actor = NULL;
|
||||
actor->LastLookActor = NULL;
|
||||
}
|
||||
|
||||
FActorIterator iterator (actor->TIDtoHate, actor->LastLook.Actor);
|
||||
FActorIterator iterator (actor->TIDtoHate, actor->LastLookActor);
|
||||
int c = (pr_look3() & 31) + 7; // Look for between 7 and 38 hatees at a time
|
||||
while ((other = iterator.Next()) != actor->LastLook.Actor)
|
||||
while ((other = iterator.Next()) != actor->LastLookActor)
|
||||
{
|
||||
if (other == NULL)
|
||||
{
|
||||
|
@ -1206,10 +1206,10 @@ bool P_LookForTID (AActor *actor, INTBOOL allaround)
|
|||
actor->reactiontime = 0;
|
||||
|
||||
actor->target = other;
|
||||
actor->LastLook.Actor = other;
|
||||
actor->LastLookActor = other;
|
||||
return true;
|
||||
}
|
||||
actor->LastLook.Actor = other;
|
||||
actor->LastLookActor = other;
|
||||
if (actor->target == NULL)
|
||||
{
|
||||
// [RH] use goal as target
|
||||
|
@ -1436,7 +1436,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround)
|
|||
}
|
||||
else
|
||||
{
|
||||
pnum = actor->LastLook.PlayerNumber;
|
||||
pnum = actor->LastLookPlayerNumber;
|
||||
}
|
||||
stop = (pnum - 1) & (MAXPLAYERS-1);
|
||||
|
||||
|
@ -1448,7 +1448,7 @@ bool P_LookForPlayers (AActor *actor, INTBOOL allaround)
|
|||
|
||||
if (actor->TIDtoHate == 0)
|
||||
{
|
||||
actor->LastLook.PlayerNumber = pnum;
|
||||
actor->LastLookPlayerNumber = pnum;
|
||||
}
|
||||
|
||||
if (++c == MAXPLAYERS-1 || pnum == stop)
|
||||
|
|
|
@ -346,22 +346,22 @@ bool P_NewLookTID (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxdist,
|
|||
actor->reactiontime = 0;
|
||||
|
||||
actor->target = other;
|
||||
actor->LastLook.Actor = other;
|
||||
actor->LastLookActor = other;
|
||||
return true;
|
||||
}
|
||||
|
||||
// The actor's TID could change because of death or because of
|
||||
// Thing_ChangeTID. If it's not what we expect, then don't use
|
||||
// it as a base for the iterator.
|
||||
if (actor->LastLook.Actor != NULL &&
|
||||
actor->LastLook.Actor->tid != actor->TIDtoHate)
|
||||
if (actor->LastLookActor != NULL &&
|
||||
actor->LastLookActor->tid != actor->TIDtoHate)
|
||||
{
|
||||
actor->LastLook.Actor = NULL;
|
||||
actor->LastLookActor = NULL;
|
||||
}
|
||||
|
||||
FActorIterator iterator (actor->TIDtoHate, actor->LastLook.Actor);
|
||||
FActorIterator iterator (actor->TIDtoHate, actor->LastLookActor);
|
||||
int c = (pr_look3() & 31) + 7; // Look for between 7 and 38 hatees at a time
|
||||
while ((other = iterator.Next()) != actor->LastLook.Actor)
|
||||
while ((other = iterator.Next()) != actor->LastLookActor)
|
||||
{
|
||||
if (other == NULL)
|
||||
{
|
||||
|
@ -448,10 +448,10 @@ bool P_NewLookTID (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxdist,
|
|||
actor->reactiontime = 0;
|
||||
|
||||
actor->target = other;
|
||||
actor->LastLook.Actor = other;
|
||||
actor->LastLookActor = other;
|
||||
return true;
|
||||
}
|
||||
actor->LastLook.Actor = other;
|
||||
actor->LastLookActor = other;
|
||||
if (actor->target == NULL)
|
||||
{
|
||||
// [RH] use goal as target
|
||||
|
@ -562,7 +562,7 @@ bool P_NewLookPlayers (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxd
|
|||
}
|
||||
else
|
||||
{
|
||||
pnum = actor->LastLook.PlayerNumber;
|
||||
pnum = actor->LastLookPlayerNumber;
|
||||
}
|
||||
stop = (pnum - 1) & (MAXPLAYERS-1);
|
||||
|
||||
|
@ -574,7 +574,7 @@ bool P_NewLookPlayers (AActor *actor, angle_t fov, fixed_t mindist, fixed_t maxd
|
|||
|
||||
if (actor->TIDtoHate == 0)
|
||||
{
|
||||
actor->LastLook.PlayerNumber = pnum;
|
||||
actor->LastLookPlayerNumber = pnum;
|
||||
}
|
||||
|
||||
if (++c == MAXPLAYERS-1 || pnum == stop)
|
||||
|
|
|
@ -600,7 +600,7 @@ bool EV_FloorCrushStop (int tag)
|
|||
sector_t *sec = sectors + secnum;
|
||||
|
||||
if (sec->floordata && sec->floordata->IsKindOf (RUNTIME_CLASS(DFloor)) &&
|
||||
static_cast<DFloor *>(sec->floordata)->m_Type == DFloor::floorRaiseAndCrush)
|
||||
barrier_cast<DFloor *>(sec->floordata)->m_Type == DFloor::floorRaiseAndCrush)
|
||||
{
|
||||
SN_StopSequence (sec);
|
||||
sec->floordata->Destroy ();
|
||||
|
|
|
@ -932,7 +932,7 @@ FUNC(LS_Thing_ChangeTID)
|
|||
{
|
||||
if (arg0 == 0)
|
||||
{
|
||||
if (it != NULL && !(it->ObjectFlags & OF_MassDestruction))
|
||||
if (it != NULL && !(it->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
it->RemoveFromHash ();
|
||||
it->tid = arg1;
|
||||
|
@ -950,7 +950,7 @@ FUNC(LS_Thing_ChangeTID)
|
|||
actor = next;
|
||||
next = iterator.Next ();
|
||||
|
||||
if (!(actor->ObjectFlags & OF_MassDestruction))
|
||||
if (!(actor->ObjectFlags & OF_EuthanizeMe))
|
||||
{
|
||||
actor->RemoveFromHash ();
|
||||
actor->tid = arg1;
|
||||
|
@ -1227,7 +1227,7 @@ FUNC(LS_Thing_Hate)
|
|||
if (arg2 != 0)
|
||||
{
|
||||
hater->TIDtoHate = arg1;
|
||||
hater->LastLook.Actor = NULL;
|
||||
hater->LastLookActor = NULL;
|
||||
|
||||
// If the TID to hate is 0, then don't forget the target and
|
||||
// lastenemy fields.
|
||||
|
|
|
@ -167,7 +167,7 @@ IMPLEMENT_POINTY_CLASS (AActor)
|
|||
DECLARE_POINTER (lastenemy)
|
||||
DECLARE_POINTER (tracer)
|
||||
DECLARE_POINTER (goal)
|
||||
DECLARE_POINTER (LastLook) // This is actually a union
|
||||
DECLARE_POINTER (LastLookActor)
|
||||
DECLARE_POINTER (Inventory)
|
||||
DECLARE_POINTER (LastHeard)
|
||||
DECLARE_POINTER (master)
|
||||
|
@ -236,11 +236,13 @@ void AActor::Serialize (FArchive &arc)
|
|||
arc << TIDtoHate;
|
||||
if (TIDtoHate == 0)
|
||||
{
|
||||
arc << LastLook.PlayerNumber;
|
||||
arc << LastLookPlayerNumber;
|
||||
LastLookActor = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
arc << LastLook.Actor;
|
||||
arc << LastLookActor;
|
||||
LastLookPlayerNumber = -1;
|
||||
}
|
||||
arc << effects
|
||||
<< alpha
|
||||
|
@ -563,7 +565,8 @@ bool AActor::SetState (FState *newstate)
|
|||
newstate->GetAction() (this);
|
||||
|
||||
// Check whether the called action function resulted in destroying the actor
|
||||
if (ObjectFlags & OF_MassDestruction) return false;
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
return false;
|
||||
}
|
||||
newstate = newstate->GetNextState();
|
||||
} while (tics == 0);
|
||||
|
@ -708,7 +711,7 @@ void AActor::DestroyAllInventory ()
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
AInventory *AActor::FirstInv () const
|
||||
AInventory *AActor::FirstInv ()
|
||||
{
|
||||
if (Inventory == NULL)
|
||||
{
|
||||
|
@ -797,7 +800,7 @@ AInventory *AActor::DropInventory (AInventory *item)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
AInventory *AActor::FindInventory (const PClass *type) const
|
||||
AInventory *AActor::FindInventory (const PClass *type)
|
||||
{
|
||||
AInventory *item;
|
||||
|
||||
|
@ -814,7 +817,7 @@ AInventory *AActor::FindInventory (const PClass *type) const
|
|||
return item;
|
||||
}
|
||||
|
||||
AInventory *AActor::FindInventory (FName type) const
|
||||
AInventory *AActor::FindInventory (FName type)
|
||||
{
|
||||
return FindInventory(PClass::FindClass(type));
|
||||
}
|
||||
|
@ -874,11 +877,12 @@ bool AActor::GiveAmmo (const PClass *type, int amount)
|
|||
//
|
||||
//============================================================================
|
||||
|
||||
void AActor::CopyFriendliness (const AActor *other, bool changeTarget)
|
||||
void AActor::CopyFriendliness (AActor *other, bool changeTarget)
|
||||
{
|
||||
level.total_monsters -= CountsAsKill();
|
||||
TIDtoHate = other->TIDtoHate;
|
||||
LastLook = other->LastLook;
|
||||
LastLookActor = other->LastLookActor;
|
||||
LastLookPlayerNumber = other->LastLookPlayerNumber;
|
||||
flags = (flags & ~MF_FRIENDLY) | (other->flags & MF_FRIENDLY);
|
||||
flags3 = (flags3 & ~(MF3_NOSIGHTCHECK | MF3_HUNTPLAYERS)) | (other->flags3 & (MF3_NOSIGHTCHECK | MF3_HUNTPLAYERS));
|
||||
flags4 = (flags4 & ~MF4_NOHATEPLAYERS) | (other->flags4 & MF4_NOHATEPLAYERS);
|
||||
|
@ -1052,7 +1056,7 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target)
|
|||
if (nextstate == NULL) nextstate = mo->FindState(NAME_Death);
|
||||
mo->SetState (nextstate);
|
||||
|
||||
if (mo->ObjectFlags & OF_MassDestruction)
|
||||
if (mo->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2865,7 +2869,7 @@ void AActor::Tick ()
|
|||
// Handle X and Y momemtums
|
||||
BlockingMobj = NULL;
|
||||
P_XYMovement (this, cummx, cummy);
|
||||
if (ObjectFlags & OF_MassDestruction)
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
{ // actor was destroyed
|
||||
return;
|
||||
}
|
||||
|
@ -2923,7 +2927,7 @@ void AActor::Tick ()
|
|||
P_ZMovement (this);
|
||||
}
|
||||
|
||||
if (ObjectFlags & OF_MassDestruction)
|
||||
if (ObjectFlags & OF_EuthanizeMe)
|
||||
return; // actor was destroyed
|
||||
}
|
||||
else if (z <= floorz)
|
||||
|
@ -3163,7 +3167,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
|
|||
|
||||
if (actor->flags3 & MF3_ISMONSTER)
|
||||
{
|
||||
actor->LastLook.PlayerNumber = rng() % MAXPLAYERS;
|
||||
actor->LastLookPlayerNumber = rng() % MAXPLAYERS;
|
||||
actor->TIDtoHate = 0;
|
||||
}
|
||||
|
||||
|
@ -3251,7 +3255,7 @@ AActor *AActor::StaticSpawn (const PClass *type, fixed_t ix, fixed_t iy, fixed_t
|
|||
if (!SpawningMapThing)
|
||||
{
|
||||
actor->BeginPlay ();
|
||||
if (actor->ObjectFlags & OF_MassDestruction)
|
||||
if (actor->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
@ -3990,7 +3994,7 @@ void P_SpawnMapThing (mapthing2_t *mthing, int position)
|
|||
|
||||
mobj->angle = (DWORD)((mthing->angle * UCONST64(0x100000000)) / 360);
|
||||
mobj->BeginPlay ();
|
||||
if (mobj->ObjectFlags & OF_MassDestruction)
|
||||
if (mobj->ObjectFlags & OF_EuthanizeMe)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2689,7 +2689,7 @@ void P_LoadBlockMap (MapData * map)
|
|||
|
||||
if (ForceNodeBuild || genblockmap ||
|
||||
count/2 >= 0x10000 || count == 0 ||
|
||||
Args.CheckParm("-blockmap")
|
||||
Args->CheckParm("-blockmap")
|
||||
)
|
||||
{
|
||||
DPrintf ("Generating BLOCKMAP\n");
|
||||
|
@ -2757,7 +2757,7 @@ static void P_GroupLines (bool buildmap)
|
|||
int totallights;
|
||||
line_t* li;
|
||||
sector_t* sector;
|
||||
DBoundingBox bbox;
|
||||
FBoundingBox bbox;
|
||||
bool flaggedNoFronts = false;
|
||||
unsigned int ii, jj;
|
||||
|
||||
|
@ -3765,7 +3765,7 @@ static void P_Shutdown ()
|
|||
P_FreeExtraLevelData ();
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
delete StatusBar;
|
||||
StatusBar->Destroy();
|
||||
StatusBar = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ public:
|
|||
|
||||
protected:
|
||||
EPusher m_Type;
|
||||
AActor *m_Source; // Point source if point pusher
|
||||
TObjPtr<AActor> m_Source;// Point source if point pusher
|
||||
int m_Xmag; // X Strength
|
||||
int m_Ymag; // Y Strength
|
||||
int m_Magnitude; // Vector strength for point pusher
|
||||
|
|
|
@ -316,6 +316,26 @@ void player_s::FixPointers (const DObject *old, DObject *rep)
|
|||
if (PendingWeapon == old) PendingWeapon = static_cast<AWeapon *>(rep);
|
||||
}
|
||||
|
||||
size_t player_s::PropagateMark()
|
||||
{
|
||||
GC::Mark(mo);
|
||||
GC::Mark(poisoner);
|
||||
GC::Mark(attacker);
|
||||
GC::Mark(camera);
|
||||
GC::Mark(dest);
|
||||
GC::Mark(prev);
|
||||
GC::Mark(enemy);
|
||||
GC::Mark(missile);
|
||||
GC::Mark(mate);
|
||||
GC::Mark(last_mate);
|
||||
GC::Mark(ReadyWeapon);
|
||||
if (PendingWeapon != WP_NOCHANGE)
|
||||
{
|
||||
GC::Mark(PendingWeapon);
|
||||
}
|
||||
return sizeof(*this);
|
||||
}
|
||||
|
||||
void player_s::SetLogNumber (int num)
|
||||
{
|
||||
char lumpname[16];
|
||||
|
|
12
src/r_defs.h
12
src/r_defs.h
|
@ -306,7 +306,7 @@ struct sector_t
|
|||
int floorpic, ceilingpic;
|
||||
BYTE lightlevel;
|
||||
|
||||
AActor * SoundTarget;
|
||||
TObjPtr<AActor> SoundTarget;
|
||||
BYTE soundtraversed; // 0 = untraversed, 1,2 = sndlines -1
|
||||
|
||||
short special;
|
||||
|
@ -326,9 +326,9 @@ struct sector_t
|
|||
fixed_t friction, movefactor;
|
||||
|
||||
// thinker_t for reversable actions
|
||||
DSectorEffect *floordata; // jff 2/22/98 make thinkers on
|
||||
DSectorEffect *ceilingdata; // floors, ceilings, lighting,
|
||||
DSectorEffect *lightingdata; // independent of one another
|
||||
TObjPtr<DSectorEffect> floordata; // jff 2/22/98 make thinkers on
|
||||
TObjPtr<DSectorEffect> ceilingdata; // floors, ceilings, lighting,
|
||||
TObjPtr<DSectorEffect> lightingdata; // independent of one another
|
||||
|
||||
// jff 2/26/98 lockout machinery for stairbuilding
|
||||
SBYTE stairlock; // -2 on first locked -1 after thinker done 0 normally
|
||||
|
@ -360,11 +360,11 @@ struct sector_t
|
|||
// flexible in a Bloody way. SecActTarget forms a list of actors
|
||||
// joined by their tracer fields. When a potential sector action
|
||||
// occurs, SecActTarget's TriggerAction method is called.
|
||||
ASectorAction *SecActTarget;
|
||||
TObjPtr<ASectorAction> SecActTarget;
|
||||
|
||||
// [RH] The sky box to render for this sector. NULL means use a
|
||||
// regular sky.
|
||||
ASkyViewpoint *FloorSkyBox, *CeilingSkyBox;
|
||||
TObjPtr<ASkyViewpoint> FloorSkyBox, CeilingSkyBox;
|
||||
|
||||
// Planes that partition this sector into different light zones.
|
||||
FExtraLight *ExtraLights;
|
||||
|
|
|
@ -2226,7 +2226,7 @@ void R_InitParticles ()
|
|||
{
|
||||
char *i;
|
||||
|
||||
if ((i = Args.CheckValue ("-numparticles")))
|
||||
if ((i = Args->CheckValue ("-numparticles")))
|
||||
NumParticles = atoi (i);
|
||||
// [BC] Use r_maxparticles now.
|
||||
else
|
||||
|
|
|
@ -100,7 +100,7 @@ class DSeqActorNode : public DSeqNode
|
|||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
DSeqActorNode (AActor *actor, int sequence, int modenum);
|
||||
~DSeqActorNode ();
|
||||
void Destroy ();
|
||||
void Serialize (FArchive &arc);
|
||||
void MakeSound () { S_SoundID (m_Actor, CHAN_BODY, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); }
|
||||
void MakeLoopedSound () { S_LoopedSoundID (m_Actor, CHAN_BODY, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); }
|
||||
|
@ -109,7 +109,7 @@ public:
|
|||
DSeqNode *SpawnChild (int seqnum) { return SN_StartSequence (m_Actor, seqnum, SEQ_NOTRANS, m_ModeNum, true); }
|
||||
private:
|
||||
DSeqActorNode () {}
|
||||
AActor *m_Actor;
|
||||
TObjPtr<AActor> m_Actor;
|
||||
};
|
||||
|
||||
class DSeqPolyNode : public DSeqNode
|
||||
|
@ -117,7 +117,7 @@ class DSeqPolyNode : public DSeqNode
|
|||
DECLARE_CLASS (DSeqPolyNode, DSeqNode)
|
||||
public:
|
||||
DSeqPolyNode (polyobj_t *poly, int sequence, int modenum);
|
||||
~DSeqPolyNode ();
|
||||
void Destroy ();
|
||||
void Serialize (FArchive &arc);
|
||||
void MakeSound () { S_SoundID (&m_Poly->startSpot[0], CHAN_BODY, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); }
|
||||
void MakeLoopedSound () { S_LoopedSoundID (&m_Poly->startSpot[0], CHAN_BODY, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); }
|
||||
|
@ -134,7 +134,7 @@ class DSeqSectorNode : public DSeqNode
|
|||
DECLARE_CLASS (DSeqSectorNode, DSeqNode)
|
||||
public:
|
||||
DSeqSectorNode (sector_t *sec, int sequence, int modenum);
|
||||
~DSeqSectorNode ();
|
||||
void Destroy ();
|
||||
void Serialize (FArchive &arc);
|
||||
void MakeSound () { S_SoundID (&m_Sector->soundorg[0], CHAN_BODY, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); Looping = false; }
|
||||
void MakeLoopedSound () { S_LoopedSoundID (&m_Sector->soundorg[0], CHAN_BODY, m_CurrentSoundID, clamp(m_Volume, 0.f, 1.f), m_Atten); Looping = true; }
|
||||
|
@ -242,7 +242,12 @@ void DSeqNode::SerializeSequences (FArchive &arc)
|
|||
arc << SequenceListHead;
|
||||
}
|
||||
|
||||
IMPLEMENT_CLASS (DSeqNode)
|
||||
IMPLEMENT_POINTY_CLASS (DSeqNode)
|
||||
DECLARE_POINTER(m_ChildSeqNode)
|
||||
DECLARE_POINTER(m_ParentSeqNode)
|
||||
DECLARE_POINTER(m_Next)
|
||||
DECLARE_POINTER(m_Prev)
|
||||
END_POINTERS
|
||||
|
||||
DSeqNode::DSeqNode ()
|
||||
: m_SequenceChoices(0)
|
||||
|
@ -331,6 +336,19 @@ void DSeqNode::Destroy()
|
|||
m_ParentSeqNode->m_ChildSeqNode = NULL;
|
||||
m_ParentSeqNode = NULL;
|
||||
}
|
||||
if (SequenceListHead == this)
|
||||
SequenceListHead = m_Next;
|
||||
if (m_Prev)
|
||||
{
|
||||
m_Prev->m_Next = m_Next;
|
||||
GC::WriteBarrier(m_Prev, m_Next);
|
||||
}
|
||||
if (m_Next)
|
||||
{
|
||||
m_Next->m_Prev = m_Prev;
|
||||
GC::WriteBarrier(m_Next, m_Prev);
|
||||
}
|
||||
ActiveSequences--;
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
|
@ -676,17 +694,6 @@ static void AddSequence (int curseq, FName seqname, FName slot, int stopsound, c
|
|||
Sequences[curseq]->Script[ScriptTemp.Size()] = MakeCommand(SS_CMD_END, 0);
|
||||
}
|
||||
|
||||
DSeqNode::~DSeqNode ()
|
||||
{
|
||||
if (SequenceListHead == this)
|
||||
SequenceListHead = m_Next;
|
||||
if (m_Prev)
|
||||
m_Prev->m_Next = m_Next;
|
||||
if (m_Next)
|
||||
m_Next->m_Prev = m_Prev;
|
||||
ActiveSequences--;
|
||||
}
|
||||
|
||||
DSeqNode::DSeqNode (int sequence, int modenum)
|
||||
: m_ModeNum(modenum), m_SequenceChoices(0)
|
||||
{
|
||||
|
@ -912,28 +919,31 @@ void SN_DoStop (void *source)
|
|||
}
|
||||
}
|
||||
|
||||
DSeqActorNode::~DSeqActorNode ()
|
||||
void DSeqActorNode::Destroy ()
|
||||
{
|
||||
if (m_StopSound >= 0)
|
||||
S_StopSound (m_Actor, CHAN_BODY);
|
||||
if (m_StopSound >= 1)
|
||||
S_SoundID (m_Actor, CHAN_BODY, m_StopSound, m_Volume, m_Atten);
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
DSeqSectorNode::~DSeqSectorNode ()
|
||||
void DSeqSectorNode::Destroy ()
|
||||
{
|
||||
if (m_StopSound >= 0)
|
||||
S_StopSound (m_Sector->soundorg, CHAN_BODY);
|
||||
if (m_StopSound >= 1)
|
||||
S_SoundID (m_Sector->soundorg, CHAN_BODY, m_StopSound, m_Volume, m_Atten);
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
DSeqPolyNode::~DSeqPolyNode ()
|
||||
void DSeqPolyNode::Destroy ()
|
||||
{
|
||||
if (m_StopSound >= 0)
|
||||
S_StopSound (m_Poly->startSpot, CHAN_BODY);
|
||||
if (m_StopSound >= 1)
|
||||
S_SoundID (m_Poly->startSpot, CHAN_BODY, m_StopSound, m_Volume, m_Atten);
|
||||
Super::Destroy();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
@ -1026,6 +1036,7 @@ void DSeqNode::Tick ()
|
|||
{
|
||||
int choice = pr_sndseq() % m_SequenceChoices.Size();
|
||||
m_ChildSeqNode = SpawnChild (m_SequenceChoices[choice]);
|
||||
GC::WriteBarrier(this, m_ChildSeqNode);
|
||||
if (m_ChildSeqNode == NULL)
|
||||
{ // Failed, so skip to next instruction.
|
||||
m_SequencePtr++;
|
||||
|
|
|
@ -20,8 +20,8 @@ struct sector_t;
|
|||
class DSeqNode : public DObject
|
||||
{
|
||||
DECLARE_CLASS (DSeqNode, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
public:
|
||||
virtual ~DSeqNode ();
|
||||
void Serialize (FArchive &arc);
|
||||
void StopAndDestroy ();
|
||||
void Destroy ();
|
||||
|
@ -56,8 +56,8 @@ protected:
|
|||
int m_ModeNum;
|
||||
|
||||
TArray<int> m_SequenceChoices;
|
||||
DSeqNode *m_ChildSeqNode;
|
||||
DSeqNode *m_ParentSeqNode;
|
||||
TObjPtr<DSeqNode> m_ChildSeqNode;
|
||||
TObjPtr<DSeqNode> m_ParentSeqNode;
|
||||
|
||||
private:
|
||||
static DSeqNode *SequenceListHead;
|
||||
|
|
|
@ -52,7 +52,11 @@ IVideo *Video;
|
|||
void I_ShutdownGraphics ()
|
||||
{
|
||||
if (screen)
|
||||
delete screen, screen = NULL;
|
||||
{
|
||||
screen->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete screen;
|
||||
screen = NULL;
|
||||
}
|
||||
if (Video)
|
||||
delete Video, Video = NULL;
|
||||
}
|
||||
|
@ -61,7 +65,7 @@ void I_InitGraphics ()
|
|||
{
|
||||
UCVarValue val;
|
||||
|
||||
val.Bool = !!Args.CheckParm ("-devparm");
|
||||
val.Bool = !!Args->CheckParm ("-devparm");
|
||||
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
||||
|
||||
Video = new SDLVideo (0);
|
||||
|
|
|
@ -75,7 +75,7 @@ extern "C" int cc_install_handlers(int, int*, const char*, int(*)(char*, char*))
|
|||
bool GtkAvailable;
|
||||
|
||||
// The command line arguments.
|
||||
DArgs Args;
|
||||
DArgs *Args;
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
|
@ -137,9 +137,9 @@ static int DoomSpecificInfo (char *buffer, char *end)
|
|||
p = 0;
|
||||
p += snprintf (buffer+p, size-p, GAMENAME" version " DOTVERSIONSTR " (" __DATE__ ")\n");
|
||||
p += snprintf (buffer+p, size-p, "\nCommand line:");
|
||||
for (i = 0; i < Args.NumArgs(); ++i)
|
||||
for (i = 0; i < Args->NumArgs(); ++i)
|
||||
{
|
||||
p += snprintf (buffer+p, size-p, " %s", Args.GetArg(i));
|
||||
p += snprintf (buffer+p, size-p, " %s", Args->GetArg(i));
|
||||
}
|
||||
p += snprintf (buffer+p, size-p, "\n");
|
||||
|
||||
|
@ -208,7 +208,7 @@ int main (int argc, char **argv)
|
|||
|
||||
try
|
||||
{
|
||||
Args.SetArgs (argc, argv);
|
||||
Args = new DArgs(argc, argv);
|
||||
|
||||
/*
|
||||
killough 1/98:
|
||||
|
|
|
@ -136,7 +136,7 @@ void I_InitMusic (void)
|
|||
|
||||
snd_musicvolume.Callback ();
|
||||
|
||||
nomusic = !!Args.CheckParm("-nomusic") || !!Args.CheckParm("-nosound");
|
||||
nomusic = !!Args->CheckParm("-nomusic") || !!Args->CheckParm("-nosound");
|
||||
|
||||
#ifdef _WIN32
|
||||
I_InitMusicWin32 ();
|
||||
|
|
|
@ -151,7 +151,7 @@ CUSTOM_CVAR (Float, snd_sfxvolume, 0.5f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG|CVAR_NOI
|
|||
void I_InitSound ()
|
||||
{
|
||||
/* Get command line options: */
|
||||
bool nosound = !!Args.CheckParm ("-nosfx") || !!Args.CheckParm ("-nosound");
|
||||
bool nosound = !!Args->CheckParm ("-nosfx") || !!Args->CheckParm ("-nosound");
|
||||
|
||||
if (nosound)
|
||||
{
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "st_stuff.h"
|
||||
#include "c_dispatch.h"
|
||||
#include "m_swap.h"
|
||||
#include "sbar.h"
|
||||
|
||||
FStat *FStat::FirstStat;
|
||||
|
||||
|
@ -84,7 +85,7 @@ void FStat::ToggleStat (const char *name)
|
|||
void FStat::ToggleStat ()
|
||||
{
|
||||
m_Active = !m_Active;
|
||||
SB_state = screen->GetPageCount ();
|
||||
SB_state = StatusBar == NULL ? 0 : screen->GetPageCount ();
|
||||
}
|
||||
|
||||
void FStat::PrintStat ()
|
||||
|
|
|
@ -357,7 +357,7 @@ void DCanvas::Dim (PalEntry color)
|
|||
if (color.a != 0)
|
||||
{
|
||||
float dim[4] = { color.r/255.f, color.g/255.f, color.b/255.f, color.a/255.f };
|
||||
FBaseStatusBar::AddBlend (dimmer.r/255.f, dimmer.g/255.f, dimmer.b/255.f, amount, dim);
|
||||
DBaseStatusBar::AddBlend (dimmer.r/255.f, dimmer.g/255.f, dimmer.b/255.f, amount, dim);
|
||||
dimmer = PalEntry (BYTE(dim[0]*255), BYTE(dim[1]*255), BYTE(dim[2]*255));
|
||||
amount = dim[3];
|
||||
}
|
||||
|
@ -1390,6 +1390,7 @@ void DFrameBuffer::WriteSavePic (player_t *player, FILE *file, int width, int he
|
|||
GetFlashedPalette (palette);
|
||||
M_CreatePNG (file, pic->GetBuffer(), palette, SS_PAL, width, height, pic->GetPitch());
|
||||
pic->Unlock ();
|
||||
pic->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete pic;
|
||||
}
|
||||
|
||||
|
@ -1426,6 +1427,7 @@ bool V_DoModeSetup (int width, int height, int bits)
|
|||
}
|
||||
|
||||
screen = buff;
|
||||
GC::WriteBarrier(screen);
|
||||
screen->SetFont (SmallFont);
|
||||
screen->SetGamma (Gamma);
|
||||
|
||||
|
@ -1594,13 +1596,13 @@ void V_Init (void)
|
|||
|
||||
width = height = bits = 0;
|
||||
|
||||
if ( (i = Args.CheckValue ("-width")) )
|
||||
if ( (i = Args->CheckValue ("-width")) )
|
||||
width = atoi (i);
|
||||
|
||||
if ( (i = Args.CheckValue ("-height")) )
|
||||
if ( (i = Args->CheckValue ("-height")) )
|
||||
height = atoi (i);
|
||||
|
||||
if ( (i = Args.CheckValue ("-bits")) )
|
||||
if ( (i = Args->CheckValue ("-bits")) )
|
||||
bits = atoi (i);
|
||||
|
||||
if (width == 0)
|
||||
|
@ -1638,6 +1640,7 @@ void V_Init2()
|
|||
float gamma = static_cast<DDummyFrameBuffer *>(screen)->Gamma;
|
||||
FFont *font = screen->Font;
|
||||
|
||||
screen->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete screen;
|
||||
screen = NULL;
|
||||
|
||||
|
|
|
@ -1148,7 +1148,7 @@ bool FWadCollection::IsMarker (const FWadCollection::LumpRecord *lump, const cha
|
|||
|
||||
void FWadCollection::ScanForFlatHack (int startlump)
|
||||
{
|
||||
if (Args.CheckParm ("-noflathack"))
|
||||
if (Args->CheckParm ("-noflathack"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1348,7 +1348,7 @@ void FWadCollection::RenameSprites (int startlump)
|
|||
break;
|
||||
}
|
||||
|
||||
renameAll = !!Args.CheckParm ("-oldsprites");
|
||||
renameAll = !!Args->CheckParm ("-oldsprites");
|
||||
|
||||
for (DWORD i = startlump + 1;
|
||||
i < NumLumps &&
|
||||
|
|
|
@ -61,7 +61,11 @@ IVideo *Video;
|
|||
void I_ShutdownGraphics ()
|
||||
{
|
||||
if (screen)
|
||||
delete screen, screen = NULL;
|
||||
{
|
||||
screen->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete screen;
|
||||
screen = NULL;
|
||||
}
|
||||
if (Video)
|
||||
delete Video, Video = NULL;
|
||||
}
|
||||
|
@ -86,7 +90,7 @@ void I_InitGraphics ()
|
|||
// are the active app. Huh?
|
||||
}
|
||||
|
||||
val.Bool = !!Args.CheckParm ("-devparm");
|
||||
val.Bool = !!Args->CheckParm ("-devparm");
|
||||
ticker.SetGenericRepDefault (val, CVAR_Bool);
|
||||
Video = new Win32Video (0);
|
||||
if (Video == NULL)
|
||||
|
@ -227,7 +231,7 @@ static void KeepWindowOnScreen (int &winx, int &winy, int winw, int winh, int sc
|
|||
void I_SaveWindowedPos ()
|
||||
{
|
||||
// Don't save if we were run with the -0 option.
|
||||
if (Args.CheckParm ("-0"))
|
||||
if (Args->CheckParm ("-0"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -268,7 +272,7 @@ void I_RestoreWindowedPos ()
|
|||
GetCenteredPos (winx, winy, winw, winh, scrwidth, scrheight);
|
||||
|
||||
// Just move to (0,0) if we were run with the -0 option.
|
||||
if (Args.CheckParm ("-0"))
|
||||
if (Args->CheckParm ("-0"))
|
||||
{
|
||||
winx = winy = 0;
|
||||
}
|
||||
|
|
|
@ -473,7 +473,7 @@ bool CD_Init ()
|
|||
|
||||
bool CD_Init (int device)
|
||||
{
|
||||
if (!cd_enabled || Args.CheckParm ("-nocdaudio"))
|
||||
if (!cd_enabled || Args->CheckParm ("-nocdaudio"))
|
||||
return false;
|
||||
|
||||
if (CDThread == NULL)
|
||||
|
|
|
@ -1105,7 +1105,7 @@ void DI_EnumJoy ()
|
|||
JoyActive = 0;
|
||||
JoystickNames.Clear ();
|
||||
|
||||
if (g_pdi != NULL && !Args.CheckParm ("-nojoy"))
|
||||
if (g_pdi != NULL && !Args->CheckParm ("-nojoy"))
|
||||
{
|
||||
g_pdi->EnumDevices (DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, NULL, DIEDFL_ALLDEVICES);
|
||||
}
|
||||
|
@ -1403,7 +1403,7 @@ bool I_InitInput (void *hwnd)
|
|||
NativeMouse = -1;
|
||||
GetCursorPos (&UngrabbedPointerPos);
|
||||
|
||||
noidle = !!Args.CheckParm ("-noidle");
|
||||
noidle = !!Args->CheckParm ("-noidle");
|
||||
g_pdi = NULL;
|
||||
g_pdi3 = NULL;
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ extern HCURSOR TheArrowCursor, TheInvisibleCursor;
|
|||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
// The command line arguments.
|
||||
DArgs Args;
|
||||
DArgs *Args;
|
||||
|
||||
HINSTANCE g_hInst;
|
||||
DWORD SessionID;
|
||||
|
@ -776,7 +776,7 @@ void DoMain (HINSTANCE hInstance)
|
|||
_set_new_handler (NewFailure);
|
||||
#endif
|
||||
|
||||
Args.SetArgs (__argc, __argv);
|
||||
Args = new DArgs(__argc, __argv);
|
||||
|
||||
// Under XP, get our session ID so we can know when the user changes/locks sessions.
|
||||
// Since we need to remain binary compatible with older versions of Windows, we
|
||||
|
@ -827,7 +827,7 @@ void DoMain (HINSTANCE hInstance)
|
|||
x = (displaysettings.dmPelsWidth - width) / 2;
|
||||
y = (displaysettings.dmPelsHeight - height) / 2;
|
||||
|
||||
if (Args.CheckParm ("-0"))
|
||||
if (Args->CheckParm ("-0"))
|
||||
{
|
||||
x = y = 0;
|
||||
}
|
||||
|
|
|
@ -404,7 +404,7 @@ void I_Init (void)
|
|||
UINT delay;
|
||||
char *cmdDelay;
|
||||
|
||||
cmdDelay = Args.CheckValue ("-timerdelay");
|
||||
cmdDelay = Args->CheckValue ("-timerdelay");
|
||||
delay = 0;
|
||||
if (cmdDelay != 0)
|
||||
{
|
||||
|
|
|
@ -504,6 +504,7 @@ DFrameBuffer *Win32Video::CreateFrameBuffer (int width, int height, bool fullscr
|
|||
return old;
|
||||
}
|
||||
old->GetFlash (flashColor, flashAmount);
|
||||
old->ObjectFlags |= OF_YesReallyDelete;
|
||||
delete old;
|
||||
}
|
||||
else
|
||||
|
|
1609
zdoom.vcproj
1609
zdoom.vcproj
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue