- 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:
Randy Heit 2008-03-12 02:56:11 +00:00
parent 3bfcc5c09c
commit f2660dc336
88 changed files with 2545 additions and 1527 deletions

View file

@ -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.

View file

@ -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:

View file

@ -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.
};

View file

@ -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);
}
}
}

View file

@ -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),

View file

@ -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;
}

View file

@ -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]);

View file

@ -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);

View file

@ -161,7 +161,7 @@ public:
void DoPickupSpecial (AActor *toucher);
private:
const PClass *DetermineType ();
AInventory *RealPickup;
TObjPtr<AInventory> RealPickup;
};
IMPLEMENT_POINTY_CLASS (ADehackedPickup)

View file

@ -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;
}
@ -2039,7 +2038,6 @@ void D_DoomMain (void)
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;

View file

@ -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

View file

@ -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);

View file

@ -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)
{

View file

@ -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;

View file

@ -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
View 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]));
}
}
}

View file

@ -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)

View file

@ -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; }

View file

@ -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 ();
}

View file

@ -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

View file

@ -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)

View file

@ -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);

View file

@ -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;
}

View file

@ -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;

View file

@ -32,7 +32,7 @@ class APod : public AActor
HAS_OBJECT_POINTERS
public:
void BeginPlay ();
AActor *Generator;
TObjPtr<AActor> Generator;
void Serialize (FArchive &arc);
};

View file

@ -803,7 +803,7 @@ public:
protected:
bool DoRespawn ();
int NumMaceSpots;
AActor *FirstSpot;
TObjPtr<AActor> FirstSpot;
private:
friend void A_SpawnMace (AActor *self);

View file

@ -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;
}

View file

@ -386,6 +386,7 @@ bool AHolySpirit::SpecialBlastHandling (AActor *source, fixed_t strength)
{
tracer = target;
target = source;
GC::WriteBarrier(this, source);
}
return true;
}

View file

@ -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;

View file

@ -66,7 +66,7 @@ protected:
virtual bool MatchPlayerClass (AActor *toucher);
const PClass *FourthWeaponClass;
int PieceValue;
AInventory *TempFourthWeapon;
TObjPtr<AInventory> TempFourthWeapon;
bool PrivateShouldStay ();
};

View file

@ -103,7 +103,7 @@ public:
void Activate (AActor *activator);
void Deactivate (AActor *activator);
ADirtClump *DirtClump;
TObjPtr<ADirtClump> DirtClump;
};
IMPLEMENT_POINTY_CLASS (AThrustFloor)

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 () {}

View file

@ -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 ()

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
};

View file

@ -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

View file

@ -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;
};

View file

@ -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;
}

View file

@ -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)

View file

@ -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 ();

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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;
}

View file

@ -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";
}

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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__

View file

@ -71,6 +71,6 @@ private:
void CopyArgs (int argc, char **argv);
};
extern DArgs Args;
extern DArgs *Args;
#endif //__M_ARGV_H__

View file

@ -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;

View file

@ -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);

View file

@ -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 "\\";
}

View file

@ -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)

View file

@ -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 ();

View file

@ -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();

View file

@ -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)

View file

@ -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)

View file

@ -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 ();

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}
}

View file

@ -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

View file

@ -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];

View file

@ -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;

View file

@ -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

View file

@ -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++;

View file

@ -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;

View file

@ -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);

View file

@ -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:

View file

@ -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 ();

View file

@ -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)
{

View file

@ -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 ()

View file

@ -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;

View file

@ -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 &&

View file

@ -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;
}

View file

@ -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)

View file

@ -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;

View file

@ -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;
}

View file

@ -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)
{

View file

@ -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

File diff suppressed because it is too large Load diff